過去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を使ったルーティングを自動的に設定できるクラスタを構成する手順について解説します。(これから検証ですが・・・)