Traefik v3配置PostgreSQL TLS Ingress TCP入口路由遇连接超时
PostgreSQL TCP IngressRoute 连接超时问题排查与解决
问题背景
- PostgreSQL以非SSL模式运行,TLS终止由Traefik v3(Beta版)处理
- 通过Traefik Helm Chart配置了TCP Entrypoint,MongoDB同款配置可正常运行
- 配置IngressRouteTCP后,PGAdmin连接数据库超时,但端口转发访问PostgreSQL服务正常
- Traefik与PostgreSQL的DEBUG日志无相关报错
配置信息
Traefik Helm Chart 端口配置
traefik: ports: metrics: port: 9100 expose: true exposedPort: 9100 protocol: TCP web: port: 8000 expose: true exposedPort: 80 protocol: TCP redirectTo: websecure websecure: port: 8443 expose: true exposedPort: 443 protocol: TCP tls: enabled: true options: "" certResolver: "" domains: [] traefik: port: 9000 expose: true exposedPort: 9000 protocol: TCP postgres: port: 5432 expose: true exposedPort: 5432 protocol: TCP tls: enabled: true options: "" certResolver: "" domains: [] mongodb: port: 27017 expose: true exposedPort: 27017 protocol: TCP tls: enabled: true options: "" certResolver: "" domains: []
IngressRouteTCP 配置
apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: labels: argocd.argoproj.io/instance: postgresdb name: postgres-ingressroute-tcp namespace: postgresdb spec: entryPoints: - postgres routes: - match: HostSNI(`postgres.**********`) services: - name: postgres-service port: 5432 tls: secretName: tls-secret
排查与解决步骤
1. 确认EntryPoint加载状态
检查Traefik是否正确初始化了postgres EntryPoint:
kubectl exec -n <traefik-namespace> <traefik-pod-name> -- traefik show entrypoints
确保输出中包含postgres EntryPoint,且端口配置正确。
2. 验证服务与IngressRoute的命名空间匹配
如果postgres-service与IngressRoute不在同一命名空间,需在服务配置中指定命名空间:
services: - name: postgres-service port: 5432 namespace: postgresdb # 替换为实际服务所在命名空间
3. 调整HostSNI匹配规则
部分PostgreSQL客户端(包括部分版本的PGAdmin)默认不发送SNI信息,导致HostSNI(postgres.**********)匹配失败。可以改为匹配所有SNI请求:
routes: - match: HostSNI(`*`) services: - name: postgres-service port: 5432
或者在PGAdmin连接设置中确认已启用SNI选项(部分版本默认开启,需检查SSL配置项)。
4. 检查Traefik服务端口暴露
确认Traefik的Service已正确暴露postgres EntryPoint的5432端口:
kubectl get svc -n <traefik-namespace>
如果是LoadBalancer类型,需确认外部IP已分配,且云服务商安全组/防火墙开放了5432端口。
5. 验证TLS证书有效性
确认tls-secret在postgresdb命名空间中存在,且证书包含postgres.**********域名的SAN字段:
kubectl get secret tls-secret -n postgresdb -o yaml
可以通过解码证书内容验证域名是否匹配:
kubectl exec -n postgresdb <any-pod> -- bash -c 'echo "$(kubectl get secret tls-secret -n postgresdb -o jsonpath='{.data.tls\.crt}')" | base64 -d | openssl x509 -noout -text'
6. 检查PostgreSQL监听配置
确保PostgreSQL允许来自Traefik Pod的访问,listen_addresses需设置为*:
kubectl exec -n postgresdb <postgres-pod-name> -- grep listen_addresses /var/lib/postgresql/data/postgresql.conf
如果配置为localhost,需修改为*并重启PostgreSQL。
7. 测试Traefik到PostgreSQL的连通性
在Traefik Pod中直接连接PostgreSQL服务,验证网络连通性:
kubectl exec -n <traefik-namespace> <traefik-pod-name> -- psql -h postgres-service.postgresdb.svc.cluster.local -p 5432 -U <postgres-username>
如果能成功连接,说明问题出在入口路由或客户端配置;如果连接失败,需排查Kubernetes网络策略或Pod间通信问题。
内容的提问来源于stack exchange,提问作者Rahul Kumar
相关产品推荐
相关产品推荐

