GKE 自动缩放器未缩小节点

abb*_*ori 6 kubernetes google-kubernetes-engine

我创建了一个谷歌 Kubernetes 引擎,启用了自动缩放功能,并具有最小和最大节点。几天前,我在生产环境中部署了几台服务器,这按预期增加了节点数量。但是当我删除这些部署时,我希望它能够调整要缩小的节点的大小。我等了一个多小时但还是没有缩小。

  • 自从我使用 kind: 部署进行部署以来,我所有其他 pod 都由副本控制器控制。
  • 我所有的有状态 Pod 都使用 PVC 作为卷。

我不确定是什么阻止了节点缩小,所以我现在手动缩放节点。由于我手动进行了更改,所以现在无法获取自动缩放器日志。

有谁知道这里可能是什么问题?

GKE 版本为 1.16.15-gke.4300

如此链接中所述 https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-types-of-pods-can-prevent-ca-from-removing-a-node

  • 我没有使用任何本地存储。
  • pod 没有 PodDisruptionBudget(不知道那是什么)
  • Pod 由部署创建(helm 图表)
  • 唯一的问题是我没有 "cluster-autoscaler.kubernetes.io/safe-to-evict": "true" 这个注释。这是必须的吗?

Pjo*_*erS 6

我已经Cluster Autoscaler在我的 GKE 集群上进行了测试。它的工作原理与您的预期有点不同。

背景

您可以使用命令启用自动缩放或在创建过程中启用它,如本文档中所述。

Cluster Autoscaler文档中,您可以找到各种信息,例如Operation criteriaLimitations等。

正如我在评论部分提到的,如果遇到以下情况之一,集群自动缩放器 - 常见问题将不起作用:

具有限制性 PodDisruptionBudget 的 Pod。

Kube 系统 pod:

  • 默认情况下不在节点上运行,*
  • 没有设置 Pod 中断预算或者其 PDB 限制过多(自 CA 0.6 起)。

不受控制器对象支持的 Pod(因此不是由部署、副本集、作业、有状态集等创建的)。*

具有本地存储的 Pod。*

由于各种限制(缺乏资源、不匹配的节点选择器或亲和力、匹配反亲和力等)而无法移动到其他地方的 Pod

设置了以下注释的 Pod: "cluster-autoscaler.kubernetes.io/safe-to-evict": "false"

对于我的测试,我使用了 6 个节点,以及autoscaling range 1-6带有nginx请求cpu: 200m和 的应用程序memory: 128Mi

正如OP提到的,无法提供自动缩放器日志,我将从Logs Explorer. 有关如何实现这些功能的描述,请参阅查看集群自动缩放程序事件文档。

在这些日志中,您应该搜索noScaleDown事件。您会发现一些信息,但最重要的是:

reason: {
parameters: [
0: "kube-dns-66d6b7c877-hddgs"
]
messageId: "no.scale.down.node.pod.kube.system.unmovable"
Run Code Online (Sandbox Code Playgroud)

正如NoScaleDown 节点级原因中所述"no.scale.down.node.pod.kube.system.unmovable"

Pod 会阻止缩小规模,因为它是非守护程序集、非镜像、未分配 pdb 的 kube-system pod。有关更多详细信息,请参阅 Kubernetes Cluster Autoscaler 常见问题解答。

解决方案

如果你想Cluster Autoscaler在 上工作GKE,你必须使用正确的信息创建中断,如何创建它可以在如何设置 PDB 以使 CA 移动 kube-system pods?

kubectl create poddisruptionbudget <pdb name> --namespace=kube-system --selector app=<app name> --max-unavailable 1
Run Code Online (Sandbox Code Playgroud)

您必须根据您的需要指定正确的selectorand --max-unavailableor 。--min-available有关更多详细信息,请阅读指定 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
Run Code Online (Sandbox Code Playgroud)

缩减部署

$ kubectl scale deploy nginx-deployment --replicas=2
deployment.apps/nginx-deployment scaled
Run Code Online (Sandbox Code Playgroud)

一段时间(约 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"
Run Code Online (Sandbox Code Playgroud)

节点数量减少:

$ 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
Run Code Online (Sandbox Code Playgroud)

您可以确认其缩小的另一个地方是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
Run Code Online (Sandbox Code Playgroud)

结论

默认情况下,kube-systemPod 会阻止 CA 删除运行它们的节点。用户可以手动添加可以安全地重新安排到其他地方的 Pod PDBs kube-system可以使用以下方法来实现:

kubectl create poddisruptionbudget <pdb name> --namespace=kube-system --selector app=<app name> --max-unavailable 1
Run Code Online (Sandbox Code Playgroud)

无法自动缩放的可能原因列表可以在Cluster Autoscaler - 常见问题CA中找到。

要验证哪些 Pod 仍可以阻止CA缩减规模,您可以使用Autoscaler Events