Цель: Автоматическое получение сертификатов от 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 hashicorp1.2. Создание файла конфигурации values.yaml: Файл конфигурации определяет параметры развертывания Vault: режим HA, количество реплик, бэкенд-хранилище.
cat <<EOF > vault-values.yaml
server:
ha:
enabled: true
raft:
enabled: true
ui:
enabled: true
EOF1.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 CA2.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 453.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 PKI3.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 created4.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://t.me/notes_devops_engineer