Використання GlusterFS з кластером Docker swarm


У цій статті я описав створення в AWS складається з трьох нод кластера Docker Swarm і підключення до нього спільного для всіх нод реплицируемого тома GlusterFS.
Введення
Режим Docker Swarm використовується для створення кластера Docker-хостів. При цьому, якщо контейнер A з підключеним до нього іменованим томом voldata запущений на node1, всі зміни voldata будуть збережені локально на node1. Якщо контейнер A буде вимкнений і трапиться так, що він знову запуститься, скажімо, на node3, при підключенні тома voldata це сховище виявиться порожнім і не буде містити змін, зроблених на node1.
Як це обійти?
Один із шляхів вирішення проблеми — використовувати GlusterFS для реплікації томів, що дозволить зробити дані доступними для всіх мод в будь-який час. При цьому для кожного Docker-хоста іменовані тома залишаться локальними.
Для виконання цієї вправи я використовував три AWS EC2-инстанса, до кожного з яких було підключено по одному EBS-того.
Підготовка серверів
В якості ОС будемо використовувати 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 create volume swarm-vols replica 3 node1:/gluster/data node2:/gluster/data node3:/gluster/data force
create volume: swarm-vols: success: please start the volume to access data

Дозволимо монтування тільки з localhost:
$ sudo gluster volume set swarm-vols аутентифікації.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.
Поставимо підписи на вузли swarm:
$ sudo docker node update --label-add вузла=node1 ip-172-31-24-234
ip-172-31-24-234
$ sudo docker node update --label-add вузла=node3 ip-172-31-26-52
ip-172-31-26-52

Перевіримо мітки:
$ sudo docker node inspect --pretty ip-172-31-26-52
ID: c7daeowfoyfua2hy0ueiznbjo
Labels:
- вузла = 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.вузла == 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.93363267 Z",
"UpdatedAt": "2017-01-06T23:03:01.935557744 Z",
"Spec": {
"ContainerSpec": {
"Image": "busybox",
"Args": [
"/bin/bash"
],
"Mounts": [
{
"Type": "bind",
"Джерело": "/swarm/volumes/testvol",
"Target": "/mnt/testvol"
}
]
},
"Resources": {
"Limits": {},
"Reservations": {}
},
"RestartPolicy": {
"Condition": "any",
"MaxAttempts": 0
},
"Placement": {
"Constraints": [
"вузла == node1"
]
}
},
"ServiceID": "duvqo3btdrrlwf61g3bu5uaom",
"Slot": 1,
"Status": {
"Timestamp": "2017-01-06T23:03:01.935553276 Z",
"State": "allocated",
"Message": "allocated",
"ContainerStatus": {}
},
"DesiredState": "running"
}
]

Вимкнемо сервіс і створимо його заново на node3:
$ sudo docker service create --name testcon --constraint 'node.labels.вузла == 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

У підсумку ми повинні побачити, що створені в обох контейнерах файли знаходяться разом в одному сховищі:
$ 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

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.