通过 AWS EC2 Auto Scaling 组使用 Cluster Autoscaler

本指南介绍如何使用 AWS EC2 Auto Scaling 组在 Rancher 自定义集群上安装和使用 Kubernetes cluster-autoscaler

我们将安装一个 Rancher RKE 自定义集群,该集群具有固定数量的具有 etcd 和 controlplane 角色的节点,以及数量可变的具有 worker 角色的节点,它们由 cluster-autoscaler 管理。

先决条件

本指南要求:

  • Rancher Server 正常运行。
  • 你的 AWS EC2 用户具有创建虚拟机、Auto Scaling 组以及 IAM 配置文件和角色的适当权限。

1. 创建自定义集群

在 Rancher Server 上,我们需要创建一个自定义的 K8s 集群。请参阅此处以检查版本兼容性。

请确保 cloud_provider 名称设置为 amazonec2。创建集群后,我们需要获得:

  • clusterID:c-xxxxx 将用于 EC2 kubernetes.io/cluster/<clusterID> 实例标签。

  • clusterName:将用于 EC2 k8s.io/cluster-autoscaler/<clusterName> 实例标签。

  • nodeCommand:将添加到 EC2 实例 user_data 上,以包含集群上的新节点。

    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>

2. 配置云提供商

在 AWS EC2 上,我们需要创建一些对象来配置系统。为了在 AWS 上进行配置,我们定义了三个不同的组和 IAM 配置文件。

  1. Autoscaling 组:将加入 EC2 Auto Scaling 组 (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. }
    20. ]
    21. }
  1. Master 组:将成为 Kubernetes etcd 和/或 controlplane 的节点。该组不会在 ASG 中。
  • IAM 配置文件:集成 Kubernetes cloud_provider 需要该文件。或者,你也可以使用 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. }
    73. ]
    74. }
    • IAM 角色:K8sMasterRole: [K8sMasterProfile,K8sAutoscalerProfile]

    • 安全组:K8sMasterSg。详情请参见 RKE 端口(自定义节点选项卡)

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

    • 用户数据:K8sMasterUserData Ubuntu 18.04(ami-0e11cbb34015ff725),安装 Docker 并将 etcd 和 controlplane 节点添加到 K8s 集群。

      1. #!/bin/bash -x
      2. cat <<EOF > /etc/sysctl.d/90-kubelet.conf
      3. vm.overcommit_memory = 1
      4. vm.panic_on_oom = 0
      5. kernel.panic = 10
      6. kernel.panic_on_oops = 1
      7. kernel.keys.root_maxkeys = 1000000
      8. kernel.keys.root_maxbytes = 25000000
      9. EOF
      10. sysctl -p /etc/sysctl.d/90-kubelet.conf
      11. curl -sL https://releases.rancher.com/install-docker/19.03.sh | sh
      12. sudo usermod -aG docker ubuntu
      13. TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
      14. PRIVATE_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/local-ipv4)
      15. PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/public-ipv4)
      16. K8S_ROLES="--etcd --controlplane"
      17. 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}
  1. Worker 组:将加入 K8s worker plane 的节点。Worker 节点将由 cluster-autoscaler 使用 ASG 进行扩缩容。
  • IAM 配置文件:提供 cloud_provider worker 集成。 此配置文件称为 K8sWorkerProfile

    1. {
    2. "Version": "2012-10-17",
    3. "Statement": [
    4. {
    5. "Effect": "Allow",
    6. "Action": [
    7. "ec2:DescribeInstances",
    8. "ec2:DescribeRegions",
    9. "ecr:GetAuthorizationToken",
    10. "ecr:BatchCheckLayerAvailability",
    11. "ecr:GetDownloadUrlForLayer",
    12. "ecr:GetRepositoryPolicy",
    13. "ecr:DescribeRepositories",
    14. "ecr:ListImages",
    15. "ecr:BatchGetImage"
    16. ],
    17. "Resource": "*"
    18. }
    19. ]
    20. }
  • IAM 角色:K8sWorkerRole:[K8sWorkerProfile]

  • 安全组:K8sWorkerSg。详情请参见 RKE 端口(自定义节点选项卡)

  • 标签:

    • kubernetes.io/cluster/<clusterID>: owned
    • k8s.io/cluster-autoscaler/<clusterName>: true
    • k8s.io/cluster-autoscaler/enabled: true
  • 用户数据:K8sWorkerUserData Ubuntu 18.04(ami-0e11cbb34015ff725),安装 Docker 并将 worker 节点添加到 K8s 集群。

    1. #!/bin/bash -x
    2. cat <<EOF > /etc/sysctl.d/90-kubelet.conf
    3. vm.overcommit_memory = 1
    4. vm.panic_on_oom = 0
    5. kernel.panic = 10
    6. kernel.panic_on_oops = 1
    7. kernel.keys.root_maxkeys = 1000000
    8. kernel.keys.root_maxbytes = 25000000
    9. EOF
    10. sysctl -p /etc/sysctl.d/90-kubelet.conf
    11. curl -sL https://releases.rancher.com/install-docker/19.03.sh | sh
    12. sudo usermod -aG docker ubuntu
    13. TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
    14. PRIVATE_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/local-ipv4)
    15. PUBLIC_IP=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" -s http://169.254.169.254/latest/meta-data/public-ipv4)
    16. K8S_ROLES="--worker"
    17. 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

3. 部署节点

我们配置 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
    • 实例:
      • 最少:2
      • 理想情况:2
      • 最大:10

部署 VM 后,你的 Rancher 自定义集群应该可以正常运行了,其中包含三个 master 节点和两个 worker 节点。

4. 安装 Cluster-autoscaler

此时,我们的 Rancher 集群应该已正常运行。我们将根据 cluster-autoscaler 的建议,在 master 节点和 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-enabledtrueCA 是否应该缩减集群
scale-down-delay-after-add“10m”扩容多久后恢复缩容评估
scale-down-delay-after-delete0节点删除多久后恢复缩容评估,默认为 scanInterval 的值
scale-down-delay-after-failure“3m”缩容失败多久后恢复缩容评估
scale-down-unneeded-time“10m”在能进行缩容之前,节点需要不被使用的时间
scale-down-unready-time“20m”在能进行缩容之前,非就绪节点应该需要不被使用的时间
scale-down-utilization-threshold0.5节点上运行的所有 pod 的 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”CA 在删除节点之前,等待删除 delay-deletion.cluster-autoscaler.kubernetes.io/ 注释的最长时间
scan-interval“10s”重新评估集群扩缩容的频率
max-nodes-total0所有节点组中的最大节点数。Cluster Autoscaler 不会让集群增长到超过此数量
cores-total“0:320000”集群中的最小和最大的核心数,格式为 <min>:<max>。Cluster Autoscaler 会在该范围内扩缩集群。
memory-total“0:6400000”集群中最小和最大内存千兆字节数,格式为 <min>:<max>。Cluster Autoscaler 会在该范围内扩缩集群。
cloud-provider-云提供商类型
max-bulk-soft-taint-count10可以同时添加/移除 PreferNoSchedule 污点的最大节点数。设置为 0 则关闭此类污点
max-bulk-soft-taint-time“3s”同时添加/移除 PreferNoSchedule 污点的最大持续时间。
max-empty-bulk-delete10可以同时删除的最大空节点数
max-graceful-termination-sec600尝试缩减节点时,CA 等待 pod 终止的最大秒数
max-total-unready-percentage45集群中未就绪节点的最大百分比。超过此值后,CA 将停止操作
ok-total-unready-count3允许的未就绪节点数,与 max-total-unready-percentage 无关
scale-up-from-zerotrue就绪节点数等于 0 时,CA 是否应该扩容
max-node-provision-time“15m”CA 等待节点配置的最长时间
nodes-以云提供商接受的格式设置节点组的最小、最大大小和其他配置数据。可以多次使用。格式是 <min>:<max>:<other…>
node-group-auto-discovery-节点组自动发现的一个或多个定义。定义表示为 <name of discoverer>:[<key>[=<value>]]
estimator-“binpacking”
expander“random”要在扩容中使用的节点组扩展器的类型。可用值:[“random”,”most-pods”,”least-waste”,”price”,”priority”]
ignore-daemonsets-utilizationfalseCA 为了缩容而计算资源利用率时,是否应忽略 DaemonSet pod
ignore-mirror-pods-utilizationfalseCA 为了缩容而计算资源利用率时,是否应忽略 Mirror pod
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优先级低于 cutoff 的 Pod 将是消耗性 pod。这些 pod 可以在缩容期间不加考虑地被终止,并且不会导致扩容。优先级是 null(禁用 PodPriority)的 pod 不是消耗性的
regionalfalse集群是区域性的
new-pod-scale-up-delay“0s”生命短于这个值的 Pod 将不考虑扩容
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 设置,更新容忍度、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: ["cluster-autoscaler-status", "cluster-autoscaler-priority-expander"]
  81. verbs: ["delete", "get", "update", "watch"]
  82. ---
  83. apiVersion: rbac.authorization.k8s.io/v1
  84. kind: ClusterRoleBinding
  85. metadata:
  86. name: cluster-autoscaler
  87. labels:
  88. k8s-addon: cluster-autoscaler.addons.k8s.io
  89. k8s-app: cluster-autoscaler
  90. roleRef:
  91. apiGroup: rbac.authorization.k8s.io
  92. kind: ClusterRole
  93. name: cluster-autoscaler
  94. subjects:
  95. - kind: ServiceAccount
  96. name: cluster-autoscaler
  97. namespace: kube-system
  98. ---
  99. apiVersion: rbac.authorization.k8s.io/v1
  100. kind: RoleBinding
  101. metadata:
  102. name: cluster-autoscaler
  103. namespace: kube-system
  104. labels:
  105. k8s-addon: cluster-autoscaler.addons.k8s.io
  106. k8s-app: cluster-autoscaler
  107. roleRef:
  108. apiGroup: rbac.authorization.k8s.io
  109. kind: Role
  110. name: cluster-autoscaler
  111. subjects:
  112. - kind: ServiceAccount
  113. name: cluster-autoscaler
  114. namespace: kube-system
  115. ---
  116. apiVersion: apps/v1
  117. kind: Deployment
  118. metadata:
  119. name: cluster-autoscaler
  120. namespace: kube-system
  121. labels:
  122. app: cluster-autoscaler
  123. spec:
  124. replicas: 1
  125. selector:
  126. matchLabels:
  127. app: cluster-autoscaler
  128. template:
  129. metadata:
  130. labels:
  131. app: cluster-autoscaler
  132. annotations:
  133. prometheus.io/scrape: 'true'
  134. prometheus.io/port: '8085'
  135. spec:
  136. serviceAccountName: cluster-autoscaler
  137. tolerations:
  138. - effect: NoSchedule
  139. operator: "Equal"
  140. value: "true"
  141. key: node-role.kubernetes.io/controlplane
  142. nodeSelector:
  143. node-role.kubernetes.io/controlplane: "true"
  144. containers:
  145. - image: eu.gcr.io/k8s-artifacts-prod/autoscaling/cluster-autoscaler:<VERSION>
  146. name: cluster-autoscaler
  147. resources:
  148. limits:
  149. cpu: 100m
  150. memory: 300Mi
  151. requests:
  152. cpu: 100m
  153. memory: 300Mi
  154. command:
  155. - ./cluster-autoscaler
  156. - --v=4
  157. - --stderrthreshold=info
  158. - --cloud-provider=aws
  159. - --skip-nodes-with-local-storage=false
  160. - --expander=least-waste
  161. - --node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/<clusterName>
  162. volumeMounts:
  163. - name: ssl-certs
  164. mountPath: /etc/ssl/certs/ca-certificates.crt
  165. readOnly: true
  166. imagePullPolicy: "Always"
  167. volumes:
  168. - name: ssl-certs
  169. hostPath:
  170. path: "/etc/ssl/certs/ca-certificates.crt"

准备好清单文件后,将该文件部署到 Kubernetes 集群中(也可以使用 Rancher UI 进行操作):

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

通过 AWS EC2 Auto Scaling 组使用 Cluster Autoscaler - 图1备注

你也可以通过手动配置来设置 Cluster-autoscaler deployment。

测试

此时,cluster-autoscaler 应该已经在 Rancher 自定义集群中启动并运行。当满足以下条件之一时,cluster-autoscaler 需要管理 K8sWorkerAsg ASG,以在 2 到 10 个节点之间进行扩缩容:

  • 集群中有 Pod 因资源不足而无法运行。在这种情况下,集群被扩容。
  • 集群中有一些节点长时间未得到充分利用,而且它们的 Pod 可以放到其他现有节点上。在这种情况下,集群被缩容。

生成负载

为了在 Kubernetes 集群上产生负载并查看 cluster-autoscaler 是否正常工作,我们准备了一个 test-deployment.yamltest-deployment 通过三个副本请求 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

准备好 test deployment 后,将其部署在 Kubernetes 集群的默认命名空间中(可以使用 Rancher UI):

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

检查扩缩容

Kubernetes 资源耗尽后,cluster-autoscaler 应该扩容无法调度 pod 的 worker 节点。它应该进行扩容,直到所有 pod 都能被调度。你应该会在 ASG 和 Kubernetes 集群上看到新节点。检查 kube-system cluster-autoscaler pod 上的日志。

检查完扩容后,我们开始检查缩容。为此,请减少 test deployment 的副本数,直到你能释放足够的 Kubernetes 集群资源以进行缩容。你应该能看到 ASG 和 Kubernetes 集群上的节点消失了。检查 kube-system cluster-autoscaler pod 上的日志。