news 2026/9/25 8:35:04

Buildah 与容器镜像仓库实战指南:私有 Registry 与 Docker Hub 的推送、拉取与互操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Buildah 与容器镜像仓库实战指南:私有 Registry 与 Docker Hub 的推送、拉取与互操作
  • 云原生

【免费下载链接】buildah

A tool that facilitates building OCI images.

项目地址:https://gitcode.com/gh_mirrors/bu/buildah
点击查看免费下载

导读

本篇教程围绕 Buildah 如何将 OCI 兼容镜像移入、移出私有或公有容器镜像仓库(container registry)展开,完整演示从"启动本地私有 Registry"、"推送镜像"、"Skopeo 验证"、"Docker 互操作测试"到"推送/拉取 Docker Hub"的端到端流程。读完本文,你将掌握buildah push、buildah from、buildah pull等命令在仓库场景下的核心用法,理解 transport 协议、--tls-verify、--creds、--pull-always等关键参数的真实语义,并能把 Buildah 构建出的标准 OCI 镜像安全地发布到任意仓库。

本文以仓库中的 docs/tutorials/02-registries-repositories.md 为主体脉络,并结合 cmd/buildah/push.go、cmd/buildah/from.go、cmd/buildah/pull.go 等源码展开原理级解读。

前置条件:上一教程留下的镜像

本文是 Buildah 教程系列的第二篇。在 第一篇教程 中,我们从 scratch 构建了一个名为fedora-bashecho的镜像——一个包含了 bash 脚本runecho.sh、并设置了CMD的小型 OCI 镜像,并且已经用docker-daemon协议把它推送到了本地 Docker daemon。本篇将把同一个镜像推送到一个私有的容器镜像仓库。

如果你还没有这个镜像,可以按第一篇教程的流程重新构建:从 scratch 创建空容器、用buildah copy放入脚本、buildah config --cmd配置启动命令、最后buildah commit生成镜像:

# newcontainer=$(buildah from scratch) # buildah copy $newcontainer ./runecho.sh /usr/bin/ # buildah config --cmd /usr/bin/runecho.sh $newcontainer # buildah commit $newcontainer fedora-bashecho

理解镜像来源与目标:Buildah 的 transport 机制

buildah from、buildah push、buildah pull等命令在指定镜像时都遵循transport:details的格式。默认(且隐含假设)的查找顺序是:先看本地 containers-storage(containers-storage:)中是否已有该镜像,再去容器镜像仓库(默认是 Docker Hub,docker:)拉取。

以buildah from为例,其源码中的示例直接体现了多种 transport 的写法(见 cmd/buildah/from.go):

# buildah from --pull imagename # buildah from docker-daemon:imagename:imagetag # buildah from --name "myimagename" myregistry/myrepository/imagename:imagetag

也就是说,如果本地 Docker daemon 中已经下载好了 registry 镜像,就不必再去仓库拉取,可以直接用docker-daemontransport 引用它:

# registryctr=$(buildah from docker-daemon:registry:latest)

同理,在buildah push侧(见 cmd/buildah/push.go),如果目标地址没有显式给出 transport,源码会自动补上docker://并按容器镜像仓库处理:

# buildah push imageID docker://registry.example.com/repository:tag # buildah push imageID docker-daemon:image:tag # buildah push imageID oci:/path/to/layout:image:tag

从源码看,push命令支持docker、docker-daemon、oci、oci-archive、dir等全部containers-transports(5)所列的 transport;不指定 transport 时,日志会提示Assuming docker:// as the transport method for DESTINATION。

第一步:拉取并启动本地私有 Registry

在推送镜像之前,需要先有一个接收镜像的仓库。最简单的方式是直接拉取官方 registry 镜像,并把buildah from返回的容器名保存到 bash 变量中(与第一篇教程中的做法一致):

# registryctr=$(buildah from registry)

提示:使用docker-daemontransport 也可以复用 Docker daemon 中已有的 registry 镜像,避免重复从 Docker Hub 下载:

# registryctr=$(buildah from docker-daemon:registry:latest)

接下来启动这个 registry 容器。建议在单独的终端(shell)中启动并让它保持前台运行:

# buildah run --net=host $registryctr /entrypoint.sh /etc/docker/registry/config.yml

这里使用了--net=host让容器共享宿主机网络栈,这样 registry 直接监听宿主机的 5000 端口;/entrypoint.sh /etc/docker/registry/config.yml是 registry 容器镜像内置的启动入口与默认配置文件路径。

如果希望看到 registry 内部的更多细节,尤其是排查推送/拉取问题时,可以用 debug 日志级别重新启动:

# buildah --log-level=debug run --net=host $registryctr /entrypoint.sh /etc/docker/registry/config.yml

--log-level=debug是 Buildah 的全局选项,可以加在任何 Buildah 命令前面,用于输出底层调用链日志(例如push源码中大量使用logrus.Debugf记录 transport 假设、镜像 digest 等信息,见 cmd/buildah/push.go)。

需要注意:这里运行的 registry 是从 Docker Hub 拉取的Docker registry 镜像,但它是通过buildah run直接运行的——此刻并没有任何 Docker daemon 在运行,这也再次印证了 Buildah 无守护进程(daemon-less)的特性。

第二步:推送镜像到私有 Registry

Registry 启动后就在等待处理请求。现在把fedora-bashecho推送到本地私有仓库。

默认情况下,Buildah只允许到仓库的安全(HTTPS)连接并验证证书。因此,对于运行在 localhost:5000 上的明文(HTTP)本地 registry,需要显式关闭 TLS 验证:

# buildah push --tls-verify=false fedora-bashecho docker://localhost:5000/ipbabble/fedora-bashecho:latest

这条命令中有三个要点:

  1. --tls-verify=false:关闭 HTTPS 证书校验。在push命令的源码(cmd/buildah/push.go)中,该标志默认值为true,其说明为"require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.";从 pkg/parse/parse.go 的SystemContextFromOptions可以看到,--tls-verify=false最终会转换为DockerInsecureSkipTLSVerify = true并同步作用于 OCI 与 docker-daemon 传输。
  2. docker://localhost:5000/ipbabble/fedora-bashecho:latest:显式指定 transport 与仓库地址。localhost:5000是刚才 registry 监听的主机与端口。
  3. ipbabble命名空间:类似多租户的 Docker Hub,仓库 URL 中的第二段(这里是ipbabble)用于区分不同用户的同名镜像,避免与他人相似命名的镜像冲突。

第三步:用 Skopeo 验证镜像已入库

Skopeo 是 containers 生态中专门用于在仓库中直接检查镜像而无需先把镜像拉下来的工具,它已经发展出很多其他用途。验证镜像是否成功存入私有 registry:

# skopeo inspect --tls-verify=false docker://localhost:5000/ipbabble/fedora-bashecho:latest { "Name": "localhost:5000/ipbabble/fedora-bashecho", "Digest": "sha256:6806f9385f97bc09f54b5c0ef583e58c3bc906c8c0b3e693d8782d0a0acf2137", "RepoTags": [ "latest" ], "Created": "2017-12-05T21:38:12.311901938Z", "DockerVersion": "", "Labels": { "name": "fedora-bashecho" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:0cb7556c714767b8da6e0299cbeab765abaddede84769475c023785ae66d10ca" ] }

输出中的Digest(sha256:6806f938...)是镜像内容寻址的唯一标识,Layers列表则对应镜像的文件系统层。这个 digest 在后面 Docker 拉取验证时会出现一致的值,这是 OCI 镜像内容可移植性的直接证据。

第四步:验证对 Docker 的可移植性

OCI 镜像最核心的价值之一就是跨引擎可移植。重新启动 Docker(和第一篇教程一样),然后从私有 registry 拉取并运行这个镜像:

# systemctl start docker # docker pull localhost:5000/ipbabble/fedora-bashecho Using default tag: latest Trying to pull repository localhost:5000/ipbabble/fedora-bashecho ... sha256:6806f9385f97bc09f54b5c0ef583e58c3bc906c8c0b3e693d8782d0a0acf2137: Pulling from localhost:5000/ipbabble/fedora-bashecho 0cb7556c7147: Pull complete Digest: sha256:6806f9385f97bc09f54b5c0ef583e58c3bc906c8c0b3e693d8782d0a0acf2137 Status: Downloaded newer image for localhost:5000/ipbabble/fedora-bashecho:latest # docker run --rm localhost:5000/ipbabble/fedora-bashecho This is a new container named ipbabble [ 0 ] This is a new container named ipbabble [ 1 ] This is a new container named ipbabble [ 2 ] This is a new container named ipbabble [ 3 ] This is a new container named ipbabble [ 4 ] This is a new container named ipbabble [ 5 ] This is a new container named ipbabble [ 6 ] This is a new container named ipbabble [ 7 ] This is a new container named ipbabble [ 8 ] This is a new container named ipbabble [ 9 ] # systemctl stop docker

注意 Docker 拉取时显示的 digest 与 Skopeo inspect 输出完全一致,且容器按镜像CMD配置直接运行了runecho.sh脚本。验证完毕后可以停掉 Docker daemon(systemctl stop docker)——它在本例中仅用于互操作性演示。

第五步:推送镜像到 Docker Hub

推送 Docker Hub 与推送私有 registry 一样简单,前提是你拥有带凭据的账户。下面示例使用的是 Docker Hub 的 API key,其形式为username:password(示例密码已做隐私脱敏处理):

# buildah push --creds=ipbabble:5bbb9990-6eeb-1234-af1a-aaa80066887c fedora-bashecho docker://ipbabble/fedora-bashecho:latest

要点说明:

  • --creds:指定仓库访问凭据,格式为[username[:password]]。在push源码(cmd/buildah/push.go)中,--creds的说明是"use[username[:password]]for accessing the registry";它最终会被解析进SystemContext.DockerAuthConfig(见 pkg/parse/parse.go)。如果只给用户名或完全省略,命令行会交互式提示输入缺失部分,密码输入时不回显。
  • docker://ipbabble/fedora-bashecho:latest:不写 registry 主机名和端口,即使用 Docker Hub 的默认主机与默认 443 端口,这是 docker transport 的默认行为。

同样用 Skopeo 验证(注意 Docker Hub 场景也需要--creds访问私有仓库):

# skopeo inspect --creds ipbabble:5bbb9990-6eeb-1234-af1a-aaa80066887c docker://ipbabble/fedora-bashecho:latest { "Name": "docker.io/ipbabble/fedora-bashecho", "Digest": "sha256:6806f9385f97bc09f54b5c0ef583e58c3bc906c8c0b3e693d8782d0a0acf2137", "RepoTags": [ "latest" ], "Created": "2017-12-05T21:38:12.311901938Z", "DockerVersion": "", "Labels": { "name": "fedora-bashecho" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:0cb7556c714767b8da6e0299cbeab765abaddede84769475c023785ae66d10ca" ] }

注意此时镜像的Name变成了docker.io/ipbabble/fedora-bashecho,而Digest与之前在私有 registry 中的完全一致——同一镜像内容在不同仓库间保持字节级一致。

登录方式的补充说明:除了每次推送时用--creds,更推荐用buildah login保存凭据。buildah login是独立命令(见 cmd/buildah/login.go,例如buildah login quay.io),它会把凭据写入认证文件(默认${XDG_RUNTIME_DIR}/containers/auth.json,见 docs/buildah-push.1.md),后续推送/拉取会自动使用;也可用REGISTRY_AUTH_FILE环境变量覆盖默认认证文件路径。

第六步:从仓库拉取镜像

现在用buildah from从 Docker Hub 把镜像拉取回来。但在拉取之前,先清理本地 containers-storage,确保本地没有fedora-bashecho的副本——否则 Buildah 会发现镜像已存在而跳过拉取。

先查看当前本地镜像:

# buildah images IMAGE ID IMAGE NAME CREATED AT SIZE d4cd7d73ee42 docker.io/library/registry:latest Dec 1, 2017 22:15 31.74 MB e31b0f0b0a63 docker.io/library/fedora-bashecho:latest Dec 5, 2017 21:38 772 B

删除本地的fedora-bashecho镜像:

# buildah rmi fedora-bashecho untagged: docker.io/library/fedora-bashecho:latest e31b0f0b0a63e94c5a558d438d7490fab930a282a4736364360ab9b92cb25f3a

确认镜像已删除:

# buildah images IMAGE ID IMAGE NAME CREATED AT SIZE d4cd7d73ee42 docker.io/library/registry:latest Dec 1, 2017 22:15 31.74 MB

然后从 Docker Hub 拉取(不带 registry 主机名,默认走 Docker Hub):

# buildah from ipbabble/fedora-bashecho

再检查本地 containers-storage,确认镜像已就位:

# buildah images IMAGE ID IMAGE NAME CREATED AT SIZE d4cd7d73ee42 docker.io/library/registry:latest Dec 1, 2017 22:15 31.74 MB 864871ac1c45 docker.io/ipbabble/fedora-bashecho:latest Dec 5, 2017 21:38 315.4 MB

成功!镜像已经从 Docker Hub 拉取到本地存储。

不想手动清理?用--pull-always强制拉取

如果不想先执行rmi清理步骤,可以直接用--pull-always标志强制重新拉取镜像并覆盖本地同名镜像:

# buildah from --pull-always ipbabble/fedora-bashecho

从 cmd/buildah/from.go 源码看,--pull-always与--pull-never都是为兼容旧习惯保留的隐藏标志,推荐的正式用法是--pull参数,其取值语义如下:

取值行为
always即使本地已有同名镜像也强制从仓库拉取
missing(默认)仅当本地没有该镜像时才拉取
never只使用本地已有镜像,绝不访问仓库
newer仅当仓库中的镜像比本地更新时才拉取

--pull不带参数时等价于--pull=always(源码中通过NoOptDefVal = "always"实现)。独立的buildah pull命令(见 cmd/buildah/pull.go)也提供--policy missing|always|ifnewer|never、--all-tags(下载仓库中所有标签)、--platform/--arch/--os(按平台拉取)等选项,适合只下载镜像而不创建工作容器的场景。

参考:push 命令的常用选项速查

结合 docs/buildah-push.1.md 与 cmd/buildah/push.go,buildah push在仓库场景下常用的选项包括:

选项作用
--tls-verify是否要求 HTTPS 并验证证书,默认true;访问明文/自签名证书仓库需设为false
--creds [username[:password]]仓库访问凭据;缺省部分交互式输入
--authfile path认证文件路径,默认${XDG_RUNTIME_DIR}/containers/auth.json
--cert-dir path指定访问仓库用的 CA 证书目录(默认/etc/containers/certs.d)
--format oci|v2s2|v2s1推送到目标时使用的 manifest 类型(默认跟随源镜像)
--digestfile file推送完成后把镜像 digest 写入指定文件
--quiet, -q关闭进度输出
--retry/--retry-delay推送失败重试次数(默认 3)与重试间隔(默认 2s)
--remove-signatures推送时不复制签名
--sign-by fingerprint用指定 GPG 指纹对推送的镜像签名

另外,BUILD_REGISTRY_SOURCES环境变量(JSON 格式,含insecureRegistries、blockedRegistries、allowedRegistries三组列表)可用于按仓库名限制允许推送的 registry;registries.conf(/etc/containers/registries.conf)则负责在镜像名不含 registry 部分时决定查询哪些仓库。

小结

通过本教程,你已经完成了 Buildah 与容器镜像仓库的完整交互闭环:

  1. 启动私有 Registry:buildah from registry+buildah run --net=host,全程无需 Docker daemon;
  2. 推送私有仓库:buildah push --tls-verify=false fedora-bashecho docker://localhost:5000/ipbabble/fedora-bashecho:latest;
  3. Skopeo 验证入库:在不拉取镜像的前提下核对 digest、标签、标签层信息;
  4. Docker 互操作验证:docker pull/docker run直接运行 Buildah 构建的镜像,digest 完全一致;
  5. 推送 Docker Hub:--creds携带凭据,默认 transport 自动指向 Docker Hub;
  6. 拉取回本地:buildah from/--pull-always强制覆盖,或用buildah pull --policy精细控制拉取策略。

整个过程验证了 Buildah 构建的 OCI 镜像在私有仓库、公有仓库与不同容器引擎之间具备一致的内容寻址(digest)与良好的可移植性。更多命令细节可参考仓库中的buildah-push(1)、buildah-from(1)、buildah-pull(1)等手册页(docs 目录),以及 Buildah 与 Podman 关系、安装说明等文档(README.md、install.md)。

  • 云原生

【免费下载链接】buildah

A tool that facilitates building OCI images.

项目地址:https://gitcode.com/gh_mirrors/bu/buildah
点击查看免费下载

相关推荐

上一篇:Powerlevel10k 字体配置完整指南:5 步搞定终端特殊符号变方框的问题
下一篇:npm-check-updates配置验证功能:避免常见的配置错误

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 8:34:55

关键信息基础设施网络安全保护基本要求:五环节闭环与工程化落地指南

简介:这份资源是《信息安全技术 关键信息基础设施网络安全保护基本要求》的国家标准征求意见稿文档,面向网络安全从业者、等保测评人员及合规管理人员,用于理解关键信息基础设施安全保护的规范框架与落地要求。文档围绕识别认定、安全防护、检…

作者头像 李华
网站建设 2026/9/25 8:32:27

APK反编译工具链实战:jadx+apktool+签名全流程

简介:面向Android开发、逆向工程与安全测试场景的APK反编译工具整合包,汇集dex2jar、JD-GUI与Apktool三款主流组件,可帮助使用者查看APK内部结构、还原Java源码、提取资源文件并重新打包应用,适合需要分析第三方应用逻辑或开展安全…

作者头像 李华
网站建设 2026/9/25 8:29:50

AI编程工具插件窃取密钥的四大路径与防御实战

1. 一个插件如何成为密钥收割机先说说我上周遇到的一件真事。团队里一个刚入行半年的小伙子,在本地用某款主流AI编程工具写业务代码,图省事装了一个号称"智能补全增强"的第三方插件。三天后,他收到云服务商的账单告警——有人用他的…

作者头像 李华
网站建设 2026/9/25 8:29:38

磁力搜索与下载工具全解析:从原理到实战优化指南

1. 磁力搜索与下载工具的核心逻辑拆解1.1 磁力链接到底是什么,为什么它比传统下载更抗压很多人第一次接触磁力搜索,脑子里冒出来的问题是:这玩意儿跟普通下载到底差在哪。我用一个生活化的类比来解释——传统下载就像你去一家指定的书店买书&…

作者头像 李华