cert-manager выпускает сертификаты через Issuer или ClusterIssuer типа vault, который обращается к механизму секретов PKI по пути <MOUNT>/sign/<ROLE>. Stronghold совместим с API Vault, поэтому такой Issuer можно направить на Stronghold. Эндпоинт <MOUNT>/sign/<ROLE> принимает поля, которые отправляет cert-manager (csr, common_name, alt_names, ip_sans, uri_sans, other_sans, ttl).
В Deckhouse Platform cert-manager устанавливается модулем cert-manager.
Цель
После настройки:
- cert-manager в кластере выпускает и перевыпускает TLS-сертификаты для поддоменов
example.comчерез промежуточный CA в Stronghold. - cert-manager входит в Stronghold через метод аутентификации Kubernetes, поэтому долгоживущие учётные данные Stronghold в кластере не хранятся.
Предварительные требования
Перед началом подготовьте:
- Механизм секретов PKI по пути
pki_intс промежуточным CA и рольюexample-comдля доменаexample.com, как в разделе «Внутренний PKI на Stronghold». - Метод аутентификации Kubernetes, включённый в Stronghold для кластера.
- cert-manager, установленный в кластере.
- Токен Stronghold с правами на запись политик и ролей метода Kubernetes.
- Сертификат CA, которым подписан TLS-сертификат Stronghold.
Шаг 1. Настройте Stronghold
Разрешите cert-manager подписывать запросы на сертификаты по роли example-com.
Создайте политику, разрешающую подписывать запросы на сертификат по роли:
d8 stronghold policy write cert-manager-pki - <<'POLICY' path "pki_int/sign/example-com" { capabilities = ["create", "update"] } POLICYСоздайте роль метода Kubernetes для ServiceAccount
stronghold-issuerв неймспейсеmyapp. Параметрaudienceдолжен совпадать с аудиторией токена, которую запрашивает cert-manager: для Issuer этоvault://<NAMESPACE>/<ISSUER_NAME>, для ClusterIssuer —vault://<CLUSTER_ISSUER_NAME>:d8 stronghold write auth/kubernetes/role/cert-manager-myapp bound_service_account_names=stronghold-issuer bound_service_account_namespaces=myapp audience=vault://myapp/stronghold policies=cert-manager-pki ttl=20mВ DP в режиме
Automaticметод аутентификации Kubernetes для текущего кластера создаётся модулем по путиkubernetes_local: в этом случае используйтеauth/kubernetes_localвместоauth/kubernetesв командах и вmountPathIssuer. Путьauth/kubernetesотносится к методу, включённому вручную.
Шаг 2. Настройте cert-manager
Создайте Issuer, который обращается к Stronghold, и запросите сертификат.
Создайте ServiceAccount и разрешите cert-manager запрашивать для него токены:
apiVersion: v1 kind: ServiceAccount metadata: name: stronghold-issuer namespace: myapp --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: stronghold-issuer-token namespace: myapp rules: - apiGroups: [""] resources: ["serviceaccounts/token"] resourceNames: ["stronghold-issuer"] verbs: ["create"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: stronghold-issuer-token namespace: myapp roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: stronghold-issuer-token subjects: - kind: ServiceAccount name: cert-manager namespace: d8-cert-managerСоздайте Issuer:
apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: stronghold namespace: myapp spec: vault: server: https://stronghold.example.com path: pki_int/sign/example-com caBundle: <CA_BUNDLE_BASE64> auth: kubernetes: role: cert-manager-myapp mountPath: /v1/auth/kubernetes serviceAccountRef: name: stronghold-issuer<CA_BUNDLE_BASE64>— сертификат CA, которым подписан TLS-сертификат Stronghold, в кодировке base64.Запросите сертификат:
apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: www namespace: myapp spec: secretName: www-tls commonName: www.example.com dnsNames: - www.example.com duration: 72h renewBefore: 24h issuerRef: name: stronghold kind: Issuer
cert-manager сохранит сертификат и закрытый ключ в Secret www-tls и будет перевыпускать сертификат до истечения срока. Значение duration не должно превышать max_ttl роли example-com.
Другие способы аутентификации
Issuer типа vault также поддерживает аутентификацию через AppRole (auth.appRole с roleId и ссылкой на Secret с secret_id) и через токен (auth.tokenSecretRef). При этих способах secret_id или токен хранится в Secret в кластере. Аутентификация Kubernetes не требует хранить долгоживущие учётные данные в кластере.
Проверка
Проверьте результат:
Проверьте, что Issuer готов:
d8 k -n myapp get issuer strongholdВ колонке
READYдолжно быть значениеTrue.Проверьте, что сертификат выпущен:
d8 k -n myapp get certificate wwwВ колонке
READYдолжно быть значениеTrue.Проверьте издателя и срок действия сертификата в Secret:
d8 k -n myapp get secret www-tls -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -issuer -enddateВ поле
issuerдолжно быть имя промежуточного CA изpki_int.
Очистка
Удалите объекты, созданные в этом руководстве.
Удалите Certificate, его Secret, Issuer и ServiceAccount с Role и RoleBinding:
d8 k -n myapp delete certificate www d8 k -n myapp delete secret www-tls d8 k -n myapp delete issuer stronghold d8 k -n myapp delete rolebinding stronghold-issuer-token d8 k -n myapp delete role stronghold-issuer-token d8 k -n myapp delete serviceaccount stronghold-issuerУдалите роль метода Kubernetes и политику в Stronghold:
d8 stronghold delete auth/kubernetes/role/cert-manager-myapp d8 stronghold policy delete cert-manager-pkiУже выпущенные сертификаты действуют до истечения срока. Чтобы отозвать их, используйте
pki_int/revoke, как в разделе «Внутренний PKI на Stronghold».