You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

部署Docker化Django+PostgreSQL应用时Kubernetes Pod无限崩溃求助

解决Django部署GCP Kubernetes时的Pod崩溃与Postgres连接问题

从你提供的错误日志和部署情况来看,核心是两个连锁问题:Postgres Pod未正常启动,导致Django无法解析数据库服务主机名,最终陷入崩溃循环。下面分步骤帮你排查修复:

一、先解决Postgres Pod的启动问题(根源)

Postgres Pod既不崩溃也不运行,大概率是资源绑定或配置错误,先做这些检查:

  • 查看Pod详细状态与日志
    运行命令获取Postgres Pod的具体故障信息:
    kubectl get pods | grep postgres
    kubectl logs <你的postgres-pod名称>
    kubectl describe pod <你的postgres-pod名称>
    
    重点看Events字段,是否有PVC绑定失败、镜像拉取错误、Secret配置缺失等提示。
  • 验证Postgres Secret配置
    确保你创建的Secret包含POSTGRES_USERPOSTGRES_PASSWORDPOSTGRES_DB这三个键,且值是正确的Base64编码(可以用echo -n "你的值" | base64验证)。运行命令检查:
    kubectl get secret postgres-secret -o yaml
    
  • 检查PVC绑定状态
    GCP动态创建PD存储需要集群有对应权限,运行命令看PVC是否处于Bound状态:
    kubectl get pvc
    
    如果是Pending状态,需要确认集群的存储类配置,或者检查GCP项目是否有足够的存储配额。

二、修复Django的数据库连接问题

错误日志里明确提示could not translate host name "postgres-service" to address,这说明Django配置的数据库主机无法被解析,解决步骤:

  • 确认Postgres Service与Pod的标签匹配
    Kubernetes Service是通过标签选择器关联Pod的,检查你的Postgres Service的spec.selector是否和Postgres Deployment的spec.template.metadata.labels完全一致。比如:
    # Postgres Service的selector
    selector:
      app: postgres
    # Postgres Deployment Pod模板的labels
    labels:
      app: postgres
    
    标签不匹配的话,Service找不到Pod,就不会生成Endpoints,自然解析不了主机名。
  • 修正Django的数据库配置
    settings.py里用环境变量管理数据库配置,避免硬编码,同时确保主机名对应Postgres Service的名称:
    import os
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('POSTGRES_DB'),
            'USER': os.environ.get('POSTGRES_USER'),
            'PASSWORD': os.environ.get('POSTGRES_PASSWORD'),
            'HOST': os.environ.get('POSTGRES_HOST', 'postgres-service'),
            'PORT': os.environ.get('POSTGRES_PORT', '5432'),
        }
    }
    
  • 在Django Deployment中注入环境变量
    把Postgres Secret里的配置注入到Django Pod的环境变量中,确保Django能拿到正确的数据库 credentials:
    env:
      - name: POSTGRES_DB
        valueFrom:
          secretKeyRef:
            name: postgres-secret
            key: POSTGRES_DB
      - name: POSTGRES_USER
        valueFrom:
          secretKeyRef:
            name: postgres-secret
            key: POSTGRES_USER
      - name: POSTGRES_PASSWORD
        valueFrom:
          secretKeyRef:
            name: postgres-secret
            key: POSTGRES_PASSWORD
      - name: POSTGRES_HOST
        value: "postgres-service"
    

三、修复Docker相关问题

从错误日志的psycopg2提示来看,Docker镜像的依赖安装需要调整:

  • 替换psycopg2为psycopg2-binary
    requirements.txt里把psycopg2改成psycopg2-binary,避免在Docker镜像中需要编译依赖(psycopg2需要Postgres开发库,而binary版本是预编译好的)。
  • 优化Dockerfile
    确保Dockerfile正确安装依赖并设置工作目录,示例:
    FROM python:3.6-slim
    
    WORKDIR /app
    
    # 安装系统依赖(如果需要)
    RUN apt-get update && apt-get install -y --no-install-recommends \
        gcc \
        && rm -rf /var/lib/apt/lists/*
    
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . .
    
    # 启动命令绑定0.0.0.0,允许容器外部访问
    CMD ["python", "src/manage.py", "runserver", "0.0.0.0:8000"]
    
  • 添加健康检查探针
    在Django Deployment中添加readinessProbelivenessProbe,避免因为数据库连接失败导致无限重启:
    readinessProbe:
      httpGet:
        path: /admin  # 用现成的admin页面做健康检查,或者自己写一个/health接口
        port: 8000
      initialDelaySeconds: 10
      periodSeconds: 5
    livenessProbe:
      httpGet:
        path: /admin
        port: 8000
      initialDelaySeconds: 30
      periodSeconds: 10
    

四、本地验证(提前规避问题)

在部署到K8s之前,先用Docker Compose在本地测试,确保Django和Postgres能正常通信:

# docker-compose.yml示例
version: '3'
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      POSTGRES_DB: your_db_name
      POSTGRES_USER: your_db_user
      POSTGRES_PASSWORD: your_db_pass
      POSTGRES_HOST: postgres-service
    depends_on:
      - postgres-service
  postgres-service:
    image: postgres:12
    environment:
      POSTGRES_DB: your_db_name
      POSTGRES_USER: your_db_user
      POSTGRES_PASSWORD: your_db_pass
    volumes:
      - postgres_data:/var/lib/postgresql/data/
volumes:
  postgres_data:

运行docker-compose up,如果本地能正常启动并访问Django,再部署到GCP Kubernetes会更稳妥。

内容的提问来源于stack exchange,提问作者Stefan Radonjic

火山引擎 最新活动