このエントリはKubernetesアドベントカレンダー2014の8日目です。
今日はKubernetesの効果を理解するために、Kubernetesなしで構成を組んでみます。 dockerだけで組むのは先日やってみたので、 昨日紹介したflannelを使って実装します。
構成
手元の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: flannel全体: 172.17.0.0/16, host01: flannel次第, host02: flannel次第
flannelは各サーバで起動するものなので各サーバに配置、etcdはhost01だけで起動します(Raftが過半数投票でleaderを決める方式なので、2台だと永遠に選出が終わらない模様)。
設定手順
host01
iptablesを全パスにしたら、 nmcli
を使ってNetowrkManagerからeth1に対してIPアドレスを設定します。
先日と同様にコネクション名が中途半端に日本語で扱いづらいので、uuidを抽出して利用しています。
ここまでは前回と同じ手順です。
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:?}
自分の eth1
のIPアドレスを設定したら、etcd(とetcdctl)とflannelをビルドします。
yum -y install golang
yum -y install git
git clone https://github.com/coreos/etcd.git /opt/etcd
cd /opt/etcd
git checkout v0.4.6
./build
cp bin/etcd /usr/local/sbin/.
git clone https://github.com/coreos/etcdctl.git /opt/etcdctl
cd /opt/etcdctl
git checkout v0.4.5
./build
cp bin/etcdctl /usr/local/sbin/.
yum -y install kernel-headers
git clone https://github.com/coreos/flannel.git /opt/flannel
cd /opt/flannel
git checkout v0.1.0
./build
cp bin/flanneld /usr/local/sbin/.
準備ができたら1.etcd、2.flannelの順に起動します。
flannelを起動する前に、etcdctlを使ってflannel用の設定をetcdに投入しておきます。
うまく起動しない場合は /tmp/etcd.log
と /tmp/flanneld.log
を見てみてください。
flannelの起動オプションで、他ホストとIPマスカレードで通信するために -ip-masq=true
を、etcdと通信するために -etcd-endpoint=〜
を、flannelが通信するために使う(ネットワークアドレス帯決定にも使う)インターフェイスを -iface=〜
で指定します。
etcd -name=host01 -data-dir=/tmp/etcd -addr=172.16.1.1:4001 -peer-addr=172.16.1.1:7001 >/tmp/etcd.log 2>&1 &
etcdctl mk /coreos.com/network/config '{"Network":"172.17.0.0/16"}'
flanneld -ip-masq=true -etcd-endpoint=http://172.16.1.1:4001 -iface=eth1 >/tmp/flanneld.log 2>&1 &
起動に成功すると、 flannel0
というインターフェイスが作成されてルーティングが設定されます。
そしてその情報が /run/flannel/subnet.env
に出力されます。
[root@localhost flannel]# ip addr show flannel0
4: flannel0: mtu 1472 qdisc pfifo_fast state UNKNOWN qlen 500
link/none
inet 172.17.59.0/16 scope global flannel0
valid_lft forever preferred_lft forever
[root@localhost flannel]# ip route
default via 10.0.2.2 dev eth0 proto static metric 1024
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
172.16.0.0/16 dev eth1 proto kernel scope link src 172.16.1.1
172.17.0.0/16 dev flannel0 proto kernel scope link src 172.17.59.0
[root@localhost flannel]# cat /run/flannel/subnet.env
FLANNEL_SUBNET=172.17.59.1/24
FLANNEL_MTU=1472
この /run/flannel/subnet.env
をもとに、dockerの起動オプションに --bip=CIDR
(と --mtu=MTU
)を指定して、 docker0
が利用するアドレス帯を指定します。
systemdの設定ファイルを書き換えて EnvironmentFile=-/run/flannel/subnet.env
行を追加するのと、 ExecStart
の引数に --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}
を追加します。
変更したら daemon-reload
して再読み込みしてから起動します。
yum -y install docker
sed -i -r 's@^(ExecStart=.*)@EnvironmentFile=-/run/flannel/subnet.env\n\1 --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}@' /usr/lib/systemd/system/docker.service
systemctl daemon-reload
systemctl start docker.service
[root@localhost ~]# cat /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.io
After=network.target
Requires=docker.socket
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/run/flannel/subnet.env
ExecStart=/usr/bin/docker -d $OPTIONS $DOCKER_STORAGE_OPTIONS --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}
Restart=on-failure
LimitNOFILE=1048576
LimitNPROC=1048576
[Install]
Also=docker.socket
WantedBy=multi-user.target
起動すると docker0
が作成されます。
[root@localhost flannel]# ip addr show docker0
5: docker0: mtu 1500 qdisc noqueue state DOWN
link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
inet 172.17.59.1/24 scope global docker0
valid_lft forever preferred_lft forever
[root@localhost ~]# ip route
default via 10.0.2.2 dev eth0 proto static metric 1024
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
172.16.0.0/16 dev eth1 proto kernel scope link src 172.16.1.1
172.17.0.0/16 dev flannel0 proto kernel scope link src 172.17.59.0
172.17.59.0/24 dev docker0 proto kernel scope link src 172.17.59.1
これでhost01は準備完了です。
host02
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:?}
自分の eth1
のIPアドレスを設定したら、flannelをビルドします。
(host01でビルド済みのものをコピーしてもよいです)
yum -y install golang
yum -y install git
yum -y install kernel-headers
git clone https://github.com/coreos/flannel.git /opt/flannel
cd /opt/flannel
git checkout v0.1.0
./build
cp bin/flanneld /usr/local/sbin/.
準備ができたらflannelを起動します。
うまく起動しない場合は /tmp/flanneld.log
を見てみてください。
flanneld -ip-masq=true -etcd-endpoint=http://172.16.1.1:4001 -iface=eth1 >/tmp/flanneld.log 2>&1 &
起動に成功すると、 flannel0
というインターフェイスが作成されます。
そしてその情報が /run/flannel/subnet.env
に出力されます。
[root@localhost flannel]# ip addr show flannel0
4: flannel0: mtu 1472 qdisc pfifo_fast state UNKNOWN qlen 500
link/none
inet 172.17.51.0/16 scope global flannel0
valid_lft forever preferred_lft forever
[root@localhost flannel]# cat /run/flannel/subnet.env
FLANNEL_SUBNET=172.17.51.1/24
FLANNEL_MTU=1472
systemdの設定ファイルを書き換えて、 daemon-reload
して再読み込みしてから起動します。
yum -y install docker
sed -i -r 's@^(ExecStart=.*)@EnvironmentFile=-/run/flannel/subnet.env\n\1 --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU}@' /usr/lib/systemd/system/docker.service
systemctl daemon-reload
systemctl start docker.service
[root@localhost flannel]# ip addr show docker0
5: docker0: mtu 1500 qdisc noqueue state DOWN
link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
inet 172.17.51.1/24 scope global docker0
valid_lft forever preferred_lft forever
[root@localhost ~]# ip route
default via 10.0.2.2 dev eth0 proto static metric 1024
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
172.16.0.0/16 dev eth1 proto kernel scope link src 172.16.2.1
172.17.0.0/16 dev flannel0 proto kernel scope link src 172.17.51.0
172.17.51.0/24 dev docker0 proto kernel scope link src 172.17.51.1
動作確認
前回と同じ手順で確認しましょう。
host01
docker run -d -P --name ngx nginx:latest
[root@localhost ~]# docker inspect -f '{{ .NetworkSettings.IPAddress }}' ngx
172.17.59.2
host02
[root@localhost ~]# docker run --rm -it centos:centos7 bash
[root@79917733444f /]# curl -v 172.17.59.2 2>&1 | grep '^<' | head
< HTTP/1.1 200 OK
< Server: nginx/1.7.8
< Date: Sat, 06 Dec 2014 02:35:04 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
<
疎通できました!
まとめ
flannelを使うとホスト間通信が楽!