TLS-Terminierung im Ingress-Gateway einrichten

Übersicht

Auf dieser Seite wird gezeigt, wie Sie eine TLS-Terminierung im Ingress-Gateway in Cloud Service Mesh einrichten, um externen HTTPS-Traffic zu Ihren Diensten zu verwalten. Eine grundlegende Einführung in die Einrichtung von Gateways finden Sie im Leitfaden zu Gateways. Sie erfahren, wie Sie das Gateway für die sichere Kommunikation mit TLS konfigurieren, um den verschlüsselten Zugriff auf Ihre Anwendungen zu ermöglichen. Dabei werden die Funktionen von Cloud Service Mesh genutzt, um Dienste sicher bereitzustellen.

Hinweise

Für die Schritte in diesem Dokument benötigen Sie die folgenden Ressourcen:

  • Einen Kubernetes-Cluster mit installiertem Cloud Service Mesh. Weitere Informationen zur Installation von Cloud Service Mesh finden Sie in der Installationsanleitung.

Umgebung einrichten

Führen Sie die folgenden Befehle über eine Workstation aus, die auf den Cluster zugreifen kann, den Sie verwenden möchten. Achten Sie darauf, dass das kubectl-Tool so konfiguriert ist, dass es den für Ihren Cluster spezifischen Clusterkontext verwendet.

  1. Legen Sie die Umgebungsvariablen fest.

    export CSM_INGRESSGATEWAY_NAMESPACE=CSM_INGRESSGATEWAY_NAMESPACE
    export CSM_INGRESSGATEWAY_DEPLOYMENT_NAME=CSM_INGRESSGATEWAY_DEPLOYMENT_NAME
    export CSM_INGRESSGATEWAY_SERVICE_NAME=CSM_INGRESSGATEWAY_SERVICE_NAME
    
  2. Stellen Sie die foo-Anwendung in Ihrem Cluster bereit. Installieren Sie es mit der folgenden YAML-Datei:

    apiVersion: v1
    kind: Service
    metadata:
      name: foo
      namespace: foo
    spec:
      selector:
        app: test-backend
      ports:
      - port: 8080
        targetPort: 8080
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: foo
      namespace: foo
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: test-backend
      template:
        metadata:
          labels:
            app: test-backend
        spec:
          containers:
          - name: whereami
            image: gcr.io/google-samples/whereami:v1.2.23
            ports:
            - containerPort: 8080
    EOF
    
  3. Generieren Sie Zertifikate und Schlüssel.

    Zum Schützen Ihres Ingress-Gateways benötigen Sie TLS-Zertifikate und ‑Schlüssel. Sie können ein beliebiges Zertifikatgenerierungstool verwenden oder mit openssl die erforderlichen Anmeldedaten erstellen.

    • Root-Zertifikat und ‑Schlüssel der Zertifizierungsstelle erstellen
    mkdir example_certs
    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example Corp/CN=example.com' \
      -keyout example.com.key -out example.com.crt
    
    • Zertifikat und Schlüssel für Ingress generieren
    openssl req -out foo.example.com.csr -newkey rsa:2048 -nodes \
      -keyout foo.example.com.key -subj "/CN=foo.example.com/O=Foo Org"
    
    openssl x509 -req -sha256 -days 365 -CA example.com.crt \
      -CAkey example.com.key -set_serial 0 \
      -in foo.example.com.csr -out foo.example.com.crt
    

TLS-Ingress-Gateway einrichten

In den folgenden Schritten wird beschrieben, wie Sie ein TLS-Ingress-Gateway einrichten.

TLS-Zertifikat speichern

  1. Erstellen Sie den Namespace. Dieser Namespace wird zum Bereitstellen des Ingress-Gateways verwendet.

    kubectl create namespace ${CSM_INGRESSGATEWAY_NAMESPACE}
    
  2. Wenden Sie das Standard-Injektionslabel auf den Namespace an:

    kubectl label namespace ${CSM_INGRESSGATEWAY_NAMESPACE} \
        istio.io/rev- istio-injection=enabled --overwrite
    
  3. Speichern Sie die TLS-Anmeldedaten in einem Kubernetes-Secret:

    kubectl create -n ${CSM_INGRESSGATEWAY_NAMESPACE} secret tls foo-credential \
      --key=example_certs/foo.example.com.key \
      --cert=example_certs/foo.example.com.crt
    

TLS-Zertifikat auf das Gateway anwenden

Es gibt zwei Möglichkeiten, das Gateway dazu zu bringen, das neu erstellte TLS-Zertifikat zu verwenden.

Bereitstellung mit bereitgestellten Anmeldedaten (bevorzugt)

  1. Kopieren Sie das Standard-Ingress-Gateway-Manifest in eine lokale Datei.

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml > ingress-gateway.yaml
    
  2. Ändern Sie die Bereitstellungsspezifikation in ingress-gateway.yaml, um die TLS-Secret-Anmeldedaten bereitzustellen.

    apiVersion: apps/v1
    kind: Deployment
    ...
    spec:
      ...
        spec:
            ...
            volumeMounts:
            - name: foo-credential # Add new volume mount specifying mount path.
              mountPath: /etc/secrets/foo-credential 
              readOnly: true
          volumes:
          - name: foo-credential # Point volume mount to the Kubernetes secret holding the TLS certificate and keys.
            secret:
              secretName: foo-credential
    

    Erstellen Sie dann die Ressourcen für das Ingress-Gateway.

    kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename ingress-gateway.yaml 
    
  3. Definieren Sie das Ingress-Gateway.

    Erstellen Sie eine Gateway-Ressource, um HTTPS-Traffic an Port 443 zu verarbeiten, der auf die bereitgestellten Secrets verweist:

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1
    kind: Gateway
    metadata:
      name: secure-gateway
      namespace: ${CSM_INGRESSGATEWAY_NAMESPACE}
    spec:
      selector:
        app: asm-ingressgateway
        istio: ingressgateway
      servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        tls:
          mode: SIMPLE
          serverCertificate: /etc/secrets/foo-credential/foo.example.com.crt
          privateKey: /etc/secrets/foo-credential/foo.example.com.key
        hosts:
        - "foo.example.com"
    EOF
    

Bereitstellung ohne bereitgestellte Anmeldedaten

  1. Wenden Sie die Manifestdatei des Ingress-Gateways an.

    kubectl --namespace ${CSM_INGRESSGATEWAY_NAMESPACE} apply --filename https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/ingress-gateway-external-lb/ingress-gateway.yaml
    

    Erwartete Ausgabe:

    serviceaccount/asm-ingressgateway created
    role.rbac.authorization.k8s.io/asm-ingressgateway created
    rolebinding.rbac.authorization.k8s.io/asm-ingressgateway created
    deployment.apps/asm-ingressgateway created
    service/asm-ingressgateway created
    poddisruptionbudget.policy/asm-ingressgateway created
    horizontalpodautoscaler.autoscaling/asm-ingressgateway created
    
  2. Definieren Sie das Ingress-Gateway.

    Erstellen Sie eine Gateway-Ressource, um HTTPS-Traffic an Port 443 zu verarbeiten:

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1
    kind: Gateway
    metadata:
      name: secure-gateway
      namespace: ${CSM_INGRESSGATEWAY_NAMESPACE}
    spec:
      selector:
        app: asm-ingressgateway
        istio: ingressgateway
      servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        tls:
          mode: SIMPLE
          credentialName: foo-credential
        hosts:
        - "foo.example.com"
    EOF
    

Test-Traffic

  1. Leiten Sie den Traffic an den foo-Dienst weiter.

    Definieren Sie einen VirtualService, um den Traffic an die Bereitstellung „foo“ weiterzuleiten:

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
      name: foo-routing
      namespace: ${CSM_INGRESSGATEWAY_NAMESPACE}
    spec:
      hosts:
      - "foo.example.com"
      gateways:
      - secure-gateway
      http:
      - match:
        - uri:
            prefix: /status
        - uri:
            prefix: /delay
        route:
        - destination:
            host: foo
            port:
              number: 8080
    EOF
    
  2. Richten Sie den externen Load Balancer ein, um eine Verbindung zum Ingress-Gateway aus dem Cluster herzustellen.

  3. Testen Sie die sichere Verbindung.

    Prüfen Sie die Einrichtung mit dem folgenden curl-Befehl:

    export EXTERNAL_LB_IP_ADDRESS=EXTERNAL_LB_IP_ADDRESS
    curl -v -H "Host: foo.example.com" --resolve "foo.example.com:443:$EXTERNAL_LB_IP_ADDRESS" \
      --cacert example_certs/example.com.crt "https://foo.example.com:443/ping"
    

    Ersetzen Sie EXTERNAL_LB_IP_ADDRESS durch die IP-Adresse des externen Load Balancers.

    Die Ausgabe sieht etwa so aus:

      {
        "cluster_name": "gke-us",
        "host_header": "34.120.175.141",
        "pod_name": "whereami-deployment-954cbf78-mtlpf",
        "pod_name_emoji": "😎",
        "project_id": "my-project",
        "timestamp": "2021-11-29T17:01:59",
        "zone": "us-central1-b"
      }
    

Nächste Schritte