Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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.
- Oba klastry muszą być przyłączone jako elementy członkowskie do usługi Azure Kubernetes Application Network.
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:$PATHUstaw 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
Sprawdź CRD Istio przy użyciu polecenia
kubectl get crds.kubectl --context $CLUSTER_NAME_1 get crds | grep istioDane 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:11ZSprawdź, czy Istio CNI i ztunnel DaemonSet są uruchomione w przestrzeni nazw
applink-systemza pomocą poleceniakubectl get daemonset.kubectl --context $CLUSTER_NAME_1 --namespace applink-system get daemonsetDane wyjściowe powinny zawierać następujące zestawy DaemonSet ze wszystkimi zasobnikami w
READYstanie: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.
-
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
Wdróż usługi w
productpageklastrze AKS 1 przy użyciu następującychkubectl applypoleceń: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=productpageWdróż usługi w
reviews-v1klastrze AKS 1 przy użyciu następującychkubectl applypoleceń: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=v1Wdróż usługi
detailsdo klastra AKS 1, używając następującychkubectl applypoleceń: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=detailsWdróż usługę curl w klastrze AKS 1 przy użyciu następującego
kubectl applypolecenia:kubectl --context $CLUSTER_NAME_1 apply -f https://raw.githubusercontent.com/istio/istio/release-1.29/samples/curl/curl.yamlWdróż usługi
reviews-v2ireviews-v3do 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)'Wdróż usługi w
ratingsklastrze AKS 2 przy użyciu następującychkubectl applypoleceń: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ą
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.yamlSprawdź, czy brama jest zaprogramowana przy użyciu następującego
kubectl get gatewaypolecenia:kubectl --context $CLUSTER_NAME_1 --namespace default get gatewayPo około jednej minucie, powinieneś zobaczyć dane wyjściowe podobne do następujących, z
PROGRAMMEDwyświetlanym jakoTrue.NAME CLASS ADDRESS PROGRAMMED AGE bookinfo-gateway istio 20.112.40.27 True 21s
Dodawanie aplikacji do siatki
Dodaj aplikację do siatki, etykietując
defaultprzestrzeń 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
Zainstaluj
waypointbramy w obu klastrach przy użyciu następującychistioctl waypoint applypoleceń:istioctl --context $CLUSTER_NAME_1 waypoint apply --enroll-namespace --wait istioctl --context $CLUSTER_NAME_2 waypoint apply --enroll-namespace --waitDane wyjściowe powinny wyglądać podobnie do poniższych, co wskazuje, że element
waypointzostał zastosowany, a przestrzeń nazwdefaultzostał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"Sprawdź,
waypointczy bramy są programowane przy użyciu następującegokubectl get gateway waypointpolecenia w obu klastrach:kubectl --context $CLUSTER_NAME_1 get gateway waypoint kubectl --context $CLUSTER_NAME_2 get gateway waypointPo około jednej minucie powinniście zobaczyć wynik podobny do poniższego w obu klastrach, z
PROGRAMMEDpokazującym się jakoTrue.NAME CLASS ADDRESS PROGRAMMED AGE waypoint istio-waypoint 10.1.78.229 True 28sOznacz usługę
reviews-v1w klastrze AKS 1 oraz usługireviews-v2ireviews-v3w klastrze AKS 2 jako usługi globalne, etykietując jeistio.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"waypointOznacz usługi jako usługi globalne, oznaczając je etykietamiistio.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"Sprawdź usługi globalne według konfiguracji ztunnel w obu klastrach przy użyciu polecenia
istioctl zc service. W kolumnieSERVICE VIPpowinny być widoczne usługireviewsiwaypointz 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
reviewsiwaypointsą 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/productpageDane 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
Zastosuj zasady autoryzacji L4, aby zezwolić na ruch do usługi
productpagetylko z bramy wejściowej, przy użyciu następującego poleceniakubectl 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 EOFSprawdź, 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/productpageDane 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: 19Sprawdź, czy dostęp do
productpageusł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
Zastosuj zasady autoryzacji L7, aby zezwolić tylko na żądania GET do
productpageusługi z konta usługi curl przy użyciu następującegokubectl applypolecenia: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"] EOFZaktualizuj zasady autoryzacji L4, aby zezwolić na ruch z punktu wyjścia do ztunnel, dodając
waypointkonto usługi jako dozwoloną jednostkę przy użyciu następującegokubectl applypolecenia: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 EOFSprawdź, czy
DELETEoperacje wproductpageusłudze są zablokowane z poziomu konta usługi curl przy użyciu następującegokubectl execpolecenia:kubectl --context $CLUSTER_NAME_1 exec deploy/curl -- curl -s "http://productpage:9080/productpage" -X DELETEDane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że odmowa dostępu wynika z zasad autoryzacji L7:
RBAC: access deniedSprawdź, czy konta usługi inne niż curl są zablokowane przed uzyskaniem
productpagedostępu do usługi za pomocą poniższego poleceniakubectl exec.kubectl --context $CLUSTER_NAME_1 exec deploy/reviews-v1 -- curl -s http://productpage:9080/productpageDane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że odmowa dostępu wynika z zasad autoryzacji L7:
RBAC: access deniedSprawdź, czy żądania
GETdo usługiproductpagesą dozwolone z konta usługi curl, używając następującego poleceniakubectl 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
productpagejest dostępne:<title>Simple Bookstore App</title>Sprawdź, czy
productpagejest nadal dostępna przez bramę ruchu przychodzącego, używając następującego polecenia:curl -I http://$BOOK_INFO_GTW_IP/productpageDane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że
productpageelement 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
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-ingressUtwó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 EOFSprawdź, czy brama jest zaprogramowana przy użyciu następującego
kubectl get gatewaypolecenia:kubectl --context $CLUSTER_NAME_1 -n applink-ingress get gatewayPo około jednej minucie powinien zostać wyświetlony wynik podobny do poniższego, z
PROGRAMMEDwyświetlonym jakoTrue.NAME CLASS ADDRESS PROGRAMMED AGE applink-ingressgateway istio 20.99.227.197 True 30sPobierz 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_URLZastosuj 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ługireviewsna podstawie roszczeniasubw tokenie JWT, używając następującego poleceniakubectl 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 EOFPobierz 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
Sprawdź, czy żądania bez tokenu JWT są odrzucane przez bramę przy użyciu następującego
kubectl execpolecenia: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/1Dane 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 intactSprawdź, czy żądania z nieprawidłowym tokenem JWT są odrzucane przez bramę przy użyciu następującego
kubectl execpolecenia: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/1Dane 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 JSONSprawdź, czy żądania z prawidłowym tokenem JWT są dozwolone przez bramę i kierowane do
reviewsusługi przy użyciu następującegokubectl execpolecenia. 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"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; echoDane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądanie jest dozwolone, a
reviewsusługa jest w dobrej kondycji:{"status": "Reviews is healthy"}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 doreviewsusługi, ponieważ oświadczenie JWT w tokeniesubjest 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; echoDane wyjściowe powinny wyglądać podobnie do następujących, co wskazuje, że żądanie jest dozwolone i kierowane do
reviewsusł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-localusługi wybierają tylkoreviews-v1zasobniki, areviews-remoteusługa celowo nie wybiera zasobników lokalnych. -
Klaster AKS 2:
reviews-localusługa celowo nie wybiera zasobników lokalnych, areviews-remoteusługa wybiera zarównoreviews-v2zasobniki, jak ireviews-v3zasobniki.
W tej sekcji terminy lokalne i zdalne są definiowane z perspektywy klastra AKS 1.
Zastosuj następujące zasoby w klastrze AKS 1, aby skonfigurować usługi
reviews-localireviews-remoteza pomocą odpowiednich selektorów z użyciem poleceniakubectl 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 EOFZastosuj następujące zasoby usługi w klastrze AKS 2, aby skonfigurować usługi
reviews-localireviews-remoteprzy użyciu odpowiednich selektorów za pomocą komendykubectl 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 EOFPodziel ruch dla
reviewsusługi20/80między klastrami lokalnymi i zdalnymi przy użyciu następującegokubectl applypolecenia: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 EOFSprawdź ustawienia przy użyciu następującego skryptu (możesz zmienić wagi i przetestować je samodzielnie).
Nagłówek
Connection: closezamyka 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 docluster-2mogą pozostać przypięte doreviews-v2lubreviews-v3w ramach jednego uruchomienia. Użyjcluster-1w porównaniu zcluster-2jako wiarygodnego sygnału weryfikacji dla podziału20/80i 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 -cPrzykł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.
Skonfiguruj usługi wirtualne dla usług
productpageidetailsw klastrze AKS numer 1, przy użyciu następującego poleceniakubectl 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 EOFSkonfiguruj usługę wirtualną dla usługi
ratingsw klastrze AKS 2, używając następującego poleceniakubectl 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 EOFZaktualizuj
reviews-remotew klastrze AKS 2, aby wybraćreviews-v2używając wyłącznie poniższego poleceniakubectl 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 EOFZmodyfikuj usługę wirtualną dla klastra AKS 1, aby kierować żądania użytkownika
jasondoreviews-remoteprzy użyciu następującegokubectl applypolecenia: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
Wstrzyknij siedmiosekundowe opóźnienie HTTP dla użytkownika
jasondo usługiratingsw klastrze AKS 2 przy użyciu następującego poleceniakubectl 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 EOFAby 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 doreviews-v1.Zaloguj się przy użyciu nazwy użytkownika
jasoni dowolnego hasła.
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.
Wzorzec ruchu po zalogowaniu się do użytkownika
jasonto:[(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-v2ma 10-sekundowy limit czasu podczas pobierania ocen, który przekracza opóźnienie zratings-v1, dzięki czemu może czekać na załadowanie klasyfikacji. -
productpage-v1ma trzysekundowy limit czasu z dwoma ponownymi próbami, co daje sześciosekundowy limit czasu. -
reviews-v2nadal czeka na odpowiedź z ratingów, aproductpage-v1osią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.
Zaktualizuj w klastrze AKS 2
reviews-remote, aby wybraćreviews-v3, używając tylko następującego poleceniakubectl 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 EOFZaktualizowany 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-v3czeka tylko przez dwie i pół sekundy przed rezygnacją z ich pobierania.
Następnie wróćmy do sekcji "Klasyfikacje". Zmniejsz opóźnienie dla
ratings-v1do jednej sekundy, używając następującego poleceniakubectl 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 EOFGwiazdki 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.
Wstrzykiwanie przerwania protokołu HTTP
Upewnij się, że
reviews-remotew klastrze AKS 2 jest ponownie wybranereviews-v2za pomocą następującego poleceniakubectl 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 EOFPozwól wszystkim żądaniom z klastra AKS 1 trafić do
reviews-remoteprzy użyciu następującego poleceniakubectl 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 EOFWstrzyknij przerwanie HTTP 503 dla użytkownika
jasonw usłudzeratingsw klastrze AKS 2, używając następującego poleceniakubectl 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 EOFNiezależnie od tego, czy logujesz się, czy nie, gwiazdki oceny nie mogą być wyświetlone, ponieważ wszystkie żądania do
ratingsusługi zwracają wartość 503.
Treści powiązane
Aby dowiedzieć się więcej o usłudze Azure Kubernetes Application Network, zobacz następujące artykuły: