Cloud Service Mesh anhand eines Beispiels: mTLS


In Cloud Service Mesh 1.5 und höher ist die automatische gegenseitige TLS-Authentifizierung (automTLS) standardmäßig aktiviert. Bei automatischem mTLS erkennt ein Client-Sidecar-Proxy automatisch, ob der Server einen Sidecar hat. Der Client-Sidecar-Proxy sendet an Arbeitslasten mit Sidecars mTLS und an Arbeitslasten ohne Sidecars Klartext-Traffic. Die Dienste akzeptieren jedoch sowohl Klartext- als auch mTLS-Traffic. Wenn Sie Ihren Pods Sidecar-Proxys hinzufügen, sollten Sie Ihre Dienste auch so konfigurieren, dass sie nur mTLS-Traffic akzeptieren.

Mit Cloud Service Mesh können Sie mTLS außerhalb Ihres Anwendungscodes erzwingen, indem Sie eine einzelne YAML-Datei anwenden. Mit Cloud Service Mesh können Sie eine Authentifizierungsrichtlinie flexibel auf das gesamte Service Mesh, einen Namespace oder eine einzelne Arbeitslast anwenden.

Gegenseitiges mTLS

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen. Neuen Google Cloud-Nutzern steht möglicherweise eine kostenlose Testversion zur Verfügung.

Nach Abschluss dieser Anleitung können Sie weitere Kosten durch Löschen von erstellten Ressourcen vermeiden. Weitere Informationen finden Sie unter Bereinigen.

Hinweise

  • Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für Ihr Projekt aktiviert ist.

  • Cloud Service Mesh in einem GKE-Cluster installieren und ein Ingress-Gateway bereitstellen Wenn Sie für diese Anleitung einen Cluster einrichten müssen, lesen Sie die Kurzanleitung zu Cloud Service Mesh, die Sie durch Folgendes führt:

    • GKE-Cluster erstellen
    • Stellt das verwaltete Cloud Service Mesh bereit.
    • Ingress-Gateway bereitstellen.
    • Bereitstellung der Beispielanwendung Online Boutique aus dem Repository anthos-service-mesh-packages, die gegenüber dem ursprünglichen Satz von Manifesten in microservices-demo-Repository verändert wurde Gemäß den Best Practices wird jeder Dienst in einem separaten Namespace mit einem eigenen Dienstkonto bereitgestellt.
  • Erstellen Sie einen TestCurl-Pod, um Klartext-Traffic zu Testzwecken zu senden.

      apiVersion: v1
      kind: Pod
      metadata:
        name: testcurl
        namespace: default
        annotations:
          sidecar.istio.io/inject: "false"
      spec:
        containers:
        - name: curl
          image: curlimages/curl
          command: ["sleep", "600"]
    

Auf Online Boutique zugreifen

  1. Legen Sie den aktuellen Kontext für kubectl auf dem Cluster fest, in dem Sie Online Boutique bereitgestellt haben:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. Listen Sie die Dienste im Namespace frontend auf:

    kubectl get services -n frontend
    

    Beachten Sie, dass frontend-external ein LoadBalancer ist und eine externe IP-Adresse hat. Die Beispielanwendung enthält einen Dienst, der ein Load-Balancer ist, sodass sie ohne Cloud Service Mesh in GKE bereitgestellt werden kann.

  3. Rufen Sie die Anwendung in Ihrem Browser mit der externen IP-Adresse des Dienstes frontend-external auf:

    http://FRONTEND_EXTERNAL_IP/
    
  4. Mit Cloud Service Mesh können Sie ein Ingress-Gateway bereitstellen. Sie können auch über die externe IP-Adresse des Ingress-Gateways auf Online Boutique zugreifen. Rufen Sie die externe IP-Adresse der Anwendung ab: Ersetzen Sie die Platzhalter durch die folgenden Informationen:

    • GATEWAY_SERVICE_NAME ist der Name des Ingress-Gateway-Dienstes. Wenn Sie das Beispielgateway ohne Änderung bereitgestellt oder das Standardgateway für eingehenden Traffic bereitgestellt haben, lautet der Name istio-ingressgateway.
    • GATEWAY_NAMESPACE ist der Namespace, in dem Sie das Ingress-Gateway bereitgestellt haben. Wenn Sie das Standard-Gateway für eingehenden Traffic bereitgestellt haben, lautet der Namespace istio-system.
    kubectl get service GATEWAY_NAME -n GATEWAY_NAMESPACE
    
  5. Öffnen Sie einen weiteren Tab in Ihrem Browser und rufen Sie die Anwendung mithilfe der externen IP-Adresse des Ingress-Gateways auf:

    http://INGRESS_GATEWAY_EXTERNAL_IP/
    
  6. Führen Sie den folgenden Befehl aus, um curl für den frontend-Dienst mit reinem HTTP aus einem anderen Pod durchzuführen. Da sich die Dienste in verschiedenen Namespaces befinden, müssen Sie den DNS-Namen des Dienstes frontend anpassen.

    kubectl debug --image istio/base --target istio-proxy -it \
      $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \
      -n product-catalog -- \
      curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    Ihre Anfrage ist mit dem Status 200 erfolgreich, da standardmäßig sowohl TLS- als auch Klartext-Traffic akzeptiert wird.

Gegenseitiges TLS pro Namespace aktivieren

Für mTLS wenden Sie eine PeerAuthentication-Richtlinie mit kubectl an.

  1. Speichern Sie die folgende Authentifizierungsrichtlinie als mtls-namespace.yaml.

    cat <<EOF > mtls-namespace.yaml
    apiVersion: "security.istio.io/v1beta1"
    kind: "PeerAuthentication"
    metadata:
      name: "namespace-policy"
    spec:
      mtls:
        mode: STRICT
    EOF
    

    Die Zeile mode: STRICT in der YAML-Datei konfiguriert die Dienste so, dass sie nur mTLS akzeptieren. mode ist standardmäßig auf PERMISSIVE gesetzt. Damit werden Dienste so konfiguriert, dass sie sowohl Klartext als auch mTLS akzeptieren.

  2. Wenden Sie die Authentifizierungsrichtlinie an, um alle Online Boutique-Dienste so zu konfigurieren, dass sie nur mTLS akzeptieren:

    for ns in ad cart checkout currency email frontend loadgenerator \
         payment product-catalog recommendation shipping; do
    kubectl apply -n $ns -f mtls-namespace.yaml
    done
    

    Erwartete Ausgabe:

    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created

  3. Öffnen Sie in Ihrem Browser den Tab, der über die externe IP-Adresse des Dienstes frontend-external auf die Online-Boutique zugreift:

    http://FRONTEND_EXTERNAL_IP/
    
  4. Aktualisieren Sie die Seite. Der Browser zeigt den folgenden Fehler an:

    Website ist nicht erreichbar

    Durch das Aktualisieren der Seite wird Klartext an den frontend-Dienst gesendet. Aufgrund der STRICT-Authentifizierungsrichtlinie blockiert der Sidecar-Proxy die Anfrage an den Dienst.

  5. Wechseln Sie in Ihrem Browser zu dem Tab, der über die externe IP-Adresse des istio-ingressgateway auf die Online Boutique zugreift, und aktualisieren Sie die Seite, die erfolgreich angezeigt wird. Wenn Sie über das Ingress-Gateway auf die Online Boutique zugreifen, verwendet die Anfrage den folgenden Pfad:

    Gegenseitiges mTLS

    mTLS-Authentifizierungsablauf:

    1. Der Browser sendet eine Klartext-HTTP-Anfrage an den Server.
    2. Der Ingress-Gateway-Proxy-Container fängt die Anfrage ab.
    3. Der Ingress-Gateway-Proxy führt einen TLS-Handshake mit dem serverseitigen Proxy aus (in diesem Beispiel den Frontend-Dienst). Dieser Handshake umfasst einen Austausch von Zertifikaten. Diese Zertifikate werden vom Cloud Service Mesh vorab in die Proxy-Container geladen.
    4. Der Ingress-Gateway-Proxy führt eine sichere Namensprüfung für das Serverzertifikat durch und bestätigt so, dass der Server über eine autorisierte Identität ausgeführt wird.
    5. Die Ingress-Gateway- und Serverproxys stellen eine gegenseitige TLS-Verbindung her und der Serverproxy leitet die Anfrage an den Server des Anwendungscontainers (den Frontend-Dienst) weiter.
  6. Führen Sie den folgenden Befehl aus, um curl für den frontend-Dienst mit reinem HTTP aus einem anderen Pod durchzuführen.

    kubectl exec testcurl -n default -- curl \
      http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    Ihre Anfrage schlägt fehl, da wir Klartext-Traffic von einer Arbeitslast ohne Sidecar senden, auf die die Richtlinie peerAuthentication STRICT angewendet wird.

Authentifizierungsrichtlinien suchen und löschen

  1. Eine Liste aller PeerAuthentication-Richtlinien im Service Mesh:

    kubectl get peerauthentication --all-namespaces
    

    Die Ausgabe sieht in etwa so aus:

    NAMESPACE         NAME               MODE     AGE
    ad                namespace-policy   STRICT   17m
    cart              namespace-policy   STRICT   17m
    checkout          namespace-policy   STRICT   17m
    currency          namespace-policy   STRICT   17m
    email             namespace-policy   STRICT   17m
    frontend          namespace-policy   STRICT   17m
    loadgenerator     namespace-policy   STRICT   17m
    payment           namespace-policy   STRICT   17m
    product-catalog   namespace-policy   STRICT   17m
    recommendation    namespace-policy   STRICT   17m
    shipping          namespace-policy   STRICT   17m
    
  2. Löschen Sie die Authentifizierungsrichtlinie aus allen Namespaces für Online Boutique:

    for ns in ad cart checkout currency email frontend loadgenerator payment \
      product-catalog recommendation shipping; do
        kubectl delete peerauthentication -n $ns namespace-policy
    done;
    

    Erwartete Ausgabe:

    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    
  3. Greifen Sie über die externe IP-Adresse des Dienstes frontend-external auf die Online Boutique zu und aktualisieren Sie die Seite. Die Seite wird wie erwartet angezeigt.

  4. Führen Sie den folgenden Befehl aus, um curl für den frontend-Dienst mit reinem HTTP aus einem anderen Pod durchzuführen.

    kubectl debug --image istio/base --target istio-proxy -it \
      $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \
      -n product-catalog -- \
      curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    Ihre Anfrage ist mit dem Status 200 erfolgreich, da standardmäßig sowohl TLS- als auch Klartext-Traffic akzeptiert wird.

Wenn Sie die Seite in der Google Cloud Console aktualisieren, auf der die Liste Arbeitslasten angezeigt wird, lautet der mTLS-Status jetzt Permissive.

Gegenseitiges TLS pro Arbeitslast aktivieren

Zum Festlegen einer PeerAuthentication-Richtlinie für eine bestimmte Arbeitslast müssen Sie den Abschnitt selector konfigurieren und die Labels angeben, die der gewünschten Arbeitslast entsprechen. Cloud Service Mesh kann jedoch keine Richtlinien auf Arbeitslastebene für ausgehenden mTLS-Traffic zu einem Dienst aggregieren. Sie müssen eine Zielregel konfigurieren, um dieses Verhalten zu verwalten.

  1. Wenden Sie eine Authentifizierungsrichtlinie auf eine bestimmte Arbeitslast an. Beachten Sie, wie die folgende Richtlinie Labels und Selektoren verwendet, um die jeweilige frontend-Bereitstellung anzusteuern.

    cat <<EOF | kubectl apply -n frontend -f -
    apiVersion: "security.istio.io/v1beta1"
    kind: "PeerAuthentication"
    metadata:
      name: "frontend"
      namespace: "frontend"
    spec:
      selector:
        matchLabels:
          app: frontend
      mtls:
        mode: STRICT
    EOF
    

    Erwartete Ausgabe:

    peerauthentication.security.istio.io/frontend created
  2. Konfigurieren Sie eine übereinstimmende Zielregel:

    cat <<EOF | kubectl apply -n frontend -f -
    apiVersion: "networking.istio.io/v1alpha3"
    kind: "DestinationRule"
    metadata:
      name: "frontend"
    spec:
      host: "frontend.demo.svc.cluster.local"
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
    EOF
    

    Erwartete Ausgabe:

    destinationrule.networking.istio.io/frontend created
  3. Greifen Sie über die externe IP-Adresse des Dienstes frontend-external auf die Online Boutique zu und aktualisieren Sie die Seite. Die Seite wird nicht angezeigt, weil der frontend service auf STRICT mTLS gesetzt ist und der Sidecar-Proxy die Anfrage blockiert.

  4. Führen Sie den folgenden Befehl aus, um curl für den frontend-Dienst mit reinem HTTP aus einem anderen Pod durchzuführen.

    kubectl exec testcurl -n default -- curl \
      http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    Ihre Anfrage schlägt fehl, da wir Klartext-Traffic von einer Arbeitslast ohne Sidecar senden, auf die die Richtlinie peerAuthentication STRICT angewendet wird.

  5. Löschen Sie die Authentifizierungsrichtlinie:

    kubectl delete peerauthentication -n frontend frontend
    

    Erwartete Ausgabe:

    peerauthentication.security.istio.io "frontend" deleted
    
  6. Löschen Sie die Zielregel:

    kubectl delete destinationrule -n frontend frontend
    

    Erwartete Ausgabe:

    destinationrule.networking.istio.io "frontend" deleted
    

Mesh-weites mTLS erzwingen

Wenn Sie verhindern möchten, dass alle Dienste im Mesh-Netzwerk Klartext-Traffic akzeptieren, legen Sie eine Mesh-weite PeerAuthentication-Richtlinie mit dem mTLS-Modus auf STRICT fest. Die Mesh-weite PeerAuthentication-Richtlinie sollte keinen Selektor haben und muss im Stamm-Namespace istio-system angewendet werden. Wenn Sie die Richtlinie bereitstellen, stellt die Steuerungsebene automatisch TLS-Zertifikate bereit, sodass Arbeitslasten sich gegenseitig authentifizieren können.

  1. Mesh-weites mTLS erzwingen:

    kubectl apply -f - <<EOF
    apiVersion: "security.istio.io/v1beta1"
    kind: "PeerAuthentication"
    metadata:
      name: "mesh-wide"
      namespace: "istio-system"
    spec:
      mtls:
        mode: STRICT
    EOF
    

    Erwartete Ausgabe:

    peerauthentication.security.istio.io/mesh-wide created

  2. Greifen Sie über die externe IP-Adresse des Dienstes frontend-external auf die Online Boutique zu und aktualisieren Sie die Seite. Die Seite wird nicht angezeigt.

  3. Führen Sie den folgenden Befehl aus, um curl für den frontend-Dienst mit reinem HTTP aus einem anderen Pod durchzuführen.

    kubectl exec testcurl -n default -- curl \
      http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    Ihre Anfrage schlägt fehl, da wir Klartext-Traffic von einer Arbeitslast ohne Sidecar senden, auf die die Richtlinie peerAuthentication STRICT angewendet wird.

  4. Löschen Sie die mesh-wide-Richtlinie:

    kubectl delete peerauthentication -n istio-system mesh-wide
    

    Erwartete Ausgabe:

    peerauthentication.security.istio.io "mesh-wide" deleted
    

Bereinigen

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, löschen Sie entweder das Projekt, das die Ressourcen enthält, oder Sie behalten das Projekt und löschen die einzelnen Ressourcen.

  • Wenn Sie zusätzliche Gebühren vermeiden möchten, löschen Sie den Cluster:

    gcloud container clusters delete  CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  • Wenn Sie den Cluster behalten und das Online Boutique-Beispiel entfernen möchten:

    1. Löschen Sie die Anwendungs-Namespaces:
    kubectl delete -f online-boutique/kubernetes-manifests/namespaces
    

    Erwartete Ausgabe:

    namespace "ad" deleted
    namespace "cart" deleted
    namespace "checkout" deleted
    namespace "currency" deleted
    namespace "email" deleted
    namespace "frontend" deleted
    namespace "loadgenerator" deleted
    namespace "payment" deleted
    namespace "product-catalog" deleted
    namespace "recommendation" deleted
    namespace "shipping" deleted
    
    1. Löschen Sie die Diensteinträge:
    kubectl delete -f online-boutique/istio-manifests/allow-egress-googleapis.yaml
    

    Erwartete Ausgabe:

    serviceentry.networking.istio.io "allow-egress-googleapis" deleted
    serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
    

Nächste Schritte