Kubernetes 有非常广泛的话题。但是构建云原生应用程序时最常见的问题还是弹性扩缩容。
什么是缩放?我们应该怎么做才能实施有效的扩展实践?Kubernetes 在这方面对我们有帮助吗?
将分享一些关于应用程序自动缩放的见解,并谈到使用 K8s 自动缩放器时面临的一些现实挑战。
缩放是一种配置应用程序的过程,它可以根据负载的变化进行不同的资源发放。有两种类型的缩放,即集群和应用程序级别。
常见的是 Horizontal Pod Autoscaler HPA。一旦你深入到 Kubernetes 中的自动缩放领域,它就会出现。HPA 基于 CPU、内存或任何外部指标源执行自动缩放。
虽然表面上 HPA 似乎是完美的,但有一些挑战限制了它在现代应用中的使用。
让我们了解一下 K8s HPA 的不足之处?
HPA 仅提供 CPU 和内存作为开箱即用的资源!
对于大多数现代应用程序来说,这可能是一个巨大的问题。您的微服务很可能会通过它进行通信。以下方式之一:
直接通过 RESTFul 或 gRPC API。
间接通过像 RabbitMQ 这样的消息传递代理。
为了保持良好的 QoS 并防止在负载高峰时打挂您的服务,您需要实现某种速率限制功能。在基于 HTTP 的 API 中,我们使用 API 速率限制器。对于消息传递代理,我们限制了我们的服务可以同时处理的事件数量。
在任何一种情况下,这些机制都可以防止 CPU / 内存消耗猛增,从而使这些指标不适合扩展目的。
向 HPA 添加新指标很困难。
解决方案看起来很简单吧?只需向 HPA 添加新的指标源,例如挂起的消息队列大小?
真的没有😔!
添加新的指标来源很困难。老实说,为这样一个小问题付出努力似乎太过分了。
HPA 不能缩小到零!
你们中的大多数人可能不需要这个。但我是事件驱动架构的重度用户。我的很多管道都是异步的。这意味着当我的系统负载为零时,我可以将后台任务缩减到零以节省成本。
你觉得这个功能有必要吗?在下面的评论中告诉我!
由于 HPA 的扩展算法的工作方式,不可能从零开始扩展您的应用程序。
![c7b34bad91a0e904723fa38d6de8136c.png](https://i-blog.csdnimg.cn/blog_migrate/fe2edec7f395b726569a7e668fa45e13.png)
如果你currentReplicas变为零,当你缩放到零时,你的乘数也将变为零。这意味着无论您的负载有多高,您desiredReplicas都将始终为零。
现在已经足够支持 HPA 了。别担心,我们有一个了不起的开源项目来帮助我们!
KEDA!
什么是KEDA?它将如何使我们的生活变得轻松 ?
KEDA 是一个基于 Kubernetes 的事件驱动自动扩缩器。
它为 Kubernetes 资源提供了30 多个内置缩放器,因此我们不必担心为我们需要的各种指标源编写自定义适配器。
KEDA 为您提供了将资源扩展到零的强大功能!是的,我不是在开玩笑。KEDA 可以将您的资源从0扩展到 1或从 1 扩展到 0。从1 到 n 以及向后扩展由 HPA 负责。
![9ae11b670b53010dccac577b64cee2fb.png](https://i-blog.csdnimg.cn/blog_migrate/ee7aba16908ab40058c858b89852d7f7.png)
KEDA架构
KEDA 的架构简单易懂。KEDA 有 3 个重要组件,即Metric adapter、Controller & Scaler。
![4d42155861f3acd6fddd189dee743092.png](https://i-blog.csdnimg.cn/blog_migrate/3bc06bc4cf53d926d896d7bf96dd1278.png)
Scaler:连接到外部组件(例如,RabbitMQ)并获取指标(例如,待处理消息队列大小)。
Operator(Agent):负责“激活”一个 Deployment 并创建一个 Horizontal Pod Autoscaler 对象。
Metrics Adapter:将来自外部来源的指标呈现给 Horizontal Pod Autoscaler。
KEDA 如何实现“0 to 1”和“1 to 0”的缩放🧐 ?
每当 KEDA 的 metric 适配器检测到不存在负载时,它就会将 Deployment 缩小到零。
当没有应用程序在运行并且 Metric 适配器感知负载时,它会将 Deployment 从 0 扩展到 1。
如何使用KEDA?我是否必须编写很多配置才能使其工作?
答案是——不是这样的。
KEDA 为缩放器指标和资源自动缩放逻辑之间的所有类型的映射提供单个 CRD 。让我们以使用 Prometheus 作为扩展部署的度量源为例。
Prometheus 已成为存储 Kubernetes 指标的标准。所以在 ScaledObject 中,我们必须添加一个 PromQL 查询来进行自动缩放。
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaledobject
namespace: keda
spec:
scaleTargetRef:
deploymentName: my-deployment
triggers: # List of triggers
- type: prometheus
metadata:
serverAddress: http://<prometheus-host>:9090 # Prometheus Server
metricName: http_requests_total
threshold: '100'
query: sum(rate(http_requests_total{deployment="my-deployment"}[2m])) #Scale if Average request per 2 minutes is greater than 100
pollingInterval: 30 # Optional. Default: 30 seconds
cooldownPeriod: 300 # Optional. Default: 300 seconds
idleReplicaCount: 0 # Optional. Default: ignored, must be less than minReplicaCount
minReplicaCount: 1 # Optional. Default: 0
maxReplicaCount: 100 # Optional. Default: 100
fallback: # Optional. Section to specify fallback options
failureThreshold: 3 # Mandatory if fallback section is included
replicas: 6 # Mandatory if fallback section is included
只需添加一行 PromQL 查询,我们现在就可以根据查询返回的值自动扩展我们的资源。
现在让我们深入了解 ScaledObject 的一些配置
pollingInterval:这是拉取指标的时间间隔。KEDA 将检查该 ScaledObject 上的每个触发源,并相应地扩大或缩小部署。
coolDownPeriod: 在缩小到零之前等待的时间。
minReplicaCount:您的应用程序需要的最小副本。默认为 0。
Prometheus 自动缩放器真的很酷!但是现在,当我们看到下一个缩放器在起作用时,事情会变得更加有趣。
在销售的时候,亚马逊和其他电子商务平台面临着大量的流量。所以在 KEDA 的帮助下,我们可以根据cron schedule自动扩展。我们基本上可以按照固定的时间表抢先扩大副本数量。
triggers:
- type: cron
metadata:
# Required
timezone: Asia/Kolkata # The acceptable values would be a value from the IANA Time Zone Database.
start: 30 * * * * # Every hour on the 30th minute
end: 45 * * * * # Every hour on the 45th minute
desiredReplicas: "20"
在上述配置中,我们必须指定 KEDA 将您的资源扩展到所需副本的时区和时间跨度。
在 cron 缩放器的帮助下,您可以提前做好管理流量的准备。
谈谈一个人在使用 KEDA 时可能面临的一些现实挑战以及如何克服这些挑战?
假设您的应用程序正在运行视频转码作业,并且每个工作负载都在对视频进行转码,这大约需要 8 小时,并且您的队列包含 1000 个此类事件。下图展示了每个视频的进度条。
现在问题将在队列事件开始变慢时开始,HPA 开始缩减您的资源
问题是 HPA 不知道每个视频的转码进度,所以它只会像灭霸一样打响指,会随机杀死一个实例。
![283cf706880f244c6543a899c0314b6f.png](https://i-blog.csdnimg.cn/blog_migrate/6540309830ccdcec2bbce305571a2f7c.png)
为避免此问题,您可以有 2 个解决方案:
使用 Kubernetes 生命周期管理钩子SIGTERM,您可以利用它来延迟终止。
我们可以使用 KEDA 的 ScaledJob 对象来创建和扩展它,而不是针对事件创建部署。这样,它可以控制并行度,并且这些作业可以运行直到完成。
结论
KEDA 是一个轻量级组件,可以添加到任何 Kubernetes 集群中以扩展其功能。它解决了 K8s HPA 无法解决的现代世界应用程序自动扩展问题。
它通过提供编写自定义事件源的能力来提供可扩展性。
KEDA 可以根据工作负载从 0 到 1 进行扩展,从而优化基础架构成本。
参考
https://keda.sh/
https://cloudblogs.microsoft.com/opensource/2020/05/12/scaling-kubernetes-keda-intro-kubernetes-based-event-driven-autoscaling/
推荐
原创不易,随手关注或者”在看“,诚挚感谢!