【问题标题】:See full command of running/stopped container in Docker查看 Docker 中运行/停止容器的完整命令
【发布时间】:2015-02-07 10:41:17
【问题描述】:

如何在 Docker 中查看正在运行的容器/进程的完整命令?

$ docker ps --all
CONTAINER ID    IMAGE          COMMAND                 CREATED          STATUS                     PORTS    NAMES
5b6291859b61    nginx:1.7.8    "nginx -g 'daemon of    4 minutes ago    Exited (0) 4 minutes ago            thirsty_brattain

我在这里只能看到“nginx -g 'daemon of”..,而不是完整的命令。

【问题讨论】:

标签: docker


【解决方案1】:

docker ps --no-trunc 将显示完整的命令以及正在运行的容器的其他详细信息。

【讨论】:

  • 这对我不起作用。它给了我命令,但不是所有的开关(这是我在使用“完整命令”时想到的)。上面提到的其他链接的 runlike 命令对我来说效果更好。
  • 对于仅运行容器的完整命令,只需删除 all 命令。 docker ps --no-trunc
  • 谢谢 -- 已更正。我之前的命令适用于所有容器,而不仅仅是运行容器,这是最初的问题。
  • 未截断的命令可能很长,只能看到每行带有docker ps --all --no-trunc|cut -c-400的前400个字符
  • 为了更方便的阅读,可以将命令通过管道传送到less,如下所示:docker ps --no-trunc | less -S。这将删除换行符并允许您水平滚动。
【解决方案2】:

用途:

docker inspect -f "{{.Name}} {{.Config.Cmd}}" $(docker ps -a -q)

...它对所有容器进行“docker 检查”。

【讨论】:

  • 这不会显示 docker ps 命令。 docker ps 命令对应 docker inspect Path 和 Args。
  • 截至 2018 年 1 月没有 bueno
  • docker inspect -f "{{.Name}} {{.Path}} {{.Args}}" $(docker ps -a -q)
  • 如果你只是在命令前面加上sudo,你会得到"docker inspect" requires at least 1 argument(s).,因为第二次调用是为了获取所有容器名称,你可能想要添加$( 内的 sudo。
  • 对于那些想要更好地理解 -f 查询的人,我在这里找到了一个很好的解释 container-solutions.com/docker-inspect-template-magic
【解决方案3】:

用途:

docker inspect -f "{{.Path}} {{.Args}} ({{.Id}})" $(docker ps -a -q)

这将显示命令路径和参数,类似于docker ps

【讨论】:

  • 您将如何修改它以搜索特定命令,例如 kube-apiserver
  • @Jonathan docker inspect -f "{{.Path}} {{.Args}} ({{.Id}})" $(docker ps -a -q) | grep kube-apiserver
【解决方案4】:

使用 git 存储库中的 runlike https://github.com/lavie/runlike

安装runlike

pip install runlike

因为它接受容器 id 作为参数,所以提取容器 id 使用以下命令

docker ps -a -q

你最好使用 runlike 来提取完整​​的 docker run 命令和以下命令

runlike <docker container ID>

【讨论】:

  • 不起作用。 Show "Command '['docker', 'inspect', u'06e6a369f909']' 返回非零退出状态 1"
  • 你安装了我提到的runlike吗
  • 更好的是,您可以在 docker 容器中运行 runlike 并避免安装它:docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike YOUR-CONTAINER
【解决方案5】:

TL-DR

docker ps --no-truncdocker inspect CONTAINER 提供了启动容器的入口点,以及传递给的命令,但这可能会错过一些部分,例如 ${ANY_VAR},因为容器环境变量未打印为已解析。

为了克服这个问题,docker inspect CONTAINER 有一个优势,因为它还允许从Config.Env 属性分别检索容器中定义的环境变量及其值。

docker psdocker 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}}"'

【讨论】:

    【解决方案6】:

    将 Dylan 的评论变成一个完整的答案,因为太有用了:

    docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike YOUR-CONTAINER
    

    它有什么作用?在容器内运行https://github.com/lavie/runlike,获取完整的 docker run 命令,然后为您移除容器。

    【讨论】:

      猜你喜欢
      • 2020-06-11
      • 2020-03-15
      • 1970-01-01
      • 2021-03-06
      • 1970-01-01
      • 2020-04-12
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多