﻿# Отказоустойчивый Kubernetes-кластер

> [HTML Version](fail-safe-kubernetes-cluster.html)

[Deckhouse](https://deckhouse.ru/) — это полнофункциональная платформа на базе Open Source-компонентов, которая, кроме Kubernetes, включает дополнительные модули для мониторинга, балансировки трафика, автомасштабирования, безопасного доступа и не только. Модули преднастроены, интегрированы друг с другом и готовы к работе. Управление всеми компонентами кластера и платформы, а также их обновление полностью автоматизированы. 

Deckhouse [в реестре российского ПО](https://reestr.digital.gov.ru/reestr/490559/) и [сертифицирован в CNCF](https://landscape.cncf.io/?view-mode=card&classify=category&sort-by=name&sort-direction=asc&item=platform--certified-kubernetes-distribution--flant-deckhouse#app-definition-and-development--application-definition-image-build ).

Установка состоит из следующих этапов:

1. [Архитектура кластера Kubernetes](#cluster-architecture).

2. [Рекомендуемые системные требования](#system-requirements).

3. [Подготовка конфигурационного файла](#preparation-config-file).

4. [Установка Kubernetes-кластера на базе Deckhouse](#installation).

5. [Добавление frontend-узлов](#addition-frontend-nodes).

6. [Добавление system-узлов](#addition-system-nodes).

7. [Добавление worker-узлов](#addition-worke-nodes).

8. [Добавление master-узлов](#addition-master-nodes).

9. [Добавление Local Path Provisioner](#addition-local-path-provisioner).

10. [Установка HELM](#installation-helm).

11. [Добавление балансировщика OpenELB - VIP](#addition-balancer).

12. [Добавление Ingress Nginx Controller - LoadBalancer](#addition-ingress-nginx-controller).

13. [Добавление пользователя для доступа к веб-интерфейсу кластера](#addition-user).

14. [Привилегии запускаемых нагрузок](#load-privileges).

## Шаг 1. Архитектура кластера Kubernetes

В рамках статьи рассматривается внедрение инфраструктуры отказоустойчивого кластера Kubernetes на базе платформы Deckhouse.

1. Структура Kubernetes-кластера.

(fail-safe-kubernetes-cluster-1.png)

Чтобы развернуть минимальную структуру Kubernetes-кластера на базе платформы Deckhouse, потребуются:

- персональный компьютер;

- master-узел — три ноды;

- worker-узел — три ноды;

- system-узел — две ноды;

- frontend-узел — две ноды.

В рассматриваемом примере web‑трафик от пользователей поступает на виртуальный IP‑адрес 192.168.1.13, размещённый на frontend-нодах. Шаблон доменного имени для доступа к web-сервисам платформы Deckhouse выберите **%s.example.com**.

Deckhouse автоматически настраивает и управляет узлами кластера и его компонентами **control plane**, постоянно поддерживая их актуальную конфигурацию. При развёртывании master-узлов автоматически создаются все необходимые компоненты для **control plane** с помощью модуля [control-plane-manager](https://deckhouse.ru/documentation/latest/modules/040-control-plane-manager/).

Deckhouse создаёт сущности Kubernetes по мере необходимости и так же их удаляет. Например, если в вашем кластере нет frontend-нод и с master-нод не снято ограничение **taint**, вы не сможете установить **IngressNginxController**.  В кластере будут отсутствовать необходимые сущности, как **ingressClass** и так далее. При добавлении system-нод Deckhouse автоматически развернёт компоненты мониторинга и web-сервисы для доступа к интерфейсу платформы. Web-сервисы автоматически привяжутся на **%s.example.com**.

2. Загрузка образов Deckhouse в локальный реестр образов.

Кластер Kubernetes с помощью Deckhouse можно развернуть в закрытом окружении, из которого нет доступа в интернет. Для этого предварительно скачайте на компьютере с доступом в интернет образы платформы Deckhouse и загрузите их в локальный реестр образов. Подробнее читайте в статье [«Загрузка образов Deckhouse»](downloading-images-deckhouse.md).

## Шаг 2. Рекомендуемые системные требования

1. Персональный компьютер.   
  
Компьютер, с которого будет производиться установка. Он нужен только для запуска инсталлятора Deckhouse и не будет частью кластера. Требования:

- ОС: Windows 10+, macOS 10.15+, Linux (Ubuntu 18.04+, Fedora 35+);

- установленный docker для запуска инсталлятора Deckhouse;

- доступ до проксирующего registry или до частного хранилища образов контейнеров с образами контейнеров Deckhouse;

- SSH-доступ по ключу до узла, который будет master-узлом будущего кластера.

2. Ноды Kubernetes:

- [поддерживаемая ОС](https://deckhouse.ru/documentation/v1/supported_versions.html);

- конфигурация нод:

| | | | | |
|------|------|------|------|------|
| **Наименование** | **vCPU** | **RAM (GB)** | **Жесткий диск (GB)** | **LAN (Gbit/s)** |
| Kubernetes worker | 8 | 16 | 60 | 1 |
| Kubernetes system | 8 | 16 | 200 | 1 |
| Kubernetes master | 4 | 8 | 60 | 1 |
| Kubernetes frontend | 4 | 6 | 60 | 1 |


- доступ до проксирующего **registry** или до частного хранилища образов контейнеров с образами контейнеров Deckhouse;

````
Начало внимание

````
Deckhouse поддерживает работу только с Bearer token схемой авторизации в **registry**.

````
Конец внимание

- ````
доступ до прокси-сервера для скачивания deb/rpm-пакетов ОС при необходимости;

- на узле не должно быть установлено пакетов container runtime, например, containerd или docker.

````
Начало примечание

````
**Примечание**

Установка непосредственно с master-узла в настоящий момент не поддерживается. Установщик в виде Docker-образа нельзя запускать на том же узле, на котором планируется развёртывание master-узла, так как на узле не должно быть установлено пакетов container runtime, например, containerd или docker. При отсутствии менеджмент узлов установите docker на любой другой ноде будущего кластера, запустите Docker-образ установщика, установите Deckhouse и удалите Docker-образ установщика c ноды вместе с docker.

````
Конец примечание

## ````
Шаг 3. Подготовка конфигурационного файла

Чтобы установить Deckhouse, подготовьте YAML-файл конфигурации установки. Для получения этого файла используйте сервис [Быстрый старт](https://deckhouse.ru/gs/) на сайте Deckhouse. Сервис сгенерирует актуальный YAML-файл для текущей версий платформы.

1. Сгенерируйте YAML-файл сервисом [Быстрый старт](https://deckhouse.ru/gs/), выполнив следующие шаги:

1. Выберите инфраструктуру — Bare Metal.

2. Ознакомьтесь с информацией об установке.

3. Укажите шаблон для DNS-имён кластера. В нашем случае — **%s.example.com**.

4. Сохраните \[OBJECT\].

2. Внесите необходимые изменения в \[OBJECT\]. Для этого выполните следующие действия:

1. Задайте адресное пространство подов кластера в **podSubnetCIDR**.

2. Задайте адресное пространство Service’ов кластера в **serviceSubnetCIDR**.

3. Задайте нужную версию Kubernetes в **kubernetesVersion**.

4. Проверьте канал обновления в **releaseChannel** (EarlyAccess).

5. Проверьте шаблон доменного имени в **publicDomainTemplate** (**%s.example.com**).  
Используется для формирования доменов системных приложений в кластере. Например, Grafana для шаблона **%s.example.com** будет доступна, как **grafana.example.com**.

6. Проверьте режим работы модуля cni-flannel в **podNetworkMode**.  
Режим работы flannel, допустимые значения **VXLAN** (если ваши сервера имеют связность L3) или **HostGW** (для L2-сетей).

7. Укажите локальную сеть, которую будут использовать узлы кластера в **internalNetworkCIDRs**.  
Список внутренних сетей узлов кластера, например, \[OBJECT\], который используется для связи компонентов Kubernetes (kube-apiserver, kubelet и т. д.) между собой.

### Пример файла первичной конфигурации кластера

 Ниже представлены примеры файла первичной конфигурации кластера — `config.yml`. В этом файле для установки через интернет и для офлайн-установки используются параметры:

- `podSubnetCIDR` — внутренние адреса подов, которые не должны пересекаться с вашей офисной или облачной сетью; 

- `serviceSubnetCIDR` — адреса сервисов внутри кластера, которые не должны пересекаться с вашей офисной или облачной сетью; 

- `internalNetworkCIDRs` — сети, с которых разрешён доступ к API кластера;

- `releaseChannel` — канал обновлений Deckhouse Virtualization Platform. Доступные каналы: Alpha, Beta, Early Access, Stable, Rock Solid. Их подробное описание смотрите в [официальной документации Deckhouse](https://deckhouse.ru/products/virtualization-platform/documentation/about/release-channels.html). 

Для установки через интернет

````
apiVersion: deckhouse.io/v1  
kind: ClusterConfiguration  
clusterType: Static  
podSubnetCIDR: 10.111.0.0/16  
serviceSubnetCIDR: 10.222.0.0/16  
kubernetesVersion: "Automatic"  
clusterDomain: "cluster.local"  
\---  
apiVersion: deckhouse.io/v1  
kind: InitConfiguration  
deckhouse:  
  imagesRepo: registry.deckhouse.ru/deckhouse/ce  
  registryDockerCfg: eyJhdXRocyI6IHsgInJlZ2lzdHJ5LmRlY2tob3VzZS5ydSI6IHt9fX0K  
\---  
apiVersion: deckhouse.io/v1alpha1  
kind: ModuleConfig  
metadata:  
  name: deckhouse  
spec:  
  version: 1  
  enabled: true  
  settings:  
    bundle: Default  
    releaseChannel: EarlyAccess  
    logLevel: Info  
\---  
apiVersion: deckhouse.io/v1alpha1  
kind: ModuleConfig  
metadata:  
  name: global  
spec:  
  version: 2  
  settings:  
    modules:  
      publicDomainTemplate: "%s.elewise.local"  
\---  
apiVersion: deckhouse.io/v1alpha1  
kind: ModuleConfig  
metadata:  
  name: user-authn  
spec:  
  version: 2  
  enabled: true  
  settings:  
    controlPlaneConfigurator:  
      dexCAMode: DoNotNeed  
    publishAPI:  
      enabled: true  
      https:  
        mode: Global  
        global:  
          kubeconfigGeneratorMasterCA: ""  
\---  
apiVersion: deckhouse.io/v1alpha1  
kind: ModuleConfig  
metadata:  
  name: cni-cilium  
spec:  
  version: 1  
  enabled: true  
  settings:  
    tunnelMode: VXLAN  
\---  
apiVersion: deckhouse.io/v1  
kind: StaticClusterConfiguration  
internalNetworkCIDRs:  
\- 192.168.1.0/24
````

````


Для офлайн-установки без доступа в интернет

````
Начало внимание

````
Для генерации YAML-файла сервисом [Быстрый старт](https://deckhouse.ru/gs/) выберите инфраструктуру — **Закрытое окружение**.

````
Конец внимание

````
Установите следующие параметры в ресурсе **InitConfiguration**:

- **devBranch**: если в изолированном приватном репозитории нет образов, содержащих информацию о каналах обновлений, используйте точный тег образа Deckhouse, чтобы установить Deckhouse Platform. Например, если вы хотите установить релиз v1.46.3, используйте образ \[OBJECT\]. Также укажите \[OBJECT\] вместо \[OBJECT\];

- **imagesRepo**: \[OBJECT\] — адрес образа Deckhouse в приватном репозитории с учётом используемой редакции. В рамках статьи образы были загружены в \[OBJECT\]. Подробнее читайте в статье [«Загрузка образов Deckhouse»](downloading-images-deckhouse.md);

- **registryDockerCfg**: \[OBJECT\] — права доступа к приватному репозиторию, зашифрованные в Base64. Примеры заполнения **registryDockerCfg** читайте в официальной документации [Deckhouse Kubernetes Platform](https://deckhouse.ru/documentation/v1/deckhouse-faq.html#%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BA%D0%B0-%D0%BA%D0%BE%D0%BD%D1%84%D0%B8%D0%B3%D1%83%D1%80%D0%B0%D1%86%D0%B8%D0%B8). В рамках статьи разрешён анонимный доступ к образам Deckhouse в стороннем **registry**. Сформируйте **registryDockerCfg**, выполнив следующую команду:

````
echo -n "\{\\"auths\\": \{ \\"registry.example.com:443/images/deckhouse\\": \{\}\}\}" | base64

- ````
**registryScheme**: укажите, по какому протоколу (HTTP, HTTPS) работает приватный репозиторий;

- **registryCA**: корневой TLS-сертификат, которым можно проверить TLS-сертификат приватного реестра, например, если хранилище использует самоподписанный сертификат. Если вы используете не самоподписанный сертификат или хранилище работает по протоколу HTTP, удалите этот параметр.

Пример файла первичной конфигурации кластера — \[OBJECT\]:

````
apiVersion: deckhouse.io/v1  
kind: ClusterConfiguration  
clusterType: Static  
podSubnetCIDR: 10.111.0.0/16  
serviceSubnetCIDR: 10.222.0.0/16  
kubernetesVersion: "Automatic"  
clusterDomain: "cluster.local"  
\---  
apiVersion: deckhouse.io/v1  
kind: InitConfiguration  
deckhouse:  
  devBranch: v1.46.3  
  configOverrides:  
    global:  
      modules:  
        publicDomainTemplate: "%s.example.com"  
    cniFlannelEnabled: true  
    cniFlannel:  
      podNetworkMode: VXLAN  
  imagesRepo: registry.example.com:443/images/deckhouse  
  registryDockerCfg: eyJhdXRocyI6IHsgInJlZ2lzdHJ5LmV4YW1wbGUuY29tOjQ0My9pbWFnZXMvZGVja2hvdXNlIjoge319fQ==  
  registryScheme: HTTPS  
  registryCA: |  
    -----BEGIN CERTIFICATE-----  
    MIIFBzCCGu+gAwIBAgIUBZ37mm02QGGcmd5pZvWwnpCfQUowDQYGKoZIhvcNAQEL  
    BQAwHjEcMBoGA1UEAwwTaW1hZ2VzLnByb2FjdG9yLnBybzAeFw0yMjA5MjkxNDUw  
    ...  
    9UpckrwxPhctmln5/Awd/2gcaRAxI3qBL7SyDFT0YpnGcAiGPY4Z67HhZ7h6y+2F  
    fQDSXli0r61/Fenkh5OLMihLYTm+5gjZlG1LCXpaGIpjAf16Q+3/pIqapQ==  
    -----END CERTIFICATE-----  
\---  
apiVersion: deckhouse.io/v1  
kind: StaticClusterConfiguration  
internalNetworkCIDRs:  
  - 192.168.1.0/24
````

## ````
Шаг 4. Установка Kubernetes-кластера на базе Deckhouse

Установка Deckhouse Platform Community Edition сводится к установке кластера, который состоит из единственного master-узла. Инсталлятор Deckhouse доступен в виде образа контейнера, в который необходимо передать конфигурационные файлы и SSH-ключи доступа на master-узел. Далее подразумевается, что используется SSH-ключ \[OBJECT\]. В основе инсталлятора лежит утилита [dhctl](https://github.com/deckhouse/deckhouse/tree/main/dhctl/).

1. Запустите установщик.

````
Начало примечание

````
**Примечание**

Установка непосредственно с master-узла в настоящий момент не поддерживается. Установщик в виде Docker-образа нельзя запускать на том же узле, на котором планируется развёртывание master-узла, так как на узле не должно быть установлено пакетов container runtime, например, containerd или docker.

````
Конец примечание

````
Установщик запускается на персональном компьютере, подготовленном на этапе [«Архитектура кластера Kubernetes»](#cluster-architecture). На ПК перейдите в директорию с файлом конфигурации \[OBJECT\], подготовленным на [предыдущем этапе](#preparation-config-file).

Для запуска установщика через интернет выполните команду:

````
sudo docker run --pull=always -it -v "\$PWD/config.yml:/config.yml" -v "\$HOME/.ssh/:/tmp/.ssh/" registry.deckhouse.io/deckhouse/ce/install:stable bash

````
Для офлайн-установки без доступа в интернет

  
Выполните команду:

````
sudo docker run --pull=always -it -v "\$PWD/config.yml:/config.yml" -v "\$HOME/.ssh/:/tmp/.ssh/" example.com:443/images/deckhouse/install:v1.46.3 bash

````
  
где \[OBJECT\] — версия устанавливаемого релиза.

2. Установите Deckhouse. Для этого внутри контейнера установщика выполните команду:

````
dhctl bootstrap --ssh-user=<username> --ssh-host=<master\_ip> --ssh-agent-private-keys=/tmp/.ssh/id\_rsa \\  
\--config=/config.yml \\  
\--ask-become-pass

````
где:

- ````
\[OBJECT\]````
 — в параметре ````
\[OBJECT\]````
 укажите имя пользователя, от которого генерировался SSH-ключ для установки;

- ````
\[OBJECT\]````
 — IP-адрес master-узла, подготовленного на этапе [«Архитектура кластера Kubernetes»](#cluster-architecture);

- `<ask-become-pass>` — опциональный параметр. Используйте его, если для доступа к узлу требуется пароль.

Процесс установки может занять 15-30 минут при хорошем соединении.

3. При необходимости настройте DNS для внутреннего домена. Для этого в Deckhouse доступен модуль kube-dns. Включите его с помощью команды: 

````
sudo -i d8 system module enable kube-dns 

````
Если модуль уже включён, для его настройки используйте команду: 

````
sudo -i d8 k edit mc kube-dns

````
Настройки DNS указываются в файле конфигурации. 

Пример минимальной конфигурации с указанием своего DNS-сервера и домена

````
apiVersion: deckhouse.io/v1alpha1  
kind: ModuleConfig  
metadata:  
  name: kube-dns  
spec:  
  version: 1  
  enabled: true  
  settings:  
    upstreamNameservers:  
    - 8.8.8.8  
    - 8.8.4.4  
    hosts:  
    - domain: one.example.com  
      ip: 192.168.0.1  
    - domain: two.another.example.com  
      ip: 10.10.0.128  
    stubZones:  
    - zone: consul.local  
      upstreamNameservers:  
      - 10.150.0.1  
    enableLogs: true  
    clusterDomainAliases:  
    - foo.bar  
    - baz.qux
````

````
Подробнее о модуле kube-dns читайте в [официальной документации Deckhouse](https://deckhouse.ru/modules/kube-dns/). 

## Шаг 5. Добавление frontend-узлов

Перед добавлением frontend-нод предварительно создайте новый custom resource [NodeGroup](https://deckhouse.ru/documentation/latest/modules/040-node-manager/cr.html#nodegroup) с именем \[OBJECT\]. Параметр \[OBJECT\] в custom resource NodeGroup задайте как \[OBJECT\].

1. Создайте на ноде master 1 файл \[OBJECT\] с описанием статичной NodeGroup с наименованием \[OBJECT\]:

````
apiVersion: deckhouse.io/v1  
kind: NodeGroup  
metadata:  
  name: frontend  
spec:  
  nodeTemplate:  
    labels:  
      node-role.deckhouse.io/frontend: ""  
    taints:  
      - effect: NoExecute  
        key: dedicated.deckhouse.io  
        value: frontend  
  nodeType: Static

2. ````
Примените файл \[OBJECT\], выполнив команду:

````
kubectl create -f frontend.yaml

3. ````
Для добавления frontend-нод выполните следующие действия:

1. Получите код скрипта в кодировке Base64 для добавления и настройки нового узла frontend, выполнив команду на ноде master 1:

````
kubectl -n d8-cloud-instance-manager get secret manual-bootstrap-for-frontend -o json | jq '.data."bootstrap.sh"' -r

2. ````
Зайдите на узел, который хотите добавить по SSH (в данном случае frontend 1) и вставьте полученную на первом шаге Base64‑строку:

````
echo <Base64-КОД-СКРИПТА> | base64 -d | bash

````
Дождитесь окончания выполнения скрипта. Нода добавлена.

Чтобы добавить новые frontend-ноды, выполните действия из пункта 3.

## Шаг 6. Добавление system-узлов

Перед добавлением system-нод предварительно создайте новый custom resource [NodeGroup](https://deckhouse.ru/documentation/latest/modules/040-node-manager/cr.html#nodegroup) с именем \[OBJECT\]. Параметр \[OBJECT\] в custom resource NodeGroup задать как \[OBJECT\].

1. Создайте на ноде master 1 файл \[OBJECT\] с описанием статичной NodeGroup с наименованием \[OBJECT\]:

````
apiVersion: deckhouse.io/v1  
kind: NodeGroup  
metadata:  
  name: system  
spec:  
  nodeTemplate:  
    labels:  
      node-role.deckhouse.io/system: ""  
    taints:  
      - effect: NoExecute  
        key: dedicated.deckhouse.io  
        value: system  
  nodeType: Static

2. ````
Примените файл \[OBJECT\], выполнив команду:

````
kubectl create -f system.yaml

3. ````
Для добавления system-нод выполните следующие действия:

1. Получите код скрипта в кодировке Base64 для добавления и настройки нового узла system, выполнив команду на ноде master 1:

````
kubectl -n d8-cloud-instance-manager get secret manual-bootstrap-for-system -o json | jq '.data."bootstrap.sh"' -r

2. ````
Зайдите на узел, который хотите добавить по SSH (в данном случае system 1) и вставьте полученную на первом шаге Base64‑строку:

````
echo <Base64-КОД-СКРИПТА> | base64 -d | bash

````
Дождитесь окончания выполнения скрипта. Нода добавлена.

Чтобы добавить новые system-ноды, выполните действия из пункта 3.

## Шаг 7. Добавление worker-узлов

Перед добавлением worker-нод предварительно создайте новый custom resource [NodeGroup](https://deckhouse.ru/documentation/latest/modules/040-node-manager/cr.html#nodegroup) с именем \[OBJECT\]. Параметр \[OBJECT\] в custom resource NodeGroup задать как \[OBJECT\].

1. Создайте на ноде master 1 файл \[OBJECT\] с описанием статичной NodeGroup с наименованием \[OBJECT\]:

````
apiVersion: deckhouse.io/v1  
kind: NodeGroup  
metadata:  
  name: worker  
spec:  
  nodeType: Static  
  kubelet:  
    maxPods: 200

2. ````
Примените файл \[OBJECT\], выполнив команду:

````
kubectl create -f worker.yaml

3. ````
Для добавления worker-нод выполните следующие действия:

1. Получите код скрипта в кодировке Base64 для добавления и настройки нового узла worker, выполнив команду на ноде master 1:

````
kubectl -n d8-cloud-instance-manager get secret manual-bootstrap-for-worker -o json | jq '.data."bootstrap.sh"' -r

2. ````
Зайдите на узел, который хотите добавить по SSH (в данном случае worker 1) и вставьте полученную на первом шаге Base64-строку:

````
echo <Base64-КОД-СКРИПТА> | base64 -d | bash

````
Дождитесь окончания выполнения скрипта. Нода добавлена.

Чтобы добавить новые worker-ноды, выполните действия из пункта 3.

## Шаг 8. Добавление master-узлов

1. Получите код скрипта в кодировке Base64 для добавления и настройки нового узла master, выполнив команду на ноде master 1:

````
kubectl -n d8-cloud-instance-manager get secret manual-bootstrap-for-master -o json | jq '.data."bootstrap.sh"' -r

2. ````
Зайдите на узел, который хотите добавить по SSH (в данном случае master 2) и вставьте полученную на первом шаге Base64-строку:

````
echo <Base64-КОД-СКРИПТА> | base64 -d | bash

````
Дождитесь окончания выполнения скрипта. Нода добавлена.

Чтобы добавить новые master-ноды, выполните действия из шага 8.

## Шаг 9. Добавление Local Path Provisioner

По умолчанию storageclass отсутствует в Deckhouse. Создайте custom resource **LocalPathProvisioner**, позволяющий пользователям Kubernetes использовать локальное хранилище на узлах. Для этого выполните следующие действия:

1. Создайте на master-узле файл \[OBJECT\], содержащий конфигурацию для **LocalPathProvisioner**.

2. Установите нужную Reclaim policy (по умолчанию устанавливается Retain). В рамках статьи для параметра \[OBJECT\] установлено \[OBJECT\] (PV после удаления PVC удаляются).

Пример файла \[OBJECT\]:

````
apiVersion: deckhouse.io/v1alpha1  
kind: LocalPathProvisioner  
metadata:  
  name: localpath-deckhouse-system  
spec:  
  nodeGroups:  
  - system  
  - worker  
  path: "/opt/local-path-provisioner"  
  reclaimPolicy: "Delete"

3. ````
Примените файл \[OBJECT\] в Kubernetes. Для этого выполните команду:

````
kubectl apply -f local-path-provisioner.yaml

4. ````
Установите созданный **LocalPathProvisioner**, как storageclass по умолчанию (default-class), выполнив команду:

````
sudo -i d8 k patch mc global --type merge -p '\{"spec": \{"settings":\{"defaultClusterStorageClass":"localpath-deckhouse-system"\}\}\}'

````
**LocalPathProvisioner** с наименованием localpath-deckhouse-system создан и готов предоставлять локальные хранилища на узлах c NodeGroup system и worker.

## Шаг 10. Установка HELM

1. Перейдите на страницу релизов [Helm](https://github.com/helm/helm/releases) и скачайте архив \[OBJECT\] нужно версии.

Для установки через интернет:

````
wget https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz

````
Для офлайн-установки без доступа в интернет

1. На компьютере с доступом в интернет перейдите на страницу релизов [Helm](https://github.com/helm/helm/releases) и скачайте архив \[OBJECT\] нужной версии, выполнив команду:

````
wget https://get.helm.sh/helm-vX.Y.Z-linux-amd64.tar.gz

2. ````
Скопируйте полученный архив на master-узел.

2. Распакуйте архив и переместите бинарный файл helm:

````
tar -zxvf helm-vX.Y.Z-linux-amd64.tar.gz  
mv linux-amd64/helm /usr/local/bin/helm

## ````
Шаг 11. Добавление балансировщика OpenELB-VIP

Для правильной работы Ingress-контроллера требуется прямой выход в интернет с публичным IP-адресом на Ingress-узле кластера с использованием NodePort. Также можно установить балансировщик [OpenELB](https://openelb.io/docs/getting-started/installation/), который будет заниматься балансировкой трафика так, как это организовано у любого облачного провайдера. Этот балансировщик использует Speaker для поддержки IP-адреса службы.

Условия использования OpenELB или отказа от него

  
**Когда нужен балансировщик: **

- нет публичного IP-адреса на Ingress-узле — OpenELB предоставляет виртуальный IP-адрес (далее — VIP), который динамически перемещается (keepalive) между нодами frontend;

- требуется отказоустойчивый Ingress — VIP автоматически переназначается на другую ноду при выходе текущей из строя;

- требуется внешнее обращение к сервисам — сервисы типа LoadBalancer получают реальный IP-адрес, доступный вне кластера.

**Когда установка OpenELB не требуется:**

- уже есть публичный IP-адрес на Ingress-узле — достаточно использовать NodePort с прямым доступом к узлу;

- кластер развёрнут в облаке, например Yandex Cloud — у облачного провайдера есть свой балансировщик (NLB, ALB и т. д.);

- используется Ingress с параметром hostNetwork, в котором установлено значение true — в таком случае Ingress принимает подключения напрямую на портах хоста, поэтому дополнительный балансировщик не нужен;

- в тестовом окружении без требований к доступности — более простым и быстрым решением является использование NodePort и IP-адреса ноды;

- уже установлен MetalLB или другой балансировщик — OpenELB будет конфликтовать с существующим компонентом.

**Итоговые рекомендации:**

- применение OpenELB целесообразно — если в кластере отсутствует публичный IP-адрес или нужно обеспечить отказоустойчивость (HA);

- установка OpenELB не требуется — если у вас есть публичный IP-адрес на определённой ноде и нет требований к отказоустойчивости.



Разверните OpenELB в режиме VIP Mode. Для этого:

1. Получите конфигурационный файл \[OBJECT\].

Для установки через интернет:

````
helm repo add elma365 https://charts.elma365.tech  
helm repo update  
helm show values elma365/openelb > values-openelb.yaml

````
Получение конфигурационного файла для установки в закрытом контуре без доступа в интернет

1. На компьютере с доступом в интернет скачайте архив актуальной версии (latest) чарта OpenELB из репозитория elma365, выполнив следующую команду:

````
helm repo add elma365 https://charts.elma365.tech  
helm repo update  
helm pull elma365/openelb

2. ````
Полученный архив чарта \[OBJECT\] скопируйте на сервер, где будет производиться установка.

3. Распакуйте чарт \[OBJECT\] на сервере, где будет производиться установка и скопируйте конфигурационный файл по умолчанию \[OBJECT\] в \[OBJECT\].

````
tar -xf openelb-X.Y.Z.tgz  
cp openelb/values.yaml values-openelb.yaml
````

2. ````
Измените конфигурационный файл \[OBJECT\].

Запланируйте размещение подов openelb-controller на frontend-нодах кластера. Для этого измените секции **tolerations** и **nodeSelector**:

````
\## Настройки openelb  
openelb:  
  speaker:  
    enable: true  
    vip: false  
    layer2: true  
    apiHosts: ":50051"  
    tolerations:  
      - key: CriticalAddonsOnly  
        operator: Exists  
      - effect: NoExecute  
        key: dedicated.deckhouse.io  
        operator: Equal  
        value: frontend  
    nodeSelector:  
      kubernetes.io/os: linux  
      node-role.deckhouse.io/frontend: ""  
  controller:  
    webhookPort: 443  
    tolerations:  
      - key: CriticalAddonsOnly  
        operator: Exists  
      - effect: NoExecute  
        key: dedicated.deckhouse.io  
        operator: Equal  
        value: frontend  
    nodeSelector:  
      kubernetes.io/os: linux  
      node-role.deckhouse.io/frontend: ""  
...

````
Заполнение параметров подключения к приватному registry для установки в закрытом контуре без доступа в интернет

  
Для подключения к приватному **registry** необходимо:

1. Задать адрес и путь для параметра \[OBJECT\].

2. Указать наименование секрета с правами доступа к приватному **registry** в параметре \[OBJECT\]. Секрет должен быть создан вручную и зашифрован в Base64.

````
\## Настройки openelb  
openelb:  
   ## параметры подключения к приватному registry  
 global:  
     ## адрес и путь для приватного registry  
   imageRegistry: registry.example.com/docker/addons  
   ## секрет с правами доступа к приватному registry должен быть создан вручную, зашифрованный в Base64  
   imagePullSecrets:  
     - name: myRegistryKeySecretName

````
где формат \[OBJECT\]: адрес — \[OBJECT\].

3. Установите OpenELB в Kubernetes.

Для установки через интернет:

````
helm upgrade --install openelb elma365/openelb -f values-openelb.yaml -n openelb-system --create-namespace

````
Для установки без доступа в интернет

  
Перейдите в каталог с загруженным чартом и выполните команду:  


````
helm upgrade --install openelb ./openelb -f values-openelb.yaml -n openelb-system --create-namespace
````

4. ````
Настройте отказоустойчивость openelb-controller.

Для достижения отказоустойчивости увеличьте количество реплик openelb-controller, выполнив команду на ноде master 1:

````
kubectl scale --replicas=2 deployment openelb-controller -n openelb-system

````
Выполните следующую команду, чтобы проверить находится ли openelb-controller в состоянии **READY:** **1/1** и **STATUS:** **Running**. Если да, OpenELB успешно установлен.

````
kubectl get po -n openelb-system

5. ````
Создайте пул IP-адресов для OpenELB.

1. Создайте на ноде master 1 файл \[OBJECT\] с описанием EIP‑объекта. Объект Eip функционирует как пул IP-адресов для OpenELB.

Пример файла \[OBJECT\]:

````
apiVersion: network.kubesphere.io/v1alpha2  
kind: Eip  
metadata:  
  name: vip-eip  
  annotations:  
    eip.openelb.kubesphere.io/is-default-eip: "true"  
spec:  
  address: 192.168.1.13  
  protocol: layer2  
  interface: ens18

2. ````
Примените файл \[OBJECT\] в Kubernetes, выполнив команду:

````
kubectl apply -f vip-eip.yaml

## ````
Шаг 12. Добавление Ingress Nginx Controller - LoadBalancer

Deckhouse устанавливает и управляет NGINX Ingress Controller при помощи Custom Resources. Если узлов для размещения Ingress-контроллера больше одного, он устанавливается в отказоустойчивом режиме и учитывает все особенности реализации инфраструктуры облаков и bare metal, а также кластеров Kubernetes различных типов.

1. Создайте на ноде master 1 файл \[OBJECT\], содержащий конфигурацию Ingress-контроллера.

Пример файла ingress-nginx-controller.yml 

````
  
\# секция, описывающая параметры nginx ingress controller  
\# используемая версия API Deckhouse  
apiVersion: deckhouse.io/v1  
kind: IngressNginxController  
metadata:  
  name: nginx  
spec:  
  # имя Ingress-класса для обслуживания Ingress NGINX controller  
  ingressClass: nginx  
  # способ поступления трафика из внешнего мира  
  inlet: LoadBalancer  
\# Аннотация для OpenELB в сервис nginx-load-balancer  
  loadBalancer:  
    annotations:  
      eip.openelb.kubesphere.io/v1alpha2: "vip-eip"  
      lb.kubesphere.io/v1alpha1: "openelb"  
  hostPort:  
    httpPort: 80  
    httpsPort: 443  
  # описывает, на каких узлах будет находиться компонент  
  nodeSelector:  
    node-role.kubernetes.io/frontend: ""  
  tolerations:  
  - operator: Exists
````

2. ````
Примените файл \[OBJECT\] в Kubernetes, выполнив команду:

````
kubectl create -f ingress-nginx-controller.yml

````
После установки ingress-контроллера Deckhouse автоматически создаст сервис nginx-load-balancer в namespace \[OBJECT\], но не свяжет данный сервис с OpenELB. 

3. Проверьте, что изменения, внесённые в сервис nginx-load-balancer применились, в **EXTERNAL-IP** появился IP-адрес 192.168.1.13. Для этого выполните следующую команду:

````
kubectl get svc -n d8-ingress-nginx

## ````
Шаг 13. Добавление пользователя для доступа к веб-интерфейсу кластера

1. Если пространство имён ещё не создано, добавьте его с помощью команды:

````
kubectl create namespace elma365

````


2. Создайте на ноде master 1 файл \[OBJECT\], содержащий описание учётной записи пользователя и прав доступа.

Пример файла user.yml

````
  
apiVersion: deckhouse.io/v1  
kind: ClusterAuthorizationRule  
metadata:  
  name: admin  
spec:  
  # список учётных записей Kubernetes RBAC  
  subjects:  
  - kind: User  
    name: admin@deckhouse.io  
  # предустановленный шаблон уровня доступа  
  accessLevel: SuperAdmin  
  # разрешить пользователю делать kubectl port-forward  
  portForwarding: true  
\---  
\# секция, описывающая параметры статического пользователя  
\# используемая версия API Deckhouse  
apiVersion: deckhouse.io/v1  
kind: User  
metadata:  
  name: admin  
spec:  
  # e-mail пользователя  
  email: admin@deckhouse.io  
  # это хэш пароля xgnv5gkggd, сгенерированного сейчас  
  # сгенерируйте свой или используйте этот, но только для тестирования  
  # echo "xgnv5gkggd" | htpasswd -BinC 10 "" | cut -d: -f2  
  # возможно, захотите изменить  
  password: '\$2a\$10\$4j4cUeyonCfX7aDJyqSHXuAxycsf/sDK0T4n9ySQ7.owE34L1uXTm'
````

3. ````
Примените файл \[OBJECT\] в Kubernetes, выполнив команду:

````
kubectl create -f user.yml

## ````
Шаг 14. Привилегии запускаемых нагрузок

Разрешите переназначить политику привилегий для запускаемых подов:

````
kubectl label namespace elma365 security.deckhouse.io/pod-policy=privileged --overwrite

## ````
