Kubernetesなしでdockerを複数台で動かしてみる

このエントリはKubernetesアドベントカレンダー2014の6日目です。

今日はKubernetesの効果を理解するために、まずはKubernetesなしで構成を組んでみます。 目指す構成としてはKubernetesのドキュメントに出てくる、GCEを使ったAdvanced Routingの構成とよく似た形です。

kubernetes/networking.md at v0.5.3 · GoogleCloudPlatform/kubernetes

構成

手元のMacBookAirのVirtualBox上に、CentOS7を2台起動します。

host01上のコンテナにhost02上のコンテナから直接アクセスできるようなれば、Kubernetesのようなアクセス分散が実現できそうです。

  • eth0(NAT): 10.0.2.0/24
  • eth1(Hostonly): 172.16.0.0/16(host01: 172.16.1.1, host02: 172.16.2.1)
  • docker0: host01: 192.168.1.0/24, host02: 192.168.2.0/24

docker-multi-small

設定手順

host01

iptablesを全パスにしたら、 nmcli を使ってNetowrkManagerからeth1に対してIPアドレスを設定します。 コネクション名が中途半端に日本語で扱いづらいので、uuidを抽出して利用しています。

自分の eth1 のIPアドレスを設定したら、相手のdocker0に対するルーティングを追加設定します。

dockerの起動オプションに -bip=CIDR を指定して、 docker0 が利用するアドレス帯を指定します。

firewall-cmd --set-default-zone=trusted

ETH1_UUID=$(nmcli --fields uuid,device con show | grep -w eth1 | awk '{print $1}')
nmcli con mod ${ETH1_UUID:?} ipv4.method manual ipv4.addresses "172.16.1.1/16"
nmcli con up ${ETH1_UUID:?}
ip route add 192.168.2.0/24 via 172.16.2.1

yum -y install docker
sed -i -r 's@^OPTIONS=(.*)@OPTIONS=\1 -bip=192.168.1.1/24@' /etc/sysconfig/docker
systemctl enable docker.service
systemctl start docker.service

host02

host01と手順は同じで、IPアドレスだけ変えて実行します。

firewall-cmd --set-default-zone=trusted

ETH1_UUID=$(nmcli --fields uuid,device con show | grep -w eth1 | awk '{print $1}')
nmcli con mod ${ETH1_UUID:?} ipv4.method manual ipv4.addresses "172.16.2.1/16"
nmcli con up ${ETH1_UUID:?}
ip route add 192.168.1.0/24 via 172.16.1.1

yum -y install docker
sed -i -r 's@^OPTIONS=(.*)@OPTIONS=\1 -bip=192.168.2.1/24@' /etc/sysconfig/docker
systemctl enable docker.service
systemctl start docker.service

動作確認

host01で起動したコンテナにhost02から接続してみます。

docker-multi-small.route

host01

nginxコンテナを起動して、付与されたIPアドレスを確認します。

IPアドレスは docker inspect -f '{{ .NetworkSettings.IPAddress }}' コンテナ名orコンテナID で確認できます。

docker run -d -P --name ngx nginx:latest

起動できたら、付与されたIPアドレスを確認します。

[root@localhost ~]# docker inspect -f '{{ .NetworkSettings.IPAddress }}' ngx
192.168.1.2

host02

docker run --rm -it centos:centos7 bash で、使い捨てな動作確認用のコンテナを作成し、その上からcurlでhost01上のコンテナにアクセスしてみます。

[root@localhost ~]# docker run --rm -it centos:centos7 bash
[root@28fcc93d748f /]# curl -v 192.168.1.2 2>&1 | grep '^<' | head
< HTTP/1.1 200 OK
< Server: nginx/1.7.8
< Date: Thu, 04 Dec 2014 13:44:10 GMT
< Content-Type: text/html
< Content-Length: 612
< Last-Modified: Tue, 02 Dec 2014 13:35:07 GMT
< Connection: keep-alive
< ETag: "547dc00b-264"
< Accept-Ranges: bytes

疎通できました!

まとめ

ホストをまたいでコンテナ間接続するためには

  1. 各ホストが重複しないアドレス帯をdocker0に割り当てる
  2. 起動したコンテナのIPアドレスを知る
  3. 各ホスト(もしくは上位ルータ)で、他ホストがどのネットワークアドレス帯をdocker0に割り当てているかを把握しルーティングする

のステップが必要です。面倒ですね。。。。というところで今日はおしまい。


See also