作为虚拟机使用的 Docker 速通


2025 年 10 月 13 日

注意:本文相关说明只适用于 Linux 发行版类容器(比如 Ubuntu 镜像),不适用于轻量级应用的容器。请记住:Docker 不是虚拟机,充其量是「轻量」的虚拟机——其内运行的东西远远不止可以是完整的 Linux 发行版。

基本概念 #

  • Docker 镜像(image):一个 Docker 镜像类似一包「料理包」,里面冻住了一系列的文件、环境、软件等数据,可以随意复制、分发、移动。
    • 镜像可以编辑:你可以将料理包临时解冻,加一点小料进去,再冻起来。
    • 镜像有名字(ID):比如 ubuntu22-cu121
  • Docker 容器(container):基于一个 Docker 镜像,可以启动一个容器,就像起一口锅然后将料理包下入其中一样。
    • 镜像是「死」的,容器是「活」的:容器才是正在运行的东西,镜像只是一堆死文件。
    • 一个镜像可以启动多个容器:就像一种料理包可以炒无数锅菜一样。
    • 容器有名字:比如,基于 ubuntu22-cu121 镜像,可以启动 nihaoiloveyou 等无数个容器。
    • 如不配置穿透,容器与外界是隔绝的:容器内外文件不互通。
    • 容器启动之后,内容可以被修改:你可以启动一个 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或名字>