如何在Docker容器内运行命令?

在Docker容器内运行命令比你想象的要简单。

Docker容器是一个隔离的环境,通常包含一个单独的应用程序及其所有所需的依赖项。很多时候,我们需要在一个docker container内运行一些命令。有几种方法可以在容器内执行命令并获取所需的输出。

让我们看看如何做到。

使用交互式Shell

我们可以直接访问容器的Shell,并像在普通Linux终端中一样执行我们的命令。要获取一个已停止(不在运行状态)容器的交互式Shell,可以使用以下命令:

$ docker run -it ubuntu bash
root@c520631f652d:/#

正如你所看到的,我们直接进入了一个新的Ubuntu容器,在这里我们可以运行我们的命令。如果容器已经在运行,你可以使用下面的exec命令。

首先,让我们找出容器ID。

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                      NAMES
c2d969adde7a   nginx     "/docker-entrypoint.…"   2 hours ago   Up 2 hours   127.0.0.1:80->80/tcp       nginx
0960560bc24b   mariadb   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   127.0.0.1:3306->3306/tcp   mariadb

然后,进入容器ID为c2d969adde7a的容器。

$ docker exec -it c2d969adde7a bash 
root@c2d969adde7a:/#

在上面的输出中,你可以观察到我们启动了一个正在运行状态的nginx容器的bash会话。在这里,我们可以执行任何受支持的命令并获得输出。

注意 – 你的容器可能没有bash,如果是这样的话,你可以使用sh。

例如:

docker exec -it c2d969adde7a sh

直接输出

通常,我们只需要一个或两个命令的输出,而不需要一个完整的交互式会话来完成我们的任务。你可以在容器内运行所需的命令,并直接获取其输出,而无需打开一个新的Shell会话,使用exec命令而不使用-it标志。其语法如下:

$ docker exec  

这里有一个例子:

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                      NAMES
c2d969adde7a   nginx     "/docker-entrypoint.…"   2 hours ago   Up 2 hours   127.0.0.1:80->80/tcp       nginx
0960560bc24b   mariadb   "docker-entrypoint.s…"   2 hours ago   Up 2 hours   127.0.0.1:3306->3306/tcp   mariadb

$ docker exec 0960560bc24b ps -ef | grep mysql
mysql          1       0  0 13:35 ?        00:00:02 mysqld
$

我们在运行的MariaDB容器中执行了ps -ef | grep mysql命令,并直接获得了输出。

Dockerfile方式

这不是你可以在一个docker container内运行命令的确切方式,尽管它可能在开发环境或初始部署调试等情况下有所帮助。我们可以在Dockerfile中使用RUN命令。下面是我们的示例Dockerfile:

FROM nginx:latest
RUN nginx -V

它简单地从注册表中拉取最新的nginx镜像,然后在构建镜像时运行nginx -V命令来显示Nginx版本。

$ docker build -t nginx-test .
正在发送上下文到 Docker 守护程序 2.048KB
步骤 1/2 : FROM nginx:latest
 ---> 7ce4f91ef623
步骤 2/2 : RUN nginx -V
 ---> Running in 43918bbbeaa5
nginx 版本: nginx/1.19.9
由 gcc 8.3.0 (Debian 8.3.0-6) 编译
使用 OpenSSL 1.1.1d  10 Sep 2019
启用 TLS SNI 支持
配置参数: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.19.9/debian/debuild-base/nginx-1.19.9=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
正在移除中间容器 43918bbbeaa5
 ---> d682277f2e50
成功构建了 d682277f2e50
成功标记为 nginx-test:latest
$

观察以上代码段中 RUN 命令的输出。以上代码段将只在第一次构建时显示,并且后续构建将不会重复显示 RUN 命令的输出。作为解决方法,您可以尝试使用 --no-cache 标志:

$ docker build -t nginx-test . --no-cache

最后一种方法不是最好的方法,但有时在调试等方面可能会有帮助。

总结

在 Docker 中运行命令是简单的,有几种可用的方法。这是 Docker 管理员的常规任务,因此了解这些命令是有用的。

接下来,学习一些流行的 Docker commands

类似文章