网站设计的七个原则,软文文案范文,免费vue前端模板网站,深圳自适应网站设计背景
2020 年 12 月初#xff0c;Kubernetes 在其最新的 Changelog 中宣布#xff0c;自 Kubernetes 1.20 之后将弃用 Docker 作为容器运行时。
弃用 Docker 带来的#xff0c;可能是一系列的改变#xff0c;包括不限于#xff1a;
容器镜像构建工具容器 CLI容器镜像仓…背景
2020 年 12 月初Kubernetes 在其最新的 Changelog 中宣布自 Kubernetes 1.20 之后将弃用 Docker 作为容器运行时。
弃用 Docker 带来的可能是一系列的改变包括不限于
容器镜像构建工具容器 CLI容器镜像仓库容器运行时
专题文章《K8S 1.20 弃用 Docker 评估》会从多方面分析由此带来的变动和影响今天先介绍镜像格式的改变。
Docker 镜像仍然可以使用吗
是的可以使用。Docker 较新版本生成的镜像实际上并不是特定于 Docker 的镜像而是 OCIOpen Container Initiative镜像。无论你使用什么工具构建镜像任何符合 OCI 标准的镜像在 Kubernetes 看来都是一样的。containerd 和 CRI-O 都能够提取这些镜像并运行它们。所以您可以仍然使用 Docker 来构建容器镜像并且可以继续在 containerd 和 CRI-O 上使用。
那为什么发现 Docker 镜像和 Containerd 镜像存在不兼容情况
具体如下在 K8S 1.20 版本中发现 containerd ctr 上传到镜像仓库的镜像与同版本的 docker 镜像间存在以下问题
不能被 docker 使用docker push不能覆盖
根本原因还是在于镜像格式的差别。下面做详细解释。
Docker 和 OCI 镜像格式的差别
目前有以下几种容器镜像格式
❌已弃用Docker Image V1:warning:已弃用Docker Image Manifest V2 Schema 1Docker Image Manifest V2 Schema 2Open Container Initiative (OCI) 规范
Docker V1 镜像
{% note danger %} ❌严重警告
Docker V1 格式早已弃用请不要再使用 {% endnote %}
{% note info %} :book: 引用
版本 1.8.3 增加了一个标志(--disable-legacy-registryfalse)用于阻止 docker 守护进程对 v1 镜像注册表进行拉、推和登录操作。尽管默认情况下是启用的但这表示不赞成 v1 协议。自 2017 年 2 月 28 日起随着 Docker v1.13 的发布Docker Engine 不再支持 v1 协议。从 Docker 17.12 开始对 V1 镜像注册表的支持已经被删除并且 --disable-legacy-registry 标志不再使用当设置该标志时 dockerd时将无法启动。 {% endnote %}
Docker V2 镜像简介
Docker V2 镜像清单Image Manifest是 Docker 的 V2 版本容器映像规范它允许多架构镜像并支持内容可寻址映像。
从 2017 年 2 月 28 日开始Docker V2 镜像注册表规范取代了 Docker V1 规范。Docker V1 规范已被弃用并且 Docker V1 映像不能再用于 Container Registry。
为支持内容可寻址镜像并简化镜像图层的跟踪Docker V2 对 Docker 镜像格式进行了一系列更改。 Docker V2 镜像清单包含镜像图层的所有内容地址“摘要”而 Docker V1 映像则不包含这些信息。
Docker Image Manifest V2 Schema 1
下面简单介绍下 V2 Schema 1 镜像清单的格式。V2 Schema 1 它是一个临时清单提供与 V1 Image 格式的兼容性V2 Schema 2 才是当前 Docker 镜像格式的最终格式。
{% note default %} :notebook: 备注
V2 Schema 1 由于需要与 V1 的向后兼容性原因它比 V2.2即 Docker Image Manifest V2 Schema 2 更复杂。 {% endnote %}
镜像清单描述了一个 Docker 镜像的各种组成部分。镜像清单可以序列化为 JSON 格式与以下媒体类型:
清单类型Manifest Type媒体类型Media Typemanifest“application/vnd.docker.distribution.manifest.v1json”signed manifest“application/vnd.docker.distribution.manifest.v1prettyjws”
清单格式不详细介绍下面通过示例说明
示例清单格式
{name: hello-world,tag: latest,architecture: amd64,fsLayers: [{blobSum: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef},{blobSum: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef},{blobSum: sha256:cc8567d70002e957612902a8e985ea129d831ebe04057d88fb644857caa45d11},{blobSum: sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef}],history: [{v1Compatibility: {\id\:\e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\,\parent\:\31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\,\created\:\2014-12-31T22:57:59.178729048Z\,\container\:\27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\,\container_config\:{\Hostname\:\8ce6509d66e2\,\Domainname\:\\,\User\:\\,\Memory\:0,\MemorySwap\:0,\CpuShares\:0,\Cpuset\:\\,\AttachStdin\:false,\AttachStdout\:false,\AttachStderr\:false,\PortSpecs\:null,\ExposedPorts\:null,\Tty\:false,\OpenStdin\:false,\StdinOnce\:false,\Env\:[\PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\],\Cmd\:[\/bin/sh\,\-c\,\#(nop) CMD [/hello]\],\Image\:\31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\,\Volumes\:null,\WorkingDir\:\\,\Entrypoint\:null,\NetworkDisabled\:false,\MacAddress\:\\,\OnBuild\:[],\SecurityOpt\:null,\Labels\:null},\docker_version\:\1.4.1\,\config\:{\Hostname\:\8ce6509d66e2\,\Domainname\:\\,\User\:\\,\Memory\:0,\MemorySwap\:0,\CpuShares\:0,\Cpuset\:\\,\AttachStdin\:false,\AttachStdout\:false,\AttachStderr\:false,\PortSpecs\:null,\ExposedPorts\:null,\Tty\:false,\OpenStdin\:false,\StdinOnce\:false,\Env\:[\PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\],\Cmd\:[\/hello\],\Image\:\31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\,\Volumes\:null,\WorkingDir\:\\,\Entrypoint\:null,\NetworkDisabled\:false,\MacAddress\:\\,\OnBuild\:[],\SecurityOpt\:null,\Labels\:null},\architecture\:\amd64\,\os\:\linux\,\Size\:0}\n},{v1Compatibility: {\id\:\e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\,\parent\:\31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\,\created\:\2014-12-31T22:57:59.178729048Z\,\container\:\27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\,\container_config\:{\Hostname\:\8ce6509d66e2\,\Domainname\:\\,\User\:\\,\Memory\:0,\MemorySwap\:0,\CpuShares\:0,\Cpuset\:\\,\AttachStdin\:false,\AttachStdout\:false,\AttachStderr\:false,\PortSpecs\:null,\ExposedPorts\:null,\Tty\:false,\OpenStdin\:false,\StdinOnce\:false,\Env\:[\PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\],\Cmd\:[\/bin/sh\,\-c\,\#(nop) CMD [/hello]\],\Image\:\31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\,\Volumes\:null,\WorkingDir\:\\,\Entrypoint\:null,\NetworkDisabled\:false,\MacAddress\:\\,\OnBuild\:[],\SecurityOpt\:null,\Labels\:null},\docker_version\:\1.4.1\,\config\:{\Hostname\:\8ce6509d66e2\,\Domainname\:\\,\User\:\\,\Memory\:0,\MemorySwap\:0,\CpuShares\:0,\Cpuset\:\\,\AttachStdin\:false,\AttachStdout\:false,\AttachStderr\:false,\PortSpecs\:null,\ExposedPorts\:null,\Tty\:false,\OpenStdin\:false,\StdinOnce\:false,\Env\:[\PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\],\Cmd\:[\/hello\],\Image\:\31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\,\Volumes\:null,\WorkingDir\:\\,\Entrypoint\:null,\NetworkDisabled\:false,\MacAddress\:\\,\OnBuild\:[],\SecurityOpt\:null,\Labels\:null},\architecture\:\amd64\,\os\:\linux\,\Size\:0}\n},],schemaVersion: 1,signatures: [{header: {jwk: {crv: P-256,kid: OD6I:6DRK:JXEJ:KBM4:255X:NSAA:MUSF:E4VM:ZI6W:CUN2:L4Z6:LSF4,kty: EC,x: 3gAwX48IQ5oaYQAYSxor6rYYc_6yjuLCjtQ9LUakg4A,y: t72ge6kIA1XOjqjVoEOiPPAURltJFBMGDSQvEGVB010},alg: ES256},signature: XREm0L8WNn27Ga_iE_vRnTxVMhhYY0Zst_FfkKopg6gWSoTOZTuW4rK0fg_IqnKkEKlbD83tD46LKEGi5aIVFg,protected: eyJmb3JtYXRMZW5ndGgiOjY2MjgsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wNC0wOFQxODo1Mjo1OVoifQ}]
}
{% note warning %} :warning: 注意
随着 Docker Image Manifest V2 Schema 2 的发布Docker Image Manifest V2 Schema 1 已被弃用。这可能导致尚未更新到 Docker Image Manifest V2 Schema 2 的镜像存在兼容性和漏洞问题。 {% endnote %}
Docker Image Manifest V2 Schema 2
然后介绍 V2 Schema 2 的格式。
V2 Schema 2 版本有两个主要目标。第一种是允许多架构镜像通过“胖清单”引用特定于平台版本的镜像的镜像清单。第二种方法是将 Docker 引擎转向可内容寻址的图像方法是支持一个镜像模型在该模型中可以对镜像的配置进行哈希以生成镜像的 ID。
清单列表Manifest List
清单列表是 Docker V2 Schema 2 和 OCI 镜像的一部分。
利用清单列表您可以使用单个摘要或标记来表示映像的多种形式。
示例清单列表Manifest List
{schemaVersion: 2,mediaType: application/vnd.docker.distribution.manifest.list.v2json,manifests: [{mediaType: application/vnd.docker.distribution.manifest.v2json,size: 7143,digest: sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f,platform: {architecture: ppc64le,os: linux,}},{mediaType: application/vnd.docker.distribution.manifest.v2json,size: 7682,digest: sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270,platform: {architecture: amd64,os: linux,features: [sse4]}}]
}
镜像清单
示例镜像清单
{schemaVersion: 2,mediaType: application/vnd.docker.distribution.manifest.v2json,config: {mediaType: application/vnd.docker.container.image.v1json,size: 7023,digest: sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7},layers: [{mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip,size: 32654,digest: sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f},{mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip,size: 16724,digest: sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b},{mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip,size: 73109,digest: sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736}]
}
如何将 Docker V1 或 Manifest V2 Schema 1 升级到Docker Image Manifest V2 Schema 2
将老的 Docker V1 或 Manifest V2 Schema 1 使用 docker pull 下来然后用新版本的 Docker docker push 到镜像仓库即可
这样做将自动将镜像转换为使用最新的镜像清单规范。
或者也可以这样升级
可以通过更新 Dockerfile 中的 FROM 语句来重新 build 镜像。如果您的镜像清单过期了那么从 Dockerfile 中的 from语句中提取的镜像也有可能过期。
OCI 格式
OCI 格式是基于 Docker Image Manifest Version 2 Schema 2 格式的容器镜像规范。该规范定义了如何创建 OCI Image(通常由构建系统完成)并输出镜像清单、文件系统(镜像层)序列化和镜像配置。下面简要拿镜像清单做一个和 Docker 的对比说明更多就不详细展开了。
镜像索引Image Index
镜像索引Image Index相当于 OCI 映像中的清单列表Manifest List。
与清单列表一样镜像索引清单指的是多个镜像清单。镜像索引对多平台镜像很有用。
示例镜像索引
{schemaVersion: 2,manifests: [{mediaType: application/vnd.oci.image.manifest.v1json,size: 7143,digest: sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f,platform: {architecture: ppc64le,os: linux}},{mediaType: application/vnd.oci.image.manifest.v1json,size: 7682,digest: sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270,platform: {architecture: amd64,os: linux}}],annotations: {com.example.key1: value1,com.example.key2: value2}
}镜像清单
示例镜像清单
{schemaVersion: 2,config: {mediaType: application/vnd.oci.image.config.v1json,size: 7023,digest: sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7},layers: [{mediaType: application/vnd.oci.image.layer.v1.targzip,size: 32654,digest: sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0},{mediaType: application/vnd.oci.image.layer.v1.targzip,size: 16724,digest: sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b},{mediaType: application/vnd.oci.image.layer.v1.targzip,size: 73109,digest: sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736}],annotations: {com.example.key1: value1,com.example.key2: value2}
}镜像格式差别总结
首先是 Docker V1 镜像这是非常老旧且已经弃用的镜像格式是 Docker 刚出来的时候没有考虑多架构多平台如x86 和 arm 镜像所以通常 Docker V1 镜像只有 x86 平台的镜像。:warning: 注意请不要再使用如果使用请尽快升级到 Docker Image Manifest V2 Schema 2 或 OCI 格式
然后是 Docker Image Manifest V2 Schema 1这个是过过渡形态的格式兼容 Docker V1 和 Docker Image Manifest V2 使得它更为复杂它的作用也仅仅是为了过渡而非长期使用。:warning: 注意请不要再使用如果使用请尽快升级到 Docker Image Manifest V2 Schema 2 或 OCI 格式
最后是 Docker Image Manifest V2 Schema 2 和 OCI 格式OCI 主要参考的就是 Docker Image Manifest V2 Schema 2 格式二者是兼容的这也就回答了上文所说的「Docker 镜像仍然可以使用吗-- 是的可以使用。」
但是二者在媒体类型Media Type、压缩方式等细节上存在不同部分举例如
清单manifest上Docker Image Manifest V2 Schema 2 的 Media Type 是application/vnd.docker.distribution.manifest.list.v2json而 OCI 是application/vnd.oci.image.manifest.v1json 每一层镜像层上Docker Image Manifest V2 Schema 2 的 Media Type 是application/vnd.docker.image.rootfs.diff.tar.gzipOCI 的 Media Type 是application/vnd.oci.image.layer.v1.targzip 或 application/vnd.oci.image.layer.v1.tar 等类型。
也正是因为这些差异最终导致即使是完全相同的镜像二者的 digest、镜像大小不尽相同。
所以这也正好解释了「那为什么发现 Docker 镜像和 Containerd 镜像存在不兼容情况」
「不能被 docker 使用」 - 可能是 docker 版本过低导致的「docker push 不能覆盖」- 因为即使是完全相同的镜像二者的 digest、镜像大小不尽相同。所以无法覆盖。
我的建议
针对镜像因为 OCI 主要参考了 Docker Image Manifest V2 Schema 2而 Docker Image Manifest V2 Schema 2 是 OCI 的一种实现。所以 Docker 较新版本生成的镜像containerd 和 CRI-O 都能够提取这些镜像并运行它们。
两种办法都可以
镜像构建方式保持不变仍然是采用 Docker 构建镜像注意 Docker 版本要较新确保构建的镜像是Docker Image Manifest V2 Schema 2 格式变更镜像构建工具不再使用 Docker而是使用可以构建 OCI 格式的镜像构建工具。
具体您可以视实际情况进行选择。 三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.