如何使用dockerexec在Docker容器中运行命令
介绍
Docker 是一个容器化工具,可帮助开发人员创建和管理可移植的、一致的 Linux 容器。
在开发或部署容器时,您通常需要查看正在运行的容器内部以检查其当前状态或调试问题。 为此,Docker 提供了 docker exec
命令在已经运行的容器中运行程序。
在本教程中,我们将了解 docker exec
命令以及如何使用它来运行命令并在正在运行的 Docker 容器中获取交互式 shell。
先决条件
本教程假设您已经安装了 Docker,并且您的用户有权运行 docker
。 如果您需要以 root 用户身份运行 docker
,请记住在本教程中的命令前添加 sudo
。
有关在没有 sudo
访问权限的情况下使用 Docker 的更多信息,请参阅我们的 如何安装 Docker 教程的 Executing the Docker Command without Sudo 部分。
启动测试容器
要使用 docker exec
命令,您需要一个正在运行的 Docker 容器。 如果您还没有容器,请使用以下 docker run
命令启动测试容器:
docker run -d --name container-name alpine watch "date >> /var/log/date.log"
此命令从 官方 alpine 映像 创建一个新的 Docker 容器。 这是一个流行的 Linux 容器镜像,它使用 Alpine Linux,一个轻量级、最小的 Linux 发行版。
我们使用 -d
标志将容器与终端分离并在后台运行它。 --name container-name
将容器命名为 container-name
。 您可以在此处选择您喜欢的任何名称,或者完全不使用它,让 Docker 自动为新容器生成一个唯一名称。
接下来我们有 alpine
,它指定了我们要用于容器的图像。
最后我们有 watch "date >> /var/log/date.log"
。 这是我们要在容器中运行的命令。 watch
将重复运行你给它的命令,默认每两秒一次。 在这种情况下 watch
将运行的命令是 date >> /var/log/date.log
。 date
打印当前日期和时间,如下所示:
OutputFri Jul 23 14:57:05 UTC 2021
命令的 >> /var/log/date.log
部分重定向来自 date
的输出并将其附加到文件 /var/log/date.log
。 每两秒就会在文件中添加一个新行,几秒钟后它看起来像这样:
OutputFri Jul 23 15:00:26 UTC 2021 Fri Jul 23 15:00:28 UTC 2021 Fri Jul 23 15:00:30 UTC 2021 Fri Jul 23 15:00:32 UTC 2021 Fri Jul 23 15:00:34 UTC 2021
在下一步中,我们将学习如何查找 Docker 容器的名称。 如果您已经有一个要定位的容器,但您不确定它的名称是什么,这将非常有用。
查找 Docker 容器的名称
我们需要向 docker exec
提供我们要使用的容器的名称(或容器 ID)。 我们可以使用 docker ps
命令找到这些信息:
docker ps
此命令列出服务器上运行的所有 Docker 容器,并提供有关它们的一些高级信息:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 76aded7112d4 alpine "watch 'date >> /var…" 11 seconds ago Up 10 seconds container-name
在此示例中,容器 ID 和名称被突出显示。 您可以使用任何一个来告诉 docker exec
使用哪个容器。
如果您想重命名容器,请使用 docker rename
命令:
docker rename container-name new-name
接下来,我们将运行几个使用 docker exec
在正在运行的 Docker 容器中执行命令的示例。
在 Docker 容器中运行交互式 Shell
如果您需要在 Docker 容器中启动交互式 shell,可能是为了探索文件系统或调试正在运行的进程,请使用带有 -i
和 -t
标志的 docker exec
。
-i
标志保持输入对容器开放,-t
标志创建一个 shell 可以附加到的伪终端。 这些标志可以像这样组合:
docker exec -it container-name sh
这将在指定容器中运行 sh
shell,为您提供基本的 shell 提示。 要退出容器,输入 exit
然后按 ENTER
:
exit
如果您的容器映像包含更高级的 shell,例如 bash
,您可以将上面的 sh
替换为 bash
。
在 Docker 容器中运行非交互式命令
如果您需要在正在运行的 Docker 容器中运行命令,但不需要任何交互性,请使用不带任何标志的 docker exec
命令:
docker exec container-name tail /var/log/date.log
此命令将在 container-name
容器上运行 tail /var/log/date.log
,并输出结果。 默认情况下,tail
命令将打印出文件的最后十行。 如果您正在运行我们在第一部分中设置的演示容器,您将看到如下内容:
OutputMon Jul 26 14:39:33 UTC 2021 Mon Jul 26 14:39:35 UTC 2021 Mon Jul 26 14:39:37 UTC 2021 Mon Jul 26 14:39:39 UTC 2021 Mon Jul 26 14:39:41 UTC 2021 Mon Jul 26 14:39:43 UTC 2021 Mon Jul 26 14:39:45 UTC 2021 Mon Jul 26 14:39:47 UTC 2021 Mon Jul 26 14:39:49 UTC 2021 Mon Jul 26 14:39:51 UTC 2021
这基本上与为 Docker 容器打开一个交互式 shell(如上一步中使用 docker exec -it container-name sh
所做的那样)然后运行 tail /var/log/date.log
命令相同。 但是,该命令不是打开 shell,运行命令,然后关闭 shell,而是在单个命令中返回相同的输出,而不打开伪终端。
在 Docker 容器的备用目录中运行命令
要在容器的某个目录中运行命令,请使用 --workdir
标志指定目录:
docker exec --workdir /tmp container-name pwd
此示例命令将 /tmp
目录设置为工作目录,然后运行 pwd
命令,打印出当前工作目录:
Output/tmp
pwd
命令确认工作目录为/tmp
。
在 Docker 容器中以不同用户身份运行命令
要在容器内以其他用户身份运行命令,请添加 --user
标志:
docker exec --user guest container-name whoami
这将使用 guest 用户在容器中运行 whoami
命令。 whoami
命令打印出当前用户的用户名:
Outputguest
whoami
命令确认容器的当前用户是 guest。
将环境变量传递给 Docker 容器
有时您需要将环境变量与要运行的命令一起传递到容器中。 -e
标志允许您指定环境变量:
docker exec -e TEST=sammy container-name env
此命令将 TEST
环境变量设置为等于 sammy
,然后在容器内运行 env
命令。 env
命令然后打印出所有环境变量:
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=76aded7112d4 TEST=sammy HOME=/root
TEST
变量设置为 sammy
。
要设置多个变量,请为每个变量重复 -e
标志:
docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env
如果您想传入一个充满环境变量的文件,您可以使用 --env-file
标志来实现。
首先,使用文本编辑器制作文件。 我们将在此处使用 nano
打开一个新文件,但您可以使用任何您喜欢的编辑器:
nano .env
我们使用 .env
作为文件名,因为这是使用这些类型的文件来管理版本控制之外的信息的流行标准。
将 KEY=value
变量写入文件,每行一个,如下所示:
.env
TEST=sammy ENVIRONMENT=prod
保存并关闭文件。 要保存文件并退出 nano
,请按 CTRL+O
,然后按 ENTER
保存,然后按 CTRL+X
退出。
现在运行 docker exec
命令,在 --env-file
之后指定正确的文件名:
docker exec --env-file .env container-name env
OutputPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=76aded7112d4 TEST=sammy ENVIRONMENT=prod HOME=/root
设置文件中的两个变量。
您可以使用多个 --env-file
标志指定多个文件。 如果文件中的变量相互重叠,则命令中最后列出的文件将覆盖以前的文件。
常见错误
在使用 docker exec
命令时,可能会遇到几个常见的错误:
Error: No such container: container-name
No such container
错误表示指定的容器不存在,可能表示容器名称拼写错误。 使用 docker ps
列出正在运行的容器并仔细检查名称。
Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running
此 not running
消息表示容器存在,但已停止。 您可以使用 docker start container-name
启动容器
Error response from daemon: Container container-name is paused, unpause the container before exec
Container is paused
错误很好地解释了这个问题。 在继续之前,您需要使用 docker unpause container-name
取消暂停容器。
结论
在本教程中,我们学习了如何在正在运行的 Docker 容器中执行命令,以及执行此操作时可用的一些命令行选项。
有关 Docker 的更多信息,请参阅我们的 Docker 标记页面 ,其中包含指向 Docker 教程、与 Docker 相关的问答页面等的链接。
有关安装 Docker 的帮助,请查看 如何在 Ubuntu 20.04 上安装和使用 Docker。