子接口支持 Multus
从版本 23.3 开始,云原生 Contrail® 网络™ (CN2) 使用 Multus“元”插件支持多个网络子接口。“元”指的是 Multus 多供应商支持。
先决条件
要使 Multus 处理子接口,父接口(物理或虚拟)必须可用。
VLAN 子接口概述
以下内容适用于 VLAN 子接口:
-
始终定义子接口并与父接口关联。
-
此子接口与不同于父接口的虚拟网络相关联。
-
子接口应具有有效的 VLAN 标记 (1–4095)。
-
子接口与常规接口一样,由 CN2 根据提供的网络注释为 Pod 创建。
有关 Multus 如何在云原生 Contrail 环境中工作的更多信息,请参阅 启用具有多个网络接口的 Pod 和 在虚拟接口上启用 VLAN 子接口支持。
在 Pod 上配置子接口
要在 Pod 上配置子接口,请使用网络定义标记 net.juniper.contrail.interfacegroup
和 net.juniper.contrail.vlan
YAML 的注释 cni-args
部分。
-
该
net.juniper.contrail.interfacegroup
标记执行以下操作:-
接口将两个或多个接口组合在一起。
-
父接口是仅与此标记关联的网络选择元素。
-
子接口是与此标记和 VLAN 标记相关联的网络选择元素。
-
-
标记指定
net.juniper.contrail.vlan
子接口上的 VLANID。
CN2 CNI 与 Multus
本节包括使用 Multus 配置 CN2 CNI 的示例 YAML。
子接口的网络附件定义示例
VLAN 子接口属于其父接口。您必须指定子接口连接到的命名空间。请参阅以下示例。
apiVersion: v1 kind: Namespace metadata: name: multus-vlan --- apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: multus-vn-1 namespace: multus-vlan annotations: juniper.net/networks: '{ "ipamV4Subnet": "172.16.1.0/24" }' spec: config: '{ "cniVersion": "0.3.1", "name": "multus-vn-1", "type": "contrail-k8s-cni" }' --- apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: multus-vn-2 namespace: multus-vlan annotations: juniper.net/networks: '{ "ipamV4Subnet": "172.16.2.0/24" }' spec: config: '{ "cniVersion": "0.3.1", "name": "multus-vn-2", "type": "contrail-k8s-cni" }' ```
示例 Pod YAML
以下示例显示了 的 cni-args
指定 Pod 注释。此示例配置将在容器中创建以下三个虚拟机接口 (VMI) 和三个接口 IP 地址 (IIP):
-
VMI、IIP for eth0 在默认 Pod 网络上
-
VMI、IIP for eth1 on multus-vn-1(父接口)
-
VMI, IIP for eth1.100 on multus-vn-2 (子接口)
apiVersion: v1 kind: Pod metadata: name: multus-pod-4 namespace: multus-vlan annotations: k8s.v1.cni.cncf.io/networks: | [ { "name": "multus-vn-1", "namespace": "multus-vlan", "cni-args": { "net.juniper.contrail.interfacegroup": "eth1" }, "ips":["172.16.1.6"], "mac":"de:ad:00:00:be:01" }, { "name": "multus-vn-2", "namespace": "multus-vlan", "cni-args": { "net.juniper.contrail.vlan": "100", "net.juniper.contrail.interfacegroup": "eth1" }, "ips":["172.16.2.6"], "mac":"ee:ad:00:00:be:02" } ] spec: containers: - name: multus-pod-4 image: <repository>:<tag> command: ["bash", "-c", "while true; do sleep 60s; done"] securityContext: capabilities: add: - NET_ADMIN privileged: true tolerations: - key: "key" operator: "Equal" value: "value" effect: "NoSchedule" ```
Pod 创建流程概述
Kubemanager 监听 Pod 创建、删除和更新事件。检测新容器创建时:
-
Kubemanager 解析 Pod 信息并创建相应的虚拟机(pod)、VMI(Pod 接口)和 IIP(Pod 接口 IP)。
-
此信息使用 Contrail 控制器和 vRouter 代理之间的 XMPP 通信通道传递到 vRouter 代理。
-
在此通信的同时,kubelet 会获取一个设置 Pod 事件,并调用 CN2 CNI 来配置 Pod 网络。
API 调用和输出
以下步骤显示了创建和配置子接口时的 API 调用和输出。
-
CN2 CNI 调用获取 vm-cfg (GET POD_CONFIG()) (示例获取网址 [<span class=“underline”>http://127.0.0.1:9091/vm-cfg/\_\_multus-vlan\_\_multus-pod-4</span>](http://127.0.0.1:9091/vm-cfg/__default__testpmd-pod)) API,以获取使用 Contrail 控制器配置的所有 VMI(虚拟机接口)的列表。
示例输出:
[{ "id": "83fbe4ee-79ce-4d1a-972e-5420138eae7f", "vm-uuid": "68627577-c1c5-4dac-acf1-3f4547b795e0", "vn-id": "4b5f3770-d0e4-4c48-ad34-898cdd76d72d", "vn-name": "default-domain:contrail-k8s-kubemanager-kubernetes-contrail:default-podnetwork", "mac-address": "02:83:fb:e4:ee:79", "sub-interface": false, "vlan-id": 65535, "annotations": [ "{index:0/3}", "{interface:eth0}", "{network:default-podnetwork}", "{vmi-address-family:dualStack}" ] },{ "id": "9779ab13-acce-48a4-a0db-1a4d07133042", "vm-uuid": "68627577-c1c5-4dac-acf1-3f4547b795e0", "vn-id": "b173bcd1-bf86-436c-888f-af3c0699865c", "vn-name": "default-domain:multus-vlan:multus-vn-1", "mac-address": "de:ad:00:00:be:01", "sub-interface": false, "vlan-id": 65535, "annotations": [ "{index:1/3}", "{interface:eth1}", "{network:multus-vn-1}", "{vmi-address-family:ipV4}" ] },{ "id": "b71a96e6-f936-477e-a072-9e61a4e16aa7", "vm-uuid": "68627577-c1c5-4dac-acf1-3f4547b795e0", "vn-id": "ceb0fc94-2848-47c6-8c08-7cc2af657517", "vn-name": "default-domain:multus-vlan:multus-vn-2", "mac-address": "ee:ad:00:00:be:02", "sub-interface": true, "vlan-id": 100, "annotations": [ "{index:2/3}", "{interface:eth1}", "{network:multus-vn-2}", "{vlan-id:100}", "{vmi-address-family:ipV4}" ] }] ```
-
CN2 CNI 处理此信息并调用端口添加消息 (POST VMI)(示例 post api [<span class=“underline”>http://127.0.0.1:9091/vm</span>](http://127.0.0.1:9091/vm) )
示例输出:
{ "time": "2023-07-04 08:31:44.276785096 +0000 UTC m=+15.080014967", "vm-id": "54b3ae3eefc4486bc826d595b1316210f9e445f7de1bcad71112037980e7c9a7", "vm-uuid": "68627577-c1c5-4dac-acf1-3f4547b795e0", "vm-name": "__multus-vlan__multus-pod-4", "host-ifname": "tapeth0-686275", "vm-ifname": "eth0", "vm-namespace": "/var/run/netns/85d564c8-a4a5-49ee-b040-0d43c5eaf883", "vn-uuid": "4b5f3770-d0e4-4c48-ad34-898cdd76d72d", "vmi-uuid": "83fbe4ee-79ce-4d1a-972e-5420138eae7f", "vhostuser-mode": 0, "vhostsocket-dir": "", "vhostsocket-filename": "", "vmi-type": "", "pod-uid": "" } ```
-
然后 CN2 CNI 确实将结果 (GET VM IP) 发送到 vrouter-agent (示例 API [<span class=“underline”>http://127.0.0.1:9091/vm/68627577-c1c5-4dac-acf1-3f4547b795e0/83fbe4ee-79ce-4d1a-972e-5420138eae7f</span>](http://127.0.0.1:9091/vm/68627577-c1c5-4dac-acf1-3f4547b795e0/83fbe4ee-79ce-4d1a-972e-5420138eae7f) )
示例输出:
[{ "id": "83fbe4ee-79ce-4d1a-972e-5420138eae7f", "instance-id": "68627577-c1c5-4dac-acf1-3f4547b795e0", "vn-id": "4b5f3770-d0e4-4c48-ad34-898cdd76d72d", "vm-project-id": "00000000-0000-0000-0000-000000000000", "mac-address": "02:83:fb:e4:ee:79", "system-name": "tapeth0-686275", "rx-vlan-id": 65535, "tx-vlan-id": 65535, "vhostuser-mode": 0, "ip-address": "192.168.0.33", "plen": 24, "dns-server": "192.168.0.1", "gateway": "192.168.0.1", "v6-ip-address": "2001::21", "v6-plen": 64, "v6-dns-server": "2001::1", "v6-gateway": "2001::1", "author": "/contrail-vrouter-agent", "time": "469016:31:59.293170" }] ```
-
现在,CN2 CNI 获取要在 Pod 中配置的 IP 地址,根据需要执行配置,并将结果返回给 kubelet。
-
如果配置请求是添加子接口,请检查父接口是否存在。如果没有,请创建父接口,然后创建子接口。
-
如果配置请求要删除父接口,请删除子接口。
-
验证子接口
要确认子接口已创建,请执行以下操作:
-
通过子接口在两个 Pod 之间执行 ping 操作。
-
在 Pod 的单个父接口上创建多个子接口。
-
在一个 Pod 中创建多个子接口和多个父接口。
您还可以运行命令以 kubectl exec
访问容器内部。然后运行 ip addr
命令以显示当前网络。
$ kubectl exec -it -n <namespace> <podname> -- /bin/bash $ ip addr
示例输出:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth1.100@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether ee:ad:00:00:be:02 brd ff:ff:ff:ff:ff:ff inet 172.16.2.6/24 brd 172.16.2.255 scope global eth1.100 valid_lft forever preferred_lft forever inet6 fe80::dc91:bbff:feea:d676/64 scope link valid_lft forever preferred_lft forever 26: eth1@if27: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether de:ad:00:00:be:01 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.16.1.6/24 brd 172.16.1.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::dc91:bbff:feea:d676/64 scope link valid_lft forever preferred_lft forever 28: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:da:89:0d:69:be brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.3.11/24 brd 192.168.3.255 scope global eth0 valid_lft forever preferred_lft forever