Usar TLS com um controlador de entrada no AKS (Serviço de Kubernetes do Azure)
O protocolo TLS (segurança da camada de transporte) usa certificados para fornecer segurança para comunicação, criptografia, autenticação e integridade. Ao usar o TLS com um controlador de entrada no AKS, é possível proteger a comunicação entre seus aplicativos e aproveite os benefícios de um controlador de entrada.
É possível usar seus próprios certificados ao integrá-los ao driver CSI do Repositório de Segredos. Como alternativa, é possível usar o gerenciador de certificados, que gera e configura automaticamente certificados Let's Encrypt. Dois aplicativos são executados no cluster do AKS, cada um dos quais é acessível em um único endereço IP.
Importante
O complemento de roteamento de aplicativos é recomendado para entrada no AKS. Para obter mais informações, consulte Entrada do nginx gerenciada com o complemento de roteamento de aplicativo.
Importante
A Microsoft não gerencia nem dá suporte ao cert-manager e a quaisquer problemas decorrentes de seu uso. Para problemas com o cert-manager, consulte a documentação solução de problemas do cert-manager.
Há dois controladores de entrada de código aberto para Kubernetes com base no Nginx: um mantido pela comunidade do Kubernetes (kubernetes/ingress-nginx) e outro mantido pela NGINX, Inc. (nginxinc/kubernetes-ingress). Este artigo usa o controlador de entrada da comunidade do Kubernetes.
Antes de começar
Este artigo pressupõe que você tem um controlador de entrada e aplicativos configurados. Se precisar de um controlador de entrada ou de aplicativos de exemplo, confira 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. Use a versão mais recente do Helm e de ter acesso aos repositórios
ingress-nginx
ejetstack
do Helm. As etapas descritas neste artigo podem não ser compatíveis com versões anteriores do gráfico do Helm, do controlador de entrada NGINX ou do Kubernetes.- Para obter mais informações sobre como configurar e usar o Helm, consulte Instalar aplicativos com Helm no AKS. Para obter instruções de atualização, confira os Documentos de instalação do Helm.
Este artigo pressupõe que você tenha um cluster do AKS com um ACR (Registro de Contêiner do Azure) integrado. Para obter mais informações sobre como criar um cluster do AKS com um ACR integrado, confira Autenticar com o ACR do AKS.
Se você estiver usando a CLI do Azure, este artigo exigirá que você esteja executando a CLI do Azure versão 2.0.64 ou posterior. Execute
az --version
para encontrar a versão. Se você precisa instalar ou atualizar, consulte Instalar a CLI do Azure.Se você estiver usando Azure PowerShell, este artigo exigirá que você esteja executando o Azure PowerShell versão 5.9.0 ou posterior. Execute
Get-InstalledModule -Name Az
para encontrar a versão. Se precisar instalar ou atualizar, consulte Instalar o Azure PowerShell.
Usar o TLS com seus próprios certificados com o driver CSI do Repositório de Segredos
Para usar o TLS com seus certificados e o driver CSI do Repositório de Segredos, você precisa de um cluster do AKS com o driver CSI do Repositório de Segredos configurado, além de uma instância do Azure Key Vault.
Para saber mais, confira Configurar o driver CSI do Repositório de Segredos para habilitar o controlador de entrada NGINX com TLS.
Usar o TLS com certificados Let's Encrypt
Para usar o TLS com certificados Let's Encrypt, implante o gerenciador de certificados, que gera e configura automaticamente certificados Let's Encrypt.
Importar as imagens do gerenciador de certificados usadas pelo gráfico do Helm em seu ACR
Use
az acr import
para importar as imagens a seguir para o 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
Observação
Você também pode importar gráficos do Helm para o ACR. Para obter mais informações, confira Enviar e extrair gráficos do Helm para um ACR.
Opções de configuração do controlador de entrada
Você pode configurar o controlador de entrada do NGINX usando um endereço IP público estático ou um endereço IP público dinâmico. Se você estiver usando um domínio personalizado, precisará adicionar um registro A à 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 entrada.
Criar um endereço IP público estático ou dinâmico
Usar 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 permanecerá, se você excluir o cluster do AKS.
Ao atualizar o controlador de entrada, você deve passar um parâmetro para a versã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, você usará 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 do AKS com o comando
az aks show
.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ático usando o comando
az network public-ip create
. O exemplo a seguir cria um endereço IP público denominado myAKSPublicIP no grupo de recursos do 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
Observação
Como alternativa, você pode criar um endereço IP em um grupo de recursos diferente que você gerencia separadamente do cluster AKS. Se você criar um endereço IP em um grupo de recursos diferente, confirme o seguinte:
- A identidade do cluster usada pelo cluster do AKS tem permissões delegadas para o outro grupo de recursos, como Colaborador de Rede.
- Adicione o parâmetro
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-resource-group"="<RESOURCE_GROUP>"
. Substitua<RESOURCE_GROUP>
pelo nome do grupo de recursos em que reside o endereço IP.
Adicione o parâmetro
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="<DNS_LABEL>"
. O rótulo DNS pode ser definido quando o controlador de entrada é implantado pela primeira vez ou mais tarde.Adicione o parâmetro
--set controller.service.loadBalancerIP="<STATIC_IP>"
. 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
Confira mais informações em Usar um endereço IP público estático e um rótulo DNS com o balanceador de carga AKS.
Usar 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 por todo o período de vida do seu controlador de entrada. O endereço IP público estático não permanecerá, se você excluir seu controlador de entrada. Se você criar um novo controlador de entrada, ele receberá um novo endereço IP público. Seu resultado deve ser semelhante ao exemplo de saída a seguir.
Use o comando
kubectl get service
para obter o endereço IP público do 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
Adiciona um registro A a uma zona DNS.
Se você estiver usando um domínio personalizado, precisará adicionar um registro A à 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 à zona DNS com o endereço IP externo do serviço NGINX usando
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
Configurar um FQDN para seu controlador de entrada
Uma opção é 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 FQDN deve seguir este formulário: <CUSTOM DNS LABEL>.<AZURE REGION NAME>.cloudapp.azure.com
.
Importante
Seu rótulo DNS deve ser exclusivo no 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 do Helm.
Para obter mais informações, confira Rótulos de nome DNS do endereço IP público.
Definir o rótulo DNS usando a CLI do Azure ou o Azure PowerShell
Substitua <DNS_LABEL>
pelo 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 do Helm
Você pode transmitir uma configuração de anotação para a configuração de gráfico do Helm usando o parâmetro --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"
. O parâmetro pode ser definido quando o controlador de entrada é implantado pela primeira vez ou mais tarde.
O exemplo a seguir mostra como atualizar essa configuração após a implantação do controlador. Substitua <DNS_LABEL>
pelo 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 NGINX dá suporte para terminação TLS. Há várias maneiras de recuperar e configurar certificados para HTTPS. Este artigo usa o cert-manager, que fornece a geração automática do certificado Lets Encrypt e funcionalidade de gerenciamento.
Para instalar o controlador cert-manager, use os comando a seguir.
# 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 docert-manager, consulte o projeto cert-manager.
Criar o emissor de cluster de CA
Antes da emissão de certificados, o cert-manager requer um dos seguintes emissores:
- Um Emissor, que funciona em um só 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 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 comando
kubectl apply
.kubectl apply -f cluster-issuer.yaml --namespace ingress-basic
Atualizar suas rotas de entrada
Você precisa atualizar suas rotas de entrada para lidar com o tráfego para o FQDN ou o domínio personalizado.
No seguinte exemplo, o tráfego é roteado como tal:
- O tráfego para o endereço hello-world-ingress.MY_CUSTOM_DOMAIN é roteado para o serviço aks-helloworld-one.
- O tráfego para hello-world-ingress.MY_CUSTOM_DOMAIN/hello-world-two é roteado para o serviço aks-helloworld-two.
- O tráfego para o endereço hello-world-ingress.MY_CUSTOM_DOMAIN/static é roteado para o serviço chamado aks-helloworld-one para ativos estáticos.
Observação
Se você tiver configurado 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 for demo-aks-ingress.eastus.cloudapp.azure.com, substitua hello-world-ingress.MY_CUSTOM_DOMAIN por demo-aks-ingress.eastus.cloudapp.azure.com em hello-world-ingress.yaml
.
Crie ou atualize o arquivo
hello-world-ingress.yaml
usando o arquivo YAML de exemplo a seguir. Atualize ospec.tls.hosts
espec.rules.host
para o nome DNS que você criou na 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 comando
kubectl apply
.kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
Verifique se foi criado um objeto de certificado
Em seguida, um recurso de certificado deve ser criado. O recurso de certificado define o certificado X.509 desejado. Saiba mais em Certificados do Gerenciador de Certificados.
O cert-manager cria automaticamente um objeto de certificado para você usando o 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 comando kubectl get certificate --namespace ingress-basic
e verifique se READY é True. Pode demorar alguns minutos para a saída chegar.
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 para o FQDN do controlador de entrada do Kubernetes. Verifique se o seguinte é verdadeiro:
- Você é 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 verifique se o segundo aplicativo de demonstração com o título personalizado é mostrado.
Limpar os recursos
Este artigo usou o Helm para instalar os componentes de ingresso, os certificados e os aplicativos de exemplo. Quando você implanta um gráfico do Helm, vários recursos do Kubernetes são criados. Esses recursos incluem pods, implantações e serviços. Para limpar esses recursos, você poderá excluir o namespace inteiro de exemplo ou os recursos individuais.
Excluir o namespace de exemplo e todos os recursos
Excluir o namespace de exemplo também exclui todos os recursos no namespace.
Exclua o namespace de exemplo inteiro usando o comando
kubectl delete
e especificando o nome do 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 versões do Helm com o comando
helm list
. Procure por 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 com o comando
helm uninstall
. O exemplo a seguir desinstala a entrada NGINX e as implantações do 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 direcionava o tráfego para os aplicativos de exemplo.
kubectl delete -f hello-world-ingress.yaml --namespace ingress-basic
Exclua o namespace. Use o comando
kubectl delete
e especifique o nome do namespace.kubectl delete namespace ingress-basic
Próximas etapas
Este artigo incluído alguns componentes externos no AKS. Para saber mais sobre esses componentes, consulte as seguintes páginas do projeto:
Também é possível: