Connettersi da Google Kubernetes Engine

In questa pagina viene descritto 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 di autenticazione Cloud SQL (con IP pubblico o privato) oppure connetterti direttamente utilizzando un indirizzo IP privato.

Il proxy di autenticazione Cloud SQL è il metodo consigliato per connettersi a Cloud SQL, anche quando utilizzi un IP privato. Questo perché il proxy di autenticazione Cloud SQL fornisce una crittografia e un'autenticazione efficaci con 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 pratiche 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 informazioni su come iniziare a utilizzare GKE, consulta la guida rapida.

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

  • Un'istanza creata.

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

  • Un account utente SQL Server configurato sull'istanza.

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

Informazioni sui secret

In Kubernetes, i secret costituiscono un modo sicuro per trasmettere i dettagli di configurazione all'applicazione. Puoi creare un secret con dettagli come il nome del database, l'utente e la password, che possono essere inseriti nell'applicazione come env vars.

I secret possono essere utilizzati in molti modi diversi, a seconda del tipo di connessione:

  • Un Secret delle credenziali del database include il nome dell'utente del database con cui ti connetti e la password del database dell'utente.
  • Se ti connetti con il proxy di autenticazione Cloud SQL, puoi utilizzare un secret per conservare il file delle credenziali del tuo account di servizio.
  • Se ti connetti con un 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 a cui si fa riferimento in un secondo momento in questa pagina.

Crea un oggetto secret

  1. Per creare gli oggetti Secret devi utilizzare il comando kubectl create secret.

    Per creare un Secret di credenziali del 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. Dopo la creazione, puoi visualizzare gli oggetti nella sezione Configurazione della pagina Google Kubernetes Engine nella console.

Connessione tramite il proxy di autenticazione Cloud SQL

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

Per scoprire di più sul proxy di autenticazione Cloud SQL, consulta Informazioni sul proxy di autenticazione Cloud SQL. Per ulteriori informazioni sull'utilizzo dei pod, consulta la Panoramica dei pod nella documentazione di Kubernetes.

Per connetterti utilizzando il proxy di autenticazione Cloud SQL, devi disporre di:

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

    Il nome di connessione istanza è disponibile nella pagina Dettagli istanza Cloud SQL della 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 adeguati per la tua istanza Cloud SQL.

    Per ulteriori informazioni, consulta la sezione Creare un account di servizio.

  3. L'API Cloud SQL Admin è abilitata.

    Abilita l'API

Fornisci l'account di servizio al proxy di autenticazione Cloud SQL

Il primo passaggio per eseguire il proxy di autenticazione Cloud SQL in Google Kubernetes Engine è creare un account di servizio Google (GSA) per rappresentare la tua applicazione. È consigliabile 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 a livello di singola applicazione.

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

  • Appartiene 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 VPC, nello stesso VPC della tua istanza Cloud SQL

Devi configurare GKE per fornire l'account di servizio al proxy di autenticazione Cloud SQL. Puoi eseguire questa operazione in due modi: 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). Ora sarà possibile accedere alle applicazioni che utilizzano il KSA corrispondente.

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 RMA, facendo in modo che tutti i deployment con tale KSA vengano autenticati come GCP 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 GCP. 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 chiave account di servizio

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

  1. Crea un file di 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 il 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 del proxy Cloud Auth di Cloud SQL.

Esegui il proxy di autenticazione Cloud SQL come sidecar

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

  • Impedisce che il traffico SQL venga esposto a livello locale; il proxy di autenticazione Cloud SQL fornisce la crittografia sulle connessioni in uscita, ma devi limitare l'esposizione per le connessioni in entrata.
  • Impedisce un singolo punto di errore; l'accesso di ogni applicazione al tuo database è indipendente dagli altri, rendendolo più resiliente.
  • Limita l'accesso al proxy di autenticazione Cloud SQL, consentendoti di utilizzare le autorizzazioni IAM per applicazione anziché esporre il database all'intero cluster.
  • Consente di definire l'ambito delle richieste di risorse in modo più accurato; poiché il proxy di autenticazione Cloud SQL consuma le risorse in modo lineare per l'utilizzo, questo pattern consente di definire l'ambito e di richiedere le risorse in modo più accurato per assicurare la corrispondenza con le applicazioni durante la scalabilità.

  • Aggiungi il proxy di autenticazione Cloud SQL 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 segreto 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 sia connessa utilizzando 127.0.0.1 indipendentemente da 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 considered 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>

Connettiti senza il proxy di autenticazione Cloud SQL

Anche se non è sicuro, è possibile connettersi da un cluster GKE nativo 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. Successivamente, 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 la tua applicazione in modo che si colleghi utilizzando l'indirizzo IP di DB_HOST env var. Dovrai utilizzare la porta corretta per SQL Server: 1433

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 assistenza per la risoluzione dei problemi del proxy, vedi Risoluzione dei problemi relativi alle connessioni proxy Cloud Auth o visita la pagina Assistenza di Cloud SQL.

Passaggi successivi