Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Com a API do Gateway de Roteamento de Aplicativos, os usuários podem expor facilmente aplicativos HTTPS no AKS com seus próprios certificados Azure Key Vault, incluindo publicação automática de Nome de Domínio. O operador de Roteamento de Aplicativos integra-se com o DNS do Azure e o Azure Key Vault e reconcilia um SecretProviderClass, um segredo do Kubernetes para certificados TLS, o campo ouvinte certificateRefs e a implantação separada external-dns para que você não precise gerenciar esses recursos manualmente.
Este artigo mostra como:
- Provisione os recursos pré-requisitos do Azure (zona DNS do Azure, Azure Key Vault, identidade gerenciada atribuída ao usuário, atribuições de funções e credenciais de identidade federada).
- Configure um ouvinte
Gatewaypara encerrar o TLS usando um certificado armazenado no Azure Key Vault por meio das opções de TLS do ouvintekubernetes.azure.com/tls-cert-keyvault-uriekubernetes.azure.com/tls-cert-service-account. - Use os recursos personalizados
ClusterExternalDNSeExternalDNSpara publicar registros DNS no DNS do Azure com base nos nomes de host dos seus recursosGateway,HTTPRouteeGRPCRoute.
Como funciona a integração
O operador de Roteamento de Aplicativos expõe duas integrações para automatizar os recursos que você criaria manualmente para colocar um Gateway recurso online com um domínio personalizado e uma terminação TLS.
Integração do TLS
Quando um recurso Gateway usa uma GatewayClass gerenciada — seja approuting-istio (da implementação da API Application Routing Gateway) ou istio (do complemento Istio service mesh) — e um ouvinte carrega as duas opções TLS a seguir, o operador de Roteamento de Aplicativos reconcilia os recursos necessários para encerrar o TLS usando um certificado armazenado no Azure Key Vault:
| Chave de opção TLS | Valor |
|---|---|
kubernetes.azure.com/tls-cert-keyvault-uri |
O URI do certificado Azure Key Vault do qual o certificado TLS será originado. Use um URI sem versão (por exemplo, https://<vault>.vault.azure.net/certificates/<cert>) para que o operador detecte automaticamente as rotações de certificados no Azure Key Vault. |
kubernetes.azure.com/tls-cert-service-account |
O nome de um ServiceAccount do Kubernetes no mesmo namespace que o Gateway. A ServiceAccount deve estar vinculada a uma identidade gerenciada atribuída pelo usuário por meio da Identidade de Carga de Trabalho do Microsoft Entra, e essa identidade gerenciada deve ter a função Key Vault Secrets User no Azure Key Vault de destino. |
Para cada listener que tem ambas as opções de TLS, o operador:
- Provisiona um
SecretProviderClasschamadokv-gw-cert-<gateway-name>-<listener-name>no namespace doGateway, configurado para obter o certificado do Azure Key Vault usando a autenticação de identidade de carga de trabalho. - Desencadeia o provedor do Azure Key Vault para o Driver CSI do repositório de segredos para sincronizar o certificado como um
kubernetes.io/tlsSecret do Kubernetes com o mesmo nome no namespace doGateway. - Corrige o campo
tls.certificateRefsdo ouvinte para fazer referência ao Segredo do Kubernetes sincronizado.
Integração do DNS
O operador de Roteamento de Aplicativos gerencia uma external-dns instância para você por meio de dois recursos personalizados:
| Recurso Personalizado | Scope |
|---|---|
ClusterExternalDNS (clusterexternaldnses.approuting.kubernetes.azure.com) |
No escopo do cluster. Monitora recursos Gateway, HTTPRoute e GRPCRoute em todos os namespaces do cluster. |
ExternalDNS (externaldnses.approuting.kubernetes.azure.com) |
No escopo do namespace. Observa apenas Gateway, HTTPRoutee GRPCRoute recursos no mesmo namespace que o recurso personalizado. |
Ambos os recursos personalizados aceitam seletores opcionais filters para restringir ainda mais quais recursos a instância gerenciada external-dns observa dentro de seu escopo:
| Filtro | O que restringe |
|---|---|
filters.gatewayLabels |
Restringe quais Gateway recursos o controlador observa. |
filters.routeAndIngressLabels |
Restringe quais recursos HTTPRoute e Ingress o controlador observa. |
Para cada recurso personalizado, o operador de Roteamento de Aplicativos:
- Implanta uma instância gerenciada
external-dns, configurada para obter registros dos recursosHTTPRouteeGRPCRoute, e visa às zonas do DNS do Azure especificadas. - Autentica-se no DNS do Azure usando a Identidade de Carga de Trabalho do Microsoft Entra, por meio da ServiceAccount referenciada no campo
identitydo recurso personalizado. - Publica registros A em cada uma das zonas do DNS do Azure listadas para cada nome de host
HTTPRouteouGRPCRoutevinculado a um recursoGatewaygerenciado no escopo.
Prerequisites
Um cluster do AKS com ambos os seguintes recursos habilitados:
- O complemento de Roteamento de Aplicativos (
--enable-app-routing). Esse complemento implanta o operador de Roteamento de Aplicativos no cluster, que é o componente que reconcilia as integrações DNS e TLS documentadas neste artigo. Em um cluster existente, você também pode habilitar esse recurso usandoaz aks approuting enable. - Uma implementação gerenciada da API de Gateway com a qual o operador possa se integrar. Escolha uma das opções a seguir (as duas opções são mutuamente exclusivas e não podem ser habilitadas ao mesmo tempo):
- A implementação da API App Routing Gateway no Istio (
--enable-app-routing-istio), que fornece aapprouting-istioGatewayClass. Em um cluster existente, você também pode habilitá-lo usandoaz aks approuting gateway istio enable. UsegatewayClassName: approuting-istioem seusGatewayrecursos. - O complemento Istio service mesh, que fornece a
istioGatewayClass. Use esta opção quando quiser que as integrações de DNS e TLS nos recursosGatewaysejam gerenciadas pelo complemento da malha de serviço Istio e para definirgatewayClassName: istionesses recursos.
- A implementação da API App Routing Gateway no Istio (
Para usar essas integrações, habilite o complemento de Roteamento de Aplicativos (usando
az aks approuting enable) e uma das implementações de API de Gateway gerenciadas listadas anteriormente.- O complemento de Roteamento de Aplicativos (
A instalação da API Managed Gateway habilitada no cluster.
O recurso Identidade de Carga de Trabalho do Microsoft Entra habilitado no cluster, juntamente com o emissor OIDC. Você pode habilitar ambos os recursos usando as flags
--enable-oidc-issuere--enable-workload-identitynoaz aks createou noaz aks update.O complemento provedor do Azure Key Vault para o Secrets Store CSI Driver está habilitado no cluster. Você pode habilitá-lo usando o
az aks enable-addonscomando com--addons azure-keyvault-secrets-provider, ou passando--enable-kvparaaz aks approuting enableouaz aks approuting update.CLI do Azure versão
2.86.0ou superior Executeaz --versionpara localizar suaazure-cliversão e executeaz upgradepara atualizar.RBAC (controle de acesso baseado em função) do Azure suficiente em sua própria identidade para criar atribuições de função e credenciais de identidade federadas. A
Ownerfunção ou uma combinação deRole Based Controle de Acesso AdministratoreManaged Identity Contributoré suficiente.
Note
Os sinalizadores --attach-kv e --attach-zones em az aks approuting update (e os subcomandos az aks approuting zone) foram projetados para a experiência baseada em NGINX herdada, na qual a identidade gerenciada atribuída pelo usuário do próprio complemento de Roteamento de Aplicativos recebe acesso ao RBAC do Azure para um único Azure Key Vault e a uma única zona DNS. Eles não são usados pela integração da API do Gateway documentada neste artigo. A nova experiência usa a Identidade de Carga de Trabalho do Microsoft Entra em vez da identidade gerenciada do complemento, portanto, você precisa criar sua própria identidade gerenciada atribuída pelo usuário, conceder a ela as funções apropriadas do DNS do Azure e do Azure Key Vault e criar credenciais de identidade federadas que a vinculem às ServiceAccounts do Kubernetes referenciadas nas opções de TLS em seu ouvinte em Gateway e nos recursos personalizados ExternalDNS/ClusterExternalDNS.
Defina as variáveis de ambiente a seguir. O passo a passo os reutiliza em todos os comandos subsequentes:
export RESOURCE_GROUP=<resource-group-name>
export CLUSTER=<cluster-name>
export LOCATION=<azure-region>
Obter credenciais do cluster para kubectl:
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER
Criar a infraestrutura de Azure
Criar a zona DNS do Azure
Se você já tiver uma zona do DNS do Azure para a qual deseja que o operador de Roteamento de Aplicativos gerencie os registros, poderá ignorar esta etapa e atribuir o valor de ZONE_NAME ao nome da zona existente.
export ZONE_NAME=<dns-zone-name>
az network dns zone create --resource-group $RESOURCE_GROUP --name $ZONE_NAME
export ZONE_ID=$(az network dns zone show --resource-group $RESOURCE_GROUP --name $ZONE_NAME --query id -o tsv)
Criar o Azure Key Vault e o certificado
Crie o Azure Key Vault que armazena o certificado TLS. Configure o cofre para usar o RBAC do Azure para autorização, que é o modelo de permissão recomendado:
export KV_NAME=<key-vault-name>
az keyvault create \
--name $KV_NAME \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--enable-rbac-authorization true
Note
Para criar o certificado na próxima etapa, sua própria identidade do Azure precisa da função Key Vault Certificates Officer (ou Key Vault Administrator) no cofre. Atribua esta função ao cofre antes de continuar.
Crie um certificado curinga autoassinado no Azure Key Vault. Para implantações de produção, importe um certificado assinado pela AC (autoridade de certificação) usando az keyvault certificate import em vez disso.
cat > cert-policy.json <<EOF
{
"issuerParameters": { "name": "Self" },
"keyProperties": { "exportable": true, "keyType": "RSA", "keySize": 2048, "reuseKey": false },
"secretProperties": { "contentType": "application/x-pkcs12" },
"x509CertificateProperties": {
"subject": "CN=*.${ZONE_NAME}",
"subjectAlternativeNames": { "dnsNames": ["*.${ZONE_NAME}", "${ZONE_NAME}"] },
"validityInMonths": 12,
"keyUsage": ["digitalSignature", "keyEncipherment"]
}
}
EOF
az keyvault certificate create \
--vault-name $KV_NAME \
--name approuting-demo-cert \
--policy @cert-policy.json
Capture o URI do certificado sem versão. O operador de Roteamento de Aplicativos usa esse URI para configurar o SecretProviderClass. Um URI sem versão garante que o operador obtenha novas versões do certificado no Azure Key Vault quando houver a rotação do certificado.
export CERT_URI=$(az keyvault certificate show \
--vault-name $KV_NAME \
--name approuting-demo-cert \
--query id -o tsv | sed 's|/[^/]*$||')
echo "Cert URI: $CERT_URI"
Criar a identidade gerenciada atribuída pelo usuário e conceder funções do Azure RBAC
Crie uma identidade gerenciada atribuída pelo usuário para que a implantação de external-dns do operador de Roteamento de Aplicativos e a sincronização de TLS do ouvinte do gateway usem essa identidade para se autenticar no DNS do Azure e no Azure Key Vault.
export UAMI_NAME=<managed-identity-name>
az identity create --resource-group $RESOURCE_GROUP --name $UAMI_NAME --location $LOCATION
export UAMI_CLIENT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $UAMI_NAME --query clientId -o tsv)
export UAMI_PRINCIPAL_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $UAMI_NAME --query principalId -o tsv)
Atribua à identidade gerenciada a função DNS Zone Contributor na zona do DNS do Azure de destino e a função Key Vault Secrets User no Azure Key Vault de destino:
az role assignment create \
--assignee-object-id $UAMI_PRINCIPAL_ID \
--assignee-principal-type ServicePrincipal \
--role "DNS Zone Contributor" \
--scope $ZONE_ID
az role assignment create \
--assignee-object-id $UAMI_PRINCIPAL_ID \
--assignee-principal-type ServicePrincipal \
--role "Key Vault Secrets User" \
--scope $(az keyvault show --name $KV_NAME --query id -o tsv)
Criar os namespaces, ServiceAccounts e credenciais de identidade federadas
As integrações de TLS e DNS do operador de Roteamento de Aplicativos se autenticam no Azure por meio de uma ServiceAccount do Kubernetes vinculada à identidade gerenciada atribuída pelo usuário por meio de uma FIC (credencial de identidade federada). Cada par (namespace, ServiceAccount) que precisa se autenticar requer uma FIC.
Capture a URL do emissor OIDC do cluster:
export OIDC_ISSUER=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query oidcIssuerProfile.issuerUrl -o tsv)
Para cada namespace em que você planeja implantar um Gateway recurso que usa a integração TLS ou um ExternalDNS recurso, crie o namespace, uma credencial de identidade federada para o ServiceAccount e o próprio ServiceAccount. O exemplo a seguir cria dois namespaces, app-a e app-b, cada um deles com uma ServiceAccount chamada approuting-demo-sa:
export SA_NAME=approuting-demo-sa
for ns in app-a app-b; do
kubectl create namespace $ns
az identity federated-credential create \
--identity-name $UAMI_NAME \
--resource-group $RESOURCE_GROUP \
--name approuting-demo-fic-$ns \
--issuer $OIDC_ISSUER \
--subject "system:serviceaccount:$ns:$SA_NAME" \
--audiences "api://AzureADTokenExchange"
kubectl apply -n $ns -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: $SA_NAME
annotations:
azure.workload.identity/client-id: $UAMI_CLIENT_ID
labels:
azure.workload.identity/use: "true"
EOF
done
A anotação azure.workload.identity/client-id associa a ServiceAccount à identidade gerenciada, e o rótulo azure.workload.identity/use: "true" instrui o webhook da Identidade de Carga de Trabalho do Microsoft Entra a projetar um token federado em pods que consomem a ServiceAccount. Ambos são necessários para que as integrações TLS e DNS do operador de Roteamento de Aplicativos sejam autenticadas para Azure com êxito.
Configurar a terminação do TLS em um Gateway
Implante uma carga de trabalho de exemplo httpbin em cada namespace:
for ns in app-a app-b; do
kubectl apply -n $ns -f https://raw.githubusercontent.com/istio/istio/release-1.27/samples/httpbin/httpbin.yaml
done
Crie um recurso Gateway em cada namespace com um listener HTTPS que faça referência ao certificado do Azure Key Vault nas opções de TLS. Cada Gateway um usa seu próprio sub-host da zona DNS do Azure (por exemplo, a.<zone> e b.<zone>):
Note
Os exemplos neste artigo usam gatewayClassName: approuting-istio, a GatewayClass fornecida pela implementação da API Gateway de Roteamento de Aplicativos. Se você habilitou o complemento Istio service mesh, defina gatewayClassName: istio em seus recursos Gateway. As integrações DNS e TLS se comportam de forma idêntica para ambas as GatewayClasses gerenciadas.
for pair in "app-a:a" "app-b:b"; do
ns=${pair%%:*}
sub=${pair##*:}
fqdn=${sub}.${ZONE_NAME}
kubectl apply -n $ns -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: ${sub}-gateway
labels:
app: approuting-demo
zone: ${sub}
spec:
gatewayClassName: approuting-istio
listeners:
- name: https
hostname: $fqdn
port: 443
protocol: HTTPS
tls:
mode: Terminate
options:
kubernetes.azure.com/tls-cert-keyvault-uri: $CERT_URI
kubernetes.azure.com/tls-cert-service-account: $SA_NAME
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ${sub}-route
spec:
parentRefs:
- name: ${sub}-gateway
hostnames: ["$fqdn"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 8000
EOF
done
Aguarde até que cada Gateway atinja a condição Programmed:
kubectl wait -n app-a --for=condition=programmed gateway a-gateway --timeout=300s
kubectl wait -n app-b --for=condition=programmed gateway b-gateway --timeout=300s
Verifique se o operador de Roteamento de Aplicativos criou um SecretProviderClass e se o provedor do Azure Key Vault para o Driver CSI do repositório de segredos sincronizou o certificado em um segredo kubernetes.io/tls em cada namespace:
kubectl get secretproviderclass,secret -n app-a
kubectl get secretproviderclass,secret -n app-b
Saída de exemplo para um namespace:
NAME AGE
secretproviderclass.secrets-store.csi.x-k8s.io/kv-gw-cert-a-gateway-https 2m
NAME TYPE DATA AGE
secret/kv-gw-cert-a-gateway-https kubernetes.io/tls 2 2m
Configurar registros DNS do Azure usando ClusterExternalDNS
Implante uma instância external-dns com escopo de cluster que publica registros A para recursos Gateway em qualquer namespace aplicando um recurso personalizado ClusterExternalDNS.
kubectl apply -f - <<EOF
apiVersion: approuting.kubernetes.azure.com/v1alpha1
kind: ClusterExternalDNS
metadata:
name: demo-cluster-dns
spec:
resourceName: demo-cluster-dns
resourceNamespace: app-a
dnsZoneResourceIDs:
- $ZONE_ID
resourceTypes:
- gateway
identity:
type: workloadIdentity
serviceAccount: $SA_NAME
EOF
O resourceNamespace campo especifica o namespace em que o operador de Roteamento de Aplicativos implanta a instância gerenciada external-dns . A ServiceAccount referenciada por identity.serviceAccount deve existir nesse namespace.
Após cerca de um minuto, dois registros A aparecem na zona DNS do Azure - um para cadaGateway:
az network dns record-set a list --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME -o table
Name ResourceGroup Ttl Type AutoRegistered Metadata
------ ------------------------- ----- ------ ---------------- --------
a <your-rg> 300 A False
b <your-rg> 300 A False
Configurar registros de DNS do Azure usando um ExternalDNS com escopo de namespace
Para publicar registros apenas para um subconjunto de recursos Gateway, use o recurso personalizado ExternalDNS com escopo de namespace. Ao contrário de ClusterExternalDNS, a variante com escopo no namespace observa apenas os recursos Gateway, HTTPRoute e GRPCRoute no mesmo namespace que o recurso personalizado. Assim como com ClusterExternalDNS, você pode opcionalmente restringir ainda mais o escopo usando os seletores filters.gatewayLabels e filters.routeAndIngressLabels.
Primeiro, exclua o ClusterExternalDNS da etapa anterior:
kubectl delete clusterexternaldns demo-cluster-dns
Implante um novo Gateway em app-a com o rótulo zone: c e um HTTPRoute correspondente:
kubectl apply -n app-a -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: c-gateway
labels:
app: approuting-demo
zone: c
spec:
gatewayClassName: approuting-istio
listeners:
- name: https
hostname: c.${ZONE_NAME}
port: 443
protocol: HTTPS
tls:
mode: Terminate
options:
kubernetes.azure.com/tls-cert-keyvault-uri: $CERT_URI
kubernetes.azure.com/tls-cert-service-account: $SA_NAME
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: c-route
spec:
parentRefs:
- name: c-gateway
hostnames: ["c.${ZONE_NAME}"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 8000
EOF
kubectl wait -n app-a --for=condition=programmed gateway c-gateway --timeout=300s
Aplique um recurso ExternalDNS em app-a com escopo de namespace com um filtro de rótulo para zone=c:
kubectl apply -n app-a -f - <<EOF
apiVersion: approuting.kubernetes.azure.com/v1alpha1
kind: ExternalDNS
metadata:
name: demo-ns-dns
spec:
resourceName: demo-ns-dns
dnsZoneResourceIDs:
- $ZONE_ID
resourceTypes:
- gateway
identity:
type: workloadIdentity
serviceAccount: $SA_NAME
filters:
gatewayLabels: "zone=c"
EOF
Duas regras de escopo se aplicam:
- O escopo do espaço de nomes de
ExternalDNSexcluib-gatewayporque ele reside no espaço de nomesapp-b. - O filtro de rótulo
zone=cexcluia-gatewayporque está emapp-a, mas é rotulado comozone=a.
O operador de Roteamento de Aplicativos publica um novo registro A para c.${ZONE_NAME}:
az network dns record-set a list --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME -o table
Verificar o tráfego HTTPS encerrado pelo TLS
Resolva o Gatewaynome do host por meio do nameserver autoritativo da zona DNS do Azure e envie uma solicitação HTTPS:
NS=$(az network dns zone show --resource-group $RESOURCE_GROUP --name $ZONE_NAME --query 'nameServers[0]' -o tsv | sed 's/\.$//')
GATEWAY_IP=$(dig +short @${NS} a.${ZONE_NAME} | tail -1)
curl -k -I --resolve "a.${ZONE_NAME}:443:${GATEWAY_IP}" "https://a.${ZONE_NAME}/get"
Você deve ver uma HTTP/2 200 resposta. O certificado TLS que o gateway apresenta é aquele sincronizado de Azure Key Vault. Se você importou um certificado assinado por AC, substitua -k--cacert <path-to-ca-chain> para validar a cadeia de certificados.
Note
O exemplo usa curl --resolve para ignorar a resolução DNS local e direcionar a solicitação para o IP externo do gateway. Esse método é útil para teste antes de delegar a zona DNS a um registrador. Para uso em produção, configure o registrador de domínios para delegar a zona aos nameservers de DNS do Azure retornados por az network dns zone show --query 'nameServers'.
Limitações
- As integrações de DNS e TLS se aplicam somente aos
Gatewayrecursos que usam um GatewayClass gerenciado:approuting-istio(a implementação da API do Gateway de Roteamento de Aplicativos) ouistio(o complemento da malha de serviço istio).Gatewayrecursos que usam qualquer outra GatewayClass não são compatíveis. - Um recurso personalizado
ClusterExternalDNSouExternalDNSpode fazer referência a até sete zonas do DNS do Azure por meio dednsZoneResourceIDs. Todas as zonas referenciadas em um único recurso personalizado devem estar na mesma assinatura do Azure e no mesmo grupo de recursos. Eles também devem ser todos do mesmo tipo (público ou privado). - A instância gerenciada
external-dnsnão exclui automaticamente os registros DNS quando você exclui oClusterExternalDNSrecurso ouExternalDNSpersonalizado. Para remover registros órfãos, exclua-os diretamente da zona DNS do Azure depois de excluir o recurso personalizado. - Atualmente, não há suporte para a reconciliação de registros DNS dos
TLSRouterecursos. A instância gerenciadaexternal-dnssó origina registros deGateway,HTTPRouteeGRPCRouterecursos.