Search code examples
doctrine-ormgoogle-cloud-platformgoogle-cloud-sqlcloud-sql-proxy

Failed to connect to cloud SQL using proxy despite following the documentation


I'm using doctrine ORM with Symfony, the PHP framework. I'm getting bizarre behaviour when trying to connect to cloud SQL using GKE.

I'm able to get a connection to the DB via doctrine on command line, for example php bin/console doctrine:database:create is successful and I can see a connection opened in the proxy pod logs.

But when I try and connect to the DB via doctrine in my application I run into this error without fail:

An exception occurred in driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known

I have been trying to get my head around this but it doesn't make sense, why would I be able to connect via command line but not in my application?

I followed the documentation here for setting up a db connection using cloud proxy. This is my Kubernetes deployment:

---
apiVersion: "extensions/v1beta1"
kind: "Deployment"
metadata:
  name: "riptides-api"
  namespace: "default"
  labels:
    app: "riptides-api"
    microservice: "riptides"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: "riptides-api"
      microservice: "riptides"
  template:
    metadata:
      labels:
        app: "riptides-api"
        microservice: "riptides"
    spec:
      containers:
        - name: "api-sha256"
          image: "eu.gcr.io/riptides/api@sha256:ce0ead9d1dd04d7bfc129998eca6efb58cb779f4f3e41dcc3681c9aac1156867"
          env:
            - name: DB_HOST
              value: 127.0.0.1:3306
            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: riptides-mysql-user-skye
                  key: user
            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: riptides-mysql-user-skye
                  key: password
            - name: DB_NAME
              value: riptides
          lifecycle:
            postStart:
              exec:
                command: ["/bin/bash", "-c", "php bin/console doctrine:migrations:migrate -n"]
          volumeMounts:
            - name: keys
              mountPath: "/app/config/jwt"
              readOnly: true
        - name: cloudsql-proxy
          image: gcr.io/cloudsql-docker/gce-proxy:1.11
          command: ["/cloud_sql_proxy",
                    "-instances=riptides:europe-west4:riptides-sql=tcp:3306",
                    "-credential_file=/secrets/cloudsql/credentials.json"]
          # [START cloudsql_security_context]
          securityContext:
            runAsUser: 2  # non-root user
            allowPrivilegeEscalation: false
          # [END cloudsql_security_context]
          volumeMounts:
            - name: riptides-mysql-service-account
              mountPath: /secrets/cloudsql
              readOnly: true
      volumes:
        - name: keys
          secret:
            secretName: riptides-api-keys
            items:
            - key: private.pem
              path: private.pem
            - key: public.pem
              path: public.pem
        - name: riptides-mysql-service-account
          secret:
            secretName: riptides-mysql-service-account
---
apiVersion: "autoscaling/v2beta1"
kind: "HorizontalPodAutoscaler"
metadata:
  name: "riptides-api-hpa"
  namespace: "default"
  labels:
    app: "riptides-api"
    microservice: "riptides"
spec:
  scaleTargetRef:
    kind: "Deployment"
    name: "riptides-api"
    apiVersion: "apps/v1beta1"
  minReplicas: 1
  maxReplicas: 5
  metrics:
    - type: "Resource"
      resource:
        name: "cpu"
        targetAverageUtilization: 70

If anyone has any suggestions I'd be forever greatful


Solution

  • This was happening because doctrine was using default values instead of the (should be overriding) environment variables I had set up in my deployment. I changed the environment variable names to be different to the default ones and it works