Casi d'uso di gestione del traffico per la rete di applicazioni di Azure Kubernetes (anteprima)

Importante

Le funzionalità di anteprima di AKS sono disponibili su base self-service, su scelta. Le anteprime vengono fornite "così come sono" e "come disponibili" e sono escluse dai contratti di servizio e dalla garanzia limitata. Le anteprime del servizio Azure Kubernetes sono parzialmente coperte dal supporto clienti con la massima diligenza possibile. Di conseguenza, queste funzionalità non sono destinate all'uso in produzione. Per altre informazioni, vedere gli articoli di supporto seguenti:

La gestione del traffico di rete dell'applicazione Azure Kubernetes usa la modalità ambiente Istio e l'API del gateway Kubernetes per consentire un controllo preciso sulle interazioni da servizio a servizio all'interno e tra cluster. Questa soluzione offre un set completo di funzionalità di gestione del traffico, tra cui:

  • Criteri di autorizzazione L4/L7
  • Routing basato su attestazioni JWT
  • Spostamento del traffico
  • Fault injection

Questo articolo fornisce istruzioni dettagliate su come implementare questi casi d'uso di gestione del traffico usando la rete di applicazioni di Azure Kubernetes in più cluster del servizio Azure Kubernetes.

Prerequisiti

Prima di iniziare, assicurarsi di disporre dei prerequisiti seguenti:

Controllare l'installazione di Istio e ztunnel

  1. Verificare i CRD di Istio usando il comando kubectl get crds.

    kubectl --context $CLUSTER_NAME_1 get crds | grep istio
    

    L'output dovrebbe mostrare i seguenti 14 CRD per la modalità ambient di Istio:

    authorizationpolicies.security.istio.io                            2026-03-12T18:02:11Z
    destinationrules.networking.istio.io                               2026-03-12T18:02:11Z
    envoyfilters.networking.istio.io                                   2026-03-12T18:02:11Z
    gateways.networking.istio.io                                       2026-03-12T18:02:11Z
    peerauthentications.security.istio.io                              2026-03-12T18:02:11Z
    proxyconfigs.networking.istio.io                                   2026-03-12T18:02:11Z
    requestauthentications.security.istio.io                           2026-03-12T18:02:11Z
    serviceentries.networking.istio.io                                 2026-03-12T18:02:11Z
    sidecars.networking.istio.io                                       2026-03-12T18:02:11Z
    telemetries.telemetry.istio.io                                     2026-03-12T18:02:11Z
    virtualservices.networking.istio.io                                2026-03-12T18:02:11Z
    wasmplugins.extensions.istio.io                                    2026-03-12T18:02:11Z
    workloadentries.networking.istio.io                                2026-03-12T18:02:11Z
    workloadgroups.networking.istio.io                                 2026-03-12T18:02:11Z
    
  2. Controllare che Istio CNI e ztunnel DaemonSet siano in esecuzione nel applink-system namespace utilizzando il comando kubectl get daemonset.

    kubectl --context $CLUSTER_NAME_1 --namespace applink-system get daemonset
    

    L'output dovrebbe mostrare i seguenti DaemonSet con tutti i pod nello stato di READY

    NAME             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
    istio-cni-node   3         3         3       3            3           kubernetes.io/os=linux   108m
    ztunnel          3         3         3       3            3           kubernetes.io/os=linux   107m
    

Creare un'applicazione di esempio

Architettura dell'applicazione

Questa architettura estende l'applicazione di esempio Bookinfo per funzionare su più cluster AKS.

Screenshot di un diagramma dell'architettura che mostra l'architettura dell'applicazione di esempio Bookinfo operante su due cluster AKS.

  • Cluster 1 ospita:
    • productpage-v1 (Python)
    • reviews-v1 (Java)
    • details-v1 (Ruby)
  • Cluster 2 hosts:
    • reviews-v2 (Java)
    • reviews-v3 (Java)
    • ratings-v1 (Node.js)

Il productpage servizio invia richieste a reviews.default.svc.cluster.local. Poiché il servizio reviews è disponibile in entrambi i cluster AKS con un ambito di servizio globale, le richieste possono essere instradate a qualsiasi back-end disponibile (reviews-v1, reviews-v2 o reviews-v3) attraverso i cluster. I servizi reviews-v2 e reviews-v3 chiamano anche il servizio ratings per recuperare i dati di valutazione prima di restituire la risposta a productpage.

Questa architettura illustra come un'applicazione distribuita può estendersi su più cluster, continuando a usare un modello di comunicazione e un nome di servizio coerenti, consentendo un'interazione senza interruzioni del servizio tra i limiti del cluster.

Distribuire i servizi dell'applicazione

  1. Distribuire i servizi productpage nel cluster AKS 1 usando i seguenti comandi kubectl apply.

    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l app=productpage
    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l account=productpage
    
  2. Distribuire i servizi reviews-v1 nel cluster 1 di Azure Kubernetes Service usando i seguenti comandi kubectl apply.

    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,service=reviews
    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews
    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v1
    
  3. Distribuire i servizi details nel cluster AKS 1 utilizzando i seguenti comandi kubectl apply:

    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l app=details
    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l account=details
    
  4. Distribuire il servizio curl nel cluster AKS 1 usando il comando seguente kubectl apply :

    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/curl/curl.yaml
    
  5. Distribuire reviews-v2 e i servizi reviews-v3 nel cluster AKS 2 utilizzando i seguenti comandi kubectl apply:

    kubectl --context $CLUSTER_NAME_2 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,service=reviews
    kubectl --context $CLUSTER_NAME_2 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews
    kubectl --context $CLUSTER_NAME_2 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l 'app=reviews,version in (v2,v3)'
    
  6. Distribuire i servizi ratings nel cluster AKS 2 utilizzando i seguenti comandi kubectl apply:

    kubectl --context $CLUSTER_NAME_2 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l app=ratings
    kubectl --context $CLUSTER_NAME_2 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/platform/kube/bookinfo.yaml -l account=ratings
    

Distribuire il gateway di ingresso

  1. Distribuire il gateway d'ingresso nel cluster AKS 1 utilizzando il seguente comando kubectl apply:

    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/bookinfo/gateway-api/bookinfo-gateway.yaml
    
  2. Verificare che il gateway sia programmato usando il comando seguente kubectl get gateway :

    kubectl --context $CLUSTER_NAME_1 --namespace default get gateway
    

    Dopo circa un minuto, verrà visualizzato un output simile al seguente, con la PROGRAMMED visualizzazione come True:

    NAME               CLASS   ADDRESS        PROGRAMMED   AGE
    bookinfo-gateway   istio   20.112.40.27   True         21s
    

Aggiungere l'applicazione al mesh

  • Aggiungere l'applicazione alla mesh etichettando lo spazio dei nomi default in entrambi i cluster del servizio Azure Kubernetes con istio.io/dataplane-mode=ambient:

    kubectl --context $CLUSTER_NAME_1 label namespace default istio.io/dataplane-mode=ambient
    kubectl --context $CLUSTER_NAME_2 label namespace default istio.io/dataplane-mode=ambient
    

Installare waypoint e contrassegnare i servizi come globali

  1. Installare i gateway waypoint in entrambi i cluster usando i comandi istioctl waypoint apply seguenti:

    istioctl --context $CLUSTER_NAME_1 waypoint apply --enroll-namespace --wait
    istioctl --context $CLUSTER_NAME_2 waypoint apply --enroll-namespace --wait
    

    L'output dovrebbe essere simile al seguente, indicando che waypoint è stato applicato e che lo spazio dei nomi default sia stato etichettato correttamente nei cluster.

    ✅ waypoint default/waypoint applied
    ✅ namespace default labeled with "istio.io/use-waypoint: waypoint"
    ✅ waypoint default/waypoint applied
    ✅ namespace default labeled with "istio.io/use-waypoint: waypoint"
    
  2. Verificare che i waypoint gateway siano programmati usando il comando seguente kubectl get gateway waypoint in entrambi i cluster:

    kubectl --context $CLUSTER_NAME_1 get gateway waypoint
    kubectl --context $CLUSTER_NAME_2 get gateway waypoint
    

    Dopo circa un minuto, l'output dovrebbe essere simile al seguente in entrambi i cluster, con PROGRAMMED visibile come True.

    NAME       CLASS            ADDRESS       PROGRAMMED   AGE
    waypoint   istio-waypoint   10.1.78.229   True         28s
    
  3. Contrassegnare il reviews-v1 servizio nel cluster del servizio Azure Kubernetes 1 e reviews-v2reviews-v3 i servizi nel cluster del servizio Azure Kubernetes 2 come servizi globali etichettandoli con istio.io/global="true":

    kubectl --context $CLUSTER_NAME_1 label service reviews istio.io/global="true"
    kubectl --context $CLUSTER_NAME_2 label service reviews istio.io/global="true"
    
  4. Contrassegnare i waypoint servizi come servizi globali etichettandoli con istio.io/global="true" in entrambi i cluster:

    kubectl --context $CLUSTER_NAME_1 label service waypoint istio.io/global="true"
    kubectl --context $CLUSTER_NAME_2 label service waypoint istio.io/global="true"
    
  5. Verificare i servizi globali nelle configurazioni di ztunnel in entrambi i cluster usando il istioctl zc service comando. I servizi reviews e waypoint devono essere visualizzati da entrambi i cluster con i rispettivi indirizzi VIP nella colonna SERVICE VIP.

    istioctl --context "$CLUSTER_NAME_1" zc service -n applink-system | awk 'NR==1 || $2=="reviews" || $2=="waypoint"'
    istioctl --context "$CLUSTER_NAME_2" zc service -n applink-system | awk 'NR==1 || $2=="reviews" || $2=="waypoint"'
    

    L'output dovrebbe essere simile al seguente in entrambi i cluster, a indicare che i servizi reviews e waypoint vengono riconosciuti come servizi globali con i loro VIP.

    # Output from cluster 1
    NAMESPACE         SERVICE NAME                 SERVICE VIP              WAYPOINT ENDPOINTS
    default           reviews                      10.1.36.199,10.1.164.195 waypoint 2/2
    default           waypoint                     10.1.78.229,10.1.135.117 None     2/2
    
    # Output from cluster 2
    NAMESPACE         SERVICE NAME                 SERVICE VIP              WAYPOINT ENDPOINTS
    default           reviews                      10.1.36.199,10.1.164.195 waypoint 3/3
    default           waypoint                     10.1.78.229,10.1.135.117 None     2/2
    

Verificare l'accesso alle applicazioni

Annotazioni

Se non è possibile accedere all'applicazione da Internet, assicurarsi che il gruppo di sicurezza di rete (NSG) associato al cluster consenta il traffico Internet in ingresso sulla porta 80 TCP al gateway di ingresso.

  • Accedere all'applicazione tramite il gateway di ingresso usando i comandi seguenti:

    export BOOK_INFO_GTW_IP=$(kubectl --context $CLUSTER_NAME_1 -n default get gateway bookinfo-gateway -o jsonpath="{.status.addresses[0].value}")
    echo $BOOK_INFO_GTW_IP
    curl -I http://$BOOK_INFO_GTW_IP/productpage
    

    L'output dovrebbe essere simile al seguente, a indicare che l'applicazione è accessibile tramite il gateway:

    20.112.40.27
    HTTP/1.1 200 OK
    server: istio-envoy
    date: Fri, 13 Mar 2026 17:52:13 GMT
    content-type: text/html; charset=utf-8
    content-length: 15070
    vary: Cookie
    x-envoy-upstream-service-time: 571
    

Distribuire le politiche di autorizzazione L4/L7

Applicare i criteri di autorizzazione L4

  1. Applicare un criterio di autorizzazione L4 per consentire il traffico al servizio productpage solo dal gateway di ingresso usando il seguente comando kubectl apply :

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: security.istio.io/v1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-ztunnel
      namespace: default
    spec:
      selector:
        matchLabels:
          app: productpage
      action: ALLOW
      rules:
      - from:
        - source:
            principals:
            - cluster.local/ns/default/sa/bookinfo-gateway-istio
    EOF
    
  2. Verificare che sia comunque possibile accedere all'applicazione tramite il gateway di ingresso usando il comando seguente:

    curl -I http://$BOOK_INFO_GTW_IP/productpage
    

    L'output dovrebbe essere simile al seguente, a indicare che l'applicazione è ancora accessibile tramite il gateway:

    HTTP/1.1 200 OK
    server: istio-envoy
    date: Fri, 13 Mar 2026 18:00:51 GMT
    content-type: text/html; charset=utf-8
    content-length: 15068
    vary: Cookie
    x-envoy-upstream-service-time: 19
    
  3. Verificare che l'accesso al productpage servizio sia bloccato da altre origini tentando di accedervi dal pod curl usando il comando seguente:

    kubectl --context $CLUSTER_NAME_1 exec deploy/curl -- curl -s "http://productpage:9080/productpage"
    

    L'output dovrebbe essere simile al seguente, a indicare che l'accesso viene negato a causa dei criteri di autorizzazione L4:

    upstream connect error or disconnect/reset before headers. reset reason: connection termination
    

Applicare i criteri di autorizzazione L7

  1. Applicare una politica di autorizzazione L7 per consentire solo le richieste GET al servizio productpage dall'account di servizio curl, usando il comando kubectl apply seguente:

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: security.istio.io/v1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-waypoint
      namespace: default
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: productpage
      action: ALLOW
      rules:
      - from:
        - source:
            principals:
            - cluster.local/ns/default/sa/curl
        to:
        - operation:
            methods: ["GET"]
    EOF
    
  2. Aggiornare i criteri di autorizzazione L4 per consentire il traffico dal waypoint a ztunnel aggiungendo l'account del servizio waypoint come entità autorizzata usando il comando seguente kubectl apply.

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: security.istio.io/v1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-ztunnel
      namespace: default
    spec:
      selector:
        matchLabels:
          app: productpage
      action: ALLOW
      rules:
      - from:
        - source:
            principals:
            - cluster.local/ns/default/sa/bookinfo-gateway-istio
            - cluster.local/ns/default/sa/waypoint
    EOF
    
  3. Verificare che le operazioni DELETE verso il servizio productpage siano bloccate dall'account del servizio curl usando il comando seguente kubectl exec.

    kubectl --context $CLUSTER_NAME_1 exec deploy/curl -- curl -s "http://productpage:9080/productpage" -X DELETE
    

    L'output dovrebbe essere simile al seguente, a indicare che l'accesso viene negato a causa dei criteri di autorizzazione L7:

    RBAC: access denied
    
  4. Verificare che gli account del servizio diversi da curl non accedano al productpage servizio usando il comando seguente kubectl exec :

    kubectl --context $CLUSTER_NAME_1 exec deploy/reviews-v1 -- curl -s http://productpage:9080/productpage
    

    L'output dovrebbe essere simile al seguente, a indicare che l'accesso viene negato a causa dei criteri di autorizzazione L7:

    RBAC: access denied
    
  5. Verificare che le richieste GET al servizio productpage siano consentite dall'account del servizio curl usando il seguente comando kubectl exec:

    kubectl --context $CLUSTER_NAME_1 exec deploy/curl -- curl -s http://productpage:9080/productpage | grep -o "<title>.*</title>"
    

    L'output dovrebbe essere simile al seguente, a indicare che le richieste GET sono consentite ed productpage è accessibile:

    <title>Simple Bookstore App</title>
    
  6. Verificare che productpage sia ancora accessibile tramite il gateway di ingresso usando il comando seguente:

    curl -I http://$BOOK_INFO_GTW_IP/productpage
    

    L'output dovrebbe essere simile al seguente, indicando che productpage è ancora accessibile tramite il gateway.

    HTTP/1.1 200 OK
    server: istio-envoy
    date: Fri, 13 Mar 2026 18:07:02 GMT
    content-type: text/html; charset=utf-8
    content-length: 15070
    vary: Cookie
    x-envoy-upstream-service-time: 45
    

Implementare il routing basato sulle attestazioni JWT

Creare un gateway in ingresso e proteggerlo con l'autenticazione JWT

  1. Creare un nuovo spazio dei nomi per il gateway di ingresso usando il comando kubectl create namespace.

    kubectl --context $CLUSTER_NAME_1 create namespace applink-ingress
    
  2. Creare un ingress gateway usando la Kubernetes Gateway API e consentire solo le rotte dallo stesso namespace usando il comando che segue kubectl apply :

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: applink-ingressgateway
      namespace: applink-ingress
      labels:
        app: applink-ingressgateway
        istio: applink-ingressgateway
    spec:
      gatewayClassName: istio
      listeners:
      - name: http
        port: 80
        protocol: HTTP
        allowedRoutes:
          namespaces:
            from: Same
    EOF
    
  3. Verificare che il gateway sia programmato usando il comando seguente kubectl get gateway :

    kubectl --context $CLUSTER_NAME_1 -n applink-ingress get gateway
    

    Dopo circa un minuto, verrà visualizzato un output simile al seguente, con la PROGRAMMED visualizzazione come True:

    NAME                     CLASS   ADDRESS         PROGRAMMED   AGE
    applink-ingressgateway   istio   20.99.227.197   True         30s
    
  4. Ottenere l'URL dell'emettitore OIDC dal cluster AKS e impostarlo come variabile di ambiente.

    export OIDC_ISSUER_URL=$(az aks show --resource-group $AKS_RG --name $CLUSTER_NAME_1 --query "oidcIssuerProfile.issuerUrl" -o tsv)
    echo $OIDC_ISSUER_URL
    
  5. Applicare un criterio di RequestAuthentication per convalidare i token JWT emessi dall'emittente OIDC del cluster AKS e inoltrare il token originale al servizio reviews e un VirtualService per instradare il traffico al servizio reviews in base alla rivendicazione sub nel token JWT utilizzando il seguente comando kubectl apply:

    envsubst <<EOF | kubectl --context $CLUSTER_NAME_1 apply -f -
    apiVersion: security.istio.io/v1
    kind: RequestAuthentication
    metadata:
      name: bookinfo-ingress-jwt-istio
      namespace: applink-ingress
    spec:
      selector:
        matchLabels:
          app: applink-ingressgateway
      jwtRules:
      - issuer: "${OIDC_ISSUER_URL}"
        audiences:
        - "${OIDC_ISSUER_URL}"
        jwksUri: "${OIDC_ISSUER_URL}openid/v1/jwks"
        forwardOriginalToken: true
    ---
    apiVersion: networking.istio.io/v1
    kind: Gateway
    metadata:
      name: bookinfo-gateway-istio
      namespace: applink-ingress
    spec:
      selector:
        app: applink-ingressgateway
      servers:
        - hosts:
          - "*"
          port:
            name: http
            number: 80
            protocol: HTTP
    ---
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: bookinfo-vs-istio
      namespace: applink-ingress
    spec:
        hosts:
        - "*"
        gateways:
        - bookinfo-gateway-istio
        http:
        - name: reviews
          match:
          - uri:
              prefix: /
            headers:
              "@request.auth.claims.sub":
                exact: "system:serviceaccount:default:curl"
          route:
          - destination:
              host: reviews.default.svc.cluster.local
              port:
                number: 9080
    EOF
    
  6. Ottenere l'indirizzo IP del nuovo gateway di ingresso e impostarlo come variabile di ambiente.

    export NO_REV_GTW_IP=$(kubectl --context $CLUSTER_NAME_1 -n applink-ingress get gateway applink-ingressgateway -o jsonpath="{.status.addresses[0].value}") 
    echo $NO_REV_GTW_IP
    

Verificare l'autenticazione JWT e il routing basato sulle attestazioni

  1. Verificare che le richieste senza token JWT vengano rifiutate dal gateway usando il comando seguente kubectl exec :

    kubectl --context $CLUSTER_NAME_1 exec -it $(kubectl --context $CLUSTER_NAME_1 get pod -l app=curl -o jsonpath='{.items[0].metadata.name}') -- curl -v http://$NO_REV_GTW_IP/reviews/1
    

    L'output dovrebbe essere simile al seguente, a indicare che la richiesta viene rifiutata con un errore 404 Non trovato perché manca il token JWT:

    *   Trying 20.99.227.197:80...
    * Established connection to 20.99.227.197 (20.99.227.197 port 80) from 10.244.2.0 port 36736 
    * using HTTP/1.x
    > GET /reviews/1 HTTP/1.1
    > Host: 20.99.227.197
    > User-Agent: curl/8.16.0
    > Accept: */*
    > 
    * Request completely sent off
    < HTTP/1.1 404 Not Found
    < date: Fri, 13 Mar 2026 18:30:34 GMT
    < server: istio-envoy
    < content-length: 0
    < 
    * Connection #0 to host 20.99.227.197:80 left intact
    
  2. Verificare che le richieste con token JWT non valido vengano rifiutate dal gateway usando il comando seguente kubectl exec :

    kubectl --context $CLUSTER_NAME_1 exec -it $(kubectl --context $CLUSTER_NAME_1 get pod -l app=curl -o jsonpath='{.items[0].metadata.name}') -- curl -v -H "Authorization: Bearer 123.456.789" http://$NO_REV_GTW_IP/reviews/1
    

    L'output dovrebbe essere simile al seguente, a indicare che la richiesta viene rifiutata con un errore 401 Non autorizzato perché il token JWT non è valido:

    *   Trying 20.99.227.197:80...
    * Established connection to 20.99.227.197 (20.99.227.197 port 80) from 10.244.2.0 port 33240 
    * using HTTP/1.x
    > GET /reviews/1 HTTP/1.1
    > Host: 20.99.227.197
    > User-Agent: curl/8.16.0
    > Accept: */*
    > Authorization: Bearer 123.456.789
    > 
    * Request completely sent off
    < HTTP/1.1 401 Unauthorized
    < www-authenticate: Bearer realm="http://20.99.227.197/reviews/1", error="invalid_token"
    < content-length: 29
    < content-type: text/plain
    < date: Fri, 13 Mar 2026 18:31:40 GMT
    < server: istio-envoy
    < 
    * Connection #0 to host 20.99.227.197:80 left intact
    Jwt header is an invalid JSON
    
  3. Verificare che le richieste con token JWT valido siano consentite dal gateway e indirizzate al reviews servizio usando il comando seguente kubectl exec . Il token JWT viene ottenuto dal token dell'account del servizio montato nel pod curl, rilasciato dall'emittente OIDC del cluster del servizio Azure Kubernetes.

    kubectl --context $CLUSTER_NAME_1 exec -it $(kubectl --context $CLUSTER_NAME1 get pod -l app=curl -o jsonpath='{.items[0].metadata.name}') -- sh -c "export NO_REV_GTW_IP=$NO_REV_GTW_IP; exec sh"
    
  4. Eseguire il comando seguente nella shell interattiva per inviare una richiesta con il token JWT valido al gateway:

    curl -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" http://$NO_REV_GTW_IP/health; echo
    

    L'output dovrebbe essere simile al seguente, a indicare che la richiesta è consentita e che il reviews servizio è integro:

    {"status": "Reviews is healthy"}
    
  5. Eseguire il comando seguente nella shell interattiva per inviare una richiesta con il token JWT valido al gateway per accedere al reviews servizio. La richiesta deve essere consentita e indirizzata al reviews servizio perché l'attestazione sub nel token JWT corrisponde al valore specificato nella condizione di corrispondenza della route VirtualService.

    curl -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" http://$NO_REV_GTW_IP/reviews/1; echo
    

    L'output dovrebbe essere simile al seguente, a indicare che la richiesta è consentita e viene indirizzata al servizio reviews, restituendo la recensione del prodotto 1.

    {"id": "1","podname": "reviews-v1-12ab34c5de-fg6hi","clustername": "null","reviews": [{  "reviewer": "Reviewer1",  "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"},{  "reviewer": "Reviewer2",  "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}]}
    

Implementare lo spostamento del traffico tra cluster

Il shift del traffico tra cluster viene implementato utilizzando la seguente configurazione nei due cluster AKS.

  • Cluster AKS 1: i servizi reviews-local selezionano solo pod reviews-v1, e il servizio reviews-remote non seleziona intenzionalmente alcun pod locale.
  • Cluster AKS 2: il servizio reviews-local non seleziona intenzionalmente alcun pod locale e il servizio reviews-remote seleziona sia i pod reviews-v2 che i pod reviews-v3.

In questa sezione, i termini locali e remoti vengono definiti dal punto di vista del cluster AKS 1.

  1. Applicare le seguenti risorse di servizio nel cluster AKS 1 per configurare i servizi reviews-local e reviews-remote con i selettori appropriati utilizzando il comando kubectl apply.

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-local
      namespace: default
      labels:
        app: reviews
        service: reviews-local
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
        version: v1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-remote
      namespace: default
      labels:
        app: reviews
        service: reviews-remote
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
        version: remote
    EOF
    
  2. Applicare le seguenti risorse di servizio nel cluster AKS 2 per configurare i servizi reviews-local e reviews-remote con i selettori appropriati usando il comando kubectl apply :

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-local
      namespace: default
      labels:
        app: reviews
        service: reviews-local
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
        version: local
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-remote
      namespace: default
      labels:
        app: reviews
        service: reviews-remote
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
    EOF
    
  3. Suddividere il traffico per il reviews servizio 20/80 tra i cluster locali e remoti usando il comando seguente kubectl apply :

    kubectl --context $CLUSTER_NAME1 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: reviews
      namespace: default
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
            host: reviews-local.default.svc.cluster.local
            port:
              number: 9080
          weight: 20
        - destination:
            host: reviews-remote.default.svc.cluster.local
            port:
              number: 9080
          weight: 80
    EOF
    
  4. Verificare le impostazioni usando lo script seguente (è possibile modificare i pesi e testarlo manualmente).

    L'intestazione Connection: close chiude solo la connessione HTTP/1.1 sul lato client. Nel multicluster di ambiente, il gateway east-west e il waypoint possono comunque riutilizzare le connessioni HBONE, quindi le richieste inviate a cluster-2 potrebbero rimanere fissate a reviews-v2 o reviews-v3 nel corso di un'unica esecuzione. Usare cluster-1 versus cluster-2 come segnale di verifica autorevole per la 20/80 scissione e considerare il colore della stella solo come dettagli illustrativi.

    results=()
    for i in $(seq 1 20); do
      html=$(curl -sS --http1.1 -H 'Connection: close' http://$BOOK_INFO_GTW_IP/productpage)
      pod=$(printf '%s' "$html" | grep -oE 'reviews-v[0-9]-[a-z0-9-]+' | head -n1)
      if printf '%s' "$pod" | grep -q '^reviews-v1-'; then
        target=cluster-1
      else
        target=cluster-2
      fi
      if printf '%s' "$html" | grep -q 'text-red-500'; then
        star=red
      elif printf '%s' "$html" | grep -q 'text-black-500'; then
        star=black
      else
        star=no-star
      fi
    
      line=$(printf '%02d  %-10s  %-8s  %s' "$i" "$target" "$star" "$pod")
      echo "$line"
      results+=("$target $star")
    done
    
    echo
    echo "Summary:"
    printf '%s\n' "${results[@]}" | sort | uniq -c
    

    Output di esempio:

    ...
    
    Summary:
    3 cluster-1 no-star
    17 cluster-2 black
    

Implementare l'inserimento di errori

Configurare i servizi virtuali

Importante

In questa sezione, riutilizziamo i servizi creati in reviews-local e reviews-remote nella sezione di spostamento del traffico.

  1. Configurare i servizi virtuali per productpage e details nel cluster AKS 1 utilizzando il comando seguente kubectl apply:

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: productpage
    spec:
      hosts:
      - productpage
      http:
      - route:
        - destination:
            host: productpage
    ---
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: details
    spec:
      hosts:
      - details
      http:
      - route:
        - destination:
            host: details
    EOF
    
  2. Configurare un servizio virtuale per il ratings nel cluster AKS 2 usando il seguente comando kubectl apply:

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - route:
        - destination:
            host: ratings
    EOF
    
  3. Aggiorna reviews-remote nel cluster AKS 2 per selezionare reviews-v2 utilizzando solo il seguente comando kubectl apply:

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-remote
      namespace: default
      labels:
        app: reviews
        service: reviews-remote
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
        version: v2
    EOF
    
  4. Modifica il servizio virtuale per il cluster AKS 1 per rivolgere le richieste dell'utente jason a reviews-remote utilizzando il seguente comando kubectl apply:

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: reviews
      namespace: default
    spec:
      hosts:
      - reviews
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        route:
        - destination:
            host: reviews-remote.default.svc.cluster.local
            port:
              number: 9080
      - route:
        - destination:
            host: reviews-local.default.svc.cluster.local
            port:
              number: 9080
    EOF
    

Inserire un ritardo HTTP

  1. Inserire un ritardo HTTP di sette secondi per l'utente jason sul servizio ratings nel cluster AKS 2 utilizzando il seguente comando kubectl apply:

    kubectl --context $CLUSTER_NAME2 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        fault:
          delay:
            percentage:
              value: 100.0
            fixedDelay: 7s
        route:
        - destination:
            host: ratings
      - route:
        - destination:
            host: ratings
    EOF
    
  2. Per visualizzare l'impatto di questo ritardo, aprire un browser e passare a http://$BOOK_INFO_GTW_IP/productpage. Inizialmente, non dovrebbero essere visualizzate stelle di classificazione nella sezione "Recensioni libro" perché tutto il traffico passa a reviews-v1.

  3. Accedere usando il nome utente jason e qualsiasi password desiderata.

    Screenshot della pagina di accesso dell'applicazione di esempio Book Info.

    Si noti che la pagina Web diventa molto lenta, con ogni aggiornamento che richiede circa sei secondi. La sezione "Book Reviews" dovrebbe visualizzare un errore.

    Screenshot del messaggio di errore che indica che le recensioni dei libri non sono attualmente disponibili.

    Il modello di traffico dopo aver eseguito l'accesso all'utente jason è: [(AKS cluster 1) productpage-v1] --(1)--> [(AKS cluster 2) reviews-v2] --(2)--> [(AKS cluster 2) ratings-v1].

    Quando si esegue l'accesso come jason, si aggiunge un ritardo di sette secondi nella connessione (2):

    • reviews-v2 ha un timeout di 10 secondi durante il recupero delle classificazioni, che supera il ritardo da ratings-v1, in modo che possa attendere il caricamento delle classificazioni.
    • productpage-v1 ha un timeout di tre secondi con due tentativi, che equivale a un timeout di sei secondi.
    • reviews-v2 è ancora in attesa della risposta dalle valutazioni e productpage-v1 raggiunge il timeout e restituisce un errore nella pagina Web.

Ridurre il ritardo e il timeout HTTP

In questa sezione viene riportata la sezione "Recensioni libro". Per ridurre il tempo di caricamento della pagina Web, è possibile modificare il modello di traffico che l'utente jason deve instradare a reviews-v3, con un timeout di due e mezzo secondo.

  1. Aggiorna reviews-remote nel cluster AKS 2 per selezionare reviews-v3 solo usando il seguente comando kubectl apply :

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-remote
      namespace: default
      labels:
        app: reviews
        service: reviews-remote
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
        version: v3
    EOF
    

    Modello di traffico aggiornato: [(AKS cluster 1) productpage-v1] --(1)--> [(AKS cluster 2) reviews-v3] --(2)--> [(AKS cluster 2) ratings-v1]

    Ora viene visualizzata la sezione "Recensioni di libri", ma le valutazioni sono ancora assenti perché reviews-v3 attende solo due secondi e mezzo prima di rinunciare al recupero.

    Screenshot che mostra le recensioni del libro senza le valutazioni.

  2. Passiamo ora a ripristinare la sezione "Valutazioni". Ridurre il ritardo per ratings-v1 un secondo usando il comando seguente kubectl apply :

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
    name: ratings
    spec:
    hosts:
    - ratings
    http:
    - match:
        - headers:
            end-user:
            exact: jason
        fault:
        delay:
            percentage:
            value: 100.0
            fixedDelay: 1s
        route:
        - destination:
            host: ratings
            subset: v1
    - route:
        - destination:
            host: ratings
            subset: v1
    EOF
    

    Le stelle di valutazione ora vengono visualizzate perché le valutazioni richiedono un secondo per restituire la risposta, che rientra nel timeout di due secondi e mezzo di reviews-v3 che, a sua volta, rientra nel timeout di sei secondi della pagina del prodotto.

    Screenshot che mostra le recensioni e le valutazioni del libro caricate.

Inserire un'interruzione HTTP

  1. Assicurarsi che reviews-remote nel cluster AKS 2 selezioni nuovamente reviews-v2 usando il seguente comandokubectl apply:

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: reviews-remote
      namespace: default
      labels:
        app: reviews
        service: reviews-remote
        istio.io/global: "true"
        istio.io/use-waypoint: waypoint
    spec:
      ports:
      - name: http
        port: 9080
        targetPort: 9080
      selector:
        app: reviews
        version: v2
    EOF
    
  2. Consentire a tutte le richieste dal cluster AKS 1 di raggiungere reviews-remote utilizzare il seguente comando kubectl apply :

    kubectl --context $CLUSTER_NAME_1 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews-remote.default.svc.cluster.local
            port:
              number: 9080
    EOF
    
  3. Iniettare un'interruzione HTTP 503 per l'utente jason al servizio ratings nel cluster AKS 2 usando il comando seguente kubectl apply:

    kubectl --context $CLUSTER_NAME_2 apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - fault:
          abort:
            httpStatus: 503
            percentage:
              value: 100
        route:
        - destination:
            host: ratings
    EOF
    

    Indipendentemente dal fatto che si effettui l'accesso o meno, le stelle di valutazione non possono essere visualizzate poiché tutte le richieste al servizio ratings restituiscono 503.

    Screenshot che mostra come le valutazioni dei libri non vengano visualizzate a causa del fatto che tutte le richieste al servizio di valutazioni restituiscono 503.

Per altre informazioni sulla rete applicativa di Azure Kubernetes, vedere gli articoli seguenti: