Search code examples
djangokubernetespsycopg2

psycopg2: Could not translate host name to address: Name or service not known


I am attempting to connect to a PostgreSQL DB using psycopg2 and a django app. The pods running the application report the following error:

127.0.0.1 - - [13/Jul/2023:17:35:05 -0500] "GET /read HTTP/1.1" 301 0 "-" "PostmanRuntime/7.32.3"  
An error occurred while processing the GET request: could not translate host name "resume-postgresql-primary-hl
" to address: Name or service not known

Internal Server Error: /read/

EDIT: Adding part of views.py responsible:

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.db import connection
from django.conf import settings
import psycopg2
import logging

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@csrf_exempt
def read(request):
    try:
        conn = psycopg2.connect(
            host=settings.DATABASES['default']['HOST'],
            dbname=settings.DATABASES['default']['NAME'],
            user=settings.DATABASES['default']['USER'],
            password=settings.DATABASES['default']['PASSWORD']
        )
        with conn.cursor() as cur:
            cur.execute('SELECT * FROM visitor_count;')
            data = cur.fetchall()

        conn.close()

        for item in data:
            response = item[1]
            return JsonResponse({'statusCode': 200, 'data': response})

    except Exception as e:
        logger.error("An error occurred while processing the GET request: %s", str(e))
        return JsonResponse({'statusCode': 500, 'message': 'Internal Server Error'}, status=500)

From settings.py:

# Database
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ.get('DATABASE'),
        'USER': os.environ.get('DB_USERNAME'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST'),
        'PORT': os.environ.get('DB_PORT', '5432'),
    }
}

The environmental variables are passed to the container with a secret:

Secret:

apiVersion: v1
kind: Secret
metadata:
  name: backend-secret
  namespace: resume
data:
  host: cmVzdW1lLXBvc3RncmVzcWwtcHJpbWFyeS1obAo= 
  database: REDACTED
  db_username: REDACTED
  db_password: REDACTED
  db_port: NTQzMgo=
  secret_key: REDACTED

Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: resume-backend
  labels:
    app: resume-backend
spec:
  template:
    metadata:
      name: resume-backend
      labels:
        app: resume-backend
    spec:
      containers:
      - name: resume-backend
        image: rustybridge/resume-backend:1.0
        imagePullPolicy: Always
        env:
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: host
        - name: DATABASE
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: database
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: db_username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: db_password
        - name: DB_PORT
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: db_port
        - name: SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: backend-secret
              key: secret_key
        ports:
        - containerPort: 8000
          name: listen
  selector:
    matchLabels:
      app: resume-backend
  replicas: 2

root@resume-backend-677cd68846-9vrm6:/srv/app# env | grep DB_HOST
DB_HOST=resume-postgresql-primary-hl

When I run it on localhost, it works (connects to the DB and returns the data)

Nslookup from the pods is also working:

root@resume-backend-677cd68846-m22h8:/srv/app# nslookup resume-postgresql-primary-hl
Server: 10.96.0.10
Address: 10.96.0.10#53

Name: resume-postgresql-primary-hl.resume.svc.cluster.local
Address: 10.244.0.114

I can't figure out what is going on. Any ideas?


Solution

  • The issue was with how the secret values were encoded (they all contained a newline)

    What worked was to encode them like this: echo -n 'resume-postgresql-primary-hl' | base64 -w0

    credit: https://github.com/kubernetes/kubernetes/issues/23404#issuecomment-203404986