Docker镜像讲解
镜像是什么
镜像是一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时,库,环境变量和配置文件。
所有的应用,直接打包docker镜像,就可以直接跑起来!
镜像原理之联合文件系统
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)
联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率
特点
Docker镜像都是可读的,当容器启动时,一个新的可写层被加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层
如何提交一个自己镜像
Commit镜像
docker commit 提交容器成为一个新的副本
#命令和git原理类似
docker commit -m "提交的描述信息" -a="作者" 容器id 目标镜像名, [TAG]
实战测试
#1.启动一个默认的tomcat
#2.发现这个默认的tomcat是没有webapps应用,镜像的原因,官方的默认的webapps下面是没有文件的!
#3.我自己拷贝进去了基本文件
#4.将我们操作过的容器通过commit提交为一个镜像!我们以后便可以使用修改过后的镜像
如果想要保存当前容器的状态,就可以通过commit来提交,获得一个镜像
容器数据卷
docker理念回顾
将应用和环境打包成一个镜像
数据?如果数据都在容器中,那么容器一删除,数据就会丢失!需求数据可以持久化
MySQL,容器删除了,删库跑路 需求:MySQL的数据可以存储在本地
容器之间可以有一个数据共享的技术! Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面
总结一句话:容器持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
方式一
#直接使用指定目录来挂载
docker run -it -v 主机目录:容器内目录
#测试
[root@localhost /]# docker run -it -v /home/ceshi:/home centos /bin/bash
#启动起来之后我们可以通过docker inspect 容器id 查看详细信息
测试文件的同步:容器内到宿主机
再来测试:宿主机到容器内
#1.停止容器
docker stop 容器id
#2.宿主机上修改文件
比如创建一个文件
#3.再次启动容器
docker restart 容器id
#4.容器内的数据依旧是同步的
好处:我们以后修改只需要在本地修改,容器内会自动同步
实战:安装MySQL
思考:MySQL的数据持久化问题
#获取镜像
[root@localhost ceshi]# docker pull mysql:5.7
#运行容器,需要数据挂载 #安装启动mysql,需要配置密码的,这里要注意点!
#官方测试:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#启动mysql
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
1.cd / & mkdir dockemysql
2.cd dockermysql & mkdir conf & mkdir data
3.我们自己在/dockermsyql/conf目录下创建my.cnf然后写入下面内容:vim my.cnf
内容为:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf8mb4
[root@localhost /]# docker run -d -p 3310:3306 -v /dockermysql/conf:/etc/mysql/conf.d -v /dockermysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql01 mysql:5.7
#启动成功之后,我们在本地使用navicat连接测试成功
#navicat连接到服务器的3310 ---3310和容器内的3306映射,这个时候我们就可以连接上了
#在navicat上创建一个数据库,查看一下我们映射的路径是否ok!
假设我们将容器删除
发现我们挂载到本地的数据卷依旧没有丢失,这就实现了容器的持久化
具名和匿名挂载
#匿名挂载
-v 容器内路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有的volume的情况
[root@localhost data]# docker volume ls
local 2b7d2ce3f506e439471471f4e42289907257cca9fcef5813320db5f93b541edd
#这里发现,这种匿名挂载,我们在-v的时候只写了容器内的路径,没写容器外的路径
#具名挂载,这里的juming不是代表一个路径,如果加了一个/则代表路径
[root@localhost data]# docker run -d -P --name nginx03 -v juming:/etc/nginx nginx
[root@localhost data]# docker volume ls
local juming
#通过-v 卷名:容器内路径
#查看一下这个卷的位置
docker volume inspect juming 或者 docker volume 容器id
所有的docker容器内的卷,没有指定目录的情况下都是在目录“/var/lib/docker/volumes/xxxx/_data”下
我们通过具名挂载可以方便的找到我们一个卷,大多数情况下都使用具名挂载
#如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
拓展:
#通过-v 容器内的路径:ro rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写
#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的,默认是可读可写
初识Dockerfile⭐
Dockerfile就是用来构建docker镜像的构建文件!命令脚本
通过这个脚本可以生成镜像,镜像是一层一层
方式二
#创建一个dockerfile文件,名字可以随机 建议dockerfile
#文件中的内容 指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
#这里的每个命令就是镜像的一层
#启动自己写的容器
docker run -it 容器id /bin/bash
#查看目录
ls -l
查看卷挂载的路径
docker insepect 容器id
#在构建镜像的时候,并没有指定挂载名,因此是匿名挂载
这种方式未来使用的十分多,因为我们通常会构建自己的镜像!⭐
假设构建镜像时候没有挂载卷,要手动镜像挂载卷 -v 卷名:容器内路径!⭐