创建镜像有三种方法,分别为基于已有镜像创建、基于本地模板创建以及基于Dockerfile创建。
一、基于现有镜像创建
创建nginx镜像:
1、首先启动一个容器,在容器里做修改
2、然后将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像
二、基于本地模板创建
三、基于Dockerfile 创建
1、基础概念
联合文件系统(UnionFS)
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。AUFS、OverlayFS 及 Devicemapper 都是一种 UnionFS。
Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
我们下载的时候看到的一层层的就是联合文件系统。
2、镜像加载原理
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。
bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统。
在Docker镜像的最底层是bootfs,这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs,提供系统环境,在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
3、dockerfile概述
镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。
dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。有了Dockerfile,当我们需要定制自己额外的需求时,只需在Dockerfile上添加或者修改指令,重新生成 image 即可, 省去了敲命令的麻烦。
4、dockerfile 操作常用的指令
FROM | 指定基础镜像(是Dockerfile的第一行指令) |
MAINTAINER | 指定镜像维护人信息(可选) |
RUN | 指定linux命令,尽量将多条linux命令合并在一个RUN指令里,用 ; 或 && 或 <<EOF 串起来使用 |
EXPOSE | 指定容器要开启的应用的端口号 |
ENV | 指定容器的环境变量 |
ADD|COPY | 复制本地文件|目录到镜像里 |
VOLUME | 指定容器的匿名数据卷 |
USER | 指定容器的运行用户 |
WORKDIR | 指定后续镜像层的工作目录 |
ARG | 指定构建镜像时传入的参数变量 |
CMD|ENTRYPOINT | 指定容器启动时执行的命令和参数 |
5、dockerfile编写案例
①使用yum安装nginx
②使用源码编译安装nginx
FROM centos:7
ADD nginx-1.24.0.tar.gz /opt/
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make && \
useradd -M -s /sbin/nologin nginx && \
cd /opt/nginx-1.24.0 && \
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module && \
make && make install
ENV PATH=$PATH:/usr/local/nginx/sbin/
EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]