
记录k8s使用nfs持久化服务日志,服务挂掉后pod变成僵尸进程问题
生产服务的集群的服务pod状态变成图片内状态,describe查看显示下图
发现端口健康检查已经500,说明内部服务已经挂了,使用exec命令也进入不了容器,查看服务日志是突然截止,没有关闭方面的日志,deploy的状态是2/3,k8s没有生成新的pod来代替他
delete指定pod后一直维持Timestamp,过了600秒默认值后也不会自己删除
进入节点查看kubelet的日志,一直在重复输出
告诉我们 Kubernetes 向 Container Runtime (containerd) 发送 StopContainer 命令失败,超时未能完成。
Kubernetes 允许这个容器有 600 秒的 gracePeriod(优雅终止时间)来退出,但这个时间过去了,容器仍然没有退出。
Kubernetes 尝试强制 kill 容器失败,意味着即使到了 gracePeriod 时间,Kubernetes 仍然无法杀死容器。
在节点用ps aux|grep java发现已经是僵尸进程了
6842 Zl [java] <defunct>
查看/proc/6830/stack
cat /proc/6830/stack
[<0>] do_wait+0x1c1/0x220
[<0>] kernel_wait4+0xa6/0x140
[<0>] zap_pid_ns_processes+0x113/0x1c0
[<0>] forget_original_parent+0x2cd/0x360
[<0>] exit_notify+0x47/0x220
[<0>] do_exit+0x24d/0x3a0
[<0>] do_group_exit+0x33/0xa0
[<0>] get_signal+0x160/0x5c0
[<0>] arch_do_signal_or_restart+0xec/0x1d0
[<0>] exit_to_user_mode_loop+0xb3/0x120
[<0>] exit_to_user_mode_prepare+0x6e/0x80
[<0>] syscall_exit_to_user_mode+0x22/0x150
[<0>] entry_SYSCALL_64_after_hwframe+0x62/0xc7
从 cat /proc/6830/stack 的输出来看,sh 进程 (PID: 6830) 正在 do_wait,这意味着它在 等待一个子进程(java,PID: 6842)退出。但 java 进程已经变成 僵尸进程 (Z),而 sh 没有正确回收它,导致 sh 进程自己也被卡住了。 查看dmesg
dmesg | tail -50
[27710983.505577] nfs_updatepage+0x255/0x400 [nfs]
[27710983.509167] nfs_write_end+0x1c5/0x490 [nfs]
[27710983.512712] generic_perform_write+0x10c/0x1d0
[27710983.516340] nfs_file_write+0x12b/0x2a0 [nfs]
[27710983.519991] new_sync_write+0x11c/0x1b0
[27710983.523410] vfs_write+0x1c9/0x260
[27710983.526593] ksys_write+0x5f/0xe0
[27710983.529780] do_syscall_64+0x33/0x40
[27710983.533020] entry_SYSCALL_64_after_hwframe+0x62/0xc7
[27710983.536864] RIP: 0033:0x7f72f19e5f26
[27710983.540113] RSP: 002b:00007f72b7c21228 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[27710983.546483] RAX: ffffffffffffffda RBX: 00007f72b7c24ae8 RCX: 00007f72f19e5f26
[27710983.552737] RDX: 00000000000011e6 RSI: 00007f72b7c212d0 RDI: 00000000000000b9
[27710983.558997] RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
[27710983.565337] R10: 0000000000000000 R11: 0000000000000246 R12: 00007f72b7c212d0
[27710983.571646] R13: 00000000000000b9 R14: 00000000000011e6 R15: 00000000000011e6
[27711104.266541] INFO: task java:5221 blocked for more than 1208 seconds.
[27711104.271083] Not tainted 5.10.201-191.748.amzn2.x86_64 #1
[27711104.275426] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[27711104.282175] task:java state:D stack: 0 pid: 5221 ppid: 6830 flags:0x00004080
看到了nfs相关报错,java 进程(PID 5221)被 NFS I/O 卡住 了,导致它进入 不可中断等待 (D 状态, disk sleep),所以 sh 进程(PID 6830)也在等待它,最终导致 kill -9都不能杀死进程 如果没有在k8s内对这个pod进行--force删除,可以手动取消nfs的挂载解决问题
mount |grep nfs
umount -f /var/lib/kubelet/pods/baf50f4e-a3fd-466d-a9e9-90c7427b0d77/volumes/kubernetes.io~nfs/pvc-ea353d50-7c69-4f54-879f-86395aa2efb9
执行完命令后k8s里面的Timestamp容器就会消失了
有一个大坑,千万不要--force来删除容器,强制删除后容器在k8s内查询不到,但是在节点一直存在,并且还是running状态,kubelet会持续重复输出日志,一个月大概产生30G的日志,而且没有办法找到删除这个进程的方法,只能重启服务器