1. Dockerfile来源
由于Docker官网公共仓库镜像大多不完整,满足不了企业的生产环境系统,因此所以需要自己制作镜像或者说来重新打包镜像。
Docker镜像的两种制作办法:
- Docker commit|export将新容器提交至Images列表;
- 编写Dockerfile,bulid新的镜像至镜像列
2 Dockerfile
Dockerfile制作原理,将一个基础一个基础的镜像,通过dockerfile的方式,将各个功能叠加起来,形成一个新的镜像。
2.1 Dockerfile语法详解
FROM 指定所创建镜像的基础镜像;不推荐
MAINTAINER 指定维护者信息;
RUN 运行执行的指令
CMD 指定启动容器时默认执行的命令;
LABEL 指定生成镜像的元数据标签信息; 使用这个指定作者名
EXPOSE 声明镜像内服务所监听的端口;
ENV 指定环境变量;
ADD 该命令执行的是相对路径./ 因此一般在执行命令的时候需要将添加的的文件复制到dockerfile形同的路径下
COPY 同上
ADD和COPY的区别就是ADD会将tar文件夹添加到目标目录下会自动解压
ENTRYPOINT 指定镜像的默认入口;
VOLUME 挂载目录
USER 指定运行容器时的用户名或UID;
WORKDIR 工作目录;
ARG 指定镜像内使用的参数(例如版本号信息等);
ONBUILD 配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令;
STOPSIGNAL 容器退出的信号;
HEALTHCHECK 如何进行健康检查;
SHELL 指定使用SHELL时的默认SHELL类型;
CMD和ENTRYPOINT 的区别
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。
ENTRYPOINT指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。 因此推荐用ENTRYPOINT
2.2 Dockerfile命令详解
FROM<image>或FROM<image>:<tag>。任何Dockerfile中的第一条指令必须为FROM指令。
MAINTAINER itzfl 该信息将会写入生成镜像的Author属性域中。
RUN 每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\换行。
RUN yum stall -y libsnappy-dev zliblg-dev libbz2-dev
CMD用来指定启动容器时默认执行的命令。它支持三种格式:
CMD ["executable","param1","param2"] 使用exec执行,是推荐使用的方式;
LABEL指令用来生成用于生成镜像的元数据的标签信息。目前更多的只用作者名用label
LABEL author="itzfl"]
EXPOSE声明镜像内服务所监听的端口。EXPOSE 22 80 443 3306
ENV指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。
格式为:ENV <key><value>或ENV<key>=<value>...。
ENV MYPATH=/usr/local
RUN mkdir $MYPATH
ADD该指令将复制指定的<src>路径下的内容到容器中的<dest>路径下。源文件为相对目录下的文件
COPY复制本地主机的<src>(为Dockerfile所在目录的一个相对路径、文件或目录)下的内容到镜像中的<dest>下。
ENTRYPOINT指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。
ENTRYPOINT ["executable","param1","param2"] (exec调用执行);
ENTRYPOINT command param1 param2(shell中执行)。
每个Dockerfile中只能有一个ENTRYPOINT,当指定多个时,只有最后一个有效。
VOLUME
创建一个数据卷挂载点。
格式为:VOLUME ["/data"]
可以从本地主机或者其他容器挂载数据卷,一般用来存放数据库和需要保存的数据等。
USER
指定运行容器时的用户名或UID,后续的RUN等指令也会使用特定的用户身份。格式为:USER daemon
当服务不需要管理员权限时,可以通过该指令指定运行用户,并且可以在之前创建所需要的用户。例如:
RUN groupadd -r nginx && useradd -r -g nginx nginx要临时获取管理员权限可以用gosu或者sudo。
WORKDIR为后续的RUN、CMD和ENTRYPOINT指令配置工作目录。
格式为:WORKDIR /path/to/workdir。
可以使用多个WORKDIR指令,后续命令如果参数是相对的,则会基于之前命令指定的路径。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为/a/b/c
ARG指定一些镜像内使用的参数(例如版本号信息等),这些参数在执行docker build命令时才以--build-arg<varname>=<value>格式传入。格式为:ARG<name>[=<default value>]。
则可以用docker build --build-arg<name>=<value>来指定参数值。
ONBUILD
配置当所创建的镜像作为其他镜像的基础镜像的时候,所执行创建操作指令。
格式为:ONBUILD [INSTRUCTION]。
例如Dockerfile使用如下的内容创建了镜像image-A:
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
如果基于image-A镜像创建新的镜像时,新的Dockerfile中使用FROM image-A指定基础镜像,会自动执行ONBUILD指令的内容,等价于在后面添加了两条指令:
FROM image-A
# Automatically run the following
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
使用ONBUILD指令的镜像,推荐在标签中注明,例如:ruby:1.9-onbuild。
STOPSIGNAL
指定所创建镜像启动的容器接收退出的信号值。例如:
STOPSIGNAL singnal
HEALTHCHECK配置所启动容器如何进行健康检查(如何判断是否健康),自Docker 1.12开始支持。格式有两种:
HEALTHCHECK [OPTIONS] CMD command :根据所执行命令返回值是否为0判断;HEALTHCHECK NONE:禁止基础镜像中的健康检查。
[OPTION]支持:
--inerval=DURATION (默认为:30s):多久检查一次;
--timeout=DURATION (默认为:30s):每次检查等待结果的超时时间;
--retries=N (默认为:3):如果失败了,重试几次才最终确定失败。
2.3 制作技巧
- 精简镜像用途
- 选用合适的基础镜像
- 减少镜像层数:因为镜像制作是从上而下制作而成的,是一层一层的,层数越多,越臃肿,因此可以减少层数。在使用run时,尽量卸载一个run下面通过&& 和\ 连接。
- 删除临时和缓存文件
3.企业实战
3.1 Dockerfile1 构建一个Centos7镜像
FROM ansible/centos7-ansible
LABEL author="itzfl"
RUN rm -rf /etc/yum.repo.d/*
ADD offline.repo /etc/yum.repo.d/
RUN yum makecache && \
yum install yum install wget passwd openssh-server gcc net-tools rsyslog -y && \
echo 'root' |passwd --stdin root && \
ssh-keygen -A
EXPOSE 22 80
CMD /usr/sbin/sshd -D
查看镜像
[root@itzfl docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos7 v1 cf3077ad95c7 3 minutes ago 1.16GB
创建一个基于centos7:v1的容器并实现远程登录该容器
3.2 Dockerfile2构建一个nginx镜像
在dockerfile的相同路径下 创建一个index.html
配置Dockerfile
FROM centos7:v1
LABEL author="zfl"
RUN yum install nginx -y
COPY index.html /usr/share/nginx/html/
EXPOSE 80
CMD ["/usr/sbin/nginx","-g","daemon off;"]
构建镜像
创建容器
访问