Sdílet prostřednictvím


Nastavení ovladače CSI úložiště tajných kódů pro povolení kontroleru příchozího přenosu dat NGINX pomocí protokolu TLS

Tento článek vás provede procesem zabezpečení kontroleru příchozího přenosu dat NGINX pomocí protokolu TLS s clusterem Azure Kubernetes Service (AKS) a instancí služby Azure Key Vault (AKV). Další informace najdete v tématu TLS v Kubernetes.

Certifikát TLS příchozího přenosu dat můžete importovat do clusteru pomocí jedné z následujících metod:

  • Aplikace: Manifest nasazení aplikace deklaruje a připojuje svazek zprostředkovatele. Pouze když nasadíte aplikaci, bude certifikát zpřístupněný v clusteru. Když aplikaci odeberete, tajný kód se odebere také. Tento scénář odpovídá vývojovým týmům zodpovědným za infrastrukturu zabezpečení aplikace a její integraci s clusterem.
  • Kontroler příchozího přenosu dat: Nasazení příchozího přenosu dat se upraví tak, aby deklarovaly a připojovaly svazek poskytovatele. Tajný kód se naimportuje při vytváření podů příchozího přenosu dat. Pody aplikace nemají přístup k certifikátu TLS. Tento scénář odpovídá scénářům, kdy jeden tým (například IT) spravuje a vytváří komponenty infrastruktury a sítě (včetně certifikátů HTTPS TLS) a další týmy spravují životní cyklus aplikace.

Požadavky

Vygenerování certifikátu TLS

  • Pomocí následujícího příkazu vygenerujte certifikát TLS.

    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"
    

Import certifikátu do AKV

  1. Pomocí následujícího příkazu exportujte certifikát do souboru PFX.

    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
    
  2. Importujte certifikát pomocí az keyvault certificate import příkazu.

    az keyvault certificate import --vault-name $AKV_NAME --name $CERT_NAME --file $CERT_NAME.pfx
    

Nasazení třídy SecretProviderClass

  1. Pomocí následujícího příkazu exportujte nový obor názvů.

    export NAMESPACE=ingress-basic
    
  2. Pomocí příkazu vytvořte obor názvů kubectl create namespace .

    kubectl create namespace $NAMESPACE
    
  3. Vyberte metodu pro poskytnutí přístupové identity a odpovídajícím způsobem nakonfigurujte YAML třídy SecretProviderClass.

    • Nezapomeňte použít objectType=secret, což je jediný způsob, jak získat privátní klíč a certifikát z AKV.
    • Nastavte kubernetes.io/tls jako v secretObjects oddílutype.

    Podívejte se na následující příklad toho, jak může vaše třída SecretProviderClass vypadat:

    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
    
  4. Pomocí příkazu použijte secretProviderClass na cluster kubectl apply Kubernetes.

    kubectl apply -f secretProviderClass.yaml -n $NAMESPACE
    

Nasazení kontroleru příchozího přenosu dat

Přidání oficiálního úložiště grafu příchozího přenosu dat

  • Pomocí následujících helm příkazů přidejte oficiální úložiště grafu příchozího přenosu dat.

    helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
    helm repo update
    

Konfigurace a nasazení příchozího přenosu dat NGINX

V závislosti na vašem scénáři se můžete rozhodnout vytvořit vazbu certifikátu na aplikaci nebo na kontroler příchozího přenosu dat. Postupujte podle následujících pokynů podle vašeho výběru:

Vytvoření vazby certifikátu k aplikaci

  • Vytvořte vazbu certifikátu k aplikaci pomocí helm install příkazu. Nasazení aplikace odkazuje na zprostředkovatele Azure Key Vault ovladače CSI služby 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
    

Vytvoření vazby certifikátu k kontroleru příchozího přenosu dat

  1. Vytvořte vazbu certifikátu na kontroler příchozího helm install přenosu dat pomocí příkazu. Nasazení kontroleru příchozího přenosu dat odkazuje na poskytovatele služby Azure Key Vault ovladače csI služby Secrets Store.

    Poznámka:

    • Pokud jako metodu přístupu nepoužíváte identitu spravovanou podem Microsoft Entra, odeberte řádek s --set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME .

    • K připojení ovladače CSI úložiště tajných kódů a generování tajného klíče Kubernetes se také vyžaduje vazba SecretProviderClass na pod. Viz Synchronizovat připojený obsah s tajným kódem Kubernetes .

    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
    
  2. Pomocí příkazu ověřte vytvoření tajného kubectl get secret kódu Kubernetes.

    kubectl get secret -n $NAMESPACE
    
    NAME                                             TYPE                                  DATA   AGE
    ingress-tls-csi                                  kubernetes.io/tls                     2      1m34s
    

Nasazení aplikace

Pokyny se zase mírně mění v závislosti na vašem scénáři. Postupujte podle pokynů odpovídajících vybranému scénáři.

Nasazení aplikace pomocí odkazu na aplikaci

  1. Vytvořte soubor s názvem aks-helloworld-one.yaml s následujícím obsahem.

    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
    
  2. Vytvořte soubor s názvem aks-helloworld-two.yaml s následujícím obsahem.

    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
    
  3. Pomocí příkazu použijte soubory YAML ve vašem clusteru kubectl apply .

    kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE
    kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
    
  4. Pomocí příkazu ověřte vytvoření tajného kubectl get secret kódu Kubernetes.

    kubectl get secret -n $NAMESPACE
    
    NAME                                             TYPE                                  DATA   AGE
    ingress-tls-csi                                  kubernetes.io/tls                     2      1m34s
    

Nasazení aplikace pomocí odkazu na kontroler příchozího přenosu dat

  1. Vytvořte soubor s názvem aks-helloworld-one.yaml s následujícím obsahem.

    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
    
  2. Vytvořte soubor s názvem aks-helloworld-two.yaml s následujícím obsahem.

    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
    
  3. Pomocí příkazu použijte soubory YAML ve vašem clusteru kubectl apply .

    kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE
    kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
    

Nasazení prostředku příchozího přenosu dat odkazujícího na tajný klíč

Teď můžeme nasadit prostředek příchozího přenosu dat Kubernetes odkazující na tajný klíč.

  1. Vytvořte název hello-world-ingress.yaml souboru s následujícím obsahem.

    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
    
  2. Poznamenejte si tls část odkazující na tajný kód vytvořený dříve a použijte soubor v clusteru kubectl apply pomocí příkazu.

    kubectl apply -f hello-world-ingress.yaml -n $NAMESPACE
    

Získání externí IP adresy kontroleru příchozího přenosu dat

  • Pomocí příkazu získejte externí IP adresu kontroleru příchozího kubectl get service přenosu dat.

    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
    

Testování příchozího přenosu dat zabezpečeného protokolem TLS

  1. Pomocí následujícího curl příkazu ověřte, že je příchozí přenos dat správně nakonfigurovaný s protokolem TLS. Ujistěte se, že používáte externí IP adresu z předchozího kroku.

    curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com
    

    Vzhledem k tomu, že jiná cesta nebyla s adresou zadanou, kontroler příchozího přenosu dat se ve výchozím nastavení nastaví na trasu / . Vrátí se první ukázková aplikace, jak je znázorněno v následujícím zhuštěném ukázkovém výstupu:

    [...]
    <!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>
    [...]
    

    Parametr -v curl příkazu vypíše podrobné informace, včetně přijatého certifikátu TLS. V polovině výstupu curl můžete ověřit použití vlastního certifikátu TLS. Parametr -k pokračuje v načítání stránky, i když používáme certifikát podepsaný svým držitelem. Následující příklad ukazuje vystavitele: CN=demo.azure.com; Byl použit certifikát O=aks-ingress-tls :

    [...]
     * 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.
    [...]
    
  2. Přidejte /hello-world-two cestu k adrese, například https://demo.azure.com/hello-world-twoa ověřte, že druhá ukázková aplikace je správně nakonfigurovaná.

    curl -v -k --resolve demo.azure.com:443:EXTERNAL_IP https://demo.azure.com/hello-world-two
    

    Vrátí se druhá ukázková aplikace s vlastním názvem, jak je znázorněno v následujícím zhuštěném příkladu výstupu:

    [...]
    <!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>
    [...]