Red Hatでコンサルタントをしている織です。この記事はOpenShift Advent Calendar 2019 19日目のエントリです。
OpenShiftはRed Hatが製品として出しているKubernetesのディストリビューションです。Kubernetesでは、コンテナのネットワークインターフェースを設定する仕組みをCNIという仕様/ライブラリとして定義しており、様々なCNIプラグインを差し替えて使うことができるようになっています。OpenShiftは、「OpenShift-SDN」という独自実装のCNIプラグインを提供しており、デフォルト設定ではこれが使われるのですが、OpenShift v4.2から、OpenShift-SDNに加えて「OVN(Open Virtual Networking)」という仕組みを使った「ovn-kubernetes」というCNIプラグインもTechnical Previewとして提供しています。本エントリでは、OVNをOpenShiftで使うとどういったいいことがあるかについてご紹介します。
OVNとは
OVNは、複数の物理ノード(もしくはハイパーバイザ)にまたがった仮想ネットワークを作るための仕組みで、Open vSwitch (以下OVS) [1]というオープンソースの仮想スイッチのサブプロジェクトとして2015に開発が始まりました。最初はOVSのリポジトリ内で開発が進められていましたが、2019年2月にリリースされたOVS v2.11からリポジトリがわかれ、今は https://github.com/ovn-org で開発が続けられています。
OVNの特徴としては、
OVSDBというデータベースの操作によるコンフィギュレーション
複数のハイパーバイザにまたがった仮想ネットワーク「Logical Network」を「Logical Flow」で定義
- Logical FlowはOpen Flowに似た構造になっており、フローの集合であるフローテーブルをつなげてパイプライン化し、入ってきたパケットがmatchするフローがあれば対応するactionを実施する、という形でパケットが処理されます
ノード間の通信はGeneveを使ってカプセル化
といった辺りが挙げられます。
OVNをKubernetesで使うためのCNIプラグインとしてovn-kubernetes [2] があります。このovn-kubernetesがOpenShift v4.2から使えるようになった、というわけです。
OVNのコンポーネントは下図のようになります。 OpenShiftとOVNはNorthbound DBというデータベースを経由して情報をやり取りし、ここにLogical Networkの情報が格納されます。 ovn-northdというデーモンがNorthbound DBにある論理情報を各ノードの物理情報と対応付け、Southbound DBに格納します。 各ノードで動いているovn-controllerというデーモンがSouthbound DBの情報を元に、自ノードのOVSに注入するOpenFlowのフローを生成します。
OpenShift + OVNのセットアップ
OpenShift + OVNの環境を作る手順は下記のとおりです。
openshift-intall create install-config
を実行してinstall-config.yaml
を生成する- install-config.yamlの
networking.networkType
の値をOVNKubernetes
に変更する openshift-install create cluster
を実行してクラスターをデプロイする
詳細はドキュメント[3]をご参照ください。
OpenShiftでOVNを使う場合、openshift-ovn-kubernetes という namespace に ovn-kubernetes 関連のPodがデプロイされ [4]、これらがOVNの制御を行います。
$ oc -n openshift-ovn-kubernetes get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ovnkube-master-7bdf6459dd-t6p27 4/4 Running 0 53d 10.0.147.198 ip-10-0-147-198.ap-northeast-1.compute.internal <none> <none> ovnkube-node-5fsgb 3/3 Running 0 53d 10.0.160.241 ip-10-0-160-241.ap-northeast-1.compute.internal <none> <none> ovnkube-node-9bb84 3/3 Running 0 53d 10.0.164.184 ip-10-0-164-184.ap-northeast-1.compute.internal <none> <none> ovnkube-node-jbjjw 3/3 Running 0 53d 10.0.142.114 ip-10-0-142-114.ap-northeast-1.compute.internal <none> <none> ovnkube-node-nf5jc 3/3 Running 0 53d 10.0.131.146 ip-10-0-131-146.ap-northeast-1.compute.internal <none> <none> ovnkube-node-vlvwh 3/3 Running 0 53d 10.0.147.198 ip-10-0-147-198.ap-northeast-1.compute.internal <none> <none> ovnkube-node-xtht2 3/3 Running 0 53d 10.0.146.63 ip-10-0-146-63.ap-northeast-1.compute.internal <none> <none>
OpenShift/KubernetesでOVNを使うとうれしい点
OpenShift/KubernetesでOVNを使うとうれしい点がいくつかあります。 大きな特徴としては、iptablesの利用を大幅に減らすことができる点が挙げられます。
KubernetesのServiceオブジェクトによるエンドポイント(Pod)間のロードバランスは、多くのCNIプラグインではiptablesのstatisticモジュールのrandomモードを使って実現しています。 iptablesはルール数が増えた場合のスケーラビリティに課題があることが知られており、Serviceオブジェクトが増えるとその分iptablesのルールが増えることになり、パフォーマンス上の懸念がありました。
一方OVNの場合は、ServiceオブジェクトはLogical Network上の分散ロードバランサとして表現されます。最終的にOVSのFlowとして処理されるため、iptablesのルールが増えることはありません。
また、Network Policyの機能も多くのCNIプラグインではiptablesで実現していますが、OVNを使った場合はOVSのFlowとして処理するため、iptablesのルールが増えることはありません。
このように、OVNではなるべくiptablesを使わないように設計されています [5]。
その他、OVNを使って、WindowsノードとLinuxノードの混在クラスターのサポートやPod単位のEgress IP、複数クラスターにまたがった通信などを実現しようとしています。
OVNの課題と今後
今のOVNはOVSDBに大きく依存しており、OVSDBが性能上のボトルネックになるケースがいくつかありました。これらに関してはすでに修正が入っており、今のupstreamのコードはスケーラビリティがかなり改善されています。
また、OpenShift v4.2でOVNを使う場合、OVSDBのPod(ovnkube-master)が冗長化されておらず、単一障害点となります。 upstreamではRaftアルゴリズムを使ったOVSDBのActive-Active構成の実装中で[6]、その成果を取り込んで冗長化する方向で開発を進めています。
OpenShiftのロードマップとしては、次かその次くらいのバージョンでOVNを正式にサポートしようと頑張っているところです。OpenShiftとOVNの今後にご期待ください。
-
OVNではなくOpenShiftデフォルトのOpenShift-SDNというCNIプラグインを使う場合は、openshift-sdnというnamespaceに関連するPodがデプロイされます。↩
-
OVNはiptablesを全く使わないわけではなく、例えばNodePortやExternalIPを使ってクラスター外部からPodに対して通信する場合は、ホスト上のiptablesでDNATしてOVNのLogical Networkにパケットを引き込みます。↩
-
OVSDBの冗長化方式としては、Raftベースのクラスタリングの他に、Master-Slave形式のレプリケーションの機能もあります。Red HatのOpenStackディストリビューションでOVNを使う場合のOVSDBは、Master-Slaveのレプリケーションを使った構成で、Pacemakerで冗長化しています。↩