自动横向伸缩pod与集群节点

可以通过调高 ReplicationController、 ReplicaSet、 Deployment等可伸缩资源的 replicas 字段, 来手动实现 pod 中应用的横向扩容。们也可以通过增加 pod 容器的资源请求和限制来纵向扩容pod (尽管目前该操作只能在pod创建时, 而非运行时进行)。虽然如果能预先知道负载何时会飘升, 或者如果负载的变化是较长时间内逐渐发生的, 手动扩容也是可以接受的, 但指望靠人工干预来处理突发而不可预测的流量增长, 仍然不够理想。

pod 的横向自动伸缩 HPA

横向 pod 自动伸缩是指由控制器管理的 pod 副本数量的自动伸缩。 它由Horizontal控制器执行, 我们通过创建一个 HorizontalpodAutoscaler(HPA) 资源来启用和配置Horizontal控制器。 该控制器周期性检查 pod 度量, 计算满足 HPA 资源所配置的目标数值所需的副本数量, 进而调整目标资源(如 Deployment、ReplicaSet、 ReplicationController、 StatefulSet等)的replicas 字段。

了解自动伸缩过程

自动伸缩 的过程可以分为三个步骤:

  • 获取被伸缩资源对象所管理的所有 pod 度量。
  • 计算使度量数值到达(或接近)所指定目标数值所需的 pod 数量。
  • 更新被伸缩资源的 replicas 字段。

获取 pod 度量
Autoscaler本身并不负责采集pod度量数据 , 而是从另外的来源获取。pod 与节点度量数据是由运行在每个节点的 kubelet 之上, 名为 cAdvisor 的 agent 采集的;这些数据将由集群级的组件 Heapster 聚合。 HPA 控制器向 Heapster 发起 REST 调用来获取所有 pod 度量数据。
度量数据从 pod 到 HPA 的流动
这样的数据 流意味着在集群中必须运行Heapster才能实现自动伸缩。

计算所需的 pod 数量
一 旦 Autoscaler 获得了它所调整的资源 (Deployment、 ReplicaSet、ReplicationController或StatetSet) 所辖 pod 的全部度量, 它便可以利用这些度量计算出所需的副本数量。 它需要计算出一个合适的副本数量, 以使所有副本上度量的平均值尽量接近配置的目标值。 该计算的输入是一组 pod 度量(每个 pod 可能有多个),输出则是一个整数 (pod副本数量)。
当 Autoscaler 配置为只考虑单个度量时, 计算所需副本数很简单。 只要将所有 pod 的度量求和后除以 HPA 资源上配置的目标值, 再向上取整即可。 实际的计算稍微复杂一些; Autoscaler 还保证了度量数值不稳定、 迅速抖动时不会导致系统抖动(thrash)。
基于多个 pod 度量的自动伸缩(例如: CPU使用率和每秒查询率[QPS])的计算也并不复杂。 Autoscaler 单独计算每个度量的副本数, 然后取最大值(例如:如果需要4个 pod 达到目标CPU 使用率, 以及需要 3 个 pod 来达到目标 QPS,那么 Autoscaler 将扩展到 4 个 pod)。

从两个度量计算副本数

更新被伸缩资源的副本数
自动伸缩操作的最后 一 步是更新被伸缩资源对象(比如ReplicaSet) 上的副本数字段 , 然后让ReplicaSet 控制器负责启动更多pod或者删除多余的pod。
Autoscaler 控制器通过 Scale 子资源来修改被伸缩资源的 replicas 字段。 这样 Autoscaler 不必了解它所管理资源的细节,而只需要通过 Scale 子资源暴露的界面,就可以完成它的工作了

HPA只对Scale子资源进行更改

这意味着只要API服务器为某个可伸缩资源暴露了Scale子资源, Autoscaler 即可操作该资源。

了解整个自动伸缩过程
 Autoscaler获取度量数据伸缩目标部署的方式
从 pod 指向 cAdvisor, 再经过 Heapster , 而最终到达 HPA 的箭头代表度量数据的流向。 值得注意的是, 每个组件从其他组件拉取数据的动作是周期性的 (即cAdvisor用 一个无限循环从 pod 中采集数据; Heapster 与 HPA 控制器亦是如此)。这意味着度量数据的传播与相应动作的触发都需要相当一段时间, 不是立即发生的。接下来实地观察 Autoscaler 行为时要注意这一点。

基于CPU使用率进行自动伸缩

假设用几个 pod 来提供服务, 如果它们的 CPU 使用率达到了100%, 显然它们已经扛不住压力了, 要么进行纵向扩容(scale up),增加它们可用的CPU时间, 要么进行横向扩容(scale out),增加pod 数量 。
因为 CPU 使用通常是不稳定的, 比较靠谱的做法是在 CPU 被压垮之前就横向扩容 —— 可能平均负载达到或超过80%的时候就进行扩容。 但这里有个问题, 到底是谁的80%呢?

提示 一定把目标 CPU 使用率设置得远远低于100% (一定不要超过90%),以预留充分空间给突发的流量洪峰。

就 Autoscaler 而言, 只有 pod 的保证 CPU 用量(CPU请求)才与确认 pod 的 CPU 使用有关。 Autoscaler 对比 pod 的实际 CPU 使用与它的请求, 这意味着你需要给被伸缩的 pod 设置CPU请求,不管是直接设置还是通过 LimitRange 对象间接设置,这样 Autoscaler 才能确定 CPU 使用率。

基千CPU使用率创建HPA
首先创建一个负载 Deployment ,其中所有 pod 都指定 CPU 资源请求,这样才有可能实现自动伸缩。

vim deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: kubia spec: replicas: 3 selector: matchLabels: app: kubia template: metadata: name: kubia labels: app: kubia spec: containers: - image: luksa/kubia:v1 name: nodejs resources: requests: cpu: 100m

这个 Deployment 对象 —— 现在还没有启用自动伸缩 。 它会运行3个实例的 kubia NodeJS 应用, 每个实例请求 100 毫核的CPU。
为了给它的 pod 启用横向自动伸缩 , 需要创建一个 HorizontalpodAutoscaler (HPA) 对象, 并把它指向该 Deployment 。可以给 HPA 准备 YAML manifest,但有个办法更简单 —— 可以用kubectl autoscale 命令

kubectl autoscale deployment kubia --cpu-percent=20 --min=1 --max=5 horizontalpodautoscaler.autoscaling/kubia autoscaled

创建了 HPA 对象, 并将叫作 kubia 的 Deployment 设置为伸缩目标。 还设置了 pod 的目标 CPU 使用率为 30%, 指定了副本的最小和最大数量。Autoscaler 会持续调整副本的数量以使CPU使用率接近30%, 但它永远不会调整到少于1个或者多于5个。

提示 一定要确保自动伸缩的目标是 Deployinent 而不是底层的 ReplicaSet。 这样才能确保预期的副本数量在应用更新后继续保持(记着 Deployinent 会给每个应用版本创建一个新的 ReplicaSet)。 手动伸缩也是同样的道理。

查看 HorizontalpodAutoscaler 资源的定义

kubectl get horizontalpodautoscaler.autoscaling kubia -o yaml apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: annotations: autoscaling.alpha.kubernetes.io/conditions: ... name: kubia # 每个 HPA 都有一个名称(井不一定非要像这里一样与 Deployment 名称一致) namespace: default resourceVersion: "302021" uid: ae46cc8f-2820-4a22-961f-ed635a750277 spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment # 该 Autoscaler将作用于的目标资源 name: kubia targetCPUUtilizationPercentage: 20 # 你想让 Autoscaler 调整 pod 数量以使每个 pod 都使用所请求 CPU 的30% status: currentReplicas: 3 # Autoscaler 的当前状态 desiredReplicas: 0

查看HPA状态 为 unknown ,需开启聚合层

kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE kubia Deployment/kubia <unknown>/20% 1 5 0 11s

修改kube-apiserver.yaml 开启聚合层

vim /etc/kubernetes/manifests/kube-apiserver.yaml ... spec: containers: - command: ... - --enable-bootstrap-token-auth=true - --enable-aggregator-routing=true #添加 systemctl restart kubelet

通过 Metrics API,可以获得指定节点或 Pod 当前使用的资源量。 此 API 不存储指标值,因此想要获取某个指定节点 10 分钟前的 资源使用量是不可能的。

下载metrics-server部署文件

wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml vim components.yaml ... containers: - name: metrics-server image: registry.cn-hangzhou.aliyuncs.com/ljck8s/metrics-server-amd64:v0.3.6 imagePullPolicy: IfNotPresent args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-insecure-tls #不验证kubelet提供的https证书 - --kubelet-preferred-address-types=InternalIP #使用节点IP连接kubelet kubectl apply -f components.yaml

启动后查看报错,需等待一会 #F44336

kubectl top node W0126 01:57:05.323264 32596 top_node.go:119] Using json format to get metrics. Next release will switch to protocol-buffers, switch early by passing --use-protocol-buffers flag error: metrics not available yet kubectl top node W0126 01:57:29.562132 32827 top_node.go:119] Using json format to get metrics. Next release will switch to protocol-buffers, switch early by passing --use-protocol-buffers flag NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% master 214m 5% 1226Mi 71% node1 30m 1% 449Mi 26% node2 <unknown> <unknown> <unknown> <unknown> kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE kubia Deployment/kubia <unknown>/20% 1 5 0 11s kubectl get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE kubia Deployment/kubia 0%/20% 1 5 1 2m42s

触发自动扩容
要往 pod 发送请求,增加它的 CPU 使用率,随后应该看到 Autoscaler 检测到这 一切并启动更多的 pod 。需要通过一个 Service 来暴露 pod, 以便用单一 的 URL 访问到所有 pod 。

kubectl expose deployment kubia --port=80 --target-port=8080 service/kubia exposed

在向 pod 发送请求之前,在另一个终端里运行以下命令,来观察 HPA 与 Deployment 上发生了什么

watch -n 1 kubectl get hpa,deployment NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE horizontalpodautoscaler.autoscaling/kubia Deployment/kubia <unknown>/30% 1 5 1 4h32m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/kubia 1/1 1 1 4h37m

运行产生负载的 pod

kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 48d kubia ClusterIP 10.105.143.135 <none> 80/TCP 67m kubectl run -it --rm --restart=Never loadgenerator --image=busybox -- sh -c "while true; do wget -O - -q http://10.105.143.135; done" If you don't see a command prompt, try pressing enter. This is v1 running in pod kubia-5957b4c689-hjnqw This is v1 running in pod kubia-5957b4c689-hjnqw This is v1 running in pod kubia-5957b4c689-hjnqw

观察 Autoscaler 扩容 Deployment

kubectl describe hpa kubia Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulRescale 7m23s horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 7m8s horizontal-pod-autoscaler New size: 5; reason: cpu resource utilization (percentage of request) above target kubectl get pod NAME READY STATUS RESTARTS AGE kubia-5957b4c689-5lrwh 1/1 Running 0 41s kubia-5957b4c689-75q8r 0/1 ContainerCreating 0 41s kubia-5957b4c689-hjnqw 1/1 Running 0 81m kubia-5957b4c689-nd54t 1/1 Running 0 41s kubia-5957b4c689-qwrsv 1/1 Running 0 26s

pod 的纵向自动伸缩 VPA

Vertical Pod Autoscaler(VPA)使用户无需为其pods中的容器设置最新的资源request。配置后,它将根据使用情况自动设置request,从而允许在节点上进行适当的调度,以便为每个pod提供适当的资源量。
使用名为VerticalPodAutoscaler的自定义资源定义对象配置自动缩放 。它允许指定垂直自动缩放的pod以及是否/如何应用资源建议。

必须在群集中部署Metrics Server

git clone https://github.com/kubernetes/autoscaler.git
下载的资源使用镜像为 v0.9.0 , 国内下载不到

wget https://github.com/kubernetes/autoscaler/archive/refs/tags/vertical-pod-autoscaler-0.8.0.tar.gz tar xvf autoscaler-vertical-pod-autoscaler-0.8.0.tar.gz cd autoscaler/vertical-pod-autoscaler/deploy admission-controller-deployment.yaml us.gcr.io/k8s-artifacts-prod/autoscaling/vpa-admission-controller:0.8.0 改为 scofield/vpa-admission-controller:0.8.0 recommender-deployment.yaml us.gcr.io/k8s-artifacts-prod/autoscaling/vpa-recommender:0.8.0 改为 image: scofield/vpa-recommender:0.8.0 updater-deployment.yaml us.gcr.io/k8s-artifacts-prod/autoscaling/vpa-updater:0.8.0 改为 scofield/vpa-updater:0.8.0 ./hack/vpa-up.sh ERROR: Failed to create CA certificate for self-signing. If the error is "unknown option -addext", update your openssl version or deploy VPA from the vpa-release-0.8 branch 需要升级openssl的版本解决 yum install gcc gcc-c++ -y openssl version -a wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz && tar zxf openssl-1.1.1k.tar.gz && cd openssl-1.1.1k ./config make && make install mv /usr/local/bin/openssl /usr/local/bin/openssl.bak mv apps/openssl /usr/local/bin openssl version -a 升级openssl后执行 vertical-pod-autoscaler/pkg/admission-controller/gencerts.sh ./hack/vpa-down.sh ./hack/vpa-up.sh kubectl get po -n kube-system | grep -E "metrics-server|vpa" metrics-server-7899654b87-xpvzp 1/1 Running 0 14h vpa-admission-controller-7958497486-m6zxx 1/1 Running 0 35m vpa-recommender-76478b64cf-57bvb 1/1 Running 0 35m vpa-updater-6b987c7559-d7tv7 1/1 Running 0 35m

VPA使用限制
不能与HPA(Horizontal Pod Autoscaler )一起使用
Pod比如使用副本控制器,例如属于Deployment或者StatefulSet

VPA的好处
Pod 资源用其所需,所以集群节点使用效率高。
Pod 会被安排到具有适当可用资源的节点上。
不必运行基准测试任务来确定 CPU 和内存请求的合适值。
VPA 可以随时调整 CPU 和内存请求,无需人为操作,因此可以减少维护时间。

VPA 参照 https://juejin.cn/post/6982867694378811400

Cluster Autoscaler介绍 CA

Cluster Autoscaler负责在由千节点资源不足, 而无法调度某pod到已有节点时,自动部署新节点。它也会在 节点长时间使用率低下的情况下下线节点。

从云端基础架构请求新节点
如果在一个 pod 被创建之后,Scheduler 无法将其调度到任何一个已有节点,一个新节点就会被创建。ClusterAutoscaler 会注意此类 pod,并请求云服务提供者启动一个新节点。但在这么做之前,它会检查新节点有没有可能容纳这个 pod, 毕竟如果新节点本来就不可能容纳它们,就没必要启动这么一个节点了。
云服务提供者通常把相同规格(或者有相同特性)的节点聚合成组。因此 Cluster Autoscaler 不能单纯地说 “给我多一个节点”,它还需要指明节点类型。
Cluster Autoscaler 通过检查可用的节点分组来确定是否有至少一种节点类型能容纳未被调度的pod。如果只存在唯一一个此种节点分组,ClusterAutoscaler 就可以增加节点分组的大小,让云服务提供商给分组中增加一个节点。但如果存在多个满足条件的节点分组, ClusterAutoscaler 就必须挑一个最合适的。这里 “ 最合适” 的精确含义显然必须是可配置的。在 最坏的情况下,它会随机挑选一个。如图简单描述了 ClusterAutoscaler 面对一个不可调度pod时是如何反应的。

 Cluster Autoscaler 发现不可调度到已有节点的 pod 时会触发集群扩容

新节点启动后,其上运行的 Kubelet 会联系 API 服务器,创建一个 Node 资源以注册该节点。从这一刻起,该节点即成为 Kubernetes 集群的一部分,可以调度 pod 于其上了。

归还节点
当节点利用率不足时, Cluster Autoscaler 也需要能够减少节点的数目。 Cluster Autoscaler 通过监控所有节点上请求的 CPU 与内存来实现这一点。 如果某个节点上所有 pod 请求的 CPU、 内存都不到 50%,该节点即被认定 为不再需要。
这并不是决定是否要归还某一节点的唯一因素。 Cluster Autoscaler 也会检查是否有系统 pod (仅仅)运行在该节点上(这并不包括每个节点上都运行的服务, 比如 DaemonSet 所部署的服务)。 如果节点上有系统 pod 在运行,该节点就不会被归还。对非托管 pod, 以及有本地存储的 pod 也是如此, 否则就会造成这些 pod 提供的服务中断。
换句话说, 只有当 Cluster Autoscaler 知道节点上运行的 pod 能够重新调度到其他节点, 该节点才会被归还。
当一个节点被选中下线, 它首先会被标记为不可调度, 随后运行其上的 pod 将被疏散至其他节点。 因为所有这些 pod 都属于 ReplicaSet 或者其他控制器, 它们的替代 pod 会被创建并调度到其他剩下的节点(这就是为何正被下线的节点要先标记为不可调度的原因)。

手动标记节点为不可调度、 排空节点
kubectl cordon <node> 标记节点为不可调度(但对其上的 pod不做任何事)。
kubectl drain <node> 标记节点为不可调度, 随后疏散其上所有 pod 。
两种情形下, 在用 kubectl uncordon <node> 解除节点的不可调度状态之前, 不会有新 pod 被调度到该节点。

启用Cluster Autoscaler

集群自动伸缩在以下云服务提供商可用:

  • Google Kubernetes En伊ne (GKE)
  • Google Compute Engine (GCE)
  • Amazon Web Services (A W S)
  • Microsoft Azure

https://dasydong.github.io/blog/2019/12/21/k8s-ca-code综合篇/

https://feisky.gitbooks.io/kubernetes/content/addons/cluster-autoscaler.html


__EOF__

本文作者何时&明月
本文链接https://www.cnblogs.com/kiyalone/p/15957179.html
关于博主:当你发现自己的才华支撑不起野心时,就请安静下来学习吧!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   何时&明月  阅读(207)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示