Featured image of post Установка cert-manager и подключение cert-manager к Vault

Установка cert-manager и подключение cert-manager к Vault

Полная цепочка для выдачи TLS сертификатов

Cert-manager – это сервис в Kubernetes, который автоматизирует выпуск и управление TLS-сертификатами.

Требования:

  • Готовый Kubernetes-кластер (или K3S)
  • Ingress NGINX
  • Приватный репозиторий Harbor
  • helm, nerdctl/docker
  • Развёрнутый Vault + настроенные роли
  • Запись в DNS: vault.k8s.domain.local (Ваш домен), например gitlab.k8s.domain.local

Данный гайд - это часть общей архитектуры по построению полноценной системы выпуска TLS сертификатов.
Cert-manager из этого мануала может быть настроен как отдельно, так и совместно с общей схемой.

План:

  • Подготовить chart и образы cert-manager
  • Установить cert-manager
  • Создать Issuer через serviceAccountRef
  • Выпустить тестовый Certificate
  • Подключить сертификаты к Ingress приложений

Шаг 1. Онлайн установка

1
2
3
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack --version <CHART_VERSION> -n cert-manager --create-namespace --set crds.enabled=true

В <CHART_VERSION> ставьте версию своего чарта.
Установка завершена.

Шаг 2. Оффлайн установка

Подготовка cert-manager chart и образов

На компе/сервере с инетом:

1
2
3
4
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm pull jetstack/cert-manager --untar
cd cert-manager

Извлекаем имена образов:

1
2
helm template cert-manager . > rendered.yaml
grep -oE 'image:\s*"?[^"]+' rendered.yaml | sed -E 's/^image:\s*"?//; s/"$//' | sort -u > cm-images.txt

Скачиваем:

1
2
3
while read -r img; do
  docker pull "$img"
done < cm-images.txt

Сохраняем:

1
docker save -o cm-images.tar $(cat cm-images.txt)

Упаковываем образы:

1
2
cd ..
tar -cvf cert-manager-src.tgz cert-manager

Загрузка в приватный репозиторий

Переносим архивы в закрытый контур:

1
2
tar -xvf cert-manager-src.tgz
cd cert-manager

Загружаем образы:

1
sudo docker load -i ./cm-images.tar

Указываем куда грузить образы Harbor репозиторий и имя проекта созданного в нём
У меня создан приватный репозиторий с именем platform

1
2
3
4
5
6
7
8
export HARBOR="harbor.domain.local"
export PROJECT="platform"

while read -r img; do
  new="${HARBOR}/${PROJECT}/${img}"
  docker tag "${img}" "$new"
  docker push "$new"
done < cm-images.txt

Удаляем лишний мусор:

1
sudo rm cm-images.txt cm-images.tar rendered.yaml

Делаем из файлов Chart и пушим его в репозиторий Harbor:

1
2
helm package . -d .
helm push cert-manager-*.tgz oci://harbor.domain.local/helm

Установка cert-manager

Для справки: Cert-manager использует ресурсы Issuer, ClusterIssuer и Certificate - это базовая модель работы сертификатов в Kubernetes.

Создаём файл:

1
nano certman-values.yaml:

Наполняем:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
replicaCount: 2

podDisruptionBudget:
  enabled: true

resources:
  requests:
    cpu: 50m
    memory: 128Mi
  limits:
    cpu: 200m
    memory: 256Mi

global:
  imagePullSecrets:
    - name: harbor-regcred
image:
  repository: harbor.domain.local/platform/quay.io/jetstack/cert-manager-controller
webhook:
  image:
    repository: harbor.domain.local/platform/quay.io/jetstack/cert-manager-webhook
cainjector:
  image:
    repository: harbor.domain.local/platform/quay.io/jetstack/cert-manager-cainjector
startupapicheck:
  image:
    repository: harbor.domain.local/platform/quay.io/jetstack/cert-manager-startupapicheck

Если доступ в репозиторий Harbor без авторизации, то секцию:

1
2
  imagePullSecrets:
    - name: harbor-regcred

Удалить. В противном случае создать сикрет для доступа с этим именем в кластере кубернетес.

Запуск оффлайн установки

Запускаем установку:

1
2
3
4
5
helm install cert-manager oci://harbor.domain.local/helm/cert-manager \
  --version <CHART_VERSION> \
  -n cert-manager \
  --create-namespace \
  -f certman-values.yaml

Проверка:

1
2
kubectl get pods -n cert-manager
kubectl get crds | grep cert-manager

Поды должны подняться, а custom resource deffinitions создаться.

Шаг 3. Подключение cert-manager к Vault

Рекомендуемый вариант ClusterIssuer

Создаём файл:

1
nano issuer.yaml:

Добавляем содержимое запроса:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: vault-issuer
spec:
  vault:
    server: http://vault.vault.svc:8200
    path: pki/sign/k8s-domain
    auth:
      kubernetes:
        mountPath: /v1/auth/kubernetes
        role: cert-manager
        serviceAccountRef:
          name: cert-manager

Для актуальных версий cert-manager используем serviceAccountRef.
Где ServiceAccountRef — это service account, от имени которого cert-manager запрашивает токен.
Применяем:

1
kubectl apply -f issuer.yaml

Проверяем:

1
2
kubectl get clusterissuers.cert-manager.io vault-issuer -o wide
kubectl describe clusterissuer vault-issuer

Выпуск тестового сертификата

Создаём файл:

1
nano test-cert.yaml:

С тестовым запросом сертификата. Домен указывайте ваш:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: test-cert
  namespace: default
spec:
  secretName: test-cert-tls
  issuerRef:
    name: vault-issuer
    kind: ClusterIssuer
  commonName: test.k8s.domain.local
  dnsNames:
    - test.k8s.domain.local

Применяем:

1
kubectl apply -f test-cert.yaml

Если всё хорошо, появится TLS secret с ключом и сертификатом.

1
2
kubectl -n default describe certificate test-cert
kubectl -n default get secret test-cert-tls

Пример запроса сертификата для приложения Gitlab

Создаётся файл:

1
nano gitlab-cert.yaml:

Внутри прописываем доменное имя сервиса и создаём имя секрета, который содержит внутри ключ и сертификат:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: gitlab-cert
  namespace: gitlab
spec:
  secretName: gitlab-tls
  issuerRef:
    name: vault-issuer
    kind: ClusterIssuer
  dnsNames:
    - gitlab.k8s.domain.local

У меня GitLab развёрнут через Helm чарт, поэтому в Helm чарте я изменяю Ingress на работу с https

1
2
3
4
5
Ingress:
  tls:
    - hosts:
        - gitlab.k8s.domain.local
      secretName: gitlab-tls

Если вы используете манифесты для ingress, то логика такая же включить tls и указать созданный ранее сикрет.

Получаем защищенное TLS соединение, а когда срок сертификата будет подходить к концу cert-manager сам его обновит.

Типовые проверки

Команды для проверки и диагностики cert-manager:

1
2
3
4
5
kubectl get pods -n cert-manager
kubectl get clusterissuer
kubectl describe clusterissuer vault-issuer
kubectl get certificaterequests -A
kubectl get certificates -A

Команды для проверки и диагностики Vault:

1
2
3
4
5
6
7
kubectl -n vault exec -it vault-0 -- vault status
kubectl -n vault exec -it vault-0 -- vault secrets list
kubectl -n vault exec -it vault-0 -- vault list pki/issuers
kubectl -n vault exec -it vault-0 -- vault read pki/config/urls
kubectl -n vault exec -it vault-0 -- vault read pki/roles/k8s-domain
kubectl -n vault exec -it vault-0 -- vault read auth/kubernetes/config
kubectl -n vault exec -it vault-0 -- vault read auth/kubernetes/role/cert-manager
Информацию можно использовать в свободном доступе, с указанием ссылки на сайт
Telegram GitHub YouTube