目录
6.1 CNM (Container Network Model)
三. docker镜像构建
1. docker镜像结构
-
共享宿主机的kernel
-
base镜像提供的是最小的Linux发行版
-
同一docker主机支持运行多种Linux发行版
-
采用分层结构的最大好处是:共享资源
2. 镜像运行的基本原理
-
Copy-on-Write 可写容器层
-
容器层以下所有镜像层都是只读的
-
docker从上往下依次查找文件
-
容器层保存镜像变化的部分,并不会对镜像本身进行任何修改一个镜像最多127层
3. 镜像获得方式
-
基本镜像通常由软件官方提供
-
企业镜像可以用官方镜像+Dockerfile来生成
-
系统关于镜像的获取动作有两种:
-
docker pull 镜像地址
-
docker load –i 本地镜像包
4. 镜像构建
#FROM COPY 和MAINTAINER
[root@Docker-node1 ~]# mkdir docker/
[root@Docker-node1 ~]# cd docker/
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile #基础镜像
[root@Docker-node1 docker]# docker build -t busybox:v1 . #构建镜像
[root@Docker-node1 docker]# docker images history busybox:v1
[root@Docker-node1 docker]#docker run -it --rm --name test1 busybox:v1
[root@Docker-node1 docker]# mv Dockerfile timinglee
[root@Docker-node1 docker]# docker build -f /root/docker/timinglee -t example:v2 . #-f指定名字
[root@Docker-node1 docker]# docker images
[root@Docker-node1 docker]# mv timinglee Dockerfile
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org #rhel版本不一样,指令不同 #指定邮箱信息
[root@Docker-node1 docker]# docker build -t busybox:v2 .
[root@Docker-node1 docker]#docker images history busybox:v2
cp /etc/passwd
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd #复制当前目录文件到容器指定位置,passwd必须在当前目录中
[root@Docker-node1 docker]#docker build -t busybox:v3 .
[root@Docker-node1 docker]#docker images history busybox:v3
[root@Docker-node1 docker]#docker run -it --rm --name test busybox:v3 #启动进入文件,看对应目录有没有文件
#如果已存在可以,删掉docker rm -f test
[root@Docker-node1 docker]# tar zcf zhuzhuxia.tar.gz Dockerfile passwd
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd
ADD zhuzhuxia.tar.gz /mnt
[root@Docker-node1 docker]# docker build -t busybox:v4 .
[root@Docker-node1 docker]# docker run -it --rm --name tes busybox:v4
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd
ADD zhuzhuxia.tar.gz /mnt
RUN mkdir /lee
[root@Docker-node1 docker]# docker build -t busybox:v5 .
[root@Docker-node1 docker]# docker images history busybox:v5
[root@Docker-node1 docker]# docker run -it --rm --name test busybox:v5
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd
ADD zhuzhuxia.tar.gz /mnt
RUN mkdir /lee
CMD ["/bin/sh", "-c", "echo hello lee"] #CMD的不同写法
#CMD echo joker
[root@Docker-node1 docker]# docker build -t busybox:v6 .
[root@Docker-node1 docker]# docker images history busybox:v6
[root@Docker-node1 docker]# docker run -it --name test busybox:v6
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd
ADD zhuzhuxia.tar.gz /mnt
RUN mkdir /lee
ENV name=timinglee
ENTRYPOINT ["/bin/sh", "-c", "echo xiaofeifei"] #不可替代
CMD ["/bin/sh", "-c", "echo $NAME"] #CMD被替代
[root@Docker-node1 docker]# docker build -t busybox:v6 .
[root@Docker-node1 docker]# docker images history busybox:v6
[root@Docker-node1 docker]# docker run -it --rm --name test busybox:v6 #有内容;CMD
[root@Docker-node1 docker]# docker rm test
[root@Docker-node1 docker]# docker run -it --rm --name test busybox:v6 sh #无内容;CMD
[root@Docker-node1 docker]# docker run -it --rm --name test busybox:v6 sh #有内容;测试ENTRYPOINT
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd
ADD zhuzhuxia.tar.gz /mnt
RUN mkdir /lee
EXPOSE 80 443 #暴露端口
ENV name=timinglee
ENTRYPOINT ["/bin/sh", "-c", "sleep 10000000"] #不可替代
CMD ["/bin/sh", "-c", "echo $NAME"] #CMD被替代
[root@Docker-node1 docker]# docker build -t busybox:v6 .
[root@Docker-node1 docker]# docker run -it --rm --name test busybox:v6
[root@Docker-node1 docker]# docker run -d --rm --name test busybox:v6
[root@Docker-node1 docker]# docker ps #看端口
[root@Docker-node1 docker]# docker stop test
[root@Docker-node1 docker]# vim Dockerfile
FROM busybox
RUN touch /leefile
LABEL Mail=lee@timinglee.org
COPY passwd /passwd
ADD zhuzhuxia.tar.gz /mnt
RUN mkdir /lee
EXPOSE 80 443
WORKDIR /mnt #工作目录
VOLUME /lee #目录挂载
[root@Docker-node1 docker]# docker build -t busybox:v6 .
[root@Docker-node1 docker]# docker run -it --rm --name test busybox:v6
[root@Docker-node1 docker]# docker inspect test #看"Mounts"的下面有没有目录/lee
5. Dockerfile实例
#清理容器
[root@node9 ~]# docker images
[root@node9 ~]# docker rmi <IMAGE ID>
[root@node9 ~]# docker rmi `docker images | awk '/none/{print $1}'`
[root@node9 ~]# docker rmi busybox:v{1..7}
#可以先拖入企业7镜像centos和nginx1.26软件包,提前下载。
[root@node9 ~]# docker load -i /mnt/centos-7
#建立构建目录,编写构建文件
[root@node9 ~]# mdkir docker
[root@node9 ~]# cd docker/
[root@node9 docker]# mv /nginx-1.26.1.tar.gz . #移动文件到当前。
[root@node9 docker]# vim Dockerfile
FROM centos:7
LABEL Mail=lee@timinglee.org
ADD /nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel
RUN ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80 443
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off"]
#通过dockerfile生成镜像
[root@node9 docker]# docker build -t nginx:v1
#出现仓库报错,添加一个rhel7.9镜像虚拟机。
#添加一个端口
[root@node9 docker]# yum install httpd -y
[root@node9 docker]# vim /etc/httpd/conf/httpd.conf
...
listen 8888
...
[root@node9 docker]# systemctl start httpd
#挂载端口
[root@node9 docker]# mkdir /var/www/html/rhel7.9
[root@node9 docker]# mount /dev/sr1 /var/www/html/rhel7.9
#查看ip
[root@node9 docker]# docker inspect centos:7
[root@node9 docker]# ping 172.17.0.2
#进入容器
[root@node9 docker]# docker run -it --name centos centos:7
cd /etc/yum.repos.d/
rm -fr *
vim centos7.repo
[centos7]
name=centos7
baseurl=http://172.17.0.1:8888/rhel7.9
gpgcheck=0
#将一个名为 “centos” 的容器创建一个新的镜像,并为新镜像添加注释信息 “add repo”,新镜像命名为 “centos:repo”
[root@node9 docker]# docker commit -m "add repo" centos centos:repo
[root@node9 docker]# docker rm centos
#修改配置文件
[root@node9 docker]# vim Dockerfile
FROM centos:repo
LABEL Mail=lee@timinglee.org
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel
RUN ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80 443
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off"]
#再一次生成镜像
[root@node9 docker]# docker build -t nginx:v1
#查看容器
[root@server1 docker]# docker images
6. 镜像优化方案
6.1. 镜像优化策略
-
选择最精简的基础镜像
-
减少镜像的层数
-
清理镜像构建的中间产物
-
选择最精简的基础镜像
-
减少镜像的层数
-
清理镜像构建的中间产物
6.2. 镜像优化示例:缩减镜像层
[root@node9 docker]# vim Dockerfile
FROM centos:repo
LABEL Mail=lee@timinglee.org
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module -- with-http_stub_status_module && make && make install && rm -fr nginx-
1.26.1 && yum clean all
EXPOSE 80 443
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off"] #CMD 是 Dockerfile 中的一个指令,用于定义容器启动时默认执行的命令。
["/usr/local/nginx/sbin/nginx", "-g", "daemon off"]:这是一个命令列表。其中,/usr/local/nginx/sbin/nginx 是启动 Nginx 服务器的命令路径。-g 是 Nginx 的全局配置指令参数,daemon off 表示以非守护进程模式运行 Nginx,即让 Nginx 在前台运行,这样容器就不会在启动 Nginx 后立即退出,而是保持运行状态直到容器被停止或者出现错误。
[root@node9 docker]# docker build -t nginx:v2 .
[root@node9 docker]# docker images nginx
[root@node9 docker]# vim Dockerfile
FROM centos:repo
LABEL Mail=lee@timinglee.org
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module -- with-http_stub_status_module && make && make install && rm -fr nginx-
1.26.1 && yum clean all
EXPOSE 80 443
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off"] #CMD 是 Dockerfile 中的一个指令,用于定义容器启动时默认执行的命令。
["/usr/local/nginx/sbin/nginx", "-g", "daemon off"]:这是一个命令列表。其中,/usr/local/nginx/sbin/nginx 是启动 Nginx 服务器的命令路径。-g 是 Nginx 的全局配置指令参数,daemon off 表示以非守护进程模式运行 Nginx,即让 Nginx 在前台运行,这样容器就不会在启动 Nginx 后立即退出,而是保持运行状态直到容器被停止或者出现错误。
[root@node9 docker]# docker build -t nginx:v2 .
[root@node9 docker]# docker images nginx
6.3. 镜像优化示例:多阶段构建
[root@node9 docker]# vim Dockerfile
FROM centos:repo AS build
ADD nginx-1.26.1.tar.gz /mnt
WORKDIR /mnt/nginx-1.26.1
RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --prefix=/usr/local/nginx --with-http_ssl_module -- with-http_stub_status_module && make && make install && rm -fr nginx-
1.26.1 && yum clean all
FROM centos:repo
LABEL Mail=lee@timinglee.org
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@node9 docker]# docker build -t nginx:v3 .
[root@node9 docker]# docker images nginx
6.4. 镜像优化示例:使用最精简镜像
使用google提供的最精简镜像
#下载地址:
https://github.com/GoogleContainerTools/distroless
#下载镜像:
docker pull gcr.io/distroless/base
#提前下载,直接拖入即可。
#利用最精简镜像构建
[root@node9 docker]# 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/