共计 5840 个字符,预计需要花费 15 分钟才能阅读完成。
大家好,我是张晋涛。
这篇文章中我将介绍 OCI 及 Docker 镜像相干的内容,欢送留言探讨。
OCI 的前世今生
2013 年 3 月 dotCloud 公司在 PyCon 上进行了 Docker 的首次展现,随后发表开源。自此 Docker 开始被众人通晓,随后掀起了一股容器化的热潮。
在 2014 年 6 月 Docker 1.0 正式公布,有近 460 位贡献者和超过 8700 次提交,这也标记着 Docker 达到了生产可用的状态。
在过后,提到容器化第一想法就是用 Docker。而过后 Docker 的实现或者说倒退方向次要是由 Docker Inc. 公司管制的,并没有一个对立的工业规范。这对于一些头部公司而言,显然是不能承受的,没有对立的工业规范意味着如果抉择了应用 Docker 的容器化技术,便会被 Docker Inc. 公司所绑定;加上随着 Docker 软件的降级,某些性能或者个性必然会进行变动,没人能保障不产生破坏性变更。
所以,为了推动容器化技术的工业标准化,2015 年 6 月在 DockerCon 上 Linux 基金会与 Google,华为,惠普,IBM,Docker,Red Hat,VMware 等公司独特发表成立凋谢容器我的项目 (OCP),后更名为 OCI。它的次要指标便是 建设容器格局和运行时的工业凋谢通用规范。
倒退至今,OCI 制订的次要规范有三个别离是 runtime-spec
、image-spec
和 distribution-spec
这三个规范别离定义了容器运行时,容器镜像还有散发的标准,前面会开展介绍。
为了反对 OCI 容器运行时规范的推动,Docker 公司起草了镜像格局和运行时标准的草案,并将 Docker 我的项目的相干实现募捐给了 OCI 作为容器运行时的根底实现,当初我的项目名为 runc
。
起初 Docker 将其容器运行时独立成了一个我的项目,名为 containerd
并将此我的项目募捐给了 CNCF,当初曾经是 CNCF 毕业我的项目了。
OCI image vs Docker image
OCI 的建设推动了容器技术的工业标准化,但是否此规范就是惟一呢?其实不然。在成立 OCI 并制订 image-spec
规范的时候 Docker 曾经空前凋敝,并失去了宽泛的利用。
因为规范只定义了最根本的内容,想要将 Docker 的实现全副依照规范进行革新的话,会对 Docker 造成破坏性变更,也不利于 Docker 性能的迭代。
所以,Docker 为了反对 OCI 规范的遍及,曾经推动了 registry 对 OCI 镜像的反对,当初也正在给 Docker 本身减少适配中,指标是让 Docker 反对两种镜像格局,别离是合乎 Docker 规范的镜像和合乎 OCI 规范的镜像。
那这两者有什么异同呢?咱们来逐渐看下。
Docker Image 和 OCI Image 的区别和分割
在我以前的文章中咱们曾经具体的从根本上介绍了 Docker image 是什么,这里咱们就疾速的介绍下。
每个 Docker 镜像都是由一系列的配置清单和相应的层进行组织的。每个层个别都是 tar 格局的归档,配置清单中形容了对应的层应该按何种程序进行组织,以及镜像的一些元属性。比方镜像所反对的架构,例如 amd64
之类的,还有 ENV 等提前配置好的一些参数等。
当然,在 Docker Image 中也蕴含着构建镜像时候所用的 Docker 版本 docker_version
以及构建镜像的历史记录 history
等信息。所以你在 DockerHub
或者其余的镜像仓库上能够看到构建镜像所用的 Docker 版本,或者可通过 docker history <IMAGE>
的形式来查看构建历史。
那么 OCI Image 是什么呢?首先咱们须要有一个 OCI Image 才好探索它到底是什么。
这里介绍一个工具 skopeo 能够很不便的从镜像仓库或者本地 Docker daemon 甚至是通过 docker save
保留的 Docker Image tar 文件转换为 OCI Image。
对于 skopeo 的装置过程就不再赘述了,参考我的项目主页的文档阐明即可。这里间接开始应用。
咱们应用 debian
的镜像为例。
(MoeLove) ➜ skopeo copy docker://debian:stretch oci:debian:stretch
Getting image source signatures
Copying blob a4d8138d0f6b done
Copying config 45f82268e3 done
Writing manifest to image destination
Storing signatures
通过下面的命令便会失去一个 OCI Image 了,咱们看下它的目录构造。
(MoeLove) ➜ tree debian
debian
├── blobs
│ └── sha256
│ ├── 0043cd2a654fe86258f43f5b1dbbb4e6c582cc4bb6e505e9c5171c124150d155
│ ├── 45f82268e32180cb1839f90467d9b8a8258953d68b7221199976653308d92ef5
│ └── a4d8138d0f6b5a441aaa533faf5fe0c3996a6ca42643c46f4402c7e8bda53742
├── index.json
└── oci-layout
2 directories, 5 files
是不是有种似曾相识的感觉?没错 OCI Image 的标准是在 Docker Image 的根底上建设的,所以大抵看起来差别不是特地大。咱们看看其中具体的内容。
oci-layout
这个文件是 OCI Image 的布局文件,也是用于阐明它所应用或者遵循的镜像标准。
(MoeLove) ➜ debian cat oci-layout| jq
{"imageLayoutVersion": "1.0.0"}
能够看到此处的内容写的是 1.0.0
这便阐明该镜像遵循 OCI 1.0.0 版本的布局标准。
index.json
index.json
文件中的 manifest
字段相似于 Docker Image 中的 manifest.json
作为 OCI Image 的顶级配置, 也是镜像的一个入口配置。
(MoeLove) ➜ debian cat index.json | jq
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"digest": "sha256:0043cd2a654fe86258f43f5b1dbbb4e6c582cc4bb6e505e9c5171c124150d155",
"size": 349,
"annotations": {"org.opencontainers.image.ref.name": "stretch"},
"platform": {
"architecture": "amd64",
"os": "linux"
}
}
]
}
从它的内容能够看到它其中的 mediaType
字段与 Docker Image 中的类型模式雷同,然而将 docker
都换成了 oci
。从这个配置文件,咱们能够找到第一个 blob 是 sha256:0043cd2a654fe86258f43f5b1dbbb4e6c582cc4bb6e505e9c5171c124150d155
咱们看看它的内容。
(MoeLove) ➜ debian cat blobs/sha256/0043cd2a654fe86258f43f5b1dbbb4e6c582cc4bb6e505e9c5171c124150d155 | jq
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:45f82268e32180cb1839f90467d9b8a8258953d68b7221199976653308d92ef5",
"size": 579
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:a4d8138d0f6b5a441aaa533faf5fe0c3996a6ca42643c46f4402c7e8bda53742",
"size": 45337510
}
]
}
这个入口文件形容了 OCI 镜像的理论配置和其中的 Layer 配置。如果有多层那 layers
也会相应减少。
留神:layers 中 mediaType
应用了 application/vnd.oci.image.layer.v1.tar+gzip
阐明数据内容是通过 gzip 压缩的 如果有趣味你能够将它用 tar 解压一下,你会发现很乏味的内容。
这里先将后果说进去,解压后你会失去一个
rootfs
这与 Docker Image 是相似的。
小结
咱们通过 skopeo 工具,从本地的 Docker daemon 中由 debian 的 Docker Image 失去了 OCI Image,并剖析了它其中的内容。
最次要的区别在于它们的目录构造不完全相同,配置信息尤其是 mediaType
的标准是不雷同的。
而它们的分割也在于此,OCI Image 的标准是由 Docker Image 的标准批改而来的,所以相似它们的 blob 的组织模式大抵是雷同的,配置文件中很多的参数也类似。
另外,咱们也能够很容易的失去另一个论断,那便是咱们能够很不便的将 Docker Image 转换为 OCI Image。
OCI image 和 Docker image 的转换
下面咱们曾经看到,应用 skopeo 工具,能够将 Docker Image 转换为 OCI Image,当然它也能够将 OCI Image 转换为 Docker Image。上面给出了办法:
# 从 DockerHub 将 debian 的 Docker Image 拉取并转换为 OCI Image
(MoeLove) ➜ skopeo copy docker://debian:stretch oci:debian:stretch
Getting image source signatures
Copying blob a4d8138d0f6b done
Copying config 45f82268e3 done
Writing manifest to image destination
Storing signatures
# 将当前目录下的 debian 的 OCI Image 转换为 Docker Image 并存储到本地 docker daemon 中
(MoeLove) ➜ skopeo copy oci:debian:stretch docker-daemon:local/debian:oci
Getting image source signatures
Copying blob 0e350e141713 done
Copying config aae58a37cf done
Writing manifest to image destination
Storing signatures
# 验证
(MoeLove) ➜ oci docker images local/debian
REPOSITORY TAG IMAGE ID CREATED SIZE
local/debian oci ac6bcf605d82 6 months ago 101MB
镜像构建工具
在 CI/CD 环境中,尽管咱们能够应用 DinD (Docker in Docker) 的形式启动一个 docker daemon 或者应用挂载的形式,将内部的 /var/run/docker.sock
挂载进容器外部,亦或者将 Docker API 应用 HTTP 的形式裸露进去,间接应用该地址进行构建。
但这些形式你是否会感觉比拟重?是否有思考平安问题,或者压力及负载的问题?
这里的压力及负载次要是指当所有的工作都共用同一个 docker daemon 提供服务的话,对该 docker daemon 造成的压力。
这里咱们来介绍一些其余的镜像构建工具,应用这些工具能够让你在无 Docker 的环境下构建出镜像并上传至 Docker 镜像仓库中。
到目前为止,咱们能够有很多种抉择:
- BuildKit
- img
- orca-build
- umoci
- buildah
- kaniko
- FTL
- Bazel rules_docker
这些工具侧重点各有不同,当然也不仅有下面列到的这些工具,只是这些工具比拟典型罢了。
通常状况下,在网络上比拟容易见到宣传为下一代镜像构建工具的是 buildah
,最次要起因是因为它能够间接构建 OCI 规范的镜像或 Docker 镜像,也能够间接应用 Dockerfile
。并且它还能够 pull
/push
镜像,能够说在镜像构建方面与 Docker 是齐全兼容,甚至能够说它在构建镜像方面能够作为 Docker 的替代品了。
并且 buildah
构建镜像的时候不须要任何 root
权限,也不依赖 Docker,它应用了简略的 fork-exec
模型,同时它也能够作为一个库蕴含在其余的工具中。它的最终目标便是提供一个更低层次的外围工具集,来实现构建镜像相干的事件。
说完这个典型的替代品,咱们再来说下 BuildKit
和 img
, img
这个工具是构建在 BuildKit
之上的,所以有很多相似性。它们应用非 root 用户来构建镜像。当然 BuildKit
我在之前的文章中具体介绍过了,它是 Docker 内置的下一代构建工具,独立应用也是能够的。称它为“下一代镜像构建工具”也并不为过。
kaniko
是 Google 推出的,它次要的宣传语为“在 Kubernetes 中构建容器镜像”实际上无论是在 K8S 集群中或者在容器中它都是能够工作的。它也能够应用 Dockerfile
构建镜像。当然还有很重要的一点,它所有的构建命令都是运行在用户态的,并且也能够很好的与 Kubernetes 联合,在云原生时代下,它也占据了肯定的劣势。
以上工具都只是大抵介绍了下,如果对它们感兴趣,可间接进入我的项目主页查看 README.md
根底应用都有比拟具体的阐明,这里不再进行赘述了。
总结
本篇为大家介绍了 OCI 的前世今生,以及 OCI Image 的标准和特点,另外也介绍了一个可用于在 OCI Image 和 Docker Image 之间镜像转换的工具 skopeo
。另外介绍了一些可用于在 CI 环境或其余有特定场景环境下代替 Docker build 的工具,请大家按理论需要进行抉择。
欢送订阅我的文章公众号【MoeLove】