K8S入门系列:HPA 自动伸缩控制器

10 HPA 自动伸缩控制器

kubectl autoscale 自动控制在k8s集群中运行的 pod 数量(水平自动伸缩),需要提前设置 pod 范围及触发条件。

k8s 从1.1 版本开始增加了名称为 HPA(Horizontal Pod Autoscaler) 的控制器,用于实现基于 pod 中资源(CPU/Memory) 利用率进行对 pod 的自动扩缩容功能的实现,早期的版本只能基于 Heapster 组件实现对CPU利用率做为触发条件,但是在 k8s 1.11版本开始使用 Metrices Server 完成数据采集,然后将采集到的数据通过 API (AggregatedAPI, 汇总API) , 例如 metrics.k8s.io、 custom.metrics.k8s.io、 external.metrics.k8s.io, 然后再把数据提供给HPA控制器进行查询,以实现基于某个资源利用率对pod进行扩缩容的目的。

10.1 Pod 水平自动扩缩

Pod 水平自动扩缩(Horizontal Pod Autoscaler) 可以基于 CPU 利用率自动扩缩 ReplicationController、Deployment、ReplicaSet 和 StatefulSet 中的 Pod 数量。 除了 CPU 利用率,也可以基于其他应程序提供的 自定义度量指标 来执行自动扩缩。 Pod 自动扩缩不适用于无法扩缩的对象,比如 DaemonSet。

Pod 水平自动扩缩特性由 Kubernetes API 资源和控制器实现。资源决定了控制器的行为。 控制器会周期性地调整副本控制器或 Deployment 中的副本数量,以使得类似 Pod 平均 CPU 利用率、平均内存利用率这类观测到的度量值与用户所设定的目标值匹配。

如果现在 pod 数限制为最小 2 个,即使我调成 5 个,过段时间他也会基于 pod 利用率来实现动态伸缩改为 2 个 pod,因为访问量不大,pod 利用率很低,这个时候就会降低我们的 pod 副本。但是如果访问流量上来之后他发现 pod 的 CPU 利用率上来了 HPA 又可能将其改为三个或者 4 个 pod,但是最多只有五个 pod

Pod 水平自动扩缩器的实现是一个控制回路,由控制器管理器的 --horizontal-pod-autoscaler-sync-period 参数指定周期(默认值为 15 秒,可以人为调整但是一般不会修改)查询 metrics 的资源使用情况。

支持一下三种 metrics 指标类型:
 1.预定义 metrics (比如 pod 的 cpu) 利用率的方式计算
 2.自定义 pod metrics ,以原始值(raw value)的方式计算
 3.自定义 object metrics

支持两种 metrics 查询方式:
 1.Heapstre
 2.自定义的 REST API

支持多 metrics ,可以基于 Prometheus 查到的数据来实现对 pod 缩容

10.2 Pod 水平自动扩缩工作机制

对于 pod 数的调整,我们可以通过命令或者修改 yaml 文件进行调整,但是这些操作都是人为手动调整,而无法做到在访问高峰期让我们的 pod 横向扩容

比如在访问高峰期我们希望我们的 pod 数能够实现自动的扩容,而且在访问量比较低的时候能够实现自动的缩容,这个时候就需要使用到 HPA 控制器

HPA 创建方式:

  • 命令行
  • yaml 文件
  • K8S API

HPA 伸缩原理

具体伸缩的方式就是上面的这张图,图中是通过 kubectl autoscale deployment foo --min=2 --max=5 --cpu-percent=80 命令,创建一个 HPA 控制器,类型是一个 foo 的 deployment 并且最大是 5 个 pod,最小 2 个 pod,而且实在 cpu 利用率在百分之 80 的时候触发,如果 pod cpu 利用率超过了百分之 80 就会扩容 pod ,直到 cpu 利用率低于 80 为止

如果该 deployment 中的 pod 运行一段时间后 CPU 利用率降低了,HPA 会自动将该 deployment 中的 pod 自动删掉两个,如果说后来高峰期访问量又上去了原有的 pod CPU 利用率升高到达 80% 他又会自动的进行扩容

所以我们需要对那个范围和那种控制器类型进行 HPA 创建,创建好之后就会生产一个 HPA 控制器,HPA 控制器会基于 API server 每隔多少秒进行一次数据的查询,可以通过 CPU 内存、或自定义的数据指标进行查询。

通过 API 会查到指定的 deployment 中数据,然后再进行条件的对比是否成立,没有成立就不会做动态扩缩容,如果成立的话也就是 CPU 资源大于 80% 了,那么 HPA 就会调用 deployment ,而 deployment 会调用 RS 动态扩缩容 pod

所以说即使是 deployment 也是控制 RS 来维护 pod 的副本数

10.3 准备 metrics-server

但是 metrics-server 现在是没有安装,需要手动安装。如果没有安装 metrics-server 就直接安装 HPA ,那么 HPA 也不会正常工作,因为 HPA 需要查询数据

metrics-server 地址:https://github.com/kubernetes-sigs/metrics-server

Metrics Server Metrics API group/version Supported Kubernetes version
0.6.x metrics.k8s.io/v1beta1 *1.19+
0.5.x metrics.k8s.io/v1beta1 *1.8+
0.4.x metrics.k8s.io/v1beta1 *1.8+
0.3.x metrics.k8s.io/v1beta1 1.8-1.21

由于我们的 K8S 是 1.21 版本,所以这里我安装 metrics-server 的 0.4 版本,而且这里的镜像是使用的国外镜像站,所以我们需要通过魔法上网将其下载 k8s.gcr.io/metrics-server/metrics-server:v0.4.4

1.导入镜像

# 通过国外服务器下载传到本地,并导入至 docker 
[12:48:57 root@k8s-master hpa]#docker load -i metrics-server-v0.4.4.tar.gz 

2.修改 tag

[12:50:26 root@k8s-master hpa]#docker tag k8s.gcr.io/metrics-server/metrics-server:v0.4.4 hub.zhangguiyuan.com/baseimage/metrics-server:v0.4.4

# 上传至本地仓库
[12:50:44 root@k8s-master hpa]#docker push hub.zhangguiyuan.com/baseimage/metrics-server:v0.4.4

3.下载 yaml

[12:52:15 root@k8s-master hpa]#wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.4/components.yaml

4.修改 yaml 镜像为本地镜像

[12:52:47 root@k8s-master hpa]#sed -i "s#k8s.gcr.io/metrics-server/metrics-server:v0.4.4#hub.zhangguiyuan.com/baseimage/metrics-server:v0.4.4#g" components.yaml 

5.修改 metrics-server 启动参数:--kubelet-insecure-tls ,防止 metrics server 访问 kubelet 采集指标时报证书问题(x509: certificate signed by unknown authority), 在 deploy/1.8+/metrics-server-deployment.yaml 中加 args:

[13:24:58 root@k8s-master hpa]#vim components.yaml 
        - --kubelet-insecure-tls        # 添加该参数

6.安装

[12:53:04 root@k8s-master hpa]#kubectl apply -f components.yaml 

7.运行成功

[12:53:43 root@k8s-master hpa]#kubectl get pod -n kube-system | grep metrics
metrics-server-647b56c486-7xqts            1/1     Running   1          39s

8.验证

# 查看 node 
[13:26:46 root@k8s-master hpa]#kubectl top node 
W1024 13:26:49.506301    1417 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%   
k8s-master   159m         7%     2429Mi          51%       
k8s-node     112m         5%     1119Mi          23%       
k8s-node2    82m          4%     1049Mi          22%    


# 查看所有 pod 
[13:27:30 root@k8s-master hpa]#kubectl top pod -A
W1024 13:27:34.279494    2245 top_pod.go:140] Using json format to get metrics. Next release will switch to protocol-buffers, switch early by passing --use-protocol-buffers flag
NAMESPACE     NAME                                          CPU(cores)   MEMORY(bytes)   
jenkins       jenkins-jenkins-deployment-6fb86f9d65-qz9sn   1m           478Mi           
kube-system   calico-kube-controllers-6778c45b7b-srv7b      1m           16Mi            
kube-system   calico-kube-controllers-6778c45b7b-tjqrn      2m           16Mi            
kube-system   calico-node-79bcr                             22m          95Mi            
kube-system   calico-node-bvxzh                             20m          94Mi            
kube-system   calico-node-wg9xc                             24m          96Mi            
kube-system   coredns-6f6b8cc4f6-p4c6q                      2m           10Mi            
kube-system   coredns-6f6b8cc4f6-zmnpb                      3m           11Mi            
kube-system   etcd-k8s-master                               13m          95Mi            
kube-system   kube-apiserver-k8s-master                     39m          315Mi           
kube-system   kube-controller-manager-k8s-master            14m          44Mi            
kube-system   kube-proxy-pbtxc                              8m           21Mi            
kube-system   kube-proxy-vsv4r                              8m           21Mi            
kube-system   kube-proxy-z4ls9                              6m           20Mi            
kube-system   kube-scheduler-k8s-master                     3m           16Mi            
kube-system   metrics-server-67ccccd9b5-69z2k               2m           15Mi            
mysql         mysql-0                                       9m           200Mi           
redis         deploy-devops-redis-5f7d956fc9-dq9mn          1m           4Mi             
web           nginx-dm-57dd86f5cc-bgp99                     0m           7Mi             
web           nginx-dm-57dd86f5cc-fh8tb                     0m           7Mi             
zookeeper     zookeeper1-77548f5584-wfv6j                   1m           53Mi            
zookeeper     zookeeper2-db4d698d7-mf6pv                    1m           48Mi            
zookeeper     zookeeper3-867cc94cc6-fbzbr                   2m           58Mi  

10.4 命令行创建 hpa

1.获取 hpa

[13:29:31 root@k8s-master hpa]#kubectl get hpa -A
No resources found

# 当前没有 hpa

2.编写我们想要被监控的 yaml

[14:09:31 root@k8s-master hpa]#vim nginx-app1.yaml 

apiVersion: v1
kind: Namespace
metadata:
  name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dm
  namespace: web
spec:
  replicas: 2
  selector:
    matchLabels:
      name: nginx
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:                  # 必须填写字段,不然 HPA 不能拿到 pod 的监控数据
          limits:
            cpu: 1
            memory: "512Mi"
          requests:
            cpu: 500m
            memory: "512Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  namespace: web
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    name: nginx

3.获取想要控制的 deployment

[14:06:49 root@k8s-master hpa]#kubectl get deployments.apps -n web
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
nginx-dm   2/2     2            2           64s

4命令创建 hpa

[14:07:06 root@k8s-master hpa]#kubectl autoscale deployment -n web nginx-dm --min=2 --max=5 --cpu-percent=30


# deployment:控制类型 deployment
# -n web nginx-dm :对 web namespace下的 nginx-dm 的 deployment 控制器
# --min=2--max=5:最大 5 个 pod 最小 2 pod
# --cpu-percent=30:cpu 利用率在 30% 时候进行扩缩容

5.由于我们当前的 nginx deployment 是 1 个但是当我们创建完了 hpa 并设置了最小 pod 为 2,我们可以看到 nginx deployment 的 pod 已经更新为了 2

[13:38:32 root@k8s-master hpa]#kubectl get po -n web 
NAME                        READY   STATUS    RESTARTS   AGE
nginx-dm-57dd86f5cc-fh8tb   1/1     Running   1          44h
nginx-dm-57dd86f5cc-zhr5k   1/1     Running   0          4m9s

6.查看 hpa

[14:07:34 root@k8s-master hpa]#kubectl get hpa -n web
NAME       REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-dm   Deployment/nginx-dm   0%/30%    2         5         2          27s

# 创建完之后 unknown 是还没有获取到数据需要等一会
# 0% 就是我们的当前的 pod 利用率比较低

7.删除 HPA

# 这是基于命令行创建,但是在工作中一般不推荐
[14:12:13 root@k8s-master hpa]#kubectl delete hpa -n web nginx-dm 

10.8 通过 yaml 文件创建

每个服务中可能都会配置一个 hpa 文件

1.编写 hpa

[14:15:31 root@k8s-master hpa]#cat hpa.yaml 
#apiVersion: autoscaling/v2beta1
apiVersion: autoscaling/v1 
kind: HorizontalPodAutoscaler
metadata:
  namespace: web
  name: nginx-hpa
  labels:
    app: nginx
    version: v2beta1
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment                    # 指定 hpa 管理类型为 deployment
    name: nginx-dm                      # 指定管理 nginx-dm 的 deployment
  minReplicas: 2                        # 最小 2 个 pod
  maxReplicas: 5                        # 最大 5 个 pod
  targetCPUUtilizationPercentage: 20    # CPU 条件 20%

2.创建

[14:48:52 root@k8s-master hpa]#kubectl apply -f hpa.yaml 

3.创建成功

[14:50:11 root@k8s-master hpa]#kubectl get hpa -n web 
NAME        REFERENCE             TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-hpa   Deployment/nginx-dm   0%/20%    2         5         2          79s
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇