GlusterFS Docker: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
 
(не показано 11 промежуточных версий этого же участника)
Строка 1: Строка 1:
  +
[[Категория:Linux]]
  +
[[Категория:GlusterFS]]
  +
[[Категория:Docker]]
  +
 
=GlusterFS и Docker=
 
=GlusterFS и Docker=
 
Тут краткое описание о "докеризации" GlusterFS
 
Тут краткое описание о "докеризации" GlusterFS
   
 
==Постановка Задачи==
 
==Постановка Задачи==
Есть 3 хардварных ноды, на каждой из которых будет запущено приложение. Для организации общего хранилища требуется настроить GlusterFS. Требования от заказчика - все процессы запускать в докер-еонтейнерах
+
Есть 3 хардварных ноды, на каждой из которых будет запущено приложение. Для организации общего хранилища требуется настроить GlusterFS. Требования от заказчика - все процессы запускать в докер-контейнерах
   
 
* Базовая система - CentOS 7
 
* Базовая система - CentOS 7
 
* Docker 1.10
 
* Docker 1.10
 
* ??
 
* ??
  +
  +
Имеется три ноды (именование сквозное потому номера идут не с 1)
  +
* node-3
  +
* node-4
  +
* node-6
  +
На кадой из них установлен CentOS 7
  +
<PRE>
  +
# cat /etc/redhat-release
  +
CentOS Linux release 7.2.1511 (Core)
  +
</PRE>
  +
  +
Хранилище будет подмонтированно на всех 3-х нодах.
   
 
==Устновка Docker==
 
==Устновка Docker==
Строка 113: Строка 129:
 
Если это не сделать, то возникает проблема с хождением через nat да и в целом конфигурация выглядит логично.
 
Если это не сделать, то возникает проблема с хождением через nat да и в целом конфигурация выглядит логично.
 
* Проброс портов -p ... - список портов (что бы не заморачиваться) взят с официальной документации (http://www.gluster.org/community/documentation/index.php/Basic_Gluster_Troubleshooting)
 
* Проброс портов -p ... - список портов (что бы не заморачиваться) взят с официальной документации (http://www.gluster.org/community/documentation/index.php/Basic_Gluster_Troubleshooting)
  +
===Насройка GlusterFS===
  +
Базовую настройку производим изнутри контейнеров
  +
<BR>
  +
Для подключения к контейнеру
  +
* Уточнить ID контейнера
  +
<PRE>
  +
docker ps
  +
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  +
b9ebafb93e82 gluster/gluster-centos "/usr/sbin/init" 21 hours ago Up 5 hours 245/tcp, 443/tcp, 2049/tcp, 6010-6012/tcp, 0.0.0.0:111->111/tcp, 8080/tcp, 38465-38466/tcp, 0.0.0.0:24007-24050->24007-24050/tcp, 38468-38469/tcp, 0.0.0.0:49152-49155->49152-49155/tcp, 49156-49162/tcp, 0.0.0.0:10022->22/tcp desperate_raman
  +
</PRE>
  +
* Подключиться к контейнеру
  +
<PRE>
  +
docker exec -it b9ebafb93e82 /bin/bash
  +
</PRE>
   
  +
Далее внутри контейнера доступна утилита gluster
  +
<BR>
  +
Создаем кластер:
  +
<PRE>
  +
gluster peer probe node-5
  +
gluster peer probe node-4
  +
</PRE>
  +
  +
Проверить результат:
  +
<PRE>
  +
# gluster peer status
  +
Number of Peers: 2
  +
  +
Hostname: node-4
  +
Uuid: c82db9d5-230f-4d79-a466-c62e0b82d74d
  +
State: Peer in Cluster (Connected)
  +
  +
Hostname: node-5
  +
Uuid: 4038195f-d9e8-4fcd-b7ba-d9a66e6d3518
  +
State: Peer in Cluster (Connected)
  +
</PRE>
  +
2 ноды (плюс третья - та на которой выполняется команда) - как и ожидалось.
  +
  +
Следующий шаг - создание volume
  +
<PRE>
  +
gluster volume create replicated_data replica 3 transport tcp node-4:/gluster_storage node-5:/gluster_storage node-6:/gluster_storage force
  +
</PRE>
  +
В этой команде параметры означают следующее:
  +
* replicated_data - имя volume - может быть любым
  +
* replica - тип volume, в нашем случае - это аналог "зеркала" RAID1 (другие типы нас в данной момент не интересуют - наша цель отказоустойчивость)
  +
* 3 - "replication factor" - количество копий. У нас - по одной копии на ноду, хотя при наличии нескольких физических дисков можно "размазать" данные и более по-другому, например в соотношении 2-2-1 или еще как-то :)
  +
* tcp - протокол который использовать для этого volume (кстати надо уточнить - только для репликации или и для монтирования?)
  +
* node-4:/gluster_storage node-5:/gluster_storage node-6:/gluster_storage - список нод и директорий которые будут хранить данные. В нашем случае - это проброшенная внутрь контейнера директория с хост-системы, таким образом все данные будут храниться на хост-системе.
  +
* force - принудительное создание (папки, а не выделеные диски - не то о чем мечтает GlusterFS но force заставляет работать с папками)
  +
  +
Старт volume
  +
<PRE>
  +
gluster volume start replicated_data
  +
</PRE>
  +
  +
Проверить статус: (вроде-бы все выглядит нормально)
  +
<PRE>
  +
gluster volume status
  +
Status of volume: replicated_data
  +
Gluster process TCP Port RDMA Port Online Pid
  +
------------------------------------------------------------------------------
  +
Brick node-4:/gluster_storage 49152 0 Y 399
  +
Brick node-5:/gluster_storage 49152 0 Y 398
  +
Brick node-6:/gluster_storage 49152 0 Y 398
  +
NFS Server on localhost N/A N/A N N/A
  +
Self-heal Daemon on localhost N/A N/A Y 393
  +
NFS Server on node-5 N/A N/A N N/A
  +
Self-heal Daemon on node-5 N/A N/A Y 393
  +
NFS Server on node-4 N/A N/A N N/A
  +
Self-heal Daemon on node-4 N/A N/A Y 416
  +
  +
Task Status of Volume replicated_data
  +
------------------------------------------------------------------------------
  +
There are no active volume tasks
  +
</PRE>
  +
<PRE>
  +
gluster volume info
  +
  +
Volume Name: replicated_data
  +
Type: Replicate
  +
Volume ID: 6462ffa2-7378-4d5f-a302-a2734fbcfcaa
  +
Status: Started
  +
Number of Bricks: 1 x 3 = 3
  +
Transport-type: tcp
  +
Bricks:
  +
Brick1: node-4:/gluster_storage
  +
Brick2: node-5:/gluster_storage
  +
Brick3: node-6:/gluster_storage
  +
Options Reconfigured:
  +
performance.readdir-ahead: on
  +
</PRE>
  +
==Подключение volumе к хост-системе==
  +
/etc/rc.local
  +
<PRE>
  +
mount.glusterfs $(hostname):/replicated_data /www-data/
  +
</PRE>
  +
Эта команда подключит volume replicated_data в www-data. <BR>
  +
Естественно что никакого нового места такое подключение не принесет - но данные записаные в /www-data будут копироваться на все три ноды кластера
  +
<PRE>
  +
# df -h
  +
Filesystem Size Used Avail Use% Mounted on
  +
/dev/mapper/centos-root 41G 4.9G 36G 13% /
  +
devtmpfs 1.9G 0 1.9G 0% /dev
  +
tmpfs 1.9G 0 1.9G 0% /dev/shm
  +
tmpfs 1.9G 8.4M 1.9G 1% /run
  +
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
  +
/dev/mapper/centos-home 20G 33M 20G 1% /home
  +
/dev/sda1 497M 164M 334M 33% /boot
  +
tmpfs 380M 0 380M 0% /run/user/0
  +
node-6:/replicated_data 41G 4.9G 36G 13% /www-data
  +
[root@node-6 ~]#
  +
</PRE>
  +
  +
==Известные проблемы==
  +
* https://joejulian.name/blog/glusterfs-path-or-a-prefix-of-it-is-already-part-of-a-volume/
  +
  +
  +
Starting with GlusterFS 3.3, one change has been the check to see if a directory (or any of it's ancestors) is already part of a volume. This is causing many support questions in #gluster.
  +
<BR>
  +
This was implemented because if you remove a brick from a volume and continue to use the volume, you can get file into a state where re-adding a former brick can cause all sort of problems, many of which can result in data loss.
  +
<BR>
  +
If you're going to reuse a brick, make sure you know what you're doing.
  +
<BR>
  +
The Solution
  +
<BR>
  +
For the directory (or any parent directories) that was formerly part of a volume, simply:
  +
Don't worry if it says that the attribute does not exist. As long as it doesn't exist, you're in good shape.
  +
  +
Finally, restart glusterd to ensure it's not "remembering" the old bricks.
  +
  +
See the bugzilla entry for more details and see Jeff Darcy's article for more information about how GlusterFS uses extended attributes.
  +
  +
  +
  +
<PRE>
  +
setfattr -x trusted.glusterfs.volume-id $brick_path
  +
setfattr -x trusted.gfid $brick_path
  +
rm -rf $brick_path/.glusterfs
  +
</PRE>
 
==Ссылки==
 
==Ссылки==
 
* http://website-humblec.rhcloud.com/building-glusterfs-in-a-docker-container/
 
* http://website-humblec.rhcloud.com/building-glusterfs-in-a-docker-container/
 
* http://andrey.org/glusterfs/
 
* http://andrey.org/glusterfs/
 
* http://sysadm.pp.ua/linux/glusterfs-setup.html
 
* http://sysadm.pp.ua/linux/glusterfs-setup.html
  +
* http://www.gluster.org/community/documentation/index.php/Basic_Gluster_Troubleshooting

Текущая версия на 13:12, 27 сентября 2016


GlusterFS и Docker

Тут краткое описание о "докеризации" GlusterFS

Постановка Задачи

Есть 3 хардварных ноды, на каждой из которых будет запущено приложение. Для организации общего хранилища требуется настроить GlusterFS. Требования от заказчика - все процессы запускать в докер-контейнерах

  • Базовая система - CentOS 7
  • Docker 1.10
  • ??

Имеется три ноды (именование сквозное потому номера идут не с 1)

  • node-3
  • node-4
  • node-6

На кадой из них установлен CentOS 7

# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)

Хранилище будет подмонтированно на всех 3-х нодах.

Устновка Docker

Установка докера хорошо описана в документации: https://docs.docker.com/engine/installation/linux/centos/

# rpm -qa | grep docker
docker-engine-selinux-1.10.2-1.el7.centos.noarch
docker-engine-1.10.2-1.el7.centos.x86_64

Включить в автозагрузку

# systemctl enable docker

Запустить:

# service docker start

GlusterFS в докере

Существует пре-собранный образ (а точнее 2 образа) которые содержат все что нужно для GlusterFS.
Однако к минусам этих образов я отнесу то, что на хост-системе Centos 6.5 (в том числе и со свежим ядром из elrepo) эти образа не работают. Проблема в том что для systemd который работает внутри нужны "капабилитез" (https://www.opennet.ru/man.shtml?topic=capabilities) котоые внутрь контейнера не пробрасываются. Беглый просмотр образов наводит на мысль что исправить это можно, нагородив костылей вместо использования родного для Centos 7 systemd однако практического смысла в этом нет, а на хост-стстеме с Centos 7 проблема не воспроизводится.

Установка

Установка предельно проста (потому мы и используме докер!)

  • Скачать образ
# docker pull gluster/gluster-centos
  • Запустить контейнер
#!/bin/bash

docker run \
--privileged \
-d \
-p 10022:22 \
-p 111:111 \
-p 24007:24007 \
-p 24008:24008 \
-p 24009:24009 \
-p 24010:24010 \
-p 24011:24011 \
-p 24012:24012 \
-p 24013:24013 \
-p 24014:24014 \
-p 24015:24015 \
-p 24016:24016 \
-p 24017:24017 \
-p 24018:24018 \
-p 24019:24019 \
-p 24020:24020 \
-p 24021:24021 \
-p 24022:24022 \
-p 24023:24023 \
-p 24024:24024 \
-p 24025:24025 \
-p 24026:24026 \
-p 24027:24027 \
-p 24028:24028 \
-p 24029:24029 \
-p 24030:24030 \
-p 24031:24031 \
-p 24032:24032 \
-p 24033:24033 \
-p 24034:24034 \
-p 24035:24035 \
-p 24036:24036 \
-p 24037:24037 \
-p 24038:24038 \
-p 24039:24039 \
-p 24040:24040 \
-p 24041:24041 \
-p 24042:24042 \
-p 24043:24043 \
-p 24044:24044 \
-p 24045:24045 \
-p 24046:24046 \
-p 24047:24047 \
-p 24048:24048 \
-p 24049:24049 \
-p 24050:24050 \
-p 49152:49152 \
-p 49153:49153 \
-p 49154:49154 \
-p 49155:49155 \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /gluster_file:/var/lib/glusterd \
-v /gluster_storage:/gluster_storage \
-v /etc/hosts:/etc/hosts \

На параметрах запуска остановлюсь подробнее:

  • --privileged : For systemd to run without crashing it is necessary to run the container in the privileged mode since systemd requires CAP_SYS_ADMIN capability.
  • -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ - проброс sysfs
  • -v /gluster_file:/var/lib/glusterd - вся конфигурация GlusterFS будет храниться на хост системе (gluster_file), для того что бы контейнер можно было смело пересоздавать или обновлять. По-хорошему никакие данные не следует хранить внутри контейнера.
  • -v /gluster_storage:/gluster_storage: Мортируем внутрь контейнера папку которая будет использоваться для данных
  • -v /etc/hosts:/etc/hosts - для простоты работы вся информация вноситься в хосты что бы упростить конфигурацию

На этом моменте нужно остановиться подробнее - тут существует тонкость.
Напомню, в нашей схеме учавствуют три хоста (host-4, host-5 и host-6). На каждом из них создаем нужные записи, причем информация о самом хосте указывает на localhost. Например, для host-6:


192.168.56.101 node-4
127.0.0.1    node-6
192.168.56.102 node-5

Если это не сделать, то возникает проблема с хождением через nat да и в целом конфигурация выглядит логично.

Насройка GlusterFS

Базовую настройку производим изнутри контейнеров
Для подключения к контейнеру

  • Уточнить ID контейнера
 docker ps
CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS                                                                                                                                                                                                                             NAMES
b9ebafb93e82        gluster/gluster-centos   "/usr/sbin/init"    21 hours ago        Up 5 hours          245/tcp, 443/tcp, 2049/tcp, 6010-6012/tcp, 0.0.0.0:111->111/tcp, 8080/tcp, 38465-38466/tcp, 0.0.0.0:24007-24050->24007-24050/tcp, 38468-38469/tcp, 0.0.0.0:49152-49155->49152-49155/tcp, 49156-49162/tcp, 0.0.0.0:10022->22/tcp   desperate_raman
  • Подключиться к контейнеру
docker exec -it b9ebafb93e82 /bin/bash

Далее внутри контейнера доступна утилита gluster
Создаем кластер:

gluster peer probe  node-5
gluster peer probe  node-4

Проверить результат:

# gluster peer status
Number of Peers: 2

Hostname: node-4
Uuid: c82db9d5-230f-4d79-a466-c62e0b82d74d
State: Peer in Cluster (Connected)

Hostname: node-5
Uuid: 4038195f-d9e8-4fcd-b7ba-d9a66e6d3518
State: Peer in Cluster (Connected)

2 ноды (плюс третья - та на которой выполняется команда) - как и ожидалось.

Следующий шаг - создание volume

gluster volume create replicated_data  replica 3 transport tcp node-4:/gluster_storage node-5:/gluster_storage node-6:/gluster_storage force

В этой команде параметры означают следующее:

  • replicated_data - имя volume - может быть любым
  • replica - тип volume, в нашем случае - это аналог "зеркала" RAID1 (другие типы нас в данной момент не интересуют - наша цель отказоустойчивость)
  • 3 - "replication factor" - количество копий. У нас - по одной копии на ноду, хотя при наличии нескольких физических дисков можно "размазать" данные и более по-другому, например в соотношении 2-2-1 или еще как-то :)
  • tcp - протокол который использовать для этого volume (кстати надо уточнить - только для репликации или и для монтирования?)
  • node-4:/gluster_storage node-5:/gluster_storage node-6:/gluster_storage - список нод и директорий которые будут хранить данные. В нашем случае - это проброшенная внутрь контейнера директория с хост-системы, таким образом все данные будут храниться на хост-системе.
  • force - принудительное создание (папки, а не выделеные диски - не то о чем мечтает GlusterFS но force заставляет работать с папками)

Старт volume

gluster volume start replicated_data

Проверить статус: (вроде-бы все выглядит нормально)

 gluster volume status
Status of volume: replicated_data
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick node-4:/gluster_storage               49152     0          Y       399
Brick node-5:/gluster_storage               49152     0          Y       398
Brick node-6:/gluster_storage               49152     0          Y       398
NFS Server on localhost                     N/A       N/A        N       N/A
Self-heal Daemon on localhost               N/A       N/A        Y       393
NFS Server on node-5                        N/A       N/A        N       N/A
Self-heal Daemon on node-5                  N/A       N/A        Y       393
NFS Server on node-4                        N/A       N/A        N       N/A
Self-heal Daemon on node-4                  N/A       N/A        Y       416

Task Status of Volume replicated_data
------------------------------------------------------------------------------
There are no active volume tasks
gluster volume info

Volume Name: replicated_data
Type: Replicate
Volume ID: 6462ffa2-7378-4d5f-a302-a2734fbcfcaa
Status: Started
Number of Bricks: 1 x 3 = 3
Transport-type: tcp
Bricks:
Brick1: node-4:/gluster_storage
Brick2: node-5:/gluster_storage
Brick3: node-6:/gluster_storage
Options Reconfigured:
performance.readdir-ahead: on

Подключение volumе к хост-системе

/etc/rc.local

mount.glusterfs $(hostname):/replicated_data /www-data/

Эта команда подключит volume replicated_data в www-data.
Естественно что никакого нового места такое подключение не принесет - но данные записаные в /www-data будут копироваться на все три ноды кластера

# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   41G  4.9G   36G  13% /
devtmpfs                 1.9G     0  1.9G   0% /dev
tmpfs                    1.9G     0  1.9G   0% /dev/shm
tmpfs                    1.9G  8.4M  1.9G   1% /run
tmpfs                    1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/mapper/centos-home   20G   33M   20G   1% /home
/dev/sda1                497M  164M  334M  33% /boot
tmpfs                    380M     0  380M   0% /run/user/0
node-6:/replicated_data   41G  4.9G   36G  13% /www-data
[root@node-6 ~]#

Известные проблемы


Starting with GlusterFS 3.3, one change has been the check to see if a directory (or any of it's ancestors) is already part of a volume. This is causing many support questions in #gluster.
This was implemented because if you remove a brick from a volume and continue to use the volume, you can get file into a state where re-adding a former brick can cause all sort of problems, many of which can result in data loss.
If you're going to reuse a brick, make sure you know what you're doing.
The Solution
For the directory (or any parent directories) that was formerly part of a volume, simply: Don't worry if it says that the attribute does not exist. As long as it doesn't exist, you're in good shape.

Finally, restart glusterd to ensure it's not "remembering" the old bricks.

See the bugzilla entry for more details and see Jeff Darcy's article for more information about how GlusterFS uses extended attributes.


setfattr -x trusted.glusterfs.volume-id $brick_path
setfattr -x trusted.gfid $brick_path
rm -rf $brick_path/.glusterfs

Ссылки