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文件的重復內容編寫。