Dockerイメージ調査ツールDiveを試してみる

はじめに

Dockerのイメージを調査するツールとしてDiveというツールがあるのを知り試してみようと思います。

何ができるか?

Diveでは主に以下のようなことができます。

  • イメージ層ごとのコンテンツの調査
  • それぞれのイメージのレイヤーの差分
  • イメージの効率の見積もり
  • ビルドと調査のサイクルの高速化
  • CIインテグレーション

ここでは羅列のみにとどめ、いくつかの機能の詳細は後ほどまとめようと思います。

環境

動作環境は以下の通り

$ uname -srvmpio
Linux 5.4.0-45-generic #49-Ubuntu SMP Wed Aug 26 13:38:52 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

$ lsb_release -a
LSB Version:    core-11.1.0ubuntu2-noarch:security-11.1.0ubuntu2-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.1 LTS
Release:    20.04
Codename:   focal

$ docker version
Client: Docker Engine - Community
 Version:           19.03.12
 API version:       1.40
 Go version:        go1.13.10
 Git commit:        48a66213fe
 Built:             Mon Jun 22 15:45:36 2020
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.12
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.10
  Git commit:       48a66213fe
  Built:            Mon Jun 22 15:44:07 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.13
  GitCommit:        7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

インストール

公式にしたがってインストールしていきます。
Ubuntuでは以下の2つのコマンドでインストールします。

$ wget https://github.com/wagoodman/dive/releases/download/v0.9.2/dive_0.9.2_linux_amd64.deb
$ sudo apt install ./dive_0.9.2_linux_amd64.deb

MacではBrewでインストールできます。

$ brew install dive

WindowsではGoのツールを使ってインストールします。
この際Goのバージョンは1.10以上である必要があります。

$ go get github.com/wagoodman/dive

使ってみる

早速使ってみます。

調査するイメージ

まずは調査するイメージをPullして置きます。

$ docker pull nginx

Diveの起動

まず、Diveコマンドでは、レイヤーごとに追加される内部のコンテンツを調査することができます。
以下のコマンドで

$ dive <tag or id or digest>

今回の場合は以下のようにNginxの調査を始めます。

$ dive nginx

f:id:yuya_hirooka:20200909204034p:plain

画面の右側のLayersと書かれた部分はイメージのレイヤーの一覧が表示されており、右側のAggregated Layer ContentsではLayersで選択されたイメージレイヤに含まれるコンテンツが表示されています。

キーバインド(操作方法)

まずは、Diveの操作を以下にまとめます。

キー 説明
Ctrl + C プログラムの終了
Tab ファイルツリーとイメージレイヤーの切り替え
Ctrl + f ファイルのフィルター
PageUp ページのスクロースアップ
PageDown ページのスクロールダウン
Ctrl + a Leyer View: 集約されたイメージの修正
Ctrl + l Layer view: 現在のレイヤーでの修正
Space Filetree view: ディレクトリの開閉
Ctrl + Space Filetree view: すべてのディレクトリの開閉
Ctrl + a Filetree view: 追加されたファイルの表示、非表示切り替え
Ctrl + r Filetree view: 削除されたファイルの表示、非表示
Ctrl + m Filetree view: 修正されたファイルの表示、非表示
Ctrl + u Filetree view: 未修正のファイルの表示、非表示
Ctrl + b Filetree view: ファイルのアトリビュート(修正日時、権限等)の表示、非表示
PageUp Filetree view: ページのスクロースアップ
PageDown Filetree view: ページのスクロールダウン

機能の詳細説明

前述の機能をいくつか細かく説明しようと思います。

イメージの層ごとのコンテンツの調査

f:id:yuya_hirooka:20200909221148p:plain

前述した画面左側イメージの一覧の1つを選択すると、右側にそのイメージの下地となっているすべてイメージのコンテンツが表示されます。
また、ファイルツリーの画面では方向キーでファイルツリーの探索を行なうことができます。

それぞれのイメージのレイヤーの差分

f:id:yuya_hirooka:20200909220746p:plain

ファイルツリーの中で、修正、追加、削除されたファイルを色の違いでみることができます。
また、コマンド(操作方法)のところでまとめているショートカットを使えばそれらのファイルの表示非表示を切り替えることができます。

イメージの効率の見積もり

f:id:yuya_hirooka:20200909221649p:plain

左下のパネルでは、イメージの基本情報とイメージ内のスペースの無駄がスコア化されたものが表示されれます。このスコアはレイヤー間で重複したファイル、レイヤー間で動かされたファイル、完全に削除されていないファイルなどを用いて計算されています。

ビルドと調査のサイクルの高速化

以下のコマンドを実行することで、イメージのビルドと調査の実行を1ステップで行なうことができます。単にdockerのビルドコマンドをdiveで置き換えるだけです。

$ dive build -t <some-tag> . 

CIインテグレーション

イメージの解析を実行し、イメージ効率と無駄スペースに基づいて成功と失敗の結果を出力することができます。単にdiveコマンドの環境変数CI=trueをセットすることでこのCIモードで実行されます。
以下のような.dive-ciファイルを自身のリポジトリのルートに配置することでCIモードの設定を行なうことができます。

rules:
  # イメージ効率が X%を下回ると失敗として結果が出力されます。  
  #  0-1のレイトで値を設定します。
  lowestEfficiency: 0.95

  #もし、無駄スペースの合計が、最低限X、もしくは、Xより大きい場合に失敗の結果が出力されます。
  #  B、KB、MB、GBなどの表現を用いることができます。  
  highestWastedBytes: 20MB

  # もし、無駄スペースの比率がX%を超えるか、もしくは、イメージより大きくなった場合失敗が出力されます。
  #  このときベースのイメージレイヤーはトータルのサイズとしてカウントされません。
  #  0-1のレイトで値を設定します。しきい値以上になった場合失敗として結果が出力されます。
  highestUserWastedPercent: 0.20

参考資料