# 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/).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.konstantinsecurity.com/readme/architect/kubernetes/frameworks/deckhouse/on-premise-install.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
