You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes中Flask应用通过psycopg2连接Postgres服务失败求助

问题

本地通过minikube搭建Kubernetes集群,集群内已运行Postgres服务。部署Flask应用通过psycopg2连接Postgres并暴露REST接口时,gunicorn日志报错无法解析Postgres服务域名postgres-postgresql.kafkaplaypen.svc.cluster.local:5432。

报错日志

[2022-12-12 18:49:41 +0000] [10] [ERROR] Error handling request /popular/locations
  File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 122, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "postgres-postgresql.kafkaplaypen.svc.cluster.local:5432" to address: Name or service not known

Postgres部署信息(Helm输出)

PostgreSQL can be accessed via port 5432 on the following DNS names from within your cluster:

    postgres-postgresql.kafkaplaypen.svc.cluster.local - Read/Write connection

To get the password for "postgres" run:

    export POSTGRES_PASSWORD=$(kubectl get secret --namespace kafkaplaypen postgres-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d)

To connect to your database run the following command:

    kubectl run postgres-postgresql-client --rm --tty -i --restart='Never' --namespace kafkaplaypen --image docker.io/bitnami/postgresql:15.1.0-debian-11-r7 --env="PGPASSWORD=$POSTGRES_PASSWORD" \
      --command -- psql --host postgres-postgresql -U postgres -d postgres -p 5432

    > NOTE: If you access the container using bash, make sure that you execute "/opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash" in order to avoid the error "psql: local user with ID 1001} does not exist"

To connect to your database from outside the cluster execute the following commands:

    kubectl port-forward --namespace kafkaplaypen svc/postgres-postgresql 5432:5432 &
    PGPASSWORD="$POSTGRES_PASSWORD" psql --host 127.0.0.1 -U postgres -d postgres -p 5432

Flask应用代码

app = Flask(__name__)
app.config["DEBUG"] = True

def get_db_connection():
    conn = psycopg2.connect(host='postgres-postgresql.kafkaplaypen.svc.cluster.local:5432',
                            database=os.environ['DB_NAME'],
                            user=os.environ['DB_USERNAME'],
                            password=os.environ['DB_PASSWORD'])
    return conn

@app.route('/popular/locations')
def get_popular_locations():
    conn = get_db_connection()

    cur = conn.cursor()
    cur.execute('SELECT * FROM tolocations;')
    data = cur.fetchall()

    cur.close()
    conn.close()

    return data

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8081, debug=True)

Flask Pod启动命令

kubectl run flaskapp -i --image flaskapp:latest --image-pull-policy Never --restart Never --namespace kafkaplaypen --env="DB_NAME=postgres" --env="DB_USERNAME=postgres"  --env="DB_PASSWORD=$POSTGRES_PASSWORD"

Flask应用Dockerfile

FROM python:3.7-slim
WORKDIR /app

RUN apt-get update && apt-get install -y curl nano
RUN pip3 install flask psycopg2-binary gunicorn

COPY rest /app

EXPOSE 8081

CMD gunicorn -b 0.0.0.0:8081 --log-file /app/logs/gunicorn.log --log-level DEBUG src.expose:app

排查与解决方案
  • 核心问题:psycopg2的connect参数使用错误,你将域名和端口合并写在host字段中,但psycopg2要求host仅填写域名/IP,端口需通过单独的port参数传递,合并写法会导致DNS解析失败。

  • 修复代码:修改Flask的数据库连接函数:

def get_db_connection():
    conn = psycopg2.connect(
        host='postgres-postgresql.kafkaplaypen.svc.cluster.local',
        port=5432,
        database=os.environ['DB_NAME'],
        user=os.environ['DB_USERNAME'],
        password=os.environ['DB_PASSWORD']
    )
    return conn
  • 额外验证步骤:
    1. 验证集群DNS解析:进入Flask Pod执行域名解析测试,确认服务域名可正常解析
      kubectl exec -it flaskapp -n kafkaplaypen -- nslookup postgres-postgresql.kafkaplaypen.svc.cluster.local
      
    2. 检查Postgres服务状态:确认服务已正常暴露端口
      kubectl get svc postgres-postgresql -n kafkaplaypen
      

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 19:25:26