> For the complete documentation index, see [llms.txt](https://utm-1.gitbook.io/utm-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://utm-1.gitbook.io/utm-docs/dokumentaciya/utm-it/resheniya/kubernetes/razvertyvanie-ha-klastera/nastroika-balansirovshika-nagruzki.md).

# Настройка балансировщика нагрузки

## Ссылки

Базовая инструкция: <https://habr.com/ru/articles/725640/>

Официальная инструкция: <https://github.com/kubernetes/kubeadm/blob/main/docs/ha-considerations.md>

## Описание и схема

Для создания виртуального IP адреса и перераспределение нагрузки между управляющими узлами будем использовать комбинацию двух демонов: keepalived и haproxy.&#x20;

Ранее эти демоны должны были быть установлены на узлы:

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

Реализуемый балансировщик нагрузки будет работать следующим образом:<br>

1. Демон keepalived обеспечит функционирование виртуального IP-адреса и его привязку к одному из управляющих узлов. Виртуальный IP будет вторым адресом на сетевом интерфейсе узла. Если данный узел откажет, то keepalived обнаружит это и перекинет виртуальный IP-адрес на другой доступный узел.
2. Поступающие на управляющий узел запросы будут обрабатываться демоном haproxy, который, выполняя роль реверс-прокси (reverse proxy), будет поочередно (round robin) пересылать их на API сервера управляющих узлов Kubernetes.

<figure><img src="/files/M7PYJLEDFIIJbwcRgOQn" alt=""><figcaption></figcaption></figure>

## Настройка

Установка демонов выполняется отдельно в операционную систему управляющих узлов.

При развертывания балансировщика нагрузки используются следующие сетевые настройки:<br>

* в качестве виртуального адреса будет использоваться 192.168.1.100;
* связанное с виртуальным адресом DNS имя: utm-k8s-haproxy.utmhome.ru;
* TCP порт для доступа к системе управления: 8888;
* в качестве бэкендов будут использоваться порты 6443 на управляющих узлах:
  * 192.168.3.1:6443
  * 192.168.4.1:6443
  * 192.168.5.1:6443

### Установка keepalived и haproxy

Работа под su

```bash
sudo su
```

На узлах&#x20;

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

Установить пакеты:  keepalived, haproxy

```bash
apt update
apt install -y keepalived
apt install -y haproxy
```

### Настройка демона keepalived

Настройка под su

```bash
sudo su
```

#### Файл */etc/keepalived/keepalived.conf*

На узлах&#x20;

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

создать файл основной конфигурационный файл демона keepalived */etc/keepalived/keepalived.conf*

```bash
nano /etc/keepalived/keepalived.conf
```

<details>

<summary>Содержание файла <em>/etc/keepalived/keepalived.conf</em></summary>

```keepalived
# File: /etc/keepalived/keepalived.conf

global_defs {
    enable_script_security
    script_user nobody
}

vrrp_script check_apiserver {
  script "/etc/keepalived/check_apiserver.sh"
  interval 3
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 5
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass ZqSj#axf1Gd
    }
    virtual_ipaddress {
        192.168.1.100
    }
    track_script {
        check_apiserver
    }
}
```

</details>

#### Файл */etc/keepalived/check\_apiserver.sh*

На узлах&#x20;

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

создать скрипт для проверки доступности серверов демона */etc/keepalived/check\_apiserver.sh*

```bash
nano /etc/keepalived/check_apiserver.sh
```

<details>

<summary>Содержание файла <em>/etc/keepalived/check_apiserver.sh</em></summary>

```bash
#!/bin/sh
# File: /etc/keepalived/check_apiserver.sh

APISERVER_VIP=192.168.1.100
APISERVER_DEST_PORT=8888
PROTO=http

errorExit() {
    echo "*** $*" 1>&2
    exit 1
}

curl --silent --max-time 2 --insecure ${PROTO}://localhost:${APISERVER_DEST_PORT}/ -o /dev/null || errorExit "Error GET ${PROTO}://localhost:${APISERVER_DEST_PORT}/"
if ip addr | 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
```

</details>

установить атрибут, разрешающий исполнение скрипта

```bash
chmod +x /etc/keepalived/check_apiserver.sh
```

#### Запуск демона keepalived

На узлах&#x20;

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

запустить демона keepalived

```bash
# Запуск
systemctl enable keepalived
systemctl start keepalived

# Перезапуск
systemctl restart keepalived

# Для анализа проблем
systemctl status keepalived
journalctl -u keepalived
```

### Настройка демона haproxy

Настройка под su

```bash
sudo su
```

#### Файл */etc/haproxy/haproxy.cfg*

На узлах&#x20;

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

сделать backup текущих настроек

```
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
```

отредактировать основной конфигурационный файл демона haproxy */etc/haproxy/haproxy.cfg*&#x20;

```
nano /etc/haproxy/haproxy.cfg
```

<details>

<summary>Содержание файла <em>/etc/haproxy/haproxy.cfg</em></summary>

```yaml
# File: /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log /dev/log local0 info alert
    log /dev/log local1 notice alert
    daemon

#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 1
    timeout http-request    10s
    timeout queue           20s
    timeout connect         5s
    timeout client          20s
    timeout server          20s
    timeout http-keep-alive 10s
    timeout check           10s

#---------------------------------------------------------------------
# apiserver frontend which proxys to the control plane nodes
#---------------------------------------------------------------------
frontend apiserver
    bind *:8888
    mode tcp
    option tcplog
    default_backend apiserver

#---------------------------------------------------------------------
# round robin balancing for apiserver
#---------------------------------------------------------------------
backend apiserver
    option httpchk GET /healthz
    http-check expect status 200
    mode tcp
    option ssl-hello-chk
    balance     roundrobin
        server node1 192.168.3.1:6443 check
        server node2 192.168.4.1:6443 check
        server node3 192.168.5.1:6443 check
```

</details>

#### Запуск демона haproxy

На узлах&#x20;

* utm-k8s-master3-1
* utm-k8s-master4-1
* utm-k8s-master5-1

запустить демона haproxy

```bash
systemctl enable haproxy
systemctl restart haproxy

# Для анализа проблем
systemctl status haproxy
journalctl -u haproxy --since "2 days ago"
```

{% hint style="info" %}
Примечание. Демон будет ругаться, что не обнаружены backend сервера. Это нормально, так как Kubernetes API еще не запущен.<br>
{% endhint %}
