k8s版本v1.20
2.1 传统弹性伸缩的困境
从传统意义上,弹性伸缩主要解决的问题是容量规划与实际负载的矛盾。
蓝色水位线表示集群资源容量随着负载的增加不断扩容,红色曲线表示集群资源实际负载变化。
弹性伸缩就是要解决当实际负载增大,而集群资源容量没来得及反应的问题。
1 Kubernetes中弹性伸缩存在的问题
常规的做法是给集群资源预留保障集群可用,通常20%左右。这种方式看似没什么问题,但放到Kubernetes中,就会发现如下2个问题。
(1) 机器规格不统一造成机器利用率百分比碎片化
在一个Kubernetes集群中,通常不只包含一种规格的机器,假设集群中存在4C8G与16C32G两种规格的机器,对于10%的资源预留,这两种规格代表的意义是完全不同的。
特别是在缩容的场景下,为了保证缩容后集群稳定性,我们一般会一个节点一个节点从集群中摘除,那么如何判断节点是否可以摘除其利用率百分比就是重要的指标。此时如果大规则机器有较低的利用率被判断缩容,那么很有可能会造成节点缩容后,容器重新调度后的争抢。如果优先缩容小规则机器,则可能造成缩容后资源的大量冗余。
(2) 机器利用率不单纯依靠宿主机计算
在大部分生产环境中,资源利用率都不会保持一个高的水位,但从调度来讲,调度应该保持一个比较高的水位,这样才能保障集群稳定性,又不过多浪费资源。
2 弹性伸缩概念的延伸
不是所有的业务都存在峰值流量,越来越细分的业务形态带来更多成本节省和可用性之间的跳转。
(2) 离线任务型:离线计算、机器学习 (3) 定时任务型:定时批量计算 不同类型的负载对于弹性伸缩的要求有所不同,在线负载对弹出时间敏感,离线任务对价格敏感,定时任务对调度敏感。
2.2 kubernetes 弹性伸缩布局
1 在 Kubernetes 的生态中,在多个维度、多个层次提供了不同的组件来满足不同的伸缩场景
有三种弹性伸缩:
(2) HPA(Horizontal Pod Autoscaler): Pod个数自动扩/缩容。 (3) VPA(Vertical Pod Autoscaler): Pod配置自动扩/缩容,主要是CPU、内存。addon-resizer组件
如果在云上建议 HPA 结合 cluster-autoscaler 的方式进行集群的弹性伸缩管理。
(1) Node级别:K8s将多台服务器抽象一个集群资源池,每个Node提供这些资源
(2) Pod级别:Pod是K8s最小部署单元,运行实际的应用程序,使用request和limit为Pod配额
因此,K8s实现弹性伸缩也是这两个级别,当Node资源充裕情况下,Pod可任意弹性,当不足情况下需要弹性增加节
点来扩容资源池。
(3) 针对Pod负载:当Pod资源不足时,使用HPA(Horizontal Pod Autoscaler)自动增加Pod副本数量
(4) 针对Node负载:当集群资源池不足时,使用CA(Cluster Autoscaler)自动增加Node
(1) Cluster Autoscaler:是一个自动调整Kubernetes集群大小的组件,需要与公有云一起使用,例如AWS、Azure、Aliyun 项目地址:https://github.com/kubernetes/autoscaler (2) 自研发:根据Node监控指标或者Pod调度状态判断是否增加Node,需要一定开发成本
2.3 Node 自动扩容/缩容
1 Cluster AutoScaler
Cluster AutoScaler 定期检测是否有充足的资源来调度新创建的 Pod,当资源不足时会调用 Cloud Provider 创建新的 Node。
Cluster AutoScaler 也会定期监测 Node 的资源使用情况,当一个 Node 长时间资源利用率都很低时(低于 50%)自动将其所在虚拟机从云服务商中删除。此时,原来的 Pod 会自动调度到其他 Node 上面。
https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler/cloudprovider/ GCE:https://kubernetes.io/docs/concepts/cluster-administration/cluster-management/ GKE:https://cloud.google.com/container-engine/docs/cluster-autoscaler/
2 自研发-基于Ansible自动增加Node
(2) 调用Ansible脚本部署组件 (3) 检查服务是否可用 (4) 调用API将新Node加入集群或者启用Node自动加入 (5) 观察新Node状态 (6) 完成Node扩容,接收新Pod
3 自研发-基于Ansible自动增加Node
(1) 自动增加Node
https://github.com/HyjyLc/ansible-install-k8s/
1)在k8s主节点添加新增节点的解析(kubectl操作节点时使用的是主机名)
# echo '172.16.1.85 k8s-node3' >> /etc/hosts
2)扩容node
# kubectl get pod -n kube-system -o wide
(2) 自动减少Node
如果是kubeadm部署的k8s,需要在master节点上重新生成node加入k8s集群的token即可。
2.4 Pod自动扩容/缩容(HPA)
1 HPA介绍
Horizontal Pod Autoscaler(HPA,Pod水平自动伸缩),根据资源利用率或者自定义指标自动调整replication controller, deployment 或 replica set,实现部署的自动扩展和缩减,让部署的规模接近于实际服务的负载。HPA不适用于无法缩放的对象,例如DaemonSet。
2 使用HPA前提条件
1)启用Kubernetes API聚合层 2)相应的API已注册 对于资源指标(例如CPU、内存),将使用metrics.k8s.io API,一般由metrics-server提供。 对于自定义指标(例如QPS),将使用custom.metrics.k8s.io API,由相关适配器(Adapter)服务提供。 已知适配器列表:https://github.com/kubernetes/metrics/blob/master/IMPLEMENTATIONS.md#custom-metrics-api
(2) Kubernetes API Aggregation
在 Kubernetes 1.7 版本引入了聚合层,允许第三方应用程序通过将自己注册到kube-apiserver上,仍然通过 API Server 的 HTTP URL 对新的 API 进行访问和操作。为了实现这个机制,Kubernetes 在 kube-apiserver 服务中引入了一个 API 聚合层(API Aggregation Layer),用于将扩展 API 的访问请求转发到用户服务的功能。
如果你使用kubeadm部署的,默认已开启。如果你使用二进制方式部署的话,需要在kube-APIServer中添加启动参数,增加以下配置:
......
在设置完成重启 kube-apiserver 服务,就启用 API 聚合功能了。
3 HPA冷却周期
可以通过调整 kube-controller-manager 组件启动参数设置冷却时间。 --horizontal-pod-autoscaler-downscale-delay // 扩容冷却 --horizontal-pod-autoscaler-upscale-delay // 缩容冷却
4 HPA的演进历程
目前大多数人比较熟悉是autoscaling/v1,这个版本只支持CPU一个指标的弹性伸缩。 而autoscaling/v2beta1增加了支持自定义指标,autoscaling/v2beta2又额外增加了外部指标支持。 而产生这些变化不得不提的是Kubernetes社区对监控与监控指标的认识与转变。从早期Heapster到Metrics Server再到将指标边界进行划分,一直在丰富监控生态。 (1) autoscaling/v1版本
v1 kind: HorizontalPodAutoscaler metadata: name: web namespace: lc spec: maxReplicas: 10 minReplicas: 2 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web targetCPUUtilizationPercentage: 80