一、镜像的分层结构
- 共享宿主机的kernel
- base镜像提供的是最小的Linux发行版
- 同一docker主机支持运行多种Linux发行版
- 采用分层结构的最大好处是:共享资源
- Copy-on-Write 可写容器层
- 容器层以下所有镜像层都是只读的
- docker从上往下依次查找文件
- 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
- 一个镜像最多127层
二、镜像的制作创建
1.交互式shell制作镜像
导入busysbox包docker load -i busybox.tar
创建一个新的容器并交互式运行
docker run -it --name demo2 busybox #demo2为容器名
建立数个文档touch file...
显示容器docker ps
未发现busybox容器
显示所有容器,包括未运行的docker ps -a
启动demo2docker start demo2
连接容器demo2,进入交互界面 docker container attach demo2
ctrl p q 打入后台,不退出,从当前容器创建一个新的镜像,容器内的修改都会被保存到新镜像
docker commit demo2 demo2:v1 #demo2为当前容器 demo2:v1 为镜像名称
docker images
查看镜像hisdocker history demo2:v1
,发现之前交互式界面创建文件操作没有被显示,镜像删除
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 images
docker history demo2:v3 .
添加脚本内容,上传新镜像
vim Dockerfile
FROM busybox
RUN echo westos > testfile
RUN echo westos > zjm
docker build -t demo2:v3 .
再次查看镜像及历史内容
三、镜像的优化
为什么要对镜像优化?
“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目录下创建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 .
创建容器demo,查看容器信息,可以看到分配的ip
docker run -d --name demo rhel7:v1
docker inspect demo
在真实主机挂载路径上创建默认发布文件index.html,进行访问
cd /var/lib/docker/volumes/72408e2cce4521a28fd2ec8bbeb4c9349ddcef44af92c9ce9e504657ce712932/_data
echo www.westos.org > index.html
curl 172.17.0.3
查看镜像docker history rhel7:v1
,发现该镜像的空间占用较大,达到300MB,需要进行优化
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;"]
其中
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 .
查看大小,缩小约50mb
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 .
查看镜像,发现缩小了近半
选择最精简的基础镜像
更换轻量级源镜像能进一步缩减空间。修改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 .