---
title: "Аддон cert-manager CSI Driver для Kubernetes"
---

# cert-manager CSI Driver

> Полный индекс документации для ИИ-агентов: [llms.txt](https://timeweb.cloud/llms.txt).

cert-manager CSI Driver — это дополнение для Kubernetes, которое позволяет подключать TLS-сертификаты напрямую к подам. Оно работает вместе с [cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager): параметры сертификата задаются в манифесте пода, а драйвер запрашивает сертификат и монтирует его вместе с приватным ключом в указанный каталог. Создавать отдельный ресурс `Certificate` и секрет для сертификата пода не требуется.

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

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

## Установка

Для работы дополнения в кластере должен быть установлен [cert-manager](https://timeweb.cloud/docs/k8s/addons/cert-manager).

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

![аддон cert-manager CSI Driver](https://content.timeweb.com/assets/dac6a57b-4f37-414c-8f32-37696f9beb68.png?width=2164&height=1756)

Для проверки [подключитесь к кластеру с помощью kubectl](https://timeweb.cloud/docs/k8s/cluster-connection/kubectl) и выполните команду:

```bash
kubectl get csidriver csi.cert-manager.io
```

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

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

```bash
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](https://timeweb.cloud/docs/k8s/addons/cert-manager-webhook) — для подтверждения владения доменом через `DNS-01`;
    
-   домен, расположенный на наших NS;
    

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

### Настройка ClusterIssuer

Для выпуска сертификатов потребуется `ClusterIssuer` с именем `letsencrypt-dns`. Создайте его по [инструкции по настройке cert-manager Webhook](https://timeweb.cloud/docs/k8s/addons/cert-manager-webhook#nastrojka-clusterissuer), указав свою почту в параметре `email` и `ID` кластера в `groupName`. Если такой `ClusterIssuer` уже настроен, его можно использовать повторно.

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

```bash
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

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

```bash
kubectl create namespace csi-tls-example
```

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

```bash
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` — страница, которая будет отображаться при обращении к сайту.
    

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

```bash
kubectl apply -f nginx-config.yaml
```

### Создание Deployment

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

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

```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](https://letsencrypt.org/docs/rate-limits/).

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

```bash
kubectl apply -f nginx-deployment.yaml
```

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

```bash
kubectl get pods -n csi-tls-example
```

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

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

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

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

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

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

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

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

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

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

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

```bash
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`:

```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, где находятся сертификат и ключ. Настраивать сертификат на самом балансировщике не требуется.

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

```bash
kubectl apply -f nginx-loadbalancer.yaml
```

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

```bash
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` на полученный адрес и выполните:

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

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

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

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

```bash
kubectl delete namespace csi-tls-example
```

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

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