制作一个docker镜像并且优化镜像大小

-####################################1. 定制一个images镜像
一些封装好的docker镜像,提取码:e4yf
我下载到root根目录下,重命名为images
移动到目录下
导入rhel7.tar镜像

cd ~/images/
ls
docker load -i rhel7.tar

制作一个docker镜像并且优化镜像大小_第1张图片
创建一个目录在里面写dockerfile

mkdir /opt/docker
cd /opt/docker/
vim dockerfile

制作一个docker镜像并且优化镜像大小_第2张图片
内容如下

FROM rhel7                                 ##源镜像是rhel7,最好将名为rhel7的镜像放在本地
ENV HOSTNAME docker1                       ##定义hostname为server1
MAINTAINER [email protected]                ##定义邮箱
EXPOSE 80                                  ##定义端口
COPY yum.repo /etc/yum.repos.d/yum.repo    ##配置yum源
RUN rpmdb --rebuilddb && yum install -y httpd && yum clean all    ##执行命令安装httpd并清除yum缓存,rpmdb 命令用于初始化和重建rpm数据库,rebuilddb:从已安装的包头文件,反向重建RPM数据库
VOLUME ["/var/www/html"]                   ##数据卷所在的位置
CMD ["/usr/sbin/httpd","-D","FOREGROUND"   ##打开apach服务,-D 是全局文件/etc/sysconfig/httpd中的打开参数

下一个yum配置文件,这里我直接复制虚拟机的

cp /etc/yum.repos.d/yum.repo .

制作一个docker镜像并且优化镜像大小_第3张图片
在这个目录下创建容器

docker build -t rhel7:v1 . #点代表这个目录

制作一个docker镜像并且优化镜像大小_第4张图片
查看容器

docker images

制作一个docker镜像并且优化镜像大小_第5张图片
在后台运行名为vm3,端口映射在8082的rhel7:v1镜像
复制一个写好的发布页给docker

docker run -d --name vm3 -p 8082:80 rhel7:v1

制作一个docker镜像并且优化镜像大小_第6张图片
真机浏览器连接172.25.16.1:8082
制作一个docker镜像并且优化镜像大小_第7张图片

  • #####################################2.直接在本地写容器文件

删除刚才创建的vm3

docker stop vm3
docker rm vm3
docker ps -a

制作一个docker镜像并且优化镜像大小_第8张图片
再次运行且查看挂载到哪个本地目录

docker run -d --name vm3 -p 8082:80 rhel7:v1
docker inspect vm3 | grep "Source"

在这里插入图片描述
移动到这个目录下写发布页文件

cd /var/lib/docker/volumes/9466892f3da8ff1d924d0d49108d7b6cad818bef120f0319ae6e2e56436f570f/_data
vim index.html

在这里插入图片描述
真机浏览器测试
制作一个docker镜像并且优化镜像大小_第9张图片

  • ########################################3.如何优化镜像

删除vm3,删除本地物理卷

docker stop vm3
rm -fr /var/lib/docker/volumes/9466892f3da8ff1d924d0d49108d7b6cad818bef120f0319ae6e2e56436f570f/_data
docker rm vm3
docker ps -a

制作一个docker镜像并且优化镜像大小_第10张图片
下载nginx安装包,验证码v4fb
以制作nginx镜像为例

写dockerfile

FROM rhel7
COPY yum.repo /etc/yum.repos.d/yum.repo ##复制虚拟机yum文件给镜像
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make ##执行命令
ADD nginx-1.15.8.tar.gz /mnt   ##ADD比COPY更强大,如果文件是可识别的压缩文件,会帮忙解压
WORKDIR /mnt/nginx-1.15.8 ##进入这个目录
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc     ##关闭debug日志
RUN ./configure --prefix=/usr/local/nginx ##执行源码编译安装命令
RUN make 
RUN make install
EXPOSE 80 ##端口为80
VOLUME ["/usr/local/nginx/html"] ##把这个目录挂载到本地数据卷
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] ##在某个目录下执行命令

开始封装

docker build -t rhel7:v2 .

制作一个docker镜像并且优化镜像大小_第11张图片
运行镜像
真机浏览器连接

docker run -d --name nginx -p 8082:80 rhel7:v2

制作一个docker镜像并且优化镜像大小_第12张图片
查看封装的镜像大小,我们刚才命名为v2
可见是非常大的,接下来要尽量缩小大小

docker images rhel7

在这里插入图片描述
我们可以在dockerfile里把不需要的输出丢进垃圾箱
在原dockerfile下在有输出的命令后加&> /dev/null

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

开始封装

docker build -t rhel7:v3 .

可见大小已经缩小了,但还是可以再缩小
制作一个docker镜像并且优化镜像大小_第13张图片
这次我们把所有run的命令都写在一起

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

制作一个docker镜像并且优化镜像大小_第14张图片
第三次优化我们不指定数据卷挂载目录,更改第1行、第7行和第8行

FROM rhel7 as build
COPY yum.repo /etc/yum.repos.d/yum.repo
ADD nginx-1.15.8.tar.gz /mnt
WORKDIR /mnt/nginx-1.15.8
RUN rpmdb --rebuilddb && yum install -y gcc pcre-devel zlib-devel make  &> /dev/null && yum clean all && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx &> /dev/null && make &> /dev/null &&  make install &> /dev/null && rm -fr /mnt/nginx-1.15.8

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

制作一个docker镜像并且优化镜像大小_第15张图片
最后一次优化从底层入手,先导入两个镜像

cd ~/images
docker load -i distroless.tar
docker load -i nginx.tar

在这里插入图片描述
改dockerfile

FROM nginx as base
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
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 /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.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libdl.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libpthread.so.* /opt && \
    cp -a --parents /lib/x86_64-linux-gnu/libcrypt.so.* /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

COPY --from=base /opt /

EXPOSE 80

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

制作一个docker镜像并且优化镜像大小_第16张图片
启动容器

docker run -d --name nginx -p 8082:80 rhel7:v6 

真机浏览器连接
制作一个docker镜像并且优化镜像大小_第17张图片

  • #########4. Dockerfile文件中CMD和ENTRYPOINT的区别

以下dockerfile为例,ENTRYPOINT

FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"]

docker build -t busybox:v4 .

docker run --rm busybox:v4 westos
hello westos

在删除时会打印命令后接的最后一个参数westos,用CMD时不会,只会打印dockerfile内写好的参数

你可能感兴趣的:(企业级部署)