0

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

skyegill
  • 83
  • 1
  • 9
  • Can you share your connection string and k8s deployments? You may need to enable VPC when creating a cluster if you want to connect on the private IP of Cloud SQL without the proxy. – petomalina Apr 16 '19 at 22:07
  • @petomalina I've updated my post with the deployment file I've been using. I'm using public IP with the proxy at the moment, would you suggest setting up with private IP instead? – skyegill Apr 17 '19 at 07:23
  • thanks for updating the post. Looking at your DB_HOST value, are you sure the port should be appended at the end? Hosts are configured only with DNS many times, e.g. `127.0.0.1` – petomalina Apr 17 '19 at 09:05
  • @petomalina Thanks for your help, sadly that does not fix the issue. I've now changed to use private IP but still facing the exact same problem. I'm able to use doctrine via command line fine but my application returns the same error. There must be some symfony config that I have malconfigured but for the life of me I can't figure out what it could be – skyegill Apr 17 '19 at 19:49
  • can you try to print the URL before connecting to the DB in Symfony? – petomalina Apr 18 '19 at 06:34

2 Answers2

0

It doesn't look like anything is wrong with your k8s yaml, but more likely in how you are connecting using Symfony. According to the documentation here, Symfony expect the DB URI to be passed in through an environment variable called "DATABASE_URL". See the following example:

# customize this line!
DATABASE_URL="postgres://db_user:db_password@127.0.0.1:5432/db_name"
kurtisvg
  • 3,412
  • 1
  • 8
  • 24
  • Thanks but I’ve already got a DB_NAME variable in my deployment file. What’s strange is CLI doctrine commands work like doctrine:database:create but it just doesn’t work in my application, there must be some config I’m missing but. I can’t see what – skyegill Apr 18 '19 at 05:17
0

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

skyegill
  • 83
  • 1
  • 9