Podman 系统注册表配置文件 containers-registries.conf

CONTAINERS-REGISTRIES 配置文件是用于容器镜像注册表的全局配置文件,其格式为 TOML。TOML(Tom's Obvious, Minimal Language)是一种易读、强类型的配置文件格式,设计目标是 “为人设计的配置语言”,比 JSON 更贴近手写习惯,比 YAML 更简洁无歧义,被广泛用于容器配置(如 Podman 的 registries.conf)、编程语言配置(如 Rust/Cargo)、工具链配置(如 Hugo、Terraform)等场景。

CONTAINERS-REGISTRIES 配置文件是用于容器镜像注册表的全局配置文件,其格式为 TOML。

TOML(Tom's Obvious, Minimal Language)是一种易读、强类型的配置文件格式,设计目标是 “为人设计的配置语言”,比 JSON 更贴近手写习惯,比 YAML 更简洁无歧义,被广泛用于容器配置(如 Podman 的 registries.conf)、编程语言配置(如 Rust/Cargo)、工具链配置(如 Hugo、Terraform)等场景。

容器引擎会优先使用 $HOME/.config/containers/registries.conf(若存在),否则将使用 /etc/containers/registries.conf。

全局设置

  • unqualified-search-registries:按顺序尝试拉取未限定镜像时使用的 host[:port] 注册表数组(什么是未限定镜像,即短名称镜像,如 redis,它的全称为 docker.io/library/alpine/redis:latest)。

  • credential-helpers:用于作为外部凭证存储的默认凭证助手数组。请注意,containers-auth.json 是保留值,用于使用 containers-auth.json(5) 中指定的身份验证文件。若未指定任何凭证助手,则默认设置为 ["containers-auth.json"]。

  • additional-layer-store-auth-helper:包含辅助程序二进制名称的字符串。启用后,每次通过 docker:// 传输协议读取镜像时,将向附加层存储传递注册表凭证,使其能够访问私有注册表。更多细节请参阅下文“启用额外层存储以访问私有注册表”章节。

命名空间 [[registry]] 设置

配置的主体以 [[registry]] TOML 表数组的形式呈现;因此,不同注册表之间的设置可能存在差异,同一注册表内不同命名空间/存储库之间的设置也可能不同。

选择一个 [[registry]] TOML 表

根据镜像名称,基于其前缀字段选择单个 [[registry]] TOML表。

prefix:用户指定镜像名称的前缀,即采用以下格式之一:

  • host[:port]

  • host[:port]/namespace[/namespace…]

  • host[:port]/namespace[/namespace…]/repo

  • host[:port]/namespace[/namespace…]/repo(:_tag|@digest)

  • [*.]host

用户指定的镜像名称必须以特定前缀开头(并以适当的分隔符继续),才能被特定的 [[registry]] TOML 表考虑;(仅)使用匹配最长的 TOML 表。它还可以包含通配符子域,格式为 *.example.com。通配符应仅出现在开头,如上述格式所示。其他情况将失效。例如:*.example.com 有效,但 example.*.com、*.example.com/foo 及 *.example.com:5000/foo/bar:baz 均无效。需注意 * 可匹配任意数量的子域名,因此 *.example.com 将匹配 bar.example.com、foo.bar.example.com 等域名。

示例:

unqualified-search-registries = ["example.com"]

[[registry]]
prefix = "example.com/foo"
insecure = false
blocked = false
location = "internal-registry-for-example.com/bar"

特殊情况:prefix 字段可省略,此时默认采用 location 字段(详见下文)的值。

命名空间级别的设置

  • insecure:true 或 false。默认情况下,容器运行时从注册表获取镜像时需要 TLS 加密。若设置为 true,则允许使用未加密的 HTTP 以及使用未受信任证书的 TLS 连接。

  • blocked:true 或 false。若为 true,则禁止拉取名称匹配的镜像。

重新映射和镜像注册表

用户指定的镜像引用本质上是一个“逻辑”镜像名称,始终用于命名镜像。默认情况下,镜像引用还会直接指定要使用的注册表和仓库,但可通过以下选项将底层访问重定向至不同的注册表服务器或位置(例如:在无需修改 Dockerfile 的情况下支持无网络访问的配置,或增加冗余)。

location:接受与前缀字段相同的格式,用于指定前缀为根的命名空间的物理位置。

默认情况下,该值等同于前缀(此时可省略前缀,且 [[registry]] TOML 表仅能指定 location)。

示例:

prefix = "example.com/foo"
location = "internal-registry-for-example.com/bar"

对镜像 example.com/foo/myimage:latest 的请求实际上会与内部注册表 internal-registry-for-example.com/bar/myimage:latest 中的镜像匹配。

若使用包含通配符的前缀(格式:*.example.com)进行子域匹配,位置字段可留空。此时将执行前缀匹配,但不进行引用重写。原始请求的镜像字符串将保持不变,但其他设置(如不安全/被封锁/镜像站点规则)仍会应用于匹配的镜像。

示例:

prefix = "*.example.com"

对镜像 blah.example.com/foo/myimage:latest 的请求将按原样使用。但其他设置(如不安全/被阻止/镜像)将应用于匹配的镜像。

mirror :一个TOML表数组,用于指定前缀根命名空间(即当前 [[registry]] TOML表)的(可能不完整的)镜像。

镜像按指定顺序尝试连接;首个可连接且包含镜像的镜像将被采用(若所有镜像均无镜像,则最后尝试由 registry.location 字段指定的主存储位置,或使用用户未修改的参考路径)。

镜像数组中的每个 TOML 表可包含以下字段:

  • location: 与 [[registry]] TOML 表格中指定的语义相同

  • insecure: 与 [[registry]] TOML 表格中指定的语义相同

  • pull-from-mirror: all, digest-only 或 tag-only。若设置为“digest-only”模式,镜像服务器仅用于摘要拉取。通过标签拉取镜像时,可能因拉取源端点不同而获得不同镜像。限制镜像仅用于摘要拉取可避免此问题。若设置为“tag-only”,镜像仅用于标签拉取。对于更新及时但资源消耗较高的镜像(即使标签变更也不易失效),不应将其用于摘要引用。默认值为“all”(或留空),此时镜像将同时用于摘要拉取和标签拉取,除非主注册表配置了mirror-by-digest-only选项。需注意:此项镜像级设置仅在主注册表未配置mirror-by-digest-only时才允许使用。

mirror-by-digest-only : true 或 false。若为true,则仅当镜像引用包含摘要时,镜像才会在拉取过程中使用。注意:若所有镜像均配置为仅摘要模式,则标签引用的镜像将仅使用主注册表;若所有镜像均配置为仅标签模式,则摘要引用的镜像将仅使用主注册表。

通过摘要引用镜像可确保始终使用同一镜像(而通过标签引用镜像可能导致不同注册表返回不同镜像,若标签映射出现不同步)。

注意:重定向和镜像功能目前仅在读取单个镜像时生效,不适用于向注册表推送数据或在注册表中执行其他类型的查找/搜索操作。此机制未来可能调整。

短名称别名

使用未限定搜索注册表会导致歧义,因为无法确定通过短名称引用的特定镜像将从哪个注册表中获取。

如本手册页末注释所述,使用短名称存在遭遇注册表命名空间被占用的风险。若未限定搜索的注册表设置为[“registry1.com”, “registry2.com”],攻击者可能接管registry1.com的命名空间,导致镜像被从registry1.com而非预期来源registry2.com拉取。

虽然强烈建议始终使用完全限定的镜像引用,但现有部署中使用的短名称可能难以更改。为规避上述歧义,可配置所谓的短名称别名,使其指向完全限定的镜像引用。

短名别名可在 [aliases] 表中配置,格式为 "name"="value",其中左侧名称为短名(例如“image”),右侧值为完全限定的镜像引用(例如“registry.com/namespace/image”)。请注意,“name”和“value”均不可包含标签或摘要。此外,“name”必须是短名称,因此不能包含注册表域名或指向本地主机。

在解析短名称时,系统将使用配置的别名表进行解析。若找到匹配的别名,则直接采用该别名,不再继续查询未限定搜索注册表列表。若未找到匹配别名,则可通过下文所述的短名称模式选项控制后续行为。

注意,在别名解析过程中,用户指定的短名称会去除标签和摘要。因此,“image”、“image:tag” 和 “image@digest” 均解析为同一别名(即 “image”)。被移除的标签和摘要将在后续解析后附加到最终别名上。

请注意,即插即用配置文件(参见 containers-registries.conf.d(5))可根据文件加载顺序覆盖别名。若别名的“value”字段为空(即“”),该别名将被清除。但需注意,单个配置文件中同一“name”仅可出现一次。

短名称别名:模式

short-name-mode 选项支持三种模式来控制短名解析的行为:

  • enforcing: 如果只设置了一个未限定搜索的注册表,就使用它,因为不存在歧义。如果有多个注册表,且用户程序正在终端中运行(即标准输出和标准输入是 TTY),则提示用户从指定的搜索注册表中选择一个。如果程序不在终端中运行,这种歧义就无法解决,从而会导致错误。

  • permissive: 其行为与 enforcing 模式类似,但如果程序不在终端中运行,不会导致错误。相反,会退回到使用所有未限定搜索的注册表。

  • disabled: 不提示就使用所有未限定搜索的注册表。

如果完全未指定 short-name-mode 或使其为空,则默认采用 permissive 模式。如果用户指定的短名称尚未设置别名,那么在成功拉取后,enforcing 模式和 permissive 模式(若有提示)会记录一个新别名。请注意,对于 root 用户,所记录的别名将写入 /var/cache/containers/short-name-aliases.conf,以便清晰区分可能由人工编辑的 registries.conf 文件和机器生成的 short-name-aliases.conf。需要注意的是,无 root 权限的用户会使用 $HOME/.cache。如果某个别名既在 registries.conf 文件中指定,又在机器生成的 short-name-aliases.conf 中指定,那么 short-name-aliases.conf 文件具有更高的优先级。

docker.io 引用的规范化

Docker Hub(即docker.io)的处理方式很特殊:如果未定义其他特定命名空间(例如对于 docker.io/namespace/image),那么每次推送和拉取操作在内部都会被规范化为加上 /library。

(请注意,上述描述的规范化恰好与Docker的行为一致。)

这意味着拉取 docker.io/alpine 会在内部被转换为 docker.io/library/alpine。而拉取 docker.io/user/alpine 则不会被重写,因为这已经是正确的远程路径。。

因此,要重新映射或镜像(隐含的)/library命名空间中的docker.io镜像(或整个命名空间),此配置文件中的prefix(前缀)和location(位置)字段必须明确包含该/library命名空间。例如,应使用prefix = "docker.io/library/alpine",而不是prefix = "docker.io/alpine"。后者会匹配docker.io/alpine/*仓库,但不会匹配docker.io/[library/]

因此,若要重映射或镜像(隐含的)/library 命名空间(或整个命名空间)中的 docker.io 镜像,该配置文件中的前缀(prefix)和位置(location)字段必须明确包含该 /library 命名空间。例如应设置 prefix="docker.io/library/alpine",而非 prefix="docker.io/alpine"。后者将匹配 docker.io/alpine/* 仓库,但不会匹配 docker.io/[library/]alpine 镜像。

示例

unqualified-search-registries = ["example.com"]

[[registry]]
prefix = "example.com/foo"
insecure = false
blocked = false
location = "internal-registry-for-example.com/bar"

[[registry.mirror]]
location = "example-mirror-0.local/mirror-for-foo"

[[registry.mirror]]
location = "example-mirror-1.local/mirrors/foo"
insecure = true

[[registry]]
location = "registry.com"

[[registry.mirror]]
location = "mirror.registry.com"

详细说明:

1、无前缀镜像的默认搜索规则

unqualified-search-registries = ["example.com"]

表示当你拉取无仓库前缀的镜像时(如 podman pull alpine),容器工具会自动为镜像补全前缀 example.com/,即实际拉取 example.com/alpine。

2、自定义仓库规则1:精准匹配 example.com/foo 前缀的镜像

[[registry]]
prefix = "example.com/foo"  # 匹配前缀:所有以 example.com/foo 开头的镜像
insecure = false            # 强制HTTPS:访问该仓库必须用HTTPS(拒绝HTTP/自签名证书)
blocked = false             # 允许访问:不拉黑该仓库
location = "internal-registry-for-example.com/bar"  # 地址映射:拉取 example.com/foo/xxx 时,实际访问 internal-registry-for-example.com/bar/xxx

[[registry.mirror]]
location = "example-mirror-0.local/mirror-for-foo"  # 镜像加速器1:优先从这个镜像地址拉取

[[registry.mirror]]
location = "example-mirror-1.local/mirrors/foo"     # 镜像加速器2:加速器1失败时,尝试这个地址
insecure = true                                      # 加速器2允许HTTP:该镜像地址可走非HTTPS

当你执行 podman pull example.com/foo/nginx 时:

  1. 容器工具先匹配到 prefix = "example.com/foo" 的规则;

  2. 优先尝试第一个镜像加速器 example-mirror-0.local/mirror-for-foo/nginx(强制 HTTPS,因为该镜像未单独设 insecure,继承父级 false);

  3. 若加速器 1 失败,尝试第二个镜像加速器 example-mirror-1.local/mirrors/foo/nginx(允许 HTTP,因为该镜像单独设 insecure = true);

  4. 若所有镜像都失败,最终访问真实地址 internal-registry-for-example.com/bar/nginx(强制 HTTPS)。

3、自定义仓库规则 2:无前缀的仓库(默认匹配所有未命中的镜像)

[[registry]]
location = "registry.com"  # 无prefix,匹配所有未被其他规则覆盖的镜像

[[registry.mirror]]
location = "mirror.registry.com"  # 该仓库的镜像加速器:拉取 registry.com/xxx 时,优先走 mirror.registry.com/xxx

所有未被 example.com/foo 前缀匹配的镜像(如 registry.com/redis),会使用此规则:

  1. 拉取 registry.com/redis 时,优先尝试镜像加速器 mirror.registry.com/redis;

  2. 加速器失败则访问原仓库 registry.com/redis;

  3. 未显式设置 insecure/blocked,默认值为 insecure = false(强制 HTTPS)、blocked = false(允许访问)。

鉴于上述情况,拉取 example.com/foo/image:latest 将会尝试:

  1. example-mirror-0.local/mirror-for-foo/image:latest

  2. example-mirror-1.local/mirrors/foo/image:latest

  3. internal-registry-for-example.com/bar/image:latest

按顺序,并使用第一个存在的。

请注意,镜像仅与当前的 [[registry]] TOML 表相关联。如果使用上面的示例,拉取镜像 registry.com/image:latest 将只会访问 mirror.registry.com,而与 example.com/foo 相关联的镜像将不会被考虑。

启用额外层存储以访问私有注册表

additional-layer-store-auth-helper 选项允许将注册表凭据传递给额外层存储,以便它能够访问私有注册表。

通过额外层存储访问私有注册表时,需要提供一个辅助二进制文件。此辅助二进制文件通过 additional-layer-store-auth-helper 选项进行注册。每次使用 docker:// 传输读取镜像时,指定的辅助二进制文件都会被执行,并通过标准输入以以下格式接收注册表凭据。

{
  "$image_reference": {
    "username": "$username",
    "password": "$password",
    "identityToken": "$identityToken"
  }
}

$image_reference 的格式为 $repo{:$tag|@$digest} 。

额外的层存储可以使用这个辅助二进制文件来访问私有注册表。

版本1 格式 - 已弃用

版本1格式仍受支持,但不支持使用注册表镜像、最长前缀匹配或位置重写。

TOML格式用于在三个类别下构建一个简单的注册表列表:registries.search、registries.insecure 和 registries.block。你可以使用逗号分隔的列表来列出多个注册表。

当容器运行时的调用者没有完整指定他们想要执行的容器镜像时,就会使用搜索注册表。这些注册表会被添加到指定容器镜像的前面,直到在某个注册表中找到该命名镜像为止。

注意,不安全的注册表可用于任何注册表,而不仅仅是在搜索项下列出的那些注册表。

registries.insecure 和 registries.block 列表与当前版本中的 insecure 和 blocked 字段含义相同。

示例

以下示例配置定义了两个可搜索的注册表、一个不安全的注册表和两个被阻止的注册表:

[registries.search]
registries = ['registry1.com', 'registry2.com']

[registries.insecure]
registries = ['registry3.com']

[registries.block]
registries = ['registry.untrusted.com', 'registry.unsafe.com']

注意:使用非限定镜像名称的风险

我们建议始终使用包含注册服务器(完整域名)、命名空间、镜像名称和标签的完整镜像名称(例如:registry.redhat.io/ubi8/ubi:latest)。使用短名称时,始终存在被拉取镜像可能被伪造的固有风险。例如:用户期望从 myregistry.com 注册表拉取名为 foobar 的镜像。若 myregistry.com 未位于搜索列表首位,攻击者可在更靠前的注册表放置伪造的 foobar 镜像。此时用户将误拉取并运行攻击者植入的镜像与代码,而非预期内容。我们建议仅添加完全可信的注册库,即禁止未知或匿名用户创建任意名称账户的注册库。此举可防止镜像遭伪造、抢注或产生其他安全隐患。若必须使用此类注册库,应将其添加至列表末尾。

建议在拉取镜像时使用完全限定的镜像,因为这样目标 registry 是明确的。通过摘要拉取镜像(即 quay.io/repository/name@digest)能进一步消除标签的歧义。

另请参阅

containers-auth.json(5) containers-certs.d(5)

历史记录

2019年12月,Tom Sweeney 添加了针对不合格镜像名称的警告 tsweeney@redhat.com

2019年3月,Sascha Grunert 添加了额外的配置格式 sgrunert@suse.com

2018年8月,Valentin Rothberg 将其重命名为 containers-registries.conf(5) vrothberg@suse.com

2018年6月,由Tom Sweeney更新 tsweeney@redhat.com

2017年8月,由Brent Baude最初编译 bbaude@redhat.com

  

原文地址:https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md

  

尺有所短;寸有所长。物有所不足;智有所不明。——屈原《卜居》
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号