第四章、Docker 容器的操作
前面我们讲过,在 Docker 中,容器(Container)是一个轻量级、可执行的独立软件包,它包含了运行某个应用所需的所有内容:根文件系、网络、名字空间、运行时环境、系统工具、运行时库和配置等信息。
Docker 的容器有如下特性:
- 基于镜像运行
- 容器是从Docker镜像创建的实例。镜像类似于模板,而容器是模板的运行实例(类似于面相对象中的 "类" 和 "对象" 的关系)。
- 例如:你可以从使用 mysql 镜像运行多个独立的 mysql 容器,每个mysql 后台服务用于不同的业务。
- 隔离性
- 每个容器拥有独立的文件系统、网络、进程空间(通过Linux内核的cgroups和namespaces实现)。
- 容器之间互不干扰,但可以通过配置进行通信。
- 轻量级
- 容器共享宿主机的操作系统内核,无需像虚拟机(VM)那样模拟完整操作系统,因此启动更快、资源占用更少。
- 临时性(可销毁)
- 容器默认是无状态的,停止后数据会丢失(除非使用卷(Volumes)持久化存储)。
- 可移植性
- 容器可以在相同宿主操作系统的 Docker 环境中制作,并能在相同类型的宿主操作系统上运行(有限的可移植性)。
- 不可跨硬件平台运行
- 在基于ARM的平台中创建的镜像均为基于 ARM 平台的,无法在 x86 平台上运行。
-
跨平台的容器无法运行,会出现格式错误,如下图所示:

Docker 容器的结构模型
一个容器通常有一个或多个只读的镜像层(如下图的 74fe38d11401 )和一个可写层(Writeable layer)组成,可写层用于容器运行时存放临时数据。
如下图所示:

上图最上层的 running job 就是 容器主程序。
一个容器一定要有一个 容器主程序,并且这个 容器主程序 一旦推向后台或者退出,则整个容器运行结束(重要)。
1. 创建并运行 docker 容器
使用 docker run 命令可以创建并运行一个容器。
docker run 命令
命令格式
docker run [选项] 镜像名[:标签]或镜像ID [命令] [参数...]
命令别名:
docker container run
命令格式说明
docker run一个容器运行必须依赖一个镜像,我们可以用镜像名[:标签]或镜像ID的形式给出镜像.[命令] [参数...]是容器内的命令和参数,如果不给定这个参数,则用镜像内的CMD设置给定。
常用选项
-d--name-p <宿主机端口>:<容器端口>-v <宿主机路径>:<容器路径>-e 环境变量名=值--restart=重启模式no 不重启,always 退出就重启,unless-stopped 不会恢复手动停止的容器,on-failure[:max-retries] 容器非正常退出时重启(可指定最大重试次数)。--rm--network--network=host 直接暴露主机端口,bridge 容器间通信(默认),container:<容器名或ID>共享其他容器的网络。none 容器不配置任何网络-iSTDIN 打开。-t-i 选项一起使用)。-w-ip <IP地址>-ip 127.17.0.100-cpus <数字>-m <字节数>-h <主机名>使用
sudo docker run --help可以查看全部选项。
示例
weimingze@mzstudio:~$ sudo docker run \
--name mysql_server \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=weimingze.com \
-v /home/weimingze/mysql_vol/data:/var/lib/mysql \
-v /home/weimingze/mysql_vol/logs:/var/log/mysql \
--restart=unless-stopped \
-d \
mysql
4d68e66019f347a444aed488acfc8aec7ebf3c9210f6ccb0467a03186eceb483
weimingze@mzstudio:~$
反斜杠
\是 Linux Shell 的折行符,当命令行太长时,可以在一行的末尾写入 反斜杠\,然后在下一行可以继续输入此命令的选项和参数而不会执行当前命令。
下面我们来详细解读上述 docker run 的选项:
--name mysql_server是为此运行的容器取一个名字mysql_server,便于查找、停止此容器等操作。-p 3306:3306,将容器内部的 3306 端口号映射到 宿主机的 3306 端口号。也就是 宿主机通过 3306 端口号和容器内的 3306 对应。不映射,我们不能从外部访问服务器。-e MYSQL_ROOT_PASSWORD=weimingze.com通过环境变量MYSQL_ROOT_PASSWORD来设定 容器内 MySQL 服务器的root密码是weimingze.com, 这个环境变量的名称是制作镜像的作者来定义的。-v /home/weimingze/mysql_vol/data:/var/lib/mysql将MySQL容器内部的/var/lib/mysql映射成宿主机的/home/weimingze/mysql_vol/data文件夹。/var/lib/mysql是 MySQL 数据保存数据的默认路径-v /home/weimingze/mysql_vol/logs:/var/log/mysql将 MySQL 保存日志的路径/var/log/mysql映射成宿主机的路径,便于查看和保存。--restart=unless-stopped如果容器非正常退出则重新启动容器。-
-d将 正在运行的容器推向后台运行,脱离终端。去掉此选项,终端会连接 容器主进程 并能看到容器主进程的输出结果。使用Control + c可以终止容器运行。 -
终端输出
4d68e66019f347a444aed488acfc8aec7ebf3c9210f6ccb0467a03186eceb483是容器的 ID。
宿主机 /home/weimingze/mysql_vol 的内容如下:
weimingze@mzstudio:~$ tree mysql_vol/
mysql_vol/
├── data
│ ├── #ib_16384_0.dblwr
│ ├── #ib_16384_1.dblwr
│ ├── #innodb_redo [error opening dir]
│ ├── #innodb_temp [error opening dir]
│ ├── auto.cnf
│ ├── binlog.000001
│ ├── binlog.000002
│ ├── binlog.000003
│ ├── binlog.index
│ ├── ca-key.pem
│ ├── ca.pem
│ ├── client-cert.pem
│ ├── client-key.pem
│ ├── ib_buffer_pool
│ ├── ibdata1
│ ├── ibtmp1
│ ├── mysql [error opening dir]
│ ├── mysql.ibd
│ ├── mysql.sock -> /var/run/mysqld/mysqld.sock
│ ├── mysql_upgrade_history
│ ├── performance_schema [error opening dir]
│ ├── private_key.pem
│ ├── public_key.pem
│ ├── server-cert.pem
│ ├── server-key.pem
│ ├── sys [error opening dir]
│ ├── undo_001
│ └── undo_002
└── logs
8 directories, 23 files
可见容器内的 mysql 启动后将运行的数据库内容映射到了宿主机的 /home/weimingze/mysql_vol 文件夹下。这样可以保证数据的安全,一但容器损坏,数据还在,还可以恢复。