Think Twice

Memorandum

マルチホストでdocker−swarm (GCP)

マルチホストでdocker swarm を試す

参考サイト

docs.docker.com

blog.docker.com

kvs の作成

  • docker-machine でswarm−kvsを作成する
$ docker-machine create \
    --driver google \
    --google-project myproject-xxxx \
    --google-zone asia-east1-a \
    --google-machine-type f1-micro \
    swarm-kvs

instanceが作成されたのを確認。

$ docker-machine ls
NAME        ACTIVE   DRIVER       STATE     URL                         SWARM
swarm-kvs   -        google       Running   tcp://130.211.246.63:2376

環境変数を整えて

$ eval "$(docker-machine env swarm-kvs)"

作成したswarm−kvs 上にconsul をサーバ・モードで実行する。

$ docker $(docker-machine config swarm-kvs) run -d \
    -p "8500:8500" \
    -h "consul" \
    progrium/consul -server -bootstrap

swarm cluster を作成する

マルチホストで通信するためにはクラスタ設定が必要。

  • swarm−master の作成
$ docker-machine create \
    --driver google \
    --google-project myproject-xxxx \
    --google-zone asia-east1-a \
    --google-machine-type f1-micro \
    --swarm \
    --swarm-master \
    --swarm-discovery="consul://$(docker-machine ip swarm-kvs):8500" \
    --engine-opt="cluster-store=consul://$(docker-machine ip swarm-kvs):8500" \
    --engine-opt="cluster-advertise=eth0:2376" \
    swarm-master
  • swarm−agent の作成
$ docker-machine create \
    --driver google \
    --google-project myproject-xxxx \
    --google-zone asia-east1-a \
    --google-machine-type f1-micro \
    --swarm \
    --swarm-discovery="consul://$(docker-machine ip swarm-kvs):8500" \
    --engine-opt="cluster-store=consul://$(docker-machine ip swarm-kvs):8500" \
    --engine-opt="cluster-advertise=eth0:2376" \
    swarm-agent

docker クライアントの環境変数の切り替え --swarm をつけるとswarmクラスタの設定になる。

$ eval $(docker-machine env --swarm swarm-master)

docker infoクラスタの状態を確認できる。

$ docker info
Containers: 3
Images: 2
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
 swarm-agent1: 104.155.201.164:2376
  └ Status: Healthy
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 618.7 MiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.19.0-28-generic, operatingsystem=Ubuntu 14.04.3 LTS, provider=google, storagedriver=aufs
 swarm-master: 104.199.156.16:2376
  └ Status: Healthy
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 618.7 MiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.19.0-28-generic, operatingsystem=Ubuntu 14.04.3 LTS, provider=google, storagedriver=aufs
CPUs: 2
Total Memory: 1.208 GiB
Name: bedd6437dbb4

compute engine のinstanceを確認。

$ gcloud compute instances list
NAME         ZONE         MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP     STATUS
swarm-agent1 asia-east1-a f1-micro                 10.240.0.4  104.155.201.164 RUNNING
swarm-kvs    asia-east1-a f1-micro                 10.240.0.2  130.211.246.63  RUNNING
swarm-master asia-east1-a f1-micro                 10.240.0.3  104.199.156.16  RUNNING
$ docker-machine ls
NAME           ACTIVE   DRIVER       STATE     URL                          SWARM
swarm-agent1   -        google       Running   tcp://104.155.201.164:2376   swarm-master
swarm-kvs      -        google       Running   tcp://130.211.246.63:2376
swarm-master   *        google       Running   tcp://104.199.156.16:2376    swarm-master (master)

オーバーレイ ネットワークの作成

  • ネットワークの作成
$ docker network create --driver overlay my-network
9e37172e132c50e8bc89e06000cf2ef6774a0fb5305e87ce5c4599383f49096e
  • 作成したネットワークの確認
$ docker network ls
NETWORK ID          NAME                  DRIVER
bfa7f2d3ea25        swarm-master/none     null
a656e617f5b0        swarm-master/host     host
9e37172e132c        my-network            overlay
fd6eaa122101        swarm-master/bridge   bridge
66f847f22da0        swarm-agent1/none     null
1e48ec001aaa        swarm-agent1/host     host
0902af9fc7d3        swarm-agent1/bridge   bridge

アプリケーションの起動(作成したネットワーク上での)

  • DB(postgres) をswarm上に起動
$ docker build -t postgres ./postgres
$ docker run -d --net=my-network --name mydb postgres
  • AP(spring-boot) をswarm上に起動 起動時の引数を以下のように設定 ↑で設定した名前(mydb)を使用できる。(自然な感じで接続できる)
FROM ubuntu

# Setup
RUN apt-get install -y software-properties-common debconf-utils
RUN add-apt-repository -y ppa:webupd8team/java
RUN apt-get update

# Java8
RUN echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 boolean true" | debconf-set-selections
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get install -y oracle-java8-installer

CMD ["java", "-version"]

EXPOSE 8080

ADD ./my-application-0.1.0.jar /my-application-0.1.0.jar

CMD ["java", "-jar", "/my-application-0.1.0.jar",\
"--spring.datasource.initialize=false",\
"--spring.datasource.driverClassName=org.postgresql.Driver",\
"--spring.datasource.url=jdbc:postgresql://mydb:5432/myschema",\
"--spring.datasource.username=scott",\
"--spring.datasource.password=tiger"]
$ docker build -t web ./web
$ docker run --rm -p 80:8080 --net=my-network --name myapp web

ホスト間の接続の確認

  • docker ps で別々のnodeで起動していることを確認
docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
b033d2069995        web                 "java -jar /isolating"   9 seconds ago       Up 6 seconds        104.199.156.16:80->8080/tcp   swarm-master/myapp
87ec3da3b615        postgres            "/usr/lib/postgresql/"   22 seconds ago      Up 21 seconds       5432/tcp                      swarm-agent1/mydb
$ docker exec -it b033d2069995 bash
root@b033d2069995:/#
root@b033d2069995:/# cat /etc/hosts
10.0.0.3    b033d2069995
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
10.0.0.2    mydb
10.0.0.2    mydb.my-network
root@b033d2069995:/#
root@b033d2069995:/# ping mydb
PING mydb (10.0.0.2) 56(84) bytes of data.
64 bytes from mydb (10.0.0.2): icmp_seq=1 ttl=64 time=1.35 ms
64 bytes from mydb (10.0.0.2): icmp_seq=2 ttl=64 time=0.631 ms
64 bytes from mydb (10.0.0.2): icmp_seq=3 ttl=64 time=0.680 ms
64 bytes from mydb (10.0.0.2): icmp_seq=4 ttl=64 time=0.590 ms
64 bytes from mydb (10.0.0.2): icmp_seq=5 ttl=64 time=0.589 ms
64 bytes from mydb (10.0.0.2): icmp_seq=6 ttl=64 time=0.620 ms
^C
--- mydb ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 4998ms
docker exec -it 87ec3da3b615 bash
postgres@87ec3da3b615:/$
postgres@87ec3da3b615:/$ cat /etc/hosts
10.0.0.2    87ec3da3b615
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
10.0.0.3    myapp
10.0.0.3    myapp.my-network
postgres@87ec3da3b615:/$
postgres@87ec3da3b615:/$ ping myapp
PING myapp (10.0.0.3) 56(84) bytes of data.
64 bytes from myapp (10.0.0.3): icmp_seq=1 ttl=64 time=1.44 ms
64 bytes from myapp (10.0.0.3): icmp_seq=2 ttl=64 time=0.820 ms
64 bytes from myapp (10.0.0.3): icmp_seq=3 ttl=64 time=0.801 ms
64 bytes from myapp (10.0.0.3): icmp_seq=4 ttl=64 time=0.814 ms
^C
--- myapp ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.801/0.970/1.446/0.275 ms

画面からもDBにアクセスするのを確認できた。*1 めでたし。めでたし。


途中、すんなり行かなかったところ。

compute engine のinstance を作成するときに、途中で止まってうまく作れない(Configuring swarm に失敗する)場合、 firewall−ruleでtcp:3386;tcp:2376を許可するルールを作成する必要がある。

Configuring swarm...
WARNING >>> Error attempting heartbeat call to plugin server: unexpected EOF

と出力された場合、以下のコマンドでfirewall−ruleを作成する

$ gcloud compute firewall-rules create swarm-firewall \
    --target-tags docker-machine --allow tcp:2376,tcp:3376

Created [https://www.googleapis.com/compute/v1/projects/myproject-xxxx/global/firewalls/swarm-firewall].
NAME           NETWORK SRC_RANGES RULES             SRC_TAGS TARGET_TAGS
swarm-firewall default 0.0.0.0/0  tcp:2379,tcp:3389          docker-machine

firewall-rulesの確認

$ gcloud compute firewall-rules list

NAME                   NETWORK SRC_RANGES    RULES                             SRC_TAGS TARGET_TAGS
default-allow-icmp     default 0.0.0.0/0     icmp
default-allow-internal default 10.240.0.0/16 tcp:0-65535,udp:0-65535,icmp
default-ssh            default 0.0.0.0/0     tcp:22
docker-machines        default 0.0.0.0/0     tcp:2376,tcp:3376,tcp:8500,tcp:80          docker-machine

docker−machine create で失敗した時の出力

$ docker-machine create     --driver google     --google-project myproject-xxxx     --google-zone asia-east1-a     --google-machine-type f1-micro     --swarm     --swarm-master     --swarm-discovery="consul://$(docker-machine ip swarm-kvs):8500"     --engine-opt="cluster-store=consul://$(docker-machine ip swarm-kvs):8500"     --engine-opt="cluster-advertise=eth0:2376"     swarm-master
Running pre-create checks...
(swarm-master) OUT | Check that the project exists
(swarm-master) OUT | Check if the instance already exists
Creating machine...
(swarm-master) OUT | Generating SSH Key
(swarm-master) OUT | Creating host...
(swarm-master) OUT | Creating instance.
(swarm-master) OUT | Waiting for Instance...
(swarm-master) OUT | Uploading SSH Key
(swarm-master) OUT | Waiting for SSH Key
Waiting for machine to be running, this may take a few minutes...
Machine is running, waiting for SSH to be available...
Detecting operating system of created instance...
Detecting the provisioner...
Provisioning created instance...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Configuring swarm...
WARNING >>> Error attempting heartbeat call to plugin server: unexpected EOF
Error creating machine: Error running provisioning: connection is shut down

*1:screenshotは撮り忘れた。