dockerfile案例三:ONBUILD用法

ONBUILD指令可以为镜像添加触发器。其参数是任意一个Dockerfile 指令。

当我们在一个Dockerfile文件中加上ONBUILD指令,该指令对利用该Dockerfile构建镜像(比如为A镜像)不会产生实质性影响。

但是当我们编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。

需要注意的是,如果是再利用B镜像构造新的镜像时,那个ONBUILD指令就无效了,也就是说只能再构建子镜像中执行,对孙子镜像构建无效。

编写父镜像dockerfile:

FROM centos
MAINTAINER father-image
ONBUILD RUN yum install tree -y
ONBUILD RUN mkdir mydir

构建镜像为father,并创建容器:

[root@izbp13m488196e5hna361rz mydocker]# docker build -f ./father -t father .
Sending build context to Docker daemon   5.12kB
Step 1/4 : FROM centos
 ---> 300e315adb2f
Step 2/4 : MAINTAINER father-image
 ---> Running in 7a5d0bfe6040
Removing intermediate container 7a5d0bfe6040
 ---> 0f9f850a3195
Step 3/4 : ONBUILD RUN yum install tree -y
 ---> Running in 9c98b3e1cd7d
Removing intermediate container 9c98b3e1cd7d
 ---> be9110ebe2ec
Step 4/4 : ONBUILD RUN mkdir mydir
 ---> Running in 200fd19f12d9
Removing intermediate container 200fd19f12d9
 ---> 083263449fa0
Successfully built 083263449fa0
Successfully tagged father:latest
[root@izbp13m488196e5hna361rz mydocker]# docker images
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
father              latest    083263449fa0   18 seconds ago   209MB
myip                latest    5f17f33fc659   3 days ago       243MB
mycentos            1.0       3b0cb5ffbc9f   2 weeks ago      281MB
nick/centos         latest    bc5060004e4f   3 weeks ago      209MB
nicktomcat          1.0       bad52e056690   5 weeks ago      601MB
nginx               latest    f6d0b4767a6c   5 weeks ago      133MB
tomcat              latest    feba8d001e3f   2 months ago     649MB
centos              latest    300e315adb2f   2 months ago     209MB
consol/tomcat-7.0   latest    7c34bafd1150   5 years ago      601MB
[root@izbp13m488196e5hna361rz mydocker]# docker run -it father
[root@f0fffccbd05d /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@f0fffccbd05d /]# tree
bash: tree: command not found

发现此时由父镜像启动的容器是没有tree命令的,根目录下也没有mydir目录。说明ONBUILD后面的指令并不会在自己的构建中执行。

编写子镜像dockerfile:

FROM father
MAINTAINER son

构建镜像为son:

[root@izbp13m488196e5hna361rz mydocker]# docker build -f ./son -t son .
Sending build context to Docker daemon  6.144kB
Step 1/2 : FROM father
# Executing 2 build triggers
 ---> Running in e4c90d9812c5
CentOS Linux 8 - AppStream                      953 kB/s | 6.3 MB     00:06    
CentOS Linux 8 - BaseOS                         1.7 MB/s | 2.3 MB     00:01    
CentOS Linux 8 - Extras                         3.8 kB/s | 8.6 kB     00:02    
Dependencies resolved.
================================================================================
 Package        Architecture     Version                 Repository        Size
================================================================================
Installing:
 tree           x86_64           1.7.0-15.el8            baseos            59 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 59 k
Installed size: 109 k
Downloading Packages:
tree-1.7.0-15.el8.x86_64.rpm                    204 kB/s |  59 kB     00:00    
--------------------------------------------------------------------------------
Total                                            32 kB/s |  59 kB     00:01     
CentOS Linux 8 - BaseOS                         1.6 MB/s | 1.6 kB     00:00    
warning: /var/cache/dnf/baseos-f6a80ba95cf937f2/packages/tree-1.7.0-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
Importing GPG key 0x8483C65D:
 Userid     : "CentOS (CentOS Official Signing Key) <security@centos.org>"
 Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                        1/1 
  Installing       : tree-1.7.0-15.el8.x86_64                               1/1 
  Running scriptlet: tree-1.7.0-15.el8.x86_64                               1/1 
  Verifying        : tree-1.7.0-15.el8.x86_64                               1/1 

Installed:
  tree-1.7.0-15.el8.x86_64                                                      

Complete!
Removing intermediate container e4c90d9812c5
 ---> Running in aa24e33373c8
Removing intermediate container aa24e33373c8
 ---> 6c515ca26675
Step 2/2 : MAINTAINER son
 ---> Running in a5acba38787a
Removing intermediate container a5acba38787a
 ---> 9d087b204a81
Successfully built 9d087b204a81
Successfully tagged son:latest

在执行第一步FROM father时,提示Executing 2 build trigger,说明有两个触发器被启动。

根据son镜像创建容器:

[root@izbp13m488196e5hna361rz mydocker]# docker run -it son
[root@9b18259573a6 /]# ls
bin dev etc home lib lib64 lost+found media mnt mydir opt proc root run sbin srv sys tmp usr var
[root@9b18259573a6 /]# tree opt/
opt/

0 directories, 0 files

容器的根目录下有mydir目录,也有tree命令。

总结:

在父镜像中使用ONBUILD指令,目的是让所有继承这个父镜像的子镜像都执行ONBUILD指定的指令,而父镜像本身并不执行。

在实际工作中,利用ONBUILD指令,通常用于创建一个模板镜像,后续可以根据该模板镜像创建特定的子镜像,需要在子镜像构建过程中执行的一些通用操作就可以在模板镜像对应的dockerfile文件中用ONBUILD指令指定。 从而减少dockerfile文件的重复内容编写。

参考:https://www.cnblogs.com/51kata/p/5265107.html

原文地址:https://www.cnblogs.com/xulan0922/p/14431131.html