In this article, we will look into an open source tool called Dive which is used for analyzing docker image and layering its contents. This tool has the capability to show docker image contents broken down into layers. Dive with another tool called Jib is ideal for a situation where you have bunch of applications running on microservices environment. If your application image size is quite big then restarting the container or pods takes huge toll on your network bandwidth as it has to download the entire image from repository every time you restart your container or deployment or pods.
Using dive with Jib tool gives you the capability to deal with this situation as Jib has the ability to break down the application components and cache all those dependencies which does not often change. This saves a lot of application bandwidth and hence improves app recycling time which in turn reduces the impact. We will see more about its usage in upcoming articles. Here we will go through the installation and capabilities dive provides in analyzing the docker images.
Some Basic Features
To summarize, some of its basic feature includes:-
- Breaking down of docker image to multiple layers
- Indicating the modified files in File Tree
- Building and analyzing docker images using a simple command
- Estimating and analyzing Image efficiency
- Support of Multiple Image Sources and Container Engines
Dive: A tool to Analyze Docker Image and Layer Contents
Also Read: Why Harbor Auth Mode showing Disabled ?
As a prerequisite, you need to have wget
or curl
utility available in your system. To install this tool on Ubuntu/Debian based systems, you can just download it from GitHub using wget or curl utility as shown below.
cyberithub@ubuntu:~$ wget https://github.com/wagoodman/dive/releases/download/v0.9.2/dive_0.9.2_linux_amd64.deb
--2022-09-14 20:29:32-- https://github.com/wagoodman/dive/releases/download/v0.9.2/dive_0.9.2_linux_amd64.deb
Resolving github.com (github.com)... 20.207.73.82
Connecting to github.com (github.com)|20.207.73.82|:443... connected.
Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/133251103/5db79280-4b50-11ea-8123-47efdc093285?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220914%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220914T145932Z&X-Amz-Expires=300&X-Amz-Signature=1073696e03ed4588aaa4c97f38694def7e5f3794730f762f0b113c2552e7ed82&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=133251103&response-content-disposition=attachment%3B%20filename%3Ddive_0.9.2_linux_amd64.deb&response-content-type=application%2Foctet-stream [following]
--2022-09-14 20:29:32-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/133251103/5db79280-4b50-11ea-8123-47efdc093285?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20220914%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220914T145932Z&X-Amz-Expires=300&X-Amz-Signature=1073696e03ed4588aaa4c97f38694def7e5f3794730f762f0b113c2552e7ed82&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=133251103&response-content-disposition=attachment%3B%20filename%3Ddive_0.9.2_linux_amd64.deb&response-content-type=application%2Foctet-stream
Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.108.133, ...
Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 4765140 (4.5M) [application/octet-stream]
Saving to: ‘dive_0.9.2_linux_amd64.deb’
dive_0.9.2_linux_amd64.deb 100%[============================================================================>] 4.54M 1.77MB/s in 2.6s
2022-09-14 20:29:35 (1.77 MB/s) - ‘dive_0.9.2_linux_amd64.deb’ saved [4765140/4765140]
Once downloaded, you can install it by using sudo apt install ./dive_0.9.2_linux_amd64.deb
command as shown below.
cyberithub@ubuntu:~$ sudo apt install ./dive_0.9.2_linux_amd64.deb [sudo] password for cyberithub: Reading package lists... Done Building dependency tree Reading state information... Done Note, selecting 'dive' instead of './dive_0.9.2_linux_amd64.deb' The following NEW packages will be installed: dive 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 0 B/4,765 kB of archives. After this operation, 12.4 MB of additional disk space will be used. Get:1 /home/cyberithub/dive_0.9.2_linux_amd64.deb dive amd64 0.9.2 [4,765 kB] Selecting previously unselected package dive. (Reading database ... 230525 files and directories currently installed.) Preparing to unpack .../dive_0.9.2_linux_amd64.deb ... Unpacking dive (0.9.2) ... Setting up dive (0.9.2) ...
In the similar way, you can install this tool on other Linux based systems as well. To verify the current installed version, you can use dive --version
command as shown below.
cyberithub@ubuntu:~$ dive --version dive 0.9.2
After successful installation, you can use the tool to analyze the image using dive <tag/id/digest>
command. Here we are analyzing python
docker image by using dive python
command as shown below.
cyberithub@ubuntu:~$ dive python
Image Source: docker://python
Fetching image... (this can take a while for large images)
Handler not available locally. Trying to pull 'python'...
Using default tag: latest
latest: Pulling from library/python
23858da423a6: Pull complete
326f452ade5c: Pull complete
a42821cd14fb: Pull complete
8471b75885ef: Pull complete
8ffa7aaef404: Pull complete
15132af73342: Pull complete
aaf3b07565c2: Pull complete
736f7bc16867: Pull complete
94da21e53a5b: Pull complete
Digest: sha256:fc1317aa13ce8f97e513dc55dff468ab98a806e8b21d61d1e1e3460ebb334278
Status: Downloaded newer image for python:latest
docker.io/library/python:latest
Analyzing image...
Building cache...
┃ ● Layers ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │ Current Layer Contents ├────────────────────────────────────────────────────
Cmp Size Command Permission UID:GID Size Filetree
69 MB FROM c58e66ca80f6e13 drwxr-xr-x 0:0 4.9 MB ├── bin
7.1 MB set -eux; apt-get update; apt-get install -y --no-install-recomm -rwxr-xr-x 0:0 1.2 MB │ ├── bash
29 MB set -eux; savedAptMark="$(apt-mark showmanual)"; apt-get update -rwxr-xr-x 0:0 44 kB │ ├── cat
0 B set -eux; for src in idle3 pydoc3 python3 python3-config; do ds -rwxr-xr-x 0:0 64 kB │ ├── chgrp
11 MB set -eux; savedAptMark="$(apt-mark showmanual)"; apt-get update -rwxr-xr-x 0:0 64 kB │ ├── chmod
-rwxr-xr-x 0:0 72 kB │ ├── chown
│ Layer Details ├───────────────────────────────────────────────────────────── -rwxr-xr-x 0:0 147 kB │ ├── cp
-rwxr-xr-x 0:0 122 kB │ ├── dash
Tags: (unavailable) -rwxr-xr-x 0:0 109 kB │ ├── date
Id: c58e66ca80f6e13925db367086a54827f262fe7c22d1fd4e6585844d5dc629df -rwxr-xr-x 0:0 77 kB │ ├── dd
Digest: sha256:e06e631d87d6fc3c91d07f74daac9737a5a1ea33497c41efd61cb6711fec77a -rwxr-xr-x 0:0 94 kB │ ├── df
2 -rwxr-xr-x 0:0 139 kB │ ├── dir
Command: -rwxr-xr-x 0:0 84 kB │ ├── dmesg
#(nop) ADD file:782d864aa72c2d5fb599311ebae56db4067d2e91ff532c1aaf1a291c3dbce5 -rwxrwxrwx 0:0 0 B │ ├── dnsdomainname → hostname
bb in / -rwxrwxrwx 0:0 0 B │ ├── domainname → hostname
-rwxr-xr-x 0:0 40 kB │ ├── echo
│ Image Details ├───────────────────────────────────────────────────────────── -rwxr-xr-x 0:0 28 B │ ├── egrep
-rwxr-xr-x 0:0 35 kB │ ├── false
-rwxr-xr-x 0:0 28 B │ ├── fgrep
Total Image size: 117 MB -rwxr-xr-x 0:0 69 kB │ ├── findmnt
Potential wasted space: 6.8 MB -rwxr-xr-x 0:0 199 kB │ ├── grep
Image efficiency score: 95 % -rwxr-xr-x 0:0 2.3 kB │ ├── gunzip
-rwxr-xr-x 0:0 6.4 kB │ ├── gzexe
Count Total Space Path -rwxr-xr-x 0:0 98 kB │ ├── gzip
4 3.1 MB /var/cache/debconf/templates.dat -rwxr-xr-x 0:0 27 kB │ ├── hostname
3 2.3 MB /var/cache/debconf/templates.dat-old -rwxr-xr-x 0:0 69 kB │ ├── ln
4 322 kB /var/lib/dpkg/status -rwxr-xr-x 0:0 57 kB │ ├── login
4 322 kB /var/lib/dpkg/status-old -rwxr-xr-x 0:0 139 kB │ ├── ls
3 243 kB /var/log/dpkg.log -rwxr-xr-x 0:0 109 kB │ ├── lsblk
2 234 kB /lib/x86_64-linux-gnu/libz.so.1.2.11 -rwxr-xr-x 0:0 89 kB │ ├── mkdir
3 95 kB /var/log/apt/term.log -rwxr-xr-x 0:0 68 kB │ ├── mknod
4 54 kB /var/cache/debconf/config.dat -rwxr-xr-x 0:0 44 kB │ ├── mktemp
4 29 kB /etc/ld.so.cache -rwxr-xr-x 0:0 43 kB │ ├── more
...........................................................
You can fully explore the above shown file tree by using arrow keys. Press Ctrl+C
to exit the prompt.
Below are the important key bindings you can use with the dive
tool.
Key Binding | Description |
Ctrl + C | Exit |
Tab | Switch between the layer and filetree views |
Ctrl + F | Filter files |
PageUp | Scroll up a page |
PageDown | Scroll down a page |
Ctrl + A | Layer view: see aggregated image modifications |
Ctrl + L | Layer view: see current layer modifications |
Space | Filetree view: collapse/uncollapse a directory |
Ctrl + Space | Filetree view: collapse/uncollapse all directories |
Ctrl + R | Filetree view: show/hide removed files |
Ctrl + M | Filetree view: show/hide modified files |
Ctrl + U | Filetree view: show/hide unmodified files |
Ctrl + B | Filetree view: show/hide file attributes |
You can also build your image and analyze it by using below command.
dive build -t <some-tag> .
You can also think to run this in your CI pipeline to ensure you're keeping wasted space to a minimum (this skips the UI):
CI=true dive <your-image>
To know more about all the available options with dive, you can do dive --help
as shown below.
cyberithub@ubuntu:~$ dive --help
This tool provides a way to discover and explore the contents of a docker image. Additionally the tool estimates
the amount of wasted space and identifies the offending files from the image.
Usage:
dive [IMAGE] [flags]
dive [command]
Available Commands:
build Builds and analyzes a docker image from a Dockerfile (this is a thin wrapper for the `docker build` command).
help Help about any command
version print the version number and exit (also --version)
Flags:
--ci Skip the interactive TUI and validate against CI rules (same as env var CI=true)
--ci-config string If CI=true in the environment, use the given yaml to drive validation rules. (default ".dive-ci")
--config string config file (default is $HOME/.dive.yaml, ~/.config/dive/*.yaml, or $XDG_CONFIG_HOME/dive.yaml)
-h, --help help for dive
--highestUserWastedPercent string (only valid with --ci given) highest allowable percentage of bytes wasted (as a ratio between 0-1), otherwise CI validation will fail. (default "0.1")
--highestWastedBytes string (only valid with --ci given) highest allowable bytes wasted, otherwise CI validation will fail. (default "disabled")
-j, --json string Skip the interactive TUI and write the layer analysis statistics to a given file.
--lowestEfficiency string (only valid with --ci given) lowest allowable image efficiency (as a ratio between 0-1), otherwise CI validation will fail. (default "0.9")
--source string The container engine to fetch the image from. Allowed values: docker, podman, docker-archive (default "docker")
-v, --version display version number