CNIプラグインを活用してKubernetesのPodをVLANにつなぐ


この記事は富士通クラウドテクノロジーズ Advent Calendar 2020の21日目の記事です。

TL;DR

背景

PodをVLANに繋ぎたい動機

業務ではインフラの管理を中心に担当しているが、IaaSとしてサービス提供している環境(いわばクラウドの裏側)の管理であり、クラウド上のシステムではないため、泥臭いことを沢山する必要がある。例えばDHCPサーバーを構築してホストのアドレスを管理できるようにしたり、ユーザーに提供しているサーバーインスタンスが利用するネットワーク機能(ファイアウォール、ロードバランサー、VPN等)を提供することなどがある。

それら必要なものには仮想マシンとしてデプロイしているものも多くあるが、自動でダウンタイムなく安全に更新できるような構成を取れていないものも残っており、管理上負担になっている。コンポーネントによって手順も異なるため、手がかかっている。

そこで、それらをKubernetesの上に立て直すことで、デプロイメントやアップデートの方法を共通化し、リリースサイクルを高速化していくことが出来ないかを考えている。

しかし、KubernetesではPodのネットワークにはある程度の制約があるため、先に例に上げたようなある種の泥臭いことをKubernetes上でやろうとすると、一筋縄ではいかない。何も考えずにクラスタを構築すれば、PodはFlannelによって作られるオーバーレイネットワークのみに接続していて、DHCPによるアドレス払い出しを行うことも、ネットワーク間のパケット転送に関わることもできない。

そこで、今回はまずIEEE 802.1QのVLANに自由にちょっかいを掛けられるようにする検証をしてみた。

CNIプラグイン

コンテナはランタイムの乱立と標準化の中で、コンテナ(より厳密にはLinux network namespace)のネットワークへの接続の実装を柔軟に取り回せるよう、インターフェイスとしてContainer Network Interfaceが定められている。そして、そのインターフェイスに準拠して作られた実装がCNIプラグインである。(CNIについての詳細は過去にも調べて軽くまとめている。)

KubernetesもこのCNIに対応していて、適切に設定することでPodネットワークの実装を切り替えたり出来る。(このあたりはクラスタ構築をする際に設定が必要なため、クラスタ構築をしたことがあれば心当たりがあると思う。)

今回はCNIプラグインとして以下で説明するMultus CNIとbridgeプラグインを使うことで、目的を果たせることを検証していく。

Multus CNI

これも過去に少し調べて書いているが、簡単に言えば複数のCNIプラグインを呼び出せるようにするためのCNIプラグインで、コンテナ(Kubernetes的にはPod)の中に複数のネットワークインターフェイスを与えることなどが可能になる。

bridge CNI plugin

標準的なCNIプラグインとして https://github.com/containernetworking/ の下で提供されている。主なところとしては

といったものになっている。直接使うことはあまりないかもしれないが、実は今なにも考えずにflannelを利用すれば(これを使ってインストールした場合)内部的にbridgeプラグインを呼び出している。

更にこのbridgeプラグインは、Linux bridge interfaceの vlan_filtering 利用できるようになっている。余談だが、このPRで実装されたようなので、以前検証した時にはなく、今回自分でプラグインを作成または拡張しようとして、参考にソースコードを読み込んでいて気がついた。

これを上手く使えば、必要なネットワークの定義などをほとんどKubernetesのmanifestに完結させて行うことが出来るはずなので、それを確認していく。

他のプラグイン

https://github.com/containernetworking/plugins/ の中には、他にもプラグインがあるのでそれについても少し言及しておく。

検証

テスト用ネットワークの準備

ノードの準備

Multusの設定

テスト用Podによる動作確認

準備

確認

つまり、以下のような状態になっている。

(二重線の箇所はタグ付きのフレームがやり取りされるイメージ)

少し気になるがまだ調べられていないこと