【问题标题】:How to use --init parameter in docker run如何在 docker run 中使用 --init 参数
【发布时间】:2017-08-24 15:03:36
【问题描述】:

docker run--init--init-path选项,但不清楚如何使用。

起初,我认为它类似于 dumb-init,但包含在 docker 核心中(有点“原生”)。但是--init 键也需要设置--init-path,指向docker-init 二进制文件,并且不知道将其放在哪里。谷歌对docker-init保持沉默。

好的,也许我应该使用yelp/dumb-init 或“phusion/baseimage-docker”,但这些解决方案似乎没有使用docker run--init 选项。

所以,我很好奇我应该在哪里使用这个“docker-init 二进制文件”来将--init-path 设置为?

【问题讨论】:

标签: docker


【解决方案1】:

在运行命令中指定新的 docker --init 选项基本上会将 ENTRYPOINT 设置为 tini 并将 CMD 传递给它或您在命令行中指定的任何内容。

例如,没有 init,CMD 变为 pid 1。在这种情况下,/bin/bash

docker run -ti --rm ubuntu:16.04 /bin/bash
root@d740f7360840:/# ps -fA
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  1 03:30 ?        00:00:00 /bin/bash
root        11     1  0 03:30 ?        00:00:00 ps -fA

使用--init,tini (/dev/init) 变为 pid 1

docker run -ti --init --rm ubuntu:16.04 /bin/bash
root@5b5fe6ee71b5:/# ps -fA
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  1 03:30 ?        00:00:00 /dev/init -- /bin/bash
root         7     1  0 03:30 ?        00:00:00 /bin/bash
root        12     7  0 03:30 ?        00:00:00 ps -fA

tini 是一个可以作为 pid 1 正确运行的一流的 init 进程。 pid 1 进程必须正确地获取分叉的子进程,否则会发生诸如资源泄漏和僵尸出现等坏事。

对于那些 fork 并且没有考虑到孩子收获的应用程序,这就是您想要的,因为通常他们会将这留给 init 系统。一个经典的例子是 java Jenkins 应用程序。

【讨论】:

  • 这里非常好!我也建议大家看看this关于tini的帖子
  • 所以我有一个安装了 python 应用程序的图像,它有多个命令和进程要运行,webserver,monitor,worker…我做了一个入口点脚本,它为每个脚本做了一些设置,所以我可以运行图像的 3 个版本,并且仅将 webserver、monitor 或 worker 作为命令传递。入口点处理与其他网络服务器不同的一点初始化。如果一个 gunicorn 工人死了,我确实会得到一些僵尸进程;我一直想知道是否可以输入--init 并保持入口点和命令不变。
  • @dlamblin 这似乎是可能的;在此处查看 Tini 的文档:github.com/krallin/tini#existing-entrypoint
  • @dlamblin 查看 PR 的 --init 功能 (github.com/moby/moby/pull/26061/…),实现的作用(在 oci_linux.go 模块的 populateCommonSpecs 过程中)是:为任何程序和参数添加前缀将使用“/dev/init”执行,它绑定安装到 Tini 的二进制文件。我的猜测是元数据没有受到影响,因为这个 populateCommonSpecs 命令的目的似乎是初始化容器的基本文件系统。
  • 我在这个答案中发现误导的一件事是,使用 --init 实际上并没有在容器元数据中设置入口点(即,如果 Dockerfile 中没有入口点,而您使用 @987654329 @,docker inspect 中的入口点字段仍将为空)。它所做的是将密钥HostConfig.Init 设置为true。 docker-init 二进制文件(使用 init-path 指定)在容器中绑定安装为/dev/init。设置该键后,/dev/init 将附加到用户的命令参数中。在 docker 18.06 上测试。
【解决方案2】:

我在documentation找到了这个:

您可以使用 --init 标志来指示一个 init 进程应该是 用作容器中的 PID 1。指定一个初始化进程确保 初始化系统的通常职责,例如收割僵尸 进程,在创建的容器内执行。默认 使用的 init 进程是在 Docker 守护进程的系统路径。这个 docker-init 二进制文件, 包含在默认安装中,由 tini.

我在 macOS Docker 安装上找不到 docker-init,但在 Linux 上它就在这里:

/usr/bin/docker-init

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2018-11-21
    • 2019-11-20
    • 2018-10-25
    • 1970-01-01
    • 2017-09-26
    • 2017-11-14
    相关资源
    最近更新 更多