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#53Name: resume-postgresql-primary-hl.resume.svc.cluster.local
Address: 10.244.0.114
I can't figure out what is going on. Any ideas?
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