3.Docker镜像和容器卷
Docker镜像简介
Docker 镜像是一个轻量级、独立、可执行的软件包,其中包含运行应用程序所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
Docker 镜像是由文件系统叠加层组成的,每个层都包含了对文件系统的一系列更改。这使得镜像的构建和分发变得高效,因为多 个镜像可以共享相同的基础层。当你启动一个容器时,Docker 引擎会将这些层叠加在一起,形成一个文件系统,然后在其上运行应用程序。
Docker镜像加载原理
关键概念
联合文件系统(UnionFs)
联合文件系统(Union File System)是一种文件系统的组织方式,它允许将多个文件系统叠加在一起,形成一个单一的文件系统视图。Docker 使用联合文件系统的概念来实现镜像的分层和构建。每个 Docker 镜像都由多个图层(layers)组成,这些图层按顺序叠加在一起,形成一个联合文件系统。每个图层都代表了文件系统的一部分,其中包含了应用程序的代码、库、配置文件等。这种叠加结构有助于镜像的构建和管理。
图层(Layer)
Docker 镜像由多个图层组成。每个图层代表了对文件系统的一系列更改。这些图层是只读的,且相互独立。当你构建一个新的镜像时,Docker 将每个图层作为一个增量添加到镜像中。
图层特点
- 只读性(Read-Only): 每个图层都是只读的。这意味着一旦图层被创建,它的内容就不能被修改。这确保了镜像的不可变性,即一个已经构建的镜像不会被改变。
- 增量性(Incremental): 每个图层都代表对文件系统的一系列更改。当构建一个新的镜像时,Docker 只需将新增的或修改过的文件添加到一个新的图层中,而不需要复制整个文件系统。这种增量构建方式使得镜像的构建和分发更加高效。
- 可重用性(Reusable): 由于图层的增量性,不同的镜像可以共享相同的底层图层。这提高了镜像的可重用性,减少了磁盘空间的占用,也加速了构建和推送镜像的速度。
- 层叠结构(Layered Structure): 多个图层按照顺序叠加在一起,形成联合文件系统。这种层叠结构使得镜像的构建和管理变得更加灵活,同时也支持版本控制。每个图层都可以看作是一个对文件系统的快照。
- 容器之间共享底层图层(Sharing of Layers): 当多个容器共享相同的基础镜像时,它们会共享底层图层,从而减少磁盘空间的占用。这种共享也使得容器的启动更加快速,因为它们可以共享已经加载的图层。
镜像加载过程
当你运行 docker run 命令启动一个容器时,Docker 引擎会从指定的镜像中创建一个容器实例。在这个过程中,Docker 引擎会将镜像的各个图层叠加在一起,形成容器的文件系统。这个文件系统是只读的,因为图层是只读的,但容器会在其上添加一个可写的层,以便存储容器运行时的变化。
以下是 Docker 镜像加载过程的详细步骤:
- 启动容器: 镜像加载的过程通常始于用户运行
docker run命令。Docker 引擎创建并启动一个新的容器实例。 - 查找镜像: Docker 引擎首先会检查本地系统中是否存在所需的镜像。如果镜像不存在本地,引擎会尝试从 Docker Hub 或其他远程镜像仓库下载镜像。镜像包含了容器运行所需的文件系统、配置信息等。
- 加载镜像: 下载完镜像后,Docker 引擎会将镜像加载到本地系统中。加载镜像的过程涉及将镜像的各个图层解压并叠加在一起,形成容器的文件系统。这个文件系统包括了所有镜像中定义的文件和目录。
- 创建可写层: 一旦只读的镜像层加载完成,Docker 引擎在其上创建一个可写层,用于存储容器运行时的变化。这个可写层允许容器在运行时修改文件系统,而不影响镜像的原始内容。
- 容器启动: Docker 引擎使用容器运行时启动容器。容器运行时负责创建容器进程、配置网络和存储等环境,并启动容器中的应用程序。容器进程运行在容器的文件系统上,这个文件系统是由镜像的图层叠加而成的。
- 容器执行: 一旦容器启动,其中的应用程序开始执行。容器运行时会监视容器的状态,同时将容器的标准输入、输出和错误连接到主机的标准输入、输出和错误,使得用户可以与容器进行交互。
示例:
下图是一个启动镜像的操作
[fams_itoper01@ca-s2104 ~]$ sudo docker run mysql:8.2 mysql #启动镜像
Unable to find image 'mysql:8.2' locally #查找镜像
8.2: Pulling from library/mysql #拉取镜像
558b7d69a2e5: Downloading [===================> ] 19.89MB/51.32MB #加载镜像
599b67b0dd6a: Download complete
50314d46ce2b: Download complete
494babc92263: Download complete
02548e6f2dbf: Download complete
a9e5e2637e0d: Download complete
657b198fe6b7: Downloading [=> ] 1.62MB/62.57MB
215a2b0eabbf: Waiting
377a4c7a89c5: Waiting
4bfe599fe218: Waiting
Docker容器卷
容器卷(Container Volume)是 Docker 中用于在容器和主机之间共享数据的一种机制。容器卷提供了一种持久化存储的方式,使得容器可以在其生命周期内保留和访问数据,即使容器被停止和删除后,数据依然可以保留在卷中。
容器卷的一些关键特点:
- 数据持久性: 容器卷是一个持久性存储卷,其数据可以在容器之间共享,并且在容器被删除后数据依然存在。这使得容器可以在不丢失数据的情况下启动、停止和重新启动。
- 容器之间共享: 容器卷可以被多个容器共享。这意味着你可以创建一个卷,然后将其挂载到多个容器中,使这些容器可以访问相同的数据。
- 主机和容器之间的数据传递: 容器卷还可以用于在容器和主机之间传递数据。主机上的数据可以通过挂载卷到容器中来提供给容器使用,而容器中的数据也可以通过卷挂载到主机上进行持久化储。
- 独立于容器的生命周期: 容器卷的生命周期独立于容器的生命周期。当容器被删除时,卷中的数据不会随之删除,除非明确删除卷。
相关命令
通过 docker run 命令的 -v 或 --volume 选项来指定卷的挂载点。
docker run -v /host/path:/container/path my-image #主机目录:容器目录
把主机上的 /host/path 目录挂载到容器中的 /container/path 目录。
启动起来后,可以通过 docker inspect 容器id 查看挂载信息
sudo docker inspect d5e41faf16d1
挂载信息字段如下:
"Mounts": [
{
"Type": "bind",
"Source": "/data/backups/mysql",
"Destination": "/data/mysqlBackup",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/data/databases/mysql",
"Destination": "/var/lib/mysql",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
其他参数简介
命令示例:
docker run --name some-mysql -p 3310:3306-v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7
解释各个选项和参数:
--name some-mysql: 为容器指定一个名字,这里是 "some-mysql"。-p 3310:3306: 将主机的端口 3310 映射到容器的端口 3306。这允许通过主机的 3310 端口访问容器中运行的 MySQL 服务。- -p : 映射指定端口
- -P : 映射随机端口,将内网端口随机映射到外网端口
-v /my/own/datadir:/var/lib/mysql: 使用容器卷,将主机上的/my/own/datadir目录挂载到容器中的/var/lib/mysql目录。这样做的目的是将 MySQL 的数据目录持久化到主机上,以便数据在容器停止或删除后仍然保留。-e MYSQL_ROOT_PASSWORD=my-secret-pw: 设置 MySQL 数据库的 root 用户的密码为 "my-secret-pw"。这是通过环境变量来传递 MySQL 镜像的配置参数。-d: 在后台运行容器(detached 模式)。不输出安装信息。mysql:8.2: 指定要运行的 Docker 镜像,这里是 MySQL 8.2 版本。