TL-DR
docker ps --no-trunc 和 docker inspect CONTAINER 提供了启动容器的入口点,以及传递给的命令,但这可能会错过一些部分,例如 ${ANY_VAR},因为容器环境变量未打印为已解析。
为了克服这个问题,docker inspect CONTAINER 有一个优势,因为它还允许从Config.Env 属性分别检索容器中定义的环境变量及其值。
docker ps 和docker inspect 提供有关已执行入口点及其命令的信息。通常,这是一个包装入口点脚本 (.sh),而不是由容器启动的“真实”程序。要获得这方面的信息,请通过ps 或/proc/1/cmdline 帮助请求进程信息。
1) docker ps --no-trunc
它打印所有正在运行的容器的入口点和执行的命令。
虽然它打印传递给入口点的命令(如果我们传递它),但它不显示 docker env 变量的值(例如 $FOO 或 ${FOO})。
如果我们的容器使用环境变量,可能还不够。
例如,运行一个 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
打印出来:
容器 ID 图像命令创建状态端口名称
5b064a6de6d8417... alpine:latest "sh -c 'ls $MY_VAR'" 2 分钟前 退出 (0) 2 分钟前 alpine-example
我们看到传递给入口点的命令:sh -c 'ls $MY_VAR' 但$MY_VAR 确实没有解决。
2) docker inspect CONTAINER
当我们检查 alpine-example 容器时:
docker inspect alpine-example | grep -4 Cmd
该命令也在那里,但我们仍然看不到 env 变量值:
"Cmd": [
"sh",
"-c",
"ls $MY_VAR"
],
事实上,我们无法使用这些 docker 命令看到内插变量。
虽然作为权衡,我们可以使用 docker inspect 分别显示容器的命令和环境变量:
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"。
对于 "docker-entrypoint.sh postgres" 的 PostgreSQL。
要获取更多信息,我们可以在正在运行的容器上执行
docker exec CONTAINER ps aux.
它可能会打印我们可能不感兴趣的其他进程。
为了缩小入口点启动的初始进程,我们可以这样做:
docker exec CONTAINER ps -1
我指定1,因为入口点执行的进程通常是具有1 id 的进程。
没有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}}"'