はじめに
Multusでipvlanで複数NICを持つPodを作成する方法が詰まったことが多かったので、備忘録を込めて記載する
環境
- Windows11(ホストOS)
- Ubuntu22.04.3(ゲストOS、Virtualbox上に構築)
- k3s
- calico
構築と確認
k3sのインストール
docs.tigera.io を参考に実施する。
cni pluginのインストール
https://github.com/containernetworking/plugins から必要なcni pluginをインストールする。 Goをインストールしてcniのpluginをコンパイルし、cniをインストールする。
$ cd ~ $ curl -OL https://go.dev/dl/go1.21.6.linux-amd64.tar.gz $ sudo tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz $ cat >> ~/.bashrc << "EOF" export GOPATH=/usr/local/go export PATH=$PATH:$GOPATH/bin EOF $ source ~/.barhrc $ git clone https://github.com/containernetworking/plugins $ cd plugins/ $ ./build_linux.sh $ cd bin $ sudo install -m 755 -D bridge /opt/cni/bin $ sudo install -m 755 -D host-device /opt/cni/bin $ sudo install -m 755 -D ipvlan /opt/cni/bin $ sudo install -m 755 -D loopback /opt/cni/bin $ sudo install -m 755 -D macvlan /opt/cni/bin $ sudo install -m 755 -D vlan /opt/cni/bin $ sudo install -m 755 -D dhcp /opt/cni/bin $ sudo install -m 755 -D host-local /opt/cni/bin $ sudo install -m 755 -D static /opt/cni/bin
multusのclone
$ git clone https://github.com/k8snetworkplumbingwg/multus-cni $ cd multus-cni
multusのインストール
今回はv3.9.3を使用する。
$ git checkout v3.9.3 $ cat ./deployments/multus-daemonset-thick-plugin.yml | kubectl apply -f -
interfae 確認
$ ip a 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: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 08:00:27:95:fa:9c brd ff:ff:ff:ff:ff:ff inet 100.64.1.18/22 metric 100 brd 100.64.3.255 scope global dynamic enp0s3 valid_lft 602466sec preferred_lft 602466sec inet6 240b:11:400:e700:a00:27ff:fe95:fa9c/64 scope global dynamic mngtmpaddr noprefixroute valid_lft 2591851sec preferred_lft 604651sec inet6 fe80::a00:27ff:fe95:fa9c/64 scope link valid_lft forever preferred_lft forever
複数interfaceを持つpodを作成
calicoとmultusで作成されるNICを異なるNICに紐づくようにしたいが、今回は省略するため、同じNIC(enp0s3)を使用することとする。 NetworkAttachmentDefinitionで、MasterのInterfaceを指定しないため、自動的にenp0s3が指定されるはずである。
iplanの場合
$ cat > pod-ipvlan.yaml << EOF apiVersion: v1 kind: Pod metadata: name: test-pod-ipvlan annotations: k8s.v1.cni.cncf.io/networks: ipvlan-conf spec: containers: - name: test-pod-ipvlan command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"] image: alpine EOF $ cat > net-attach-def-ipvlan.yaml << EOF apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: ipvlan-conf spec: config: '{ "cniVersion": "0.3.1", "type": "ipvlan", "ipam": { "type": "host-local", "subnet": "198.17.0.0/24" } }' EOF # pod作成 $ kubectl apply -f net-attach-def-ipvlan.yaml $ kubectl apply -f pod-ipvlan.yaml $ kubectl get pods NAME READY STATUS RESTARTS AGE test-pod-ipvlan 1/1 Running 0 8m14s # interface確認 $ kubectl exec -it test-pod-ipvlan -- ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 3: eth0@if56: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1480 qdisc noqueue state UP qlen 1000 link/ether d6:42:48:c8:c6:a7 brd ff:ff:ff:ff:ff:ff inet 192.168.243.240/32 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::d442:48ff:fec8:c6a7/64 scope link valid_lft forever preferred_lft forever 4: net1@tunl0: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN link/ether 08:00:27:95:fa:9c brd ff:ff:ff:ff:ff:ff inet 198.17.0.205/24 brd 198.17.0.255 scope global net1 valid_lft forever preferred_lft forever inet6 fe80::800:2700:195:fa9c/64 scope link valid_lft forever preferred_lft forever
github.com にあるpluginsという記載のあるJSONファイルだと上手に動作しなかったので、古いタイプのフォーマットで記載する。
bridgeの場合
bridgeを使った場合も記載する。
$ cat net-attach-def-bridge.yaml apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: bridge-conf spec: config: > { "cniVersion": "0.3.0", "type": "bridge", "bridge": "test-br", "ipam": { "type": "host-local", "subnet": "192.168.1.0/24", "rangeStart": "192.168.1.100", "rangeEnd": "192.168.1.200" } } $ cat pod-bridge.yaml apiVersion: v1 kind: Pod metadata: name: test-pod-bridge annotations: k8s.v1.cni.cncf.io/networks: bridge-conf spec: containers: - name: test-pod-bridge command: ["/bin/sh", "-c", "trap : TERM INT; sleep infinity & wait"] image: alpine # pod作成 $ kubectl apply -f net-attach-def-bridge.yaml $ kubectl apply -f cat pod-bridge.yaml $ kubectl get pods NAME READY STATUS RESTARTS AGE test-pod-bridge 1/1 Running 0 28m # interface確認 $ kubectl exec -it test-pod-bridge -- ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 3: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1480 qdisc noqueue state UP qlen 1000 link/ether 06:35:61:72:8d:6d brd ff:ff:ff:ff:ff:ff inet 192.168.243.199/32 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::435:61ff:fe72:8d6d/64 scope link valid_lft forever preferred_lft forever 4: net1@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 3a:28:10:f4:47:17 brd ff:ff:ff:ff:ff:ff inet 192.168.1.100/24 brd 192.168.1.255 scope global net1 valid_lft forever preferred_lft forever inet6 fe80::3828:10ff:fef4:4717/64 scope link valid_lft forever preferred_lft forever