dockerfile原理与实现

2,198 阅读3分钟

一、什么是dockerfile

Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

二、dockerfile的设计思想

dockerfile 的设计思想,是使用一些标准的原语(即大写高亮的词语),描述我们所要构建的 Docker 镜像。并且这些原语,都是按顺序处理的。

三、rootfs文件系统分层

只读层

它们的挂载方式都是只读的,是操作系统的一部分

可读写层

在没有写入文件之前,这个目录是空的。而一旦在容器里做了写操作,你修改产生的内容就会以增量的方式出现在这个层中。 使用了一种叫的 whiteout 文件,用来存放修改 rootfs 后产生的增量。

Init 层

  • 夹在只读层和读写层之间。Init 层是 Docker 项目单独生成的一个内部层,专门用来存放 /etc/hosts、/etc/resolv.conf 等信息。
  • 需要这样一层的原因是,这些文件本来属于只读的 Ubuntu 镜像的一部分,但是用户往往需要在启动容器时写入一些指定的值比如 hostname,所以就需要在可读写层对它们进行修改。

这里我们介绍的dockerfile,可以理解为制造rootfs一种更便捷的方式。

四、dockerfile语法

基本结构

dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令

FROM

  • 指定基础镜像,必须为第一个命令。
  • 如,指定了“python:2.7-slim”这个官方维护的基础镜像,从而免去了安装 Python 等语言环境的操作。
FROM python:2.7-slim

MAINTAINER

  • 记录了维护者信息
MAINTAINER KD   

RUN

  • 用于执行后面跟着的命令行命令。
FROM centos
RUN yum install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos
RUN yum install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

ADD

  • 将本地文件添加到容器中。
ADD test /testDir     # 添加 "test" 到 /testDir

CMD

  • 构建容器后调用,也就是在容器启动时才进行调用。
  • CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
CMD ["executable","param1","param2"] (执行可执行文件或shell命令)

ENV

  • 设置环境变量
ENV myName KD

EXPOSE

  • 映射端口
  • EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
EXPOSE 80

WORKDIR

  • 切换工作目录,类似于cd命令
WORKDIR /test

五、demo

# 使用官方提供的Python开发镜像作为基础镜像
FROM python:2.7-slim
# 将工作目录切换为/appWORKDIR /app
# 将当前目录下的所有内容复制到/app下
ADD . /app
# 使用pip命令安装这个应用所需要的依赖
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# 允许外界访问容器的80端口
EXPOSE 80
# 设置环境变量
ENV NAME World
# 设置容器进程为:python app.py,即:这个Python应用的启动命令
CMD ["python", "app.py"]