Kubernetes 当pod处于crash状态的时候,容器不断重启,此时用 kubelet logs 可能出现一直捕捉不到日志。解决方法:

    kubectl previous 参数作用:If true, print the logs for the previous instance of the container in a pod if it exists.

    • 单容器pod:
    1. kubectl logs pod-name --previous
    • 多容器pod:
    1. kubectl logs pod-name --previous -c container-name
    比如:
    1. NAME READY STATUS RESTARTS AGE
    2. nginx-7d8b49557c-c2lx9 2/2 Running 5
    3. kubectl logs nginx-7d8b49557c-c2lx9 --previous
    4. Error: xxxxxxxxxxx
    kubelet会保持pod的前几个失败的容器,这个是查看的前提条件。kubelet实现previous的原理:将pod的日志存放在 /var/log/pods/podname,并且是链接文件,链接到docker的容器的日志文件,同时kubelet还会保留上一个容器,同时有一个链接文件链接到pod上一个崩溃的容器的日志文件,使用previous就是查看的这个文件 比如查看一个pod:
    1. ubuntu@~$ kubelet get pod
    2. NAME READY STATUS RESTARTS AGE
    3. busybox 1/1 Running 2394 99d
    4. nginx-deployment-6wlhd 1/1 Running 0 79d
    5. redis 1/1 Running 0 49d
    到pod所在node查看kubelet放的两个日志文件:
    1. ls /var/log/pods/default_busybox_f72ab71a-5b3b-4ecf-940d-28a5c3b30683/busybox
    2. 2393.log 2394.log
    数字的含义:2393 证明是第 2393 次重启后的日志,2394 代表是第2394次重启后的日志。 实际这两个日志文件是链接文件,指向了docker的日志文件:
    1. /busybox# stat 2393.log
    2. File: 2393.log -> /data/kubernetes/docker/containers/68a5b32c9fdb1ad011b32e6252f9cdb759f69d7850e6b7b8591cb4c2bf00bcca/68a5b32c9fdb1ad011b32e6252f9cdb759f69d7850e6b7b8591cb4c2bf00bcca-json.log
    3. Size: 173 Blocks: 8 IO Block: 4096 symbolic link
    4. Device: fc02h/64514d Inode: 529958 Links: 1
    5. Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
    6. Access: 2023-01-31 13:32:03.751514283 +0800
    7. Modify: 2023-01-31 13:32:03.039526838 +0800
    8. Change: 2023-01-31 13:32:03.039526838 +0800
    9. Birth: -
    10. /busybox# stat 2394.log
    11. File: 2394.log -> /data/kubernetes/docker/containers/2ed9ebf0585215602874b076783e12191dbb010116038b8eb4646273ebfe195c/2ed9ebf0585215602874b076783e12191dbb010116038b8eb4646273ebfe195c-json.log
    12. Size: 173 Blocks: 8 IO Block: 4096 symbolic link
    13. Device: fc02h/64514d Inode: 529955 Links: 1
    14. Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
    15. Access: 2023-01-31 14:32:03.991106950 +0800
    16. Modify: 2023-01-31 14:32:03.183119308 +0800
    17. Change: 2023-01-31 14:32:03.183119308 +0800
    18. Birth: -
    看到分别指向了这两个容器的日志文件,一个是当前pod里在跑的容器,一个是pod上次跑的容器,现在已经退出了
    1. docker ps -a
    2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    3. 2ed9ebf05852 ff4a8eb070e1 "sleep 3600" 24 minutes ago Up 24 minutes k8s_busybox_busybox_default_f72ab71a-5b3b-4ecf-940d-28a5c3b30683_2394
    4. 68a5b32c9fdb ff4a8eb070e1 "sleep 3600" About an hour ago Exited (0) 24 minutes ago k8s_busybox_busybox_default_f72ab71a-5b3b-4ecf-940d-28a5c3b30683_2393
    使用logs的时候读的是当前容器那个文件,使用 –previous 的时候,读的是上次退出的容器的日志文件,由于kubelet为pod保留了上次退出的容器。 手动编辑这两个文件的内容,看kubelet是否读的是这两个文件
    1. /busybox# cat 2393.log
    2. {"log":"last crash logs\n","stream":"stderr","time":"2022-11-05T08:11:27.31523845Z"}
    3. /busybox# cat 2394.log
    4. {"log":"now pod log\n","stream":"stderr","time":"2022-11-05T08:11:27.31523845Z"}
    5. ubuntu@10-234-32-51:~$ k logs busybox --previous
    6. last crash logs
    7. ubuntu@10-234-32-51:~$ k logs busybox
    8. now pod log
    由于是链接文件,那么可能实际是从别的地方读的,或者说直接读容器目录下的,由于链接文件改了后容器目录下的日志文件也跟着改了,直接创建两个文件来做验证:
    1. ubuntu@10-234-32-51:~$ k get pod
    2. NAME READY STATUS RESTARTS AGE
    3. busybox 1/1 Running 2395 99d
    4. nginx-deployment-6wlhd 1/1 Running 0 79d
    5. redis 1/1 Running 0 49d
    6. /busybox# ls
    7. 2394.log 2395.log
    8. /busybox# rm 2394.log 2395.log
    9. 删除然后自己创建,这时是regular file,而不是链接文件了:
    10. /busybox# ls
    11. 2394.log 2395.log
    12. /busybox# stat 2394.log
    13. File: 2394.log
    14. Size: 100 Blocks: 8 IO Block: 4096 regular file
    15. Device: fc02h/64514d Inode: 529965 Links: 1
    16. Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 0/ root)
    17. Access: 2023-01-31 15:42:11.307170422 +0800
    18. Modify: 2023-01-31 15:42:07.711225229 +0800
    19. Change: 2023-01-31 15:42:07.711225229 +0800
    20. Birth: -
    21. /busybox# stat 2395.log
    22. File: 2395.log
    23. Size: 86 Blocks: 8 IO Block: 4096 regular file
    24. Device: fc02h/64514d Inode: 529967 Links: 1
    25. Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 0/ root)
    26. Access: 2023-01-31 15:41:17.539989934 +0800
    27. Modify: 2023-01-31 15:41:14.348038586 +0800
    28. Change: 2023-01-31 15:41:14.352038525 +0800
    29. Birth: -
    30. /busybox# cat 2394.log
    31. {"log":"previous logs create by myself\n","stream":"stderr","time":"2022-11-05T08:11:27.31523845Z"}
    32. /busybox# cat 2395.log
    33. {"log":"create by myself\n","stream":"stderr","time":"2022-11-05T08:11:27.31523845Z"}
    34. ubuntu@10-234-32-51:~$ k logs busybox
    35. create by myself
    36. ubuntu@10-234-32-51:~$ k logs busybox --previous
    37. previous logs create by myself
    得出结论:kubelet读的是 /var/log/pods/ 下的日志文件,–previous 读的也是 /var/log/pods/ 下的日志文件,且专门有个链接文件来指向上一个退出容器的日志文件,以此来获取容器崩溃前的日志。