学习Docker(2017-10-3)

来源:互联网 发布:娃娃幼儿园软件 编辑:程序博客网 时间:2024/06/05 03:51

本节目录:
1. ENV 设置环境变量
2. ARG 构建参数
3. VOLUME 定义匿名类
4. EXPOSE 声明端口
5. USER 指定当前用户
6. HEALTHCHECK 检查健康
7. ONBULID 为他人做嫁衣

接着上一节学习 Dockerfile 的指令

ENV 设置环境变量

标题中已经告诉我们 ENV 是设置环境变量的,环境变量大家都不陌生,就是定义一个环境变量,可以在程序中重复使用,一般用在需要大量使用该参数的地方。这个好处就是,方便代码的维护。

格式:
1. ENV key value
2. ENV key1=value1 key2=value2

这个指令很容易理解,直接上图吧

ARG 构建参数

跟 ENV 效果一样,都是设置环境变量,但 ARG 的区别在于,它是设置 构建环境 的环境变量。意思就是当时用构建命令时使用的。

格式:
ARG <参数名>[=<默认值>]

在 Dockerfile 中 的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令中覆盖

docker --build-arg<参数名>=<>

需要注意的是,在1.13版本之前 要求使用 –build-arg 中的参数名,必须在 Dockerfile 中用 ARG 定义。在1.13开始,这种严格的限制解除了,不会报错退出,而只是显示警告信息。

实例:

FROM xxxARG user=xxx...

在上面的 Dockerfile 中 ARG 指定了我们 user ,当我们构建这个镜像的时候,如果想更换用户,就可以

docker --build-arg user=2xxx 构建后的名称

VOLUME 定义匿名类

容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中。为了防止运行时用户忘记将动态文件保存目录挂载为卷。在 Dockerfile 中,我们事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会像容器存储层写入大量数据。
关于挂载

格式:
VOLUME [“<路径1>”,”<路径2>”…]

VOLUME /data

该命令表示,在运行时自动挂载为匿名类,任何想 /data 中写入的信息都不会记录进容器存储层,从而保证容器存储层的无状态化。运行时也可以覆盖掉这个匿名挂载设置

docker run -d -v mydata:/data xxxx<!--mydata这个命名卷挂载了 /data 这个位置-->

EXPOSE 声明端口

格式:
EXPOSE 端口1[端口2…]

EXPOSE 只是声明运行时容器提供服务端口号,这个只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile中写入声明的好处:
1. 帮助镜像使用者理解这个镜像服务的守护进程,以方便映射
2. 在运行使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

以前的 Docker 所以容器是互通的,这存在于安全性问题。现在通过自定义网络可以实现容器间的互联与隔离。要将 EXPOSE 和 运行时使用 -p <宿主端口>:<容器端口>区分开来。

-p 是映射宿主端口和容器端口,就是容器对应的端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。

WORKDIR 指定工作目录

格式:
WORKDIR 工作目录路径

该指令指定工作目录,以后各层的当前目录就会被改为指定的目录,如果不存在,就自动创建

USER 指定当前用户

格式:USER 用户名
USER 指令与 WORKDIR 相似,都是改变环境状态并影响以后的层。一个改变目录,一个是改变之后执行命令的身份。

HEALTHCHECK 检查健康

格式: HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令

HEALTHCHECK NONE :如果基础镜像有检查健康检查指令,可以屏蔽其他健康检查指令。
之前没有什么 HEALTHCHECK 指令前,Docker 引擎只可以通过容器内主程序是否退出来判断容器是否状态异常。在程序进入死锁状态或者,死循环状态,应用进程并不退出,也就无法提供服务了。

当使用 HEALTHCHECK 指令后,用其启动容器,初始状态会变成 starting ,在 HEALTHCHECK 指令检查成功后变为 healthy ,如果连续一定次数失败,则会变为 unhealthy 。

选项:
–interval=<间隔>:两次健康检查的间隔,默认30秒
–timeout=<时长>:如果超过这个时间,表示失败
–retries=<次数>:当连续失败状态为 unhealthy 默认 3 次

假设我们的镜像是一个最简单的 Web 服务,我们希望增加健康检查来判断其Web服务是否在正常工作,我们可以用 curl 帮助判断

FROM nginxRUN apt-get update \&& apt-get install -y curl \&& rm -rf /var/lib/apt/lists/*HEALTHCHECK --interval=5s --timeout=3s \CMD curl -fs http://localhost/ || exit 1

构建 docker build -t myweb:v1 .
启动容器docker run -d --name web -p 81:80 myweb:v1
查询状态docker ps

ONBULID 为他人做嫁衣

格式: ONBULID 其他指令
这是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等, 而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

假设我们要制作 Node.js 所写的应用的镜像.Node 使用 npm进行包管理。
有依赖、配置、启动信息等会放 package.json 文件里。一般 npm install 获取依赖,然后 npm start 启动应用

FROM node:slimRUN mkdir /appWORKDIR /appCOPY ./package.json /appRUN [ "npm", "install" ]COPY . /app/CMD [ "npm", "start" ]

如果我们构建第二个相同项目,我们可能会复制,如果有很多文件,文件副本也很多,版本控制就越困难。如果第一个文件出现需要修改的问题,我们如何同步多个项目?
1. 写一个基础镜像,让各个需要构建的项目都指向基础镜像,重新构建,会继承基础镜像的更新。构建 基础 镜像,起名 my-node (docker build -t my-node .)

其他项目的 Dockerfile 指向基础镜像 my-node,就是上面那幅图

(问题解决了一半,如果我需要给npm install 加一些参数)

  1. ONBUILD 可以解决这个问题。 使用 ONBUILD 重写 Dockerfile 基础镜像my-node
FROM node:slimRUN mkdir /appWORKDIR /appONBUILD COPY ./package.json /appONBUILD RUN [ "npm", "install" ]ONBUILD COPY . /app/CMD [ "npm", "start" ]

加上 ONBUILD 的指令并不会执行,然后各个项目的 Dockerfile 都为

FROM my-node

只有一行的 Dockerfile 构建的时候,就执行 基础镜像里面的 ONBUILD 后面的,成功的将但钱项目的代码复制进镜像,当遇到修改时 我们知道修改一份 镜像,然后构建成基础镜像,供其他镜像使用。


最后是关于网上我觉得不错的博客,很崇拜比自己写的好的人,对于我这个快要毕业的人来说,还有许多要学,现在唯一能做的就是让自己不骄不躁,安心做好当下的事情,我相信即使毕业了,自己的技术还不够找一份好工作,我也会坚持学习!ヾ(◍°∇°◍)ノ゙
如何写Dockerfile,Dockerfile 参考文档
Docker 官方文档
Dockerfile 实践文档