构建派生容器

跳转到:导航搜索
本文档提供了一个指南和规范,用于为 openSUSE 发行版构建容器镜像。

规范

这是 openSUSE 发行版中所有容器镜像的规范。如果您在 OBS 的个人项目或非用于提交到 openSUSE 发行版的开发项目中构建镜像,则它们不需要遵循此规范。

正在努力在构建期间检查大多数规则。一旦激活,任何违反规则的情况都将在构建期间报告,并且在 `openSUSE:` 项目中导致构建失败。

本文档中使用了许多术语,这些术语指的是容器镜像的各个部分。

                     namespace     tag
                     |-------|    |----|
registry.opensuse.org/foo/bar/baz:latest
|--------------------|-----------|
       registry       repository
|--------------------------------------|
           reference

构建工具的选择

容器镜像必须使用 KIWI 配方或 Dockerfile(使用 podman 构建)构建。

每种方法都有其自身的优点和缺点。Kiwi 支持使用主机/构建系统的软件包管理器,因此它可以构建基本镜像并派生不包含软件包管理器的镜像,例如 `opensuse/busybox`。使用 Dockerfile,实际上需要使用完整的基本镜像,例如 `opensuse/tumbleweed`。

通用规则

  • 提交的名为 `foo-image` 的镜像需要包含匹配的 `foo.changes` 文件
  • 不允许直接引用仓库(使用 `obsrepositories:/` 可以)
  • 在使用 kiwi 时,用于提交的软件包名称和 `.kiwi` 文件中的 `` 属性必须相同
  • 构建配方和附带文件必须在 OSI 批准的许可下。完整的许可文本必须包含在一个单独的文件中。

镜像名称

从 OBS 的 `openSUSE:Containers` 子项目发布的所有镜像在 registry.opensuse.org 上可见,其仓库和标签由这些镜像定义(参见标签 (Tagging))。与 home: 和 devel 项目不同,没有基于项目和(构建)仓库名称的强制前缀。

由于每个镜像都可以自由定义其在注册表中的位置,因此重要的是它们之间进行协调和协作。这主要是为了避免冲突和混淆,但也为了确保一致性,因为这些引用是公开可见的。

由于 `registry.opensuse.org` 在官方发布的镜像和 devel 和 home 项目的任意镜像之间共享,因此必须特别注意,以便轻松辨别特定镜像是否来自官方来源。目前,这是通过保留不与非官方项目重叠的特殊前缀来实现的:`opensuse/`、`kubic/` 和 `kubevirt/`。

虽然仓库和标签名称可以是任何有效的 OCI 标识符,但外部工具施加了一些限制

  • docker 默认使用 Docker Hub 作为注册表(硬编码!),任何人都可以上传镜像。选择的仓库名称未在 Docker Hub 上分配是有益的,否则可能会意外使用。Docker Hub 上的 `opensuse/` 前缀(例如,用于基本容器)为空,因此没有歧义。
  • 一些注册表不支持根目录中的仓库(`registry.opensuse.org/foo:latest`)或嵌套命名空间(`registry.opensuse.org/asdf/bar/baz:latest`)。后者最近已不再成为一个问题。
  • 仓库名称也不能用作命名空间,例如(`registry.opensuse.org/some/container:latest` 和 `registry.opensuse.org/some/container/withstuff:latest`),这意味着例如 `opensuse/tumbleweed/httpd` 是不可能的。

软件包名称

软件包名称(例如 `opensuse-tumbleweed-image`)必须以 `image` 或 `container` 结尾,并且与主镜像名称相关。对于 `opensuse/hello-world`,匹配的软件包名称将是 `opensuse-hello-world-image` 或 `hello-world-container`。

标签

标签可以自由定义。在每次发布新的构建(Tumbleweed Snapshot、Leap 镜像构建)时,新的构建都会发布到 `openSUSE:Container` 的子项目中,旧镜像会被保留。如果多个镜像提供了一个标签,则使用最新的镜像。

必须有一个标签,该标签仅由特定的构建提供。只能通过包含完整的版本(包括构建计数器)来实现。

在使用 kiwi_metainfo_helper 服务时,可以将其表示为例如:

 #!BuildTag: opensuse/example:1.0 opensuse/example:1.0.%RELEASE%

此标签是必须在 `org.opensuse.reference` 标签中使用的标签。

标签 (Labels)

使用 Docker 标签的一个缺点(我们需要它来实现兼容性)是镜像中只有一个级别的标签,而不是每个层一个。这意味着基本容器中定义的标签可以被派生镜像中的标签覆盖。未被覆盖的标签不会显示来自基本容器。

为了解决这个问题,必须将特定信息克隆到带有 `org.opensuse.` 前缀的容器特定标签中。

标签 (Label) OCI 注释 派生镜像必须提供 描述 示例
org.opencontainers.image.title org.opensuse.base.title org.opencontainers.image.title 镜像标题 openSUSE Tumbleweed 基本容器
org.opencontainers.image.description org.opensuse.base.description org.opencontainers.image.description 镜像的简短描述 包含基于 openSUSE Tumbleweed 的容器的最小环境的镜像。
org.opencontainers.image.version org.opensuse.base.version org.opencontainers.image.version 镜像版本。<version>.<cicnt>.<bldcnt> 20181224.4.2
org.opencontainers.image.created org.opensuse.base.created org.opencontainers.image.created 镜像构建日期/时间 2019-01-05T14:12:30Z
org.opencontainers.image.vendor org.opensuse.base.vendor org.opencontainers.image.vendor 镜像供应商 openSUSE Project
org.opencontainers.image.url org.opensuse.base.url org.opencontainers.image.url 包含更多信息的 URL https://opensuse.net.cn/
org.openbuildservice.disturl org.opensuse.base.disturl org.openbuildservice.disturl OBS 提供的分发 URL obs://build.opensuse.org/openSUSE:Factory/images/4985c42063a1f194292ecb777d41923b-opensuse-tumbleweed-image:docker
org.opensuse.reference org.opensuse.base.reference org.opensuse.reference 指向此特定镜像的引用(`registry.opensuse.org/imagename[:tag]`) registry.opensuse.org/opensuse/tumbleweed:20181224.4.2

历史

每个镜像都应定义一个历史记录条目,其中包含对该镜像的易于理解的描述。这样可以轻松了解镜像中的每一层是什么。

  > docker history opensuse/tumbleweed
  IMAGE               CREATED             CREATED BY          SIZE                COMMENT
  aaa05880bad2        2 days ago          KIWI 9.17.15        123MB               openSUSE Tumbleweed 20190312 Base Container

入门

开始构建新容器镜像的最简单方法是使用预定义的模板并提交它们。

分支模板

在 OBS 主页上,有一个链接到 可用模板的概述。“使用 Dockerfile/KIWI 的应用程序容器”和“使用 KIWI 的派生容器”模板可用于提交到 openSUSE 发行版。如果您单击模板的标题,可以四处查看并找出最适合您的模板

根据您的工具选择,选择要构建的发行版的适当模板。确保分支到尚不存在的项目,否则镜像将无法构建。如果目标项目已经设置为针对您选择的发行版构建镜像,例如之前分支到该项目,那也可以。

调整构建配方文件

每个模板都有一个 README 文件,其中包含模板内部的特定说明。

添加 .changes 文件

可以使用 Web UI 创建匹配软件包名称的 `foo.changes` 文件并创建一个条目,或者在 OSC 结账中运行 `osc vc foo.changes`。第一个 changelog 条目应包含对镜像的简短描述。

添加 README

此步骤不是必需的,但建议用于具有自定义入口点的镜像。有关如何使用镜像及其接受的变量的文档应在此处。

测试

在启用 OBS 上软件包(或整个项目)的发布后,可以通过 registry.opensuse.org 访问该镜像。您可以使用 docker 和 podman 下载它,请参阅 注册表概述页面

位置是 OBS 上的项目名称,其中 ':' 替换为 '/',并附加了仓库(KIWI:`images`,Dockerfile:`containers`)。例如,https://build.opensuse.org/package/show/openSUSE:Templates:Images:Tumbleweed/dockerfile-application-container 构建 `opensuse/example:latest` 并且可用作

 registry.opensuse.org/opensuse/templates/images/tumbleweed/containers/opensuse/example:latest

提交

可以将容器镜像提交到 `openSUSE:Factory` 和 `openSUSE:Leap:15.1` 及更高版本。对于 Leap,可以通过提交维护更新来引入新镜像。

提交到发行版的常用规则适用,因此需要选择一个 devel 项目并将其用作提交基础。

有用的 OBS 服务

多个 OBS 服务通过简化标签定义和版本控制等过程来帮助实施规范。

它们在 _service 文件中添加和配置(请参阅模板中的示例),并在构建开始之前运行各种脚本。

Dockerfile + KIWI: obs-service-kiwi_metainfo_helper

为了能够在标签和标签中包含构建时信息(例如当前构建编号),此服务会替换配方文件中的某些占位符。它适用于 .kiwi 和 Dockerfile 配方。

更新的占位符列表及其内容在软件包本身中,您可以在 此处 阅读。

KIWI only: obs-service-kiwi_label_helper

为了更容易地定义 “org.opensuse.” 命名空间的标签,有一个 OBS 服务可以将 OCI 注释转换为最终标签。

README 的副本

此服务可以在构建时运行,此时它将编辑 kiwi 镜像描述以扩展 `<suse_label_helper:add_prefix/>` 元素。

示例

<image [...] xmlns:suse_label_helper="com.suse.label_helper">
[...]
       <containerconfig [...]>
         <labels>
          <suse_label_helper:add_prefix prefix="org.opensuse.base">
            <label name="org.opencontainers.image.title" value="openSUSE Tumbleweed Base Container"/>
          </suse_label_helper:add_prefix>

扩展到

<image [...] xmlns:suse_label_helper="com.suse.label_helper">
[...]
       <containerconfig [...]>
         <labels>
           <label name="org.opencontainers.image.title" value="openSUSE Tumbleweed Base Container"/>
           <label name="org.opensuse.base.title" value="openSUSE Tumbleweed Base Container"/>

Dockerfile only: obs-service-docker_label_helper

为了更容易地定义 “org.opensuse.” 命名空间的标签,有一个 OBS 服务提供了一个 `PREFIXEDLABEL` 伪指令,该指令将扩展到原始标签以及带有定义的 `labelprefix` 的容器特定标签。

有关详细信息,请参阅 README

使用 KIWI 的技巧

标签 (Tagging)

KIWI 支持 `additionaltags` 属性,OBS 服务(例如 obs-service-kiwi_metainfo_helper)可以将构建时信息添加到标签中。

  <preferences>
    <type image="docker">
       <containerconfig
            name="opensuse/leap"
            tag="15.0.%RELEASE%"
            additionaltags="15.0"
            maintainer="Fabian Vogt &lt;fvogt@suse.com&gt;">
         <labels>

使用 Dockerfile 的技巧

标签 (Tagging)

Dockerfile 配方没有关于应如何命名构建镜像的信息,这在 `docker/podman build` 手动构建镜像时传递。OBS 从 Dockerfile 中的特殊注释中获取此信息,例如:

  #!BuildTag: opensuse/example:1.0 opensuse/example:latest

可以在同一个 `BuildTag` 注释中提及多个名称,或者添加多个此类注释。

发布机制

容器在 `openSUSE:Factory` 和 `openSUSE:Leap:15.x:Images` 中与其他镜像一起构建。`OSRT:ToTestManagerConfig` 属性中的列表,用于每个项目,告诉 totest-manager 机器人哪些构建的镜像是容器镜像,应该发布到注册表而不是下载服务器。

这些镜像发布到 `containers` repo 的 `ToTest` 子项目,在那里它们被推送到 `registry.opensuse.org`,openQA 可以从那里下载和测试它们。这是由 “image”测试模块 完成的,该模块针对多个容器运行时(docker、podman、...)实例化。

在 openQA 将快照/构建标记为良好后,ttm 会将容器从 `ToTest/containers` 发布到其 releasetarget。对于 `openSUSE:Factory:ToTest/containers`,那是 `openSUSE:Containers:Tumbleweed`。这些目标项目在其元数据中设置了 `kind="maintenance_release"`,因此每次发布都会添加二进制文件而不是覆盖它们。这意味着在 OBS 和注册表中可用所有发布的(且未清理的)容器。

对于注册表中的每个 repo(例如 `opensuse/tumbleweed` 和 `kubic/pause`),OBS 中只有一个项目/repo 组合提供向这些 repo 馈送镜像。目前,这对于 Tumbleweed 和 Kubic 来说不是问题,但由于 Leap 的所有版本共享一个 repo,但镜像分布在多个项目(`openSUSE:Containers:Leap:15.x`)上,因此必须解决这个问题。这是通过在 `openSUSE:Containers:Leap` 创建一个中间项目来实现的,该项目聚合最终进入注册表 `opensuse/leap` repo 中的所有二进制文件。原始项目本身被禁用发布,以使其正常工作。

为了提供动态的 `opensuse/leap:latest` 和 `opensuse/leap:15` 标签,这些标签如 项目配置 中所述添加到聚合中。