首页 > 解决方案 > 在 systemd 服务文件中访问 docker 环境变量的问题

问题描述

1)我正在使用以下 cmd 运行 docker 容器(使用 -e 选项传递一些环境变量)

$ docker run --name=xyz -d -e CONTAINER_NAME=xyz -e SSH_PORT=22 -e NWMODE=HOST -e XDG_RUNTIME_DIR=/run/user/0 --net=host -v /mnt:/mnt -v /dev:/dev -v /etc/sysconfig/network-scripts:/etc/sysconfig/network-scripts -v /:/hostroot/ -v /etc/hostname:/etc/host_hostname -v /etc/localtime:/etc/localtime -v /var/run/docker.sock:/var/run/docker.sock --privileged=true cf3681e04bfb

2)如上运行容器后,我检查容器内的环境变量NWMODE,它正确显示如下所示:

$ docker exec -it xyz bash $ env | grep NWMODE NWMODE=HOST

3) 现在,我创建了一个示例服务“b”,如下所示,它执行脚本 b.sh(我尝试访问 NWMODE):

root@ubuntu16:/etc/systemd/system# cat b.service
[Unit]
Description=testing service b

[Service]
ExecStart=/bin/bash /etc/systemd/system/b.sh

root@ubuntu16:/etc/systemd/system# cat b.sh
#!/bin/bash`
systemctl import-environment
echo "NWMODE:" $NWMODE`

4)现在如果我启动服务'b'并查看它的日志,它表明它无法访问 NWMODE 环境变量

$ systemctl start b
$ journalctl -fu b
...
systemd[1]: Started testing service b.
bash[641]: NWMODE:      //blank for $NWMODE here`

5) 现在不是在 b.sh 中使用“systemctl import-environment”,如果我遵循,那么 b.service 日志会显示 NWMODE env 变量的正确值: $ systemctl import-environment $ systemctl start b

虽然上面的第 5 步有效,但我不能这样做,因为我系统中的所有服务都将由 systemd 自动启动。在这种情况下,谁能告诉我如何访问服务文件中的环境变量(使用上面的 'docker run...' cmd 传递)(例如上面的 b.sh)。这可以通过某种方式实现systemctl import-environment还是有其他方式?

标签: dockerubuntu-16.04systemd

解决方案


systemd 取消设置所有环境变量以提供干净的环境。Afaik 旨在成为一项安全功能。

解决方法:创建文件/etc/systemd/system.conf.d/myenvironment.conf

[Manager]
DefaultEnvironment=CONTAINER_NAME=xyz NWMODE=HOST XDG_RUNTIME_DIR=/run/user/0

systemd 将设置在此文件中声明的环境变量。

您可以设置一个ENTRYPOINT脚本,在运行之前自动创建此文件systemd。例子:

RUN echo '#! /bin/bash \n\
echo "[Manager] \n\
DefaultEnvironment=$(while read -r Line; do echo -n "$Line" ; done < <(env) \n\
" >/etc/systemd/system.conf.d/myenvironment.conf \n\
exec /lib/systemd/systemd \n\
' >/usr/local/bin/setmyenv && chmod +x /usr/bin/setmyenv

ENTRYPOINT /usr/bin/setmyenv

Dockerfile您可以将其存储在外部并使用以下命令添加,而不是在其中创建脚本COPY

#! /bin/bash
echo "[Manager]
DefaultEnvironment=$(while read -r Line; do echo -n "$Line" ; done < <(env)
" >/etc/systemd/system.conf.d/myenvironment.conf
exec /lib/systemd/systemd

推荐阅读