Цель: Автоматическое получение сертификатов от Certificate Authority c самоподписанным сертификатом используя vault и cert-manager в Kubernetes
Обзор
Эта инструкция представляет собой полное руководство по развертыванию отказоустойчивого кластера HashiCorp Vault в Kubernetes и настройке двухуровневой Public Key Infrastructure (PKI). Корневой сертификат и промежуточный CA создаются через OpenSSL, но промежуточный импортируется и настраивается в Vault для повседневного выпуска сертификатов. Инфраструктура интегрируется с cert-manager для автоматического управления жизненным циклом TLS-сертификатов.

План:
Установка Vault в Kubernetes: Развертывание отказоустойчивого кластера Vault с использованием Helm-чарта и встроенного хранилища Raft, с активацией Ingress непосредственно в чарте.
Создание корневого и промежуточного сертификатов через OpenSSL: Генерация корневого сертификата
apatsev.corpи промежуточного CAintermediate.apatsev.corpс помощью OpenSSL.Импорт промежуточного сертификата в Vault: Настройка PKI-движка в Vault для промежуточного CA.
Интеграция с cert-manager: Установка и настройка
cert-managerдля автоматизации выпуска и обновления сертификатов.Настройка Ingress для Vault через Helm: Активация и конфигурация Ingress непосредственно в Helm-чарте Vault для безопасного доступа с автоматическим созданием TLS-сертификата.
Создание ролей и выпуск сертификатов для приложений: Демонстрация процесса создания ролей для различных сервисов и автоматического выпуска сертификатов для них.
Комментарии для начинающих DevOps
Перед началом, несколько ключевых концепций, которые помогут понять происходящее:
PKI (Public Key Infrastructure) — это набор технологий, позволяющих выпускать и управлять цифровыми сертификатами. Вместо одного сертификата используется цепочка доверия: Корневой CA - Промежуточный CA - Сертификат приложения. Это повышает безопасность: корневой ключ хранится в сейфе и используется редко, а промежуточный — для повседневных задач.
HashiCorp Vault — это не просто хранилище секретов, а мощная система управления секретами и шифрования. Его движок PKI может выступать в роли полноценного Удостоверяющего Центра.
cert-manager — это оператор для Kubernetes, который автоматически запрашивает и продлевает TLS-сертификаты у различных провайдеров (в нашем случае — Vault), избавляя вас от рутины.
Ingress в Kubernetes — это объект, который управляет внешним доступом к услугам внутри кластера, обычно через HTTP/HTTPS. В этой статье весь TLS-трафик расшифровывается на уровне Ingress, а до Vault доходит уже чистый HTTP, что упрощает его конфигурацию.
Предварительные требования
Рабочий кластер Kubernetes.
Установленные утилиты командной строки:
kubectl,helm,openssl,jq,vault.Настроенный доступ
kubectlк целевому кластеру.Установленный и настроенный Ingress-контроллер (например, nginx-ingress).
Шаг 1: Установка HashiCorp Vault в режиме HA в Kubernetes
Используется официальный Helm-чарт от HashiCorp для развертывания Vault в отказоустойчивом режиме (HA) с использованием встроенного хранилища Raft.
1.1. Добавление Helm-репозитория HashiCorp:
$ helm repo add hashicorp https://helm.releases.hashicorp.com $ helm repo update
Проверка:
$ helm repo list | grep hashicorp
1.2. Создание файла конфигурации values.yaml: Файл конфигурации определяет параметры развертывания Vault: режим HA, количество реплик, бэкенд-хранилище.
cat <<EOF > vault-values.yaml server: ha: enabled: true raft: enabled: true ui: enabled: true EOF
1.3. Установка Vault с помощью Helm: Команда создает пространство имен и устанавливает Vault с заданной конфигурацией.
$ kubectl create namespace vault $ helm install vault hashicorp/vault --namespace vault --wait --version 0.31.0 --values vault-values.yaml REVISION: 1 NOTES: Thank you for installing HashiCorp Vault! Now that you have deployed Vault, you should look over the docs on using Vault with Kubernetes available here: https://developer.hashicorp.com/vault/docs Your release is named vault. To learn more about the release, try: $ helm status vault $ helm get manifest vault
Проверка: Дождитесь запуска всех подов.
$ kubectl get pods -n vault NAME READY STATUS RESTARTS AGE vault-0 0/1 Running 0 108s vault-1 0/1 Running 0 108s vault-2 0/1 Running 0 108s vault-agent-injector-556c5dd8fb-pp5q7 1/1 Running 0 108s
1.4. Инициализация и распечатывание Vault: Инициализация генерирует корневой токен и ключи для распечатывания. Ключи необходимо сохранить в безопасном месте.
ВАЖНО ДЛЯ НАЧИНАЮЩИХ:
-key-shares=1 -key-threshold=1— это настройки для демо-среды. В продакшене используйте, например,-key-shares=5 -key-threshold=3. Это создаст 5 ключей, и для распечатывания потребуется любые 3 из них. Это реализует схему разделения секрета.Файл
vault-init-keys.json— САМЫЙ ГЛАВНЫЙ СЕКРЕТ ВО ВСЕЙ ИНФРАСТРУКТУРЕ. Сохраните его в надёжном месте (например, в зашифрованном хранилище). Без него вы не сможете восстановить Vault.Распечатывание (Unseal) — это процесс расшифровки данных Vault. При перезагрузке подов Vault окажется в запечатанном состоянии, и его снова нужно будет распечатать этими же ключами.
$ kubectl exec -n vault vault-0 -- vault operator init -key-shares=1 -key-threshold=1 -format=json > vault-init-keys.json
Проверка созданных ключей:
$ cat vault-init-keys.json | jq { "unseal_keys_b64": [ "r+tBg2Z/74+MXGxjwr6HXY1AORnmfTUYUv2GSNLUI68=" ], "unseal_keys_hex": [ "afeb4183667fef8f8c5c6c63c2be875d8d403919e67d351852fd8648d2d423af" ], "unseal_shares": 1, "unseal_threshold": 1, "recovery_keys_b64": [], "recovery_keys_hex": [], "recovery_keys_shares": 0, "recovery_keys_threshold": 0, "root_token": "hvs.RElUuUX0whALAB6WIdCiq5b6" }
Получение ключа для разблокировки Vault и root-токен для входа:
VAULT_UNSEAL_KEY=$(jq -r ".unseal_keys_b64[0]" vault-init-keys.json) VAULT_ROOT_TOKEN=$(jq -r ".root_token" vault-init-keys.json)
Распечатывание всех нод Vault: Процесс распечатывания делает данные Vault доступными. Каждая нода должна быть распечатана.
# Распечатываем vault-0 $ kubectl exec -n vault vault-0 -- vault operator unseal $VAULT_UNSEAL_KEY Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 1 Threshold 1 Version 1.20.4 Build Date 2025-09-23T13:22:38Z Storage Type raft Cluster Name vault-cluster-f9a825be Cluster ID d73bd827-58bc-afea-0c62-0faf949fd455 Removed From Cluster false HA Enabled true HA Cluster https://vault-0.vault-internal:8201 HA Mode active Active Since 2025-12-05T08:49:48.668482716Z Raft Committed Index 37 Raft Applied Index 37 # Присоединяем и распечатываем vault-1 $ kubectl exec -n vault vault-1 -- vault operator raft join http://vault-0.vault-internal:8200 Key Value --- ----- Joined true $ kubectl exec -n vault vault-1 -- vault operator unseal $VAULT_UNSEAL_KEY Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 1 Threshold 1 Unseal Progress 0/1 Unseal Nonce n/a Version 1.20.4 Build Date 2025-09-23T13:22:38Z Storage Type raft Removed From Cluster false HA Enabled true # Присоединяем и распечатываем vault-2 $ kubectl exec -n vault vault-2 -- vault operator raft join http://vault-0.vault-internal:8200 Key Value --- ----- Joined true $ kubectl exec -n vault vault-2 -- vault operator unseal $VAULT_UNSEAL_KEY Key Value --- ----- Seal Type shamir Initialized true Sealed true Total Shares 1 Threshold 1 Unseal Progress 0/1 Unseal Nonce n/a Version 1.20.4 Build Date 2025-09-23T13:22:38Z Storage Type raft Removed From Cluster false HA Enabled true
Проверка статуса:
$ kubectl get pods -n vault NAME READY STATUS RESTARTS AGE vault-0 1/1 Running 0 4m56s vault-1 1/1 Running 0 4m56s vault-2 1/1 Running 0 4m56s vault-agent-injector-556c5dd8fb-kb975 1/1 Running 0 4m56s
Шаг 2: Создание корневого и промежуточного сертификатов через OpenSSL
Пояснение: Мы создаём двухуровневую PKI. Корневой сертификат (Root CA) — это корень доверия. Его приватный ключ должен храниться максимально защищённо (оффлайн). Промежуточный сертификат (Intermediate CA) подписан корневым и используется для ежедневной выдачи сертификатов. Если он скомпрометирован, мы отзываем его, не трогая корневой.
2.1. Создание корневого сертификата через OpenSSL: Корневой сертификат является корнем доверия всей инфраструктуры. Его закрытый ключ должен храниться в безопасном месте, в идеале — оффлайн.
Создание конфигурационного файла для корневого CA:
cat <<EOF > rootCA.cnf [ req ] distinguished_name = req_distinguished_name x509_extensions = v3_ca prompt = no [ req_distinguished_name ] C = RU ST = Omsk Oblast L = Omsk O = MyCompany OU = Apatsev CN = apatsev.corp Root CA [ v3_ca ] basicConstraints = critical, CA:TRUE, pathlen:1 keyUsage = critical, digitalSignature, cRLSign, keyCertSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer EOF
Генерация приватного ключа для корневого CA:
openssl genrsa -out rootCA.key 4096
Создание самоподписанного корневого сертификата:
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt -config rootCA.cnf -extensions v3_ca
Проверка:
$ openssl x509 -in rootCA.crt -text -noout | grep "Subject:" Subject: C=RU, ST=Omsk Oblast, L=Omsk, O=MyCompany, OU=Apatsev, CN=apatsev.corp Root CA
2.2. Создание промежуточного сертификата через OpenSSL: Промежуточный сертификат будет использоваться Vault для ежедневного выпуска сертификатов, что ограничивает риск компрометации корневого ключа.
Генерация приватного ключа для промежуточного CA:
openssl genrsa -out intermediateCA.key 4096
Создание конфигурационного файла для промежуточного CA:
cat <<EOF > intermediateCA.cnf [ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] C = RU ST = Omsk Oblast L = Omsk O = MyCompany OU = Apatsev CN = intermediate.apatsev.corp Intermediate CA [ v3_intermediate_ca ] basicConstraints = critical, CA:TRUE, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer authorityInfoAccess = @issuer_info crlDistributionPoints = @crl_info [ issuer_info ] caIssuers;URI.0 = http://vault.apatsev.corp/v1/pki/ca [ crl_info ] URI.0 = http://vault.apatsev.corp/v1/pki/crl EOF
Примечание: Расширения authorityInfoAccess и crlDistributionPoints критически важны. Они указывают клиентам (браузерам, ОС) где искать цепочку сертификатов (CA Issuers) и списки отозванных сертификатов (CRL). Мы указываем будущий внешний URL Vault.
Создание CSR (Certificate Signing Request) для промежуточного CA:
openssl req -new -key intermediateCA.key -out intermediateCA.csr -config intermediateCA.cnf
Подписание промежуточного CA корневым сертификатом:
$ openssl x509 -req -in intermediateCA.csr \ -CA rootCA.crt -CAkey rootCA.key -CAcreateserial \ -out intermediateCA.crt -days 1825 -sha256 \ -extfile intermediateCA.cnf -extensions v3_intermediate_ca Certificate request self-signature ok subject=C=RU, ST=Omsk Oblast, L=Omsk, O=MyCompany, OU=Apatsev, CN=intermediate.apatsev.corp Intermediate CA
Проверка цепочки сертификатов:
$ openssl verify -CAfile rootCA.crt intermediateCA.crt intermediateCA.crt: OK
Шаг 3: Импорт промежуточного сертификата в Vault
3.1. Настройка подключения к Vault: Проброс порта позволяет взаимодействовать с Vault, работающим внутри кластера, с локальной машины.
Внимание: Команда kubectl port-forward блокирует терминал. Запускайте её в отдельном окне или в фоновом режиме (&).
Запустите в отдельном окне терминала проброс порта:
kubectl port-forward -n vault service/vault 8200:8200
Настройка переменных окружения для CLI Vault:
export VAULT_ADDR='http://127.0.0.1:8200' export VAULT_TOKEN="${VAULT_ROOT_TOKEN}"
Проверка подключения:
$ vault status Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 1 Threshold 1 Version 1.20.4 Build Date 2025-09-23T13:22:38Z Storage Type raft Cluster Name vault-cluster-f9a825be Cluster ID d73bd827-58bc-afea-0c62-0faf949fd455 Removed From Cluster false HA Enabled true HA Cluster https://vault-0.vault-internal:8201 HA Mode active Active Since 2025-12-05T08:49:48.668482716Z Raft Committed Index 45 Raft Applied Index 45
3.2. Импорт промежуточного CA в Vault: Включение движка PKI и импорт связки сертификата и ключа промежуточного CA.
Включение PKI движка:
$ vault secrets enable -path=pki -description="Apatsev Intermediate PKI" -max-lease-ttl="43800h" pki Success! Enabled the pki secrets engine at: pki/
Импорт промежуточного сертификата и ключа:
$ vault write pki/config/ca pem_bundle="$(cat intermediateCA.crt intermediateCA.key)" WARNING! The following warnings were returned from Vault: * This mount hasn't configured any authority information access (AIA) fields; this may make it harder for systems to find missing certificates in the chain or to validate revocation status of certificates. Consider updating /config/urls or the newly generated issuer with this information. Key Value --- ----- existing_issuers <nil> existing_keys <nil> imported_issuers [9cbb2bf9-46ef-be2d-09f6-e9686d707661] imported_keys [4d6c375c-b9da-6acf-d44d-1144a5c55806] mapping map[9cbb2bf9-46ef-be2d-09f6-e9686d707661:4d6c375c-b9da-6acf-d44d-1144a5c55806]
Совет: Команда vault write ... pem_bundle=... — это ключевой момент, когда Vault принимает на себя роль промежуточного CA.
Настройка URL-адресов для промежуточного CA: Эти URL будут указываться в выпускаемых сертификатах для доступа к CA и CRL.
$ vault write pki/config/urls \ issuing_certificates="http://vault.apatsev.corp/v1/pki/ca" \ crl_distribution_points="http://vault.apatsev.corp/v1/pki/crl" Key Value --- ----- crl_distribution_points [http://vault.apatsev.corp/v1/pki/crl] delta_crl_distribution_points [] enable_templating false issuing_certificates [http://vault.apatsev.corp/v1/pki/ca] ocsp_servers []
Проверка:
$ vault secrets list | grep pki pki/ pki pki_137733b8 Apatsev Intermediate PKI
3.3. Создание роли для выпуска сертификатов: Роль определяет параметры (домены, TTL, ключи), с которыми могут быть выпущены сертификаты.
$ vault write pki/roles/k8s-services \ allowed_domains="apatsev.corp,svc.cluster.local,vault,vault.vault" \ allow_subdomains=true \ max_ttl="8760h" \ key_bits="2048" \ key_type="rsa" \ allow_bare_domains=true \ allow_ip_sans=true \ allow_localhost=true \ server_flag=true \ enforce_hostnames=false \ key_usage="DigitalSignature,KeyEncipherment" \ ext_key_usage="ServerAuth" Key Value --- ----- allow_any_name false allow_bare_domains true allow_glob_domains false allow_ip_sans true allow_localhost true allow_subdomains true allow_token_displayname false allow_wildcard_certificates true allowed_domains [apatsev.corp svc.cluster.local vault vault.vault] allowed_domains_template false allowed_other_sans [] allowed_serial_numbers [] allowed_uri_sans [] allowed_uri_sans_template false allowed_user_ids [] basic_constraints_valid_for_non_ca false client_flag true cn_validations [email hostname] code_signing_flag false country [] email_protection_flag false enforce_hostnames false ext_key_usage [ServerAuth] ext_key_usage_oids [] generate_lease false issuer_ref default key_bits 2048 key_type rsa key_usage [DigitalSignature KeyEncipherment] locality [] max_ttl 8760h no_store false not_after n/a not_before_duration 30s organization [] ou [] policy_identifiers [] postal_code [] province [] require_cn true serial_number_source json-csr server_flag true signature_bits 256 street_address [] ttl 0s use_csr_common_name true use_csr_sans true use_pss false
Разбор роли:
allowed_domainsиallow_subdomains=true— позволяют выпускать сертификаты для любого поддоменаapatsev.corp(например,app1.apatsev.corp,api.service.apatsev.corp), а также для внутренних DNS-имён Kubernetes.max_ttl— максимальное время жизни выпускаемого сертификата. Vault не выдаст сертификат на срок больше этого.enforce_hostnames=false— упрощает жизнь, разрешая выпускать сертификаты для IP-адресов и "голых" доменов, но может быть менее безопасно. Настройте под свои нужды.
Шаг 4: Установка и настройка cert-manager
4.1. Установка cert-manager: Установка cert-manager с помощью Helm для автоматического управления сертификатами в Kubernetes.
$ helm repo add jetstack https://charts.jetstack.io $ helm repo update $ helm upgrade --install --wait cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.18.2 \ --set crds.enabled=true "jetstack" already exists with the same configuration, skipping Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "jetstack" chart repository Update Complete. ⎈Happy Helming!⎈ Release "cert-manager" does not exist. Installing it now. NAME: cert-manager LAST DEPLOYED: Fri Dec 5 15:25:02 2025 NAMESPACE: cert-manager STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: ⚠️ WARNING: New default private key rotation policy for Certificate resources. The default private key rotation policy for Certificate resources was changed to `Always` in cert-manager >= v1.18.0. Learn more in the [1.18 release notes](https://cert-manager.io/docs/releases/release-notes/release-notes-1.18). cert-manager v1.18.2 has been deployed successfully! In order to begin issuing certificates, you will need to set up a ClusterIssuer or Issuer resource (for example, by creating a 'letsencrypt-staging' issuer). More information on the different types of issuers and how to configure them can be found in our documentation: https://cert-manager.io/docs/configuration/ For information on how to configure cert-manager to automatically provision Certificates for Ingress resources, take a look at the `ingress-shim` documentation: https://cert-manager.io/docs/usage/ingress/
4.2. Настройка аутентификации для cert-manager в Vault: Создание роли AppRole и политики доступа, чтобы cert-manager мог запрашивать сертификаты из Vault.
Пояснение по аутентификации: Чтобы cert-manager мог общаться с Vault и запрашивать сертификаты, ему нужны права. Мы используем метод AppRole. Мы создаём в Vault "роль" для приложения (cert-manager), выдаём ему RoleID и SecretID (как логин и пароль). SecretID мы храним в Kubernetes Secret, чтобы cert-manager мог его безопасно использовать.
Включение аутентификации AppRole:
В целях упрощения на стенде используем AppRole.
$ vault auth enable approle Success! Enabled approle auth method at: approle/
Создание политики для cert-manager:
vault policy write cert-manager-policy - <<EOF path "pki/sign/k8s-services" { capabilities = ["create", "update"] } path "pki/issue/k8s-services" { capabilities = ["create"] } EOF
Создание AppRole:
$ vault write auth/approle/role/cert-manager \ secret_id_ttl=10m \ token_num_uses=100 \ token_ttl=20m \ token_max_ttl=30m \ secret_id_num_uses=40 \ token_policies="cert-manager-policy" Success! Data written to: auth/approle/role/cert-manager
Получение RoleID и SecretID:
ROLE_ID=$(vault read auth/approle/role/cert-manager/role-id -format=json | jq -r .data.role_id) SECRET_ID=$(vault write -f auth/approle/role/cert-manager/secret-id -format=json | jq -r .data.secret_id)
Создание Kubernetes Secret для хранения SecretID:
$ kubectl create secret generic cert-manager-vault-approle \ --namespace=cert-manager \ --from-literal=secretId="${SECRET_ID}" secret/cert-manager-vault-approle created
4.3. Создание VaultIssuer: ClusterIssuer представляет cert-manager'у точку входа в Vault для запроса сертификатов.
Создание файла с полной цепочкой сертификатов для caBundle:
cat rootCA.crt intermediateCA.crt > full-chain.crt
Важно: caBundle в ClusterIssuer нужен для того, чтобы cert-manager мог проверить подлинность сервера Vault по TLS. Так как наш Vault пока работает по HTTP, это не так критично, но хорошая практика — указывать цепочку доверия.
Создание ClusterIssuer:
cat <<EOF | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: vault-cluster-issuer spec: vault: server: http://vault.vault.svc.cluster.local:8200 path: pki/sign/k8s-services caBundle: $(cat full-chain.crt | base64 | tr -d '\n') auth: appRole: path: approle roleId: "${ROLE_ID}" secretRef: name: cert-manager-vault-approle key: secretId EOF
Проверка:
$ kubectl get clusterissuer vault-cluster-issuer -o wide NAME READY STATUS AGE vault-cluster-issuer True Vault verified 96s
Шаг 5: Обновление конфигурации Vault для работы через Ingress
Обновляем values.yaml для корректной работы Vault через Ingress с отключенным TLS.
cat <<EOF > vault-values.yaml server: ha: enabled: true raft: enabled: true ingress: enabled: true annotations: cert-manager.io/cluster-issuer: vault-cluster-issuer cert-manager.io/common-name: vault.apatsev.corp nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" ingressClassName: nginx pathType: Prefix hosts: - host: vault.apatsev.corp paths: - / tls: - secretName: vault-ingress-tls hosts: - vault.apatsev.corp ui: enabled: true EOF
Пояснение архитектуры: Обратите внимание на аннотацию nginx.ingress.kubernetes.io/backend-protocol: "HTTP". Она говорит Ingress-контроллеру, что сам Vault принимает трафик по HTTP. Это сделано в целях упрощения статьи.
Применение обновлений:
$ helm upgrade --install vault hashicorp/vault --namespace vault -f vault-values.yaml Release "vault" has been upgraded. Happy Helming! NAME: vault LAST DEPLOYED: Fri Dec 5 15:34:21 2025 NAMESPACE: vault STATUS: deployed REVISION: 2 NOTES: Thank you for installing HashiCorp Vault! Now that you have deployed Vault, you should look over the docs on using Vault with Kubernetes available here: https://developer.hashicorp.com/vault/docs Your release is named vault. To learn more about the release, try: $ helm status vault $ helm get manifest vault
Проверка создания Ingress и сертификата:
$ kubectl get ingress -n vault NAME CLASS HOSTS ADDRESS PORTS AGE vault nginx vault.apatsev.corp ip 80, 443 31s $ kubectl get certificate -n vault NAME READY SECRET AGE vault-ingress-tls True vault-ingress-tls 57s
Добавляем vault.apatsev.corp в /etc/hosts
echo ip-load-balancer vault.apatsev.corp | sudo tee -a /etc/hosts
Добавляем корневой сертификат в браузер и проверяем https://vault.apatsev.corp

Шаг 6: Пример выпуска сертификата для приложения
Создание ресурса Certificate для приложения: Пример создания сертификата для тестового приложения с использованием Wildcard DNS имени.
cat <<EOF > my-app-certificate.yaml apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: my-app-tls namespace: apps spec: secretName: my-app-tls issuerRef: name: vault-cluster-issuer kind: ClusterIssuer duration: 720h renewBefore: 360h commonName: my-app.apatsev.corp dnsNames: - my-app.apatsev.corp - "*.apps.apatsev.corp" EOF
Автоматизация в действии: После создания этого ресурса cert-manager:
Увидит новый
Certificate.Свяжется с
vault-cluster-issuer.Issuerаутентифицируется в Vault через AppRole.Vault выпустит новый TLS-сертификат согласно правилам роли
k8s-services.cert-managerсохранит сертификат и приватный ключ в Kubernetes Secretmy-app-tls.За 360 часов до истечения срока действия (
renewBefore)cert-managerавтоматически обновит сертификат.
Применение манифестов:
kubectl create namespace apps kubectl apply -f my-app-certificate.yaml
Проверка:
$ kubectl get certificate -n apps my-app-tls NAME READY SECRET AGE my-app-tls True my-app-tls 10s $ kubectl describe secret -n apps my-app-tls Name: my-app-tls Namespace: apps Labels: controller.cert-manager.io/fao=true Annotations: cert-manager.io/alt-names: *.apps.apatsev.corp,my-app.apatsev.corp cert-manager.io/certificate-name: my-app-tls cert-manager.io/common-name: my-app.apatsev.corp cert-manager.io/ip-sans: cert-manager.io/issuer-group: cert-manager.io/issuer-kind: ClusterIssuer cert-manager.io/issuer-name: vault-cluster-issuer cert-manager.io/uri-sans: Type: kubernetes.io/tls Data ==== ca.crt: 2297 bytes tls.crt: 4216 bytes tls.key: 1675 bytes
Заключение
После выполнения всех шагов у вас будет полностью функционирующая PKI-инфраструктура в Kubernetes с HashiCorp Vault в качестве промежуточного Удостоверяющего Центра и автоматическим управлением сертификатами через cert-manager.
Исходный код: https://github.com/patsevanton/vault-pki-ca-setup
Подписывайтесь на телеграм канал https://t.me/notes_devops_engineer
