xiaohanliang
Docker
Docker
  • hi
  • STORAGE DRIVER
    • 1. 什么叫联合挂载
    • 2. 镜像ID是从哪来的
    • 3. 如何组装出一个镜像
    • 4. 为什么有这么多fs@aufs
    • 5. 为什么有这么多fs@overlay
    • 6. 为什么有这么多fs@dm
    • 7. 正确安装devicemapper
  • EXEC DRIVER
    • 1. 资源限制-cgroup
    • 2. 制造小型监狱
    • 3. 切换根目录是什么概念
    • 4. 标准极简容器runC
    • 5. 尝试安装runc工具
  • KUBERNETES NETWORK
    • 0. [WIP]我想串联容器网络的故事
    • 1. 容器网络是什么样的网络
    • 2. cnm认为应该怎样让容器组网
    • 3. 为什么会有一大堆cni插件
    • 4. 为什么要设计出pod
    • 5. 怎样形成一个服务
    • 6. Service就是iptables规则
    • 7. IPVS也能实现Service
    • 8. 从集群外访问服务-nodeport
    • 9. 从集群外访问服务-ingress
    • 10. 想要把域名变成IP
    • 11. DNS是怎么实现的
    • 12. 最常见的方案@flannel
    • 13. 使用tun设备封包@flannel
    • 14. 使用vxlan设备封包@flannel
    • 15. 可不可以不封包@flannel
Powered by GitBook
On this page
  • 什么叫"制作一个镜像"?
  • Aufs 在Docker中的玩法
  • 如何组装出一个完整的镜像
  • 如何在Overlay2下组装出一个镜像

Was this helpful?

  1. STORAGE DRIVER

3. 如何组装出一个镜像

什么叫"制作一个镜像"?

Aufs 在Docker中的玩法

上一节好像扯的有点远, 本来是想研究一下Docker是怎么管理这些层级, 以及这些层级分别是干啥的, 结果给扯到镜像ID上去了, 现在必须严肃起来了:

# 用busybox起一个容器
$ docker run -it busybox:latest sh

# 在容器内生成一个 1M 大小的文件
$ dd if=/dev/zero of=test bs=1M count=1

# 随便从容器里删掉一个文件
$ rm bin/find

# 然后用commit的方式生成镜像
$ docker commit a09 xiaohan-building:v2

我们在原有镜像的基础上做出了两个改动, 一个创建操作, 一个删除操作, 来看看按照 aufs 的玩法会发生什么呢? 我们先进入 docker 用来存储镜像的文件夹 /var/lib/docker

# 多出来的 4cd 这个文件夹, 代表我们新产生的层
$ cd /var/lib/docker && ls
ef4da5b601859191dabb3343818295bfaa2112ad # busybox 自带层
4cd218cc42c9b4368543b1dfcd47488145259b1d # 我们Commit所产生的层

$ cd 4cd218cc && ls
test bin root

$ ls -al bin
.wh.find
$ ls -al root
.ash_history

现在一切都真相大白了, 已经完全跟 aufs 一节里提到的知识对接上了, 我们在容器里一共执行了两个动作:

  • [创建] 创建出来的 /test文件, 被原模原样带到镜像里, 等待下次联合挂载的时候带到容器里

  • [删除] 删除的文件会以.wh文件的形式存在, 代表被删除了

如何组装出一个完整的镜像

我们在上一节里提到了, 一个ID唯一的决定一个镜像, 而一个ID是由镜像的配置文件所决定的. 换句话说, 一个完整的, 包含好几层的镜像, 是通过这个json文件组装出来的. 先把镜像整体搞出来, 看看完整的镜像包含那些内容

$ docker save -o xiaohan-building.tar xiaohan-building:v2 && \
    tar -xvf xiaohan-building.tar && \
    ls

# [身份证] 告诉你这个镜像叫什么名字, 是什么ID
repositories
# [配置清单] 告诉你如何组装
manifest.json
# 运行变量, 环境变量/ 等参数
dceb31305909be6852b30109eb006f.json
# 底层镜像
cc42b70ac29c27cb9c528153178d46
# 顶层镜像 
ff12c2f47a046f2bdd61e7b542fb54


$ cat manifest.json | jq -M
  {
    "Config": "dceb31305909be6852b30109eb006f.json",
    "RepoTags": ["xiaohan-building:v2"],
    "Layers": [    
      # 使用路径下的cc/layer.tar 作为镜像的第一层
      "cc42b70ac29c27cb9c528153178d46/layer.tar", 
      # 使用路径下的ff/layer.tar 作为镜像的第顶层
      "ff12c2f47a046f2bdd61e7b542fb54/layer.tar"
    ]
  }
]

$ cat dce.json
{
  ...
  "config": {
    ...
    "OpenStdin": true,
    "StdinOnce": true,
    # 说明了当时我们是从命令行出发制作出这个镜像的 
    "Tty": true,
    # 环境变量
    "Env": ["PATH=/usr/local/sbin:/usr/local/bin"],
    # 类似Dockerfile里的 Entrypoint
    "Cmd": ["sh"]
  },
  ...
}

如何在Overlay2下组装出一个镜像

其实现在Ubuntu的默认选择已经切换成 Overlay2, 原因我们会在下一节介绍overlay2的时候再说, 简单来说是出于效率考虑, 我们先看看overlay2是怎么玩的, 本质上这两者的基本原理都离不开 union mounting , 先把你的容器存储驱动切换成 overlay2 并重启

# 拉一个包含三层的ubuntu
$ docker pull ubuntu:latest

# 存了三个镜像层, 一个l目录, 什么名字只有一个字母
$ cd /var/lib/docker/overlay2 && ls
5120783b613078666e93b04
e80337d2b3f9b8f513aa493
56db4ed53b76a40926bda33
l

# 记录了三个软连接, 分别指向ubuntu三层镜像
$ ls -al l
IQONIIKCSDRBAJNBDCSBTAZHQB -> ../5120783b613078666e93b04/diff
TBVVT2OB2EINS3RZOLAQ6RSNBG -> ../56db4ed53b76a40926bda33/diff
TEZXOCGIWOSOD3Q4TQN74DNOF6 -> ../e80337d2b3f9b8f513aa493/diff

# 看看这个镜像顶层, 是这三者中的哪一个
$ docker inspect ubuntu:latest
...
"GraphDriver": {
    "Data": {
        "UpperDir": 
            # 哟西, ubuntu镜像的顶层是 56db
            "/var/lib/docker/overlay2/56db4ed53b76a40926bda33/diff",
        "LowerDir": 
            # ubuntu的次顶层是e8033
            "/var/lib/docker/overlay2/e80337d2b3f9b8f513aa493/diff:
            # ubuntu的最底层(base)是512
            "/var/lib/docker/overlay2/5120783b613078666e93b04/diff",
    },
    "Name": "overlay2"
}
...


# 切进去看看顶层镜像
$ cd /var/lib/docker/overlay2/56db4ed53b76a40926bda33 && tree
.
|-- diff
|   `-- run
|-- link
|-- lower
`-- work

# 顶层镜像的短ID
$ cat link 
TBVVT2OB2EINS3RZOLAQ6RSNBGroot
# 顶层镜像下辖两个镜像的短ID, 见上面的l目录, 这两个位置指向两个底层镜像的目录
$ cat lower
l/TEZXOCGIWOSOD3Q4TQN74DNOF6
l/IQONIIKCSDRBAJNBDCSBTAZHQB
Previous2. 镜像ID是从哪来的Next4. 为什么有这么多fs@aufs

Last updated 4 years ago

Was this helpful?