Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Com a API do Gateway de Roteamento de Aplicações, os utilizadores podem facilmente expor aplicações HTTPS no AKS com os seus próprios certificados Azure Key Vault, incluindo a publicação automática de Nomes de Domínio. O operador de Encaminhamento de Aplicações integra-se com o DNS do Azure e o Azure Key Vault e coordena um SecretProviderClass, um Segredo do Kubernetes para certificados TLS, o campo certificateRefs do escutador e o Deployment external-dns separado, para que não tenha de gerir manualmente estes recursos.
Este artigo mostra-lhe como:
- Provisionar os recursos Azure pré-requisitos (zona DNS do Azure, Azure Key Vault, identidade gerida atribuída pelo utilizador, atribuição de funções e credenciais de identidade federada).
- Configure um serviço de escuta
Gatewaypara terminar TLS com um certificado armazenado no Azure Key Vault através das opções TLS do serviço de escutakubernetes.azure.com/tls-cert-keyvault-uriekubernetes.azure.com/tls-cert-service-account. - Utilize os recursos personalizados
ClusterExternalDNSeExternalDNSpara publicar registos DNS no DNS do Azure com base nos nomes de anfitrião dos seus recursosGateway,HTTPRouteeGRPCRoute.
Como funciona a integração
O operador de Encaminhamento de Aplicações expõe duas integrações para automatizar os recursos que de outra forma criaria manualmente para colocar um Gateway recurso online com um domínio personalizado e terminação TLS.
Integração com TLS
Quando um recurso Gateway usa uma GatewayClass gerida — seja approuting-istio (da implementação da API Gateway do Encaminhamento de Aplicações) ou istio (do suplemento de malha de serviço Istio) — e um listener inclui as duas opções de TLS seguintes, o operador de Encaminhamento de Aplicações efetua a reconciliação dos recursos necessários para efetuar a terminação de TLS com um certificado armazenado no Azure Key Vault:
| Chave de opção TLS | Valor |
|---|---|
kubernetes.azure.com/tls-cert-keyvault-uri |
O URI do certificado do Azure Key Vault para obter o certificado TLS. Use um URI não versionado (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 uma ServiceAccount do Kubernetes no mesmo espaço de nomes que o Gateway. A ServiceAccount tem de estar vinculada a uma identidade gerida atribuída pelo utilizador através do Microsoft Entra Workload Identity, e essa identidade gerida tem de ter a função Key Vault Secrets User no Azure Key Vault de destino. |
Para cada escutador que inclui ambas as opções de TLS, o operador:
- Provisiona um(a)
SecretProviderClassdenominado(a)kv-gw-cert-<gateway-name>-<listener-name>no espaço de nomes deGateway, configurado(a) para obter o certificado do Azure Key Vault através da autenticação de identidade de carga de trabalho. - Faz com que o fornecedor Azure Key Vault para o driver CSI da Secrets Store sincronize o certificado como um
kubernetes.io/tlsKubernetes Secret com o mesmo nome noGatewaynamespace de . - Atualiza o campo do
tls.certificateRefsouvinte para referenciar o Kubernetes Secret sincronizado.
Integração DNS
O operador de Roteamento de Aplicações gere uma external-dns instância para si através de dois recursos personalizados:
| Recurso personalizado | Scope |
|---|---|
ClusterExternalDNS (clusterexternaldnses.approuting.kubernetes.azure.com) |
Âmbito do cluster. Observa os recursos Gateway, HTTPRoute e GRPCRoute em todos os espaços de nomes do cluster. |
ExternalDNS (externaldnses.approuting.kubernetes.azure.com) |
Ao nível do espaço de nomes. Monitoriza apenas os recursos Gateway, HTTPRoute e GRPCRoute no mesmo espaço de nomes que o recurso personalizado. |
Ambos os recursos personalizados aceitam seletores opcionais filters para restringir ainda mais quais os recursos que a instância gerida external-dns observa dentro do seu âmbito:
| Filtrar | O que restringe |
|---|---|
filters.gatewayLabels |
Restringe que recursos Gateway o controlador observa. |
filters.routeAndIngressLabels |
Restringe quais HTTPRoute e Ingress recursos o controlador observa. |
Para cada recurso personalizado, o operador de Roteamento de Aplicações:
- Implementa uma instância gerida
external-dns, configurada para obter registos a partir dos recursosHTTPRouteeGRPCRoute, e tem como destino as zonas de DNS do Azure especificadas. - Autentica-se no DNS do Azure utilizando o Microsoft Entra Workload Identity, através da conta de serviço referenciada no campo
identitydo recurso personalizado. - Publica registos A em cada uma das zonas de DNS do Azure indicadas para cada nome de anfitrião
HTTPRouteouGRPCRouteassociado a um recurso geridoGatewayno âmbito.
Prerequisites
Um cluster AKS com ambas as seguintes funcionalidades ativadas:
- O complemento de Encaminhamento de Aplicações (
--enable-app-routing). Este complemento implementa o operador de Roteamento de Aplicações no cluster, que é o componente que concilia as integrações DNS e TLS documentadas neste artigo. Num cluster existente, também pode ativar esta funcionalidade usandoaz aks approuting enable. - Uma implementação gerida de API Gateway com a qual o operador se possa integrar. Escolha uma das seguintes opções (as duas opções são mutuamente exclusivas e não podem ser ativadas ao mesmo tempo):
- A implementação da API App Routing Gateway para o Istio (
--enable-app-routing-istio), que disponibiliza a GatewayClassapprouting-istio. Num cluster existente, também pode ativa-lo usandoaz aks approuting gateway istio enable. UtilizegatewayClassName: approuting-istionos seus recursosGateway. - A extensão de malha de serviços Istio, que fornece a
istioGatewayClass. Usa esta opção quando quiseres as integrações DNS e TLS emGatewayrecursos geridos pelo add-on de malha de serviço Istio, e definegatewayClassName: istioesses recursos.
- A implementação da API App Routing Gateway para o Istio (
Para utilizar estas integrações, ative tanto o complemento de Ruteamento de Aplicações (usando
az aks approuting enable) como uma das implementações geridas da API de Gateway mencionadas anteriormente.- O complemento de Encaminhamento de Aplicações (
Instalação da API de Gateway Gerido ativada no cluster.
A funcionalidade Microsoft Entra Workload Identity ativada no cluster, juntamente com o emissor OIDC. Pode ativar ambas as funcionalidades utilizando as opções
--enable-oidc-issuere--enable-workload-identityemaz aks createouaz aks update.O suplemento fornecedor do Azure Key Vault para o Secrets Store CSI Driver ativado no cluster. Pode ativá-lo utilizando o comando
az aks enable-addonscom--addons azure-keyvault-secrets-provider, ou ao passar--enable-kvparaaz aks approuting enableouaz aks approuting update.Versão da CLI
2.86.0do Azure ou superior. Correaz --versionpara encontrar a tuaazure-cliversão e correaz upgradepara atualizar.Nível suficiente de controlo de acesso baseado em funções do Azure (RBAC) na sua própria identidade para criar atribuições de funções e credenciais de identidade federada. A função
Ownerou uma combinação deRole Based Controlo de Acesso AdministratoreManaged Identity Contributoré suficiente.
Note
As opções --attach-kv e --attach-zones em az aks approuting update (e os subcomandos az aks approuting zone) foram concebidas para a experiência legada baseada em NGINX, em que à identidade gerida atribuída pelo utilizador do próprio suplemento Application Routing é concedido acesso do Azure RBAC a um único Azure Key Vault e a uma única zona DNS. Eles não são usados pela integração da API Gateway documentada neste artigo. A nova experiência é impulsionada pelo Microsoft Entra Workload Identity em vez da identidade gerida do add-on, por isso precisa de criar a sua própria identidade gerida atribuída pelo utilizador, conceder-lhe os papéis DNS do Azure e Azure Key Vault apropriados, e criar credenciais de identidade federadas que a vinculem às Kubernetes ServiceAccounts que refere no seu Gateway Opções TLS para ouvintes e os seus ExternalDNS/ClusterExternalDNS recursos personalizados.
Defina as seguintes variáveis de ambiente. O guia passo a passo reutiliza-os em cada comando subsequente:
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 do Azure
Criar a zona DNS do Azure
Se já tens uma zona DNS do Azure onde queres que o operador de Application Routing gere registos, podes saltar este passo e atribuir o valor de ZONE_NAME ao nome da tua 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)
Crie o Azure Key Vault e o certificado
Crie o Azure Key Vault que armazena o certificado TLS. Configure o cofre para usar o Azure RBAC para autorização, que é o modelo de permissões 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 no passo seguinte, a sua própria identidade do Azure precisa da função Key Vault Certificates Officer (ou Key Vault Administrator) no cofre. Atribua esta função no cofre antes de continuar.
Crie um certificado universal autoassinado no Azure Key Vault. Para implementações em produção, importa um certificado assinado pela autoridade certificadora (CA) 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
Capturar o URI do certificado não versionado. O operador de encaminhamento de aplicações utiliza este URI para configurar o SecretProviderClass. Um URI não versionado garante que o operador deteta novas versões do certificado no Azure Key Vault à medida que o certificado é renovado.
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"
Crie a identidade gerida atribuída pelo utilizador e conceda funções Azure RBAC
Crie uma identidade gerida atribuída pelo utilizador que a implementação do external-dns operador de Ruteamento de Aplicações e a sincronização TLS do ouvinte do gateway usem para 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 gerida a DNS Zone Contributor função na zona de DNS do Azure de destino e a Key Vault Secrets User função 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)
Crie os namespaces, ServiceAccounts e credenciais de identidade federada
As integrações TLS e DNS do operador de Encaminhamento de Aplicações autenticam-se ambas no Azure através de uma ServiceAccount do Kubernetes associada à identidade gerida atribuída pelo utilizador através da utilização de uma credencial de identidade federada (FIC). Cada par (namespace, ServiceAccount) que precisa de se autenticar requer um FIC.
Obtenha o 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 onde planeia implementar um Gateway recurso que use a integração TLS ou um ExternalDNS recurso, crie o namespace, uma credencial federada de identidade para a ServiceAccount e a própria ServiceAccount. O exemplo seguinte cria dois namespaces, app-a e app-b, cada um com uma ServiceAccount nomeada 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 gerida, e o rótulo azure.workload.identity/use: "true" instrui o webhook do Microsoft Entra Workload Identity a injetar um token federado nos pods que utilizam a ServiceAccount. Ambos são necessários para que as integrações TLS e DNS do operador de Encaminhamento de Aplicações autentiquem com sucesso no Azure.
Configurar a terminação TLS num Gateway
Implemente 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 escutador HTTPS que faça referência ao certificado do Azure Key Vault nas opções de TLS. Cada um Gateway usa o seu próprio sub-hospedeiro da zona DNS do Azure (por exemplo, a.<zone> e b.<zone>):
Note
Os exemplos neste artigo utilizam gatewayClassName: approuting-istio, a GatewayClass fornecida pela implementação da API do Gateway de Roteamento de Aplicações. Se, em vez disso, ativaste a extensão de malha de serviço Istio, define gatewayClassName: istio nos teus recursos Gateway. As integrações DNS e TLS comportam-se de forma idêntica para ambas as GatewayClass geridas.
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
Espere que cada um 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 Encaminhamento de Aplicações criou um SecretProviderClass e que o fornecedor do Azure Key Vault para o Driver CSI Secrets Store sincronizou o certificado num kubernetes.io/tls Secret em cada namespace:
kubectl get secretproviderclass,secret -n app-a
kubectl get secretproviderclass,secret -n app-b
Exemplo de saída 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
Configure registos DNS do Azure usando ClusterExternalDNS
Implemente uma instância de âmbito de cluster de external-dns que publique registos A para recursos Gateway em qualquer espaço de nomes, 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 onde o operador de Roteamento de Aplicações implementa a instância gerida external-dns . A ServiceAccount referenciada por identity.serviceAccount deve existir nesse espaço de nomes.
Após cerca de um minuto, dois registos A aparecem na zona DNS do Azure - um para cada Gateway:
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
Configure os registos do DNS do Azure utilizando um ExternalDNS com âmbito delimitado ao namespace
Para publicar registos apenas para um subconjunto de recursos Gateway, utilize o recurso personalizado ExternalDNS com âmbito de espaço de nomes. Ao contrário de ClusterExternalDNS, a variante com escopo de espaço de nomes apenas observa Gateway, HTTPRoute, e GRPCRoute recursos no mesmo espaço de nomes que o recurso personalizado. Tal como com ClusterExternalDNS, pode, opcionalmente, restringir ainda mais o âmbito utilizando os seletores filters.gatewayLabels e filters.routeAndIngressLabels.
Primeiro, apague os ClusterExternalDNS do passo anterior:
kubectl delete clusterexternaldns demo-cluster-dns
Implemente um novo Gateway em app-a com o rótulo zone: c e o 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
Aplicar um recurso ExternalDNS com âmbito de espaço de nomes em app-a com um filtro de rótulos 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
Aplicam-se duas regras de âmbito de abrangência:
- O âmbito do namespace de
ExternalDNSexcluib-gatewayporque está noapp-bnamespace. - O filtro de etiquetas
zone=cexcluia-gatewayporque está emapp-a, mas tem o rótulozone=a.
O operador de encaminhamento de aplicações publica um novo registo A para c.${ZONE_NAME}:
az network dns record-set a list --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME -o table
Verificar tráfego HTTPS com terminação TLS
Resolva o nome do anfitrião de Gateway através do servidor de nomes autoritativo da zona DNS do Azure e envie um pedido 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ê verá uma HTTP/2 200 resposta. O certificado TLS que o gateway apresenta é o sincronizado do Azure Key Vault. Se importou um certificado assinado pela CA, substitua -k por --cacert <path-to-ca-chain> para validar a cadeia de certificados.
Note
O exemplo serve curl --resolve para contornar a resolução DNS local e direcionar o pedido para o IP externo do gateway. Este método é útil para testar antes de delegar a zona DNS a um registrador. Para uso em produção, configure o seu registo de domínio para delegar a zona aos servidores de nomes do DNS do Azure devolvidos por az network dns zone show --query 'nameServers'.
Limitações
- As integrações de DNS e TLS aplicam-se apenas aos recursos
Gatewayque utilizam uma GatewayClass gerida:approuting-istio(a implementação da API Application Routing Gateway) ouistio(o suplemento do service mesh Istio).Gatewayrecursos que utilizam qualquer outra GatewayClass não são suportados. - Um recurso personalizado
ClusterExternalDNSouExternalDNSpode referenciar até sete zonas de DNS do Azure através dednsZoneResourceIDs. Todas as zonas referenciadas num único recurso personalizado devem estar na mesma subscrição e grupo de recursos do Azure. Devem também ser todos do mesmo tipo (público ou privado). - A instância gerida
external-dnsnão apaga automaticamente os registos DNS quando apagas oClusterExternalDNSouExternalDNSo recurso personalizado. Para remover registos órfãos, apague-os diretamente da zona DNS do Azure depois de eliminar o recurso personalizado. - A reconciliação de registos DNS a partir de
TLSRouterecursos não é atualmente suportada. A instância geridaexternal-dnsapenas obtém registos deGateway,HTTPRoute, eGRPCRouterecursos.