Docker Exec:在Docker中运行命令的首选指令


你是否曾经需要查看Docker容器内部发生了什么?容器旨在是幂等的:如果有问题,重新部署一个新的容器。然而,生活通常并非如此简单。您可能需要在容器中运行命令以识别问题。这就是docker exec命令能够帮助您的地方。

本文将教您如何使用docker exec命令在运行中的Docker容器上运行命令。

先决条件

要按照本文中的示例进行操作,您需要遵循以下要求。

  • 任何最新版本的Docker Desktop都可以在Windows、Linux或macOS上使用。本教程使用在Windows 10上运行的v3.1.0版本。

启动NGINX容器

Docker exec在容器中运行命令。但是,在这之前,您必须首先有一个容器来运行这些命令。让我们从下载Docker镜像并创建演示容器开始。

  1. 创建一个新目录,本教程使用C:\gitrepos\test,用于保存容器使用的文件。

2. 创建一个名为 dockerfile(无扩展名) 的文件,其中包含以下代码。Dockerfile 定义了创建容器所需的步骤。

FROM nginx:alpine
 COPY index.html /usr/share/nginx/html/index.html

3. 接下来,在相同的目录中创建一个名为 index.html 的文件,其中包含以下代码。这是一个 HTML 文件,当容器启动时,将显示一个 Hello World 消息。

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <meta http-equiv="X-UA-Compatible" content="ie=edge"> 
    <title>Hello World - Nginx Docker</title> 
    <style> 
       h1{ font-weight:lighter; font-family: Arial, Helvetica, sans-serif; 
       } 
    </style> 
    </head> 
    <body> 
       <h1> 
          Hello World 
       </h1> 

    </body> 
    </html>

4. 现在创建 Nginx Docker 容器。由于 Dockerfile 在当前工作目录中,使用 . 指定让 Docker 引擎知道要在那里查找。另外,请确保使用 t 参数为容器打上 my-ngnix 标签,以便将来更容易地引用。

docker build -t my-nginx .
Creating a Docker container with the build command.

5. 现在容器已构建完成,使用 Docker run 命令启动容器。

# rm - 通知 Docker 在容器停止后删除容器
# d - 在命令执行后返回命令行控制
# p - 将内部容器端口 80 映射到外部端口 80 docker run --rm -d -p 80:80 my-nginx
Start the container with the Docker run command.

6. 最后,打开您的 Web 浏览器并导航至 http://localhost/,将看到以下内容。

Output of the running NGINX container.

使用 Docker Exec 运行命令

当在Docker容器中运行命令时,可能需要以交互方式运行命令。以交互方式运行命令意味着输入一个命令,获取反馈,输入另一个命令,依此类推。交互式命令会接管您的会话,并阻止您执行其他任何操作。

但是,如果您已经提前知道要发送到容器的命令,并希望在后台运行命令呢?在这种情况下,您可以运行非交互式命令。非交互式命令允许您向Docker发送命令并立即返回控制台的控制权。

查找容器名称和ID

现在,您已经构建了容器,可以在容器内执行命令。在运行命令之前,请找到NGINX容器的名称或ID。在Docker命令中,名称或ID都可以使用。请记住,记住ID可能比记住名称更具挑战性!

要显示任何正在运行的容器信息,请运行Docker ps命令以输出以下信息。

docker ps
Displaying running Docker containers.

将唯一的ID e17e4b6be01a 或随机生成的名称 mystifying_chandrasekhar 复制到剪贴板以备将来使用。

使用Docker Exec运行非交互式命令

作为运行非交互式命令的示例,请复制并运行以下命令以返回/var/log目录中文件的列表,使用ls -l命令。将容器名称 mystifying_chandrasekhar 后面的所有内容传递给Docker exec命令。

docker exec mystifying_chandrasekhar ls -l /var/log
Executing a directory listing within the NGINX container.

使用Docker命令避免控制台输出

通过立即将Shell控制返回给用户,大型操作避免将控制台占用。通过使用分离的d选项放弃控制台输出。下面的命令通过在容器内使用touch命令创建文件/tmp/execWorks,并且不在控制台上显示任何输出。

docker exec -d mystifying_chandrasekhar touch /tmp/execWorks

使用Docker Exec执行交互命令

到目前为止,您已经学会了如何使用docker exec在Docker容器中运行非交互式命令。但是,可能会有这样的情况,您需要在容器中进行故障排除,例如当您需要交互式地向容器发出命令时。在这种情况下,您需要以交互方式运行命令。

使用docker exec以交互方式运行命令需要两个选项,iti选项保持STDIN打开,允许将命令发送到容器,t选项分配一个伪终端(PTY),即一个通信通道,以输入命令。

复制并粘贴以下命令以打开到运行中的Docker容器的交互命令提示符,使用Bourne(sh) shell,如提示更改为/ #所示。

docker exec -it mystifying_chandrasekhar sh
Running an interactive Docker shell.

一旦进入Shell,现在运行下面的命令以演示从容器内列出文件。最后,运行exit命令以退出交互式Shell。

ls -l /var/log
exit
Open an interactive command prompt to the container.

要在特定目录中打开交互式提示符,请将路径传递给w选项,告诉Docker在指定目录中启动shell。

将环境变量传递给运行中的容器

许多程序在启动时使用环境变量来设置配置。例如,大多数Java应用程序需要将JAVA_HOME环境变量设置为Java路径。

您可以使用e选项将环境变量传递给会话。例如,也许您需要将名为MYVAR的环境变量传递给运行中的容器。要执行此操作,请使用e选项,并像下面所示提供MYVAR="<some value>"的键/值对。

docker exec -it -e MYVAR="hello" mystifying_chandrasekhar sh
echo $MYVAR
Pass environment variables

使用文件传递环境变量

如果有许多环境变量或共享配置,则将这些变量存储在文件中可能更容易。使用--env-file选项将文件通过相对或绝对路径传递给Docker。此技术通常用于向容器提供安全凭据。务必不要将凭据提交到版本控制!

创建名为env-vars.txt的文本文件,其中包含要传递的环境变量及其值。此文件可以命名为任何您喜欢的名称,不需要.txt文件扩展名。

Text file with environmental variables defined.

使用env-file选项将环境变量传递给Docker。使用下面的屏幕截图中所示的echo命令验证变量是否可用。

# 传递 env-vars.txt 文件并打开交互式提示符
docker exec -it --env-file env-vars.txt mystifying_chandrasekhar sh
# 验证 Docker 容器中是否存在环境变量
echo $MYVAR
echo $FOO
echo $SOMETHING
Passing a environmental variables file to Docker and verifying the environment variables exist in the container.

以不同用户身份与运行中的容器交互

在生产环境中,应用程序通常以特定用户身份运行以限制其访问权限。如果在生产中以特定用户身份运行应用程序,则在测试命令时也应该这样做。

在此示例中,Docker 容器以 nginx 用户身份运行。通过将用户传递给 w 选项,告诉 Docker 以 nginx 帐户启动容器。在容器内运行的 whoami 命令确认确实使用了 nginx 用户。

docker exec -it -u nginx mystifying_chandrasekhar sh
whoami
Running the container as the nginx user.

下一步

您已经学会使用 docker exec 命令在运行中的容器中执行命令。利用 exec 命令进入并询问运行中的容器,您在故障排除 Docker 容器时拥有了一个强大的新工具。

现在尝试进一步学习,使用 Git 版本控制从容器中拉取静态网站,而不是复制单个文件。如果 Git 对您来说是新的,那么文章《Visual Studio Code 和 Git 的初学者指南》是一个很好的起点。

Source:
https://adamtheautomator.com/docker-exec/