记录遇到的问题,后面会一点点补充

Kubernetes使用到的端口

服务名 备注 需要的端口
kube-scheduler 调度服务 10251 tcp
etcd 2379端口API 服务,2380端口peer 通信 2379,2380 tcp
kube-controller-manager 容器管理 10252 tcp
kube-apiserver apiserver 443 tcp 此端口随配置而变化
calico-typha 管理calico 5437 tcp
kubelet 认证API 10250 tcp
bird bgp通信 179 tcp
kube-proxy 10249:对外提供 /metrics; 10256:对外提供 /healthz 的访问。 10249,10256 tcp
calico-node 网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报 9099 tcp
vxlan vxlan协议端口 4789 udp

一, kubelet

1 查看节点状态 NotReady

1.1 PLEG is not healthy

1.1.1 查看节点信息

在使用top命令检查系统负载的时候,可以看到Load averages字段,但是这个字段并不是表示 CPU 的繁忙程度,而是度量系统整体负载。系统有很高的负载但是 CPU 使用率却很低,或者负载很低而 CPU 利用率很高,这两者没有直接关系.

  • pod 数量不算多 70 左右

  • cpu 使用率不到百分之 20

  • 内存使用率不到百分之 50

  • top 查看 load 一直持续在 200 以上

1.1.2 检测运行队列中的进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cat init.sh
#!/bin/bash
LANG=C
PATH=/sbin:/usr/sbin:/bin:/usr/bin
interval=1
length=86400
for i in $(seq 1 $(expr ${length} / ${interval}));do
date
LANG=C ps -eTo stat,pid,tid,ppid,comm --no-header | sed -e 's/^ \*//' | perl -nE 'chomp;say if (m!^\S*[RD]+\S*!)'
date
cat /proc/loadavg
echo -e "\n"
sleep ${interval}
done

发现有大量的 mount.nfs 命令处于 D 状态, 估计这是造成 load 上伤的元凶,

D 代表不可中断的睡眼进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.....
D 176108 176108 176107 mount.nfs
D 179927 179927 179926 mount.nfs
D 182432 182432 182431 mount.nfs
D 182884 182884 182883 mount.nfs
D 183495 183495 183494 mount.nfs
D 185283 185283 185282 mount.nfs
D 188423 188423 188422 mount.nfs
D 189740 189740 189739 mount.nfs
D 191333 191333 191332 mount.nfs
D 193889 193889 193888 mount.nfs
D 196476 196476 196475 mount.nfs
D 197029 197029 197028 mount.nfs
D 200640 200640 200639 mount.nfs
D 200841 200841 200840 mount.nfs
D 200992 200992 200991 mount.nfs
D 205285 205285 205282 mount.nfs
D 209356 209356 209355 mount.nfs
D 210161 210161 210160 mount.nfs
.....

1.1.3 查看前 20 使用 CPU 比较高的进程

如果发现 CPU 使用率过高使用此命令

1
ps -eT -o%cpu,pid,tid,ppid,comm | grep -v CPU | sort -n -r | head -20

1.1.4 查看前 20 使用内存比较高的进程

如果发现内存使用率过高使用此命令

1
ps -eT -o%mem,pid,tid,ppid,comm  | sort -n -r | head -20

1.1.5 查看有问题的进程

1
2
root       210161 210161  0 Aug23 ?        00:00:00 /sbin/mount.nfs 10.1.1.1:/pvc_ad704803_221b_4b54_9b27_c4dc3f8cd3b2/ /data/kubelet/pods/ebc34128-274e-4949-832f-c6c374c95899/volumes/kubernetes.io~csi/pvc-ad7
04803-221b-4b54-9b27-c4dc3f8cd3b2/mount -o rw

1.1.6 测试 nfs 地址

showmount 这个 nfs 服务地址发现直接卡死,所以导致这些进程睡眠

1
showmount 10.1.1.1

1.1.7 关闭异常进程

1
kill -9 `sh init.sh | grep ^D |awk '{print $2}'`

1.1.8 查看 load

已经恢复正常,并且查看节点状态不会出现 PLEG

1
2
uptime
15:26:01 up 65 days, 45 min, 1 user, load average: 0.17, 2.17, 51.33

2 pod 一直 ContainerCreating 状态

2.1 查看 pod 事件

1
2
kubectl get pod -A -o wide | grep 32.220
monitoring node-exporter-ltw97 0/1 Pending

注意: 只有调度到某个节点事件,后续没任何事件

1
2
3
4
5
kubectl describe pod -n monitoring
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m59s default-scheduler Successfully assigned monitoring/node-exporter-ltw97 to k8snode-2

2.2 查看节点

节点状态在这里也是好的

1
kubectl describe node k8snode-2

2.3 查看 kubelet 日志

到对应节点查询这个 pod 日志

可以看到其中有一个错误是”Error deleting pod from network”

1
2
3
4
cat kubelet.ERROR |grep node-exporter-ltw97
E1122 13:35:18.295578 275102 cni.go:380] "Error deleting pod from network" err="error getting ClusterInformation: Get https://[172.123.0.1]:443/apis/crd.projectcalico.org/v1/clusterinformat
ions/default: dial tcp 172.123.0.1:443: i/o timeout" pod="monitoring/earth-monitoring-collect-zk56k" podSandboxID={Type:docker ID:46fc59b379bd146d53540a98399dd25d7d0e09e02370c021d70060e633cb71de}
podNetnsPath="" networkType="calico" networkName="k8s-pod-network"

2.4 检测此节点 cni

这里我们用的 calico,并且可以看到 pod 异常,这是导致上面 pod 分配不了网络的直接原因

1
2
get pod -n kube-system -o wide | grep 32.220
kube-system calico-node-8c9sz 0/1 CrashLoopBackOff

2.5 查看 calico-node 日志

看到这里又有新的报错,网上搜的都是账号权限不对,我又尝试 logs 别的节点的 pod 发现没任何问题,说明跟 Role 没关系
这里说明 kubelet 连接 api 有问题

扩展下 logs 流程:

  • kubectl 发起 logs 请求到 apiserver

  • kubelet watch apiserver 发现有人要看我这个 pod 日志 (这里 kubelet 访问 api 有问题所有就看不了日志了,但是为什么报权限问题我也很迷)

  • kubelet 处理 logs 请求,实际上是将请求转发给 CRI,CRI 将会启动一个临时的 streaming server 服务,后续 apiserver 的信息获取是与 streaming server 进行交互。

1
2
kubectl logs -n kube-system      calico-node-8c9sz
Error from server (InternalError): Internal error occurred: Authorization error (user=kubernetes, verb=get, resource=nodes, subresource=proxy)

2.6 继续查看 kubelet 日志,尝试搜索 api 相关日志

可以看到这条日志解析有问题,10.1.1.1 找不到这条 dns 解析
这里说下架构,我们是一个 SLB 负载后端三台 master,然后 dns 解析这个 SLB 地址

1
2
cat kubelet.ERROR |grep api
Service: Get "https://api-k8s.test.cc:6443/api/v1/services?limit=500&resourceVersion=0": dial tcp: lookup api-k8s.test.cc on 10.1.1.1:53: no such host

2.6.1 尝试添加 hosts

1
2
3
cat /etc/hosts
...
10.251.66.185 api-k8s.test.cc

2.6.2 重启后 pod 创建正常

1
2
3
kubectl get pod -A -o wide | grep 32.220
kube-system calico-node-8c9sz 1/1 Running
monitoring node-exporter-ltw97 2/2 Running

这个问题挺不好排查,节点没 NoReady,pod 调度上去就是没任何事件,logs 会提示没权限

2.7 无报错

这种情况一般是运行好长时间,ceph 集群出问题了

2.7.1 现象

说挂载成功但是一直没下一步

1
2
3
4
5
6
7
8
9
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulAttachVolume 4s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-431074ba-ce3f-4f8d-9f71-04e958695176"
[root@1 cephrbd]# kubectl get pod
NAME READY STATUS RESTARTS AGE
rbd-pod 0/1 ContainerCreating 0 10s


2.7.2 查看 ceph 集群

我们 ceph 集群出问题了,所以会这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ceph status
cluster:
id: f801d435-d991-4b61-9a0f-7face6a1adab
health: HEALTH_WARN
1 osds down
1 host (1 osds) down

services:
mon: 3 daemons, quorum a,b,c (age 2d)
mgr: a(active, since 2d)
osd: 3 osds: 2 up (since 5s), 3 in (since 2d)

data:
pools: 2 pools, 33 pgs
objects: 7 objects, 577 KiB
usage: 66 MiB used, 600 GiB / 600 GiB avail
pgs: 25 active+clean
8 stale+active+clean

2.7.3 修复 ceph 集群后操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 进入对应节点的csi-rbdplugin容器内操作
kubectl exec -it -n kube-system csi-rbdplugin-sp6k4 -c csi-rbdplugin bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@ /]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 20K 1 loop
loop1 7:1 0 89.1M 1 loop
loop2 7:2 0 89.1M 1 loop
loop3 7:3 0 2.8M 1 loop
loop4 7:4 0 1G 0 loop
sda 8:0 0 200G 0 disk
|-sda1 8:1 0 300M 0 part
|-sda2 8:2 0 1.4G 0 part
`-sda3 8:3 0 198.3G 0 part
|-centos-root 253:0 0 192.5G 0 lvm /var/log/ceph
`-centos-swap 253:1 0 4G 0 lvm
sdb 8:16 0 500G 0 disk
`-vol_sltekdbb7ds_01-volume 253:2 0 500G 0 lvm /data/kubelet/pods
sr0 11:0 1 470K 0 rom
rbd0 252:0 0 1G 0 disk

# 当时解决问题的时候忘截图了,这节点上有n个rbd设备,卸载不在使用
rbd unmap /dev/rbd0

如果卸载不了,节点排水后重启机器

二, flannel

现象: 在新 dc 添加的 node 节点 pod 里 dns 解析不了,测试命令nslookup kubernetes.default.svc.cluster.local $coredns_svc_ip详细如下:
只有异常节点 pod 通过 svc 访问出现问题

访问方式 访问地址 访问结果
正常节点宿主机 coredns_svc yes
正常节点宿主机 coredns_pod yes
正常节点 pod 内 coredns_svc yes
正常节点 pod 内 coredns_pod yes
异常节点宿主机 coredns_svc yes
异常节点宿主机 coredns_pod yes
异常节点 pod 内 coredns_svc no
异常节点 pod 内 coredns_pod yes
1
2
3
traceroute $coredns_svc
...
这部有结果,但是转发到 docker0 网卡的时候特别慢

查询后发现Site Unreachable有一样的情况

1
sudo iptables -A OUTPUT -p udp -m udp --dport 8472 -j MARK --set-xmark 0x0

后面测试 nslookuptraceroute都恢复正常

三,calico

1 查看节点状态

因为我们集群都是双网卡,东西流量过第二块网卡

第一块网卡是 10 网段的,第二块网卡是 172 网段的

1
2
3
4
5
6
7
8
9
10
calicoctl node status
Calico process is running.

IPv4 BGP status
+--------------+---------------+-------+------------+--------------------------------+
| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |
+--------------+---------------+-------+------------+--------------------------------+
| 172.30.0.25 | node specific | start | 2023-03-14 | Connect Received: Hold timer |
| | | | | expired |
+--------------+---------------+-------+------------+--------------------------------+

2 查看异常的节点

1
2
calicoctl get node -o wide |grep 172.30.0.25
10-62-189-25.earth-restonsen-appz1p.xcloud.lenovo.com 61230 172.30.0.25/16

3 查看 calico 组件状态

发现一直为准备好

1
2
kubectl get pod -n kube-system -o wide |grep 10-62-189-25.earth-restonsen-appz1p.xcloud.lenovo.com
calico-node-lr6s5 0/1 Running 0 47m 10.62.189.25 10-62-189-25.earth-restonsenappz1p.xcloud.lenovo.com <none> <none>

4 查看 calico-node 日志

日志太多,所以过滤下 INFO 日志,但因为过滤没查到关键信息就不展示结果了

1
logs -f -n kube-system calico-node-lr6s5  |grep -v INFO

5 登录节点查看 kubelet 日志

一直获取不到对等体,后来在想,是不是网络出问题了

1
2
3
tail -n 100000 kubelet.INFO|grep calico-node-lr6s5
# 其中最关键的
[INFO][254] readiness.go 88: Number of node(s) with BGP peering established = 0

5.1 这里补充下 calico 端口

角色 服务名 需要的端口 备注
system calico-typha 5437 tcp 管理 calico
ALL bird 179 tcp 路由表
ALL calico-node 9099 tcp 网络接口管理和监听、路由、ARP 管理、ACL 管理和同步、状态上报
ALL vxlan 4789 udp vxlan 协议端口

6 尝试测试 bird 端口

从正常节点 telnet 其他节点没问题,但是故障节点网络就不通

发现故障所在,找网络看看第二块网卡为啥网不通了

这里主要,每个公司环境不同,正常访问第一块网卡 ip+端口就行

1
2
3
4
5
6
7
8
9
10
11
telnet 172.30.0.12 179
Trying 172.30.0.12...
Connected to 172.30.0.12.
Escape character is '^]'.
????????=.
@xA.EF
Connection closed by foreign host.

telnet 172.30.0.25 179
Trying 172.30.0.25...
^C

四, kube-apiserver

服务正常,能获取到 pod 信息,但是 get 返回特别慢

1 查看日志

发现一条关键信息

1
E0804 16:18:58.100247    1704 available_controller.go:524] v1beta1.metrics.k8s.io failed with: Operation cannot be fulfilled on apiservices.apiregistration.k8s.io "v1beta1.metrics.k8s.io": the object has been modified; please apply your changes to the latest version and try again

1.1 简单粗暴解决

自己环境可以这样搞

看到api 接口有问题,尝试删除v1beta1.metrics.k8s.io 快速测试

1
kubectl delete apiservice v1beta1.metrics.k8s.io

2 修复对应接口服务

这里就不展示了,因为每个服务修复方式都不一样