golang探索Docker镜像各层结构的工具插件dive的使用

Golang探索Docker镜像各层结构的工具插件dive的使用

简介

dive是一个用于探索Docker镜像、分析层内容并发现缩小Docker/OCI镜像大小方法的工具。

基本功能

  • 按层显示Docker镜像内容:选择左侧的层时,右侧会显示该层与之前所有层组合的内容
  • 指示每层的变化:显示文件树中已更改、修改、添加或删除的文件
  • 估算"镜像效率":左下角面板显示基本层信息和实验性指标,猜测镜像包含多少浪费空间
  • 快速构建/分析周期:可以使用一个命令构建Docker镜像并立即分析
  • CI集成:分析镜像并根据镜像效率和浪费空间获得通过/失败结果
  • 支持多种镜像源和容器引擎:通过--source选项选择从何处获取容器镜像

安装方法

Ubuntu/Debian

DIVE_VERSION=$(curl -sL "https://api.github.com/repos/wagoodman/dive/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
curl -fOL "https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.deb"
sudo apt install ./dive_${DIVE_VERSION}_linux_amd64.deb

RHEL/Centos

DIVE_VERSION=$(curl -sL "https://api.github.com/repos/wagoodman/dive/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
curl -fOL "https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.rpm"
rpm -i dive_${DIVE_VERSION}_linux_amd64.rpm

Mac (使用Homebrew)

brew install dive

Windows (使用Chocolatey)

choco install dive

Go工具安装

go install github.com/wagoodman/dive@latest

Docker方式

docker pull docker.io/wagoodman/dive
# 或
docker pull ghcr.io/wagoodman/dive

使用示例

分析现有镜像

dive <your-image-tag>
# 例如
dive nginx:latest

使用Docker直接运行

alias dive="docker run -ti --rm -v /var/run/docker.sock:/var/run/docker.sock docker.io/wagoodman/dive"
dive <your-image-tag>

构建镜像并立即分析

dive build -t <some-tag> .

在macOS上构建

docker run --rm -it \
      -v /var/run/docker.sock:/var/run/docker.sock \
      -v "$(pwd)":"$(pwd)" \
      -w "$(pwd)" \
      -v "$HOME/.dive.yaml":"$HOME/.dive.yaml" \
      docker.io/wagoodman/dive:latest build -t <some-tag> .

CI集成

CI=true dive <your-image>

CI配置示例

创建一个.dive-ci文件放在项目根目录:

rules:
  # 如果效率低于X%,标记为失败 (0-1之间的比率)
  lowestEfficiency: 0.95

  # 如果浪费空间大于等于X,标记为失败 (可用B, KB, MB, GB表示)
  highestWastedBytes: 20MB

  # 如果浪费空间占镜像的X%或更多,标记为失败 (0-1之间的比率)
  highestUserWastedPercent: 0.20

键绑定

按键绑定 描述
Ctrl+C 或 Q 退出
Tab 在层视图和文件树视图之间切换
Ctrl+F 过滤文件
ESC 关闭文件过滤器
PageUp 或 U 向上滚动一页
PageDown 或 D 向下滚动一页
Up 或 K 在页面内向上移动一行
Down 或 J 在页面内向下移动一行

UI配置示例

创建配置文件~/.dive.yaml

container-engine: docker
ignore-errors: false
log:
  enabled: true
  path: ./dive.log
  level: info

keybinding:
  quit: ctrl+c
  toggle-view: tab
  filter-files: ctrl+f, ctrl+slash
  close-filter-files: esc
  up: up,k
  down: down,j
  left: left,h
  right: right,l

diff:
  hide:
    - added
    - removed
    - modified
    - unmodified

filetree:
  collapse-dir: false
  pane-width: 0.5
  show-attributes: true

layer:
  show-aggregated-changes: false

dive会按以下顺序查找配置文件:

  1. $XDG_CONFIG_HOME/dive/*.yaml
  2. $XDG_CONFIG_DIRS/dive/*.yaml
  3. ~/.config/dive/*.yaml
  4. ~/.dive.yaml

也可以使用.yml扩展名代替.yaml


更多关于golang探索Docker镜像各层结构的工具插件dive的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang探索Docker镜像各层结构的工具插件dive的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


探索Docker镜像各层结构的工具Dive使用指南

Dive是一个强大的Docker镜像分析工具,它可以帮助开发者深入了解镜像的层结构、文件系统变化以及优化镜像大小。下面我将详细介绍如何使用Dive以及相关的Golang代码示例。

Dive安装

首先需要安装Dive工具:

# Linux
wget https://github.com/wagoodman/dive/releases/download/v0.10.0/dive_0.10.0_linux_amd64.deb
sudo apt install ./dive_0.10.0_linux_amd64.deb

# MacOS
brew install dive

# Windows
choco install dive

基本使用

分析一个Docker镜像:

dive <镜像名>:<标签>

例如:

dive golang:1.18

主要功能界面

Dive的界面分为三个主要部分:

  1. 左侧:镜像层(Layers)列表
  2. 中间:当前层文件系统变化
  3. 右侧:当前选中文件/目录的详细信息

常用快捷键

  • Tab:在层视图和文件视图之间切换
  • Ctrl + Space:折叠/展开所有目录
  • Ctrl + F:过滤文件
  • PageUp/PageDown:在层之间导航

Golang集成示例

如果你想在Golang程序中集成Dive的功能,可以使用Docker SDK来分析镜像层:

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		panic(err)
	}

	// 指定要分析的镜像
	imageName := "golang:1.18"

	// 获取镜像历史记录(层信息)
	history, err := cli.ImageHistory(context.Background(), imageName)
	if err != nil {
		fmt.Printf("获取镜像历史失败: %v\n", err)
		os.Exit(1)
	}

	fmt.Println("镜像层分析结果:")
	for i, layer := range history {
		fmt.Printf("层 %d:\n", len(history)-i-1) // Docker历史是倒序的
		fmt.Printf("  创建时间: %s\n", layer.Created)
		fmt.Printf("  大小: %.2f MB\n", float64(layer.Size)/1024/1024)
		fmt.Printf("  创建命令: %s\n", layer.CreatedBy)
		fmt.Println("----------------------------------------")
	}

	// 获取镜像详细配置
	img, _, err := cli.ImageInspectWithRaw(context.Background(), imageName)
	if err != nil {
		fmt.Printf("获取镜像详情失败: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("\n镜像总大小: %.2f MB\n", float64(img.Size)/1024/1024)
	fmt.Printf("层数: %d\n", len(img.RootFS.Layers))
}

高级用法

1. 分析并导出结果

dive <镜像名> --json | jq '.' > analysis.json

2. 设置CI集成

在CI中可以使用Dive来检查镜像是否满足某些标准:

dive <镜像名> --lowestEfficiency 0.9 --highestWastedBytes 1MB

如果镜像效率低于90%或浪费空间超过1MB,命令会返回非零退出码。

3. 构建时分析

可以在Docker构建时立即分析:

docker build -t my-image . && dive my-image

镜像优化建议

使用Dive分析后,你可以:

  1. 合并多个RUN指令减少层数
  2. 删除不必要的中间文件
  3. 使用多阶段构建
  4. 合理安排指令顺序,将变化频繁的指令放在后面

总结

Dive是优化Docker镜像的强大工具,通过可视化界面可以直观地看到每一层的变化和空间占用情况。结合Golang程序,你还可以实现自动化的镜像分析流程。

记住,优化Docker镜像不仅能减少存储和传输开销,还能提高安全性(减少攻击面)和构建速度。

回到顶部