Docker镜像的首行从FROM alpine之类的镜像开始,但是最初的基础镜像是如何创建的,本文使用一个busybox创建一个基础镜像,相信在此过程中会对docker一些相关的概念有进一步的理解。
简单来说,基础镜像就是没有From或者FROM scratch开头的Dockerfile所构建出来的镜像。比如alpine,这个很小的linux镜像目前只有4M左右
busybox被称为嵌入式linux的瑞士军刀,这句话是在busybox自己介绍自己的时候提出的(The Swiss Army Knife of Embedded Linux)。busybox整合了很多小的unix下的通用功能到一个小的可执行文件之中,简单来说在unix或者linux下常用的那些功能在这里你都能找到,但是为了busybox的目标:嵌入式的linux,大小对于busybox来说是非常重要的优化要素和限制,这些功能有可能会有所阉割,但是对于一般需求来说已经足够。而alpine就是在busybox基础上增加了自己的包管理工具apk等功能创建了风靡一时的小巧镜像。busybox是用C语言开发的基于GPL的开源项目,目前的稳定版本为1.28.4
输入busybox可以看出版本以及熟悉的linux下的工具,仔细看一遍就会理解busybox号称自己是瑞士军刀一点都不夸张,反过来说,瑞士军刀如果敢号称linux里的busybox可能会引起非议。
[root@kong ~]# busyboxBusyBox v1.28.1 (2018-02-15 14:34:02 CET) multi-call binary.BusyBox is copyrighted by many authors between 1998-2015.Licensed under GPLv2. See source distribution for detailedcopyright notices.Usage: busybox [function [arguments]...] or: busybox --list[-full] 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, arch, arp, arping, ash, awk, base64, basename, beep, 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, ether-wake, expand, expr, factor, fakeidentd, fallocate, false, fatattr, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, 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, ifdown, ifenslave, ifplugd, ifup, inetd, init, 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, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsscsi, lsusb, lzcat, lzma, lzop, 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, nanddump, nandwrite, nbd-client, nc, netstat, nice, nl, nmeter, nohup, nproc, nsenter, nslookup, 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, readahead, 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, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, taskset, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, truncate, tty, ttysize, tunctl, ubiattach, ubidetach, ubimkvol, ubirename, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, uevent, umount, uname, unexpand, uniq, unix2dos, unlink, unlzma, unshare, 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[root@kong ~]
这张图在镜像基础介绍的时候已经被无数次看到了,rootfs是linux中重要的概念,而alpine中也有ADD rootfs.tar.xz这样一句,接下来我们将了解一下如何生成一个简单的rootfs
此处注意相对路径,而后续次相对路径会展开至/下,从而创建新的系统的rootfs,这也是从零搭建linux(linux from scratch)的重要操作之一。
创建base镜像,由于没有发现具体的内容,所以未创建出具体镜像。另外,本文为了演示方便,直接在此处创建Dockerfile,这并不是一个好主意,实际的时候请不要这样做,如果当前目录下有100G的文件,就会无比缓慢,而且也不规范,无关物品需要清场。
这篇文章介绍了如何使用busybox结合from scratch机制创建docker的基础镜像以及相关原理。本文利用busybox 1.28.1版本创建了一个1.01M的可用的基础镜像,从瑞士军刀到瑞士指甲刀,你可以继续优化到若干K都是可行的,但是到了10M以下其实应该更多考虑的是后续的扩展性和功能性的因素了。但是从另外的角度考虑,集成进来了那么多功能的同时,也将这些功能的不安定因素也集成进来了。利用from scratch机制,创建小并且依赖性少的上下文环境是非常有用的。