Privat genutzte öffentliche IP-Adressen für GKE konfigurieren

In dieser Anleitung wird beschrieben, wie Sie privat genutzte öffentliche IP-Adressen für Pod-Adressblöcke von Google Kubernetes Engine (GKE) verwenden. Dienstnutzerorganisationen, die durch IPv4-Adressen eingeschränkt sind, können PAPI-Adressen in Virtual Private Clouds (VPCs) als Adressverwaltungsoption verwenden.

Dieses Dokument richtet sich an Netzwerkarchitekten und GKE-Systemadministratoren, deren Unternehmen verwaltete Dienste über eine GKE-Infrastruktur in Google Cloud anbieten.

Einführung

Einige Unternehmen möchten verwaltete Dienste für ihre Kunden über Kubernetes- oder GKE-Cluster in Google Cloud bereitstellen. Kubernetes kann jedoch viele IP-Adressen für die verschiedenen Komponenten haben. Einigen Organisationen fällt es nicht leicht oder sie können diese Anforderung gar nicht erfüllen, da sie keine CIDR-Blöcke (Classless Inter-Domain Routing) in der richtigen Größe (10.0.0.0/8, 172.16.0.0/12 und 192.168.0.0/16 (RFC 1918)) zuweisen können.

Eine Möglichkeit, die Ausschöpfung von Adressen zu reduzieren, besteht darin, privat genutzte öffentliche IP-Adressen (Privately Used Public IPs; PUPIs) für den CIDR-Block des GKE-Pods zu verwenden. PUPIs sind öffentliche IP-Adressen, die nicht Google gehören und die ein Kunde privat in Google Cloud verwenden kann. Der Kunde ist nicht zwingend Inhaber dieser Adressen.

Das folgende Diagramm zeigt ein Unternehmen (Producer), das einem Kunden (Nutzer) einen verwalteten Dienst anbietet.

PUPI-Adressen für den CIDR-Block des GKE-Pods.

Dieses Setup beinhaltet folgende Überlegungen:

  • Primärer CIDR-Block: Ein Nicht-PUPI-CDR-Block, der für Knoten und ILB verwendet wird und VPCs nicht überlappen darf.
  • Sekundärer CIDR-Block für Producer: Ein PUPI-CIDR-Block, der für Pods verwendet wird (z. B. 45.45.0.0/16).
  • Sekundärer CIDR-Block für Nutzer: Jeder andere PUPI-CIDR-Block auf Kundenseite (z. B. 5.5/16)

Der verwaltete Dienst des Unternehmens befindet sich in der Produzenten-VPC (vpc-producer) und basiert auf einer GKE-Bereitstellung. Der GKE-Cluster des Unternehmens verwendet den PUPI-CIDR-Block 45.0.0.0/8 für Pod-Adressen. Die Anwendungen des Kunden befinden sich in der Nutzer-VPC (vpc-consumer). Der Kunde hat auch eine GKE-Installation. Der GKE-Cluster in der Nutzer-VPC verwendet den PUPI-CIDR-Block 5.0.0.0/8 für Pod-Adressen. Die beiden VPCs werden über Peering verbunden. Beide VPCs verwenden für die Knoten-, Dienst- und Load-Balancing-Adressen den Adressbereich RFC 1918.

Standardmäßig exportiert die Nutzer-VPC (vpc-consumer) alle RFC 1918 in die Producer-VPC (vpc-producer). Im Gegensatz zu privaten RFC 1918-Adressen und erweiterten privaten Adressen (CGN, Klasse E) werden PUPIs nicht standardmäßig automatisch für VPC-Peers beworben. Wenn die vpc-consumer-Pods mit vpc-producer kommunizieren müssen, muss der Nutzer die VPC-Peering-Verbindung aktivieren, um PUPI-Adressen zu exportieren. Ebenso muss der Producer die Producer-VPC so konfigurieren, dass PUPI-Routen über die VPC-Peering-Verbindung importiert werden.

Der in vpc-producer exportierte Adressbereich vpc-consumer darf sich nicht mit einer in vpc-producer verwendeten RFC 1918- oder PUPI-Adresse überschneiden. Der Producer muss dem Nutzer mitteilen, welche PUPI-CIDR-Blöcke der verwalteter Dienst verwendet und darauf achten, dass der Nutzer diese Blöcke nicht verwendet. Producer und Nutzer müssen sich außerdem einigen und den nicht überlappenden Adressbereich für internes Load-Balancing (ILB) und Knotenadressen in vpc-producer zuweisen.

In den meisten Fällen kommunizieren Ressourcen in vpc-consumer mit Diensten in vpc-producer über ILB-Adressen im Producer-Cluster. Wenn die Producer-Pods die Kommunikation direkt mit Ressourcen in vpc-consumer initiieren müssen, und die PUPI-Adressierung nicht überlappt, muss der Producer die Producer-VPC so konfigurieren, dass die PUPI-Routen über die VPC-Peering-Verbindung exportiert werden. Ebenso muss der Nutzer die VPC-Peering-Verbindung so konfigurieren, dass Routen in vpc-consumer importiert werden. Wenn die Nutzer-VPC bereits die PUPI-Adresse verwendet, sollte der Producer stattdessen das IP-Masquerade-Feature konfigurieren und die Pod-IP-Adressen hinter den IP-Adressen des Producer-Knotens verbergen.

Die folgende Tabelle zeigt die Standard-Import- und Exporteinstellungen für jede VPC. Sie können Standard-VPC-Peering-Einstellungen mit dem Cloud SDK-Befehl gcloud compute networks peerings update ändern.

PUPI-Flag Import Export
Producer-Seite (Flags, die über Dienstnetzwerke gesteuert werden)

Aktivieren: --import-subnet-routes-with-public-ip (über Peering)

Standardverhalten: Deaktiviert

Deaktivieren: --no-export-subnet-routes-with-public-ip (über Peering)

Standardverhalten: Aktiviert

Nutzerseite (gehört dem Kunden, muss nicht über das Dienstnetzwerk geändert werden) Deaktiviert (Standard) Aktiviert (Standard)

Diese Einstellungen führen zu Folgendem:

  • In der Producer-VPC werden alle Kundenrouten angezeigt.
  • In der Nutzer-VPC werden die PUPI-Routen, die auf dem Pod-Subnetz in der Producer-VPC konfiguriert sind, nicht angezeigt.
  • Traffic von den Producer-Pods zum vpc-consumer-Netzwerk muss hinter den Knotenadressen im Producer-Cluster übersetzt werden.

Qualifikationen

  • Der Adressbereich, den Sie für eine PUPI auswählen, kann nicht über das Internet erreichbar oder eine Adresse von Google sein.
  • Die Knoten-IPs und der primäre Bereich dürfen nicht zwischen den beiden VPCs überlappen.
  • Wenn eine direkte Pod-zu-Pod-Kommunikation zwischen der VPC des Kunden und dem verwalteten Dienst erforderlich ist, müssen die IP-Adressen der Producer-Pods hinter den entsprechenden Knoten-IPs übersetzt werden.

Ziele

  • Zwei VPC-Netzwerke konfigurieren
  • Ein Subnetz in jedem VPC-Netzwerk konfigurieren
  • In jedem Subnetz einen PUPI-Adressbereich in einem sekundären Adressbereich konfigurieren
  • Eine geeignete VPC-Peering-Beziehung zwischen den beiden VPC-Netzwerken mit entsprechenden Import- und Exporteinstellungen herstellen
  • Die Routen in jeder VPC prüfen

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.

Vorbereitung

  1. Aktivieren Sie Cloud Shell in der Cloud Console.

    Cloud Shell aktivieren

    Mit Terraform von HashiCorp und dem Cloud SDK führen Sie den Großteil dieser Anleitung über das Cloud Shell-Terminal aus.

  2. Klonen Sie das GitHub-Repository und wechseln Sie in das lokale Arbeitsverzeichnis:

    git clone https://github.com/GoogleCloudPlatform/terraform-vpc-pupi $HOME/pupi
    

    Das Repository enthält alle Dateien, die Sie für diese Anleitung benötigen. Eine vollständige Beschreibung der einzelnen Dateien finden Sie in der Datei README.md im Repository.

  3. Wandeln Sie alle Shell-Skripts in ausführbare Dateien um:

    sudo chmod 755 $HOME/pupi/*.sh
    

Umgebung vorbereiten

In diesem Abschnitt installieren und richten Sie Terraform ein und legen dann Umgebungsvariablen fest.

Terraform einrichten

  1. Folgen Sie den Schritten in der HashiCorp-Dokumentation, um Terraform zu installieren.
  2. Initialisieren Sie in Cloud Shell Terraform:

    cd $HOME/pupi
    terraform init
    

    Die Ausgabe sieht etwa so aus:

    ...
    Initializing provider plugins...
    The following providers do not have any version constraints in
    configuration, so the latest version was installed.
    ...
    Terraform has been successfully initialized!
    ...
    

    Bei der Initialisierung von Terraform werden Statusmeldungen protokolliert. Am Ende der Nachrichtenausgabe wird die Meldung angezeigt, dass Terraform erfolgreich initialisiert wurde.

Umgebungsvariablen festlegen

  1. Legen Sie in Cloud Shell die Variable TF_VAR_org_id fest:

    export TF_VAR_org_id=$(gcloud organizations list | \
        awk '/YOUR_ORGANIZATION_NAME/ {print $2}')
    

    Ersetzen Sie Folgendes:

    • YOUR_ORGANIZATION_NAME: Der Name der Organisation in Google Cloud, den Sie für diese Anleitung verwenden möchten
  2. Prüfen Sie, ob die Umgebungsvariable richtig festgelegt ist:

    echo $TF_VAR_org_id
    

    Die Ausgabe enthält Ihre numerische Organisations-ID und sieht in etwa so aus:

    ...
    123123123123
    ...
    
  3. Legen Sie die restlichen Umgebungsvariablen fest:

    source $HOME/pupi/set_variables.sh
    

    In diesem Shell-Skript werden grundlegende Parameter wie die Google Cloud-Region, die Organisations-ID und die Projekt-ID als Variablen in der Shell-Umgebung festgelegt. Terraform verwendet diese Variablen, um Ihre Google Cloud-Ressourcen zu konfigurieren. Sie können die Parameter im Shell-Skript entsprechend Ihrer Umgebung anpassen oder ändern. Eine vollständige Liste der Variablen finden Sie im Shell-Skript set_variables.

  4. Prüfen Sie, ob die Umgebungsvariablen richtig festgelegt sind:

    env | grep TF_
    

    Die Ausgabe sieht etwa so aus:

    ...
    TF_VAR_billing_account=QQQQQQ-XAAAAA-E8769
    TF_VAR_org_id=406999999999
    TF_VAR_region1=us-west1
    TF_VAR_region2=us-west2
    TF_VAR_consumer_ilb_ip=10.129.0.200
    TF_VAR_user_account=user@example
    TF_VAR_pid=pupi-pid--999999999
    TF_VAR_zone2=us-west2-b
    TF_VAR_zone1=us-west1-b
    ...
    
  5. Erstellen Sie eine Datei mit Umgebungsvariablen:

    $HOME/pupi/saveVars.sh
    

    Mit diesem Befehl werden die von Ihnen erstellten Umgebungsvariablen in eine Datei namens TF_ENV_VARS weitergeleitet. Jeder Variable wird der Befehl export vorangestellt. Wenn Ihre Cloud Shell-Sitzung beendet wurde, können Sie mit dieser Datei die Variablen zurücksetzen. Diese Variablen werden von Terraform-Skripts, Cloud Shell-Skripts und dem gcloud-Befehlszeilentool verwendet.

    Wenn Sie die Variablen später neu initialisieren müssen, führen Sie den folgenden Befehl aus:

    source $HOME/pupi/TF_ENV_VARS
    

Unterstützende Infrastruktur bereitstellen

  1. Stellen Sie in Cloud Shell die unterstützende Infrastruktur von Terraform bereit:

    terraform apply
    

    Geben Sie bei Aufforderung yes ein, um eine der beiden Konfigurationen anzuwenden. Die Bereitstellung der Ressourcen durch Terraform kann einige Minuten dauern.

    Der Befehl terraform apply weist Terraform an, alle Komponenten der Lösung bereitzustellen. Informationen darüber, wie die Infrastruktur deklarativ definiert ist, finden Sie in den Terraform-Manifesten (Dateien mit der Erweiterung .tf).

  2. Richten Sie die VPC-Peering-Beziehung ein. Da sich das Feature in der Alphaphase befindet und von Terraform nicht unterstützt wird, verwenden Sie gcloud-Befehle, um das Peering einzurichten.

    gcloud alpha compute networks peerings create consumer \
        --project="$TF_VAR_pid" \
        --network=consumer \
        --peer-network=producer
    
    gcloud alpha compute networks peerings create producer \
        --project="$TF_VAR_pid" \
        --network=producer \
        --peer-network=consumer \
        --no-export-subnet-routes-with-public-ip \
        --import-subnet-routes-with-public-ip
    

    Standardmäßig exportiert die VPC des Nutzers die PUPI-Adressen. Beim Erstellen der Producer-VPC verwenden Sie die folgenden Argumente, um die VPC so zu konfigurieren, dass sie PUPI-Adressen importiert, aber nicht exportiert:

    --no-export-subnet-routes-with-public-ip
    --import-subnet-routes-with-public-ip
    

Unterstützende Infrastruktur prüfen

Prüfen Sie jetzt, ob Terraform die Ressourcen erfolgreich erstellt hat. Die Ressourcen müssen nach dem Senden eines Befehls antworten.

Projekte prüfen

  1. Listen Sie das Projekt in Cloud Shell auf:

    gcloud projects list | grep pupi-pid
    

    Die Ausgabe sieht etwa so aus:

    ...
    pupi-pid--1234567899            pupi-test             777999333555
    ...
    

    In dieser Ausgabe ist pupi-test der Projektname und pupi-pid- das Präfix Ihrer Projekt-ID.

  2. Listen Sie den API-Status auf:

    gcloud services list --project=$TF_VAR_pid \
        | grep -E "compute|container"
    

    Die Ausgabe sieht etwa so aus:

    ...
    compute.googleapis.com            Compute Engine API
    container.googleapis.com          Kubernetes Engine API
    containerregistry.googleapis.com  Container Registry API
    ...
    

    Diese Ausgabe zeigt, dass die Compute Engine, GKE und Container Registry APIs aktiviert sind.

Netzwerke und Subnetzwerke prüfen

  1. Prüfen Sie in Cloud Shell das Producer-Netzwerk und das Subnetzwerk:

    gcloud compute networks describe producer \
        --project=$TF_VAR_pid
    
    gcloud compute networks subnets describe producer-nodes \
        --project=$TF_VAR_pid \
        --region=$TF_VAR_region1
    

    Die Ausgabe sieht etwa so aus:

    ...
    kind: compute#network
    name: producer
    ...
    ipCidrRange: 10.128.0.0/24
    kind: compute#isubnetwork
    name: producer-nodes
    ...
    secondaryIpRanges:
    - ipCidrRange: 45.45.45.0/24
      rangeName: producer-pods
    - ipCidrRange: 172.16.45.0/24
      rangeName: producer-cluster
    ...
    

    Diese Ausgabe zeigt Folgendes:

    • Das Netzwerk wurde mit dem CIDR-Block 10.128.0.0/24 erstellt.
    • Die beiden Subnetze wurden mit den CIDR-Blöcken 45.45.45.0/24 und 172.16.45.0/24 erstellt.
  2. Prüfen Sie das Nutzernetzwerk und das Subnetzwerk:

    gcloud compute networks describe consumer \
        --project=$TF_VAR_pid
    
    gcloud compute networks subnets describe consumer-nodes \
        --project=$TF_VAR_pid \
        --region=$TF_VAR_region2
    

    Die Ausgabe sieht etwa so aus:

    ...
    kind: compute#network
    name: consumer
    ...
    ipCidrRange: 10.129.0.0/24
    kind: compute#isubnetwork
    name: consumer-nodes
    ...
    secondaryIpRanges:
    - ipCidrRange: 5.5.5.0/24
      rangeName: producer-pods
    - ipCidrRange: 172.16.5.0/24
      rangeName: consumer-cluster
    ...
    

    Diese Ausgabe zeigt Folgendes:

    • Das Netzwerk wurde mit dem CIDR-Block 10.129.0.0/24 erstellt.
    • Die beiden Subnetze wurden mit den CIDR-Blöcken 5.5.5.0/24 und 172.16.5.0/24 erstellt.

GKE-Cluster und seine Ressourcen prüfen

  1. Rufen Sie in Cloud Shell die Clusteranmeldedaten ab:

    gcloud container clusters get-credentials consumer-cluster \
        --project=$TF_VAR_pid \
        --zone=$TF_VAR_zone2
    

    Die Ausgabe sieht etwa so aus:

    ...
    Fetching cluster endpoint and auth data.
    kubeconfig entry generated for consumer-cluster.
    ...
    
  2. Prüfen Sie den Cluster:

    gcloud container clusters list \
        --project=$TF_VAR_pid \
        --zone=$TF_VAR_zone2
    

    Die Ausgabe sieht etwa so aus:

    NAME              LOCATION    MASTER_VERSION  MASTER_IP      MACHINE_TYPE   NODE_VERSION    NUM_NODES  STATUS
    consumer-cluster  us-west2-b  1.14.10-gke.17  35.236.104.74  n1-standard-1  1.14.10-gke.17  3          RUNNING
    

    Diese Ausgabe zeigt einen Cluster mit dem Namen consumer-cluster.

  3. Prüfen Sie die Hello-World-Anwendung:

    kubectl get deployment my-app
    

    Die Ausgabe sieht etwa so aus:

    ...
    NAME     DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    my-app   3         3         3            3           118m
    ...
    

    Diese Ausgabe zeigt eine Bereitstellung mit dem Namen my-app.

  4. Prüfen Sie den internen Load-Balancer-Dienst:

    kubectl get service hello-server
    

    Die Ausgabe sieht etwa so aus:

    NAME           TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)          AGE
    hello-server   LoadBalancer   172.16.5.99   10.129.0.200   8080:31673/TCP   4d23h
    

    Diese Ausgabe zeigt einen Dienst mit dem Namen hello-server.

Lösung prüfen

  1. Prüfen Sie in Cloud Shell, ob das VPC-Peering erfolgreich erstellt wurde:

    gcloud alpha compute networks peerings list
    

    Die Ausgabe sieht etwa so aus:

    NAME      NETWORK   PEER_PROJECT          PEER_NETWORK  IMPORT_CUSTOM_ROUTES  EXPORT_CUSTOM_ROUTES  STATE   STATE_DETAILS
    consumer  consumer  pupi-pid--1324732197  producer      False                 False                 ACTIVE  [2020-02-26T11:33:16.886-08:00]: Connected.
    producer  producer  pupi-pid--1324732197  consumer      False                 False                 ACTIVE  [2020-02-26T11:33:16.886-08:00]: Connected.
    

    Diese Ausgabe zeigt Peerings mit den Namen consumer und producer.

  2. Prüfen Sie, ob die Nutzer-VPC PUPI-Routen exportiert:

    gcloud alpha compute networks peerings list-routes consumer \
        --direction=OUTGOING \
        --network=consumer \
        --region="$TF_VAR_region2"
    

    Die Ausgabe sieht etwa so aus:

    DEST_RANGE     TYPE                  NEXT_HOP_REGION  PRIORITY  STATUS
    10.129.0.0/24  SUBNET_PEERING_ROUTE  us-west2         1000      accepted by peer
    172.16.5.0/24  SUBNET_PEERING_ROUTE  us-west2         1000      accepted by peer
    5.5.5.0/24     SUBNET_PEERING_ROUTE  us-west2         1000      accepted by peer
    

    Diese Ausgabe zeigt alle drei Nutzer-CIDR-Blöcke.

  3. Prüfen Sie die PUPI-Routen, die die Producer-VPC importiert hat:

    gcloud alpha compute networks peerings list-routes producer \
        --direction=INCOMING \
        --network=producer \
        --region="$TF_VAR_region1"
    

    Die Ausgabe sieht etwa so aus:

    DEST_RANGE     TYPE                  NEXT_HOP_REGION  PRIORITY  STATUS
    10.129.0.0/24  SUBNET_PEERING_ROUTE  us-west2         1000      accepted
    172.16.5.0/24  SUBNET_PEERING_ROUTE  us-west2         1000      accepted
    5.5.5.0/24     SUBNET_PEERING_ROUTE  us-west2         1000      accepted
    

    Diese Ausgabe zeigt alle drei Nutzer-CIDR-Blöcke.

  4. Prüfen Sie, ob die GKE-Pods eine PUPI-Adresse haben:

    kubectl get pod -o wide
    

    Die Ausgabe sieht etwa so aus:

    NAME                      READY   STATUS    RESTARTS   AGE     IP         NODE                                              NOMINATED NODE   READINESS GATES
    my-app-594b56d7bc-642d8   1/1     Running   0          4d23h   5.5.5.21   gke-consumer-cluster-default-pool-cd302b68-tccf   <none>           <none>
    my-app-594b56d7bc-chnw8   1/1     Running   0          4d23h   5.5.5.38   gke-consumer-cluster-default-pool-cd302b68-h8v9   <none>           <none>
    my-app-594b56d7bc-fjvbz   1/1     Running   0          4d23h   5.5.5.20   gke-consumer-cluster-default-pool-cd302b68-tccf   <none>           <none>
    

    Die IP-Adressen der Pods liegen im Bereich 5.5.5/24.

Bereinigen

So vermeiden Sie, dass Ihrem Google Cloud-Konto die in dieser Anleitung verwendeten Ressourcen in Rechnung gestellt werden:

Infrastruktur bereinigen

  1. Löschen Sie in Cloud Shell alle Komponenten der Anleitung:

    terraform destroy
    

    Geben Sie bei Aufforderung yes ein, um die Konfiguration zu löschen.

    Möglicherweise wird der folgende Terraform-Fehler angezeigt:

    ...
    ∗ google_compute_network.ivpc (destroy): 1 error(s) occurred:
    ∗ google_compute_network.ivpc: Error waiting for Deleting Network: The network resource 'projects/pupi-pid--1324732197/global/networks/consumer-cluster' is already being used by 'projects/pupi-pid--1324732197/global/firewalls/k8s-05693142c93de80e-node-hc'
    ...
    

    Dieser Fehler tritt auf, wenn der Befehl versucht, das VPC-Netzwerk zu löschen, bevor die GKE-Firewallregeln gelöscht werden. Wenn dieser Fehler auftritt, gehen Sie so vor:

    1. Entfernen Sie die nicht standardmäßigen Firewallregeln aus der VPC:

      $HOME/pupi/k8-fwr.sh
      

      Die Ausgabe zeigt die zu entfernenden Firewallregeln. Prüfen Sie die Regeln und geben Sie yes ein, wenn Sie dazu aufgefordert werden.

    2. Führen Sie den folgenden Befehl noch einmal aus:

      cd $HOME/pupi
      terraform destroy
      

    Geben Sie bei Aufforderung yes ein, um die Konfiguration zu löschen.

  2. Entfernen Sie das Git-Repository:

    rm -rf $HOME/pupi
    

Nächste Schritte