Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Con l'Application Routing Gateway API, gli utenti possono esporre facilmente applicazioni HTTPS su AKS con i propri certificati di Azure Key Vault, inclusa la pubblicazione automatica del nome di dominio. L'operatore di routing dell'applicazione si integra con DNS di Azure e Azure Key Vault e riconcilia un SecretProviderClasssegreto Kubernetes per i certificati TLS, il campo listener certificateRefs e la distribuzione separata external-dns in modo da non dover gestire manualmente queste risorse.
Questo articolo illustra come:
- Effettuare il provisioning delle risorse Azure prerequisiti (area DNS di Azure, Azure Key Vault, identità gestita assegnata dall'utente, assegnazioni di ruolo e credenziali di identità federate).
- Configurare un listener
Gatewayper eseguire la terminazione TLS usando un certificato memorizzato in Azure Key Vault tramite le opzioni TLS del listenerkubernetes.azure.com/tls-cert-keyvault-uriekubernetes.azure.com/tls-cert-service-account. - Usare le risorse personalizzate
ClusterExternalDNSeExternalDNSper pubblicare record DNS in DNS di Azure in base ai nomi host delle risorseGateway,HTTPRouteeGRPCRoute.
Funzionamento dell'integrazione
L'operatore di routing delle applicazioni espone due integrazioni per automatizzare le risorse che altrimenti creeresti manualmente per portare online una risorsa Gateway con un dominio personalizzato e terminazione TLS.
Integrazione TLS
Quando una risorsa Gateway usa una GatewayClass gestita, ovvero approuting-istio (dall'implementazione dell'API di Application Routing Gateway) oppure istio (dal componente aggiuntivo service mesh Istio), e un listener presenta le due opzioni TLS seguenti, l'operatore di Application Routing esegue la riconciliazione delle risorse necessarie per la terminazione TLS usando un certificato archiviato in Azure Key Vault:
| Chiave dell'opzione TLS | Value |
|---|---|
kubernetes.azure.com/tls-cert-keyvault-uri |
URI del certificato di Azure Key Vault da cui recuperare il certificato TLS. Usare un URI non modificato ,ad esempio , https://<vault>.vault.azure.net/certificates/<cert>in modo che l'operatore rilevi automaticamente le rotazioni dei certificati in Azure Key Vault. |
kubernetes.azure.com/tls-cert-service-account |
Il nome di un ServiceAccount Kubernetes nello stesso namespace di Gateway. Il ServiceAccount deve essere vincolato a un'identità gestita assegnata dall'utente tramite Microsoft Entra Workload Identity e tale identità gestita deve avere il ruolo Key Vault Secrets User nell'Azure Key Vault di destinazione. |
Per ogni listener che include entrambe le opzioni TLS, l'operatore :
- Eseguire il provisioning di un
SecretProviderClassdenominatokv-gw-cert-<gateway-name>-<listener-name>nello spazio dei nomi diGateway, configurato per ottenere il certificato da Azure Key Vault tramite l'Identity Authentication del carico di lavoro. - Attiva il provider Azure Key Vault per il driver CSI dell'archivio segreti per sincronizzare il certificato come segreto Kubernetes
kubernetes.io/tlscon lo stesso nome nello spazio dei nomi diGateway. - Applica una patch al campo
tls.certificateRefsdel listener in modo che faccia riferimento al segreto di Kubernetes sincronizzato.
Integrazione DNS
L'operatore Application Routing gestisce per te un'istanza external-dns tramite due risorse personalizzate:
| Risorsa personalizzata | Scope |
|---|---|
ClusterExternalDNS (clusterexternaldnses.approuting.kubernetes.azure.com) |
Con ambito cluster. Monitora le risorse Gateway, HTTPRoute e GRPCRoute in tutti i namespace del cluster. |
ExternalDNS (externaldnses.approuting.kubernetes.azure.com) |
Con ambito spazio dei nomi. Monitora solo le risorse Gateway, HTTPRoute e GRPCRoute nello stesso namespace della risorsa personalizzata. |
Entrambe le risorse personalizzate accettano selettori facoltativi filters per restringere ulteriormente le risorse osservate dall'istanza gestita external-dns all'interno dell'ambito:
| Filter | Cosa restringe |
|---|---|
filters.gatewayLabels |
Limita le Gateway risorse osservate dal controller. |
filters.routeAndIngressLabels |
Limita le risorse HTTPRoute e Ingress osservate dal controller. |
Per ogni risorsa personalizzata, l'operatore di routing dell'applicazione:
- Distribuisce un'istanza gestita
external-dns, configurata per ottenere i record dalle risorseHTTPRouteeGRPCRoutee usare come destinazione le zone di DNS di Azure specificate. - Si autentica ad DNS di Azure usando Microsoft Entra Workload Identity, tramite il ServiceAccount a cui si fa riferimento nel campo
identitydella risorsa personalizzata. - Pubblica record A in ognuna delle zone DNS di Azure elencate per ogni nome host
HTTPRouteoGRPCRouteassociato a una risorsa gestitaGatewayche rientra nell'ambito.
Prerequisites
Un cluster AKS con entrambe le funzionalità seguenti abilitate:
- Il componente aggiuntivo per l'instradamento dell'applicazione (
--enable-app-routing). Questo componente aggiuntivo distribuisce l'operatore application routing nel cluster, che è il componente che riconcilia le integrazioni DNS e TLS documentate in questo articolo. In un cluster esistente è anche possibile abilitare questa funzionalità usandoaz aks approuting enable. - Implementazione dell'API gateway gestita con cui l'operatore deve integrarsi. Scegliere una delle opzioni seguenti (le due opzioni si escludono a vicenda e non possono essere abilitate contemporaneamente):
- L'implementazione dell'API App Routing Gateway su Istio (
--enable-app-routing-istio), che fornisce laapprouting-istioGatewayClass. In un cluster esistente è anche possibile abilitarlo usandoaz aks approuting gateway istio enable. UsagatewayClassName: approuting-istiocon le tue risorseGateway. - Il componente aggiuntivo del service mesh Istio, che fornisce la GatewayClass
istio. Usare questa opzione quando si desidera che le integrazioni DNS e TLS nelle risorseGatewaygestite dal componente aggiuntivo del service mesh Istio siano attivate e chegatewayClassName: istiosia impostato su tali risorse.
- L'implementazione dell'API App Routing Gateway su Istio (
Per usare queste integrazioni, abilitare sia il componente aggiuntivo Routing delle applicazioni (usando
az aks approuting enable) che una delle implementazioni dell'API del gateway gestito elencate in precedenza.- Il componente aggiuntivo per l'instradamento dell'applicazione (
Installazione dell'API gateway gestita abilitata nel cluster.
La funzionalità Identità del carico di lavoro Microsoft Entra abilitata nel cluster, insieme all'autorità emittente OIDC. È possibile abilitare entrambe le funzionalità usando i
--enable-oidc-issuerflag e--enable-workload-identityinaz aks createoaz aks update.Il provider di Azure Key Vault per il driver CSI dell'archivio segreti abilitato nel cluster. È possibile abilitarlo usando il
az aks enable-addonscomando con--addons azure-keyvault-secrets-providero passando--enable-kvaaz aks approuting enableoaz aks approuting update.interfaccia della riga di comando di Azure versione
2.86.0o successiva. Eseguireaz --versionper trovare laazure-cliversione ed eseguireaz upgradeper eseguire l'aggiornamento.Controllo degli accessi in base al ruolo di Azure (RBAC) sufficiente per la propria identità per creare assegnazioni di ruolo e credenziali di identità federate. Il
Ownerruolo o una combinazione diRole Based Controllo di accesso AdministratoreManaged Identity Contributorè sufficiente.
Note
I flag --attach-kv e --attach-zones in az aks approuting update (e i sottocomandi az aks approuting zone) sono progettati per l'esperienza legacy basata su NGINX, in cui all'identità gestita assegnata dall'utente del componente aggiuntivo Application Routing viene concesso l'accesso RBAC di Azure a un singolo Azure Key Vault e a una zona DNS. Non vengono usati dall'integrazione dell'API gateway documentata in questo articolo. La nuova esperienza si basa su Microsoft Entra Workload Identity anziché sull'identità gestita del componente aggiuntivo, quindi è necessario creare una propria identità gestita assegnata dall'utente, assegnarle i ruoli appropriati di DNS di Azure e Azure Key Vault e creare credenziali di identità federata che la associno ai ServiceAccount di Kubernetes a cui si fa riferimento nelle opzioni TLS del listener Gateway e nelle risorse personalizzate ExternalDNS/ClusterExternalDNS.
Impostare le variabili di ambiente seguenti. La guida dettagliata li riutilizza in ciascun comando successivo:
export RESOURCE_GROUP=<resource-group-name>
export CLUSTER=<cluster-name>
export LOCATION=<azure-region>
Eseguire il pull delle credenziali del cluster per kubectl:
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER
Creare l'infrastruttura Azure
Creare la zona DNS di Azure
Se si dispone già di una zona DNS di Azure in cui si vuole che l'operatore di routing dell'applicazione gestisca i record, è possibile ignorare questo passaggio e assegnare il valore di al nome della ZONE_NAME zona esistente.
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)
Creare il Azure Key Vault e il certificato
Creare il Azure Key Vault che archivia il certificato TLS. Configurare l'insieme di credenziali per usare RBAC di Azure per l'autorizzazione, che è il modello di autorizzazione consigliato:
export KV_NAME=<key-vault-name>
az keyvault create \
--name $KV_NAME \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--enable-rbac-authorization true
Note
Per creare il certificato nel passaggio successivo, la propria identità Azure deve avere il ruolo Key Vault Certificates Officer (o Key Vault Administrator) nell'insieme di credenziali. Assegnare questo ruolo all'insieme di credenziali prima di continuare.
Creare un certificato con carattere jolly autofirmato in Azure Key Vault. Per le distribuzioni in produzione, importare un certificato firmato da un'autorità di certificazione (CA) utilizzando invece az keyvault certificate import.
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
Acquisire l'URI del certificato non modificato. L'operatore di instradamento dell'applicazione usa questo URI per configurare il SecretProviderClass. Un URI senza versione garantisce che l'operatore recuperi le nuove versioni del certificato in Azure Key Vault quando il certificato viene rinnovato.
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"
Creare l'identità gestita assegnata dall'utente e assegnare i ruoli RBAC di Azure
Creare un'identità gestita assegnata dall'utente che la distribuzione dell'operatore di Instradamento dell'applicazione external-dns e la sincronizzazione TLS del listener del gateway usano per autenticarsi su DNS di Azure e 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)
Concedere all'identità gestita il DNS Zone Contributor ruolo nella zona di DNS di Azure di destinazione e al Key Vault Secrets User ruolo nel Azure Key Vault di destinazione:
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)
Crea i namespace, i ServiceAccounts e le credenziali di identità federata
Le integrazioni TLS e DNS dell'operatore di routing dell'applicazione eseguono entrambe l'autenticazione per Azure tramite un ServiceAccount Kubernetes associato all'identità gestita assegnata dall'utente usando una credenziale di identità federata (FIC). Ogni coppia (namespace, ServiceAccount) che deve autenticarsi richiede un FIC.
Recupera l'URL dell'emittente OIDC del cluster:
export OIDC_ISSUER=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query oidcIssuerProfile.issuerUrl -o tsv)
Per ogni namespace in cui si intende distribuire una risorsa Gateway che usa l'integrazione TLS o una risorsa ExternalDNS, crea il namespace, una credenziale di identità federata per il ServiceAccount e il ServiceAccount stesso. L'esempio seguente crea due namespace, app-a e app-b, ciascuno dei quali con un ServiceAccount denominato 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
L'annotazione azure.workload.identity/client-id associa il ServiceAccount all'identità gestita e l'etichetta azure.workload.identity/use: "true" indica al webhook Microsoft Entra Workload Identity di proiettare un token federato nei pod che usano il ServiceAccount. Entrambi sono necessari affinché le integrazioni TLS e DNS dell'operatore di routing delle applicazioni possano autenticarsi correttamente ad Azure.
Configurare la terminazione TLS in un gateway
Distribuisci un carico di lavoro di esempio httpbin in ciascuno spazio dei nomi:
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
Crea una risorsa Gateway in ogni namespace con un listener HTTPS che fa riferimento al certificato di Azure Key Vault tramite le opzioni TLS. Ognuno Gateway usa il proprio sub-host della zona DNS di Azure (ad esempio, a.<zone> e b.<zone>):
Note
Gli esempi in questo articolo usano gatewayClassName: approuting-istio, la classe Gateway fornita dall'implementazione dell'API del gateway di routing dell'applicazione. Se invece hai abilitato il componente aggiuntivo service mesh di Istio, imposta gatewayClassName: istio nelle risorse Gateway. Le integrazioni DNS e TLS si comportano in modo identico per entrambe le classi gateway gestite.
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
Attendere che ognuna Gateway raggiunga la Programmed condizione:
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
Verificate che l'operatore Application Routing abbia creato un SecretProviderClass e che il provider Azure Key Vault per Secrets Store CSI Driver abbia sincronizzato il certificato in un segreto kubernetes.io/tls in ogni namespace:
kubectl get secretproviderclass,secret -n app-a
kubectl get secretproviderclass,secret -n app-b
Output di esempio per uno spazio dei nomi:
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
Configurazione dei record DNS di Azure usando ClusterExternalDNS
Distribuisci un'istanza external-dns con ambito cluster che pubblica record A per le risorse Gateway in qualsiasi namespace applicando una risorsa personalizzata 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
Il campo resourceNamespace specifica il namespace in cui l'operatore Application Routing distribuisce l'istanza gestita external-dns. Il ServiceAccount a cui fa riferimento identity.serviceAccount deve esistere in quel namespace.
Dopo circa un minuto, due record A vengono visualizzati nella zona DNS di Azure , uno per ogni 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
Configurare i record DNS di Azure usando un ExternalDNS con ambito namespace
Per pubblicare record per solo un sottoinsieme di risorse Gateway, utilizza la risorsa personalizzata con ambito namespace ExternalDNS. A differenza di ClusterExternalDNS, la variante con ambito del namespace osserva solo le risorse Gateway, HTTPRoute e GRPCRoute nello stesso namespace della risorsa personalizzata. Come con ClusterExternalDNS, facoltativamente è possibile restringere ulteriormente l'ambito usando i filters.gatewayLabels selettori e filters.routeAndIngressLabels .
Prima di tutto, eliminare l'oggetto ClusterExternalDNS dal passaggio precedente:
kubectl delete clusterexternaldns demo-cluster-dns
Distribuisci un nuovo oggetto Gateway in app-a con l'etichetta zone: c e il HTTPRoute corrispondente:
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
Applicare una risorsa con ambito dello spazio dei nomi ExternalDNS in app-a con un filtro di etichette per 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
Si applicano due regole di ambito:
- L'ambito dello spazio dei nomi di
ExternalDNSescludeb-gatewayperché appartiene allo spazio dei nomiapp-b. - Il filtro di etichetta
zone=cescludea-gatewayperché si trova inapp-ama è etichettatozone=a.
L'operatore di routing dell'applicazione pubblica un nuovo record A per c.${ZONE_NAME}:
az network dns record-set a list --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME -o table
Verificare il traffico HTTPS con terminazione TLS
Risolvi il nome host di Gateway tramite il nameserver autorevole della zona DNS di Azure e invia una richiesta 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"
Verrà visualizzata una HTTP/2 200 risposta. Il certificato TLS presentato dal gateway è quello sincronizzato da Azure Key Vault. Se è stato importato un certificato firmato dalla CA, sostituire -k con --cacert <path-to-ca-chain> per convalidare la catena di certificati.
Note
L'esempio usa curl --resolve per ignorare la risoluzione DNS locale e indirizzare la richiesta all'indirizzo IP esterno del gateway. Questo metodo è utile per i test prima di delegare la zona DNS a un registrar. Per l'uso in produzione, configurare il registrar del dominio in modo che deleghi la zona ai name server di DNS di Azure restituiti da az network dns zone show --query 'nameServers'.
Limitations
- Le integrazioni DNS e TLS si applicano solo alle risorse
Gatewayche utilizzano una GatewayClass gestita:approuting-istio(l'implementazione dell'API Application Routing Gateway) oistio(il componente aggiuntivo del service mesh Istio).Gatewayle risorse che usano qualsiasi altra classe GatewayClass non sono supportate. - Una risorsa personalizzata
ClusterExternalDNSoExternalDNSpuò fare riferimento a un massimo di sette zone DNS di Azure tramitednsZoneResourceIDs. Tutte le zone a cui si fa riferimento in una singola risorsa personalizzata devono trovarsi nello stesso Azure sottoscrizione e gruppo di risorse. Devono anche essere tutti dello stesso tipo (pubblico o privato). - L'istanza gestita
external-dnsnon elimina automaticamente i record DNS quando viene eliminata la risorsa personalizzataClusterExternalDNSoExternalDNS. Per rimuovere i record orfani, eliminarli direttamente dalla zona DNS di Azure dopo l'eliminazione della risorsa personalizzata. - La riconciliazione dei record DNS dalle
TLSRouterisorse non è attualmente supportata. L'istanza gestitaexternal-dnsricava i record solo dalle risorseGateway,HTTPRouteeGRPCRoute.