LOADING

Follow me

运维之我的docker-Dockerfile构建镜像详情【zoues.com】
一月 20, 2017|DockerPaaS

运维之我的docker-Dockerfile构建镜像详情【zoues.com】

运维之我的docker-Dockerfile构建镜像详情【zoues.com】

介绍

docker 构建镜像就像 java 的编译代码工作一样“ docker build -t centos7-nginx . , 这句话意思是自动寻找当前目录下的 Dockerfile 文件进行构建( build )镜像,镜像名“ centos7-nginx ”,至于执行 Dockerfile 内的指令则是自上而下逐步进行的 .

运维之我的docker-Dockerfile构建镜像详情

当然 Dockerfile 写起来很简单,但是希望大家遵循几个 docker 初创理念,同样是官方推荐用法:

  • 1. 你的 docker 尽量保持轻盈的,保证我们随时可以停止,删除,重新构建新的实现最小化的设置和配置。

  • 这样就要求你在构建镜像时尽量创建一个空目录,在里面放入有效文件进行构建,如果实在无法避免就写一个 .dockerignore 文件把不必要的文件忽略

  • 2. 避免安装不必要的包,否则会增加你的镜像大小 运维之我的docker-Dockerfile构建镜像详情

  • 3. 每个容器尽量只运行一个进程,多个应用运行多个容器,这样更容易让你横向批量拓展。而不是把多个应用集成到一个容器内,当然如果你只是为了方便拷贝环境确实可以这么做,或者使用更聪明的 link 方法。

  • 4. 层数的最小化,可以说 docekr 里面每个指令都是一层。为了可读行,快速性方便你以后长期维护

  • 5. 当你一行的操作太长的时候尽量使用“ / ”去把各个操作分成更短的行方便你修改和查看

  • 6. 因为 Dockerfile 是由上向下执行,每个指令都会生成一个层默认会缓存构建结果。如果你最后一指令构建错了或做了修改,重新构建时只会执行最后一个指令。如果想去掉这个缓存请使用 –no-cache=true

docker在构建新的镜像时需要写一个Dockerfile文件里面描述了新的镜像是基于哪个镜像,中间需要哪些操作等等,下面做把镜像做比喻

docker 创建镜像的创建想做饭一样:

1. 首先我们准备一个干净厨房:目录 `myimage` ,然后把需要的食材 ( 文件 ) 放到这

2. 在目录里面写一个饭菜需要的:食谱“ Dockerfile ”,当然食谱是需要注明食材加入的先后顺序的

FROM registry.cn-hangzhou.aliyuncs.com/forker/centos7            #这里声明镜像是基于哪个镜像创建的 MAINTAINER baishaohua                                                     #指定维护的人 RUN yum -y install sshd                                                                         #给你的镜像执行特定操作相当于/bin/sh -c CMD  /usr/sbin/sshd -D                                       #一个dockerfile只能有一个CMD如果有多个只执行最后一个 LABEL  version="1.0"                                                          #标签信息 EXPOSE                                                                                           #容器监听指定端口 上面是几个常用的,下面有几个:ENV,ADD, COPY, ENTRYPOINT, VOLUME, USER, WORKDIR

3. 构建容器:材料准备好以后,下面就开始做饭了

[root@salt-node1 bai]# cat Dockerfile FROM centos7 RUN yum -y install openssh-server openssh-clients CMD /usr/sbin/sshd -D   [root@salt-node1 bai]# docker build -t centos7sshv1 . Sending build context to Docker daemon 2.048 kB            #docker确认build需要的信息 Step 1 : FROM centos7                                                             #引用指定的镜像到本地,这里ID是中间基础容器  ---> 00f6c5817350 Step 2 : RUN yum -y install openssh-server openssh-clients               #基于上面的容器运行RUN里面的命令生成新的基础容器  ---> Using cache  ---> c173480a6c42 Step 3 : CMD /usr/sbin/sshd -D                                                                  #基于上面的容器运行RUN里面的命令生成新的基础容器并构建成镜像,删除临时容器  ---> Running in e8072b88b11b  ---> ee81230261f1 Removing intermediate container e8072b88b11b Successfully built ee81230261f1   4.运行新的容器 [root@salt-node1 bai]# docker run -d --name "testssh" -p  8022:22 centos7sshv2 cc225eff2520c47d54b264d5a338bb127933812d53e98f1c2b799bc8bb688f21

#########################| 华丽分割线 |###################################

下面详细介绍各个Dockerfile的参数,这里执行要大些

  • FROM

FROM [base_image]

你的镜像基于哪个基础镜像进行构建的

  • MAINTAINER

MAINTAINER operation@example.com

这个是显示镜像维护人

  • RUN

运行命令,有两种方式如下 , 它的运行原理是 /bin/sh -c

注意: 1. 这里传递是通过 json 所以只能用双引号, 2. 他不会运行脚本所以执行的时候不能获取系统变量

RUN ps

RUN ["executable", "param1", "param2"]

  • LABEL

你可以通过标签让更多的人知道你的镜像信息例如:授权许可,帮助你的自动化,或者其它。

你可以添加一个开始标签,一个值或多个值。如果你的字符串包含空格请用双引号进行包裹。

举例:

# Set one or more individual labels

LABEL com.example.version="0.0.1-beta"

LABEL vendor="ACME Incorporated"

LABEL com.example.release-date="2015-02-12"

LABEL com.example.version.is-production=""

# Set multiple labels on one line

LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"

# Set multiple labels at once, using line-continuation characters to break long lines

LABEL vendor=ACME/ Incorporated /

com.example.is-beta= /

com.example.is-production="" /

com.example.version="0.0.1-beta" /

com.example.release-date="2015-02-12"

  • EXPOSE

用来指定容器监听哪些端口,但是容器并不会暴露这些端口给服务器,除非你启动容器时使用 -P 参数。

  • ENV

它将把容器内部的很多变量替换掉,用你指定的 key

ENV key=value

  • ADD

把指定文件标准输入到镜像内,如果是压缩文件将会被自动解压,当然这里是 支持通配符

< dest > 是一个绝对路径或相对路径 WORKDIR, 源将被复制在目的地的容器。

ADD hom* /mydir/        # adds all files starting with "hom"

ADD hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

ADD test relativeDir/          # adds "test" to `WORKDIR`/relativeDir/

ADD test /absoluteDir/         # adds "test" to /absoluteDir/

ADD http://example.com/foobar /

  • COPY

用法基本和 ADD 一致

  • ENTRYPOINT

有两种运行方式,他的主要作用:一些你常用的参数可以加到这里,当你执行的时候自动添加

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)

ENTRYPOINT command param1 param2 (shell form)

运维之我的docker-Dockerfile构建镜像详情

  • VOLUME

创建一个数据卷,这个是映射到系统的“ /var/lib/docker/volumes /< 容器 ID>/ _data/

如果你重新构建镜像这个数据卷信息将被清除,注意:因为这里是为了构建一个标准 json 所以只能用双引号,

单引号是会报错的

VOLUME /opt/code/

VOLUME ["/data" , "/opt" ]

USER

RUN ENTRYPOINT 将使用哪个用户运行

USER daemon

  • WORKDIR

设置 Dockerfile 里面 RUN, CMD, ENTRYPOINT, COPY ADD 工作目录,如果 WORKDIR 不存在,它将被创建,即使它没有在任何后续的 Dockerfile 指令中使用。

  • ARG

docker build 时候的参数,如果命令中带有将不会被使用

ARG <name>[=<default value>]

1 FROM busybox

2 USER ${user:-some_user}

3 ARG user

4 USER $user

构建 docker 时就可以传入参数

$ docker build –build-arg user=what_user Dockerfile

使用此 Dockerfile 示例, CONT_IMG_VER 仍然保留在映像中,但其值为 v1.0.0 ,因为它是 ENV 指令在第 3 行中的默认设置。

此示例中的变量扩展技术允许您从命令行传递参数,并通过利用 ENV 指令将它们持久保存在最终映像中。 仅对一组有限的 Dockerfile 指令支持变量扩展。

Docker 有一组预定义的 ARG 变量,您可以在 Dockerfile 中使用相应的 ARG 指令。 通过这个参数调用下面的变量

–build-arg <varname>=<value>

HTTP_PROXY

http_proxy

HTTPS_PROXY

https_proxy

FTP_PROXY

ftp_proxy

NO_PROXY

no_proxy

  • ONBUILD

ONBUILD 指令在 镜像 被用作另一个 镜像 的构建基础时,会触发执行的指令。 触发器将在下游构建的上下文中执行,就好像它已经在下游 Dockerfile 中的 FROM 指令之后立即插入 指令

任何构建指令都可以注册为触发器。

如果您正在构建将用作构建其他映像的基础的图像,例如应用程序构建环境或可以使用用户特定配置自定义的后台驻留程序,这将非常有用。

详解:

  1. build 镜像时遇到 ONBUILD 时候它将插入一个触发器到镜像的 metadata ,他不会影响当前的构建

  2. 在构建结束时,所有触发器的列表存储在镜像的 OnBuild 清单中的 key 下。 可以使用 docker inspect 命令检查它们。

  3. build 执行的时候第一个执行的是 FROM 引用一个基础镜像引用后这一步并不会结束他会检查并执行触发器,如果触发器全部执行完成 FROM 才能算成功,否则只要一个触发器失败 FROM 就算失败

  4. 触发器在执行完成后会被清楚,也就是在新建的镜像中是不会集成这个触发器的

  5. 使用 ONBUILD ONBUILD 是不允许的,也就是不能自己触发自己,同样也不可以触发 FROM MAINTAINER

[…]

ONBUILD ADD . /app/src

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

[…]

  • STOPSIGNAL

给系统发送退出信号(终止信号),该信号可以是与内核系统调用 9 ”相似, 或者是格式为 SIGNAME 的信号名称,例如 SIGKILL

STOPSIGNAL signal

  • HEALTHCHECK

HEALTHCHECK 指令是在 Docker 1.12 版本加入,此指令有两种格式:

HEALTHCHECK [OPTIONS] CMD command                    # 在容器内运行一个命令检测容器健康

HEALTHCHECK NONE                                                          # 禁止从基础镜像集成任何健康检测

描述

HEALTHCHECK 指令告诉 docker 如何去检测容器仍然在工作,例如你的 web 容器因为一个无限循环卡住无法创建新的连接它可以告诉容器不再健康,即使现在进程依然在运行。

容器的初始状态是‘ starting , 如果健康检测容器正常他的状态会是 healthy 状态码为“ 0 , 如果健康检测出现连续失败会出现 unhealthy 状态码为“ 1 ”,如果因为非健康执行退出则为“ reserved ”状态码为“ 2 ”。

参数介绍:

可以出现在 CMD 的参数:

–interval=DURATION          # 默认间隔 30s

–timeout=DURATION          # 默认超时时间 30s

–retries=N          # 默认重试 3

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

上面三个参数连贯起来就是,健康检测默认间隔 5 分钟运行一次,如果超过 3 秒则认为超时,如果尝试三次一直失败则认为容器不再健康执行 "exit 1 "

假如说在 Dockerfile 里面多次出现这个参数,将会采用最后一个 HEALTHCHECK 指令,这个是和 CMD 指令一样的。

如果你想获取容器现在的状态可以使用“ docker inspect [ CONTAINER ID ] ”获取当前容器的 health_status

本文出自 “nginxs小白” 博客,转载请与作者联系!

no comments
Share

发表评论