一、镜像的分层结构

  • 共享宿主机的kernel
  • base镜像提供的是最小的Linux发行版
  • 同一docker主机支持运行多种Linux发行版
  • 采用分层结构的最大好处是:共享资源
  • Copy-on-Write 可写容器层
  • 容器层以下所有镜像层都是只读的
  • docker从上往下依次查找文件
  • 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
  • 一个镜像最多127层

二、镜像的制作创建

1.交互式shell制作镜像

导入busysbox包docker load -i busybox.tar

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux

创建一个新的容器并交互式运行

docker  run -it --name demo2 busybox #demo2为容器名

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_02

建立数个文档touch file...

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_03

显示容器docker ps未发现busybox容器

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_04


显示所有容器,包括未运行的docker ps -a

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_05


启动demo2docker start demo2

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_06

连接容器demo2,进入交互界面 docker container attach demo2

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_07

ctrl p q 打入后台,不退出,从当前容器创建一个新的镜像,容器内的修改都会被保存到新镜像

docker commit  demo2 demo2:v1  #demo2为当前容器  demo2:v1 为镜像名称
docker images

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_08


查看镜像hisdocker history demo2:v1,发现之前交互式界面创建文件操作没有被显示,镜像删除

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_09

2.docker脚本制作镜像

编写脚本,执行当前目录内操作创建v2镜像,注意一定要在脚本所在目录

mkdir /root/docker
cd /root/docker/
vim Dockerfile #新建Docekrfile为脚本

FROM busybox
RUN echo westos > testfile

docker build -t demo2:v2  . #执行当前目录内脚本创建v2镜像

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_10


查看镜像及历史内容

docker images
docker history  demo2:v3 .

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_11


添加脚本内容,上传新镜像

vim Dockerfile

FROM busybox
RUN echo westos > testfile
RUN echo westos > zjm

docker build -t demo2:v3 .

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_nginx_12


再次查看镜像及历史内容

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_13

三、镜像的优化

为什么要对镜像优化?

“docker镜像太大,导致用户服务器的磁盘空间很紧张,导致用户部署该产品时,花费的时间变长,如果客户的服务器规格不够,增大部署失败的概率”

小镜像的制作原则

  • 选择最精简的基础镜像
  • 减少镜像的层数
  • 清理镜像构建的中间产物
  • 注意优化网络请求
  • 尽量去用构建缓存
  • 使用多阶段构建镜像

1.部署基础镜像

实验环境:部署了nginx的rhel-7.6系统

在/root/docker目录下进行实验,准备软件仓库文件和镜像

mv rhel7.tar  docker/
mv nginx-1.20.1.tar.gz  docker/
cp /etc/yum.repos.d/dvd.repo   /root/docker

导入rhel7 镜像,创建交互式容器,用于测试命令

docker  load -i rhel7.tar 
docker images
docker run -it --name demo3 rhel7 bash

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_nginx_14


从docker目录下创建dockerfile文件,生成镜像,如果遇到错误进行修改

vim /root/docker/Dockerfile

FROM rhel7
EXPOSE 80                           #开放端口
VOLUME ["/usr/local/nginx/html"]    #挂载实际目录,数据存在于真实主机
COPY dvd.repo /etc/yum.repos.d/     #拷贝软件仓库文件
ADD  nginx-1.20.1.tar.gz  /mnt      #压缩到指定目录
RUN  rpmdb --rebuilddb              #仓库记录清理
RUN  yum install -y gcc pcre-devel zlib-devel make
WORKDIR /mnt/nginx-1.20.1
RUN ./configure &> /dev/null
RUN make &> /dev/null
RUN make install &> /dev/null
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

docker build -t rhel7:v1 .

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_15

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_16


创建容器demo,查看容器信息,可以看到分配的ip

docker run -d --name demo rhel7:v1
docker inspect  demo

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_17


在真实主机挂载路径上创建默认发布文件index.html,进行访问

cd /var/lib/docker/volumes/72408e2cce4521a28fd2ec8bbeb4c9349ddcef44af92c9ce9e504657ce712932/_data
echo www.westos.org > index.html
curl 172.17.0.3

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_18


查看镜像docker history rhel7:v1,发现该镜像的空间占用较大,达到300MB,需要进行优化

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_19

2.层级优化

在脚本中的每一行为一层结构,因此将RUN命令进行集合,减少层级

FROM rhel7 
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/
ADD  nginx-1.20.1.tar.gz  /mnt
WORKDIR /mnt/nginx-1.20.1
RUN  rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure &> /dev/null &&  make &> /dev/null &&  make install &> /dev/null && rm -rf /mnt/nginx-1.20.1 /var/cache/*
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_nginx_20


其中

sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc #关闭nginx编译debug模块

rm -rf /mnt/nginx-1.20.1 /var/cache/* #清除系统缓存及nginx编译目录

接下来生成rhel7:v2镜像docker build -t rhel7:v2 .

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_nginx_21


查看大小,缩小约50mb

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_22

3.使用多阶段构建镜像

通过v2配置参数修改镜像,此时镜像内的环境除了nginx的运行环境还包括为了编译nginx而部署的环境,待nginx部署完毕,将该镜像上的nginx移植到只用运行环境的rhel7源镜像,从而达到节省空间目的

FROM rhel7 as build
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
COPY dvd.repo /etc/yum.repos.d/
ADD  nginx-1.20.1.tar.gz  /mnt
WORKDIR /mnt/nginx-1.20.1
RUN  rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure &> /dev/null &&  make &> /dev/null &&  make install &> /dev/null && rm -rf /mnt/nginx-1.20.1 /var/cache/*
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

FROM rhel7
COPY --from=build /usr/local/nginx  /usr/local/nginx
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

生成rhel7:v3镜像docker build -t rhel7:v3 .

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_nginx_23


查看镜像,发现缩小了近半

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_linux_24

选择最精简的基础镜像

更换轻量级源镜像能进一步缩减空间。修改Dockerfile

FROM nginx:latest as base

# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

ARG TIME_ZONE

RUN mkdir -p /opt/var/cache/nginx && \
    cp -a --parents /usr/lib/nginx /opt && \
    cp -a --parents /usr/share/nginx /opt && \
    cp -a --parents /var/log/nginx /opt && \
    cp -aL --parents /var/run /opt && \
    cp -a --parents /etc/nginx /opt && \
    cp -a --parents /etc/passwd /opt && \
    cp -a --parents /etc/group /opt && \
    cp -a --parents /usr/sbin/nginx /opt && \
    cp -a --parents /usr/sbin/nginx-debug /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \
    cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \
    cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime

FROM gcr.io/distroless/base-debian10

COPY --from=base /opt /

EXPOSE 80 443

ENTRYPOINT ["nginx", "-g", "daemon off;"]

生成rhel7:v4镜像docker build -t rhel7:v4 .

docker ubuntu 国内镜像拉取笛之爱 docker linux镜像_docker_25