1

作为一个实验,我以两种方式在我的 Docker 容器中设置环境变量:使用该-e选项,以及使用environment安装/etc/environment在容器内的文件。该文件有一行:

FROM_ENV_FILE=true

我的docker run命令:

docker run -de FROM_CMD_LINE=true -v $(pwd)/environment:/etc/environment ubuntu:14.04 sleep infinity

当我运行时,docker exec b20543b507e3 cat /etc/environment我确实看到该文件已正确安装并包含我的值,但是我只FROM_CMD_LINE在运行时看到 set printenv,所以我的 /etc/environment 文件似乎被忽略了。

我的问题不仅仅是为什么 /etc/environment 在我的 ubuntu:14.04 docker 映像中不起作用?. 我正在寻找一个答案来解释 Docker 为设置进程环境所做的工作,以使通过传递-e给容器中所有正在运行的进程的自定义环境变量可用,所以我希望能理解为什么/etc/environment在容器中被忽略.

我正在使用的相关运行时详细信息粘贴在下面。

docker version

Client:
 Version:      18.03.1-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   9ee9f40
 Built:        Thu Apr 26 07:13:02 2018
 OS/Arch:      darwin/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.03.1-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   9ee9f40
  Built:        Thu Apr 26 07:22:38 2018
  OS/Arch:      linux/amd64
  Experimental: true

查看 18.03.1-ce的发行说明:

Containerd:更新到 1.0.3 版本moby/moby#36749

我正在挖掘containerd源代码,但我希望已经熟悉容器运行时的人可以帮助我。

4

1 回答 1

3

当在 Linux 中生成任何进程时(使用fork/execve系统调用),它的环境通过将带有变量的数组传递给execve. 当 Docker 启动容器(即它产生容器的根进程)时,它会聚合使用-e参数传递的所有变量,并将它们添加到必须设置到容器主进程的环境变量列表中。

然而,Docker 不知道任何关于/etc/environment的 ,它属于容器并且是其文件系统的内部,无论是否从外部安装。该文件归 Linux PAM 系统(负责身份验证)所有,用于在有人登录时为身份验证会话设置公共环境变量。su您可以通过在容器内运行来检查它:

$ docker run -v $PWD/environment:/etc/environment -it ubuntu:14.04 bash
root@4902dd72b49b:/# env | grep ENV
root@4902dd72b49b:/# su -
root@4902dd72b49b:/# env | grep ENV
FROM_ENV_FILE=true

当您运行时su,将启动身份验证会话,因此/etc/environment使用文件。

因此,您不应该尝试使用此文件来设置容器主进程的变量。这个文件有不同的用途,Docker 不知道。

于 2018-07-09T18:15:00.620 回答