Включение модуля

Модуль работает в одной из двух редакций, и она определяется наличием лицензионного ключа в ModuleConfig. Выберите редакцию до включения модуля.

Базовый Stronghold — лицензионный ключ не требуется, достаточно включить модуль:

d8 system module enable stronghold

Stronghold EE — создайте ModuleConfig с лицензионным ключом в параметре spec.settings.license. Отдельная команда включения не нужна: модуль включает spec.enabled: true в манифесте.

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: stronghold
spec:
  enabled: true
  version: 1
  settings:
    license: <STRONGHOLD_EE_LICENSE_KEY>

Stronghold EE лицензируется отдельно и доступен для использования только в коммерческих редакциях Deckhouse Platform. Сравнение редакций — в разделе «Редакции».

Если модуль уже работает и в хранилище есть данные, добавляйте ключ по инструкции по переключению на редакцию EE

Подробнее о включении и первичной настройке — в бесплатном курсе «Обзор возможностей Deckhouse Stronghold» Академии Deckhouse.

По умолчанию модуль запустится в режиме Automatic (management.mode) с инлетом Ingress (inlet).

Доступны следующие режимы и инлеты:

  • management.mode: Automatic (по умолчанию) или Manual.
  • inlet: Ingress (по умолчанию), GatewayAPI, LoadBalancer, NodePort или None. Для LoadBalancer, NodePort и None обязательно укажите https.mode: CustomCertificate.

Выключение модуля

Чтобы выключить модуль, выполните команду:

d8 k annotate mc stronghold modules.deckhouse.io/allow-disabling=true
d8 system module disable stronghold

Отключение модуля требует подтверждения, поэтому сначала необходимо установить аннотацию modules.deckhouse.io/allow-disabling=true.

При отключении модуля удалятся все контейнеры Stronghold из неймспейса d8-stronghold, а так же секрет stronghold-keys с root-ключом и ключами распечатывания. Если storageClass не задан, данные сервиса не удалятся с узла (подробнее — ниже); если storageClass задан, данные хранятся в PVC data-stronghold-N, которые удаляются вместе с StatefulSet. Вы можете включить модуль снова, создать и поместить в неймспейс d8-stronghold сохранённую копию секрета stronghold-keys, тогда доступ к данным будет восстановлен.

Если storageClass не задан и старые данные больше не нужны, нужно предварительно удалить директорию /var/lib/deckhouse/stronghold со всех узлов, на которых хранятся данные Stronghold (по умолчанию master-узлы). Если storageClass задан, данные находятся в PVC data-stronghold-N, а не в этой директории.

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

Доступ к сервису осуществляется через инлеты. Инлет - это источник входных данных для пода. Поддерживаются инлеты Ingress (по умолчанию), GatewayAPI, LoadBalancer, NodePort и None. В примерах ниже используется Ingress.

Адрес веб-интерфейса Stronghold формируется следующим образом: в шаблоне publicDomainTemplate глобального параметра конфигурации Deckhouse ключ %s заменяется на stronghold. Например, если publicDomainTemplate установлен как %s-kube.mycompany.tld, веб-интерфейс Stronghold будет доступен по адресу stronghold-kube.cmycompany.tld.

Использование хранилища данных. Режимы работы

Информация, содержащаяся в Stronghold, защищена шифрованием. Для того чтобы расшифровать данные хранилища, требуется ключ шифрования. Этот ключ также сохраняется вместе с данными (в хранилище ключей), однако он зашифрован другим ключом, который называется root-ключом.

Для расшифровки данных Stronghold сначала расшифровывает ключ шифрования, используя root-ключ. Доступ к root-ключу осуществляется через процесс, называемый распечатыванием хранилища. Root-ключ хранится вместе с остальными данными хранилища, однако шифруется ещё одним ключом — ключом распечатывания.

Модуль поддерживает два режима, задаваемых параметром management.mode: Automatic (по умолчанию) и Manual.

В режиме Automatic при первом запуске модуля происходит автоматическая инициализация хранилища. В процессе инициализации ключ распечатывания и root-токен помещаются в секрет stronghold-keys неймспейса kubernetes d8-stronghold. После инициализации модуль автоматически распечатывает узлы кластера Stronghold. В автоматическом режиме, при перезапуске узлов Stronghold, хранилище также будет автоматически распечатано без вмешательства пользователя.

В режиме Manual автоматическая инициализация отключена, интеграции с Dex и Kubernetes не настраиваются, секрет stronghold-keys не создаётся, а параметр management.administrators недоступен. Инициализацию и распечатывание хранилища нужно выполнять самостоятельно.

Управление доступами

В автоматическом режиме Automatic в Stronghold после инициализации хранилища создаётся политика deckhouse_administrators, для которой включается доступ к веб-интерфейсу через OIDC аутентификацию Dex. Также настраивается автоматическое подключение текущего кластера Deckhouse к Stronghold для работы модуля secrets-store-integration.

Практический разбор доставки секретов в приложение — в курсе «Обзор возможностей Deckhouse Stronghold».

Для того, чтоб выдать права пользователям, находящимся в группе admins (членство в группе передаётся из используемого IdP или LDAP с помощью Dex), нужно указать эту группу в массиве management.administrators в ModuleConfig (доступно только при management.mode: Automatic; у каждого элемента есть type — Group или User — и name):

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: stronghold
spec:
  enabled: true
  version: 1
  settings:
    management:
      mode: Automatic
      administrators:
      - type: Group
        name: admins

Для того, чтоб выдать права administrator пользователям manager и securityoperator, можно использовать следующие параметры в ModuleConfig:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: stronghold
spec:
  enabled: true
  version: 1
  settings:
    management:
      mode: Automatic
      administrators:
      - type: User
        name: manager@mycompany.tld
      - type: User
        name: securityoperator@mycompany.tld

Несмотря на возможность назначать доступ отдельным пользователям, для аутентификации через OIDC они должны входить хотя бы в одну группу.

В дальнейшем можно создать пользователей в Stronghold с различными правами доступа к секретам с помощью встроенного механизма хранилища.

Первый запуск

Перед первым включением модуля Stronghold (при пустом storageClass) директория /var/lib/deckhouse/stronghold должна отсутствовать в файловой системе узлов, на которых будут запускаться узлы Stronghold (по умолчанию это master-узлы) и отключённый модуль stronghold.

Нужен опыт работы с утилитой kubectl.

Ниже приведены варианты организации доступа к модулю через инлет Ingress и далее процесс включения модуля и проверки работоспособности.

Способы организации доступа через инлет Ingress

ClusterIssuer LetsEncrypt

Этот метод получения сертификата настроен по умолчанию. Однако он подходит только для сервисов, доступных из Интернета (и не подходит для внутренних сетей). Для проверки доступности:

  1. Получите адрес платформы аутентификации:

    d8 k -n d8-user-authn get ing dex
    # Ожидаемый ответ:
    # NAME   CLASS   HOSTS               ADDRESS         PORTS     AGE
    # dex    nginx   dex.mycompany.tld   34.85.243.109   80, 443   4d20h

    В столбце HOSTS указан проверяемый домен, а в столбце ADDRESS — его IP-адрес. Теперь необходимо убедиться, что доменное имя указывает на этот IP-адрес. Для этого выполните команду:

    nslookup dex.mycompany.tld 8.8.8.8
    # Ожидаемый ответ:
    # ...
    # Name: dex.mycompany.tld
    # Address: 34.85.243.109
    # ...
    
    # Либо:
    dig @8.8.8.8 dex.mycompany.tld
    # Ожидаемый ответ:
    # ...
    # ;; ANSWER SECTION:
    # dex.mycompany.tld. 3600 IN A 34.85.243.109
    # ...

    Если ответом стала ошибка с кодом NXDOMAIN, нужно настроить DNS пользователя.

  2. В браузере откройте https://dex.mycompany.tld/healthz, либо выполните команду curl -kL https://dex.mycompany.tld/healthz. Должен вернуться ответ Health check passed.

  3. Проверьте, что Ingress-контроллер обрабатывает запросы на ваш поддомен stronghold.mycompany.tld. Снова в браузере, либо командой curl -kL откройте https://stronghold.mycompany.tld. Должна вернуться 404 ошибка.

ClusterIssuer с самоподписанным центром сертификации

Этот вариант подходит, если вы хотите использовать свой самоподписанный центр сертификации. В качестве примера используется уже созданный ClusterIssuer selfsigned. Чтобы добавить Issuer или ClusterIssuer со своим самоподписанным центром сертификации, воспользуйтесь официальной документацией.

Для этого способа подойдёт как наличие публичного доменного имени, так и доступ только из внутренней сети.

Отредактируйте глобальные настройки модуля. Для этого воспользуйтесь командой d8 k edit mc global. Добавьте параметр settings.modules.https.certManager.clusterIssuerName: selfsigned. Итоговая конфигурация модуля:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: global
spec:
  settings:
    modules:
      https:
        certManager:
          # Единственный параметр, который нужно добавить.
          clusterIssuerName: selfsigned
      publicDomainTemplate: '%s.mycompany.tld'
  version: 1

Далее отредактируйте настройки модуля user-authn. Выполните команду d8 k edit mc user-authn и измените параметр settings.controlPlaneConfigurator.dexCAMode на FromIngressSecret:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: user-authn
spec:
  enabled: true
  settings:
    controlPlaneConfigurator:
      # Параметр, который нужно изменить.
      dexCAMode: FromIngressSecret
  ...

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

  1. Получите адрес платформы аутентификации командой:

    d8 k -n d8-user-authn get ing dex
    # Ожидаемый ответ:
    # NAME   CLASS   HOSTS               ADDRESS         PORTS     AGE
    # dex    nginx   dex.mycompany.tld   34.85.243.109   80, 443   4d20h

    В столбце HOSTS указан проверяемый домен, а в столбце ADDRESS — его IP-адрес. Теперь необходимо убедиться, что доменное имя указывает на этот IP-адрес. Для этого выполните команду:

    nslookup dex.mycompany.tld
    # Ожидаемый ответ:
    # ...
    # Name: dex.mycompany.tld
    # Address: 34.85.243.109
    # ...
    
    # Либо:
    dig dex.mycompany.tld
    # Ожидаемый ответ:
    # ...
    # ;; ANSWER SECTION:
    # dex.mycompany.tld. 3600 IN A 34.85.243.109
    # ...

    Если ответом стала ошибка с кодом NXDOMAIN, нужно настроить DNS пользователя. Если домен недоступен из Интернета, необходимо выполнить дополнительный шаг.

    Как временное решение можно добавить следующую строку в файл /etc/hosts вашей Unix-системы:

    34.85.243.109 dex.mycompany.tld stronghold.mycompany.tld
  2. В браузере откройте https://dex.mycompany.tld/healthz, либо выполните команду curl -kL https://dex.mycompany.tld/healthz. Должен вернуться ответ Health check passed.

  3. Проверьте, что Ingress-контроллер обрабатывает запросы на ваш поддомен stronghold.mycompany.tld. Снова в браузере, либо командой curl -kL откройте https://stronghold.mycompany.tld. Должна вернуться 404 ошибка.

Через файл сертификата

Необходимо создать СА и сертификат, после чего подписать сертификат этим СА. Если СА уже существует, можно подписать сертификат существующим СА. Сертификат должен быть сформирован с полной цепочкой (fullchain).

Ниже представлен скрипт createCertificate.sh, который с помощью openssl создаёт нужную пару сертификат + ключ для домена mycompany.tld (*.mycompany.tld).

#!/bin/bash

set -e
# Имя CA (CN).
caName="MyOrg-RootCA"
# Имя кластерного домена (параметр publicDomainTemplate).
publicDomain="mycompany.tld"
# Имя сертификата для кластера (CN).
certName="kubernetes"

mkdir -p "${caName}"
cd "${caName}"

[ ! -f "${caName}.key" ] && openssl genrsa -out "${caName}.key" 4096

[ ! -f "${caName}.crt" ] &&  openssl req -x509 -new -nodes -key "${caName}.key" -sha256 -days 1826 -out "${caName}.crt" \
   -subj "/CN=${caName}/O=MyOrganisation"

openssl req -new -nodes -out ${certName}.csr -newkey rsa:4096 -keyout "${certName}.key" \
  -subj "/CN=${certName}/O=MyOrganisation"

# v3 ext file
cat > "${certName}.v3.ext" << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${publicDomain}
DNS.2 = *.${publicDomain}
EOF

openssl x509 -req -in "${certName}.csr" -CA "${caName}.crt" -CAkey "${caName}.key" -CAcreateserial -out "${certName}.crt" -days 730 -sha256 -extfile "${certName}.v3.ext"

cat "${certName}.crt" "${caName}.crt" > "${certName}_fullchain.crt"

Используя полученные файлы kubernetes.key и kubernetes_fullchain.crt нужно создать секрет в неймспейсе d8-system.

d8 k -n d8-system create secret tls mycompany-wildcard-tls --cert=kubernetes_fullchain.crt --key=kubernetes.key

Для использования полученного сертификата в кластере нужно привести глобальную конфигурацию к следующему виду, выполнив команду d8 k edit mc global:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: global
spec:
  settings:
    modules:
      https:
        customCertificate:
          # Здесь указываем название объекта Secret, содержащего fullchain сертификат и ключ.
          secretName: mycompany-wildcard-tls
        # Меняем режим работы с tls для всех модулей.
        mode: CustomCertificate
      publicDomainTemplate: '%s.mycompany.tld'

Также требуется настроить модуль user-authn, включив в настройках controlPlaneConfigurator.dexCAMode в значение FromIngressSecret. В этом случае CA будет получен из цепочки, которая помещена в файл kubernetes_fullchain.crt.

Пример

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: user-authn
spec:
  enabled: true
  settings:
    controlPlaneConfigurator:
      dexCAMode: FromIngressSecret
  ...

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

  1. Получите адрес платформы аутентификации командой:

    d8 k -n d8-user-authn get ing dex
    # Ожидаемый ответ:
    # NAME   CLASS   HOSTS               ADDRESS         PORTS     AGE
    # dex    nginx   dex.mycompany.tld   34.85.243.109   80, 443   4d20h

    В столбце HOSTS указан проверяемый домен, а в столбце ADDRESS — его IP-адрес. Теперь необходимо убедиться, что доменное имя указывает на этот IP-адрес. Для этого выполните команду:

    nslookup dex.mycompany.tld
    # Ожидаемый ответ:
    # ...
    # Name: dex.mycompany.tld
    # Address: 34.85.243.109
    # ...
    
    # Либо:
    dig dex.mycompany.tld
    # Ожидаемый ответ:
    # ...
    # ;; ANSWER SECTION:
    # dex.mycompany.tld. 3600 IN A 34.85.243.109
    # ...

    Если ответом стала ошибка с кодом NXDOMAIN, нужно настроить DNS пользователя. Если домен не доступен из Интернета, необходимо выполнить дополнительный шаг.

    Как временное решение можно добавить следующую строку в файл /etc/hosts вашей Unix-системы:

    34.85.243.109 dex.mycompany.tld stronghold.mycompany.tld
  2. В браузере откройте https://dex.mycompany.tld/healthz, либо выполните команду curl -kL https://dex.mycompany.tld/healthz. Должен вернуться ответ Health check passed.

  3. Проверьте, что Ingress-контроллер обрабатывает запросы на ваш поддомен stronghold.mycompany.tld. Снова в браузере, либо командой curl -kL откройте https://stronghold.mycompany.tld. Должна вернуться 404 ошибка.

Действия при отсутствии DNS-разрешения для dex.mycompany.tld

Если домен не разрешается через DNS и планируется использование файла hosts, для работы Dex необходимо добавить адрес балансировщика или IP frontend-узла в кластерный DNS. В его роли можно использовать модуль kube-dns, чтобы поды могли получить доступ к домену dex.mycompany.tld по имени.

Пример получения IP для Ingress nginx-load-balancer с типом LoadBalancer:

d8 k -n d8-ingress-nginx get svc nginx-load-balancer -o jsonpath='{ .spec.clusterIP }'

Предположим, адрес — 34.85.243.109. Конфигурация модуля kube-dns для этого адреса:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: kube-dns
spec:
  version: 1
  enabled: true
  settings:
    hosts:
    - domain: dex.mycompany.tld
      ip: 34.85.243.109

Включение модуля

После организации доступа включите модуль stronghold. Инициализация и настройка интеграции с dex произойдёт автоматически.

d8 system module enable stronghold

После запуска модуля:

  1. Убедитесь в наличии сертификата для домена stronghold.* с помощью команды d8 k -n d8-stronghold get secret ingress-tls (либо через консоль). В разделе «Устранение неполадок» есть описания решений возможных проблем с отсутствием сертификата.
  2. Убедитесь в доступности адреса https://stronghold.mycompany.tld/v1/sys/health.
  3. Проверьте соответствие Издателя сертификата и CA-сертификата (опционально).

Устранение неполадок

Поды в состоянии ContainerCreating, объекта Secret с названием ingress-tls нет

Проверьте статус пода Stronghold:

d8 k -n d8-stronghold describe pod stronghold-0

Найдите строку:

MountVolume.SetUp failed for volume "certificates" : secret "ingress-tls" not found

При использовании метода ClusterIssuer с LetsEncrypt может возникнуть проблема с автоматическим созданием сертификата для домена stronghold.mycompany.tld центром сертификации Let’s Encrypt.

Получите список CertificateRequest:

d8 k -n d8-stronghold get certificaterequest

Найдите среди них объект начинающийся с stronghold-, для примера это будет stronghold-b5wc6:

Проверьте его статус:

d8 k -n d8-stronghold describe certificaterequest stronghold-b5wc6

Одной из причин может быть ошибка too many certificates already issued for mycompany.tld, в особенности, если используется бесплатный dynDNS сервис, например sslip.io или getmoss.site. В этом случае необходимо либо дождаться окончания ограничения, либо использовать другой способ создания сертификата для домена stronghold.mycompany.tld (ClusterIssuer selfsigned или ручная подпись сертификата).

При успешном завершении генерации сертификата в статусе CertificateRequest должны быть строчки:

Message:               Certificate fetched from issuer successfully
Reason:                Issued
Status:                True
Type:                  Ready

Также должен появиться объект Secret типа kubernetes.io/tls с названием ingress-tls.

Мониторинг

В Deckhouse Platform модуль автоматически настраивает сбор метрик и алерты: ручная настройка не требуется. Схема сбора метрик, перечень алертов и способ ручного запроса метрик описаны в разделе «Мониторинг в Deckhouse Platform».