Von Google Kubernetes Engine aus eine Verbindung zu Cloud SQL herstellen

Auf dieser Seite wird beschrieben, wie Sie eine Verbindung von einer in Google Kubernetes Engine (GKE) ausgeführten Anwendung zu einer Cloud SQL-Instanz einrichten.

Für eine Schritt-für-Schritt-Anleitung zum Ausführen einer mit Cloud SQL verbundenen Google Kubernetes Engine-Beispiel-Webanwendung finden Sie weitere Informationen unter: Schnellstart zum Herstellen einer Verbindung von Google Kubernetes Engine.

Cloud SQL ist ein vollständig verwalteter Datenbankdienst, mit dem Sie Ihre relationalen Datenbanken in der Cloud einrichten, warten und verwalten können.

Google Kubernetes Engine bietet eine einfache Möglichkeit zur automatischen Bereitstellung, Skalierung und Verwaltung von Kubernetes.

Google Kubernetes Engine mit Cloud SQL verbinden

Für den Zugriff auf eine Cloud SQL-Instanz von einer Anwendung aus, die in Google Kubernetes Engine ausgeführt wird, können Sie entweder den Cloud SQL Auth-Proxy (mit öffentlicher oder privater IP-Adresse) verwenden oder direkt eine Verbindung über eine private IP-Adresse herstellen.

Wir empfehlen, den Cloud SQL Auth-Proxy zum Herstellen einer Verbindung zu Cloud SQL zu nutzen, auch wenn eine private IP-Adresse verwendet wird. Dies liegt daran, dass der Cloud SQL Auth-Proxy eine starke Verschlüsselung und Authentifizierung mit IAM bietet, wodurch die Sicherheit Ihrer Datenbank gewährleistet werden kann.

Datenbankverbindungen nutzen Ressourcen des Servers und der Anwendung, von der die Verbindung ausgeht. Daher sollten Sie sich bei der Verbindungsverwaltung immer an Best Practices orientieren. So können Sie die Kosten für die Anwendung minimieren und die Wahrscheinlichkeit senken, dass die Verbindungslimits für Cloud SQL überschritten werden. Weitere Informationen finden Sie unter Datenbankverbindungen verwalten.

Hinweis

Zum Herstellen einer Verbindung mit Cloud SQL benötigen Sie Folgendes:

  • Einen GKE-Cluster, in dem das kubectl-Befehlszeilentool installiert und für die Kommunikation mit dem Cluster konfiguriert ist.

    Hilfe zum Einstieg in GKE finden Sie unter Anwendung in einem GKE-Cluster bereitstellen.

    Zum Herstellen einer Verbindung über eine private IP-Adresse muss der GKE-Cluster VPC-nativ sein und mit demselben VPC-Netzwerk (Virtual Private Cloud) wie die Cloud SQL-Instanz verbunden sein.

  • Eine erstellte Instanz.

    Informationen zum Erstellen einer Cloud SQL-Instanz finden Sie unter Instanzen erstellen.

  • Ein MySQL-Nutzerkonto, das für die Instanz konfiguriert wurde.

    Ihre Anwendung verwendet dieses Konto, um eine Verbindung zur Datenbank herzustellen. Hilfe beim Erstellen von Nutzerkonten finden Sie unter Nutzer erstellen.

Informationen zu Kubernetes-Secrets

In Kubernetes sind Secrets eine sichere Möglichkeit, Konfigurationsdetails an Ihre Anwendung zu übergeben. Sie können ein Secret mit Details wie dem Datenbanknamen, dem Nutzer und dem Passwort erstellen. Diese Details können als Umgebungsvariablen in Ihre Anwendung eingefügt werden.

Je nach Verbindungstyp können Secrets auf unterschiedliche Weise verwendet werden:

  • Ein Secret für Datenbankanmeldedaten enthält den Namen des Datenbanknutzers, mit dem Sie eine Verbindung herstellen, und das Datenbankpasswort des Nutzers.
  • Wenn Sie eine Verbindung über den Cloud SQL Auth-Proxy herstellen, kann ein Secret verwendet werden, um die Anmeldedatendatei Ihres Dienstkontos zu speichern.
  • Wenn Sie eine Verbindung mit einer privaten IP-Adresse herstellen, kann ein Secret verwendet werden, um die private IP-Adresse Ihrer Cloud SQL-Instanz anzugeben.

Vollständige Beispiele zur Verwendung von Secrets finden Sie in den GitHub-Repositories weiter unten auf dieser Seite.

Secret-Objekt erstellen

  1. Sie erstellen die Secret-Objekte mit dem Befehl kubectl create secret.

    So erstellen Sie ein Secret für Datenbankanmeldedaten:

    kubectl create secret generic <YOUR-DB-SECRET> \
      --from-literal=username=<YOUR-DATABASE-USER> \
      --from-literal=password=<YOUR-DATABASE-PASSWORD> \
      --from-literal=database=<YOUR-DATABASE-NAME>
    
  2. Nach der Erstellung können Sie die Objekte im Bereich Konfiguration auf der Google Kubernetes Engine-Seite in der Google Cloud Console ansehen.

Verbindung zu Cloud SQL über den Cloud SQL Auth-Proxy herstellen

Wenn Sie eine Verbindung über den Cloud SQL Auth-Proxy herstellen, wird der Cloud SQL Auth-Proxy mithilfe des Containermusters sidecar zu Ihrem Pod hinzugefügt. Der Cloud SQL Auth-Proxy-Container befindet sich im selben Pod wie Ihre Anwendung, sodass die Anwendung mithilfe von localhost eine Verbindung zum Cloud SQL Auth-Proxy herstellen kann, wodurch Sicherheit und Leistung erhöht werden.

Weitere Informationen zum Cloud SQL Auth-Proxy finden Sie unter Informationen zum Cloud SQL Auth-Proxy. Weitere Informationen zum Arbeiten mit Pods finden Sie in der Kubernetes-Dokumentation unter Pod-Übersicht.

Zum Herstellen einer Verbindung mit dem Cloud SQL Auth-Proxy benötigen Sie Folgendes:

  1. Den Namen der Instanzverbindung Ihrer Cloud SQL-Instanz.

    Der Name der Instanzverbindung kann auf der Seite Cloud SQL-Instanzdetails der Google Cloud Console oder über den Befehl gcloud sql instances describe INSTANCE_ID abgerufen werden.

  2. Den Speicherort der Schlüsseldatei, die einem Dienstkonto mit den erforderlichen Berechtigungen für Ihre Cloud SQL-Instanz zugeordnet ist.

    Weitere Informationen finden Sie unter Dienstkonto erstellen.

  3. Die Cloud SQL Admin API ist aktiviert.

    Enable the API

Dienstkonto für den Cloud SQL-Auth-Proxy bereitstellen

Der erste Schritt zum Ausführen des Cloud SQL Auth-Proxys in Google Kubernetes Engine besteht darin, ein Google-Dienstkonto (Google Service Account, GSA) für Ihre Anwendung zu erstellen. Es empfiehlt sich, für jede Anwendung ein eigenes Dienstkonto zu erstellen, anstatt überall dasselbe Dienstkonto zu verwenden. Dieses Modell ist sicherer, da Sie damit Berechtigungen auf Anwendungsbasis beschränken können.

Das Dienstkonto für Ihre Anwendung muss die folgenden Kriterien erfüllen:

  • Es muss zu einem Projekt mit aktivierter Cloud SQL Admin API gehören.
  • Ihm muss die IAM-Rolle "Cloud SQL-Client" oder eine gleichwertige Rolle für das Projekt mit der Instanz zugewiesen sein, zu der Sie eine Verbindung herstellen möchten.
  • Wenn Sie eine Verbindung mithilfe einer privaten IP-Adresse herstellen, muss ein VPC-nativer GKE-Cluster in derselben VPC wie Ihre Cloud SQL-Instanz verwendet werden.

Sie müssen GKE so konfigurieren, dass das Dienstkonto für den Cloud SQL Auth-Proxy bereitgestellt wird. Dafür gibt es zwei Möglichkeiten: über Workload Identity oder eine Schlüsseldatei des Dienstkontos.

Workload Identity

Wenn Sie Google Kubernetes Engine verwenden, wird das GKE-Feature Workload Identity als bevorzugte Methode empfohlen. Mit dieser Methode können Sie ein Kubernetes-Dienstkonto (Kubernetes Service Account, KSA) an ein Google-Dienstkonto (Google Service Account, GSA) binden. Das GSA ist dann für Anwendungen zugänglich, die das entsprechende KSA verwenden.

Ein Google-Dienstkonto (Google Service Account, GSA) ist eine IAM-Identität, die Ihre Anwendung in Google Cloud darstellt. Entsprechend ist ein Kubernetes-Dienstkonto (Kubernetes Service Account, KSA) eine Identität, die Ihre Anwendung in einem Google Kubernetes Engine-Cluster darstellt.

Workload Identity bindet ein KSA an ein GSA. Dadurch werden alle Deployments mit diesem KSA als GSA bei Interaktionen mit Google Cloud authentifiziert.

  1. Workload Identity für den Cluster aktivieren
  2. Normalerweise hat jede Anwendung eine eigene Identität, die durch ein KSA- und GSA-Paar dargestellt wird. Führen Sie kubectl apply -f service-account.yaml aus, um ein KSA für Ihre Anwendung zu erstellen:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: <YOUR-KSA-NAME> # TODO(developer): replace these values
  3. Aktivieren Sie die IAM-Bindung zwischen YOUR-GSA-NAME und YOUR-KSA-NAME:

    gcloud iam service-accounts add-iam-policy-binding \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:YOUR-GOOGLE-CLOUD-PROJECT.svc.id.goog[YOUR-K8S-NAMESPACE/YOUR-KSA-NAME]" \
    YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
    
  4. Fügen Sie YOUR-KSA-NAME eine Anmerkung hinzu, um die Bindung fertigzustellen:

    kubectl annotate serviceaccount \
    YOUR-KSA-NAME \
    iam.gke.io/gcp-service-account=YOUR-GSA-NAME@YOUR-GOOGLE-CLOUD-PROJECT.iam.gserviceaccount.com
    
  5. Geben Sie schließlich das Dienstkonto für das k8s-Objekt an.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: <YOUR-DEPLOYMENT-NAME>
    spec:
      selector:
        matchLabels:
          app: <YOUR-APPLICATION-NAME>
      template:
        metadata:
          labels:
            app: <YOUR-APPLICATION-NAME>
        spec:
          serviceAccountName: <YOUR-KSA-NAME>

Dienstkontoschlüsseldatei

Wenn Sie Workload Identity nicht verwenden können, wird empfohlen, eine Dienstkonto-Schlüsseldatei im Pod des Cloud SQL Auth-Proxys bereitzustellen und das Flag --credentials-file zu verwenden.

  1. Erstellen Sie eine Anmeldedatendatei für Ihren Dienstkontoschlüssel:

    gcloud iam service-accounts keys create ~/key.json \
    --iam-account=YOUR-SA-NAME@project-id.iam.gserviceaccount.com
    
  2. Machen Sie aus Ihrem Dienstkontoschlüssel ein k8s-Secret:

    kubectl create secret generic YOUR-SA-SECRET \
    --from-file=service_account.json=~/key.json
    
  3. Stellen Sie das Secret als Volume unter spec: für Ihr k8s-Objekt bereit:

    volumes:
    - name: <YOUR-SA-SECRET-VOLUME>
      secret:
        secretName: <YOUR-SA-SECRET>
  4. Folgen Sie der Anleitung im nächsten Abschnitt, um auf das Volume aus dem Pod des Cloud SQL Auth-Proxys zuzugreifen.

Cloud SQL Auth-Proxy in einem Sidecar-Muster ausführen

Wir empfehlen, den Cloud SQL Auth-Proxy in einem sidecar-Muster auszuführen (als zusätzlichen Container, der einen Pod für Ihre Anwendung freigibt). Diese Vorgehensweise wird aus verschiedenen Gründen gegenüber der Ausführung eines separaten Dienstes empfohlen:

  • Verhindert, dass SQL-Traffic lokal verfügbar gemacht wird. Der Cloud SQL Auth-Proxy bietet die Möglichkeit, ausgehende Verbindungen zu verschlüsseln, aber Sie sollten die Sichtbarkeit für eingehende Verbindungen einschränken.
  • Verhindert einen Single Point of Failure. Der Zugriff jeder Anwendung auf Ihre Datenbank ist unabhängig von den anderen, was die Ausfallsicherheit erhöht.
  • Beschränkt den Zugriff auf den Cloud SQL Auth-Proxy, sodass Sie IAM-Berechtigungen pro Anwendung verwenden können, anstatt die Datenbank für den gesamten Cluster freizugeben.
  • Ermöglicht eine genauere Bestimmung von Ressourcenanfragen. Da der Cloud SQL Auth-Proxy Ressourcen linear zur Nutzung verbraucht, können Sie mit diesem Muster Ressourcen genauer bestimmen und entsprechend der Skalierung Ihrer Anwendungen anfordern.

  • Fügen Sie den Cloud SQL Auth-Proxy der Pod-Konfiguration unter containers hinzu:

    - name: cloud-sql-proxy
      # It is recommended to use the latest version of the Cloud SQL Auth Proxy
      # Make sure to update on a regular schedule!
      image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.11.4
      args:
        # If connecting from a VPC-native GKE cluster, you can use the
        # following flag to have the proxy connect over private IP
        # - "--private-ip"
    
        # Enable structured logging with LogEntry format:
        - "--structured-logs"
    
        # Replace DB_PORT with the port the proxy should listen on
        - "--port=<DB_PORT>"
        - "<INSTANCE_CONNECTION_NAME>"
    
      securityContext:
        # The default Cloud SQL Auth Proxy image runs as the
        # "nonroot" user and group (uid: 65532) by default.
        runAsNonRoot: true
      # You should use resource requests/limits as a best practice to prevent
      # pods from consuming too many resources and affecting the execution of
      # other pods. You should adjust the following values based on what your
      # application needs. For details, see
      # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
      resources:
        requests:
          # The proxy's memory use scales linearly with the number of active
          # connections. Fewer open connections will use less memory. Adjust
          # this value based on your application's requirements.
          memory: "2Gi"
          # The proxy's CPU use scales linearly with the amount of IO between
          # the database and the application. Adjust this value based on your
          # application's requirements.
          cpu:    "1"

    Wenn Sie einen Dienstkontoschlüssel verwenden, geben Sie Ihr Secret-Volume an und fügen Sie dem Befehl das Flag --credentials-file hinzu:

      # This flag specifies where the service account key can be found
      - "--credentials-file=/secrets/service_account.json"
    securityContext:
      # The default Cloud SQL Auth Proxy image runs as the
      # "nonroot" user and group (uid: 65532) by default.
      runAsNonRoot: true
    volumeMounts:
    - name: <YOUR-SA-SECRET-VOLUME>
      mountPath: /secrets/
      readOnly: true
  • Abschließend konfigurieren Sie Ihre Anwendung so, dass eine Verbindung über 127.0.0.1 auf dem DB_PORT hergestellt wird, den Sie im Befehlsbereich angegeben haben.

Vollständige Beispielkonfigurationsdateien:

Workload Identity

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      serviceAccountName: <YOUR-KSA-NAME>
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
      - name: cloud-sql-proxy
        # It is recommended to use the latest version of the Cloud SQL Auth Proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.11.4
        args:
          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "--private-ip"

          # Enable structured logging with LogEntry format:
          - "--structured-logs"

          # Replace DB_PORT with the port the proxy should listen on
          - "--port=<DB_PORT>"
          - "<INSTANCE_CONNECTION_NAME>"

        securityContext:
          # The default Cloud SQL Auth Proxy image runs as the
          # "nonroot" user and group (uid: 65532) by default.
          runAsNonRoot: true
        # You should use resource requests/limits as a best practice to prevent
        # pods from consuming too many resources and affecting the execution of
        # other pods. You should adjust the following values based on what your
        # application needs. For details, see
        # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        resources:
          requests:
            # The proxy's memory use scales linearly with the number of active
            # connections. Fewer open connections will use less memory. Adjust
            # this value based on your application's requirements.
            memory: "2Gi"
            # The proxy's CPU use scales linearly with the amount of IO between
            # the database and the application. Adjust this value based on your
            # application's requirements.
            cpu:    "1"

Dienstkontoschlüssel

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
      - name: cloud-sql-proxy
        # It is recommended to use the latest version of the Cloud SQL Auth Proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.11.4
        args:
          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "--private-ip"

          # Enable structured logging with LogEntry format:
          - "--structured-logs"


          # Replace DB_PORT with the port the proxy should listen on
          - "--port=<DB_PORT>"
          - "<INSTANCE_CONNECTION_NAME>"

          # This flag specifies where the service account key can be found
          - "--credentials-file=/secrets/service_account.json"
        securityContext:
          # The default Cloud SQL Auth Proxy image runs as the
          # "nonroot" user and group (uid: 65532) by default.
          runAsNonRoot: true
        volumeMounts:
        - name: <YOUR-SA-SECRET-VOLUME>
          mountPath: /secrets/
          readOnly: true
        # Resource configuration depends on an application's requirements. You
        # should adjust the following values based on what your application
        # needs. For details, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
        resources:
          requests:
            # The proxy's memory use scales linearly with the number of active
            # connections. Fewer open connections will use less memory. Adjust
            # this value based on your application's requirements.
            memory: "2Gi"
            # The proxy's CPU use scales linearly with the amount of IO between
            # the database and the application. Adjust this value based on your
            # application's requirements.
            cpu:    "1"
      volumes:
      - name: <YOUR-SA-SECRET-VOLUME>
        secret:
          secretName: <YOUR-SA-SECRET>

Verbindung zu Cloud SQL ohne den Cloud SQL Auth-Proxy herstellen

Sie können auch eine Verbindung von einem VPC-nativen GKE-Cluster zu einer Cloud SQL-Instanz in derselben VPC mit privater IP-Adresse ohne den Cloud SQL Auth-Proxy herstellen. Diese Vorgehensweise ist jedoch weniger sicher.

  1. Erstellen Sie ein Secret mit der privaten IP-Adresse Ihrer Instanz:

    kubectl create secret generic <YOUR-PRIVATE-IP-SECRET> \
        --from-literal=db_host=<YOUR-PRIVATE-IP-ADDRESS>
    
  2. Als Nächstes fügen Sie das Secret dem Container Ihrer Anwendung hinzu:

    - name: DB_HOST
      valueFrom:
        secretKeyRef:
          name: <YOUR-PRIVATE-IP-SECRET>
          key: db_host
  3. Abschließend konfigurieren Sie Ihre Anwendung so, dass eine Verbindung mit der IP-Adresse aus der Umgebungsvariable DB_HOST hergestellt wird. Verwenden Sie den richtigen Port für MySQL: 3306.

Vollständige Beispielkonfigurationsdatei:

Private IP-Adresse

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: <YOUR-DEPLOYMENT-NAME>
spec:
  selector:
    matchLabels:
      app: <YOUR-APPLICATION-NAME>
  template:
    metadata:
      labels:
        app: <YOUR-APPLICATION-NAME>
    spec:
      containers:
      - name: <YOUR-APPLICATION-NAME>
        # ... other container configuration
        env:
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: username
        - name: DB_PASS
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: password
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: <YOUR-DB-SECRET>
              key: database
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: <YOUR-PRIVATE-IP-SECRET>
              key: db_host

Fehlerbehebung

Benötigen Sie Hilfe? Informationen zur Fehlerbehebung für den Proxy finden Sie unter Fehlerbehebung bei Cloud SQL Auth-Proxyverbindungen oder auf der Seite Cloud SQL-Support.

Nächste Schritte