docker镜像创建方式
这篇文章主要介绍dockerfile方式创建镜像,其余方式看链接文章
docker-save保存镜像
docker-export导出容器镜像
docker-container-commit创建镜像
Dockerfile创建镜像
Dockerfile使用
Dockerfile的使用很简单,如下:
root@DESKTOP-UCCCCAE:~/docker# docker build -t test/curl:v1 .
# docker build -t test/curl:v1 -f ./Dockerfile .
觉得长的只用看-t,-f
-c, --cpu-shares int CPU shares (相对权重,默认1024,只有一个容器时不需要设置
容器cpu占用时间比=value1/(value1+..+valueN))
--disable-content-trust 跳过镜像验证 (default true)
--force-rm 总是移除临时容器
--iidfile string 把镜像ID写入文件
--isolation string 容器隔离技术
--label list 设置镜像元数据
-m, --memory bytes Memory limit
-q, --quiet 压制build输出和
--rm 成功build后移除临时容器 (default true)
-f, --file string Dockerfile路径 (Default is 'PATH/Dockerfile',即./dockerfile)
-t, --tag list 设置镜像名 ,'name:tag'格式
命令的最后有一个.,点为上下文路径
Dockerfile结构
Dockerfile的结构其实很简单清晰,主要分为三部分:镜像信息、镜像操作指令和容器启动时执行指令
FROM ubuntu:16.04 #基础镜像
#LABEL 镜像元数据信息
LABEL version="1.0" maintainer="hjm<depthfirst@github>"
#MAINTAINER指令在新版本中已经废弃,可以在LABEL中声明maintainer=xxx
#RUN 镜像构建执行的命令
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/libs/apt/lists/*
ENTRYPOINT ["curl","-s","http://ip.cn"]
#下面是举例
#WORKDIR 工作目录
WORKDIR /usr/xxx
#EXPOSE 映射端口
EXPOSE xxxx
#CMD 容器启动后运行的命令
CMD ["xxx"]
可能有人不了解&& 和\是什么含义:
Dockerfile的指令每执行一次都会在 docker 上新建一层,生成太多无意义层,使用&& 符号连接命令,执行后只会创建 1 层镜像。
\为换行符,避免一行命令过长无意义。
另外执行时可能会因为镜像失败,可在Dockerfile中添加指令更换ubuntu阿里镜像源
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list
可与上文RUN指令进行合并
指令介绍
举例中有的就不介绍了,下面到文章结尾参考自其他文章
指令 | 简介 |
---|---|
ENTRYPOINT | 指定镜像的默认入口 |
ENV | 指定环境变量 |
ADD | 赋值指定路径下的内容到容器中路径 |
COPY | 基本同ADD,一般推荐COPY |
VOLUME | 创建数据挂载点 |
USER | 指定运行容器时的用户(通过用户名或UID指定) |
ARG | 指定镜像内使用参数 |
ONBUILD | 配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的构建命令 |
STOPSIGNAL | 容器退出信号 |
HEALTHCHECK | 健康检查 |
SHELL | 指定默认SHELL类型 |
LABEL
LABEL指令用于添加一个元数据到镜像,键和值配对存在。例如可以给容器添加辅助说明信息。值中支持换行字符斜杠(\)。如果Docker中出现重复的键,则新的值会覆盖原来的值。为了减少Docker的层数,可以在单一LABEL指令中指定多个标签:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
EXPOSE
EXPOSE指定容器在运行中监听的端口。默认情况下,EXPOSE指定的是TCP端口,若要指定监听udp端口:
EXPOSE 80/udp
COPY
COPY能够从构建上下文中复制文件到新的一层中镜像中,COPY指令有两种形式:
COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
chown属性只支持Linux容器构建。COPY命令支持通配符,可以把多个源文件复制到目标文件下
ADD
ADD 指令和 COPY 的使用格式一致(同样需求下推荐使用 COPY)。功能类似,不同如下:
ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。
VOLUME
VOLUME旨在创建一个具有名称的挂载点。容器在运行时尽量保持存储层不发生数据写入操作。一个卷可以存在于一个或多个容器的特定目录,这个目录可以绕过联合文件系统,并提供数据共享或数据持久化功能。卷可以在容器间共享或重用,对卷的修改是及时生效的。对卷的修改不会对新的镜像产生影响,卷会一直存在直到没有容器使用它。可以使用数组的形式指定多个卷。使用方式如下:
VOLUME /data
VOLUME ["/data"]
VOLUME ["data","test","chatdevops"]
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点
USER
USER指令为Dockerfile中全部RUN,CMD,ENTRYPOINT设置运行Image时使用的用户名或UID。这个用户或组必须事先在系统中存在。若不存在则下一层镜像以root用户进行执行。
USER <user>[:<group>]
USER <UID>[:<GID>]
WORKDIR
WORKDIR用来为Dockerfile下文中的RUN, CMD, ENTRYPOINT, COPY和ADD等指令指定当前工作目录。如果存在多个WORKDIR则以指令钱最近的一条为参考。如果该目录不存在,则系统会自动创建该目录。如果要改变当前的工作目录,不能使用cd命令来切换,需要使用WORKDIR来进行切换。
ONBUILD
这是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY等;在构建本镜像时不生效,在基于此镜像构建镜像时生效。
STOPSIGNAL
STOPSIGNAL指令设置唤醒信号并将其发送到容器后退出。后跟信号值(无符号整数)或者SIGNAME格式的信号名称,例如SIGKILL。
STOPSIGNAL signal
HEALTHCHECK
Docker提供了HEALTHCHECK指令,通过该指令指定一行命令,用这行命令来判断容器主进程的服务状态是否还正常,从而比较真实的反应容器实际状态。当在一个镜像指定了HEALTHCHECK指令后,用其启动容器,初始状态会为 starting ,在HEALTHCHECK指令检查成功后变为healthy,如果连续一定次数失败,则会变为 unhealthy。格式如下:
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)
HEALTHCHECK 支持下列选项: - –interval=<间隔> :两次健康检查的间隔,默认为 30 秒; - –timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒; - –retries=<次数> :当连续失败指定次数后,则将容器状态视为 unhealthy ,默认3次。
HEALTHCHECK在Dockerfile中只能出现一次,如果出现多次则最后一个生效。
SHELL
SHEELL指令允许默认的shell形式被命令形式覆盖。在Linux系统中默认shell形式为 [“/bin/sh”, “-c”], 在 Windows上是[“cmd”, “/S”, “/C”]。SHELL指令必须用Dockerfile中的JSON格式写入。SHELL指令在Windows上特别有用,其中有两个常用的和完全不同的本机shell:cmd和powershell,以及包括sh的备用shell。 SHELL指令可以出现多次。每个SHELL指令都会覆盖所有以前的SHELL指令,并影响所有后续指令。
ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
ENTRYPOINT ["nginx", "-c", "-param2"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
CMD ["executable","param1","param2"] #使用 exec 执行