我已经在我的 GKE 集群上测试了 Cluster Autoscaler。它的工作方式与您的预期有些不同。
背景
您可以使用命令启用自动缩放,也可以在创建过程中启用它,如 in this documentation 所述。
在Cluster Autoscaler 文档中,您可以找到各种信息,例如Operation criteria、Limitations 等。
正如我在评论部分提到的,Cluster Autoscaler - Frequently Asked Questions 如果遇到以下情况之一将不起作用:
具有限制性 PodDisruptionBudget 的 Pod。
Kube-system pod:
- 默认不在节点上运行,*
- 没有设置 pod 中断预算,或者它们的 PDB 过于严格(自 CA 0.6 起)。
不受控制器对象支持的 Pod(因此不是由部署、副本集、作业、有状态集等创建的)。 *
具有本地存储的 Pod。 *
由于各种限制(缺乏资源、不匹配的节点选择器或亲和性、匹配的反亲和性等)而无法移动到其他地方的 Pods
具有以下注释集的 Pod:
"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"
对于我的测试,我使用了 6 个节点,autoscaling range 1-6 和 nginx 应用程序请求 cpu: 200m 和 memory: 128Mi。
正如 OP 提到的无法提供自动缩放器日志,我将从 Logs Explorer 粘贴我的日志。在Viewing cluster autoscaler events 文档中描述了如何实现它们。
在这些日志中,您应该搜索 noScaleDown 事件。您会在其中找到一些信息,但最重要的是:
reason: {
parameters: [
0: "kube-dns-66d6b7c877-hddgs"
]
messageId: "no.scale.down.node.pod.kube.system.unmovable"
正如NoScaleDown node-level reasons 中为"no.scale.down.node.pod.kube.system.unmovable" 描述的那样:
Pod 正在阻止缩减,因为它是一个非守护程序集、非镜像、非 pdb 分配的 kube-system pod。有关详细信息,请参阅 Kubernetes Cluster Autoscaler FAQ。
解决方案
如果你想让Cluster Autoscaler在GKE上工作,你必须用正确的信息创建Disruptions,如何创建它可以在How to set PDBs to enable CA to move kube-system pods?中找到
kubectl create poddisruptionbudget <pdb name> --namespace=kube-system --selector app=<app name> --max-unavailable 1
您必须在哪里指定正确的 selector 和 --max-unavailable 或 --min-available 取决于您的需要。更多详情请阅读Specifying a PodDisruptionBudget文档。
测试
$ kubectl get deploy,nodes
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 16/16 16 16 66m
NAME STATUS ROLES AGE VERSION
node/gke-cluster-1-default-pool-6d42fa0a-1ckn Ready <none> 11m v1.16.15-gke.6000
node/gke-cluster-1-default-pool-6d42fa0a-2j4j Ready <none> 11m v1.16.15-gke.6000
node/gke-cluster-1-default-pool-6d42fa0a-388n Ready <none> 3h33m v1.16.15-gke.6000
node/gke-cluster-1-default-pool-6d42fa0a-5x35 Ready <none> 3h33m v1.16.15-gke.6000
node/gke-cluster-1-default-pool-6d42fa0a-pdfk Ready <none> 3h33m v1.16.15-gke.6000
node/gke-cluster-1-default-pool-6d42fa0a-wqtm Ready <none> 11m v1.16.15-gke.6000
$ kubectl get pdb -A
NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
kube-system kubedns 1 N/A 1 43m
缩减部署
$ kubectl scale deploy nginx-deployment --replicas=2
deployment.apps/nginx-deployment scaled
一段时间后(约 10-15 分钟),您将在事件查看器中找到 Decision 事件,并在其中找到节点已删除的信息。
...
scaleDown: {
nodesToBeRemoved: [
0: {
node: {
mig: {
zone: "europe-west2-c"
nodepool: "default-pool"
name: "gke-cluster-1-default-pool-6d42fa0a-grp"
}
name: "gke-cluster-1-default-pool-6d42fa0a-wqtm"
节点数量减少:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
gke-cluster-1-default-pool-6d42fa0a-2j4j Ready <none> 30m v1.16.15-gke.6000
gke-cluster-1-default-pool-6d42fa0a-388n Ready <none> 3h51m v1.16.15-gke.6000
gke-cluster-1-default-pool-6d42fa0a-5x35 Ready <none> 3h51m v1.16.15-gke.6000
gke-cluster-1-default-pool-6d42fa0a-pdfk Ready <none> 3h51m v1.16.15-gke.6000
另一个可以确认它正在缩小的地方是kubectl get events --sort-by='.metadata.creationTimestamp'
输出:
5m16s Normal NodeNotReady node/gke-cluster-1-default-pool-6d42fa0a-wqtm Node gke-cluster-1-default-pool-6d42fa0a-wqtm status is now: NodeNotReady
4m56s Normal NodeNotReady node/gke-cluster-1-default-pool-6d42fa0a-1ckn Node gke-cluster-1-default-pool-6d42fa0a-1ckn status is now: NodeNotReady
4m Normal Deleting node gke-cluster-1-default-pool-6d42fa0a-wqtm because it does not exist in the cloud provider node/gke-cluster-1-default-pool-6d42fa0a-wqtm Node gke-cluster-1-default-pool-6d42fa0a-wqtm event: DeletingNode
3m55s Normal RemovingNode node/gke-cluster-1-default-pool-6d42fa0a-wqtm Node gke-cluster-1-default-pool-6d42fa0a-wqtm event: Removing Node gke-cluster-1-default-pool-6d42fa0a-wqtm from Controller
3m50s Normal Deleting node gke-cluster-1-default-pool-6d42fa0a-1ckn because it does not exist in the cloud provider node/gke-cluster-1-default-pool-6d42fa0a-1ckn Node gke-cluster-1-default-pool-6d42fa0a-1ckn event: DeletingNode
3m45s Normal RemovingNode node/gke-cluster-1-default-pool-6d42fa0a-1ckn Node gke-cluster-1-default-pool-6d42fa0a-1ckn event: Removing Node gke-cluster-1-default-pool-6d42fa0a-1ckn from Controller
结论
默认情况下,kube-system pod 会阻止 CA 删除运行它们的节点。用户可以手动为kube-system pod 添加PDBs ,这些pod 可以安全地在其他地方重新安排。可以通过以下方式实现:
kubectl create poddisruptionbudget <pdb name> --namespace=kube-system --selector app=<app name> --max-unavailable 1
CA 无法自动缩放的可能原因列表可在 Cluster Autoscaler - Frequently Asked Questions 中找到。
要验证哪些 pod 仍然可以阻止 CA downscale,您可以使用 Autoscaler Events。