(五)、Docker镜像
1.镜像是什么
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来,不需要运维部署环境了
如何得到镜像:
- 从远处仓库下载
- 朋友拷贝给你
- 自己制作一个镜像DockerFile
2.Docker镜像加载原理
(1).UnionFS(联合文件系统)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础
。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
git每次操作都有记录,docker pull 下载时候看到一层一层的就是这个
A软件有的部分,B软件需要的话就不用重新下载了
(2).镜像加载原理
docker的镜像实际上由一层一层的渐渐系统组成,这种层级的文件UnionFS
bootfs(boot file system主要包含bootloader
和kernel
, bootloader
主要是引导加载kernel
, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
。
rootfs (root file system),在bootfs之上。包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等
。
平时我们安装虚拟机的centos都是好几个G,为什么Docker这里才200M?因为是精简过的,引导没了,只有文件,效率最大化
。
对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
虚拟机是分钟级别的,容器是秒级别的。
- 任何系统安装需要引导加载,所以Bootfs
- 黑屏-开机-系统 这过程就是种加载
- 容器就是小的虚拟机环境
- 底层的内核是不变的
3.镜像原理之分层理解
我们去下载一个镜像,注意观察下载的日志输出,可以看到是一层一层的在下载!
最大的好处,莫过于是资源共享。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需要在磁盘上保留一份base镜像
,同时内存中只需要加载一份base镜像,这样就可以为多有的容器服务了,而且每一层都可以被共享!!!
查看镜像分层的方式可以通过docker image inspect 命令
"RootFS": { "Type": "layers", "Layers": [ "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f", "sha256:9b24afeb7c2f21e50a686ead025823cd2c6e9730c013ca77ad5f115c079b57cb", "sha256:4b8e2801e0f956a4220c32e2c8b0a590e6f9bd2420ec65453685246b82766ea1", "sha256:529cdb636f61e95ab91a62a51526a84fd7314d6aab0d414040796150b4522372", "sha256:9975392591f2777d6bf4d9919ad1b2c9afa12f9a9b4d260f45025ec3cc9b18ed", "sha256:8e5669d8329116b8444b9bbb1663dda568ede12d3dbcce950199b582f6e94952" ] },
理解:
- 所有的 Docker|镜像都
起始于一个基础镜像层
,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的镜像层。 - 举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就会创建第三个镜像层。
在添加额外的镜像层的同时,镜像始终是保持当前所有镜像的组合,理解这一点是非常重要的。下图距举了一个简单的例子,每个镜像包含三个文件,而镜像包含了来自两个镜像层的6个文件。
和搭积木一样。单个零件单个零件搭建。如果遇到不喜欢的,在原有的基础上进行替换掉不喜欢的部分即可。
这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新镜像层添加到镜像当中。 Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统一的文件系統。 Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点
。
特点
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像顶部
!
顶层就是我们通常说的容器层,容器之下的都叫镜像层
镜像层是远程下载过来的,无法改变!!!。但是镜像层+操作可以组合成容器层,可以修改。理解的意思就是原有仓库镜像不能修改,但是操作后的镜像可以再次被我们打包成一个新的镜像。
4.提交镜像 【创建自己的镜像】
如果你想要保存当前的状态,就通过commit提交,获得一个镜像,就好比我们以前学习VM时候,快照
# docker commit 提交容器成为一个新的副本 # 命令和git原理类似 docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[tag] ------------------------------------------------------------ [root@Jsxs ~]# docker ps #查看正在运行的容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4aba86a517af portainer/portainer "/portainer" About an hour ago Up About an hour 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi db99d2ee658c tomcat:9.0 "catalina.sh run" 5 hours ago Up 2 hours 0.0.0.0:3355->8080/tcp, :::3355->8080/tcp tomcat01 [root@Jsxs ~]# docker commit -a="jsxs" -m="add webapps application" db99d2ee658c tomcat02:1.0 #打包,名字叫做tomcat02版本1.0 sha256:3cdc89385182ebcc15497f6ac38299ad3dd7e4449faa4f1ae4ee73f4874414ff [root@Jsxs ~]# docker images #查看镜像 REPOSITORY TAG IMAGE ID CREATED SIZE tomcat02 1.0 3cdc89385182 8 seconds ago 685MB #自定义的镜像 nginx latest 605c77e624dd 14 months ago 141MB tomcat 9.0 b8e65a4d736d 15 months ago 680MB hello-world latest feb5d9fea6a5 18 months ago 13.3kB centos latest 5d0da3dc9764 18 months ago 231MB portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB [root@Jsxs ~]# docker rmi 3cdc89385182 #删除镜像 Untagged: tomcat02:1.0 Deleted: sha256:3cdc89385182ebcc15497f6ac38299ad3dd7e4449faa4f1ae4ee73f4874414ff Deleted: sha256:a5c33b51384b808f00ba9d8e3e4868e69bb9ff538669ae94dc5c5555d159d195 [root@Jsxs ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 605c77e624dd 14 months ago 141MB tomcat 9.0 b8e65a4d736d 15 months ago 680MB hello-world latest feb5d9fea6a5 18 months ago 13.3kB centos latest 5d0da3dc9764 18 months ago 231MB portainer/portainer latest 580c0e4e98b0 2 years ago 79.1MB
(六)、容器数据卷
1.什么是容器数据卷
将应用环境打包成一个镜像!
如果数据都在容器中,那么我们容器删除,数据就会丢失!
需求:数据可以持久化。比如:Docker安装了MySQL,容器删除了,删库跑路
!需求:MySQL的数据可以存储在本地。容器之间可以有一个数据共享的技术!docker容器中产生的数据,同步到本地
。这就是卷技术
,目录的挂载,将容器内的目录挂载在Linux上面。
总结一句话:容器的持久化和同步操作,容器间也是可以数据共享的。
2.使用数据卷 【容器和主机挂载】💥
(1). 挂载centOS (1)
docker run -it -v 主机目录:容器的目录 #做映射 ------------------------------------------------------------- # docker run -it -v 主机目录:容器的目录 镜像 /bin/bash docker run -it -v /home/test:/home centos /bin/bash #挂载并启动 docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d6db1a46fdb4 centos "/bin/bash" 3 minutes ago Up 3 minutes heuristic_volhard 4aba86a517af portainer/portainer "/portainer" 2 hours ago Up 2 hours 0.0.0.0:8088->9000/tcp, :::8088->9000/tcp eager_agnesi
查看挂在信息
docker inspect d6db1a46fdb4 #查看
创建一个新的文件,查看是否双向绑定
[root@d6db1a46fdb4 home]# touch test.java #容器种创建一个文件
容器关机,在主机中进行修改文件在容器上也是可以同步的
容器的数据卸载了,但容器还在
以后我们修改只需要在主机中进行修改就好了。
(2).挂载MySql
docker pull mysql:5.7 #拉取镜像 docker images #查看镜像 # 运行MySql,需要做数据挂载,安装MySQL需要配置密码 -v 挂载 #可以挂载多个 -d 后台 -p 端口映射 -e MYSQL_ROOT_PASSWORD=AAA 密码 # 在启动成功后,我们在本地使用sqlyog来测试连接一下# sqlyog--连接到服务器3310---3310和容器内部的3306进行映射,这个时候我们就可以连接上了# 在本地测试新建一个数据库,查看一下我们映射的路径是否ok --------------------------------------------------------------- # 启动MySQL,并且把主机的3310映射到容器的3306端口 然后挂载 数据库的配置,和数据库的信息 docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 使用本地第三方数据库连接工具进行测试:navicat navicat 连接到服务器的3310,3310与容器内3306映射 所以可以访问
测试链接..
window下创建一个数据库,并在linux下同步
本地 把容器给删除了,但数据依然存在