作为虚拟机使用的 Docker 速通
注意:本文相关说明只适用于 Linux 发行版类容器(比如 Ubuntu 镜像),不适用于轻量级应用的容器。请记住:Docker 不是虚拟机,充其量是「轻量」的虚拟机——其内运行的东西远远不止可以是完整的 Linux 发行版。
基本概念 #
- Docker 镜像(image):一个 Docker 镜像类似一包「料理包」,里面冻住了一系列的文件、环境、软件等数据,可以随意复制、分发、移动。
- 镜像可以编辑:你可以将料理包临时解冻,加一点小料进去,再冻起来。
- 镜像有名字(ID):比如
ubuntu22-cu121
。
- Docker 容器(container):基于一个 Docker 镜像,可以启动一个容器,就像起一口锅然后将料理包下入其中一样。
- 镜像是「死」的,容器是「活」的:容器才是正在运行的东西,镜像只是一堆死文件。
- 一个镜像可以启动多个容器:就像一种料理包可以炒无数锅菜一样。
- 容器有名字:比如,基于
ubuntu22-cu121
镜像,可以启动nihao
,iloveyou
等无数个容器。 - 如不配置穿透,容器与外界是隔绝的:容器内外文件不互通。
- 容器启动之后,内容可以被修改:你可以启动一个
ubuntu
容器,给里面安装一些软件。 - 容器内的修改会保留,直到该容器被销毁。
- 宿主机(host):运行 Docker 容器的物理机。
常用命令 #
Docker 是需要 root 的,默认情况下,以下所有命令都需要加 sudo
,除非配置了 docker 用户组。
镜像相关 #
- 从互联网(DockerHub)下载一个镜像:
docker pull <镜像ID>
- 从文件导入一个镜像:
docker load -i <本地镜像tar文件>
- 查看系统中有哪些镜像可用:或
docker images
docker image ls
- 删除一个镜像
docker image rm <镜像ID>
容器相关 #
此处的相关用法是较为安全的做法,但是与互联网上的其他用法有出入,请谨慎参照,不要混淆。
启动一个容器 #
docker run --name <容器的名字> --gpus all -v "<文件映射>" -d <镜像的名字> sleep infinity
其中各部分解释:
--name <容器的名字>
是给这个容器起名,前文已经说过,容器的名字与镜像名字无关,当然二者也可以一样。--gpus all
用于让容器能访问宿主机的 GPU。-v "<文件映射>"
用来设置文件映射。前文提及,Docker 内外文件不互通,为了让 Docker 容器内可以访问宿主机的代码和数据,需要在此处配置文件映射。- 例如,宿主机的代码放在
/home/hans/mycode
下,希望在 Docker 中能访问这个文件夹的内容 - 则可以使用
-v "/home/hans/mycode:/workspace"
命令 - 这样,在容器中,
/workspace
目录的内容就和宿主机的/home/hans/mycode
是同步的了。你可以把代码和数据在宿主机上放于/home/hans/mycode
,然后在容器中用/workspace
访问它们。在容器销毁之后,它对外部文件进行的修改仍然会保留。 -v
可以多次使用,以映射多个位置。比如,-v "/home/hans/a:/workspace/a" -v "/home/hans/b:/workspace/b"
- 注意:你只能在容器第一次启动的时候配置文件映射,后续无法再增补新的映射或删除已有的映射
- 例如,宿主机的代码放在
-d
的作用是让容器启动之后在后台运行,不占用前台终端。<镜像的名字>
是镜像的名字。sleep infinity
的作用是让容器保持运行,不要自己主动退出。
举个例子:如果你需要基于镜像 ubuntu22-cu121
启动一个容器,名为 myubuntu
,配置宿主的 /home/hans/mycode
映射到 /workspace
,请运行:
docker run --name myubuntu --gpus all -v "/home/hans/mycode:/workspace" -d ubuntu22-cu121 sleep infinity
运行此命令后,容器会启动并在后台运行,相当于启动了一台在后台运行的虚拟机。终端仍然会回到宿主机。下面,我们需要在容器中启动 shell,以进入该虚拟机。
列出现正运行的容器 #
你可以在宿主机中运行 docker ps
来查看当前有哪些容器正在运行。
该命令会列出正在运行容器的 ID、名字和镜像 ID 等信息。
启动容器的 shell #
要在某容器中启动一个 shell(终端、命令行),请运行
docker exec -it <容器ID或名字> /bin/bash
其中:
-it
的意思是启动交互式终端。<容器ID>
就是容器的名字。/bin/bash
是 shell 程序的位置。如果你在容器中安装了其他 shell,亦可自行使用。
执行后,我们将进入该容器的 shell。你应该注意到当前的命令提示符前端会变成:
root@1f024e940da3:/workspace#
这就说明现在已经进入容器内部了。你也会发现:容器内部默认直接使用 root 用户,没有其他用户。因此容器内执行命令不需要再 sudo
。
离开当前容器 #
按上面的操作进入容器的 shell 之后,你可以像连接到一台远程服务器那样使用它了。如果需要退出容器的 shell,可以直接运行 exit
,你就会回到宿主机的终端,而容器仍然会在后台稳定运行。
当然,如果你直接关闭了 shell,就像断开 SSH 连接那样,shell 中运行的东西会退出。所以,如果你需要在容器中持久运行某程序,可以使用容器内部的 tmux。
需要再次回到容器?按上一节「启动容器的 shell」操作即可。
停止容器 #
如果需要停止一个容器的运行,可以使用
docker stop <容器ID或名字>