【集群】K8S集群搭建记录——故障排除:K8S 下 Calico 网络配置错误
🐛 背景:Java 应用无法连接到 Postgresql 容器
在使用 Kubernetes 部署服务的过程中,我遇到了一个令人头疼的问题:我的 Java 应用无法连接到 Postgresql 容器。我决定展开一系列的 bug 查询和修复,寻找并解决问题的根源。
🚀 过程
1️⃣ 发现 Java 应用无法连接
- 一开始,Java 应用报错并显示无法连接到以数据库服务名
postgres-service
为地址的 Kubernetes Service,因为应用所在的 Pod 无法与数据库建立连接,导致了 Pod 的无限重启。 - 通过使用
kubectl logs <app-pod-name>
,我看到了以下报错:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20...
Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:272)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:215)
at org.postgresql.Driver.makeConnection(Driver.java:404)
at org.postgresql.Driver.connect(Driver.java:272)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:95)
at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:101)
at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:341)
at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:506)
... 115 common frames omitted
Caused by: java.net.UnknownHostException: postgres-service
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.postgresql.core.PGStream.<init>(PGStream.java:61)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:144)
... 123 common frames omitted
...
2️⃣ 检查 DNS 解析问题
- 将情况向 GPT 描述并询问后,我获得了以下建议:
请尝试以下方法来解决这个问题:
确保您的应用程序使用正确的服务名称。在您的代码中,您应该使用
postgres-service
作为主机名来访问 PostgreSQL 服务。如果您的应用程序和 PostgreSQL 服务位于同一个命名空间中,您可以直接使用postgres-service
。如果它们位于不同的命名空间中,您需要使用完整的服务名称,例如postgres-service.<namespace>.svc.cluster.local
。检查您的 Kubernetes 集群的 DNS 配置。您可以在应用程序的 Pod 中运行以下命令来检查 DNS 解析是否正常:
1 $ kubectl exec -it <your-app-pod-name> -- nslookup postgres-service如果 DNS 解析正常,您应该能看到类似以下的输出:
1
2
3
4
5 Server: 10.96.0.10
Address: 10.96.0.10#53
Name: postgres-service.default.svc.cluster.local
Address: 10.102.181.13如果您看到类似
server can't find postgres-service: NXDOMAIN
的错误,那么可能是您的 Kubernetes 集群的 DNS 配置有问题。您需要检查您的集群 DNS 配置并修复它。如果上述方法都无法解决问题,您可以尝试使用 PostgreSQL 服务的 ClusterIP 或者 NodePort 来访问它。您可以通过以下命令获取 ClusterIP 和 NodePort:
1 $ kubectl get svc postgres-service -o jsonpath='{.spec.clusterIP}{"\n"}{.spec.ports[0].nodePort}{"\n"}'然后在您的应用程序中使用这个 ClusterIP 或者 NodePort 作为主机名和端口号来访问 PostgreSQL 服务。
- 不得不说,GPT 的建议非常有用,在修复本文所提到的 bug 前,我就是使用第三条建议完成的临时修复
- 根据 GPT 的建议,我首先验证了应用所在的 Pod 是否能够正常进行 DNS 解析。通过运行相关命令,我发现 DNS 解析确实存在问题。
3️⃣ 定位问题到 Kubernetes 网络组件
- 进一步通过
kubectl get pods -n kube-system
查看 Kubernetes 系统组件的 Pod,我发现其中一个 calico-node Pod 的状态不是 READY。这提示了问题可能出现在 Kubernetes 网络组件上。
1 | NAME READY STATUS RESTARTS AGE |
4️⃣ 检查 Calico 配置
我开始检查 Calico 的配置,通过执行
kubectl describe pod xx
和kubectl logs xx
查看日志,但没有找到直接的错误提示。受到日志信息误导,在过程中还调整了各种 calico 参数,例如尝试开启 vxlan 模式和 ipip 模式[1],安装 calicoctl 工具[2],以及将报错等级调整为 debug[3],虽然这让我对 calico 有了更多了解,但也花了我大把时间。当时看到的 bug 信息有以下三条:
1
2
3
4
5
6
7
8
9
101.
(combined from similar events): Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with x. Number of node(s) with BGP peering established = 0
2.
Failed to query VXLAN device error=Link not found
3.
Failed to cleanup preexisting XDP state error=failed to load BPF program (/tmp/felix-bpf-270596970): stat /sys/fs/bpf/calico/xdp/prefilter_v1_calico_tmp_A: no such file or directory
libbpf: failed to get EHDR from /tmp/felix-bpf-270596970
Error: failed to open object file顺便总结一下,想修改 calico 配置通常在两处,一是configMap,二是 daemonSet,也可以通过
find
查找相关文件,修改方法分别如下:1
2
3
4
5
6# configMap
$ kubectl edit configmap calico-config -n kube-system
# daemonSet
$ kubectl edit daemonset calico-node -n kube-system
# find
$ find / -name "*calico-node.cfg"
5️⃣ 发现 IP 配置问题
最终,我发现了问题所在。我注意到在 master 节点的配置中,IP 地址被错误地设置为 “172.18.0.1”,这导致其他节点无法与 master 节点建立连接。
1
2
3
4
5
6
7
8
9
10
11
12
13$ calicoctl node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.60.150.28 | node-to-node mesh | up | 14:36:17 | Established |
| 172.18.0.1 | node-to-node mesh | start | 15:29:38 | Passive |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.经过进一步排查和调研,发现当 IP 属性被设置为 “autodetect” 时,默认的 “first-found” 算法会导致错误[4]。
1
2
3
4
5
6
7
8
9
10
11
12$ kubectl edit daemonset calico-node -n kube-system
...
spec:
template:
spec:
containers:
- env:
- name: IP
value: autodetect
- name: IP_AUTODETECTION_METHOD # 新增
value: can-reach=114.114.114.114 # 新增
...修复完这个问题后,一切恢复了正常(真美好🤣)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14$ calicoctl node status
Calico process is running.
IPv4 BGP status
+--------------+-------------------+-------+----------+-------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+-------------------+-------+----------+-------------+
| 10.60.150.28 | node-to-node mesh | up | 14:36:17 | Established |
| 10.60.150.56 | node-to-node mesh | up | 15:33:23 | Established |
+--------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.
🤔 反思
- 今天花费了很大一部分时间在漫无头绪的检查上,缺乏系统性和逻辑性。幸好有 GPT 的帮助,我发现它是一个很好的工具,能够帮助梳理思路。类似于小黄鸭调试法,与 GPT 进行交流过程中,由于给予它的信息越详细和具体,它就越能提供有价值的指导和建议,因此会督促我不断整理和理清思路,而且 GPT 的能力也让我的思维更加开阔。
- 希望通过分享我的故障排除经历,可以帮助你在类似的问题上更加迅速和高效地解决困扰你的 bug。
- 希望这篇博客对你有帮助!如果你有任何问题或需要进一步的帮助,请随时提问。
- 如果你喜欢这篇文章,欢迎动动小手 给我一个follow或star。
🗺参考文献
[1] 第二篇:kubernetes部署calico网络插件
- 标题: 【集群】K8S集群搭建记录——故障排除:K8S 下 Calico 网络配置错误
- 作者: Fre5h1nd
- 创建于 : 2023-06-05 23:01:26
- 更新于 : 2024-03-08 15:36:39
- 链接: https://freshwlnd.github.io/2023/06/05/k8s/k8s-debug/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。