add: keepalived (-2-)

This commit is contained in:
Sergei Erjemin 2025-01-02 16:21:02 +03:00
parent 02c8e7d9da
commit 6132c774c3

View File

@ -573,9 +573,9 @@ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin kub
#### Установка CRI (Container Runtime Interface #### Установка CRI (Container Runtime Interface
Так же нам надо **на каждый узел** установить `cri-dockerd` -- демон, который позволяет Kubernetes использовать Так же нам надо **на каждый узел** установить `cri-dockerd` демон, который позволяет Kubernetes использовать
Docker в качестве контейнерного рантайма. Начиная с версии 1.20, Kubernetes прекратил прямую поддержку Docker Docker в качестве контейнерного рантайма. Начиная с версии 1.20, Kubernetes прекратил прямую поддержку Docker
и для взаимодействия появился `cri-dockerd` -- интерфейс Container Runtime Interface (CRI) для Docker, и для взаимодействия появился `cri-dockerd` интерфейс Container Runtime Interface (CRI) для Docker,
выступающий в роли моста между Kubernetes и Docker. Он позволяет Kubernetes управлять контейнерами. выступающий в роли моста между Kubernetes и Docker. Он позволяет Kubernetes управлять контейнерами.
Найти самый свежий релиз `cri-dockerd` можно на [странице релизов](https://github.com/Mirantis/cri-dockerd/releases). Найти самый свежий релиз `cri-dockerd` можно на [странице релизов](https://github.com/Mirantis/cri-dockerd/releases).
@ -629,29 +629,29 @@ KillMode=process
WantedBy=multi-user.target WantedBy=multi-user.target
``` ```
Где: Где:
* [Unit] -- Описывает службу. * [Unit] Описывает службу.
* `Description` -- Описание службы. * `Description` Описание службы.
* `Documentation` -- Ссылка на документацию. * `Documentation` Ссылка на документацию.
* `After` -- Указывает, что служба должна быть запущена после указанных служб. * `After` Указывает, что служба должна быть запущена после указанных служб.
* `Wants` -- Указывает, что служба требует наличия указанных служб. * `Wants` Указывает, что служба требует наличия указанных служб.
* `Requires` -- Указывает зависимость от сокета `cri-docker.socket`. * `Requires` Указывает зависимость от сокета `cri-docker.socket`.
* [Service] -- Конфигурация службы. * [Service] Конфигурация службы.
* `Type` -- Определяет тип службы. * `Type` Определяет тип службы.
* `ExecStart` -- Указывает команду, которая будет запущена при старте службы. * `ExecStart` Указывает команду, которая будет запущена при старте службы.
* `ExecReload` -- Указывает команду, которая будет запущена при перезагрузке службы. * `ExecReload` Указывает команду, которая будет запущена при перезагрузке службы.
* `TimeoutSec` -- Устанавливает время ожидания завершения службы. * `TimeoutSec` Устанавливает время ожидания завершения службы.
* `RestartSec` -- Устанавливает время между перезапусками службы. * `RestartSec` Устанавливает время между перезапусками службы.
* `Restart` -- Указывает, как ведет себя сервис в случае ошибки. `always` -- перезапускать всегда. * `Restart` Указывает, как ведет себя сервис в случае ошибки. `always` перезапускать всегда.
* `StartLimitBurst` -- Устанавливает количество попыток запуска службы. * `StartLimitBurst` Устанавливает количество попыток запуска службы.
* `StartLimitInterval` -- Устанавливает интервал между попытками запуска службы. * `StartLimitInterval` Устанавливает интервал между попытками запуска службы.
* `LimitNOFILE` -- Устанавливает максимальное количество открытых файлов. `infinity` -- неограничено. * `LimitNOFILE` Устанавливает максимальное количество открытых файлов. `infinity` неограничено.
* `LimitNPROC` -- Устанавливает максимальное количество процессов. * `LimitNPROC` Устанавливает максимальное количество процессов.
* `LimitCORE` -- Устанавливает максимальный размер ядра. * `LimitCORE` Устанавливает максимальный размер ядра.
* `TasksMax` -- Устанавливает максимальное количество задач. * `TasksMax` Устанавливает максимальное количество задач.
* `Delegate` -- Указывает, что служба может делегировать свои привилегии. * `Delegate` Указывает, что служба может делегировать свои привилегии.
* `KillMode` -- Устанавливает режим завершения процесса. * `KillMode` Устанавливает режим завершения процесса.
* [Install] -- Указывает, когда и как служба должна быть активирована. * [Install] Указывает, когда и как служба должна быть активирована.
* `WantedBy` -- Указывает, что служба должна быть активирована вместе с ёmulti-user.targetё. * `WantedBy` Указывает, что служба должна быть активирована вместе с ёmulti-user.targetё.
Создадим конфигурацию сокета `cri-docker.socket` для службы `cri-dockerd`. Она определяет, как и где сервис будет Создадим конфигурацию сокета `cri-docker.socket` для службы `cri-dockerd`. Она определяет, как и где сервис будет
слушать входящие соединения и управлять доступом к нему. Создадим файл: слушать входящие соединения и управлять доступом к нему. Создадим файл:
@ -676,16 +676,16 @@ WantedBy=sockets.target
``` ```
Где: Где:
* [Unit] -- Описывает службу. * [Unit] Описывает службу.
* `Description` -- Описание сокета. * `Description` Описание сокета.
* `PartOf` -- Указывает, что этот сокет является частью службы cri-docker.service. * `PartOf` Указывает, что этот сокет является частью службы cri-docker.service.
* [Socket] -- Конфигурация сокета. * [Socket] Конфигурация сокета.
* `ListenStream` -- Указывает путь к сокету, который будет использоваться для связи. * `ListenStream` Указывает путь к сокету, который будет использоваться для связи.
* `SocketMode` -- Устанавливает права доступа к сокету (0660 -- чтение и запись для владельца и группы, чтение для остальных). * `SocketMode` — Устанавливает права доступа к сокету (0660 — чтение и запись для владельца и группы, чтение для остальных).
* `SocketUser` -- Устанавливает владельца сокета. * `SocketUser` Устанавливает владельца сокета.
* `SocketGroup` -- Устанавливает группу, которой принадлежит сокет. * `SocketGroup` Устанавливает группу, которой принадлежит сокет.
* [Install]: Указывает, когда и как сокет должен быть активирован. * [Install]: Указывает, когда и как сокет должен быть активирован.
* `WantedBy` -- Указывает, что сокет должен быть активирован вместе с sockets.target. * `WantedBy` Указывает, что сокет должен быть активирован вместе с sockets.target.
* Этот файл гарантирует, что cri-dockerd будет слушать на указанном сокете . * Этот файл гарантирует, что cri-dockerd будет слушать на указанном сокете .
Теперь перезагрузим службы, настроим их на автозапуск и запустим их: Теперь перезагрузим службы, настроим их на автозапуск и запустим их:
@ -718,25 +718,29 @@ RuntimeApiVersion: v1
#### Настройка балансировщика нагрузки #### Настройка балансировщика нагрузки
Для обеспечения высокой доступности и автоматического переключения узлов в случае сбоя используется `keepalived`. Для обеспечения высокой доступности и автоматического переключения узлов в случае сбоя используется `keepalived`.
Он нужен только на мастер-узлах, используется для настройки виртуальных IP-адресов (VIP) и в качестве Он используется для настройки виртуальных IP-адресов (VIP) и в качестве балансировки нагрузки. VIP будет перемещаться
балансировки нагрузки. между узлами в зависимости от их состояния и приоритетов. Это означает, что в любой момент времени только один узел
будет отвечать на запросы, направленные на VIP. Когда этот узел выходит из строя, резервный узел с наивысшим
приоритетом берет на себя VIP и начинает отвечать на запросы. Это достигается с помощью протокола VRRP (Virtual Router
Redundancy Protocol), который обеспечивает автоматическое переключение VIP между узлами.
На Ubuntu для Orange Pi 5 `keepalived` уже установлен. Но можно проверить его наличие: На предыдущейм шаге мы уже установили `keepalived` и можно проверить его наличие:
```shell ```shell
dpkg -l | grep keepalived dpkg -l | grep keepalived
``` ```
и в случае отсутствия установить: Настройка `keepalived` осуществляется через файл конфигурации `/etc/keepalived/keepalived.conf`. Этот конфиг
```shell настраивает мониторинг состояния API-сервера и переключения на резервный узел в случае сбоя основного узла. Создадим
sudo apt install keepalived файл конфигурации:
```
Настройка `keepalived` осуществляется через файл конфигурации `/etc/keepalived/keepalived.conf`. Создадим его:
```shell ```shell
sudo nano /etc/keepalived/keepalived.conf sudo nano /etc/keepalived/keepalived.conf
``` ```
Пример конфигурации для мастер-узла `opi5plus-1`: Пример конфигурации для мастер-узла `opi5plus-1`. Он будет называться --
**Betelgeuse** (_звезда спектрального класса M, т.е. оранжевая звезда, так же как и апельсинка Orange Pi_), и иметь
VIP `192.168.1.250` (поменяйте на свой). Так же надо указать пароль для аутентификации между узлами,
участвующими в VRRP (вместо `********`) и чтобы узлы могли корректно взаимодействовать между собой этот пароль должен
быть одинаковым на всех узлах.
``` ```
global_defs { global_defs {
enable_script_security enable_script_security
@ -745,11 +749,11 @@ global_defs {
vrrp_script check_apiserver { vrrp_script check_apiserver {
script "/etc/keepalived/check_apiserver.sh" script "/etc/keepalived/check_apiserver.sh"
interval 3 interval 4
} }
vrrp_instance VI_1 { vrrp_instance ORANGENET {
state BACKUP state MASTER
interface enP4p65s0 interface enP4p65s0
virtual_router_id 5 virtual_router_id 5
priority 100 priority 100
@ -767,3 +771,71 @@ vrrp_instance VI_1 {
} }
} }
``` ```
Вот что делает каждая часть конфигурации:
* `global_defs` — Глобальные настройки.
* `enable_script_security` — Включает безопасность скриптов.
* `script_user nobody` — Указывает пользователя, от имени которого будут выполняться скрипты, `noboby` --
минимальные привилегии.
* `vrrp_script check_apiserver` — Определяет скрипт для проверки состояния API-сервера.
* `script "/etc/keepalived/check_apiserver.sh"` — Указывает путь к скрипту.
* `interval 4` — Интервал выполнения скрипта в секундах.
* `vrrp_instance MilkyWay` — Определяет экземпляр VRRP (Virtual Router Redundancy Protocol).
* `state MASTER` — Указывает, что этот узел находится в резервном состоянии.
* `interface enP4p65s0` — Указывает сетевой интерфейс (у нас `enP4p65s0`).
* `virtual_router_id 5` — Идентификатор виртуального маршрутизатора (от 1 до 255)
* `priority 100` — Приоритет узла (чем выше значение, тем выше приоритет).
* `advert_int 1` — Интервал объявлений VRRP в секундах.
* `nopreempt` — Запрещает узлу с более высоким приоритетом вытеснять активный узел, даже если он становится
доступным. Это означает, что текущий MASTER узел останется активным до тех пор, пока он работает корректно,
и только в случае его сбоя резервный узел с более высоким приоритетом станет MASTER. Другое значения `preempt`
(и это значение по умолчанию) указывает, что если узел с более высоким приоритетом становится доступным, то он
вытеснит текущий активный MASTER-узел. Т.е. если узел с более высоким приоритетом восстанавливается,
он автоматически снова станет MASTER.
* `authentication` — Настройки аутентификации.
* `auth_type PASS` — Тип аутентификации (пароль).
* `auth_pass ********` — Пароль для аутентификации.
* `virtual_ipaddress` — Виртуальный IP-адрес, по которому будет доступны узлы кластера.
* `192.168.1.250` — Виртуальный IP-адрес, который будет использоваться.
* `track_script` — Настройки отслеживания скрипта.
* `check_apiserver` — Указывает скрипт для проверки состояния.
Теперь создадим скрипт `/etc/keepalived/check_apiserver.sh` для проверки состояния API-сервера. Он будет проверять
доступность API-сервера Kubernetes:
```shell
sudo nano /etc/keepalived/check_apiserver.sh
```
Содержимое скрипта:
```shell
#!/bin/bash
# File: /etc/keepalived/check_apiserver.sh
# Задаем переменные: VIP-адрес API-сервера, порт и протокол
APISERVER_VIP=192.168.1.250
APISERVER_DEST_PORT=8888
PROTO=http
# Определение функции errorExit
errorExit() {
# $* — это специальная переменная в shell, которая представляет все позиционные параметры, переданные в скрипт.
# 1>&2 — это перенаправление стандартного вывода (file descriptor 1) в стандартный поток ошибок (file descriptor 2).
echo "*** $*" 1>&2
# "код завершения" 1.
exit 1
}
# Проверка доступности API-сервера на localhost
curl --silent --max-time 2 --insecure ${PROTO}://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET ${PROTO}://localhost:${APISERVER_DEST_PORT}/"
# Если в сетевом интерфейсе узла есть VIP-адрес, то проверяем доступность API-сервера по VIP-адресу
if ip ad | grep -q ${APISERVER_VIP}; then
curl --silent --max-time 2 --insecure ${PROTO}://${APISERVER_VIP}:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET ${PROTO}://${APISERVER_VIP}:${APISERVER_DEST_PORT}/"
fi
# Если все проверки прошли успешно, то "код завершения" 0
exit 0
```
`keepalived` будет отслеживать код завершения и если скрипт завершится с ненулевым кодом, он интерпретирует это
как сбой и инициирует переключение виртуального IP-адреса (VIP) на другой узел с более высоким приоритетом.