docker 多架构接口数据交换

前言

docker 的仓库支持一个 tag 下多个架构镜像, 这是如何实现的呢? 抓包看看其数据交互流程

前提

错误处理

执行命令buildx报错:

ERROR: Multi-platform build is not supported for the docker driver.
Switch to a different driver, or turn on the containerd image store, and try again.
Learn more at https://docs.docker.com/go/build-multi-platform/

修复: 执行命令docker buildx create --use desktop-linux . 参考链接

OCI参考文档

构建

Dockerfile:

FROM hub.hujingnb.com/hj-public/debian

RUN date > /tmp/date.txt

构建命令:

docker buildx build --platform linux/amd64,linux/arm64 -t hub.hujingnb.com/hj-public/test1:new --push .

抓包接口调用(2张图连续的, 1张图放不下了):

接口调用说明:

method 接口 说明 OCI 对应
HEAD /v2/hj-public/debian/manifests/latest 判断远端此镜像是否存在(每个架构) /v2/<name>/manifests/<reference>
GET /v2/hj-public/debian/manifests/sha256:520ce6d85... 获取镜像 manifests(多架构的). 内容参考: [多架构manifest](#method 接口 说明 OCI 对应 HEAD /v2/hj-public/debian/manifests/latest 判断远端此镜像是否存在(每个架构) /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/manifests/sha256:520ce6d85... 获取镜像 manifests(多架构的). 内容参考: 多架构manifest /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/manifests/sha256:d15e83b3... 获取镜像 manifests(每个架构. 内容参考: 镜像manifests /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/blobs/sha256:8ea8... 获取上一步拿到的所有 blob /v2/<name>/blobs/<digest> … 中间步骤和普通的镜像上传一样. 可参考之前的文章 HEAD /v2/hj-public/test1/manifests/new 判断远端 manifests 是否存在. /v2/<name>/manifests/<reference> PUT /v2/hj-public/test1/manifests/new 上传manifests. 内容参考: 多架构manifest /v2/<name>/manifests/<reference>) /v2/<name>/manifests/<reference>
GET /v2/hj-public/debian/manifests/sha256:d15e83b3... 获取镜像 manifests(每个架构. 内容参考: [镜像manifests](#method 接口 说明 OCI 对应 HEAD /v2/hj-public/debian/manifests/latest 判断远端此镜像是否存在(每个架构) /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/manifests/sha256:520ce6d85... 获取镜像 manifests(多架构的). 内容参考: 多架构manifest /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/manifests/sha256:d15e83b3... 获取镜像 manifests(每个架构. 内容参考: 镜像manifests /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/blobs/sha256:8ea8... 获取上一步拿到的所有 blob /v2/<name>/blobs/<digest> … 中间步骤和普通的镜像上传一样. 可参考之前的文章 HEAD /v2/hj-public/test1/manifests/new 判断远端 manifests 是否存在. /v2/<name>/manifests/<reference> PUT /v2/hj-public/test1/manifests/new 上传manifests. 内容参考: 多架构manifest /v2/<name>/manifests/<reference>) /v2/<name>/manifests/<reference>
GET /v2/hj-public/debian/blobs/sha256:8ea8... 获取上一步拿到的所有 blob /v2/<name>/blobs/<digest>
... 中间步骤和普通的镜像上传一样. 可参考之前的文章
HEAD /v2/hj-public/test1/manifests/new 判断远端 manifests 是否存在. /v2/<name>/manifests/<reference>
PUT /v2/hj-public/test1/manifests/new 上传manifests. 内容参考: [多架构manifest](#method 接口 说明 OCI 对应 HEAD /v2/hj-public/debian/manifests/latest 判断远端此镜像是否存在(每个架构) /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/manifests/sha256:520ce6d85... 获取镜像 manifests(多架构的). 内容参考: 多架构manifest /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/manifests/sha256:d15e83b3... 获取镜像 manifests(每个架构. 内容参考: 镜像manifests /v2/<name>/manifests/<reference> GET /v2/hj-public/debian/blobs/sha256:8ea8... 获取上一步拿到的所有 blob /v2/<name>/blobs/<digest> … 中间步骤和普通的镜像上传一样. 可参考之前的文章 HEAD /v2/hj-public/test1/manifests/new 判断远端 manifests 是否存在. /v2/<name>/manifests/<reference> PUT /v2/hj-public/test1/manifests/new 上传manifests. 内容参考: 多架构manifest /v2/<name>/manifests/<reference>) /v2/<name>/manifests/<reference>

至此, 一次多架构镜像构建并上传就完成了.

手动创建 manifests

我们也可以手动创建多架构, 而不是用 buildx. 命令如下:

bash 复制代码
# 假设仓库中已经存在: image:amd64 image:arm64 2个镜像
docker manifest create --insecure --amend  image:new image:arm64 image:amd64
docker manifest annotate image:new image:arm64 --os=linux --arch=arm64
docker manifest annotate image:new image:amd64 --os=linux --arch=amd64
docker manifest push --insecure --purge image:new

此时的接口调用, 直接跳到上面的最后2步: HEAD/PUT manifests接口.

拉取

其实在上一步构建的时候已经能够看到拉取的接口调用了. 在每次构建的时候, 要把不同架构的基础镜像拉倒本地进行构建.

这里就简单放一张接口调用流程, 命令: docker pull --platform=linux/arm64 hub.hujingnb.com/hj-public/test1:new:

总结

单独镜像的推拉, 可以参考之前的文章

可以看到, 实现多架构时, 与非多架构镜像的唯一区别, 就是额外加了一个 manifests 类型, 用来将单架构镜像整合为多架构.

附件

多架构manifest
json 复制代码
{
    "schemaVersion": 2,
    "mediaType": "application/vnd.oci.image.index.v1+json",
    "manifests":
    [
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:b4df0c22aa74c1aa7e1941619c4c63b2e3b1b1dc57436ecc6515e547b6888dab",
            "size": 481,
            "platform":
            {
                "architecture": "386",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:651dd02a84abdd528e35e73d483aec5c361078bf169919bd3dac7bfe66d19290",
            "size": 481,
            "platform":
            {
                "architecture": "amd64",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:9dac568c16fc9d22304b66eb1be48e849c912c0c1f233b7c8233eee5834fc082",
            "size": 481,
            "platform":
            {
                "architecture": "arm",
                "os": "linux",
                "variant": "v5"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:e30e0f9e2580058251db6012e2886fa8b3971d980ae04c0d2e304190df601b4a",
            "size": 481,
            "platform":
            {
                "architecture": "arm",
                "os": "linux",
                "variant": "v7"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:d15e83b3662501593be46a5a2aef02c2f5b4a1826aa5bef8cd21e7047a497af8",
            "size": 481,
            "platform":
            {
                "architecture": "arm64",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:bddc1b85037e49dcbeef083c2b2868c73e23d7443e3c13bc177762b90ddaf80f",
            "size": 481,
            "platform":
            {
                "architecture": "mips64le",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:e0d4150147fe4f2ecaf11fd532bd3d707d8632024f6743da58141b122a305887",
            "size": 481,
            "platform":
            {
                "architecture": "ppc64le",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:ed6e2e64d1f0a99ca795c481ca08ff62fc8e1efca022ae22c5604bb27e6c76c1",
            "size": 481,
            "platform":
            {
                "architecture": "s390x",
                "os": "linux"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:785cf1dd62c0b02ce1fbf6cf615ef6eba5d4087385613ddcf26c221daac8e6a0",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:b4df0c22aa74c1aa7e1941619c4c63b2e3b1b1dc57436ecc6515e547b6888dab",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:520be2ba49e9d29e94745580f96858c3960f5fcf1eaa2b8b6e2574d5bba4bc91",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:651dd02a84abdd528e35e73d483aec5c361078bf169919bd3dac7bfe66d19290",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:edbe0bc83fdd4b6516399b43dcb4422c9b5e78a1a485fc8870554b7f1b59a501",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:9dac568c16fc9d22304b66eb1be48e849c912c0c1f233b7c8233eee5834fc082",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:3d456f67aef005b6da1b9ae91c778314b6d79553917d7d37e6aa484eb8ea5a91",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:e30e0f9e2580058251db6012e2886fa8b3971d980ae04c0d2e304190df601b4a",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:fe2aa90b281550a68cdc80208979c65acf8f64ca7ba709fe07fc38ed4eae7400",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:d15e83b3662501593be46a5a2aef02c2f5b4a1826aa5bef8cd21e7047a497af8",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:5308441e25778d9e467114c998ed3faf9c4bc18df17702fdbe7fcf495ff44eb9",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:bddc1b85037e49dcbeef083c2b2868c73e23d7443e3c13bc177762b90ddaf80f",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:264d85222bd6ff7a724dd33fa5071e6c3e1a30361989d52f2f7ca191ac7b9b20",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:e0d4150147fe4f2ecaf11fd532bd3d707d8632024f6743da58141b122a305887",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        },
        {
            "mediaType": "application/vnd.oci.image.manifest.v1+json",
            "digest": "sha256:8f06e8c4e23717acbe73a0cd2f6ef9678b0c8c0387d67f7e604c85d43ba22cbf",
            "size": 566,
            "annotations":
            {
                "vnd.docker.reference.digest": "sha256:ed6e2e64d1f0a99ca795c481ca08ff62fc8e1efca022ae22c5604bb27e6c76c1",
                "vnd.docker.reference.type": "attestation-manifest"
            },
            "platform":
            {
                "architecture": "unknown",
                "os": "unknown"
            }
        }
    ]
}

其中后面几个 annotations 类型的内容, 是每个架构下的 manifests 证明文件. 用于镜像签名.

镜像manifests
json 复制代码
{
	"schemaVersion": 2,
	"mediaType": "application/vnd.oci.image.manifest.v1+json",
	"config": {
		"mediaType": "application/vnd.oci.image.config.v1+json",
		"digest": "sha256:fe997a1b6216319619839e4ffe4bf083b70e58e751d5a26837254dc113b743f6",
		"size": 579
	},
	"layers": [{
		"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
		"digest": "sha256:c1e0ef7b956a07c7b090256aa16cbb0550a34d0625d1d23c5b1a76e92a58d01e",
		"size": 49584978
	}]
}
相关推荐
小蜗牛慢慢爬行20 分钟前
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
java·架构·hibernate
saynaihe1 小时前
安全地使用 Docker 和 Systemctl 部署 Kafka 的综合指南
运维·安全·docker·容器·kafka
思忖小下2 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
G_whang2 小时前
centos7下docker 容器实现redis主从同步
redis·docker·容器
认真学习的小雅兰.2 小时前
如何在Ubuntu上利用Docker和Cpolar实现Excalidraw公网访问高效绘图——“cpolar内网穿透”
linux·ubuntu·docker
the丶only3 小时前
单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号
linux·运维·服务器·docker·gitlab
书生-w3 小时前
Docker部署GitLab服务器
服务器·docker·gitlab
塔克拉玛攻城狮3 小时前
私有网盘+在线文档:内网离线搭建NextCloud+OnlyOffice详细指南
docker·在线文档·网盘
ccubee4 小时前
docker 安装 ftp
运维·docker·容器
TsengOnce5 小时前
Docker 安装 禅道-21.2版本-外部数据库模式
运维·docker·容器