Docker4.12.0Docker在刚刚发布的DockerDesktop4.12.0[1]中,增加了一个实验性的特性:进一步集成containerd,使用containerd管理和存储镜像。为什么说“进一步融合”?这就是Docker和containerd的历史。containerd的诞生containerd最早出现在DockerEngine中。后来为了让DockerEngine更加轻量、快速和健壮,Docker在2016年将containerd从daemon(dockerd)中分离出来,并完成了与daemonintegration的整合。独立的containerd完全支持OCI(OpenContainerInitiative[2])资源的启动和生命周期管理,因此containerd可以支持除runc(以前是Docker中的libcontainer,后来捐赠给LF)以外的其他OCI实现。2017年,Docker将containerd捐赠给CNCF;2019年2月,containerd毕业。dockerwithcontainerdcontainerd独立后,发送给DockerEngine的请求:Dockerdaemon完成镜像管理操作(拉取和更新镜像)和daemon准备创建容器(创建OCIbundle[3]):镜像信息和运行时间信息。守护进程调用containerd的API。收到请求的containerd不会直接操作容器(不会直接作为容器的父进程,防止containerd挂掉影响容器),而是先创建一个container-shim进程。container-shim调用runccli[4]运行容器,并启动Unixdomainsocket将API暴露给containerd进行容器管理。随着containerd的不断演进,除了容器创建和容器生命周期管理,containerd从1.1开始就增加了对CRI(ContainerRuntimeInterface)的支持。CRI在《源码解析 kubectl port-forward 工作原理》[5]的中间层提到kubelet会调用rumtime服务的gRPC接口。除了用于portforward流的流服务器之外,实际上还有CRI接口`RuntimeService`[6]和`ImageService`[7]RuntimeServiceServer和ImageServiceServer的实现。RuntimeServiceServer用于接收和处理与容器及其生命周期相关的操作,而ImageServiceServer用于处理与图像相关的操作。containerd提供镜像拉取、删除、查看、存储等功能。既然containerd可以管理镜像,Docker已经在用了,Docker就没必要再继续维护同一套功能了。切换到containerd镜像管理在DockerDesktop设置中启动containerd管理镜像后,运行dockerinfo,会发现存储驱动从原来的overlay2变成了containerd的stargz。切换前:切换前切换后:切换后,由于containerd的snapshotter是用来管理存储的(挂在容器的根文件系统上),所以可以支持多种snapshotter,比如stargz的延迟拉取[8]].另外,得益于containerd对多平台镜像存储的原生支持,或者说因为snapshotters,可以使用docker构建多平台镜像。#在切换dockerbuildxbuild-tdemo--no-cache--platformlinux/amd64,linux/arm64之前。[+]构建0.0s(0/0)错误:docker驱动程序目前不支持多平台功能。PleaseSwitchtoadifferentdriver(eg."dockerbuildxcreate--use")总结使用containerd作为Docker的镜像管理还在实验阶段,势必会避免出现问题。使用时请小心。随着DockerSwarm在容器编排大战中失利,Kubernetes的声音越来越大。随着Kubernetes1.24.0中dockershim代码的移除,看起来containerd已经接管了Docker曾经的位置,Docker越来越不为人所知。从趋势来看,Docker未来会全面整合containerd。参考ExtendingDocker'sIntegrationwithcontainerd[9]Dockercontainerdintegration[10]LearningContainersFromBottomUp[11]参考资料[1]DockerDesktop4.12.0:https://docs.docker.com/desktop/release-notes/#docker-desktop-4120[2]开放容器计划:https://www.opencontainers.org[3]OCI包:https://chromium.googlesource.com/external/github.com/docker/containerd/+/refs/tags/v0.2.0/docs/bundle.md[4]runccli:https://github.com/opencontainers/runc[5]《源码解析 kubectl port-forward 工作原理》:https://atbug.com/how-kubectl-port-forward-works/[6]RuntimeService:https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1/api.proto#L34[7]图片服务:https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1/api.proto#L128[8]stargz:https://github.com/containerd/stargz-snapshotter[9]扩展Docker与containerd的集成:https://www.docker.com/blog/extending-docker-integration-with-containerd/[10]Dockercontainerd集成:https://www.docker.com/博客/码头er-containerd-integration/[11]自下而上学习容器:https://iximiuz.com/en/posts/container-learning-path/
