Konfigurationsupdates für die Modernisierung

In diesem Dokument werden Konfigurationsaktualisierungen beschrieben, die Sie möglicherweise an Ihrem verwalteten Cloud Service Mesh vornehmen müssen, bevor Sie Ihr Mesh von der ISTIOD-Steuerungsebene zur TRAFFIC_DIRECTOR-Steuerungsebene modernisieren.

Im Folgenden finden Sie eine Liste der möglichen Konfigurationsaktualisierungen, die erforderlich sind, um Ihren Cluster für die Modernisierung vorzubereiten. In den einzelnen Abschnitten finden Sie eine Anleitung zum Aktualisieren:

Weitere Informationen zum Modernisierungs-Workflow finden Sie auf der Seite Modernisierung der verwalteten Steuerungsebene.

Von Istio-Secrets zu multicluster_mode migrieren

Multi-Cluster-Secrets werden nicht unterstützt, wenn ein Cluster die TRAFFIC_DIRECTOR-Steuerungsebene verwendet. In diesem Dokument wird beschrieben, wie Sie von der Verwendung von Istio-Multi-Cluster-Secrets zu multicluster_mode migrieren können.

Istio-Secrets im Vergleich zur deklarativen API – Übersicht

Die Open-Source-Istio-Multi-Cluster-Endpunkterkennung funktioniert, indem mit istioctl oder anderen Tools ein Kubernetes-Secret in einem Cluster erstellt wird. Mit diesem Secret kann ein Cluster den Traffic auf einen anderen Cluster im Mesh-Netzwerk verteilen. Die ISTIOD-Steuerungsebene liest dann dieses Secret und beginnt, Traffic an diesen anderen Cluster weiterzuleiten.

Cloud Service Mesh verfügt über eine deklarative API, mit der Sie Multi-Cluster-Traffic steuern können, anstatt Istio-Secrets direkt zu erstellen. Bei dieser API werden Istio-Secrets als Implementierungsdetail behandelt. Sie ist zuverlässiger als das manuelle Erstellen von Istio-Secrets. Zukünftige Cloud Service Mesh-Funktionen hängen von der deklarativen API ab. Sie können diese neuen Funktionen nicht direkt mit Istio-Secrets verwenden. Die deklarative API ist die einzige unterstützte Möglichkeit.

Wenn Sie Istio-Secrets verwenden, sollten Sie so schnell wie möglich zur deklarativen API migrieren. Mit der Einstellung multicluster_mode wird jeder Cluster angewiesen, Traffic an jeden anderen Cluster im Mesh-Netzwerk weiterzuleiten. Mit Secrets ist eine flexiblere Konfiguration möglich, da Sie für jeden Cluster konfigurieren können, an welchen anderen Cluster im Mesh-Netzwerk er Traffic weiterleiten soll. Eine vollständige Liste der Unterschiede zwischen den unterstützten Funktionen der deklarativen API und Istio-Secrets finden Sie unter Unterstützte Funktionen mit Istio-APIs.

Von Istio-Secrets zur deklarativen API migrieren

Wenn Sie Cloud Service Mesh mit automatischer Verwaltung mit der Fleet Feature API bereitgestellt haben, müssen Sie dieser Anleitung nicht folgen. Diese Schritte gelten nur, wenn Sie das Onboarding mit asmcli --managed durchgeführt haben.

Hinweis: Bei diesem Vorgang werden Secrets geändert, die auf einen Cluster verweisen. Dabei werden die Endpunkte entfernt und dann wieder hinzugefügt. Zwischen dem Entfernen und Hinzufügen der Endpunkte wird der Traffic kurzzeitig wieder lokal weitergeleitet, anstatt auf andere Cluster verteilt zu werden. Weitere Informationen finden Sie in diesem GitHub-Problem.

So wechseln Sie von der Verwendung von Istio-Secrets zur deklarativen API: Führen Sie diese Schritte gleichzeitig oder kurz nacheinander aus:

  1. Aktivieren Sie die deklarative API für jeden Cluster in der Flotte, in dem Sie die Endpunkterkennung für mehrere Cluster aktivieren möchten, indem Sie multicluster_mode=connected festlegen. Hinweis: Sie müssen multicluster_mode=disconnected explizit festlegen, wenn der Cluster nicht auffindbar sein soll.

    Verwenden Sie den folgenden Befehl, um die clusterübergreifende Endpunkterkennung für einen Cluster zu aktivieren:

     kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'
    

    Verwenden Sie den folgenden Befehl, um die Endpunkterkennung für einen Cluster zu deaktivieren:

     kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"disconnected"}}'
    
  2. Löschen Sie alte Secrets.

    Nachdem Sie multicluster_mode=connected für Ihre Cluster festgelegt haben, wird für jeden Cluster ein neues Secret für jeden anderen Cluster generiert, für den ebenfalls multicluster_mode=connected festgelegt ist. Das Secret wird im Namespace „istio-system“ platziert und hat das folgende Format:

    istio-remote-secret-projects-PROJECT_NAME-locations-LOCATION-memberships-MEMBERSHIPS
    

    Jedes Secret erhält außerdem das Label istio.io/owned-by: mesh.googleapis.com.

    Nachdem die neuen Secrets erstellt wurden, können Sie alle Secrets löschen, die manuell mit istioctl create-remote-secret erstellt wurden:

    kubectl delete secret SECRET_NAME -n istio-system
    

Prüfen Sie nach der Migration die Anfragemesswerte, um sicherzugehen, dass die Anfragen wie erwartet weitergeleitet werden.

Identitätsföderation von Arbeitslasten für GKE aktivieren

Die Identitätsföderation von Arbeitslasten ist die empfohlene sichere Methode für Google Kubernetes Engine-Arbeitslasten. Dies ermöglicht den Zugriff auf Google Cloud Dienste wie Compute Engine, BigQuery und Machine Learning APIs. Für die Workload Identity-Föderation sind keine manuelle Konfiguration oder weniger sichere Methoden wie Dienstkonto-Schlüsseldateien erforderlich, da IAM-Richtlinien verwendet werden. Weitere Informationen zur Identitätsföderation von Arbeitslasten finden Sie unter Funktionsweise der Identitätsföderation von Arbeitslasten für GKE.

Im folgenden Abschnitt wird beschrieben, wie Sie die Workload Identity-Föderation aktivieren.

Workload Identity-Föderation in Clustern aktivieren

  1. Prüfen Sie, ob die Workload Identity Federation für Ihren Cluster aktiviert ist. Dazu muss für den GKE-Cluster ein Workload Identity-Föderationspool festgelegt sein, der für die Validierung von IAM-Anmeldedaten erforderlich ist.

    Mit dem folgenden Befehl können Sie den für einen Cluster festgelegten Workload Identity-Pool prüfen:

    gcloud container clusters describe CLUSTER_NAME \
      --format="value(workloadIdentityConfig.workloadPool)"
    

    Ersetzen Sie dabei CLUSTER_NAME durch den Namen Ihres GKE-Cluster. Wenn Sie noch keine Standardzone oder -region für gcloud angegeben haben, müssen Sie beim Ausführen dieses Befehls evtl. das Flag --region oder --zone angeben.

  2. Wenn die Ausgabe leer ist, folgen Sie der Anleitung unter Vorhandenen Cluster aktualisieren, um Workload Identity auf vorhandenen GKE-Clustern zu aktivieren.

Workload Identity-Föderation für Knotenpools aktivieren

Nachdem die Identitätsföderation von Arbeitslasten in einem Cluster aktiviert wurde, müssen Knotenpools für die Verwendung des GKE-Metadatenservers konfiguriert werden.

  1. Alle Knotenpools eines Standard-Clusters auflisten Führen Sie den Befehl gcloud container node-pools list aus:

    gcloud container node-pools list --cluster CLUSTER_NAME
    

    Ersetzen Sie dabei CLUSTER_NAME durch den Namen Ihres GKE-Cluster. Wenn Sie noch keine Standardzone oder -region für gcloud angegeben haben, müssen Sie beim Ausführen dieses Befehls evtl. das Flag --region oder --zone angeben.

  2. Prüfen Sie, ob jeder Knotenpool den GKE-Metadatenserver verwendet:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    

    Ersetzen Sie Folgendes:

    • NODEPOOL_NAME durch den Namen Ihres Knotenpools.
    • CLUSTER_NAME durch den Namen Ihres GKE-Cluster.
  3. Wenn die Ausgabe GKE_METADATA nicht enthält, aktualisieren Sie den Knotenpool anhand der Anleitung Vorhandenen Knotenpool aktualisieren.

Verwaltete Container Network Interface (CNI) aktivieren

In diesem Abschnitt wird beschrieben, wie Sie verwaltetes CNI für Cloud Service Mesh in Google Kubernetes Engine aktivieren.

Verwaltete CNI – Übersicht

Die verwaltete Container Network Interface (CNI) ist eine von Google verwaltete Implementierung der Istio-CNI. Das CNI-Plug-in optimiert die Pod-Vernetzung durch die Konfiguration von iptables-Regeln. Dadurch wird die Umleitung des Traffics zwischen Anwendungen und Envoy-Proxys ermöglicht. Es sind keine privilegierten Berechtigungen für den Init-Container mehr erforderlich, der zum Verwalten von iptables benötigt wird.

Das Istio CNI-Plug-in ersetzt den istio-init-Container. Der istio-init-Container war bisher dafür zuständig, die Netzwerkumgebung des Pods einzurichten, um das Abfangen von Traffic für den Istio-Sidecar zu ermöglichen. Das CNI-Plug-in führt dieselbe Netzwerkumleitungsfunktion aus, hat aber den zusätzlichen Vorteil, dass weniger erweiterte Berechtigungen erforderlich sind, was die Sicherheit erhöht.

Aus diesem Grund ist Managed CNI für alle Managed Cloud Service Mesh-Bereitstellungen erforderlich, um die Sicherheit und Zuverlässigkeit zu erhöhen und die Verwaltung und Fehlerbehebung zu vereinfachen.

Auswirkungen auf Init-Container

Init-Container sind spezielle Container, die vor Anwendungscontainern für Einrichtungsaufgaben ausgeführt werden. Einrichtungsvorgänge können Aufgaben wie das Herunterladen von Konfigurationsdateien, die Kommunikation mit externen Diensten oder die Vorinitialisierung der Anwendung umfassen. Bei Init-Containern, die auf Netzwerkzugriff angewiesen sind, können Probleme auftreten, wenn das verwaltete CNI im Cluster aktiviert ist.

So läuft die Einrichtung von Pods mit verwaltetem CNI ab:

  1. Das CNI-Plug-in richtet Pod-Netzwerkschnittstellen ein, weist Pod-IPs zu und leitet Traffic an den Istio-Sidecar-Proxy weiter, der noch nicht gestartet wurde.
  2. Alle Init-Container werden ausgeführt und abgeschlossen.
  3. Der Istio-Sidecar-Proxy wird zusammen mit den Anwendungscontainern gestartet.

Wenn ein Init-Container versucht, ausgehende Netzwerkverbindungen herzustellen oder eine Verbindung zu Diensten innerhalb des Mesh herzustellen, werden die Netzwerkanfragen von den Init-Containern möglicherweise verworfen oder falsch weitergeleitet. Das liegt daran, dass der Istio-Sidecar-Proxy, der den Netzwerkverkehr für den Pod verwaltet, nicht ausgeführt wird, wenn die Anfragen gestellt werden. Weitere Informationen finden Sie in der Istio-CNI-Dokumentation.

Verwaltetes CNI für Ihren Cluster aktivieren

Führen Sie die Schritte in diesem Abschnitt aus, um Managed CNI in Ihrem Cluster zu aktivieren.

  1. Entfernen Sie Netzwerkabhängigkeiten aus Ihrem Init-Container. Sie haben folgende Alternativen:

    • Anwendungslogik oder Container ändern:Sie können Ihre Dienste so ändern, dass die Abhängigkeit von Init-Containern, für die Netzwerkanfragen erforderlich sind, entfernt wird oder dass Netzwerkoperationen in Ihren Anwendungscontainern ausgeführt werden, nachdem der Sidecar-Proxy gestartet wurde.
    • Kubernetes-ConfigMaps oder -Secrets verwenden:Speichern Sie Konfigurationsdaten, die durch die Netzwerkanfrage abgerufen werden, in Kubernetes-ConfigMaps oder -Secrets und stellen Sie sie in Ihren Anwendungscontainern bereit. Alternative Lösungen finden Sie in der Istio-Dokumentation.
  2. Aktivieren Sie Managed CNI in Ihrem Cluster:

    1. Nehmen Sie die folgenden Konfigurationsänderungen vor:

      1. Führen Sie den folgenden Befehl aus, um den controlPlaneRevision zu finden.

        kubectl get controlplanerevision -n istio-system
        
      2. Legen Sie in der benutzerdefinierten Ressource (CR) ControlPlaneRevision (CPR) das Label mesh.cloud.google.com/managed-cni-enabled auf true fest.

        kubectl label controlplanerevision CPR_NAME \
            -n istio-system mesh.cloud.google.com/managed-cni-enabled=true \
            --overwrite
        

        Ersetzen Sie CPR_NAME durch den Wert in der Spalte NAME aus der Ausgabe des vorherigen Schritts.

      3. Legen Sie in der ConfigMap „asm-options“ den Wert ASM_OPTS auf CNI=on fest.

        kubectl patch configmap asm-options -n istio-system \
            -p '{"data":{"ASM_OPTS":"CNI=on"}}'
        
      4. Legen Sie in der benutzerdefinierten Ressource (CR) ControlPlaneRevision (CPR) das Label mesh.cloud.google.com/force-reprovision auf true fest. Diese Aktion löst einen Neustart der Steuerungsebene aus.

        kubectl label controlplanerevision CPR_NAME \
            -n istio-system mesh.cloud.google.com/force-reprovision=true \
            --overwrite
        
    2. Prüfen Sie den Status des Features. Rufen Sie den Funktionsstatus mit dem folgenden Befehl ab:

      gcloud container fleet mesh describe --project FLEET_PROJECT_ID
      

      Ersetzen Sie FLEET_PROJECT_ID durch die ID des Flotten-Hostprojekts. Im Allgemeinen hat die FLEET_PROJECT_ID denselben Namen wie das Projekt.

      • Prüfen Sie, ob die Bedingung MANAGED_CNI_NOT_ENABLED aus servicemesh.conditions entfernt wurde.
      • Es kann bis zu 15–20 Minuten dauern, bis der Status aktualisiert wird. Warten Sie einige Minuten und führen Sie den Befehl dann noch einmal aus.
    3. Sobald controlPlaneManagement.state im Feature-Status des Clusters Active ist, starten Sie die Pods neu.

Umstellung von der nicht standardmäßigen binären Verwendung in Sidecar

In diesem Abschnitt finden Sie Vorschläge, wie Sie Ihre Bereitstellungen mit dem Distroless-Envoy-Proxy-Image kompatibel machen können.

Distroless-Envoy-Proxy-Sidecar-Images

Cloud Service Mesh verwendet zwei Arten von Envoy-Proxy-Sidecar-Images, die auf Ihrer Steuerungsebenenkonfiguration basieren: ein Ubuntu-basiertes Image mit verschiedenen Binärdateien und ein Distroless-Image. Distroless-Basis-Images sind minimale Container-Images, bei denen Sicherheit und Ressourcenoptimierung im Vordergrund stehen, da sie nur die wichtigsten Komponenten enthalten. Die Angriffsfläche wird reduziert, um Sicherheitslücken zu vermeiden. Weitere Informationen finden Sie in der Dokumentation zum Distroless-Proxy-Image.

Binärkompatibilität

Als Best Practice sollten Sie den Inhalt einer Containerlaufzeit auf die erforderlichen Pakete beschränken. Dieser Ansatz verbessert die Sicherheit und das Signal-Rausch-Verhältnis von CVE-Scannen (Common Vulnerabilities and Exposures). Das Distroless-Sidecar-Image hat eine minimale Anzahl von Abhängigkeiten und enthält keine nicht erforderlichen ausführbaren Dateien, Bibliotheken und Debugging-Tools. Daher ist es nicht möglich, einen Shell-Befehl auszuführen oder curl, ping oder andere Fehlerbehebungsfunktionen wie kubectl exec im Container zu verwenden.

Cluster mit distroless-Images kompatibel machen

Wenn Sie keine Lösung für Ihren speziellen Anwendungsfall finden, Google Cloudwenden Sie sich an den Support.

Zum Istio Ingress Gateway migrieren

In diesem Abschnitt erfahren Sie, wie Sie zum Istio Ingress-Gateway migrieren. Es gibt zwei Methoden für die Migration zum Istio Ingress Gateway:

  1. Stufenweise Migration mit Traffic-Aufteilung

    Bei dieser Methode wird die Minimierung von Unterbrechungen priorisiert. Sie senden den Traffic inkrementell an das neue Istio-Gateway. So können Sie die Leistung bei einem kleinen Prozentsatz von Anfragen überwachen und bei Bedarf schnell zurücksetzen. Die Konfiguration der Layer 7-Traffic-Aufteilung kann für einige Anwendungen schwierig sein. Daher müssen Sie beide Gatewaysysteme während der Umstellung gleichzeitig verwalten. Eine Anleitung finden Sie unter Phased Migration with traffic splitting.

  2. Direkte Migration

    Bei dieser Methode wird der gesamte Traffic gleichzeitig zum neuen Istio-Gateway umgeleitet, sobald Sie die Tests abgeschlossen haben. Der Vorteil dieses Ansatzes ist die vollständige Trennung von der Infrastruktur des alten Gateways. So kann das neue Gateway flexibel konfiguriert werden, ohne dass die Einschränkungen der vorhandenen Einrichtung berücksichtigt werden müssen. Es besteht jedoch ein erhöhtes Risiko für Ausfallzeiten, falls während der Umstellung unerwartete Probleme mit dem neuen Gateway auftreten. Eine Anleitung finden Sie unter Direkte Migration.

In den folgenden Migrationsbeispielen wird davon ausgegangen, dass Sie einen HTTP-Dienst (httpbin) im Anwendungsnamespace (Standard) ausführen und extern über die Kubernetes Gateway API verfügbar machen. Die relevanten Konfigurationen sind:

  • Gateway: k8-api-gateway (im Namespace istio-ingress) – konfiguriert für das Monitoring von HTTP-Traffic auf Port 80 für alle Hostnamen, die mit .example.com enden.
  • HTTPRoute: httpbin-route (im Namespace default) – leitet alle HTTP-Anfragen mit dem Hostnamen httpbin.example.com und einem Pfad, der mit /get beginnt, an den Dienst httpbin im Namespace default weiter.
  • Die httpbin-Anwendung ist über die externe IP-Adresse 34.57.246.68 zugänglich.

Einfaches Gateway-Diagramm

Stufenweise Migration mit Trafficaufteilung

Neues Istio-Ingress-Gateway bereitstellen

  1. Stellen Sie ein neues Ingress-Gateway gemäß der Anleitung im Abschnitt Beispiel-Gateway bereitstellen bereit und passen Sie die Beispielkonfigurationen an Ihre Anforderungen an. Die Beispiele im Repository anthos-service-mesh sind für die Bereitstellung eines istio-ingressgateway-LoadBalancer-Dienstes und der entsprechenden ingress-gateway-Pods vorgesehen.

    Beispiel für eine Gateway-Ressource (istio-ingressgateway.yaml)

     apiVersion: networking.istio.io/v1beta1
     kind: Gateway
     metadata:
       name: istio-api-gateway
       namespace: GATEWAY_NAMESPACE
     spec:
       selector:
         istio: ingressgateway  # The selector should match the ingress-gateway pod labels.
       servers:
       - port:
           number: 80
           name: http
           protocol: HTTP
         hosts:   # or specific hostnames if needed
         - "httpbin.example.com"
    
  2. Wenden Sie die Gateway-Konfiguration an, um den Traffic zu verwalten:

    kubectl apply -f istio-ingressgateway.yaml -n GATEWAY_NAMESPACE
    

    Achten Sie darauf, dass „spec.selector“ in Ihrer Gateway-Ressource mit den Labels Ihrer ingress-gateway-Pods übereinstimmt. Wenn die ingress-gateway-Pods beispielsweise das Label istio=ingressgateway haben, muss in Ihrer Gateway-Konfiguration auch das Label istio=ingressgateway ausgewählt werden.

Erstes Routing für das neue Gateway konfigurieren

  1. Definieren Sie die ersten Routingregeln für Ihre Anwendung mit einem VirtualService von Istio.

    Beispiel für VirtualService (my-app-vs-new.yaml):

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-vs
      namespace: APPLICATION_NAMESPACE
    spec:
        gateways:
        - istio-ingress/istio-api-gateway  # Replace with <gateway-namespace/gateway-name>
        hosts:
        - httpbin.example.com
        http:
        - match:
          - uri:
              prefix: /get
          route:
          - destination:
              host: httpbin
              port:
                number: 8000
    
  2. Wenden Sie den VirtualService an:

    kubectl apply -f my-app-vs-new.yaml -n MY_APP_NAMESPACE
    

Über das neu bereitgestellte Istio-Ingress-Gateway auf den Backend-Dienst (httpbin) zugreifen

  1. Legen Sie die Umgebungsvariable „Ingress Host“ auf die externe IP-Adresse fest, die dem kürzlich bereitgestellten istio-ingressgateway-Load-Balancer zugeordnet ist:

    export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    
  2. Prüfen Sie, ob die Anwendung (httpbin) über das neue Gateway erreichbar ist:

    curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
    

    Die Ausgabe sieht etwa so aus:

    HTTP/1.1 200 OK
    

Anfragefluss mit dem neuen Istio-Ingress-Gateway

Vorhandenen Ingress für die Trafficaufteilung ändern

Nachdem Sie die erfolgreiche Einrichtung des neuen Gateways (z. B. istio-api-gateway) bestätigt haben, können Sie einen Teil Ihres Traffics darüber weiterleiten. Aktualisieren Sie dazu Ihre aktuelle HTTPRoute, um einen kleinen Prozentsatz des Traffics an das neue Gateway weiterzuleiten, während der größere Teil weiterhin das vorhandene Gateway (k8-api-gateway) verwendet.

  1. Öffnen Sie die httproute zum Bearbeiten:

    kubectl edit httproute httpbin-route -n MY_APP_NAMESPACE
    
  2. Fügen Sie einen neuen Backend-Verweis hinzu, der auf den Loadbalancer-Dienst des neuen Ingress-Gateways verweist, mit einer anfänglichen Gewichtung von 10 %. Aktualisieren Sie die Gewichtung für das Backend des alten Gateways.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-route
      namespace: MY_APP_NAMESPACE  # your application's namespace
    spec:
      parentRefs:
      - name: k8-api-gateway
        namespace: istio-ingress
      hostnames: ["httpbin.example.com"]
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /get
        backendRefs:
        - name: httpbin
          port: 8000
          weight: 90
        - name: istio-ingressgateway # Newly deployed load balancer service
          namespace: GATEWAY_NAMESPACE
          port: 80
          weight: 10
    
  3. Berechtigung für Namespace-übergreifende Referenzierung mit Referenzgewährung erteilen.

    Damit Ihre HTTPRoute im Anwendungs-Namespace (Standard) auf den loadbalancer-Dienst im Gateway-Namespace (istio-ingress) zugreifen kann, müssen Sie möglicherweise eine Referenzzuweisung erstellen. Diese Ressource dient als Sicherheitskontrolle, mit der explizit definiert wird, welche Namespace-übergreifenden Referenzen zulässig sind.

    Im Folgenden wird ein Beispiel für eine Referenzgewährung beschrieben:istio-ingress-grant.yaml

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: ReferenceGrant
    metadata:
      name: istio-ingressgateway-grant
      namespace: istio-ingress # Namespace of the referenced resource
    spec:
      from:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute 
        namespace: MY_APP_NAMESPACE # Namespace of the referencing resource
      to:
      - group: ""               # Core Kubernetes API group for Services
        kind: Service
        name: istio-ingressgateway # Loadbalancer Service of the new ingress gateway
    
  4. So wenden Sie die Referenzzuweisung an:

    kubectl apply -f istio-ingress-grant.yaml -n GATEWAY_NAMESPACE
    
  5. Anfragen an die vorhandene externe IP-Adresse prüfen (z. B. 34.57.246.68) werden nicht als Fehler angezeigt. Im Folgenden wird ein Skript zum Prüfen von Anfragen beschrieben, die fehlgeschlagen sind:check-traffic-flow.sh

    # Update the following values based on your application setup
    external_ip="34.57.246.68" # Replace with existing external IP
    url="http://$external_ip/get"
    host_name="httpbin.example.com"
    
    # Counter for successful requests
    success_count=0
    
    # Loop 50 times
    for i in {1..50}; do
      # Perform the curl request and capture the status code
      status_code=$(curl -s -HHost:"$host_name" -o /dev/null -w "%{http_code}" "$url")
      # Check if the request was successful (status code 200)
      if [ "$status_code" -eq 200 ]; then
        ((success_count++))  # Increment the success counter
      else
        echo "Request $i: Failed with status code $status_code"
      fi
    done
    
    # After the loop, check if all requests were successful
    if [ "$success_count" -eq 50 ]; then
      echo "All 50 requests were successful!"
    else
      echo "Some requests failed.  Successful requests: $success_count"
    fi
    
  6. Führen Sie das Script aus, um zu bestätigen, dass unabhängig vom Traffic-Pfad keine Anfragen fehlschlagen:

    chmod +x check-traffic-flow.sh
    ./check-traffic-flow.sh
    

Anfragefluss mit Traffic, der zwischen dem vorhandenen Gateway und dem neuen Istio-Ingress-Gateway aufgeteilt wird

Prozentsatz des Traffics langsam erhöhen

Wenn für die vorhandene externe IP-Adresse (z. B. 34.57.246.68) keine Anforderungsfehler auftreten, leiten Sie nach und nach mehr Traffic an das neue Istio Ingress-Gateway weiter. Dazu passen Sie die Backend-Gewichtungen in Ihrer HTTPRoute an. Erhöhen Sie die Gewichtung für istio-ingressgateway und verringern Sie die Gewichtung für das alte Gateway in kleinen Schritten, z. B. um 10%, 20 % usw.

Verwenden Sie den folgenden Befehl, um Ihre vorhandene HTTPRoute zu aktualisieren:

kubectl edit httproute httpbin-route -n MY_APP_NAMESPACE

Vollständige Trafficmigration und Entfernen des alten Gateways

  1. Wenn das neue Istio Ingress Gateway eine stabile Leistung und eine erfolgreiche Anfragebearbeitung zeigt, leiten Sie den gesamten Traffic dorthin um. Aktualisieren Sie HTTPRoute, um das Backend-Gewicht des alten Gateways auf 0 und das des neuen Gateways auf 100 festzulegen.

  2. Sobald der gesamte Traffic an das neue Gateway weitergeleitet wird, aktualisieren Sie die externen DNS-Einträge für den Hostnamen Ihrer Anwendung (z. B. httpbin.example.com), sodass sie auf die externe IP-Adresse des Load-Balancer-Dienstes verweisen, der in Neues Istio Ingress-Gateway bereitstellen erstellt wurde.

  3. Löschen Sie schließlich das alte Gateway und die zugehörigen Ressourcen:

    kubectl delete gateway OLD_GATEWAY -n GATEWAY_NAMESPACE
    kubectl delete service OLD_GATEWAY_SERVICE -n GATEWAY_NAMESPACE
    

Direkte Migration

Neues Istio-Ingress-Gateway bereitstellen

  1. Stellen Sie ein neues Ingress-Gateway gemäß der Anleitung im Abschnitt Beispiel-Gateway bereitstellen bereit und passen Sie die Beispielkonfigurationen an Ihre Anforderungen an. Die Beispiele im Repository anthos-service-mesh sind für die Bereitstellung eines istio-ingressgateway-LoadBalancer-Dienstes und der entsprechenden ingress-gateway-Pods vorgesehen.

    Beispiel für eine Gateway-Ressource (istio-ingressgateway.yaml)

     apiVersion: networking.istio.io/v1beta1
     kind: Gateway
     metadata:
       name: istio-api-gateway
       namespace: GATEWAY_NAMESPACE
     spec:
       selector:
         istio: ingressgateway  # The selector should match the ingress-gateway pod labels.
       servers:
       - port:
           number: 80
           name: http
           protocol: HTTP
         hosts:   # or specific hostnames if needed
         - "httpbin.example.com"
    
  2. Wenden Sie die Gateway-Konfiguration an, um den Traffic zu verwalten:

    kubectl apply -f istio-ingressgateway.yaml -n GATEWAY_NAMESPACE
    

    Achten Sie darauf, dass „spec.selector“ in Ihrer Gateway-Ressource mit den Labels Ihrer ingress-gateway-Pods übereinstimmt. Wenn die ingress-gateway-Pods beispielsweise das Label istio=ingressgateway haben, muss in Ihrer Gateway-Konfiguration auch das Label istio=ingressgateway ausgewählt werden.

Erstes Routing für das neue Gateway konfigurieren

  1. Definieren Sie die ersten Routingregeln für Ihre Anwendung mit einem VirtualService von Istio.

    Beispiel für VirtualService (my-app-vs-new.yaml):

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-vs
      namespace: APPLICATION_NAMESPACE
    spec:
        gateways:
        - istio-ingress/istio-api-gateway  # Replace with <gateway-namespace/gateway-name>
        hosts:
        - httpbin.example.com
        http:
        - match:
          - uri:
              prefix: /get
          route:
          - destination:
              host: httpbin
              port:
                number: 8000
    
  2. Wenden Sie den VirtualService an:

    kubectl apply -f my-app-vs-new.yaml -n MY_APP_NAMESPACE
    

Über das neu bereitgestellte Istio-Ingress-Gateway auf den Backend-Dienst (httpbin) zugreifen

  1. Legen Sie die Umgebungsvariable „Ingress Host“ auf die externe IP-Adresse fest, die dem kürzlich bereitgestellten istio-ingressgateway-Load-Balancer zugeordnet ist:

    export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    
  2. Prüfen Sie, ob die Anwendung (httpbin) über das neue Gateway erreichbar ist:

    curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
    

    Die Ausgabe sieht etwa so aus:

    HTTP/1.1 200 OK
    

Anfragefluss mit dem neuen Istio-Ingress-Gateway

Neues Gateway testen und überwachen

  1. Testen Sie alle Routingregeln, validieren Sie die TLS-Konfiguration, Sicherheitsrichtlinien und andere Funktionen. Führen Sie einen Lasttest durch, um zu prüfen, ob das neue Gateway den erwarteten Traffic verarbeiten kann.

  2. Sobald das neue Gateway vollständig getestet wurde, aktualisieren Sie die externen DNS-Einträge für den Hostnamen Ihrer Anwendung (z. B. httpbin.example.com), sodass sie auf die externe IP-Adresse des Load-Balancer-Dienstes verweisen, der in Neues Istio-Ingress-Gateway bereitstellen erstellt wurde.

  3. Behalten Sie wichtige Messwerte wie die Erfolgsrate von Anfragen, die Latenz, die Fehlerraten und die Ressourcennutzung Ihrer Anwendungs-Pods im Blick, um die Stabilität mit dem neuen Istio Ingress-Gateway zu prüfen. Sobald die neue Verbindung stabil ist, können Sie das alte Gateway und die zugehörigen Ressourcen löschen.

    kubectl delete gateway OLD_GATEWAY -n GATEWAY_NAMESPACE
    kubectl delete service OLD_GATEWAY_SERVICE -n GATEWAY_NAMESPACE
    

Wichtige Hinweise: Wenn Ihre Anwendung HTTPS erfordert, müssen TLS-Zertifikate und -Konfigurationen auf dem neuen Istio-Ingress-Gateway korrekt eingerichtet sein. Weitere Informationen finden Sie unter TLS-Terminierung im Ingress-Gateway einrichten.

Mehrere Steuerungsebenen korrigieren

Cloud Service Mesh unterstützte zuvor das Onboarding mit asmcli (eingestellt), wodurch die Bereitstellung mehrerer Steuerungsebenen nicht blockiert wurde. In Cloud Service Mesh wird jetzt die Best Practice erzwungen, nur einen Kanal pro Cluster bereitzustellen, der dem Clusterkanal entspricht. Die Verwendung mehrerer bereitgestellter Kanäle im selben Cluster wird nicht unterstützt.

Wenn Sie Canary-Bereitstellungen für neue Mesh-Versionen im Rapid Channel durchführen möchten, bevor sie im Stable Channel oder Regular Channel verfügbar sind, benötigen Sie zwei verschiedene Cluster mit jeweils einem separaten Channel. Beachten Sie, dass Channels vom GKE-Cluster-Channel gesteuert werden und Mesh keinen separaten Channel hat.

Ob du mehrere Kanäle hast, kannst du daran erkennen, dass in deiner Mitgliedschaft der Status UNSUPPORTED_MULTIPLE_CONTROL_PLANES angezeigt wird. Wenn diese Warnung nicht angezeigt wird, sind Sie nicht betroffen und können diesen Abschnitt überspringen.

  1. Führen Sie den folgenden Befehl aus, um zu prüfen, ob Ihr Cluster mehrere Channels für die Steuerungsebene hat:

    gcloud container fleet mesh describe
    

    Die Ausgabe sieht etwa so aus:

    ...
    projects/.../locations/global/memberships/my-membership:
        servicemesh:
          conditions:
          - code: UNSUPPORTED_MULTIPLE_CONTROL_PLANES
            details: 'Using multiple control planes is not supported. Please remove a control plane from your cluster.'
            documentationLink: https://cloud.google.com/service-mesh/v1.26/docs/migrate/modernization-configuration-updates#multiple_control_planes
            severity: WARNING
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed-stable'
            implementation: ISTIOD
            state: ACTIVE
    ...
    
  2. Wenn die Bedingung UNSUPPORTED_MULTIPLE_CONTROL_PLANES angezeigt wird, ermitteln Sie, welche Channels für Ihren Cluster vorhanden sind:

    kubectl get controlplanerevisions -n istio-system
    

    Die Ausgabe sieht etwa so aus:

    NAME                 RECONCILED   STALLED   AGE
    asm-managed-stable   True         False     97d
    asm-managed          True         False     97d
    asm-managed-rapid    True         False     97d
    

    In diesem Beispiel wurden alle drei Channels bereitgestellt:

    • asm-managed-stable -> STABIL
    • asm-managed -> REGULAR
    • asm-managed-rapid -> RAPID

    Wenn nur ein Ergebnis angezeigt wird, ist nur ein Kanal auf deinem Cluster bereitgestellt. Du kannst die restlichen Schritte überspringen.

    Wenn zwei oder mehr Ergebnisse angezeigt werden, folge den restlichen Schritten, um die zusätzlichen Kanäle zu entfernen.

Arbeitslasten auf einem Channel konsolidieren

Bevor Sie zusätzliche Channels entfernen können, müssen Sie dafür sorgen, dass Ihre Arbeitslasten nur einen einzigen Channel verwenden.

  1. Alle Labels, die Sie in Ihrem Cluster verwenden, finden Sie so:

    kubectl get namespaces -l istio.io/rev=RELEASE_CHANNEL
    

    Ersetzen Sie RELEASE_CHANNEL je nach Ausgabe des vorherigen Befehls durch asm-managed-stable, asm-managed oder asm-managed-rapid. Wiederholen Sie diesen Schritt für jeden bereitgestellten Channel.

    Die Ausgabe sieht etwa so aus:

    NAME      STATUS   AGE
    default   Active   110d
    

    In diesem Beispiel wird der Standard-Namespace mit dem regulären Channel injiziert.

    Wenn alle Ihre Arbeitslasten bereits denselben Channel verwenden, können Sie mit Schritt 4 fortfahren. Andernfalls fahren Sie mit diesem Abschnitt fort.

  2. Ändern Sie die Labels so, dass nur ein Channel verwendet wird:

    • In einigen Fällen können Pods auch direkt mit dem Label sidecar.istio.io/inject eingefügt werden. Prüfen Sie auch diese.
    • Sie können istio-injection=enabled-Labels für diesen Schritt ignorieren. Namespaces mit diesem Label werden automatisch an den verbleibenden Channel im Cluster angepasst.
    • Wenn Sie einen Kanal auswählen, den Sie behalten möchten, sollten Sie den Kanal auswählen, der mit Ihrem GKE-Clusterkanal identisch ist. Wenn dieser Kanal nicht vorhanden ist, wählen Sie einen der aktiven Kanäle aus.
    • Es spielt keine Rolle, welchen Kanal Sie auswählen. Der GKE-Cluster-Channel bestimmt, welche Version von Mesh Sie erhalten, nicht der Mesh-Channel.
    • Prüfen Sie die Meshconfig-Konfiguration zwischen allen aktiven Kanälen, die verwendet werden, um sicherzustellen, dass es keine Unterschiede gibt. Jeder Channel verwendet eine separate ConfigMap für die Konfiguration. Wenn Sie also zwei Channels in einem zusammenfassen, sollte das Verhalten der beiden Channels konsistent sein.kubectl get configmap istio-asm-managed{-rapid | -stable} -n istio-system -o yaml
    kubectl label namespace NAMESPACE istio.io/rev- istio-injection=enabled --overwrite
    

    Ersetzen Sie NAMESPACE durch den Namen Ihres Namespace:

    Am besten verwenden Sie istio-injection=enabled. Wenn Sie dieses Label jedoch nicht verwenden möchten, können Sie auch istio.io/rev=RELEASE_CHANNEL verwenden.

    Nachdem Sie das Label für einen Namespace oder Pod geändert haben, müssen Sie alle Arbeitslasten neu starten, damit sie von der richtigen Steuerungsebene eingefügt werden.

Zusätzliche Channels entfernen

Wenn Sie bestätigt haben, dass alle Ihre Arbeitslasten auf einem einzigen Channel ausgeführt werden, können Sie die nicht verwendeten zusätzlichen Channels entfernen. Wenn alle drei Release-Channels bereitgestellt wurden, führen Sie die folgenden Befehle für jeden Channel aus.

  1. Löschen Sie die zusätzliche ControlPlaneRevision-Ressource:

    kubectl delete controlplanerevision RELEASE_CHANNEL -n istio-system
    

    Ersetzen Sie RELEASE_CHANNEL durch asm-managed-stable, asm-managed oder asm-managed-rapid.

  2. Löschen Sie das MutatingWebhookConfiguration:

    kubectl delete mutatingwebhookconfiguration istiod-RELEASE_CHANNEL
    
  3. Löschen Sie die meshconfig-ConfigMap:

    kubectl delete configmap istio-RELEASE_CHANNEL
    

Automatische Verwaltung aktivieren

  1. Führen Sie den folgenden Befehl aus, um die automatische Verwaltung zu aktivieren:

    gcloud container fleet mesh update \
        --management automatic \
        --memberships MEMBERSHIP_NAME \
        --project PROJECT_ID \
        --location MEMBERSHIP_LOCATION
    

    Ersetzen Sie Folgendes:

    • MEMBERSHIP_NAME ist der Mitgliedschaftsname, der bei der Registrierung des Clusters bei der Flotte aufgeführt wurde.
    • PROJECT_ID ist die Projekt-ID Ihres Projekts.
    • MEMBERSHIP_LOCATION ist der Standort deiner Mitgliedschaft (entweder eine Region oder global). Du kannst den Standort deiner Mitgliedschaft unter gcloud container fleet memberships list --project PROJECT_ID prüfen.
  2. So prüfen Sie, ob die automatische Verwaltung aktiviert ist:

    gcloud container fleet mesh describe
    

    Die Ausgabe sieht etwa so aus:

    ...
    membershipSpecs:
      projects/.../locations/us-central1/memberships/my-member:
        mesh:
          management: MANAGEMENT_AUTOMATIC
    membershipStates:
      projects/.../locations/us-central1/memberships/my-member:
        servicemesh:
          conditions:
          - code: VPCSC_GA_SUPPORTED
            details: This control plane supports VPC-SC GA.
            documentationLink: http://cloud.google.com/service-mesh/v1.26/docs/managed/vpc-sc
            severity: INFO
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed'
            implementation: TRAFFIC_DIRECTOR
            state: ACTIVE
          dataPlaneManagement:
            details:
            - code: OK
              details: Service is running.
            state: ACTIVE
        state:
          code: OK
          description: |-
            Revision ready for use: asm-managed.
            All Canonical Services have been reconciled successfully.
    ...