关注上方 云原生CTO 更多云原生干货等你来探索
专注于 云原生技术
分享
提供优质 云原生开发
视频技术培训
面试技巧
,及技术疑难问题 解答
云原生技术分享不仅仅局限于 Go
、 Rust
、 Python
、 Istio
、 containerd
、 CoreDNS
、 Envoy
、 etcd
、 Fluentd
、 Harbor
、 Helm
、 Jaeger
、 Kubernetes
、 Open Polic y Agent
、 Prometheus
、 Rook
、 TiKV
、 TUF
、 Vitess
、 Argo
、 Buildpacks
、 CloudEvents
、 CNI
、 Contour
、 Cortex
、 CRI-O
、 Falco
、 Flux
、 gRPC
、 KubeEdge
、 Linkerd
、 NATS
、 Notary
、 OpenTracing
、 Operator Framework
、 SPIFFE
、 SPIRE
和 Thanos
等
Kube-fledged:在 Kubernetes 中缓存容器镜像 介绍 当容器化应用部署到 Kubernetes
集群时, K8s
控制平面会将 Pod
调度到集群中的工作节点。运行在工作节点中的节点代理 (Kubelet)
与安装在节点中的容器运行时(例如 containerd
)协调,并从镜像 registry
中拉取必要的容器镜像。根据镜像的大小和可用的网络带宽,将所有镜像拉取到节点需要时间。因此,在任何容器化应用程序中,我们都应该意识到由于从 registry
中获取镜像而引入的延迟。然而,作为进程运行的传统应用程序(例如由 systemd
管理)不会受到这种延迟的影响,因为所有必需的文件都已经安装在机器中。
想象一下,您的容器化应用程序遇到了突然的流量激增,它需要立即横向扩展(即需要创建额外的实例)。如果您配置了 Horizontal Pod Autoscaler (HPA)
, K8s
控制平面会创建额外的 Pod
副本。但是,这些 Pod
将无法用于处理增加的流量,直到所需的镜像被拉取,容器启动并运行。或者假设您的应用程序需要处理高速实时数据。此类应用程序对其启动和扩展的速度有严格的要求,因为它实现的目的的本质。
简而言之,在一些用例中,由于从 registry
中提取镜像而引入的延迟是不可接受的。此外,集群和镜像 registry
之间的网络连接可能会受到带宽不足的影响,或者连接可能会完全丢失。在某些情况下,尤其是在边缘计算中,应用程序必须优雅地容忍间歇性网络连接。
这些挑战可以通过不同的方式来解决。在这些场景中非常有用的一种解决方案是将容器镜像直接缓存在集群工作节点上,这样 Kubelet
不需要拉取这些镜像,而是立即使用已经缓存在节点中的镜像。在这篇博客中,我将解释如何使用开源项目 kube-fledged
在 Kubernetes
集群中构建和管理容器镜像的缓存。
现有解决方案 在向您介绍 kube-fledged
之前,让我简要介绍一下解决此问题的现有解决方案。广泛使用的方法是在集群内运行一个 Registry
镜像。两种广泛使用的解决方案是
在前一种解决方案中,本地注册中心在 k8s
集群中运行,并在容器运行时配置为镜像注册中心。
任何镜像拉取请求都被定向到集群内 registry
。如果失败,请求将被定向到主注册中心。在后一种解决方案中,本地 registry
具有缓存功能。第一次拉取镜像时,它会缓存在本地 registry
中。对镜像的后续请求由本地 registry
提供服务。
现有解决方案的缺点 设置和维护本地 registry
镜像会消耗大量计算资源和人力资源。
对于跨越多个区域的庞大集群,我们需要有多个本地 registry
镜像。当应用程序实例跨越多个区域时,这会引入不必要的复杂性。您可能需要有多个部署清单,每个清单都指向该区域的本地 registry
镜像。
这些方法并不能完全解决Pod快速启动的需求,因为从本地镜像拉取镜像仍然存在明显的延迟。有几个用例不能容忍这种延迟。
节点可能会失去与本地 registry
镜像的网络连接,因此 Pod 将卡住,直到连接恢复。
kube-fledged 概述 kube-fledged
是一个 kubernetes
插件或 operator
,用于直接在 kubernetes
集群的工作节点上创建和管理容器镜像的缓存。
它允许用户定义镜像列表以及这些镜像应该缓存(即拉取)到哪些工作节点上。因此,应用程序 pod
几乎立即启动,因为不需要从 registry
中提取镜像。 kube-fledged
提供了 CRUD API
来管理镜像缓存的生命周期,并支持多个可配置的参数来根据需要自定义功能。
https : github.com/senthilrch/kube-fledged)
kube-fledged
被设计和构建为用于管理 Kubernetes
中的镜像缓存的通用解决方案。尽管主要用例是实现快速 Pod
启动和扩展,但该解决方案支持多种用例,如下所述
用例 需要快速启动的应用程序。例如,由于数据量激增,执行实时数据处理的应用程序需要快速扩展。
无服务器函数,因为它们需要对传入的事件立即做出反应。
在边缘设备上运行的 IoT 应用程序,因为边缘设备和镜像registry之间的网络连接是间歇性的。
如果需要从私有registry中拉取镜像,并且无法授予每个人从该registry中拉取镜像的访问权限,则可以在集群节点上提供这些镜像。
如果集群管理员或操作员需要对应用程序进行升级,并希望事先验证是否可以成功拉取新镜像。
kube-fledged 的工作原理 Kubernetes
允许开发人员通过自定义资源扩展 kubernetes api
。 kube-fledged
定义了一个类型为“ ImageCache
”的自定义资源并实现了一个自定义控制器(名为 kubefledged-controller
)。
kubefledged-controller
负责管理镜像缓存。用户可以使用 kubectl
命令来创建和删除 ImageCache
资源。
kubefledged-controller
有一个内置的 Image Manager
例程,负责拉取和删除镜像。使用 kubernetes job
拉取或删除镜像。如果启用,刷新工作者会定期刷新镜像缓存。 kubefledged-controller
在 ImageCache
资源的 status
字段中更新镜像拉取、刷新和镜像删除的状态。 kubefledged-webhook-server
负责验证 ImageCache
资源的字段。
如果您需要在集群中创建镜像缓存,则只需 ImageCache
通过指定要拉取的镜像列表以及 nodeSelector.
将 nodeSelector
用于指定在其上的镜像应该被高速缓存的节点。如果您希望镜像缓存在集群的所有节点中,则省略 nodeSelector
. 当您将清单提交到集群时, API
服务器将向 kubefledged-webhook-server
发布验证 webhook
事件。 Webhook
服务器验证 cacheSpec
的清单。在收到来自 webhook
服务器的成功响应后, API
服务器将 ImageCache
资源持久保存在 etcd
中。这会触发对 kubefledged-controller
的 Informer
通知,该通知将请求排队。该请求由镜像缓存工作器接收,它创建多个镜像拉取请求(每个节点每个镜像一个请求)并将它们放入镜像拉取/删除队列中。
这些请求由镜像管理器例程处理。对于每个请求,镜像管理器都会创建一个 k8s job
,负责将镜像拉入缓存。镜像管理器会跟踪它创建的 job
,一旦 job
完成,它就会将响应放在一个单独的队列中。然后镜像缓存工作器聚合来自镜像管理器的所有结果,最后更新 ImageCache
资源的状态部分。
kube-fledged
有一个刷新工作例程,它会定期运行以保持镜像缓存刷新。如果它发现缓存中缺少任何镜像(可能被 kubelet
的镜像垃圾收集删除了),它会重新将镜像拉入缓存。带有 :latest
标签的镜像总是在刷新周期中被重新拉出。默认情况下,刷新周期每 5m
. 用户可以在部署 kube-fledged
时将其修改为不同的值或完全禁用自动刷新机制。还支持按需刷新机制,用户可以使用该机制请求 kube-fledged
立即刷新镜像缓存。
kube-fledged 支持的镜像缓存操作 kube-fledged
支持以下镜像缓存操作。所有这些操作都可以使用 kubectl
或通过直接向 Kubernetes API
服务器提交 REST API
请求来执行:
支持的Container Runtime 支持的平台 使用 kube-fledged 使用 kube-fledged
的最快方法是使用项目的 GitHub Repo ( https://github.com/senthilrch/kube-fledged
) 中的 YAML
清单来部署它。您还可以使用 helm chart
和 helm operator
部署它。在下面找到使用清单部署 kube-fledged
的步骤:
克隆源代码存储库
$ mkdir -p $HOME /src/github.com/senthilrch $ git clone https://github.com/senthilrch/kube-fledged.git $HOME /src/github.com/senthilrch/kube-fledged $ cd $HOME /src/github.com/senthilrch/kube-fledged
将 kube-fledged
部署到集群
$ make deploy-using-yaml
验证 kube-fledged
是否成功部署
$ kubectl get pods -n kube-fledged -l app=kubefledged $ kubectl get imagecaches -n kube-fledged (Output should be: 'No resources found' )
类似解决方案 在下面找到我注意到的类似开源解决方案的列表。这些解决方案尝试使用替代方法解决问题
Stargz Snapshotter
:具有延迟拉动功能的快速容器镜像分发插件
(https://github.com/containerd/stargz-snapshotter)
Uber Kraken
: Kraken
是一个 P2P Docker registry
,能够在几秒钟内分发 TB
数据
(https://github.com/uber/kraken)
Imagewolf
: ImageWolf
是一种 PoC
,它提供了一种将 Docker
镜像加载到集群上的极快方式,从而可以更快地推送更新
https://github.com/ContainerSolutions/ImageWolf)
结论 有些应用程序和用例需要快速启动和扩展。在这种情况下,从 registry
中拉取镜像所带来的延迟可能是不可接受的。此外,与 registry
的网络连接可能不稳定/间歇性。不授予所有用户访问安全 registry
的权限可能是出于安全原因。 Kube-fledged
是一个简单而有用的解决方案,可以直接在集群工作节点上构建和管理容器镜像的缓存
5.3 参考资料 参考地址 [1]
参考资料 [1] 参考地址: https://itnext.io/kube-fledged-cache-container-images-in-kubernetes-7880a00bab91