k8s 问题排错小技巧
1. 容器环境中没有 shell 环境
有时候我们想要查看下容器内部的一些东西,但是无奈容器没有shell 执行环境,比如想看看 coredns 容器中 /etc/resolv.conf
的内容是否正确继承了节点的配置,比较简单的操作步骤如下(以 docker 运行时为例):
登录到容器所在节点上,执行 docker ps
查找到 coredns 容器 ID,然后再使用 cp
命令把文件复制出来就可以看了:
1docker ps | grep <容器名>
2docker cp <容器ID>:/want/to/see/dir .
2. 常用排查命令
1.查看 kubelet 守护服务日志(运行时日志类似)
1# 查找相关 daemon 服务
2systemctl list-units | grep <DAEMON_SERVICE_NAME>
3
4# 显示 kubelet 滚动日志
5journalctl -u kubelet -f
6
7# 导出 kubelet 日志到文件
8journalctl -u kubelet > k.log
9
10# 查看 kubelet 2 小时之前到现在的日志
11journalctl -u kubelet --since "2 hours ago" | less
2.获取当前资源配置的 YAML
1kubectl get <RESOURCE> <POD_NAME> -n <NAMESPACE> -o yaml
2
3命令示例:
4kubectl get pod nginx-xxx -n default -o yaml
5kubectl get deploy nginx -n default -o yaml
3.查看资源当前状态描述
1kubectl describe <RESOURCE> <POD_NAME> -n <NAMESPACE>
2
3命令示例:
4kubectl describe pod nginx-xxx -n default
5kubectl describe pvc nginx -n default
4.查看容器日志
1# 动态刷新查看 Pod 中指定容器的后 20 行日志
2kubectl logs <POD_NAME> -c <CONTAINER_NAME> --tail 20 -f -n <NAMESPACE>
3
4命令示例:
5kubectl logs nginx-xxx -c nginx --tail 20 -f -n default
5.打印出资源指定的字段值(YAML结构)
1kubectl get <RESOURCE> -o custom-columns=<ALIAS_NAME_1>:<RESOURCE_KEY_1>,<ALIAS_NAME_2>:<RESOURCE_KEY_2>
2
3命令示例:
4# 分别打印资源中的 .metadata.name(别名 Name),.status.eniInfos(别名 eni) 字段值。
5kubectl get nec -ocustom-columns=Name:.metadata.name,eni:.status.eniInfos
6# 如果字段中有"."符号, 需要整体使用""扩起来再转译, 比如"tke.cloud.tencent.com/eni-ip" 写成 "tke\.cloud\.tencent\.com/eni-ip"
7kubectl get no -o=custom-columns=NAME:.metadata.name,Allocatable_eni-ip:.status.allocatable."tke\.cloud\.tencent\.com/eni-ip"
6.使用 kubectl 执行容器命令
1kubectl exec -it <POD_NAME> -c <CONTAINER_NAME> -n <NAMESPACE> -- <COMMAND>
2
3命令示例:
4kubectl exec -it nginx-xxx -c nginx -n default -- sh
5kubectl exec -it nginx-xxx -c nginx -n default -- sleep 100000
7.使用 kubectl 创建测试 Pod
1kubectl run busybox --image=busybox --overrides='{ "spec": { "nodeName": "<NODE_NAME>" } }' --command -- sleep 100000
2
3命令示例:
4# 测试 Pod 运行在指定的节点"10.0.5.3"上
5kubectl run busybox --image=busybox --overrides='{ "spec": { "nodeName": "10.0.5.3" } }' --command -- sleep 100000
8.更多 kubectl 命令用法
1kubectl 命令各种使用方法:
2kubectl --help
3. 常用抓包命令
1
2# 查看容器ID
3docker ps | grep <CONTAINER_NAME>
4
5# 查看容器进程ID
6docker inspect <CONTAINER_ID> | grep Pid
7
8# 进入进程的网络命名空间
9nsenter -t <TARGET_PID> -n
10
11# tcpdump 抓包
12tcpdump -i <INTERFACE_NAME> host <HOST> and port <PORT> -nve
13
14命令示例:
15# 查看某容器ID
16docker ps | grep xxx
17
18# OUTPUT:
19# ede761bade47 xxxx
20
21# 查看某容器进程ID
22docker inspect ede761bade4 | grep Pid
23# OUTPUT:
24# "Pid": 13062,
25# "PidMode": "",
26# "PidsLimit": null,
27
28# 使用nsenter 进入进程的网络命名空间
29nsenter -t 13062 -n
30
31# 查看在 eth0 接口 ip 为8.8.8.8,端口号为 53 的非域名显示详细包
32tcpdump -i eth0 host 8.8.8.8 and port 53 -nvve
33
34# 查看在 eth0 接口 src ip 为8.8.8.8, dst ip 为 1.1.1.1 的非域名显示详细包
35tcpdump -i eth0 src 8.8.8.8 and dst 1.1.1.1 -nvve
36
37# 使用 Wireshark 分析完整报文文件 dns.pcap
38tcpdump -i eth0 host 8.8.8.8 and port 53 -s 0 -w dns.pcap