栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

docker分层及镜像构建(三)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

docker分层及镜像构建(三)

目录

一、docker镜像分层

1、docker三要素

2、创建容器的几种方式

3、镜像所包含的部分

4、镜像的分层原理

 二、dockerfile介绍

1、dockerfile结构四部分

2、dockerfile操作指令

3、dockerfile镜像分层特点

三、dockerfile分层原理

1、涉及技术

2、docker存储引擎overlay分层结构

四、基于dockerfile构建镜像

1、Dockerfile结构四部分

2、编写dockerfile标准格式(构建nginx镜像)

3、优化dockerfile制作镜像

总结


一、docker镜像分层

1、docker三要素

镜像:容器的一种静态模板(一组资源的集合,分层的方式一层层累加,组成了完整的镜像

容器:是一种应用/环境的运行时状态/运行时环境

仓库:存放镜像

2、创建容器的几种方式

①基于已有的模板文件进行创建

②基于已有的镜像进行创建

③基于dockerfile创建

3、镜像所包含的部分

①基础镜像——操作系统centos 7等

②应用服务软件包——nginx等服务

③依赖环境——gcc gcc-C++ make jdk jre gd 等

④编译安装——./confugure

⑤应用服务的相关配置文件——.conf

⑥启动方式/容器开启时运行的脚本/命令/指令

4、镜像的分层原理

 二、dockerfile介绍

dockerfile是由一组指令组成的文件。Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以“#“号开头的注释。

1、dockerfile结构四部分

◆基础镜像信息

◆维护者信息

◆镜像操作指令

◆容器启动时执行指令

2、dockerfile操作指令

指令

含义

FROM [镜像]

指定新镜像所基于的镜像,第一条指令必须为FROM指令,每创建一个镜像就需要一条FROM指令

MAINTAINER [名字]

说明新镜像的维护人信息

RUN [命令]

在所基于的镜像执行命令,并提交到新的镜像中

CMD [“要运行的程序”,“参数1”、“参数2”]

指令启动容器时要运行的命令或者脚本,Dockerfile只能有一条CMD命令,如果指定多条则只能执行最后一条

EXPOSE [端口号]

指定新镜像加载到Docker时要开启的端口

ENV [环境变量] [变量值]

设置一个环境变量的值,会被后面的RUN使用

ADD [源文件/目录] [目标文件/目录]

将源文件复制到目标文件,源文件要与Dockerfile位于相同目录中,或者是一个URL,若源文件是压缩包则会将其解压缩

COPY [源文件/目录] [目标文件/目录]

将本地主机上的文件/目录复制到目标地点,源文件/目录要与Dockerfile在相同的目录中

VOLUME [“目录”]

在容器中创建一个挂载点

USER [用户名/UID]

指定运行容器时的用户

WORKDIR [路径]

为后续的RUN、CMD、ENTRYPOINT指定工作目录,相当于是一个临时的"CD",否则需要使用绝对路径

onBUILD [命令]

指定所生成的镜像作为一个基础镜像时所要运行的命令(是一种优化)

HEALTHCHECK

健康检查

注:

①、ADD和copy区别

◆Dockerfile中的COPY指令和ADD指令都可以将主机上的资源复制或加入到容器镜像中,都是在构

建镜像的过程中完成的。

◆copy = cp复制,将宿主机指定的文件复制到image层中(节省资源)

◆ADD可以复制,同时兼有了解压的功能add nginx-1.12.tar.gz /root/nginx(消耗资源),在复制进

去的同时会对压缩包进行解压到容器内部就是 nginx-1.12/,◆COPY指令和ADD指令的唯一区别在

于是否支持从远程URL获取资源。COPY指令只能从执行docker build所在的主机上读取资源并复

制到镜像中。而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中add复制的对象可

以是URL,跨节点的数据(URL)。

注意:满足同等功能的情况下,推荐使用COPY指令。ADD指令更擅长读取本地tar文件并解压缩。

②、CMD和entrypoint的区别、shell模式与exec模式的区别

它们都是容器启动时要加载的命令。cmd是容器环境启动时默认加载的命令;entrypoint是容器环

境启动时第一个加载的命令程序/脚本程序init。

◎如果 ENTRYPOINT使用了shell模式,CMD指令会被忽略。

entrypoint ["sh","-c", "echo $HOME"]

cmd [ "restart" ] #CMD会被忽略

◎如果 ENTRYPOINT使用了exec模式,CMD指定的内容被追加为ENTRYPOINT 指定命令的参

数。

entrypoint ["/etc/init.d/nginx"]

cmd [ "restart"]  #CMD作为entrypoint的参数

◎如果 ENTRYPOINT使用了exec模式,CMD也应该使用exec模式。

同一个dockerfile中有多个cmd指令的话,哪个生效?最后一个生效。

◎如果dockerfile中同时有多个cmd命令,docker build -t nginx:new

/bin/bash 哪个生效?docker build指定的生效。

◎如果dockerfile中cmd和entrypoint同时存在哪个生效呢?看情况,如果都是默认加载的类型。

cmd:默认加载的命令

entrypoint:第一个加载的环境

◎exec方式启动的话,那么entrypoint会覆盖,或将cmd做为entrypoint传入参数;shell 方式启动的话,直接就是entrypoint生效。

◎exec模式与shell模式:

exec:容器加载时使用的启动的第一个任务进程

shell:容器加载时使用的第一个bash

3、dockerfile镜像分层特点

◆Dockerfile中的每个指令都会创建一个新的镜像层;

◆镜像层将被缓存和复用;

◆当Dockerfile的指令修改了,复制的文件变化了,或者构建镜像时指定的变量不同了,对应的镜像层缓存就会失效;

◆某一层的镜像缓存失效之后,它之后的镜像层缓存都会失效;

◆镜像层是不可变的,如果在某一层中添加一个文件,然后在下一层中删除它,则镜像中依然会包含该文件。

三、dockerfile分层原理

        docker容器是基于AUFS构建,而AUFS是一种可叠加的文件系统。Docker镜像位于bootfs之

上;每一层镜像的下一层成为父镜像;第一层镜像成为base image(操作系统环境镜像);最后

为容器层(可读可写),在最顶层( writable);容器层以下都是readonly。

1、涉及技术

①、bootfs (boot file system)内核空间

主要包含bootloader和kernel。bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件

系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot

加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交

给内核,此时系统也会卸载bootfs。

在linux操作系统中(不同版本的linux发行版本),linux.加载bootfs时会将rootfs设置为read-only,

系统自检后会将只读改为读写,让我们可以在操作系统中进行操作。

②、rootfs (root file system)内核空间

rootfs即根文件系统

在bootfs之上 (base images,例如centos 、 ubuntu)。包含的就是典型 Linux系统中

的/dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如

Ubuntu,Centos等等。

③、AUFS与overlay / overlay2 (docker 高版本)

AUFS是一种联合文件系统。内核默认使用的就是AUFS,它使用同一个Linux host上的多个目录,

逐个堆叠起来,对外呈现出一个统一的文件系统。一种可叠加式的文件系统,主要功能是把多个文

件夹的内容合并到一起,提供一个统一的视图, 主要用于各个Linux发行版的livecd中,以及

docker里面用来组织image,使用AUFS该特性,实现了docker镜像的分层。

而docker使用了overlay/overlay2存储引擎/驱动来支持分层结构。OverlayFs将单个Linux主机上的

两个目录合并成一个目录。这些目录被称为层,统一过程被称为联合挂载

④、LXC(内核容器技术)

LXC内核中容器技术,早期docker在没有将资源容器化的功能时,就是靠内核中LXC来完成容器虛

拟化的;现在docker拥有了自己的docker libcontainer库文件,这个库文件可以做到将资源容器化

的操作,所以对LXC的依赖性大大降低。

LXC内核中容器技术/驱动:将资源容器化(虚拟化);是早期docker的依赖组件;目前docker拥有自

己的libcontianer库,可以实现容器虚拟化的功能,对LXC的依赖性降低。

⑤、注意:为什么docker的centos镜像只有200M多一点?

bootfs + rootfs:作用是加载、引导内核程序,以及挂载使用linux操作系统(centos ubantu)等等一

些关键的目录文件。

docker实现了将内核中的bootfs和rootfs进行了简单分离,而对于不同的linux发行版,bootfs基本是

一致的,rootfs会有差别,因此不同的发行版可以公用bootfs;对于一个精简的OS,rootfs可以很

小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,docker自

己只需要提供rootfs 就行了。

因为各linux发行版本公用一套bootfs引导、加载文件系统(是由宿主机内核提供的),同时vm虚拟

机的操作系统需要完整的模拟出来,所以容器的操作系统比vm虚拟机的操作系统更为轻量级(区

别在于容器是共享宿主机内核的)。

2、docker存储引擎overlay分层结构

docker使用了overlay/overlay2存储引擎/驱动来支持分层结构。OverlayFs将单个Linux主机上的两

个目录合并成一个目录。这些目录被称为层,统一过程被称为联合挂载。

overlayfs在linux主机上只有两层,一个目录在下层,用来保存镜像;另外一个目录在上层,用来存

储容器信息。

Ⅰ、rootfs          基础镜像

Ⅱ、lower          下层信息(为镜像层,容器)

Ⅲ、upper          上层目录(容器信息,可写)

Ⅳ、worker          运行的工作目录( copy-on-write写时复制,准备容器环境)

Ⅴ、mergod         "视图层”(容器视图)

注:可以使用命令docker inspect 容器id 查看里面的一些分层。

注:在修改时,若upper层没有,则会将lower层有的文件复制到upper层进行修改并保存结果。

四、基于dockerfile构建镜像

dockerfile自动生成镜像,Dockerfile是由一组指令组成的文件,其中每条指令对应 Linux 中的一条

命令,Docker 程序将读取 Dockerfile 中的指令生成指定镜像。

1、Dockerfile结构四部分

①基础镜像信息(指定操作系统镜像是什么镜像、什么版本)

②维护者信息

③镜像操作指令

④容器启动时执行指令(启动容器的时候,执行的脚本/命令参数等等)

注:Dockerfile每行支持一条指令,每条指令可携带多个参数,支持使用以"#"号开头的注释。

2、编写dockerfile标准格式(构建nginx镜像)

①、建立工作目录

[root@docker ~]# mkdir daemo  #作为生成镜像的工作目录

[root@docker ~]# cd daemo/

②、创建并编写dockerfile文件

[root@docker nginx]# vim dockerfile 
##第一行必须指明基于的基础镜像
FROM centos:7
##维护该镜像的用户信息
MAINTAINER the centos progect 
##以下写镜像操作指令
RUN yum -y update
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.2.tar.gz /usr/local/src
VOLUME ["/usr/local/nginx/html"]
##为后续的操作指令指定工作目录(相当于cd)
WORKDIR /usr/local/src/nginx-1.12.2
RUN ./configure 
--prefix=/usr/local/nginx 
--user=nginx 
--group=nginx 
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
##开启80端口
EXPOSE 80
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
##启动容器时执行指令脚本
CMD nginx

##查看我们制作的镜像,我们制作的标签为v的镜像大小为716MB,而docker仓库中的相同版本nginx1.12.0大小仅为107MB
[root@docker ~]# docker images   
nginx          v          cfeb40a7b94d   2 hours ago         716MB
nginx          1.12.0     313ec0a602bc   4 years ago         107MB

◆◆◆构建nginx镜像

①创建一个对应的目录( mkdir nginx)

②编写Dockerfile文件(最简单的方式,nginx部署脚本放进去,每条命令用RUN执行,环境变量使

用ENV,移动到对应目录使用workdir,EXPOSE暴露端口,最后使用CMD 进行启动设置)

③在nginx目录中上传nginx-1.12.2.tar.gz软件包等文件

④docker build 创建

⑤docker run运行容器

⑥检验

◆◆◆镜像构建过程中

①每一层镜像会临时产生一层新的镜像层,并且会运行为临时容器。

②每一层临时容器会基于前一层镜像的缓存层(容器)进行运行。

③如果该镜像层的临时容器在运行时报错,会exited (非0值)退出,并且在docker ps -a中会保存下

来,同时,docker build构建过程, 会中止。

④在基于同一个dockerfile修改时,修改的指令对应的image镜像缓存会失效,但该镜像层之前的

image层的缓存会保留。

3、优化dockerfile制作镜像

前面看到我们在未进行优化前的nginx:v大小未716MB,可以说很大了,下面我们就对其进行优

化。


①、优化1:不需要输出的指令丢入/dev/null (需要确定命令执行的是正确的)。

[root@docker nginx]# vim dockerfile 

FROM centos:7
RUN yum -y update &> /dev/null
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null && yum clean all
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.2.tar.gz /usr/local/src
VOLUME ["/usr/local/nginx/html"]
WORKDIR /usr/local/src/nginx-1.12.2
RUN ./configure 
--prefix=/usr/local/nginx 
--user=nginx 
--group=nginx 
--with-http_stub_status_module && make && make install &> /dev/null
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
CMD nginx

[root@docker nginx]# docker build -t "nginx:v1" .   #构建为镜像优化1版本为nginx:v1
[root@docker nginx]# docker images  #查看镜像大小
nginx          v1         c63eab10ae17   about a minute ago   597MB
nginx          v          cfeb40a7b94d   3 hours ago          716MB

注:结论:明显看到镜像大小减小了。

②、优化2:减少RUN指令的使用

[root@docker nginx]# vim dockerfile 

FROM centos:7
RUN yum -y update && yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null && yum clean all && useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.2.tar.gz /usr/local/src
VOLUME ["/usr/local/nginx/html"]
WORKDIR /usr/local/src/nginx-1.12.2
RUN ./configure 
--prefix=/usr/local/nginx 
--user=nginx 
--group=nginx 
--with-http_stub_status_module && make && make install &> /dev/null && echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80
CMD nginx

[root@docker nginx]# docker build -t "nginx:v2" .  #构建为镜像优化2版本为nginx:v2
[root@docker nginx]# docker images  #查看镜像大小
nginx          v1         c63eab10ae17   about a minute ago   597MB
nginx          v          cfeb40a7b94d   3 hours ago          716MB
nginx          v2         e7ab54678277   26 minutes ago      453MB

③、优化3:多阶段构建(使用FROM命令生成多个镜像,将指定的镜像做为其他镜像的基础镜像环

境来构建)。

[root@docker nginx]# vim dockerfile 

FROM centos:7 as build   #as build 用于构建的基础镜像
RUN yum -y update && yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null && yum clean all && useradd -M -s /sbin/nologin nginx &> /dev/null
ADD nginx-1.12.2.tar.gz /usr/local/src
WORKDIR /usr/local/src/nginx-1.12.2
RUN ./configure 
--prefix=/usr/local/nginx 
--user=nginx 
--group=nginx 
--with-http_stub_status_module && make && make install &> /dev/null && echo "daemon off;">>/usr/local/nginx/conf/nginx.conf &> /dev/null && rm -rf /usr/local/src/nginx-1.12.2
ENV PATH /usr/local/nginx/sbin:$PATH

FROM centos:7    #以上一个镜像运行的结果为基础镜像环境来构建
VOLUME ["/usr/local/nginx/html"]
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
CMD nginx

[root@docker nginx]# docker build -t "nginx:v3" .  #构建为镜像优化3版本为nginx:v3
[root@docker nginx]# docker images  #查看镜像大小
nginx          v1         c63eab10ae17   about a minute ago   597MB
nginx          v          cfeb40a7b94d   3 hours ago          716MB
nginx          v2         e7ab54678277   26 minutes ago      453MB
nginx          v3         1a79abf73ac9   19 seconds ago    208MB

注:结论:可以看到经过三次优化,镜像大小明显小了。

④、优化:4 使用更为轻量级的linux 发行版本

如debian、alpine、apt add等轻量级本版。

总结

1、docker镜像层次结构小结

①base image :基础镜像

②image:固化了一个标准运行环境,镜像本身的功能-封装一组功能性的文件,通过统一的方式,

文件格式提供出来(只读)

③container:容器层(读写)

④docker-server端

⑤呈现给docker-client(视图)

2、镜像分层简洁概述:

本从顶层到底层顺序

container                 容器层

image (s)                 镜像层(应用的像层——》上层镜像层)

image (s)                 镜像层(依赖环境的镜像层——》下层镜像层)

base image                基础镜像层(linux发行版本操作系统rootfs)

kernel                    内核层(aufs + bootfs )

3、优化dockerfile镜像

优化1:不需要输出的指令丢入/dev/null (需要确定命令执行的是正确的)

优化2:减少RUN构建

优化3:多阶段构建(使用FROM命令生成多个镜像,将指定的镜像做为其他镜像的基础镜像环境来

构建)

优化4 :使用更为轻量级的linux 发行版本

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/642380.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号