До 12.5 млн токенов на тест ИИ-агента
Вход/ Регистрация

cert-manager CSI Driver

cert-manager CSI Driver — это дополнение для Kubernetes, которое позволяет подключать TLS-сертификаты напрямую к подам. Оно работает вместе с cert-manager: параметры сертификата задаются в манифесте пода, а драйвер запрашивает сертификат и монтирует его вместе с приватным ключом в указанный каталог. Создавать отдельный ресурс Certificate и секрет для сертификата пода не требуется.

Такой способ подключения подходит для приложений, которые сами обрабатывают TLS-соединения и читают сертификаты из файлов. Например, драйвер может выдать и подключить сертификат к поду с Nginx или предоставить каждому поду собственный сертификат для взаимной аутентификации между сервисами. Сертификаты выпускаются через настроенный Issuer или ClusterIssuer, в том числе от Let's Encrypt.

Каждая реплика приложения получает собственный сертификат и ключ. Приватный ключ генерируется на ноде, где запущен под, хранится в оперативной памяти и не передается драйвером по сети. При удалении пода файлы удаляются, а при его пересоздании сертификат выпускается заново. Если сертификат нужно сохранять между пересозданиями подов или использовать для HTTPS на Ingress-контроллере, можно настроить его через cert-manager с ресурсом Certificate и секретом.

Установка

Для работы дополнения в кластере должен быть установлен cert-manager.

Откройте панель управления кластером, перейдите во вкладку «Дополнения» и выберите cert-manager CSI Driver. В открывшемся мастере нажмите кнопку «Установить» и дождитесь завершения установки.

аддон cert-manager CSI Driver

Для проверки подключитесь к кластеру с помощью kubectl и выполните команду:

    
kubectl get csidriver csi.cert-manager.io

В выводе должен присутствовать драйвер csi.cert-manager.io с режимом Ephemeral. Он используется для временных томов, связанных с жизненным циклом пода. Создавать StorageClass, PersistentVolume и PersistentVolumeClaim для них не нужно.

Драйвер запускается на рабочих нодах как DaemonSet. Проверить его состояние можно командой:

    
kubectl get daemonsets -A

Найдите DaemonSet cert-manager CSI Driver. Значения в колонках DESIRED и READY должны совпадать и быть больше нуля.

Пример использования

В качестве примера развернем Nginx и подключим к нему сертификат с помощью cert-manager CSI Driver. Выпустим сертификат Let's Encrypt для домена site.example.com, подключим его к поду через CSI Driver и настроим доступ к сайту через балансировщик нагрузки. HTTPS-соединения будет обрабатывать Nginx внутри пода.

Помимо cert-manager и cert-manager CSI Driver, для примера потребуются:

  • дополнение cert-manager Webhook — для подтверждения владения доменом через DNS-01;

  • домен, расположенный на наших NS;

В манифестах и командах замените site.example.com на свой домен или поддомен.

Настройка ClusterIssuer

Для выпуска сертификатов потребуется ClusterIssuer с именем letsencrypt-dns. Создайте его по инструкции по настройке cert-manager Webhook, указав свою почту в параметре email и ID кластера в groupName. Если такой ClusterIssuer уже настроен, его можно использовать повторно.

Проверьте готовность созданного ресурса:

    
kubectl get clusterissuer letsencrypt-dns

В колонке READY должно быть значение True.

При запросе сертификата cert-manager Webhook автоматически создаст TXT-запись в DNS. Это позволяет подтвердить владение доменом до запуска Nginx и настройки A-записи сайта.

Выполнять шаги из раздел «Выпуск сертификата» из инструкции про Webhook не нужно. CSI Driver сам создаст CertificateRequest при запуске пода. Секрет, указанный в privateKeySecretRef у ClusterIssuer, будет хранить только ключ учетной записи ACME для взаимодействия с Let's Encrypt.

Создание ConfigMap

Для ресурсов сайта создадим отдельный неймспейс:

    
kubectl create namespace csi-tls-example

Конфигурацию Nginx и HTML-страницу сохраним в ConfigMap. Создайте файл nginx-config.yaml со следующим содержимым:

    
apiVersion: v1 kind: ConfigMap metadata: name: nginx-site-config namespace: csi-tls-example data: default.conf: | server { listen 8443 ssl; server_name site.example.com; ​ ssl_certificate /tls/tls.crt; ssl_certificate_key /tls/tls.key; ​ root /usr/share/nginx/html; index index.html; ​ location / { try_files $uri $uri/ =404; } } index.html: | <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title>Nginx с сертификатом Let’s Encrypt</title> </head> <body> <h1>Сайт работает по HTTPS</h1> <p>Сертификат подключен через cert-manager CSI Driver.</p> </body> </html>

В этом манифесте:

  • default.conf — конфигурация Nginx. Сервер принимает HTTPS-соединения на порту 8443 для домена из server_name.

  • ssl_certificate и ssl_certificate_key — пути к сертификату и приватному ключу, которые подключит CSI Driver.

  • index.html — страница, которая будет отображаться при обращении к сайту.

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

    
kubectl apply -f nginx-config.yaml

Создание Deployment

Теперь создадим деплоймент с Nginx. Подключим к контейнеру конфигурацию и страницу из ConfigMap, а сертификат и ключ смонтируем в каталог /tls с помощью CSI Driver.

Создайте файл nginx-deployment.yaml:

    
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-site namespace: csi-tls-example spec: replicas: 1 selector: matchLabels: app: nginx-site template: metadata: labels: app: nginx-site spec: containers: - name: nginx image: nginx:1.28-alpine ports: - name: https containerPort: 8443 readinessProbe: httpGet: path: / port: https scheme: HTTPS volumeMounts: - name: nginx-config mountPath: /etc/nginx/conf.d readOnly: true - name: html mountPath: /usr/share/nginx/html readOnly: true - name: tls mountPath: /tls readOnly: true volumes: - name: nginx-config configMap: name: nginx-site-config items: - key: default.conf path: default.conf - name: html configMap: name: nginx-site-config items: - key: index.html path: index.html - name: tls csi: driver: csi.cert-manager.io readOnly: true volumeAttributes: csi.cert-manager.io/issuer-name: letsencrypt-dns csi.cert-manager.io/issuer-kind: ClusterIssuer csi.cert-manager.io/dns-names: "site.example.com" csi.cert-manager.io/key-usages: "digital signature,key encipherment,server auth"

Параметры сертификата задаются в секции volumeAttributes:

  • csi.cert-manager.io/issuer-name — имя Issuer, через который будет выпущен сертификат. В примере используется letsencrypt-dns.

  • csi.cert-manager.io/issuer-kind — тип ресурса: Issuer или ClusterIssuer. При использовании Issuer он должен находиться в том же неймспейсе, что и под.

  • csi.cert-manager.io/dns-names — домен сайта. Если нужно указать несколько имен, перечислите их через запятую.

  • csi.cert-manager.io/key-usages — назначение ключа и сертификата. Значение server auth используется для аутентификации HTTPS-сервера.

В секциях volumes и volumeMounts том подключается в режиме только для чтения — readOnly: true. Сертификат и ключ будут храниться в оперативной памяти ноды, в файловой системе tmpfs.

В примере запускается одна реплика Nginx. При увеличении количества реплик каждый новый под получит отдельный сертификат для того же домена. При масштабировании и частом пересоздании подов учитывайте лимиты Let's Encrypt.

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

    
kubectl apply -f nginx-deployment.yaml

Проверьте состояние пода:

    
kubectl get pods -n csi-tls-example

При создании пода драйвер сформирует CertificateRequest в неймспейсе csi-tls-example. cert-manager обработает запрос через letsencrypt-dns, а драйвер запишет полученный сертификат в подключенный том.

Выпуск может занять несколько минут из-за распространения DNS-записей. В это время под может находиться в статусе ContainerCreating. После получения сертификата запустится Nginx.

Повторно выполните команду проверки. У пода nginx-site-... в колонке STATUS должно появиться Running, а в READY1/1.

Проверка сертификата

Проверить статус выпуска можно командой:

    
kubectl get certificaterequests,orders,challenges -n csi-tls-example

При успешном выпуске у CertificateRequest в колонке READY будет значение True, а у Order — состояние valid. Ресурс Challenge после завершения проверки может быть удален автоматически.

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

    
kubectl exec deployment/nginx-site -n csi-tls-example -- ls -l /tls

В каталоге должны быть файлы tls.crt и tls.key. Первый содержит сертификат сайта и промежуточные сертификаты цепочки, второй — приватный ключ.

Чтобы посмотреть центр сертификации, срок действия и доменное имя, передайте содержимое tls.crt в локальный openssl:

    
kubectl exec deployment/nginx-site -n csi-tls-example -- cat /tls/tls.crt \ | openssl x509 -noout -issuer -dates -ext subjectAltName

В поле issuer будет указан центр сертификации Let's Encrypt, а в Subject Alternative Name — ваш домен.

Создание балансировщика нагрузки

Для доступа к сайту из интернета создадим Service типа LoadBalancer. Он получит внешний IP-адрес и будет передавать TCP-трафик на HTTPS-порт Nginx.

Создайте файл nginx-loadbalancer.yaml:

    
apiVersion: v1 kind: Service metadata: name: nginx-site namespace: csi-tls-example spec: type: LoadBalancer selector: app: nginx-site ports: - name: https port: 443 targetPort: https protocol: TCP appProtocol: k8s.timeweb.cloud/proto-tcp

Балансировщик принимает соединения на порту 443 и передает их на порт 8443 в поде. Параметр appProtocol: k8s.timeweb.cloud/proto-tcp включает передачу TCP-трафика: TLS-соединение обрабатывает Nginx, где находятся сертификат и ключ. Настраивать сертификат на самом балансировщике не требуется.

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

    
kubectl apply -f nginx-loadbalancer.yaml

Дождитесь создания балансировщика и проверьте, что сервис получил внешний IP-адрес:

    
kubectl get service nginx-site -n csi-tls-example

IP-адрес будет отображаться в колонке EXTERNAL-IP. Создание балансировщика также можно отследить в разделе «Балансировщики» панели управления.

Настройка домена и проверка HTTPS

Создайте A-запись для домена site.example.com, указав IP-адрес балансировщика. После обновления DNS откройте https://site.example.com в браузере. Должна появиться страница «Сайт работает по HTTPS» без предупреждений о сертификате.

Если DNS еще не обновился, можно проверить сайт, явно указав IP-адрес балансировщика. Замените EXTERNAL_IP на полученный адрес и выполните:

    
curl --fail --show-error \ --resolve site.example.com:443:EXTERNAL_IP \ https://site.example.com/

Параметр --resolve направляет запрос на указанный IP-адрес, сохраняя проверку сертификата для домена site.example.com.

Удаление примера

Чтобы удалить ресурсы сайта, созданные в примере, выполните:

    
kubectl delete namespace csi-tls-example

Вместе с неймспейсом будут удалены поды, конфигурация сайта и сервис LoadBalancer. Связанный балансировщик также будет удален из панели управления. Если домен больше не используется, удалите его A-запись.

Дополнения, ClusterIssuer и ключ учетной записи ACME останутся в кластере — их можно использовать для других приложений.

Была ли статья полезна?
Ваш ответ поможет улучшить документацию
Пока нет комментариев