镜像的分层结构
共享宿主机的kernel
base镜像提供的是最小的Linux发行版
同一docker主机支持运行多种Linux发行版
采用分层结构的最大好处是:共享资源
- Copy-on-Write 可写容器层
- 容器层以下所有镜像层都是只读的
- docker从上往下依次查找文件
- 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
一个镜像最多127层
镜像的构建
- docker commit 构建新镜像三部曲
运行容器
修改容器
将容器保存为新的镜像 - 缺点:
效率低、可重复性弱、容易出错
使用者无法对镜像进行审计,存在安全隐患 - 运行容器
docker run -it --name test busybox - 修改容器 (以下命令在容器内运行)
echo helloworld > testfile - 将容器保存为新的镜像
docker commit test test:v1 - 查看镜像
docker images test:v1
也可通过dockerfile文件来构建镜像
- 创建一个Dockerfile
- dockerfile 最佳实践
dockerfile常用指令
FROM
指定base镜像,如果本地不存在会从远程仓库下载。
MAINTAINER
设置镜像的作者,比如用户邮箱等。
COPY
把文件从build context复制到镜像
支持两种形式:COPY src dest 和 COPY [“src”, “dest”]
src必须指定build context中的文件或目录
ADD
用法与COPY类似,不同的是src可以是归档压缩文件,文件会被自动解压到dest,也可以自动下载URL并拷贝到镜像:
ADD html.tar /var/www
ADD http://ip/html.tar /var/www
ENV
设置环境变量,变量可以被后续的指令使用:
ENV HOSTNAME sevrer1.example.com
EXPOSE
如果容器中运行应用服务,可以把服务端口暴露出去:
EXPOSE 80
VOLUME
申明数据卷,通常指定的是应用的数据挂在点:
VOLUME ["/var/www/html"]
WORKDIR
为RUN、CMD、ENTRYPOINT、ADD和COPY指令设置镜像中的当前工
作目录,如果目录不存在会自动创建。
RUN
在容器中运行命令并创建新的镜像层,常用于安装软件包:
RUN yum install -y vim
CMD 与 ENTRYPOINT
这两个指令都是用于设置容器启动后执行的命令,但CMD会被
docker run后面的命令行覆盖,而ENTRYPOINT不会被忽略,一定会
被执行。
docker run后面的参数可以传递给ENTRYPOINT指令当作参数。
Dockerfile中只能指定一个ENTRYPOINT,如果指定了很多,只有最后
一个有效。
Shell和exec格式的区别
#cat Dockerfile
FROM busybox
ENV name world ENTRYPOINT
echo “hello, $name”
Shell格式底层会调用/bin/sh -c来执行命令,可以解析变量,而下面 的exec格式不会:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", “hello, $name”]
需要改写成以下形式:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", “-c”, “echo hello, $name”]
Exec格式时,ENTRYPOINT可以通过CMD提供额外参数,CMD的额外
参数可以在容器启动时动态替换。在shell格式时ENTRYPOINT会忽略
任何CMD或docker run提供的参数。
#cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", “hello”]
CMD [“world”]
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", “hello, $name”]
看下在运行容器时的区别:
#docker run --rm busybox:v1
hello world
#docker run --rm busybox:v1 linux
hello linux
推荐使用exec格式书写
- 构建镜像
- 查看镜像的分层结构
- 镜像的缓存特性
镜像的优化
选择最精简的基础镜像
减少镜像的层数
清理镜像构建的中间产物
注意优化网络请求
尽量去用构建缓存
使用多阶段构建镜像
实例分析:
减少镜像层数
查看重构后的镜像大小,比原来小了30MB
清理镜像构建的中间产物
查看重构后的镜像大小,又小了32MB
使用多阶段构建镜像
查看重构后的镜像大小,变成了144MB
选择最精简的基础镜像
查看重构后的镜像大小,只有23.5MB,所以在实际构建中尽量选
择最精简的base镜像。