Konfigurera CSI-drivrutin för Secrets Store för att aktivera NGINX-ingresskontrollant med TLS
Den här artikeln beskriver hur du skyddar en NGINX-ingresskontrollant med TLS med ett Azure Kubernetes Service-kluster (AKS) och en Azure Key Vault-instans (AKV). Mer information finns i TLS i Kubernetes.
Du kan importera det inkommande TLS-certifikatet till klustret med någon av följande metoder:
- Program: Programdistributionsmanifestet deklarerar och monterar providervolymen. Endast när du distribuerar programmet görs certifikatet tillgängligt i klustret. När du tar bort programmet tas även hemligheten bort. Det här scenariot passar utvecklingsteam som ansvarar för programmets säkerhetsinfrastruktur och dess integrering med klustret.
- Ingresskontrollant: Ingressdistributionen ändras för att deklarera och montera providervolymen. Hemligheten importeras när inkommande poddar skapas. Programmets poddar har ingen åtkomst till TLS-certifikatet. Det här scenariot passar scenarier där ett team (till exempel IT) hanterar och skapar infrastruktur- och nätverkskomponenter (inklusive HTTPS TLS-certifikat) och andra team hanterar programmets livscykel.
Förutsättningar
- Om du inte har någon Azure-prenumeration skapar du ett kostnadsfritt konto innan du börjar.
- Innan du börjar kontrollerar du att din Azure CLI-version är >=
2.30.0
eller installerar den senaste versionen. - Ett AKS-kluster med CSI-drivrutinen för Secrets Store konfigurerad.
- En Azure Key Vault-instans.
Generera ett TLS-certifikat
Generera ett TLS-certifikat med hjälp av följande kommando.
export CERT_NAME=aks-ingress-cert openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -out aks-ingress-tls.crt \ -keyout aks-ingress-tls.key \ -subj "/CN=demo.azure.com/O=aks-ingress-tls"
Importera certifikatet till AKV
Exportera certifikatet till en PFX-fil med hjälp av följande kommando.
export AKV_NAME="[YOUR AKV NAME]" openssl pkcs12 -export -in aks-ingress-tls.crt -inkey aks-ingress-tls.key -out $CERT_NAME.pfx # skip Password prompt
Importera certifikatet med kommandot
az keyvault certificate import
.az keyvault certificate import --vault-name $AKV_NAME --name $CERT_NAME --file $CERT_NAME.pfx
Distribuera en SecretProviderClass
Exportera ett nytt namnområde med hjälp av följande kommando.
export NAMESPACE=ingress-basic
Skapa namnområdet med kommandot
kubectl create namespace
.kubectl create namespace $NAMESPACE
Välj en metod för att tillhandahålla en åtkomstidentitet och konfigurera din SecretProviderClass YAML i enlighet med detta.
- Se till att använda
objectType=secret
, vilket är det enda sättet att hämta den privata nyckeln och certifikatet från AKV. - Ange
kubernetes.io/tls
somtype
i avsnittetsecretObjects
.
Se följande exempel på hur Din SecretProviderClass kan se ut:
apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-tls spec: provider: azure secretObjects: # secretObjects defines the desired state of synced K8s secret objects - secretName: ingress-tls-csi type: kubernetes.io/tls data: - objectName: $CERT_NAME key: tls.key - objectName: $CERT_NAME key: tls.crt parameters: usePodIdentity: "false" useVMManagedIdentity: "true" userAssignedIdentityID: <client id> keyvaultName: $AKV_NAME # the name of the AKV instance objects: | array: - | objectName: $CERT_NAME objectType: secret tenantId: $TENANT_ID # the tenant ID of the AKV instance
- Se till att använda
Använd SecretProviderClass på ditt Kubernetes-kluster med kommandot
kubectl apply
.kubectl apply -f secretProviderClass.yaml -n $NAMESPACE
Distribuera ingresskontrollanten
Lägg till den officiella lagringsplatsen för inkommande diagram
Lägg till den officiella lagringsplatsen för inkommande diagram med hjälp av följande
helm
kommandon.helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
Konfigurera och distribuera NGINX-ingressen
Beroende på ditt scenario kan du välja att binda certifikatet till antingen programmet eller till ingresskontrollanten. Följ anvisningarna nedan enligt ditt val:
Binda certifikat till program
Binda certifikatet till programmet med hjälp av
helm install
kommandot . Programmets distribution refererar till CSI-drivrutinens Azure Key Vault-provider i Secrets Store.helm install ingress-nginx/ingress-nginx --generate-name \ --namespace $NAMESPACE \ --set controller.replicaCount=2 \ --set controller.nodeSelector."kubernetes\.io/os"=linux \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \ --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux
Binda certifikat till ingresskontrollant
Binda certifikatet till ingresskontrollanten med hjälp av
helm install
kommandot . Ingresskontrollantens distribution refererar till CSI-drivrutinens Azure Key Vault-provider för Secrets Store.Kommentar
Om du inte använder Microsoft Entra poddhanterad identitet som åtkomstmetod tar du bort raden med
--set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME
.Dessutom krävs bindning av SecretProviderClass till en podd för att CSI-drivrutinen för Secrets Store ska montera den och generera Kubernetes-hemligheten. Se Synkronisera monterat innehåll med en Kubernetes-hemlighet .
helm install ingress-nginx/ingress-nginx --generate-name \ --namespace $NAMESPACE \ --set controller.replicaCount=2 \ --set controller.nodeSelector."kubernetes\.io/os"=linux \ --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \ --set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME \ -f - <<EOF controller: extraVolumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-tls" extraVolumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true EOF
Kontrollera att Kubernetes-hemligheten
kubectl get secret
skapades med kommandot .kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Distribuera programmet
Återigen ändras anvisningarna något beroende på ditt scenario. Följ anvisningarna som motsvarar det scenario som du valde.
Distribuera programmet med hjälp av en programreferens
Skapa en fil med namnet
aks-helloworld-one.yaml
med följande innehåll.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-one spec: replicas: 1 selector: matchLabels: app: aks-helloworld-one template: metadata: labels: app: aks-helloworld-one spec: containers: - name: aks-helloworld-one image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "Welcome to Azure Kubernetes Service (AKS)" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-tls" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-one spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-one
Skapa en fil med namnet
aks-helloworld-two.yaml
med följande innehåll.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-two spec: replicas: 1 selector: matchLabels: app: aks-helloworld-two template: metadata: labels: app: aks-helloworld-two spec: containers: - name: aks-helloworld-two image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "AKS Ingress Demo" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "azure-tls" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-two spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-two
Använd YAML-filerna i klustret med hjälp av
kubectl apply
kommandot .kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Kontrollera att Kubernetes-hemligheten
kubectl get secret
skapades med kommandot .kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
Distribuera programmet med hjälp av en referens för ingresskontrollant
Skapa en fil med namnet
aks-helloworld-one.yaml
med följande innehåll.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-one spec: replicas: 1 selector: matchLabels: app: aks-helloworld-one template: metadata: labels: app: aks-helloworld-one spec: containers: - name: aks-helloworld-one image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "Welcome to Azure Kubernetes Service (AKS)" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-one spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-one
Skapa en fil med namnet
aks-helloworld-two.yaml
med följande innehåll.apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-two spec: replicas: 1 selector: matchLabels: app: aks-helloworld-two template: metadata: labels: app: aks-helloworld-two spec: containers: - name: aks-helloworld-two image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "AKS Ingress Demo" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-two spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-two
Använd YAML-filerna i klustret med hjälp av
kubectl apply
kommandot .kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Distribuera en ingressresurs som refererar till hemligheten
Nu kan vi distribuera en Kubernetes-ingressresurs som refererar till hemligheten.
Skapa ett filnamn
hello-world-ingress.yaml
med följande innehåll.apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-tls annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx tls: - hosts: - demo.azure.com secretName: ingress-tls-csi rules: - host: demo.azure.com 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
Anteckna avsnittet
tls
som refererar till hemligheten som skapades tidigare och tillämpa filen på klustret med hjälp avkubectl apply
kommandot .kubectl apply -f hello-world-ingress.yaml -n $NAMESPACE
Hämta den externa IP-adressen för ingresskontrollanten
Hämta den externa IP-adressen för ingresskontrollanten med hjälp av
kubectl get service
kommandot .kubectl get service --namespace $NAMESPACE --selector app.kubernetes.io/name=ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-1588032400-controller LoadBalancer 10.0.255.157 EXTERNAL_IP 80:31293/TCP,443:31265/TCP 19m nginx-ingress-1588032400-default-backend ClusterIP 10.0.223.214 <none> 80/TCP 19m
Testa ingress som skyddas med TLS
Kontrollera att ingressen är korrekt konfigurerad med TLS med hjälp av följande
curl
kommando. Kontrollera att du använder den externa IP-adressen från föregående steg.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com
Eftersom en annan sökväg inte har angetts med adressen använder ingresskontrollanten / som standard vägen. Det första demoprogrammet returneras, enligt följande komprimerade exempelutdata:
[...] <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="/static/default.css"> <title>Welcome to Azure Kubernetes Service (AKS)</title> [...]
Parametern -v i
curl
kommandot matar ut utförlig information, inklusive TLS-certifikatet som tagits emot. Halvvägs genom curl-utdata kan du kontrollera att ditt eget TLS-certifikat användes. Parametern -k fortsätter att läsa in sidan trots att vi använder ett självsignerat certifikat. I följande exempel visas utfärdaren : CN=demo.azure.com; O=aks-ingress-tls-certifikat användes:[...] * Server certificate: * subject: CN=demo.azure.com; O=aks-ingress-tls * start date: Oct 22 22:13:54 2021 GMT * expire date: Oct 22 22:13:54 2022 GMT * issuer: CN=demo.azure.com; O=aks-ingress-tls * SSL certificate verify result: self signed certificate (18), continuing anyway. [...]
Lägg till sökvägen /hello-world-two till adressen, till exempel
https://demo.azure.com/hello-world-two
, och kontrollera att det andra demoprogrammet är korrekt konfigurerat.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com/hello-world-two
Det andra demoprogrammet med den anpassade rubriken returneras, enligt följande komprimerade exempelutdata:
[...] <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="/static/default.css"> <title>AKS Ingress Demo</title> [...]
Azure Kubernetes Service