相信你已经见识到了 Kubernetes 的强大能力,它能帮你轻松管理大规模的容器服务,尤其是面对复杂的环境时,比如节点异常、容器异常退出等,Kubernetes 内部的 Service、Deployment 会动态地进行调整,比如增加新的副本、关联新的 Pod 等。

当然 Kubernetes 的这种自动伸缩能力可不止于此。

我们今天就来看看如果利用这些伸缩能力,帮我们在应对大促这样的大流量活动时,控制业务的资源水位,以提供稳定的服务,避免容器的负载过高被打爆,出现流量下跌、业务抖动等情况,从而引发业务故障。

Pod 水平自动伸缩(Horizontal Pod Autoscaler,HPA)

一般来说,我们在遇到这种大流量的场景时,映入我们脑海中的一个想法就是水平扩展,即增加一些实例来分担流量压力。像 Deployment 这种支持多副本的工作负载,我们就可以通过调整spec.replicas来增加或减少副本数,从而改变整体的业务水位满足我们的需求,即整体负载高时就增加一些实例,负载低就适当减少一些实例来节省资源。

当然人为不断地调整spec.replicas的数值显然是不太现实的,HPA 可以根据应用的 CPU 利用率等水位信息,动态地增加或者减少 Pod 副本数量,帮你自动化地完成这一调和过程。

HPA 大多数是用来自动扩缩(Scale)一些无状态的应用负载,比如 Deployment,或者你自己定义的其他类型的无状态工作负载。当然你也可以用来扩缩有状态的应用负载,比如 StatefulSet。

我们来看下面这张图,它描述了 HPA 通过动态地调整Deployment的副本数,从而控制 Pod 的数量。

在使用 HPA 的时候,你需要提前部署好 metrics-server,可以通过 kubectl apply -f一键部署完成(如果你想了解更多关于 metrics-server 的部署,可以参考官方文档)。

$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created

我们来查看下metrics-server对应的 Deployment 的状态,如下图它已经处于 Ready 状态。

kubectl get deploy -n kube-system metrics-server
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server   1/1     1            1           26s

你可以通过kubectl logs来查看对应 Pod 的日志,来确定其是否正常工作。如果有异常,可以参考这里调整部署参数。

现在我们来看看如何来使用 HPA。

首先我们部署一个 Deployment,其 YAML 配置如下(你可以保存为nginx-deploy-hpa.yaml文件):

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: demo
spec:selector:matchLabels:app: nginxusage: hpareplicas: 1template:metadata:labels:app: nginxusage: hpaspec:containers:- name: nginximage: nginx:1.19.2ports:- containerPort: 80resources:requests: # 这里我们把quota设置得小一点,方便做压力测试memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"

下面我们通过 kubectl 来创建这个 Deployment:

$ kubectl create -f nginx-deploy-hpa.yaml
deployment.apps/nginx-deployment created

现在我们来查看一下该 Deployment 的状态,通过下面几条命令可以看到它已经 ready :

$ kubectl get deploy -n demo
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           4s
$ kubectl get pod -n demo
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-6d4b885966-zngnd   1/1     Running   0          8s

可以看到,我们创建的 Deployment 运行成功。
现在我们来创建一个 Service ,来关联这个 Deployment,我们后续就可以通过这个 Service 来访问 Deployment 的各个 Pod 实例了。通过如下命令,我们就可以快速创建一个对应的 Service 出来,当然你也可以通过 YAML 文件来创建。

$ kubectl expose deployment/nginx-deployment -n demo
service/nginx-deployment exposed

我们用kubectl get来查看一下这个 Service 和对应的 Endpoints 对象:

$ kubectl get svc -n demo
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
nginx-deployment   ClusterIP   10.109.93.199   <none>        80/TCP    4s
$ kubectl get endpoints -n demo
NAME               ENDPOINTS                     AGE
nginx-deployment   10.1.0.163:80,10.1.0.164:80   12s

后面我们就可以通过访问这个 Service 的10.109.93.199地址来访问该服务。

现在我们来创建一个 HPA 对象。通过 kubectl autoscale 的命令,我们就可以将 Deployment 的副本数控制在 1~10 之间,CPU 利用率保持在 50% 以下,即当该 Deployment 所关联的 Pod 的平均 CPU 利用率超过 50% 时,就增加副本数,直到小于该阈值。当平均 CPU 利用率低于 50% 时,就减少副本数:

$ kubectl autoscale deploy nginx-deployment -n demo --cpu-percent=50 --min=1 --max=10
horizontalpodautoscaler.autoscaling/nginx-deployment autoscaled

我们来查看一下刚才创建出来的 HPA 对象:

$ kubectl get hpa -n demo
NAME               REFERENCE                     TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   0%/50%          1         10        0          6s

在 kube-controller-manager 中有对应的 HPAController 负责算出合适的副本数,它会根据 metrics-server 上报的对应 Pod metrics 进行计算,具体的算法细节可以通过官方文档来了解。

好了,到现在,一切准备就绪,我们开始见证 HPA 的魔力!

我们现在新开两个终端,分别运行命令kubectl get deploy -n demo -wkubectl get hpa -n demo -w来观察其状态变化。

现在创建一个 Pod 来增加上面 Nginx 服务的访问压力。这里我们用压测工具 ApacheBench 进行压力测试看看:

$ kubectl run demo-benchmark --image httpd:2.4.46-alpine -n demo -it sh
/usr/local/apache2 # ab -n 50000 -c 500 -s 60 http://10.109.93.199/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 10.109.93.199 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requestsServer Software:        nginx/1.19.2
Server Hostname:        10.109.93.199
Server Port:            80
Document Path:          /
Document Length:        612 bytes
Concurrency Level:      500
Time taken for tests:   74.783 seconds
Complete requests:      50000
Failed requests:        2(Connect: 0, Receive: 0, Length: 1, Exceptions: 1)
Total transferred:      42250000 bytes
HTML transferred:       30600000 bytes
Requests per second:    668.60 [#/sec] (mean)
Time per request:       747.830 [ms] (mean)
Time per request:       1.496 [ms] (mean, across all concurrent requests)
Transfer rate:          551.73 [Kbytes/sec] received
Connection Times (ms)min  mean[+/-sd] median   max
Connect:        0   95 347.7     10    3134
Processing:     9   49 295.1     33   60048
Waiting:        5   44 122.8     30    3393
Total:         19  144 477.2     50   60048
Percentage of the requests served within a certain time (ms)50%     5066%     6175%     6580%     6990%     8395%   107198%   114399%   1946100%  60048 (longest request)

在上述 ab 命令运行的同时,我们可以切回之前打开的两个终端窗口看看输出信息:

$ kubectl get hpa -n demo -w
NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   0%/50%    1         10        1          48m
nginx-deployment   Deployment/nginx-deployment   125%/50%   1         10        1         50m
nginx-deployment   Deployment/nginx-deployment   125%/50%   1         10        3         50m
nginx-deployment   Deployment/nginx-deployment   0%/50%     1         10        3         51m
nginx-deployment   Deployment/nginx-deployment   0%/50%     1         10        3         56m
nginx-deployment   Deployment/nginx-deployment   0%/50%     1         10        1         56m
$ kubectl get deploy -n demo -w
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           48m
nginx-deployment   1/3     1            1           50m
nginx-deployment   1/3     1            1           50m
nginx-deployment   1/3     1            1           50m
nginx-deployment   1/3     3            1           50m
nginx-deployment   2/3     3            2           50m
nginx-deployment   3/3     3            3           50m
nginx-deployment   3/1     3            3           56m
nginx-deployment   3/1     3            3           56m
nginx-deployment   1/1     1            1           56m

可以看到,随着访问压力的增加,Pod 的平均利用率也直线上升,一度达到了 125%,超过我们的阈值 50%。这个时候,Deployment 的副本数被调整到了 3,随之 2 个新 Pod 被拉起,负载很快降到了 50% 以下。而后随着压测结束,HPA 又将 Deployment 调整为了 1,维持在低水位。
我们现在回过头来看看 metrics-server 创建的对象 PodMetrics:

$ kubectl get podmetrics -n demo
NAME                                AGE
nginx-deployment-6d4b885966-zngnd   0s
nginx-deployment-6d4b885966-lgwd9   0s
nginx-deployment-6d4b885966-hhk7v   0s
$ kubectl get podmetrics -n demo nginx-deployment-6d4b885966-zngnd -o yaml
apiVersion: metrics.k8s.io/v1beta1
containers:
- name: nginxusage:cpu: "0"memory: 5524Ki
kind: PodMetrics
metadata:creationTimestamp: "2020-10-13T09:38:15Z"name: nginx-deployment-6d4b885966-zngndnamespace: demoselfLink: /apis/metrics.k8s.io/v1beta1/namespaces/demo/pods/nginx-deployment-6d4b885966-zngnd
timestamp: "2020-10-13T09:37:55Z"

HPAController 就是通过这些 PodMetrics 来计算平均的 CPU 使用率,从而确定 spec.replicas 的新数值。
除了 CPU 以外,HPA 还支持其他自定义度量指标,有兴趣可以参考官方文档。

HPA 能够自适应地伸缩 Pod 的数目,但是如果集群中资源不够了怎么办?比如节点紧张无法支撑新的 Pod 运行?

这个时候我们就可以添加新的节点资源到集群中,那么有没有类似 HPA 的做法可以自动化地扩容集群的节点资源?

当然是有的!我们来看看 Cluster Autoscaler。

Cluster Autoscaler

Cluster Autoscaler(下文统称 CA)目前对接了阿里云、AWS、Azure、百度云、华为云、Openstack等云厂商,你可以参照各个厂商的部署要求,进行部署。在部署的时候,请注意 CA 和 Kubernetes 版本要对应,最好两者版本一样。

这里描述了 CA 和 HPA 一起使用的情形。两者一般可以配合起来一起使用。

我们来看看 CA 是如何工作的。CA 主要用来监听(watch)集群中未被调度的 Pod (即 Pod 暂时由于某些调度策略、抑或资源不满足,导致无法被成功调度),然后确定是否可以通过增加节点资源来解决无法调度的问题。

如果可以的话,就会调用对应的 cloud provider 接口,向集群中增加新的节点。当然 CA 在创建新的节点资源前,也会尝试是否可以将正在运行的一部分 Pod “挤压”到某些节点上,从而让这些未被调度的 Pod 可以被调度,如果可行的话,CA 会将这些 Pod 进行驱逐。这些被驱逐的 Pod 会被重新调度(reschedule)到其他的节点上。

目前 CA 仅支持部分云厂商,如果不满足你的需求,你可以考虑基于社区的代码进行二次开发。

最后

除了 HPA 和 CA 以外,还有 Vertical Pod Autoscaler (VPA)可以帮我们确定 Pod 中合适的 CPU 和 Memory 区间,有兴趣可以了解下。限于篇幅,本节不多做介绍。在实际使用的时候,注意千万不要同时使用 HPA 和 VPA,以免造成异常。

使用 HPA 的时候,也尽量对 Deployment 这类对象进行操作,避免对 ReplicaSet 操作。毕竟 ReplicaSet 由 Deployment 管理着,一旦 Deployment 更新了,旧的ReplicaSet 会被新的 ReplicaSet 替换掉。

欢迎大家扫码关注,获取更多信息

#yyds干货盘点# Kubernetes 怎样控制业务的资源水位?(16)相关推荐

  1. #yyds干货盘点# 如何在 Kubernete 中运行 DaemonSet 守护进程?(13)

    通过前面章节的学习,我们对 Kubernetes 中一些常见工作负载已经有所了解.比如无状态工作负载 Dployment 可以帮助我们运行指定数目的服务副本,并维护其状态,而对于有状态服务来说,我们同 ...

  2. #yyds干货盘点# 如何在 Kubernete 中做日志收集与管理(14)

    说到日志,你应该不陌生.日志中不仅记录了代码运行的实时轨迹,往往还包含着一些关键的数据.错误信息,等等.日志方便我们进行分析统计及监控告警,尤其是在后期问题排查的时候,我们通过日志可以很方便地定位问题 ...

  3. #yyds干货盘点#DHCP动态分配IP以及静态分配IP

    前言 使用命令ifconfig查看当前的IP地址,如下所示: 可以看到当前IP地址为192.168.0.102,查看配置文件使用以下命令: vim /etc/sysconfig/network-scr ...

  4. #yyds干货盘点#HC-05与HC-06蓝牙模块对比

    HC-05与HC-06蓝牙串行端口通讯模块 HC-05和HC-06的硬件相同,都采用英国剑桥的CSR (Cambridge Silicon Radio) 公司的BC417143芯片,支持蓝牙2.1+E ...

  5. #yyds干货盘点# Golang 有趣的 logo

    最近迷恋上了 Go 的吉祥物,越看越喜欢,故此想收集一下各大有意思的 logo 图片. Go 的第一个徽标由 Renee 绘制,出现在第一件 Go T恤和 Google Code 网站上, Go 语言 ...

  6. Kubernetes-2018干货盘点

    2019独角兽企业重金招聘Python工程师标准>>> 毫无疑问,Kubernetes在2018年是个丰收年,不仅本身取得了重大的进步,也让使用它的人获益匪浅. 2018年,我跟随着 ...

  7. 灵魂拷问,上 Kubernetes 有什么业务价值?

    本文整理自 2020 年 7 月 22 日<基于 Kubernetes 与 OAM 构建统一.标准化的应用管理平台>主题线上网络研讨会.文章共分为上下两篇,本文为上篇,主要和大家介绍上 K ...

  8. Spring Boot干货系列:(六)静态资源和拦截器处理 | 掘金技术征文

    原本地址:Spring Boot干货系列:(六)静态资源和拦截器处理 博客地址:tengj.top/ 前言 本章我们来介绍下SpringBoot对静态资源的支持以及很重要的一个类WebMvcConfi ...

  9. RBAC、控制权限设计、权限表设计 基于角色权限控制和基于资源权限控制的区别优劣

    RBAC.控制权限设计.权限表设计 基于角色权限控制和基于资源权限控制的区别优劣 一.介绍 二.基于角色的权限设计 三.基于资源的权限设计 四.主体.资源.权限关系图 主体.资源.权限相关的数据模型 ...

最新文章

  1. div+css兼容性
  2. 武大计算机学院推免清北,南大2020年推免生来自哪儿?山大73,武大41,清北5人...
  3. 深度学习-Tensorflow2.2-Tensorboard可视化{5}-可视化基础-17
  4. input最大长度限制问题
  5. span标签显示、隐藏、取值、赋值
  6. oracle如何链接到另外一个数据库DB_LINK
  7. 【精品分享】OpenStack Cinder mutliattach技术探秘
  8. Spring Cloud (6)config 客户端配置 与GitHub通信
  9. 常用10个Excel快捷键,提高工作效率
  10. 边缘风行视频采集软件V1.0
  11. Altium Designer 10 PCB简要设计及其例程
  12. WIN7 ftp网线直连传东西怎么设置
  13. Python实现九宫格解锁
  14. 学习数据分析、数据挖掘、大数据ETL工程师到什么程度可以找工作?
  15. 教你什么时候用Vue计算属性!!!
  16. ty博客后台搭建教程
  17. 几种STM32开发IDE的比较与选择
  18. 北京大学公开课:操作系统与虚拟化安全 学习与研究
  19. 【2017.11.15】设计师的正确工作流程
  20. 我家云/粒子云 影音娱乐服务器-不掉盘-风扇转-LED亮-可关机-smb高速读写

热门文章

  1. 实验二 RGB到YUV格式的转换
  2. 【将金令】1.21早评:欧QE独占鳌头,金银高位不休
  3. 产业经济学-习题汇总
  4. 基于OpenGL的Koch分形雪花实现
  5. Springboot 中文文档 —— Actuator
  6. Poi 导出excel多个sheet的内容
  7. Win10激活提示“连接到internet激活windows”的最佳解决方法
  8. 支持python的交易软件_能用python的期货交易软件,期货量化交易软件哪个好
  9. 西门子博途安装服务器未响应,西门子博途软件安装问题,急
  10. 程序猿的2019年终总结