Kubernetes中kube-system组件为何探测PostgreSQL?
我是Kubernetes新手,用Docker Desktop搭建学习环境,部署了自定义PostgreSQL实例——已经正常运行,能通过pgAdmin/DataGrip连接,启用了SSL,还修改了默认用户名(从postgres改成myPgUser)和初始数据库(从postgres改成myPgData),平时用psql -U myPgUser -d myPgData连接。
现在PostgreSQL日志里出现多条FATAL错误:
2023-04-29 08:56:57.088 GMT [6361] FATAL: no pg_hba.conf entry for host "192.168.65.4", user "postgres", database "postgres", no encryption
2023-04-29 09:33:48.919 GMT [8402] LOG: invalid length of startup packet
2023-04-29 09:33:49.588 GMT [8404] LOG: invalid length of startup packet
2023-04-29 09:33:50.357 GMT [8406] FATAL: unsupported frontend protocol 65363.19778: server supports 3.0 to 3.0
2023-04-29 09:33:50.654 GMT [8410] FATAL: no pg_hba.conf entry for host "192.168.65.4", user "postgres", database "template0", no encryption
排查后发现,192.168.65.4是kube-system命名空间下组件(如etcd、kube-apiserver)的IP。当前pg_hba.conf配置如下:
# TYPE DATABASE USER ADDRESS METHOD local all all scram-sha-256 # "local" is for Unix domain socket connections only host all all 127.0.0.1/32 scram-sha-256 # IPv4 local connections: host all all ::1/128 scram-sha-256 # IPv6 local connections: local replication all scram-sha-256 host replication all 127.0.0.1/32 scram-sha-256 host replication all ::1/128 scram-sha-256 hostssl all all 0.0.0.0/0 scram-sha-256 clientcert=verify-ca # IPv4 remote connections for authenticated users hostssl all all ::/0 scram-sha-256 clientcert=verify-ca # IPv6 remote connections for authenticated users
想请教两个问题:
- kube-system组件为什么会探测PostgreSQL?
- 如果这种探测是必需的,在不用默认postgres用户名和数据库的情况下,该怎么修改配置?
原因分析
- Docker Desktop自带的Kubernetes环境中,kube-system下的组件(比如kube-proxy、CoreDNS或集群默认的服务探测机制)可能在做端口扫描;或者你部署PostgreSQL时暴露的端口被Kubernetes的健康检查/服务发现机制误触——如果你的PostgreSQL Service用了NodePort或LoadBalancer类型,集群内组件会尝试连接端口做可用性探测,且探测时默认使用PostgreSQL的默认用户名
postgres和默认库postgres。 - 那些
invalid length of startup packet和unsupported frontend protocol错误,是因为探测工具不是标准PostgreSQL客户端,只是发送了简单TCP包,导致PostgreSQL解析失败。
解决方案
方案1:调整Kubernetes服务的探测配置(推荐)
如果是PostgreSQL Deployment的livenessProbe/readinessProbe配置问题,直接修改探测规则,适配你的自定义用户和数据库:
livenessProbe: exec: command: - psql - -U - myPgUser - -d - myPgData - -c - "SELECT 1;" initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: exec: command: - psql - -U - myPgUser - -d - myPgData - -c - "SELECT 1;" initialDelaySeconds: 5 periodSeconds: 5
- 若之前用的是
tcpSocket探测,建议换成上述exec方式的PostgreSQL客户端探测,避免非标准连接请求。
方案2:修改pg_hba.conf允许kube-system组件的连接(注意安全)
如果不想改探测配置,可以在pg_hba.conf中添加规则,允许192.168.65.4的连接,同时适配SSL要求:
- 若希望探测用SSL连接,添加:
hostssl all postgres 192.168.65.4/32 scram-sha-256 hostssl all postgres 192.168.65.4/32 scram-sha-256 - 更安全的方式是创建专用探测用户:
- 在PostgreSQL中创建用户:
CREATE USER pg_probe WITH PASSWORD 'your-probe-password'; - 授予连接权限:
GRANT CONNECT ON DATABASE myPgData TO pg_probe; - 在pg_hba.conf添加规则:
hostssl all pg_probe 192.168.65.4/32 scram-sha-256 - 最后修改Kubernetes探测配置使用这个新用户。
- 在PostgreSQL中创建用户:
方案3:限制PostgreSQL服务的访问范围
如果不需要集群内其他组件访问PostgreSQL,可以调整Service类型并添加NetworkPolicy限制:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: restrict-postgres-access spec: podSelector: matchLabels: app: postgres # 替换为你的PostgreSQL Pod标签 policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: your-app # 只允许你的业务应用Pod访问 ports: - protocol: TCP port: 5432
内容的提问来源于stack exchange,提问作者jake wong

