TL-DR
docker ps——no-trunc和docker inspect CONTAINER提供了用于启动容器的入口点,沿着传递给的命令,但可能会遗漏一些部分,例如${ANY_VAR},因为容器环境变量不会打印为解析。
为了克服这个问题,docker inspect CONTAINER有一个优势,因为它还允许从Config中分别检索容器中定义的env变量及其值。Env财产。
Docker ps和Docker inspect提供了关于执行的入口点及其命令的信息。通常,这是一个包装器入口点脚本(.sh),而不是由容器启动的“真正”程序。要获得这方面的信息,请使用ps或/proc/1/cmdline帮助请求进程信息。
1) docker ps -no-trunc
它打印为所有运行的容器执行的入口点和命令。
当它输出传递到入口点的命令时(如果我们传递了它),它不会显示docker env变量的值(例如$FOO或${FOO})。
如果我们的容器使用env变量,这可能还不够。
例如,运行一个alpine容器:
docker run --name alpine-example -e MY_VAR=/var alpine:latest sh -c 'ls $MY_VAR'
当使用docker -ps时,例如:
Docker ps -a——filter name=alpine-example——no-trunc
它打印:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5b064a6de6d8417... alpine:latest "sh -c 'ls $MY_VAR'" 2 minutes ago Exited (0) 2 minutes ago alpine-example
我们看到命令被传递到入口点:sh -c 'ls $MY_VAR',但是$MY_VAR确实没有被解析。
2)码头工人检查集装箱
检查以alpine为例的容器时:
docker inspect alpine-example | grep -4 Cmd
命令也在那里,但我们仍然看不到env变量值:
"Cmd": [
"sh",
"-c",
"ls $MY_VAR"
],
事实上,我们无法看到这些docker命令内插的变量。
作为权衡,我们可以在docker inspect容器中分别显示command和env变量:
docker inspect alpine-example | grep -4 -E "Cmd|Env"
打印:
"Env": [
"MY_VAR=/var",
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"sh",
"-c",
"ls $MY_VAR"
]
一个更docker的方法是使用docker inspect的——format标志,它允许指定JSON属性来呈现:
docker inspect --format '{{.Name}} {{.Config.Cmd}} {{ (.Config.Env) }}' alpine-example
输出:
/alpine-example [sh -c ls $MY_VAR] [MY_VAR=/var PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]
3)从容器本身检索已启动的进程以用于运行容器
docker执行的入口点和命令可能会有帮助,但在某些情况下,这是不够的,因为这“只是”一个包装器入口点脚本(.sh),负责启动真正的/核心进程。
例如,当我运行一个Nexus容器时,执行的命令是“sh -c ${SONATYPE_DIR}/start-nexus-repository-manager.sh”。
对于PostgreSQL,是“docker-entrypoint.sh postgres”。
为了获得更多信息,我们可以在一个正在运行的容器上执行
docker exec CONTAINER ps aux。
它可能会打印我们不感兴趣的其他进程。
为了缩小到由入口点启动的初始进程,我们可以这样做:
docker exec CONTAINER ps -1
我指定1是因为入口点执行的进程通常是id为1的进程。
如果没有ps,我们仍然可以在/proc/1/cmdline中找到信息(在大多数Linux发行版中,但不是全部)。例如:
docker exec CONTAINER cat /proc/1/cmdline | sed -e "s/\x00/ /g"; echo
如果我们可以访问启动容器的docker主机,另一个获取入口点执行的进程的完整命令的替代方法是:
:执行ps -PID,其中PID是由Docker守护进程创建的本地进程,用于运行容器,例如:
ps -$(docker container inspect --format '{{.State.Pid}}' CONTAINER)
用户友好的格式与docker ps
Docker ps -no-trunc并不总是容易阅读。
指定要打印的列并以表格格式打印可能会更好:
docker ps --no-trunc --format "table{{.Names}}\t{{.CreatedAt}}\t{{.Command}}"
创建别名可能会有帮助:
alias dps='docker ps --no-trunc --format "table{{.Names}}\t{{.CreatedAt}}\t{{.Command}}"'