Использование GlusterFS с кластером Docker swarm

в 13:18, , рубрики: devops, docker, glusterfs, Блог компании centos-admin.ru, Настройка Linux, Серверное администрирование, системное администрирование

Использование GlusterFS с кластером Docker swarm - 1

В этой статье я описал создание в 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 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.

Поставим метки на узлы swarm:

$ 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

В итоге мы должны увидеть, что созданные в обоих контейнерах файлы находятся вместе в одном хранилище:

$ 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

Автор: Centos-admin.ru

Источник

Поделиться

* - обязательные к заполнению поля