前言
为什么会记录这篇文章呢,是因为在工作中,遇到了这个问题,由于我们这个是 C++写的代码,crash tracing 并没有 golang 好,所以代码 crash 在 pod 中的 container 里面,很难调查。最多的也就是多加 log,但是你懂的,添加 log debug 效率还是蛮低的。所以就要用 coredump 去快速找到问题所在。但是就遇到文章的问题。你怎么去 pod 中的 container 生成 coredump 呢,然后拷到本地 gdb 呢?
在 helm chart 里面加上一个 initContainer
-
在 deployment.yaml 里面添加一个 initContainer 和 volume
```yaml volumes: - name: dumps emptyDir: {} initContainers: - name: {{ .Values.initContainers.coredumps.service.name }} image: "{{ .Values.global.registry.url }}/{{ .Values.imageCredentials.repoPath }}/{{.Values.initContainers.coredumps.images.name }}:{{ .Values.initContainers.coredumps.images.tag}}" command: ['sh', '-c', 'ulimit -c unlimited; echo "{{ .Values.initContainers.coredumps.service.dst }}/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern;'] securityContext: privileged: true ```
-
为需要生成 coredump 的 container 加上个 volumeMounts.
``` yaml volumeMounts: - name: dumps mountPath: {{ .Values.initContainers.coredumps.service.dst }} ```
-
添加下面 code 在你的 value.yaml 里面 (如何你在第一步里面是 hardcode 的话,这里可以省略)
``` yaml # here image i used suse, you can use "docker pull registry.suse.com/suse/sles12sp4" pull ito your local # and then use "docker tag xxx bbb" command to retag it(this command can omit if you usorigin tag directly) initContainers: coredumps: images: name: xxx tag: 1.xxx service: name: coredumps dst: /root/dumps ```
用 debug 模式编译代码,然后 docker build 一个 image
-
可参考下面命令生成 image
``` shell // "." means current directory docker build XXXX . ```
更新你的 image 到 deployment 里面
这里有两个方案:
-
用下面命令直接在线修改你的 deployment, k8s 通过重启 pod 动态生效。
``` shell kubectl edit deploy your_deployment_name ```
-
修改本地 deployment.yaml 文件,然后在 kubectl upgrade 更新(基于 helm install 的方式).
找到你挂载的 coredump 文件映射到本地的具体目录
-
可参考下面命令
docker ps | grep ApplicationName #to found container id . docker inspect container id | grep dump #to found dir that docker volume mapped local dir.
将生成的 coredump 文件拷贝到你本地目录
Note: 其实好像还有个 docker cp 命令可以拷贝文件,但是我没有在这个情况亲自尝试过,这是用过将本地文件 copy 到 container 里面 . 具体怎么使用,可以参考官网指导 docker cp command guidance.
copy file from/to minikube
1. minikube ssh -p master
2. sudo passwd docker // to create a new password.
3. exit from ssh
4. scp /local/path/file docker@minikubeip:/destionation/folder
抓取coredump in minikube
1. minikube ssh -p master
2. sudo -i
3. ps -axu |grep processinfo
4. ctr -n k8s.io task list |grep processId
5. ctr -n k8s.io c info $(ctr -n k8s.io taks list | grep processID | awk -F " " '{print $1}') | grep core
6. copy file to local from minikube
gdb 调试你的程序
总结
本文讲的方式是在主 container 运行之前,启动一个定制的 initContainer,目的是将 coredump 默认生成文件目录修改到自己设定的目录下。然后就可以将 coredump 文件弄出到本地,进行 debug 分析。