TLS ile NGINX Giriş Denetleyicisi'ni etkinleştirmek için Gizli Dizi Deposu CSI Sürücüsünü ayarlama

Bu makalede, Azure Kubernetes Service (AKS) kümesi ve Azure Key Vault (AKV) örneği ile TLS ile NGINX Giriş Denetleyicisinin güvenliğini sağlama işlemi adım adım açıklanmaktadır. Daha fazla bilgi için bkz . Kubernetes'te TLS.

Aşağıdaki yöntemlerden birini kullanarak giriş TLS sertifikasını kümeye aktarabilirsiniz:

  • Uygulama: Uygulama dağıtım bildirimi sağlayıcı birimini bildirir ve bağlar. Yalnızca uygulamayı dağıttığınızda, kümede kullanıma sunulan sertifika olur. Uygulamayı kaldırdığınızda gizli dizi de kaldırılır. Bu senaryo, uygulamanın güvenlik altyapısından ve kümeyle tümleştirmeden sorumlu geliştirme ekiplerine uygundur.
  • Giriş Denetleyicisi: Giriş dağıtımı, sağlayıcı birimini bildirmek ve bağlamak için değiştirilir. Giriş podları oluşturulduğunda gizli dizi içeri aktarılır. Uygulamanın podlarının TLS sertifikasına erişimi yoktur. Bu senaryo, bir ekibin (örneğin BT) altyapı ve ağ bileşenlerini (HTTPS TLS sertifikaları dahil) yönettiği ve oluşturduğu ve diğer ekiplerin uygulama yaşam döngüsünü yönettiği senaryolara uyar.

Ön koşullar

TLS sertifikası oluşturma

  • Aşağıdaki komutu kullanarak bir TLS sertifikası oluşturun.

    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"
    

Sertifikayı AKV'ye aktarma

  1. Aşağıdaki komutu kullanarak sertifikayı bir PFX dosyasına aktarın.

    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. komutunu kullanarak sertifikayı içeri aktarın az keyvault certificate import .

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

SecretProviderClass dağıtma

  1. Aşağıdaki komutu kullanarak yeni bir ad alanını dışarı aktarın.

    export NAMESPACE=ingress-basic
    
  2. komutunu kullanarak ad alanını kubectl create namespace oluşturun.

    kubectl create namespace $NAMESPACE
    
  3. Erişim kimliği sağlamak için bir yöntem seçin ve SecretProviderClass YAML'nizi uygun şekilde yapılandırın.

    • Özel anahtarı ve sertifikayı AKV'den almanın tek yolu olan komutunu kullandığınızdan objectType=secretemin olun.
    • bölümünüzde typesecretObjects olarak ayarlayınkubernetes.io/tls.

    SecretProviderClass örneğinizin nasıl görünebileceğine ilişkin aşağıdaki örneğe bakın:

    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. Komutunu kullanarak SecretProviderClass'ı kubectl apply Kubernetes kümenize uygulayın.

    kubectl apply -f secretProviderClass.yaml -n $NAMESPACE
    

Giriş denetleyicisini dağıtma

Resmi giriş grafiği deposunu ekleme

  • Aşağıdaki helm komutları kullanarak resmi giriş grafiği deposunu ekleyin.

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

NGINX girişini yapılandırma ve dağıtma

Senaryonuza bağlı olarak, sertifikayı uygulamaya veya giriş denetleyicisine bağlamayı seçebilirsiniz. Seçiminize göre aşağıdaki yönergeleri izleyin:

Sertifikayı uygulamaya bağlama

  • komutunu kullanarak sertifikayı uygulamaya bağlayın helm install . Uygulamanın dağıtımı, Gizli Dizi Deposu CSI Sürücüsünün Azure Key Vault sağlayıcısına başvurur.

    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
    

Sertifikayı giriş denetleyicisine bağlama

  1. komutunu kullanarak sertifikayı giriş denetleyicisine bağlayın helm install . Giriş denetleyicisinin dağıtımı, Gizli Dizi Deposu CSI Sürücüsünün Azure Key Vault sağlayıcısına başvurur.

    Dekont

    • Erişim yönteminiz olarak Microsoft Entra pod yönetilen kimliği kullanmıyorsanız ile --set controller.podLabels.aadpodidbinding=$AAD_POD_IDENTITY_NAME satırını kaldırın.

    • Ayrıca Gizli Dizi Deposu CSI Sürücüsünün bunu bağlaması ve Kubernetes gizli dizisini oluşturması için SecretProviderClass'ı bir pod'a bağlamanız gerekir. Bkz. Kubernetes gizli dizisiyle bağlı içeriği eşitleme.

    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. Komutunu kullanarak Kubernetes gizli dizisinin oluşturulduğunu kubectl get secret doğrulayın.

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

Uygulamayı dağıtma

Yine yönergeler senaryonuza bağlı olarak biraz değişir. Seçtiğiniz senaryoya karşılık gelen yönergeleri izleyin.

Uygulama başvurusu kullanarak uygulamayı dağıtma

  1. Aşağıdaki içeriğe sahip adlı aks-helloworld-one.yaml bir dosya oluşturun.

    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. Aşağıdaki içeriğe sahip adlı aks-helloworld-two.yaml bir dosya oluşturun.

    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. komutunu kullanarak kubectl apply YAML dosyalarını kümenize uygulayın.

    kubectl apply -f aks-helloworld-one.yaml -n $NAMESPACE
    kubectl apply -f aks-helloworld-two.yaml -n $NAMESPACE
    
  4. Komutunu kullanarak Kubernetes gizli dizisinin oluşturulduğunu kubectl get secret doğrulayın.

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

Giriş denetleyicisi başvurusu kullanarak uygulamayı dağıtma

  1. Aşağıdaki içeriğe sahip adlı aks-helloworld-one.yaml bir dosya oluşturun.

    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. Aşağıdaki içeriğe sahip adlı aks-helloworld-two.yaml bir dosya oluşturun.

    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. komutunu kullanarak kubectl apply YAML dosyalarını kümenize uygulayın.

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

Gizli diziye başvuran bir giriş kaynağı dağıtma

Artık gizli diziye başvuran bir Kubernetes giriş kaynağı dağıtabiliriz.

  1. Aşağıdaki içeriğe sahip bir dosya adı hello-world-ingress.yaml oluşturun.

    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. Daha önce oluşturulan gizli diziye başvuran bölümü not tls alın ve komutunu kullanarak kubectl apply dosyayı kümenize uygulayın.

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

Giriş denetleyicisinin dış IP adresini alma

  • komutunu kullanarak kubectl get service giriş denetleyicisinin dış IP adresini alın.

    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
    

TlS ile güvenliği sağlanan test girişi

  1. Aşağıdaki curl komutu kullanarak girişinizin TLS ile düzgün yapılandırıldığını doğrulayın. Önceki adımdaki dış IP'yi kullandığınızdan emin olun.

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

    Adresle birlikte başka bir yol sağlanmadığından, giriş denetleyicisi varsayılan olarak yolu kullanır / . Aşağıdaki daraltılmış örnek çıktıda gösterildiği gibi ilk tanıtım uygulaması döndürülür:

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

    Komuttaki curl -v parametresi, alınan TLS sertifikası da dahil olmak üzere ayrıntılı bilgiler döndürür. Curl çıkışınızın ortasında kendi TLS sertifikanızın kullanıldığını doğrulayabilirsiniz. - k parametresi, otomatik olarak imzalanan bir sertifika kullansak bile sayfayı yüklemeye devam eder. Aşağıdaki örnekte veren gösterilir: CN=demo.azure.com; O=aks-ingress-tls sertifikası kullanıldı:

    [...]
     * 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. Adresine /hello-world-two yolunu ekleyin( gibihttps://demo.azure.com/hello-world-two) ve ikinci tanıtım uygulamasının düzgün yapılandırıldığını doğrulayın.

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

    Aşağıdaki daraltılmış örnek çıktıda gösterildiği gibi, özel başlığa sahip ikinci tanıtım uygulaması döndürülür:

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