Docker镜像
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境并且打包基于运行环境开发的软件 unionfs —> bootfs —>rootfs
1. 联合文件系统(UnionFS)
-
UnionFS是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,UnionFS是docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。 -
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
2. docker镜像加载原理
docker的镜像实际上是由一层层的文件系统组成,这种层级的文件系统就是UnionFS
-
bootfs(boot file system)主要包含bootloader和kernel(内核) -
bootloader主要是引导加载kernel(内核),Linux刚启动的时候会加载bootfs文件系统,在docker镜像的最底层是bootfs。当boot加载完成后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。 -
rootfs(root file system),在bootfs之上,包含的是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,如Ubuntu、CentOS等。
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就行了。所以对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以共用bootfs。
3. 镜像的特点和优点
(1) 镜像的特点(只读)
- docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的为“镜像层”。
(2) 分层镜像的优点
- 使用分层镜像可以共享资源
- 比如有多个镜像都从相同的base镜像构建而来,那么宿主机上只需要保存一份base镜像,内存中也只需要加载一份base镜像,就可以为所有容器服务了。镜像的每一层都可以被共享。
- 以pull为例,在下载的过程中可以看到docker的镜像好像是在一层一层的在下载。
4. 镜像提交
(1) 提交命令
- docker commit 提交容器副本使之成为一个新的镜像
- docker commit -m=“提交的描述信息” -a=“作者” 容器名 要创建的目标镜像名:[TAG]:提交容器副本使之成为一个新的镜像
(2) 镜像提交实例
- docker run -it -p 8081:8080 tomcat:从hub上下载tomcat镜像到本地并运行
- 暴露端口自己随便起
- docker run -it -P tomcat
- 用P会随机给一个端口 通过 docker ps 查看 port
- 故意删除上一步镜像生产tomcat容器的文档
- docker commit -m=“del tomcat docs” -a=“zzyy” xxxx atguigu/tomcat/02:1.2:以它为模板提交一个没有文档的tomcat新镜像atguigu/tomcat02
分别启动两个镜像就发现,提交的镜像不存在文档 —> 提交容器副本使之成为一个新的镜像
容器数据卷
将docker容器运行产生的数据进行持久化,用卷持久化,共享数据
数据卷
2. 容器内添加数据卷
(1) 直接命令添加
-
docker run -it -v /宿主机绝对路径 : /容器内目录 : ro 镜像名 . -
docker run -it -v /mydataVolume:/dataVolumeContainer --privileged=true centos /bin/bash -
v : volume 容积 -
ro : read only 只读 宿主机可修改 -
没有权限在目录后加上 --privileged=true -
将宿主机目录和容器目录绑定,实现宿主机与容器同步。容器每次启动后会将同步数据。 -
docker inspect 容器名:查看数据卷是否挂载成功,其中Volumes里面有绑定的目录 -
inspect 检查 -
容器和宿主机之间数据共享 -
容器停止后,宿主机修改数据是否同步
(2) dockerFile添加
dockerFile是镜像的描述文件
-
根目录下新建mydocker文件夹并进入 -
VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"] -
dockerFile中能使用volume指令来给镜像添加一个或多个数据卷 -
vi dockerfile:File构建
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bash
-
docker build -f /mydocker/dockerfile -t lll/centos . -
build后生成镜像,获得一个新镜像lll/centos , -t 命名空间 ,. 在当前目录下 -
docker run -it lll/centos: -
运行容器,容器内自带两个容器数据卷,对应的宿主机的目录默认,可以通过docker inspect查看
3.数据卷容器
移动硬盘上挂移动硬盘,实现数据的传递依赖
–volumes-from 数据间传递共享
1.主机
docker run -it --name dc01 lll/centos
ls -l
cd dataVolumeContainer2
ls
touch dc01_add txt
ctrl + p + q 退出
dc02 ,dc03 继承 dc01
docker run -it --name dc02 --volumes-from dc01 lll/centos touch dc02_add txt docker run -it --name dc03 --volumes-from dc01 lll/centos 退出 进入dc01 说明:即达到了共享,也达到了传递的目的
接下来:删除dc01 docker rm -f dc01 修改dc02 touch dc02_update.txt 进入dc03 结论:容器之间配置信息的传递,数据卷的声明周期一直持续到没有容器使用它为止
docker file
dockerfile 操作步骤
- 1.dicker file 是用来构建docker·镜像的文件
每条指令都会创建新的镜像层并对镜像进行提交
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bash
- 2.三步骤:编写dockerfile文件,docker build , docker run
保留字指令
from 类似extends , scratch 抓痒痒这个是(base)元镜像
maintainer 镜像维护者的姓名和邮箱地址
run
expose 暴露 对外端口
workdir 创建容器后,默认的工作夹,登录之后的落脚点
env 设置环境变量
add 拷贝+解压
copy src 拷贝 1. copy src dest 2. copy [ "src", "dest" ]
volume 容器数据卷 用来保存数据和持久化
cmd 指定容器运行时的命令
1. shell格式: cmd<命令> 2. exec 格式: cmd[ "可执行文件" , "参数1" , "参数2" ]
2. 最后一行生效,会覆盖之前的命令
3. cmd 会被docker run 之后的参数替换
entrypoint 和cmd一样,不会被替换,但是会追加
onbuild 触发器 父镜像在被子镜像继承后触发
自定义镜像mycentos:
docker rm -f $(docker ps -q) 删除所有运行的container , -q 查出 container ID,用id进行批量删除
ifconfig: linux 命令 查看ip配置
FROM centos MAINTAINER lll1787293713@qq.com
ENV MYPATH /usr/local WORKDIR $MYPATH
RUN yum -y install vim RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH CMD echo “success--------ok” CMD /bin/bash
cat dockerfile2 查看文件
docker build -f /mydocker/dockerfile2 -t mycentos:1.3 . 运行文件
docker history xxxx 列出镜像变更历史
dockerfile模板
FROM centos
MAINTAINER zuzhiang<zuzhiang@126.com>
# 把宿主机当前上下文的c.txt靠背巾容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
# 把javahetomcat添加到容器内
ADD jdk-8u171-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.8.tar.gz
# 安装vim编辑器
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置java和tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 容器运行时的监听的端口
ENVEXPOSE 8080
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh"]
# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
总结
|