Использование TLS с контроллером объекта ingress в Службе Azure Kubernetes (AKS)
Протокол TLS использует сертификаты для обеспечения безопасности связи, шифрования, проверки подлинности и целостности. Использование TLS с контроллером входящего трафика в AKS позволяет защитить связь между приложениями и воспользоваться преимуществами контроллера входящего трафика.
Вы можете использовать собственные сертификаты и интегрировать их с драйвером CSI хранилища секретов. Кроме того, можно использовать cert-manager, который автоматически создает и настраивает сертификаты Let's Encrypt . Два приложения выполняются в кластере AKS, каждый из которых доступен по одному IP-адресу.
Внимание
Надстройка маршрутизации приложений рекомендуется для входящего трафика в AKS. Дополнительные сведения см. в статье Managed nginx Ingress с надстройкой маршрутизации приложений.
Внимание
Корпорация Майкрософт не управляет или не поддерживает диспетчер сертификатов и любые проблемы, связанные с его использованием. Сведения о проблемах с cert-manager см . в документации по устранению неполадок с cert-manager.
Существует два контроллера объекта ingress с открытым исходным кодом для Kubernetes на основе Nginx: один поддерживается сообществом Kubernetes (kubernetes/ingress-nginx), а второй — компанией Nginx, Inc. (nginxinc/kubernetes-ingress). В этой статье используется контроллер входящего трафика сообщества Kubernetes.
Подготовка к работе
В этой статье предполагается, что у вас есть контроллер входящего трафика и приложения. Если вам нужен контроллер объекта ingress или примеры приложений, см. статью Создание контроллера входящего трафика в Службе Azure Kubernetes (AKS).
В данной статье описано использование Helm 3 для установки контроллера объекта ingress NGINX на поддерживаемую версию Kubernetes. Убедитесь, что вы используете последний выпуск Helm и имеете доступ к
ingress-nginx
jetstack
репозиториям Helm. Порядок действий, описанный в этой статье, может не подходить для предыдущих версий диаграммы Helm, контроллера объекта ingress NGINX или Kubernetes.- Дополнительные сведения о настройке и использовании Helm см. в статье "Установка приложений с помощью Helm" в AKS. Инструкции по обновлению см. в документации по установке Helm.
В этой статье предполагается, что у вас есть существующий кластер AKS с интегрированным Реестр контейнеров Azure (ACR). Дополнительные сведения о создании кластера AKS с интегрированным ACR см. в статье Аутентификация с помощью ACR из AKS.
Если вы используете Azure CLI, эта статья требует, чтобы вы использовали Azure CLI версии 2.0.64 или более поздней. Чтобы узнать версию, выполните команду
az --version
. Если вам необходимо выполнить установку или обновление, см. статью Установка Azure CLI 2.0.Если вы используете Azure PowerShell, в этой статье требуется, чтобы вы работали с Azure PowerShell версии 5.9.0 или более поздней. Чтобы узнать версию, выполните команду
Get-InstalledModule -Name Az
. Если вам необходимо выполнить установку или обновление, см. статью об установке Azure PowerShell.
Использование TLS с собственными сертификатами с драйвером CSI хранилища секретов
Чтобы использовать TLS с собственными сертификатами с драйвером CSI хранилища секретов, вам потребуется кластер AKS с настроенным драйвером CSI хранилища секретов и экземпляром Azure Key Vault.
Дополнительные сведения см. в статье Настройка драйвера CSI хранилища секретов для включения контроллера объекта ingress NGINX с протоколом TLS.
Использование протокола TLS с сертификатами Let's Encrypt
Чтобы использовать TLS с сертификатами Let's Encrypt , вы развернете диспетчер сертификатов, который автоматически создает и настраивает сертификаты Let's Encrypt.
Импорт образов cert-manager, используемых чартом Helm, в ACR
Используйте
az acr import
для импорта следующих изображений в ACR.REGISTRY_NAME=<REGISTRY_NAME> CERT_MANAGER_REGISTRY=quay.io CERT_MANAGER_TAG=v1.8.0 CERT_MANAGER_IMAGE_CONTROLLER=jetstack/cert-manager-controller CERT_MANAGER_IMAGE_WEBHOOK=jetstack/cert-manager-webhook CERT_MANAGER_IMAGE_CAINJECTOR=jetstack/cert-manager-cainjector az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_CONTROLLER:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_CONTROLLER:$CERT_MANAGER_TAG az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_WEBHOOK:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_WEBHOOK:$CERT_MANAGER_TAG az acr import --name $REGISTRY_NAME --source $CERT_MANAGER_REGISTRY/$CERT_MANAGER_IMAGE_CAINJECTOR:$CERT_MANAGER_TAG --image $CERT_MANAGER_IMAGE_CAINJECTOR:$CERT_MANAGER_TAG
Примечание.
Вы также можете импортировать диаграммы Helm в ACR. Дополнительные сведения см. в статье "Отправка и извлечение диаграмм Helm" в ACR.
Параметры конфигурации контроллера объекта ingress
Контроллер входящего трафика NGINX можно настроить с помощью статического общедоступного IP-адреса или динамического общедоступного IP-адреса. Если вы используете личный домен, необходимо добавить запись A в зону DNS. Если вы не используете личный домен, можно настроить полное доменное имя (FQDN) для IP-адреса контроллера входящего трафика.
Создание статического или динамического общедоступного IP-адреса
Использование статического общедоступного IP-адреса
Контроллер входящего трафика можно настроить со статическим общедоступным IP-адресом. Статический общедоступный IP-адрес остается при удалении контроллера входящего трафика. IP-адрес не остается, если удалить кластер AKS.
При обновлении контроллера входящего трафика необходимо передать параметр в выпуск Helm, чтобы служба контроллера входящего трафика была осведомлена о подсистеме балансировки нагрузки, которая будет выделена для него. Чтобы сертификаты HTTPS работали правильно, используйте метку DNS для настройки полного доменного имени для IP-адреса контроллера входящего трафика.
Получите имя группы ресурсов кластера AKS с
az aks show
помощью команды.az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
Создайте общедоступный IP-адрес со статическим методом выделения с помощью
az network public-ip create
команды. В следующем примере создается общедоступный IP-адрес с именем myAKSPublicIP в группе ресурсов кластера AKS, полученной на предыдущем шаге.az network public-ip create --resource-group MC_myResourceGroup_myAKSCluster_eastus --name myAKSPublicIP --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv
Примечание.
Кроме того, можно создать IP-адрес в другой группе ресурсов, которую можно управлять отдельно от кластера AKS. Если вы создаете IP-адрес в другой группе ресурсов, проверьте следующие характеристики:
- Удостоверение кластера, используемое кластером AKS, имеет делегированные разрешения на доступ к группе ресурсов, например участник сетей.
- Добавьте параметр
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-resource-group"="<RESOURCE_GROUP>"
. Замените<RESOURCE_GROUP>
именем группы ресурсов, в которой находится IP-адрес.
Добавьте параметр
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="<DNS_LABEL>"
. Метку DNS можно задать либо при первом развертывании контроллера объекта ingress, либо настроить позже.Добавьте параметр
--set controller.service.loadBalancerIP="<STATIC_IP>"
. Укажите собственный общедоступный IP-адрес, созданный на предыдущем шаге.DNS_LABEL="<DNS_LABEL>" NAMESPACE="ingress-basic" STATIC_IP=<STATIC_IP> helm upgrade ingress-nginx ingress-nginx/ingress-nginx \ --namespace $NAMESPACE \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$DNS_LABEL \ --set controller.service.loadBalancerIP=$STATIC_IP \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
Дополнительные сведения см. в статье Использование статического общедоступного IP-адреса и DNS-метки с подсистемой балансировки нагрузки Службы Azure Kubernetes (AKS).
Использование динамического общедоступного IP-адреса
Общедоступный IP-адрес Azure создается для контроллера входящего трафика при создании. Общедоступный IP-адрес является статическим в течение срока существования контроллера входящего трафика. Общедоступный IP-адрес не остается, если удалить контроллер входящего трафика. При создании нового контроллера входящего трафика он будет назначен новый общедоступный IP-адрес. Выходные данные должны выглядеть примерно так, как в следующем примере выходных данных.
kubectl get service
Используйте команду, чтобы получить общедоступный IP-адрес для контроллера входящего трафика.# Get the public IP address for your ingress controller kubectl --namespace ingress-basic get services -o wide -w nginx-ingress-ingress-nginx-controller # Sample output NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR nginx-ingress-ingress-nginx-controller LoadBalancer 10.0.74.133 EXTERNAL_IP 80:32486/TCP,443:30953/TCP 44s app.kubernetes.io/component=controller,app.kubernetes.io/instance=nginx-ingress,app.kubernetes.io/name=ingress-nginx
Добавление записи A в зону DNS
Если вы используете личный домен, необходимо добавить запись A в зону DNS. Если вы не используете личный домен, можно настроить общедоступный IP-адрес с полным доменным именем.
Добавьте запись A в зону DNS с внешним IP-адресом службы NGINX с помощью
az network dns record-set a add-record
.az network dns record-set a add-record \ --resource-group myResourceGroup \ --zone-name MY_CUSTOM_DOMAIN \ --record-set-name "*" \ --ipv4-address MY_EXTERNAL_IP
Настройка полного доменного имени для контроллера входящего трафика
При необходимости можно настроить полное доменное имя для IP-адреса контроллера входящего трафика вместо личного домена, задав метку DNS. Полное доменное имя должно соответствовать следующей форме: <CUSTOM DNS LABEL>.<AZURE REGION NAME>.cloudapp.azure.com
Внимание
Ваша метка DNS должна быть уникальной в своем расположении Azure.
Полное доменное имя можно настроить с помощью одного из следующих методов:
- Задайте метку DNS с помощью Azure CLI или Azure PowerShell.
- Задайте метку DNS с помощью параметров диаграммы Helm.
Дополнительные сведения см. в метках DNS-имени общедоступного IP-адреса.
Настройка метки DNS с помощью Azure CLI или Azure PowerShell
Обязательно замените <DNS_LABEL>
уникальной меткой DNS.
# Public IP address of your ingress controller
IP="MY_EXTERNAL_IP"
# Name to associate with public IP address
DNSLABEL="<DNS_LABEL>"
# Get the resource-id of the public IP
PUBLICIPID=$(az network public-ip list --query "[?ipAddress!=null]|[?contains(ipAddress, '$IP')].[id]" --output tsv)
# Update public IP address with DNS name
az network public-ip update --ids $PUBLICIPID --dns-name $DNSLABEL
# Display the FQDN
az network public-ip show --ids $PUBLICIPID --query "[dnsSettings.fqdn]" --output tsv
Задание метки DNS с помощью параметров диаграммы Helm
Вы можете передать параметр заметки в конфигурацию диаграммы Helm с помощью --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"
параметра. Этот параметр можно задать при первом развертывании контроллера входящего трафика или его можно настроить позже.
В следующем примере показано, как обновить этот параметр после развертывания контроллера. Обязательно замените <DNS_LABEL>
уникальной меткой DNS.
DNSLABEL="<DNS_LABEL>"
NAMESPACE="ingress-basic"
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
--namespace $NAMESPACE \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$DNSLABEL \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz
Установка cert-manager
Контроллер NGINX Ingress поддерживает завершение TLS. Существует несколько способов извлечения и настройки сертификатов для протокола HTTPS. В этой статье используется диспетчер сертификатов, который предоставляет автоматические функции создания сертификатов и управления ими.
Чтобы установить контроллер cert-manager, используйте следующие команды.
# Set variable for ACR location to use for pulling images
ACR_URL=<REGISTRY_URL>
# Label the ingress-basic namespace to disable resource validation
kubectl label namespace ingress-basic cert-manager.io/disable-validation=true
# Add the Jetstack Helm repository
helm repo add jetstack https://charts.jetstack.io
# Update your local Helm chart repository cache
helm repo update
# Install the cert-manager Helm chart
helm install cert-manager jetstack/cert-manager \
--namespace ingress-basic \
--version=$CERT_MANAGER_TAG \
--set installCRDs=true \
--set nodeSelector."kubernetes\.io/os"=linux \
--set image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_CONTROLLER \
--set image.tag=$CERT_MANAGER_TAG \
--set webhook.image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_WEBHOOK \
--set webhook.image.tag=$CERT_MANAGER_TAG \
--set cainjector.image.repository=$ACR_URL/$CERT_MANAGER_IMAGE_CAINJECTOR \
--set cainjector.image.tag=$CERT_MANAGER_TAG
Дополнительные сведения о конфигурации cert-manager см. в описании проекта cert-manager.
Создание издателя кластера ЦС
Прежде чем сертификаты будут выданы, диспетчер сертификатов требует одного из следующих издателей:
- Издатель, который работает в одном пространстве имен.
- Ресурс ClusterIssuer, который работает во всех пространствах имен.
Дополнительные сведения см. в документации по издателю cert-manager.
Создайте издатель кластера, например
cluster-issuer.yaml
, используя приведенный ниже пример манифеста. ЗаменитеMY_EMAIL_ADDRESS
допустимым адресом из вашей организации.apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: MY_EMAIL_ADDRESS privateKeySecretRef: name: letsencrypt solvers: - http01: ingress: class: nginx podTemplate: spec: nodeSelector: "kubernetes.io/os": linux
Примените издателя с помощью
kubectl apply
команды.kubectl apply -f cluster-issuer.yaml --namespace ingress-basic
Обновление маршрутов входящего трафика
Необходимо обновить маршруты входящего трафика для обработки трафика в полное доменное имя или личный домен.
В следующем примере трафик направляется следующим образом:
- Трафик к hello-world-ingress. MY_CUSTOM_DOMAIN направляется в службу aks-helloworld-one .
- Трафик к hello-world-ingress. MY_CUSTOM_DOMAIN/hello-world-two направляется в службу aks-helloworld-two .
- Трафик к hello-world-ingress.MY_CUSTOM_DOMAIN/static перенаправляется к службе aks-helloworld-one для статических ресурсов.
Примечание.
Если вы настроили полное доменное имя для IP-адреса контроллера входящего трафика вместо личного домена, используйте полное доменное имя вместо hello-world-ingress.MY_CUSTOM_DOMAIN.
Например, если полное доменное имя demo-aks-ingress.eastus.cloudapp.azure.com, замените hello-world-ingress. MY_CUSTOM_DOMAIN с demo-aks-ingress.eastus.cloudapp.azure.com в hello-world-ingress.yaml
.
Создайте или обновите файл с помощью следующего
hello-world-ingress.yaml
примера YAML-файла.spec.tls.hosts
Обновите dns-имя,spec.rules.host
созданное на предыдущем шаге.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-world-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/use-regex: "true" cert-manager.io/cluster-issuer: letsencrypt spec: ingressClassName: nginx tls: - hosts: - hello-world-ingress.MY_CUSTOM_DOMAIN secretName: tls-secret rules: - host: hello-world-ingress.MY_CUSTOM_DOMAIN http: paths: - path: /hello-world-one(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 - path: /hello-world-two(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-two port: number: 80 - path: /(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-world-ingress-static annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/rewrite-target: /static/$2 spec: ingressClassName: nginx tls: - hosts: - hello-world-ingress.MY_CUSTOM_DOMAIN secretName: tls-secret rules: - host: hello-world-ingress.MY_CUSTOM_DOMAIN http: paths: - path: /static(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80
Обновите ресурс входящего трафика с помощью команды
kubectl apply
.kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
Проверка создания объекта сертификата
Далее нужно создать ресурс сертификата. Этот ресурс сертификата определяет необходимый сертификат X.509. Дополнительные сведения см. в описании сертификатов cert-manager.
Cert-manager автоматически создает объект сертификата для вас с помощью ingress-shim, который автоматически развертывается с помощью диспетчера сертификатов с версии 0.2.2. Дополнительные сведения см. в документации по ingress-shim.
Чтобы убедиться, что сертификат был создан успешно, используйте kubectl get certificate --namespace ingress-basic
команду и убедитесь , что готово к работе с значением True. Для получения выходных данных может потребоваться несколько минут.
kubectl get certificate --namespace ingress-basic
В следующем выходных данных показано состояние сертификата.
NAME READY SECRET AGE
tls-secret True tls-secret 11m
Проверка конфигурации входящего трафика
Откройте браузер по адресу hello-world-ingress.MY_CUSTOM_DOMAIN или по полному доменному имени контроллера объекта ingress в Kubernetes. Убедитесь, что следующие значения имеют значение true:
- Вы перенаправляетесь для использования HTTPS.
- Сертификат является доверенным.
- Демонстрационное приложение отображается в веб-браузере.
- Добавьте /hello-world-two в конец домена и убедитесь, что второе демонстрационное приложение с пользовательским заголовком отображается.
Очистка ресурсов
В этой статье для установки компонентов обработки входящего трафика, сертификатов и примеров приложений используется Helm. При развертывании чарта Helm создается множество ресурсов Kubernetes. К ним относятся элементы pod, развертывания и службы. Чтобы очистить эти ресурсы, можно удалить все образец пространства имен или отдельные ресурсы.
Удаление примера пространства имен и всех ресурсов
При удалении примера пространства имен также удаляются все ресурсы в пространстве имен.
Удалите весь образец пространства имен с помощью
kubectl delete
команды и укажите имя пространства имен.kubectl delete namespace ingress-basic
Удаление ресурсов по отдельности
Кроме того, можно удалить ресурс по отдельности.
Удалите ресурсы издателя кластера.
kubectl delete -f cluster-issuer.yaml --namespace ingress-basic
Получите список выпусков Helm с помощью команды
helm list
. Найдите диаграммы с именем nginx и cert-manager, как показано в следующем примере выходных данных.$ helm list --namespace ingress-basic NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager ingress-basic 1 2020-01-15 10:23:36.515514 -0600 CST deployed cert-manager-v0.13.0 v0.13.0 nginx ingress-basic 1 2020-01-15 10:09:45.982693 -0600 CST deployed nginx-ingress-1.29.1 0.27.0
Удалите выпуски
helm uninstall
с помощью команды. В следующем примере производится удаление развертываний входящего трафика NGINX и cert-manager.$ helm uninstall cert-manager nginx --namespace ingress-basic release "cert-manager" uninstalled release "nginx" uninstalled
Удалите два примера приложений.
kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
Удалите маршрут входящего трафика, направленный на примеры приложений.
kubectl delete -f hello-world-ingress.yaml --namespace ingress-basic
Удалите само пространство имен.
kubectl delete
Используйте команду и укажите имя пространства имен.kubectl delete namespace ingress-basic
Следующие шаги
В данной статье упоминаются некоторые внешние компоненты для AKS. Чтобы узнать больше об этих компонентах, см. следующие страницы проекта:
Кроме того, вы можете сделать следующее: