psycopg2: 无法将主机名转换为地址:名称或服务未知

huangapple go评论93阅读模式
英文:

psycopg2: Could not translate host name to address: Name or service not known

问题

我正尝试使用 psycopg2 和 Django 应用程序连接到 PostgreSQL 数据库。运行应用程序的 Pod 报告以下错误:

  1. 127.0.0.1 - - [13/Jul/2023:17:35:05 -0500] "GET /read HTTP/1.1" 301 0 "-" "PostmanRuntime/7.32.3"
  2. 在处理 GET 请求时发生错误:无法将主机名 "resume-postgresql-primary-hl" 转换为地址:名称或服务未知
  3. 内部服务器错误:/read/

编辑:
添加负责的 views.py 部分:

  1. from django.http import JsonResponse
  2. from django.views.decorators.csrf import csrf_exempt
  3. from django.db import connection
  4. from django.conf import settings
  5. import psycopg2
  6. import logging
  7. # 设置日志记录
  8. logging.basicConfig(level=logging.INFO)
  9. logger = logging.getLogger(__name__)
  10. @csrf_exempt
  11. def read(request):
  12. try:
  13. conn = psycopg2.connect(
  14. host=settings.DATABASES['default']['HOST'],
  15. dbname=settings.DATABASES['default']['NAME'],
  16. user=settings.DATABASES['default']['USER'],
  17. password=settings.DATABASES['default']['PASSWORD']
  18. )
  19. with conn.cursor() as cur:
  20. cur.execute('SELECT * FROM visitor_count;')
  21. data = cur.fetchall()
  22. conn.close()
  23. for item in data:
  24. response = item[1]
  25. return JsonResponse({'statusCode': 200, 'data': response})
  26. except Exception as e:
  27. logger.error("处理 GET 请求时发生错误:%s", str(e))
  28. return JsonResponse({'statusCode': 500, 'message': '内部服务器错误'}, status=500)

从 settings.py 中:

  1. # 数据库配置
  2. DATABASES = {
  3. 'default': {
  4. 'ENGINE': 'django.db.backends.postgresql_psycopg2',
  5. 'NAME': os.environ.get('DATABASE'),
  6. 'USER': os.environ.get('DB_USERNAME'),
  7. 'PASSWORD': os.environ.get('DB_PASSWORD'),
  8. 'HOST': os.environ.get('DB_HOST'),
  9. 'PORT': os.environ.get('DB_PORT', '5432'),
  10. }
  11. }

环境变量通过一个密钥传递给容器:

密钥:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: backend-secret
  5. namespace: resume
  6. data:
  7. host: cmVzdW1lLXBvc3RncmVzcWwtcHJpbWFyeS1obAo=
  8. database: 已编辑
  9. db_username: 已编辑
  10. db_password: 已编辑
  11. db_port: NTQzMgo=
  12. secret_key: 已编辑

部署:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: resume-backend
  5. labels:
  6. app: resume-backend
  7. spec:
  8. template:
  9. metadata:
  10. name: resume-backend
  11. labels:
  12. app: resume-backend
  13. spec:
  14. containers:
  15. - name: resume-backend
  16. image: rustybridge/resume-backend:1.0
  17. imagePullPolicy: Always
  18. env:
  19. - name: DB_HOST
  20. valueFrom:
  21. secretKeyRef:
  22. name: backend-secret
  23. key: host
  24. - name: DATABASE
  25. valueFrom:
  26. secretKeyRef:
  27. name: backend-secret
  28. key: database
  29. - name: DB_USERNAME
  30. valueFrom:
  31. secretKeyRef:
  32. name: backend-secret
  33. key: db_username
  34. - name: DB_PASSWORD
  35. valueFrom:
  36. secretKeyRef:
  37. name: backend-secret
  38. key: db_password
  39. - name: DB_PORT
  40. valueFrom:
  41. secretKeyRef:
  42. name: backend-secret
  43. key: db_port
  44. - name: SECRET_KEY
  45. valueFrom:
  46. secretKeyRef:
  47. name: backend-secret
  48. key: secret_key
  49. ports:
  50. - containerPort: 8000
  51. name: listen
  52. selector:
  53. matchLabels:
  54. app: resume-backend
  55. replicas: 2

当我在本地主机上运行时,它可以正常工作(连接到数据库并返回数据)。

Pod 中的 nslookup 也正常工作:

  1. root@resume-backend-677cd68846-m22h8:/srv/app# nslookup resume-postgresql-primary-hl
  2. Server: 10.96.0.10
  3. Address: 10.96.0.10#53
  4. Name: resume-postgresql-primary-hl.resume.svc.cluster.local
  5. Address: 10.244.0.114

我无法弄清楚发生了什么。有任何想法吗?

英文:

I am attempting to connect to a PostgreSQL DB using psycopg2 and a django app. The pods running the application report the following error:

  1. 127.0.0.1 - - [13/Jul/2023:17:35:05 -0500] "GET /read HTTP/1.1" 301 0 "-" "PostmanRuntime/7.32.3"
  2. An error occurred while processing the GET request: could not translate host name "resume-postgresql-primary-hl
  3. " to address: Name or service not known
  4. Internal Server Error: /read/

EDIT:
Adding part of views.py responsible:

  1. from django.http import JsonResponse
  2. from django.views.decorators.csrf import csrf_exempt
  3. from django.db import connection
  4. from django.conf import settings
  5. import psycopg2
  6. import logging
  7. # Set up logging
  8. logging.basicConfig(level=logging.INFO)
  9. logger = logging.getLogger(__name__)
  10. @csrf_exempt
  11. def read(request):
  12. try:
  13. conn = psycopg2.connect(
  14. host=settings.DATABASES['default']['HOST'],
  15. dbname=settings.DATABASES['default']['NAME'],
  16. user=settings.DATABASES['default']['USER'],
  17. password=settings.DATABASES['default']['PASSWORD']
  18. )
  19. with conn.cursor() as cur:
  20. cur.execute('SELECT * FROM visitor_count;')
  21. data = cur.fetchall()
  22. conn.close()
  23. for item in data:
  24. response = item[1]
  25. return JsonResponse({'statusCode': 200, 'data': response})
  26. except Exception as e:
  27. logger.error("An error occurred while processing the GET request: %s", str(e))
  28. return JsonResponse({'statusCode': 500, 'message': 'Internal Server Error'}, status=500)

From settings.py:

  1. # Database
  2. DATABASES = {
  3. 'default': {
  4. 'ENGINE': 'django.db.backends.postgresql_psycopg2',
  5. 'NAME': os.environ.get('DATABASE'),
  6. 'USER': os.environ.get('DB_USERNAME'),
  7. 'PASSWORD': os.environ.get('DB_PASSWORD'),
  8. 'HOST': os.environ.get('DB_HOST'),
  9. 'PORT': os.environ.get('DB_PORT', '5432'),
  10. }
  11. }

The environmental variables are passed to the container with a secret:

Secret:

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: backend-secret
  5. namespace: resume
  6. data:
  7. host: cmVzdW1lLXBvc3RncmVzcWwtcHJpbWFyeS1obAo=
  8. database: REDACTED
  9. db_username: REDACTED
  10. db_password: REDACTED
  11. db_port: NTQzMgo=
  12. secret_key: REDACTED

Deployment:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: resume-backend
  5. labels:
  6. app: resume-backend
  7. spec:
  8. template:
  9. metadata:
  10. name: resume-backend
  11. labels:
  12. app: resume-backend
  13. spec:
  14. containers:
  15. - name: resume-backend
  16. image: rustybridge/resume-backend:1.0
  17. imagePullPolicy: Always
  18. env:
  19. - name: DB_HOST
  20. valueFrom:
  21. secretKeyRef:
  22. name: backend-secret
  23. key: host
  24. - name: DATABASE
  25. valueFrom:
  26. secretKeyRef:
  27. name: backend-secret
  28. key: database
  29. - name: DB_USERNAME
  30. valueFrom:
  31. secretKeyRef:
  32. name: backend-secret
  33. key: db_username
  34. - name: DB_PASSWORD
  35. valueFrom:
  36. secretKeyRef:
  37. name: backend-secret
  38. key: db_password
  39. - name: DB_PORT
  40. valueFrom:
  41. secretKeyRef:
  42. name: backend-secret
  43. key: db_port
  44. - name: SECRET_KEY
  45. valueFrom:
  46. secretKeyRef:
  47. name: backend-secret
  48. key: secret_key
  49. ports:
  50. - containerPort: 8000
  51. name: listen
  52. selector:
  53. matchLabels:
  54. app: resume-backend
  55. replicas: 2
  1. root@resume-backend-677cd68846-9vrm6:/srv/app# env | grep DB_HOST
  2. DB_HOST=resume-postgresql-primary-hl

When I run it on localhost, it works (connects to the DB and returns the data)

Nslookup from the pods is also working:

> root@resume-backend-677cd68846-m22h8:/srv/app# nslookup resume-postgresql-primary-hl
Server: 10.96.0.10
Address: 10.96.0.10#53
>
>Name: resume-postgresql-primary-hl.resume.svc.cluster.local
Address: 10.244.0.114

I can't figure out what is going on. Any ideas?

答案1

得分: 0

问题出在秘密值的编码方式上(它们都包含了一个换行符)

解决方法是将它们编码为这样:
echo -n 'resume-postgresql-primary-hl' | base64 -w0

来源:https://github.com/kubernetes/kubernetes/issues/23404#issuecomment-203404986

英文:

The issue was with how the secret values were encoded (they all contained a newline)

What worked was to encode them like this:
echo -n 'resume-postgresql-primary-hl' | base64 -w0

credit: https://github.com/kubernetes/kubernetes/issues/23404#issuecomment-203404986

huangapple
  • 本文由 发表于 2023年7月14日 06:53:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76683734.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定