Установка Zookeeper и настройка кластера на Rocky Linux

Thank you for reading this post, don't forget to subscribe!

Zookeeper — cер­вис-коор­ди­на­тор, кото­рый поз­во­ля­ет обес­пе­чить кон­троль син­хро­ни­за­ции дан­ных. Раз­ра­бо­тан на Java ком­па­ни­ей Apache Software Foundation.

Как пра­ви­ло, Zookeeper исполь­зу­ют для:

Созда­ния рас­пре­де­лен­но­го сер­ве­ра имен.
Опре­де­ле­ния лиде­ра в дру­гих кла­стер­ных системах.
Созда­ния рас­пре­де­лен­ной кон­фи­гу­ра­ции дру­гих при­ло­же­ний (напри­мер, Kafka, ClickHouse).
При­ло­же­ние явля­ет­ся откры­тым и может быть загру­же­но с офи­ци­аль­но­го сай­та.

Архи­тек­тур­но, Zookeeper пред­став­ля­ет кли­ент-сер­вер­ное при­ло­же­ние и вклю­ча­ет в себя сле­ду­ю­щие компоненты:

  1. Кли­ент — узел в кла­сте­ре, кото­рый нахо­дит­ся на свя­зи с сер­ве­ром, посто­ян­но отправ­ляя ему сиг­на­лы о сво­ей рабо­то­спо­соб­но­сти (heartbeat), кото­рый не дол­жен пре­вы­шать опре­де­лен­ное зна­че­ние (опре­де­ля­ет­ся пара­мет­ром tickTime).
  2. Сер­вер — одна из нод кла­сте­ра Zookeeper, кото­рая про­ве­ря­ет состо­я­ние кли­ен­тов и пере­на­прав­ля­ет запро­сы на один из рабо­чих сер­ве­ров (кли­ен­тов).
  3. Лидер — глав­ный сер­вер сре­ди сер­ве­ров кла­сте­ра (ансам­бля). Он отве­ча­ет за все опе­ра­ции записи.
  4. После­до­ва­тель — все сер­ве­ры в ансам­бле, за исклю­че­ни­ем лиде­ра. Они при­ни­ма­ют от послед­не­го инфор­ма­цию на изме­не­ние и запи­сы­ва­ют ее у себя.
  5. Ансамбль — кла­стер из сер­ве­ров Zookeeper. Лидер опре­де­ля­ет­ся при стар­те служб, а если про­ис­хо­дит раз­рыв соеди­не­ния — на осно­ве кво­ру­ма. Поэто­му мини­маль­ное коли­че­ство нод в ансам­бле явля­ет­ся 3-м.

Для сво­ей рабо­ты исполь­зу­ет порты:

При­ло­же­ние по умол­ча­нию рабо­та­ет на сле­ду­ю­щих портах:

Порт Опи­са­ние
2181 Порт для кли­ент­ских подключений.
2888 Репли­ка­ция дан­ных меж­ду нода­ми кластера.
3888 Выбор лиде­ра меж­ду нода­ми кластера.

В каче­стве аль­тер­на­тив выделяют:

  • etcd
  • Consul

Подготовка системы

На всех трех нодах выпол­ня­ем сле­ду­ю­щие действия.

1. Настройка времени

Нам важ­но, что­бы на нодах наше­го кла­сте­ра было оди­на­ко­вое вре­мя. Для это­го уста­но­вим ути­ли­ту chrony:

yum install chrony

Запу­стим ее и раз­ре­шим автозапуск:

systemctl enable chronyd --now

2. Установка OpenJava

Zookeeper раз­ра­бо­тан на Java, поэто­му выпол­ним установку:

yum install java-11-openjdk

Смот­рим вер­сию openjdk:

java -version

Мы долж­ны уви­деть что-то на подобие:

openjdk version "11.0.13" 2021-10-19 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.13+8-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.13+8-LTS, mixed mode, sharing)

Идем даль­ше.

3. Настройка безопасности

Для кор­рект­ной рабо­ты при­ло­же­ния нам нуж­но отклю­чить SELinux и открыть пор­ты в бранд­мау­э­ре. Рас­смот­рим про­цес­сы по очереди.

Отклю­ча­ем SELinux.

Выпол­ним 2 команды:

setenforce 0

sed -i 's/^SELINUX=.*/SELINUX=disabled/g' /etc/selinux/config

Настрой­ка брандмауэра.

Для рабо­ты Zookeeper тре­бу­ет­ся открыть порты:

  • 2181 — для кли­ент­ских подключений.
  • 2888 — репли­ка­ция дан­ных меж­ду нода­ми кластера.
  • 3888 — выбор лиде­ра меж­ду нода­ми кластера.

Для откры­тия пор­тов вводим:

firewall-cmd --permanent --add-port={2181,2888,3888}/tcp

При­ме­ня­ем настройки:

firewall-cmd --reload

4. Установка дополнительных пакетов

Для кор­рект­ной загруз­ки и рас­па­ков­ки архи­ва, нам нуж­но уста­но­вить неко­то­рые ути­ли­ты и обно­вить кор­не­вые сер­ти­фи­ка­ты. Это дела­ет­ся командами:

yum install ca-certificates wget tar nc

update-ca-trust

* где:

  • ca-certificates — набор кор­не­вых сертификатов.
  • wget — ути­ли­та для загруз­ки фай­лов по сети.
  • tar — ути­ли­та для рабо­ты с архивами.
  • nc — сете­вая ути­ли­та, кото­рая счи­ты­ва­ет и запи­сы­ва­ет дан­ные из команд­ной стро­ки. Мы ее будем исполь­зо­вать для отправ­ки команд в zookeeper.

Пере­хо­дим к уста­нов­ке Zookeeper.

Установка, настройка и запуск Zookeeper

Уста­нов­ку с настрой­кой так­же будем делать на всех сер­ве­рах. Так как в репо­зи­то­рии дан­но­го про­грамм­но­го про­дук­та нет, мы долж­ны будем ска­чать архив рели­за с сай­та раз­ра­бот­чи­ка и рас­па­ко­вать его на сер­ве­ре. Запуск при­ло­же­ния будет настро­ен с исполь­зо­ва­ни­ем systemd.

Установка

Как было ска­за­но выше, уста­нов­ка выпол­ня­ет­ся путем рас­па­ков­ки архи­ва, ска­чан­но­го с офи­ци­аль­но­го сай­та. Пере­хо­дим на стра­ни­цу загруз­ки Zookeeper. Кли­ка­ем по ссыл­ке для пере­хо­да к послед­ней вер­сии Zookeeper:

Копи­ру­ем ссыл­ку для загруз­ки архи­ва tar gz:

Исполь­зуя ско­пи­ро­ван­ную ссыл­ку, загру­жа­ем архив на все три сервера:

https://dlcdn.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz

Созда­ем ката­лог для раз­ме­ще­ния zookeeper:

mkdir /opt/zookeeper

Рас­па­ко­вы­ва­ем ска­чан­ный архив:

tar zxvf apache-zookeeper-*-bin.tar.gz -C /opt/zookeeper --strip-components=1

Настройка

Созда­ем допол­ни­тель­ные ката­ло­ги для логов и данных:

mkdir -p /opt/zookeeper/data /var/log/zookeeper

Созда­ем кон­фи­гу­ра­ци­он­ный файл:

vi /opt/zookeeper/conf/zoo.cfg

* где:

  • tickTime — дли­на тика в мил­ли­се­кун­дах. Тик явля­ет­ся базо­вой еди­ни­цей вре­ме­ни в Zookeeper, отно­си­тель­но кото­ро­го ведут­ся дру­гие расчеты.
  • maxSessionTimeout — вре­мя в мил­ли­се­кун­дах, отве­ден­ное для вза­и­мо­дей­ствия сер­ве­ра с клиентом.
  • syncLimit — вре­мя в тиках, в тече­ние кото­ро­го под­клю­чен­ные кли­ен­ты долж­ны син­хро­ни­зи­ро­вать дан­ные. При пре­вы­ше­нии это­го вре­ме­ни, кли­ент будет отброшен.
  • initLimit — коли­че­ство вре­ме­ни в тиках, кото­рое отве­де­но на под­клю­че­ние к сер­ве­ру и выпол­не­ние син­хро­ни­за­ции с ним.
  • autopurge.purgeInterval — ука­зы­ва­ем интер­вал в часах для авто­ма­ти­че­ской чистки.
  • autopurge.snapRetainCount — коли­че­ство послед­них сним­ков, кото­рые нуж­но сохра­нить при выпол­не­нии авто­ма­ти­че­ской чистки.
    snapCount — коли­че­ство запи­сей в жур­на­ле тран­зак­ций, после кото­ро­го будет запу­щен сни­мок с обну­ле­ни­ем журнала.
  • clientPort — порт, на кото­ром наше при­ло­же­ние будет слу­шать запро­сы клиентов.
  • maxClientCnxns — чис­ло одно­вре­мен­ных соеди­не­ний, кото­рое может сде­лать клиент.
  • 4lw.commands.whitelist — спи­сок раз­ре­шен­ных команд через запя­тую. Дан­ные коман­ды мож­но будет отпра­вить через telnet. В дан­ном при­ме­ре это коман­да для отоб­ра­же­ния ста­ту­са рабо­ты приложения.
  • dataDir — путь для хра­не­ния сним­ков жур­на­лов базы данных.
  • dataLogDir — путь, по кото­ро­му zookeeper будет хра­нить жур­на­лы тран­зак­ций. Если не ука­зан, то хра­нить­ся будет в dataDir.

Настройка запуска

После уста­нов­ки при­ло­же­ния, настро­им его запуск в каче­стве сервиса.

Созда­ем слу­жеб­ную учет­ную запись, под кото­рой будет рабо­тать zookeeper:

useradd -r -c 'Zookeeper service' zookeeper

Зада­дим вла­дель­цем создан­но­го поль­зо­ва­те­ля для всех ката­ло­гов, кото­рые мы создали:

chown -R zookeeper:zookeeper /opt/zookeeper /var/log/zookeeper

Созда­ем файл для юни­та в systemd:

vi /etc/systemd/system/zookeeper.service

Пере­чи­ты­ва­ем кон­фи­гу­ра­цию systemd:

systemctl daemon-reload

Раз­ре­ша­ем авто­за­пуск и стра­зу стар­ту­ем сервис:

systemctl enable zookeeper --now

Про­ве­ря­ем, что сер­вис запустился:

systemctl status zookeeper

Так­же мож­но убе­дить­ся, что при­ло­же­ние слу­ша­ет на пор­ту 2181:

ss -tunlp | grep :2181

Мы долж­ны уви­деть что-то на подобие:

tcp   LISTEN 0      50       *:2181     *:*    users:(("java",pid=2945,fd=51))

Настройка кластера

И так, мы уста­но­ви­ли и запу­сти­ли при­ло­же­ние, но сей­час оно рабо­та­ет отдель­но на наших сер­ве­рах. Сде­ла­ем кластер.

На всех сер­ве­рах откры­ва­ем кон­фи­гу­ра­ци­он­ный файл:

vi /opt/zookeeper/conf/zoo.cfg

Доба­вим строку:


dynamicConfigFile=/opt/zookeeper/conf/zoo.cfg.dynamic

dynamicConfigFile ука­зы­ва­ет путь до дина­ми­че­ско­го фай­ла кон­фи­гу­ра­ции, в кото­ром могут менять­ся пара­мет­ры "на лету".

Теперь созда­дим файл дина­ми­че­ской конфигурации:

vi /opt/zookeeper/conf/zoo.cfg.dynamic

* как и гово­ри­лось в нача­ле, у нас в кла­сте­ре будет три сер­ве­ра. В дан­ном фай­ле мы их пере­чис­ля­ем с при­сва­и­ва­ни­ем поряд­ко­вых номеров.

Теперь на каж­дом сер­ве­ре созда­ем свой файл со сво­им поряд­ко­вым номером.

а) на сер­ве­ре 1:

vi /opt/zookeeper/data/myid
1

б) на сер­ве­ре 2:

vi /opt/zookeeper/data/myid
2

в) на сер­ве­ре 3:

vi /opt/zookeeper/data/myid
3

Настрой­ка завершена.

Пере­за­пус­ка­ем наш сер­вис на всех серверах:

systemctl restart zookeeper

Для про­вер­ки состо­я­ния кла­сте­ра вво­дим коман­ды на всех нодах:

echo "stat" | nc localhost 2181

На двух из них мы долж­ны увидеть:


Mode: follower

На одной:


Mode: leader