usbToaster
usbToaster

Reputation: 525

Running rails + postgres in kubernetes: Connection refused

My rails deployment is not able to connect to the postgres database. Error in the logs:

PG::ConnectionBad (could not connect to server: Connection refused
  Is the server running on host "db" (10.0.105.11) and accepting
  TCP/IP connections on port 5432?
):

This is my kubectl get services output:

NAME                     TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
load-balancer            LoadBalancer   10.0.5.147     60.86.4.33    80:31259/TCP   10m
db                       ClusterIP      10.0.105.11    <none>        5432/TCP       10m
kubernetes               ClusterIP      10.0.0.1       <none>        443/TCP        10m
web                      ClusterIP      10.0.204.107   <none>        3000/TCP       10m

db-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: db
  name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - env:
        - name: POSTGRES_DB
          value: postgres
        - name: POSTGRES_HOST_AUTH_METHOD
          value: trust
        - name: POSTGRES_USER
          value: postgres
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
        ports:
        - containerPort: 5432
        image: postgres
        imagePullPolicy: ""
        name: db
        resources: {}
        volumeMounts:
        - mountPath: /var/lib/postgresql/data
          name: postgres
      restartPolicy: Always
      serviceAccountName: ""
      volumes:
      - name: postgres
        persistentVolumeClaim:
          claimName: postgres
status: {}

db-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: db
  labels:
    app: db
spec:
  ports:
    - port: 5432
  selector:
    app: db
    tier: database

config/database.yml:

default: &default
  adapter: postgresql
  encoding: utf8
  host: db
  username: postgres
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production

How do I ensure the postgres instance is running and accepting connections? Did I misconfigure something in the manifest files, or does the database.yml file need to point to a different host?

Upvotes: 0

Views: 1714

Answers (1)

Patrick Magee
Patrick Magee

Reputation: 362

The first thing that jumps out at me is that your db service is targeting two selectors app: db and tier: database, however the corresponding deployment.yml only has the db label. You will need to add the tier label to your deployment template metadata so that the service will appropriately target the right pod.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: db
    tier: database 
  name: db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
      tier: database
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: db
        tier: database

In general, if a service is not connecting to a backend pod, you can easily diagnose the issue with a simple kubectl command.
This will tell you what current selectors are applied to your service

kubectl describe service db -o yaml

Then you can fetch the pods that the selectors refer to and make sure that this is returning something.

kubectl get pods -l app=db -l tier=database

Finally, I would recommend using the DNS name of the service setup through kube-proxy instead of the cluster IP address. I tend to view this as more resilient then a cluster up, as it will be automatically routed if the services IP ever changes. In your connection string use db:5432 instead of 10.0.105.11.

Upvotes: 4

Related Questions