Aracılığıyla paylaş


Azure Kubernetes Service için Istio hizmet ağı eklentisi için güvenli giriş ağ geçidi

Dış veya iç Istio Giriş dağıtma makalesinde, http hizmetini dış/iç trafiğe açık olacak şekilde giriş ağ geçidinin nasıl yapılandırılacağı açıklanır. Bu makalede, basit veya karşılıklı TLS kullanarak güvenli bir HTTPS hizmetini kullanıma sunma işlemi gösterilmektedir.

Önkoşullar

Not

Bu makale, tanıtım için dış giriş ağ geçidini ifade eder; iç giriş ağ geçidi için karşılıklı TLS'yi yapılandırmak için de aynı adımlar geçerli olacaktır.

Gerekli istemci/sunucu sertifikaları ve anahtarları

Bu makale çeşitli sertifikalar ve anahtarlar gerektirir. Sık kullandığınız aracı kullanarak oluşturabilir veya aşağıdaki openssl komutlarını kullanabilirsiniz.

  1. Örnek hizmetler için sertifikaları imzalamak için bir kök sertifika ve özel anahtar oluşturun:

    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. için productpage.bookinfo.combir sertifika ve özel anahtar oluşturun:

    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. İstemci sertifikası ve özel anahtar oluşturma:

    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
    

TLS giriş ağ geçidi yapılandırma

Giriş ağ geçidi için bir Kubernetes TLS gizli dizisi oluşturun; sertifikaları/anahtarları barındırmak için Azure Key Vault'u ve gizli dizileri kümeyle eşitlemek için Azure Key Vault Gizli Dizi Sağlayıcısı eklentisini kullanın.

Azure Key Vault'un ayarlanması ve gizli dizilerin kümeyle eşitlenmesi

  1. Azure Key Vault oluşturma

    Istio eklentisine sertifika ve anahtar girişleri sağlamak için bir Azure Key Vault kaynağına ihtiyacınız vardır.

    export AKV_NAME=<azure-key-vault-resource-name>  
    az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
    
  2. Kümenizde Gizli Depolama CSI Sürücüsü eklentisi için Azure Key Vault sağlayıcısını etkinleştirin.

    az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
    
  3. Erişim ilkesini kullanarak Azure Key Vault kaynağına erişmek için eklentinin kullanıcı tarafından atanan yönetilen kimliğini yetkileyin. Alternatif olarak, Key Vault'unuz izin modeli için Azure RBAC kullanıyorsa, eklentinin kullanıcı tarafından atanan yönetilen kimliği için Key Vault'un Azure rolünü atamak için buradaki yönergeleri izleyin.

    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. Sertifikaları ve anahtarları kullanarak Azure Key Vault'ta gizli diziler oluşturun.

    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. CSI sürücüsüne Azure Key Vault'a özgü parametreler sağlamak üzere SecretProviderClass'ı dağıtmak için aşağıdaki bildirimi kullanın.

    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. Örnek pod dağıtmak için aşağıdaki bildirimi kullanın. Gizli dizi deposu CSI sürücüsü, gizli dizilerin Azure Key Vault'tan kümeye eşitlenmesini sağlamak için SecretProviderClass kaynağına başvurmak için bir pod gerektirir.

    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
    
    • SecretProviderClass kaynağında tanımlandığı gibi küme ad alanında aks-istio-ingress oluşturulan gizli diziyi doğrulayınproductpage-credential.

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

      Örnek çıkış:

      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
      

Giriş ağ geçidini ve sanal hizmeti yapılandırma

Istio giriş ağ geçidi aracılığıyla HTTPS trafiğini örnek uygulamalara yönlendirin. Ağ geçidi ve sanal hizmet kaynaklarını dağıtmak için aşağıdaki bildirimi kullanın.

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

Not

Ağ geçidi tanımında SecretProviderClass kaynağıyla eşleşmeli ve selector dış giriş ağ geçidine etiketiyle başvurmalıdır; burada etiketin anahtarı ve değeri olmalıdır istio aks-istio-ingressgateway-external.secretName credentialName İç giriş ağ geçidi etiketi için istio ve değeri şeklindedir aks-istio-ingressgateway-internal.

Dış giriş konağı ve bağlantı noktaları için ortam değişkenlerini ayarlayın:

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"

Doğrulama

HTTPS aracılığıyla ürün sayfası hizmetine erişmek için bir HTTPS isteği gönderin:

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>"

Örnek uygulamanın ürün sayfasının erişilebilir olduğunu onaylayın. Beklenen çıkış:

<title>Simple Bookstore App</title>

Not

BIR HTTPS hizmetine HTTPS giriş erişimini yapılandırmak için, gelen isteklerde TLS sonlandırması yerine bir giriş ağ geçidini SNI geçişi gerçekleştirecek şekilde yapılandırın, ağ geçidi tanımındaki tls modunu olarak PASSTHROUGHgüncelleştirin. Bu, ağ geçidine TLS'yi sonlandırmadan giriş trafiğini "olduğu gibi" geçirmesini bildirir.

Karşılıklı TLS giriş ağ geçidi yapılandırma

Ağ geçidi tanımınızı karşılıklı TLS'yi destekleyecek şekilde genişletin.

  1. Geçerli gizli diziyi silip yeni bir tane oluşturarak giriş ağ geçidi kimlik bilgilerini güncelleştirin. Sunucu istemcilerini doğrulamak için CA sertifikasını kullanır ve CA sertifikasını tutmak için ca.crt anahtarını kullanmamız gerekir.

    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
    

    CA sertifikasıyla SecretProviderClass'ı yeniden oluşturmak için aşağıdaki bildirimi kullanın.

    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
    

    Azure Key Vault'tan kümeye gizli dizileri eşitlemek üzere örnek podu yeniden dağıtmak için aşağıdaki bildirimi kullanın.

    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
    
    • Küme ad alanında aks-istio-ingressoluşturulan gizli diziyi doğrulayınproductpage-credential.

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

      Örnek çıkış:

      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. TLS modunu MUTUAL olarak ayarlamak üzere ağ geçidi tanımını güncelleştirmek için aşağıdaki bildirimi kullanın.

    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
    

Doğrulama

İstemci sertifikasını geçirmeden önceki yaklaşımı kullanarak HTTPS isteği göndermeyi deneyin ve başarısız olduğunu görün.

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" 

Örnek çıkış:


...
* 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

İstemcinizin sertifikasını bayrağıyla --cert ve özel anahtarla birlikte curl bayrağıyla --key geçirin.

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>"

Örnek uygulamanın ürün sayfasının erişilebilir olduğunu onaylayın. Beklenen çıkış:

<title>Simple Bookstore App</title>

Kaynakları silme

Istio hizmet ağı ve girişlerini (kümenin arkasında bırakarak) temizlemek istiyorsanız aşağıdaki komutu çalıştırın:

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

Istio nasıl yapılır kılavuzu belgelerinden oluşturulan tüm kaynakları temizlemek istiyorsanız aşağıdaki komutu çalıştırın:

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