k8s cni

作者: shoyu666 | 来源:发表于2022-03-12 23:06 被阅读0次

背景

提到k8s网络就不得不提 CNI(容器网络接口),本文主要是说下CNI是什么,以及在哪里被调用,不对CNI插件的具体实现做分析。

k8s网络

k8s要求每个Pod都有自己独立的Ip地址,同个Host下 Pod和Pod之间访问,跨Host 下 Pod之间的访问可以在一个虚拟的网络层中,虚拟的网络层在实际网络层之上。满足这个要求的实现方式有很多种,所以K8s就将网络实现独立出来,以插件的形式加载,CNI 容器网络接口就定义了一种实现k8s网络的规范接口。cni官方定义

CNI

CNI 是一个标准和约定,只要实现CNI标准的网络解决方案都可以被k8s使用。CNI的实现有Bridge,Flannel,Calico,terway(阿里云基于VPC的实现)
网上一般对CNI的调用分析(也就是CNI是怎么被调用的),会基于 /pkg/kubelet/dockershim/network/cni.go和/pkg/kubelet/dockershim/docker_sandbox.go,但是新版本的k8s kubelet模块移除了dockershim。
移除的原因是因为K8s遵循CRI(Container Runtime Interface),CRI的目的是为了让K8s和容器实现解耦,只要符合CRI规范的容器实现都可以被K8s使用,早期因为CRI未出现,或者CRI出现后未壮大,所以K8s会内置容器实现,比如dockershim。
之前CNI的调用代码在dockershim也说明一个定位,就是CNI不是K8s kubelet的一部分,CNI是给容器定的规范,
所以官方也说CRI自己管理CNI 出自:this is only true for Docker, as CRI manages its own CNI plugins
综上得出,CRI基于CNI管理K8s网络,所以看CNI的调用,我们可以去看CRI某个具体实现的调用。

containerd

containerd是OCI的标准实现,并在后来直接内置了CRI(因为k8s成为了标准),containerd通过runC运行容器(曾经的libcontainer)。
kubelet 创建Pod时会请求 containerd 经过一系列代码,最终会到 sandbox_run.go 的 RunPodSandbox方法, RunPodSandbox方法会调用setupPodNetwork。

https://github.com/containerd/containerd/blob/d4641e1ce1e07393115cd52bd71041ee8a99a180/pkg/cri/server/sandbox_run.go#L61
func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandboxRequest) (_ *runtime.RunPodSandboxResponse, retErr error) {
   ....
if err := c.setupPodNetwork(ctx, &sandbox); err != nil {...
}

可以看到setupPodNetwork 的 netPlugin = c.getNetworkPlugin(sandbox.RuntimeHandler) 正是CNI插件

//https://github.com/containerd/containerd/blob/d4641e1ce1e07393115cd52bd71041ee8a99a180/pkg/cri/server/sandbox_run.go#L377
func (c *criService) setupPodNetwork(ctx context.Context, sandbox *sandboxstore.Sandbox) error {
    var (
        id        = sandbox.ID
        config    = sandbox.Config
        path      = sandbox.NetNSPath
        netPlugin = c.getNetworkPlugin(sandbox.RuntimeHandler)
    )
      ....
    result, err := netPlugin.Setup(ctx, id, path, opts...)
}

// getNetworkPlugin returns the network plugin to be used by the runtime class
// defaults to the global CNI options in the CRI config
func (c *criService) getNetworkPlugin(runtimeClass string) cni.CNI {
    if c.netPlugin == nil {
        return nil
    }
    i, ok := c.netPlugin[runtimeClass]
    if !ok {
        if i, ok = c.netPlugin[defaultNetworkPlugin]; !ok {
            return nil
        }
    }
    return i
}

到这里就是CNI插件的逻辑了,那么会问,插件安装在哪里?多个插件如何选择?
插件安装在哪里?
在 /opt/cni/bin,在该目录下可以看到很多插件的可执行文件,比如bridge
多个插件如何选择?
在 /etc/cni/net.d/目录下的配置文件定义
CNI会加载/etc/cni/net.d/目录下的配置文件定义,来决定使用哪几个插件。
比如下面配置文件使用bridge插件和host-local插件

$ mkdir -p /etc/cni/net.d
$ cat >/etc/cni/net.d/10-mynet.conf <<EOF
{
    "cniVersion": "0.2.0",
    "name": "mynet",
    "type": "bridge",
    "bridge": "cni0",
    "isGateway": true,
    "ipMasq": true,
    "ipam": {
        "type": "host-local",
        "subnet": "10.22.0.0/16",
        "routes": [
            { "dst": "0.0.0.0/0" }
        ]
    }
}

bridge的网络模型如图所示


图1

bridge插件实际干的事件就是配置出图1的网络模型。
方法就是通过几个系统调用(创建bride,创建veth对,启用,设置Ip,设置路由等)
比如
创建 bridge:

brctl addbr Bridge

创建两对 veth:

//veth1 和 veth1_peer 是一对 它们相互连通。
ip link add veth type veth1 peer name veth1_peer
ip link add veth type veth2 peer name veth2_peer

也就是bridge插件通过这些系统命令创建和配置出类似图1的网络模型完成Pod的网络配置。
所以理解容器网络需要对linux网络和相关的系统调用都比较熟悉。

综上,CNI是给CRI实现的,kubelet 不涉及CNI实现,kubelet请求CRI创建容器时,CRI会负责通过CNI配置网络。
以containerd为例,通过 /etc/cni/net.d/ 下的配置确定CNI的具体插件,在netPlugin.Setup方法调用CNI的插件。
k8s体系庞大,了解流程后,关于CNI插件的具体实现,比如bridge或Flannel可以单独去看。

相关文章

  • k8s cni

    背景 提到k8s网络就不得不提 CNI(容器网络接口),本文主要是说下CNI是什么,以及在哪里被调用,不对CNI插...

  • K8S 网络插件对比

    集群网络架构是 K8s 中比较复杂的,最让用户头痛的方面之一。K8s 拥有众多的 CNI 插件,该如何做好CNI的...

  • k8s之ovs-cni

    ovs-cni是由kubevirt提供的一种k8s cni, 用于将pod接口长在ovs网桥上面,其原理为:创建一...

  • k8s flannel host-gw

    接 k8s flannel cni plugin[https://www.jianshu.com/p/d1917a...

  • 查看CNI中的veth pair

    flannel是k8s的pod网络之一,cni0是配置flannel时会出现的典型网桥Cni0:网桥设备,每创建一...

  • k8s 网络三

    k8s网络包括网络模型、CNI、Service、Ingress、DNS。k8s的容器网络关注两点:IP地址分配,路...

  • 压测iptables规则条数的限制

    前言 今天在使用k8s的时候,由于运用到了calico这个cni插件和k8s自带的NetworkPolicy的功能...

  • k8s Flannel网络方案

    k8s中规定了CNI接口,但是没有标准化网络方案,网络方案也是网络基础,在这个基础上k8s提供了service负载...

  • k8s cni

    https://github.com/containernetworking/cni/blob/master/pk...

  • K8S CNI

    从网络模型说起 容器的网络技术日新月异,经过多年发展,业界逐渐聚焦到 Docker 的 CNM(Container...

网友评论

    本文标题:k8s cni

    本文链接:https://www.haomeiwen.com/subject/fjekdrtx.html