Продолжаем серию статей про установку Deckhouse в разные окружения. Мы уже рассказывали про развертывание в Yandex Cloud. Эта статья посвящена установке платформы в закрытое окружение, когда у машин, на которых разворачивается кластер, нет доступа в Интернет.

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

  • Чтобы предоставить приложениям доступ в Интернет в закрытом контуре, нужно явно указать параметры прокси-сервера в конфигурации кластера.

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

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

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

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

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

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

Требования

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

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

  • ОС Ubuntu 18.04+, Fedora 35+, Windows 10+ или macOS 10.15+;

  • Docker для запуска инсталлятора Deckhouse (см. инструкции по установке для Ubuntu, macOS, Windows);

  • SSH-доступ по ключу к master-узлу будущего кластера;

  • доступ к развернутому хранилищу с образами контейнеров Deckhouse;

  • crane, jq.

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

  • 4 ядра CPU;

  • 8 Гб RAM;

  • не менее 40 Гб на диске;

  • установленная ОС (на выбор);

  • доступ к развернутому хранилищу с образами контейнеров Deckhouse;

  • доступ к прокси-серверу для скачивания deb/rpm-пакетов ОС (при необходимости);

  • SSH-доступ от персонального компьютера (см. п.1) по ключу;

  • на узле не должно быть установлено пакетов container runtime, например containerd или Docker.

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

Установка container registry

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

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

В официальной документации разработчики 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 поддерживает установку двумя способами — онлайн и офлайн. У обоих схожий принцип. Но поскольку мы уже настроили доступ в Интернет на время подготовки машины к установке, воспользуемся первым вариантом.

В соответствии с официальной документацией скачиваем с GitHub последний актуальный релиз (на момент написания статьи это 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 необходимо добавить соответствующие сертификаты. В нашем случае можно обойтись без него, поэтому закомментируем эти строки.

  • hostname — имя хоста хранилища образов. Это может быть как доменное имя, так и IP-адрес.

  • harbor_admin_password — пароль администратора для входа в систему.

Установка

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

sudo ./install.sh

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

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

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

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

Установка Deckhouse

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

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

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

  • Перенести в Harbor образы вручную. Актуально, если при установке использовался офлайн-способ, и доступа наружу из окружения нет. 

Рассмотрим первый вариант. (О ручном переносе образов можно прочитать в документации.)

Настройка Proxy Cache

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

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

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

Перейдем на страницу AdministrationRegistriesNew Endpoint:

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

  • Provider: Docker Registry.

  • Name — имя, может быть любым.

  • Description — краткое описание, можно оставить пустым.

  • Endpoint URL: https://registry.deckhouse.io.

  • Access ID и Access Secret — если используется Deckhouse Enterprise Edition; в нашем случае оставляем пустым.

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

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

  • Project Name — станет частью URL. Используйте любой, например, d8s.

  • Access Level — Public.

  • Proxy Cache — включаем и выбираем в списке Registry, созданный на предыдущем шаге.

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

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

Переходим на страницу конфигурации в Getting Started. Здесь нужно ввести параметры, которые в дальнейшем будут указаны в конфигурационных файлах будущего кластера:

  • Шаблон DNS-имён кластера в формате %s.domain.my — по нему будут доступны веб-интерфейсы, предоставляемые Deckhouse. Например, Grafana — по адресу grafana.domain.my.

  • Адрес прокси-сервера для HTTP-трафика (если необходимо), через который будет предоставляться доступ в Интернет изнутри кластера.

  • Адрес прокси-сервера для HTTPS-трафика.

  • Список IP-адресов, для которых проксирование трафика не будет включено.

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

В поле префикса имени образов указываем созданный ранее 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-трафика.

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

На следующей странице отобразится содержимое файла 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 минут, состояние отображается в виде подробного лога.

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

Установленный кластер состоит из одного узла. Добавить в него статичные узлы можно по инструкции из официальной документации.

Если же кластер развернут в ознакомительных целях либо для какой-то специфической задачи, и дополнительные узлы не требуются — нужно разрешить компонентам 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 инструкции по зачистке узла.

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

P.S.

Статья основана на материалах раздела сайта «Getting Started». Подробную информацию о дальнейшей настройке платформы и ее модулей можно найти в официальной документации.

С любыми вопросами и предложениями ждем вас в комментариях к статье, а также в Telegram-чате deckhouse_ru, где всегда готовы помочь. Будем рады issues (и, конечно, звёздам) в GitHub-репозитории Deckhouse.

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

Комментарии (4)


  1. k3NGuru
    00.00.0000 00:00
    +1

    По поводу переменной registryDockerCfg тут нужно сразу учесть её корректность, которая описывается тут Сам столкнулся с такой проблемой при первичном развертывании.

    И про удаление кластера - его наконец починили? Ибо destroy в основном работал для management решений (облака), для self-hosted не работало (куча ошибок). В итоге приходилось удалять как написано тут


    1. Zhbert Автор
      00.00.0000 00:00
      +1

      И про удаление кластера - его наконец починили? Ибо destroy в основном работал для management решений (облака), для self-hosted не работало (куча ошибок). В итоге приходилось удалять как написано тут

      Спасибо за внимательность :) Удаление кластера с  dhctl destroy и правда не работает для bare metal (и ВМок). Удалить можно, выполнив шаги 1-7 инструкции по зачистке узла, все верно.

      Обновил в статье раздел про удаление.


  1. alexkuzko
    00.00.0000 00:00

    А так ли нужен отдельный docker-compose если его уже некоторое время неплохо заменяет docker compose (без дефиса)? Можно упростить инсталляцию.


    1. zimmermann
      00.00.0000 00:00
      +1

      Compose нужен конечно, не важно какой. Тут в статье используется v1, хотя он уже устаревает конечно и лучше использовать compose v2, который плагином. Но в целом, опять же, это не так важно.