Docker Image 管理:从 Image 到 Container

Container 本来也不是什么新技术,为什么 Docker 就火了,而前辈们如 lxc、OpenVZ 等没这么火。其实一部分原因得益于 Docker 的 Image 管理。Docker 借鉴了 vm 的方式,让用户像管理 vm 一样的管理他们的 container 镜像,并且也同样叫做 Image。在实现上,Docker 利用 container 的 Rootfs 是从 host 上挂载的、并且能挂载多个目录这个特点,将 Docker Image 分成多个小块(这是按照 vm Image 的思维来说的,实际上这多个小块,每个都是一个 Image,最终使用的是一个 Image 组合),方便管理与共享。

我们已经了解了 Container 是什么,那么 Image 是怎么转换为 Container 的 Rootfs 的? Image 本身是怎么在磁盘上存储的?带着这些疑问,我们一起来看看 Docker 的实现。

磁盘上的 image

先来看看磁盘中存储的 image 是什么样子的,这里以 aufs 为例, devicemapper 的存储形式和 aufs 还不太一样,后续有空再来分析。

现在我们有一个 image:

【plain】1.ubuntu@ubuntu:~$ sudo docker images

2.[sudo] password for ubuntu:

3.REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

4. ubuntu-12.04 latest 212e4aaf49e7 25 minutes ago 172.7 MB

对应的 /var/lib/docker 目录下就有这些东西:

image

【plain】

1. ubuntu@ubuntu:~$ sudo ls -lh /var/lib/docker

2. total 48K

3. drwxr-xr-x 2 root root 4.0K Apr 16 22:26 apparmor

4. drwxr-xr-x 5 root root 4.0K Jun 21 16:14 aufs

5. drwx------ 3 root root 4.0K Jun 22 13:01 containers

6. drwx------ 5 root root 4.0K Jun 22 12:59 devicemapper

7. drwx------ 3 root root 4.0K Apr 16 22:16 execdriver

8. drwx------ 6 root root 4.0K Jul 13 11:32 graph

9. drwx------ 2 root root 4.0K Jul 13 11:40 init

10. -rw-r--r-- 1 root root 5.0K Jun 22 13:01 linkgraph.db

11. -rw------- 1 root root 111 Jul 13 11:32 repositories-aufs

12. -rw------- 1 root root 180 Apr 16 22:56 repositories-devicemapper

13. drwx------ 2 root root 4.0K Apr 16 22:16 volumes


抛开其他的不管,现在只关心里面的 aufs, graph 目录和 repositories-aufs 文件(如果是 devicemapper,则是 devicemapper 目录和 repositories-devicemapper 文件,graph 为共用的目录)。

aufs 目录的结构如下:

【plain】

1.ubuntu@ubuntu:~$ sudo tree /var/lib/docker/aufs -L 3

2. /var/lib/docker/aufs

3. |-- diff

4. | `-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

5. | |-- bin

6. | |-- boot

7. | |-- dev

8. | |-- etc

9. | |-- home

10. | |-- lib

11. | |-- lib64

12. | |-- media

13. | |-- mnt

14. | |-- opt

15. | |-- proc

16. | |-- root

17. | |-- run

18. | |-- sbin

19. | |-- selinux

20. | |-- srv

21. | |-- sys

22. | |-- tmp

23. | |-- usr

24. | `-- var

25. |-- layers

26. | `-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

27. `-- mnt

28. `-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

layers 目录和 mnt 目录里面目前还只有一个空目录,后面再来看。这里主要是 diff 目录下对应 image 的目录,image 内部的所有文件都在这。

而 graph 目录的结构如下:

【plain】

1. ubuntu@ubuntu:~$ sudo tree /var/lib/docker/graph -L 3

2. /var/lib/docker/graph

3. |-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

4. | |-- json

5. | `-- layersize

6. |-- 317c1f4475ad860bdcf0e529fd03f181b2c6b64e5b78358051efc94c8f728cd7

7. | |-- json

8. | `-- layersize

9. |-- bcd86fdd0ba0b84f10f4539f99e8730958fc1028d35495f8dd11ae1913370e42

10. | |-- json

11. | `-- layersize

12. `-- _tmp

这里只看 212e 这个 image,另外两个 image 其实是 devicemapper 下的 image,所有 image 的描述都放在 graph 目录下。json 文件为 image 的描述文件,主要是创建这个 image 的 container 配置信息, layersize 文件内为该 image 的大小。

最后看看 repositories-aufs 文件:

[plain]

1. ubuntu@ubuntu:~$ sudo cat /var/lib/docker/repositories-aufs |python -m json.tool

2. {

3. "Repositories": {

4. "ubuntu-12.04": {

5. "latest": "212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d"

6. }

7. }

8. }

其实就是描述在 aufs 模式下有哪些 image 可用。

了解了 image 包括哪些东西,接下来再看看这些东西是怎么用的。

从 Image 到 Container

当我们通过命令行 docker run 创建一个 container 并运行时,其中就经历了从 image 到 container rootfs 的转化,蓝图如下(省略了其他操作):

上图横轴为执行流程,纵轴是对每个过程的解释。

因为 docker run 命令实际的执行主要分两步:create 和 start。在 create 过程中,主要是将 image 挂载到 /var/lib/docker/aufs/mnt/:id-init 目录 (:id 为container id ),并且取消掉对某些文件/文件夹的挂载,重新创建一份新的。这里的文件/文件夹主要为:

[plain]

1. "/dev/pts": "dir",

2. "/dev/shm": "dir",

3. "/proc": "dir",

4. "/sys": "dir",

5. "/.dockerinit": "file",

6. "/.dockerenv": "file",

7. "/etc/resolv.conf": "file",

8. "/etc/hosts": "file",

9. "/etc/hostname": "file",

10. "/dev/console": "file",

11. "/etc/mtab": "/proc/mounts",

然后在 start 流程中,主要是生成 container 真正的 rootfs 目录 /var/lib/docker/aufs/mnt/:id, 然后又将几个 /host 上的目录挂载到 rootfs,主要是 /etc/hosts, /etc/hostname, /etc/resolv.conf 等。

(其实这里没看明白为啥这几个文件要这样处理,也没看明白为什么要用:id-init 目录隔一层。主要是对 aufs 不熟悉,后面再学习一下。)

现在来看看,当我们创建了一个 container 后,aufs 目录有什么变化:

[plain]

1. ubuntu@ubuntu:~$ sudo tree -L 3 /var/lib/docker/aufs

2.[sudo] password for ubuntu:

3. /var/lib/docker/aufs

4. |-- diff

5. | |-- 09b1be94a4444076375b7cb386609990622a1746802858ea85f1de607c1e5167

6. | |-- 09b1be94a4444076375b7cb386609990622a1746802858ea85f1de607c1e5167-init

7. | | |-- dev

8. | | `-- etc

9. | `-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

10. | |-- bin

11. | |-- boot

12. | |-- dev

13. | |-- etc

14. | |-- home

15. | |-- lib

16. | |-- lib64

17. | |-- media

18. | |-- mnt

19. | |-- opt

20. | |-- proc

21. | |-- root

22. | |-- run

23. | |-- sbin

24. | |-- selinux

25. | |-- srv

26. | |-- sys

27. | |-- tmp

28. | |-- usr

29. | `-- var

30. |-- layers

31. | |-- 09b1be94a4444076375b7cb386609990622a1746802858ea85f1de607c1e5167

32. | |-- 09b1be94a4444076375b7cb386609990622a1746802858ea85f1de607c1e5167-init

33. | `-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

34. `-- mnt

35. |-- 09b1be94a4444076375b7cb386609990622a1746802858ea85f1de607c1e5167

36. | |-- bin

37. | |-- boot

38. | |-- dev

39. | |-- etc

40. | |-- home

41. | |-- lib

42. | |-- lib64

43. | |-- media

44. | |-- mnt

45. | |-- opt

46. | |-- proc

47. | |-- root

48. | |-- run

49. | |-- sbin

50. | |-- selinux

51. | |-- srv

52. | |-- sys

53. | |-- tmp

54. | |-- usr

55. | `-- var

56. |-- 09b1be94a4444076375b7cb386609990622a1746802858ea85f1de607c1e5167-init

57. `-- 212e4aaf49e7cde3c280d05f1a6bd74ecf66ad83917fa757137deb0dae82806d

这里创建了一个 id 为 09b1 的 container,其中 /aufs/mnt/09b1xxx 为 rootfs, /aufs/layers 目录下的文件,主要存储 image 的 parents image id。

小结:

Docker 的 image 管理涉及到不少 linux 文件系统使用的细节,对 linux 文件系统掌握得不深的话,这部分就只能看个大概的流程。而且这只是其中的 aufs 部分,其他的 devicemapper、btrfs、vfs 部分的都不太一样。下来先补习一下 linux 文件系统知识,再回过头来看看 docker 的 image 管理,可能会稍微轻松些。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容