一种 core 文件在 docker 中的挂接方法

core 文件在 docker 中的特别之处

core 文件产生的路径,是由宿主机上的 /proc/sys/kernel/core_pattern 来指定的

默认是在可执行文件所在目录

因此有几个问题:

  • 不能通过 /proc/sys/kernel/core_pattern 来修改 core 产生路径,你改了就会影响宿主机上其他容器的 core 路径
  • 不能简单 -v 挂接,直接挂接可执行文件所在目录,则容器内的程序都要被覆盖掉啦
  • core 文件在生产环境中对于程序员又特别重要
    • 同宿主机上会开很多容器,容器状态有正常、有异常,人工手动经常性的去检查是否有 core 文件,不是很现实
    • 这种情况下,获取 core 文件的自动化脚本也很难实现

解决方法

0. 原理

利用 a 、 b 变量实现交换,可以:

tmp := a
a = b
b = tmp

细节见下步骤

1. Dockerfile 文件调整
  • 工作目录下的所有内容,在 Dockerfile 中,不是 COPY 到工作目录
  • 先把所有内容 COPY 到一个临时目录,如 /tmp/work/ 下
2. 使用 docker-entrypoint.sh 来作为入口程序脚本

docker-entrypoint.sh 大致如下:

mv /tmp/work your_work_dir
exec "$@"

以上的意思是,先把临时目录下的所有内容移到工作目录下,然后开始

3. 正常挂接工作目录

通过 1 、 2 点, 这比如 docker run -v 就可以正常挂接工作目录到宿主机了

以上

该方案中的缺点

通常我们可能会给程序发信号量,来触发诸如资源热更新打开性能分析器等操作

然而 docker kill 发送信号量有个小缺陷:

细节见官方文档: https://docs.docker.com/engine/reference/commandline/kill/

文中提到:

Note: ENTRYPOINT and CMD in the shell form run as a subcommand of /bin/sh -c, which does not pass signals. This means that the executable is not the container’s PID 1 and does not receive Unix signals.

通过 docker-entrypoint.sh 并使用 exec "$@" 的方式启动程序,docker kill 的信号量会被屏蔽

该方案的附带补充

需要捕获信号量的程序,可内置 http 服务

这样就可以通过 curl 命令来触发你要的功能,如资源热更新

以上

发布了129 篇原创文章 · 获赞 73 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/u013272009/article/details/90599263
今日推荐