Docker 1.9でプロダクションになったMulti-Host Docker Networkingを使ってDockerホストのクラスタをセットアップしていきます。Ambari on DockerやDocker SwarmとDocker Composeを使ったデプロイ環境の構築が目的です。
IDCFクラウドでようやく利用できるようになったDebian Jessieを利用してみます。今回は手動で設定をしていますが、Manage the cloud with Terraform, Salt, Consul and DigitalOceanのようにSaltで構成管理をする予定です。
このシリーズ
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 1: Overlayネットワークの作成
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 2: Docker Swarmクラスタの作成
- IDCFクラウドのDebian JessieでMulti-Host Docker Networking - Part 3: OverlayネットワークとDocker SwarmとDocker ComposeでRethinkDBをスケールさせる
参考
以下のサイトを参考にしました。
仮想マシンの用意
IDCFクラウドのクラウドコンソールから仮想マシンを3台作成します。プライベートIPアドレスはわかりやすいように連番で作成します。
Dockerホストのhostname | Dockerホストのeth0 |
---|---|
minion-1 | 10.3.0.101 |
minion-2 | 10.3.0.102 |
minion-3 | 10.3.0.103 |
Debianのバージョンを確認します。
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 8.2 (jessie)
Release: 8.2
Codename: jessie
libnetworkのoverlayドライバはLinux Kernel 3.16以上が必要です。Debian 8.2のカーネルは3.16なのでこのまま利用することができます。
$ uname -r
3.16.0-4-amd64
minion[1-3]
の仮想マシンにConsulとDockerをインストールしていきます。
Consul
overlayドライバのメタデータを保存する分散KVSにConsulを使います。以下の作業はroot権限で実行します。
インストール
執筆時点で最新の0.6.0
をインストールします。
$ curl -LO https://releases.hashicorp.com/consul/0.6.0/consul_0.6.0_linux_amd64.zip
$ unzip consul_0.6.0_linux_amd64.zip
$ mv consul /usr/local/bin
$ consul version
Consul v0.6.0
Consul Protocol: 3 (Understands back to: 1)
Consulを実行するのconsul
ユーザーを作成します。
$ useradd consul
設定ファイル
Consulの設定ファイルを配置するディレクトリを作成します。データを保存する/var/consul
ディレクトリのオーナーをconsul
に変更します。
$ mkdir /var/consul /etc/consul.d /etc/sysconfig
$ chown consul:consul /var/consul
Debian用の環境設定ファイルを作成します。minion-1
の場合-advertise
をeth0の10.3.0.101
に設定します。minion-2
とminon-3
はそれぞれのIPアドレスを設定します。
GOMAXPROCS=2
CMD_OPTS="agent -advertise 10.3.0.101 -config-dir=/etc/consul.d -data-dir=/var/consul"
Consulの設定ファイルはJSON形式で以下のように記述します。bootstrap_expect
、retry_join
にConsulクラスタを構成するノードのIPアドレスを設定して3台が参加するまで起動を待機します。
{
"bootstrap_expect": 3,
"server": true,
"data_dir": "/var/consul",
"log_level": "INFO",
"enable_syslog": false,
"retry_join": ["10.3.0.101", "10.3.0.102", "10.3.0.103"],
"client_addr": "0.0.0.0"
}
systemd
Jessieではデフォルトのinitとしてsystemdが採用されています。Consulの設定ファイルはconsul.serviceを参考にしました。
[Unit]
Description=Consul agent
Requires=network-online.target
After=network-online.target
[Service]
User=consul
Group=consul
EnvironmentFile=-/etc/default/consul
ExecStart=/usr/local/bin/consul $CMD_OPTS
ExecReload=/bin/kill -HUP $MAINPID
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
`編集したsystemdの設定ファイルをリロードして反映させます。
$ systemctl daemon-reload
Consulサービスの自動起動を有効にしてサービスを起動します。
$ systemctl enable consul
Created symlink from /etc/systemd/system/multi-user.target.wants/consul.service to /lib/systemd/system/consul.service.
$ systemctl start consul
Docker
Dockerのインストールはワンライナーで簡単にします。
$ curl -sSL https://get.docker.com/ | sh
systemd
Docker init script on Debian Jessie not honoring DOCKER_OPTSにあるように、Jessieの/lib/systemd/system/docker.service
ではDOCKER_OPTS
の起動オプションを読み込みません。オフィシャルのControl and configure Docker with systemdを参考にsystemdの設定ファイルを編集します。
dockerサービスを停止します。
$ systemctl stop docker
/etc/default/docker
にDockerの起動オプションをDOCKER_OPTS
環境変数に設定します。
DOCKER_OPTS="--cluster-store=consul://localhost:8500 --cluster-advertise=eth0:2376"
systemdのdocker.service
ファイルを編集して環境設定ファイルからDOCKER_OPTS
環境変数を読み込み、docker daemon
の起動オプションに追加します。
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network.target docker.socket
Requires=docker.socket
[Service]
Type=notify
EnvironmentFile=-/etc/default/docker
ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
設定ファイルのリロードとサービスを開始します。
$ systemctl daemon-reload
$ systemctl start docker
docker info
コマンドを実行するとCluster store
とCluster advertise
の情報が表示されます。Consulを分散KVSに使ったMulti-Host Docker Networkingの準備ができました。
$ docker info
Containers: 1
Images: 8
Server Version: 1.9.1
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 10
Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Kernel Version: 3.16.0-4-amd64
Operating System: Debian GNU/Linux 8 (jessie)
CPUs: 2
Total Memory: 7.812 GiB
Name: minion-1
ID: NQQD:HJHQ:HQE5:23ZH:H5XH:A6KR:YY3B:36QY:557I:CTB7:TS5Z:BCML
WARNING: No memory limit support
WARNING: No swap limit support
Cluster store: consul://localhost:8500
Cluster advertise: 10.3.0.101:2376
Overlayネットワークの作成
Understand Docker container networksを読みながら、Docker 1.9からプロダクションになったdocker network
コマンドを使いOverlayネットワークを作成します。dn
は任意につけたネットワーク名です。--subnet
フラグでDockerのネットワークアドレスを設定します。docker network
はminion-[1-3]
のどこのノードで実行しても構いません。
$ docker network create \
--subnet=192.168.0.0/24 \
--driver=overlay \
dn
minion-1
にログインしてDockerのネットワークを確認します。
$ docker network ls
NETWORK ID NAME DRIVER
f10c0f7978af dn overlay
339726e9a8c5 bridge bridge
4b052cb2cf21 none null
662ed6607bf0 host host
minion-2
とminion-3
も同様に確認します。どのノードでも同じdn
ネットワークは同じIDになっています。
$ docker network ls
NETWORK ID NAME DRIVER
4af071c309a6 bridge bridge
4524099d60f2 none null
c49d7d97bf1a host host
f10c0f7978af dn overlay
コンテナの作成
--netフラグ
docker run
の--net
フラグは指定されたネットワークに参加した状態でコンテナを起動します。minion-1
のDockerホストでamb1
コンテナを作成します。eth0
がdocker network create
で作成したネットワークに割り当てられます。
$ docker run -d -it \
--name amb1 \
-h amb1 \
--net dn \
debian:jessie
$ docker exec amb1 ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
9: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
link/ether 02:42:c0:a8:00:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.2/24 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:c0ff:fea8:2/64 scope link
valid_lft forever preferred_lft forever
12: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe12:2/64 scope link
valid_lft forever preferred_lft forever
同様にminion-2
Dockerホストからamb2
コンテナを作成します。
$ docker run -d -it \
--name amb2 \
-h amb2 \
--net dn \
debian:jessie
minion-3
ではamb3
コンテナを作成します。
$ docker run -d -it \
--name amb3 \
-h amb3 \
--net dn \
debian:jessie
/etc/hosts
作成したコンテナの/etc/hosts
に--net
フラグで指定したネットッワークに参加しているコンテナのホスト名とIPアドレスが追加されます。
$ docker exec amb1 cat /etc/hosts
192.168.0.2 amb1
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.0.3 amb2
192.168.0.3 amb2.dn
192.168.0.4 amb3
192.168.0.4 amb3.dn
作成したコンテナはdn
ネットワークで以下のIPアドレスが割り当てられました。
コンテナのhostname | Dockerホスト | コンテナのeth0 |
---|---|---|
amb1 | minion-1 | 192.168.0.2 |
amb2 | minion-2 | 192.168.0.3 |
amb3 | minion-3 | 192.168.0.4 |
pingを使ったテスト
pingを実行して異なるDockerホストのコンテナからネットワークの疎通確認をします。
amb1
コンテナからamb2
コンテナへping。
$ docker exec amb1 ping -c 1 amb2
PING amb2 (192.168.0.3): 56 data bytes
64 bytes from 192.168.0.3: icmp_seq=0 ttl=64 time=0.426 ms
--- amb2 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.426/0.426/0.426/0.000 ms
コンテナから別のDockerホストへも通信できます。amb1
コンテナからminion-2(10.3.0.102)
へping。
$ docker exec amb1 ping -c 1 10.3.0.102
docker exec amb1 ping -c 1 10.3.0.102
PING 10.3.0.102 (10.3.0.102): 56 data bytes
64 bytes from 10.3.0.102: icmp_seq=0 ttl=63 time=0.307 ms
--- 10.3.0.102 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.307/0.307/0.307/0.000 ms
$ docker exec amb1 ping -c 1 minion-2
PING minion-2.cs3d0idcfcloud.internal (10.3.0.102): 56 data bytes
64 bytes from 10.3.0.102: icmp_seq=0 ttl=63 time=0.254 ms
--- minion-2.cs3d0idcfcloud.internal ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.254/0.254/0.254/0.000 ms
コンテナから名前解決をしてインターネットへ通信もできます。
$ docker exec amb1 ping -c 1 www.yahoo.co.jp
PING www.g.yahoo.co.jp (182.22.40.240): 56 data bytes
64 bytes from 182.22.40.240: icmp_seq=0 ttl=57 time=1.139 ms
--- www.g.yahoo.co.jp ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.139/1.139/1.139/0.000 ms