在本系列博客的第1部分中,我们介绍了这样一种想法,即Kubernetes运营商(在大规模部署时)可以消耗大量资源,无论是实际资源消耗还是可调度容量的消耗。我们还介绍了一种想法,即无服务器技术可以通过在活动控制器部署空闲时减少其规模来减少对Kubernetes集群的影响。在本文中,我们将基于闲置时将Pod实例的数量缩放为零的想法,介绍一种无需进行源修改即可减少现有控制器的资源开销的技术。
除了核心的Kubernetes平台之外,大多数运营商和其他通用控制器都使用Deployments或StatefulSets进行部署。这两种构造都具有将标度设置为特定值的能力。然后,Kubernetes平台添加或删除吊舱以实现所需的价值。但是,将控制器扩展到一个以上的实例通常仅提供冗余。这是由于内置的一致性检查所致,该检查可确保控制器容器不会相互干扰。以下是许多控制器和操作员所特有的部署:
如果将此类部署的规模设置为0,Kubernetes控制器管理器将终止任何正在运行的Pod,从而使我们没有任何活动的控制器实例来处理资源事件。实际上,在更改比例时,我们将禁用当前控制器的事件处理。
在最简单的情况下,控制器停止时不会发生资源修改,并且在修改监视的资源之前会恢复控制器规模。在这种情况下,只需将部署规模设置为大于零的标量值,即可将控制器恢复到之前的状态。但是,当控制器停止时发生资源修改的情况又如何呢?
Kubernetes中的和解是基于称为“级别触发”的概念构建的。在级别触发的系统中,对帐是针对整个状态进行的,而不是依赖于单个事件或自上次对帐以来发生的那些事件的顺序。当进行扩展时,我们的控制器将仅查看要监视的资源,并将其状态与目标资源协调一致,而不管过渡期间发生了多少个人更改。要了解有关Kubernetes中的电平触发的更多信息,请查看James Bowes的文章“ Kubernetes中的电平触发和对帐”。
如果Kubernetes控制器部署可以容忍从零扩展到零并且可以再次备份,那么这可以根据实际活动自动完成吗?绝对是,这是控制器零缩放器的目标。
控制器零缩放器本身就是一个Kubernetes控制器,它监视Kubernetes API的活动,一旦它们变得空闲,就会自动按比例缩小控制器,稍后在发生相关资源修改后恢复缩放。由于它是由各个控制器部署上的注释完全驱动的,因此可以在现有Kubernetes部署中启用零标度控制器而无需进行源代码修改。
图2显示了控制器零缩放器如何针对正在运行的控制器部署进行工作。
启动时,控制器零缩放器开始监视具有一组批注的部署。这些注释将部署标识为控制器零缩放器应对其执行操作的控制器。一旦确定部署正在管理中,控制器零缩放器便开始监视与该控制器相关的API服务器活动。一旦在一段时间内没有发生任何资源修改,就确定该单个控制器为空闲,并且其规模设置为零。
同时,控制器零缩放器会继续监视控制器需要处理的任何Kubernetes API服务器活动。如果确实发生资源更改,将恢复规模,这将对控制器吊舱做出反应。最终结果是,在发生诸如“ kubectl apply”之类的操作之后的几分钟内,下游资源修改将完成。
让我们来看一个使用Banzai Cloud中Istio Operator的示例。我们将执行以下顺序:
首先,将通过克隆项目并利用makefile来安装相关的“自定义资源定义”(CRD)和用于部署控制器容器的StatefulSet,来安装Istio Operator:
git clone git@github.com:banzaicloud/istio-operator.git cd istio-operator make deploy
通过查看正在运行的实例数(应为1)来验证此部署是否成功。您可能需要等待片刻才能激活控制器,因为首先需要拉动图像。
kubectl get statefulsets -n istio-system istio-operator-controller-manager NAME DESIRED CURRENT AGE istio-operator-controller-manager 1 1 8s
现在,让我们部署控制器零缩放器。由于Docker映像尚未公开可用,因此我们需要首先构建该映像。
再次,我们将验证控制器部署实际上已经开始:
kubectl get deployments -n controller-zero-scaler controller-zero-scaler NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE controller-zero-scaler 1 1 1 1 21s
现在,让我们来看看自动缩放的作用。首先,我们需要在这个特定的控制器上启用零缩放,我们将使用一组注释来做到这一点。
kubectl annotate -n istio-system statefulset -l \ controller-tools.k8s.io='1.0' \ controller-zero-scaler/idleTimeout='30s' \ controller-zero-scaler/watchedKinds='[{"apiVersion": "istio.banzaicloud.io/v1beta1", "Kind": "Istio"}]' statefulset.apps/istio-operator-controller-manager annotated
这将添加两个与零标度活动相关的注释:
等待至少30秒后,您应该看到Istio控制器容器已停止:
sleep 30 && kubectl get statefulsets --all-namespaces
NAMESPACE NAME DESIRED CURRENT AGE
istio-system istio-operator-controller-manager 0 0 2m36s
到目前为止,我们已成功将Istio控制器缩放为零。现在,我们来看看更改Istio资源时会发生什么。让我们使用istio-operator目录中提供的示例:
kubectl apply -f config/samples/istio_v1beta1_istio.yaml
现在,我们可以通过查看Istio控制器的容器数量来验证放大是否成功。我们还可以检查下游操作员动作是否发生。对于Istio Operator,将安装一些自定义资源定义(CRD)(以及多个部署)。
# Here we should see 1 available as long as we do not wait too long!
kubectl get deployments -n controller-zero-scaler controller-zero-scaler
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
controller-zero-scaler 1 1 1 1 7m33s
# There should be 55 CRDs as well as 8 deployments
kubectl get crd | grep -i istio.io | wc -l
55
kubectl get deployments --all-namespaces | grep istio | wc -l
控制器零标度解决方案非常适合现有的控制器实现,因为可以在单个集群上启用它而无需进行任何源修改。这意味着您可以直接购买操作员,并带有正确的注释,即可立即受益。
Knative是另一种在运营商和Kubernetes控制器之外具有广泛吸引力的无服务器技术。在本系列的最后一篇博文中,我们将探讨如何将Knative事件(使用Kubernetes API Server作为事件源)用作构建Kubernetes控制器和运算符的基础。
原文:https://www.ibm.com/cloud/blog/new-builders/being-frugal-with-kubernetes-operators-part-2
本文:http://jiagoushi.pro/node/874/