Geheimenarchief CSI-stuurprogramma instellen om NGINX-ingangscontroller in te schakelen met TLS
In dit artikel wordt u begeleid bij het beveiligen van een NGINX-ingangscontroller met TLS met een AKS-cluster (Azure Kubernetes Service) en een AZURE Key Vault-exemplaar (AKV). Zie TLS in Kubernetes voor meer informatie.
U kunt het TLS-certificaat voor inkomend verkeer importeren in het cluster met behulp van een van de volgende methoden:
- Toepassing: Het manifest voor toepassingsimplementatie declareert en koppelt het providervolume. Alleen wanneer u de toepassing implementeert, is het certificaat dat beschikbaar is in het cluster. Wanneer u de toepassing verwijdert, wordt het geheim ook verwijderd. Dit scenario past bij ontwikkelteams die verantwoordelijk zijn voor de beveiligingsinfrastructuur van de toepassing en de integratie met het cluster.
- Ingangscontroller: de implementatie van inkomend verkeer wordt gewijzigd om het providervolume te declareren en te koppelen. Het geheim wordt geïmporteerd wanneer inkomende pods worden gemaakt. De pods van de toepassing hebben geen toegang tot het TLS-certificaat. Dit scenario past bij scenario's waarin één team (bijvoorbeeld IT) infrastructuur- en netwerkonderdelen beheert en maakt (inclusief HTTPS TLS-certificaten) en andere teams de levenscyclus van toepassingen beheren.
Vereisten
- Als u geen Azure-abonnement hebt, maakt u een gratis account voordat u begint.
- Voordat u begint, controleert u of uw Azure CLI-versie =
2.30.0
is >of installeert u de nieuwste versie. - Een AKS-cluster met het CSI-stuurprogramma Secrets Store geconfigureerd.
- Een Azure Key Vault-exemplaar.
Een TLS-certificaat genereren
Genereer een TLS-certificaat met behulp van de volgende opdracht.
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"
Het certificaat importeren in AKV
Exporteer het certificaat naar een PFX-bestand met behulp van de volgende opdracht.
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
Importeer het certificaat met behulp van de
az keyvault certificate import
opdracht.az keyvault certificate import --vault-name $AKV_NAME --name $CERT_NAME --file $CERT_NAME.pfx
Een SecretProviderClass implementeren
Exporteer een nieuwe naamruimte met behulp van de volgende opdracht.
export NAMESPACE=ingress-basic
Maak de naamruimte met behulp van de
kubectl create namespace
opdracht.kubectl create namespace $NAMESPACE
Selecteer een methode om een toegangsidentiteit op te geven en configureer uw SecretProviderClass YAML dienovereenkomstig.
- Zorg ervoor dat u
objectType=secret
gebruikt, wat de enige manier is om de persoonlijke sleutel en het certificaat van AKV te verkrijgen. - Stel
kubernetes.io/tls
deze insecretObjects
als detype
sectie.
Bekijk het volgende voorbeeld van hoe uw SecretProviderClass eruit kan zien:
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
- Zorg ervoor dat u
Pas de SecretProviderClass toe op uw Kubernetes-cluster met behulp van de
kubectl apply
opdracht.kubectl apply -f secretProviderClass.yaml -n $NAMESPACE
De ingangscontroller implementeren
De officiële opslagplaats voor inkomend verkeer toevoegen
Voeg de officiële opslagplaats voor inkomend verkeer toe met behulp van de volgende
helm
opdrachten.helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
De NGINX-ingang configureren en implementeren
Afhankelijk van uw scenario kunt u ervoor kiezen om het certificaat te binden aan de toepassing of aan de ingangscontroller. Volg de onderstaande instructies op basis van uw selectie:
Certificaat binden aan toepassing
Bind het certificaat aan de toepassing met behulp van de
helm install
opdracht. De implementatie van de toepassing verwijst naar de Azure Key Vault-provider van het Secrets Store CSI-stuurprogramma.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
Certificaat binden aan toegangsbeheerobjectcontroller
Bind het certificaat aan de ingangscontroller met behulp van de
helm install
opdracht. De implementatie van de toegangsbeheerobjectcontroller verwijst naar de Azure Key Vault-provider van het Secrets Store CSI-stuurprogramma.Notitie
Als u geen door Microsoft Entra beheerde identiteit als toegangsmethode gebruikt, verwijdert u de regel met
--set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME
.Daarnaast is het koppelen van de SecretProviderClass aan een pod vereist voor het CSI-stuurprogramma Secrets Store om het te koppelen en het Kubernetes-geheim te genereren. Zie Gekoppelde inhoud synchroniseren met een Kubernetes-geheim .
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
Controleer of het Kubernetes-geheim is gemaakt met behulp van de
kubectl get secret
opdracht.kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
De toepassing implementeren
Nogmaals, de instructies veranderen enigszins, afhankelijk van uw scenario. Volg de instructies die overeenkomen met het scenario dat u hebt geselecteerd.
De toepassing implementeren met behulp van een toepassingsreferentie
Maak een bestand met de naam
aks-helloworld-one.yaml
met de volgende inhoud.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
Maak een bestand met de naam
aks-helloworld-two.yaml
met de volgende inhoud.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
Pas de YAML-bestanden toe op uw cluster met behulp van de
kubectl apply
opdracht.kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Controleer of het Kubernetes-geheim is gemaakt met behulp van de
kubectl get secret
opdracht.kubectl get secret -n $NAMESPACE NAME TYPE DATA AGE ingress-tls-csi kubernetes.io/tls 2 1m34s
De toepassing implementeren met behulp van een verwijzing naar een toegangsbeheerobjectcontroller
Maak een bestand met de naam
aks-helloworld-one.yaml
met de volgende inhoud.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
Maak een bestand met de naam
aks-helloworld-two.yaml
met de volgende inhoud.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
Pas de YAML-bestanden toe op uw cluster met behulp van de
kubectl apply
opdracht.kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
Een toegangsbeheerobjectresource implementeren die verwijst naar het geheim
We kunnen nu een Kubernetes-toegangsbeheerobjectresource implementeren die verwijst naar het geheim.
Maak een bestandsnaam
hello-world-ingress.yaml
met de volgende inhoud.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
Noteer de
tls
sectie die verwijst naar het geheim dat u eerder hebt gemaakt en pas het bestand toe op uw cluster met behulp van dekubectl apply
opdracht.kubectl apply -f hello-world-ingress.yaml -n $NAMESPACE
Het externe IP-adres van de ingangscontroller verkrijgen
Haal het externe IP-adres voor de ingangscontroller op met behulp van de
kubectl get service
opdracht.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
Inkomend verkeer testen dat is beveiligd met TLS
Controleer of uw toegangsbeheerobject correct is geconfigureerd met TLS met behulp van de volgende
curl
opdracht. Zorg ervoor dat u het externe IP-adres uit de vorige stap gebruikt.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com
Omdat er geen ander pad bij het adres is opgegeven, wordt de ingangscontroller standaard ingesteld op de / route. De eerste demotoepassing wordt geretourneerd, zoals wordt weergegeven in de volgende verkorte voorbeelduitvoer:
[...] <!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> [...]
De parameter -v in de
curl
opdracht voert uitgebreide informatie uit, inclusief het ONTVANGEN TLS-certificaat. Halverwege de curl-uitvoer kunt u controleren of uw eigen TLS-certificaat is gebruikt. De parameter -k blijft de pagina laden, ook al gebruiken we een zelfondertekend certificaat. In het volgende voorbeeld ziet u de verlener: CN=demo.azure.com; O=aks-ingress-tls-certificaat is gebruikt:[...] * 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. [...]
Voeg /hello-world-two-pad toe aan het adres, zoals
https://demo.azure.com/hello-world-two
en controleer of de tweede demotoepassing juist is geconfigureerd.curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com/hello-world-two
De tweede demotoepassing met de aangepaste titel wordt geretourneerd, zoals wordt weergegeven in de volgende verkorte voorbeelduitvoer:
[...] <!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