GKE集群部署PostgreSQL+Django应用遇Pod崩溃及连接问题
看起来你在GKE上部署Django+PostgreSQL应用时遇到了两个棘手的问题,我来帮你逐一拆解解决:
1. PostgreSQL初始化失败:目录非空报错
你看到的initdb: directory "/var/lib/postgresql/data" exists but is not empty错误,根源在于你直接把PersistentVolume挂载到了PostgreSQL的默认数据目录。当挂载块存储时,系统会自动生成lost+found目录用于数据恢复,但PostgreSQL要求初始化的目录必须完全为空,所以就触发了这个报错。
修复方案
修改你的PostgreSQL Deployment配置,做两个小调整:
- 把挂载路径从
/var/lib/postgresql/data改成该目录下的子文件夹(比如/var/lib/postgresql/data/pgdata) - 添加
PGDATA环境变量,告诉PostgreSQL使用这个干净的子文件夹作为数据存储目录
修改后的容器部分配置如下:
containers: - name: postgres-container image: postgres:9.6.6 env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: postgres-credentials key: user - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: postgres-credentials key: password - name: POSTGRES_DB value: agent_technologies_db # 添加这个环境变量,指定PostgreSQL数据存储的子目录 - name: PGDATA value: /var/lib/postgresql/data/pgdata ports: - containerPort: 5432 volumeMounts: # 挂载路径保持为父目录,让PV包含子文件夹 - name: postgres-volume-mount mountPath: /var/lib/postgresql/data
修改后重新部署PostgreSQL,初始化就能正常完成了。
2. Django无法连接PostgreSQL的问题
从Django的日志来看,它一直在尝试连接本地Unix套接字/var/run/postgresql/.s.PGSQL.5432,这说明你的Django数据库配置没有指向集群内的PostgreSQL Service,而是默认尝试本地连接——但你的PostgreSQL是在独立的Pod里,必须通过Service进行跨Pod通信。
修复步骤
(1)修正Django的数据库配置
打开你的settings.py,确保DATABASES配置里的HOST设置为PostgreSQL Service的名称(也就是你定义的postgres-service):
import os DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'agent_technologies_db', 'USER': os.environ.get('POSTGRES_USER'), 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'), 'HOST': 'postgres-service', # 关键:用Service名称而不是localhost或空 'PORT': '5432', } }
Kubernetes的DNS服务会自动把postgres-service解析到对应的PostgreSQL Pod IP,这样Django就能跨Pod访问数据库了。
(2)确保Django Pod能读取数据库凭证
你的Django Deployment需要挂载postgres-credentials Secret,这样才能获取到POSTGRES_USER和POSTGRES_PASSWORD环境变量。可以参考PostgreSQL Deployment的方式,在Django的Pod模板里添加:
volumes: - name: postgres-credentials secret: secretName: postgres-credentials
然后在容器部分添加环境变量引用,或者直接挂载Secret到文件读取。
(3)验证Service和Pod的关联
执行以下命令确认PostgreSQL Service已经正确关联到运行的Pod:
kubectl get svc postgres-service
查看输出的ENDPOINTS字段,如果显示了PostgreSQL Pod的IP和5432端口,说明关联正常。
(4)重启Django Deployment
当你修正配置后,重启Django的Deployment让新配置生效:
kubectl rollout restart deployment <你的Django Deployment名称>
完成这些步骤后,再查看Django Pod的日志,应该就能成功连接到PostgreSQL了。
内容的提问来源于stack exchange,提问作者Stefan Radonjic

