これは、なにをしたくて書いたもの?
Dockerコンテナ内で解析などの作業をする必要が出た時に、コマンドなどが入っていないDockerイメージが相手の場合は
どうすればいい?という時の選択肢のひとつとして、BusyBoxが使えそうな気がしたので。
Case
例えば、以下のようにDebianのDockerイメージを使った時に、デフォルトではpsやmpstatなど、調べものをする際に
使いたいコマンドが入っていません。
$ docker container run -it --rm --name debian debian:stretch root@f28f50fe47ca:/# ps bash: ps: command not found root@f28f50fe47ca:/# wget bash: wget: command not found root@f28f50fe47ca:/# mpstat bash: mpstat: command not found
もちろん、「docker container exec」でコンテナ内に入り、aptなどでインストールするのもありです。
$ docker container exec -it debian bash # apt update -y # apt install sysstat -y
実行可能なコマンドを見つけてきて、「docker container cp」でコンテナ内に放り込むのも良いでしょう。
しかし、Distrolessのようなシェルすら入っていないDockerイメージの場合は、それも困難です。
こういうケースでは、BusyBoxを覚えておくと役に立ちそうだな、と。
BusyBox
BusyBoxとは、Aboutページによると「多くの一般的なUnixユーティリティを小さな実行可能ファイルにまとめたもの」だそうです。
BusyBoxを使うと、単独で実行可能なコマンド、もしくはコマンドをまとめたバイナリを単独で使うことができます。
Aboutページを見ると、「組み込みLinuxのスイスアーミーナイフ」だとか。
ちなみに、Dockerイメージとして提供されているのと
Alpine Linuxでも利用されているようです。
BusyBoxを使ってみる
それでは、試してみましょう。
今回利用するBusyBoxは、1.30.0とします。
ダウンロードは、こちらから対象のバージョン、必要なバイナリをダウンロードします。
まずは、対象としてDebianのコンテナを起動しておきます。
$ docker container run -it --rm --name debian debian:stretch
ここに、BusyBoxからPSコマンドをダウンロードして、実行権限を付与します。
$ wget https://busybox.net/downloads/binaries/1.30.0-i686/busybox_PS $ chmod a+x busybox_PS
あとはこちらを、コンテナ内の「/usr/local/bin」にでも放り込んであげましょう。このあたりに置けば、PATHが通っているので
便利かなと。
$ docker container cp busybox_PS debian:/usr/local/bin
すると、コンテナ内でこのコマンドが利用できるようになります。
root@eeab426fb585:/# busybox_PS
PID USER TIME COMMAND
1 root 0:00 bash
6 root 0:00 busybox_PS
wgetの場合。
$ wget https://busybox.net/downloads/binaries/1.30.0-i686/busybox_WGET $ chmod a+x busybox_WGET $ docker container cp busybox_WGET debian:/usr/local/bin
wgetを使って、コンテナ内でBusyBoxの他のコマンドをダウンロード。
# busybox_WGET -q https://busybox.net/downloads/binaries/1.30.0-i686/busybox_CHMOD Connecting to busybox.net (140.211.167.122:443) wget: note: TLS certificate validation not implemented busybox_CHMOD 100% |***********************************************************************************************************************************| 36780 0:00:00 ETA
対象のDockerイメージ内にシェルすらない場合は、ashを使えば良いでしょう。
$ wget https://busybox.net/downloads/binaries/1.30.0-i686/busybox_ASH $ chmod a+x busybox_ASH $ docker container cp busybox_ASH debian:/usr/local/bin
これで、シェルがないコンテナでもashで入れるようになります。
$ docker container exec -it debian busybox_ASH / #
良さそうですが、通常のコマンドと比べるとオプションが少なかったりするので、それなりに制限はありそうです。
# busybox_WGET -h
Usage: wget [-c|--continue] [--spider] [-q|--quiet] [-O|--output-document FILE]
[--header 'header: value'] [-Y|--proxy on/off] [-P DIR]
[-S|--server-response] [-U|--user-agent AGENT] [-T SEC] URL...
Retrieve files via HTTP or FTP
--spider Only check URL existence: $? is 0 if exists
-c Continue retrieval of aborted transfer
-q Quiet
-P DIR Save to DIR (default .)
-S Show server response
-T SEC Network read timeout is SEC seconds
-O FILE Save to FILE ('-' for stdout)
-U STR Use STR for User-Agent header
-Y on/off Use proxy
とはいえ、即席としてはやはり便利ですね。
全部入りのバイナリを使う
ここまでは、単一のコマンドを使用してきましたが、「busybox」というバイナリを使えば、BusyBoxで使えるコマンドが
全部入りのものとして利用することができます。
$ wget https://busybox.net/downloads/binaries/1.30.0-i686/busybox $ chmod a+x busybox $ docker container cp busybox debian:/usr/local/bin
コマンドを実行すると、利用できるコマンドの一覧が表示されます。
# busybox
BusyBox v1.30.0 (2018-12-30 22:25:27 CET) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list[-full]
or: busybox --show SCRIPT
or: busybox --install [-s] [DIR]
or: function [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as.
Currently defined functions:
[, [[, acpid, add-shell, addgroup, adduser, adjtimex, ar, arch, arp, arping, ash, awk, base64, basename, bc, blkdiscard, blkid, blockdev, bootchartd, brctl, bunzip2,
bzcat, bzip2, cal, cat, chat, chattr, chgrp, chmod, chown, chpasswd, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, conspy, cp, cpio, crond, crontab, cryptpw,
cttyhack, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname, dos2unix, dpkg, dpkg-deb, du,
dumpkmap, dumpleases, echo, ed, egrep, eject, env, envdir, envuidgid, expand, expr, factor, fakeidentd, false, fatattr, fbset, fbsplash, fdflush, fdformat, fdisk,
fgconsole, fgrep, find, findfs, flash_eraseall, flash_lock, flash_unlock, flashcp, flock, fold, free, freeramdisk, fsck, fsck.minix, fsfreeze, fstrim, fsync, ftpd,
ftpget, ftpput, fuser, getopt, getty, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hexedit, hostid, hostname, httpd, hush, hwclock, i2cdetect, i2cdump,
i2cget, i2cset, id, ifconfig, ifenslave, ifplugd, inetd, init, inotifyd, insmod, install, ionice, iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, ipneigh, iproute,
iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, last, less, link, linux32, linux64, linuxrc, ln, loadfont, loadkmap, logger, login, logname, losetup, lpd,
lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsscsi, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs,
mkfifo, mkfs.ext2, mkfs.minix, mkfs.vfat, mknod, mkpasswd, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mt, mv, nameif, nbd-client, nc, netstat,
nice, nl, nmeter, nohup, nologin, nproc, ntpd, nuke, od, openvt, partprobe, passwd, paste, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap,
popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readlink, readprofile, realpath, reboot, reformime,
remove-shell, renice, reset, resize, resume, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-init, run-parts, runlevel, runsv, runsvdir, rx, script,
scriptreplay, sed, sendmail, seq, setarch, setconsole, setfattr, setfont, setkeycodes, setlogcons, setpriv, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha3sum,
sha512sum, showkey, shred, shuf, slattach, sleep, smemcap, softlimit, sort, split, ssl_client, start-stop-daemon, stat, strings, stty, su, sulogin, sum, sv, svc, svlogd,
svok, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, taskset, tc, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr,
traceroute, traceroute6, true, truncate, tty, ttysize, tunctl, tune2fs, ubiattach, ubidetach, ubimkvol, ubirename, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd,
udpsvd, uevent, umount, uname, uncompress, unexpand, uniq, unix2dos, unlink, unlzma, unlzop, unxz, unzip, uptime, users, usleep, uudecode, uuencode, vconfig, vi, vlock,
volname, w, wall, watch, watchdog, wc, wget, which, who, whoami, whois, xargs, xxd, xz, xzcat, yes, zcat, zcip
この場合、利用したいコマンドは「busybox」コマンドのサブコマンドとして実行します。
# busybox ps
PID USER TIME COMMAND
1 root 0:00 bash
58 root 0:00 busybox ps
# busybox wget
BusyBox v1.30.0 (2018-12-30 22:25:27 CET) multi-call binary.
Usage: wget [-c|--continue] [--spider] [-q|--quiet] [-O|--output-document FILE]
[--header 'header: value'] [-Y|--proxy on/off] [-P DIR]
[-S|--server-response] [-U|--user-agent AGENT] [-T SEC] URL...
Retrieve files via HTTP or FTP
--spider Only check URL existence: $? is 0 if exists
-c Continue retrieval of aborted transfer
-q Quiet
-P DIR Save to DIR (default .)
-S Show server response
-T SEC Network read timeout is SEC seconds
-O FILE Save to FILE ('-' for stdout)
-U STR Use STR for User-Agent header
-Y on/off Use proxy
# busybox mpstat
Linux 4.15.0-48-generic (eeab426fb585) 04/27/19 _x86_64_ (8 CPU)
14:11:18 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
14:11:18 all 10.29 0.02 1.48 2.32 0.00 0.05 0.00 0.00 85.85
ashでコンテナに入る場合。
$ docker container exec -it debian busybox ash / #
Dockerコンテナ内の調査時で困った時に知っておくと、便利そうですね。
覚えておきましょう。