在运行实例至少一次后,基于某些现有的 LXC 模板创建自定义模板

在运行实例至少一次后,基于某些现有的 LXC 模板创建自定义模板

(请注意这个问题关于 LXC 1.x,而这个关于 LXC 2.x/LXD)

我在网上搜索了这个问题的答案,但无法想出任何合理的非黑客答案。

我正在寻找一种以我想要的方式塑造现有模板的方法。我特别想要的是通过在其根 FS 中进行各种更改并添加/更改配置来自定义上游 Ubuntu 云映像。

因此,我当前的方法是lxc launch ubuntu:lts CONTAINER运行lxc exec CONTAINER -- ...我编写的脚本(将其推入容器后)来执行我的自定义。

我使用这种方法得到的是一个合理定制的容器。唉,有一个问题。此时的容器已准备好cloud-init,它是一个容器实例,而不是图像/模板。

所以这就是我现在不知所措的地方。我需要的是将我的容器转回图像(应该可以通过使用lxc publish),并撤消对它所做的更改,cloud-init或者至少cloud-init再次“cock”,以便下次将图像用作lxc init或的源时触发lxc launch。或者,也许有一种方法可以cloud-init在我lxc launch从上游图像中完全禁用它?

有权威的办法吗?尽管我查阅了各种文档,包括LXD 存储库中的 Markdown 文档以及 Stéphane Graber(LXD 项目负责人)的博客系列,尤其是[5/12],我无法找到合适的方法。也许我只是错过了它(也就是说,如果您知道一些描述我需要的内容,我将很乐意阅读更多文档)。

使用的 LXC 版本是 2.20(即我使用的是 LXD 前端)。

答案1

在链接的页码 [5/12]通过 Stéphane Graber,您可以找到第二种方法:

手动构建镜像

建立自己的形象也非常简单。

  1. 生成容器文件系统。这完全取决于您使用的发行版。对于 Ubuntu 和 Debian,可以使用 debootstrap。
  2. 配置分发在容器中正常工作所需的任何内容(如果需要的话)。
  3. 制作该容器文件系统的 tarball,可以选择压缩它。
  4. 根据上述文件编写一个新的metadata.yaml 文件。
  5. 创建另一个包含该metadata.yaml 文件的tarball。
  6. 使用以下命令将这两个 tarball 导入为 LXD 映像:

这样,您无需在发布映像之前启动容器。您可以从现有图像开始:

$ lxc image copy ubuntu:16.04/amd64 local: --alias ubuntu
$ mkdir export-directory
$ lxc image export ubuntu export-directory
$ cd export-directory
$ ls 
5f364e2e3f460773a79e9bec2edb5e993d236f035f70267923d43ab22ae3bb62.squashfs
meta-5f364e2e3f460773a79e9bec2edb5e993d236f035f70267923d43ab22ae3bb62.tar.xz

$ mkdir meta squashfs
$ tar -xf *.tar.xz -D meta
$ sudo unsquashfs -f -d squash/ *squashfs

现在您可以调整文件甚至 chroot 到南瓜目录中。然后,您可以 tar 这两个目录并使用以下命令导入调整后的图像:

lxc image import <metadata tarball> <rootfs tarball> --alias my-adjusted-image

答案2

lxd构建/图像的主要工具lxc发行版构建者

配置图像的现代方法是云初始化


为了自定义 LXD / LXC 图像,我写道:

Distrobuilder 的 python 控制台前端(包含两者)

LXD 和 LXC 的发行版菜单


它遵循一个类似的方法到 Hashicorp Packer 并分层构建模板。

  1. 创建base覆盖standard模板并包含您的shell自定义和其他自定义的图像
  2. custom使用您的网络服务等创建一个图像覆盖来覆盖您的base图像(即在生成图像时使用base图像模板作为模板)SOURCE自定义模板使用您的自定义服务覆盖/cloud-init 配置)

我用于dbmenu构建非特权 LXD 容器并添加(和包)示例配置来创建:

  • base经过一些定制的Alpine Linux / Ubuntu镜像
  • Alpine Linux 构建环境alpine-sdk(&cloud-init在首次启动时被删除)
  • 首次启动时安装 Gitlab 的 Ubuntu 容器(通过 cloud-init)

我还用来dbmenu创建一个适合在rootless内部运行 podman / docker 的Ubuntu 映像lxd(在撰写本文时尚未添加到例子


  • 自述文件现在已经相当完整了

  • Ubuntu 的 LXD 和新的incusfork 都支持构建镜像

  • 请参阅依赖关系需要dbmenu.在2023 年 10 月您需要最新git版本来distrobuilder构建最新的模板格式

  • 在幕后dbmenu是使用 Mike Farahyqyaml模板合并在一起(yq&distrobuilder都是用相同的底层库编写的Go,所以都使用相同的底层yaml库)

  • 使用PyYaml合并是有问题的 - 它读取和写入配置yaml的速度非常快yaml.CSafeLoader

  • dbmenu安装非常简单:

  • pipx install distrobuilder-menu(pypi - 最新版本

  • pipx install git+https://github.com/itoffshore/distrobuilder-menu.git(github最新dev/发布)

相关内容