calico cni阅码笔记

kubernetes版本 :V1.22.2

CNI 概述

CNI(Container Network Interface),是CNCF基金会的一个子项目,包括一些规则说明(SPEC),库文件(libcni),一些插件(bridge,macvlan等)。CNI只关注容器网络的连通性,在创建和删除POD时,创建或删除相应的网络资源。用通俗的话就是说,CNI只是定义了一些接口和一些规范,接口是给CRI调用使用的,规范是CNI插件要遵守的。
CNI规范
1、定义网络配置文件的格式
2、定义container runtime向cni插件的请求协议
3、定义cni插件的二进制文件的执行参数
4、定义插件的委托模式,即将一些功能交给其他plugin去处理,如ipam plugin,multus
5、定义cni返回结果的数据类型

为避免歧义,在这里粘贴下英文原文 :

  1. A format for administrators to define network configuration.
  2. A protocol for container runtimes to make requests to network plugins.
  3. A procedure for executing plugins based on a supplied configuration.
  4. A procedure for plugins to delegate functionality to other plugins.
  5. Data types for plugins to return their results to the runtime.

来个概览图

image.png

docker与CNI

docker也是CRI的一种实现,但是docker的CRI实现部分(dockershim)在kubernetes v1.23.0版本依然在kubernetes的代码库中。

# 命名空间的路径文件
dockerNetNSFmt = "/proc/%v/ns/net" %pid  
# 调用cni二进制的代码,c.exec即是二进制文件的路径
pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
invoke.ExecPluginWithResult(ctx, pluginPath, newConf.Bytes, c.args("ADD", rt), c.exec)  

containerd与CNI

比起docker的CNI接口实现,containerd的cni实现更加的简洁,标准。这里需要注意 :是CRI调用CNI,CNI调用具体的网络插件。

RunPodSandbox
sandbox.NetNSPath = sandbox.NetNS.GetPath()
c.setupPodNetwork(ctx, &sandbox)
c.netPlugin.Setup(ctx, id, path, opts...)
network.Attach(ctx, ns)
n.cni.AddNetworkList(ctx, n.config, ns.config(n.ifName))
c.addNetwork(ctx, list.Name, list.CNIVersion, net, result, rt)
invoke.ExecPluginWithResult(ctx, pluginPath, newConf.Bytes, c.args("ADD", rt), c.exec)

calico cni实现

cni规范的最新版本是V1.0.0,calico目前最高支持到v0.3.1。

skel.PluginMain(cmdAdd, nil, cmdDel,
    cniSpecVersion.PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1"),
    "Calico CNI plugin "+version)
        // 1) Call the configured IPAM plugin to get IP address(es)
        // 2) Configure the Calico endpoint
        // 3) Create the veth, configuring it on both the host and container namespace.
// 取得calixx网卡的名称
desiredVethName := k8sconversion.NewConverter().VethNameForWorkload(epIDs.Namespace, epIDs.Pod)   

下图重点展示DoNetworking函数的作用 :
包括设置网卡地址对,设置路由,启用转发等。

DoNetworking.png

calico ipam插件

// 注册ADD和DEL回调函数
skel.PluginMain(cmdAdd, nil, cmdDel,
    cniSpecVersion.PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1"),
    "Calico CNI IPAM "+version)
utils.ResolvePools(ctx, calicoClient, conf.IPAM.IPv4Pools, true)
v6pools, err := utils.ResolvePools(ctx, calicoClient, conf.IPAM.IPv6Pools, false)
calicoClient.IPAM().AutoAssign(ctx, assignArgs
c.autoAssign(ctx, args.Num4, args.HandleID, args.Attrs, args.IPv4Pools, 4, hostname, args.MaxBlocksPerHost, args.HostReservedAttrIPv4s)
c.prepareAffinityBlocksForHost(ctx, requestedPools, version, host, rsvdAttr)  
c.determinePools(ctx, requestedPools, version, *v3n, maxPrefixLen)
c.blockReaderWriter.getAffineBlocks(ctx, host, version, pools)
.assignFromExistingBlock(ctx, b, rem, handleID, attrs, host, false)
b.autoAssign(num, handleID, host, attrs, affCheck)
attrIndex := b.findOrAddAttribute(handleID, attrs) 
c.blockReaderWriter.updateBlock(ctx, block)

涉及到的资源对象有IPPool,IPAMBlock,BlockAffinity,WorkloadEndpoint,IPAMHandle

ipam.png

看懂IPAMBLOCK

// ipamblock的资源定义
[root@10 cni]# kubectl  explain ipamblocks.crd.projectcalico.org.spec
KIND:     IPAMBlock
VERSION:  crd.projectcalico.org/v1
RESOURCE: spec <Object>
DESCRIPTION:
     IPAMBlockSpec contains the specification for an IPAMBlock resource.
FIELDS:
   affinity     <string>
   allocations  <[]> -required-
   attributes   <[]Object> -required-
   cidr <string> -required-
   deleted      <boolean>
   strictAffinity       <boolean> -required-
   unallocated  <[]integer> -required-

[root@10 cni]# kubectl  get ipamblocks.crd.projectcalico.org 10-244-5-128-26 -o yaml
apiVersion: crd.projectcalico.org/v1
kind: IPAMBlock
metadata:
  name: 10-244-5-128-26
  uid: abb02b81-3dfc-4a30-a0d9-58f15f24c47d
spec:
  affinity: host:10.10.101.91-slave
  allocations:
  - null
  - 0
  - null
  - null
  - 1
  - 省略
  - 2
  - null
  - 3
  - 省略
  - null
  - 6
  - null
  - null
  - 7
  - null
  - null
  - null
  - 5
  - 4
  - null
  attributes:
  - handle_id: vxlan-tunnel-addr-10.10.101.91-slave
    secondary:
      node: 10.10.101.91-slave
      type: vxlanTunnelAddress
  - handle_id: k8s-pod-network.014688d18778c72045e9c0b05260c90dda84a7faea109d01adee487e6b40d70e
    secondary:
      namespace: kube-system
      node: 10.10.101.91-slave
      pod: calico-kube-controllers-cf4844b67-sddbj
      timestamp: 2021-11-28 03:18:53.22987459 +0000 UTC
  - handle_id: k8s-pod-network.2393551f10bd7b4371499f53ce28815222814db3ae291c5fe865faebc291070d
    secondary:
      namespace: default
      node: 10.10.101.91-slave
      pod: lugl-deploy-busybox-66f4444d68-kbgdc
      timestamp: 2021-12-15 10:19:14.495804833 +0000 UTC
  - handle_id: k8s-pod-network.0e34072f8b17070afd0d5163284ae42f95379432cacfd030476cdc7f7fce2652
    secondary:
      namespace: default
      node: 10.10.101.91-slave
      pod: lugl-deploy-busybox-66f4444d68-5k2cm
      timestamp: 2021-12-15 10:19:14.524535051 +0000 UTC
  cidr: 10.244.5.128/26
  deleted: false
  strictAffinity: false
  unallocated:
  - 49
  - 35
  - 52
  - 60
  - 8
  - 40
  - 54
  - 省略

attributes 包含了所有使用该ipamblock的ip的资源对象,并且是有序的。
比如要查看attributes数组的第三个资源的ip,要在alloctions数组中找到值为3看看是在哪一项,比如allocations[5] = 3,那么第三个资源的ip就是这个block的cidr的第5个ip。
相反的,如果删除了一个资源对象,对应的ipamblock资源对象也需要删除,首先在attributes数组中删除对应的资源对象,再将allocations[i]置为nil,再将i值append到unallocations中,这就完成了ip的释放。

kubelet配置项

HairpinMode

func NewContainerRuntimeOptions() *config.ContainerRuntimeOptions {
    dockerEndpoint := ""
    if runtime.GOOS != "windows" {
        dockerEndpoint = "unix:///var/run/docker.sock"
    }

    return &config.ContainerRuntimeOptions{
        ContainerRuntime:          kubetypes.DockerContainerRuntime,
        DockerEndpoint:            dockerEndpoint,
        DockershimRootDirectory:   "/var/lib/dockershim",
        PodSandboxImage:           defaultPodSandboxImage,
        ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},

        CNIBinDir:   "/opt/cni/bin",
        CNIConfDir:  "/etc/cni/net.d",
        CNICacheDir: "/var/lib/cni/cache",
    }
}

有用的冷知识

Q : 容器内部的lo网卡是如何创建的?
A : 内核中注册了很多命名空间的初始化函数,其中就包括lo设备。当新建一个命名空间时,内核会自动在该命名空间内创建lo设备。

static __net_init int loopback_net_init(struct net *net)
{
    struct net_device *dev;
    int err;
    dev = alloc_netdev(0, "lo", NET_NAME_UNKNOWN, loopback_setup);
    dev_net_set(dev, net);
   // 注册环回口lo设备
    err = register_netdev(dev);
    net->loopback_dev = dev;
    return 0;
}

struct pernet_operations __net_initdata loopback_net_ops = {
    .init = loopback_net_init,
};
register_pernet_device(&loopback_net_ops)

Q : 路由条目中的onlink参数
A : 添加路由时,加上onlink参数,内核就不再判断下一跳是否可达。

参考文档 :
https://github.com/containernetworking/cni
https://github.com/containernetworking/cni/blob/master/SPEC.md

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 228,386评论 6 532
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,504评论 3 416
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 176,324评论 0 374
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,968评论 1 311
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,733评论 6 410
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,194评论 1 324
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,259评论 3 441
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,412评论 0 288
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,947评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,779评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,978评论 1 369
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,521评论 5 359
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,217评论 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,647评论 0 26
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,886评论 1 286
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,658评论 3 391
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,963评论 2 373

推荐阅读更多精彩内容