目录



  • 六、docker的存储卷
  • 1、简介
  • 2、存储卷
  • 七、Dockerfile详解
  • 1、简介
  • 2、Dockerfile指令



六、docker的存储卷

1、简介

  • Docker镜像是由多个只读层叠加而成,启动容器的时候,docker会加载只读镜像并再镜像栈顶添加一些读写层
  • 如果运行的容器修改了现有的一个已经存在的文件,那改文件会从读写层下的只读层复制到读写曾,改文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,就是所说的写时复制机制
  • 类似于挂载 把容器内的数据 与宿主机的一个路径简历关联关系,可以让宿主机和容器交换文件等 也可以让两个容器的隔离系统 在某个子路径实现绑定关系 共享该路径的效果
  • 容器关闭后自动删除 容器内部数据也会丢失 如果重新创建容器直接关联到原数据的存储卷,可保证数据和业务的持久性
  • 扩展: 容器的存储卷所在宿主机的位置可以是宿主机NFS挂载的位置,这样的话,所有挂载了nfs目录的主机就都可以看到该存储卷 可以实现集群范围内任意机器启动docker来继续业务,云计算的基础理论就是这样

2、存储卷

存储卷:关闭重启容器数据不受影响,但是删除docker则会全部丢失
存在的问题
存储与联合文件系统中,不易于宿主机访问
荣期间数据共享不便
删除容器其数据会丢失
解决方案 卷
卷是容器上的一个或多个目录 此类目录也可以绕过联合文件系统 与宿主机上的某目录关联
种类
1、绑定挂载卷:

  • 需要制定容器和宿主机的关联路径
    docker run -it -v HOSTDIR:VOLUMEDIR --name aaa aaa
    2、docker管理的卷:
  • 只指定容器路径 -v
    docker run -it --name aaa -v /data
1、docker管理的卷

验证

#开启容器并指定容器路径
[root@node1 ~]# docker run --name b2 -it -v /data busybox
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
#查看卷详情
[root@node1 ~]# docker inspect b2
"Mounts": [
            {
                "Type": "volume",
                "Name": "f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff",
                "Source": "/var/lib/docker/volumes/f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
#看到容器挂载路径为/data
#宿主机挂载路径为/var/lib/docker/volumes/f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff/_data
#测试宿主机和容器之间共享文件
#宿主机
[root@node1 ~]# cd /var/lib/docker/volumes/f7a3823aa84cab14754c145f9645b4509d749d7131c5115fdf325286067276ff/_data
[root@node1 _data]# touch 406056573
[root@node1 _data]# ls
406056573
#容器
/ # ls data
406056573
#容器和宿主机之间可以实现文件共享
2、绑定挂载卷

验证

#开启容器指定宿舍主机和容器存储卷路径
[root@node1 ~]#  docker run --name b2 -it --rm -v /data/volumes/bs:/data busybox
/ # ls
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
[root@node1 ~]# docker inspect b2
       "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/volumes/bs",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
#宿舍主  /data/volumes/bs(没有会自动生成) 与容器内的/data绑定
#验证
#容器
/ # cd data
/data # touch test.php
#宿主机
[root@node1 _data]# cd /data/volumes/bs/
[root@node1 bs]# ls
test.php

扩展

多个容器可以通过绑定挂在卷实现共享

#启动容器b3  使用b2 一样的挂载路径和方式
[root@node1 ~]# docker run --name b3 -it --rm -v /data/volumes/bs:/data busybox
/ # ls /data
test.php
#此时可以实现 b2  b3 共享 手动指定共享
#生产中可以先创建一个基础容器   可以不提供服务  做基础支撑   真正生产服务的容器复制基础支撑的存储卷设置,生产服务的容器通过基础支撑的容器获得一切生产环境的设定
#类似虚拟机 克隆,还可以指定数据的读写权限,默认是可读可写,可指定为只读  /data/volumes/bs:/dat:ro  ro 设置了只读权限,在容器中是无法对 bind mount 数据进行修改的。只有 host 有权修改数据,提高了安全性。
#除了绑定目录外也可以绑定单个文件,/data/volumes/bs/index.html:/data/web/html

还可以指定数据的读写权限,默认是可读可写,可指定为只读:
docker 不会销毁 bind mount,删除数据的工作只能由 host 负责。对于 docker managed volume,在执行 docker rm 删除容器时可以带上 -v 参数,docker 会将容器使用到的 volume 一并删除,但前提是没有其他容器 mount 该 volume,目的是保护数据,非常合理。

如果删除容器时没有带 -v 呢?这样就会产生孤儿 volume,好在 docker 提供了 volume 子命令可以对 docker managed volume 进行维护
可以通过 docker volume ls 查看 docker volume rm 删除,由于种种原因对docker容器维护的不善,导致在销毁容器的时候没有使用-v这个参数,所有就导致留下了很多“孤儿volume”,但是docker volume ls这个命令只能简单查看本地的docker managed volume,而并不能显示是挂载到哪个容器,而即便是使用docker volume inspect [volume name]也无法确认是哪个容器正在使用,这样就出现很多有效和无效的docker managed volume混在一起,用这个命令删除孤儿 volume: docker volume prune

七、Dockerfile详解

1、简介

制作容器两种方法
1、基于原有容器进行修改
2、dockerfile制作
dockerfile只是构建docker镜像的源码,只是简单的命令,
语法格式:包含两类语句 1、#注释信息 2、指令及其参数
从上到下逐行操作
第一个非注释行一定是FROM
要求:

  • 1)工作目录
  • 2)首字母大写
  • 3)所有配置文件等需要打包的文件及目录只能放在这个目录内
  • 4)可以有一个.dockeringore的文件写入制定不需要打包的文件路径,打包的时候就会把指定文件排除在外

变量
$如果没有该变量或者变量为空则引用字符串(常用){variable:-word} 如果没有该变量或者变量为空则引用word字符串 (常用)
${variable:+word} 如果该变量存在,则使用word字符串

2、Dockerfile指令

1、FROM

最重要的以一个且必须为Dockerfile文件开篇的第一个非主事行,用于为影响见闻构建过程指定基准镜像,后续的指令

运行与基础镜像所提供的运行环境

  • 语法 :

FROM <repository>[:<tag>] 或

FROM <repository>@<digest>

2、LABEL

标签 说明 类型:键值对数据

  • 语法:

LABEL <key>=<value>

3、MAINTAINER

描述

现在已经被LABEL maintainer= 取代

  • 语法:

MAINTAINER <desc>

4、COPY

拷贝,宿主机当前工作目录中的文件,复制到目标镜像的文件系统

  • 语法:

COPY ...
COPY ["",...""] #如果路径中有空格,建议使用该方式

COPY准则

1、<src>必须是build上下文中的路径,不能是其父目录中的文件

2、如果<src>是目录,则再内部文件或者子目录会被递归复制,但是<src>目录本身不被复制

3、如果<dest>事先不存在,它会被自动创建,包括其父目录

测试:

#编写Dockfile
[root@node1 ~]# mkdir image1
[root@node1 ~]# cd image1
[root@node1 image1]# echo "who let the dogs out1111" >index.html
[root@node1 image1]# vim Dockerfile

#descripts: test images
FROM busybox
#MAINTAINER 已经被LABEL替代
#MAINTAINER 
LABEL maintainer
COPY index.html /data/web/html/

#保存  biuld镜像
[root@node1 image1]# docker build -t tinyhttpd:v0.1-1 ./

[root@node1 image1]# ll
total 8
-rw-r--r--. 1 root root 185 Dec  9 16:42 Dockerfile
-rw-r--r--. 1 root root  25 Dec  9 16:43 index.html
[root@node1 image1]# docker build -t tinyhttpd:v0.1-1 ./
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM busybox
 ---> 59788edf1f3e
Step 2/3 : LABEL maintainer="white "
 ---> Using cache
 ---> 9a816e188f25
Step 3/3 : COPY index.html /data/web/html/
 ---> 31a2b7060b22
Successfully built 31a2b7060b22
Successfully tagged tinyhttpd:v0.1-1
[root@node1 image1]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
tinyhttpd            v0.1-1              31a2b7060b22        13 seconds ago      1.15MB
xiaobai20201/httpd   v0.2                74606456efe3        5 days ago          1.15MB
xiaobai20201/httpd   latest              8a3222f26545        5 days ago          1.15MB
xiaobai20201/httpd   v0.1-1              8a3222f26545        5 days ago          1.15MB
nginx                1.14.1-alpine       77bae8d00654        4 weeks ago         17.7MB
redis                4-alpine3.8         05097a3a0549        2 months ago        30MB
busybox              latest              59788edf1f3e        2 months ago        1.15MB
#验证
[root@node1 bs]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-1 cat /data/web/html/index.html 
who let the dogs outllll


#测试拷贝目录
#注意:DOCKERFILE内 每执行一行命令就会形成一个镜像层,所以尽可能减少语句,如果可以合并尽量多个合并到一条
[root@node1 image1]# cp /etc/yum.repos.d/ ./ -r
[root@node1 image1]# vim Dockerfile

#descripts: test images
FROM busybox
#MAINTAINER 已经被LABEL替代
#MAINTAINER "white 
LABEL maintainer="white 
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
[root@node1 image1]# docker build -t tinyhttpd:v0.1-2 ./
Sending build context to Docker daemon  23.55kB
Step 1/4 : FROM busybox
 ---> 59788edf1f3e
Step 2/4 : LABEL maintainer="white 
 ---> Using cache
 ---> 9a816e188f25
Step 3/4 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 31a2b7060b22
Step 4/4 : COPY yum.repos.d /etc/yum.repos.d/
 ---> 821b2c754d7b
Successfully built 821b2c754d7b
Successfully tagged tinyhttpd:v0.1-2

#验证
[root@node1 bs]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-2 ls -l /etc/yum.repos.d
total 36
-rw-r--r--    1 root     root          1664 Dec  9 08:46 CentOS-Base.repo
-rw-r--r--    1 root     root          1309 Dec  9 08:46 CentOS-CR.repo
-rw-r--r--    1 root     root           649 Dec  9 08:46 CentOS-Debuginfo.repo
-rw-r--r--    1 root     root           630 Dec  9 08:46 CentOS-Media.repo
-rw-r--r--    1 root     root          1331 Dec  9 08:46 CentOS-Sources.repo
-rw-r--r--    1 root     root          4768 Dec  9 08:46 CentOS-Vault.repo
-rw-r--r--    1 root     root           314 Dec  9 08:46 CentOS-fasttrack.repo
-rw-r--r--    1 root     root          2640 Dec  9 08:46 docker-ce.repo
5、ADD

ADD 与COPY类似 但是ADD支持TAR文件和URL路径

  • 语法
    ADD ...
    ADD ["",...""]

ADD准则
1、当源文件是URL的时候ADD可以把RUL对应的文件下载下来打包发送
2、如果源文件是tar的压缩包,将会被展开为一个目录,行为类似tar xf 然而 通过URL获取的TAR文件不会自动展开
3、如果src有多个或者使用了通配符,则dest必须是一个以/结尾的目录路径;如果<dest>不已/结尾,则被视作一个普通文件,src的内容会被直接写入到dest。

测试:

[root@node1 image1]# vim Dockerfile 

#descripts: test images
FROM busybox
#MAINTAINER "white
LABEL maintainer="white 
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
#执行测试
[root@node1 image1]# docker build -t tinyhttpd:v0.1-3 ./
Sending build context to Docker daemon  23.55kB
Step 1/5 : FROM busybox
 ---> 59788edf1f3e
Step 2/5 : LABEL maintainer="white
 ---> Using cache
 ---> 9a816e188f25
Step 3/5 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 31a2b7060b22
Step 4/5 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> 821b2c754d7b
Step 5/5 : ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
Downloading  1.014MB/1.014MB
 ---> 01da54e70076
Successfully built 01da54e70076
Successfully tagged tinyhttpd:v0.1-3
#验证
[root@node1 bs]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-3 ls -l /usr/local/src/
total 992
-rw-------    1 root     root       1014040 Nov  6 15:26 nginx-1.14.1.tar.gz
###测试ADD 复制tar文件直接解压
#准备tar包
[root@node1 image1]# wget http://nginx.org/download/nginx-1.14.1.tar.gz
#编辑
[root@node1 image1]# vim Dockerfile 

#descripts: test images
FROM busybox
#MAINTAINER "white
LABEL maintainer="white
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
ADD ./nginx-1.14.1.tar.gz /usr/local/src/

[root@node1 image1]# docker build -t tinyhttpd:v0.1-4 ./
Sending build context to Docker daemon  1.038MB
Step 1/5 : FROM busybox
 ---> 59788edf1f3e
Step 2/5 : LABEL maintainer="white
 ---> Using cache
 ---> 9a816e188f25
Step 3/5 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 31a2b7060b22
Step 4/5 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> 821b2c754d7b
Step 5/5 : ADD ./nginx-1.14.1.tar.gz /usr/local/src/
 ---> c76524b56f3c
Successfully built c76524b56f3c
Successfully tagged tinyhttpd:v0.1-4
#验证
[root@node1 bs]# docker run --name tinyweb1 --rm tinyhttpd:v0.1-4 ls -l /usr/local/src/
total 0
drwxr-xr-x    8 1001     1001           158 Nov  6 13:52 nginx-1.14.1
6、WORKDIR

用于为Dockerfile中所有的RUN\CMD\ENTRYPOINT\COPY\ADD设定工作目录

  • 语法
    WORKDIR <dirpath>
    在Dockerfile中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过相对的是前一个WORKDIR指令制定的路径
7、VOLUME

用于在image中创建一个挂载点目录,以挂载Docker host上的卷或者其他容器上的卷

  • 语法
    VOLUME <mountpoint> 或者
    VOLUME ["<mountpoint>"]

如果挂载点目录路径下此前在文件存在,docker run命令会在卷挂载完成后把此前所有文件复制到新挂载的卷中

注意! dockerfile中的存储卷只能指定docker容器内的路径,不能指定宿主机的路径

测试:

[root@node1 image1]# vim Dockerfile

#descripts: test images
FROM busybox
#MAINTAINER "white 
LABEL maintainer="white
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
WORKDIR /usr/local/
#相对路径
ADD ./nginx-1.14.1.tar.gz ./src/
VOLUME /data/mysql/
#
[root@node1 image1]# docker build -t tinyhttpd:v0.1-5 ./
Sending build context to Docker daemon  1.038MB
Step 1/7 : FROM busybox
 ---> 59788edf1f3e
Step 2/7 : LABEL maintainer="white
 ---> Using cache
 ---> 9a816e188f25
Step 3/7 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 31a2b7060b22
Step 4/7 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> 821b2c754d7b
Step 5/7 : WORKDIR /usr/local/
 ---> Running in 2c45b837b407
Removing intermediate container 2c45b837b407
 ---> 5a746b5d61cf
Step 6/7 : ADD ./nginx-1.14.1.tar.gz ./src/
 ---> 33c4c3b5e58d
Step 7/7 : VOLUME /data/mysql/
 ---> Running in 9ad5e6bc4a9e
Removing intermediate container 9ad5e6bc4a9e
 ---> 024fe1d452bd
Successfully built 024fe1d452bd
Successfully tagged tinyhttpd:v0.1-5
###验证
[root@node1 bs]#  docker run --name tinyweb1 --rm tinyhttpd:v0.1-5 mount|grep mysql
/dev/sda3 on /data/mysql type xfs (rw,seclabel,relatime,attr2,inode64,noquota)
8、EXPOSE

等待暴露端口,用于为容器打开指定要监听的端口以实现与外部通信

  • 语法
    EXPOSE [/] [/] ... ]
    protocol 用于指定传输层协议 tcp udp 二选一 默认在TCP
    EXPOSE指令可以一次执行多个端口
    EXPOSE 11211/udp 11211/tcp

注意: 写入Dockerfile内的EXPOSE的端口不会直接暴露,只是表示可以暴露或者需要暴露该端口,可以在docker run的时候使用-P 来真正暴露端口,此时只是表示可以暴露。

测试:

[root@node1 image1]# vim Dockerfile

#descripts: test images
FROM busybox
#MAINTAINER "white
LABEL maintainer="white 
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
WORKDIR /usr/local/
#相对路径
ADD ./nginx-1.14.1.tar.gz ./src/
VOLUME /data/mysql/
EXPOSE 80/tcp
#build
[root@node1 image1]# docker build -t tinyhttpd:v0.1-6 ./
Sending build context to Docker daemon  1.038MB
Step 1/8 : FROM busybox
 ---> 59788edf1f3e
Step 2/8 : LABEL maintainer="white 
 ---> Using cache
 ---> 9a816e188f25
Step 3/8 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 31a2b7060b22
Step 4/8 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> 821b2c754d7b
Step 5/8 : WORKDIR /usr/local/
 ---> Using cache
 ---> 5a746b5d61cf
Step 6/8 : ADD ./nginx-1.14.1.tar.gz ./src/
 ---> Using cache
 ---> 33c4c3b5e58d
Step 7/8 : VOLUME /data/mysql/
 ---> Using cache
 ---> 024fe1d452bd
Step 8/8 : EXPOSE 80/tcp
 ---> Running in e2a80b5a4536
Removing intermediate container e2a80b5a4536
 ---> 6a9ed6279a6e
Successfully built 6a9ed6279a6e
Successfully tagged tinyhttpd:v0.1-6
#验证
[root@node1 bs]#  docker run --name tinyweb1 --rm tinyhttpd:v0.1-5 /bin/httpd -f -h /data/web/html
#复制终端 查看容器ip
[root@node1 ~]# docker inspect tinyweb1
"IPAddress": "172.16.1.2",
#验证
[root@node1 ~]# curl 172.16.1.2
who let the dogs outllll
#此时并未暴露端口
[root@node1 ~]# docker port tinyweb1
[root@node1 ~]# 
#停止刚才的容器 使用-P 暴露EXPOSE设置的端口
[root@node1 ~]# docker kill tinyweb1
tinyweb1
[root@node1 ~]# docker run --name tinyweb1 --rm -P tinyhttpd:v0.1-6 /bin/httpd -f -h /data/web/html
[root@node1 bs]# docker port tinyweb1
80/tcp -> 0.0.0.0:32768
[root@node1 bs]# curl 172.16.1.2
who let the dogs outllll
9、ENV

环境变量用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其他指令 ENV ADD COPY等调用

  • 语法
    ENV <key> <value> 或者
    ENV <key>=<value> <key>=<value> ...

第一种格式中key后的所有内容被视为value的组成部分,因此只能设置一个变量,

第二章格式可用一次设置多个变量,每个变量为一个KV键值对,value内可以包含空格 可以用\转义 也可以通过对value加引号进行标识,反斜线也可以用于续行.

定义多个变量时,建议使用第二种方式,以便在他那个一层完成所有功能,docker每多一条指令就多一个读写层。
dockerfile中使用ENV定义的变量是注入镜像的,在docker run后直接在容器内引用使用的变量
也可以在docker run 的时候使用 -e为环境变量赋值 类似传参

测试:

[root@node1 image1]# vim Dockerfile

#descripts: test images
FROM busybox
#MAINTAINER "white 
LABEL maintainer="white 
ENV DOC_ROOT=/data/weeb/html \
        WEEB_SERVER_PAC="nginx-1.14.1.tar.gz"
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
#ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
WORKDIR /usr/local/
#相对路径
ADD ./nginx-1.14.1.tar.gz ./src/
VOLUME /data/mysql/
EXPOSE 80/tcp
#
[root@node1 image1]# docker build -t tinyhttpd:v0.1-7 ./
Sending build context to Docker daemon  1.038MB
Step 1/9 : FROM busybox
 ---> 59788edf1f3e
Step 2/9 : LABEL maintainer="white
 ---> Using cache
 ---> 9a816e188f25
Step 3/9 : ENV DOC_ROOT=/data/weeb/html     WEEB_SERVER_PAC="nginx-1.14.1.tar.gz"
 ---> Running in 80fe5e58eb63
Removing intermediate container 80fe5e58eb63
 ---> 31bbfd3e788f
Step 4/9 : COPY index.html /data/web/html/
 ---> c0a8a55325a8
Step 5/9 : COPY yum.repos.d /etc/yum.repos.d/
 ---> 5f3ca71adb80
Step 6/9 : WORKDIR /usr/local/
 ---> Running in a2b2c5fb81e1
Removing intermediate container a2b2c5fb81e1
 ---> 18c8e0ca56ae
Step 7/9 : ADD ./nginx-1.14.1.tar.gz ./src/
 ---> 67dec88fe23c
Step 8/9 : VOLUME /data/mysql/
 ---> Running in ff16f01825f1
Removing intermediate container ff16f01825f1
 ---> e60571d77561
Step 9/9 : EXPOSE 80/tcp
 ---> Running in 77ccadaef6c1
Removing intermediate container 77ccadaef6c1
 ---> 1193c3a2de10
Successfully built 1193c3a2de10
Successfully tagged tinyhttpd:v0.1-7
#验证
[root@node1 bs]# docker run --name tinyweb1 --rm -P tinyhttpd:v0.1-7 ls /usr/local/src -l
total 0
drwxr-xr-x    8 1001     1001           158 Nov  6 13:52 nginx-1.14.1
#测试使用-e参数指定环境变量
[root@node1 bs]# docker run --name tinyweb1 --rm -P -e WEB_SERVER_PAC="nginx-1.11" tinyhttpd:v0.1-7 printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=01d586f824c8
WEB_SERVER_PAC=nginx-1.11
DOC_ROOT=/data/weeb/html
WEEB_SERVER_PAC=nginx-1.14.1.tar.gz
HOME=/root
[root@node1 bs]# docker run --name tinyweb1 --rm -P -e WEB_SERVER_PAC="nginx-1.11" tinyhttpd:v0.1-7 ls /usr/local/src -l
total 0
drwxr-xr-x    8 1001     1001           158 Nov  6 13:52 nginx-1.14.1

验证发现 虽然docker run的时候赋予了新变量名,但是还是按照之前build的时候的配置执行,因为在docker build制作镜像的时候已经完成了之前的操作,docker run -e 只是在使用镜像做容器的时候进行传参,所以只影响开启容器后的操作。

10、RUN

运行命令 RUN的命令是在docker build制作镜像的时候运行

  • 语法
    RUN
    RUN ["","",""]

建议多个RUN写一行 或者 && \换行 执行
第一种格式中,i一般是shell命令,且以"/bin.sh -c"来运行它,这就意味着改进程再容器的PID不是1不,不能接收Unix信号,因此当使用 docker stop 命令停止容器的时候,改进程接受不到SIGTERM信号(docker stop kill等)
第二种格式中的参数是一个JSON格式数组,此格式指定的命令不会以"/bin/sh -c"来发起,因此常见的shell操作比如变量替换 通配符替换等将不会执行,不过如果要运行的命令依赖此shell特性的话,可以将其替换为下面的格式
RUN ["/bin/bash","-c","",""]
JSON数组中一定要使用双引号。

测试:

[root@node1 image1]# vim Dockerfile

#descripts: test images
FROM busybox
#MAINTAINER "white 
LABEL maintainer="white 
ENV DOC_ROOT=/data/weeb/html \
        WEB_SERVER_PAC="nginx-1.14.1.tar.gz"
COPY index.html /data/web/html/
COPY yum.repos.d /etc/yum.repos.d/
ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
WORKDIR /usr/local/
#相对路径
#ADD ./nginx-1.14.1.tar.gz ./src/
VOLUME /data/mysql/
EXPOSE 80/tcp
RUN cd /usr/local/src && \
               tar xf ${WEB_SERVER_PAC} && \
               ln -s nginx-1.14.1 nginx
#
[root@node1 image1]# docker build -t tinyhttpd:v0.1-8 ./
Sending build context to Docker daemon  1.039MB
Step 1/10 : FROM busybox
 ---> 59788edf1f3e
Step 2/10 : LABEL maintainer="white 
 ---> Using cache
 ---> 9a816e188f25
Step 3/10 : ENV DOC_ROOT=/data/weeb/html    WEB_SERVER_PAC="nginx-1.14.1.tar.gz"
 ---> Using cache
 ---> cbbf442fbe07
Step 4/10 : COPY index.html /data/web/html/
 ---> Using cache
 ---> 1ddff90269d0
Step 5/10 : COPY yum.repos.d /etc/yum.repos.d/
 ---> Using cache
 ---> adf8d7dc58c8
Step 6/10 : ADD http://nginx.org/download/nginx-1.14.1.tar.gz /usr/local/src/
Downloading  1.014MB/1.014MB
 ---> b43a41108c10
Step 7/10 : WORKDIR /usr/local/
 ---> Running in bb083a330502
Removing intermediate container bb083a330502
 ---> a1dc426a3b35
Step 8/10 : VOLUME /data/mysql/
 ---> Running in aeb793155a81
Removing intermediate container aeb793155a81
 ---> 0489fafcd5dc
Step 9/10 : EXPOSE 80/tcp
 ---> Running in 696a6163e99a
Removing intermediate container 696a6163e99a
 ---> 8dbc74131301
Step 10/10 : RUN cd /usr/local/src &&          tar xf ${WEB_SERVER_PAC} &&         ln -s nginx-1.14.1 nginx
 ---> Running in 13c5b72b6959
Removing intermediate container 13c5b72b6959
 ---> 96c6227ca444
Successfully built 96c6227ca444
Successfully tagged tinyhttpd:v0.1-8
#验证
[root@node1 bs]#  docker run --name tinyweb1 --rm -P tinyhttpd:v0.1-8 ls /usr/local/src -l
total 992
lrwxrwxrwx    1 root     root            12 Dec  9 09:17 nginx -> nginx-1.14.1
drwxr-xr-x    8 1001     1001           158 Dec  9 09:17 nginx-1.14.1
-rw-------    1 root     root       1014040 Nov  6 15:26 nginx-1.14.1.tar.gz
11、CMD

定义一个镜像文件启动为容器的时候默认的命令,类似与RUN,CMD也可以用于运行任何命令或应用程序

CMD执行运行于基于Dockerfile构建出的镜像文件启动为容器的时候 docker run,

CMD命令的首要目的在于为启动的容器制定默认要运行的程序且其运行结束后 容器也终止,不过CMD制定的命令其可以被docker run的命令行覆盖,

Dockerfile中可以存在多个CMD 但是只有最后一个生效。

  • 语法
    CMD
    CMD ["","",""]
    CMD["",""]

前两种和RUN一样 第三者用于为ENTRYPOINT指令提供默认参数
JSON数组中一定要使用双引号

测试:

[root@node1 image1]# cd ..
[root@node1 ~]# mkdir image2
[root@node1 ~]# cd image2
[root@node1 image2]# vim Dockerfile

FROM busybox
LABEL maintainer="white 
ENV WEB_DOC_ROOT="/data/web/html"
RUN   mkdir -p  $WEB_DOC_ROOT && \
       echo 'command run test' >${WEB_DOC_ROOT}/index.html
CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
~                                      
#
[root@node1 image2]# docker build -t tinyhttpd:v0.2-1 ./
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM busybox
 ---> 59788edf1f3e
Step 2/5 : LABEL maintainer="white
 ---> Using cache
 ---> 9a816e188f25
Step 3/5 : ENV WEB_DOC_ROOT="/data/web/html"
 ---> Running in dc359e634eb8
Removing intermediate container dc359e634eb8
 ---> 80c2fd145b0b
Step 4/5 : RUN   mkdir -p  $WEB_DOC_ROOT &&        echo 'command run test' >${WEB_DOC_ROOT}/index.html
 ---> Running in ca9141b04389
Removing intermediate container ca9141b04389
 ---> b1fdaf6afdbb
Step 5/5 : CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
 ---> Running in 331db2bf0160
Removing intermediate container 331db2bf0160
 ---> 2ac047c51cf9
Successfully built 2ac047c51cf9
Successfully tagged tinyhttpd:v0.2-1
#验证、
[root@node1 bs]# docker image inspect  tinyhttpd:v0.2-1

 "Cmd": [
                "/bin/sh",
                "-c",
                "/bin/httpd -f -h ${WEB_DOC_ROOT}"
            ],
#默认执行程序还是  /bin/sh
[root@node1 bs]# docker run --name tinyweb1 --rm -P tinyhttpd:v0.2-1 
#此时是否使用-it都是一样  因为CMD指定了默认命令 可以使用docker image inspect 查看CMD
#可以使用docker exec -it *** /bin/sh进入
[root@node1 ~]# docker exec -it tinyweb1 /bin/sh
/ # netstat -lnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 :::80
#此时httpd对应的进程是1  确认默认的启动命令为httpd 

#测试CMD
[root@node1 image2]# vim Dockerfile

FROM busybox
LABEL maintainer="white
ENV WEB_DOC_ROOT="/data/web/html"
RUN   mkdir -p  $WEB_DOC_ROOT && \
       echo 'command run test' >${WEB_DOC_ROOT}/index.html
#CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
~                                             
#
[root@node1 image2]# docker build -t tinyhttpd:v0.2-2 ./
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM busybox
 ---> 59788edf1f3e
Step 2/5 : LABEL maintainer="white 
 ---> Using cache
 ---> 9a816e188f25
Step 3/5 : ENV WEB_DOC_ROOT="/data/web/html"
 ---> Using cache
 ---> 80c2fd145b0b
Step 4/5 : RUN   mkdir -p  $WEB_DOC_ROOT &&        echo 'command run test' >${WEB_DOC_ROOT}/index.html
 ---> Using cache
 ---> b1fdaf6afdbb
Step 5/5 : CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
 ---> Running in 70ca535911c6
Removing intermediate container 70ca535911c6
 ---> 9aca3e7bb653
Successfully built 9aca3e7bb653
Successfully tagged tinyhttpd:v0.2-2
#验证
[root@node1 ~]# docker image inspect  tinyhttpd:v0.2-2
"Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"/bin/httpd\" \"-f\" \"-h ${WEB_DOC_ROOT}\"]"
            ],

[root@node1 bs]# docker run --name tinyweb1 --rm -P tinyhttpd:v0.2-2 
httpd: can't change directory to ' ${WEB_DOC_ROOT}': No such file or directory
报错
由于此时默认进程不是shell  而${WEB_DOC_ROOT}是shell的环境变量,既然shell没有运行 则无法使用。
修改为绝对路径即可
12、ENTRYPOINT

类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是单独的可执行程序
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行执行的参数覆盖,而且这些命令行参数会被当作参数传递给ENTRYPOINT指定的指定程序(不过 docker run --entrypoint参数可以覆盖ENTRYPOINT指定的指定程序)

  • 语法
    CMD["",""]
    ENTRYPOINT

CMD所给的内容会被当作ENTRYPOINT的参数传递给ENTRYPOINT

可以理解为 优先级排序:
1、docker run --enrtrypoint
2、ENTRYPOINT
3、docker run
4、CMD
问:为什么需要有CMD 和ENTRYPOINT
1、多数情况ENTRYPOINT用来指定作为父进程的程序 命令行中的参数会当作参数来传参
2、容器接受配置要靠环境变量,

测试:

[root@node1 image2]# vim Dockerfile

FROM busybox
LABEL maintainer="white
ENV WEB_DOC_ROOT="/data/web/html"
RUN   mkdir -p  $WEB_DOC_ROOT && \
       echo 'command run test' >${WEB_DOC_ROOT}/index.html
#CMD /bin/httpd -f -h ${WEB_DOC_ROOT}
#CMD ["/bin/httpd","-f","-h ${WEB_DOC_ROOT}"]
ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
#
[root@node1 image2]# docker build -t tinyhttpd:v0.2-3 ./
Sending build context to Docker daemon  2.048kB
Step 1/5 : FROM busybox
 ---> 59788edf1f3e
Step 2/5 : LABEL maintainer="white
 ---> Using cache
 ---> 9a816e188f25
Step 3/5 : ENV WEB_DOC_ROOT="/data/web/html"
 ---> Using cache
 ---> 80c2fd145b0b
Step 4/5 : RUN   mkdir -p  $WEB_DOC_ROOT &&        echo 'command run test' >${WEB_DOC_ROOT}/index.html
 ---> Using cache
 ---> b1fdaf6afdbb
Step 5/5 : ENTRYPOINT /bin/httpd -f -h ${WEB_DOC_ROOT}
 ---> Running in 7e04a3956e12
Removing intermediate container 7e04a3956e12
 ---> 863429a29ee3
Successfully built 863429a29ee3
Successfully tagged tinyhttpd:v0.2-3
#验证
[root@node1 bs]# docker run --name tinyweb2 --rm -P tinyhttpd:v0.2-3

[root@node1 ~]# docker inspect tinyweb2
    "IPAddress": "172.16.1.2",
[root@node1 ~]# curl 172.16.1.2
command run test
#如果 docker run --name tinyweb2 -it --rm -P tinyhttpd:v0.2-3   ls /data  ,执行该命令的时候由于使用的是ENTRYPOINT 所以 ls /data会被当作是 httpd -f -h /data/web/html 后的参数 即:httpd -f -h /data/web/html  ls /data,除非使用 --entrypoing ls /data来执行,此时执行的结果是 ls /data httpd -f -h /data/web/html  

#测试测试ENTRYPOINT
[root@node1 image2]# cd ..
[root@node1 ~]# mkdir image3
[root@node1 ~]# cd image3/
[root@node1 image3]# vim Dockerfile

FROM nginx:1.14.1-alpine
LABEL maintainer "white 
ENV NGX_DOC_ROOT="/data/web/html"
ADD index.html ${NGX_DOC_ROOT}/
ADD entrypoint.sh /bin/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
#其中
[root@node1 image3]# vim entrypoint.sh

#!/bin/sh
cat > /etc/nginx/conf.d/www.conf<<EOF
server
{
        server_name $HOSTNAME;
        listen ${IP:-0.0.0.0}:${PORT:-80};
        root ${NGX_DOC_ROOT:-/usr/share/nginx/html};
}
EOF
#把CMD后面的所有命令当作参数的传递到ENTRYPOINT,且替换当前进程
exec "$@"
[root@node1 image3]# chmod +x entrypoint.sh   
[root@node1 image3]#  docker build -t myweb:v0.3-1 ./
13、USER

用于指定运行image时或运行Dockdile中任何RUN CMD ENTRYPOINT指令指定的程序时候的用户名或UID
默认情况下,container的运行身份为root

  • 语法
    USER
    需要注意的是 可以是任意数字,但是实践中其必须为/etc/passwd中某用户的有效UID 否则 docker run会失败
14、HEALTHCKECK

通过容器运行与否无法判断真正的服务是否正常,所以引入健康检查,定义一个CMD command 用来检查主进程工作状态健康如否,

  • 语法
    HEALTHCHECK [OPTIONS] CMD command

--interval= 默认30s 间隔时间 s m h
--timeout= 默认30s 服务器反应超时时间 s m h
--start-period= 默认0s,初始化等待时间,刚开启容器等待容器初始化得时间 s m h
--reties= 默认3次 ,重试次数 ,超过该次数认证为非健康 times
CMD命令检查健康状态的返回值
0:success 成功 容器健康可以使用
1:unhealthy 失败 容器运行不正常
2:reserved 无意义

举例
HEALTHYCHECK --interval=5m --timeout=3s CMD curl -f http:/loclahost || exit 1
如果不需要健康检查 可以使用HEALTHCHECK NONE来关闭所有健康检查

测试:

[root@node1 image3]# vim Dockerfile 

ENV NGX_DOC_ROOT="/data/web/html"
ADD index.html ${NGX_DOC_ROOT}/
ADD entrypoint.sh /bin/
EXPOSE 80/tcp
HEALTHCHECK --interval=40s --timeout=30s \
        --start-period=5s --retries=3 \
        CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
#
[root@node1 image3]# echo "healthy check test" >index.html
[root@node1 image3]#  docker build -t myweb:v0.3-3 ./
Sending build context to Docker daemon  4.096kB
Step 1/9 : FROM nginx:1.14.1-alpine
 ---> 77bae8d00654
Step 2/9 : LABEL maintainer "white 
 ---> Using cache
 ---> 0bb45a975d25
Step 3/9 : ENV NGX_DOC_ROOT="/data/web/html"
 ---> Using cache
 ---> b1a6e20bd862
Step 4/9 : ADD index.html ${NGX_DOC_ROOT}/
 ---> 91a1327ac8c2
Step 5/9 : ADD entrypoint.sh /bin/
 ---> 8b80361ca7d4
Step 6/9 : EXPOSE 80/tcp
 ---> Running in e0d28e40e001
Removing intermediate container e0d28e40e001
 ---> 5e02dade60ae
Step 7/9 : HEALTHCHECK --interval=40s --timeout=30s         --start-period=5s --retries=3         CMD wget -O - -q http://${IP:-0.0.0.0}:${PORT:-80}/
 ---> Running in 6c440b190808
Removing intermediate container 6c440b190808
 ---> 925872e74af1
Step 8/9 : CMD ["/usr/sbin/nginx","-g","daemon off;"]
 ---> Running in 2da2fa1c14cf
Removing intermediate container 2da2fa1c14cf
 ---> ce5c8c7cc8dd
Step 9/9 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in c1fbe4fe1e9e
Removing intermediate container c1fbe4fe1e9e
 ---> b271d2811c6b
Successfully built b271d2811c6b
Successfully tagged myweb:v0.3-3
#验证
[root@node1 bs]# docker run --name myweb1 --rm -P -e "PORT=8080" myweb:v0.3-3
127.0.0.1 - - [09/Dec/2018:11:22:04 +0000] "GET / HTTP/1.1" 200 19 "-" "Wget" "-"
127.0.0.1 - - [09/Dec/2018:11:22:44 +0000] "GET / HTTP/1.1" 200 19 "-" "Wget" "-"
127.0.0.1 - - [09/Dec/2018:11:23:25 +0000] "GET / HTTP/1.1" 200 19 "-" "Wget" "-"
##健康检查已经开始
#测试健康检查失败情况 ,HEALTHCHECK部分修改如下
[root@node1 image3]#  docker build -t myweb:v0.3-4 ./
Sending build context to Docker daemon  4.096kB
Step 1/9 : FROM nginx:1.14.1-alpine
 ---> 77bae8d00654
Step 2/9 : LABEL maintainer "white <406056573@qq.com>"
 ---> Using cache
 ---> 0bb45a975d25
Step 3/9 : ENV NGX_DOC_ROOT="/data/web/html"
 ---> Using cache
 ---> b1a6e20bd862
Step 4/9 : ADD index.html ${NGX_DOC_ROOT}/
 ---> Using cache
 ---> 91a1327ac8c2
Step 5/9 : ADD entrypoint.sh /bin/
 ---> Using cache
 ---> 8b80361ca7d4
Step 6/9 : EXPOSE 80/tcp
 ---> Using cache
 ---> 5e02dade60ae
Step 7/9 : HEALTHCHECK --interval=40s --timeout=30s         --start-period=5s --retries=3         CMD wget -O - -q http://${IP:-0.0.0.0}:12345/
 ---> Running in e0d0b0128ea2
Removing intermediate container e0d0b0128ea2
 ---> 349fe139044c
Step 8/9 : CMD ["/usr/sbin/nginx","-g","daemon off;"]
 ---> Running in fb34d3f2b359
Removing intermediate container fb34d3f2b359
 ---> 700608bbf6f6
Step 9/9 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in 009744406bf9
Removing intermediate container 009744406bf9
 ---> ee3b3c1ad8b2
Successfully built ee3b3c1ad8b2
Successfully tagged myweb:v0.3-4
#等待结果,等待时间是次数*timeout
[root@node1 bs]# docker run --name myweb1 --rm -P -e "PORT=8080" myweb:v0.3-4
15、SHELL

定义运行程序默认要适用的shell程序, LINUX 默认是["/bin/sh","-c"] windows默认是["cmd","/S","/C"]

SHELL在Dockerfile内格式必须是JSON格式
SHELL可以在一个Dockerfile内出现多次

16、STOPSIGNAL

进程号为1的进程可以直接接受docker stop命令从而停止主机名,来停止容器
默认情况 docker stop 传递的是 -15 docker kill 传递的是-9

17、ARG

参数,和ENV类似 ,区别:ARG定义的变量可以在docker build过程中使用 --build-arg =标签来 ENV不能在build的时候定义变量 ,只能在docker run的过程传递变量
控制定义的变量只在docker build过程生效

测试:

[root@node1 image3]# vim Dockerfile 

FROM nginx:1.14.1-alpine
ARG auth="white 
LABEL maintainer "$auth"
ENV NGX_DOC_ROOT="/data/web/html"
ADD index.html ${NGX_DOC_ROOT}/
ADD entrypoint.sh /bin/
EXPOSE 80/tcp
HEALTHCHECK --interval=40s --timeout=30s \
        --start-period=5s --retries=3 \
        CMD wget -O - -q http://${IP:-0.0.0.0}:12345/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
#
[root@node1 image3]#  docker build -t myweb:v0.3-5 ./
Sending build context to Docker daemon  4.096kB
Step 1/10 : FROM nginx:1.14.1-alpine
 ---> 77bae8d00654
Step 2/10 : ARG auth="white <406056573@qq.com>"
 ---> Running in 2ed17d634507
Removing intermediate container 2ed17d634507
 ---> 316c718ecaa0
Step 3/10 : LABEL maintainer "$auth"
 ---> Running in 14490be791a4
Removing intermediate container 14490be791a4
 ---> 76aa29538a16
Step 4/10 : ENV NGX_DOC_ROOT="/data/web/html"
 ---> Running in 087658d3afdf
Removing intermediate container 087658d3afdf
 ---> b72aa46ad75e
Step 5/10 : ADD index.html ${NGX_DOC_ROOT}/
 ---> 074c94b85f50
Step 6/10 : ADD entrypoint.sh /bin/
 ---> 53a8e7ab029a
Step 7/10 : EXPOSE 80/tcp
 ---> Running in 2847b2d8849e
Removing intermediate container 2847b2d8849e
 ---> d7cc415c0da3
Step 8/10 : HEALTHCHECK --interval=40s --timeout=30s         --start-period=5s --retries=3         CMD wget -O - -q http://${IP:-0.0.0.0}:12345/
 ---> Running in 7ee17b2899a4
Removing intermediate container 7ee17b2899a4
 ---> 9b5fee4cd750
Step 9/10 : CMD ["/usr/sbin/nginx","-g","daemon off;"]
 ---> Running in 681c4dce05b9
Removing intermediate container 681c4dce05b9
 ---> 0f8884fadf24
Step 10/10 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in 5862e4322b01
Removing intermediate container 5862e4322b01
 ---> 886e69981b3f
Successfully built 886e69981b3f
Successfully tagged myweb:v0.3-5
#验证
[root@node1 bs]# docker image inspect myweb:v0.3-5
"Labels": {
                "maintainer": "white <406056573@qq.com>"
            },
#验证--build-arg
[root@node1 image3]# docker build --build-arg auth="white <white@test.com>" -t myweb:v0.3-6 ./
Sending build context to Docker daemon  4.096kB
Step 1/10 : FROM nginx:1.14.1-alpine
 ---> 77bae8d00654
Step 2/10 : ARG auth="white 
 ---> Using cache
 ---> 316c718ecaa0
Step 3/10 : LABEL maintainer "$auth"
 ---> Running in 746c249968ec
Removing intermediate container 746c249968ec
 ---> d903ad31734c
Step 4/10 : ENV NGX_DOC_ROOT="/data/web/html"
 ---> Running in fab0b51ae852
Removing intermediate container fab0b51ae852
 ---> b84e2b3c8b5f
Step 5/10 : ADD index.html ${NGX_DOC_ROOT}/
 ---> bf6990335b96
Step 6/10 : ADD entrypoint.sh /bin/
 ---> 47d564c825a9
Step 7/10 : EXPOSE 80/tcp
 ---> Running in d64e47b8b5c5
Removing intermediate container d64e47b8b5c5
 ---> d73abae36814
Step 8/10 : HEALTHCHECK --interval=40s --timeout=30s         --start-period=5s --retries=3         CMD wget -O - -q http://${IP:-0.0.0.0}:12345/
 ---> Running in 95485a51d070
Removing intermediate container 95485a51d070
 ---> 1e54a1c73ecf
Step 9/10 : CMD ["/usr/sbin/nginx","-g","daemon off;"]
 ---> Running in 9ae84426fe2b
Removing intermediate container 9ae84426fe2b
 ---> 48e5a8f22618
Step 10/10 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in e373d1a1da2b
Removing intermediate container e373d1a1da2b
 ---> 58852bdd8525
Successfully built 58852bdd8525
Successfully tagged myweb:v0.3-6
#验证
[root@node1 bs]# docker image inspect myweb:v0.3-6
 "Labels": {
                "maintainer": "white "
            },
18、ONBUILD

用于在Dockerfile中定义一个触发器
Dockerfile用于build映像文件,此映像文件也可以作为base image被另外一个Dockerfile用作FROM指令的参数,并用来构建新的映像文件,在后面的这个Dockerfile文件中的FROM指令在build过程中被执行的时候,将会触发创建其base image的Dockerfile文件中的ONBUILD指令定义的触发器。

  • 语法
    ONBUILD

1、尽管任何指令都可以称为触发器指令,但是ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令。

2、使用包含ONBUILD指令的Dockerfile构建的镜像应该使用特殊标签。比如 ruby:v2.0-onbuild

3、在ONBUILD指令正使用ADD和COPY指令应该格外小心,因为新构建过程的上下文缺失指定的源文件时会失败

测试:

[root@node1 image3]# vim Dockerfile 

FROM nginx:1.14.1-alpine
ARG auth="white 
LABEL maintainer "$auth"
ENV NGX_DOC_ROOT="/data/web/html"
ADD index.html ${NGX_DOC_ROOT}/
ADD entrypoint.sh /bin/
ONBUILD ADD http://mirrors.aliyun.com/repo/Centos-7.repo /usr/local
EXPOSE 80/tcp
#在ONBUILD指令正使用ADD和COPY指令应该格外小心,因为新构建过程的上下文缺失指定的源文件时会失败
HEALTHCHECK --interval=40s --timeout=30s \
        --start-period=5s --retries=3 \
        CMD wget -O - -q http://${IP:-0.0.0.0}:12345/
CMD ["/usr/sbin/nginx","-g","daemon off;"]
ENTRYPOINT ["/bin/entrypoint.sh"]
#
[root@node1 image3]#  docker build -t myweb:v0.3-6 ./
Sending build context to Docker daemon  4.608kB
Step 1/11 : FROM nginx:1.14.1-alpine
 ---> 77bae8d00654
Step 2/11 : ARG auth="white 
 ---> Using cache
 ---> 316c718ecaa0
Step 3/11 : LABEL maintainer "$auth"
 ---> Using cache
 ---> 76aa29538a16
Step 4/11 : ENV NGX_DOC_ROOT="/data/web/html"
 ---> Using cache
 ---> b72aa46ad75e
Step 5/11 : ADD index.html ${NGX_DOC_ROOT}/
 ---> Using cache
 ---> 074c94b85f50
Step 6/11 : ADD entrypoint.sh /bin/
 ---> Using cache
 ---> 53a8e7ab029a
Step 7/11 : ONBUILD ADD http://mirrors.aliyun.com/repo/Centos-7.repo /usr/local
 ---> Running in 848291e7328a
Removing intermediate container 848291e7328a
 ---> 18abb66067e7
Step 8/11 : EXPOSE 80/tcp
 ---> Running in e5e995d06269
Removing intermediate container e5e995d06269
 ---> fb1db1855b71
Step 9/11 : HEALTHCHECK --interval=40s --timeout=30s         --start-period=5s --retries=3         CMD wget -O - -q http://${IP:-0.0.0.0}:12345/
 ---> Running in fd65814435e9
Removing intermediate container fd65814435e9
 ---> 596f21f56aeb
Step 10/11 : CMD ["/usr/sbin/nginx","-g","daemon off;"]
 ---> Running in bce544ab1f5a
Removing intermediate container bce544ab1f5a
 ---> 9502ad88c6c5
Step 11/11 : ENTRYPOINT ["/bin/entrypoint.sh"]
 ---> Running in 0eda01915320
Removing intermediate container 0eda01915320
 ---> 247a222547bf
Successfully built 247a222547bf
Successfully tagged myweb:v0.3-6
#查看可知ONBUILD后的命令在build过程未执行
#利用刚制作的myweb:v0.3-13镜像为基础制作镜像,只是验证ONBUILD 

[root@node1 image3]# cd ..
[root@node1 ~]# mkdir image4
[root@node1 ~]# cd image4
[root@node1 image4]# vim Dockerfile
[root@node1 image4]# vim Dockerfile


FROM myweb:v0.3-6
RUN mkdir /tmp/tes
#
[root@node1 image4]# docker build  -t test:v0.1-1 ./
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM myweb:v0.3-6
# Executing 1 build trigger
Downloading  2.523kB/2.523kB
 ---> ffc46fea5ab2
Step 2/2 : RUN mkdir /tmp/tes
 ---> Running in 9e2e9a2e1c12
Removing intermediate container 9e2e9a2e1c12
 ---> d48446f29c68
Successfully built d48446f29c68
Successfully tagged test:v0.1-1
#验证成功