Kubernetes Pod 多网卡 Multus-CNI 实现

半兽人 发表于: 2021-05-08   最后更新时间: 2023-10-30 20:28:52  
{{totalSubscript}} 订阅, 1,076 游览

快速入门指南

本指南旨在帮助你使用 Multus CNI 创建具有多个接口的 Kubernetes pod。如果您已经在使用 Multus 并需要更多细节,请参阅综合使用指南。本文档集快速入门和入门指南于一体,适用于首次使用 Multus CNI 的用户。

我们将首先安装 Multus CNI,然后设置一些配置,以便了解如何为 pod 创建多个接口。

关键概念

在本文件中,我们将多次提到两件事:

  • "默认网络" -- 这就是 pod 之间的网络。这是 pod 在集群中相互通信的方式,也是它们的连接方式。一般来说,这表现为名为 "eth0 "的接口。这个接口会一直连接到 pod 上,这样 pod 之间就可以相互连接。除此以外,我们还将添加其他接口。

  • "CRDs" -- Custom Resource Definitions。自定义资源是 Kubernetes API 的一种扩展方式。我们在这里用它们来存储 Multus 可以读取的一些信息。我们主要用它们来存储连接到 pod 的每个附加接口的配置。

前提条件

我们的安装方法要求您首先安装 Kubernetes 并配置默认网络 -- 即用于 pod 到 pod 连接的 CNI 插件。

我们推荐 Kubernetes 1.16 或更高版本。

安装 Kubernetes 后,必须安装默认网络 CNI 插件。简单起见,我们一般建议使用 Flannel。

或者,对于高级用例,要同时安装 Multus 和默认网络插件,您可以参考 Kubernetes Network Plumbing Group 的参考部署

要验证默认网络是否就绪,可使用以下命令列出 Kubernetes 节点:

kubectl get nodes

如果默认网络已就绪,将看到每个节点的 "STATUS "栏也切换为 "Ready"。

NAME                  STATUS   ROLES           AGE    VERSION
master-0              Ready    master          1h     v1.17.1
master-1              Ready    master          1h     v1.17.1
master-2              Ready    master          1h     v1.17.1

安装

我们推荐的快速入门方法是使用 Daemonset(在集群中的每个节点上运行 pod 的一种方法)部署 Multus,这会启动安装 Multus 二进制文件的 pod 并配置 Multus 的使用。

首先,克隆这个 GitHub 仓库。

git clone https://github.com/k8snetworkplumbingwg/multus-cni.git && cd multus-cni

使用kubectl 应用一个 YAML 文件。

推荐安装:

cat ./deployments/multus-daemonset-thick.yml | kubectl apply -f -

有关此架构的更多信息,请参阅 thick插件 文档。

或者,也可以通过以下方式安装瘦身插件:

$ cat ./images/multus-daemonset.yml | kubectl apply -f -

Multus 守护进程集的作用

  • 启动 Multus 守护进程,在每个节点上运行一个 pod,该 pod 会在每个节点上的 /opt/cni/bin 中放置一个 Multus 二进制文件。

  • 读取 /etc/cni/net.d 中按字母顺序排列的第一个配置文件,并在每个节点上为 Multus 创建一个新的配置文件,文件名为 /etc/cni/net.d/00-multus.conf,该配置文件是自动生成的,基于默认网络配置(假定为按字母顺序排列的第一个配置文件)。

  • 在每个节点上创建一个 /etc/cni/net.d/multus.d 目录,其中包含 Multus 访问 Kubernetes API 的身份验证信息。

验证安装

一般来说,验证安装的第一步是确保 Multus pod 运行无误:

$ kubectl get pods --all-namespaces | grep -i multus

您还可以通过查看 /etc/cni/net.d/ 目录,确保自动生成的 /etc/cni/net.d/00-multus.conf 与按字母顺序排列的第一个配置文件相对应,从而进一步验证它是否已运行。

创建更多的接口

我们要做的第一件事是为附加到 pod 的每个附加接口创建配置。为此,我们将创建自定义资源。快速启动安装的一部分功能是创建一个 "CRD"(自定义资源定义),它是我们保存这些自定义资源的 "家",我们将在其中存储每个接口的配置。

CNI Configurations

我们要添加的每个配置都是 CNI 配置。如果你对它们不熟悉,让我们快速分解它们。下面是一个 CNI 配置示例:

{
  "cniVersion": "0.3.0",
  "type": "loopback",
  "additional": "information"
}

CNI 配置是 JSON 格式,我们这里有一个结构,其中包含一些我们感兴趣的内容:

  1. cniVersion: 告诉每个 CNI 插件正在使用的版本,并在插件使用过晚(或过早)版本时提供相关信息。
  2. type: 告诉 CNI 在磁盘上调用哪个二进制文件。每个 CNI 插件都是一个被调用的二进制文件。通常,这些二进制文件存储在每个节点上的 /opt/cni/bin中,CNI 会执行该二进制文件。在本例中,我们指定了 loopback 二进制文件(用于创建环回类型的网络接口)。如果这是您第一次安装 Multus,你可能需要验证"类型"字段中的插件是否确实在磁盘上的 /opt/cni/bin 目录中。
  3. additional: 此字段仅作为示例,每个 CNI 插件都可以在 JSON 中指定自己想要的任何配置参数。这些参数是针对 type 字段中调用的二进制文件的。

如需更多示例,请参阅 bridge CNI 插件 README,其中显示了更多细节。

如果您想了解有关 CNI 配置的更多信息,可以阅读CNI 规范全文。此外,查看CNI 参考插件 并了解它们是如何配置的也会有所帮助。

当 CNI 配置发生变化时,您无需重新加载或刷新 Kubelet。每次创建和删除 pod 时都会读取这些配置。因此,如果您更改了配置,下次创建 pod 时就会应用。如果现有 pod 需要新配置,则可能需要重新启动。

将配置存储为自定义资源

因此,我们要创建一个额外的接口。让我们创建一个供 pod 使用的 macvlan 接口。我们将创建一个自定义资源,用于定义接口的 CNI 配置。

请注意,下面的命令中有一个 kind: NetworkAttachmentDefinition。这是我们配置的花名 -- 它是 Kubernetes 的自定义扩展,定义了我们如何将网络连接到 pod。

其次,请注意config字段。你会看到这是一个 CNI 配置,就像我们之前解释的那样。

最后但非常重要的一点是,请注意 metadata 下的 name 字段 -- 这里是我们为配置命名的地方,也是我们告诉 pod 使用此配置的方式。这里的名称是 macvlan-conf -- 因为我们正在为 macvlan 创建配置。

下面是创建此配置示例的命令:

cat <<EOF | kubectl create -f -
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: macvlan-conf
spec:
  config: '{
      "cniVersion": "0.3.0",
      "type": "macvlan",
      "master": "eth0",
      "mode": "bridge",
      "ipam": {
        "type": "host-local",
        "subnet": "192.168.1.0/24",
        "rangeStart": "192.168.1.200",
        "rangeEnd": "192.168.1.216",
        "routes": [
          { "dst": "0.0.0.0/0" }
        ],
        "gateway": "192.168.1.1"
      }
    }'
EOF

注意: 此示例使用eth0作为master参数,此master参数应与集群中主机的接口名称相匹配。

你可以使用 kubectl 查看已创建的配置:

kubectl get network-attachment-definitions

也可以通过 describe 命令获得更多细节:

kubectl describe network-attachment-definitions macvlan-conf

创建可附加接口的 pod

我们将创建一个 pod。这个 pod 与之前创建的任何 pod 看起来都很相似,但我们会有一个特殊的annotations字段 -- 在本例中,我们会有一个名为 k8s.v1.cni.cncf.io/networks的注释。该字段以逗号分隔,包含上文创建的NetworkAttachmentDefinition名称列表。请注意,在下面的命令中,我们注释了 k8s.v1.cni.cncf.io/networks: macvlan-conf,其中 macvlan-conf 是我们在上面创建配置时使用的名称。

让我们用这条命令来创建一个 pod(它会休眠很长时间):

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: macvlan-conf
spec:
  containers:
  - name: samplepod
    command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"]
    image: alpine
EOF

现在,可以检查 pod 并查看连接了哪些接口:

$ kubectl exec -it samplepod -- ip a

请注意有 3 个接口:

  • lo 一个环回接口
  • eth0 我们的默认网络
  • net1 我们使用 macvlan 配置创建的新接口。

网络状态注解

如需进一步确认,请使用 kubectl describe pod samplepod,这时会出现类似下面的注释部分:

Annotations:        k8s.v1.cni.cncf.io/networks: macvlan-conf
                    k8s.v1.cni.cncf.io/networks-status:
                      [{
                          "name": "cbr0",
                          "ips": [
                              "10.244.1.73"
                          ],
                          "default": true,
                          "dns": {}
                      },{
                          "name": "macvlan-conf",
                          "interface": "net1",
                          "ips": [
                              "192.168.1.205"
                          ],
                          "mac": "86:1d:96:ff:55:0d",
                          "dns": {}
                      }]

这个元数据告诉我们,我们有两个 CNI 插件正在成功运行。

如果我想要更多接口怎么办?

可以创建更多自定义资源,然后在 pod 的注释中引用这些资源,从而为 pod 添加更多接口。你还可以重复使用配置,例如,要在 pod 上附加两个 macvlan 接口,您可以创建一个这样的 pod:

cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: macvlan-conf,macvlan-conf
spec:
  containers:
  - name: samplepod
    command: ["/bin/ash", "-c", "trap : TERM INT; sleep infinity & wait"]
    image: alpine
EOF

请注意,注解现在是 k8s.v1.cni.cncf.io/networks:macvlan-conf,macvlan-conf。在这里,我们两次使用了相同的配置,并用逗号隔开。

如果您要创建另一个名称为 foo 的自定义资源,您可以使用该资源,例如: k8s.v1.cni.cncf.io/networks:foo,macvlan-conf,并使用任意数量的附加。

REF

https://github.com/k8snetworkplumbingwg/multus-cni
https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/docs/quickstart.md

更新于 2023-10-30

查看kubernetes更多相关的文章或提一个关于kubernetes的问题,也可以与我们一起分享文章