繁体   English   中英

Exec 不替换 Docker 入口点脚本中的 bash shell

[英]Exec not replacing bash shell in Docker entrypoint script

我正在尝试从 Docker 容器运行 UWSGI 服务器。 我已经成功了,但我遇到了一个问题,因为在容器启动后,我的入口点脚本仍将以 root 身份运行,PID 为 1,而我宁愿将初始/bin/bash进程替换为 UWSGI 进程:

bash-4.4# ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 {docker-entrypoi} /bin/bash /usr/local/bin/docker-entrypoint.sh
   19 myuser    0:00 uwsgi --ini /opt/mysite/uwsgi.ini
   21 myuser    0:00 uwsgi --ini /opt/mysite/uwsgi.ini
   22 myuser    0:00 uwsgi --ini /opt/mysite/uwsgi.ini
   24 myuser    0:02 python3 ./manage.py qcluster
   28 myuser    0:00 python3 ./manage.py qcluster
   29 myuser    0:00 python3 ./manage.py qcluster
   30 myuser    0:00 python3 ./manage.py qcluster
   31 myuser    0:00 python3 ./manage.py qcluster
   32 myuser    0:00 python3 ./manage.py qcluster
   33 myuser    0:00 python3 ./manage.py qcluster
   34 myuser    0:00 python3 ./manage.py qcluster

我已经尝试了execsu-exec一些变体,但我仍然遇到了上述问题。 我需要在启动时向 UWSGI 提供我的 PEM 密码,所以我一直在使用这样的语法:

echo $PEM_PASSPHRASE | exec uwsgi --ini /opt/mysite/uwsgi.ini

这可以很好地启动和运行,但我仍然让 PID 1 /bin/bash进程运行,UWSGI 进程作为下面的子进程。 我觉得我错过了一些明显的细节,无法通过exec将 bash 进程替换为 UWSGI 进程。

对于它的价值,我只在 Dockerfile 中使用 ENTRYPOINT,而不是 CMD:

ENTRYPOINT ["docker-entrypoint.sh"]

任何指向正确方向的指针将不胜感激。

管道中的 Shell 命令——包括exec在子 shell 中运行。 因此, echo ... | exec uwsgi ... echo ... | exec uwsgi ...创建两个子进程,一个运行echo (实际上可能是一个运行 shell 内置的子shell),另一个子shell 会立即用uwsgi替换自己。

我还没有在 docker 中测试过这个,但以下任一方法都应该有效:

exec uwsgi --ini /opt/mysite/uwsgi.ini <<<"$PEM_PASSPHRASE"
exec uwsgi --ini /opt/mysite/uwsgi.ini < <(echo "$PEM_PASSPHRASE")

写完这篇之后,我突然想到在 bash v4.3 及更高版本中,它实际上更容易,因为lastpipe shell 选项将告诉 bash 在当前 shell 中运行管道的最后一个元素,而不是在子 shell 中:

shopt -s lastpipe
echo "$PEM_PASSPHRASE" | exec uwsgi --ini /opt/mysite/uwsgi.ini

但是,由于这是我们正在讨论的密码,因此存在关于这些密码如何公开的安全考虑。 第一个选项(“here-string”)创建一个临时文件(在磁盘上!)存储密码,打开它输入,然后立即取消链接。 这意味着它在任何普通文件路径下都无法访问,但它会无限期地存储在磁盘上(并且不会被安全删除)。 可以物理访问计算机的人(或在某些系统上,可直接通过 /proc 读取)。 所以不太好。

(here-document 会做同样的事情。)

第二个(从“进程替换”重定向)和第三个( lastpipe )可能更好......或更糟。 在 bash 中, echo是一个内置函数,因此进程替换( <( )部分)会创建一个运行echo内置函数的子外壳程序)到管道中……然后退出。 哪个更好。 但是在没有内置echo shell 中,它将运行一个单独的echo进程,并且它的参数列表(即密码)实际上是公共信息(例如,通过ps命令)。 这可能更糟。

所以我的建议是使用第二个或第三个,并确保你在 bash 下运行它。

你的那个命令应该被放置为ENTRYPOINT ,因为它的命令将是第一个进程。 (我假设您是从docker-entrypoint.sh内部调用它的)

ENTRYPOINT ["echo $PEM_PASSPHRASE | exec uwsgi --ini /opt/mysite/uwsgi.ini"]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM