V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GopherDaily
V2EX  ›  Kubernetes

K8s Network: CNI 初探, 以 flannel 为例

  •  
  •   GopherDaily · 2023-12-07 14:01:59 +08:00 · 990 次点击
    这是一个创建于 377 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在过去的这些年, K8s 参与并推动了两个容器相关的标准.

    一个是挂在 OCI 下的 runtime-spec, 定义并规范了容器运行的方方面面. 依赖于此我们使用 K8s 时可以自由选择底层的容器运行时实现而不影响上层功能.

    另一个是 CNI (Container Network Interface), 定义了容器运行时如何管理容器网络. 在这个标准下开发的各类插件都可以直接在容器运行时中使用, 不再需要双方适配.

    CNI 速览

    CNI 中有两个关键角色, 一是容器运行时, 一是各类网络插件. 容器运行时负责在容器创建和销毁时, 根据配置调用指定插件的 ADD 和 DEL 命令.

    同时, 比较有意义的点是:

    • 插件以可执行文件的方式放置在宿主机的特定目录, 默认是 /opt/cni/bin
    • 容器运行时通过环境变量向插件传递参数
    • 插件通过 stdout 和 stderr 返回执行结果

    为了避免重复实现, CNI 推荐插件通过调用其他插件来完成部分工作, 即 delegate. 同时, CNI 也为最基本的那部分需求提供了官方插件, 罗列于 Plugins Overview.

    flannel

    Flannel 是一个简单但流行的容器网络方案, 其提供了一个 200 多行的 Yaml 文件来将自身部署到 K8s 中, 具体参见 kube-flannel.yaml.

    部署的核心逻辑在于其中的 DaemonSet,

    • 一方面通过两个 initContaienrs 将插件和配置文件复制到宿主机.
    • 一方面通过 flanneld 监听节点信息, 处理路由转发逻辑.

    flannel-cni

    容器运行时根据配置文件调用 flannel-cni 后, flannel-cni 会生成具体的配置文件调用其他插件来完成具体工作.

    我们可以在宿主机上找到生成的具体配置信息:

    ~ cat /var/lib/cni/flannel/0e31e47db3bdb67088cd4b2369e641a8eea835208161177a02cbf6b8d26f3373 | jq
    {
      "cniVersion": "0.3.1",
      "hairpinMode": true,
      "ipMasq": false,
      "ipam": {
        "ranges": [
          [
            {
              "subnet": "172.22.0.0/24"
            }
          ]
        ],
        "routes": [
          {
            "dst": "172.22.0.0/16"
          }
        ],
        "type": "host-local"
      },
      "isDefaultGateway": true,
      "isGateway": true,
      "mtu": 1500,
      "name": "cbr0",
      "type": "bridge"
    }
    

    这份配置文件依然遵循 CNI 的配置规范, 我们可以看出其调用了插件 bridge. bridge 会将宿主机上的所有容器都链接到一个虚拟交换机上. 同时也调用 IPAM 在指定的网段内为容器分配了 IP.

    flannel daemon

    flannel 以 DaemonSet 的方式运行在宿主机上.

    我们以测试集群为例, 其配置保存 ConfigMap 中, 并且开启了 ipmasq.

    ~ k get -n kube-flannel cm kube-flannel-cfg -o json | jq '.data["net-conf.json"]' -r | jq
    {
      "Network": "172.22.0.0/16",
      "Backend": {
        "Type": "host-gw"
      }
    }
    ~ ps -ef | grep flanneld
    root      49965  49079  0 8 月 01 ?       09:00:24 /opt/bin/flanneld --ip-masq --kube-subnet-mgr
    root     224755 308100  0 12:11 pts/0    00:00:00 grep --color=auto flanneld
    

    flanneld 的主要职责包括三个方面. 一是将提供给 flannel-cni 的配置文件保存到宿主机的文件系统, 其中包括了宿主机的 podCIDR.

    ~ cat /run/flannel/subnet.env
    FLANNEL_NETWORK=172.22.0.0/16
    FLANNEL_SUBNET=172.22.0.1/24
    FLANNEL_MTU=1500
    FLANNEL_IPMASQ=true
    

    二是通过 iptables 为进出容器网络的流量做 SNAT.

    ~ iptables -t nat -L | grep "Chain FLANNEL-POSTRTG" -A 8
    Chain FLANNEL-POSTRTG (1 references)
    target     prot opt source               destination
    RETURN     all  --  anywhere             anywhere             mark match 0x4000/0x4000 /* flanneld masq */
    RETURN     all  --  172.22.0.0/24        172.22.0.0/16        /* flanneld masq */
    RETURN     all  --  172.22.0.0/16        172.22.0.0/24        /* flanneld masq */
    RETURN     all  -- !172.22.0.0/16        172.22.0.0/24        /* flanneld masq */
    MASQUERADE  all  --  172.22.0.0/16       !base-address.mcast.net/4  /* flanneld masq */
    MASQUERADE  all  -- !172.22.0.0/16        172.22.0.0/16        /* flanneld masq */
    

    MASQUERADE 的效果类似 SNAT, 其会修改数据包的来源地址. Pod 访问外界网络的请求, 经过宿主机后, 来源地址会被修改宿主机, 因为 Pod IP 仅在容器网络内有效.

    三是监听 node 信息后, 通过 ip route 将目标为宿主机上容器的数据包转发到宿主机. 172.22.1.0/24 是另一个节点的 podCIDR, 任何发送到相关容器的流量都会被转发给宿主机.

    ~ ip route | grep 172.22.1.0/24
    172.22.1.0/24 via 10.30.180.55 dev eth0
    ~ k get nodes 10.30.180.55 -o json | jq '.spec.podCIDR' -r
    172.22.1.0/24
    

    Source: https://github.com/j2gg0s/j2gg0s/blob/main/_posts/2023-12-07-k8s%20network%3A%20CNI%20%E5%88%9D%E6%8E%A2%2C%20%E4%BB%A5%20flannel%20%E4%B8%BA%E4%BE%8B.md

    2 条回复    2023-12-07 14:39:45 +08:00
    FabricPath
        1
    FabricPath  
       2023-12-07 14:34:55 +08:00
    可以学点好的,比如 Cilium
    GopherDaily
        2
    GopherDaily  
    OP
       2023-12-07 14:39:45 +08:00
    @FabricPath ROI 很关键,人力有限
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3780 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 10:25 · PVG 18:25 · LAX 02:25 · JFK 05:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.