【问题标题】:Kubernetes: Django and Postgres Containers don't communicateKubernetes:Django 和 Postgres 容器不通信
【发布时间】:2020-09-23 17:44:35
【问题描述】:

我创建了一个带有 postgres 数据库的 Django-Python 应用程序。它在我的 PC 以及任何其他基于 Windows 的系统中运行良好。 我正在尝试使用 K8s 来托管应用程序。 我已经成功设置了 postgres 容器。

但是当我尝试创建 Django-Python 容器并尝试启动它时,它向我显示了这种错误:

服务器是否在主机“127.0.0.1”上运行并接受 端口 5432 上的 TCP/IP 连接?

postgres 容器的部署和服务 yaml:

---
# 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

Postgres 容器的日志:

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

现在,当我尝试部署 Django-Python 容器时,它只是无法连接到数据库容器。

Django-Python应用部署和服务YAML文件:

---
# 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

在这一步之后,pod 开始运行,但是一旦我 bash 进入 Django 容器并运行命令:

python3 manage.py 迁移

它显示了这个错误:

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?

有人知道如何解决这个问题吗?

这是对 settings.py 文件的数据库配置的引用。

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)
    }
}

秘密 yaml 文件:

---
# 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=

【问题讨论】:

    标签: django postgresql docker kubernetes yaml


    【解决方案1】:
    kind: Service
    metadata:
      name: postgresql
      namespace: trojanwall  
      labels:
        app: postgres-db
    spec:
      type: ClusterIP
    

    您的 PostreSQL 实例服务将从 Kubernetes 集群分配一个新的 IP 地址,因为您的服务的类型为 ClusterIP。这很好。

    但您的 Python 应用程序必须在该 IP 地址 上连接到 PostgreSQL,并且不是127.0.0.1

    从您的setting.py 中的以下行看来,您的 PostgreSQL 实例的 IP 地址可以被覆盖,必须更改它以反映 Kubernetes 集群中的 IP。

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

    为应用更新您的Deployment,以包含POSTGRES_SERVICE_HOST 的环境值。

    例子:

        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
    

    【讨论】:

    • 非常感谢!!正在深入挖掘如何解决这个问题!终于做对了!!我先运行 PostGreSQL 容器,然后运行“kubectl get svc -n trojanwall”,得到了 Postgresql 容器的 ClusterIP。然后我将它添加到 python 应用程序部署文件的环境变量(POSTGRES_SERVICE_HOST)中。应用程序的容器立即连接到 db 容器!这有很大帮助!干杯!
    • 但是让我问一下。有什么办法可以主动将postgres db容器的clusterIP添加到python应用程序部署文件的env变量((POSTGRES_SERVICE_HOST)中??请告诉。
    • 从这个答案看来,它可能与该字段中的 DNS 名称一起使用:dba.stackexchange.com/a/260243/106
    • 看来我们可以在service.yml文件本身中为postgres容器指定任意的随机clusterIP。 eg: apiVersion: v1 kind: Service metadata: name: postgresql namespace: trojanwall labels: app: postgres-db spec: clusterIP: 10.107.194.222 #指定ClusterIP类型:ClusterIP ports: - port: 5432目标端口:5432 协议:TCP
    • 现在我们可以在python应用部署文件的“POSTGRES_SERVICE_HOST”环境变量中指定ClusterIP了。例如: 规范:容器:环境:-名称:POSTGRES_SERVICE_HOST 值:“10.107.194.222”# ClusterIP
    猜你喜欢
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2021-10-18
    相关资源
    最近更新 更多