使用 AWS Auto Scaling 组进行集群弹性伸缩

本文提供了使用 AWS EC2 自动伸缩组在 Rancher 自定义集群上安装和使用Kubernetes cluster-autoscaler的操作指导。

我们将安装一个 Rancher RKE 自定义集群,这个集群中有固定数量的节点,这些节点配置了 etcd 或 controlplane 角色,还有一个的节点,配置了 worker 角色,由cluster-autoscaler管理。

先决条件

使用 AWS Auto Scaling 组进行集群弹性伸缩需要满足以下条件:

  • Rancher server 已经启动,并正在运行
  • 已有 AWS EC2 账户,而且这个账户具有创建虚拟机、自动扩展组、IAM 配置文件和角色的权限。

创建一个自定义集群

使用 Kubernetes v1.18.x,在 Rancher server 上创建一个自定义 k8s 集群。请将cloud_provider名称配置为amazonec2。完成自定义集群的创建流程后,需要运行以下命令,获取如下参数信息:

  1. sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:<RANCHER_VERSION> --server https://<RANCHER_URL> --token <RANCHER_TOKEN> --ca-checksum <RANCHER_CHECKSUM> <roles>
  • clusterID: c-xxxxx 用于 EC2kubernetes.io/cluster/<clusterID>实例标签
  • clusterName:用于 EC2k8s.io/cluster-autoscaler/<clusterName>实例标签
  • nodeCommand: 将被添加到 EC2 实例 user_data 上,以包括集群上的新节点

配置云服务提供商

在 AWS EC2 上,创建一些 objects 完成系统配置。下文定义了三个不同的组:Autoscaling group、Master group 和 Worker group,以及 IAM 配置文件,您需要用到这些组和配置文件完成系统配置。

  1. Autoscaling group(下文简称 ASG):属于 EC2 自动缩放组 ASG 的节点。cluster-autoscaler使用 ASG 以扩大或缩小集群规模。
  • IAM 配置文件:运行 cluster-autoscaler 的 k8s 节点需要使用的配置文件,建议 Kubernetes master 节点使用。这个配置文件叫做K8sAutoscalerProfile

    1. {
    2. "Version": "2012-10-17",
    3. "Statement": [
    4. {
    5. "Effect": "Allow",
    6. "Action": [
    7. "autoscaling:DescribeAutoScalingGroups",
    8. "autoscaling:DescribeAutoScalingInstances",
    9. "autoscaling:DescribeLaunchConfigurations",
    10. "autoscaling:SetDesiredCapacity",
    11. "autoscaling:TerminateInstanceInAutoScalingGroup",
    12. "autoscaling:DescribeTags",
    13. "autoscaling:DescribeLaunchConfigurations",
    14. "ec2:DescribeLaunchTemplateVersions"
    15. ],
    16. "Resource": ["*"]
    17. }
    18. ]
    19. }
  1. Master group:独立于 ASG 之外的 etcd 或 controlplane 节点。
  • IAM 配置文件:与云服务厂商集成的时候,需要提供的 IAM 配置文件。可以选择使用AWS_ACCESS_KEYAWS_SECRET_KEY代替using-aws-credentials.这个配置文件叫做K8sMasterProfile

    1. {
    2. "Version": "2012-10-17",
    3. "Statement": [
    4. {
    5. "Effect": "Allow",
    6. "Action": [
    7. "autoscaling:DescribeAutoScalingGroups",
    8. "autoscaling:DescribeLaunchConfigurations",
    9. "autoscaling:DescribeTags",
    10. "ec2:DescribeInstances",
    11. "ec2:DescribeRegions",
    12. "ec2:DescribeRouteTables",
    13. "ec2:DescribeSecurityGroups",
    14. "ec2:DescribeSubnets",
    15. "ec2:DescribeVolumes",
    16. "ec2:CreateSecurityGroup",
    17. "ec2:CreateTags",
    18. "ec2:CreateVolume",
    19. "ec2:ModifyInstanceAttribute",
    20. "ec2:ModifyVolume",
    21. "ec2:AttachVolume",
    22. "ec2:AuthorizeSecurityGroupIngress",
    23. "ec2:CreateRoute",
    24. "ec2:DeleteRoute",
    25. "ec2:DeleteSecurityGroup",
    26. "ec2:DeleteVolume",
    27. "ec2:DetachVolume",
    28. "ec2:RevokeSecurityGroupIngress",
    29. "ec2:DescribeVpcs",
    30. "elasticloadbalancing:AddTags",
    31. "elasticloadbalancing:AttachLoadBalancerToSubnets",
    32. "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer",
    33. "elasticloadbalancing:CreateLoadBalancer",
    34. "elasticloadbalancing:CreateLoadBalancerPolicy",
    35. "elasticloadbalancing:CreateLoadBalancerListeners",
    36. "elasticloadbalancing:ConfigureHealthCheck",
    37. "elasticloadbalancing:DeleteLoadBalancer",
    38. "elasticloadbalancing:DeleteLoadBalancerListeners",
    39. "elasticloadbalancing:DescribeLoadBalancers",
    40. "elasticloadbalancing:DescribeLoadBalancerAttributes",
    41. "elasticloadbalancing:DetachLoadBalancerFromSubnets",
    42. "elasticloadbalancing:DeregisterInstancesFromLoadBalancer",
    43. "elasticloadbalancing:ModifyLoadBalancerAttributes",
    44. "elasticloadbalancing:RegisterInstancesWithLoadBalancer",
    45. "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer",
    46. "elasticloadbalancing:AddTags",
    47. "elasticloadbalancing:CreateListener",
    48. "elasticloadbalancing:CreateTargetGroup",
    49. "elasticloadbalancing:DeleteListener",
    50. "elasticloadbalancing:DeleteTargetGroup",
    51. "elasticloadbalancing:DescribeListeners",
    52. "elasticloadbalancing:DescribeLoadBalancerPolicies",
    53. "elasticloadbalancing:DescribeTargetGroups",
    54. "elasticloadbalancing:DescribeTargetHealth",
    55. "elasticloadbalancing:ModifyListener",
    56. "elasticloadbalancing:ModifyTargetGroup",
    57. "elasticloadbalancing:RegisterTargets",
    58. "elasticloadbalancing:SetLoadBalancerPoliciesOfListener",
    59. "iam:CreateServiceLinkedRole",
    60. "ecr:GetAuthorizationToken",
    61. "ecr:BatchCheckLayerAvailability",
    62. "ecr:GetDownloadUrlForLayer",
    63. "ecr:GetRepositoryPolicy",
    64. "ecr:DescribeRepositories",
    65. "ecr:ListImages",
    66. "ecr:BatchGetImage",
    67. "kms:DescribeKey"
    68. ],
    69. "Resource": ["*"]
    70. }
    71. ]
    72. }
  • IAM 角色:K8sMasterRole。[K8sMasterProfile,K8sAutoscalerProfile]

    • 安全组:K8sMasterSg更多信息请见RKE ports (custom nodes tab)

    • 标签: kubernetes.io/cluster/<clusterID>: owned

    • 用户数据:K8sMasterUserDataUbuntu 18.04(ami-0e11cbb34015ff725),安装 docker 并将 etcd+controlplane 节点添加到 k8s 集群中。- IAM 角色:K8sMasterRole。[K8sMasterProfile,K8sAutoscalerProfile]

      1. ```sh
      2. #!/bin/bash -x
      3. cat <<EOF > /etc/sysctl.d/90-kubelet.conf
      4. vm.overcommit_memory = 1
      5. vm.panic_on_oom = 0
      6. kernel.panic = 10
      7. kernel.panic_on_oops = 1
      8. kernel.keys.root_maxkeys = 1000000
      9. kernel.keys.root_maxbytes = 25000000
      10. EOF
      11. sysctl -p /etc/sysctl.d/90-kubelet.conf
      12. curl -sL https://releases.rancher.com/install-docker/19.03.sh | sh
      13. sudo usermod -aG docker ubuntu
      14. TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
      15. PRIVATE_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/local-ipv4)
      16. PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/public-ipv4)
      17. K8S_ROLES="--etcd --controlplane"
      18. sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:<RANCHER_VERSION> --server https://<RANCHER_URL> --token <RANCHER_TOKEN> --ca-checksum <RANCHER_CA_CHECKSUM> --address ${PUBLIC_IP} --internal-address ${PRIVATE_IP} ${K8S_ROLES}
      19. ```
  1. Worker group:worker 节点,将由集群 autoscaler 使用 ASG 进行缩放。
  • IAM 配置文件。提供 cloud_provider worker 集成。此配置文件称为K8sWorkerProfilejson { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:DescribeInstances", "ec2:DescribeRegions", "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:GetRepositoryPolicy", "ecr:DescribeRepositories", "ecr:ListImages", "ecr:BatchGetImage" ], "Resource": "*" } ] }

  • IAM 角色:K8sWorkerRole: [K8sWorkerProfile]

    • 安全组:K8sWorkerSg 更多信息请见 RKE ports (custom nodes tab)

    • 标签:

      • kubernetes.io/cluster/<clusterID>: owned
      • k8s.io/cluster-autoscaler/<clusterName>: true
      • k8s.io/cluster-autoscaler/enabled: true
    • 用户数据:K8sWorkerUserDataUbuntu 18.04(ami-0e11cbb34015ff725),安装 docker 并将 worker 节点添加到 k8s 集群中。
    1. #!/bin/bash -x cat <<EOF > /etc/sysctl.d/90-kubelet.conf
    2. vm.overcommit_memory = 1
    3. vm.panic_on_oom = 0
    4. kernel.panic = 10
    5. kernel. panic_on_oops = 1
    6. kernel.keys.root_maxkeys = 1000000
    7. kernel.keys.root_maxbytes = 25000000
    8. EOF
    9. sysctl -p /etc/sysctl.d/90-kubelet. conf
    10. curl -sL https://releases.rancher.com/install-docker/19.03.sh | sh sudo usermod -aG docker ubuntu
    11. TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
    12. PRIVATE_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169. 254.169.254/latest/meta-data/local-ipv4)
    13. PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169. 254/latest/meta-data/public-ipv4)
    14. K8S_ROLES="--worker"
    15. sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent: <RANCHER_VERSION> --server https://<RANCHER_URL> --token <RANCHER_TOKEN> --ca-checksum <RANCHER_CA_CHECKCSUM> --address ${PUBLIC_IP} --internal-address ${PRIVATE_IP} ${K8S_ROLES}`

更多信息请参见AWS 上的 RKE 集群AWS 上的 Cluster Autoscaler

部署节点

配置了 AWS 后,需要创建虚拟机来引导集群。

  • master(etcd+controlplane)节点:部署三个 master 实例。更多信息请参见生产就绪集群的建议

    • IAM 角色:K8sMasterRole
    • 安全组:K8sMasterSg
    • 标签:
      • kubernetes.io/cluster/<clusterID>: owned
    • 用户数据: K8sMasterUserData
  • worker 节点:在 EC2 上定义一个 ASG,设置如下:

    • 名称:K8sWorkerAsg
    • IAM 角色:K8sWorkerRole
    • 安全组:K8sWorkerSg
    • 标签:
      • kubernetes.io/cluster/<clusterID>: owned
      • k8s.io/cluster-autoscaler/<clusterName>: true
      • k8s.io/cluster-autoscaler/enabled: true
    • 用户数据:K8sWorkerUserData
    • 实例数量: minimum: 2 desired: 2 * maximum: 10 部署了虚拟机后,您应该拥有一个由三个主节点和两个工作节点组成的 Rancher 自定义集群。

安装 Cluster-autoscaler

此时,我们应该已经有了 rancher 集群并开始运行。我们将按照 cluster-autoscaler 的建议,在主节点和kube-system命名空间安装 cluster-autoscaler。

参数对照表

下表说明了用于微调的集群 cluster-autoscaler 参数:

参数默认值描述
cluster-name-配置自动弹性伸缩的集群名称
address:8085暴露 Prometheus 指标的地址
kubernetes-Kubernetes master 节点的位置,默认情况下不需要填写
kubeconfig-包含认证信息和 master 节点信息的 kubeconfig 文件的路径。
cloud-config-云提供商配置文件的路径,空字符串表示没有配置文件
namespace“kube-system”运行 cluster-autoscaler 的命名空间名称
scale-down-enabledtruecluster-autoscaler 是否具有对集群进行缩容操作的权限
scale-down-delay-after-add“10m”扩容后,重新评估是否应该缩容前的等待时间,默认值为”10m”,表示 10 分钟
scale-down-delay-after-delete0删除节点后,重新评估是否应该缩容前的等待时间,通过scanInterval参数配置该时间
scale-down-delay-after-failure“3m”节点出现 failures 后,重新评估是否应该缩容前的等待时间,默认值为”3m”,表示 3 分钟
scale-down-unneeded-time“10m”一个节点被判定为”unneeded“,满足缩容的时间条件
scale-down-unready-time“20m”一个 unready 节点被判定为”unneeded“,满足缩容的时间条件
scale-down-utilization-threshold0.5节点上运行的所有 pods 的 cpu 或内存之和除以节点相应的可分配资源,低于此值的节点可以考虑缩减
scale-down-gpu-utilization-threshold0.5节点上运行的所有 pod 的 gpu 请求的总和除以节点的可分配资源,低于此值的节点可以考虑进行缩减
scale-down-non-empty-candidates-count30每次批量缩容可以容纳的最大非空节点数量
scale-down-candidates-pool-ratio0.1当上一次迭代中的一些候选者不再有效时,被认为是额外的非空候选者的节点比例
scale-down-candidates-pool-min-count50当上一次迭代中的一些候选者不再有效时,被认为是额外的非空候选者的最小节点数
node-deletion-delay-timeout“2m”在删除节点之前,cluster-autoscaler 等待删除 delay-deletion.cluster-autoscaler.ko/注释的最长时间
scan-interval“10s”对集群进行一次扩大或缩小规模的重新评估的间隔时长
max-nodes-total0所有节点组中的最大节点数,cluster-autoscaler 不会将集群扩容到超过这个数字的数量
cores-total“0:320000”集群中的最小和最大核心数,格式为<min>:<max>:<other…>,集群自动扫描器不会将集群的规模扩大到这些数字之外
memory-total“0:6400000”集群中内存的最小和最大千兆字节数,格式为<min>:<max>:<other…>,集群自动扫描器不会将集群的规模扩大到这些数字之外
cloud-provider-云服务提供商的类型
max-bulk-soft-taint-count10可以同时被污染/不污染 PreferNoSchedule 的节点的最大数量,设置为 0 可以关闭这种污点标记
max-bulk-soft-taint-time“3s”同时作为 PreferNoSchedule 的污点/污点节点的最大持续时间
max-empty-bulk-delete10可同时删除的空节点的最大数量
max-graceful-termination-sec600当 cluster-autoscaler 试图缩减一个节点时,等待 pod 终止的最大秒数
max-total-unready-percentage45集群中未准备好的节点的最大百分比。超过这个百分比后,CA 就会停止操作。
ok-total-unready-count3允许的未准备好的节点数,不考虑最大总未准备好的百分比。
scale-up-from-zerotrue当有 0 个准备好的节点时,集群自动加速器是否应该扩大规模
max-node-provision-time“15m”cluster-autoscaler 等待配置节点的最长时间
nodes-以云提供商接受的格式为节点组设置最小、最大大小和其他配置数据。可多次使用。格式: <min>:<max>:<其他…><min>:<max>:<其他…>
node-group-auto-discovery-节点组自动发现的一个或多个定义。定义表示为<name of discoverer>:[<key>[=<value>]]
estimator-“binpacking”扩大规模时使用的资源估算器类型,可用值:[“binpacking”]
expander“random”扩大规模时要使用的节点组扩展器的类型。可用的值:[“random”,”most-pods”,”least-waste”,”price”,”priority”]
ignore-daemonsets-utilizationfalseCA 在计算资源利用率进行伸缩时,是否应该忽略 DaemonSet pods
ignore-mirror-pods-utilizationfalse在计算缩减资源利用率时,CA 是否应该忽略 Mirror pods
write-status-configmaptrueCA 是否应该将状态信息写入 configmap
max-inactivity“10m”在自动重启之前,从最后一次记录的 autoscaler 活动开始的最长时间
max-failing-time“15m”在自动重启之前,从最后一次记录的 autoscaler 成功运行的最长时间
balance-similar-node-groupsfalse检测相似的节点组,并平衡它们之间的节点数量
node-autoprovisioning-enabledfalseCA 是否应该在需要的时候自动提供节点组
max-autoprovisioned-node-group-count15集群中自动提供的组的最大数量
unremovable-node-recheck-timeout“5m”我们再次检查之前无法删除的节点之前的超时时间
expendable-pods-priority-cutoff-10优先级低于截止值的 pods 将被消耗掉。他们可以在缩减规模的时候被杀死,而且不会导致规模扩大。优先级为空的 pods(PodPriority 禁用)是不可消耗的
regionalfalse是不是 regional 集群
new-pod-scale-up-delay“0s”不扩容小存活时间小于这个设定时间的 pods
ignore-taint-指定在考虑缩放节点组时,在节点模板中忽略的污点。
balancing-ignore-label-指定在比较两个节点组是否相似时,除了基本标签和云提供商标签集外,还要忽略的标签
aws-use-static-instance-listfalseCA 应该在运行时获取实例类型还是使用静态列表,这个参数只有 AWS 可用
profilingfalse是否启用了 debug/pprof 端点

部署

基于cluster-autoscaler-run-on-master.yaml的例子,我们创建了自己的cluster-autoscaler-deployment.yaml,使用首选的auto-discovery setup,更新容忍度、nodeSelector、镜像版本和命令配置。

  1. ---
  2. apiVersion: v1
  3. kind: ServiceAccount
  4. metadata:
  5. labels:
  6. k8s-addon: cluster-autoscaler.addons.k8s.io
  7. k8s-app: cluster-autoscaler
  8. name: cluster-autoscaler
  9. namespace: kube-system
  10. ---
  11. apiVersion: rbac.authorization.k8s.io/v1
  12. kind: ClusterRole
  13. metadata:
  14. name: cluster-autoscaler
  15. labels:
  16. k8s-addon: cluster-autoscaler.addons.k8s.io
  17. k8s-app: cluster-autoscaler
  18. rules:
  19. - apiGroups: [""]
  20. resources: ["events", "endpoints"]
  21. verbs: ["create", "patch"]
  22. - apiGroups: [""]
  23. resources: ["pods/eviction"]
  24. verbs: ["create"]
  25. - apiGroups: [""]
  26. resources: ["pods/status"]
  27. verbs: ["update"]
  28. - apiGroups: [""]
  29. resources: ["endpoints"]
  30. resourceNames: ["cluster-autoscaler"]
  31. verbs: ["get", "update"]
  32. - apiGroups: [""]
  33. resources: ["nodes"]
  34. verbs: ["watch", "list", "get", "update"]
  35. - apiGroups: [""]
  36. resources:
  37. - "pods"
  38. - "services"
  39. - "replicationcontrollers"
  40. - "persistentvolumeclaims"
  41. - "persistentvolumes"
  42. verbs: ["watch", "list", "get"]
  43. - apiGroups: ["extensions"]
  44. resources: ["replicasets", "daemonsets"]
  45. verbs: ["watch", "list", "get"]
  46. - apiGroups: ["policy"]
  47. resources: ["poddisruptionbudgets"]
  48. verbs: ["watch", "list"]
  49. - apiGroups: ["apps"]
  50. resources: ["statefulsets", "replicasets", "daemonsets"]
  51. verbs: ["watch", "list", "get"]
  52. - apiGroups: ["storage.k8s.io"]
  53. resources: ["storageclasses", "csinodes"]
  54. verbs: ["watch", "list", "get"]
  55. - apiGroups: ["batch", "extensions"]
  56. resources: ["jobs"]
  57. verbs: ["get", "list", "watch", "patch"]
  58. - apiGroups: ["coordination.k8s.io"]
  59. resources: ["leases"]
  60. verbs: ["create"]
  61. - apiGroups: ["coordination.k8s.io"]
  62. resourceNames: ["cluster-autoscaler"]
  63. resources: ["leases"]
  64. verbs: ["get", "update"]
  65. ---
  66. apiVersion: rbac.authorization.k8s.io/v1
  67. kind: Role
  68. metadata:
  69. name: cluster-autoscaler
  70. namespace: kube-system
  71. labels:
  72. k8s-addon: cluster-autoscaler.addons.k8s.io
  73. k8s-app: cluster-autoscaler
  74. rules:
  75. - apiGroups: [""]
  76. resources: ["configmaps"]
  77. verbs: ["create", "list", "watch"]
  78. - apiGroups: [""]
  79. resources: ["configmaps"]
  80. resourceNames:
  81. ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
  82. verbs: ["delete", "get", "update", "watch"]
  83. ---
  84. apiVersion: rbac.authorization.k8s.io/v1
  85. kind: ClusterRoleBinding
  86. metadata:
  87. name: cluster-autoscaler
  88. labels:
  89. k8s-addon: cluster-autoscaler.addons.k8s.io
  90. k8s-app: cluster-autoscaler
  91. roleRef:
  92. apiGroup: rbac.authorization.k8s.io
  93. kind: ClusterRole
  94. name: cluster-autoscaler
  95. subjects:
  96. - kind: ServiceAccount
  97. name: cluster-autoscaler
  98. namespace: kube-system
  99. ---
  100. apiVersion: rbac.authorization.k8s.io/v1
  101. kind: RoleBinding
  102. metadata:
  103. name: cluster-autoscaler
  104. namespace: kube-system
  105. labels:
  106. k8s-addon: cluster-autoscaler.addons.k8s.io
  107. k8s-app: cluster-autoscaler
  108. roleRef:
  109. apiGroup: rbac.authorization.k8s.io
  110. kind: Role
  111. name: cluster-autoscaler
  112. subjects:
  113. - kind: ServiceAccount
  114. name: cluster-autoscaler
  115. namespace: kube-system
  116. ---
  117. apiVersion: apps/v1
  118. kind: Deployment
  119. metadata:
  120. name: cluster-autoscaler
  121. namespace: kube-system
  122. labels:
  123. app: cluster-autoscaler
  124. spec:
  125. replicas: 1
  126. selector:
  127. matchLabels:
  128. app: cluster-autoscaler
  129. template:
  130. metadata:
  131. labels:
  132. app: cluster-autoscaler
  133. annotations:
  134. prometheus.io/scrape: "true"
  135. prometheus.io/port: "8085"
  136. spec:
  137. serviceAccountName: cluster-autoscaler
  138. tolerations:
  139. - effect: NoSchedule
  140. operator: "Equal"
  141. value: "true"
  142. key: node-role.kubernetes.io/controlplane
  143. nodeSelector:
  144. node-role.kubernetes.io/controlplane: "true"
  145. containers:
  146. - image: eu.gcr.io/k8s-artifacts-prod/autoscaling/cluster-autoscaler:v1.18.1
  147. name: cluster-autoscaler
  148. resources:
  149. limits:
  150. cpu: 100m
  151. memory: 300Mi
  152. requests:
  153. cpu: 100m
  154. memory: 300Mi
  155. command:
  156. - ./cluster-autoscaler
  157. - --v=4
  158. - --stderrthreshold=info
  159. - --cloud-provider=aws
  160. - --skip-nodes-with-local-storage=false
  161. - --expander=least-waste
  162. - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<clusterName>
  163. volumeMounts:
  164. - name: ssl-certs
  165. mountPath: /etc/ssl/certs/ca-certificates.crt
  166. readOnly: true
  167. imagePullPolicy: "Always"
  168. volumes:
  169. - name: ssl-certs
  170. hostPath:
  171. path: "/etc/ssl/certs/ca-certificates.crt"

准备好 manifest 文件后,将其部署在 Kubernetes 集群中(可以使用 Rancher UI 代替)。

  1. kubectl -n kube-system apply -f cluster-autoscaler-deployment.yaml

说明:集群自动识别器的部署也可以使用手动配置进行设置。

测试

此时,我们应该在 Rancher 自定义集群中建立并运行一个集群缩放器。当以下条件之一为真时,Cluster-scale 应该管理K8sWorkerAsg ASG 在 2 到 10 个节点之间进行伸缩。

  • 有一些 pods 由于资源不足而未能在集群中运行。在这种情况下,集群被放大。
  • 集群中存在长时间未被充分利用的节点,它们 pods 可以放在其他现有节点上。在这种情况下,集群将被缩减。

生成负载

我们准备了一个test-deployment.yaml,只是为了在 Kubernetes 集群上产生负载,看看集群-autoscaler 是否正常工作。测试部署通过三个副本请求 1000m CPU 和 1024Mi 内存。调整请求的资源和/或副本,以确保你用尽 Kubernetes 集群资源。

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: hello-world
  6. name: hello-world
  7. spec:
  8. replicas: 3
  9. selector:
  10. matchLabels:
  11. app: hello-world
  12. strategy:
  13. rollingUpdate:
  14. maxSurge: 1
  15. maxUnavailable: 0
  16. type: RollingUpdate
  17. template:
  18. metadata:
  19. labels:
  20. app: hello-world
  21. spec:
  22. containers:
  23. - image: rancher/hello-world
  24. imagePullPolicy: Always
  25. name: hello-world
  26. ports:
  27. - containerPort: 80
  28. protocol: TCP
  29. resources:
  30. limits:
  31. cpu: 1000m
  32. memory: 1024Mi
  33. requests:
  34. cpu: 1000m
  35. memory: 1024Mi

准备好测试部署后,将其部署在 Kubernetes 集群的默认命名空间中(可以使用 Rancher UI 代替)。

  1. kubectl -n default apply -f test-deployment.yaml

检查自动扩缩容能力

Kubernetes 资源耗尽后,cluster-autoscaler 应该在 pods 未能被调度的地方扩 worker 节点。它应该向上扩展,直到所有的 pods 都可以调度。您应该在 ASG 和 Kubernetes 集群上看到新节点。检查kube-system cluster-autoscaler pod 上的日志。

检查扩容能力后,需要继续检查缩容能力。减少测试部署上的副本数量,直到释放了足够的 Kubernetes 集群资源来缩小规模。您应该可以看到 ASG 上和 Kubernetes 集群上的节点消失。检查kube-system cluster-autoscaler pod 上的日志。