Kubernetes предоставляет мощные механизмы оркестрации, но не включает автоматическое шифрование трафика между сервисами или для Ingress. Трафик между подами и от внешнего мира к приложениям передается в незашифрованном виде, если вы не настроили TLS явно. Это создает риски перехвата данных и атак типа "человек посередине" в производственных средах. Cert-manager решает эту проблему, автоматизируя выпуск, управление и ротацию TLS-сертификатов внутри кластера.
Этот инструмент интегрируется с внешними центрами сертификации, такими как Let's Encrypt, для публичных сервисов и может создавать внутренний PKI для защиты межсервисного общения. Руководство содержит пошаговые инструкции для установки cert-manager, настройки автоматического HTTPS для Ingress и организации внутреннего шифрования. Все примеры проверены на практике и готовы к применению.
Проблема: что и почему не шифруется в Kubernetes по умолчанию
Kubernetes - это платформа оркестрации, которая предоставляет примитивы для управления контейнерами, но не реализует готовые решения для всех задач безопасности. По умолчанию шифруется только трафик между клиентом и API-сервером кластера, а также между API-сервером и хранилищем данных etcd. Это обеспечивает безопасность управления кластером.
Трафик между подами, от контроллеров Ingress к сервисам и между внутренними сервисами передается в открытом виде (plaintext), если не настроены дополнительные механизмы. Такая архитектура - это не ошибка, а дизайн. Kubernetes дает вам свободу выбирать и внедрять инструменты шифрования, соответствующие вашим требованиям.
Отсутствие шифрования для прикладного трафика создает риски в производственных средах. Внутренние коммуникации между микросервисами могут быть перехвачены, если злоумышленник получит доступ к сети кластера. Входящий трафик через Ingress без TLS подвергает данные пользователей угрозам. Для решения этих проблем требуется система управления TLS-сертификатами, которая масштабируется вместе с кластером.
Cert-manager как универсальное решение для управления TLS-сертификатами
Cert-manager - это контроллер Kubernetes, который автоматизирует жизненный цикл TLS-сертификатов. Он работает как расширение кластера, отслеживая специальные ресурсы (Custom Resource Definitions, CRD) и выполняя действия по их запросу, выпуску и обновлению. Основные сущности системы: Issuer или ClusterIssuer определяет источник сертификатов, Certificate описывает нужный сертификат, а Order и Challenge управляют процессом проверки для ACME.
Контроллер наблюдает за ресурсами Certificate и при необходимости создает CertificateRequest. Для публичных сертификатов он взаимодействует с внешним центром сертификации через ACME протокол, выполняя проверки владения доменом. После успешной проверки сертификат создается и сохраняется как Kubernetes Secret. Cert-manager также отслеживает срок действия сертификатов и автоматически запускает ротацию перед их expiration.
Issuer и ClusterIssuer: определяем источник доверия
Issuer - это ресурс, который определяет, где и как получать сертификаты. Он работает в пределах одного namespace кластера. ClusterIssuer имеет кластерный scope и может использоваться любым ресурсом в любом namespace. Выбор зависит от вашего сценария.
Для тестового окружения в namespace staging можно создать Issuer, использующий staging-сервер Let's Encrypt. Для всех производственных сервисов удобнее создать единый ClusterIssuer, который будет выпускать сертификаты для всего кластера. Пример структуры YAML для ClusterIssuer типа ACME:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: nginxПоле server указывает на ACME-сервер, email используется для регистрации и уведомлений, privateKeySecretRef ссылается на Secret, где хранится ключ аккаунта. Раздел solvers определяет метод проверки домена.
ACME-проверки: HTTP-01 vs DNS-01 - ключевой выбор
ACME протокол требует доказательства контроля над доменом перед выпуском сертификата. Cert-manager поддерживает два основных метода: HTTP-01 и DNS-01.
HTTP-01 challenge - это простой метод. Cert-manager создает временный HTTP-ресурс на вашем домене по пути /.well-known/acme-challenge/, и ACME-сервер запрашивает его. Метод требует, чтобы ваш домен был публично доступен на порту 80, и не поддерживает выпуск wildcard-сертификатов.
DNS-01 challenge сложнее в настройке, но более универсален. Cert-manager создает специальную TXT-запись в DNS вашего домена через API провайдера. Этот метод работает для любых доменов, включая внутренние, и позволяет получать wildcard-сертификаты, которые покрывают все поддомены.
Сравнение методов:
| Метод | Сложность настройки | Поддержка провайдеров | Wildcard | Применимость |
|---|---|---|---|---|
| HTTP-01 | Низкая | Все | Нет | Публичные домены с открытым портом 80 |
| DNS-01 | Высокая (API ключи) | Cloudflare, AWS Route53, и др. | Да | Все домены, включая внутренние |
Для начала рекомендуется использовать HTTP-01 для простых публичных сервисов. Переход на DNS-01 необходим для wildcard-сертификатов или если порт 80 недоступен из интернета.
Практика: автоматизируем TLS для публичного Ingress с Let's Encrypt
Настройка автоматического HTTPS для публичного веб-приложения в Kubernetes состоит из четырех шагов: установка cert-manager, создание тестового ClusterIssuer, развертывание приложения с Ingress и переход на production-сервер Let's Encrypt.
Шаг 1: Установка cert-manager в кластер
Наиболее стабильный метод установки cert-manager - использование Helm. Перед установкой проверьте совместимость версий cert-manager с вашей версией Kubernetes в официальной документации.
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.14.4 --set installCRDs=trueКоманда устанавливает cert-manager в отдельный namespace cert-manager и автоматически применяет необходимые Custom Resource Definitions (CRD). После установки убедитесь, что поды контроллеров запущены: kubectl get pods -n cert-manager.
Шаг 2: Настройка ClusterIssuer для Let's Encrypt staging
Let's Encrypt предоставляет staging-сервер для тестирования без риска превышения лимитов production-окружения. Создайте ClusterIssuer для staging.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: nginxПримените манифест: kubectl apply -f issuer-staging.yaml. Проверьте статус: kubectl describe clusterissuer letsencrypt-staging. В статусе должно быть Ready.
Шаг 3: Развертывание приложения и настройка Ingress с TLS
Разверните простое веб-приложение, например, nginx:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80Создайте Service и Ingress ресурс с аннотациями cert-manager:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-app-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
ingressClassName: nginx
tls:
- hosts:
- your-domain.example.com
secretName: web-app-tls
rules:
- host: your-domain.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app-service
port:
number: 80Аннотация cert-manager.io/cluster-issuer указывает контроллеру, какой Issuer использовать для выпуска сертификата для этого Ingress. Поле tls определяет домен и имя Secret, где будет сохранен сертификат.
Шаг 4: Переход на Let's Encrypt production
После успешного тестирования с staging-сервером создайте ClusterIssuer для production. Лимиты Let's Encrypt строгие: не более 5 сертификатов на домен в неделю для production, поэтому тестирование на staging критически важно.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-production-key
solvers:
- http01:
ingress:
class: nginxОбновите аннотацию в Ingress ресурсе: cert-manager.io/cluster-issuer: letsencrypt-production. Cert-manager автоматически создаст новый сертификат с production-сервера.
Для более сложных конфигураций и работы с wildcard-сертификатами, включая интеграцию с DNS провайдерами, полезно ознакомиться с руководством по полной настройке Let's Encrypt.
Организация внутреннего PKI: шифрование трафика между сервисами
Шифрование публичного трафика через Ingress необходимо, но внутренние коммуникации между микросервисами также требуют защиты. Cert-manager может выступать как внутренний центр сертификации, выпуская TLS-сертификаты для сервисов внутри кластера.
Создание корневого CA и внутреннего ClusterIssuer
Создайте самоподписанный корневой CA-сертификат, который будет основой доверия для всех внутренних сертификатов.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: root-ca
spec:
isCA: true
commonName: my-cluster.internal.ca
secretName: root-ca-secret
issuerRef:
name: selfsigned-issuer
kind: Issuer
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}После создания корневого CA создайте ClusterIssuer типа CA, который будет использовать этот секрет для выпуска сертификатов.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: internal-ca-issuer
spec:
ca:
secretName: root-ca-secretЭтот Issuer может выпускать сертификаты для любых внутренних доменов, таких как database.default.svc.cluster.local.
Выпуск и использование сертификата для внутреннего сервиса
Запросите сертификат для внутреннего сервиса:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: internal-service-cert
spec:
secretName: internal-service-tls
issuerRef:
name: internal-ca-issuer
kind: ClusterIssuer
commonName: internal-service.default.svc
dnsNames:
- internal-service.default.svc
- internal-service.default.svc.cluster.localCert-manager создаст TLS Secret с именем internal-service-tls. Этот секрет можно монтировать в под приложения через volumeMounts:
spec:
containers:
- name: app
volumeMounts:
- name: tls-secret
mountPath: /etc/app/tls
volumes:
- name: tls-secret
secret:
secretName: internal-service-tlsПриложение получит файлы tls.crt и tls.key в указанной директории. Клиенты внутри кластера должны доверять корневому CA-сертификату. Распространите его через sidecar контейнер или проекцию volumes в поды. Для комплексного решения SSL/TLS termination в Kubernetes, включая сравнение архитектур, обратитесь к статье SSL/TLS termination в Kubernetes.
Этот подход можно расширить до mutual TLS (mTLS), где обе стороны проверяют сертификаты друг друга, обеспечивая двустороннюю аутентификацию.
Отладка и решение частых проблем с cert-manager
При внедрении cert-manager могут возникать ошибки. Системная диагностика начинается с проверки статусов ресурсов Kubernetes.
Диагностика по статусам ресурсов: Certificate, Order, Challenge
Проверьте статус ресурса Certificate: kubectl describe certificate <name>. В поле Status.Conditions тип Ready со статусом True означает успех. Статус False указывает на проблему, детали которой находятся в сообщении.
Для ACME-сертификатов исследуйте связанные ресурсы Order и Challenge: kubectl describe order <name> и kubectl describe challenge <name>. В их событиях (Events) часто содержится точная причина сбоя, например, "connection refused" для HTTP-01 или "provider not recognized" для DNS-01.
Логи cert-manager находятся в подах контроллеров в namespace cert-manager. Используйте команду kubectl logs -n cert-manager deployment/cert-manager для получения детальной информации.
Типичные ошибки ACME-проверок и их решение
Ошибка "connection refused" для HTTP-01 challenge обычно означает, что ACME-сервер не может подключиться к вашему домену на порту 80. Проверьте, что Ingress-контроллер работает и маршрутизирует трафик на порт 80, и что нет NetworkPolicy, блокирующих доступ.
Ошибка "provider not recognized" для DNS-01 возникает, если cert-manager не поддерживает ваш DNS провайдер или секрет с API ключами настроен неправильно. Убедитесь, что вы используете поддерживаемую версию cert-manager и правильно создали Secret с ключами, как указано в документации провайдера.
Ошибка "too many certificates" от Let's Encrypt указывает на превышение лимитов production-сервера. Переключитесь на staging-сервер для тестирования или подождите, пока лимиты обновятся (обычно неделя).
Для глубокого аудита безопасности всей контейнерной среды, включая управление секретами и проверку конфигураций, используйте чек-лист аудита безопасности Docker и Kubernetes.
Безопасность и эксплуатация: ротация, RBAC и политики
Cert-manager автоматически отслеживает срок действия сертификатов и начинает процесс ротации заранее, обычно когда до expiration остается менее 30 дней. Это предотвращает сбои из-за просроченных сертификатов. Контроллер создает новый CertificateRequest, выполняет проверки и обновляет Secret с новым сертификатом и ключом.
Для безопасной эксплуатации ограничьте права service account cert-manager через RBAC. Давайте минимально необходимые разрешения в кластере. Привилегии для создания Secrets и управления CRD в namespace cert-manager обычно достаточны.
Приватные ключи сертификатов хранятся в Kubernetes Secrets. Рассмотрите интеграцию с внешними системами управления ключами, такими как HashiCorp Vault, для повышенной безопасности в производственных средах с высокими требованиями.
Настройте мониторинг событий cert-manager. Оповещения о неуспешной ротации критически важны. В случае сбоя можно временно создать сертификат вручную через kubectl или использовать резервный Issuer.
Автоматизация безопасности инфраструктуры - часть практик DevSecOps. Для комплексного внедрения этих практик в ваш процесс, включая управление секретами и SAST, ознакомьтесь с практическим справочником по интеграции безопасности в DevOps.
Эффективное управление сертификатами снижает операционные риски и позволяет сосредоточиться на разработке приложений. Cert-manager, настроенный по этому руководству, обеспечивает надежное шифрование трафика в Kubernetes на 2026 год.