Baca dalam bahasa Inggris

Bagikan melalui


Gateway ingress aman untuk add-on mesh layanan Istio untuk Azure Kubernetes Service

Artikel Sebarkan Istio Ingress eksternal atau internal menjelaskan cara mengonfigurasi gateway ingress untuk mengekspos layanan HTTP ke lalu lintas eksternal/internal. Artikel ini menunjukkan cara mengekspos layanan HTTPS yang aman menggunakan TLS sederhana atau bersama.

Prasyarat

Catatan

Artikel ini mengacu pada gateway ingress eksternal untuk demonstrasi, langkah yang sama akan berlaku untuk mengonfigurasi TLS bersama untuk gateway masuk internal.

Sertifikat dan kunci klien/server yang diperlukan

Artikel ini memerlukan beberapa sertifikat dan kunci. Anda dapat menggunakan alat favorit Anda untuk membuatnya atau Anda dapat menggunakan perintah openssl berikut.

  1. Buat sertifikat akar dan kunci privat untuk menandatangani sertifikat untuk layanan sampel:

    mkdir bookinfo_certs
    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=bookinfo Inc./CN=bookinfo.com' -keyout bookinfo_certs/bookinfo.com.key -out bookinfo_certs/bookinfo.com.crt
    
  2. Buat sertifikat dan kunci privat untuk productpage.bookinfo.com:

    openssl req -out bookinfo_certs/productpage.bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo_certs/productpage.bookinfo.com.key -subj "/CN=productpage.bookinfo.com/O=product organization"
    openssl x509 -req -sha256 -days 365 -CA bookinfo_certs/bookinfo.com.crt -CAkey bookinfo_certs/bookinfo.com.key -set_serial 0 -in bookinfo_certs/productpage.bookinfo.com.csr -out bookinfo_certs/productpage.bookinfo.com.crt
    
  3. Buat sertifikat klien dan kunci privat:

    openssl req -out bookinfo_certs/client.bookinfo.com.csr -newkey rsa:2048 -nodes -keyout bookinfo_certs/client.bookinfo.com.key -subj "/CN=client.bookinfo.com/O=client organization"
    openssl x509 -req -sha256 -days 365 -CA bookinfo_certs/bookinfo.com.crt -CAkey bookinfo_certs/bookinfo.com.key -set_serial 1 -in bookinfo_certs/client.bookinfo.com.csr -out bookinfo_certs/client.bookinfo.com.crt
    

Mengonfigurasi gateway masuk TLS

Buat rahasia TLS Kubernetes untuk gateway ingress; gunakan Azure Key Vault untuk menghosting sertifikat/kunci dan add-on Penyedia Rahasia Azure Key Vault untuk menyinkronkan rahasia ke kluster.

Menyiapkan Azure Key Vault dan menyinkronkan rahasia ke kluster

  1. Buat Azure Key Vault

    Anda memerlukan sumber daya Azure Key Vault untuk menyediakan sertifikat dan input kunci ke add-on Istio.

    export AKV_NAME=<azure-key-vault-resource-name>  
    az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
    
  2. Aktifkan penyedia Azure Key Vault untuk add-on Driver Secret Store CSI di kluster Anda.

    az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
    
  3. Otorisasi identitas terkelola add-on yang ditetapkan pengguna untuk mengakses sumber daya Azure Key Vault menggunakan kebijakan akses. Atau, jika Key Vault Anda menggunakan Azure RBAC untuk model izin, ikuti instruksi di sini untuk menetapkan peran Azure Key Vault untuk identitas terkelola add-on yang ditetapkan pengguna.

    OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r')
    CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId')
    TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $AKV_NAME --query 'properties.tenantId')
    
    az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list
    
  4. Buat rahasia di Azure Key Vault menggunakan sertifikat dan kunci.

    az keyvault secret set --vault-name $AKV_NAME --name test-productpage-bookinfo-key --file bookinfo_certs/productpage.bookinfo.com.key
    az keyvault secret set --vault-name $AKV_NAME --name test-productpage-bookinfo-crt --file bookinfo_certs/productpage.bookinfo.com.crt
    az keyvault secret set --vault-name $AKV_NAME --name test-bookinfo-crt --file bookinfo_certs/bookinfo.com.crt
    
  5. Gunakan manifes berikut untuk menyebarkan SecretProviderClass untuk menyediakan parameter khusus Azure Key Vault ke driver CSI.

    cat <<EOF | kubectl apply -f -
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: productpage-credential-spc
      namespace: aks-istio-ingress
    spec:
      provider: azure
      secretObjects:
      - secretName: productpage-credential
        type: tls
        data:
        - objectName: test-productpage-bookinfo-key
          key: key
        - objectName: test-productpage-bookinfo-crt
          key: cert
      parameters:
        useVMManagedIdentity: "true"
        userAssignedIdentityID: $CLIENT_ID 
        keyvaultName: $AKV_NAME
        cloudName: ""
        objects:  |
          array:
            - |
              objectName: test-productpage-bookinfo-key
              objectType: secret
              objectAlias: "test-productpage-bookinfo-key"
            - |
              objectName: test-productpage-bookinfo-crt
              objectType: secret
              objectAlias: "test-productpage-bookinfo-crt"
        tenantId: $TENANT_ID
    EOF
    
  6. Gunakan manifes berikut untuk menyebarkan pod sampel. Driver CSI penyimpanan rahasia memerlukan pod untuk mereferensikan sumber daya SecretProviderClass untuk memastikan sinkronisasi rahasia dari Azure Key Vault ke kluster.

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: secrets-store-sync-productpage
      namespace: aks-istio-ingress
    spec:
      containers:
        - name: busybox
          image: mcr.microsoft.com/oss/busybox/busybox:1.33.1
          command:
            - "/bin/sleep"
            - "10"
          volumeMounts:
          - name: secrets-store01-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store01-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "productpage-credential-spc"
    EOF
    
    • Verifikasi productpage-credential rahasia yang dibuat pada namespace aks-istio-ingress kluster seperti yang didefinisikan dalam sumber daya SecretProviderClass.

      kubectl describe secret/productpage-credential -n aks-istio-ingress
      

      Contoh output:

      Name:         productpage-credential
      Namespace:    aks-istio-ingress
      Labels:       secrets-store.csi.k8s.io/managed=true
      Annotations:  <none>
      
      Type:  tls
      
      Data
      ====
      cert:  1066 bytes
      key:   1704 bytes
      

Mengonfigurasi gateway ingress dan layanan virtual

Rutekan lalu lintas HTTPS melalui gateway masuk Istio ke aplikasi sampel. Gunakan manifes berikut untuk menyebarkan gateway dan sumber daya layanan virtual.

cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: aks-istio-ingressgateway-external
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: productpage-credential
    hosts:
    - productpage.bookinfo.com
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productpage-vs
spec:
  hosts:
  - productpage.bookinfo.com
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        port:
          number: 9080
        host: productpage
EOF

Catatan

Dalam definisi gateway, credentialName harus cocok dengan secretName dalam sumber daya SecretProviderClass dan selector harus merujuk ke gateway ingress eksternal dengan labelnya, di mana kunci label adalah istio dan nilainya adalah aks-istio-ingressgateway-external. Untuk label gateway ingress internal adalah istio dan nilainya adalah aks-istio-ingressgateway-internal.

Atur variabel lingkungan untuk host dan port ingress eksternal:

export INGRESS_HOST_EXTERNAL=$(kubectl -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export SECURE_INGRESS_PORT_EXTERNAL=$(kubectl -n aks-istio-ingress get service aks-istio-ingressgateway-external -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
export SECURE_GATEWAY_URL_EXTERNAL=$INGRESS_HOST_EXTERNAL:$SECURE_INGRESS_PORT_EXTERNAL

echo "https://$SECURE_GATEWAY_URL_EXTERNAL/productpage"

Verifikasi

Kirim permintaan HTTPS untuk mengakses layanan halaman produk melalui HTTPS:

curl -s -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" | grep -o "<title>.*</title>"

Konfirmasikan bahwa halaman produk aplikasi sampel dapat diakses. Output yang diharapkan adalah:

<title>Simple Bookstore App</title>

Catatan

Untuk mengonfigurasi akses masuk HTTPS ke layanan HTTPS, yaitu, konfigurasikan gateway ingress untuk melakukan passthrough SNI alih-alih penghentian TLS pada permintaan masuk, perbarui mode tls dalam definisi gateway ke PASSTHROUGH. Ini menginstruksikan gateway untuk melewati lalu lintas masuk "apa adanya", tanpa mengakhiri TLS.

Mengonfigurasi gateway masuk TLS bersama

Perluas definisi gateway Anda untuk mendukung TLS bersama.

  1. Perbarui kredensial gateway masuk dengan menghapus rahasia saat ini dan membuat yang baru. Server menggunakan sertifikat CA untuk memverifikasi kliennya, dan kita harus menggunakan ca.crt kunci untuk memegang sertifikat CA.

    kubectl delete secretproviderclass productpage-credential-spc -n aks-istio-ingress
    kubectl delete secret/productpage-credential -n aks-istio-ingress
    kubectl delete pod/secrets-store-sync-productpage -n aks-istio-ingress
    

    Gunakan manifes berikut untuk membuat ulang SecretProviderClass dengan sertifikat CA.

    cat <<EOF | kubectl apply -f -
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: productpage-credential-spc
      namespace: aks-istio-ingress
    spec:
      provider: azure
      secretObjects:
      - secretName: productpage-credential
        type: opaque
        data:
        - objectName: test-productpage-bookinfo-key
          key: tls.key
        - objectName: test-productpage-bookinfo-crt
          key: tls.crt
        - objectName: test-bookinfo-crt
          key: ca.crt
      parameters:
        useVMManagedIdentity: "true"
        userAssignedIdentityID: $CLIENT_ID 
        keyvaultName: $AKV_NAME
        cloudName: ""
        objects:  |
          array:
            - |
              objectName: test-productpage-bookinfo-key
              objectType: secret
              objectAlias: "test-productpage-bookinfo-key"
            - |
              objectName: test-productpage-bookinfo-crt
              objectType: secret
              objectAlias: "test-productpage-bookinfo-crt"
            - |
              objectName: test-bookinfo-crt
              objectType: secret
              objectAlias: "test-bookinfo-crt"
        tenantId: $TENANT_ID
    EOF
    

    Gunakan manifes berikut untuk menyebarkan ulang pod sampel untuk menyinkronkan rahasia dari Azure Key Vault ke kluster.

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: secrets-store-sync-productpage
      namespace: aks-istio-ingress
    spec:
      containers:
        - name: busybox
          image: registry.k8s.io/e2e-test-images/busybox:1.29-4
          command:
            - "/bin/sleep"
            - "10"
          volumeMounts:
          - name: secrets-store01-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store01-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "productpage-credential-spc"
    EOF
    
    • Verifikasi productpage-credential rahasia yang dibuat pada namespace aks-istio-ingresskluster .

      kubectl describe secret/productpage-credential -n aks-istio-ingress
      

      Contoh output:

      Name:         productpage-credential
      Namespace:    aks-istio-ingress
      Labels:       secrets-store.csi.k8s.io/managed=true
      Annotations:  <none>
      
      Type:  opaque
      
      Data
      ====
      ca.crt:   1188 bytes
      tls.crt:  1066 bytes
      tls.key:  1704 bytes
      
  2. Gunakan manifes berikut untuk memperbarui definisi gateway untuk mengatur mode TLS ke MUTUAL.

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: aks-istio-ingressgateway-external # use istio default ingress gateway
      servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        tls:
          mode: MUTUAL
          credentialName: productpage-credential # must be the same as secret
        hosts:
        - productpage.bookinfo.com
    EOF
    

Verifikasi

Coba kirim permintaan HTTPS menggunakan pendekatan sebelumnya - tanpa meneruskan sertifikat klien - dan melihatnya gagal.

curl -v -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" 

Contoh output:


...
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS alert, unknown (628):
* OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0
* Failed receiving HTTP2 data
* OpenSSL SSL_write: SSL_ERROR_ZERO_RETURN, errno 0
* Failed sending HTTP2 data
* Connection #0 to host productpage.bookinfo.com left intact
curl: (56) OpenSSL SSL_read: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0

Teruskan sertifikat klien Anda dengan --cert bendera dan kunci privat dengan --key bendera untuk melengkung.

curl -s -HHost:productpage.bookinfo.com --resolve "productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL:$INGRESS_HOST_EXTERNAL" --cacert bookinfo_certs/bookinfo.com.crt --cert bookinfo_certs/client.bookinfo.com.crt --key bookinfo_certs/client.bookinfo.com.key "https://productpage.bookinfo.com:$SECURE_INGRESS_PORT_EXTERNAL/productpage" | grep -o "<title>.*</title>"

Konfirmasikan bahwa halaman produk aplikasi sampel dapat diakses. Output yang diharapkan adalah:

<title>Simple Bookstore App</title>

Menghapus sumber daya

Jika Anda ingin membersihkan jala layanan Istio dan ingress (meninggalkan kluster), jalankan perintah berikut:

az aks mesh disable --resource-group ${RESOURCE_GROUP} --name ${CLUSTER}

Jika Anda ingin membersihkan semua sumber daya yang dibuat dari dokumen panduan Istio, jalankan perintah berikut:

az group delete --name ${RESOURCE_GROUP} --yes --no-wait