# Horizontal Pod Autoscaler

我们已经可以通过手动执行 kubectl scale命令实现 Pod 的扩缩容,但是这显然不符合 k8s 的定位目标:自动化和智能化。k8s 期望可以通过监测 Pod 的使用情况,实现 Pod 数量的自动调整,于是就产生了 HPA 这种控制器。

HPA 可以获取每个 Pod 的利用率,然后和 HPA 中定义的指标进行对比,同时计算出需要伸缩的具体值,最后实现 Pod 的数量的调整。其实 HPA 和之前的 Deployment 一样,也属于一种 k8s 资源对象,它通过追踪分析目标 Pod 的负载变化情况,来确定是否需要针对性的调整目标 Pod 的副本数。

HPA概述.png

# 一、安装 metrics-server(v0.3.6)

  • 下载 metrics-server

    wget https://github.com/kubernetes-sigs/metrics-server/archive/v0.3.6.tar.gz
    
  • 解压

    tar -zxvf v0.3.6.tar.gz
    
  • 进入 metrics-server-0.3.6/deploy/1.8+ 目录

    cd metrics-server-0.3.6/deploy/1.8+
    
  • 修改 metrics-server-deployment.yaml 文件:

    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: metrics-server
      namespace: kube-system
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: metrics-server
      namespace: kube-system
      labels:
        k8s-app: metrics-server
    spec:
      selector:
        matchLabels:
          k8s-app: metrics-server
      template:
        metadata:
          name: metrics-server
          labels:
            k8s-app: metrics-server
        spec:
          # 添加
          hostNetwork: true
          serviceAccountName: metrics-server
          volumes:
          - name: tmp-dir
            emptyDir: {}
          containers:
          - name: metrics-server
            # 修改
            image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
            imagePullPolicy: Always
            # 添加
            args:
             - --kubelet-insecure-tls 
             - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP
            volumeMounts:
            - name: tmp-dir
              mountPath: /tmp
    
  • 安装 metrics-server

    [root@k8s-master 1.8+]# kubectl apply -f ./
    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 生成的 Pod

    [root@k8s-master 1.8+]# kubectl get pod -n kube-system
    NAME                                 READY   STATUS    RESTARTS   AGE
    coredns-66bff467f8-7n949             1/1     Running   3          24h
    coredns-66bff467f8-knb4n             1/1     Running   1          23h
    etcd-k8s-master                      1/1     Running   4          5d23h
    kube-apiserver-k8s-master            1/1     Running   1          23h
    kube-controller-manager-k8s-master   1/1     Running   7          5d23h
    kube-flannel-ds-l5jfm                1/1     Running   4          5d23h
    kube-flannel-ds-rjxpl                1/1     Running   0          23h
    kube-flannel-ds-vpbd9                1/1     Running   0          23h
    kube-proxy-9z64b                     1/1     Running   0          23h
    kube-proxy-j9pkd                     1/1     Running   4          5d23h
    kube-proxy-znbcm                     1/1     Running   2          5d23h
    kube-scheduler-k8s-master            1/1     Running   2          23h
    metrics-server-5f55b696bd-9hg5w      1/1     Running   0          2m3s   #这个就是
    
  • 查看资源使用情况

    [root@k8s-master 1.8+]# kubectl top pod -n kube-system
    NAME                                 CPU(cores)   MEMORY(bytes)   
    coredns-66bff467f8-7n949             3m           11Mi            
    coredns-66bff467f8-knb4n             3m           8Mi             
    etcd-k8s-master                      19m          58Mi            
    kube-apiserver-k8s-master            45m          375Mi           
    kube-controller-manager-k8s-master   17m          68Mi            
    kube-flannel-ds-l5jfm                3m           18Mi            
    kube-flannel-ds-rjxpl                3m           15Mi            
    kube-flannel-ds-vpbd9                3m           16Mi            
    kube-proxy-9z64b                     1m           19Mi            
    kube-proxy-j9pkd                     1m           16Mi            
    kube-proxy-znbcm                     1m           19Mi            
    kube-scheduler-k8s-master            4m           26Mi            
    metrics-server-5f55b696bd-9hg5w      1m           10Mi
    

# 二、准备 Deployment

  • 编写 nginx.yaml 文件

    apiVersion: apps/v1 
    kind: Deployment 
    metadata: 
      name: nginx
    spec: 
      selector: 
        matchLabels: 
          app: nginx-pod
      template: 
        metadata:
          labels:
            app: nginx-pod
        spec:
          containers:
            - name: nginx 
              image: nginx:1.17.1 
              ports:
                - containerPort: 80 
              resources: # 资源限制
                requests:
                  cpu: "100m" # 100m表示100millicpu,即0.1个CPU
    
  • 创建 Deployment

    [root@k8s-master 1.8+]# kubectl apply -f nginx-hpa.yaml 
    deployment.apps/nginx-hpa created
    

# 三、准备 Service

kubectl expose deployment nginx --name=nginx --type=NodePort --port=80 --target-port=80

# 四、部署 HPA

  • 创建 ps-hpa.yaml 文件

    apiVersion: autoscaling/v1
    kind: HorizontalPodAutoscaler
    metadata:
      name: pc-hpa
    spec:
      minReplicas: 1 #最小Pod数量
      maxReplicas: 10 #最大Pod数量
      targetCPUUtilizationPercentage: 3 #CPU使用率指标
      scaleTargetRef: #指定要控制的Nginx信息
        apiVersion: apps/v1
        kind: Deployment
        name: nginx #要和前面的Deployment名称对应上
    
  • 创建 hpa

    [root@k8s-master 1.8+]# kubectl create -f pc-hpa.yaml 
    horizontalpodautoscaler.autoscaling/pc-hpa created
    
  • 查看 hpa

    [root@k8s-master 1.8+]# kubectl get hpa
    NAME     REFERENCE              TARGETS        MINPODS   MAXPODS   REPLICAS   AGE
    pc-hpa   Deployment/nginx   <unknown>/3%   1         10        1          39s
    

# 五、测试

  • 查看 Service

    [root@k8s-master 1.8+]# kubectl get service nginx
    NAME        TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
    nginx      NodePort   10.96.88.161   <none>        80:31395/TCP   42s
    
  • 使用压测工具 Jmeter 对 service 的地址 http://172.16.58.200:31395 进行压测,然后通过控制台查看 hpa 和 pod 的变化

  • HPA 的变化

    img

  • Pod 的变化

    image-20210708112410664

上次更新: 7/8/2021, 11:28:32 AM