容器镜像加速指南:探索 Kubernetes 缓存最佳实践

介绍

将容器化应用程序部署到 Kubernetes 集群时,由于从 registry 中提取必要的容器镜像需要时间,因此可能会出现延迟。在应用程序需要横向扩展或处理高速实时数据的情况下,这种延迟尤其容易造成问题。幸运的是,有几种工具和策略可以改善 Kubernetes 中容器镜像的可用性和缓存。在本篇文章中,我们将全面介绍这些工具和策略,包括 kube-fledged、kuik、Kubernetes 内置的镜像缓存功能、本地缓存以及监控和清理未使用的镜像。

前提

将工作负载部署到 Kubernetes 时,某个 Pod 中的容器自然会基于 OCI 容器镜像。这些镜像可以从多种私有/公共存储库中提取。Kubernetes 会在拉取镜像的每个节点上本地缓存镜像,以便其他 Pod 使用相同的镜像。

然而在大多数用例中,这还不够。如今,大多数云 Kubernetes 集群都需要自动扩展,并根据客户的使用情况动态分配节点。如果多个节点必须多次调用同一个镜像怎么办?如果这个镜像很重,那可能需要几分钟时间。在应用自动伸缩的情况下,需要相对较长的时间。

现有解决方案

预期的解决方案需要在 Kubernetes 上建立一个缓存层,这样 Kubernetes 就有了一个集中的镜像缓存,所有节点都能从其中 "提取 "镜像。但是,由于缓存需要非常快,因此缓存解决方案需要位于 Kubernetes 内部,所有节点都应该以最快的延迟到达缓存。

要解决从 registry 中提取容器镜像的延迟问题,广泛使用的方法是在集群内运行 registry 镜像。

两种广泛使用的解决方案是集群内自托管 registry推送缓存 (pull-through cache)

在前一种解决方案中,本地 registry 在 Kubernetes 集群内运行,并在容器运行时配置为镜像 registry。任何镜像拉取请求都会指向集群内的 registry。在后一种解决方案中,容器镜像的缓存直接在工作节点上构建和管理。

其他现有解决方案包括使用 kuik 等可靠的缓存解决方案、在 Kubernetes 中启用镜像缓存、使用本地缓存、优化容器镜像构建以及监控和清理未使用的镜像。

Harbor

Harbor 是一个 CNCF 毕业项目,它的功能是容器 registry ,但最重要的是它还是一个推送代理缓存 (Pull Through Proxy Cache)

推送代理缓存是一种缓存机制,旨在优化容器 registry 环境中容器镜像的分发和检索。它充当用户端(如容器运行时或构建系统)和上游容器 registry 之间的中介。

当用户端请求容器镜像时,直通式代理缓存会检查它是否已经拥有所请求镜像的本地副本。如果镜像存在,代理缓存会直接将其提供给客户端,而无需从上游 registry 下载。这样可以减少网络延迟并节省带宽。

如果本地缓存中没有请求的镜像,代理缓存就会充当普通代理,将请求转发到上游 registry。然后,代理缓存会从 registry 中检索镜像,并将其提供给客户端。此外,代理缓存还会在其本地缓存中存储一份镜像副本,以备将来请求之用

kube-fledged

kube-fledged 是一个 K8s 附加组件或 operator,用于直接在 Kubernetes 集群的工作节点上创建和管理容器镜像缓存。它允许用户定义镜像列表,并将这些镜像缓存到哪个工作节点上。kube-fledged 提供了 CRUD API 来管理镜像缓存的生命周期,并支持多个可配置参数,以便根据个人需求定制功能。

kube-fledged 是为管理 Kubernetes 中的镜像缓存而设计和构建的通用解决方案。虽然主要用例是实现 Pod 的快速启动和扩展,但该解决方案支持下列的各种实例。

工作原理

kube-fledged 定义了一种名为 "ImageCache " 的自定义资源,并实现了一个自定义控制器(名为 kubefledged-controller)。用户可以使用 kubectl 命令创建和删除 ImageCache 资源

Kubernetes-image-puller

为了缓存镜像,Kubernetes Image Puller 会在所需集群上创建一个 Daemonset,然后在集群中的每个节点上创建一个 pod,其中包含一个命令 sleep 720h 的容器列表。这样就能确保集群中的所有节点都缓存了这些镜像。使用的 sleep 二进制基于 golang(请参阅 Scratch Images:https://github.com/che-incubator/kubernetes-image-puller#scratch-images)。我们还会定期检查守护进程集的健康状况,并在必要时重新创建它。

可以通过 Helm 或处理和应 OpenShift 模板来部署应用程序。此外,OperatorHub 上还有一个社区支持的 Operator。

kubernetes-image-puller 部署了大量容器(每个镜像和每个节点一个容器,缓存机制使用 daemonset),以实现缓存功能。举个例子:缓存中有 5 个节点和 10 个镜像,而我们在集群中已经有 50 个容器专门用于缓存功能。

Tugger

Tugger 使用单一配置文件,通过其 Helm 文件值定义。它不允许我们将"系统"配置(例如:从缓存系统中排除特定图片)和 "用户"配置分开。

Tugger 使用通过 Helm 文件值定义的单一配置文件。它不允许分离 "系统 "配置,比如从缓存系统中排除特定镜像,和 "用户 "配置。

kube-image-keeper (kuik)

kube-image-keeper(又名 kuik,类似于 "quick")是 Kubernetes 的容器镜像缓存系统。它能将 pod 使用的容器镜像保存在自己的本地 registry 中,这样在原始镜像不可用时,这些镜像仍可使用。

工作原理

创建 pod 时,kuik 的 webhook 会即时重写其镜像,并添加 localhost:{port}/ 前缀(默认 port 为 7439,可配置)。

localhost:{port} 上有一个镜像代理,它从 kuik 的缓存 registry (当镜像已被缓存时)或直接从原始 registry (当镜像尚未被缓存时)提供镜像。

控制器负责监控 pod,当发现新的镜像时,就会为这些镜像创建 CachedImage 自定义资源。另一个控制器会监测这些 CachedImage 自定义资源,并相应地将镜像从源 registry 复制到 kuik 的缓存 registry 中。

架构和组件

在 kuik 的命名空间中,您可以找到:

  • 运行 kuik 控制器的 Deployment

  • 运行 kuik 镜像代理的 DaemonSet

  • 当该组件在 HA 模式下运行时,会使用 StatefulSet 来运行 kuik 的镜像缓存,而不是Deployment

运行镜像缓存显然需要一定的磁盘空间(请参考 Garbage collection and limitations:https://github.com/enix/kube-image-keeper#garbage-collection-and-limitations)。除此之外,就计算资源而言,kuik 组件是相当轻量级的。这显示了默认设置下的 CPU 和 RAM 使用情况,其中两个控制器处于 HA 模式:

$ kubectl top pods
NAME                                             CPU(cores)   MEMORY(bytes)
kube-image-keeper-0                              1m           86Mi
kube-image-keeper-controllers-5b5cc9fcc6-bv6cp   1m           16Mi
kube-image-keeper-controllers-5b5cc9fcc6-tjl7t   3m           24Mi
kube-image-keeper-proxy-54lzk                    1m           19Mi

Warm-image

WarmImage CRD 获取镜像参考,并将其预取到集群中的每个节点上。

要在集群中安装这一自定义资源,只需运行:

# Install the CRD and Controller.
curl https://raw.githubusercontent.com/mattmoor/warm-image/master/release.yaml \
  | kubectl create -f -

或者,您也可以 git clone 该仓库并运行:

# Install the CRD and Controller.
kubectl create -f release.yaml

结论

在这篇文章中,我们向您展示了如何通过在节点上缓存镜像来加快 Pod 的启动速度。通过在 kubernetes 集群的工作节点上预取容器镜像,您可以显著缩短 Pod 的启动时间,即使是大型镜像,也可以缩短到几秒钟。这项技术能让运行机器学习、仿真、数据分析和代码构建等工作负载的客户受益匪浅,提高容器启动性能和整体工作负载效率。

由于无需额外管理基础设施或 Kubernetes 资源,这种方法为解决基于 Kubernetes 的环境中容器启动缓慢的问题提供了一种经济高效的解决方案。

文章转载自: Seal软件

原文链接: https://www.cnblogs.com/sealio/p/18093224

体验地址: 引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

相关推荐
qq_3643717216 分钟前
Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现
前端·vue.js·缓存
JunLan~5 小时前
Rocky Linux 系统安装/部署 Docker
linux·docker·容器
小袁搬码8 小时前
Windows中指定路径安装DockerDesktop
windows·docker·容器·docker desktop
qq_312920119 小时前
docker 部署 kvm 图形化管理工具 WebVirtMgr
运维·docker·容器
踏雪Vernon9 小时前
[OpenHarmony5.0][Docker][环境]OpenHarmony5.0 Docker编译环境镜像下载以及使用方式
linux·docker·容器·harmonyos
条纹布鲁斯10 小时前
dockerdsktop修改安装路径/k8s部署wordpress和ubuntu
docker·kubernetes
刘九灵10 小时前
Redis ⽀持哪⼏种数据类型?适⽤场景,底层结构
redis·缓存
CP-DD12 小时前
Docker 容器化开发 应用
运维·docker·容器
老司机张师傅12 小时前
【微服务实战之Docker容器】第七章-Dockerfile解析
容器·dockerfile·虚悬镜像·docker学习
登云时刻13 小时前
Kubernetes集群外连接redis集群和使用redis-shake工具迁移数据(一)
redis·kubernetes·bootstrap