15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать
22.10.2024

Cert-Manager на Kubernetes: Полное руководство по настройке автоматизированного управления TLS-сертификатами

Cert-Manager — это контроллер Kubernetes с открытым исходным кодом, который полностью автоматизирует жизненный цикл TLS-сертификатов — от первоначальной выдачи через валидацию до обновления — путём прямой интеграции с центрами сертификации, такими как Let’s Encrypt, HashiCorp Vault и частными PKI-системами. Он устраняет необходимость в ручных процессах работы с сертификатами, рассматривая их как нативные ресурсы Kubernetes, управляемые декларативно через Custom Resource Definitions (CRDs).

Для любого производственного кластера Kubernetes просроченные или неправильно настроенные TLS-сертификаты являются одной из наиболее распространённых причин незапланированных простоев. Cert-Manager решает эту проблему, непрерывно согласовывая состояние сертификатов, автоматически обновляя учётные данные до истечения срока действия и сохраняя полученный ключевой материал в Kubernetes Secrets, которые контроллеры Ingress и рабочие нагрузки могут использовать немедленно.

Почему Cert-Manager является стандартом для автоматизации TLS в Kubernetes

До того как Cert-Manager стал де-факто решением, команды либо создавали скрипты для обновления certbot на отдельных узлах, вручную ротировали сертификаты между пространствами имён, либо полагались на специфические для облачных провайдеров интеграции, которые создавали привязку к поставщику. Cert-Manager объединяет все эти подходы под единой, нативной для Kubernetes плоскостью управления.

Ключевые преимущества перед специализированными подходами:

  • Декларативное управление: намерение относительно сертификата выражается в виде YAML-манифеста, версионируемого вместе с кодом приложения.
  • Автоматическое согласование: цикл контроллера обнаруживает расхождение между желаемым и фактическим состоянием сертификата и исправляет его без участия человека.
  • Поддержка нескольких издателей: один кластер может одновременно использовать Let’s Encrypt для публичных сервисов, внутренний CA для mTLS сервисной сети и HashiCorp Vault для рабочих нагрузок, чувствительных к секретам.
  • Журнал аудита: каждый объект CertificateRequest сохраняется в Kubernetes API, предоставляя вам полную историю выдачи.

Запуск Kubernetes на платформе VPS Хостинга с хранилищем на основе NVMe и полным root-доступом даёт вам контроль, необходимый для настройки пользовательских DNS-резолверов, управления правилами брандмауэра для ACME HTTP-01 запросов и установки CRDs на уровне кластера без ограничений — всё это является обязательными условиями для производственного развёртывания Cert-Manager.

Основная архитектура: как Cert-Manager работает изнутри

Понимание внутренней архитектуры Cert-Manager предотвращает неправильные конфигурации и помогает быстро отлаживать сбои при выдаче.

Конечный автомат жизненного цикла сертификата

Cert-Manager управляет сертификатами через детерминированный конечный автомат. Каждый ресурс Certificate проходит через следующие состояния:

  1. Pending (Ожидание) — объект Certificate существует, но ни один действительный CertificateRequest не был выполнен.
  2. Issuing (Выдача)CertificateRequest был создан и отправлен настроенному издателю.
  3. Ready (Готов) — действительный, не истёкший сертификат хранится в указанном Kubernetes Secret.
  4. Renewal Pending (Ожидание обновления) — сертификат находится в пределах окна renewBefore (по умолчанию: за 30 дней до истечения срока), и новый CertificateRequest обрабатывается.

Контроллер отслеживает все объекты Certificate в масштабе кластера и непрерывно согласовывает их состояние. Если Secret удалён вручную, Cert-Manager обнаруживает отсутствующий ресурс и немедленно инициирует повторную выдачу — критически важное самовосстанавливающееся поведение, предотвращающее случайные сбои.

Основные компоненты CRD

РесурсОбластьНазначение
`Issuer`Пространство имёнОпределяет конфигурацию CA для одного пространства имён
`ClusterIssuer`Весь кластерОпределяет конфигурацию CA, доступную для всех пространств имён
`Certificate`Пространство имёнОбъявляет желаемый TLS-сертификат и его свойства
`CertificateRequest`Пространство имёнОтслеживает единственный, одномоментный запрос на подпись сертификата
`Order`Пространство имёнПредставляет ACME-заказ у CA (например, Let’s Encrypt)
`Challenge`Пространство имёнОтслеживает единственный ACME-запрос (HTTP-01 или DNS-01)

Ресурсы Order и Challenge создаются автоматически издателем ACME — вы редко взаимодействуете с ними напрямую, но их проверка является основным путём отладки при зависании выдачи.

Хранение сертификатов и формат Secret

После выдачи Cert-Manager записывает три ключа данных в целевой Kubernetes Secret:

  • tls.crt — полная цепочка сертификатов (конечный + промежуточные), в кодировке PEM.
  • tls.key — закрытый ключ, в кодировке PEM.
  • ca.crt — сертификат издающего CA (заполняется для внутренних CA; может быть пустым для ACME-издателей).

Контроллеры Ingress, сервисные сети и поды приложений монтируют этот Secret напрямую. Формат совместим с NGINX, Traefik, Istio, Linkerd и большинством других нативных для Kubernetes потребителей TLS.

Поддерживаемые издатели и когда использовать каждый из них

ACME (Let’s Encrypt и альтернативы)

Протокол ACME является наиболее распространённым путём выдачи. Cert-Manager реализует полный ACME-клиент RFC 8555, поддерживая как тестовые, так и производственные конечные точки.

Запрос HTTP-01: Cert-Manager временно обслуживает токен по адресу http://<domain>/.well-known/acme-challenge/<token>. Для этого требуется, чтобы домен разрешался в публично доступный IP-адрес на порту 80. Работает для сертификатов с одним доменом и SAN, но не может выдавать wildcard-сертификаты.

Запрос DNS-01: Cert-Manager создаёт TXT-запись _acme-challenge.<domain> через API DNS-провайдера. Работает за брандмауэрами, поддерживает wildcard-сертификаты (*.example.com) и требуется для любого кластера, не имеющего прямого доступа к интернету. Поддерживаемые DNS-провайдеры включают Cloudflare, Route53, Google Cloud DNS, Azure DNS и многие другие через webhook-решатели.

HashiCorp Vault

Издатель Vault интегрируется с движком секретов PKI в Vault. Это предпочтительный выбор для:

  • Внутреннего mTLS микросервисов, где сертификаты должны быть краткосрочными (часы, а не месяцы).
  • Сред со строгими требованиями к хранению ключей, где закрытые ключи никогда не должны покидать Vault.
  • Автоматической ротации сертификатов, привязанной к системе обновления аренды Vault.

Самоподписанные и CA-издатели

Издатель SelfSigned генерирует сертификаты, подписанные собственным закрытым ключом сертификата — полезно для начальной загрузки корневого CA внутри кластера. Издатель CA использует Kubernetes Secret, содержащий пару ключей CA, для подписи сертификатов, что делает его подходящим для внутренних сред разработки и PKI сервисной сети.

Venafi

Интеграция с Venafi ориентирована на корпоративные среды с централизованным применением политик сертификатов, аудитом соответствия требованиям и интеграцией с аппаратными модулями безопасности (HSM).

Cert-Manager в сравнении с альтернативными подходами к автоматизации TLS

ПодходПоддержка WildcardНативность для KubernetesНесколько CAАвтообновлениеСложность
Cert-ManagerДа (DNS-01)Да (CRDs)ДаДаСредняя
Ручной CertbotНет (только HTTP-01)НетОграниченноПо скриптуНизкая–Средняя
Завершение TLS на облачном балансировщике нагрузкиЗависит от провайдераНетНетДаНизкая
Istio / CA сервисной сетиТолько внутренниеДаНетДаВысокая
HashiCorp Vault (автономный)ДаНетДаВручнуюВысокая

Для команд, запускающих Kubernetes на Выделенном сервере или VPS, Cert-Manager — единственный подход, который одновременно является нативным для Kubernetes, поддерживает все основные CA и не требует никакого постоянного ручного вмешательства.

Установка Cert-Manager: готовая к производству настройка

Предварительные требования

  • Kubernetes 1.22+ (рекомендуется 1.26+ для полной стабильности CRD)
  • kubectl настроен с привилегиями cluster-admin
  • Установлен Helm 3.x
  • Зарегистрированный домен с доступом к управлению DNS (для DNS-01) или публично доступный IP-адрес ingress (для HTTP-01)

Если вы управляете собственным доменом, настоятельно рекомендуется Регистрация домена через провайдера, предоставляющего API — это позволяет полностью автоматизировать решение DNS-01 запросов без ручного вмешательства.

Шаг 1: Установка CRDs и контроллера Cert-Manager

Рекомендуемый метод производственной установки использует Helm с CRDs, управляемыми отдельно, чтобы избежать конфликтов при обновлении Helm:

# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update

# Install Cert-Manager with CRDs included
helm install cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --create-namespace 
  --version v1.14.5 
  --set installCRDs=true 
  --set global.leaderElection.namespace=cert-manager

Убедитесь, что все три основных пода запущены, прежде чем продолжить:

kubectl get pods --namespace cert-manager

Ожидаемый вывод:

NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-xxxxxxxxx-xxxxx              1/1     Running   0          60s
cert-manager-cainjector-xxxxxxxxx-xxxxx   1/1     Running   0          60s
cert-manager-webhook-xxxxxxxxx-xxxxx      1/1     Running   0          60s

cainjector внедряет данные пакета CA в конфигурации webhook. webhook проверяет и изменяет объекты CRD Cert-Manager — если он не запущен, все операции kubectl apply с ресурсами Cert-Manager завершатся ошибкой.

Шаг 2: Настройка ClusterIssuer для Let’s Encrypt

Всегда начинайте с тестовой среды Let’s Encrypt, чтобы избежать превышения производственных ограничений на количество запросов (50 сертификатов на зарегистрированный домен в неделю):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-staging-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

После успешной выдачи тестовых сертификатов создайте производственный издатель:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

Примените оба манифеста:

kubectl apply -f clusterissuer-staging.yaml
kubectl apply -f clusterissuer-prod.yaml

Проверьте готовность издателя:

kubectl describe clusterissuer letsencrypt-prod

Поле Status.Conditions должно отображать Ready: True. Если отображается False, регистрация учётной записи ACME завершилась неудачей — проверьте адрес электронной почты и сетевое подключение из пода cert-manager.

Шаг 3: Явный запрос сертификата

Вы можете запрашивать сертификаты либо путём непосредственного создания ресурса Certificate, либо путём аннотирования ресурса Ingress. Явный подход с Certificate даёт вам больше контроля:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com-tls
  namespace: production
spec:
  secretName: example-com-tls-secret
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: example.com
  dnsNames:
    - example.com
    - www.example.com
  duration: 2160h    # 90 days (Let's Encrypt default)
  renewBefore: 720h  # Renew 30 days before expiry

Примените и отслеживайте выдачу:

kubectl apply -f certificate.yaml
kubectl describe certificate example-com-tls -n production

Отслеживайте объекты CertificateRequest и Order для получения подробного статуса:

kubectl get certificaterequest -n production
kubectl describe order -n production

Шаг 4: Метод аннотации Ingress (упрощённый)

Для команд, использующих NGINX Ingress Controller, Cert-Manager может быть запущен автоматически через аннотацию — отдельный манифест Certificate не требуется:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: production
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - example.com
        - www.example.com
      secretName: example-com-tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: example-service
                port:
                  number: 80

Cert-Manager обнаруживает аннотацию и автоматически создаёт соответствующий ресурс Certificate. Это наиболее распространённый шаблон в рабочих процессах GitOps.

Расширенные шаблоны конфигурации

Wildcard-сертификаты с DNS-01 (пример Cloudflare)

Wildcard-сертификаты требуют валидации DNS-01. Сначала создайте Secret, содержащий ваш API-токен Cloudflare:

kubectl create secret generic cloudflare-api-token 
  --from-literal=api-token=<YOUR_CLOUDFLARE_API_TOKEN> 
  --namespace cert-manager

Настройте ClusterIssuer с решателем DNS-01:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-dns
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: ops@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-dns-account-key
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token
              key: api-token

Запросите wildcard-сертификат:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-example-com
  namespace: production
spec:
  secretName: wildcard-example-com-tls
  issuerRef:
    name: letsencrypt-prod-dns
    kind: ClusterIssuer
  dnsNames:
    - "*.example.com"
    - example.com

Критическая ошибка: Secret, содержащий учётные данные DNS-провайдера, должен находиться в пространстве имён cert-manager при ссылке из ClusterIssuer. Если вы разместите его в другом пространстве имён, контроллер не сможет его прочитать, и выдача молча завершится неудачей. Проверьте журналы контроллера cert-manager с помощью kubectl logs -n cert-manager deploy/cert-manager, если запросы зависают.

Внутренняя PKI с CA-издателем

Для mTLS между сервисами внутри кластера издатель CA, основанный на самоподписанном корневом CA, более подходит, чем ACME:

# Step 1: Create a self-signed root CA certificate
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-root
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: internal-root-ca
  namespace: cert-manager
spec:
  isCA: true
  commonName: internal-root-ca
  secretName: internal-root-ca-secret
  issuerRef:
    name: selfsigned-root
    kind: ClusterIssuer
---
# Step 2: Create a CA issuer backed by the root certificate
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: internal-ca-issuer
spec:
  ca:
    secretName: internal-root-ca-secret

Теперь сервисы могут запрашивать краткосрочные сертификаты у internal-ca-issuer для mTLS без какой-либо зависимости от внешнего CA.

Настройка renewBefore для высокозащищённых сред

Значение renewBefore по умолчанию в 30 дней подходит для 90-дневных сертификатов Let’s Encrypt. Для краткосрочных внутренних сертификатов (например, со сроком действия 24 часа) установите renewBefore равным доле от общей продолжительности:

spec:
  duration: 24h
  renewBefore: 8h

Cert-Manager начнёт обновление за 8 часов до истечения срока, предоставляя контроллеру три окна обновления в течение 24-часового срока действия сертификата — критически важный запас безопасности на случай, если кластер испытывает временную недоступность API-сервера.

Отладка распространённых сбоев Cert-Manager

Сертификат завис в состоянии «Issuing»

# Check the Certificate status
kubectl describe certificate <name> -n <namespace>

# Check the associated CertificateRequest
kubectl describe certificaterequest -n <namespace>

# Check the ACME Order
kubectl describe order -n <namespace>

# Check the Challenge
kubectl describe challenge -n <namespace>

# Check controller logs
kubectl logs -n cert-manager deploy/cert-manager --tail=100

Распространённые первопричины:

  • Сбой HTTP-01: контроллер Ingress неправильно маршрутизирует трафик /.well-known/acme-challenge/. Убедитесь, что объект Ingress запроса был создан и что порт 80 доступен из интернета. Брандмауэры на хосте должны разрешать входящий TCP/80.
  • Сбой DNS-01: API-токен DNS-провайдера имеет недостаточные разрешения, или распространение DNS ещё не завершено. Серверы валидации Let’s Encrypt могут запрашивать другие резолверы, чем ваш локальный DNS — задержки распространения в 60–120 секунд являются нормой.
  • Превышен лимит запросов: Let’s Encrypt применяет ограничение в 5 неудачных попыток валидации на домен в час. После достижения этого лимита необходимо подождать перед повторной попыткой. Всегда сначала тестируйте с тестовой конечной точкой.
  • Webhook не готов: если под webhook cert-manager не запущен, все операции с CRD завершатся ошибкой отказа в соединении. Убедитесь, что служба webhook имеет действительную конечную точку.

Проверка развёрнутого сертификата

# Check the Secret contents
kubectl get secret example-com-tls-secret -n production -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -text

# Check expiry date specifically
kubectl get secret example-com-tls-secret -n production -o jsonpath='{.data.tls.crt}' | base64 -d | openssl x509 -noout -enddate

Контрольный список для усиления защиты в производственной среде

Развёртывание Cert-Manager в производственной среде требует большего, чем стандартная установка через Helm. Примените эти меры по усилению защиты перед запуском в эксплуатацию:

  • Ограничения ресурсов: установите requests и limits CPU и памяти для всех трёх подов Cert-Manager, чтобы предотвратить конкуренцию за ресурсы на общих узлах.
  • Аудит RBAC: Cert-Manager требует широких разрешений RBAC. Проверьте установленные объекты ClusterRole и ограничьте их до минимально необходимого для ваших типов издателей.
  • Отдельное пространство имён: всегда развёртывайте Cert-Manager в собственном пространстве имён cert-manager, изолированном от рабочих нагрузок приложений.
  • Мониторинг: откройте конечную точку метрик Prometheus Cert-Manager (--metrics-listen-address) и настройте оповещения на certmanager_certificate_expiration_timestamp_seconds, чтобы выявлять сбои обновления до того, как они повлияют на сервисы.
  • Резервное копирование состояния CRD: включите объекты Certificate, ClusterIssuer и Issuer в стратегию резервного копирования кластера. Потеря этих манифестов после события аварийного восстановления означает необходимость вручную воссоздавать все конфигурации сертификатов.
  • Тестовая валидация: никогда не выдавайте первый сертификат через производственную конечную точку ACME. Нарушения ограничений на количество запросов могут заблокировать ваш домен на срок до недели.

Если вы управляете несколькими кластерами Kubernetes — например, разделяя тестовые и производственные рабочие нагрузки — Панели управления VPS могут упростить управление жизненным циклом кластеров и предоставить вам единый интерфейс для подготовки базовой инфраструктуры, на которой работает каждый кластер.

Для рабочих нагрузок, требующих GPU-ускоренного инференса или обслуживания ML за TLS-терминированными конечными точками, те же шаблоны Cert-Manager применяются на инфраструктуре GPU Хостинга, где автоматизированное управление сертификатами не менее критично для защиты конечных точек API моделей.

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

СценарийРекомендуемый издательТип запросаWildcard
Публичное веб-приложение, один домен`letsencrypt-prod`HTTP-01Нет
Публичное веб-приложение, несколько поддоменов`letsencrypt-prod`DNS-01Да
Изолированный / частный кластер`CA` или `Vault`Н/Д (внутренний)Да
Корпоративная среда с требованиями соответствия`Venafi`Н/ДДа
mTLS сервисной сети (краткосрочные сертификаты)`Vault` или `CA`Н/Д (внутренний)Да
Разработка / локальный кластер`SelfSigned` или `CA`Н/ДДа

Ключевые выводы

  • Устанавливайте Cert-Manager с помощью Helm с installCRDs=true и всегда выполняйте валидацию с тестовой конечной точкой ACME перед переключением на производственную.
  • Используйте ClusterIssuer для кластеров с несколькими пространствами имён; используйте Issuer с областью видимости пространства имён только тогда, когда вам нужна изоляция CA на уровне команды.
  • DNS-01 строго обязателен для wildcard-сертификатов и для кластеров, не доступных напрямую из интернета на порту 80.
  • Поле renewBefore не является необязательным в производственной среде — установите его не менее чем в одну треть от общего duration сертификата.
  • Когда выдача зависает, путь отладки всегда следующий: CertificateCertificateRequestOrderChallenge → журналы контроллера.
  • Учётные данные API DNS-провайдера, на которые ссылается ClusterIssuer, должны находиться в пространстве имён cert-manager, а не в пространствах имён приложений.
  • Отслеживайте certmanager_certificate_expiration_timestamp_seconds в Prometheus и настройте оповещения — молчаливые сбои обновления являются наиболее опасным режимом отказа.
  • Включите манифесты Certificate и ClusterIssuer в план аварийного восстановления.

Часто задаваемые вопросы

В чём разница между Issuer и ClusterIssuer в Cert-Manager?

Issuer ограничен пространством имён и может выдавать сертификаты только в том пространстве имён, где он определён. ClusterIssuer действует в масштабе всего кластера и может быть указан ресурсами Certificate в любом пространстве имён. Для большинства производственных кластеров ClusterIssuer является правильным выбором, если только вам не нужна строгая изоляция CA на уровне пространства имён.

Почему мой сертификат Cert-Manager завис в состоянии «Issuing»?

Проверьте объекты Order и Challenge в том же пространстве имён с помощью kubectl describe. Наиболее распространённые причины: порт 80 заблокирован брандмауэром (HTTP-01), неверные учётные данные DNS API или задержка распространения (DNS-01), превышены ограничения на количество запросов Let’s Encrypt, или под webhook cert-manager не запущен. Всегда проверяйте журналы контроллера с помощью kubectl logs -n cert-manager deploy/cert-manager.

Может ли Cert-Manager выдавать wildcard-сертификаты от Let’s Encrypt?

Да, но только с использованием типа запроса DNS-01. HTTP-01 не может валидировать wildcard-домены. Вы должны настроить интеграцию с DNS-провайдером (Cloudflare, Route53 и т.д.) в конфигурации решателя ClusterIssuer и убедиться, что учётные данные API имеют разрешение на создание TXT-записей для целевого домена.

Как Cert-Manager автоматически обрабатывает обновление сертификатов?

Контроллер Cert-Manager непрерывно сравнивает срок истечения каждого объекта Certificate с текущим временем. Когда оставшийся срок действия опускается ниже порога renewBefore (по умолчанию: 30 дней), контроллер создаёт новый CertificateRequest, выполняет ACME-запрос и атомарно заменяет содержимое целевого Secret — всё это без перезапуска подов, использующих сертификат. Поды, монтирующие Secret как том, увидят обновлённый сертификат при следующем цикле синхронизации kubelet.

Подходит ли Cert-Manager для защиты внутреннего взаимодействия между сервисами, а не только для публичного HTTPS?

Да. Используя издатель CA или издатель HashiCorp Vault, Cert-Manager может выдавать краткосрочные сертификаты для внутреннего mTLS между микросервисами. Это распространённый шаблон в развёртываниях сервисных сетей, где каждая рабочая нагрузка нуждается в уникальном сертификате идентификации. Поля duration и renewBefore позволяют сертификатам иметь срок действия от нескольких минут с полностью автоматизированной ротацией.

15%

Сэкономьте 15% на всех хостинговых услугах

Проверьте свои навыки и получите скидку на любой тарифный план

Используйте код:

Skills
Начать