1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Docker - Dockerfile之FROM ARG LABEL MAINTAINER RUN CMD指令详解

Docker - Dockerfile之FROM ARG LABEL MAINTAINER RUN CMD指令详解

时间:2022-11-21 19:55:27

相关推荐

Docker - Dockerfile之FROM ARG LABEL MAINTAINER RUN CMD指令详解

Docker - Dockerfile之FROM、ARG、LABEL、MAINTAINER、RUN、CMD指令详解

Dockerfile是什么

Dockerfile是一个包含用于组装镜像的所有指令的文本文档。Docker可以使用docker build命令读取Dockerfile中的指令自动生成镜像。

Dockerfile由一行行指令组成,支持以#开头的注释行。一般的,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。

FROM

构建所需要的镜像,就是一个定制化的过程,那么就需要以一个镜像为基础,在其基础上进行修改定制。而FROM指令就是用来指定基础镜像,因此在Dockerfile中,FROM指令是必备指定,并且必需是第一条指令!

格式

FROM [--platform=<platform>] <image> [AS <name>]FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]

FROM指令在Dockerfile中可以出现多次,这样可以创建多个镜像。每个FROM指令会清除由先前指令创建的任何状态。

通过添加可选的[AS <name>]可以给予一个新的构建阶段FROM指令进行命名。该名称可以在后续的FROM指令和COPY --from=<name>中使用,以引用此阶段中构建的镜像。

[:<tag>][@<digest>]也都是可选的。如果两个都不选择,那么构建器默认情况下将使用latest标签。如果构建器找不到该tagdigest版本,命令则会返回错误。

示例

FROM centosFROM centos:8.3.

除了指定现有的基础镜像以外,Dockerfile还存在一个特殊的镜像srcatch,这个镜像是一个虚拟的概念,并不实际存在,它表示一个空白的镜像:

FROM scratch

如果以scratch作为基础镜像,意味着将不使用任何镜像为基础,接下来所写的指令将作为第一层开始存在。不以任何系统为基础,直接将可执行文件复制进镜像的做法并不罕见。对Linux下静态编译的程序来说,并不需要其他操作提供其运行时支持,所需的一切库都在可执行文件里了,因此使用scratch作为基础镜像,可以使镜像的体积更加小巧,之前介绍Docker中关于Image的build命令时,就使用过scratch作为基础镜像,将主机上编译好的c语言程序放入镜像中运行:Docker - Docker Image及Image命令详解

FROM scratchADD hello /CMD ["/hello"]

ARG

Dockerfile中的ARG指令用以定义构建镜像时需要的参数。

格式

ARG <name>[=<default value>]

ARG指令定义了一个参数,用户可以通过docker build命令的--build-arg <varname>=<value>选项将其值传递给构建器(如果ARG指令定义的参数具有默认值,此时默认值会被覆盖)。

默认值

如果ARG指令定义的参数具有默认值(通过设置可选项[=<default value>]来实现),并且在构建镜像时未传递该参数的值,则构建器将使用默认值。

范围

ARG指令定义的参数从Dockerfile中定义的行开始生效,而不是从参数使用处开始生效。

FROM centos:7USER ${user:-kaven}ARG userUSER $user

使用该Dockerfile来构建image,通过-t选项来对image设置nametag

docker build --build-arg user=kaven_centos -t centos:kaven .

[root@izoq008ryseuupz ~]# docker build --build-arg user=kaven_centos -t centos:kaven .Sending build context to Docker daemon 1.316GBStep 1/4 : FROM centos:7---> 8652b9f0cb4cStep 2/4 : USER ${user:-kaven}---> Running in 0db31a9b2ba2Removing intermediate container 0db31a9b2ba2---> b9cd1bab4371Step 3/4 : ARG user---> Running in 68370ca04defRemoving intermediate container 68370ca04def---> e85d5f280c22Step 4/4 : USER $user---> Running in 357cc35e19faRemoving intermediate container 357cc35e19fa---> 94891bfd473bSuccessfully built 94891bfd473bSuccessfully tagged centos:kaven

查看USER是否设置成功。

docker image inspect centos:kaven

2行的USERkaven,因为在随后的第3行中定义了user参数,并且通过选项--build-arg传递该参数的值为kaven_centos,所以第4行的USER为kaven_centos

不要用ARG指令来保存密码之类的信息,因为通过docker history命令是能够看到这些信息的。

[root@izoq008ryseuupz ~]# docker history centos:kavenIMAGECREATED CREATED BY SIZECOMMENT94891bfd473b 2 days ago/bin/sh -c #(nop) USER kaven_centos 0B e85d5f280c22 2 days ago/bin/sh -c #(nop) ARG user 0B b9cd1bab4371 2 days ago/bin/sh -c #(nop) USER kaven 0B 8652b9f0cb4c 4 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 4 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 4 weeks ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB

Dockerfile的每一条指令都会新构建一层,从上面docker history命令产生的输出也可以看出来。

在通过ARG指令对参数进行定义之前或者没有通过--build-arg <varname>=<value>选项给定义的参数传递值,对参数的任何使用都会导致一个空字符串。

通过--build-arg <varname>=<value>选项给未定义的参数传递值,很显然这里并没有给user参数传递值。

docker build --build-arg xxx=kaven -t kaven .

[root@izoq008ryseuupz ~]# docker build --build-arg xxx=kaven -t kaven .Sending build context to Docker daemon 1.317GBStep 1/4 : FROM centos:7---> 8652b9f0cb4cStep 2/4 : USER ${user:-kaven}---> Using cache---> b9cd1bab4371Step 3/4 : ARG user---> Using cache---> e85d5f280c22Step 4/4 : USER $user---> Running in 20022b5eb237Removing intermediate container 20022b5eb237---> 0dbfbc335abb[Warning] One or more build-args [xxx] were not consumedSuccessfully built 0dbfbc335abbSuccessfully tagged kaven:latest

如果通过--build-arg <varname>=<value>选项传递了未在Dockerfile中定义的参数,则构建过程中会输出警告。

[Warning] One or more build-args [xxx] were not consumed

查看刚刚构建的镜像信息。

docker image inspect kaven

确实是空字符串。

LABEL

LABEL指令将一些元数据添加到镜像中。LABEL指令对应一个或多个键值对。

格式

LABEL <key>=<value> <key>=<value> <key>=<value> ...

LABEL <key>=<value> LABEL <key>=<value> LABEL <key>=<value> ...

Dockerfile的每一条指令都会新构建一层,所以,上面的多条LABEL指令可以写成一条指令,使用\符号进行换行操作:

LABEL <key>=<value> \<key>=<value> \<key>=<value> ...

示例

LABEL maintainer="kaven"LABEL version="1.0"LABEL description="This is Kaven's blog."

LABEL maintainer="kaven" version="1.0" description="This is Kaven's blog."

LABEL maintainer="kaven" \version="1.0" \description="This is Kaven's blog."

所以LABEL指令的作用也很明显了,就是给需要构建的镜像添加一些元数据,用来描述这个镜像的元数据信息。

MAINTAINER (Deprecated)

已弃用。

MAINTAINER <name>

MAINTAINER指令用于设置创建镜像的作者的标识。但LABEL指令比MAINTAINER指令灵活得多,应该使用LABEL指令,因为LABEL指令可以设置所需的任何元数据,并且可以很容易查看这些元数据,例如使用docker inspect命令。

比如:

MAINTAINER "kaven"

可以换成:

LABEL maintainer="kaven"

RUN

构建镜像时执行的命令。

格式

RUN <command>shell格式)RUN ["executable", "param1", "param2"]exec格式)

RUN指令将在当前镜像顶部的新层中执行任何命令并提交结果。生成的镜像将用于Dockerfile的下一步。

分层运行指令和生成提交符合Docker的核心概念,在Docker中提交是很轻量的,可以从镜像历史的任何一点来创建容器,就像源代码管理一样。

RUN apt-get updateRUN ["/bin/bash", "-c", "echo hello"]

RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache选项,如:docker build --no-cache

对于一些编译、软件的安装和更新等操作,无需分成好几层来操作,这样会使得镜像非常臃肿,拥有非常多的层,不仅仅增加了构建部署的时间,也很容易出错。例如:

RUN buildDeps=apt-get update && mkdir -p /usr/src/redis && apt-get purge -y --auto-remove $buildDeps

这里仅仅使用了一条RUN指令,所以只会新建一层。可以使用&&符号将多个命令分割开,使其先后执行。此时,一条RUN指令有可能会变得非常长,可以使用\进行换行操作。

刚刚编写的RUN指令,会发现在指令的结尾处添加了清理工作的命令。镜像是多层存储,每一层存储的东西不会在下一层删除,会一直跟随着镜像。因此在镜像构建时,一定要确保每一层只添加真正需要的东西,任何无关的东西都应该被清理掉。

CMD

格式

CMD ["executable","param1","param2"](exec格式,官方推荐的方式)。CMD ["param1","param2"](提供给ENTRYPOINT指令的默认参数)。CMD command param1 param2(shell格式)。

Dockerfile中只会有一条有效的CMD指令。如果有多条CMD指令,则只有最后一条CMD指令生效。

Docker不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,就需要指定运行的程序及参数。

所以,CMD指令的主要用途是为启动容器时指定运行的程序及参数,而RUN指令用于指定镜像构建时所要执行的命令。

示例

CMD echo "This is kaven's blog." CMD ["/bin/bash", "-c", "echo This is kaven's blog."]

当使用了ENTRYPOINT指令时,CMD指令的性质将会发生改变:CMD指令中的内容将会以参数形式传递给ENTRYPOINT指令,如下:

FROM ubuntuENTRYPOINT ["rm", "docker"]CMD ["-rf"]

其实,它真正执行的命令将会是:

rm docker -rf

Docker - Dockerfile之ENV、ENTRYPOINT、VOLUME、ONBUILD、STOPSIGNAL指令详解

例子

ARG CENTOS_VERSION=8.3.FROM centos:$CENTOS_VERSIONLABEL maintainer="kaven" \description="This is Kaven's blog." \version="centos.kaven.1.0" \name="CentOS Base Image" \date="0-12-15"CMD ["/bin/bash"]RUN yum install -y /pub/epel/epel-release-latest-8.noarch.rpmRUN yum updateRUN yum install -y mysql

使用Dockerfile来构建image,并且通过-t选项来对image设置nametag

docker build -t centos:kaven.1 .

[root@izoq008ryseuupz ~]# docker build -t centos:kaven.1 .Sending build context to Docker daemon 1.308GBStep 1/7 : ARG CENTOS_VERSION=8.3.Step 2/7 : FROM centos:$CENTOS_VERSION---> 300e315adb2fStep 3/7 : LABEL maintainer="kaven"description="This is Kaven's blog."version="centos.kaven.1.0"name="CentOS Base Image"date="0-12-15"---> Using cache---> 72b4d13e9df0Step 4/7 : CMD ["/bin/bash"]---> Using cache---> 69305c7a0a74Step 5/7 : RUN yum install -y /pub/epel/epel-release-latest-8.noarch.rpm---> Using cache---> 2f0cb9c6f0edStep 6/7 : RUN yum update---> Using cache---> 473cf8a6416eStep 7/7 : RUN yum install -y mysql---> Running in 4e5e446fe864Last metadata expiration check: 0:01:30 ago on Tue Dec 15 08:49:57 .Dependencies resolved.===========================================================================================Package Arch VersionRepo Size===========================================================================================Installing:mysql x86_64 8.0.21-1.module_el8.2.0+493+63b41e36 appstream 12 MInstalling dependencies:libedit x86_64 3.1-23.0329cvs.el8baseos102 kmariadb-connector-c-config noarch 3.0.7-1.el8appstream 13 kmysql-common x86_64 8.0.21-1.module_el8.2.0+493+63b41e36 appstream 148 kEnabling module streams:mysql 8.0Transaction Summary===========================================================================================Install 4 PackagesTotal download size: 12 MInstalled size: 63 MDownloading Packages:(1/4): mariadb-connector-c-config-3.0.7-1.el8.n 440 kB/s | 13 kB00:00 (2/4): mysql-common-8.0.21-1.module_el8.2.0+493 3.1 MB/s | 148 kB00:00 (3/4): mysql-8.0.21-1.module_el8.2.0+493+63b41e 33 MB/s | 12 MB00:00 (4/4): libedit-3.1-23.0329cvs.el8.x86_64.rp 60 kB/s | 102 kB00:01 --------------------------------------------------------------------------------Total 2.9 MB/s | 12 MB00:04warning: /var/cache/dnf/appstream-02e86d1c976ab532/packages/mariadb-connector-c-config-3.0.7-1.el8.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEYCentOS Linux 8 - AppStream 1.6 MB/s | 1.6 kB00:00 Importing GPG key 0x8483C65D:Userid: "CentOS (CentOS Official Signing Key) <security@>"Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65DFrom : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficialKey imported successfullyRunning transaction checkTransaction check succeeded.Running transaction testTransaction test succeeded.Running transactionPreparing :1/1 Installing : libedit-3.1-23.0329cvs.el8.x86_64 1/4 Installing : mariadb-connector-c-config-3.0.7-1.el8.noarch2/4 Installing : mysql-common-8.0.21-1.module_el8.2.0+493+63b41e36.x8 3/4 Installing : mysql-8.0.21-1.module_el8.2.0+493+63b41e36.x86_644/4 Running scriptlet: mysql-8.0.21-1.module_el8.2.0+493+63b41e36.x86_644/4 Verifying : mariadb-connector-c-config-3.0.7-1.el8.noarch1/4 Verifying : mysql-8.0.21-1.module_el8.2.0+493+63b41e36.x86_642/4 Verifying : mysql-common-8.0.21-1.module_el8.2.0+493+63b41e36.x8 3/4 Verifying : libedit-3.1-23.0329cvs.el8.x86_64 4/4 Installed:libedit-3.1-23.0329cvs.el8.x86_64 mariadb-connector-c-config-3.0.7-1.el8.noarch mysql-8.0.21-1.module_el8.2.0+493+63b41e36.x86_64 mysql-common-8.0.21-1.module_el8.2.0+493+63b41e36.x86_64 Complete!Removing intermediate container 4e5e446fe864---> 5b689502d907Successfully built 5b689502d907Successfully tagged centos:kaven.1

查看镜像的详细信息。

docker image inspect centos:kaven.1

查看所有镜像,很明显镜像构建成功了。

docker images

[root@izoq008ryseuupz ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEcentos kaven.1 5b689502d907 4 minutes ago 347MBcentos 8.3. 300e315adb2f 7 days ago209MB

基于构建的镜像创建centos.test.1容器。

docker run -it --name centos.test.1 centos:kaven.1

[root@izoq008ryseuupz ~]# docker run -it --name centos.test.1 centos:kaven.1[root@48ef31528900 /]# lsbin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var[root@48ef31528900 /]# exit exit

Dockerfile中的FROM、ARG、LABEL、MAINTAINER、RUN、CMD指令就介绍到这里。

写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。