docker详解介绍+基础操作 (四)容器镜像
Docker 镜像是 Docker 技术的核心组成部分之一,它用于封装应用程序及其依赖项,以便在任何支持 Docker 的环境中运行。当构建一个新的镜像时,Docker 会根据 Dockerfile 中的指令逐层构建。dive 是一个用于探索和分析 Docker 镜像的工具,可以帮助你理解镜像的每一层,并优化镜像构建过程。启动 dive 后,你可以逐层查看镜像的构建过程,发现哪些层占用了较多的空间
一.镜像结构和原理
Docker 镜像是 Docker 技术的核心组成部分之一,它用于封装应用程序及其依赖项,以便在任何支持 Docker 的环境中运行。了解 Docker 镜像的结构和原理对于有效使用 Docker 至关重要。以下是对 Docker 镜像结构和原理的详细介绍。
Docker 镜像的结构
1. 层(Layers)
Docker 镜像是由多个层(layers)组成的。每个层代表了一个文件系统的快照。这些层是只读的,每个层都基于前一层,形成一个堆栈。当构建一个新的镜像时,Docker 会根据 Dockerfile 中的指令逐层构建。
基础层:通常是一个操作系统的基础镜像,如 ubuntu:20.04。
中间层:包含应用程序的依赖项和配置。
顶层:包含应用程序本身。
2. 工作原理
Union File System (UnionFS):Docker 使用 UnionFS 将多个层合并为一个文件系统。UnionFS 允许文件系统中的文件和目录位于多个不同的物理位置,但在用户看来是一个统一的整体。
只读层:每个层都是只读的,这意味着一旦层被创建,就不能被修改。
写时复制(Copy-on-Write):当容器启动时,Docker 会在最顶层添加一个可写层,称为容器层。这个层允许对文件系统进行读写操作。如果某个文件被修改,实际上是在容器层中创建一个新文件,而原始文件保持不变。
Docker 镜像的构建
1. Dockerfile
Dockerfile 是一个文本文件,包含了一系列指令,用于自动构建 Docker 镜像。每个指令都会创建一个新的层。
例如,一个简单的 Dockerfile 可能如下所示:
Dockerfile
使用官方的 Node.js 运行时作为父镜像
FROM node:14
设置工作目录
WORKDIR /app
将当前目录的内容复制到工作目录中
COPY . /app
安装应用程序的依赖
RUN npm install
构建应用程序
RUN npm run build
暴露端口
EXPOSE 3000
启动应用程序
CMD ["npm", "start"]
2. 构建过程
解析 Dockerfile:Docker 读取 Dockerfile 并解析其中的指令。
创建基础层:根据 FROM 指令创建基础层。
逐层构建:根据后续的指令逐层构建镜像。
- COPY 和 ADD 指令会将文件复制到镜像中,创建新的层。
- RUN 指令会执行命令,创建新的层。
- ENV 指令会设置环境变量,创建新的层。
- EXPOSE 指令会暴露端口,但不会创建新的层。
- CMD 和 ENTRYPOINT 指令会设置容器启动时的默认命令,但不会创建新的层。
3. 缓存机制
Docker 在构建镜像时会使用缓存机制来加速构建过程。如果某个指令之前已经执行过,并且其上下文没有发生变化,Docker 会直接使用缓存的层,而不是重新执行该指令。
Docker 镜像的存储
1. 镜像存储
Docker 镜像存储在 Docker 守护进程的本地存储中,默认情况下位于 /var/lib/docker 目录下。每个镜像的层都存储在 overlay2 或 aufs 子目录中,具体取决于使用的存储驱动。
2. 镜像压缩
Docker 镜像在存储和传输时会被压缩,以节省空间和带宽。每个层都会被单独压缩,并且可以独立下载和验证。
二.Docker 镜像的使用
1. 拉取镜像
从 Docker Hub 或其他注册表拉取镜像:
docker pull ubuntu:20.04
2. 列出本地镜像
查看本地已有的镜像:
docker images
3. 删除镜像
删除本地镜像:
docker rmi ubuntu:20.04
三.优化 Docker 镜像
1. 减少层的数量
合并 RUN 指令:将多个 RUN 指令合并为一个,以减少镜像层数。
Dockerfile
RUN apt-get update && apt-get install -y \
package1 \
package2 \
&& rm -rf /var/lib/apt/lists/*
2. 清理临时文件
在 RUN 指令中删除不必要的文件和缓存:
Dockerfile
RUN apt-get update && apt-get install -y package && rm -rf /var/lib/apt/lists/*
3. 使用多阶段构建
将构建过程分为多个阶段,只将最终所需的文件复制到最终镜像中:
Dockerfile
第一阶段:构建
FROM node:14 as builder
WORKDIR /app
COPY . /app
RUN npm install
RUN npm run build
第二阶段:运行
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app/dist /app
CMD ["node", "app.js"]
4. 使用较小的基础镜像
选择较小的基础镜像,如 alpine,以减少镜像大小:
Dockerfile
FROM alpine:3.14
优化镜像工具dive
dive 是一个用于探索和分析 Docker 镜像的工具,可以帮助你理解镜像的每一层,并优化镜像构建过程。通过 dive,你可以查看每层添加了哪些文件,以及每层的大小,从而更好地管理镜像的大小和内容
安装 dive
使用 Docker 安装
docker pull wagoodman/dive:latest
使用包管理器安装
Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y dive
CentOS/RHEL
sudo yum install epel-release
sudo yum install dive
macOS (使用 Homebrew)
brew install dive
基本用法
启动 dive
你可以使用 dive 分析现有的 Docker 镜像或构建新的镜像。
分析现有镜像
dive <image-name-or-id>
例如,分析名为 my-image 的镜像:
dive my-image
构建新镜像并分析
dive build -t <image-name> .
例如,构建并分析名为 my-image 的镜像:
dive build -t my-image .
dive 界面
启动 dive 后,你会进入一个基于 TUI(Text User Interface)的界面,其中包含多个视图和操作选项。
主界面
主界面分为两个主要部分:
1. 左侧面板:显示镜像的每一层及其元数据。
2. 右侧面板:显示当前选中层的详细信息。
常用操作
- 上下箭头:在层之间导航。
- Enter:进入当前选中层的详细视图。
- q:退出 dive。
- h:显示帮助信息。
详细视图
选择一个层后,dive 会显示该层的详细信息,包括:
- 命令:构建该层时执行的 Dockerfile 命令。
- 大小:该层的大小。
- 文件变化:该层相对于前一层的文件变化,包括新增、删除和修改的文件。
- 环境变量:该层中设置的环境变量。
- 标签:该层中设置的标签。
- 历史记录:该层的历史记录。
优化镜像
通过 dive,你可以发现以下几种优化镜像的方法:
1. 减少层的数量:合并多个 RUN 命令,减少镜像层数。
2. 清理临时文件:在 RUN 命令中删除不必要的文件和缓存。
3. 使用多阶段构建:将构建过程分为多个阶段,只将最终所需的文件复制到最终镜像中。
4. 使用较小的基础镜像:选择较小的基础镜像,如 alpine,以减少镜像大小。
示例
假设你有一个简单的 Dockerfile:
Dockerfile
使用官方的 Node.js 运行时作为父镜像
FROM node:14
设置工作目录
WORKDIR /app
将当前目录的内容复制到工作目录中
COPY . /app
安装应用程序的依赖
RUN npm instal
构建应用程序
RUN npm run build
暴露端口
EXPOSE 3000
启动应用程序
CMD ["npm", "start"]
你可以使用 dive 构建并分析这个镜像:
dive build -t my-node-app .
启动 dive 后,你可以逐层查看镜像的构建过程,发现哪些层占用了较多的空间,并进行相应的优化。
更多推荐
所有评论(0)