🚀 启动 Docker 容器
Docker 容器的启动有两大方式:
- 基于镜像新建并启动容器 🆕
- 启动已经在终止状态(exited)的容器 🔁
由于 Docker 容器如此轻量级,用户常常选择随时删除和新建容器。
🔹 新建并启动
主要命令: docker run
-
示例1: 输出“Hello World”然后终止容器
$ docker run ubuntu:18.04 /bin/echo 'Hello world' Hello world
这与在本地直接执行
/bin/echo 'hello world'
感觉几乎相同。 -
示例2: 启动一个交互式的 bash 终端
$ docker run -t -i ubuntu:18.04 /bin/bash root@af8bae53bdd3:/#
其中,
-t
选项为 Docker 分配一个伪终端并绑定到容器的标准输入,-i
保持容器的标准输入打开。在此模式下,你可以:
root@af8bae53bdd3:/# pwd / root@af8bae53bdd3:/# ls bin boot dev ... usr var
当使用 docker run
创建容器时,Docker 会:
- 检查本地是否有指定的镜像,没有则下载
- 利用镜像创建并启动容器
- 挂载可读写层到只读的镜像层外
- 桥接虚拟接口到容器
- 为容器配置 IP 地址
- 执行指定应用
- 应用执行完毕后,容器终止
🔹 启动已终止容器
使用 docker container start
可以启动一个已经终止的容器。
容器的核心是其运行的应用程序,它所需的所有资源都是必要的。例如,在伪终端中,你可以看到:
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
这显示了容器中仅运行了 bash 应用。这使得 Docker 的资源利用率非常高,是真正的轻量级虚拟化。🌟
🌟 守护态运行 Docker 容器
在很多情境下,我们希望 Docker 容器在后台守护式运行,而不是直接在当前宿主机下输出执行命令的结果。这时,可以使用 -d
参数。
📌 不使用 -d
参数
当你不使用 -d
参数运行容器时,例如:
$ docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
输出会如下:
hello world
hello world
hello world
hello world
容器会将其输出(STDOUT)直接打印到宿主机上。
📌 使用 -d
参数
当你使用 -d
参数来运行容器时,例如:
$ docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
你会看到这样的输出:
77b2dc01fe0f3f1265df143181e7b9af5e05279a884f4776ee75350ea9d8017a
此时,容器会在后台运行,而不会将其输出(STDOUT)直接打印到宿主机上。但你可以使用 docker logs
来查看这些输出。
💡 提示:容器是否持续运行与你使用的 docker run
指定的命令有关,与 -d
参数无关。
📌 查看后台运行的容器
使用 -d
参数启动容器后,Docker 会返回一个唯一的容器 ID。你可以使用以下命令来查看后台运行的容器信息:
$ docker container ls
输出可能是这样的:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77b2dc01fe0f ubuntu:18.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute agitated_wright
📌 获取容器的输出信息
要查看容器的输出,可以使用 docker container logs
命令,例如:
$ docker container logs [container ID or NAMES]
输出可能是这样的:
hello world
hello world
hello world
...
这就是容器在后台持续打印的“hello world”。
📢 进入 Docker 容器
当你使用 -d
参数启动 Docker 容器后,容器会在后台运行。为了进入容器进行某些操作,你可以选择使用 docker attach
或 docker exec
命令。我们推荐使用 docker exec
,原因稍后解释。
📌 attach
命令
使用 docker attach
可以连接到一个正在运行的容器。以下是如何使用它的例子:
-
首先启动一个容器:
$ docker run -dit ubuntu
-
查看正在运行的容器:
$ docker container ls
-
使用
docker attach
连接到容器:$ docker attach 243c
⚠️ 注意: 如果你在这个连接中执行
exit
,容器会停止。
📌 exec
命令
docker exec
命令用于在运行的容器中执行命令。它可以与 -i
和 -t
参数一起使用,分别表示交互模式和分配一个伪终端。
-
启动一个容器:
$ docker run -dit ubuntu
-
查看正在运行的容器:
$ docker container ls
-
使用
docker exec
命令,只有-i
参数:$ docker exec -i 69d1 bash
-
使用
docker exec
命令,同时有-i
和-t
参数:$ docker exec -it 69d1 bash
在这种情况下,如果你执行
exit
,容器不会停止。这就是我们推荐使用docker exec
而不是docker attach
的原因。
📌 更多参数
要查看 docker exec
提供的所有参数和它们的详细描述,你可以使用以下命令:
$ docker exec --help
这将列出与 docker exec
命令相关的所有选项和描述。
🛠️ 导出与导入 Docker 容器
Docker 提供了工具,允许你导出容器的当前状态为一个文件,然后可以从该文件再次导入为一个 Docker 镜像。以下是具体操作:
📌 导出容器
要导出一个容器,你可以使用 docker export
命令。
-
查看所有的容器,包括已停止的:
$ docker container ls -a
-
使用
docker export
导出容器的状态:$ docker export 7691a814370e > ubuntu.tar
这会将容器的当前状态保存为一个名为 ubuntu.tar
的文件。
📌 导入容器快照
要从一个容器快照文件导入为 Docker 镜像,你可以使用 docker import
命令。
-
使用以下命令从文件导入容器快照:
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
-
查看本地的 Docker 镜像,以确认导入成功:
$ docker image ls
你还可以从一个 URL 或一个目录导入容器,例如:
$ docker import http://example.com/exampleimage.tgz example/imagerepo
💡 注意:Docker 提供了两种方式将镜像数据从文件导入到本地镜像库:docker load
和 docker import
。它们的主要区别是:
docker load
导入的是一个镜像存储文件,它会保存所有的历史记录和元数据信息。这通常是通过docker save
命令从现有镜像创建的。docker import
导入的是一个容器快照文件,它只保存容器的当前状态,丢弃所有历史和元数据。这意味着文件体积通常较小。
当从容器快照文件导入时,你可以重新指定标签和其他元数据信息。
🎉 删除 Docker 容器
在 Docker 中,容器和镜像占据磁盘空间。随着时间的推移,可能会有大量不再需要的旧容器或旧镜像堆积,因此清理这些资源变得很重要。
📌 删除容器
-
使用
docker container rm
命令可以删除一个已经停止的容器。例如:$ docker container rm trusting_newton
这会删除名为
trusting_newton
的容器。 -
如果你试图删除一个正在运行的容器,需要使用
-f
参数,这会强制停止并删除容器。Docker 会发送一个 SIGKILL 信号给容器。$ docker container rm -f trusting_newton
📌 清理所有已停止的容器
随着时间的推移,你可能会发现有很多已经停止的容器。一次性删除所有这些容器可以使用以下命令:
$ docker container prune
这个命令会询问你是否确定要删除所有已停止的容器。一旦确认,Docker 将删除它们并释放与这些容器相关的磁盘空间。
💡 小贴士:定期检查并清理不再需要的资源可以帮助保持 Docker 主机的磁盘空间和性能。除了容器,你还可以考虑清理旧的镜像、未使用的数据卷和悬挂的网络资源。