如何创建一个继承主机根文件系统的linux容器,可能还有zfs?


3

什么

希望标题中的问题是有道理的。我想创建一个低开销(因此没有虚拟机)的主机操作系统副本,它在Linux容器中运行。

我想以某种方式使用zfs创建主机rootfs的快照,然后以某种方式将其提供给lxc。这样,容器中的任何更改都通过ZFS的写时复制功能限制在容器中,并且对主机rootfs的任何未来更改都不会传播到容器。

我是否有任何潜在的问题需要考虑,例如递归目录会造成严重破坏或其他什么?

为什么

这样做的原因是我可以快速使用主机作为模板,并使用例如安装污染rootfs的新构建工具而不必担心影响主机,而不必浪费大量的驱动器空间复制主机根文件系统。另外,我花了相当多的时间以我喜欢的方式设置主机,并且不想再花几天时间创建一个过程的模板(尽管我应该这样做,把它全部写下来是一个好主意,自动化它甚至更好)。由于这将在一个linux容器中,我可以同时运行多个实例。

Answers:


3

我起草了一个可以实现此目的的手动程序。

先决条件

这些程序做出以下假设:

  • 你的外壳是 /bin/bash
  • 你是根。
  • 您已在ZFS池上部署了操作系统 rpool 并且还希望LXD容器位于同一个ZFS池中( rpool )。
  • 您的主机rootfs已安装到 rpool/ROOT/os ZFS数据集。
  • 您拍摄了主机rootfs的快照并将其调用 rpool/ROOT/os@20180516T091126CDT
  • 你正在运行 瞬间 LXD包装。
  • 你有一个 lxc storage 命名 rpool 使用 zfs 源头上的驱动程序 rpool/lxd
  • 您想要创建一个名为的非特权容器 demo

您必须针对与上述要求的每个偏差调整程序。

说明

  1. 使用与主机操作系统类似的映像创建LXC容器:

    root@node51 [~]# lxc launch images:ubuntu/18.04 demo -s rpool
    Creating demo
    Starting demo
    
  2. 停止容器:

    root@node51 [~]# lxc stop demo
    
  3. 挂载LXC存储卷,以便我们可以从中获取一些元数据:

    root@node51 [~]# zfs mount rpool/lxd/containers/demo
    
  4. 将元数据复制到某个地方(比如 /tmp/demo/ ):

    root@node51 [~]# rsync -avHXShPs --exclude rootfs/ /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/ /tmp/demo/
    sending incremental file list
    created directory /tmp/demo
    ./
    backup.yaml
              2.05K 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=4/6)
    metadata.yaml
                529 100%  516.60kB/s    0:00:00 (xfr#2, to-chk=3/6)
    templates/
    templates/hostname.tpl
                 21 100%   20.51kB/s    0:00:00 (xfr#3, to-chk=1/6)
    templates/hosts.tpl
                140 100%  136.72kB/s    0:00:00 (xfr#4, to-chk=0/6)
    
    sent 3.12K bytes  received 135 bytes  6.50K bytes/sec
    total size is 2.74K  speedup is 0.84
    
  5. 删除LXC创建的ZFS数据集:

    root@node51 [~]# zfs destroy rpool/lxd/containers/demo
    
  6. 将ZFS数据集克隆为LXC期望的相同名称:

    root@node51 [~]# zfs clone rpool/ROOT/os@20180516T091126CDT rpool/lxd/containers/demo
    
  7. 将mountpoint设置为原始挂载点:

    root@node51 [~]# zfs set mountpoint=/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo rpool/lxd/containers/demo
    
  8. 为新容器数据创建rootfs目录:

    root@node51 [~]# mkdir -v /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/rootfs/
    mkdir: created directory '/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/rootfs/'
    
  9. 扩展shell的globbing功能 确保即将到来 mv 获取所有文件系统数据:

    root@node51 [~]# shopt -s extglob ; shopt -s dotglob
    
  10. 稍微缩短即将发布的命令 cd 进入容器的数据集:

    root@node51 [~]# cd /var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo/
    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]#
    
  11. 将所有容器的数据移动到 rootfs/ 夹:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mv !(rootfs) rootfs/
    
  12. 创建容器引导所需的一些文件夹:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mkdir rootfs/{dev,sys,proc}
    
  13. 将之前备份的元数据移动到容器的数据集中:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# mv /tmp/demo/* .
    
  14. 从元数据备份中删除空的临时目录:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# rm -rfv /tmp/demo
    removed directory '/tmp/demo'
    
  15. 返回到上一个目录,以便卸载容器的数据集:

    root@node51 [/var/snap/lxd/common/lxd/storage-pools/rpool/containers/demo]# cd -
    /root
    
  16. 卸载容器的数据集,以便LXC可以将其接管:

    root@node51 [~]# zfs umount rpool/lxd/containers/demo
    
  17. 要告诉LXC在下次启动时将容器的文件转换为非特权,请运行

    lxc config edit demo
    

    并更改读取的行

    volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
    

    volatile.last_state.idmap: '[{"Isuid":true,"Isgid":true,"Hostid":1,"Nsid":0,"Maprange":1000000000}]'
    
  18. 启动容器。
    这将需要一段时间,因为容器的rootfs中的每个文件都被转换为非特权。 没有进度指标。

    root@node51 [~]# lxc start demo
    
  19. 输入容器:

    root@node51 [~]# lxc exec demo -- bash
    

    从这里,您可以配置网络,系统启动顺序和/或使主机的LXC容器克隆启动并运行所需的其他内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.