首先我们使用Dockerfile构建一个镜像:
vim Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.16.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.1
RUN rpmdb --rebuilddb
RUN yum install -y gcc make pcre-devel zlib-devel
RUN sed -i.bak 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --prefix=/usr/local/nginx
RUN make
RUN make install
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
其中还需要repo文件:
[root@server1 ~]# cd docker/
[root@server1 ~]# vim dvd.repo
[root@server1 docker]# cat dvd.repo
[dvd]
name=rhel7
baseurl=http://172.25.63.250/rhel7.6
gpgcheck=0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
之后build:
[root@server1 docker]# docker build -t nginx:v1 .
- 1
查看这个镜像构建历史:
[root@server1 docker]# docker history nginx:v1
- 1
运行这个镜像:
[root@server1 docker]# docker run -d --name web nginx:v1
088df7d425bf47182746753dd68d5a99f1de767afd6f53e264b09da3edc3b638
- 1
- 2
[root@server1 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
088df7d425bf nginx:v1 "/usr/local/nginx/sb…" 33 seconds ago Up 12 seconds web
- 1
- 2
- 3
查看容器的信息:
docker inspect nginx:v1
- 1
可以看到容器的ip为172.17.0.2,之后访问这个ip:
curl 172.17.0.2
- 1
此时可以查看该镜像的大小:
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 dbff0bd7b93a 9 minutes ago 289MB
- 1
- 2
- 3
为289M,我们可以优化镜像的构建过程以使镜像的大小缩小:
镜像的优化
可以从以下几个方面来优化镜像:
选择最精简的基础镜像我们在最后实验,这一步可以大大减少镜像的大小,我们先从减少镜像的层数开始:
减少镜像的层数
更改Dockerfile文件将多个RUN层合并为一层:
[root@server1 docker]# vim Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.16.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i.bak 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
之后build:
[root@server1 docker]# docker build -t nginx:v2 .
- 1
成功后查看镜像大小发现变成了283M:
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v2 77a1177f2c37 45 seconds ago 283MB
nginx v1 dbff0bd7b93a 20 minutes ago 289MB
- 1
- 2
- 3
- 4
说明减少中间层数可以优化镜像
清理镜像构建的中间产物
更改Dockerfile文件:
[root@server1 docker]# vim Dockerfile
FROM rhel7
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.16.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i.bak 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && yum clean all && rm -rf /mnt/nginx-1.16.1
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
之后build:
[root@server1 docker]# docker build -t nginx:v3 .
- 1
成功后查看镜像大小发现变成了255M:
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 24bf8bf50b43 37 seconds ago 255MB
nginx v2 77a1177f2c37 4 minutes ago 283MB
nginx v1 dbff0bd7b93a 24 minutes ago 289MB
- 1
- 2
- 3
- 4
- 5
说明清理中间产物可以优化镜像
使用多阶段构建
更改Dockerfile文件:
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM rhel7 as build
COPY dvd.repo /etc/yum.repos.d/
ADD nginx-1.16.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.16.1
RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i.bak 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && yum clean all && rm -rf /mnt/nginx-1.16.1
FROM rhel7
COPY --from=build /usr/local/nginx /usr/local/nginx
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
之后build:
[root@server1 docker]# docker build -t nginx:v4 .
- 1
成功后查看镜像大小发现变成了141M:
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v4 3a092e83aad7 20 seconds ago 141MB
nginx v3 24bf8bf50b43 4 minutes ago 255MB
nginx v2 77a1177f2c37 8 minutes ago 283MB
nginx v1 dbff0bd7b93a 28 minutes ago 289MB
- 1
- 2
- 3
- 4
- 5
- 6
说明多阶段构建可以明显减少镜像的大小。
使用更为精简的基础镜像
我们使用的基础镜像是google提供的base-debian10镜像,它非常小,仅为19.2M,因此可以从源头减小build后镜像的大小
拉取base-debian10基础镜像,由于google官方没有上传因此我们下载其他用户上传的镜像,两个镜像的内部其实是相同的:
docker pull madeforgoods/base-debian10
- 1
更改名称为google官方的名称:
docker tag madeforgoods/base-debian10 gcr.io/distroless/base-debian10
- 1
编辑Dockerfile文件:
[root@server1 docker]# vim Dockerfile
[root@server1 docker]# cat Dockerfile
FROM nginx as base
ARG Asia/Shanghai
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 /
ENTRYPOINT ["nginx", "-g", "daemon off;"]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
注意:以上文件内容可以从github找到,搜索:distroless nginx
,网址:https://github.com/evry-ace/nginx-distroless
之后build:
[root@server1 docker]# docker build -t nginx:v5 .
- 1
查看镜像大小:
[root@server1 docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v5 21829713aead 30 seconds ago 31.1MB
<none> <none> fb6d4957e715 31 seconds ago 139MB
nginx v4 3a092e83aad7 8 minutes ago 141MB
nginx v3 24bf8bf50b43 12 minutes ago 255MB
nginx v2 77a1177f2c37 16 minutes ago 283MB
nginx v1 dbff0bd7b93a 36 minutes ago 289MB
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
发现大小仅为31.1M,说明这种方法可以大幅减小镜像的大小。