1

I have created a Django-Python application with a postgres database. Its working fine in my PC as well as in any other windows based systems. I am trying to use K8s to host the application. I have setup the postgres container successfully.

But when I am trying to create the Django-Python container and tryong to start it, it shows me this kind of error:

Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432?

The Deployment and service yaml for the postgres container:

---
# Deployment for the PostgreSQL container

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgresql
  namespace: trojanwall  
  labels:
    app: postgres-db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres-db
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: postgres-db
        tier: postgreSQL
    spec:
      containers:
        - name: postgresql
          image: postgres:10.3
          ports:
          - containerPort: 5432
          env:
          - name: POSTGRES_USER
            valueFrom:
              secretKeyRef:
                name: postgres-db-credentials
                key: user
          - name: POSTGRES_PASSWORD
            valueFrom:
              secretKeyRef:
                name: postgres-db-credentials
                key: password
          - name: POSTGRES_DB
            value: 'postgres'
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgresql-volume-mount
          resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"
      volumes:
      - name: postgresql-volume-mount
        persistentVolumeClaim:
          claimName: postgres-pv-claim
---
# Service for the PostgreSQL container

apiVersion: v1
kind: Service
metadata:
  name: postgresql
  namespace: trojanwall  
  labels:
    app: postgres-db
spec:
  type: ClusterIP
  ports:
  - port: 5432
    targetPort: 5432
    protocol: TCP
  selector:
    app: postgres-db
    tier: postgreSQL

The log of the Postgres container:

2020-09-23 15:39:58.034 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2020-09-23 15:39:58.034 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2020-09-23 15:39:58.038 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-09-23 15:39:58.049 UTC [23] LOG:  database system was shut down at 2020-09-23 15:37:17 UTC
2020-09-23 15:39:58.053 UTC [1] LOG:  database system is ready to accept connections
2020-09-23 15:47:12.845 UTC [1] LOG:  received smart shutdown request
2020-09-23 15:47:12.846 UTC [1] LOG:  worker process: logical replication launcher (PID 29) exited with exit code 1
2020-09-23 15:47:12.846 UTC [24] LOG:  shutting down
2020-09-23 15:47:12.851 UTC [1] LOG:  database system is shut down
2020-09-23 15:47:13.123 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2020-09-23 15:47:13.123 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2020-09-23 15:47:13.126 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-09-23 15:47:13.134 UTC [24] LOG:  database system was shut down at 2020-09-23 15:47:12 UTC
2020-09-23 15:47:13.138 UTC [1] LOG:  database system is ready to accept connections
2020-09-23 15:47:25.722 UTC [1] LOG:  received smart shutdown request
2020-09-23 15:47:25.724 UTC [1] LOG:  worker process: logical replication launcher (PID 30) exited with exit code 1
2020-09-23 15:47:25.725 UTC [25] LOG:  shutting down
2020-09-23 15:47:25.730 UTC [1] LOG:  database system is shut down
2020-09-23 15:47:25.925 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2020-09-23 15:47:25.925 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2020-09-23 15:47:25.927 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2020-09-23 15:47:25.937 UTC [23] LOG:  database system was shut down at 2020-09-23 15:47:25 UTC
2020-09-23 15:47:25.941 UTC [1] LOG:  database system is ready to accept connections

Now when I am trying to deploy the Django-Python container, it just wont connect to the database container.

Django-Python application deployment and service YAML file:

---
# Deployment for the Django-Python application container

apiVersion: apps/v1
kind: Deployment
metadata:
  name: trojanwall-django
  namespace: trojanwall  
  labels:
    app: django
spec:
  replicas: 1
  selector:
    matchLabels:
      app: django
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
      - name: trojanwall-django
        image: arbabu/trojan-wall:v3.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8000
        env:
          - name: POSTGRES_USER
            valueFrom:
              secretKeyRef:
                name: postgres-db-credentials
                key: user
          - name: POSTGRES_PASSWORD
            valueFrom:
              secretKeyRef:
                name: postgres-db-credentials
                key: password
          - name: POSTGRES_DB
            value: 'postgres'
          - name: DATABASE_URL
            value: postgres://$(POSTGRES_USER):$(POSTGRES_PASSWORD)@postgresql:5432/$(POSTGRES_DB)
          - name: DJANGO_SETTINGS_MODULE
            value: 'TestProject.settings'
          - name: SECRET_KEY
            valueFrom:
              secretKeyRef:
                name: django-secret-key
                key: secret_key
        resources:
            requests:
              memory: "64Mi"
              cpu: "250m"
            limits:
              memory: "128Mi"
              cpu: "500m"
        volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgresql-volume-mount
      volumes:
      - name: postgresql-volume-mount
        persistentVolumeClaim:
          claimName: postgres-pv-claim

---
# Service for the Django-Python application container

apiVersion: v1
kind: Service
metadata:
  name: trojanwall-django
  namespace: trojanwall  
  labels:
    app: django
spec:
  ports:
  - port: 8000
    targetPort: 8000
    protocol: TCP
  type: NodePort
  selector:
    app: django

After this step, the pods do start running, but once I bash into the Django container and run the command:

python3 manage.py migrate

It shows me this error:

root@trojanwall-django-7df4bc7759-89bgv:/TestProject# python3 manage.py migrate
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: Connection refused
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.8/site-packages/django/core/management/__init__.py", line 395, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 330, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 371, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/base.py", line 85, in wrapped
    res = handle_func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 92, in handle
    executor = MigrationExecutor(connection, self.migration_progress_callback)
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
    self.loader = MigrationLoader(self.connection)
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/loader.py", line 53, in __init__
    self.build_graph()
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/loader.py", line 216, in build_graph
    self.applied_migrations = recorder.applied_migrations()
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
    if self.has_table():
  File "/usr/local/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 55, in has_table
    with self.connection.cursor() as cursor:
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 259, in cursor
    return self._cursor()
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 235, in _cursor
    self.ensure_connection()
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
    self.connect()
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/base/base.py", line 200, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/usr/local/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/usr/local/lib/python3.8/site-packages/psycopg2/__init__.py", line 127, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not connect to server: Connection refused
        Is the server running on host "127.0.0.1" and accepting
        TCP/IP connections on port 5432?

Does anyone know how to resolve this?

Here's a reference to the settings.py file's database configurations.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': os.environ.get('POSTGRES_NAME', 'postgres'),
        'USER': os.environ.get('POSTGRES_USER', 'postgres'),
        'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'postgres'),     
        'HOST': os.getenv('POSTGRES_SERVICE_HOST','127.0.0.1'),
        'PORT': os.getenv('POSTGRES_SERVICE_PORT',5432)
    }
}

The secrets yaml file:

---
# Secrets for the Database Credential Management

apiVersion: v1
kind: Secret
metadata:
  name: postgres-db-credentials
  namespace: trojanwall
  labels:
    app: postgres-db
type: opaque
data:
  user: cG9zdGdyZXM=
  password: cG9zdGdyZXM=

1 Answer 1

3
kind: Service
metadata:
  name: postgresql
  namespace: trojanwall  
  labels:
    app: postgres-db
spec:
  type: ClusterIP

You service for the PostreSQL instance will allocate a new IP address from the Kubernetes cluster, since your service has type ClusterIP. This is well.

But your Python app has to connect to PostgreSQL on that IP address and not to 127.0.0.1.

From the line below in your setting.py it looks like the IP address for your PostgreSQL instance can be overridden, it must be changed to reflect the IP in the Kubernetes cluster.

        'HOST': os.getenv('POSTGRES_SERVICE_HOST','127.0.0.1'),

Update your Deployment for the app, to contain an environment value for POSTGRES_SERVICE_HOST.

Example:

    spec:
      containers:
      - name: trojanwall-django
        image: arbabu/trojan-wall:v3.0
        imagePullPolicy: Always
        ports:
        - containerPort: 8000
        env:
          - name: POSTGRES_SERVICE_HOST
            value: "<INSERT YOUR IP ADDRESS>" # update this to reflect your IP
          - name: POSTGRES_USER
            valueFrom:
              secretKeyRef:
                name: postgres-db-credentials
                key: user
          - name: POSTGRES_PASSWORD
            valueFrom:
              secretKeyRef:
                name: postgres-db-credentials
                key: password
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks a lot!! Was digging deep how to fix this!! Finally got it right!! I ran the PostGreSQL container first and then ran "kubectl get svc -n trojanwall", and got the ClusterIP of the Postgresql container. Then I added it to the environment variable(POSTGRES_SERVICE_HOST) of the python app's deployment file. The app's container was instantly connected to the db container! This helped a lot! Cheers!
But let me ask. Is there any way to pro actively add the clusterIP of the postgres db container to env variable((POSTGRES_SERVICE_HOST)of the python app's deployment file ?? Please do tell.
From this answer, it looks like it may work with a DNS-name in that field: dba.stackexchange.com/a/260243/106
It seems that we can specify any random clusterIP for the postgres container in the service.yml file itself. Eg: <Postgres-service.yml> apiVersion: v1 kind: Service metadata: name: postgresql namespace: trojanwall labels: app: postgres-db spec: clusterIP: 10.107.194.222 #Specify the ClusterIP type: ClusterIP ports: - port: 5432 targetPort: 5432 protocol: TCP
And now we can specify the ClusterIP in the "POSTGRES_SERVICE_HOST" environment variable in the python app's deployment file. Eg: <pythonapp-deploy.yml> spec: containers: env: - name: POSTGRES_SERVICE_HOST value: "10.107.194.222" # ClusterIP

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.