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

相关系列文章