首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >OCI 镜像规范详解

OCI 镜像规范详解

作者头像
宅蓝三木
发布2026-03-06 09:33:52
发布2026-03-06 09:33:52
900
举报
文章被收录于专栏:三木的博客三木的博客

在容器技术发展的早期,Docker 镜像是事实上的标准。随着容器生态的爆发,为了确保不同容器运行时(如 Docker, containerd, CRI-O, Podman 等)和构建工具之间的互操作性,Open Container Initiative (OCI) 成立并推出了 OCI Image Specification

本文将基于最新的 OCI Image Specification 详细解读 OCI 镜像的构成及其背后的技术细节。

OCI 镜像规范概览

OCI 镜像规范定义了 OCI 镜像的结构。简单来说,一个 OCI 镜像包含以下几个核心部分:

  1. Image Manifest (镜像清单): 描述构成镜像的组件(包括配置和层)。
  2. Image Index (镜像索引): (可选) 指向多个 Manifest 的列表,通常用于支持多架构(如 amd64, arm64)。
  3. Image Layout (镜像布局): 镜像在文件系统上的目录结构。
  4. Filesystem Layer (文件系统层): 包含了容器文件系统的更改集 (Changeset)。
  5. Image Configuration (镜像配置): 包含了镜像的元数据(如启动命令、环境变量)以及层级顺序。

这些组件共同工作,使得镜像可以被构建、传输、校验并最终运行。

核心概念:Content Descriptors (内容描述符)

在深入各个组件之前,必须先理解 Content Descriptor。它是 OCI 规范中用来引用内容的通用方式。

一个描述符(Descriptor)就是一个 JSON 对象,它告诉我们“去哪里找内容”、“内容长什么样”以及“内容的指纹是什么”。核心字段包括:

  • mediaType: 内容的类型(例如:application/vnd.oci.image.manifest.v1+json)。
  • digest: 内容的哈希摘要(通常是 sha256),用于唯一标识和校验内容。
  • size: 内容的大小(字节)。
代码语言:javascript
复制
{
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "size": 7682,
  "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270"
}

OCI 广泛使用了 Merkle Directed Acyclic Graph (DAG) 结构,描述符就是图中的边,连接了不同的组件。

组件结构详解

OCI 镜像的结构关系如下图所示:

1. Image Manifest (镜像清单)

Manifest 是镜像的“物料清单”。对于一个特定的架构和操作系统,Manifest 定义了镜像由哪些层组成,以及配置文件的位置。

一个典型的 Manifest JSON 结构如下:

代码语言:javascript
复制
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.manifest.v1+json",
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:b5b2b2...",
    "size": 7023
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:983487...",
      "size": 32654
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:3c3a46...",
      "size": 16724
    }
  ],
  "annotations": {
    "com.example.key1": "value1"
  }
}
  • config: 引用镜像配置 Blob。
  • layers: 一个有序数组,引用了组成文件系统的各个层 Blob。数组索引 0 是底层 (Base Layer),后续层依次叠加。

2. Image Configuration (镜像配置)

Configuration 是一个 JSON 文档,包含了将镜像转换为运行时 Bundle 所需的信息。它不包含文件系统的实际内容,而是包含元数据。

主要包含:

  • architecture / os: 适用的 CPU 架构和操作系统。
  • config: 运行时配置,如 Env (环境变量), Cmd (默认命令), Entrypoint, User, WorkingDir 等。
  • rootfs: 引用了由于层叠加而产生的 Diff IDs,用于校验文件系统完整性。
  • history: 描述了每一层是如何构建出来的(例如 Dockerfile 中的指令)。

3. Filesystem Layers (文件系统层)

Layers 包含了文件系统的实际变化。每一个层通常是一个 .tar.tar.gz 归档文件。

OCI 镜像采用分层存储写时复制 (CoW) 策略。每一层只记录相对于上一层的 变化 (Changeset) 。变化主要有三种类型:

  1. Add (新增): 包含了完整的文件或目录内容。
  2. Modify (修改): 包含了修改后文件的完整内容。在 Tar 包中,增加和修改的表现形式是一样的(即存在该文件)。
  3. Delete (删除): OCI 使用 Whiteouts (遮盖文件) 来表示删除。
关于 Whiteouts (遮盖文件)

如果我们在上层删除了下层的一个文件 /etc/my-app-config,我们不能直接从 Tar 包里把这个文件拿掉(因为下层是只读的)。相反,我们在新层中创建一个特殊的文件,名字叫 .wh.my-app-config

运行时在联合挂载(Union Mount)时,看到 .wh. 前缀的文件,就会知道要“遮挡”住下层的同名文件,从而实现删除效果。

还有一个特殊的 Opaque Whiteout (.wh..wh..opq),用于隐藏父目录下的所有子项。

代码语言:javascript
复制
# 示例:层内容
/etc/my-app.d/
/etc/my-app.d/default.cfg
/bin/my-app-tools
/etc/.wh.my-app-config  <-- 表示删除了 /etc/my-app-config

4. Image Index (镜像索引)

Image Index 是一个更高层级的 Manifest。它本身不包含层或配置,而是包含了一个指向其他 Manifest 的列表。

这主要用于多平台支持。当你 docker pull my-image:latest 时,客户端会先获取 Index,然后根据当前的机器架构(如 linux/amd64),找到列表中对应的 Manifest 并下载。

代码语言:javascript
复制
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:e69241...",
      "size": 7143,
      "platform": {
        "architecture": "ppc64le",
        "os": "linux"
      }
    },
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:5b0bca...",
      "size": 7682,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    }
  ]
}

OCI 生态工具推荐

了解 OCI 规范后,值得深入了解两个在云原生生态中被广泛使用的工具和库,它们完美体现了 OCI 标准带来的互操作性。

Skopeo

Skopeo 是一个功能强大的命令行工具,用于对容器镜像和镜像库执行各种操作。与其他工具不同,Skopeo 的最大优势在于它无需运行容器守护进程(如 Docker Daemon) 即可工作。

常用场景示例:

远程检视 (skopeo inspect) 在不下载(Pull)镜像层的情况下,直接读取远程仓库中镜像的 Manifest 和配置信息。这在 CI/CD 流水线中非常实用,可以快速检查镜像标签、架构或创建时间。

命令:

代码语言:javascript
复制
skopeo inspect docker://hub.example.io/library/alpine:latest

输出示例 (JSON):

代码语言:javascript
复制
skopeo inspect docker://hub.example.io/library/alpine:latest --tls-verify=false
{
    "Name": "hub.example.io/library/alpine",
    "Digest": "sha256:9d04ae17046f42ec0cd37d0429fff0edd799d7159242938cc5a964dcd38c1b64",
    "RepoTags": [
        "3.10",
        "3.22",
        "latest"
    ],
    "Created": "2025-10-08T11:04:56Z",
    "DockerVersion": "",
    "Labels": null,
    "Architecture": "amd64",
    "Os": "linux",
    "Layers": [
        "sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b"
    ],
    "LayersData": [
        {
            "MIMEType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "Digest": "sha256:2d35ebdb57d9971fea0cac1582aa78935adf8058b2cc32db163c98822e5dfa1b",
            "Size": 3802452,
            "Annotations": null
        }
    ],
    "Env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ]
}

镜像复制与格式转换 (skopeo copy) 支持在不同的存储机制之间直接复制镜像。例如,将 Docker Hub 上的镜像直接下载并转换为符合 OCI Layout 标准的本地文件目录,而无需中间环节。

命令:

代码语言:javascript
复制
# 将 Docker 在线镜像复制为本地 OCI 目录结构
skopeo copy docker://docker.io/library/alpine:latest oci:/tmp/alpine-layout:latest

输出:

代码语言:javascript
复制
Getting image source signatures
Copying blob 05455a5d5d3e done  
Copying config 124c7d2707 done  
Writing manifest to image destination
Storing signatures

containers/image 库

containers/image(也被称为 image library)是上述 Skopeo 以及 Podman、Buildah 等下一代容器工具背后的核心库。

这是一个 Go 语言库,提供了一套通用的 API 来处理容器镜像的传输、签名、及其元数据管理。它抽象了底层的存储细节,支持多种 传输协议 (Transports)

  • docker://:访问标准的远程 Docker/OCI 注册表。
  • docker-daemon://:直接操作 Docker 守护进程的本地存储。
  • oci://:操作符合 OCI 目录布局(OCI Layout)的本地镜像。
  • dir://tarball:// 等:支持本地目录和归档文件。

正是因为有了 containers/image 库的底层支持,OCI 生态中的工具才能实现跨平台、跨存储后端的无缝互操作,真正践行了 OCI “一次构建,到处运行” 的理念。

代码示例 (Go) : 以下代码展示了如何使用该库编程将一个远程 Docker 镜像复制到本地 OCI 目录中。

代码语言:javascript
复制
package main

import (
    "context"
    "os"
    "github.com/containers/image/v5/copy"
    "github.com/containers/image/v5/signature"
    "github.com/containers/image/v5/transports/alltransports"
)

func main() {
    src := "docker-daemon://alpine:latest"
    dest := "oci:/tmp/my-alpine-layout:latest"

    // 1. 解析源和目标引用
    srcRef, err := alltransports.ParseImageName(src)
    if err != nil {
        panic(err)
    }
    destRef, err := alltransports.ParseImageName(dest)
    if err != nil {
        panic(err)
    }

    // 2. 配置策略上下文 (示例中使用宽松策略)
    policy := &signature.Policy{Default: []signature.PolicyRequirement{signature.NewPRInsecureAcceptAnything()}}
    policyContext, _ := signature.NewPolicyContext(policy)
    
    // 3. 执行 Image Copy 操作
    // 这相当于运行 `skopeo copy`
    _, err = copy.Image(context.Background(), policyContext, destRef, srcRef, &copy.Options{
        ReportWriter: os.Stdout, // 将进度输出到控制台
    })

    if err != nil {
        panic(err)
    }
}

执行结果:

代码语言:javascript
复制
Getting image source signatures
Copying blob 989e799e6349 done   | 
Copying config b956011c2e done   | 
Writing manifest to image destination

总结

OCI 镜像规范不仅仅是一个文件格式标准,它构成了现代云原生基础设施的基石。通过解耦 Manifest (清单)、Config (配置)Layers (数据) ,它实现了高度的灵活性和互操作性。

本文的核心要点回顾:

  1. 内容寻址 (Content Addressable): 一切皆通过 Digest 引用,确保内容不可篡改且易于去重。
  2. 分层机制: 极大地优化了存储和传输效率,公共的基础镜像层只需存储一份。
  3. 多架构支持: Image Index 使得同一个标签可以无缝支持多种硬件平台。
  4. 生态互通: 借助 Skopeo 和 containers/image 等工具,我们可以轻松在不同环境(Docker, OCI Layout, Remote Registry)之间迁移和操作镜像。

理解这些底层细节,有助于我们更好地进行容器镜像的构建优化、安全扫描以及故障排查,从而构建更高效、更安全的云原生应用。


本文参考自 Open Container Initiative Image Specification

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-02-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OCI 镜像规范概览
  • 核心概念:Content Descriptors (内容描述符)
  • 组件结构详解
    • 1. Image Manifest (镜像清单)
    • 2. Image Configuration (镜像配置)
    • 3. Filesystem Layers (文件系统层)
      • 关于 Whiteouts (遮盖文件)
    • 4. Image Index (镜像索引)
  • OCI 生态工具推荐
    • Skopeo
    • containers/image 库
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档