Przypadki użycia zarządzania ruchem dla usługi Azure Kubernetes Application Network (wersja zapoznawcza)

Ważna

Funkcje usługi AKS w wersji zapoznawczej są dostępne na zasadzie samoobsługi i wymagają zapisania się. Wersje zapoznawcze są udostępniane w wersji "as is" i "jako dostępne" i są wykluczone z umów dotyczących poziomu usług i ograniczonej gwarancji. Wersje zapoznawcze usługi AKS są częściowo objęte pomocą techniczną dla klientów, świadczoną w miarę możliwości. W związku z tym te funkcje nie są przeznaczone do użytku produkcyjnego. Aby uzyskać więcej informacji, zobacz następujące artykuły pomocy technicznej:

Zarządzanie ruchem sieciowym aplikacji Azure Kubernetes wykorzystuje tryb otoczenia Istio i interfejs API bramy Kubernetes, aby umożliwić precyzyjną kontrolę nad interakcjami między usługami zarówno wewnątrz klastrów, jak i pomiędzy nimi. To rozwiązanie oferuje kompleksowy zestaw funkcji zarządzania ruchem, w tym:

  • Zasady autoryzacji L4/L7
  • Routing oparty na oświadczeniach JWT
  • Przesuwanie ruchu
  • Wstrzykiwanie błędów

Ten artykuł zawiera instrukcje krok po kroku dotyczące implementowania przypadków użycia zarządzania ruchem przy użyciu usługi Azure Kubernetes Application Network w wielu klastrach usługi Azure Kubernetes Service (AKS).

Wymagania wstępne

Przed rozpoczęciem upewnij się, że zostały spełnione następujące wymagania wstępne:

  • Istniejący zasób usługi Azure Kubernetes Application Network.

  • Dwa istniejące klastry AKS z dostępnością sieciową między ich bramami wschód-zachód. Można to osiągnąć przy użyciu połączenia sieci wirtualnej VNet z siecią wirtualną sieci VPN, komunikacji równorzędnej sieci wirtualnej platformy Azure (VNet peering) lub innego obsługiwanego modelu łączności.

  • Zainstalowano interfejs wiersza polecenia Istio, istioctl. Aby wybrać poprawną wersję pliku istioctl, zapoznaj się z obsługiwaną wersją istio dla sieci aplikacji. Program istioctl można zainstalować przy użyciu następującego polecenia:

    curl -sL https://istio.io/downloadIstioctl | sh -
    export PATH=$HOME/.istioctl/bin:$PATH
    
  • Ustaw następujące zmienne środowiskowe do użycia w całym artykule:

    export AKS_RG=<resource-group-name>
    export CLUSTER_NAME_1=<cluster-1-name>
    export CLUSTER_NAME_2=<cluster-2-name>
    
  • Skonfiguruj narzędzie kubectl, aby nawiązać połączenie z klastrami AKS przy użyciu polecenia az aks get-credentials:

    az aks get-credentials --resource-group $AKS_RG --name $CLUSTER_NAME_1 --overwrite-existing
    az aks get-credentials --resource-group $AKS_RG --name $CLUSTER_NAME_2 --overwrite-existing
    

Sprawdzanie instalacji istio i ztunnel

  1. Sprawdź CRD Istio przy użyciu polecenia kubectl get crds.

    kubectl --context $CLUSTER_NAME_1 get crds | grep istio
    

    Dane wyjściowe powinny zawierać następujące 14 CRD dla trybu ambient 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. Sprawdź, czy Istio CNI i ztunnel DaemonSet są uruchomione w przestrzeni nazw applink-system za pomocą polecenia kubectl get daemonset.

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

    Dane wyjściowe powinny zawierać następujące zestawy DaemonSet ze wszystkimi zasobnikami w READY stanie:

    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
    

Tworzenie przykładowej aplikacji

Architektura aplikacji

Ta architektura rozszerza przykładową aplikację Bookinfo, aby działała w wielu klastrach usługi AKS.

Zrzut ekranu przedstawiający diagram architektury przedstawiający przykładową architekturę aplikacji Bookinfo działającą w dwóch klastrach usługi AKS.

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

Usługa productpage wysyła żądania do reviews.default.svc.cluster.local. reviews Ponieważ usługa jest dostępna w obu klastrach usługi AKS z globalnym zakresem usługi, żądania mogą być kierowane do wszystkich dostępnych zapleczy (reviews-v1, reviews-v2lub reviews-v3) w klastrach. Usługi reviews-v2 i reviews-v3 również wywołują usługę ratings w celu pobrania danych klasyfikacji przed zwróceniem odpowiedzi do productpage.

Ta architektura pokazuje, jak aplikacja rozproszona może obejmować wiele klastrów, a jednocześnie nadal używać spójnej nazwy usługi i wzorca komunikacji, umożliwiając bezproblemową interakcję z usługą w granicach klastra.

Wdrażanie usług aplikacji

  1. Wdróż usługi w productpage klastrze AKS 1 przy użyciu następujących kubectl apply poleceń:

    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. Wdróż usługi w reviews-v1 klastrze AKS 1 przy użyciu następujących kubectl apply poleceń:

    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. Wdróż usługi details do klastra AKS 1, używając następujących kubectl apply poleceń:

    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. Wdróż usługę curl w klastrze AKS 1 przy użyciu następującego kubectl apply polecenia:

    kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/curl/curl.yaml
    
  5. Wdróż usługi reviews-v2 i reviews-v3 do klastra AKS 2 przy użyciu następujących poleceń 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. Wdróż usługi w ratings klastrze AKS 2 przy użyciu następujących kubectl apply poleceń:

    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
    

Wdróż bramę wejściową

  1. Wdróż bramę wejściową do klastra AKS 1, używając następującego polecenia 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. Sprawdź, czy brama jest zaprogramowana przy użyciu następującego kubectl get gateway polecenia:

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

    Po około jednej minucie, powinieneś zobaczyć dane wyjściowe podobne do następujących, z PROGRAMMED wyświetlanym jako True.

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

Dodawanie aplikacji do siatki

  • Dodaj aplikację do siatki, etykietując default przestrzeń nazw w obu klastrach AKS za pomocą 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
    

Zainstaluj waypoint i oznakuj usługi jako globalne

  1. Zainstaluj waypoint bramy w obu klastrach przy użyciu następujących istioctl waypoint apply poleceń:

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

    Dane wyjściowe powinny wyglądać podobnie do poniższych, co wskazuje, że element waypoint został zastosowany, a przestrzeń nazw default została poprawnie oznaczona w obu klastrach.

    ✅ 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. Sprawdź, waypoint czy bramy są programowane przy użyciu następującego kubectl get gateway waypoint polecenia w obu klastrach:

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

    Po około jednej minucie powinniście zobaczyć wynik podobny do poniższego w obu klastrach, z PROGRAMMED pokazującym się jako True.

    NAME       CLASS            ADDRESS       PROGRAMMED   AGE
    waypoint   istio-waypoint   10.1.78.229   True         28s
    
  3. Oznacz usługę reviews-v1 w klastrze AKS 1 oraz usługi reviews-v2 i reviews-v3 w klastrze AKS 2 jako usługi globalne, etykietując je 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. waypoint Oznacz usługi jako usługi globalne, oznaczając je etykietami istio.io/global="true" w obu klastrach:

    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. Sprawdź usługi globalne według konfiguracji ztunnel w obu klastrach przy użyciu polecenia istioctl zc service. W kolumnie SERVICE VIP powinny być widoczne usługi reviews i waypoint z obu klastrów ze swoimi odpowiednimi adresami 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"'
    

    Dane wyjściowe powinny wyglądać podobnie do następujących w obu klastrach, co wskazuje, że usługi reviews i waypoint są rozpoznawane jako usługi globalne z ich adresami 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
    

Weryfikowanie dostępu do aplikacji

Uwaga / Notatka

Jeśli nie możesz uzyskać dostępu do aplikacji z Internetu, upewnij się, że sieciowa grupa zabezpieczeń skojarzona z klastrem zezwala na przychodzący ruch internetowy na porcie 80 TCP do bramy ruchu przychodzącego.

  • Uzyskaj dostęp do aplikacji za pośrednictwem bramy wejściowej przy użyciu następujących poleceń:

    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
    

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że aplikacja jest dostępna za pośrednictwem bramy:

    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
    

Wdrażanie zasad autoryzacji L4/L7

Wymuszanie zasad autoryzacji L4

  1. Zastosuj zasady autoryzacji L4, aby zezwolić na ruch do usługi productpage tylko z bramy wejściowej, przy użyciu następującego polecenia 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. Sprawdź, czy nadal możesz uzyskać dostęp do aplikacji za pośrednictwem bramy wejściowej przy użyciu następującego polecenia:

    curl -I http://$BOOK_INFO_GTW_IP/productpage
    

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że aplikacja jest nadal dostępna za pośrednictwem bramy:

    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. Sprawdź, czy dostęp do productpage usługi jest zablokowany z innych źródeł, próbując uzyskać do niego dostęp z zasobnika curl, używając następującego polecenia:

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

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że odmowa dostępu wynika z zasad autoryzacji L4:

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

Wymuszanie zasad autoryzacji L7

  1. Zastosuj zasady autoryzacji L7, aby zezwolić tylko na żądania GET do productpage usługi z konta usługi curl przy użyciu następującego kubectl apply polecenia:

    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. Zaktualizuj zasady autoryzacji L4, aby zezwolić na ruch z punktu wyjścia do ztunnel, dodając waypoint konto usługi jako dozwoloną jednostkę przy użyciu następującego kubectl apply polecenia:

    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. Sprawdź, czy DELETE operacje w productpage usłudze są zablokowane z poziomu konta usługi curl przy użyciu następującego kubectl exec polecenia:

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

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że odmowa dostępu wynika z zasad autoryzacji L7:

    RBAC: access denied
    
  4. Sprawdź, czy konta usługi inne niż curl są zablokowane przed uzyskaniem productpage dostępu do usługi za pomocą poniższego polecenia kubectl exec.

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

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że odmowa dostępu wynika z zasad autoryzacji L7:

    RBAC: access denied
    
  5. Sprawdź, czy żądania GET do usługi productpage są dozwolone z konta usługi curl, używając następującego polecenia kubectl exec:

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

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądania GET są dozwolone, a productpage jest dostępne:

    <title>Simple Bookstore App</title>
    
  6. Sprawdź, czy productpage jest nadal dostępna przez bramę ruchu przychodzącego, używając następującego polecenia:

    curl -I http://$BOOK_INFO_GTW_IP/productpage
    

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że productpage element jest nadal dostępny za pośrednictwem bramy:

    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
    

Implementowanie routingu opartego na oświadczeniach JWT

Tworzenie bramy ruchu przychodzącego i zabezpieczanie jej przy użyciu uwierzytelniania JWT

  1. Utwórz nową przestrzeń nazw dla bramy ruchu przychodzącego przy użyciu polecenia kubectl create namespace.

    kubectl --context $CLUSTER_NAME_1 create namespace applink-ingress
    
  2. Utwórz bramę wejściową za pomocą interfejsu API bramy Kubernetes i zezwalaj tylko na trasy z tej samej przestrzeni nazw przy użyciu następującego polecenia 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. Sprawdź, czy brama jest zaprogramowana przy użyciu następującego kubectl get gateway polecenia:

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

    Po około jednej minucie powinien zostać wyświetlony wynik podobny do poniższego, z PROGRAMMED wyświetlonym jako True.

    NAME                     CLASS   ADDRESS         PROGRAMMED   AGE
    applink-ingressgateway   istio   20.99.227.197   True         30s
    
  4. Pobierz adres URL wystawcy OIDC z klastra AKS i ustaw go jako zmienną środowiskową.

    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. Zastosuj politykę RequestAuthentication, aby zweryfikować tokeny JWT wystawione przez dostawcę OIDC w klastrze AKS oraz przekazać oryginalny token do usługi reviews, a także skonfiguruj Usługę Wirtualną do kierowania ruchu do usługi reviews na podstawie roszczenia sub w tokenie JWT, używając następującego polecenia 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. Pobierz adres IP nowej bramy ruchu przychodzącego i ustaw go jako zmienną środowiskową.

    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
    

Weryfikowanie uwierzytelniania JWT i routingu opartego na oświadczeniach

  1. Sprawdź, czy żądania bez tokenu JWT są odrzucane przez bramę przy użyciu następującego kubectl exec polecenia:

    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
    

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądanie zostało odrzucone z powodu błędu 404 Nie znaleziono, ponieważ brakuje tokenu 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. Sprawdź, czy żądania z nieprawidłowym tokenem JWT są odrzucane przez bramę przy użyciu następującego kubectl exec polecenia:

    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
    

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądanie zostało odrzucone z błędem 401 Brak autoryzacji, ponieważ token JWT jest nieprawidłowy:

    *   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. Sprawdź, czy żądania z prawidłowym tokenem JWT są dozwolone przez bramę i kierowane do reviews usługi przy użyciu następującego kubectl exec polecenia. Token JWT jest uzyskiwany z tokenu konta serwisowego zamontowanego w podzie curl, który jest wystawiany przez wystawcę OIDC klastra AKS.

    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. Uruchom następujące polecenie w powłoce interaktywnej, aby wysłać żądanie z prawidłowym tokenem JWT do bramy sieciowej.

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

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądanie jest dozwolone, a reviews usługa jest w dobrej kondycji:

    {"status": "Reviews is healthy"}
    
  5. Uruchom następujące polecenie w interaktywnej powłoce, aby wysłać żądanie z prawidłowym tokenem JWT do bramy w celu uzyskania dostępu do usługi reviews. Żądanie powinno być dozwolone i kierowane do reviews usługi, ponieważ oświadczenie JWT w tokenie sub jest zgodne z wartością określoną w warunku dopasowania trasy VirtualService.

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

    Dane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądanie jest dozwolone i kierowane do reviews usługi, zwracając recenzję produktu 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."}]}
    

Implementowanie przenoszenia ruchu między klastrami

Implementujemy przekierowanie ruchu między klastrami za pomocą następującej konfiguracji w dwóch klastrach AKS.

  • Klaster AKS 1: reviews-local usługi wybierają tylko reviews-v1 zasobniki, a reviews-remote usługa celowo nie wybiera zasobników lokalnych.
  • Klaster AKS 2: reviews-local usługa celowo nie wybiera zasobników lokalnych, a reviews-remote usługa wybiera zarówno reviews-v2 zasobniki, jak i reviews-v3 zasobniki.

W tej sekcji terminy lokalne i zdalne są definiowane z perspektywy klastra AKS 1.

  1. Zastosuj następujące zasoby w klastrze AKS 1, aby skonfigurować usługi reviews-local i reviews-remote za pomocą odpowiednich selektorów z użyciem polecenia 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. Zastosuj następujące zasoby usługi w klastrze AKS 2, aby skonfigurować usługi reviews-local i reviews-remote przy użyciu odpowiednich selektorów za pomocą komendy 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. Podziel ruch dla reviews usługi 20/80 między klastrami lokalnymi i zdalnymi przy użyciu następującego kubectl apply polecenia:

    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. Sprawdź ustawienia przy użyciu następującego skryptu (możesz zmienić wagi i przetestować je samodzielnie).

    Nagłówek Connection: close zamyka tylko połączenie HTTP/1.1 po stronie klienta. W ambientnym wieloklasterze brama wschód-zachód i punkt trasy mogą nadal ponownie używać połączeń HBONE, więc żądania wysyłane do cluster-2 mogą pozostać przypięte do reviews-v2 lub reviews-v3 w ramach jednego uruchomienia. Użyj cluster-1 w porównaniu z cluster-2 jako wiarygodnego sygnału weryfikacji dla podziału 20/80 i traktuj barwę gwiazdy wyłącznie jako detal ilustracyjny.

    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
    

    Przykładowy wynik:

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

Implementowanie iniekcji błędów

Konfigurowanie usług wirtualnych

Ważna

W tej sekcji ponownie używamy usług reviews-local i reviews-remote utworzonych w sekcji zmiany ruchu.

  1. Skonfiguruj usługi wirtualne dla usług productpage i details w klastrze AKS numer 1, przy użyciu następującego polecenia 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. Skonfiguruj usługę wirtualną dla usługi ratings w klastrze AKS 2, używając następującego polecenia 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. Zaktualizuj reviews-remote w klastrze AKS 2, aby wybrać reviews-v2 używając wyłącznie poniższego polecenia 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. Zmodyfikuj usługę wirtualną dla klastra AKS 1, aby kierować żądania użytkownika jasondo reviews-remote przy użyciu następującego kubectl apply polecenia:

    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
    

Dodanie opóźnienia HTTP

  1. Wstrzyknij siedmiosekundowe opóźnienie HTTP dla użytkownika jason do usługi ratings w klastrze AKS 2 przy użyciu następującego polecenia 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. Aby zobaczyć wpływ tego opóźnienia, otwórz przeglądarkę i przejdź do http://$BOOK_INFO_GTW_IP/productpage. Początkowo w sekcji "Recenzje książek" nie powinny być widoczne żadne gwiazdki oceny, ponieważ cały ruch przechodzi do reviews-v1.

  3. Zaloguj się przy użyciu nazwy użytkownika jason i dowolnego hasła.

    Zrzut ekranu przedstawiający stronę logowania przykładowej aplikacji Informacje o książce.

    Zwróć uwagę, że strona internetowa staje się bardzo wolna, a każde odświeżanie trwa około sześciu sekund. W sekcji "Recenzje książek" powinien zostać wyświetlony błąd.

    Zrzut ekranu przedstawiający komunikat o błędzie wskazujący, że recenzje książek są obecnie niedostępne.

    Wzorzec ruchu po zalogowaniu się do użytkownika jason to: [(AKS cluster 1) productpage-v1] --(1)--> [(AKS cluster 2) reviews-v2] --(2)--> [(AKS cluster 2) ratings-v1].

    Po zalogowaniu się jako jasondodamy siedem sekund opóźnienia w połączeniu (2):

    • reviews-v2 ma 10-sekundowy limit czasu podczas pobierania ocen, który przekracza opóźnienie z ratings-v1, dzięki czemu może czekać na załadowanie klasyfikacji.
    • productpage-v1 ma trzysekundowy limit czasu z dwoma ponownymi próbami, co daje sześciosekundowy limit czasu.
    • reviews-v2 nadal czeka na odpowiedź z ratingów, a productpage-v1 osiąga limit czasu i zwraca błąd na stronie internetowej.

Zmniejsz opóźnienie HTTP i czas oczekiwania

W tej sekcji przywrócimy sekcję "Recenzje książek". Aby skrócić czas ładowania strony internetowej, możemy zmienić wzorzec ruchu dla użytkownika jason na trasę do reviews-v3, która ma limit czasu dwóch i pół sekundy.

  1. Zaktualizuj w klastrze AKS 2 reviews-remote, aby wybrać reviews-v3, używając tylko następującego polecenia 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
    

    Zaktualizowany wzorzec ruchu: [(AKS cluster 1) productpage-v1] --(1)--> [(AKS cluster 2) reviews-v3] --(2)--> [(AKS cluster 2) ratings-v1]

    Teraz pojawi się sekcja "Recenzje książek", ale wciąż brakuje ocen, ponieważ reviews-v3 czeka tylko przez dwie i pół sekundy przed rezygnacją z ich pobierania.

    Zrzut ekranu przedstawiający recenzje książek bez ocen.

  2. Następnie wróćmy do sekcji "Klasyfikacje". Zmniejsz opóźnienie dla ratings-v1 do jednej sekundy, używając następującego polecenia 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
    

    Gwiazdki klasyfikacji są teraz wyświetlane, ponieważ oceny potrzebują jednej sekundy na przesłanie odpowiedzi, co mieści się w dwupółsekundowym limicie czasu reviews-v3, który z kolei mieści się w sześciu sekundach limitu czasu strony produktu.

    Zrzut ekranu przedstawiający załadowane recenzje i oceny książek.

Wstrzykiwanie przerwania protokołu HTTP

  1. Upewnij się, że reviews-remote w klastrze AKS 2 jest ponownie wybrane reviews-v2 za pomocą następującego polecenia 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
    
  2. Pozwól wszystkim żądaniom z klastra AKS 1 trafić do reviews-remote przy użyciu następującego polecenia 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. Wstrzyknij przerwanie HTTP 503 dla użytkownika jason w usłudze ratings w klastrze AKS 2, używając następującego polecenia 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
    

    Niezależnie od tego, czy logujesz się, czy nie, gwiazdki oceny nie mogą być wyświetlone, ponieważ wszystkie żądania do ratings usługi zwracają wartość 503.

    Zrzut ekranu przedstawiający klasyfikacje książek nie są wyświetlane ze względu na wszystkie żądania do usługi klasyfikacji zwracającej wartość 503.

Aby dowiedzieć się więcej o usłudze Azure Kubernetes Application Network, zobacz następujące artykuły: