Docker镜像构建 您所在的位置:网站首页 构建docker镜像的两种方法 Docker镜像构建

Docker镜像构建

2023-06-06 16:19| 来源: 网络整理| 查看: 265

WORKDIR dirpath

示例:

WORKDIR /usr/local ENV

  用于为镜像定义所需的环境变量,并可被Dockfile中位于其以后的指令所调用,如ADD、COPY、RUN等调用格式为$variable_name或者${variable_name},此外在启动容器时候这些变量也是存在的。

语法:

ENV ENV = ...

注意: 第一种格式中key之后的所有值会被作为value,因此一次只能设置一个变量 第二种格式可一次性设置多个变量,每个变量为一个key=value的键值对,如果value种包含空格,可以用反斜线(\)转义,也可以通过对value加引号进行标识,此外反斜线也可用于续行,多个变量时候建议使用。 

示例:

ENV myName="John Doe” \ myDog=Rex \ myCat=fluffy ENV myCat fluffy RUN

  用于在build过程中运行的程序,可以是任何指令,可以指定多个RUN

语法:

RUN #shell 格式默认linux采用/bin/sh -c,windows采用cmd /S /C RUN ["executable", "param1", "param2”] #可执行程序格式

示例:

RUN yum install -y nginx RUN ["/bin/bash", "-c", "echo hello"] EXPOSE

  用于为容器暴露端口到外部,用于实现通讯,类似于docker run的-p选项

语法:

EXPOSE [/...]

解释: port:端口 protocol:协议,可以是udp或tcp,默认tcp 示例:  EXPOSE 8080 EXPOSE 8080/udp 8088/tcp VOLUME

  用于在image中创建一个挂载目录,以挂载宿主机上的目录

语法:

VOLUME VOLUME ["path"]

解释: path:代表容器中的目录,与docker run 不同,Dockerfile中不能指定宿主机目录,默认使用docker管理的挂载点 示例:  VOLUME ["/var/log/“] VOLUME /myvol CMD

  用于为在镜像启动为容时候提供的默认命令,该指定可以有多个,但是只有最后一个生效。 语法 : CMD command param1 param2 #shell格式,含有shell环境 CMD ["executable","param1","param2”] #可执行程序格式 CMD ["param1","param2”] #第三种用于为ENTRYPOINT提供默认参数

注意:

在第一种格式中command 通常是一个shell命令,且默认以/bin/sh -c来运行它,这意味着此进程在容器的的PID不为1,不能接受unix信号,因此使用docker stop 命令停止容器时,此进程接受不到SIGTERM信号。 第二种格式是可执行程序运行方式,不会以"/bin/sh -c”来发起,无shell环境,所有shell变量不能引用,但是可以用"/bin/bash -c”作为启动命令达到第一种格式效果 第三种格式需要结合ENTRYPOINT使用,作用是为其提供默认参数  ENTRYPOINT

  类似于CMD功能,用于为启动容器指定默认启动命令,与CMD不同的是ENTRYPOINT命令不会随着docker run 后使用的命令覆盖而会把命令作为参数,除非docker run 参数中指定了—entrypoint 语法 : ENTRYPOINT ENTRYPOINT ["", "", ""]

注意事项: 与CMD类似,第一种方式默认会以/bin/sh -c 启动,而第二种则不会,也就意味着没有shell环境 通常ENTRPOINT用于使用ENTRPOINT脚本启动 当CMD与ENTRYPOINT同时存在时,CMD的参数为ENTRYPOINT提供 

示例:

[“nginx”,"-g","daemon off"] USER

  用于指定构建镜像时RUN、CMD、ENTRYPOINT等指令使用的用户或UID,默认情况容器运行身份为ROOT 语法 : USER [:] USER [:]

注意事项: 指定的USER或者GROUP必须在容器中存在,否则指令会运行失败 示例:  USER nginx STOPSIGNAL

  该指令用于设置容器停止时向容器内进程发送的信号,列如 9 、SIGKILL、SIGTERM。

语法:

STOPSIGNAL signal

示例:

STOPSIGNAL SIGKILL

注意事项: 向容器发送信号只能被PID=1的进程所接收,当PID=1进程不是应用进程时候,应用进程收不到终止信号。  HEALTHCHECK

  该指令在1.12版本中添加,用于对容器中的应用进行健康检查,不做检查使用NONE。当对容器做了健康检查时候,检查值为0表示成功,非0表示不健康。  语法: HEALTHCHECK [OPTIONS] CMD command

其中OPTIONS有如下选项:

--interval=DURATION 检查间隔(默认: 30s) --timeout=DURATION 超时时间(默认t: 30s) --start-period=DURATION 等待检查的时间,默认0s代表一启动就检查 (默认: 0s) --retries=N (default: 3)  重试次数 

示例:

HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/ || exit 1 SHELL

  将可执行程序运行为shell环境,默认以/bin/sh -c运行

语法:

SHELL ["executable", "parameters"]

示例:

SHELL ["echo", “hello"] #等价于 RUN echo hello

ARG   该指令用于在build过程中提供参数,而在命令行使用--build-arg =来传递参数值,这样可以使用参数进行构建镜像。  语法: ARG [=]

示例: Dockerfile FROM nginx ARG CONF="/tmp/nginx.conf" LABEL Author=wd RUN touch "${CONF}"

构建镜像:

[root@app51 ~]# docker build --build-arg CONF='/etc/test.conf' -t nginx:v15.2 ./ Sending build context to Docker daemon 225.6MB Step 1/4 : FROM nginx ---> f09fe80eb0e7 Step 2/4 : ARG CONF="/tmp/nginx.conf" ---> Using cache ---> ac081589c644 Step 3/4 : LABEL Author=wd ---> Using cache ---> 53b9b0ba4460 Step 4/4 : RUN touch "${CONF}" ---> Running in 50debe96f876 Removing intermediate container 50debe96f876 ---> d8680a2433bc Successfully built d8680a2433bc Successfully tagged nginx:v15.2

运行容器查看:

[root@app51 ~]# docker run --rm nginx:v15.2 ls /etc/test.conf -l -rw-r--r-- 1 root root 0 Feb 27 11:18 /etc/test.conf ONBULD

  用于在Dockerfile中定义一个触发器,当制作出来的镜像被别人用于基础镜像时候自动触发。

语法:

ONBUILD [INSTRUCTION]

解释: INSTRUCTION:指令可以是RUN 、COPY等 注意事项: ONBUILD不会触发FROM指令。 在镜像标签中应明确指出onbuild关键字,以标记使用其基础镜像会触发其他指令 

示例:

ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src

 

四、使用multi-stage

  在构建镜像过程中,我们可能只需要某些镜像的产物,比如在运行一个go程序需要先go程序包编译后才运行,如果在一个镜像里面完成,先要经过安装编译环境,程序编译完再安装运行环境,最后运行程序,这样的镜像体积往往比较大,不利于我们使用。而真正我们需要的镜像是只有程序包和运行环境,编译环境的构建在运行容器时候是不需要的,所以Docker提供了一种解决方案就是multi-stage(多阶段构建)。     Docker允许多个镜像的构建可以使用同一个Dockerfile,每个镜像构建过程可以称之为一个stage,简单理解就是一个FROM指令到下一个FROM指令,而每个stage可使用上一个stage过程的产物或环境(其实还支持其他镜像的),这样一来,最终所得镜像体积相对较小。不仅如此多阶段构建同样可以很方便地将多个彼此依赖的项目通过一个Dockerfile就可轻松构建出期望的容器镜像,而不用担心镜像太大、项目环境依赖等问题。     通过上述介绍,我们可以在第一个stage将go程序编译得到编译后程序包,然后在第二个stage中直接拷贝编译好的go程序包到运行环境中,最后的镜像中就只有程序包和运行环境。以下作为示例:  FROM golang:1.7.3 WORKDIR /go/src/github.com/alexellis/href-counter/ RUN go get -d -v golang.org/x/net/html COPY app.go . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=0 /go/src/github.com/alexellis/href-counter/app . CMD ["./app"]

在以上Dockerfile中存在两个FROM指令,也就是两个stage,第一个stage用于构建产物,而在第二个stage中使用COPY --from=0 意思将第一个stage中的/go/src/github.com/alexellis/href-counter/app拷贝到.目录,第二个stage仅仅相当于执行copy就有了构建产物,不用在安装编译环境,镜像会很缩小。    命名stage

  默认情况下,stage未命名,可以通过整数来引用它们,第一个stage表示0,第二个表1以此类推。 但是,当有多个stage时候,这样会显得麻烦,Docker提供AS 语法可以为stage命名:

FROM golang:1.7.3 as builder

然后在另一个stage中使用:

COPY --from=builder /go/src/github.com/alexellis/href-counter/app . 使用本地stage

  除了可以使用Dockerfile中的stage外,构建镜像时候还可以直接使用本地已存在的环境和产物,例如:

COPY --from=nginx:latest /etc/nginx/nginx.conf /nginx.conf 构建镜像建议

基础镜像尽量选择比体积较小的镜像,如每个官方发行的alpine镜像。虽然这版本镜像比较小,但是与之带来的是利用该类镜像运行的容器中排错的命令很少; 使用RUN指令时候,尽量把多个RUN指令合并为一个,通常做法是使用&&符号; 通过multi-stage方法减少一些不必要使用的环境来减小镜像; 安装完成软件同时删除一些不需要的文件或目录; 

ref: 《Dockerfile reference》 《Use multistage builds》

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有