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
  • 原料
  • 准备两个"文件"
  • 把文件变成loopback设备
  • 基于这两个设备搭建thin-pool
  • 然后基于thin-pool创建逻辑盘
  • 整活
  • 创建第一层
  • 然后创建第一层的snapshot
  • 挂载 / 使用上这个快照
  • 在快照的基础上做一些修改
  • 继续往上磊

Was this helpful?

  1. STORAGE DRIVER

7. 正确安装devicemapper

原料

devicemapper本身不是一种盘/设备, 跟 aufs不同, 我们梳理一遍:

  • 从用户的角度出发他只关心/只需要一个设备, 来mount, 因此我们需要准备一个逻辑盘.

  • 然后这个逻辑盘底层使用一个thinpool, 这两者全都是基于devicemapper框架, 映射在两个loopback设备上的,

梳理完了整个逻辑 我们需要如下原料:

  1. 两个设备, 分别用于存储数据 / 元数据

  2. 用这两个设备搭建出一个 thin-pool

  3. 创建出一个逻辑设备, 基于这个thin-pool

准备两个"文件"

$ dd if=/dev/zero of=data.img      bs=1K count=1 seek=10M
$ dd if=/dev/zero of=meta.data.img bs=1K count=1 seek=1M

$ ls -lsh 
total 12K
4.0K -rw-r--r-- 1 root root  11G Oct 28 10:03 data.img
8.0K -rw-r--r-- 1 root root 1.1G Oct 28 10:04 meta.data.img

既然thin-pool底层是用两个"设备", 那我们就搞两个loop-back设备交差, 以上命令首先创造出两个文件, 其中 /dev/zero是零源, 代表我们一次从零源里读1K大小的数据, 而其中的seek=10M, 代表跳过前10M个块, 造成前10G内容都是被跳过的, 根据ls -lsh的内容能看出, 他们表面上这么11G大, 实际只占据了4K的空间, 我理解这就造成了一种类似"磁盘"的效果 → 我提供10G的存储空间

把文件变成loopback设备

$ losetup /dev/loop0 data.img
$ losetup /dev/loop1 meta.data.img

$ losetup -a
/dev/loop0: [64769]:1348 (/root/data.img)
/dev/loop1: [64769]:1359 (/root/meta.data.img)

现在两个文件, 已经成为两个loopback设备了, 翻译成人话: 在linux看来, 这两个文件跟两个外挂磁盘是没有区别的, 你往这个loopback设备上写入, 在linux看来就是往磁盘里写入, 不管如何, 我们已经有 devicemapper框架下, thin-pool策略中, 底层要用到的两个设备了

基于这两个设备搭建thin-pool

$ dmsetup create xiaohan-thin-pool --table \
  "0 20971522 thin-pool /dev/loop1 /dev/loop0 128 65536 1 skip_block_zeroing"

$ ls -l /dev/ | grep "dm"
root disk Oct 28 10:39 dm-0

$ ls -l /dev/mapper/
root root Oct 28 10:01 control
root root Oct 28 10:39 xiaohan-thin-pool -> ../dm-0

dmsetup 命令就是device-mapper-setup, 创建出一个名为 xiaohan-thin-pool 的设备, 然后 --table指参数表, 里面描述了, 创建的设备基于"thin-pool"策略, 分别使用 loop1/loop0 作为底层磁盘.

这个命令执行完, 我们去 dev 下就能看到一个名为 dm0 (device-mapper-0) 的设备, /dev/mapper 下记录了一个名为 xiaohan-thin-pool的东西, 通过软链指向 dm0

然后基于thin-pool创建逻辑盘

$ dmsetup message /dev/mapper/xiaohan-thin-pool 0 "create_thin 0"
$ dmsetup create xiaohan-vol --table "0 2097152 thin /dev/mapper/xiaohan-thin-pool 0"

$ ls -l /dev/mapper
root root Oct 28 10:01 control
root root Oct 28 10:39 xiaohan-thin-pool -> ../dm-0
root root Oct 28 10:52 xiaohan-vol -> ../dm-1

$ mkfs.ext4 /dev/mapper/xiaohan-vol

好. 一个基于thin-pool策略的 devicemapper 框架已经搭好了, 接下来我们只要基于这个框架, 分配出一个逻辑盘拿来用, 它就是天然的基于thin-pool, 并使用上devicemapper框架的特性了.

第一个+第二个 命令指, 基于xiaohan-thin-pool创建出一个名为xiaohan-vol的盘, 最后一个命令是把它格式化成ext4的文件格式, 这样我们就可以拿来直接当成正常的"设备" / "盘" 来使用了. 我们可以通过看看 /dev下. 能发现我们多出了一个名为 dm1的设备. 一个xiaohan-vol的设备(同一个东西)

这个盘, 就是我们心心念念的, 基于thin-pool的磁盘分配策略, 基于devicemapper框架下的块使用策略的, 一个可以直接拿来用的, 存文件的地方.

整活

到这一步, 我们才把devicemapper框架设置好. 然后才可以像 aufs 一样, 去mount 这个盘, 不可谓不复杂, 接下来我们可以一一去验证网上那些关于dm的特性, 什么snapshot之类的东西了

创建第一层

$ mkdir /mnt/base
$ mount /dev/mapper/xiaohan-vol /mnt/base

于是我们开始把刚刚创建的逻辑盘拿来用, 挂载到 /mnt/base 下, 换句话说如果现在对base做 siusiu 读写, 就是对 xiaohan-vol 做 siusiu 读写, 也就会走 devicemapper 哪一套了, 那我们就来做 siusiu 读写

$ echo "this is base layer" > /mnt/base/id.txt

然后创建第一层的snapshot

$ dmsetup message /dev/mapper/xiaohan-thin-pool 0 "create_snap 1 0"
$ dmsetup create xiaohan-snap0  --table \
  "0 2097152 thin /dev/mapper/xiaohan-thin-pool 1"

彳亍. 我们通过message命令里的 create-snap . 创建 xiaohan-thin-pool 下 xiaohan-vol 的 snapshot (我们没有用到xiaohan-vol的字眼. 但是在 create-snap后面跟着的1 0 是通过device-id指定了xiaohan-vol)

$ ll /dev/mapper/
root root Oct 28 10:01 control
root root Oct 28 11:13 xiaohan-snap0 -> ../dm-2
root root Oct 28 10:39 xiaohan-thin-pool -> ../dm-0
root root Oct 28 10:55 xiaohan-vol -> ../dm-1

好! 很有精神! (小曲儿) 原来这个snapshot的本质是另外一个设备, 一个名为 dm2 的 devicemapper 设备. 然后同样可以被挂载. 那么我们基于这个(base设备的)snapshot创建一个挂载路径:

挂载 / 使用上这个快照

$ mkdir /mnt/snap0
$ mnt /dev/mapper/xiaohan-snap0 /mnt/snap0
$ ls /mnt/snap0
id.txt  lost+found

通过上面的两条命令, 我们把 base 层的镜像, 挂载到 mnt/snap0目录中. 我们看看我们创造的快照都有啥内容. 有一个id.txt . lost+found. 基本上就是 base层里一模一样的东西

在快照的基础上做一些修改

$ echo "this layer was built above base layer snapshot" > /mnt/snap0/id.txt
$ echo "this layer was built above base layer snapshot" > /mnt/snap0/id1.txt

先等等, 我们先捋一下, 我们现在的 /mnt/snap0. 是基于快照弄出来的文件系统, 而不是base本身, 是base的快照, 然后这一小节, 要做的是对快照进行修改

$ cat /mnt/base/id.txt
this is base layer

看来对快照进行修改, 并不会导致base本体被修改, 仔细思考这个现象:

  • 我有什么: 我有一些文件

  • 我做了什么:

    • 我对这些文件做了快照

    • 我拥有了一个基于这些快照而得到的目录

    • 我在这个目录下做修改, 但文件本体没修改

想想这个现象, 这几乎跟镜像, 容器的表现是一模一样了. 文件, 对应着镜像里的源文件, 快照以及你挂载快照后得到的目录, 相当于容器内部的目录结构. 仔细想想, 我们已经很接近容器文件系统那些特性了

继续往上磊

$ dmsetup message /dev/mapper/xiaohan-thin-pool 0 "create_snap 2 1"
$ dmsetup create snap1 --table "0 2097152 thin /dev/mapper/xiaohan-thin-pool 2"
$ ll /dev/mapper/snap1
Oct 28 11:35 /dev/mapper/snap1 -> ../dm-3

我们继续对这一层做快照, 得到snap1

$ mkdir -p /mnt/snap1 
$ mount /dev/mapper/snap1 /mnt/snap1
$ ls /mnt/snap1
id.txt  id1.txt  lost+found
$ cat /mnt/snap1/id.txt
this layer was built above base layer snapshot

挂载snap1, 看到我们拿到了上一层中的文件, 所谓 devicemapper 是基于一层一层的快照, 就是基于这个原理

Previous6. 为什么有这么多fs@dmNext1. 资源限制-cgroup

Last updated 4 years ago

Was this helpful?