Multus CNIって?
MultusはPodに複数のネットワークインタフェースをアタッチ可能とするCNIプラグインです。Multus自体が複数インタフェースを利用可能なCNIだと勘違いしていましたが、複数のCNIを同時に利用可能とするためのメタCNIプラグインとして稼働するようです。Multus自体、ハイパフォーマンスを要求される通信事業者向けコンテナアプリケーションで、サービス系、管理系のネットワークインターフェースを分離するような目的で使われることが多いようなので、私も通信事業者に務めるエンジニアの端くれとして、Multusのクイックスタートガイドを参考に簡単に動きを確認してみようと思います。
手順概要
- 準備
- MutlusバイナリのインストールとDaemonsetのデプロイ
- 追加ネットワークインタフェース用CustomResourceDefinition(NetworkAttachmentDefinition)の作成
- 複数NICをアタッチしたPodの作成
- 確認
1. 準備
確認した環境はVMware社のK8SディストリビューションであるTanzu kubernetes Gridです。worker2台構成で、各workerノードにはeth0、eth1の2つのNICを接続しています。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
tkc18-control-plane-j2twb Ready master 115m v1.19.1+vmware.2
tkc18-md-0-988884c8-95z7v Ready <none> 114m v1.19.1+vmware.2
tkc18-md-0-988884c8-k5j9p Ready <none> 114m v1.19.1+vmware.2
2. MutlusバイナリのインストールとDaemonsetのデプロイ
まずMultusバイナリをインストールし、Multusを使用するための設定を行うDaemonsetをデプロイします。Daemonsetによって、各ノード上へのMultusバイナリの配置、設定ファイルの作成、Multusがk8s APIにアクセスするための認証情報の配置などが実行されるようです。
$ git clone https://github.com/intel/multus-cni.git && cd multus-cni
$ cat ./images/multus-daemonset.yml | kubectl apply -f -
$ kubectl get pods --all-namespaces | grep -i multus
kube-system kube-multus-ds-amd64-pdx88 1/1 Running 0 94m
kube-system kube-multus-ds-amd64-pq28r 1/1 Running 0 94m
kube-system kube-multus-ds-amd64-r8kn9 1/1 Running 0 94m
3. 追加ネットワークインタフェース用CustomResourceDefinition(NetworkAttachmentDefinition)の作成
次にPodに接続される追加ネットワークインタフェースを定義するCustom Resource Definition(Network Resource Definition)を作成します。
今回はクイックスタートガイドの通り、macvlanを利用、利用するインタフェースはeth1、IPAMについてはとりあえず試すだけだったのでStatic設定としています。
$ cat <<EOF | kubectl create -f -
> apiVersion: "k8s.cni.cncf.io/v1"
> kind: NetworkAttachmentDefinition
> metadata:
> name: macvlan-conf
> spec:
> config: '{
> "cniVersion": "0.3.1",
> "plugins": [
> {
> "type": "macvlan",
> "capabilities": { "ips": true },
> "master": "eth1",
> "mode": "bridge",
> "ipam": {
> "type": "static"
> }
> }, {
> "capabilities": { "mac": true },
> "type": "tuning"
> } ]
> }'
> EOF
$ kubectl get network-attachment-definitions
NAME AGE
macvlan-conf 85m
$ kubectl describe network-attachment-definitions macvlan-conf
Name: macvlan-conf
Namespace: default
Labels: <none>
Annotations: <none>
API Version: k8s.cni.cncf.io/v1
Kind: NetworkAttachmentDefinition
Metadata:
Creation Timestamp: 2020-12-06T07:27:19Z
Generation: 1
Managed Fields:
API Version: k8s.cni.cncf.io/v1
Fields Type: FieldsV1
fieldsV1:
f:spec:
.:
f:config:
Manager: kubectl-create
Operation: Update
Time: 2020-12-06T07:27:19Z
Resource Version: 10002
Self Link: /apis/k8s.cni.cncf.io/v1/namespaces/default/network-attachment-definitions/macvlan-conf
UID: f5520a94-6401-401f-a1d9-5c57d5f2393f
Spec:
Config: { "cniVersion": "0.3.1", "plugins": [ { "type": "macvlan", "capabilities": { "ips": true }, "master": "eth1", "mode": "bridge", "ipam": { "type": "static" } }, { "capabilities": { "mac": true }, "type": "tuning" } ] }
Events: <none>
$
4. 複数NICをアタッチしたPodの作成
annotationで追加ネットワークインタフェースに関する記述を記載し、デプロイします。
$ cat <<EOF | kubectl create -f -
> apiVersion: v1
> kind: Pod
> metadata:
> name: samplepod1
> annotations:
> k8s.v1.cni.cncf.io/networks: '[
> {
> "name": "macvlan-conf",
> "ips": [ "192.168.3.201/24" ]
> }
> ]'
> spec:
> containers:
> - name: centos-tools
> image: docker.io/centos/tools:latest
> command:
> - /sbin/init
> nodeSelector:
> type: node1
> EOF
$ cat <<EOF | kubectl create -f -
> apiVersion: v1
> kind: Pod
> metadata:
> name: samplepod4
> annotations:
> k8s.v1.cni.cncf.io/networks: '[
> {
> "name": "macvlan-conf",
> "ips": [ "192.168.3.204/24" ]
> }
> ]'
> spec:
> containers:
> - name: centos-tools
> image: docker.io/centos/tools:latest
> command:
> - /sbin/init
> nodeSelector:
> type: node2
> EOF
5. 確認
デプロイ後、別々の物理インターフェースに紐付いたNICが2つPodに接続されており、Pingによる疎通性も確認できました(不要な出力は削除しています)。
$ kubectl exec -it samplepod1 -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
3: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
inet 100.96.1.4/24 brd 100.96.1.255 scope global eth0
4: net1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
inet 192.168.3.201/24 brd 192.168.3.255 scope global net1
$ kubectl exec -it samplepod4 -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
inet 127.0.0.1/8 scope host lo
3: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
inet 100.96.2.7/24 brd 100.96.2.255 scope global eth0
4: net1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
inet 192.168.3.204/24 brd 192.168.3.255 scope global net1
$ kubectl exec -it samplepod1 -- ping 192.168.3.204
PING 192.168.3.204 (192.168.3.204) 56(84) bytes of data.
64 bytes from 192.168.3.204: icmp_seq=1 ttl=64 time=0.028 ms
64 bytes from 192.168.3.204: icmp_seq=2 ttl=64 time=0.042 ms
$ kubectl exec -it samplepod1 -- ping 100.96.2.7
PING 100.96.2.7 (100.96.2.7) 56(84) bytes of data.
64 bytes from 100.96.2.7: icmp_seq=1 ttl=62 time=1.76 ms
64 bytes from 100.96.2.7: icmp_seq=2 ttl=62 time=0.916 ms
ほぼクイックスタートガイドの通りに実行するだけでMultiNIC構成が出来上がりますので、試すだけなら非常に簡単です。ただしプロダクション利用となると色々な考慮が必要となるため、しっかりとした検証が必要になります。時間見つけて深堀りしてみたいと思います。
## 参照したサイト
https://github.com/intel/multus-cni