KubernetesでWindowsコンテナをクラスタ化して管理~Node間ルーティング設定編~

過去3回の記事で環境のセットアップLinux上でのKubernetes Master Nodeの構築Windows Node構築を行いました。今回はWindows Node間のルーティングを設定し、コンテナクラスタを完成させます。

0. 環境の構成の確認と参考サイト

今回設定する部分は下図の通り各Node間のルーティング設定となります。

また、設定自体はこちらのサイトの情報をもとに行っています。

1. ネットワークトポロジーの決定

クラスタを構成するためのネットワークトポロジーの構成方法にはいくつかの方法があります。Windowsコンテナーで利用可能なトポロジーは以下の5つがあります。

トポロジー 実装 特徴
上位L3SW Routing Top of RackのL3スイッチでStatic Routing 各Node内のコンテナNW向けルーティングを手動で設定
Host Gateway 各NodeでStatic Routing 各Nodeでクラスタ内全Node向けStatic Routeを手動設定
OVS & OVN with Overlay STTなどのOverlayプロトコルをOpen vSwitch上で実装 Hyper-V vSwitchがあるのにOVSをインストールするなんて・・・
FlannelによるOverlayまたはL2Bridge VXLAN OverlayかL2Bridgeを自動設定 ベータサポート
CalicoによるRouting BGPでRouting設定 開発途中

今回は上記の中でマニュアルがちゃんと存在しているHost Gatewayモードでのネットワーク構成を行います。

2. Linux Master Node出のルーティング設定

以下のコマンドをLinux Master Nodeで実行すると、各Node内にあるコンテナNW向けのStatic Routeを設定できます。

$ CLUSTER_PREFIX="172.16"
$ sudo route add -net $CLUSTER_PREFIX.0.0 netmask 255.255.0.0 dev eth0
$ sudo route add -net $CLUSTER_PREFIX.1.0 netmask 255.255.255.0 gw $CLUSTER_PREFIX.1.2 dev eth0
$ sudo route add -net $CLUSTER_PREFIX.2.0 netmask 255.255.255.0 gw $CLUSTER_PREFIX.2.2 dev eth0
$ sudo route add -net $CLUSTER_PREFIX.3.0 netmask 255.255.255.0 gw $CLUSTER_PREFIX.3.2 dev eth0

Nodeが増えるたび、Master Nodeを再起動するたびに設定が必要です(あえて非永続的な手順で行っています)。

3. Windows Nodeでのルーティング設定

Windows Nodeの場合、前回の構築の際にGithub上のmicrosoft/SDNレポジトリC:\k\フォルダにダウンロードしているため、AddRoutes.ps1というスクリプトが既に存在しています。

以下の通り引数を指定して実行することで、Kubernetes Masterからクラスタ内のほかのNodeの情報を取得し、Static Routeを設定します。

PS C:\k\> .\AddRoutes.ps1 -MasterIp 192.168.1.20 -Gateway 192.168.1.1

上記では-MasterIpにLinux Master NodeのIPを、-Gatewayには最初の図に記載の外部NetworkのGatewayを指定します。

このスクリプトによるStatic Route設定は永続的ですが、Nodeが増えるたびに実行する必要があります。

4. サンプルアプリケーションの実行と動作テスト

Kubernetes Master Nodeに低下の通りコマンドを実行し、Windowsコンテナのサンプルアプリケーションを展開します。

$ kubectl apply -f https://raw.githubusercontent.com/Microsoft/SDN/master/Kubernetes/WebServer.yaml -O win-webserver.yaml

展開後、サービスが展開されていることを確認しますs。

$ kubectl get pods -o wide
NAME                          READY  STATUS    RESTARTS   AGE       IP                      NODE
win-webserver-bc9d6d478-5rwqv 1/1    Running   0          3m        172.16.2.187   winworker02
win-webserver-bc9d6d478-j7k9x 1/1    Running   0          3m        172.16.3.218   winworker03 

$ kubectl get service win-webserver
NAME            TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
win-webserver   LoadBalancer   11.0.7.87    <pending>     80:31932/TCP   1m

出力の確認方法ですが、サンプルアプリケーションでは2個のコンテナをNodeを分散して起動させます。1つ目のコマンドでNODEの欄にWindows Nodeのうち2台が表示されるはずです。そして、正常起動するとSTATUSがRunningとなります。
また、2つ目のコマンドではCLUSTER-IPというアドレスが表示されます。これは負荷分散されたサービスに接続するためのIPで、アクセスするたびにいずれかのコンテナに分散されます。

実際にcurlコマンドでアクセスしてみます。まずはコンテナ自体が持つIPの80/tcpへアクセスしてみます。

$ curl "http://172.16.2.187"
<html><body><H1>Windows Container Web Server</H1><p>IP 192.168.1.20 callerCount 1</body></html>

$ curl "http://172.16.3.218"
<html><body><H1>Windows Container Web Server</H1><p>IP 192.168.1.20 callerCount 1</body></html>

次に、このサンプルサービスでは各NodeのIPの4444/tcpへのPort Forwardingも設定しているため、Windows NodeのIPへのcurlでも応答が返ってきます。上記の例では、Node2,3にコンテナが存在するため、その2台にアクセスします。

$ curl "http://192.168.1.32:4444"
<html><body><H1>Windows Container Web Server</H1><p>IP 192.168.1.20 callerCount 2</body></html>

$ curl "http://192.168.1.33:4444"
<html><body><H1>Windows Container Web Server</H1><p>IP 192.168.1.20 callerCount 2</body></html>

最後に、Serviceの外部公開IPであるCLUSTER-IPにアクセスしてみます。アクセスするたびにカウンターが増えるので、片方のコンテナにたくさんアクセスしてからテストすると、どちらのNodeにアクセスしているか分かりやすいです。(下記の例ではNode3側のコンテナだけ100回アクセスしたケースです。)

$ curl "http://11.0.7.87"
<html><body><H1>Windows Container Web Server</H1><p>IP 192.168.1.20 callerCount 3</body></html>

$ curl "http://11.0.7.87"
<html><body><H1>Windows Container Web Server</H1><p>IP 192.168.1.20 callerCount 101</body></html>

5. 今後の動き

今回までの4回で、Host GatewayモードによるWindowsコンテナークラスタをKubernetesで管理する方法について解説しました。しかし、今回解説した通り、コンテナ間のルーティング設定がすべて手動では、とても本番環境で利用することができません。
2018年2月末の時点では手動以外の方法がOVS/OVNしかなかったのですが、2018年3月4日~8日に行われたMicrosoft MVP Global Summitにてこの件を話したところ、Windowsコンテナでのflannelサポート開発が急激に進み、帰国した3月12日にはベータリリースとなっていました。
そんなわけで、次回はflannelを使ったルーティングを自動的に設定できるクラスタを構成する手順について解説します。(これから検証ですが・・・)