> For the complete documentation index, see [llms.txt](https://book.konstantinsecurity.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.konstantinsecurity.com/readme/architect/kubernetes/frameworks/deckhouse/on-premise-install.md).

# On premise Install

<https://habr.com/ru/companies/flant/articles/717484/>

Продолжаем серию статей про установку Deckhouse в разные окружения. Мы уже рассказывали [про развертывание в Yandex Cloud](https://habr.com/ru/company/flant/blog/707422/). Эта статья посвящена установке платформы в закрытое окружение, когда у машин, на которых разворачивается кластер, нет доступа в Интернет.

![](/files/9tmbdGTWJxAOy00uXke7)

Установка Deckhouse в закрытое окружение почти не отличается от установки на bare metal. Главные особенности:

* Чтобы предоставить приложениям доступ в Интернет в закрытом контуре, нужно явно указать параметры прокси-сервера [в конфигурации кластера](https://deckhouse.ru/documentation/v1/installing/configuration.html#parameters-proxy).
* Для обновлений или подключения дополнительных компонентов кластера необходимо [указать адрес](https://deckhouse.ru/documentation/latest/installing/configuration.html#initconfiguration-deckhouse-imagesrepo) развернутого хранилища с образами контейнеров Deckhouse, прописав в случае необходимости [параметры прав доступа](https://deckhouse.ru/documentation/latest/installing/configuration.html#initconfiguration-deckhouse-registrydockercfg).

Рассмотрим все необходимые этапы по порядку.

## Исходные данные и требования к установке

Пример схемы развертывания Deckhouse в закрытом контуре с прокси-сервером:

![](/files/bE9aK1EPprzMaXlchURs)

Здесь между сетью Интернет и будущим кластером поднят прокси-сервер, через который предоставляется доступ к репозиториям пакетов ОС. Через этот же прокси-сервер можно открыть доступ в Интернет для приложений, настроив соответствующие параметры в конфигурации кластера. Однако использование прокси-сервера — не обязательное условие: кластер может работать и в полностью изолированном контуре.

Также внутри закрытого контура нужно организовать хранилище образов Docker, в котором разместятся образы Deckhouse и образы контейнеров будущих приложений.

## Требования

Для установки Deckhouse понадобятся персональный компьютер, а также два сервера (или ВМ).

Требования к ПК:

* ОС Ubuntu 18.04+, Fedora 35+, Windows 10+ или macOS 10.15+;
* Docker для запуска инсталлятора Deckhouse (см. инструкции по установке для [Ubuntu](https://docs.docker.com/engine/install/ubuntu/), [macOS](https://docs.docker.com/desktop/mac/install/), [Windows](https://docs.docker.com/desktop/windows/install/));
* SSH-доступ по ключу к master-узлу будущего кластера;
* доступ к развернутому хранилищу с образами контейнеров Deckhouse;
* [crane](https://gitlab.com/johnmkane/tech-recipe-book/-/blob/main/Book/Architect/Kubernetes/Frameworks/Deckhouse/On%20premise%20Install/README/README.md), jq.

Требования к серверу или ВМ для master-узла:

* 4 ядра CPU;
* 8 Гб RAM;
* не менее 40 Гб на диске;
* установленная ОС ([на выбор](https://deckhouse.ru/documentation/v1/supported_versions.html));
* доступ к развернутому хранилищу с образами контейнеров Deckhouse;
* доступ к прокси-серверу для скачивания deb/rpm-пакетов ОС (при необходимости);
* SSH-доступ от персонального компьютера (см. п.1) по ключу;
* на узле не должно быть установлено пакетов container runtime, например containerd или Docker.

Также нужен сервер или ВМ для развертывания хранилища образов Deckhouse и образов приложений.

## Установка container registry

В качестве container registry будем использовать [Harbor](https://goharbor.io/) — популярный Open Source-инструмент, с помощью которого можно развернуть self-hosted хранилище Docker-образов.

### Подготовка машины

[В официальной документации](https://goharbor.io/docs/2.7.0/install-config/) разработчики Harbor рекомендуют следующие минимальные характеристики машины для хранилища:

* 2 ядра CPU;
* 4 Гб RAM;
* 40 Гб на жестком диске.

*Рекомендуемые требования: 4 ядра, 8 Гб оперативной памяти и 160 Гб на жестком диске.*

Для тестов возьмем машину с минимальными требованиями, установленной Ubuntu 22.04 и без прямого доступа к Интернету.

Помимо требований к «железу» в документации указаны также и требования к установленному ПО:

* Docker Engine 17.06.0+;
* Docker Compose;
* OpenSSL (желательно последней доступной версии).

Для установки софта требуется доступ к репозиториям пакетов дистрибутива. Временно предоставим его через поднятый прокси-сервер.

*Настройка прокси или NAT в этой статье не рассматривается, потому что выходит за ее рамки. К тому же это процесс зависит от инфраструктуры, на которой разворачивается Deckhouse*.

### Установка Docker Engine

Подключимся по SSH к машине и добавим новый репозиторий в `/etc/sources.list`:

```
sudo apt update
sudo apt install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
```

Добавим GPG-ключи репозитория:

```
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
```

Подключим новый репозиторий:

```
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```

Установим последнюю версию Docker Engine:

```
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
```

Убедимся, что Docker Engine работает:

```
sudo docker run hello-world
```

Если все прошло успешно, будет запущен тестовый контейнер, который выведет сообщение `Hello from Docker!`.

### Установка Docker Compose

Установим docker-compose командой:

```
sudo apt install docker-compose
```

### Установка OpenSSL

Скорее всего, последняя версия OpenSSL уже установлена в системе. Если нет, выполним команду:

```
sudo apt install openssl
```

### Установка Harbor

Harbor поддерживает установку двумя способами — онлайн и офлайн. У обоих схожий принцип. Но поскольку мы уже настроили доступ в Интернет на время подготовки машины к установке, воспользуемся первым вариантом.

В соответствии [с официальной документацией](https://goharbor.io/docs/2.7.0/install-config/download-installer/) скачиваем с GitHub [последний актуальный релиз](https://github.com/goharbor/harbor/releases) (на момент написания статьи это v2.5.5):

```
$ curl -OL https://github.com/goharbor/harbor/releases/download/v2.5.5/harbor-online-installer-v2.5.5.tgz
```

*Ключ **L** нужен для того, чтобы curl прошел по всем редиректам, которые будет предлагать ему GitHub. Если попытаться просто скачать файл (только ключ **-O**), велика вероятность, что он окажется пустым.*

Распаковываем установщик:

```
$ tar -xzvf ./harbor-online-installer-v2.5.5.tgz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl
```

### Настройка перед установкой

Harbor настраивается в файле `harbor.yml`. В распакованном архиве есть его шаблон с расширением `*.tmpl`, в котором уже заданы рекомендуемые параметры.

Переименуем шаблон в `harbor.yml` и отредактируем нужные параметры\*\*:\*\*

```
$ mv ./harbor.yml.tmpl ./harbor.yml
$ vim ./harbor.yml
```

На что следует обратить внимание:

* `HTTPS` — важен, если хранилище используется в production. Для настройки поддержки HTTPS необходимо [добавить соответствующие сертификаты](https://goharbor.io/docs/2.7.0/install-config/configure-https/). В нашем случае можно обойтись без него, поэтому закомментируем эти строки.
* `hostname` — имя хоста хранилища образов. Это может быть как доменное имя, так и IP-адрес.
* `harbor_admin_password` — пароль администратора для входа в систему.

### Установка

Запускаем установку командой:

```
sudo ./install.sh
```

Установщик скачает все необходимые для работы Harbor образы и запустит сервис. Если все прошло успешно, в конце лога будет сообщение `✔ ----Harbor has been installed and started successfully.----`.

Откроем браузер на машине, с которой будет разворачиваться Deckhouse, и перейдем по адресу машины, на которой развернут Harbor.

![](/files/GCEDENz69EMn9xNclIsX)

Страница входа в Harbor

Теперь переходим к установке платформы.

## Установка Deckhouse

### Получение образов Deckhouse

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

* Настроить Proxy Cache в Harbor. В этом режиме он будет работать как прокси-сервер для всех запросов к хранилищу `https://registry.deckhouse.io`**,** кэшируя получаемые образы и раздавая их в закрытое окружение.
* Перенести в Harbor образы вручную. Актуально, если при установке использовался офлайн-способ, и доступа наружу из окружения нет.

Рассмотрим первый вариант. (О ручном переносе образов можно прочитать [в документации](https://deckhouse.ru/documentation/v1/deckhouse-faq.html#%D1%80%D1%83%D1%87%D0%BD%D0%B0%D1%8F-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B0-%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2-%D0%B2-%D0%B8%D0%B7%D0%BE%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9-%D0%BF%D1%80%D0%B8%D0%B2%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-registry).)

### Настройка Proxy Cache

Войдем в систему: имя пользователя по умолчанию `admin`, пароль — тот, что указан в конфигурационном файле.

![](/files/mKWSMP4mAWR9pO3ucmSu)

Главная страница интерфейса Harbor

*При необходимости имя пользователя можно изменить в настройках профиля.*

Перейдем на страницу *Administration* → *Registries* → *New Endpoint*:

![](/files/C2FtUPK8P5jE5jSV9n3j)

В открывшемся окне настроим следующие параметры:

* *Provider*: Docker Registry.
* *Name* — имя, может быть любым.
* *Description* — краткое описание, можно оставить пустым.
* *Endpoint URL*: `https://registry.deckhouse.io`.
* *Access ID* и *Access Secret* — если используется Deckhouse Enterprise Edition; в нашем случае оставляем пустым.

![](/files/WpkiHISHkmh2Ea4MpaaM)

Кнопкой *Test Connection* можно проверить, что Harbor получил доступ к указанному хранилищу и готов к работе.

Теперь вернемся на главную вкладку *Projects* и создадим новый проект:

* `Project Name` — станет частью URL. Используйте любой, например, `d8s`.
* `Access Level` — Public.
* `Proxy Cache` — включаем и выбираем в списке Registry, созданный на предыдущем шаге.

![](/files/4gLMq2MoRN2Q0xuaEoTF)

Теперь все образы Deckhouse будут доступны по адресу `https://your-harbor.com/d8s/deckhouse/{d8s-edition}:{d8s-version}`.

### Настройка будущего кластера

Переходим [на страницу конфигурации](https://deckhouse.ru/gs/bm-private/step3.html) в Getting Started. Здесь нужно ввести параметры, которые в дальнейшем будут указаны в конфигурационных файлах будущего кластера:

* Шаблон DNS-имён кластера в формате `%s.domain.my` — по нему будут доступны веб-интерфейсы, предоставляемые Deckhouse. Например, Grafana — по адресу `grafana.domain.my`.
* Адрес прокси-сервера для HTTP-трафика (если необходимо), через который будет предоставляться доступ в Интернет изнутри кластера.
* Адрес прокси-сервера для HTTPS-трафика.
* Список IP-адресов, для которых проксирование трафика не будет включено.

![](/files/7gQtclrxcDjyO2lu2QlQ)

В следующей части страницы настраиваем доступ к созданному ранее container registry:

![](/files/m7j9bbFBkZ5KU8vRQGMf)

В поле префикса имени образов указываем созданный ранее endpoint в хранилище: `your-harbor.com/d8s/deckhouse/ce`.

Теперь нужно авторизоваться в container registry. Так как мы используем HTTP-протокол, необходимо указать Docker-server'у, к каким хранилищам допустимо присоединяться без шифрования. Для этого откроем файл `/etc/docker/daemon.json` (если его нет — создадим) и добавим туда хранилище:

```
{
  "insecure-registries" : ["http://myregistrydomain.com"]
}
```

Вместо доменного имени можно использовать IP-адрес хранилища во внутренней сети.

Перезапускаем Docker-server, чтобы параметры подхватились, и логинимся в хранилище:

```
$ docker login http://your-harbor.com
```

Теперь закодируем параметры доступа в Base64:

```
$ base64 ~/.docker/config.json
```

Полученную в ответ строку копируем в поле с правами доступа.

Так как мы не стали ранее настраивать HTTPS-доступ к хранилищу, последний пунктом нужно включить использование только HTTP-трафика.

Нажимаем кнопку «*Далее: Установка*» внизу страницы.

![](/files/XcEchDZW8xY9oiIc50tc)

На следующей странице отобразится содержимое файла `config.yml`, сгенерированного на основе введенных ранее данных:

```
# Секция с общими параметрами кластера.
# https://deckhouse.ru/documentation/v1/installing/configuration.html#clusterconfiguration
apiVersion: deckhouse.io/v1
kind: ClusterConfiguration
clusterType: Static
# Адресное пространство Pod'ов кластера.
podSubnetCIDR: 10.111.0.0/16
# Адресное пространство для service'ов кластера.
serviceSubnetCIDR: 10.222.0.0/16
kubernetesVersion: "1.23"
clusterDomain: "cluster.local"
---
# Секция первичной инициализации кластера Deckhouse.
# https://deckhouse.ru/documentation/v1/installing/configuration.html#initconfiguration
apiVersion: deckhouse.io/v1
kind: InitConfiguration
deckhouse:
  releaseChannel: Stable
  configOverrides:
    global:
      modules:
        # Шаблон, который будет использоваться для составления адресов системных приложений в кластере.
        # Например, Grafana для %s.example.com будет доступна на домене grafana.example.com.
        publicDomainTemplate: "%s.example.com"
    # Включить модуль cni-flannel.
    # Возможно, захотите изменить.
    cniFlannelEnabled: true
    # Настройки модуля cni-flannel.
    # Возможно, захотите изменить.
    cniFlannel:
      # Режим работы flannel, допустимые значения VXLAN (если ваши сервера имеют связность L3) или HostGW (для L2-сетей).
      podNetworkMode: VXLAN
  # Адрес Docker registry с образами Deckhouse.
  imagesRepo: your-harbor.com/d8s/deckhouse/ce
  # Строка с ключом для доступа к Docker registry.
  registryDockerCfg: ewoJImF1LjAuMzMiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVlt OXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
  # Протокол доступа к registry (HTTP или HTTPS).
  registryScheme: HTTP
```

В этом примере мы создаем простой кластер из одного узла с одним адресом, поэтому секцию `StaticClusterConfiguration` сгенерированного конфигурационного файла можно удалить.

Сохраним содержимое в файл и разместим его в отдельном каталоге с произвольным именем.

### Развертывание кластера

Установщик Deckhouse запускается в отдельном контейнере командой:

```
docker run --pull=always -it -v "$PWD/config.yml:/config.yml" -v "$HOME/.ssh/:/tmp/.ssh/" your-harbor.com/d8s/deckhouse/ce/install:stable bash
```

*Обратите внимание, что здесь в качестве источника образа указано локальное хранилище, созданное на предыдущих шагах.*

По окончании загрузки появится приглашение командной строки внутри контейнера:

```
[deckhouse] root@8e5bd71f05b4 / #
```

Для развертывания кластера достаточно выполнить одну команду:

```
dhctl bootstrap --ssh-user=<username> --ssh-host=<master_ip> --ssh-agent-private-keys=/tmp/.ssh/id_rsa \
  --config=/config.yml \
  --ask-become-pass
```

Если на сервере для работы с *sudo* требуется пароль, нужно его ввести в ответ на соответствующий запрос.

Процесс установки может занять от 15 до 30 минут, состояние отображается в виде подробного лога.

## Получение доступа к кластеру

Установленный кластер состоит из одного узла. Добавить в него статичные узлы можно по инструкции [из официальной документации](https://deckhouse.ru/documentation/latest/modules/040-node-manager/faq.html#%D0%BA%D0%B0%D0%BA-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-%D1%81%D1%82%D0%B0%D1%82%D0%B8%D1%87%D0%BD%D1%8B%D0%B9-%D1%83%D0%B7%D0%B5%D0%BB-%D0%B2-%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80).

Если же кластер развернут в ознакомительных целях либо для какой-то специфической задачи, и дополнительные узлы не требуются — нужно разрешить компонентам Deckhouse работать на master-узле. Для этого снимем с master-узла taint, выполнив на нем команду:

```
kubectl patch nodegroup master --type json -p '[{"op": "remove", "path": "/spec/nodeTemplate/taints"}]'
```

Если в ответ выводится ошибка:

```
The connection to the server localhost:8080 was refused - did you specify the right host or port?
```

…нужно настроить kubectl командой:

```
sudo cat /etc/kubernetes/admin.conf >> ~/.kube/config
```

### Установка Ingress-контроллера

Создадим на master-узле файл `ingress-nginx-controller.yml` со следующим содержимым:

```
# Секция, описывающая параметры Nginx Ingress controller.
# https://deckhouse.ru/documentation/v1/modules/402-ingress-nginx/cr.html
apiVersion: deckhouse.io/v1
kind: IngressNginxController
metadata:
  name: nginx
spec:
  # Имя Ingress-класса для обслуживания Ingress NGINX controller.
  ingressClass: nginx

  # Способ поступления трафика из внешнего мира.
  inlet: HostPort
  hostPort:
    httpPort: 80
    httpsPort: 443
  # Описывает, на каких узлах будет находиться компонент.
  # Возможно, захотите изменить.
  nodeSelector:
    node-role.kubernetes.io/master: ""
  tolerations:
  - operator: Exists
```

Применим его:

```
kubectl create -f ingress-nginx-controller.yml
```

### Создание пользователя для доступа в веб-интерфейсы

Создадим на master-узле файл `user.yml` со следующим содержимым:

```
# Настройки RBAC и авторизации.
# https://deckhouse.ru/documentation/v1/modules/140-user-authz/cr.html#clusterauthorizationrule
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
---
# Данные статического пользователя.
# https://deckhouse.ru/documentation/v1/modules/150-user-authn/cr.html#user
apiVersion: deckhouse.io/v1
kind: User
metadata:
  name: admin
spec:
  # E-mail пользователя.
  email: admin@deckhouse.io
  # Это хэш пароля tk6776lyo2, сгенерированного сейчас.
  # Сгенерируйте свой или используйте этот, но только для тестирования:
  # echo "tk6776lyo2" | htpasswd -BinC 10 "" | cut -d: -f2
  # Возможно, захотите изменить.
  password: '$2a$10$/8aOtxwur79/lAUawVQYkOcb5Z55ooIRdJf5PH45oqVcoeD3ebtR.'
```

*Обратите внимание, что в секции с паролем есть подсказка, как его сгенерировать.*

Применим файл:

```
kubectl create -f user.yml
```

### Настройка DNS-записей

Для доступа к веб-интерфейсам кластера нужно настроить resolve соответствующих адресов. Это можно сделать несколькими способами: настроить полноценный DNS-сервер, прописать их в файл `/etc/hosts` или воспользоваться сторонними сервисами, предоставляющими такие услуги.

Веб-интерфейсы расположены по следующим адресам:

* api.example.com
* argocd.example.com
* dashboard.example.com
* deckhouse.example.com
* dex.example.com
* grafana.example.com
* hubble.example.com
* istio.example.com
* istio-api-proxy.example.com
* kubeconfig.example.com
* openvpn-admin.example.com
* prometheus.example.com
* status.example.com
* upmeter.example.com

Для доступа к ним необходимо настроить адресацию на IP-адрес Ingress-контроллера.

Кластер развернут и готов к работе.

## Удаление кластера (обновлено)

Изначально был неверно описан способ удаления кластера с помощью команды `dhctl destroy`. В случае с self-hosted-кластером команда завершится с ошибками, а элементы кластера не будут удалены.

Для удаления кластера, развернутого на ВМ или bare-metal сервере, необходимо **выполнить шаги с 1 по 7** [инструкции по зачистке узла](https://deckhouse.ru/documentation/v1/modules/040-node-manager/faq.html#%D0%BA%D0%B0%D0%BA-%D0%B7%D0%B0%D1%87%D0%B8%D1%81%D1%82%D0%B8%D1%82%D1%8C-%D1%83%D0%B7%D0%B5%D0%BB-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B5%D0%B3%D0%BE-%D0%B2%D0%B2%D0%BE%D0%B4%D0%B0-%D0%B2-%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80).

*Обратите внимание, что если выполнить последующие шаги с 8 по 10, на узел можно снова установить необходимые компоненты, и такой узел станет готовым для последующего введения в другой кластер.*

## P.S.

Статья основана на материалах раздела сайта [«Getting Started»](https://deckhouse.ru/gs/bm-private/step2.html). Подробную информацию о дальнейшей настройке платформы и ее модулей можно найти [в официальной документации](https://deckhouse.ru/documentation/v1/deckhouse-overview.html).

С любыми вопросами и предложениями ждем вас в комментариях к статье, а также в Telegram-чате [deckhouse\_ru](https://t.me/deckhouse_ru), где всегда готовы помочь. Будем рады issues (и, конечно, звёздам) [в GitHub-репозитории Deckhouse](https://github.com/deckhouse/deckhouse).

Читайте также в нашем блоге:

* [«Разворачиваем Kubernetes-платформу Deckhouse в Yandex Cloud»](https://habr.com/ru/company/flant/blog/707422/);
* [«Настройка LDAP-аутентификации в кластере Kubernetes под управлением Deckhouse»](https://q.flant.com/?class=other\&query=Deckhouse\&sources%5B%5D=loghouse\&sources%5B%5D=flantblog#:~:text=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0%20LDAP%2D%D0%B0%D1%83%D1%82%D0%B5%D0%BD%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D0%B8%20%D0%B2%20%D0%BA%D0%BB%D0%B0%D1%81%D1%82%D0%B5%D1%80%D0%B5%20Kubernetes%20%D0%BF%D0%BE%D0%B4%20%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC%20Deckhouse);
* [«Deckhouse соответствует большинству рекомендаций PCI Security Standards Council»](https://habr.com/ru/company/flant/news/t/711730/).
