Golang Web服务器无法连接K8s集群中Postgres StatefulSet求助
我用Golang开发了一个Web服务器,需要连接以StatefulSet方式部署在Kubernetes集群中的Postgres数据库,但出现“找不到对应主机”的连接错误。Web服务器通过ClusterIP Service和Deployment部署,Postgres采用Headless Service和StatefulSet部署。以下是我的K8s配置文件及错误信息:
配置文件
Headless Service配置(headless-service.yml)
apiVersion: v1 kind: Service metadata: name: authentication-headless-service labels: ims: authentication spec: clusterIP: None # headless service selector: ims: authentication-postgres ports: - name: authentication-postgres-h port: 5432 targetPort: 5432
StatefulSet配置(statefulset.yml)
apiVersion: apps/v1 kind: StatefulSet metadata: name: authentication-postgres-statefulset spec: serviceName: authentication-headless-service replicas: 1 selector: matchLabels: ims: authentication-postgres template: metadata: labels: ims: authentication-postgres spec: containers: - name: postgres image: postgres:14.2 env: - name: POSTGRES_USER valueFrom: secretKeyRef: name: authentication-secret key: POSTGRES_USER - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: authentication-secret key: POSTGRES_PASSWORD - name: POSTGRES_HOST valueFrom: secretKeyRef: name: authentication-secret key: POSTGRES_HOST ports: - containerPort: 5432 name: postgres volumeMounts: - name: postgres-authentication-data mountPath: /var/lib/postgresql/data subPath: postgres # specific to postgres livenessProbe: tcpSocket: port: 5432 initialDelaySeconds: 60 periodSeconds: 30 failureThreshold: 3 readinessProbe: tcpSocket: port: 5432 initialDelaySeconds: 60 periodSeconds: 30 failureThreshold: 3 volumeClaimTemplates: - metadata: name: postgres-authentication-data spec: accessModes: - "ReadWriteOnce" resources: requests: storage: 500Mi storageClassName: ims-storage-class
其他配置(Secret、ClusterIP Service、Deployment)
apiVersion: v1 kind: Secret metadata: name: authentication-secret type: Opaque data: POSTGRES_USER: YXV0aGVudGljYXRpb24tcG9zdGdyZXM= POSTGRES_PASSWORD: cGFzc3dvcmQ= # base64编码内容为 'authentication-postgres-0.authentication-headless-service.default.svc.cluster.local' POSTGRES_HOST: YXV0aGVudGljYXRpb24tcG9zdGdyZXMtMC5hdXRoZW50aWNhdGlvbi1oZWFkbGVzcy1zZXJ2aWNlLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWw= --- apiVersion: v1 kind: Service metadata: name: authentication-clusterip spec: type: ClusterIP ports: - targetPort: 8001 port: 8001 selector: ims: authentication --- apiVersion: apps/v1 kind: Deployment metadata: name: authentication-deployment namespace: default spec: replicas: 4 selector: matchLabels: ims: authentication template: metadata: labels: ims: authentication spec: containers: - name: authentication image: localhost:5050/ims-authentication:latest ports: - containerPort: 8001 env: - name: MODE value: docker - name: POSTGRES_USER valueFrom: secretKeyRef: name: authentication-secret key: POSTGRES_USER - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: authentication-secret key: POSTGRES_PASSWORD - name: POSTGRES_HOST valueFrom: secretKeyRef: name: authentication-secret key: POSTGRES_HOST - name: POSTGRES_PORT valueFrom: configMapKeyRef: name: authentication-configmap key: POSTGRES_PORT - name: POSTGRES_DB valueFrom: configMapKeyRef: name: authentication-configmap key: POSTGRES_DB strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0
错误信息
kubectl logs authentication-deployment-99c845645-vr48p 2024/09/18 17:16:10 failed to connect to postgres db: failed to connect to `user=authentication-postgres database=imsdb`: hostname resolving error: lookup authentication-postgres-0.authentication-headless-service.default.svc.cluster.local on 10.96.0.10:53: no such host
排查与解决方案
1. 确认StatefulSet Pod运行状态
先检查Postgres的StatefulSet Pod是否正常启动并处于Running状态:
kubectl get pods -l ims=authentication-postgres
如果Pod未处于Running状态,查看Pod日志和事件定位启动失败原因(比如存储卷挂载失败、镜像拉取错误等):
kubectl logs authentication-postgres-statefulset-0 kubectl describe pod authentication-postgres-statefulset-0
2. 测试DNS解析有效性
在Web服务的Pod中执行nslookup,验证目标主机名能否正常解析:
kubectl exec -it authentication-deployment-99c845645-vr48p -- nslookup authentication-postgres-0.authentication-headless-service.default.svc.cluster.local
如果解析失败,检查:
- Headless Service的
selector是否与StatefulSet Pod的标签完全匹配(当前配置匹配,确认无拼写错误) - StatefulSet的
serviceName是否正确指向Headless Service名称(当前配置正确)
3. 简化数据库连接地址
由于仅部署了1个Postgres副本,可直接使用Headless Service的名称作为连接地址,无需带Pod序号的FQDN:authentication-headless-service.default.svc.cluster.local
修改Secret中的POSTGRES_HOST值为该地址,Headless Service会自动解析到后端Pod的IP,避免序号相关的解析问题。
4. 检查命名空间一致性
确认所有资源(Secret、Service、StatefulSet、Deployment)都在同一命名空间下(当前均在default命名空间,无问题)。
5. 验证CoreDNS状态
集群DNS服务异常也会导致解析失败,检查CoreDNS Pod运行状态:
kubectl get pods -n kube-system -l k8s-app=kube-dns
若CoreDNS存在异常,查看日志或重启Pod:
kubectl logs -n kube-system coredns-xxxxxx-xxxx kubectl delete pod -n kube-system coredns-xxxxxx-xxxx
内容的提问来源于stack exchange,提问作者helloitsme

