Connettersi da Google Kubernetes Engine

Questa pagina descrive come configurare una connessione da un'applicazione in esecuzione in Google Kubernetes Engine a un'istanza Cloud SQL.

Introduzione

Per accedere a un'istanza Cloud SQL da un'applicazione in esecuzione in Google Kubernetes Engine, puoi utilizzare il proxy Cloud SQL Auth (con IP pubblico o privato) o connetterti direttamente utilizzando un indirizzo IP privato.

Il proxy di autenticazione Cloud SQL è il metodo consigliato per connettersi a Cloud SQL, anche quando si utilizza l'IP privato. perché il proxy Cloud SQL Auth fornisce crittografia e autenticazione efficaci tramite IAM, che possono contribuire a proteggere il tuo database.

Le connessioni di database consumano risorse sul server e sull'applicazione di connessione. Utilizza sempre buone prassi di gestione delle connessioni per ridurre al minimo l'impatto della tua applicazione e ridurre la probabilità di superare i limiti di connessione di Cloud SQL. Per ulteriori informazioni, consulta Gestione delle connessioni ai database.

Prima di iniziare

Per connetterti a Cloud SQL, devi avere:

  • Un cluster GKE, con lo strumento a riga di comando kubectl installato e configurato per comunicare con il cluster.

    Per assistenza su come iniziare a utilizzare GKE, consulta la guida rapida.

    Per la connessione tramite IP privato, il cluster GKE deve essere VPC-native e in peering con la stessa rete VPC dell'istanza Cloud SQL.

  • Un'istanza creata.

    Per assistenza sulla creazione di un'istanza Cloud SQL, consulta Creazione di istanze.

  • Un account utente MySQL configurato sull'istanza.

    L'applicazione utilizzerà questo account per connettersi al database. Per assistenza sulla creazione di un account utente, vedi Creazione di un utente.

Informazioni sui secret

In Kubernetes, i secret sono un modo sicuro per trasmettere i dettagli di configurazione all'applicazione. Puoi creare un Secret con dettagli come nome del tuo database, utente e password, che puoi inserire nella tua applicazione come env vars.

Esistono molti modi diversi per utilizzare i secret, a seconda del tipo di connessione:

  • Le credenziali del database includono il nome dell'utente di database con cui esegui la connessione e la password del database dell'utente.
  • Se ti connetti al proxy Cloud SQL Auth, puoi utilizzare un secret per contenere il tuo file delle credenziali dell'account di servizio.
  • Se ti connetti tramite IP privato, puoi utilizzare un secret per specificare l'indirizzo IP privato della tua istanza Cloud SQL.

Per esempi completi su come utilizzare i secret, consulta i repository GitHub indicati più avanti in questa pagina.

Crea un oggetto Secret

  1. Puoi creare gli oggetti Secret utilizzando il comando kubectl create secret.

    Per creare un Secret di credenziali database:

    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. Una volta creati, puoi visualizzare gli oggetti nella sezione Configurazione della pagina Google Kubernetes Engine in Google Cloud Console.

Connessione tramite il proxy di autenticazione Cloud SQL

Quando ti connetti utilizzando il proxy Cloud SQL Auth, il proxy Cloud SQL Auth viene aggiunto al tuo pod utilizzando il pattern container sidecar. Il container proxy Cloud SQL Auth si trova nello stesso pod dell'applicazione, il che consente all'applicazione di connettersi al proxy Cloud SQL Auth utilizzando localhost, aumentando la sicurezza e le prestazioni. Scopri di più.

Per ulteriori informazioni sul proxy Cloud SQL Auth, consulta la sezione Informazioni sul proxy Cloud SQL Auth. Per ulteriori informazioni sull'utilizzo dei pod, consulta Panoramica dei pod nella documentazione di Kubernetes.

Per connetterti utilizzando il proxy Cloud SQL Auth devi avere:

  1. Il nome di connessione istanza dell'istanza Cloud SQL.

    Il nome di connessione istanza è disponibile nella pagina Dettagli istanza Cloud SQL di Google Cloud Console o nel comando gcloud sql instances describe INSTANCE_ID.

  2. La posizione del file della chiave associato a un account di servizio con i privilegi appropriati per l'istanza Cloud SQL.

    Per ulteriori informazioni, vedi Creazione di un account di servizio.

  3. L'API Cloud SQL Admin è abilitata.

    Abilita l'API

Fornisci l'account di servizio al proxy Cloud SQL Auth

Il primo passaggio per eseguire il proxy Cloud SQL Auth in Google Kubernetes Engine è creare un account di servizio Google (GSA) per rappresentare la tua applicazione. Ti consigliamo di creare un account di servizio univoco per ogni applicazione, anziché utilizzare lo stesso account di servizio ovunque. Questo modello è più sicuro poiché consente di limitare le autorizzazioni in base all'applicazione.

L'account di servizio per la tua applicazione deve soddisfare i seguenti criteri:

  • Appartengono a un progetto con l'API Cloud SQL Admin abilitata
  • È stato concesso il ruolo IAM Client Cloud SQL (o equivalente) per il progetto contenente l'istanza a cui vuoi connetterti
  • Se la connessione avviene tramite IP privato, devi utilizzare un cluster GKE nativo di VPC, nello stesso VPC della tua istanza Cloud SQL

Devi configurare GKE in modo che fornisca l'account di servizio al proxy di autenticazione Cloud SQL. Puoi usare due metodi: identità del carico di lavoro o file della chiave dell'account di servizio.

Workload Identity

Se utilizzi Google Kubernetes Engine, il metodo preferito è utilizzare la funzionalità Workload Identity di GKE. Questo metodo ti consente di associare un account di servizio Kubernetes (KSA) a un account di servizio Google (GSA). GSA sarà quindi accessibile dalle applicazioni utilizzando il KSA.

Un account di servizio Google (GSA) è un'identità IAM che rappresenta la tua applicazione in Google Cloud. In modo simile, un account di servizio Kubernetes (KSA) è un'identità che rappresenta la tua applicazione in un cluster Google Kubernetes Engine.

Workload Identity associa un KSA a un GSA, facendo in modo che tutti i deployment con KSA si autentichino come GSA nelle loro interazioni con Google Cloud.

  1. Abilita Workload Identity per il tuo cluster
  2. In genere, ogni applicazione ha la propria identità, rappresentata da una coppia KSA e GSA. Crea un KSA per la tua applicazione eseguendo kubectl apply -f service-account.yaml:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: <YOUR-KSA-NAME> # TODO(developer): replace these values
  3. Abilita l'associazione IAM tra YOUR-GSA-NAME e YOUR-KSA-NAME:

    gcloud iam service-accounts add-iam-policy-binding \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:YOUR-GCP-PROJECT.svc.id.goog[YOUR-K8S-NAMESPACE/YOUR-KSA-NAME]" \
    YOUR-GSA-NAME@YOUR-GCP-PROJECT.iam.gserviceaccount.com
    
  4. Aggiungi un'annotazione a YOUR-KSA-NAME per completare l'associazione:

    kubectl annotate serviceaccount \
    YOUR-KSA-NAME \
    iam.gke.io/gcp-service-account=YOUR-GSA-NAME@YOUR-GCP-PROJECT.iam.gserviceaccount.com
    
  5. Infine, assicurati di specificare l'account di servizio per l'oggetto k8s.

    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>

File di chiave dell'account di servizio

In alternativa, se non puoi utilizzare Workload Identity, il modello consigliato consiste nel montare un file della chiave dell'account di servizio nel pod proxy Cloud SQL Auth e utilizzare il flag -credential_file.

  1. Crea un file delle credenziali per la chiave dell'account di servizio:

    gcloud iam service-accounts keys create ~/key.json \
    --iam-account=YOUR-SA-NAME@project-id.iam.gserviceaccount.com
    
  2. Trasforma la chiave del tuo account di servizio in un secret k8s:

    kubectl create secret generic YOUR-SA-SECRET \
    --from-file=service_account.json=~/key.json
    
  3. Monta il secret come volume sotto l'elemento spec: per l'oggetto k8s:

    volumes:
    - name: <YOUR-SA-SECRET-VOLUME>
      secret:
        secretName: <YOUR-SA-SECRET>
  4. Segui le istruzioni nella sezione seguente per accedere al volume dal pod Cloud Identity Auth proxy.

Esegui il proxy Cloud SQL Auth come sidecar

Ti consigliamo di eseguire il proxy Cloud SQL Auth in un pattern sidecar (come contenitore aggiuntivo che condivide un pod con la tua applicazione). Ti consigliamo di eseguirlo come servizio separato per diversi motivi:

  • Impedisce l'esposizione locale del traffico SQL; il proxy di autenticazione Cloud SQL fornisce la crittografia sulle connessioni in uscita, ma è necessario limitare l'esposizione per le connessioni in entrata.
  • Impedisce un single point of failure: l'accesso di ogni applicazione al database è indipendente dagli altri, rendendo l'applicazione più resiliente.
  • Limita l'accesso al proxy Cloud SQL Auth, consentendoti di utilizzare autorizzazioni IAM per applicazione, anziché esporre il database all'intero cluster.
  • Consente di definire un ambito più preciso per le richieste di risorse; poiché il proxy Cloud SQL Auth consuma le risorse in modo lineare per l'utilizzo, questo pattern consente di definire l'ambito e le richieste in modo più accurato per soddisfare le applicazioni in base alla scalabilità.

  • Aggiungi il proxy Cloud SQL Auth alla configurazione del pod in containers:

    - name: cloud-sql-proxy
      # It is recommended to use the latest version of the Cloud SQL proxy
      # Make sure to update on a regular schedule!
      image: gcr.io/cloudsql-docker/gce-proxy:1.28.0 # make sure the use the latest version
      command:
        - "/cloud_sql_proxy"
    
        # If connecting from a VPC-native GKE cluster, you can use the
        # following flag to have the proxy connect over private IP
        # - "-ip_address_types=PRIVATE"
    
        # By default, the proxy will write all logs to stderr. In some
        # environments, anything printed to stderr is consider an error. To
        # disable this behavior and write all logs to stdout (except errors
        # which will still go to stderr), use:
        - "-log_debug_stdout"
    
        # Replace DB_PORT with the port the proxy should listen on
        # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
        - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"
      securityContext:
        # The default Cloud SQL 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"

    Se utilizzi una chiave dell'account di servizio, specifica il volume del secret e aggiungi il flag -credential_file al comando:

      # This flag specifies where the service account key can be found
      - "-credential_file=/secrets/service_account.json"
    securityContext:
      # The default Cloud SQL 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
  • Infine, configura l'applicazione in modo che esegua il collegamento utilizzando 127.0.0.1 su qualsiasi DB_PORT specificato nella sezione dei comandi.

Completa i file di configurazione di esempio:

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 proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloudsql-docker/gce-proxy:1.28.0 # make sure the use the latest version
        command:
          - "/cloud_sql_proxy"

          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "-ip_address_types=PRIVATE"

          # By default, the proxy will write all logs to stderr. In some
          # environments, anything printed to stderr is consider an error. To
          # disable this behavior and write all logs to stdout (except errors
          # which will still go to stderr), use:
          - "-log_debug_stdout"

          # Replace DB_PORT with the port the proxy should listen on
          # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"
        securityContext:
          # The default Cloud SQL 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"

Chiave account di servizio

# 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 proxy
        # Make sure to update on a regular schedule!
        image: gcr.io/cloudsql-docker/gce-proxy:1.28.0 # make sure the use the latest version
        command:
          - "/cloud_sql_proxy"

          # If connecting from a VPC-native GKE cluster, you can use the
          # following flag to have the proxy connect over private IP
          # - "-ip_address_types=PRIVATE"

          # By default, the proxy will write all logs to stderr. In some
          # environments, anything printed to stderr is consider an error. To
          # disable this behavior and write all logs to stdout (except errors
          # which will still go to stderr), use:
          - "-log_debug_stdout"

          # Replace DB_PORT with the port the proxy should listen on
          # Defaults: MySQL: 3306, Postgres: 5432, SQLServer: 1433
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:<DB_PORT>"

          # This flag specifies where the service account key can be found
          - "-credential_file=/secrets/service_account.json"
        securityContext:
          # The default Cloud SQL 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>

Connessione senza il proxy Cloud SQL Auth

Anche se non è sicuro, è possibile connettersi da un cluster GKE nativo di VPC a un'istanza Cloud SQL sullo stesso VPC utilizzando l'IP privato senza il proxy di autenticazione Cloud SQL.

  1. Crea un secret con l'indirizzo IP privato della tua istanza:

    kubectl create secret generic <YOUR-PRIVATE-IP-SECRET> \
        --from-literal=db_host=<YOUR-PRIVATE-IP-ADDRESS>
    
  2. Dopodiché assicurati di aggiungere il secret al container dell'applicazione:

    - name: DB_HOST
      valueFrom:
        secretKeyRef:
          name: <YOUR-PRIVATE-IP-SECRET>
          key: db_host
  3. Infine, configura l'applicazione in modo che esegua la connessione utilizzando l'indirizzo IP da DB_HOST env var. Dovrai utilizzare la porta corretta per MySQL: 3306

Completa il file di configurazione di esempio:

IP privato

# 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

Serve aiuto? Per informazioni su come risolvere i problemi del proxy, consulta Risoluzione dei problemi di connessione al proxy Cloud SQL Auth o visita la nostra pagina di assistenza Cloud SQL.

Passaggi successivi