TLS-Zertifikatsverwaltung für Cloud Service Mesh-Ingress-Gateway mit Certificate Authority Service automatisieren

In dieser Anleitung erfahren Plattformbetreiber, wie Sie mit dem Aussteller des Certificate Authority Service für das cert-manager-Tool die TLS-Zertifikatsverwaltung für das Cloud Service Mesh-Ingress-Gateway automatisieren. Mit den Zertifikaten kann das Ingress-Gateway HTTPS- und anderen TLS- und mTLS-Traffic beenden, der von Clients in Ihrer Virtual Private Cloud (VPC), aber von außerhalb des Service Mesh stammt. In dieser Anleitung werden Grundkenntnisse über Kubernetes- und TLS-Zertifikate vorausgesetzt.

Einleitung

Cloud Service Mesh stellt TLS-Zertifikate für jede Arbeitslast im Service Mesh bereit. Diese Zertifikate ermöglichen die verschlüsselte und gegenseitig authentifizierte TLS-Kommunikation (mTLS) zwischen Arbeitslasten im Service Mesh. Eine der unterstützten Zertifizierungsstellen stellt die Zertifikate aus und signiert sie.

Cloud Service Mesh stellt jedoch nicht automatisch Zertifikate für das Ingress-Gateway bereit, um Traffic in das Service Mesh aufzunehmen. Eine gängige Lösung ist die Verwendung des Open-Source-Tools cert-manager, um die Verwaltung von Zertifikaten für eingehenden Gateway zu automatisieren.

Das cert-manager-Tool fordert Zertifikate von einem Aussteller an, der eine Zertifizierungsstelle (CA) darstellt. Certificate Authority Service (CA Service) ist ein Google Cloud-Dienst, mit dem Sie eine eigene private Zertifizierungsstelle erstellen können. Das cert-manager-Tool kann Zertifikate von CA Service anfordern. Dazu wird der externe Aussteller für CA Service verwendet.

Eine private Zertifizierungsstelle kann TLS-Zertifikate ausstellen, die den Traffic innerhalb eines internen Netzwerks authentifizieren und verschlüsseln. Cloud Service Mesh-Ingress-Gateways sind häufig so eingerichtet, dass eingehender Traffic von Clients innerhalb Ihrer VPC, aber außerhalb des Service Mesh zugelassen wird. Für den internen Netzwerkverkehr können Sie eine private Zertifizierungsstelle in CA Service verwenden, um Zertifikate für das Ingress-Gateway auszustellen.

In dieser Anleitung erfahren Sie, wie Sie das cert-Manager-Tool und den CA Service-Aussteller einrichten, um die Bereitstellung und Verlängerung von TLS-Zertifikaten für das Ingress-Gateway zu automatisieren. Das cert-Manager-Tool stellt Zertifikate als Kubernetes Secret-Ressourcen vom Typ TLS bereit. Wenn das cert-manager-Tool ein Zertifikat verlängert, wird die Secret-Ressource mit einem neuen Zertifikat aktualisiert. Das Ingress-Gateway führt den Envoy-Proxy aus und unterstützt den Secret Discovery Service (SDS) von Envoy. Durch SDS kann der Ingress-Gateway ein neues Zertifikat verwenden, ohne dass ein Administrator den Prozess neu starten oder neu laden muss.

Sidecar-Proxys, die Teil des Mesh sind, können TLS-Zertifikate entweder von CA Service oder der Cloud Service Mesh-Zertifizierungsstelle abrufen. In dieser Anleitung verwenden Sie CA Service für Sidecar-Proxy- und Ingress-Gateway-Zertifikate. Dadurch können Sie eine Stammzertifizierungsstelle für alle TLS-Zertifikate verwenden.

Das folgende Diagramm zeigt die Ressourcen, die Sie in dieser Anleitung bereitstellen. Sie stellen einen internen Passthrough-Network Load Balancer für das Ingress-Gateway bereit. Der interne Passthrough-Netzwerk-Load Balancer ist kein Proxy. Daher werden TCP-Verbindungen nicht beendet und keine TLS-Handshakes ausgeführt. Stattdessen werden Verbindungen zu den Pods des Deployments istio-ingressgateway weitergeleitet.

Das Secret hello-example-com-credential enthält ein Zertifikat und einen privaten Schlüssel. Das Gateway hello konfiguriert die Pods des Deployments istio-ingressgateway so, dass dieses Zertifikat und dieser private Schlüssel verwendet werden, um TLS-Handshakes für Anfragen mit dem Hostnamen hello.example.com auszuführen.

Grafik: mtls-Verwaltung mit CA-Dienst

Die Pods des google-cas-issuer-Deployments im Namespace cert-manager fordern Zertifikate von der Zertifizierungsstelle an, die Sie in CA Service erstellen. Sie erstellen eine Richtlinienbindung für Identity and Access Management, mit der die Pods ca-service-isser die Identität eines Google-Dienstkontos mithilfe von Workload Identity-Föderation für GKE übernehmen können. Sie gewähren diesem Google-Dienstkonto die Berechtigung, Zertifikate von Ihrer Zertifizierungsstelle in CA Service anzufordern, indem Sie eine IAM-Richtlinienbindung für Ihren CA-Pool erstellen.

Ziele

Kosten

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

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 vermeiden, wenn Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Vorbereitung

  1. Rufen Sie in der Google Cloud Console die Seite für die Projektauswahl auf und wählen Sie ein Projekt aus oder erstellen Sie eines.

  2. Die Abrechnung für das Google Cloud-Projekt muss aktiviert sein.

  3. Rufen Sie in der Google Cloud Console Cloud Shell auf.

    Unten in der Google Cloud Console wird eine Cloud Shell-Sitzung mit einer Eingabeaufforderung geöffnet. Für alle Befehle in dieser Anleitung wird Cloud Shell verwendet.

  4. Legen Sie das Google Cloud Console-Projekt fest, das Sie für diese Anleitung verwenden möchten:

    gcloud config set core/project PROJECT_ID
    

    Ersetzen Sie PROJECT_ID durch die Projekt-ID Ihres Cloud-Projekts.

    Klicken Sie im Dialogfeld „Cloud Shell autorisieren“ auf Autorisieren. Durch Klicken auf Autorisieren erlauben Sie gcloud-Befehle, die Sie in Cloud Shell ausführen, um Ihre Nutzeranmeldedaten zur Authentifizierung bei Google APIs zu verwenden.

  5. Aktivieren Sie die Resource Manager-, GKE-, GKE Hub-, die Cloud Service Mesh-Zertifizierungsstelle und die CA Service APIs:

    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        gkehub.googleapis.com \
        meshca.googleapis.com \
        privateca.googleapis.com
    

CA Service konfigurieren

In diesem Abschnitt erstellen Sie eine Stamm-CA und zwei untergeordnete CAs in CA Service. Eine untergeordnete CA stellt Zertifikate für das Ingress-Gateway aus, während die andere untergeordnete CA Zertifikate für Sidecar-Proxys im Mesh-Netzwerk ausstellt.

Der Einfachheit halber verwenden Sie dasselbe Projekt für den GKE-Cluster sowie die Stamm-CAs und untergeordneten CAs in dieser Anleitung. In Ihrer eigenen Umgebung können Sie für den GKE-Cluster und die Zertifizierungsstellen ein anderes Projekt verwenden.

  1. Erstellen Sie in Cloud Shell einen CA-Pool für die Stammzertifizierungsstelle:

    gcloud privateca pools create ROOT_CA_POOL \
        --location CA_LOCATION \
        --tier enterprise
    
    • ROOT_CA_POOL ist der Name des CA-Pools. Beispiel: root-ca-pool-tutorial
    • CA_LOCATION ist der Standort des CA-Pools. Beispiel: us-central1

    Mit dem folgenden Befehl können Sie die verfügbaren CA Service-Standorte auflisten: gcloud privateca locations list

  2. Erstellen und aktivieren Sie eine Stamm-CA:

    gcloud privateca roots create ROOT_CA \
        --auto-enable \
        --key-algorithm ec-p384-sha384 \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --subject "CN=Example Root CA, O=Example Organization" \
        --use-preset-profile root_unconstrained
    
    • ROOT_CA ist der Name, den Sie für die Stamm-CA verwenden möchten. Beispiel: root-ca-tutorial.
  3. Erstellen Sie einen CA-Pool für die untergeordnete CA, die Zertifikate an das Ingress-Gateway ausstellt:

    gcloud privateca pools create SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --tier devops
    
    • SUBORDINATE_CA_POOL_GATEWAYS ist der Name des CA-Pools. Beispiel: subordinate-ca-mtls-pool-gateways-tutorial.
  4. Erstellen und aktivieren Sie die untergeordnete Zertifizierungsstelle, die Zertifikate für das Ingress-Gateway ausstellt:

    gcloud privateca subordinates create SUBORDINATE_CA_GATEWAYS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --subject "CN=Example Gateway mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS ist der Name, den Sie für die untergeordnete Zertifizierungsstelle verwenden möchten. Beispiel: subordinate-ca-mtls-gateways-tutorial.
    • Das Flag --use-preset-profile konfiguriert die untergeordnete CA für die Verwendung des Zertifikatprofils des untergeordneten mTLS. Mit diesem Profil kann die untergeordnete Zertifizierungsstelle sowohl Client- als auch Server-TLS-Zertifikate für mTLS ausstellen.

    Wenn Ihr Ingress-Gateway einfaches TLS anstelle von mTLS verwenden soll, muss Ihre untergeordnete Zertifizierungsstelle nur Server-TLS-Zertifikate ausstellen. In diesem Fall können Sie stattdessen das Zertifikatprofil des untergeordneten Servers TLS (subordinate_server_tls_pathlen_0) verwenden.

  5. Erstellen Sie eine Zertifikatsausstellungsrichtlinie:

    cat << EOF > policy.yaml
    baselineValues:
      keyUsage:
        baseKeyUsage:
          digitalSignature: true
          keyEncipherment: true
        extendedKeyUsage:
          serverAuth: true
          clientAuth: true
      caOptions:
        isCa: false
    identityConstraints:
      allowSubjectPassthrough: false
      allowSubjectAltNamesPassthrough: true
      celExpression:
        expression: subject_alt_names.all(san, san.type == URI && san.value.startsWith("spiffe://PROJECT_ID.svc.id.goog/ns/") )
    EOF
    

    Durch diese Ausstellungsrichtlinie sind Zertifizierungsstellen so eingeschränkt, dass nur Zertifikate für Arbeitslasten im Mesh-Netzwerk ausgestellt werden.

  6. Erstellen Sie einen CA-Pool für die untergeordnete CA, die Zertifikate für die Sidecar-Proxys im Mesh-Netzwerk ausstellt. Wenden Sie die Ausstellungsrichtlinie auf den CA-Pool an:

    gcloud privateca pools create SUBORDINATE_CA_POOL_SIDECARS \
     --issuance-policy policy.yaml \
     --location CA_LOCATION \
     --tier devops
    
    • SUBORDINATE_CA_POOL_SIDECARS ist der Name des CA-Pools. Beispiel: subordinate-ca-mtls-pool-sidecars-tutorial.
  7. Erstellen und aktivieren Sie die untergeordnete Zertifizierungsstelle, die Zertifikate für die Sidecar-Proxys im Mesh-Netzwerk ausstellt:

    gcloud privateca subordinates create SUBORDINATE_CA_SIDECARS \
        --auto-enable \
        --issuer-location CA_LOCATION \
        --issuer-pool ROOT_CA_POOL \
        --key-algorithm ec-p256-sha256 \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --subject "CN=Example Sidecar mTLS CA, O=Example Organization" \
        --use-preset-profile subordinate_mtls_pathlen_0
    
    • SUBORDINATE_CA_GATEWAYS ist der Name, den Sie für die untergeordnete Zertifizierungsstelle verwenden möchten. Beispiel: subordinate-ca-mtls-sidecars-tutorial

Google Kubernetes Engine-Cluster erstellen

  1. Erstellen Sie in Cloud Shell einen GKE-Cluster:

    gcloud container clusters create CLUSTER_NAME \
        --enable-ip-alias \
        --num-nodes 4 \
        --release-channel regular \
        --scopes cloud-platform \
        --workload-pool PROJECT_ID.svc.id.goog \
        --zone ZONE
    

    Ersetzen Sie CLUSTER_NAME durch den Namen, den Sie für den Cluster verwenden möchten. Beispiel: asm-ingress-cert-manager-ca-service.

    Ersetzen Sie ZONE durch die Zone, die Sie für den Cluster verwenden möchten. Beispiel: us-central1-f.

    Beachten Sie für den Befehl Folgendes:

    • Das Flag --release-channel wählt die GKE-Release-Version für den Cluster aus.
    • Sowohl Cloud Service Mesh als auch der CA Service-Aussteller für das cert-Manager-Tool erfordern, dass Sie den Bereich cloud-platform auf den Clusterknoten festlegen.
    • Das Argument --workload-pool aktiviert die Workload Identity-Föderation für GKE, wodurch das Kubernetes-Dienstkonto des CA Service-Ausstellers die Identität eines Google-Dienstkontos übernehmen kann. Diese Identitätsübertragung bedeutet, dass die CA Service-Aussteller-Pods auf die CA Service API zugreifen können, ohne eine Schlüsseldatei für das Google-Dienstkonto herunterzuladen.
  2. Gewähren Sie dem Nutzerkonto Administratorberechtigungen:

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config get-value core/account)
    

    Sie benötigen die Berechtigungen, die von der ClusterRole cluster-admin von Kubernetes bereitgestellt werden, um die Regeln für die rollenbasierte Zugriffssteuerung (Role-Based Access Control, RBAC) für Cloud Service Mesh zu erstellen und das cert-Manager-Tool zu installieren.

Anthos Service Mesh-Steuerungsebene installieren

In dieser Anleitung installieren Sie verwaltetes Cloud Service Mesh für einen GKE-Cluster in Google Cloud, wobei sich alle Ressourcen in einem Projekt befinden. In Ihrer eigenen Umgebung können Sie die in diesem Dokument beschriebene Lösung entweder mit einem verwalteten Cloud Service Mesh oder einer Steuerungsebene im Cluster anwenden.

Cloud Service Mesh bietet eine Reihe von Installationsoptionen für verschiedene Szenarien. Nachdem Sie mit dieser Anleitung fertig sind, sollten Sie die Installationsanleitungen lesen, um die Option auszuwählen, die am besten zu Ihrer Umgebung passt.

  1. Laden Sie in Cloud Shell das Installationstool asmcli herunter:

    curl --location --output asmcli https://storage.googleapis.com/csm-artifacts/asm/asmcli_1.11
    
    chmod +x asmcli
    

    Sie verwenden asmcli, um die Cloud Service Mesh-Steuerungsebene zu installieren.

  2. Cloud Service Mesh-Steuerungsebene installieren:

    ./asmcli install \
        --ca gcp_cas \
        --ca_pool projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_SIDECARS \
        --channel regular \
        --cluster_location ZONE \
        --cluster_name CLUSTER_NAME \
        --enable_all \
        --enable_registration \
        --fleet_id PROJECT_ID \
        --managed \
        --output_dir asm-files \
        --project_id PROJECT_ID \
        --verbose
    

    Die Installation dauert einige Minuten. Nach Abschluss der Installation wird die folgende Ausgabe angezeigt:

    asmcli: Successfully installed ASM.
    

Ingress-Gateway installieren

  1. Erstellen Sie in Cloud Shell einen Kubernetes-Namespace für das Gateway für eingehenden Traffic:

    kubectl create namespace GATEWAY_NAMESPACE
    
    • GATEWAY_NAMESPACE ist der Name des Namespace, den Sie für das Ingress-Gateway verwenden möchten. Beispiel: istio-ingress
  2. Reservieren Sie eine statische interne IP-Adresse, die für den internen Passthrough-Network-Load-Balancer des Ingress-Gateways verwendet wird:

    LOAD_BALANCER_IP=$(gcloud compute addresses create \
        asm-ingress-gateway-ilb \
        --region REGION \
        --subnet default \
        --format 'value(address)')
    
    • Ersetzen Sie REGION durch die Region, die die von den GKE-Clusterknoten verwendeten Zonen enthält. Wenn Ihr Cluster beispielsweise die Zone us-central1-f verwendet, ersetzen Sie REGION durch us-central1.

    Dieser Befehl reserviert eine IP-Adresse aus dem Standardsubnetz in der von Ihnen angegebenen Region.

  3. Erstellen Sie ein Operatormanifest für das Ingress-Gateway:

    cat << EOF > ingressgateway-operator.yaml
    apiVersion: install.istio.io/v1alpha1
    kind: IstioOperator
    metadata:
      name: ingressgateway-operator
      annotations:
        config.kubernetes.io/local-config: "true"
    spec:
      profile: empty
      revision: asm-managed
      components:
        ingressGateways:
        - name: istio-ingressgateway
          namespace: GATEWAY_NAMESPACE
          enabled: true
          k8s:
            overlays:
            - apiVersion: apps/v1
              kind: Deployment
              name: istio-ingressgateway
              patches:
              - path: spec.template.metadata.annotations
                value:
                  inject.istio.io/templates: gateway
              - path: spec.template.metadata.labels.sidecar\.istio\.io/inject
                value: "true"
              - path: spec.template.spec.containers[name:istio-proxy]
                value:
                  name: istio-proxy
                  image: auto
            service:
              loadBalancerIP: $LOAD_BALANCER_IP
            serviceAnnotations:
              networking.gke.io/load-balancer-type: Internal
              networking.gke.io/internal-load-balancer-allow-global-access: "true"
    EOF
    

    Beachten Sie Folgendes zum Operator-Manifest:

  4. Erstellen Sie das Installationsmanifest für das Ingress-Gateway mit dem Operatormanifest und dem Tool istioctl, das das Skript asmcli bei der Installation der Steuerungsebene heruntergeladen hat:

    ./asm-files/istioctl manifest generate \
        --filename ingressgateway-operator.yaml \
        --output ingressgateway
    
  5. Installieren Sie das Ingress-Gateway:

    kubectl apply --recursive --filename ingressgateway/
    

Cert-Manager-Tool installieren

  1. Laden Sie in Cloud Shell das Installationsmanifest für das cert-manager-Tool herunter und wenden Sie es an:

    CERT_MANAGER_VERSION=v1.5.4
    
    curl --location --output cert-manager.yaml "https://github.com/jetstack/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"
    
    kubectl apply --filename cert-manager.yaml
    

    Die Installation des Cert-Manager-Tools dauert etwa eine Minute.

CA Service-Aussteller-Controller installieren

Mit dem CA Service-Aussteller-Controller kann das cert-Manager-Tool Zertifikate mit CA Service anfordern. Der Controller verwendet den Erweiterungsmechanismus externer Aussteller des cert-managers.

  1. Erstellen Sie in Cloud Shell ein Google-Dienstkonto:

    gcloud iam service-accounts create CAS_ISSUER_GSA \
        --display-name "CA Service issuer for cert-manager"
    
    • CAS_ISSUER_GSA ist der Name des Google-Dienstkontos. Beispiel: cert-manager-ca-service-issuer.

    Der Certificate Authority Service-Aussteller-Controller verwendet dieses Google-Dienstkonto, um sich bei den Certificate Authority Service APIs zu authentifizieren.

  2. Erstellen Sie eine Richtlinienbindung für Identity and Access Management, die es dem Google-Dienstkonto des Certificate Authority Service-Aussteller-Controllers ermöglicht, Zertifikate vom CA-Pool anzufordern, der Ihre untergeordnete Zertifizierungsstelle enthält:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  3. Laden Sie das Installationsmanifest des Certificate Authority Service-Aussteller-Controllers herunter:

    CAS_ISSUER_VERSION=v0.5.3
    
    curl --location --output ca-service-issuer.yaml "https://github.com/jetstack/google-cas-issuer/releases/download/${CAS_ISSUER_VERSION}/google-cas-issuer-${CAS_ISSUER_VERSION}.yaml"
    
  4. Erstellen Sie eine IAM-Richtlinienbindung, damit das Kubernetes-Dienstkonto ksa-google-cas-issuer im Namespace cert-manager die Identität des Google-Dienstkontos (GSA) mithilfe der Workload Identity-Föderation für GKE übernehmen kann:

    gcloud iam service-accounts add-iam-policy-binding \
     CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    

    Die Controller des CA Service-Ausstellers verwenden das Kubernetes-Dienstkonto ksa-google-cas-issuer.

  5. Installieren Sie den CA Service-Aussteller-Controller in Ihrem GKE-Cluster:

    kubectl apply --filename ca-service-issuer.yaml
    
  6. Fügen Sie dem Kubernetes-Dienstkonto, das von den Controller-Pods des CA Service-Ausstellers verwendet wird, die Annotation „Workload Identity Federation for GKE“ iam.gke.io/gcp-service-account hinzu:

    kubectl annotate serviceaccount ksa-google-cas-issuer --namespace cert-manager \
       "iam.gke.io/gcp-service-account=CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com"
    

    Diese Annotation teilt GKE mit, dass das Kubernetes-Dienstkonto die Identität des Google-Dienstkontos für den Zugriff auf Google APIs imitieren kann.

Zertifikatsaussteller erstellen

  1. Erstellen Sie in Cloud Shell ein Manifest von GoogleCASIssuer und wenden Sie es an:

    cat << EOF > gateway-cas-issuer.yaml
    apiVersion: cas-issuer.jetstack.io/v1beta1
    kind: GoogleCASIssuer
    metadata:
      name: gateway-cas-issuer
      namespace: GATEWAY_NAMESPACE
    spec:
      caPoolId: SUBORDINATE_CA_POOL_GATEWAYS
      location: CA_LOCATION
      project: PROJECT_ID
    EOF
    
    kubectl apply --filename gateway-cas-issuer.yaml
    

    Durch den Aussteller kann das cert-manager-Tool Zertifikate aus dem untergeordneten CA-Pool in dem Namespace für eingehenden Traffic bereitstellen.

Beispielanwendung bereitstellen

In diesem Abschnitt prüfen Sie, ob das cert-manager-Tool den CA Service-Aussteller verwenden kann, um Zertifikate von CA Service abzurufen. Zur Überprüfung stellen Sie eine Beispielanwendung mit einer Anfragerouting-Konfiguration und einem Zertifikat für das Ingress-Gateway bereit.

  1. Erstellen Sie in Cloud Shell einen Namespace für die Beispielanwendungsressourcen:

    cat << EOF > sample-app-namespace.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: APP_NAMESPACE
      annotations:
        mesh.cloud.google.com/proxy: '{"managed":"true"}'
      labels:
        istio.io/rev: asm-managed
    EOF
    
    kubectl apply --filename sample-app-namespace.yaml
    
    • APP_NAMESPACE ist der Name des Namespace für die Beispielanwendung. Beispiel: sample-app.

    Die Annotation mesh.cloud.google.com/proxy aktiviert die von Google verwaltete Datenebene für den Namespace.

    Mit dem Label istio.io/rev: asm-managed wird die reguläre Release-Version für die von Google verwaltete Datenebene im Namespace der Beispielanwendung ausgewählt. Ändern Sie den Wert dieses Labels, wenn Sie die Rapid- oder Stable-Release-Version verwenden.

  2. Erstellen Sie eine Deployment-Ressource für die Beispielanwendung:

    cat << EOF > deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hello
      namespace: APP_NAMESPACE
      labels:
        app: hello
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: hello
      template:
        metadata:
          labels:
            app: hello
        spec:
          containers:
          - image: gcr.io/google-samples/hello-app:1.0
            name: hello-app
            ports:
            - containerPort: 8080
    EOF
    
    kubectl apply --filename deployment.yaml
    
  3. Erstellen Sie eine Dienstressource für die Beispielanwendung:

    cat << EOF > service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: SERVICE_NAME
      namespace: APP_NAMESPACE
    spec:
      ports:
      - name: http-hello
        port: 8080
      selector:
        app: hello
      type: ClusterIP
    EOF
    
    kubectl apply --filename service.yaml
    
    • SERVICE_NAME ist der Name des Dienstes. Beispiel: hello
  4. Erstellen Sie mit dem Zertifikatsaussteller eine Zertifikatsressource für den Domainnamen hello.example.com:

    cat << EOF > certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: hello-example-com-certificate
      namespace: GATEWAY_NAMESPACE
    spec:
      secretName: hello-example-com-credential
      commonName: hello.example.com
      dnsNames:
      - hello.example.com
      duration: 24h
      renewBefore: 8h
      issuerRef:
        group: cas-issuer.jetstack.io
        kind: GoogleCASIssuer
        name: gateway-cas-issuer
    EOF
    
    kubectl apply --filename certificate.yaml
    

    Der Zertifikat-Namespace muss mit dem Namespace des Ingress-Gateways übereinstimmen. In der Regel können nur Plattformadministratoren Ressourcen in diesem Namespace ändern, da sich Änderungen auf das gesamte Service Mesh auswirken können. Das cert-Manager-Tool erstellt die Secret-Ressource für das TLS-Zertifikat im selben Namespace. Das bedeutet, dass Anwendungsadministratoren keinen Zugriff auf den Ingress-Gateway-Namespace haben müssen.

    Sie können weitere Hostnamen in der dnsNames-Liste im Zertifikat hinzufügen. Diese Hostnamen sind im Zertifikat als alternative Antragstellernamen (Subject Alternative Names, SANs) enthalten.

  5. Erstellen Sie eine Gateway-Ressource für die Beispielanwendung:

    cat << EOF > gateway.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: GATEWAY_NAME
      namespace: GATEWAY_NAMESPACE
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - APP_NAMESPACE/hello.example.com
        port:
          name: https-hello
          number: 443
          protocol: HTTPS
        tls:
          credentialName: hello-example-com-credential
          mode: MUTUAL
    EOF
    
    kubectl apply --filename gateway.yaml
    
    • GATEWAY_NAME ist der Name des Gateways. Beispiel: hello
    • Das Feld credentialName im Gateway stimmt mit dem Feld secretName im Zertifikat überein. Das cert-manager-Tool erstellt ein Kubernetes-Secret mit dem TLS-Zertifikat von CA Service. Mit diesem Zertifikat kann das Ingress-Gateway den an hello.example.com gerichteten TLS-Traffic beenden.

    Das Gateway-Manifest gibt MUTUAL TLS (mTLS) an. Wenn Sie das Gateway für reguläre TLS konfigurieren möchten, legen Sie stattdessen den TLS-Modus des Gateways auf SIMPLE fest.

  6. Erstellen Sie eine VirtualService-Ressource für die Beispielanwendung:

    cat << EOF > virtual-service.yaml
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: hello
      namespace: APP_NAMESPACE
    spec:
      hosts:
      - hello.example.com
      gateways:
      - GATEWAY_NAMESPACE/GATEWAY_NAME
      http:
      - route:
        - destination:
            host: SERVICE_NAME
            port:
              number: 8080
    EOF
    
    kubectl apply --filename virtual-service.yaml
    

    Das Gateway und VirtualService verwenden unterschiedliche Namespaces. Durch dieses allgemeine Muster werden Änderungen am hostbasierten Routing im Gateway auf Plattformadministratoren beschränkt, die Berechtigungen zum Ändern von Ressourcen im Namespace für eingehenden Gateway haben.

    Anwendungsadministratoren mit Berechtigungen zum Bearbeiten des VirtualService im Namespace der Beispielanwendung können das Routing nach anderen Anfragefeldern wie dem URL-Pfad ändern, ohne sich mit Plattformadministratoren abzustimmen.

Wenn Sie andere Konfigurationsoptionen entdecken möchten, lesen Sie die API-Dokumentation für Zertifikats-, Gateway- und VirtualService-Ressourcen.

Sie können Authentifizierungs- und Autorisierungsrichtlinien auf Traffic anwenden, der über das Ingress-Gateway in das Service Mesh eintritt. Lesen Sie dazu die Dokumentation für die Istio APIs für PeerAuthentication und AuthorizationPolicy.

Lösung prüfen

In diesem Abschnitt prüfen Sie, ob Sie HTTPS-Anfragen mit mTLS an die Beispielanwendung von außerhalb des Service Mesh senden können. Erstellen Sie zum Bestätigen eine Compute Engine-VM-Instanz, fordern Sie ein Client-TLS-Zertifikat von CA Service an und verwenden Sie dieses Zertifikat, um die Anfrage an die Beispielanwendung zu authentifizieren.

Sie benötigen SSH-Zugriff auf die VM-Instanz. Das Standardnetzwerk enthält eine Firewallregel, die den SSH-Zugriff zulässt. Wenn Sie keinen SSH-Zugriff haben, folgen Sie der Dokumentation zu Firewallregeln, um eine Firewallregel zu erstellen, die eingehende TCP-Verbindungen an Port 22 zulässt.

  1. Erstellen Sie in Cloud Shell ein Google-Dienstkonto:

    gcloud iam service-accounts create CLIENT_VM_GSA \
        --display-name "CA Service tutorial VM instance service account"
    
    • CLIENT_VM_GSA ist der Name des Google-Dienstkontos. Beispiel: cas-tutorial-client.

    Sie weisen dieses Google-Dienstkonto der Compute Engine-VM-Instanz zu.

  2. Weisen Sie im untergeordneten CA-Pool dem Google-Dienstkonto die Rolle CA Service-Zertifikatsanfragesteller zu:

    gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    

    Diese Rolle bietet Berechtigungen zum Anfordern von Zertifikaten vom CA-Pool.

  3. Erstellen Sie eine Compute Engine-VM-Instanz in derselben VPC wie der GKE-Cluster:

    gcloud compute instances create cas-tutorial-client \
        --scopes cloud-platform \
        --service-account CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --zone ZONE
    

    Die VM-Instanz benötigt den Bereich cloud-platform, um auf die CA Service API zuzugreifen.

  4. Speichern Sie die IP-Adresse des internen Passthrough-Network Load Balancers des Ingress-Gateways in einer Datei:

    kubectl get services istio-ingressgateway \
       --namespace GATEWAY_NAMESPACE \
       --output jsonpath='{.status.loadBalancer.ingress[0].ip}' > ilb-ip.txt
    
  5. Speichern Sie das Zertifikat für den öffentlichen Schlüssel Ihrer Stammzertifizierungsstelle in einer Datei:

    gcloud privateca roots describe ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --format 'value(pemCaCertificates)' > root-ca-cert.pem
    
  6. Kopieren Sie das Zertifikat der Stammzertifizierungsstelle und die Datei mit der IP-Adresse des internen Passthrough-Network Load Balancers des Ingress-Gateways auf die VM-Instanz:

    gcloud compute scp root-ca-cert.pem ilb-ip.txt cas-tutorial-client:~ \
       --zone ZONE
    
  7. Stellen Sie eine SSH-Verbindung zur VM-Instanz her.

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Führen Sie die übrigen Befehle in diesem Abschnitt aus der SSH-Sitzung aus.

  8. Installieren Sie die Pakete ca-certificates und coreutils sowie die Befehlszeilentools curl, openssl und jq:

    sudo apt-get update --yes
    
    sudo apt-get install --yes ca-certificates coreutils curl jq openssl
    
  9. Erstellen Sie ein Schlüsselpaar für das Client-TLS-Zertifikat:

    openssl genrsa -out private-key.pem 2048
    
    openssl rsa -in private-key.pem -pubout -out public-key.pem
    
  10. Fragen Sie den Metadatenserver ab, um die E-Mail-Adresse der mit der VM-Instanz verknüpften Identität des Google-Dienstkontos zu erhalten:

    GSA_EMAIL=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email)
    
  11. Erstellen Sie eine JSON-Datei, die Sie als Anfragetext verwenden, wenn Sie ein Client-TLS-Zertifikat von der Certificate Authority Service API anfordern:

    cat << EOF > request.json
    {
      "config": {
        "publicKey": {
          "format": "PEM",
          "key": "$(base64 --wrap 0 public-key.pem)"
        },
        "subjectConfig": {
          "subject": {
            "commonName": "$(hostname --short)",
            "organization": "Example Organization"
          },
          "subjectAltName": {
            "dnsNames": [
              "$(hostname --fqdn)"
            ],
            "emailAddresses": [
              "$GSA_EMAIL"
            ]
          }
        },
        "x509Config": {
          "caOptions": {
            "isCa": false
          },
          "keyUsage": {
            "baseKeyUsage": {
              "digitalSignature": true,
              "keyEncipherment": true
            },
            "extendedKeyUsage": {
              "clientAuth": true
            }
          }
        }
      },
      "lifetime": "86400s"
    }
    EOF
    

    Weitere Informationen zu den Feldern im Konfigurationsabschnitt finden Sie unter CertificateConfig-Typ in der Dokumentation zur CA Service API.

  12. Fordern Sie vom Metadatenserver ein OAuth 2.0-Zugriffstoken an:

    TOKEN=$(curl --silent --header "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq --raw-output ".access_token")
    

    Dieses Zugriffstoken stellt die Berechtigungen bereit, die dem Google-Dienstkonto gewährt wurden, das an die VM-Instanz angehängt ist.

  13. Fordern Sie ein Client-TLS-Zertifikat von der CA Service API an und speichern Sie den Antworttext in einer Datei:

    curl --silent --request POST \
        --header "Authorization: Bearer $TOKEN" \
        --header "Content-Type: application/json" \
        --data @request.json \
        --output response.json \
        "https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/CA_LOCATION/caPools/SUBORDINATE_CA_POOL_GATEWAYS/certificates"
    

    Der Befehl verwendet das Zugriffstoken, um die API-Anfrage zu authentifizieren.

  14. Speichern Sie das Clientzertifikat und die Zertifikatskette in einer Datei:

    jq --raw-output --join-output ".pemCertificate , .pemCertificateChain[]" response.json > client-cert-chain.pem
    
  15. Verwenden Sie curl, um eine HTTPS-Anfrage von der VM-Instanz an die Beispielanwendung zu senden:

    curl --cert client-cert-chain.pem --key private-key.pem \
        --cacert root-ca-cert.pem \
        --resolve hello.example.com:443:$(cat ilb-ip.txt) \
        --silent https://hello.example.com | head -n1
    

    Sie erhalten folgende Ausgabe:

    Hello, world!
    

    Diese Antwort zeigt, dass curl die HTTPS-Anfrage erfolgreich mit mTLS gesendet hat. Die Beispielanwendung hat mit der Nachricht geantwortet, die in der Terminalausgabe angezeigt wird.

    Der Befehl curl führt folgende Schritte durch:

    • Die Flags --cert und --key weisen curl an, das Client-TLS-Zertifikat und den privaten Schlüssel zur Authentifizierung der Anfrage zu verwenden. Die Clientzertifikatsdatei enthält die vollständige Zertifikatskette vom Clientzertifikat zur Stammzertifizierungsstelle.

    • Das Flag --cacert weist curl an, zu prüfen, ob die in dieser Anleitung erstellte Stamm-CA oder eine ihrer untergeordneten CAs das Serverzertifikat ausgestellt hat.

      Wenn Sie dieses Flag weglassen, versucht curl, das Serverzertifikat mit dem Standard-CA-Bundle Ihres Betriebssystems zu prüfen, z. B. mit dem Paket ca-certificates unter Debian. Die Prüfung schlägt fehl, weil das Standard-CA-Bundle nicht die in dieser Anleitung erstellte Stamm-CA enthält.

    • Das Flag --resolve weist curl an, die IP-Adresse des internen Passthrough-Netzwerk-Load Balancers als Ziel für Anfragen zum Hosten von hello.example.com auf Port 443 zu verwenden.

      Wenn Sie dieses Flag weglassen, versucht curl, mithilfe von DNS den Hostnamen hello.example.com aufzulösen. Die DNS-Auflösung schlägt fehl, weil für diesen Hostnamen kein DNS-Eintrag vorhanden ist.

      In Ihrer eigenen Umgebung empfehlen wir, einen DNS-A-Eintrag zu erstellen, der auf die IP-Adresse des internen Passthrough-Netzwerk-Load Balancers ($LOAD_BALANCER_IP) verweist. Erstellen Sie diesen Eintrag mithilfe von Cloud DNS. Folgen Sie dazu der Dokumentation zum Verwalten von Einträgen.

    • Das Flag --silent unterdrückt die Berichterstellung zum Fortschritt beim Herunterladen der Antwort in der Terminalausgabe.

    • Der Befehl leitet die curl-Ausgabe an head -n1 weiter. Das hat zur Folge, dass die Ausgabe im Terminal nur die erste Zeile des Antworttexts enthält.

  16. Verlassen Sie die SSH-Sitzung:

    exit
    

In diesem Abschnitt haben Sie direkt über die CA Service API ein Client-TLS-Zertifikat angefordert. Wenn der Client das Ausgangsgateway eines anderen Service Mesh in einem separaten Kubernetes-Cluster ist, können Sie das cert-Manager-Tool und den Aussteller des CA Service mit derselben Stammzertifizierungsstelle verwenden, um Clientzertifikate für das Ausgangsgateway bereitzustellen.

In anderen Situationen können Sie Tools wie HashiCorp Vault, Terraform oder gcloud verwenden, um Client-TLS-Zertifikate für Arbeitslasten außerhalb des Service Mesh anzufordern. Weitere Informationen finden Sie in der CA Service-Dokumentation für Beispiellösungen und in der gcloud-Dokumentation für CA Service.

(Optional) CA-Zertifikate dem Trust Store hinzufügen

In diesem optionalen Abschnitt wird gezeigt, wie Sie dem Speicher vertrauenswürdige CA-Zertifikate für die Debian-Distribution von Linux CA-Zertifikate hinzufügen. Diese Anleitung gilt auch für Distributionen, die von Debian abgeleitet werden, z. B. Ubuntu.

Wenn Sie Ihre CA-Zertifikate in diesen Speicher aufnehmen, müssen Sie den Standort vertrauenswürdiger CA-Zertifikate nicht angeben, wenn Sie HTTPS-Anfragen mit curl, Python, Go und Ruby senden.

  1. Stellen Sie eine SSH-Verbindung zur VM-Instanz her.

    gcloud compute ssh cas-tutorial-client --zone ZONE
    

    Führen Sie die übrigen Befehle in diesem Abschnitt aus der SSH-Sitzung aus.

  2. Kopieren Sie das Zertifikat der Stammzertifizierungsstelle in das Verzeichnis /usr/local/share/ca-certificates und achten Sie darauf, dass die Datei die Erweiterung .crt hat:

    sudo cp root-ca-cert.pem /usr/local/share/ca-certificates/cas-rootca.crt
    
  3. Legen Sie die Dateiberechtigungen fest, damit alle Nutzer die Datei der Stammzertifizierungsstelle lesen können:

    sudo chmod 644 /usr/local/share/ca-certificates/cas-rootca.crt
    
  4. Führen Sie das Skript update-ca-certificates aus:

    sudo update-ca-certificates
    

    Mit diesem Skript wird das Zertifikat dem Satz vertrauenswürdiger Zertifikate im Verzeichnis /etc/ssl/certs und der Datei /etc/ssl/certs/ca-certificates.crt hinzugefügt.

    Die Ausgabe sieht so aus:

    Updating certificates in /etc/ssl/certs...
    1 added, 0 removed; done.
    Running hooks in /etc/ca-certificates/update.d...
    done.
    
  5. Verwenden Sie curl, um eine HTTPS-Anfrage von der VM-Instanz an die Beispielanwendung zu senden:

    curl --cert client-cert-chain.pem --key private-key.pem \
       --resolve hello.example.com:443:$(cat ilb-ip.txt) \
       --silent https://hello.example.com | head -n1
    

    Sie erhalten folgende Ausgabe:

    Hello, world!
    

    Diese Antwort zeigt, dass curl die HTTPS-Anfrage erfolgreich mit mTLS gesendet und das Server-TLS-Zertifikat vom Ingress-Gateway mit dem Standard-CA-Zertifikatsspeicher validiert wurde.

  6. Verlassen Sie die SSH-Sitzung:

    exit
    

Fehlerbehebung

Wenn der CA Service-Aussteller-Controller das TLS-Zertifikat-Secret nicht erstellt, rufen Sie die Logs des CA Dienst-Aussteller-Controllers auf:

kubectl logs deployment/google-cas-issuer --namespace cert-manager

Wenn bei der Installation von Cloud Service Mesh Probleme auftreten, führen Sie das asmcli-Tool aus, um Ihr Cloud-Projekt und den GKE-Cluster zu validieren.

Wenn Sie Probleme mit dieser Anleitung haben, empfehlen wir Ihnen, die folgenden Dokumente zu lesen:

Bereinigen

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

  1. Löschen Sie das Projekt in Cloud Shell:

    gcloud projects delete PROJECT_ID
    

Ressourcen löschen

Wenn Sie das in dieser Anleitung verwendete Google Cloud-Projekt beibehalten möchten, löschen Sie die einzelnen Ressourcen:

  1. Heben Sie in Cloud Shell die Registrierung des GKE-Clusters im GKE-Hub auf:

    gcloud container hub memberships unregister CLUSTER_NAME \
        --gke-cluster ZONE/CLUSTER_NAME
    
  2. Löschen Sie den GKE-Cluster:

    gcloud container clusters delete CLUSTER_NAME \
        --zone ZONE --async --quiet
    
  3. Löschen Sie die IAM-Richtlinienbindungen für den untergeordneten CA-Pool:

    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
    gcloud privateca pools remove-iam-policy-binding SUBORDINATE_CA_POOL_GATEWAYS \
        --location CA_LOCATION \
        --member "serviceAccount:CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com" \
        --role roles/privateca.certificateRequester
    
  4. Deaktivieren und planen Sie das Löschen der untergeordneten Zertifizierungsstellen und der Stammzertifizierungsstelle:

    gcloud privateca subordinates disable SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_GATEWAYS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_GATEWAYS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca subordinates disable SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --quiet
    
    gcloud privateca subordinates delete SUBORDINATE_CA_SIDECARS \
        --location CA_LOCATION \
        --pool SUBORDINATE_CA_POOL_SIDECARS \
        --ignore-active-certificates \
        --quiet
    
    gcloud privateca roots disable ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --quiet
    
    gcloud privateca roots delete ROOT_CA \
        --location CA_LOCATION \
        --pool ROOT_CA_POOL \
        --ignore-active-certificates \
        --quiet
    
  5. Löschen Sie die IAM-Richtlinienbindung für das Google-Dienstkonto des CA Service-Aussteller-Controllers:

    gcloud iam service-accounts remove-iam-policy-binding \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[cert-manager/ksa-google-cas-issuer]" \
        --role roles/iam.workloadIdentityUser
    
  6. Löschen Sie die Google-Dienstkonten:

    gcloud iam service-accounts delete --quiet \
        CAS_ISSUER_GSA@PROJECT_ID.iam.gserviceaccount.com
    
    gcloud iam service-accounts delete --quiet \
        CLIENT_VM_GSA@PROJECT_ID.iam.gserviceaccount.com
    
  7. Löschen Sie die reservierte IP-Adresse des Load-Balancers:

    gcloud compute addresses delete asm-ingress-gateway-ilb \
        --region REGION --quiet
    
  8. Löschen Sie die Compute Engine-VM-Instanz:

    gcloud compute instances delete cas-tutorial-client \
        --zone ZONE --quiet
    

Nächste Schritte