前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

k8s cni

原创
作者头像
conanma
发布2022-03-17 20:40:35
5710
发布2022-03-17 20:40:35
举报
文章被收录于专栏:正则正则
背景

提到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

综上得出,CRI基于CNI管理K8s网络,所以看CNI的调用,我们可以去看CRI某个具体实现的调用。

containerd

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

代码语言:javascript
复制
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插件

代码语言:javascript
复制
//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插件

代码语言:javascript
复制
$ 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的网络模型如图所示

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

代码语言:javascript
复制
brctl addbr Bridge

创建两对 veth:

代码语言:javascript
复制
//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可以单独去看。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • k8s网络
    • CNI
    • containerd
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档