zoukankan      html  css  js  c++  java
  • 使用Dockerfile创建镜像

    文本格式的配置文件

    基本结构

    由一行行命令语句组成,支持 # 注释
    一般,主体分为4部分:基础镜像信息,维护者信息,镜像操作指令,容器启动时执行指令
    # 镜像名称
    FROM ubuntu:xeniel
    # 维护者信息
    LABEL maintainer docker_user<docker_user@email.com>
    # 镜像操作指令 每运行一条RUN指令,镜像添加新的一层,并提交
    RUN echo "deb http://archive.ubuntu.com/ubuntu/ xeniel main universe" >> /etc/apt/sources.list
    RUN apt-get update && apt-get install -y nginx
    RUN echo " daemon off;" >> /etc/nginx/nginx.conf
    # CMD指令 运行容器时的操作指令
    CMD /usr/sbin/nginx

    指令说明

    1.ARG
    定义创建创建镜像过程中使用的变量
    格式:
    • ARG <name> [=<default value>]
    在执行docker build时,可以通过 -build-arg [=] 来为变量赋值,当镜像编译成功后,ARG指定的变量将不再存在(ENV指定的变量将在镜像中保留)
    内置变量(不区分大小写):HTTP_PROXY, HTTPS_PROXY, FTP_PROXY, NO_PROXY
    2.FROM
    指定所创建镜像的基础镜像
    格式:
    • FROM <image> [AS <name>]
    • FROM <image>:<tag> [AS <name>]
    • FROM <image>@<digest> [AS <name>]
    任何Dockerfile第一条指定必须是 FROM 指令。如果在统一个Dockerfile中创建了多个镜像时,可以使用多个FROM指令(每个镜像一次)
    ARG VERSION=9.3
    FROM debian:${VERSION}
    3.LABEL
    添加元数据标签信息,辅助过滤镜像
    格式:
    • LABEL <key>=<value> <key>=<value> <key>=<value> ...
    4.EXPOSE
    声明镜像内服务监听的端口
    格式:
    • EXPOSE <port> [<port>/<protocol> ...]
    该指令只起到声明作用,并不会自动完成端口映射
    5.ENV
    指定环境变量,在镜像生成过程中,会被后续RUN指令使用,在镜像启动的容器中也会存在。
    格式:
    • ENV <key> <value> ...
    • ENV <key>=<value> ...
    指令指定的环境变量在运行时可以被覆盖掉,如docker run --env <key>=<value> built_image
    当一条ENV指令中同时为多个环境变量赋值并且值也是从环境变量读取时,会为变量都赋值后再更新。如下面的指令,最终结果为key1=value1 key2=value2:
    ENV key1=value2
    ENV key1=value1 key2=${ key1 }
    6.ENTRYPOINT
    指定镜像默认入口命令,该命令会在启动容器时作为根命令执行,所有传入值作为根命令的参数。
    格式:
    • ENTRYPOINT ["executable", "param1", "param2"] exec调用执行
    • ENTRYPOINT command param1 param2 shell中执行
    此时,CMD指令指定值将作为根命令的参数
    每个Dockerfile只能有一个ENTRYPOINT,当指定多个时,只有最后一个起效
    在运行时,可以被 --entrypoint 参数覆盖掉
    7.VOLUME
    创建一个数据卷挂载点
    格式:
    • VOLUME ["/data"]
    运行时可以从本地主机或其他容器挂载数据卷,一般用来存放数据库和需要保持的数据等
    8.USER
    指定运行容器时的用户名或UID,后续的RUN等指令也会使用指定的用户身份
    格式:
    • USER daemon
    当服务不需要管理员权限时,可以通过该命令指定运行用户,并且可以在Dockerfile中创建所需要的用户。例如:
    RUN groundadd -r postgres && useradd --no-log-init -r -g postgres postgres
    要临时获取管理员权限可以使用 gosu 命令
    9.WORKDIR
    为后续的 RUN,CMD,ENTRYPOINT指定配置工作目录
    格式:
    • WORKDIR /path/to/workdir
    可以使用多个WORKDIR指令,后续命令如果参数时相对路径,则会基于之前命令指定的路径。例如:
    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd
    则最终路径为 /a/b/c
    推荐只使用绝对路径
    10.ONBUILD
    指定当基于所生成镜像创建子镜像时,自动执行的操作指令
    格式:
    • ONBUILD [INSTRUCTION]
    隐式执行,推荐在使用它的镜像标签中进行标注,例如 ruby:2.1-onbuild
    ONBUILD指令在创建专门用于自动翻译、检查等操作的基础镜像时,十分有用。
    11.STOPSIGNAL
    指定所创建镜像启动的容器接收退出的信号值:
    • STOPSIGNAL signal
    12.HEALTHCHECK
    配置所启动容器如何进行健康检查(如何判断健康与否),1.12之后支持
    格式:
    • HEALTHCHECK [OPTIONS] CMD command 根据所执行指令是否为0来判断
    • HEALTHCHECK NONE 禁止基础镜像中的健康检查
    OPTION支持参数如下:
    • -interval=DURATION (default 30s) 过多久检查一次
    • -timeout=DURATION (default 30s) 每次检查等待结果的超时
    • -retries=N (default 3) 如果失败了,重试几次才最终确认失败
    13.SHELL
    指定其他命令使用shell时的默认shell类型:
    • SHELL ["executable", "parameters"]
    默认值为 ["/bin/sh", "-c"]
     
    对于windows系统,shell路径中使用了“”作为分隔符,建议在Dockerfile开头添加 # escape=`来指定转义符
     
     
     
    1.RUN
    运行指令命令
    格式:
    • RUN <command>
    • RUN ["executable", "param1", "param2"]
    后者指定会被解析成json数组,因此必须用双引号。
    前者默认在shell终端中运行命令,即 /bin/sh -c,后者则使用 exec 执行,不启动shell 环境
    指定使用其他终端类型,可以用后者实现,例如:
    RUN ["/bin/bash", "-c", "echo hello"]
    每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像层,当命令较长时可以使用 来换行。
    2.CMD
    指定启动容器时默认执行的命令
    格式:
    • CMD ["executable", ”param1“, "param2"] 相当于执行 executable param1 param2, 推荐方式
    • CMD command param1 param2 默认在shell中执行,提供给需要交互的应用
    • CMD ["param1", "param2"] 提供给ENTRYPOINT的默认参数
    每个Dockerfile只能有一条CMD命令,如果指定了多条命令,只有最后一条被执行
    如果启动容器时手动指定了运行的命令(作为run命令的参数),则会覆盖掉CMD指定的命令
    3.ADD
    添加内容到镜像
    格式:
    • ADD <src> <dest>
    该命令将复制指定的<src>路径下内容到容器中的<dest>路径下
    其中<src>可以是Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是一个tar文件(自动解压为目录)
    <dest>可以是镜像内绝对路径,或者相对于工作目录(WORKDIR)的相对路径
    路径支持正则格式,例如:
    ADD *.c /code/
    4.COPY
    复制内容到镜像
    格式为:
    • COPY <src> <dest>
    复制本地主机的<src>(为Dockerfile所在目录的相对路径,文件或目录)下内容到镜像中的<dest>。目标路径不存在时,会自动创建。
    路径同样支持正则格式
    COPY和ADD指令功能类似,当使用本地目录为源目录时,推荐使用COPY

    创建镜像

    • docker [image] build [OPTIONS] PATH | URL | -
    该命令将读取指定路径(包括子目录)下的Dockerfile,并将路径下的所有数据作为上下文发送给Docker服务器端。Docker服务器端校验Dockerfile格式通过后,逐条执行其中定义的指令,碰到ADD,COPY,RUN指令会生成一层新的镜像,最终如果创建镜像成功,则返回最终镜像的ID
    如果上下文过大,会延缓创建过程
    如果使用非上下文路径下的Dockerfile,可以通过 -f 选项来指定其路径
    要指定镜像的标签信息,可以通过 -t 选项。可以重复使用多次为镜像一次添加多个名称
    例如,上下文路径为/tmp/docker_builder/,并希望生成镜像标签为builder/first_image:1.0.0,可以使用下面的命令:
    docker build -t builder/first_image:1.0.0 /tmp/docker_builder/
    命令选项 ...

    选择父镜像

    普通镜像:往往不存在FROM指令,或基于scratch镜像(FROM scratch)
    基础镜像(第三方创建,基于基础镜像)

    使用.dockerignore文件

    忽略匹配路径或文件,创建竟像是不将无关文件发送到服务端
    支持golang风格的正则表达式:
    • * 任意多个字符
    • ? 单个字符
    • ! 不匹配(即不忽略指定的路径或文件)

    多步骤创建

    17.05版本开始支持 Multi-stage build。
    对于需要编译的应用,如c, go, java等来说,通常来说需要准备两个环境的docker镜像:
    • 编译环境镜像:包括完整的编译引擎,依赖库等,往往比较庞大。目的是编译应用为二进制文件
    • 运行环境镜像:体积较小
    以go语言为例。创建干净目录,进入目录中,创建main.go文件,内容为:
    # main.go will output "hello, docker"
    package main
    import {
    "fmt"
    }
    func main(){
    fmt.Println("hello, docker")
    }
    创建Dockerfile文件,使用golang:1.9镜像编译应用二进制文件为app,使用精简的镜像alpine:latest作为运行环境。Dockerfile完整内容为:
    FROM golang:1.9 as builder
    RUN mkdir -p /go/src/test
    WORKDIR /go/src/test
    COPY main.go .
    RUN CGO_ENABLED=0 GOOS=linux go build -o app .
     
    FROM alpine:latest
    RUN apk --no-cache add ca-certificates
    WORKDIR /root/
    COPY --from=builder /go/src/test/app .
    CMD ["./app"]
    执行如下命令创建镜像,并运行应用:
    docker build -t yeasy/test-multistage:latest .
    docker run --rm yeasy/test-multistage:latest
    查看生成的最终镜像:
    docker image|grep test-multistage
     
     

    最佳实践

    尽量吃透每个指令的含义和执行结果
    阅读学习docker hub的镜像及对应的dockerfile
    • 精简镜像用途
    • 选择合适的基础镜像 大系统镜像ubuntu 小系统镜像alpine、busybox、debian 应用镜像 node:slim
    • 提供注释和维护者信息
    • 正确使用版本号 避免环境不一致导致的问题 latest
    • 减少镜像层数 尽量合并RUN、ADD、COPY指令
    • 恰当使用多步骤创建
    • 使用 .dockerignore文件
    • 及时删除临时文件和缓存文件 使用apt-get后,/var/cache/apt 会缓存一些安装包
    • 提高生成速度 合理使用cache,减少目录下的文件,使用 .dockerignore文件指定等
    • 调整合理的指令顺序 在开启cache的情况下,内容不变的指令尽量放在前面,这样可以尽复用
    • 减少外部源的干扰 如果确实要从外部引入数据,需要指定持久的地址,并带版本信息等,让他人可以复用而不出错
  • 相关阅读:
    跟踪spring MVC的请求
    spring的Java注解方式
    spring IOC理解
    spring aop
    spring mvc开发过程中的乱码问题
    springmvc的Controller里实现转发的同时弹出提示对话框
    C++程序加速的12个方法
    VSCode官方配置C/C++
    VSCode配置C/C++环境
    Numba 0.44 中文文档
  • 原文地址:https://www.cnblogs.com/catyuang/p/12130245.html
Copyright © 2011-2022 走看看