Docker实践(9) – 虚拟机转换为容器

Docker Hub没有所有可能的基本镜像,所以对于一些小众的Linux发行版本和用例,人们需要自己来创建它。如果你想把一个存在状态的虚拟机放入Docker上层迭代,或者受益于Docker生态系统,同样的原则也适用。
理想情况下,你希望使用标准的Docker技术从头开始构建一个等效的VM,例如Dockerfiles与标准配置管理工具。然而现实是,许多VM没有仔细配置管理。这个有可能发生,因为一个VM已经发展成为一个有机体,人们已经在用它了,以一个更结构化的方式来重新创建它的投资可能不值得。

问题

你想把一个VM转换为一个Docker镜像

解决办法

通过ssh使用qemu-nbd,tar或者其它方法把VM文件系统打包成一个TAR文件,然后在Dockerfile中使用ADD命令添加TAR文件来创建镜像。

讨论

首先我们要将虚拟机分为两大类:本地(VM磁盘镜像和VM的执行在你的电脑)和远程(VM磁盘镜像的存储和VM执行在其它地方)。两组虚拟机(和任何你想创建Docker镜像)转换为Docker镜像的原理是一样的 – 打包文件系统为TAR文件并添加TAR文件到scratch镜像的根目录。
ADD命令 – ADD Dockerfile命令(不像COPY命令)当把TAR文件(也可以是gzipped文件和其它类似的文件类型)放置到镜像时会自动解压。
SCRATCH镜像 – scratch镜像是你在上面创建镜像的一个零字节的假镜像,通常它用于你想使用Dockerfile复制(或添加)一个完整文件系统到一个镜像的情况。
我们现在来看一个你有一个本地Virtualbox VM的情况。
在我们开始之前,你需要做如下事件:

  • 安装qemu-nbd工具(在Ubuntu系统的qemu-utils包里)
  • 记下VM磁盘映像的路径
  • 关闭VM
  • 如果你的VM磁盘映像是.vdi或.vmdk格式,应该能使用qemu-nbd成功挂载。其它的格式也有可能可行。
    以下代码演示了如何将虚拟机文件转换为虚拟磁盘,然后你可以从中复制所有文件:

    如果你的VM是在远程,你可以请求你的运维团队来对你想要的分区作一个转储,或者在VM运行时创建TAR。
    如果你得到一个分区转储,可以很容易的挂载并打包成一个TAR文件:

    1. $ sudo mount -o loop partition.dump /mnt
    2. $ sudo tar cf $(pwd)/img.tar -C /mnt .
    3. $ sudo umount /mnt

    或者你可能在正在运行的系统上创建TAR文件:

    1. $ cd /
    2. $ sudo tar cf /img.tar --exclude=/img.tar --one-file-system /

    你现在得到了包含文件系统的TAR文件,可以通过scp命令传输到其它机器。

    从正在运行的系统上创建TAR文件看起来是一个最简单的方法(不用关机,安装软件或者请求其他团队),不过它有一个严重的缺点 – 你可能会一个不一致的状态下复制文件,这样当使用Docker镜像时会遇到奇怪的问题。如果你必须这样做,那么就尽可能的关闭应用和服务。

    一旦你得到了文件系统TAR文件,你就可以添加到镜像了。这是最简单的一步,只有Dockerfile的两行:

    1. FROM scratch
    2. ADD img.tar /

    然后执行docker build .就生成镜像了。
    现在你得到了一个新的镜像,你可以运行一个容器,然后在上面做你想要的修改,比如删除不需要的包来缩减容器大小并重新导出为一个新的小的镜像,下面是流程图:

    标签:容器Docker 发布于:2019-11-20 22:19:26