日常工作中,遇到日常工作使用的小技巧,便于生产环境进行生产debug和排障,现进行整理和梳理,便于梳理和沉淀。

  1. k8s常用技巧
    1.1 pod一启动就crash,来不及定位相关的日志,该如何debug?
    1.2 pod内部没有安装tcpdump,该如何抓包?
  2. linux常用技巧
    2.1 服务出现性能问题,怀疑到系统调用,该如何继续定位?
    2.2 ping一个域名有延迟,该如何定位哪个环节慢?
    2.3 服务器load很高,该如何定位?
    2.4 如何判断服务器磁盘io性能慢以及慢的原因?
    2.5 如何udp协议对端是否正常?

1. k8s常用技巧

1.1 pod一启动就crash,来不及定位相关的日志,该如何debug?

通常k8s的pod是由docker在启动时执行entrypoint脚本,作为启动脚本。由于各种原因,一些应用将相关的日志输出到日志文件中,而不是输出到标准输出中,因此通过docker logs(或者kubectl logs)无法获取到相关的日志。

由于各种原因,pod在启动时通过entrypoint脚本启动的应用程序启动失败,无法通过docker logs(或者kubectl logs)来定位启动失败的原因,由于pod启动失败,我们又不能通过docker exec -it(或者kubectl exec -it)到pod中,人工查看相关日志。因此这种时候似乎我们遇到了一个难题,无法找到启动失败的原因。

针对这种情况,我们可以通过人工修改docker entrypoint的方式,人工启动容器,之后通过docker exec -it的方式登陆到容器中,手动执行entrypoint脚本(或者应用的启动脚本),从而能够在容器内部找到相关的日志,进行应用启动失败的原因。

# 调整docker的entrypoint
docker run -it --entrypoint /bin/bash [dockerid]

这将覆盖 Dockerfile 中定义的入口点,使用 /bin/bash 作为容器的入口点,并启动一个新的 bash 终端。通过这种方式,能够修改docker的entrypoint,从而启动docker,后续的原因定位就可以在容器内部进行。

1.2 pod内部没有安装tcpdump,该如何抓包?

我们可能会经常遇到,一个pod需要抓包进行协助原因分析,但是对应的pod中没有安装tcpdump命令,从而无法抓包。针对这种情况,可以通过如下方式进行操作

# 登陆pod所在的机器,并获取对应的dockerid
docker ps|grep $dockername

# 获取docker对应的pid(linux只认pid)
docker inspect -f {{.State.Pid}} $dockerid

# 在linux中通过nsenter的方式,进入到对应的ns,从而获取对应ns的操作环境
nsenter -n -t $pid

# 进入到nsenter后,可以获取docker的执行ns环境,可以执行如下命令验证是否跟docker中执行环境相同,以验证是否nsenter成功
ifconfig

# 执行tcpdump抓包
tcpdump -nnn -vvv -i any host xxx and port xxx -w /data/xx.pcap

# 退出nsenter
exit

在这里插入图片描述

2. linux常用技巧

2.1 服务出现性能问题,怀疑到系统调用,该如何继续定位?

strace 命令是一个集诊断、调试、统计于一体的工具,我们可以使用 strace 对程序的系统调用和信号传递的跟踪结果来对程序进行分析,以达到解决问题或者是了解程序工作过程的目的。当然strace 与专业的调试工具比如说 gdb 之类的是没法相比的,因为它不是一个专业的调试器。

strace 的最简单的用法就是执行一个指定的命令,在指定的命令结束之后它也就退出了。在命令执行的过程中,strace 会记录和解析命令进程的所有系统调用以及这个进程所接收到的所有的信号值。

  1. 通过strace统计执行的进程的输出结果,并记录在日志文件中
# 重新执行命令
strace -o strace.out [命令]

# 针对一个现有的pid
strace -p pid  -o strace.out

# 分析strace.out
vim strace.out

在这里插入图片描述

  1. 统计分析各个阶段的耗时
# 重新执行命令
strace -c [命令]

# 针对一个现有的pid
strace -p pid  -c

在这里插入图片描述

更多可以参考Linux 命令(137)—— strace 命令

2.2 ping一个域名有延迟,该如何定位哪个环节慢?

可以通过traceroute,跟踪整个链路环节

traceroute ip/域名

在这里插入图片描述

2.3 服务器load很高,该如何定位?

服务器的负载高,按照负载高的计算公式,负载高主要来自

  • 大量R进程(代表进程活跃,但是应用程序进程、线程过多,这是正常的应用调用)
  • 大量D进程(代表进程发起了io请求,但是硬件io响应还没有完成,处于不可中断的进程,可以排查磁盘的io性能或者是否应用程序的问题)
  • 僵尸进程
    具体可以参考Linux服务器节点性能问题排查和优化思路

2.4 如何判断服务器磁盘io性能慢以及慢的原因?

通常判断磁盘io性能慢,是通过配合await和磁盘的读写带宽(或者iops)配合查看。具体可以参考Linux磁盘性能方法以及磁盘io性能分析

2.5 如何udp协议对端是否正常?

客户端执行nc命令, 探测ip的udp53端口

yum install -y nc
nc  -vzu ip 53

需要注意的是
通过nc命令探测udp协议成功,并不能代表对端一定正常
如果探测对端失败,就一定失败。

原因如下
在这里插入图片描述

tcpdump -i any 'host ip and ((udp and port 53) or (udp and port 54) or icmp)' -nnX

在这里插入图片描述
前20个字节(红框)是IP协议头, 紧跟着8个字节(蓝框)是UDP协议头, 绿色箭头所指的00是nc发过来的内容, 后边的00是协议栈补位的内容.

可以得知,nc探测udp端口, 就是发送一个0x00的udp包.

客户端执行nc命令, 向服务端发送udp包, 提示连接被拒绝
在这里插入图片描述
服务端抓包显示, 服务端向客户端发送 type3 code3 的 icmp包, 意为目标不可达.

在这里插入图片描述
客户端nc就是通过对端返回的icmp回包, 判断对端没有这个udp端口.

如果对端不返回icmp包, 那么nc就会误判.

比如在服务端设置iptables规则, 屏蔽icmp包:
在这里插入图片描述
那么nc收不到icmp回包, 就会认为udp端口探测成功了.
在这里插入图片描述

使用nc探测一个不存在的ip, 因为没收到icmp回包, 所以nc同样会认为探测成功了.

在这里插入图片描述
总结下来nc客户端在如下情况下会判断成功

  • 对端不回包(如机器不存在、端口收到包后不返回)
  • 对端正确回包

因此

  • 如果通过nc测试udp,就算返回success,也不能代表对端正常。
  • 但是如果不返回,则代表对端一定不正常。

3. 参考文档

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐