镜像层由两部分组成:镜像层,容器层
镜像就是静态文件,和安装光盘类似,只有把镜像创建完容器以后,才能正常运行
镜像是只读的,容器创建完之后,所有的读写都是在容器内完成的,且每个容器内的读写都是独立且互不干扰
基于以上了解,展开关于dockerfile的构建过程:
FROM tomcat:latest
MAINTAINER 机构/人名
WORKDIR /webapps
ADD docker-web ./docker-web
以上四步,每步都会生成一个临时容器,临时容器相当于构建过程中的存档【且临时容器只能用于镜像的构建,不可做其他用途】,生成1个镜像存储,当更新dockerfile内容的时候,会发现已有的内容从缓存获取,新增的内容重新创建,然后旧有的内容 ,即临时的容器ID 会移除出去
体现docker特别重要的特点
第一个机制:按层堆叠;
最底层tomcat容器,后面每一步都会产生临时容器堆叠一起
第二个机制:采用系统快照;
以docker临时容器机制体现,每执行一步,都会产生一个临时容器,对当前状态有一个存档,在创建过程中是可以被重用的,比如前三步如果是一样的,则不需要重新处理,只需要将第四步重新构建,
好处:极大加速镜像构建速度,同时也为系统节约资源,如下:
1、在image里创建新的目录 mkdir docker_layer
cd docker_layer
编辑文件Dockerfile并保存:
vim Dockerfile
#以下文件内容: centos是docker官方提供的基准镜像,会在镜像内创建标准的centos容器
FROM centos
RUN["echo",'aaa']
RUN["echo",'bbb']
RUN["echo",'ccc']
RUN["echo",'ddd']
容器分层,如果没有变化,都是用的已有的,执行构建指令:
docker build -t wq.com/docker_layer:1.0
构建过程输出的内容,可以看出每个命令都生成一个临时容器,在本地就可以看到刚才构建的镜像,docker images
2、再次编辑并保存,vim Dockerfile
:
RUN["echo",'aaa']
RUN["echo",'bbb']
RUN["echo",'eee']
RUN["echo",'ffff']
构建:
docker build -t wq.com/docker_layer:1.0
发现前面三步,使用之前的临时镜像作为缓存,从缓存拿来用后面2步是新建的临时容器,然后移除之前的容器ID
镜像内部执行分层的镜像和原理:容器分层的时候,如果命令没有发生变化的步骤,都会使用已有的镜像,只会对发生变化的语句重新处理
FROM centos # 制作基准镜像(基于centos:latest)
FROM scratch # 不依赖任何基准镜像base image
FROM tomcat:9.0.22-jdk8-openjdkps:尽量使用官方提供的Base Image
MAINTAINER wq.com
LABEL version="1.0"
LABEL description ="testpro"
WORKDIR /usr/local
WORKDIR /usr/local/newdir #自动创建
ps:尽量使用绝对路径
ADD absd / #复制到根路径
ADD xxx.tar.gz / # 添加根目录并解压
ADD 除了复制,还具备添加远程文件功能
ENV JAVA_HOME /usr/local/openjdk8
RUN ${JAVA_HOME}/bin/java -jar test.jar
ps :尽量使用环境常量,可提高程序维护性
在build构建镜像时执行命令,一旦镜像构建完成,不允许被修改
ENTRYPOINT(入口点)用于在容器启动时执行命令
Dockerfile中只有最后一个ENTRYPOINT会被执行
推荐使用EXEC形式:ENTRYPOINT["ps"]
CMD默认命令:
CMD用于设置默认执行的命令
如Dockerfile中出现多个CMD,则只有最后一个被执行,如容器启动时附加指令,则CMD被忽略
推荐使用EXEC格式:CMD["ps","ef"]
linux底层有2种运行方式,所以Dockerfile有两种执行方式:
Run yum install -y vim
Shell运行方式:实用Shell执行时,当前shell是父进程,生成一个子shell进程在子shell中执行脚本。脚本执行完毕,退出子shell,回到当前shell。
RUN ["yum","install","-y","vim"]
Exec运行方式:使用Exec方式,会用Exec进程替换当前进程,并且保持PID不变执行完毕直接退出,并不会退回之前的进程环境
综合应用,官方推荐使用Exec执行命令格式 。
进入到image文件夹,
mkdir docker_run
cd docker_run
vim Dockerfile
编辑并保存内容:
FROM centos
RUN ["echo","image building !!!"]
CMD ["echo","containner starting!!!"]
进行构建:
docker build -t wq.com/docker_run .
启动容器:
docker run wq.com/docker_run
执行构建和启动容器命令后,可以看出来,cmd命令是默认启动容器会执行
启动容器:
docker run wq.com/docker_run ls
修改dockerfile内容:
FROM centos
RUN ["echo","image building !!!"]
ENTRYPOINT ["echo","containner starting!!!"]
保存后,重新构建:
docker build -t wq.com/docker_run .
重启:docker run wq.com/docker_run
与上面输出内容无差异
修改dockerfile内容:
FROM centos
RUN ["echo","image building !!!"]
ENTRYPOINT ["ps"]
CMD ["-ef"]
保存后,重新构建:
docker build -t wq.com/docker_run .
重启:docker run wq.com/docker_run
与上面输出内容无差异
这样写的好处是cmd可以从外部传参:
重启:docker run wq.com/docker_run -aux
输出内容更加完整