【Docker】Docker基础教程(3)
前言:
推荐免费Docker基础讲解视频:【狂神说Java】Docker最新超详细版教程通俗易懂_哔哩哔哩_bilibili
镜像联合文件系统
镜像是什么
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,包含运行某个软件所需的全部内容,包括代码、库、环境变量、配置文件等。
如何得到镜像:
- 远程仓库下载镜像;
- 自己制作镜像;
Docker镜像加载原理
UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行集成,基于基础镜像,可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外表来看,只能看到一个文件系统,联合加载会把各层文件系统叠加,最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS;
bootfs(boot file system)主要包含bootloader
和kernel
,Linux刚启动会加载bootfs文件系统,在Docker镜像的最底层是bootfs,这一层与我们典型的Linux系统一样,包含boot加载器和内核,当boot内核加载完成之后整个内核就都在内存中了,此时内存使用权由bootfs转交给内核,系统也会卸载bootfs。
rootfs(root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,例如Centos等。
一般我们安装虚拟机都是好多个G大小,为什么Docker才200多M;
对于一个精简的OS,rootfs非常小,只需要包含基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,不同的发行版可以共用bootfs;
镜像分层理解
分层的镜像
我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是分层下载。
思考:为什么Docker镜像要采用这种分层结构?
最大的好处莫过于资源共享!比如多个镜像都是从相同的Base镜像构建而来,那么宿主机只需要在磁盘保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务,而且镜像的每一层都可以被共享。
查看镜像分层 docker image inspect
1 | 查看nginx的镜像分层 |
分层理解
所有的 Docker镜像都起始于一个基础镜像层,当进行修改或添加新的内容时,就会在当前镜像层之上,创建新的镜像层。
举一个简单的例子,假如基于 Ubuntu Linux16.04创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创健第三个镜像层该像当前已经包含3个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
上图中的镜像层跟之前图中的略有区別,主要目的是便于展示文件
下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有6个文件,这是因为最上层中的文件7是文件5的一个更新版;
文种情況下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中;
Docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系统;
Linux上可用的存储引撃有AUFS、 Overlay2、 Device Mapper、Btrfs以及ZFS。顾名思义,每种存储引擎都基于 Linux中对应的件系统或者块设备技术,井且每种存储引擎都有其独有的性能特点。
Docker在 Windows上仅支持 windowsfilter 一种存储引擎,该引擎基于NTFS文件系统之上实现了分层和CoW。
下图展示了与系统显示相同的三层镜像。所有镜像层堆并合井,对外提供统一的视图
特点
Docker镜像都是只读,当容器启动时,一个新的可写层被加载到镜像的顶部!
这一层就是我们通常说的容器层,容器之下叫镜像层。
Commit镜像
提交命令
1 | docker commit # 提交容器称为一个新的副本 |
测试
1 | 启动tomcat |
容器数据卷使用
什么是容器数据卷
将应用环境打包成一个镜像!
如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求:数据可以持久化;
容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地
这就是卷技术,目录的挂载,将容器内的目录挂载在Linux上面。
容器的持久化和同步操作,容器间可以数据共享
使用数据卷
使用命令来挂载
-v
1 | 数据挂载 |
测试
1 | 将容器的/home挂载到主机/home/test1 |
测试挂载是否生效
MySQL同步数据
MySQL数据持久化问题
-
MySQL下载
1
docker pull mysql:8.0
-
运行MySQL容器
1
2
3启动MySQL及相关配置
-v 挂载 -e MYSQL_ROOT_PASSWORD 配置密码
docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:8.0运行
1
2
3
4
5
6[root@jokerdig home]# docker run -d -p 3306:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:8.0
146e27589f8999fff3319b2d57da51f49b5ff15ff78f7430443891d78aed4e24
查看进程
[root@jokerdig home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
146e27589f89 mysql:8.0 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp mysql01 -
尝试连接到服务器MySQL
-
测试数据映射
在本地创建数据库,就会自动映射到服务器;
本地新建数据库
数据库自动映射到服务器
即使容器被删除,MySQL的数据仍然是存在的,实现了容器数据的持久化。