Cloud Service Mesh am Beispiel: Autorisierung


In dieser Anleitung erfahren Sie, was Autorisierung ist und wie Sie sie mit Cloud Service Mesh in einer Beispielanwendung aktivieren. Außerdem erfahren Sie, wie Sie Autorisierungsrichtlinien für Ihre Mikrodienste aktivieren. Sie erstellen einen AuthorizationPolicy bis DENY-Zugriff auf einen Mikrodienst und dann einen AuthorizationPolicy bis ALLOW-spezifischen Zugriff auf einen Mikrodienst.

Was ist Autorisierung?

Bei der Authentifizierung wird eine Identität überprüft: Ist dieser Dienst das, was er vorgibt zu sein? Bei der Autorisierung wird die Berechtigung überprüft: Darf dieser Dienst das tun? Identität ist für diese Idee von grundlegender Bedeutung. Mit Cloud Service Mesh können Sie AuthorizationPolicies die Kommunikation zwischen Arbeitslasten in Ihrem Mesh steuern, um die Sicherheit und den Zugriff zu verbessern.

In einer Mikrodienstarchitektur, in der Aufrufe über Netzwerkgrenzen hinweg erfolgen, sind herkömmliche IP-basierte Firewallregeln oft nicht ausreichend, um den Zugriff zwischen Arbeitslasten zu sichern. Mit Cloud Service Mesh können Sie Autorisierungsregeln für Folgendes festlegen:

  • Zugriff auf Arbeitslasten innerhalb Ihres Mesh steuern, entweder zwischen Arbeitslasten oder zwischen Endnutzern und Arbeitslasten
  • Sie können Richtlinien je nach Bedarf allgemein oder detailliert definieren. Eine ausführliche Erklärung zur Konfiguration von Richtlinien und Best Practices finden Sie unter Autorisierung mit Cloud Service Mesh.

Kosten

In dieser Anleitung werden die folgenden kostenpflichtigen Komponenten von Google Cloud verwendet:

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

Hinweise

  • Klonen Sie das Repository:

    git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
    cd anthos-service-mesh-samples
    

Ingress-Gateway bereitstellen

  1. Legen Sie den aktuellen Kontext für kubectl auf den Cluster fest:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Erstellen Sie einen Namespace für Ihr Ingress-Gateway:

    kubectl create namespace asm-ingress
    
  3. Aktivieren Sie den Namespace für die Injection: Die Schritte hängen vom Cloud Service Mesh-Typ ab (entweder verwaltet oder im Cluster):

    Verwaltet

    Wenden Sie das Überarbeitungslabel asm-managed auf den Namespace an:

    kubectl label namespace asm-ingress \
      istio-injection- istio.io/rev=asm-managed --overwrite
    

    Dieses Label entspricht dem aktuellen Release-Kanal des verwalteten Cloud Service Mesh für die Cloud Service Mesh-Version.

    Clusterintern

    1. Verwenden Sie den folgenden Befehl, um das Überarbeitungslabel für istiod zu finden:

      kubectl get deploy -n istio-system -l app=istiod -o \
        jsonpath={.items[*].metadata.labels.'istio\.io\/rev'}'{"\n"}'
      
    2. Wenden Sie das Überarbeitungslabel auf den Namespace an. Im folgenden Befehl ist REVISION der Wert des Überarbeitungslabels istiod, den Sie im vorherigen Schritt notiert haben.

      kubectl label namespace asm-ingress \
        istio-injection- istio.io/rev=REVISION --overwrite
      
  4. Stellen Sie das Beispiel-Gateway im anthos-service-mesh-samples-Repository bereit:

    kubectl apply -n asm-ingress \
    -f docs/shared/asm-ingress-gateway
    

    Erwartete Ausgabe:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

Beispielanwendung Online Boutique bereitstellen

  1. Legen Sie den aktuellen Kontext für kubectl auf den Cluster fest, falls Sie das noch nicht getan haben:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. Erstellen Sie den Namespace für die Beispielanwendung:

    kubectl create namespace onlineboutique
    
  3. Fügen Sie dem Namespace onlineboutique ein Label hinzu, um Envoy-Proxys automatisch einzufügen. Folgen Sie der Anleitung unter Automatische Sidecar-Einfügung aktivieren.

  4. Stellen Sie die Beispielanwendung, das VirtualService für das Frontend und Dienstkonten für die Arbeitslasten bereit. In dieser Anleitung stellen Sie die Mikrodienst-Demo-Anwendung „Online Boutique“ bereit.

    kubectl apply \
    -n onlineboutique \
    -f docs/shared/online-boutique/virtual-service.yaml
    kubectl apply \
    -n onlineboutique \
    -f docs/shared/online-boutique/service-accounts
    

Ihre Dienste ansehen

  1. Rufen Sie die Pods im Namespace onlineboutique auf:

    kubectl get pods -n onlineboutique
    

    Erwartete Ausgabe:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    Alle Pods für Ihre Anwendung sollten mit dem Wert 2/2 in der Spalte READY ausgeführt werden. Dieser Wert weist darauf hin, dass die Pods einen Envoy-Sidecar-Proxy erfolgreich eingefügt haben. Wenn 2/2 nach einigen Minuten noch nicht angezeigt wird, lesen Sie den Leitfaden zur Fehlerbehebung.

  2. Rufen Sie die externe IP-Adresse ab und legen Sie sie auf eine Variable fest:

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    Die Ausgabe sollte in etwa so aussehen:

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. Rufen Sie die EXTERNAL-IP-Adresse in Ihrem Webbrowser auf. Der Online Boutique-Shop sollte in Ihrem Browser angezeigt werden.

    Online-Boutique-Frontend

DenyAll-Autorisierung für eine Arbeitslast

In diesem Abschnitt wird eine AuthorizationPolicy hinzugefügt, um allen eingehenden Traffic an den Währungsdienst zu verweigern. AuthorizationPolicies funktioniert, indem AuthorizationPolicies in von Envoy lesbare Konfigurationen umgewandelt und die Konfigurationen auf Ihre Sidecar-Proxys angewendet werden. So kann der Envoy-Proxy eingehende Anfragen an einen Dienst autorisieren oder ablehnen.

  1. Wenden Sie eine AuthorizationPolicy auf die currencyservice an. Beachten Sie die Übereinstimmung mit dem Label currencyservice in der YAML-Datei.

    kubectl apply -f docs/authorization/currency-deny-all.yaml -n onlineboutique
    
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
      name: currency-policy
    spec:
      selector:
        matchLabels:
          app: currencyservice
  2. Versuchen Sie, über die EXTERNAL-IP Ihres Gateways auf Online Boutique im Webbrowser zuzugreifen. Von currency service sollte ein Autorisierungsfehler (500 Interner Dienstfehler) angezeigt werden.

    authz rbac 500 error

Sidecar-Proxy-Logs beobachten

Wenn Sie sehen möchten, was im Sidecar-Proxy passiert, können Sie die Logs im Pod prüfen.

  1. Rufen Sie den Namen Ihres currencyservice-Pods ab:

    CURRENCY_POD=$(kubectl get pod -n onlineboutique |grep currency|awk '{print $1}')
    
  2. Legen Sie den Envoy-Proxy so fest, dass Protokolle auf Trace-Ebene zulässig sind. Blockierte Autorisierungsanfragen werden standardmäßig nicht protokolliert:

    kubectl exec -it $CURRENCY_POD -n onlineboutique -c istio-proxy -- curl -X POST "http://localhost:15000/logging?level=trace"
    

    Erwartete Ausgabe: active loggers: admin: trace alternate_protocols_cache: trace ... tracing: trace upstream: trace udp: trace wasm: trace

  3. Verwenden Sie curl, um Traffic an Ihre EXTERNAL_IP zu senden und Protokolle zu generieren:

    for i in {0..10}; do
    curl -s -I $FRONTEND_IP ; done
    
  4. Rufen Sie die Logs zur rollenbasierten Zugriffssteuerung (Role-Based Access Control, RBAC) in Ihrem Istio-Proxy auf:

    kubectl logs -n onlineboutique $CURRENCY_POD -c istio-proxy | grep -m5 rbac
    

    Erwartete Ausgabe:

    2022-07-08T14:19:20.442920Z     debug   envoy rbac      checking request: requestedServerName: outbound_.7000_._.currencyservice.onlineboutique.svc.cluster.local, sourceIP: 10.8.8.5:34080, directRemoteIP: 10.8.8.5:34080, remoteIP: 10.8.8.5:34080,localAddress: 10.8.0.6:7000, ssl: uriSanPeerCertificate: spiffe://christineskim-tf-asm.svc.id.goog/ns/onlineboutique/sa/default, dnsSanPeerCertificate: , subjectPeerCertificate: OU=istio_v1_cloud_workload,O=Google LLC,L=Mountain View,ST=California,C=US, headers: ':method', 'POST'
    2022-07-08T14:19:20.442944Z     debug   envoy rbac      enforced denied, matched policy none
    2022-07-08T14:19:20.442965Z     debug   envoy http      [C73987][S13078781800499437460] Sending local reply with details rbac_access_denied_matched_policy[none]
      ```
    

In den Protokollen sollte eine enforced denied-Meldung angezeigt werden, aus der hervorgeht, dass currencyservice so konfiguriert ist, dass eingehende Anfragen blockiert werden.

Eingeschränkten Zugriff zulassen

Anstatt einer DENYALL-Richtlinie können Sie den Zugriff für bestimmte Arbeitslasten zulassen. Dies ist in einer Mikrodienstarchitektur relevant, in der Sie dafür sorgen möchten, dass nur autorisierte Dienste miteinander kommunizieren können.

In diesem Abschnitt aktivieren Sie die Kommunikation zwischen den Diensten frontend und checkout und dem Dienst currency.

  1. In der folgenden Datei ist zu sehen, dass ein bestimmter source.principal(Client) auf die Zulassungsliste für den Zugriff auf currencyservice gesetzt wurde:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: currency-policy
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/onlineboutique/sa/checkoutservice"]

Wenden Sie die Richtlinie an:

kubectl apply -f docs/authorization/currency-allow-frontend-checkout.yaml -n onlineboutique
  1. Rufen Sie EXTERNAL-IP in Ihrem Webbrowser auf. Sie sollten jetzt auf Online Boutique zugreifen können.

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.

Damit Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen nicht in Rechnung gestellt werden, können Sie entweder das Projekt löschen oder die einzelnen Ressourcen entfernen.

Projekt löschen

Löschen Sie das Projekt in Cloud Shell:

gcloud projects delete PROJECT_ID

Ressourcen löschen

  • Wenn Sie den Cluster behalten und das Online Boutique-Beispiel entfernen möchten:

    1. Löschen Sie die Anwendungs-Namespaces:

      kubectl delete namespace onlineboutique
      

      Erwartete Ausgabe:

      namespace "onlineboutique" deleted
      
    2. Löschen Sie den Ingress-Gateway-Namespace:

      kubectl delete namespace asm-ingress
      

      Erwartete Ausgabe:

      amespace "asm-ingress" deleted
      
  • 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 
    

Nächste Schritte