Private GKE-Cluster mit Netzwerk-Proxys für Controller-Zugriff erstellen

Last reviewed 2019-07-02 UTC

Wenn Sie einen privaten GKE-Cluster mit einem privaten Cluster-Controller-Endpunkt erstellen, ist der Zugriff auf den Controller-Knoten des Clusters über das öffentliche Internet nicht möglich. Er muss jedoch für die Administration zugänglich sein.

Standardmäßig können Cluster über den privaten Endpunkt des Controllers auf diesen zugreifen. Außerdem können autorisierte Netzwerke in der VPC definiert werden.

Für den Zugriff auf den Controller von einem lokalen oder einem anderen VPC-Netzwerk aus sind jedoch zusätzliche Schritte erforderlich. Dies liegt daran, dass das VPC-Netzwerk, das den Controller hostet, Google gehört und nicht über Ressourcen zugänglich ist, die über eine andere VPC-Netzwerk-Peering-Verbindung, Cloud VPN oder Cloud Interconnect verbunden sind.

Wenn Sie von einem lokalen oder einem anderen über Cloud VPN oder Cloud Interconnect verbundenen VPC-Netzwerk auf den Controller zugreifen möchten, aktivieren Sie den Export von Routen von Ihrem VPC-Netzwerk zum VPC-Netzwerk von Google.

Wenn Sie den Zugriff auf den Controller über ein anderes VPC-Netzwerk oder lokal über ein anderes VPC-Netzwerk-Peering (z. B. Hub-and-Spoke-Designs) ermöglichen möchten, erstellen Sie einen Proxy, der in einem autorisierten IP-Adressbereich gehostet wird, da VPC-Netzwerk-Peering nicht transitiv ist.

In dieser Anleitung erfahren Sie, wie Sie einen Proxy in Ihrem privaten GKE-Cluster konfigurieren.

Ziele

  • Privaten GKE-Cluster ohne externen Zugriff erstellen
  • Docker-Image zum Ausführen des Proxys anlegen und bereitstellen
  • Kubernetes-Dienst für den Zugriff auf den Proxy erstellen
  • Zugriff auf den Proxy testen

Kosten

In dieser Anleitung werden kostenpflichtige Komponenten der Google Cloud Platform verwendet, darunter:

Mit dem Preisrechner können Sie eine Kostenschätzung für die geplante Nutzung vornehmen.

Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.

Vorbereitung

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Compute Engine and Google Kubernetes Engine APIs.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine and Google Kubernetes Engine APIs.

    Enable the APIs

Umgebung einrichten

In dieser Anleitung verwenden Sie Cloud Shell zum Eingeben von Befehlen. Mit Cloud Shell erhalten Sie Zugriff auf die Befehlszeile der Google Cloud Console. Außerdem enthält Cloud Shell das die Google Cloud CLI und weitere Tools, die Sie für die Entwicklung in Google Cloud benötigen. Cloud Shell wird am unteren Rand der Google Cloud Console als Fenster angezeigt. Die Initialisierung kann einige Minuten dauern, aber das Fenster ist sofort sichtbar.

So richten Sie Ihre Umgebung mit Cloud Shell ein:

  1. Öffnen Sie Cloud Shell in der Google Cloud Console.

    Zu Cloud Shell

  2. Achten Sie darauf, dass Sie in dem Projekt arbeiten, das Sie erstellt oder ausgewählt haben. Ersetzen Sie [YOUR_PROJECT_ID] durch Ihr Google Cloud-Projekt.

    gcloud config set project [YOUR_PROJECT_ID]
    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  3. Stellen Sie die Standardzone für die Verarbeitung ein. Für diese Anleitung ist dies us-central1-c. Wenn das Deployment in einer Produktionsumgebung erfolgt, wählen Sie hierzu eine Region Ihrer Wahl aus.

    gcloud config set compute/region us-central1
    gcloud config set compute/zone us-central1-c
    export REGION=us-central1
    export ZONE=us-central1-c
    
    

VPC-Netzwerk und Client-VM erstellen

Erstellen Sie ein VPC-Netzwerk und ein Subnetz zum Hosten der Ressourcen.

  1. Erstellen Sie ein VPC-Netzwerk:

    gcloud compute networks create k8s-proxy --subnet-mode=custom
    
  2. Erstellen Sie im neu erstellten VPC-Netzwerk ein benutzerdefiniertes Subnetz:

    gcloud compute networks subnets create subnet-cluster \
        --network=k8s-proxy --range=10.50.0.0/16
    
  3. Erstellen Sie eine Client-VM, mit der Sie im Kubernetes-Cluster Ressourcen bereitstellen:

    gcloud compute instances create --subnet=subnet-cluster \
        --scopes cloud-platform proxy-temp
    
  4. Speichern Sie die interne IP-Adresse der neu erstellten Instanz in einer Umgebungsvariablen:

    export CLIENT_IP=`gcloud compute instances describe proxy-temp \
        --format="value(networkInterfaces[0].networkIP)"`
    
  5. Erstellen Sie eine Firewallregel, um SSH-Zugriff auf das VPC-Netzwerk zu ermöglichen:

    gcloud compute firewall-rules create k8s-proxy-ssh --network k8s-proxy \
        --allow tcp:22
    

Private Cluster erstellen

Erstellen Sie nun einen privaten Cluster für diese Anleitung.

Falls Sie bereits einen Cluster haben, den Sie lieber verwenden möchten, können Sie den Schritt zum Erstellen des Clusters überspringen. Allerdings müssen Sie Ihren Clientcomputer so konfigurieren, dass ein Erstzugriff möglich ist.

  • Erstellen Sie in Cloud Shell einen Cluster:

    gcloud container clusters create frobnitz  \
        --master-ipv4-cidr=172.16.0.64/28 \
        --network k8s-proxy \
        --subnetwork=subnet-cluster \
        --enable-ip-alias \
        --enable-private-nodes \
        --enable-private-endpoint \
        --master-authorized-networks $CLIENT_IP/32 \
        --enable-master-authorized-networks
    

    Der Befehl erstellt einen privaten GKE-Cluster mit dem Namen frobnitz, auf dem master-authorized-networks so festgelegt ist, dass nur dem Clientcomputer Zugriff gewährt wird.

Docker-Image erstellen

Erstellen Sie anhand der folgenden Schritte ein Proxy-Image für die Kubernetes API namens k8s-api-proxy,, das als Weiterleitungs-Proxy für den Kubernetes API-Server fungiert.

  1. Erstellen Sie in Cloud Shell ein Verzeichnis und wechseln Sie in dieses Verzeichnis:

    mkdir k8s-api-proxy && cd k8s-api-proxy
  2. Erstellen Sie Dockerfile. Die folgende Konfiguration erstellt einen Container auf der Basis von Alpine. Dies ist eine einfache Containerverteilung mit einem Privoxy-Proxy. Das Dockerfile installiert außerdem curl und jq für die Containerinitialisierung, fügt die erforderlichen Konfigurationsdateien hinzu, gibt Port 8118 intern für GKE frei und fügt ein Startskript hinzu.

    FROM alpine
    RUN apk add -U curl privoxy jq && \ mv /etc/privoxy/templates /etc/privoxy-templates && \ rm -rf /var/cache/apk/* /etc/privoxy/* && \ mv /etc/privoxy-templates /etc/privoxy/templates ADD --chown=privoxy:privoxy config \ /etc/privoxy/ ADD --chown=privoxy:privoxy k8s-only.action \ /etc/privoxy/ ADD --chown=privoxy:privoxy k8s-rewrite-internal.filter \ /etc/privoxy/ ADD k8s-api-proxy.sh /
    EXPOSE 8118/tcp
    ENTRYPOINT ["./k8s-api-proxy.sh"]
  3. Erstellen Sie im Verzeichnis k8s-api-proxy die Datei config und fügen Sie ihr folgenden Inhalt hinzu:

    #config directory
    confdir /etc/privoxy
    # Allow Kubernetes API access only
    actionsfile /etc/privoxy/k8s-only.action
    # Rewrite https://CLUSTER_IP to https://kubernetes.default
    filterfile /etc/privoxy/k8s-rewrite-internal.filter
    # Don't show the pod name in errors
    hostname k8s-privoxy
    # Bind to all interfaces, port :8118
    listen-address  :8118
    # User cannot click-through a block
    enforce-blocks 1
    # Allow more than one outbound connection
    tolerate-pipelining 1
    
  4. Erstellen Sie im selben Verzeichnis die Datei k8s-only.action und fügen Sie ihr den folgenden Inhalt hinzu. Beachten Sie, dass CLUSTER_IP ersetzt wird, wenn k8s-api-proxy.sh ausgeführt wird.

    # Block everything...
    {+block{Not Kubernetes}}
    /
    # ... except the internal k8s endpoint, which you rewrite (see # k8s-rewrite-internal.filter). {+client-header-filter{k8s-rewrite-internal} -block{Kubernetes}} CLUSTER_IP/
  5. Erstellen Sie die Datei k8s-rewrite-internal.filter und fügen Sie ihr folgenden Inhalt hinzu. Beachten Sie, dass CLUSTER_IP ersetzt wird, wenn k8s-api-proxy.sh ausgeführt wird.

    CLIENT-HEADER-FILTER: k8s-rewrite-internal\
     Rewrite https://CLUSTER_IP/ to https://kubernetes.default/
    s@(CONNECT) CLUSTER_IP:443\
     (HTTP/\d\.\d)@$1 kubernetes.default:443 $2@ig
    
  6. Erstellen Sie die Datei k8s-api-proxy.sh und fügen Sie ihr folgenden Inhalt hinzu.

    #!/bin/sh
    
    set -o errexit
    set -o pipefail
    set -o nounset
    
    # Get the internal cluster IP
    export TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
    INTERNAL_IP=$(curl -H "Authorization: Bearer $TOKEN" -k -SsL https://kubernetes.default/api |
    jq -r '.serverAddressByClientCIDRs[0].serverAddress')
    
    # Replace CLUSTER_IP in the rewrite filter and action file
    sed -i "s/CLUSTER_IP/${INTERNAL_IP}/g"\
     /etc/privoxy/k8s-rewrite-internal.filter
    sed -i "s/CLUSTER_IP/${INTERNAL_IP}/g"\
     /etc/privoxy/k8s-only.action
    
    # Start Privoxy un-daemonized
    privoxy --no-daemon /etc/privoxy/config
    
  7. Machen Sie k8s-api-proxy.sh ausführbar.

    chmod +x k8s-api-proxy.sh
  8. Erstellen Sie den Container und verschieben Sie ihn in Ihr Projekt.

    docker build -t gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 .
    docker push gcr.io/$PROJECT_ID/k8s-api-proxy:0.1
    

Image und Dienst bereitstellen

  1. Melden Sie sich in Cloud Shell bei der Client-VM an, die Sie zuvor erstellt haben:

    gcloud compute ssh proxy-temp
    
  2. Installieren Sie das kubectl-Tool:

    sudo apt-get install kubectl
    
  3. Speichern Sie die Projekt-ID als Umgebungsvariable:

    export PROJECT_ID=`gcloud config list --format="value(core.project)"`
    
  4. Rufen Sie die Clusteranmeldedaten ab:

    gcloud container clusters get-credentials frobnitz \
    --zone us-central1-c --internal-ip
    
  5. Erstellen Sie ein Kubernetes-Deployment, das den gerade erstellten Container zur Verfügung stellt:

    kubectl run k8s-api-proxy \
        --image=gcr.io/$PROJECT_ID/k8s-api-proxy:0.1 \
        --port=8118
    
  6. Erstellen Sie die Datei ilb.yaml für den internen Load-Balancer und kopieren Sie Folgendes in diese Datei:

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        run: k8s-api-proxy
      name: k8s-api-proxy
      namespace: default
      annotations:
        cloud.google.com/load-balancer-type: "Internal"
    spec:
      ports:
      - port: 8118
        protocol: TCP
        targetPort: 8118
      selector:
        run: k8s-api-proxy
      type: LoadBalancer
    
  7. Stellen Sie den internen Load-Balancer bereit:

    kubectl create -f ilb.yaml
  8. Überprüfen Sie den Dienst und warten Sie auf eine IP-Adresse:

    kubectl get service/k8s-api-proxy

    Die Ausgabe sollte wie unten gezeigt aussehen. Wenn Sie eine externe IP-Adresse sehen, ist der Proxy bereit.

    NAME            TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
    k8s-api-proxy   LoadBalancer   10.24.13.129   10.24.24.3    8118:30282/TCP   2m
    

    Die externe IP-Adresse aus diesem Schritt ist Ihre Proxy-Adresse.

  9. Speichern Sie die IP-Adresse des internen Load-Balancers als Umgebungsvariable:

    export LB_IP=`kubectl get  service/k8s-api-proxy \
    -o jsonpath='{.status.loadBalancer.ingress[].ip}'`
    
  10. Speichern Sie die Controller-IP-Adresse des Clusters in einer Umgebungsvariablen:

    export CONTROLLER_IP=`gcloud container clusters describe frobnitz \
    --zone=us-central1-c \
    --format="get(privateClusterConfig.privateEndpoint)"`
    
  11. Damit Sie feststellen können, ob der Proxy verwendet werden kann, greifen Sie über ihn auf die Kubernetes API zu:

    curl -k -x $LB_IP:8118 https://$CONTROLLER_IP/version
    
    Die Ausgabe sieht so aus (Ihre Ausgabe kann abweichen):
    {
      "major": "1",
      "minor": "15+",
      "gitVersion": "v1.15.11-gke.5",
      "gitCommit": "a5bf731ea129336a3cf32c3375317b3a626919d7",
      "gitTreeState": "clean",
      "buildDate": "2020-03-31T02:49:49Z",
      "goVersion": "go1.12.17b4",
      "compiler": "gc",
      "platform": "linux/amd64"
    }
    
  12. Legen Sie die Umgebungsvariable https_proxy auf den HTTP(S)-Proxy fest, damit der Befehl kubectl den internen Load-Balancer von überall aus erreichen kann:

    export https_proxy=$LB_IP:8118
  13. Testen Sie Ihren Proxy und die Variable https_proxy mit dem Befehl kubectl:

    kubectl get pods

    Sie erhalten eine Ausgabe, die wie die folgende aussieht. Dies bedeutet, dass Sie über den Proxy erfolgreich eine Verbindung zur Kubernetes API hergestellt haben:

    NAME                             READY   STATUS    RESTARTS   AGE
    k8s-api-proxy-766c69dd45-mfqf4   1/1     Running   0          6m15s
    
  14. Beenden Sie die Client-VM:

    exit

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.

Projekt löschen

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

GKE-Cluster löschen

Wenn Sie das Projekt nicht löschen möchten, löschen Sie den GKE-Cluster:

gcloud container clusters delete frobnitz

Nächste Schritte