1. Docker镜像原理
1.1 什么是镜像
镜像时一种轻量级,可执行的独立软件包,用来打包软件运行环境和基于运行运行环境开发的软件,包含某个软件运行时需要的代码,环境,库等等。(用Java来说就是:在Java中我们通常将我们的代码打包成jar包来发布运行,而镜像你可以理解为:jar包+运行环境=镜像)。
镜像的常见来源为:1. docker Hub拉取,2.别人提供,3.自己打包
1.2 镜像加载原理
1.2.1 联合文件系统
联合文件系统(UnionFS),是Linux系统的一个亮点,它是一种分层,轻量级而且高性能的文件系统,它可以支持对文件系统的修改作为一次次提交来一层层叠加,同时可以将不同目录挂载到同一个文件系统下来统一管理,可以很大的节省资源。docker镜像基础就是联合文件系统,在docker里面,我们的镜像可以通过分层来继承,基于基础镜像,我们可以创建很多自己的镜像。(注意:docker没有父镜像)
docker镜像是基于联合文件系统设计的,所以镜像其实是由一层一层的文件系统组成的。如上图所示:bootfs主要包含了BootLoader和kernel,前者主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,而我们的镜像也是这个样子的,包含boot加载器和内核。当boot加载器加载完成后,内核就在内存中了,此时内存的使用权就开始由kernel管理,bootfs就会被卸载。(你可以理解为:bootfs只是用来加载内核的,加载完后就被卸载掉了)
rootfs在bootfs上面,主要包含了典型Linux系统中的一些文件,如:/dev/,/etc/订单,rootfs就是不同操作系统发行版,如:CentOS,Ubuntu等等。
1.2.2 镜像分层加载原理
如上图所示:docker镜像第一层有三个文件(镜像),第二层也有三个,看起来只有三层,实际上他有7层,上层的文件覆盖了底层镜像的文件,这样子我们就可以在原有的镜像上再次打包成一个我们自己的镜像。docker利用存储引擎(快照机制)的方式来实现镜像层堆栈,并保证7层的镜像文件对外展示为一个统一的文件系统。
1.2.3 commit镜像
docker commit [可选参数] 容器id 新生成的镜像名 #这个容器id是已经修改完的容器的id
2. DockerFile镜像构建
DockerFile是一个用来构建镜像的一个文件,里面的内容是一些命令参数脚本,使用相关的脚本可以分层的来构建出我们的镜像。
构建步骤:
- 编写dockerfile脚本文件
- docker build 构建一个镜像
- docker run 运行镜像生成容器
- docker push 发布镜像(阿里云镜像仓库,DockerHub)
2.1 常用命令
DockerFile指令全部都是大写的
- FROM: 设置镜像的基础镜像,因为docker镜像是分层构建的,所以在构建一个镜像时可以选择一个基础镜像,在基础镜像中继续构建,生成我们想要的镜像
- MAINTAINER: 标明镜像的作者,一般是:姓名<邮箱>
- RUN:镜像构建时需要运行的命令,这个命令一般是在镜像构建时执行
- CMD:指定启动容器时要运行的命令,一般在容器容器启动时执行,用来指定启动容器时默认执行的一个命令,这个命令会覆盖,所以当docker run携带参数时,这个命令会被docker run所携带的命令替换
- LABEL: 设置镜像的标签,就比如tag一样
- EXPOSE: 设置镜像暴露的端口,可以让别人访问
- ENV: 设置镜像的环境变量,比如你构建镜像时需要用到JDK,那么就可以用ENV来指定JDK的一些配置信息
- ADD: 在镜像中添加一些东西,比如:JDK的压缩包,tomcat的压缩包等等
- COPY: 跟ADD指令类似,都是在镜像中加东西,但COPY更偏向于复制一个文件,比较小一点的
- ENTRYPOINT:指定启动容器时要运行的命令,和CMD类似,但ENTRYPOINT 不能被 docker run 提供的参数覆盖,会直接被追加命令
- VOLUME: 设置挂载卷,和docker run -v类似
- USER: 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户当服务不需要管理员权限时,可以通过该命令指定运行用户这个用户必须是事先建立好的,否则无法切换,如果没有指定 USER,默认是 root 身份执行
- WORKDIR: 设置镜像的工作目录,可以让我们进入容器时自动进入到该目录
- ARG: ARG指令在build 阶段指定变量,和ENV不同的是,容器运行时不会存在这些环境变量,如果和ENV同名,ENV覆盖ARG变量
- ONBUILD: 可以用来配置当构建当前镜像的子镜像时,会自动触发执行的指令,但在当前镜像构建时,并不会执行,即延迟到子镜像构建时才执行
2.2 构建一个Tomact镜像
#前提:准备tomcat,jdk压缩包
#1.编写dockerFile文件
#设置基础镜像
FROM centos
#设置镜像作者
MAINTAINE ljm<11111@.com>
#添加jdk压缩包到镜像(第一个是jdk路径,第二个是放jdk的容器位置,ADD可以帮我们自动解压)
ADD /home/jdk.tar /user/loacl
#添加tomcat压缩包到镜像()
ADD /home/tomcat.tar /user/loacl
#添加镜像基本命令()
RUN yun -y install vim
#设置工作路径
ENV MYPATH /user/home
WORKDIR $MYPATH
#配置相关配置,如:jdk,tomcat(和我们平常在Linux配置一样)
ENV JAVA_HOME /user/local/jdk1.8
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /user/local/apache-tomcat
ENV CATALINA_BASH /user/local/apache-tomcat
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#暴露端口
EXPOSE 8080
#设置启动容器时,自动启动我们的tomcat
CMD /user/local/apache-tomcat/bin/startup.sh
#2.构建镜像(当dockerfile文件名为DockerFiel时,会自动去找我们的文件)
docker build -t 镜像名 .
#3.启动镜像(和我们平常运行一样)
docker run -d -it -p -v 镜像名
2.3 镜像发布
#1.发布到dockerhub(已经注册)
docker login -u 用户名 #登录docker
docker push 作者名(用户名)/镜像:标签 #发布镜像