add: keepalived (-2-)
This commit is contained in:
parent
02c8e7d9da
commit
6132c774c3
@ -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
|
||||||
@ -766,4 +770,72 @@ vrrp_instance VI_1 {
|
|||||||
check_apiserver
|
check_apiserver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Вот что делает каждая часть конфигурации:
|
||||||
|
* `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) на другой узел с более высоким приоритетом.
|
Loading…
Reference in New Issue
Block a user