在之前的文章 Depolyment中提到的伸缩 ,是通过 Deployment 管理的 ReplicaSet 来手动控制 pod 的伸缩,而在刚接触 Kubernetes 时,就一直听到或者看到各种视频文章教程,都说K8S可以通过对资源利用率的判断,进行 pod 的自动伸缩。本文中,它来了。

HPA,全称是 Horizontal Pod Autoscaling ,简称HPA自动水平伸缩,它可以根据 cpu/qps/vpa 等指标进行伸缩。

应用场景:如业务的流量高峰和低峰,不管是物理服务器还是 pod,都不能为了高峰一直保持着资源的高利用,着实有点浪费资源

以常用的 cpu 为伸缩指标,HPA 依赖 metrics-server 服务 pod 用来资源指标收集。另外 kubectl top 命令也依赖于 metrics-server,仅支持查看 node 和 pod 的资源利用率

Metrics Server 是一个集群范围的资源使用情况的数据聚合器。作为一个应用部署在集群中。Metrics Server 从每个节点的 kubelet API 收集指标,通过 Kubernetes 聚合器注册在 Master API Server 中。

部署metrics-server

修改apiserver配置参数

$ vi /etc/kubernetes/manifests/kube-apiserver.yaml
...
spec:
  containers:
  - command:
...
  - --enable-aggregator-routing=true

下载 metrics-server 的yaml文件并部署

$ wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.4/components.yaml
# 需要修改该文件的两个值,找到Deployment部分的yaml配置
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=4443
        # 如果旧版中以下三行都没有,手动添加1/3即可,
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname   # 这里改为InternalIP,使用节点ip访问kubelet
        # 默认使用的Hostname,没有解析则访问不到,也不会部署成功
        - --kubelet-use-node-status-port
        - --kubelet-insecure-tls   # 添加该行,跳过tls的验证
        # 国内用户修改镜像为以下
        image: bitnami/metrics-server:0.4.4

$ kubectl apply -f components.yaml

此时可以根据以下确认 metrics-server 部署成功

$ kubectl get pods -A
NAMESPACE         NAME                                       READY   STATUS    RESTARTS   AGE
...
kube-system       metrics-server-6fb5c69669-t6p2f            1/1     Running   0          8m10s
$ kubectl get apiservices
NAME                                   SERVICE                      AVAILABLE   AGE
...
v1beta1.metrics.k8s.io                 kube-system/metrics-server   True        7m47s
...    

查看资源

查看节点资源利用率

$ kubectl top nodes
NAME    CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
feiyi   640m         0%     6147Mi          2%   

查看pod资源利用率

$ kubectl top pods -A
NAMESPACE         NAME                                       CPU(cores)   MEMORY(bytes)   
calico-system     calico-kube-controllers-867fdc777c-rvkfx   3m           36Mi            
calico-system     calico-node-kqs8s                          106m         177Mi           
calico-system     calico-typha-79fbf7798f-flqm6              3m           46Mi                      
kube-system       coredns-558bd4d5db-pxlh9                   5m           27Mi            
kube-system       coredns-558bd4d5db-qlsnw                   6m           29Mi            
kube-system       etcd-feiyi                                 34m          318Mi           
kube-system       kube-apiserver-feiyi                       97m          445Mi           
kube-system       kube-controller-manager-feiyi              27m          73Mi            
kube-system       kube-proxy-z5qns                           18m          33Mi            
kube-system       kube-scheduler-feiyi                       6m           29Mi            
kube-system       metrics-server-6fb5c69669-t6p2f            5m           28Mi            

自动伸缩

正如文章开头所说,自动伸缩需要有事件去触发伸缩。这里的事件也是上面提到的 cpu/qps/vpa 等指标,当这些指标到达一定的峰值,触发自动伸缩,这里以 cpu 为例

先来创建一个 nginx 的 deployment

# 这是我自己练习时写的一个yaml,里面包含了namespace/configmap/deployment/service
# service使用nodeport,端口号为30000,如果冲突,自行修改
wget https://www.feiyiblog.com/files/practise/nginx.yaml
kubectl apply -f nginx.yaml

查看部署好的资源

$ kubectl get pods -n nginx 
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-54b69b44b5-r7vsw   1/1     Running   0          7s
nginx-deployment-54b69b44b5-x9chf   1/1     Running   0          7s
[root@feiyi nginx]# kubectl get all -n nginx 
NAME                                    READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-54b69b44b5-r7vsw   1/1     Running   0          44s
pod/nginx-deployment-54b69b44b5-x9chf   1/1     Running   0          44s

NAME                TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/nginx-svc   NodePort   10.103.255.125   <none>        8080:30000/TCP   44s

NAME                               READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx-deployment   2/2     2            2           44s

NAME                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-deployment-54b69b44b5   2         2         2       44s

访问 nodeip:nodeport 页面如下

test_nginx

对刚才创建的nginx进行自动伸缩的设置

kubectl autoscale deployment -n nginx nginx-deployment --min=2 --max=10 --cpu-percent=10
# --max: 当达到扩展规则,需要进行扩展时,按照该参数给出的值进行伸展pod
# --min: 当低于扩展规则,则会自动进行缩小pod,直到缩小到该参数的值为止
# --cpu-percent: 改参数的值默认为百分比,当pod cpu的使用率达到该值,则进行扩展,生产一半为60-80,这里就以10%为例测试

查看创建好的 hpa

$ kubectl get hpa -n nginx 
NAME               REFERENCE                     TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   <unknown>/10%   2         10        0          7s

可以看到 TARGETS 的值中有 <unknown>,这是因为在创建的 nginx pod 中没有添加资源限制的参数,这是必须的,否则默认 pod 使用宿主机的 cpu 配置,那将是很大的

# 修改nginx.yaml中deployment的containers部分,添加资源限制
      containers:
      - name: nginx
        image: nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "0.5"

重新加载配置

kubectl apply -f nginx.yaml

再次查看hpa:这里需要等个一两分钟来获取指标

$ kubectl get hpa -n nginx 
NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   0%/10%    2         10        2          2m54s

接下来人为手动的给该pod增加cpu使用压力

# 安装压测工具abyum -y install httpd-tools

使用ab工具对svc暴露的 nodeip:nodeport 或者 clusterip:port 端口压测

 ab -n 100000 -c 10000 http://172.16.182.193:30000/index.html
# -n: 请求数
# -c: 并发量
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 172.16.182.193 (be patient)
socket: Too many open files (24)

这里报错了 socket: Too many open files (24),这是因为有文件打开数的限制,默认是1024,使用命令 ulimit -n 查看,将限制提高到最大65536

# 临时
ulimit -SHn 65536
# 永久,需重启
echo "* soft nofile 65536" >>/etc/security/limits.conf
echo "* hard nofile 65536" >>/etc/security/limits.conf

重新压测

# 1-2分钟内可以看到 hpa 中 replicas 的值伸展到了8
$ kubectl get hpa -n nginx 
NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   40%/10%   2         10        8          9m48s
# pod数量也增长到了8
$ kubectl get pods -n nginx 
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-75cb949d68-4gh46   1/1     Running   0          9m10s
nginx-deployment-75cb949d68-8442x   1/1     Running   0          24s
nginx-deployment-75cb949d68-qdh75   1/1     Running   0          24s
nginx-deployment-75cb949d68-qks2d   1/1     Running   0          24s
nginx-deployment-75cb949d68-qvd65   1/1     Running   0          39s
nginx-deployment-75cb949d68-rfnnl   1/1     Running   0          9m12s
nginx-deployment-75cb949d68-vd79j   1/1     Running   0          39s
nginx-deployment-75cb949d68-xcsch   1/1     Running   0          24s

压测结束过一段时间cpu压力减小后,会自动缩容,这个时间有点慢,实验环境用了5-10分钟

$ kubectl get hpa -n nginx 
NAME               REFERENCE                     TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
nginx-deployment   Deployment/nginx-deployment   0%/10%    2         10        2          15m

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0