设为首页 收藏本站
查看: 1347|回复: 0

[经验分享] docker_基础_DockerFile

[复制链接]

尚未签到

发表于 2019-2-22 07:42:08 | 显示全部楼层 |阅读模式
  ps:接上篇

利用 Dockerfile 定制镜像

1、Dockerfile概述
    镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是Dockerfile
   Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建.
   Dockfile是由一行行命令语句组成,并且迟滞以#开头的注释行;一般而言,Dockerfiel分为四部分:1.基础镜像信息 ;2.维护者信息;3.镜像操作指令;4.容器启动时指令,例如

配置第一个dockerfile文件
$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile
内容:
# this is dockerfile uses the nginx images
# VERSION 1 - EDITON 1
# Author: docker
#base image the use
FROM nginx
# maintainer: docker_user
MAINTAINER docker_user docker_user@docker.com
RUN echo ' hello,docker! ' > /usr/share/nginx/html/index.html
1.1、FROM 指定基础镜像
    所谓定制镜像,那一定是以一个镜像为基础,在其上进行定制,基础镜像是必须指定的。而 FROM 就是指定基础镜像,因此一个 Dockerfile 中 FROM 是必备的指令,并且必须是第一条指令
  除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch 。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像

            FROM scratch
    如果你以 scratch 为基础镜像的话,意味着你不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。
  不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见,比如swarm 、 coreos/etcd 。对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 FROM scratch 会让镜像体积更加小巧。使用 Go 语言 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go是特别适合容器微服务架构的语言的原因之一

1.2、RUN 执行命令
    RUN 指令是用来执行命令行命令的。由于命令行的强大能力, RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:
  shell 格式: RUN  ,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
  例如:RUN echo "123" > /tmp/1.txt
    exec 格式: RUN ["可执行文件", "参数1", "参数2"] ,这更像是函数调用中的格式
    Dockerfile 中每一个指令都会建立一层, RUN 也不例外。每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后, commit 这一层的修改,构成新的镜像.
  Union FS 是有最大层数限制的,比如 AUFS,曾经是最大不得超过 42 层,现在是不得超过127 层
    因此,这里没有使用很多个 RUN对应一一不同的命令,而是仅仅使用一个 RUN 指令,并使用 && 将各个所需命令串联起来, 在撰写 Dockerfile 的时候,要经常提醒自己,这并不是在写 Shell 脚本,而是在定义每一层该如何构建

比如 RUN yum -y install nginx \
&& echo "hello docker" > /usr/share/nginx/html/index.html\
&& RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf \
CMD /usr/bin/nginx
     Dockerfile 支持 Shell 类的行尾添加 \ 的命令换行方式,以及行首 # 进行注释的格式。良好的格式,比如换行、缩进、注释等,会让维护、排障更为容易,这是一个比较好的习惯


1.3、构建镜像
    语法: docker build [选项]


[root@docker mynginx]# docker build -t nginx:v4 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx
---> 7f70b30f2cc6
Step 2/2 : RUN echo ' hello,docker! ' > /usr/share/nginx/html/index.html
---> Running in 065c3e52b540
Removing intermediate container 065c3e52b540
---> 3d80dfa73097
Successfully built 3d80dfa73097
Successfully tagged nginx:v4
[root@docker mynginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
nginx               v4                  3d80dfa73097        About a minute ago   109MB
运行   以后台方式运行 名称为test 端口映射80:80
$ docker run -dit --name test -p 80:80 nginx:v4


第一个例子,使用centos基础镜像安装nginx环境,从而创建一个新的nginx


1.4、镜像构建上下文(Context)
    build 构建时最后带的那个. 并不是指定Dockerfile所在的路径,这样理解是不正确的,如果对应上面的命令格式,这其实是在指定上下文路径,那么什么是上下文呢?

    首先我们要理解docker build 工作原理: Docker 在运行时分为 Docker 引擎(也就是服务端守护进程)和客户端工具。Docker 的引擎提供了一组 REST API,被称为 DockerRemote API,而如 docker 命令这样的客户端工具,则是通过这组 API 与 Docker 引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种 docker 功能,但实际上,一切都是使用的远程调用形式在服务端(Docker 引擎)完成。也因为这种 C/S 设计,让我们操作远程服务器的 Docker 引擎变得轻而易举。
    而 docker build 命令构建镜像,其实并非在本地构建,而是在服务端,也就是 Docker 引擎中构建的。那么在这种客户端/服务端的架构中,如何才能让服务端获得本地文件呢?
    这就引入了上下文的概念。当构建的时候,用户会指定构建镜像上下文的路径, docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。这样Docker 引擎收到这个上下文包后,展开就会获得构建镜像所需的一切文件


  一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下。如果该目录下没有所需文件,那么应该把所需文件复制一份过来。如果目录下有些东西确实不希望构建时传给 Docker 引擎,那么可以用 .gitignore 一样的语法写一个.dockerignore ,该文件是用于剔除不需要作为上下文传递给 Docker 引擎的,如果在根目录下直接build -t name .的话 会将整个系统都打包给docker容器.

    直接指定. 构建的时候默认行为就是直接指定的Dockerfile文件,当然也可以指定别的文件做为构建参数, 比如 -f test.txt, 当然大家最好还是习惯性使用默认文件名Dockerfile。

1.5、Docker build的其它用法


  • 直接使用Git repo进行构建

使用该方法老报错,我们可以给它先下载到本地,然后再build
$ docker build https://github.com/twang2218/gitlab-ce-zh.git#:10.6
$ git clone https://github.com/twang2218/gitlab-ce-zh.git
$ docker build -t name .
    这行命令指定了构建所需的 Git repo,并且指定默认的 master 分支,构建目录为 /8.14/ ,然后 Docker 就会自己去 git clone 这个项目、切换到指定分支、并进入到指定目录后开始构建。
  2、用给定的tar压缩包构建

[root@docker ~]# mkdir mytar
[root@docker ~]# cd mytar/
\#内容如下
FROM nginx
RUN echo "test tar images" > /usr/share/nginx/html/index.html \
&& echo "test" > /tmp/1.txt
注意这里得直接打包 $ tar mytar.tar.gz Dockerfile
docker build -t test/nginx:v4.1 - < mytar.tar.gz
Sending build context to Docker daemon     208B
Step 1/2 : FROM nginx
---> 7f70b30f2cc6
Step 2/2 : RUN echo "test tar images" > /usr/share/nginx/html/index.html     && echo "test" > /tmp/1.txt
---> Running in a8f2b14e8576
Removing intermediate container a8f2b14e8576
---> d5398275b4d7
Successfully built d5398275b4d7
Successfully tagged test/nginx:v4.1
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
test/nginx          v4.1                d5398275b4d7        4 seconds ago       109MB

     如果发现标准输入的文件格式是 gzip 、 bzip2 以及 xz 的话,将会使其为上下文压缩包,直接将其展开,将里面视为上下文,并开始构建。


2、COPY 复制文件
     和 RUN 指令一样,也有两种格式,一种类似于命令行,一种类似于函数调用

  语法:

    COPY ...
COPY ["",... ""]
比如:
COPY package.json /usr/src/app/
也可以是多个,甚至是通配符
COPY home* /usr/src/app/
COPY hom?.txt /usr/src/app/
      可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录

例如:
Dockerfile内容
FROM centos
WORKDIR /usr/local/app/
COPY a* ./
$ docker build -t filetest/test .
Sending build context to Docker daemon  3.584kB
Step 1/3 : FROM centos
---> 2d194b392dd1
Step 2/3 : WORKDIR /usr/local/app/
Removing intermediate container 7fc63b9b6c51
---> f5bd6a0a5ba8
Step 3/3 : COPY a* ./
---> 738d1c5a877a
Successfully built 738d1c5a877a
Successfully tagged filetest/test:latest
[root@docker mytar]# docker run -it --rm filetest/test /bin/bash
[root@b043e7420357 app]# ls
a  ab  ac
     此外,还需要注意一点,使用 COPY 指令,源文件的各种元数据都会保留。比如读、写、执行权限、文件变更时间等。这个特性对于镜像定制很有用。特别是构建相关文件都在使用 Git进行管理的时候。


3、ADD 更高级的复制文件
  ADD 指令和 COPY 的格式和性质基本一致。但是在 COPY 基础上增加了一些功能。

     比如  可以是一个URL,docker会试图下载这个链接的文件放到,权限默认为600,如果想调整需要在增加一层RUN,另外如果是压缩文件还需要额外增加一层RUN进行解压缩, 不如直接使用wget 处理权限来的直接,因此这个功能其实不实用,而且不推荐使用。
   如果  为一个 tar 压缩文件的话,压缩格式为 gzip , bzip2 以及 xz 的情况下, ADD 指令将会自动解压缩这个压缩文件到  去。但在某些情况下,如果我们真的是希望复制个压缩文件进去,而不解压缩,这时就不可以使用 ADD 命令
   因此在 COPY 和 ADD 指令中选择的时候,可以遵循这样的原则,所有的文件复制均使用COPY 指令,仅在需要自动解压缩的场合使用 ADD


4、CMD
     启动容器时默认执行的命令,每个Dockerfile只能有一条CMD命令,如果指定多条,只有最后一条会被执行。

  CMD 指令的格式和 RUN 相似,也是两种格式:
shell 格式: CMD
exec 格式: CMD [&quot;可执行文件&quot;, &quot;参数1&quot;, &quot;参数2&quot;...]
参数列表格式: CMD [&quot;参数1&quot;, &quot;参数2&quot;...] 。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
   之前介绍容器的时候曾经说过,Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。 CMD 指令就是用于指定默认的容器主进程的启动命令的。
   在指令格式上,一般推荐使用 exec 格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 &quot; ,而不要使用单引
   如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:

     CMD echo $HOME
  在实际执行中,会将其变更为:

   CMD [ "sh", "-c", "echo $HOME" ]
  注意:Docker 不是虚拟机,容器中的应用都应该以前台执行,对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西

  例如: 使用from run cmd copy 制造一个nginx镜像
先下载一个nginx yum源到构造的目录下  http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
[root@dockers nginx]# cat Dockerfile
# this Docker file use centos images
# Version 1
# Author: xiong
# Base image to used
FROM centos
COPY nginx.repo /etc/yum.repos.d/
# configure nginx start to Reception
RUN yum install -y nginx \
&& echo "hello my frist dockerfile" > /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建一个镜像 名称为centos/nginx:v1
[root@dockers nginx]# docker build -t centos/nginx:v1 .
查看镜像是否构建完成
[root@dockers nginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
centos/nginx        v1                  68c6fc13188a        23 seconds ago      302MB
测试并启动镜像
[root@dockers nginx]# docker run -dit -p 80:80 --name web centos/nginx:v1



5、ENTRYPOINT
     指定镜像的默认入口命令,该入口会在启动容器时做为根命令执行,所有传入值作为该命令的参数。

  ENTRYPOINT 的格式和 RUN 指令格式一样,分为 exec 格式和 shell 格式。

exec语法 ENTRYPOINT ["executable","param1","param2"] (exec调用执行);
shell语法ENTRYPOINTcommand param1 param2 (shell执行)
     ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数,当指定了 ENTRYPOINT 后, CMD 的含义就发生了改变,不再是直接的运行其命令,而是将CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:

""
例如:使用CMD查询自己本地的IP
[root@dockers curl]# cat Dockerfile
FROM centos
COPY local.repo /etc/yum.repos.d/
RUN yum -y install curl \
&& rm -rf /etc/yum.repos.d/local.repo
CMD [ "curl","-s", "https://ip.cn" ]
构建它
[root@dockers curl]# docker run centos/curl:v1
运行
[root@dockers curl]# docker run centos/curl:v1
当前 IP:1.1.1.1 来自:北京市 xx
     看起来好像可以直接当成命令使用,但是命令总归有参数,直接运行上面命令,它在构建完成最后一步的时候已经处理完成了,所以增加参数也没有任何效果

如果直接这样运行,那么镜像中指定的CMD命令就被覆盖了
docker run centos/curl  curl -i https://ip.cn
而使用ENTRYPOINT就可以解决这个问题
[root@dockers entry]# cat Dockerfile
FROM centos
COPY local.repo /etc/yum.repos.d/
RUN yum -y install curl \
&& rm -rf /etc/yum.repos.d/local.repo
ENTRYPOINT [ "curl","-s", "https://ip.cn" ]
执行也是同样的效果了
docker run enrty
当前 IP:1.1.1.1 来自:北京市 xx
这里我们来查询Http头部信息
[root@dockers curl]# docker run enrty -i
HTTP/1.1 200 OK
Date: Wed, 04 Apr 2018 06:38:35 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=db95eb1f0c8b7f59fe0bba7e8b8979ae31522823915; expires=Thu, 04-Apr-19 06:38:35 GMT; path=/; domain=.ip.cn; HttpOnly
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 4061c5e2ecb52882-SJC
     这是因为当存在 ENTRYPOINT 后, CMD 的内容将会作为参数传给ENTRYPOINT ,而这里 -i 就是新的 CMD ,因此会作为参数传给 curl
   这里就相当于ENTRYPOINT exec语法  ENTRYPOINT ['exectable','param1','param2']
executable 命令不动,将param1 param2的值 做为可传递参数进行修改。


docker run enrty -i http://www.baidu.com
HTTP/1.1 200 OK
Date: Wed, 04 Apr 2018 06:39:40 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d1ba6914d20dc0b50f785572c21994a551522823980; expires=Thu, 04-Apr-19 06:39:40 GMT; path=/; domain=.ip.cn; HttpOnly
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 4061c7732e8392ee-SJC

6、ENV环境变量

  指定环境变量,在镜像生成过程中会被后续RUN指令使用
格式:ENV&lt;KEY&gt; &lt;VALUE&gt; 或 ENV &lt;KEY&gt;=&lt;value&gt;....

例如安装一个JDK
[root@dockers jdk]# cat Dockerfile
FROM centos
COPY jdk-8u77-linux-x64.rpm /usr/src/app/
RUN jdk_dir=/usr/src/app/jdk-8u77-linux-x64.rpm \
&& rpm -ivh $jdk_dir \
&& rm -rf $jdk_dir
ENV JDK_HOME /usr/java/default/
ENV PATH $JDK_HOME/bin:$PATH
CMD ["java","-version"]
ENV 如果加了变量那么生效就一定是  ENV PATH $key:$PATH
最后测试
[root@dockers jdk]# docker run jdk
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

7、ARG

  指定镜像内使用的参数(例如版本号信息等)
     构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是, ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的。
   Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令docker build 中用 --build-arg = 来覆盖。

来个例子说明:
[root@dockers nginx]# cat Dockerfile
FROM centos
ARG nginx=1.11
COPY nginx.repo /etc/yum.repos.d/
RUN yum install -y nginx \
&& echo "hello my frist dockerfile" > /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建一个镜像
[root@dockers nginx]# docker build -t testnginx .
查看历史信息
[root@dockers nginx]# docker history testnginx
IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
3f54a75772f3        About a minute ago   /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B                  
598c5676eeed        About a minute ago   /bin/sh -c #(nop)  EXPOSE 80                    0B                  
17ec99c29593        About a minute ago   |1 nginx=1.11 /bin/sh -c yum install -y ngin…   107MB               
1e03021d4d43        About a minute ago   /bin/sh -c #(nop) COPY file:c33f426ae65e9d11…   113B               
88a51545ba05        About a minute ago   /bin/sh -c #(nop)  ARG nginx=1.11               0B                  
2d194b392dd1        4 weeks ago          /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
           4 weeks ago          /bin/sh -c #(nop)  LABEL name=CentOS Base Im…   0B                  
           4 weeks ago          /bin/sh -c #(nop) ADD file:8d83f3e2c14f39e7f…   195MB               

     ARG感觉没有实际作用,只能指定构建时的版本信息,一次只能指定一个key=value,并且还占用一层资源


8、定义匿名卷
     创建数据卷挂载点,可以从本地主机或其它容器挂载数据卷,一般用来存放数据库和需要保存的数据等,容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。   格式为: VOLUME


$ cat Dockerfile
FROM centos
VOLUME /data
$ docker build -t store .
$ docker run -it  store
container# df -Th | grep /data
/dev/mapper/centos-root     xfs     37G  2.9G   34G   8% /data
container# touch containessss
查找容器与本地关连的卷
$find / -name containessss
/var/lib/docker/volumes/3a17321d0a8a78f2b3c7709b9302bf43bb036c42da2cfc87a5dd1c71e835132b/_data/containessss

9、EXPOSE
     EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。
   在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口

    注意:EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。

此处还是使用nginx做为例子声明80端口
[root@dockers nginx]# vim Dockerfile
FROM centos
COPY nginx.repo /etc/yum.repos.d/
RUN yum install -y nginx \
&& echo "EXPOSE 80 , dockerfile from nginx " > /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建镜像
[root@dockers nginx]# docker build -t test/nginx:v2.0 .
查看镜像
[root@dockers nginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
test/nginx          v2.0                120eaeae17d4        About a minute ago   302MB
指定一个随机端口
[root@dockers nginx]# docker run -dit -p :80 --name tnginx test/nginx:v2.0
使用 docker container ls查看容器,最后访问



10、WORKDIR
    使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在, WORKDIR 会帮你建立目录,因此如果需要改变以后各层的工作目录的位置,那么应该使用 WORKDIR 指令。
  格式为 WORKDIR


创建前一个要先创建一个空目录,工作目录/tmp/ 复制当前上下文中的testfile.txt文件到容器的/tmp目录下
[root@dockers work]# cat Dockerfile
FROM centos
WORKDIR /tmp
COPY testfile.txt ./
CMD ls /tmp
启动一个容器,因为有CMD执行最后一个命令,显示/tmp目录下的文件
[root@dockers work]# docker run -it --name works work
ks-script-IAlIsB  testfile.txt  yum.log

11、USER指定当前用户
    USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层。 WORKDIR 是改变工作目录, USER 则是改变之后层的执行 RUN , CMD 以及 ENTRYPOINT 这类命令的身份
  格式: USER

  注意:USER 只是帮助你切换到指定用户而已,这个用户必须是事先建立好的,否则无法切换

这里用文档中的例子来说明
创建用户并切换redis用户来启动redis-server服务
RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]
第二个例子.
RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/
gosu-amd64" \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true
# 设置 CMD,并以另外的用户执行
CMD [ "exec", "gosu", "redis", "redis-server" ]


12、HEALTHCHECK 健康检查
    HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常,这是 Docker 1.12引入的新指令。
格式:
  HEALTHCHECK [选项] CMD  :设置检查容器健康状况的命令
  HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令

    当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting ,在HEALTHCHECK 指令检查成功后变为 healthy ,如果连续一定次数失败,则会变为unhealthy。
 HEALTHCHECK 支持下列选项:
  --interval= :两次健康检查的间隔,默认为 30 秒;
  --timeout= :健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
  --retries= :当连续失败指定次数后,则将容器状态视为 unhealthy ,默认 3次。
  注意: HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效

空目录下创建一个Dockerfile
FROM centos
COPY nginx.repo /etc/yum.repos.d/
RUN groupadd -g 1000 nginx \
&& useradd -g 1000 -u 1001 nginx \
&& yum -y install nginx
# 每10秒检查一次,超时时长5秒就退出
HEALTHCHECK --interval=10s --timeout=5s \
CMD curl -fs http://127.0.0.1 || exit 1
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
构建并运行并查看状态,一开始是healthy状态,然后理性成starting说明就启动了,失效了就会改变成 unhealthy状态
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                            PORTS                    NAMES
e7982e3ec394        nginx:v3            "nginx -g 'daemon of…"   2 seconds ago       Up 2 seconds (health: starting)   0.0.0.0:80->80/tcp       Tnginx
最后可以使用 docker inspect 查看容器的状态 使用python json模块打印
docker inspect -f '{{json .State.Health}}' Tnginx | python -m json.tool
{
"FailingStreak": 0,
"Log": [
{
"End": "2018-04-07T04:39:29.265404529+08:00",
"ExitCode": 0,
"Output": "\n\n\nWelcome to nginx!\n\n    body {\n        width: 35em;\n        margin: 0 auto;\n        font-family: Tahoma, Verdana, Arial, sans-serif;\n    }\n\n\n\nWelcome to nginx!\nIf you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.\n\nFor online documentation and support please refer to\nnginx.org.\nCommercial support is available at\nnginx.com.\n\nThank you for using nginx.\n\n\n",
"Start": "2018-04-07T04:39:29.177126247+08:00"
},
],
"Status": "healthy"
}


13、ONBUILD 为他人做嫁衣裳
    ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。
  Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的
  格式: ONBUILD


正常镜像写法:
[root@dockers onbuild]# cat Dockerfile
FROM centos
COPY nginx.repo /etc/yum.repos.d/
RUN yum -y install nginx
CMD ["nginx", "-g", "daemon off;"]
构建,运行,查看
[root@dockers onbuild]# docker run -dit -p 80:80 --name TestWeb1 web1
96c3a74da2d9ea63664d7a47c298747a5bb2679f1812a74a2d6d235f4989f624
[root@dockers onbuild]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
96c3a74da2d9        web1                "nginx -g 'daemon of…"   2 seconds ago       Up 1 second         0.0.0.0:80->80/tcp       TestWeb1

    但如果很多项目都需要相同的项目只是Html文件不一样哩,那么每次都需要再生成一次Dockerfile文件挺麻烦,这里就可以使用 ONBUILD了。

[root@dockers onbuild]# cat Dockerfile
FROM centos
ONBUILD COPY nginx.repo /etc/yum.repos.d/
ONBUILD RUN yum -y install nginx
ONBUILD CMD ["nginx", "-g", "daemon off;"]
这时构建一下这个Dockerfile生成一个镜像 onbuilds
[root@dockers onbuild]# docker build -t onbuilds .
我们在创建一个目录生成一个Dockerfile
[root@dockers ontwo]# cat Dockerfile
FROM onbuilds
构建这个文件提示nginx.repo不存在,需要将文件都复制在这个目录下
[root@dockers ontwo]# docker build -t onbuild2 .
Sending build context to Docker daemon  2.048kB
Step 1/1 : FROM onbuilds
# Executing 3 build triggers
COPY failed: stat /var/lib/docker/tmp/docker-builder748734679/nginx.repo: no such file or directory
正确的构建方式:
[root@dockers ontwo]# docker build -t onbuild2 .
Sending build context to Docker daemon  3.072kB
Step 1/1 : FROM onbuilds
# Executing 3 build triggers
---> Running in fafe6903070c
Loaded plugins: fastestmirror, ovl
.....................
Successfully built 7f1a2af8e80d
Successfully tagged onbuild2:latest

    当在各个项目目录中,用这个只有一行的 Dockerfile 构建镜像时,之前基础镜像的那三行 ONBUILD 就会开始执行,成功的将当前项目的代码复制进镜像、并且针对本项目执行 yum以及copy ,生成应用镜像。
  dockerfile 最佳实验手册
dockerfile 官方文档




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-675489-1-1.html 上篇帖子: 创建认证授权的docker私有仓库 下篇帖子: 1、《每天5分钟玩转Docker容器技术》学习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表