Usar TLS com um controlador de entrada no Serviço Kubernetes do Azure (AKS)
O protocolo TLS (Transport Layer Security) usa certificados para fornecer segurança para comunicação, criptografia, autenticação e integridade. Usar TLS com um controlador de entrada no AKS permite que você proteja a comunicação entre seus aplicativos e experimente os benefícios de um controlador de entrada.
Você pode trazer seus próprios certificados e integrá-los com o driver CSI da Secrets Store. Como alternativa, você pode usar o cert-manager, que gera e configura automaticamente os certificados Let's Encrypt . Duas aplicações são executadas no cluster AKS, cada uma das quais é acessível através de um único endereço IP.
Importante
O complemento de roteamento de aplicativos é recomendado para entrada no AKS. Para obter mais informações, consulte Managed nginx Ingress with the application routing add-on.
Importante
A Microsoft não gerencia nem oferece suporte ao cert-manager e a quaisquer problemas decorrentes de seu uso. Para problemas com o cert-manager, consulte a documentação de solução de problemas do cert-manager.
Existem dois controladores de entrada de código aberto para Kubernetes baseados em Nginx: um é mantido pela comunidade Kubernetes (kubernetes/ingress-nginx), e um é mantido pela NGINX, Inc. Este artigo usa o controlador de entrada da comunidade Kubernetes.
Antes de começar
Este artigo pressupõe que você tenha um controlador de entrada e aplicativos configurados. Se você precisar de um controlador de entrada ou aplicativos de exemplo, consulte Criar um controlador de entrada.
Este artigo usa o Helm 3 para instalar o controlador de entrada NGINX em uma versão suportada do Kubernetes. Certifique-se de que está a utilizar a versão mais recente do Helm e tenha acesso aos
ingress-nginx
repositórios ejetstack
Helm. As etapas descritas neste artigo podem não ser compatíveis com versões anteriores do gráfico Helm, controlador de entrada NGINX ou Kubernetes.- Para obter mais informações sobre como configurar e usar o Helm, consulte Instalar aplicativos com o Helm no AKS. Para obter instruções de atualização, consulte os documentos de instalação do Helm.
Este artigo pressupõe que você tenha um cluster AKS existente com um Registro de Contêiner do Azure (ACR) integrado. Para obter mais informações sobre como criar um cluster AKS com um ACR integrado, consulte Autenticar com ACR do AKS.
Se você estiver usando a CLI do Azure, este artigo requer que você esteja executando a CLI do Azure versão 2.0.64 ou posterior. Executar
az --version
para localizar a versão. Se precisar de instalar ou atualizar, veja Install Azure CLI (Instalar o Azure CLI).Se você estiver usando o Azure PowerShell, este artigo requer que você esteja executando o Azure PowerShell versão 5.9.0 ou posterior. Executar
Get-InstalledModule -Name Az
para localizar a versão. Se precisar de instalar ou atualizar, veja Install Azure PowerShell(Instalar o Azure PowerShell).
Use TLS com seus próprios certificados com o Secrets Store CSI Driver
Para usar o TLS com seus próprios certificados com o Driver CSI do Secrets Store, você precisa de um cluster AKS com o Driver CSI do Secrets Store configurado e uma instância do Azure Key Vault.
Para obter mais informações, consulte Configurar o driver CSI do Secrets Store para habilitar o NGINX Ingress Controller com TLS.
Usar TLS com certificados Let's Encrypt
Para usar o TLS com certificados Let's Encrypt , você implantará o cert-manager, que gera e configura automaticamente os certificados Let's Encrypt.
Importe as imagens do cert-manager usadas pelo gráfico Helm para o ACR
Use
az acr import
para importar as seguintes imagens para o seu 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
Nota
Você também pode importar gráficos Helm para seu ACR. Para obter mais informações, consulte Enviar e puxar gráficos de leme para um ACR.
Opções de configuração do controlador de ingresso
Você pode configurar seu controlador de entrada NGINX usando um endereço IP público estático ou um endereço IP público dinâmico. Se estiver a utilizar um domínio personalizado, tem de adicionar um registo A à sua zona DNS. Se você não estiver usando um domínio personalizado, poderá configurar um FQDN (nome de domínio totalmente qualificado) para o endereço IP do controlador de ingresso.
Criar um endereço IP público estático ou dinâmico
Utilizar um endereço IP público estático
Você pode configurar seu controlador de entrada com um endereço IP público estático. O endereço IP público estático permanecerá se você excluir seu controlador de entrada. O endereço IP não permanece se você excluir seu cluster AKS.
Ao atualizar seu controlador de entrada, você deve passar um parâmetro para a liberação do Helm para garantir que o serviço do controlador de entrada esteja ciente do balanceador de carga que será alocado a ele. Para que os certificados HTTPS funcionem corretamente, use um rótulo DNS para configurar um FQDN para o endereço IP do controlador de entrada.
Obtenha o nome do grupo de recursos do cluster AKS com o
az aks show
comando.az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
Crie um endereço IP público com o método de alocação estática usando o
az network public-ip create
comando. O exemplo a seguir cria um endereço IP público chamado myAKSPublicIP no grupo de recursos de cluster AKS obtido na etapa anterior.az network public-ip create --resource-group MC_myResourceGroup_myAKSCluster_eastus --name myAKSPublicIP --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv
Nota
Como alternativa, você pode criar um endereço IP em um grupo de recursos diferente, que pode ser gerenciado separadamente do cluster AKS. Se você criar um endereço IP em um grupo de recursos diferente, verifique se o seguinte é verdadeiro:
- A identidade do cluster usada pelo cluster AKS delegou permissões ao grupo de recursos, como Colaborador de Rede.
- Adicione o
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-resource-group"="<RESOURCE_GROUP>"
parâmetro. Substitua<RESOURCE_GROUP>
pelo nome do grupo de recursos onde reside o endereço IP.
Adicione o
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="<DNS_LABEL>"
parâmetro. O rótulo DNS pode ser definido quando o controlador de entrada é implantado pela primeira vez ou pode ser configurado posteriormente.Adicione o
--set controller.service.loadBalancerIP="<STATIC_IP>"
parâmetro. Especifique seu próprio endereço IP público que foi criado na etapa anterior.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
Para obter mais informações, consulte Usar um endereço IP público estático e um rótulo DNS com o balanceador de carga AKS.
Utilizar um endereço IP público dinâmico
Um endereço IP público do Azure é criado para seu controlador de entrada após a criação. O endereço IP público é estático durante a vida útil do seu controlador de entrada. O endereço IP público não permanece se você excluir seu controlador de entrada. Se você criar um novo controlador de entrada, ele receberá um novo endereço IP público. Sua saída deve ser semelhante à saída de exemplo a seguir.
Use o
kubectl get service
comando para obter o endereço IP público para seu controlador de entrada.# 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
Adicionar um registo A à sua zona DNS
Se estiver a utilizar um domínio personalizado, tem de adicionar um registo A à sua zona DNS. Se você não estiver usando um domínio personalizado, poderá configurar o endereço IP público com um FQDN.
Adicione um registro A à sua zona DNS com o endereço IP externo do serviço NGINX usando
az network dns record-set a add-record
o .az network dns record-set a add-record \ --resource-group myResourceGroup \ --zone-name MY_CUSTOM_DOMAIN \ --record-set-name "*" \ --ipv4-address MY_EXTERNAL_IP
Configurar um FQDN para seu controlador de entrada
Opcionalmente, você pode configurar um FQDN para o endereço IP do controlador de entrada em vez de um domínio personalizado definindo um rótulo DNS. O seu FQDN deve seguir este formulário: <CUSTOM DNS LABEL>.<AZURE REGION NAME>.cloudapp.azure.com
.
Importante
Seu rótulo DNS deve ser exclusivo em seu local do Azure.
Você pode configurar seu FQDN usando um dos seguintes métodos:
- Defina o rótulo DNS usando a CLI do Azure ou o Azure PowerShell.
- Defina o rótulo DNS usando as configurações do gráfico Helm.
Para obter mais informações, consulte Rótulos de nome DNS de endereço IP público.
Definir o rótulo DNS usando a CLI do Azure ou o Azure PowerShell
Certifique-se de substituir <DNS_LABEL>
por seu rótulo DNS exclusivo.
# 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
Definir o rótulo DNS usando as configurações do gráfico Helm
Você pode passar uma configuração de anotação para a configuração do gráfico Helm usando o --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"
parâmetro. Esse parâmetro pode ser definido quando o controlador de entrada é implantado pela primeira vez ou pode ser configurado posteriormente.
O exemplo a seguir mostra como atualizar essa configuração após a implantação do controlador. Certifique-se de substituir <DNS_LABEL>
por seu rótulo DNS exclusivo.
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
Instalar o cert-manager
O controlador de entrada do NGINX suporta a terminação de TLS. Existem várias formas de obter e configurar certificados para HTTPS. Este artigo usa o cert-manager, que fornece a funcionalidade automática de geração e gerenciamento de certificados Lets Encrypt .
Para instalar o controlador cert-manager, use os seguintes comandos.
# 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
Para obter mais informações sobre a configuração do cert-manager, consulte o projeto cert-manager.
Criar um emissor de cluster de CA
Antes que os certificados possam ser emitidos, o cert-manager requer um dos seguintes emissores:
- Um emissor, que funciona em um único namespace.
- Um recurso ClusterIssuer , que funciona em todos os namespaces.
Para obter mais informações, consulte a documentação do emissor do cert-manager.
Crie um emissor de cluster, como
cluster-issuer.yaml
, usando o manifesto de exemplo a seguir. SubstituaMY_EMAIL_ADDRESS
por um endereço válido da sua organização.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
Aplique o emissor usando o
kubectl apply
comando.kubectl apply -f cluster-issuer.yaml --namespace ingress-basic
Atualize suas rotas de entrada
Você precisa atualizar suas rotas de entrada para lidar com o tráfego para seu FQDN ou domínio personalizado.
No exemplo a seguir, o tráfego é roteado como tal:
- Tráfego para hello-world-ingress. MY_CUSTOM_DOMAIN é roteado para o serviço aks-helloworld-one .
- Tráfego para hello-world-ingress. MY_CUSTOM_DOMAIN/hello-world-two é roteado para o serviço aks-helloworld-two .
- Tráfego para hello-world-ingress. MY_CUSTOM_DOMAIN/static é roteado para o serviço chamado aks-helloworld-one para ativos estáticos.
Nota
Se você configurou um FQDN para o endereço IP do controlador de entrada em vez de um domínio personalizado, use o FQDN em vez de hello-world-ingress. MY_CUSTOM_DOMAIN.
Por exemplo, se o FQDN estiver demo-aks-ingress.eastus.cloudapp.azure.com, substitua hello-world-ingress. MY_CUSTOM_DOMAIN com demo-aks-ingress.eastus.cloudapp.azure.com em hello-world-ingress.yaml
.
Crie ou atualize o
hello-world-ingress.yaml
arquivo usando o seguinte exemplo de arquivo YAML. Atualize ospec.tls.hosts
espec.rules.host
para o nome DNS que você criou em uma etapa anterior.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
Atualize o recurso de entrada usando o
kubectl apply
comando.kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
Verificar se um objeto de certificado foi criado
Em seguida, um recurso de certificado deve ser criado. O recurso de certificado define o certificado X.509 desejado. Para obter mais informações, consulte certificados cert-manager.
O Cert-manager cria automaticamente um objeto de certificado para você usando ingress-shim, que é implantado automaticamente com o cert-manager desde a v0.2.2. Para obter mais informações, consulte a documentação do ingress-shim.
Para verificar se o certificado foi criado com êxito, use o kubectl get certificate --namespace ingress-basic
comando e verifique se READY é True. Pode levar vários minutos para obter a saída.
kubectl get certificate --namespace ingress-basic
A saída a seguir mostra o status do certificado.
NAME READY SECRET AGE
tls-secret True tls-secret 11m
Testar a configuração de entrada
Abra um navegador da Web para hello-world-ingress. MY_CUSTOM_DOMAIN ou o FQDN do seu controlador de entrada do Kubernetes. Certifique-se de que o seguinte é verdadeiro:
- Você será redirecionado para usar HTTPS.
- O certificado é confiável.
- O aplicativo de demonstração é mostrado no navegador da web.
- Adicione /hello-world-two ao final do domínio e certifique-se de que o segundo aplicativo de demonstração com o título personalizado seja mostrado.
Clean up resources (Limpar recursos)
Este artigo usou o Helm para instalar os componentes de entrada, certificados e aplicativos de exemplo. Quando você implanta um gráfico Helm, muitos recursos do Kubernetes são criados. Esses recursos incluem pods, implantações e serviços. Para limpar esses recursos, você pode excluir todo o namespace de exemplo ou os recursos individuais.
Excluir o namespace de exemplo e todos os recursos
A exclusão do namespace de exemplo também exclui todos os recursos no namespace.
Exclua todo o namespace de exemplo usando o comando e especificando o nome do
kubectl delete
namespace.kubectl delete namespace ingress-basic
Excluir recursos individualmente
Como alternativa, você pode excluir o recurso individualmente.
Remova os recursos do emissor do cluster.
kubectl delete -f cluster-issuer.yaml --namespace ingress-basic
Liste as liberações do Helm com o
helm list
comando. Procure gráficos chamados nginx e cert-manager, conforme mostrado na saída de exemplo a seguir.$ 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
Desinstale as versões usando o
helm uninstall
comando. O exemplo a seguir desinstala as implantações NGINX ingress e cert-manager.$ helm uninstall cert-manager nginx --namespace ingress-basic release "cert-manager" uninstalled release "nginx" uninstalled
Remova os dois aplicativos de exemplo.
kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
Remova a rota de entrada que direcionou o tráfego para os aplicativos de exemplo.
kubectl delete -f hello-world-ingress.yaml --namespace ingress-basic
Exclua o namespace próprio. Use o comando e especifique o nome do
kubectl delete
namespace.kubectl delete namespace ingress-basic
Próximos passos
Este artigo incluiu alguns componentes externos ao AKS. Para saber mais sobre esses componentes, consulte as seguintes páginas do projeto:
Também pode: