前情提要:本篇博客将详细的介绍使用Dockerfile构建镜像的参数以及构建实例的全流程及解析,通过本篇博客你可以学会使用Dockerfile来构建镜像
一、镜像构建
1.1 参数介绍
| FROM | 指定base镜像 eg:FROM busybox:version |
|---|---|
| COPY | 复制文件 eg:COPY file /file 或者 COPY ["file","/"] |
| MAINTAINER | 指定作者信息,比如邮箱 eg:MAINTAINER user@example.com 在最新版的docker中用LABEL KEY="VALUE"代替 |
| ADD | 功能和copy相似,指定压缩文件或url eg: ADD test.tar /mnt 或者 eg:ADD http://ip/test.tar /mnt |
| ENV | 指定环境变量 eg:ENV FILENAME test |
| EXPOSE | 暴漏容器端口 eg:EXPOSE 80 |
| VOLUME | 申明数据卷,通常指数据挂载点 eg:VOLUME ["/var/www/html"] |
| WORKDIR | 切换路径 eg:WORKDIR /mnt |
| RUN | 在镜像构建时运行的指令,容器启动时不会再次执行 eg: touch file |
| CMD | 在启动容器时自动运行动作,可以被覆盖 eg:CMD echo FILENAME 会调用shell解析 eg:CMD ["/bin/sh","-c","echo FILENAME"] 不调用shell解析 |
| ENTRYPOINT | 和CMD功能和用法类似,但动作不可被覆盖 |
1.2 Dockerfile构建实例
1.2.1 建立构建目录,编写Dockerfile
cpp
[root@server1 ~]# mdkir docker
[root@server1 ~]# cd docker/
[root@server1 docker]# cp ~/nginx-1.23.3.tar.gz .
[root@server1 docker]# vim Dockerfile
FROM centos:7 # 指定base镜像为centos:7
ADD nginx-1.23.3.tar.gz /mnt # 添加nginx源码包到/mnt
WORKDIR /mnt/nginx-1.23.3 # 指定容器工作目录为/mnt/nginx-1.23.3,后续所有RUN命令都会在该目录下执行
RUN yum install -y gcc make pcre-devel openssl-devel # 镜像创建时安装编译软件和依赖
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc # 修改 Nginx 源码中的编译配置,注释掉 -g 调试标志,减小编译后的二进制文件体积
RUN ./configure --with-http_ssl_module --with-http_stub_status_module # 配置编译选项
RUN make # 编译安装nginx
RUN make install
EXPOSE 80 # 开放80端口
VOLUME ["/usr/local/nginx/html"] # 将nginx发行目录作为挂载卷
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"] # 让Nginx以前台模式运行(Docker容器要求主进程前台运行)
1.2.2 通过Dockerfile生成镜像
cpp
[root@server1 docker]# docker build -t webserver:v1 .
1.2.3 测试镜像可用性
cpp
[root@server1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v1 bfd6774cc216 8 seconds ago 494MB
[root@server1 docker]# docker history webserver:v1
[root@server1 docker]# docker run -d --name checkimage webserver
1.2.4 查看容器详情
cpp
[root@server1 docker]# docker inspect web1
二、镜像优化
2.1 优化策略
-
选择最精简的基础镜像
-
减少镜像的层数
-
清理镜像构建的中间产物
2.2 镜像优化示例
2.2.1 缩减镜像层
cpp
# 减少Dockerfile中指令的使用
[root@server1 docker]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23.3 && yum clean all
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t webserver:v2 .
[root@server1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v2 caf0f80f2332 4 seconds ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB
2.2.2 多阶段构建
cpp
# 将不需要的构建过程作为临时镜像
[root@server1 docker]# vim Dockerfile
FROM centos:7 AS build
ADD nginx-1.23.3.tar.gz /mnt
WORKDIR /mnt/nginx-1.23.3
RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23.3 && yum clean all
FROM centos:7
COPY --from=build /usr/local/nginx /usr/local/nginx
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]
[root@server1 docker]# docker build -t webserver:v3 .
[root@server1 docker]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v3 1ac964f2cefe 29 seconds ago 205MB
webserver v2 caf0f80f2332 3 minutes ago 317MB
webserver v1 bfd6774cc216 About an hour ago 494MB
2.2.3 使用最精简镜像
使用google提供的最精简镜像
下载地址: https://github.com/GoogleContainerTools/distroless
下载镜像
cpp
docker pull gcr.io/distroless/base
利用最精简镜像构建
cpp
[root@server1 ~]# mkdir new
[root@server1 ~]# cd new/
[root@server1 new]# vim Dockerfile
FROM nginx:1.23 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 /usr/lib/x86_64-linux-gnu/libpcre* /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-debian11
COPY --from=base /opt /
EXPOSE 80 443
ENTRYPOINT ["nginx", "-g", "daemon off;"]
[root@server1 new]# docker build -t webserver:v4 .
[root@server1 new]# docker images webserver
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver v4 c0c4e1d49f3d 4 seconds ago 34MB 使用最精简镜像构建
webserver v3 1ac964f2cefe 12 minutes ago 205MB 缩减镜像层+多阶段构建
webserver v2 caf0f80f2332 15 minutes ago 317MB 缩减镜像层
webserver v1 bfd6774cc216 About an hour ago 494MB