GlusterFS с кластером Docker swarm
Здесь мы рассмотрим как создать кластер из трех нод Docker Swarm с подключить ко всем нодам общий реплицируемый том на GlusterFS.
Для созданий кластера из Docker хостов, используется Docker Swarm. Особенность в том, что если контейнер А с используемым им томом voltdata запущен на ноде1, то все внесенные изменения сохраняются локально на ноде1. В случае выключения контейнера А, а потом запуска например на ноде3, и подключении тома voldata — данных на хранилище не будет, и не будет тех внесенных изменений, которые были сделаны на ноде1.
Как решить это ограничение?
Решения могут быть разными, расмотрим решение с использованием репликацию томов с GlusterFS, это обеспечить постоянную доступность данных с любой из нод. Не смотря на это имя тома на каждом Docker хосте будет локальным.
В примере использованы три инстанса AWS EC2, у каждого по тому EBS.
Настройка серверов
На всех серверах установим Ubuntu 16.04
Внесем изменения в /etc/hosts укажем имена нод
1 2 3 |
XX.XX.XX.XX node_1 XX.XX.XX.XX node_2 XX.XX.XX.XX node_3 |
Обновим пакеты и ОС
1 2 |
sudo apt update sudo apt upgrade |
Перезагрузим сервера и установим нужные пакет для всех нод
1 2 |
sudo apt install -y docker.io sudo apt install -y glusterfs-server |
выполним запуск сервисов
1 2 |
sudo systemctl start glusterfs-server sudo systemctl start docker |
Далее создаем хранилище GlusterFS
1 |
sudo mkdir -p /gluster/data /swarm/volumes |
Настройка GlusterFS
Выполним подготовку файловой системы GlusterFS на всех нодах
1 2 |
sudo mkfs.xfs /dev/xvdb sudo mount /dev/xvdb /gluster/data/ |
На node_1
1 2 3 4 |
$ sudo gluster peer probe node_2 peer probe: success. $ sudo gluster peer probe node_3 peer probe: success. |
Создание реплицируемого томя
sudo gluster volume create swarm-vols replica 3 node_1:/gluster/data node_2:/gluster/data node_3:/gluster/data force
Дадим разрешения на монтирование только с локального хоста
1 |
sudo gluster volume set swarm-vols auth.allow 127.0.0.1 |
Выполним запуск тома
1 |
sudo gluster volume start swarm-vols |
Монтируем его для каждой ноды
1 |
sudo mount.glusterfs localhost:/swarm-vols /swarm/volumes |
Настройка Docker swarm
Создадим управляющий узел и два рабочих
1 2 3 4 5 6 7 |
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.32.24.235:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. |
Для рабочих узлов получаем токен
1 2 3 4 5 |
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.32.24.235:2377 |
На двух рабочих узлах введем команду
sudo docker swarm join --token SWMTKN-1-697xeeiei6wsnsr29ult7num899o5febad143ellqx7mt8avwn-1m7wlh59vunohq45x3g075r2h 172.32.24.235:2377
Выполним проверку swarm кластера
1 2 3 4 5 |
sudo docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 6he3dgbanee20h7lul705q196 ip-172-32-27-191 Ready Active 82f5ud4z97q7q74bz9ycwclnd * ip-172-32-24-235 Ready Active Leader c7daeowfoyfua2hy0ueiznbjo ip-172-32-26-55 Ready Active |
Испытание
Выполним создание меток для node_1 и node_3, и создание контейнера node_1. Затем выключим его, и создадим на node_3, смонтировав такие же томаи проверим остались файлы, которые были созданы при работе на node_1
Установка меток
1 2 |
sudo docker node update --label-add nodename=node1 ip-172-32-24-235 sudo docker node update --label-add nodename=node3 ip-172-32-26-55 |
Проверяем
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
sudo docker node inspect --pretty ip-172-32-26-55 ID: c7daeowfoyfua2hy0ueiznbjo Labels: - nodename = node_3 Hostname: ip-172-32-26-55 Joined at: 2017-02-05 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 |
Создаем докер на node_1 для тестирования общего хранилища
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
Проверяем
1 2 3 |
sudo docker service ls ID NAME REPLICAS IMAGE COMMAND duvqo3btdrrl testcon 0/1 busybox /bin/bash |
Проверим, что запущен на первой ноде
1 2 3 4 5 6 |
sudo docker service ps testcon ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 6nw6sm8sak512x24bty7fwxwz testcon.1 ubuntu:latest ip-172-32-24-235 Ready Ready 1 seconds ago 6ctzew4b3rmpkf4barkp1idhx \_ testcon.1 ubuntu:latest ip-172-32-24-235 Shutdown Complete 1 seconds ago |
Проверим монтирование томов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
$ sudo docker inspect testcon [ { "ID": "8lnpmwcv56xwmwavu3gc2aay8", "Version": { "Index": 26 }, "CreatedAt": "2017-02-05T23:03:01.93363267Z", "UpdatedAt": "2017-02-05T23: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 == node_1" ] } }, "ServiceID": "duvqo3btdrrlwf61g3bu5uaom", "Slot": 1, "Status": { "Timestamp": "2017-02-05T23:03:01.935553276Z", "State": "allocated", "Message": "allocated", "ContainerStatus": {} }, "DesiredState": "running" } ] |
Выключаем и создаем на третьей ноде
1 |
sudo docker service create --name testcon --constraint 'node.labels.nodename == node_3' --mount type=bind,source=/swarm/volumes/testvol,target=/mnt/testvol ubuntu:latest /bin/touch /mnt/testvol/testfile3.txt |
Проверяем где запущен
1 2 3 4 |
sudo docker service ps testcon ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 5p57xyottput3w34r7fclamd9 testcon.1 ubuntu:latest ip-172-32-26-55 Ready Ready 1 seconds ago aniesakdmrdyuq8m2ddn3ga9b \_ testcon.1 ubuntu:latest ip-172-32-26-55 Shutdown Complete 2 seconds ago |
В результате мы увидим, что файлы созданные в разных контейнерах, хранятся в одном хранилище
1 2 3 4 |
ls -l /swarm/volumes/testvol/ total 0 -rw-r--r-- 1 root root 0 Feb 5 23:59 testfile3.txt -rw-r--r-- 1 root root 0 Feb 5 23:58 testfile1.txt |
Нужна установка, настройка или поддержка docker? Обращайтесь [email protected]