10 ポイント 投稿者 GN⁺ 2024-01-09 | 1件のコメント | WhatsAppで共有
  • Diveは、Docker/OCIイメージのレイヤーとファイル内容を探索し、イメージサイズを削減できる余地を見つけるためのツール
  • イメージタグ・ID・ダイジェストを指定して dive <your-image-tag> を実行するか、dive build -t <some-tag> .ビルド直後の分析まで一度に実行できる
  • レイヤーを選択すると、そのレイヤーと前のレイヤーを結合したファイルツリーが表示され、追加・変更・削除されたファイルと累積変更をファイルツリーで確認できる
  • 実験的な image efficiency 指標により、重複ファイル、レイヤー間でのファイル移動、完全に削除されていないファイルによって発生した無駄な領域をスコアと総容量で推定する
  • CI=true でUIをスキップし、イメージ効率・無駄領域の基準に応じて pass/fail を返せるため、CIパイプラインでイメージサイズ管理を自動化できる

Diveができること

  • Diveは、Dockerイメージ、レイヤー内容、Docker/OCIイメージのサイズを削減する方法を探索するツール
  • 基本的な実行方法は、イメージタグ・ID・ダイジェストを渡す形式
    • dive <your-image-tag>
  • Dockerコンテナとして実行することもでき、その場合はDockerソケットをマウントする必要がある
    • docker.io/wagoodman/dive イメージを使用
    • 対象イメージの例として nginx:latest が示されている
  • イメージをビルドした直後に分析したい場合は、docker build の代わりに同じ形式の dive build コマンドを使える
    • dive build -t <some-tag> .
  • macOSでビルド分析をコンテナとして実行する方式は、Dockerコンテナエンジンのみをサポートする
  • プロジェクトの状態は beta quality で、新機能要望やバグは issue として提出できる

レイヤーとファイル変更の探索

  • 左側でレイヤーを選ぶと、右側にそのレイヤーと前のレイヤーを結合したファイルツリーが表示される
  • 方向キーでファイルツリーを移動できる
  • 各レイヤーで変更されたファイルの状態がファイルツリーに表示される
    • 変更あり
    • 修正済み
    • 追加済み
    • 削除済み
  • 変更表示の方式は、特定レイヤー基準またはそのレイヤーまでの累積変更基準に切り替えられる

イメージ効率と無駄領域の推定

  • 左下パネルには基本的なレイヤー情報と実験的な image efficiency 指標が表示される
  • この指標はイメージ内の無駄な領域を推定する
    • レイヤー間のファイル重複
    • レイヤー間でのファイル移動
    • 完全に削除されていないファイル
  • 結果は百分率の score と、無駄になったファイル領域の総量として提供される

CIで pass/fail 基準として利用

  • CI=true 環境変数を指定して実行すると、Dive UIをスキップしてイメージを分析し、終了コードとして pass/fail 結果を返す
  • リポジトリルートの .dive-ci ファイルで3つの基準を設定できる
    • lowestEfficiency: 効率が指定割合より低いと失敗
    • highestWastedBytes: 無駄領域が指定容量以上だと失敗
    • highestUserWastedPercent: ユーザーレイヤー基準の無駄割合が指定値以上だと失敗
  • highestUserWastedPercent の計算では、base image layer はイメージ全体サイズに含まれない
  • CI設定ファイルのパスは --ci-config オプションで上書きできる

イメージソースとコンテナエンジン

  • --source オプションで、コンテナイメージを取得する場所を選択できる
    • dive <your-image> --source <source>
    • dive <source>://<your-image>
  • サポートされる source オプションは以下の通り
    • docker: Docker engine、デフォルト
    • docker-archive: ディスク上の Docker Tar Archive
    • podman: Podman engine、Linuxのみ対応

インストールと実行方法

  • Ubuntu/Debian では .deb パッケージまたは Snap でインストールできる
  • Snap方式は Docker を apt-get でインストールした場合には推奨されず、既存の Docker daemon を壊す可能性があるという注意がある
  • RHEL/Centos では .rpm パッケージでインストールできる
  • Arch Linux では extra repository で提供されており、pacman でインストールできる
  • macOS では HomebrewMacPorts、または releases page の Darwin ビルドでインストールできる
  • Windows では Chocolateyscoopwinget、または releases page の Windows ビルドでインストールできる
  • Goツールとしてインストールするには Go 1.10 以上が必要
    • go install github.com/wagoodman/dive@latest
    • この方法でインストールすると、dive -v 実行時に正しいバージョンが表示されない
  • Nix/NixOS と x-cmd によるインストール方法も提供されている
  • Dockerイメージとして実行する場合は、Dockerソケットファイルを含める必要がある
    • -v /var/run/docker.sock:/var/run/docker.sock
  • ローカルの Docker バージョンによっては、DOCKER_API_VERSION=1.37 のような環境変数が必要になる場合がある
  • Colima のような代替ランタイムを使う場合、ローカルイメージを取得するために DOCKER_HOST 環境変数の指定が必要になることがある

操作とUI設定

  • 主なキーバインドでは、レイヤー表示とファイルツリー表示を切り替えながら、移動・フィルタリング・表示トグルを行える
    • Ctrl+C または Q: 終了
    • Tab: レイヤー表示とファイルツリー表示の切り替え
    • Ctrl+F: ファイルフィルタ
    • Ctrl+A: レイヤー表示では累積イメージ変更表示、ファイルツリー表示では追加ファイル表示のトグル
    • Ctrl+L: 現在のレイヤー変更表示
    • Ctrl+R, Ctrl+M, Ctrl+U: 削除・修正・変更なしファイルの表示トグル
    • Ctrl+B: ファイル属性表示のトグル
  • 個別設定は不要だが、YAML設定ファイルで値を上書きできる
  • 設定可能な項目には、コンテナエンジン、イメージアーカイブ解析エラーの無視可否、ログ、キーバインド、diff表示、ファイルツリー幅、ディレクトリのデフォルト折りたたみ状態、レイヤー累積変更表示が含まれる
  • 設定ファイルの検索場所は以下の通り
    • $XDG_CONFIG_HOME/dive/*.yaml
    • $XDG_CONFIG_DIRS/dive/*.yaml
    • ~/.config/dive/*.yaml
    • ~/.dive.yaml
  • .yaml の代わりに .yml 拡張子も使用できる

1件のコメント

 
GN⁺ 2024-01-09
Hacker News のコメント
  • イメージとレイヤーを扱うなら crane が優れていて、基盤ライブラリの go-containerregistry も良い
    既存イメージに新しいレイヤーを追加したり、メタデータ(env vars、labels、entrypoint など)を変更したりでき、複数レイヤーのイメージを単一レイヤーに「平坦化」することもできる
    また、変更内容を新しいベースイメージに再適用する「rebase」も可能で、これらすべてをレジストリ上で直接処理するため Docker は不要
    https://github.com/google/go-containerregistry/blob/main/cmd...

    • 良いおすすめ。Docker と違って crane は root もデーモンもなしで動作するので Nix で使いやすく、Nix リポジトリでも crane という名前で提供されている
      そのおかげで、Nix でビルド用の依存関係(例: Go)だけでなく、パッケージング・デプロイ用ツール(例: gnu tar、crane)まで一緒に管理できる
    • レイヤー数が少ないと性能面で利点があるのか気になる。イメージをまとめても全体サイズはそのままなので、レイヤーのマージ自体で得られるメリットはないと理解している
  • dive は、Docker イメージがどう動作するのか、効率的な Dockerfile をどう書くのかを理解するのに本当に役立った
    ドキュメントを読むことも重要だが、Dockerfile を変更した後に結果のレイヤー構造がどう変わるのかを直接見ることが、理解には決定的だった

  • Dive は素晴らしい。こうしたツールは、自分が正確に何をビルドしデプロイしているのかを学び、確信するうえで重要
    Dredge も見る価値のあるツールで、レイヤー差分を比較するときに使っている
    https://github.com/mthalman/dredge/blob/main/docs/commands/i...

  • 愚かな質問かもしれないが、なぜほとんどのコンテナ・インフラ系ツールが Go で書かれているのか気になる
    Docker、Podman、nerdctl、Terraform、Kubernetes が思い浮かぶが、こうしたツールを作るうえで Go が提供する明確な利点があるのか知りたい

    • Docker については答えられる。最初のプロトタイプは Python で書かれていて、会社も Python 中心だった
      Go で書き直した主な理由は、当時(2012年)伸びていた Go の人気に乗るためだった。その場にいた
    • Go はクロスコンパイルと配布が最も簡単な言語で、生産性に対する性能が高く、標準搭載の並行性が良く、標準ライブラリのネットワーキング機能も素晴らしい
      Docker と Kubernetes が別の人気言語で書かれていたと想像してみると、その違いが見えてくる
    • システムツール、ユーティリティ、コマンドラインツール、ネットワーキングソフトウェアは、Go が最も輝く領域だと思う
      成熟した現代的な代替としては Rust くらいしか見当たらない
    • Kubernetes が Go で書かれているのは、Google が Go を作り、Kubernetes も作ったから
      社内チームに Go エンジニアが多いのも同じ理由
    • コンテナを実行するときは、基盤システムのことをできるだけ気にしたくないし、Go は自分だけの小さな世界の中で動作しやすくしてくれる
      さらにエコシステム効果もあり、他の実装のパッケージをコードの一部にそのまま活用できる
  • Dive が好きで、月に何度もツールボックスから取り出して使っている
    ただ、選択したファイルの内容をすぐ見る方法があるのか気になる。レイヤー内にファイルが存在することを確認した後、その中身を見たいことが多いが、今はたいていコンテナを実行して cat を使うか、内容を抽出してからフォルダを探して入っている

    • 少し工夫すれば rsync でファイルにアクセスできるが、cat を使うのと大きくは変わらない
  • いくつもの公開 Docker コンテナを拡張するとき、中で何をしているのか調べる過程で Dive に何度も救われた
    本当に A+ 級のソフトウェア

  • dive のような優れたターミナル TUI ツールは他にもある。lazydocker と dry が思い浮かぶ
    Docker カテゴリにもいくつかある
    [0] https://terminaltrove.com/

    • Lazydocker にも似ているが、より単純な機能がある
      確認してみるとレイヤーは見られるが、各レイヤーのコマンドだけを表示する
  • Dive はコンテナ/Docker 領域で驚くべきツール。コンテナの中に実際に何が入っているのかをデバッグするのがずっと楽になる
    Depot [0] を始めた当初、イメージサイズを減らしビルドを速くする方法をよく質問されたので、Dive でその問題を解決する方法を短い記事 [1] にまとめた。今では少し古くなっているかもしれないが、誰かの役に立つかもしれない
    Dive に着想を得て、各ビルドごとにビルドコンテキストの中に実際に何があるのかもより簡単に見えるようにし、数週間前に Depot の機能としてリリースした
    [0] https://depot.dev
    [1] https://depot.dev/blog/reducing-image-size-with-dive
    [2] https://depot.dev/blog/build-context

  • Dive には非常に便利なこと以外にも、過小評価されている長所がある。作者が素晴らしい開発者で、一緒に仕事をするのが本当に楽しい人だということ

  • Google の container-diff というツールも本当に便利
    bash にパイプして実行するよう勧められている任意のスクリプトが、システムに何をするのか確認するときに使っている

    • 一般的なコンテナユーティリティとは少し関係が薄いが、GoogleContainerTools/container-structure-test を熱心に使っている
      コンテナアプリやイメージに統合テストを実行するのに便利な方法
      こうした Google のオープンソースプロジェクトは、元々管理していた人たちが多く去ってしまい、手が必要なようで残念。可能なときは PR を送り、時々 issue も閉じるようにしている。特にこのテストツールは、社内で維持しなければならない多数のベースイメージを扱う際に正気を保つうえで非常に貴重