【集群】K8S集群搭建记录——故障排除:K8S 下 Calico 网络配置错误

【集群】K8S集群搭建记录——故障排除:K8S 下 Calico 网络配置错误

Fre5h1nd Lv5

🐛 背景: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 描述并询问后,我获得了以下建议:

请尝试以下方法来解决这个问题:

  1. 确保您的应用程序使用正确的服务名称。在您的代码中,您应该使用 postgres-service 作为主机名来访问 PostgreSQL 服务。如果您的应用程序和 PostgreSQL 服务位于同一个命名空间中,您可以直接使用 postgres-service。如果它们位于不同的命名空间中,您需要使用完整的服务名称,例如 postgres-service.<namespace>.svc.cluster.local

  2. 检查您的 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 配置并修复它。

  3. 如果上述方法都无法解决问题,您可以尝试使用 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
2
3
4
5
NAME                                       READY   STATUS    RESTARTS   AGE
calico-kube-controllers-7f6768fdfb-gfhvb 1/1 Running 4 76d
calico-node-6llk9 0/1 Running 0 76d
calico-node-rtgpz 1/1 Running 0 76d
...

4️⃣ 检查 Calico 配置

  • 我开始检查 Calico 的配置,通过执行kubectl describe pod xxkubectl logs xx查看日志,但没有找到直接的错误提示。受到日志信息误导,在过程中还调整了各种 calico 参数,例如尝试开启 vxlan 模式和 ipip 模式[1],安装 calicoctl 工具[2],以及将报错等级调整为 debug[3],虽然这让我对 calico 有了更多了解,但也花了我大把时间。

  • 当时看到的 bug 信息有以下三条:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    1. 
    (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网络插件

[2] kubernetes 中 calico 组件的 calicoctl 工具的使用示例及 BGP 相关配置

[3] 解决 calico-node 无法启动问题

[4] k8s 使用 calico 作为 CNI ,calico-node 启动失败

  • 标题: 【集群】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 进行许可。
评论