この記事では、AWSで3ノードのAWS Docker Swarmクラスターを作成し、共通のGlusterFS複製ボリュームをすべてのノードに接続する方法について説明しました。
はじめに
Docker Swarmモードは、Dockerホストのクラスターを作成するために使用されます。 この場合、名前付きボリュームvoldataが接続されたコンテナAがnode1で実行されている場合 、 voldataへのすべての変更はnode1でローカルに保存されます。 コンテナーAがオフになっていて、例えばnode3で再び開始する場合、 voldataボリュームが接続されると、このストレージは空になり、 node1で行われた変更は含まれません。
これを回避する方法は?
この問題を解決する1つの方法は、GlusterFSを使用してボリュームを複製することです。これにより、いつでもすべてのノードがデータにアクセスできるようになります。 ただし、Dockerホストごとに、名前付きボリュームはローカルのままです。
この演習を完了するために、3つのAWS EC2インスタンスを使用しました。各インスタンスには1つのEBSボリュームが接続されていました。
サーバーの準備
OSとしてUbuntu 16.04を使用します。
まず、/ etc / hostsにノード名を書きます:
XX.XX.XX.XX node1 XX.XX.XX.XX node2 XX.XX.XX.XX node3
次に、システムを更新します。
$ sudo apt update $ sudo apt upgrade
再起動して、すべてのノードで必要なパッケージのインストールを開始します。
$ sudo apt install -y docker.io $ sudo apt install -y glusterfs-server
サービスを起動します。
$ sudo systemctl start glusterfs-server $ sudo systemctl start docker
GlusterFSリポジトリを作成します。
$ sudo mkdir -p /gluster/data /swarm/volumes
GlusterFSを構成する
すべてのノードで、Glusterストレージ用のファイルシステムを準備します。
$ sudo mkfs.xfs /dev/xvdb $ sudo mount /dev/xvdb /gluster/data/
node1で :
$ sudo gluster peer probe node2 peer probe: success. $ sudo gluster peer probe node3 peer probe: success.
複製ボリュームを作成します。
$ sudo gluster volume create swarm-vols replica 3 node1:/gluster/data node2:/gluster/data node3:/gluster/data force volume create: swarm-vols: success: please start the volume to access data
localhostでのみマウントを許可します。
$ sudo gluster volume set swarm-vols auth.allow 127.0.0.1 volume set: success
ボリュームを実行します。
$ sudo gluster volume start swarm-vols volume start: swarm-vols: success
次に、各Glusterノードにマウントします。
$ sudo mount.glusterfs localhost:/swarm-vols /swarm/volumes
Docker swarmを構成する
私たちの目標は、1つのマネージャーと2つの作業ノードを作成することです。
$ sudo docker swarm init Swarm initialized: current node (82f5ud4z97q7q74bz9ycwclnd) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-697xeeiei6wsnsr29ult7num899o5febad143ellqx7mt8avwn-1m7wlh59vunohq45x3g075r2h \ 172.31.24.234:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
作業ノードのトークンを取得します。
$ sudo docker swarm join-token worker To add a worker to this swarm, run the following command: ```docker docker swarm join \ --token SWMTKN-1-697xeeiei6wsnsr29ult7num899o5febad143ellqx7mt8avwn-1m7wlh59vunohq45x3g075r2h \ 172.31.24.234:2377
両方の作業ノードで次を実行します。
$ sudo docker swarm join --token SWMTKN-1-697xeeiei6wsnsr29ult7num899o5febad143ellqx7mt8avwn-1m7wlh59vunohq45x3g075r2h 172.31.24.234:2377 This node joined a swarm as a worker.
swarmクラスターを確認します。
$ sudo docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 6he3dgbanee20h7lul705q196 ip-172-31-27-191 Ready Active 82f5ud4z97q7q74bz9ycwclnd * ip-172-31-24-234 Ready Active Leader c7daeowfoyfua2hy0ueiznbjo ip-172-31-26-52 Ready Active
テスト中
node1とnode3のラベルを作成し、 node1にコンテナを作成し、それをオフにし、 node3に再度作成し、同じボリュームをマウントし、 node1でのコンテナの操作中に作成されたファイルがストレージに残っているかどうかを確認します。
群れノードにラベルを付けます:
$ sudo docker node update --label-add nodename=node1 ip-172-31-24-234 ip-172-31-24-234 $ sudo docker node update --label-add nodename=node3 ip-172-31-26-52 ip-172-31-26-52
タグを確認します。
$ sudo docker node inspect --pretty ip-172-31-26-52 ID: c7daeowfoyfua2hy0ueiznbjo Labels: - nodename = node3 Hostname: ip-172-31-26-52 Joined at: 2017-01-06 22:44:17.323236832 +0000 utc Status: State: Ready Availability: Active Platform: Operating System: linux Architecture: x86_64 Resources: CPUs: 1 Memory: 1.952 GiB Plugins: Network: bridge, host, null, overlay Volume: local Engine Version: 1.12.1
node1にDockerサービスを作成します。これは、共有ストレージ内のファイルの操作をテストするために使用されます。
$ sudo docker service create --name testcon --constraint 'node.labels.nodename == node1' --mount type=bind,source=/swarm/volumes/testvol,target=/mnt/testvol /bin/touch /mnt/testvol/testfile1.txt duvqo3btdrrlwf61g3bu5uaom
サービスを確認します。
$ sudo docker service ls ID NAME REPLICAS IMAGE COMMAND duvqo3btdrrl testcon 0/1 busybox /bin/bash
node1で実行されていることを確認します。
$ sudo docker service ps testcon ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 6nw6sm8sak512x24bty7fwxwz testcon.1 ubuntu:latest ip-172-31-24-234 Ready Ready 1 seconds ago 6ctzew4b3rmpkf4barkp1idhx \_ testcon.1 ubuntu:latest ip-172-31-24-234 Shutdown Complete 1 seconds ago
マウントされたボリュームも確認します。
$ sudo docker inspect testcon [ { "ID": "8lnpmwcv56xwmwavu3gc2aay8", "Version": { "Index": 26 }, "CreatedAt": "2017-01-06T23:03:01.93363267Z", "UpdatedAt": "2017-01-06T23:03:01.935557744Z", "Spec": { "ContainerSpec": { "Image": "busybox", "Args": [ "/bin/bash" ], "Mounts": [ { "Type": "bind", "Source": "/swarm/volumes/testvol", "Target": "/mnt/testvol" } ] }, "Resources": { "Limits": {}, "Reservations": {} }, "RestartPolicy": { "Condition": "any", "MaxAttempts": 0 }, "Placement": { "Constraints": [ "nodename == node1" ] } }, "ServiceID": "duvqo3btdrrlwf61g3bu5uaom", "Slot": 1, "Status": { "Timestamp": "2017-01-06T23:03:01.935553276Z", "State": "allocated", "Message": "allocated", "ContainerStatus": {} }, "DesiredState": "running" } ]
サービスをオフにして、 node3で再度作成します。
$ sudo docker service create --name testcon --constraint 'node.labels.nodename == node3' --mount type=bind,source=/swarm/volumes/testvol,target=/mnt/testvol ubuntu:latest /bin/touch /mnt/testvol/testfile3.txt 5y99c0bfmc2fywor3lcsvmm9q
現在node3で実行されていることを確認します。
$ sudo docker service ps testcon ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 5p57xyottput3w34r7fclamd9 testcon.1 ubuntu:latest ip-172-31-26-52 Ready Ready 1 seconds ago aniesakdmrdyuq8m2ddn3ga9b \_ testcon.1 ubuntu:latest ip-172-31-26-52 Shutdown Complete 2 seconds ago
その結果、両方のコンテナで作成されたファイルが1つのリポジトリに一緒に配置されていることがわかります。
$ ls -l /swarm/volumes/testvol/ total 0 -rw-r--r-- 1 root root 0 Jan 6 23:59 testfile3.txt -rw-r--r-- 1 root root 0 Jan 6 23:58 testfile1.txt