Docker Swarm を利用して Resin のクラスタリングを構築する。
この CookBook では、Docker Swarm を利用して Resin のクラスタリングを構築する手順について紹介しています。
Docker Swarm を利用することで、複数マシンにまたがった仮想 Docker ネットワークを定義し、そのネットワーク上にコンテナをデプロイすることでクラスタリング環境を構築することができます。
レシピ
- Docker Swarm Manager を作成する
- Docker Swarm クラスタに参加する
- Swarm 用 Docker Overlay Network を作成する
- Resin の Docker Image を作成する
- Swarm クラスタに Resin タスクをデプロイする
この CookBook では 2 台のマシンを利用します。
1 台目 | 2 台目 | |
名前 | マシン A | マシン B |
役割 | Docker Swarm Manager | Docker Swarm Worker |
プライベート IP アドレス | 192.168.0.2 | 192.168.0.3 |
マシン A を Docker Swarm クラスタのマネージャーとします。
マシン B をマシン A のクラスタに参加するノードとします。
1. Docker Swarm Manager を作成する
マシン A 上で以下のコマンドを実行します。
docker swarm init --advertise-addr 192.168.0.2
以下のような実行結果が返却されます。
Swarm initialized: current node (xxxxxxxxxxxxxxxxxxxxxxxxx) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token XXXXXX-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx 192.168.0.2:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
エラーが出た場合 2377 ポートを他のプログラムが使用していないか確認してください。2377 ポートが利用できない場合 --listen-addr フラグを指定することで他のポートを使用することも可能です。
返却された実行結果の docker swarm join --token ... のコマンドをコピーします。
2. Docker Swarm クラスタに参加する
マシン B 上で、先ほどコピーしたコマンドを実行します。
docker swarm join --token XXXXXX-x-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxx 192.168.0.2:2377
以下のような実行結果が返却されます。
This node joined a swarm as a worker.
マシン A 上で以下のコマンドを実行します。
docker node ls
以下のような実行結果が返却されます。
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
xxxxxxxxxxxxxxxxxxxxxxxxx * machine-a Ready Active Leader 18.03.1-ce
yyyyyyyyyyyyyyyyyyyyyyyyy machine-b Ready Active 18.03.1-ce
マシン A とマシン B の 2 ノードで構成されていることが確認できます。
3. Swarm 用 Docker Overlay Network を作成する
マシン A 上で以下のコマンドを実行します
docker network create -d overlay --subnet=172.16.0.0/24 resin-cluster
-d overlay を指定することで、Docker Swarm の各ノード上でまたがって利用可能なオーバーレイネットワークを作成します。
ここで作成したネットワークを Docker Swarm の各ノード内で利用する仮想的なネットワークとします。
マシン A 上で以下のコマンドを実行します
docker network ls
以下のように、NAME=resin-cluster, DRIVER=overlay, SCOPE=swarm のネットワークが作成されていることが確認できます。
NETWORK ID NAME DRIVER SCOPE
xxxxxxxxxxxx bridge bridge local
yyyyyyyyyyyy docker_gwbridge bridge local
zzzzzzzzzzzz host host local
wwwwwwwwwwww ingress overlay swarm
uuuuuuuuuuuu none null local
vvvvvvvvvvvv resin-cluster overlay swarm
SCOPE=swarm となっていることから分かるように、オーバーレイネットワークは Docker Swarm と組み合わせた場合のみ利用可能です。
docker run --net=resin-cluster のような利用はできません。
4. Resin の Docker Image を作成する
Dockerfile
FROM centos:centos6.9
# gcc
RUN yum groupinstall -y 'Development Tools'
# jdk
COPY jdk-8u181-linux-x64.tar.gz /jdk-8u181-linux-x64.tar.gz
RUN tar zxvf jdk-8u181-linux-x64.tar.gz
RUN mkdir -p /usr/local/java
RUN mv jdk1.8.0_181 /usr/local/java/jdk1.8.0_181
RUN ln -s /usr/local/java/jdk1.8.0_181 /usr/local/java/jdk
ENV JAVA_HOME /usr/local/java/jdk
ENV PATH /usr/local/java/jdk/bin:$PATH
RUN echo 'JAVA_HOME=/usr/local/java/jdk' >> /root/.bashrc
RUN echo 'PATH=/usr/local/java/jdk/bin:$PATH' >> /root/.bashrc
# resin
RUN curl -L -C - -O http://caucho.com/download/resin-pro-4.0.57.zip
RUN unzip resin-pro-4.0.57.zip
RUN cd resin-pro-4.0.57 && ./configure && make && make install
RUN echo "web_admin_external : true" >> /etc/resin/resin.properties
RUN echo "admin_external : true" >> /etc/resin/resin.properties
RUN echo "admin_user : admin" >> /etc/resin/resin.properties
RUN echo "admin_password : {SSHA}bTLnpGjSarNFd/EQe8W4d/IjAxfQdGe8" >> /etc/resin/resin.properties
RUN echo "admin_external : true" >> /etc/resin/resin.properties
RUN echo "admin_secure : true" >> /etc/resin/resin.properties
COPY myresin.license /etc/resin/licenses/myresin.license
CMD sleep 20 && \
sed -i -e "s/app_servers : 127.0.0.1:6800/app_servers : $(echo $(dig tasks.resin-service A +short))/g" /etc/resin/resin.properties && \
touch /var/log/resin/jvm-app-0.log && \
service resin start && \
tail -F /var/log/resin/jvm-app-0.log
resin-admin に admin/password でログインできるようにし、app_servers に DNS「tasks.resin-service」の A レコードから取れる値を指定し、2 台のクラスタリング環境を構築するよう設定しています。
DNS「tasks.resin-service」についての詳細は Container discovery を参照してください。
後の手順で resin-service という名称で Swarm サービスを作成するため、DNS「tasks.resin-service」で Swarm ノードのプライベート IP アドレスの一覧が取得できます。
この DNS は Swarm サービス起動完了後に利用可能になるため、利用可能になるまである程度時間がかかるため sleep 20 を入れています。
20 秒 sleep した後で、DNS「tasks.resin-service」の値を取得(dig)し、スペース区切りに変換(echo)し app_servers に指定しています。
マシン A, マシン B の両方で、myresin というタグでビルドします。
docker build -t myresin:4.0.57 .
(イメージを DockerHub に push している場合、Worker ノードは自動的に pull するためすべてのノード上でビルドする必要はなくなります。)
5. Swarm クラスタに Resin タスクをデプロイする
マシン A 上で、以下のコマンドでタスクをデプロイします。
docker service create \
--name resin-service \
--replicas 2 \
--network resin-cluster \
--publish published=8080,target=8080 \
--hostname="{{.Service.Name}}-{{.Task.Slot}}" \
myresin:4.0.57
サービス名「resin-service」、レプリカ数 = 2, ネットワークは先ほど作成した「resin-cluster」でサービスを作成します。
レプリカを 2 個にしているため、マシン A, マシン B 上にデプロイされます。
以下のコマンドで、どのマシン上で実行されているかを確認できます。
docker service ps resin-service
マシン A, マシン B 上で実行されていることが確認できます。
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xxxxxxxxxxxx resin-service.1 myresin:4.0.57 machine-a Running Running 10 minutes ago
yyyyyyyyyyyy resin-service.2 myresin:4.0.57 machine-b Running Running 10 minutes ago
コンテナのホスト名の設定(--hostname)は本来不要ですが、ここでは分かりやすい名前にすることを優先して設定しています。
コンテナの Resin が利用する 8080 ポート(target)をそのままホスト側の 8080 ポート(published)で開放しています。
そのため、http://192.168.0.2:8080/resin-admin, http://192.168.0.3:8080/resin-admin から resin-admin にアクセスできます。
resin-admin に admin/password でログインすることで、2 台のマシン上にデプロイされた Overlay ネットワーク上の Resin コンテナでクラスタリングを組めていることが確認できます。
まとめ
このように、Docker Swarm を利用することで、複数マシン上でのクラスタリング環境を構築できます。
上手く利用することで、10 台 や 20 台といった多数のマシンからなるクラスタリング環境も素早く構築することが可能です。
是非ご活用ください。