【云原生】一文学会Dockerfile所有常用命令

 

        Docker file的作用方便管理员来根据需求来进行构建镜像,前面学习过commit来将一个容器打包成镜像,但是Docker 并不建议用户通过commit方式构建镜像。

原因如下:

1. 这是一种手工创建镜像的方式,容易出错,效率低且可重复性弱。比如要在 debian base 镜像中也加入 vi,还得重复前面的所有步骤。 
2. 更重要的:使用者并不知道镜像是如何创建出来的,里面是否有恶意程序。也就是说无法对镜像进行审 计,存在安全隐患。 
3. 用 Dockerfile(推荐方法)构建镜像,底层也 docker commit 一层一层构建新镜像的。docker file能够帮 助我们更加深入地理解构建过程和镜像的分层结构。

        运行 docker build 命令,-t 将新镜像命名为 centos-yum,命令末尾的 . 指明 build context 为当前目录。 Docker 默认会从 build context 中查找名为Dockerfile 文件,我们也可以通过 -f 参数指定 Dockerfile 的位 置。

构建一个安装了vim的centos7

[root@localhost ~]# vi Dockerfile
FROM centos:7
RUN yum install -y vim
[root@localhost ~]# docker build -t centos7:vim .
[+] Building 18.9s (6/6) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                    0.0s
 => => transferring dockerfile: 74B                                                                                                                     0.0s
 => [internal] load .dockerignore                                                                                                                       0.0s
 => => transferring context: 2B                                                                                                                         0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                             0.0s
 => [1/2] FROM docker.io/library/centos:7                                                                                                               0.0s
 => [2/2] RUN yum install -y vim                                                                                                                       17.8s
 => exporting to image                                                                                                                                  1.1s
 => => exporting layers                                                                                                                                 1.1s
 => => writing image sha256:634da32af45aaaea9c68309bb41676ba9b4b96586621ed0600aa726fa8f93b8c                                                            0.0s
 => => naming to docker.io/library/centos7:vim                                                                                                          0.0s
[root@localhost ~]# docker images
REPOSITORY                                          TAG       IMAGE ID       CREATED         SIZE
centos7                                             vim       634da32af45a   7 seconds ago   468MB
registry.cn-hangzhou.aliyuncs.com/conquerbug/test   v1        feb5d9fea6a5   21 months ago   13.3kB
centos                                              7         eeb6ee3f44bd   21 months ago   204MB

构建这个镜像的过程

  1. 运行docker build命令 -t 将新镜像命名为centos7:vim,找到当前路径的Dockerfile文件

  2. 开始根据Dockerfile的命令来进行构建

  3. 执行FROM,将centos7做为base镜像

  4. 执行RUN,安装vim

    扫描二维码关注公众号,回复: 15746176 查看本文章
  5. 启动一个临时的容器,在容器中安装vim

  6. 安装完成后,将当前容器创建为镜像

  7. 删除临时容器

  8. 镜像构建完成,通过docker images 查看镜像信息

Docker file命令

1.FROM

        功能为指定基础镜像,并且必须是第一条指令。 如果不以任何镜像为基础,那么写法为:FROM scratch。 同 时意味着接下来所写的指令将作为镜像的第一层开始 语法:

FROM <image>
FROM <image>:<tag>

2.RUN

功能为运行指定的命令 RUN命令有两种格式

  1. RUN

  2. RUN ["executable", "param1", "param2"] 第一种后边直接跟shell命令 . 在linux操作系统上默认 /bin/sh -c . 在windows操作系统上默认 cmd /S /C 第二种是类似于函数调用。 可将executable理解成为可执行文 件,后面就是两个参数。

两种写法比对: 
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME 
RUN ["/bin/bash", "-c", "echo hello"]

        注意:多行命令不要写多个RUN,原因是Dockerfile中每一个指令都会建立一层. 多少个RUN就构建了多 少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。 RUN书写时的换行 符是\

3.CMD

功能为容器启动时要运行的命令

语法有三种写法

  1. CMD ["executable","param1","param2"]

  2. CMD ["param1","param2"]

  3. CMD command param1 param2

第三种比较好理解了,就时shell这种执行方式和写法 第一种和第二种其实都是可执行文件加上参数的形 式 举例说明两种写法:

CMD [ "sh", "-c", "echo $HOME"]
CMD [ "echo", "$HOME" ]

        注意:补充细节:这里边包括参数的一定要用双引号,就是",不能是单引号。千万不能写成单引号。 原因是参数传递后,docker解析的是一个JSON array

4.RUN和CMD的区别

        不要把RUN和CMD搞混了。 RUN是构件容器时就运行的命令以及提交运行结果 CMD是容器启动时执行的命 令,在构件时并不运行,构件时紧紧指定了这个命令到底是个什么样子

5.LABEL

        功能是为镜像指定标签,为镜像写一些注释信息

语法:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
一个Dockerfile种可以有多个LABEL,如下:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines.

但是并不建议这样写,最好就写成一行,如太长需要换行的话则使用\符号 如下:

LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

注意:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖

6.EXPOSE

        功能为暴漏容器运行时的监听端口给外部 但是EXPOSE并不会vim 使容器访问主机的端口 如果想使得容器与主 机的端口有映射关系,必须在容器启动的时候加上 -P参数

语法:

EXPOSE 90/tcp 9090/udp 6000/tcp

注意:如果在端口号后面加/tcp,默认为tcp协议,如果需要UDP端口需要添加/udp

7.ENV

功能为设置环境变量 语法有两种

1. ENV 变量名=值
2. ENV = 变量名1=值1,变量名2=值2

两者的区别就是第一种是一次设置一个,第二种是一次设置多个

例子:创建一个httpd服务的镜像

[root@localhost ~]# vi Dockerfile
FROM centos:7
RUN yum install -y httpd
CMD /bin/bash
LABEL version="1.0"
LABEL "QQ"="34241235324"
LABEL "[email protected]"
EXPOSE 80/tcp
ENV service=httpd
​
docker build -t cenos7:httpd .
docker run -itd --name httpd --privileged=true cenos7:httpd /usr/sbin/init -p 80:80
docker exec -it 487cdf7ddfc56249f59bee6639b52b03f2bd1090c6430eafc2e6973567249372 /bin/bash

8.ADD

        一个复制命令,把文件复制到镜象中。 如果把虚拟机与容器想象成两台linux服务器的话,那么这个命令就类似 于scp,只是scp需要加用户名和密码的权限验证,而ADD不用。

语法如下:

ADD source源文件 目标位置
ADD http:/aliyuan/httpd.html 目标位置
ADD tar包 目标位置

        注意:尽量不要把写成一个文件夹,如果是一个文件夹了,复制整个目录的内容,包括文件系统元数据

9.COPY

复制命令,与ADD类似

语法如下:

COPY 源文件 目标文件

10.ADD与COPY的区别

  1. ADD在拷贝tar包时,到目标位置会自动解压,COPY还是源文件不会有任何变化

  2. ADD在拷贝过程中可以使用http链接来下载文件

11.ENTRYPOINT

该命令与CMD类似,用于执行命令使用,还可以与CMD命令一起拼合使用

它与CMD的区别: ​ 相同点:只能写一条,如果写多条,那么只有最后一条生效

不同点:CMD在创建容器时,在后面添加其他的CMD指令,CMD会被覆盖,但是ENTRYPOINT不会被覆盖,如果两个同时使用,CMD会变成ENTRYPOINT的参数

语法如下:

ENTRYPOINT ["ls","-l"]
ENTRYPOINT ls -al

        注意: 如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD是一个完整的指令,那么它们两个会互相覆 盖,谁在最后谁生效 如下:

ENTRYPOINT ["ls","-l"]
CMD ["ps","-ef"]

12.USER

        设置启动容器的用户,可以是用户名或UID,所以,只有下面的两种写法是正确的

语法如下:

USER zhangsan
USER UUID

13.WORKDIR

        设置工作目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。如果不存在则会创建,也可以设置多次

语法如下:

WORKDIR /tmp
ENTRYPOINT ls -l

14.ARG

        语法: ARG [=] 设置变量命令,ARG命令定义了一个变量,在docker build创建镜像的时候,使用 --build-arg = 来指定参数 如果用户在build镜像时指定了一个参数没有定义在Dockerfile种,那么将有一个Warning 提示如 下:

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

        我们可以定义一个或多个参数并赋予默认值。如下:

ARG name
ARG age=18

         使用场景,当我们需要指定一些软件的版本时,可以使用ARG来指定外部变量,在下载时使用较新的版本,还可以定义默认值

注意:如果我们给了ARG定义的参数默认值,那么当build镜像时没有指定参数值,将会使用这个默认值

15.VOLUME

        可实现挂载功能,可以将内部文件夹挂载到外部

语法如下:

VOLUME /var/log

        使用环境,一般的使用场景为需要持久化数据,当容器被删除后,数据将会被全部删除,当需要把容器内的数据持久化时,可以使用该命令,当容器被删除时,指定的文件,在外部不会丢失。

16.ONBUILD

        这个命令只对当前镜像的子镜像生效。 在镜像A的Dockerfile文件中添加,当B镜像的dockerfile中FROM使用的镜像为A,此时当B镜像RUN构建时,就会执行A镜像中添加的ONBUILD指令。

语法如下:

ONBUILD [INSTRUCTION]

比如当前镜像为A,在Dockerfile种添加:

ONBUILD RUN ls -al 这个 ls -al 命令不会在A镜像构建或启动的时候执行

此时有一个镜像B是基于A镜像构建的,那么这个ls -al 命令会在B镜像构建的时候被执行。

17.STOPSIGNAL

        这个命令的作用是当容器退出时给系统发送什么样的指令

语法如下:

STOPSIGNAL signal

 附真实案例:
        要求:制作一个httpd服务的centos7镜像

FROM centos:7
LABEL version="httpd v1"
LABEL "emill"="[email protected]"
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /usr/local/src
ADD httpd-2.4.57.tar.gz ./
WORKDIR /usr/local/src/httpd-2.4.57
RUN yum install -y epel-release.noarch && yum makecache fast
RUN yum install -y gcc gcc++ make apr-devel apr apr-util apr-util-devel pcre-devel
RUN ./configure --prefix=/usr/local/apache2 --enable-mods-shared=most --enable-so && make && make install
RUN sed -i 's/#ServerName www.example.com:80/ServerName localhost:80/g' /usr/local/apache2/conf/httpd.conf
RUN /usr/local/apache2/bin/httpd
EXPOSE 80/tcp
CMD /usr/local/apache2/bin/httpd -D FOREGROUND

        到此,就把常用的dockerfile指令介绍完毕了,大家在工作中,常用那些指令,欢迎大家进行补充,如果觉得还写的不错,记得点赞+收藏+关注

猜你喜欢

转载自blog.csdn.net/weixin_53678904/article/details/131426141