Установка Ingress-контроллера NGINX с сертификатом из Yandex Certificate Manager
- Перед началом работы
- Добавьте сертификат в Certificate Manager
- Установите External Secrets Operator
- Настройте кластер Managed Service for Kubernetes
- Создайте ExternalSecret
- Установите Ingress-контроллер NGINX
- Создайте веб-ресурс в вашем кластере Managed Service for Kubernetes
- Настройте DNS-запись для Ingress-контроллера
- Создайте ресурс Ingress
- Проверьте доступность ресурса
- Удалите созданные ресурсы
Управляйте TLS-сертификатом для Ingress-контроллера NGINX через Yandex Certificate Manager.
External Secrets Operator
Перед началом работы
-
Если у вас еще нет интерфейса командной строки Yandex Cloud, установите и инициализируйте его.
По умолчанию используется каталог, указанный в профиле CLI. Вы можете указать другой каталог с помощью параметра
--folder-name
или--folder-id
. -
Установите утилиту
jq
:sudo apt update && sudo apt install jq
-
eso-service-account
— для взаимодействия External Secrets Operator с Certificate Manager.k8s-sa
с ролямиeditor
,container-registry.images.puller
иload-balancer.admin
на каталог — для создания ресурсов кластера Managed Service for Kubernetes и скачивания Docker-образов. Рольload-balancer.admin
нужна для создания сетевого балансировщика нагрузки.
-
Создайте авторизованный ключ для сервисного аккаунта и сохраните его в файл
authorized-key.json
:yc iam key create \ --service-account-name eso-service-account \ --output authorized-key.json
-
Создайте группы безопасности для кластера Managed Service for Kubernetes и входящих в него групп узлов.
Важно
От настройки групп безопасности зависит работоспособность и доступность кластера, а также запущенных в нем сервисов и приложений.
-
Создайте кластер Managed Service for Kubernetes и группу узлов любой подходящей конфигурации. В настройках кластера Managed Service for Kubernetes укажите сервисный аккаунт
k8s-sa
и группы безопасности, подготовленные ранее. -
Установите kubectl
и настройте его на работу с созданным кластером.
Необходимые платные ресурсы
В стоимость поддержки инфраструктуры входит:
- Использование мастера Managed Service for Kubernetes и исходящий трафик (см. тарифы Managed Service for Kubernetes).
- Использование узлов кластера Managed Service for Kubernetes (см. тарифы Yandex Compute Cloud).
- Использование публичных IP-адресов (см. тарифы Yandex Virtual Private Cloud).
- Входящий трафик, обработанный балансировщиком, и использование сетевого балансировщика (см. тарифы Yandex Network Load Balancer).
Добавьте сертификат в Certificate Manager
-
Выпустите и добавьте в Certificate Manager сертификат Let's Encrypt® или загрузите собственный сертификат.
-
Для сертификата Let's Encrypt® пройдите проверку прав на домен, который указан в сертификате.
-
Назначьте роль
certificate-manager.certificates.downloader
сервисному аккаунтуeso-service-account
, чтобы он мог читать содержимое сертификата:yc cm certificate add-access-binding \ --id <идентификатор_сертификата> \ --service-account-name eso-service-account \ --role certificate-manager.certificates.downloader
-
Проверьте, что права назначены:
yc cm certificate list-access-bindings --id <идентификатор_сертификата>
Результат:
+---------------------------------------------+----------------+-------------------------------------+ | ROLE ID | SUBJECT TYPE | SUBJECT ID | +---------------------------------------------+----------------+-------------------------------------+ | certificate-manager.certificates.downloader | serviceAccount | <идентификатор_сервисного_аккаунта> | +---------------------------------------------+----------------+-------------------------------------+
Установите External Secrets Operator
-
Добавьте Helm-репозиторий
external-secrets
:helm repo add external-secrets https://charts.external-secrets.io
-
Установите External Secrets Operator в кластер Managed Service for Kubernetes:
helm install external-secrets \ external-secrets/external-secrets \ --namespace external-secrets \ --create-namespace
Эта команда создаст новое пространство имен
external-secrets
, необходимое для работы External Secrets Operator.Результат:
NAME: external-secrets LAST DEPLOYED: Sun Sep 19 11:20:58 2021 NAMESPACE: external-secrets STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: external-secrets has been deployed successfully! ...
Настройте кластер Managed Service for Kubernetes
-
Создайте пространство имен
ns
для объектов External Secrets Operator:kubectl create namespace ns
-
Создайте секрет
yc-auth
, содержащий в себе ключ сервисного аккаунтаeso-service-account
:kubectl --namespace ns create secret generic yc-auth \ --from-file=authorized-key=authorized-key.json
-
Создайте хранилище секретов (SecretStore)
secret-store
, содержащее секретyc-auth
:kubectl --namespace ns apply -f - <<< ' apiVersion: external-secrets.io/v1beta1 kind: SecretStore metadata: name: secret-store spec: provider: yandexcertificatemanager: auth: authorizedKeySecretRef: name: yc-auth key: authorized-key'
Создайте ExternalSecret
-
Создайте объект ExternalSecret
external-secret
, указывающий на сертификат из Certificate Manager:kubectl --namespace ns apply -f - <<< ' apiVersion: external-secrets.io/v1beta1 kind: ExternalSecret metadata: name: external-secret spec: refreshInterval: 1h secretStoreRef: name: secret-store kind: SecretStore target: name: k8s-secret template: type: kubernetes.io/tls data: - secretKey: tls.crt remoteRef: key: <идентификатор_сертификата> property: chain - secretKey: tls.key remoteRef: key: <идентификатор_сертификата> property: privateKey'
Где:
k8s-secret
— имя секрета, в который External Secret Operator поместит сертификат из Certificate Manager.tls.crt
— параметр секретаk8s-secret
, который будет содержать сертификат.tls.key
— параметр секретаk8s-secret
, который будет содержать закрытый ключ сертификата.
Доступны следующие значения параметра
property
:chain
— получить цепочку сертификатов в формате PEM.privateKey
— получить закрытый ключ в формате PEM.chainAndPrivateKey
или пустое значение — получить и цепочку сертификатов, и закрытый ключ.
External Secrets Operator получит сертификат из Certificate Manager и поместит его в секрет
k8s-secret
. -
Проверьте, что сертификат попал в секрет
k8s-secret
:kubectl -n ns get secret k8s-secret -ojson \ | jq '."data"."tls.crt"' -r \ | base64 --decode
Пример результата:
-----BEGIN CERTIFICATE----- MIIFKTCCBBGgAwIBAgISBAlQtxTUnXa75N1TnPYRWbSLMA0GCSqGSIb3DQEBCwUA MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD EwJSMzAeFw0yMjA3MTMxNDMxNTVaFw0yMjEwMTExNDMxNTRaMB0xGzAZBgNVBAMT EmRkb3Mtd2ViLm5yay5tZS51azCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC…
Чтобы просмотреть сертификат в удобном виде, выполните команды:
kubectl -n ns get secret k8s-secret -ojson | jq '."data"."tls.crt"' -r \ | base64 --decode > cert.pem
openssl x509 -in cert.pem -text
Пример результата:
Certificate: Data: Version: 3 (0x2) Serial Number: 04:09:50:b7:14:d4:9d:76:bb:e4:dd:53:9c:f6:11:59:b4:8b Signature Algorithm: sha256WithRSAEncryption Issuer: C = US, O = Let's Encrypt, CN = R3 Validity Not Before: Jul 13 14:31:55 2022 GMT Not After : Oct 11 14:31:54 2022 GMT Subject: CN = example.com ...
Установите Ingress-контроллер NGINX
Установите приложение Ingress NGINX из Cloud Marketplace по инструкции.
-
Добавьте в Helm-репозиторий для NGINX:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
Результат:
"ingress-nginx" has been added to your repositories
-
Обновите набор данных для создания экземпляра приложения в кластере Managed Service for Kubernetes:
helm repo update
Результат:
Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "ingress-nginx" chart repository Update Complete. ⎈Happy Helming!⎈
-
Установите контроллер в стандартной конфигурации. Контроллер будет установлен вместе с Network Load Balancer:
helm install ingress-nginx ingress-nginx/ingress-nginx
Результат:
NAME: ingress-nginx LAST DEPLOYED: Sun Jul 18 22:35:37 2021 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The ingress-nginx controller has been installed. It may take a few minutes for the LoadBalancer IP to be available. You can watch the status by running 'kubectl --namespace default get services -o wide -w ingress-nginx-controller' ...
Чтобы настроить конфигурацию контроллера самостоятельно, обратитесь к документации Helm
Чтобы пробросить определенные порты при установке Ingress-контроллера NGINX, следуйте инструкции.
Создайте веб-ресурс в вашем кластере Managed Service for Kubernetes
Создайте объект
kubectl --namespace ns apply -f - <<< '
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: app
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
labels:
app: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80'
Настройте DNS-запись для Ingress-контроллера
-
Узнайте IP-адрес Ingress-контроллера (значение в колонке
EXTERNAL-IP
):kubectl get svc
Результат:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ... ingress-nginx-controller LoadBalancer 10.96.164.252 84.201.153.122 80:31248/TCP,443:31151/TCP 2m19s ...
-
Разместите у своего DNS-провайдера или на собственном DNS-сервере A-запись, указывающую на публичный IP-адрес Ingress-контроллера:
<имя_домена> IN A 84.201.153.122
Примечание
Регистрация сертификата Let's Encrypt® и A-записи может занять несколько минут.
Создайте ресурс Ingress
Создайте ресурс Ingressk8s-secret
для HTTPS:
kubectl --namespace ns apply -f - <<< '
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
namespace: ns
spec:
tls:
- hosts:
- <имя_домена>
secretName: k8s-secret
ingressClassName: nginx
rules:
- host: <имя_домена>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app
port:
number: 80'
Где <имя_домена>
— доменное имя, для которого выпущен сертификат.
Проверьте доступность ресурса
Выполните GET-запрос к ресурсу по HTTPS, например, командой:
curl https://<ваш_домен> -vv
Пример результата:
* Trying 51.250.64.86:443...
* Connected to <имя_домена> (51.250.64.86) port 443 (#0)
...
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=<имя_домена>
* start date: Jul 13 14:31:55 2022 GMT
* expire date: Oct 11 14:31:54 2022 GMT
* subjectAltName: host "<имя_домена>" matched cert's "<имя_домена>"
...
* SSL certificate verify ok.
Примечание
Если ресурс недоступен по указанному URL, то убедитесь, что группы безопасности для кластера Managed Service for Kubernetes и его групп узлов настроены корректно. Если отсутствует какое-либо из правил — добавьте его.
Сертификат от Let's Encrypt® должен обновляться автоматически вслед за обновлением сертификата в Certificate Manager.
Вы можете задать таймаут синхронизации в параметре refreshInterval
объекта ExternalSecret.
Удалите созданные ресурсы
Некоторые ресурсы платные. Чтобы за них не списывалась плата, удалите ресурсы, которые вы больше не будете использовать: