Skip to content

Latest commit

 

History

History
111 lines (89 loc) · 5.16 KB

File metadata and controls

111 lines (89 loc) · 5.16 KB

部署后 calico-kube-controllers 日志报错 dial tcp 10.96.0.1:443: i/o timeout

该案例是一名微信好友找到我,写出来时让读者以排查角度来加深 K8S 组件作用印象。

排查

日志

部署完成后,发现 calico-kube-controllers 日志报错:

$ kubectl -n calico-system get pod
NAME                                            REDAY STATUS   RESTARTS     AGE
calico-kube-controllers-596576f79-j2pkgRunning  0/1   Running  3 (32s ago)  13m
calico-node-gqz7n                               1/1   Running  0            34m
calico-node-tg9gr                               1/1   Running  0            34m
calico-node-tg9gr                               1/1   Running  0            34m
calico-typha-b8cccb6bb-nr4m5                    1/1   Running  0            48m
calico-typha-b8cccb6bb-v9db21                   1/1   Running  0            48m
csi-node-driver-6wkcb                           2/2   Running  0            13m
csi-node-driver-gdc67                           2/2   Running  0            13m
csi-node-driver-kb896                           2/2   Running  0            13m
$ kubectl logs calico-kube-controllers-596576f7
2024-06-12 05:53:08.531 [INF0][1] main.go 107: Loaded configuratiocyWorkers:1, NodeWorkers:1, Kubeconfig:"", DatastoreType:"kubernetes"}
...
2024-06-12 05:53:38.561 [ERROR][1] client.go 295: Error getting cluster information config ClusterInformations="default" error=Get "https://10.96.0.1:443/apis/crd.projectcalico.org/v1/clusterinformations/default": dial tcp 10.96.0.1:443: io timeout
2024-06-12 05:53:38.561 [INF0][1] main.go 138: Failed to initializal datastore error=Get "https://10.96.0.1:443/apis/crd.projectcalico.org/v1/clusterinformations.default": dial tcp 10.96.0.1:443: i/o timeout

排查过程

确认系统防火墙关了,然后 kube-proxy 也部署了,问题根因是 kuberentes Service https://10.96.0.1:443 不通,让在每台机器上直接 curl 来看看 Service 工作否:

$ curl -vk https://10.96.0.1
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

有 http 内容返回,说明节点上 Service 的 DNAT 是正常没问题的,问题是 Pod 内访问不了 Service,也就是 DNAT 后的流量有问题 PodIP -> kube-apiserver:6443 不通,所以故障节点上直接绕过 Service 看下:

# 192.168.21.11 是一个 master 节点
$ tcpdump -nn -i any host 192.168.21.11
# 开启抓包后,进入容器的 network namespace 里 curl 
$ crictl inspect 或者 docker inspect xx 获取 calico-kube-controllers /pause 容器的 Pid
$ nsenter --net --target <pid> curl -k https://192.168.21.11.6443

然后抓包显示
....
16:40:19.165180 calia9589d79281 In IP 192.168.236.10.59894 > 192.168.21.11.6443: Flags ...
16:40:19.165190 ens192 Out IP 192.168.236.10.59894 > 192.168.21.11.6443: Flags ...
16:40:23.357175 calia9589d79281 In IP 192.168.236.10.59894 > 192.168.21.11.6443: Flags ...
16:40:23.357195 ens192 In IP 192.168.236.10.59894 > 192.168.21.11.6443: Flags ...

从抓包看就是节点上没做 SNAT,包到 master 机器上后,目标 master 机器上回包走默认路由到网关,网关发出去,最后没回来。就让他看 nat 表的 MASQUERADE:

# 他发的截图,这里我只手打下关键信息并折叠方便阅读
$ iptables -w -t nat -S | grep MASQ
...
-A cali-POSTROUTING -o tunl0 -m comment --comment "cali:SXwvdsbh4Mw7wOln" \
   -m addrtype !--src-type LOcAL --limit-iface-out -m addrtype LOCAL -j MASQUERADE --randomm-fully
-A cali-nat-outgoing -m comment --comment "cali:flqWnvo8yg4ULQLam" -m set --match-set cali40masg-ipam-pools src \
  -m set ! --match-set cali40all-ipam-pools dst -j MASQUERADE --randomm-fully

从 iptables 规则看,calico 使用 ipset 匹配(因为可以多个 IPPool 地址池而不增加 iptables 规则)来做 SNAT 判断条件的,查看下这俩 ipset:

$ ipset list cali40masg-ipam-pools
Name: cali40masq-ipam-pools
Type: hash: net
Revision: 7
Header: family inet hashsize 1024 maxelem 1048576 bucketsize 12 initval 0x793b8a70
size in memory: 504
References: 1
Number of entries: 1
Members:
192.168.0.0/16

$ ipset list cali40all-ipam-pools
Name: cali40all-ipam-pools
Type: hash:net
Revision:7
Header: family inet hashsize 1024 maxelem 1048576 bucketsize 12 initval 0xaa98b84c
size in memory: 504
References: 1
Number of entries: 1Members:
192.168.0.0/16

上面 iptables 配合 ipset 字面意思就是:来源IP 192.168.0.0/16 访问 目标 IP 不是 192.168.0.0/16 的才做 SNAT,而目标 IP master 的 192.168.21.11 匹配到了所以没做 SNAT。

让他 /pause 网络里去 curl -I https://223.5.5.5 看看是不是通的,回答是通的,因为没匹配上面规则而做了 SNAT 而正常。

这里根因就是他把 calico 的 ippool 和宿主机重合了,宿主机网段是 192.168.21.0/24,calico 默认网段是 192.168.0.0/16。让他把 kubectl edit ippool default-ipv4-ippool 修改 cidr 后删下 Pod 就正常了。

链接