- 背景
- 解决方案
当使用Kubernetes 时,最终会发现自己的 pod 处于CrashLoopBackoff 中,并且对正在发生的事情感到头疼。
要做的就是为失败的容器获取一个 shell,这样就可以对失败的原因进行故障排除,但没有容器可以连接!
在很多情况下,这非常有用,比如一个java应用,当java -jar没有启动起来,而且你还没有在pod logs当中获取任何日志,排查的思路就是让这个pod持续运行,这样好让我们进去此pod,将这个jar包运行起来,或者拿到外部带java的环境下运行,找出日志的关键所在!
另外当我们自己编写自定义的应用时,通常会挂载一些文件到容器的目录当中,一些意外情况可能会排查是不是容器的文件正常挂载,这都会用到!
解决方案首先要做的是更改您的 pod 命令规范并将其设置为无限循环。
正如 Kubernetes在 Shell 文档中运行命令中所述,可以覆盖docker用于运行容器的命令。编辑定义 pod 的工作负载,例如部署或副本集:
$ kubectl edit deploy mydeployment -n mynamespace
查找 pod 容器的定义位置,例如,如果有一个名为的启动脚本**「bootstrap.sh」**:
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
command: bootstrap.sh
如果规范没有定义命令,也可以添加一个,它将覆盖镜像中定义的默认值。现在用一个将容器设置为无限循环的命令替换它:
spec:
containers:
- name: nginx
image: nginx:1.14.2
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
请注意,args是一个数组,因此当保存并重新加载时,它将被扩展为:
spec:
containers:
- name: nginx
image: nginx:1.14.2
command:
- /bin/sh
args:
- -c
- while true; do echo hello; sleep 60;done
还可以添加环境变量:
spec:
containers:
- name: nginx
image: nginx:1.14.2
command:
- /bin/sh
args:
- -c
- while true; do echo hello; sleep 60;done
env:
- name: MYAPP_DEBUG
value: "true"
现在保存资源定义,你的 pod 应该进入运行状态。
运行后,现在可以获取正在运行的容器的shell:
$ kubectl exec -it mydeployment-65gvm -n mynamespace -- sh
现在你在运行的容器中有一个 shell:
/ # echo $MYAPP_DEBUG true / #
参考资料:https://maurogiusti.medium.com/how-to-debug-a-kubernetes-pod-in-crashloopbackoff-45d0556fb13b



