Usare TLS con un controller in ingresso nel servizio Azure Kubernetes
Il protocollo TLS (Transport Layer Security) usa certificati per garantire la sicurezza delle comunicazioni, la crittografia, l'autenticazione e l'integrità. L'uso di TLS con un controller in ingresso del servizio Azure Kubernetes consente di proteggere le comunicazioni tra le applicazioni e di usufruire dei vantaggi di un controller in ingresso.
È possibile usare certificati personalizzati e integrarli con il driver CSI dell'archivio segreti. In alternativa, è possibile usare cert-manager, che genera e configura automaticamente i certificati Let's Encrypt. Vengono eseguite due applicazioni nel cluster del servizio Azure Kubernetes, ognuna delle quali è accessibile tramite un singolo indirizzo IP.
Importante
È consigliabile usare il componente aggiuntivo Instradamento dell’applicazione per l'ingresso nel servizio Azure Kubernetes. Per ulteriori informazioni, consultare Ingresso nginx gestito con il componente aggiuntivo Instradamento dell’applicazione.
Importante
Microsoft non gestisce o supporta cert-manager e eventuali problemi derivanti dal suo uso. Per problemi relativi a cert-manager, vedere la documentazione sulla risoluzione dei problemi di cert-manager.
Sono disponibili due controller in ingresso open source per Kubernetes basati su Nginx: uno gestito dalla community di Kubernetes (kubernetes/ingress-nginx) e uno gestito da NGINX, Inc. (nginxinc/kubernetes-ingress). In questo articolo si fa riferimento al controller in ingresso della community Kubernetes.
Operazioni preliminari
Questo articolo presuppone che il controller in ingresso e le applicazioni siano stati configurati. Per un esempio di controller in ingresso o delle applicazioni, vedere Creare un controller in ingresso.
In questo articolo viene usato Helm 3 per installare il controller in ingresso NGINX in una versione supportata di Kubernetes. Assicurarsi di usare la versione più recente di Helm e di avere accesso ai repository Helm
ingress-nginx
ejetstack
. I passaggi descritti in questo articolo potrebbero non essere compatibili con le versioni precedenti del grafico Helm, del controller in ingresso NGINX o di Kubernetes.- Per altre informazioni sulla configurazione e l'uso di Helm, vedere Installare le applicazioni con Helm nel servizio Azure Kubernetes. Per istruzioni sull'aggiornamento, consultare Installare i documenti Helm.
Questo articolo presuppone che sia già presente un cluster del servizio Azure Kubernetes con un servizio Registro Azure Container (ACR) integrato. Per altre informazioni sulla creazione di un cluster del servizio Azure Kubernetes con un servizio Registro Azure Container integrato, vedere Eseguire l'autenticazione con Registro Azure Container dal servizio Azure Kubernetes.
In questo articolo si presuppone che sia in esecuzione l’interfaccia della riga di comando di Azure versione 2.0.64 o versione successiva se si usa l'interfaccia della riga di comando di Azure. Eseguire
az --version
per trovare la versione. Se è necessario eseguire l'installazione o l'aggiornamento, vedere Installare l'interfaccia della riga di comando di Azure.In questo articolo si presuppone che sia in esecuzione Azure PowerShell versione 5.9.0 o una versione successiva se si usa Azure PowerShell. Eseguire
Get-InstalledModule -Name Az
per trovare la versione. Se è necessario eseguire l'installazione o l'aggiornamento, vedere Installare Azure PowerShell.
Usare TLS con certificati personalizzati con il driver CSI dell'archivio segreti
Per usare TLS con certificati personalizzati con il driver CSI dell'archivio segreti, è necessario un cluster del servizio Azure Kubernetes con il driver CSI dell'archivio segreti configurato e un'istanza di Azure Key Vault.
Per altre informazioni, vedere Configurare il driver CSI dell'archivio segreti per abilitare il controller in ingresso NGINX con TLS.
Usare TLS con i certificati Let's Encrypt
Per usare TLS con i certificati Let's Encrypt, è necessario distribuire cert-manager, che genera e configura automaticamente i certificati Let's Encrypt.
Importare le immagini cert-manager usate dal grafico Helm in Registro Azure Container
Usare
az acr import
per importare le immagini seguenti in Registro Azure Container.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
È anche possibile importare grafici Helm in Registro Azure Container. Per altre informazioni, vedere Eseguire il push e il pull dei grafici Helm in Registro Azure Container.
Opzioni di configurazione per il controller in ingresso
È possibile configurare il controller in ingresso NGINX usando un indirizzo IP pubblico statico o un indirizzo IP pubblico dinamico. Se si usa un dominio personalizzato, è necessario aggiungere un record A alla zona DNS. Se non si usa un dominio personalizzato, è possibile configurare un nome di dominio completo (FQDN) per l'indirizzo IP del controller in ingresso.
Creare un indirizzo IP pubblico statico o dinamico
Usare un indirizzo IP pubblico statico
È possibile configurare il controller in ingresso con un indirizzo IP pubblico statico. L'indirizzo IP pubblico statico viene mantenuto dopo l’eliminazione del controller in ingresso. L'indirizzo IP non viene mantenuto se si elimina il cluster del servizio Azure Kubernetes.
Quando si aggiorna il controller in ingresso, è necessario passare un parametro alla versione Helm per assicurarsi che il servizio del controller in ingresso sia informato del servizio di bilanciamento del carico che verrà allocato. Per un uso corretto dei certificati HTTPS, è necessario configurare un nome di dominio completo per l'indirizzo IP del controller in ingresso.
Ottenere il nome del gruppo di risorse del cluster del servizio Azure Kubernetes con il comando
az aks show
.az aks show --resource-group myResourceGroup --name myAKSCluster --query nodeResourceGroup -o tsv
Creare un indirizzo IP pubblico con il metodo di allocazione statica usando il comando
az network public-ip create
. Nell'esempio seguente viene creato un indirizzo IP pubblico denominato myservizio Azure KubernetesPublicIP nel gruppo di risorse cluster servizio Azure Kubernetes ottenuto nel passaggio precedente.az network public-ip create --resource-group MC_myResourceGroup_myAKSCluster_eastus --name myAKSPublicIP --sku Standard --allocation-method static --query publicIp.ipAddress -o tsv
Nota
In alternativa, è possibile creare un indirizzo IP in un gruppo di risorse diverso, che è possibile gestire separatamente dal cluster del servizio Azure Kubernetes. Se si crea un indirizzo IP in un gruppo di risorse diverso, verificare che siano soddisfatte le condizioni seguenti:
- L'identità del cluster usata dal cluster del servizio Azure Kubernetes ha autorizzazioni delegate per il gruppo di risorse, ad esempio Collaboratore rete.
- Aggiungere il parametro
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-resource-group"="<RESOURCE_GROUP>"
. Sostituire<RESOURCE_GROUP>
con il nome del gruppo di risorse in cui risiede l'indirizzo IP.
Aggiungere il parametro
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"="<DNS_LABEL>"
. È possibile impostare l'etichetta DNS durante la prima distribuzione del controller in ingresso oppure configurarlo in un secondo momento.Aggiungere il parametro
--set controller.service.loadBalancerIP="<STATIC_IP>"
. Specificare l’indirizzo IP pubblico creato nel passaggio precedente.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
Per altre informazioni, vedere Usare un indirizzo IP pubblico statico e un'etichetta DNS con il servizio di bilanciamento del carico del servizio Azure Kubernetes.
Usare un indirizzo IP pubblico dinamico
Al momento della creazione viene creato un indirizzo IP pubblico di Azure per il controller in ingresso. L'indirizzo IP pubblico è statico per la durata del controller in ingresso. L'indirizzo IP pubblico non viene mantenuto se si elimina il controller in ingresso. Se si crea un nuovo controller in ingresso, verrà assegnato un nuovo indirizzo IP pubblico. L'output dovrebbe essere simile al seguente esempio.
Usare il comando
kubectl get service
per ottenere l'indirizzo IP pubblico per il controller in ingresso.# 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
Aggiungere un record A alla zona DNS
Se si usa un dominio personalizzato, è necessario aggiungere un record A alla zona DNS. Se non si usa un dominio personalizzato, è possibile configurare l'indirizzo IP pubblico con un nome di dominio completo.
Aggiungere un record A alla zona DNS con l'indirizzo IP esterno del servizio 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
Configurare un nome di dominio completo per il controller in ingresso
Facoltativamente, è possibile configurare un nome di dominio completo per l'indirizzo IP del controller in ingresso anziché un dominio personalizzato impostando un'etichetta DNS. Il nome di dominio completo deve seguire questo formato: <CUSTOM DNS LABEL>.<AZURE REGION NAME>.cloudapp.azure.com
.
Importante
L'etichetta DNS deve essere univoca all'interno della posizione di Azure.
È possibile configurare il nome di dominio completo usando uno dei metodi seguenti:
- Impostare l'etichetta DNS usando l'interfaccia della riga di comando di Azure o Azure PowerShell.
- Impostare l'etichetta DNS usando le impostazioni del grafico Helm.
Per altre informazioni, vedere Etichette dei nomi DNS per l'indirizzo IP pubblico.
Impostare l'etichetta DNS usando l'interfaccia della riga di comando di Azure o Azure PowerShell
Assicurarsi di sostituire <DNS_LABEL>
con l'etichetta DNS univoca.
# 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
Impostare l'etichetta DNS usando le impostazioni del grafico Helm
È possibile passare un'impostazione di annotazione alla configurazione del grafico Helm usando il parametro --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"
. È possibile impostare questo parametro durante la prima distribuzione del controller in ingresso oppure configurarlo in un secondo momento.
Nell'esempio seguente viene illustrato come aggiornare questa impostazione dopo la distribuzione del controller. Assicurarsi di sostituire <DNS_LABEL>
con l'etichetta DNS univoca.
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
Installare cert-manager
Il controller di ingresso NGINX supporta la terminazione TLS. Esistono diversi modi per recuperare e configurare i certificati per HTTPS. Questo articolo descrive l'uso di cert-manager, che consente di generare automaticamente il certificato Let's Encrypt e che dispone di funzionalità di gestione.
Per installare il controller di cert-manager, usare i comandi seguenti.
# 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
Per altre informazioni sulla configurazione di cert-manager, vedere progetto cert-manager.
Creare un'autorità di certificazione (CA) cluster
Prima del rilascio dei certificati, cert-manager richiede una delle seguenti autorità di certificazione:
- Un’autorità di certificazione che possa essere usata in un singolo spazio dei nomi.
- Una risorsa ClusterIssuer che possa essere usata in tutti gli spazi dei nomi.
Per altre informazioni, vedere la documentazione relativa all'autorità di certificazione cert-manager.
Creare un'autorità di certificazione del cluster, ad esempio
cluster-issuer.yaml
, tramite il manifesto di esempio seguente. SostituireMY_EMAIL_ADDRESS
con un indirizzo valido dell'organizzazione.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
Applicare l'autorità di certificazione usando il comando
kubectl apply
.kubectl apply -f cluster-issuer.yaml --namespace ingress-basic
Aggiornare le route in ingresso
È necessario aggiornare le route in ingresso per gestire il traffico verso il nome di dominio completo o il dominio personalizzato.
Nell'esempio seguente il traffico viene instradato come tale:
- Il traffico diretto a hello-world-ingress.MY_CUSTOM_DOMAIN viene instradato al servizio aks-helloworld-one.
- Il traffico diretto a hello-world-ingress.MY_CUSTOM_DOMAIN/hello-world-two viene instradato al servizio aks-helloworld-two.
- Il traffico diretto a hello-world-ingress.MY_CUSTOM_DOMAIN/static viene instradato al servizio denominato aks-helloworld-one per gli asset statici.
Nota
Se è stato configurato un nome di dominio completo per l'indirizzo IP del controller in ingresso anziché un dominio personalizzato, usare il nome di dominio completo anziché hello-world-ingress.MY_CUSTOM_DOMAIN.
Ad esempio, se il nome di dominio completo è demo-aks-ingress.eastus.cloudapp.azure.com, sostituire hello-world-ingress.MY_CUSTOM_DOMAIN con demo-aks-ingress.eastus.cloudapp.azure.com in hello-world-ingress.yaml
.
Creare o aggiornare il file
hello-world-ingress.yaml
usando il file YAML di esempio seguente. Aggiornarespec.tls.hosts
espec.rules.host
al nome DNS creato in un passaggio precedente.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
Creare la risorsa in ingresso con il comando
kubectl apply
.kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
Verificare che sia stato creato un oggetto certificato
Successivamente, è necessario creare una risorsa certificato. La risorsa certificato definisce il certificato X.509 desiderato. Per altre informazioni, vedere cert-manager certificates (Certificati cert-manager).
Cert-manager crea utomaticamente un oggetto certificato per l'uso in ingress-shim, che viene distribuito automaticamente con cert-manager dalla versione 0.2.2. Per altre informazioni, consultare la documentazione su ingress-shim.
Per verificare che il certificato sia stato creato correttamente, usare il comando kubectl get certificate --namespace ingress-basic
e verificare che READY sia impostato su True. Potrebbero essere necessari alcuni minuti per ottenere l'output.
kubectl get certificate --namespace ingress-basic
L'output seguente mostra lo stato del certificato.
NAME READY SECRET AGE
tls-secret True tls-secret 11m
Testare la configurazione di ingresso
Aprire un Web browser visualizzando hello-world-ingress.MY_CUSTOM_DOMAIN o il nome di dominio completo del controller in ingresso Kubernetes. Accertarsi che si verifichino le condizioni seguenti:
- Si venga reindirizzati all'uso di HTTPS.
- Il certificato sia attendibile.
- L'applicazione demo venga visualizzata nel Web browser.
- Aggiungere /hello-world-two alla fine del dominio e assicurarsi che venga visualizzata la seconda applicazione demo con il titolo personalizzato.
Pulire le risorse
Questo articolo ha usato Helm per installare i componenti di ingresso, i certificati e le app di esempio. Quando si distribuisce un grafico Helm, vengono create numerose risorse Kubernetes. Queste risorse includono pod, distribuzioni e servizi. Per pulire queste risorse, è possibile eliminare l'intero spazio dei nomi di esempio o eliminare le risorse singolarmente.
Eliminare lo spazio dei nomi di esempio e tutte le risorse
L'eliminazione dello spazio dei nomi di esempio elimina anche tutte le risorse nello spazio dei nomi .
Per eliminare l'intero spazio dei nomi di esempio, usare il comando
kubectl delete
e specificare il nome dello spazio dei nomi.kubectl delete namespace ingress-basic
Eliminare le risorse singolarmente
In alternativa, è possibile eliminare la risorsa singolarmente.
Rimuovere le risorse dell'autorità di certificazione del cluster.
kubectl delete -f cluster-issuer.yaml --namespace ingress-basic
Elencare le versioni di Helm con il comando
helm list
. Cercare i grafici denominati nginx e cert-manager, come illustrato nell'output di esempio seguente.$ 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
Disinstallare le versioni usando il comando
helm uninstall
. L'esempio mostra la disinstallazione delle distribuzioni NGINX in ingresso e di cert-manager.$ helm uninstall cert-manager nginx --namespace ingress-basic release "cert-manager" uninstalled release "nginx" uninstalled
Successivamente, rimuovere le due applicazioni di esempio.
kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
Rimuovere la route in ingresso che ha indirizzato il traffico verso le app di esempio.
kubectl delete -f hello-world-ingress.yaml --namespace ingress-basic
Eliminare lo spazio dei nomi stesso. Usare il comando
kubectl delete
e specificare il nome dello spazio dei nomi.kubectl delete namespace ingress-basic
Passaggi successivi
In questo articolo sono stati inclusi alcuni componenti esterni ad servizio Azure Kubernetes. Per altre informazioni su questi componenti, vedere le pagine di progetto seguenti:
È anche possibile: