Модуль доступен только в Deckhouse Enterprise Edition.

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

Включите модуль, применив ModuleConfig, как представлено ниже:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: stronghold
spec:
  enabled: true

или выполните команду:

kubectl -n d8-system exec deploy/deckhouse -c deckhouse -it -- deckhouse-controller module enable stronghold

По умолчению модуль запустится в режиме Automatic с инлетом Ingress. В текущей версии другие режимы и инлеты отсутствуют.

Как выключить модуль

Выключить модуль можно, установив в moduleconfig stronghold значение enabled на false Либо выполнив команду:

kubectl -n d8-system exec deploy/deckhouse -c deckhouse -it -- deckhouse-controller module disable stronghold

ВНИМАНИЕ!

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

Если старые данные больше не нужны, нужно предварительно удалить каталог /var/lib/deckhouse/stronghold со всех мастер-нод кластера.

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

Доступ к сервису осуществляется через инлеты. Инлет - это источник входных данных для пода. В примере доступен один инлет - Ingress Адрес веб-интерфейса Stronghold формируется следующим образом: в шаблоне publicDomainTemplate глобального параметра конфигурации Deckhouse ключ %s заменяется на stronghold.

Например, если publicDomainTemplate установлен как %s-kube.mycompany.tld, веб-интерфейс Stronghold будет доступен по адресу stronghold-kube.cmycompany.tld.

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

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

Для раскрытия данных Stronghold расшифрует ключ шифрования, требующий для этого корневой ключ. Доступ к корневому ключу можно получить с помощью процесса, называемого разблокировкой хранилища. Корневой ключ сохраняется вместе со всеми остальными данными хранилища, однако шифруется еще одной технологией: ключом разблокировки.

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

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

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

Для того, чтоб выдать пользователям, находящимся в группе admins (членство в группе передаётся из используемого IdP или LDAP с помощью Dex), нужно указать эту группу в массиве administrators в ModuleConfig:

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:
    configuration:
      mode: Automatic
      administrators:
      - type: User
        name: manager@mycompany.tld
      - type: User
        name: securityoperator@mycompany.tld

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

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

Запуск с самоподписанным сертификатом

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

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

#!/bin/bash

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

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

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

Для использования полученного сертификата в кластере нужно привести конфигурацию модуля global к такому виду. Сделать это можно например командой kubectl edit mc global

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: global
spec:
  settings:
    modules:
      https:
        customCertificate:
          secretName: mycompany-wildcard-tls
        mode: CustomCertificate
      publicDomainTemplate: '%s.mycompany.tld'

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

Пример получения IP для ингресса nginx-load-balancer с типом LoadBlancer

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

Допустим наш адрес 10.202.166.188, тогда модуль-конфиг kube-dns будет выглядеть так

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

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

Пример

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

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

kubectl -n d8-system exec deploy/deckhouse -c deckhouse -it -- deckhouse-controller module enable stronghold