【docker笔记】DockerFile

DockerFile

Docker镜像结构的分层

镜像不是一个单一的文件,而是有多层构成。

容器其实是在镜像的最上面加了一层读写层,在运行容器里做的任何文件改动,都会写到这个读写层。

如果删除了容器,也就是删除了其最上面的读写层,文件改动也就丢失了。

Docker使用存储驱动管理镜像像每层内容及可读可写的容器层

  • Dockerfile中的每个指令都会创建一个新的镜像层
  • 镜像层将被缓存和复用
  • 当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效。
  • 某一层的镜像缓存失效,它之后的镜像层缓存都会失效
  • 镜像层是不可变的,如果在某一层中添加一个文件,然后在一层中删除它,则镜像中依然会包含该文件,只是这个文件在Docker容器中不可见了

DockerFile构建过程解析

【docker笔记】DockerFile_第1张图片
官网:https://docs.docker.com/engine/reference/builder/

构建三步骤

1、编写DockerFile文件
2、docker build命令构建镜像
3、docker run 依镜像运行容器实例

从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段

Dockerfile是软件的原材料

Docker镜像是软件的交付品

Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。

【docker笔记】DockerFile_第2张图片

Docker执行DockerFile的大致流程

  1. docker从基础镜像运行一个容器
  2. 执行一条指令对容器做出修改
  3. 执行类似docker commit 的操作提交一个新的镜像层
  4. docker 在基于刚提交的镜像运行一个新容器
  5. 执行dockerfile中的下一条指令直到所有执行执行完成。

DockerFile内容基础知识

  1. 每条保留字指令都必须为大写字母且后面跟随至少一个参数
  2. 指令按照从上到下,顺序执行
  3. #表示注释
  4. 每条指令都会创建一个新的镜像层并对镜像进行提交。

DockerFile常用保留字指令

参考tomcat8的dockerfile入门

From
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from

MANINTAINER
镜像维护者的姓名和邮箱地址

Run
容器构建时需要运行的命令,RUN是在docker build时运行
两种格式:
1.shell格式
<命令行命令>等同于,在终端操作的shell命令
RUN yum -y install vim

2.exec格式

【docker笔记】DockerFile_第3张图片

EXPOSE
当前容器对外暴露出的端口

WORKDIR
指定在创建容器后。终端默认登录的进来工作目录,一个落脚点。

USER
指定该镜像以什么样的用户去执行,如果都不指定,默认是root

ENV
用来在构建镜像过程中设置环境变量

ENV MY_PATH /usr/mytest 

这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样,
也可以在其它指令中直接使用这些环境变量, 比如:WORKDIR $MY_PATH

ADD
将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包

COPY
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层镜像内的<目标路径>位置

COPY src dest
COPY["src","dest"]
<src源路径>:源文件或源目录
<dest目标路径>: 容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

VOLUME
容器数据卷,用于数据保存和持久化的工作

CMD
指定容器启动时的要干的事情。
Dockerfile 中可以由多个CMD指令,但是只有最后一个生效,CMD会被 docker run 命令行参数中指定要运行的程序所覆盖。

他和前面RUN命令的区别 CMD 是在 docker run 时运行。 RUN 是在docker build 时运行

ENTRYPOINT
类似于CMD指令,但是ENTRYPOINT不会被docker run 后面的命令覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序

命令格式:ENTRYPOINT[" < executeable >","< param1 >","< param2 >",...]

ENTRYPOINT 可以和CMD一起用
一般是变参才会使用 CMD ,这里的CMD等于是在给 ENTRYPOINT 传参
当制定了ENTRYPOINT 后,CMD的含义就发生了变化,不再是直接运行其命令而是将 CMD 的内容作为参数传递给 ENTRYPOINT指定,他两个组合会变成< ENTRYPOINT > “< CMD >”

优点:在执行docker run 的时候可以指定 ENTRYPOINT 运行所需的参数
注意:如果Dockerfile 中如果存在多个ENTRYPOINT 指令,仅最后一个生效。

假设已通过 Dockerfile 构建了 nginx:test 镜像:

FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参 
CMD ["/etc/nginx/nginx.conf"] # 变参 

1、不传参运行 $ docker run nginx:test
容器内会默认运行以下命令,启动主进程。

nginx -c /etc/nginx/nginx.conf 

2、传参运行 $ docker run nginx:test -c
/etc/nginx/new.conf 容器内会默认运行以下命令,启动主进程(/etc/nginx/new.conf:假设容器内已有此文件)

nginx -c /etc/nginx/new.conf

Docker之docker run参数覆盖Dockerfile中CMD命令以及CMD与ENTRYPOINT的区别

明确docker run指令中的参数是什么?
docker run 指令(-it/-p/-d等) 镜像名 参数(/bin/sh、bash等)
即docker run命令中,镜像名后面的都是给容器执行的命令参数

举例说明docker run参数覆盖Dockerfile中CMD命令的情况

【docker笔记】DockerFile_第4张图片

举例说明docker run参数覆盖Dockerfile中ENTRYPOINT命令的情况

【docker笔记】DockerFile_第5张图片

案例

自定义镜像mycentosjava8

要求Centos7镜像具备 vim + ifconfig + jdk8

JDK下载镜像地址
官网:https://www.oracle.com/java/technologies/downloads/#java8
https://mirrors.yangxingzhen.com/jdk/

构建Dockerfile

FROM centos
MAINTAINER mzr
  
ENV MYPATH /usr/local 
WORKDIR $MYPATH 
  
#安装vim编辑器 
RUN yum -y install vim 
#安装ifconfig命令查看网络IP 
RUN yum -y install net-tools 
#安装java8及lib库 
RUN yum -y install glibc.i686 
RUN mkdir /usr/local/java 
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置 
ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/ 
#配置java环境变量 
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171 
ENV JRE_HOME $JAVA_HOME/jre 
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH 
ENV PATH $JAVA_HOME/bin:$PATH 
  
EXPOSE 80 
 
CMD echo $MYPATH 
CMD echo "success--------------ok" 
CMD /bin/bash

使用Dockerfile构建镜像

docker build -t 新镜像名字:TAG .

例如:docker build -t centosjava8:1.5 .

#【注意】上面TAG 后面有个空格,有个点

运行镜像

docker run -it 新镜像名字:TAG

例如:docker run -it centosjava8:1.5 /bin/bash

虚悬镜像

仓库名,标签都是 < none > 的镜像,俗称dangling image

构建Dockerfile

from ubuntu
CMD echo 'action is sucdess'

构建

docker build .

查看

docker image ls -f dangling=true

虚悬镜像已经失去存在价值,可以删除

docker image prune 

myubuntu

构建Dockerfile

FROM ubuntu
MAINTAINER zzyy<[email protected]> 
  
ENV MYPATH /usr/local 
WORKDIR $MYPATH 
  
RUN apt-get update 
RUN apt-get install net-tools 
#RUN apt-get install -y iproute2 
#RUN apt-get install -y inetutils-ping 
  
EXPOSE 80 
  
CMD echo $MYPATH 
CMD echo "install inconfig cmd into ubuntu success--------------ok" 
CMD /bin/bash 

使用Dockerfile构建镜像

docker build -t 新镜像名字:TAG .

例如:docker build -t myubuntu:1.0 .

#【注意】上面TAG 后面有个空格,有个点

运行镜像

docker run -it 新镜像名字:TAG

例如:docker run -it myubuntu:1.0 /bin/bash

你可能感兴趣的:(docker,docker)