docker 不归路 (二)

Dockerfile介绍

Dockerfile 是一个文本格式的配置文件,文本内容包含了一条条构建镜像所需的指令(包括配置指令如 FROM 和操作指令如 RUN )和说明(以 # 开头的注释),用户可以使用 Dockerfile 来快速创建自定义的镜像。

Dockerfile基本结构

Dockerfile由一行行命令语句组成,可以在命令行中调用任何命令。

一般来说,Dockerfile主体内容分为四个部分:

  1. 基础镜像信息 —— FROM centos 表示基于 centos 镜像来构建
  2. 维护者信息 —— MAINTAINER 指定维护者的一些信息
  3. 镜像操作指令 —— 如 RUN (构建时运行指定命令,可以有多条)、CMD(在启动容器时默认执行的命令,只能有一条)、ADD(添加内容到镜像)以及COPY(复制内容到镜像)
  4. 容器启动执行指令 —— CMD 指定运行容器时的操作命令

基于Dockerfile制作镜像

创建镜像的方法主要有三种:

  1. 基于已有镜像的容器创建 —— 主要使用 docker [container] commit 命令。主要方法是启动一个镜像,并在其中进行操作(如配置nginx环境),完成后退出,使用 commit 命令提交,顺利的话,会返回新创建镜像的 ID 信息,即创建完成
  2. 基于本地模板导入 —— 用户可以直接从一个操作系统模板文件导入一个镜像,主要使用 docker [container] import 命令。可使用 openVZ 提供的模板或其他导出的镜像模板来创建,如 cat ubuntu-18.04-x86_64-minimal.tar.gz | docker import - ubuntu:18.04
  3. 基于Dockerfile创建 —— 最常用的方法,Dockerfile是一个文本文件,描述基于某个父镜像创建新镜像的过程,下面会具体介绍

下面基于 centos (父镜像)来创建一个 nginx 新镜像。下面是 Dockerfile 的内容:

#  指定父镜像,注意名字须与 docker images 的 REPOSITORY 的一致
FROM centos

#  维护者信息
MAINTAINER 知泥博客 https://www.vnshu.com

#  设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH

#  接下来的 RUN 都是执行 centos 里面的命令
RUN yum -y install wget

RUN wget https://nginx.org/download/nginx-1.8.1.tar.gz -P /usr/local
RUN wget http://ftp.riken.jp/Linux/fedora/epel/epel-release-latest-7.noarch.rpm -P /usr/local

RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#  WORKDIR 相当于 cd ,改变工作目录
WORKDIR /usr/local
RUN tar xf nginx-1.8.1.tar.gz
WORKDIR /usr/local/nginx-1.8.1

#  编译安装 nginx
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

# 注意,这里只是声明了端口,并没有打开,还需要 用 -p outerPort:innerPort 来建立映射
EXPOSE 80

#  容器运行时执行的命令,这里指的是启动 nginx ,注意后面的分号
CMD ["nginx", "-g", "daemon off;"]

首先指定 centos 镜像的名字,不一定名字恰好就是centos,可能带有前缀,具体名称使用 docker images 查看 REPOSITORY 栏。然后指定维护者信息,设置环境变量,方便最后 CMD 直接执行 nginx 命令。

之后就是一系列的 RUN 命令,主要是下载必要的内容以及编译安装 nginx。 EXPOSE 更多的是说明作用,方便后期维护,最后启动 nginx。

可以发现,启动 nginx 时使用了 daemon off,具体原因如下:

  • docker容器启动时默认会把容器内部第一个进程,也就是PID为1的程序,作为容器是否正在运行的依据,若 pid=1 的程序挂了(不一定真的是挂了,有可能只是切换到后台运行了),那么docker 容器就会直接退出(使用 docker ps -a 可以发现 状态已经是 Exited)
  • 新制作的nginx镜像 pid=1 的程序就是nginx,若转到后台运行,则 bash 或 sh脚本的 pid 变成了1,那么docker判断 nginx  已经挂了从而直接退出容器

nginx的压缩包和epel的rpm包也可以预先下载,然后使用 ADD 命令复制到 centos 镜像的 /use/local目录下(压缩包会自动解压)。

写好了 dockerfile后,使用 docker build 制作镜像,首先将写好的dockerfile文件命名为 dockerfile 或者 Dockerfile,然后放到某个目录 Z 下(Z目录最好别放置无关文件,若使用 ADD 复制则需要将资源文件放到Z目录下),最后使用 docker build -t nginx Z (-t 指定新创建的镜像名称)来创建 nginx 镜像。下面是几个步骤的输出内容:

docker不归路

看到 Successfully tagged 说明已经创建好了 nginx 镜像。

创建好了后,使用 docker images 可以看到 nginx 镜像。使用 docker run -p 80:80 -d nginx (-p 80:80 将本机的80端口与容器的80端口建立映射)在后台运行 nginx 容器,使用 docker ps 可以看到类似下面内容

docker不归路

其中的 COMMAND 就是 dockerfile 中 CMD的内容。使用 docker exec -it a6 /bin/bash (-it 后面的 container id 需要能唯一标识容器,类似于 git 的 commit id)即可新建一个nginx镜像的bash并在里面进行操作。也可以使用 docker attach 进入容器,但退出后会导致容器关闭以及多窗口中某窗口阻塞会导致其他窗口阻塞,因此并不推荐。

小结

本文详细讲解了 docker 的镜像制作方法,并就 dockerfile 方式给出了一个完整的实例。

参考

镜像命名规范与Dockerfile编写规范

docker批量删除停止的容器与镜像

评论或私信站长


  1. #该文章暂时没有评论