docker的系统学习能够看我这篇博文:http://www.javashuo.com/article/p-gzgvjepy-bn.html 有很是详细的讲解
容器如今都是用kubernetes来编排了, 存储、网络、都归Kubernetes层面管理了,因此对于docker的主要掌握点也就剩dockerfile了,这也是docker的重点。html
Dockerfile是一个文本文件,里面包含一条条指令,每一条指令就是一层镜像。
Dockerfile 通常分为四部分:基础镜像信息、维护者信息、镜像操做指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。
Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本镜像,第一条指令必须是FROM。一个声明以#
字符开头则被视为注释。
Dockerfile中所用的全部文件必定要和Dockerfile文件在同一级父目录下,能够为Dockerfile父目录的子目录。
Dockerfile中相对路径默认都是Dockerfile所在的目录。
Dockerfile中必定要惜字如金,能写到一行的指令,必定要写到一行,缘由是分层构建,联合挂载这个特性。Dockerfile中每一条指令被视为一层。
Dockerfile中指明大写(约定俗成)linux
FROMgit
指定基础镜像,而且必须是第一条非注释指令。docker
若是不以任何镜像为基础,那么写法为:FROM scratch。shell
同时意味着接下来所写的指令将做为镜像的第一层开始ubuntu
语法:windows
FROM <image> FROM <image>:<tag> FROM <image>:<digest> 三种写法,其中<tag>和<digest> 是可选项,若是没有选择,那么默认值为latest 在一个 Dockerfile 文件中建立多个镜像时,FROM 能够屡次出现。只需在每一个新命令 FROM 以前,记录提交上次的镜像 ID。
LABEL缓存
功能是为镜像指定标签服务器
语法:网络
LABEL <key>=<value> <key>=<value> <key>=<value> ... 一个Dockerfile种能够有多个LABEL,不建议这么写,最好是写成一行,如太长须要换行的话则使用\符号 LABEL会继承基础镜像中的LABEL,如遇到key相同,则值覆盖
ENV
设置环境变量
语法:
ENV <key> <value> ENV <key>=<value> ... 二者的区别就是第一种是一次设置一个,第二种是一次设置多个
ADD
一个复制命令,把文件复制到镜像中
若是把虚拟机与容器想象成两台linux服务器的话,那么这个命令就相似于scp,只是scp须要加用户名和密码的权限验证,而ADD不用
语法:
ADD <src>... <dest> ADD ["<src>",... "<dest>"] 路径的填写能够是容器内的绝对路径,也能够是相对于工做目录的相对路径,推荐写成绝对路径 能够是一个本地文件或者是一个本地压缩文件,还能够是一个url 若是把写成一个url,那么ADD就相似于wget命令 src为一个目录的时候,会自动把目录下的文件复制过去,目录自己不会复制 若是src为多个文件,dest必定要是一个目录 若是 docker 发现文件内容被改变,则接下来的指令都不会再使用缓存。关于复制文件时须要处理的/,基本跟正常的 copy 一致
COPY
看这个名字就知道,又是一个复制命令
语法:
COPY <src>... <dest> COPY ["<src>",... "<dest>"] 与ADD的区别: COPY的只能是本地文件,其余用法一致
RUN
功能为运行指定的命令
语法:
RUN <command> RUN ["executable", "param1", "param2"] 第一种后边直接跟shell命令 在linux操做系统上默认 /bin -c 在windows操做系统上默认 cmd /S /C 第二种是相似于函数调用。 可将executable理解成为可执行文件,后面就是两个参数。 RUN 指令建立的中间镜像会被缓存,并会在下次构建中使用。若是不想使用这些缓存镜像,能够在构建时指定 --no-cache 参数,如:docker build --no-cache。
CMD
功能为容器启动时要运行的命令
语法:
CMD ["executable","param1","param2"] CMD ["param1","param2"] CMD command param1 param2 第三种比较好理解了,就时shell这种执行方式和写法 第一种和第二种其实都是可执行文件加上参数的形式 举例说明两种写法: CMD [ "sh", "-c", "echo $HOME" CMD [ "echo", "$HOME" ] 这里边包括参数的必定要用双引号,就是",不能是单引号。千万不能写成单引号。 缘由是参数传递后,docker解析的是一个JSON array
RUN&&CMD
RUN是构件容器时就运行的命令以及提交运行结果 CMD是容器启动时执行的命令,在构件时并不运行,构件时仅仅指定了这个命令究竟是作什么的
WORKDIR
设置工做目录,对RUN,CMD,ENTRYPOINT,COPY,ADD生效。若是不存在则会建立,也能够设置屡次。
语法:
WORKDIR /path/to/workdir WORKDIR也能够解析环境变量 ENV DIRPATH /path WORKDIR $DIRPATH/$DIRNAME RUN pwd pwd的执行结果是/path/$DIRNAME
VOLUME
实现挂载功能,能够将宿主机目录挂载到容器中
可用专用的文件存储看成Docker容器的数据存储部分
语法:
VOLUME ["/data"] 使用场景为须要持久化存储数据时. 容器使用的是AUFS,这种文件系统不能持久化数据,当容器关闭后,全部的更改都会丢失。 因此当数据须要持久化时用这个命令。 VOLUME ["/var/log/"] VOLUME /var/log VOLUME /var/log /var/db 卷能够容器间共享和重用 容器并不必定要和其它容器共享卷 修改卷后会当即生效 对卷的修改不会对镜像产生影响 卷会一直存在,直到没有任何容器在使用它 VOLUME 让咱们能够将源代码、数据或其它内容添加到镜像中,而又不并提交到镜像中,并使咱们能够多个容器间共享这些内容。
USER
设置启动容器的用户,能够是用户名或UID
语法:
USER daemo USER UID 若是设置了容器以daemon用户去运行,那么RUN, CMD 和 ENTRYPOINT 都会以这个用户去运行, 使用这个命令必定要确认容器中拥有这个用户,而且拥有足够权限。
ENTRYPOINT
启动时的默认命令
语法:
ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2 第一种就是可执行文件加参数 第二种就是写shell
ENTRYPOINT&&CMD
相同点: 只能写一条,若是写了多条,那么只有最后一条生效 容器启动时才运行,运行时机相同 不一样点: ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖 若是咱们在Dockerfile种同时写了ENTRYPOINT和CMD,而且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会做为ENTRYPOINT的参数。 FROM ubuntu ENTRYPOINT ["netstat", "-ln"] CMD ["-tup"] 若是在Dockerfile种同时写了ENTRYPOINT和CMD,而且CMD是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效 FROM ubuntu ENTRYPOINT ["netstat", "-ln"] CMD ls -l 那么将执行ls -l ,netstat -ln不会执行。
ARG
设置变量命令,ARG命令定义了一个变量,在docker build建立镜像的时候,使用 --build-arg =来指定参数
语法:
ARG <name>[=<default value>] 若是用户在build镜像时指定了一个参数没有定义在Dockerfile中,那么将有一个Warning [Warning] One or more build-args [foo] were not consumed. 能够定义一个或多个参数 FROM busybox ARG user1 ARG buildno 能够给参数一个默认值 FROM busybox ARG user1=someuser ARG buildno=1 若是给了ARG定义的参数默认值,那么当build镜像时没有指定参数值,将会使用这个默认值
HEALTHCHECK
容器健康情况检查命令
语法:
HEALTHCHECK [OPTIONS] CMD command HEALTHCHECK NONE 第一个的功能是在容器内部运行一个命令来检查容器的健康情况 第二个的功能是在基础镜像中取消健康检查命令 [OPTIONS]的选项支持如下三中选项: –interval=DURATION 两次检查默认的时间间隔为30秒 –timeout=DURATION 健康检查命令运行超时时长,默认30秒 –retries=N 当连续失败指定次数后,则容器被认为是不健康的,状态为unhealthy,默认次数是3 注意: HEALTHCHECK命令只能出现一次,若是出现了屡次,只有最后一个生效。 CMD后边的命令的返回值决定了本次健康检查是否成功,具体的返回值以下: 0: success - 表示容器是健康的 1: unhealthy - 表示容器已经不能工做了 2: reserved - 保留值 例: HEALTHCHECK --interval=5m --timeout=3s \ CMD curl -f http://localhost/8080 || exit 1 健康检查命令是:curl -f http://localhost/8080 || exit 1 两次检查的间隔时间是5秒 命令超时时间为3秒
ONBUILD
用于在dockerfile中定义一个触发器,只对当前镜像的子镜像生效
语法:
ONBUILD [INSTRUCTION] dockerfile用于build镜像文件,此镜像文件亦可做为base image被另外一个dockerfile用做FROM指令参数,并以之构建新的镜像,在后面的dockerfile中的FROM指令在build过程当中被执行时,将会触发建立其baseimage的dockerfile文件中的ONBUILD指令定义的触发器。 好比当前镜像为A,在Dockerfile种添加: ONBUILD RUN ls -l 这个 ls -l 命令不会在A镜像构建或启动的时候执行 此时有一个镜像B是基于A镜像构建的,那么这个ls -l 命令会在B镜像构建的时候被执行。
EXPOSE
功能为暴漏容器运行时的监听端口给外部
语法:
EXPOSE <port>/<tcp/udp> 可是EXPOSE并不会使容器访问主机的端口 EXPOSE 指令并不会让容器监听 host 的端口,若是须要,须要在 docker run 时使用 `-p`、`-P` 参数来发布容器端口到 host 的某个端口上。
STOPSIGNAL
STOPSIGNAL命令是的做用是当容器中止时给系统发送什么样的指令,默认是15
语法:
STOPSIGNAL signal
Dockerfile中使用变量的方式
$varname ${varname} ${varname:-default value} ${varname:+default value} 第一种和第二种相同 第三种表示当变量不存在使用-号后面的值 第四种表示当变量存在时使用+号后面的值
容器轻量化。从镜像中产生的容器应该尽可能轻量化,能在足够短的时间内中止、销毁、从新生成并替换原来的容器。
使用 .gitignore。在大部分状况下,Dockerfile 会和构建所需的文件放在同一个目录中,为了提升构建的性能,应该使用 .gitignore 来过滤掉不须要的文件和目录。
为了减小镜像的大小,减小依赖,仅安装须要的软件包。
一个容器只作一件事。解耦复杂的应用,分红多个容器,而不是全部东西都放在一个容器内运行。如一个 Python Web 应用,可能须要 Server、DB、Cache、MQ、Log 等几个容器。一个更加极端的说法:One process per container。
减小镜像的图层。不要多个 Label、ENV 等标签。
对续行的参数按照字母表排序,特别是使用apt-get install -y安装包的时候。
使用构建缓存。若是不想使用缓存,能够在构建的时候使用参数--no-cache=true来强制从新生成中间镜像。
个人一篇docker实战博文