当前位置 博文首页 > Linux-1874:容器编排系统K8s之HPA资源

    Linux-1874:容器编排系统K8s之HPA资源

    作者:Linux-1874 时间:2021-01-30 18:06

    HPA的全称是Horizontal Pod Autoscaler,从字面意思理解它就是水平pod自动伸缩器;简单讲HPA的主要作用是根据指定的指标数据,监控对应的pod控制器,一旦对应pod控制器下的pod的对应指标数据达到我们定义的阀值,即HPA就会被触发,它会根据对应指标数据的值来扩展/缩减对应pod副本数量;扩展和缩减都是有上下限的,当pod数量达到上限,即便指标数据还是超过了我们定义的阀值它也不会再扩展,对于下线默认不指定就是为1;下限和上限都是一样的逻辑,即便一个访问都没有,它会保持最低有多少个pod运行;需注意hpa只能用于监控可扩缩的pod控制器,对DaemonSet类型控制器不支持;

      前文我们了解了用Prometheus监控k8s上的节点和pod资源,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14287942.html;今天我们来了解下k8s上的HPA资源的使用;

      HPA的全称是Horizontal Pod Autoscaler,从字面意思理解它就是水平pod自动伸缩器;简单讲HPA的主要作用是根据指定的指标数据,监控对应的pod控制器,一旦对应pod控制器下的pod的对应指标数据达到我们定义的阀值,即HPA就会被触发,它会根据对应指标数据的值来扩展/缩减对应pod副本数量;扩展和缩减都是有上下限的,当pod数量达到上限,即便指标数据还是超过了我们定义的阀值它也不会再扩展,对于下线默认不指定就是为1;下限和上限都是一样的逻辑,即便一个访问都没有,它会保持最低有多少个pod运行;需注意hpa只能用于监控可扩缩的pod控制器,对DaemonSet类型控制器不支持;

      在k8s上HPA有两个版本v1和v2;v1只支持根据cpu这个指标数据来自动扩展/缩减pod数量;V2支持根据自定义指标数量来自动扩展/缩减pod数量;HPA是k8s上的标准资源,我们可以通过命令或资源清单的方式去创建它;

      使用命令创建HPA资源的使用语法格式

    Usage:
      kubectl autoscale (-f FILENAME | TYPE NAME | TYPE/NAME) [--min=MINPODS] --max=MAXPODS [--cpu-percent=CPU] [options]
    

      提示:默认不指定hpa的名称,它会同对应的pod控制名称相同;--min选项用于指定对应pod副本最低数量,默认不指定其值为1,--max用于指定pod最大副本数量;--cpu-percent选项用于指定对应pod的cpu资源的占用比例,该占用比例是同对应pod的资源限制做比较;

      示例:使用命令创建v1版本的hpa资源

      使用deploy控制器创建pod资源

    [root@master01 ~]# cat myapp.yaml
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp
      namespace: default
      labels:
        app: myapp
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: myapp
      template:
        metadata:
          name: myapp-pod
          labels:
            app: myapp
        spec:
          containers:
          - name: myapp
            image: ikubernetes/myapp:v1
            resources:
              requests:
                cpu: 50m
                memory: 64Mi
              limits:
                cpu: 50m
                memory: 64Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-svc
      labels:
        app: myapp
      namespace: default
    spec:
      selector:
        app: myapp
      ports:
      - name: http
        port: 80
        targetPort: 80
      type: NodePort
    [root@master01 ~]# 
    

      应用资源清单

    [root@master01 ~]# kubectl apply -f myapp.yaml
    deployment.apps/myapp created
    service/myapp-svc created
    [root@master01 ~]# kubectl get pods 
    NAME                     READY   STATUS    RESTARTS   AGE
    myapp-779867bcfc-657qr   1/1     Running   0          6s
    myapp-779867bcfc-txvj8   1/1     Running   0          6s
    [root@master01 ~]# kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        8d
    myapp-svc    NodePort    10.111.14.219   <none>        80:31154/TCP   13s
    [root@master01 ~]#
    

      查看pod的资源占比情况

    [root@master01 ~]# kubectl top pods
    NAME                     CPU(cores)   MEMORY(bytes)   
    myapp-779867bcfc-657qr   0m           3Mi             
    myapp-779867bcfc-txvj8   0m           3Mi             
    [root@master01 ~]# 
    

      提示:现在没有访问对应pod,其cpu指标为0;

      使用命令创建hpa资源,监控myapp deploy,指定对应pod的cpu资源使用率达到50%就触发hpa

    [root@master01 ~]# kubectl autoscale deploy myapp --min=2 --max=10 --cpu-percent=50
    horizontalpodautoscaler.autoscaling/myapp autoscaled
    [root@master01 ~]# kubectl get hpa 
    NAME    REFERENCE          TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
    myapp   Deployment/myapp   <unknown>/50%   2         10        0          10s
    [root@master01 ~]# kubectl describe hpa/myapp
    Name:                                                  myapp
    Namespace:                                             default
    Labels:                                                <none>
    Annotations:                                           <none>
    CreationTimestamp:                                     Mon, 18 Jan 2021 15:26:49 +0800
    Reference:                                             Deployment/myapp
    Metrics:                                               ( current / target )
      resource cpu on pods  (as a percentage of request):  0% (0) / 50%
    Min replicas:                                          2
    Max replicas:                                          10
    Deployment pods:                                       2 current / 2 desired
    Conditions:
      Type            Status  Reason               Message
      ----            ------  ------               -------
      AbleToScale     True    ScaleDownStabilized  recent recommendations were higher than current one, applying the highest recent recommendation
      ScalingActive   True    ValidMetricFound     the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request)
      ScalingLimited  False   DesiredWithinRange   the desired count is within the acceptable range
    Events:           <none>
    [root@master01 ~]# 
    

      验证:使用ab压测工具,对pod进行压力访问,看看对应pod cpu资源使用率大于50%,对应pod是否会扩展?

      安装ab工具

     yum install httpd-tools -y
    

      使用外部主机对pod svc 进行压力访问

      查看pod的资源占比情况

    [root@master01 ~]# kubectl top pods 
    NAME                     CPU(cores)   MEMORY(bytes)   
    myapp-779867bcfc-657qr   51m          4Mi             
    myapp-779867bcfc-txvj8   34m          4Mi             
    [root@master01 ~]# 
    

      提示:可以看到对应pod的cpu资源都大于限制的资源上限的50%;这里需要注意hpa扩展pod它有一定的延迟,不是立刻马上就扩展;

      查看对应hpa资源的详情

      提示:hpa详情告诉我们对应pod扩展到7个;

      查看pod数量是否被扩展到7个?

    [root@master01 ~]# kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    myapp-779867bcfc-657qr   1/1     Running   0          16m
    myapp-779867bcfc-7c4dt   1/1     Running   0          3m27s
    myapp-779867bcfc-b2jmn   1/1     Running   0          3m27s
    myapp-779867bcfc-fmw7v   1/1     Running   0          2m25s
    myapp-779867bcfc-hxhj2   1/1     Running   0          2m25s
    myapp-779867bcfc-txvj8   1/1     Running   0          16m
    myapp-779867bcfc-xvh58   1/1     Running   0          2m25s
    [root@master01 ~]# 
    

      提示:可以看到对应pod被控制到7个;

      查看对应pod的资源占比是否还高于限制的50%?

    [root@master01 ~]# kubectl top pods 
    NAME                     CPU(cores)   MEMORY(bytes)   
    myapp-779867bcfc-657qr   49m          4Mi             
    myapp-779867bcfc-7c4dt   25m          4Mi             
    myapp-779867bcfc-b2jmn   36m          4Mi             
    myapp-779867bcfc-fmw7v   42m          4Mi             
    myapp-779867bcfc-hxhj2   46m          3Mi             
    myapp-779867bcfc-txvj8   21m          4Mi             
    myapp-779867bcfc-xvh58   49m          4Mi             
    [root@master01 ~]# 
    

      提示:可以看到对应pod的cpu使用率还是高于限制的50%,说明扩展到pod数量不能够响应对应的请求,此时hpa还会扩展;

      查看hpa详情,看看是否又一次扩展pod的数量?

      提示:可以看到对应pod被扩展到10个,但是对应cpu资源使用率为94%,此时pod数量已经到达上限,即便对应指标数据还是大于指定的阀值,它也不会扩展;

      查看pod数量是否为10个?

    [root@master01 ~]# kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    myapp-779867bcfc-57zw7   1/1     Running   0          5m39s
    myapp-779867bcfc-657qr   1/1     Running   0          23m
    myapp-779867bcfc-7c4dt   1/1     Running   0          10m
    myapp-779867bcfc-b2jmn   1/1     Running   0          10m
    myapp-779867bcfc-dvq6k   1/1     Running   0          5m39s
    myapp-779867bcfc-fmw7v   1/1     Running   0          9m45s
    myapp-779867bcfc-hxhj2   1/1     Running   0          9m45s
    myapp-779867bcfc-n8lmf   1/1     Running   0          5m39s
    myapp-779867bcfc-txvj8   1/1     Running   0          23m
    myapp-779867bcfc-xvh58   1/1     Running   0          9m45s
    [root@master01 ~]# 
    

      停止压测,看看对应pod是否会缩减到最低pod数量为2个呢?

    [root@master01 ~]# kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    myapp-779867bcfc-57zw7   1/1     Running   0          8m8s
    myapp-779867bcfc-657qr   1/1     Running   0          26m
    myapp-779867bcfc-7c4dt   1/1     Running   0          13m
    myapp-779867bcfc-b2jmn   1/1     Running   0          13m
    myapp-779867bcfc-dvq6k   1/1     Running   0          8m8s
    myapp-779867bcfc-fmw7v   1/1     Running   0          12m
    myapp-779867bcfc-hxhj2   1/1     Running   0          12m
    myapp-779867bcfc-n8lmf   1/1     Running   0          8m8s
    myapp-779867bcfc-txvj8   1/1     Running   0          26m
    myapp-779867bcfc-xvh58   1/1     Running   0          12m
    [root@master01 ~]# kubectl top pods
    NAME                     CPU(cores)   MEMORY(bytes)   
    myapp-779867bcfc-57zw7   0m           4Mi             
    myapp-779867bcfc-657qr   0m           4Mi             
    myapp-779867bcfc-7c4dt   7m           4Mi             
    myapp-779867bcfc-b2jmn   0m           4Mi             
    myapp-779867bcfc-dvq6k   0m           4Mi             
    myapp-779867bcfc-fmw7v   0m           4Mi             
    myapp-779867bcfc-hxhj2   3m           3Mi             
    myapp-779867bcfc-n8lmf   10m          4Mi             
    myapp-779867bcfc-txvj8   0m           4Mi             
    myapp-779867bcfc-xvh58   0m           4Mi             
    [root@master01 ~]# 
    

      提示:pod缩减也是不会立刻执行;从上面信息可以看到停止压测对应pod的cpu资源使用率都降下来了;

      再次查看对应pod数量

    [root@master01 ~]# kubectl top pods
    NAME                     CPU(cores)   MEMORY(bytes)   
    myapp-779867bcfc-57zw7   0m           4Mi             
    myapp-779867bcfc-657qr   0m           4Mi             
    [root@master01 ~]# kubectl get pods
    NAME                     READY   STATUS    RESTARTS   AGE
    myapp-779867bcfc-57zw7   1/1     Running   0          13m
    myapp-779867bcfc-657qr   1/1     Running   0          31m
    [root@master01 ~]# 
    

      提示:可以看到对应pod缩减到最低pod副本数量;

      查看hpa的详情

      提示:可以看到对应pod的cpu使用率小于50%,它会隔一段时间就缩减对应pod;

      示例:使用资源清单定义hpa资源

    [root@master01 ~]# cat hpa-demo.yaml
    apiVersion: autoscaling/v1
    kind: HorizontalPodAutoscaler
    metadata:
      name: hpa-demo
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: myapp
      minReplicas: 2
      maxReplicas: 10
      targetCPUUtilizationPercentage: 50
    [root@master01 ~]# 
    

      提示:以上是hpa v1的资源清单定义示例,其中targetCPUUtilizationPercentage用于指定cpu资源使用率阀值,50表示50%,即达到pod上限的50%对应hpa就会被触发;

      应用清单

    [root@master01 ~]# kubectl apply -f hpa-demo.yaml
    horizontalpodautoscaler.autoscaling/hpa-demo created
    [root@master01 ~]# kubectl get hpa
    NAME       REFERENCE          TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
    hpa-demo   Deployment/myapp   <unknown>/50%   2         10        0          8s
    myapp      Deployment/myapp   0%/50%          2         10        2          35m
    [root@master01 ~]# kubectl describe hpa/hpa-demo 
    Name:                                                  hpa-demo
    Namespace:                                             default
    Labels:                                                <none>
    Annotations:                                           <none>
    CreationTimestamp:                                     Mon, 18 Jan 2021 16:02:25 +0800
    Reference:                                             Deployment/myapp
    Metrics:                                               ( current / target )
      resource cpu on pods  (as a percentage of request):  0% (0) / 50%
    Min replicas:                                          2
    Max replicas:                                          10
    Deployment pods:                                       2 current / 2 desired
    Conditions:
      Type            Status  Reason               Message
      ----            ------  ------               -------
      AbleToScale     True    ScaleDownStabilized  recent recommendations were higher than current one, applying the highest recent recommendation
      ScalingActive   True    ValidMetricFound     the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request)
      ScalingLimited  False   DesiredWithinRange   the desired count is within the acceptable range
    Events:           <none>
    [root@master01 ~]# 
    

      提示:可以看到使用命令创建hpa和使用资源清单创建hpa其创建出来的hpa都是一样的;以上是hpa v1的使用示例和相关说明;使用命令创建hpa,只能创建v1的hpa;v2必须使用资源清单,明确指定对应hpa的群组版本;

      使用自定义资源指标定义hpa

      部署自定义资源指标服务器

      下载部署清单

    [root@master01 ~]# mkdir custom-metrics-server
    [root@master01 ~]# cd custom-metrics-server
    [root@master01 custom-metrics-server]# git clone https://github.com/stefanprodan/k8s-prom-hpa
    Cloning into 'k8s-prom-hpa'...
    remote: Enumerating objects: 223, done.
    remote: Total 223 (delta 0), reused 0 (delta 0), pack-reused 223
    Receiving objects: 100% (223/223), 102.23 KiB | 14.00 KiB/s, done.
    Resolving deltas: 100% (117/117), done.
    [root@master01 custom-metrics-server]# ls
    k8s-prom-hpa
    [root@master01 custom-metrics-server]# 
    

      查看custom-metrics-server的部署清单

    [root@master01 custom-metrics-server]# cd k8s-prom-hpa/
    [root@master01 k8s-prom-hpa]# ls
    custom-metrics-api  diagrams  ingress  LICENSE  Makefile  metrics-server  namespaces.yaml  podinfo  prometheus  README.md
    [root@master01 k8s-prom-hpa]# cd custom-metrics-api/
    [root@master01 custom-metrics-api]# ls
    custom-metrics-apiserver-auth-delegator-cluster-role-binding.yaml   custom-metrics-apiservice.yaml
    custom-metrics-apiserver-auth-reader-role-binding.yaml              custom-metrics-cluster-role.yaml
    custom-metrics-apiserver-deployment.yaml                            custom-metrics-config-map.yaml
    custom-metrics-apiserver-resource-reader-cluster-role-binding.yaml  custom-metrics-resource-reader-cluster-role.yaml
    custom-metrics-apiserver-service-account.yaml                       hpa-custom-metrics-cluster-role-binding.yaml
    custom-metrics-apiserver-service.yaml
    [root@master01 custom-metrics-api]# cat custom-metrics-apiserver-deployment.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: custom-metrics-apiserver
      name: custom-metrics-apiserver
      namespace: monitoring
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: custom-metrics-apiserver
      template:
        metadata:
          labels:
            app: custom-metrics-apiserver
          name: custom-metrics-apiserver
        spec:
          serviceAccountName: custom-metrics-apiserver
          containers:
          - name: custom-metrics-apiserver
            image: quay.io/coreos/k8s-prometheus-adapter-amd64:v0.4.1
            args:
            - /adapter
            - --secure-port=6443
            - --tls-cert-file=/var/run/serving-cert/serving.crt
            - --tls-private-key-file=/var/run/serving-cert/serving.key
            - --logtostderr=true
            - --prometheus-url=http://prometheus.monitoring.svc:9090/
            - --metrics-relist-interval=30s
            - --v=10
            - --config=/etc/adapter/config.yaml
            ports:
            - containerPort: 6443
            volumeMounts:
            - mountPath: /var/run/serving-cert
              name: volume-serving-cert
              readOnly: true
            - mountPath: /etc/adapter/
              name: config
              readOnly: true
          volumes:
          - name: volume-serving-cert
            secret:
              secretName: cm-adapter-serving-certs
          - name: config
            configMap:
              name: adapter-config
    [root@master01 custom-metrics-api]# 
    

      提示:上述清单中明确定义了把自定义指标服务器部署到monitoring名称空间下,对应server的启动还挂在了secret证书;所以应用上述清单前,我们要先创建名称空间和secret;在创建secret前还要先准备好证书和私钥;这里还需要注意custom-metrics-server是连接Prometheus server,把对应自定义数据通过apiservice注册到对应原生apiserver上,供k8s组件使用,所以这里要注意对应Prometheus的地址;

      创建monitoring名称空间

    [root@master01 custom-metrics-api]# cd ..
    [root@master01 k8s-prom-hpa]# ls
    custom-metrics-api  diagrams  ingress  LICENSE  Makefile  metrics-server  namespaces.yaml  podinfo  prometheus  README.md
    [root@master01 k8s-prom-hpa]# cat namespaces.yaml 
    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: monitoring
    
    
    [root@master01 k8s-prom-hpa]# kubectl apply -f namespaces.yaml
    namespace/monitoring created
    [root@master01 k8s-prom-hpa]# kubectl get ns
    NAME                   STATUS   AGE
    default                Active   41d
    ingress-nginx          Active   27d
    kube-node-lease        Active   41d
    kube-public            Active   41d
    kube-system            Active   41d
    kubernetes-dashboard   Active   16d
    mongodb                Active   4d20h
    monitoring             Active   4s
    [root@master01 k8s-prom-hpa]# 
    

      生成serving.key和serving.csr

    [root@master01 k8s-prom-hpa]# cd /etc/kubernetes/pki/
    [root@master01 pki]# ls
    apiserver.crt              apiserver.key                 ca.crt  etcd                front-proxy-client.crt  sa.pub   tom.key
    apiserver-etcd-client.crt  apiserver-kubelet-client.crt  ca.key  front-proxy-ca.crt  front-proxy-client.key  tom.crt
    apiserver-etcd-client.key  apiserver-kubelet-client.key  ca.srl  front-proxy-ca.key  sa.key                  tom.csr
    [root@master01 pki]# openssl genrsa -out serving.key 2048
    Generating RSA private key, 2048 bit long modulus
    .............................................................................................................................................................+++
    ..............................+++
    e is 65537 (0x10001)
    [root@master01 pki]# openssl req -new -key ./serving.key -out ./serving.csr -subj "/CN=serving"
    [root@master01 pki]# ll
    total 80
    -rw-r--r-- 1 root root 1277 Dec  8 14:38 apiserver.crt
    -rw-r--r-- 1 root root 1135 Dec  8 14:38 apiserver-etcd-client.crt
    -rw------- 1 root root 1679 Dec  8 14:38 apiserver-etcd-client.key
    -rw------- 1 root root 1679 Dec  8 14:38 apiserver.key
    -rw-r--r-- 1 root root 1143 Dec  8 14:38 apiserver-kubelet-client.crt
    -rw------- 1 root root 1679 Dec  8 14:38 apiserver-kubelet-client.key
    -rw-r--r-- 1 root root 1066 Dec  8 14:38 ca.crt
    -rw------- 1 root root 1675 Dec  8 14:38 ca.key
    -rw-r--r-- 1 root root   17 Jan 17 13:03 ca.srl
    drwxr-xr-x 2 root root  162 Dec  8 14:38 etcd
    -rw-r--r-- 1 root root 1078 Dec  8 14:38 front-proxy-ca.crt
    -rw------- 1 root root 1675 Dec  8 14:38 front-proxy-ca.key
    -rw-r--r-- 1 root root 1103 Dec  8 14:38 front-proxy-client.crt
    -rw------- 1 root root 1679 Dec  8 14:38 front-proxy-client.key
    -rw------- 1 root root 1679 Dec  8 14:38 sa.key
    -rw------- 1 root root  451 Dec  8 14:38 sa.pub
    -rw-r--r-- 1 root root  887 Jan 18 16:54 serving.csr
    -rw-r--r-- 1 root root 1679 Jan 18 16:54 serving.key
    -rw-r--r-- 1 root root  993 Dec 30 00:29 tom.crt
    -rw-r--r-- 1 root root  907 Dec 30 00:27 tom.csr
    -rw-r--r-- 1 root root 1675 Dec 30 00:21 tom.key
    [root@master01 pki]# 
    

      用kubenetes CA的key和证书为custom-metrics-server签署证书

    [root@master01 pki]# openssl x509 -req -in serving.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out serving.crt -days 3650
    Signature ok
    subject=/CN=serving
    Getting CA Private Key
    [root@master01 pki]# ll serving.crt 
    -rw-r--r-- 1 root root 977 Jan 18 16:55 serving.crt
    [root@master01 pki]# 
    

      在monitoring名称空间下创建secret资源

    [root@master01 pki]# kubectl create secret generic cm-adapter-serving-certs --from-file=./serving.key --from-file=./serving.crt -n monitoring
    secret/cm-adapter-serving-certs created
    [root@master01 pki]# kubectl get secret -n monitoring
    NAME                       TYPE                                  DATA   AGE
    cm-adapter-serving-certs   Opaque                                2      10s
    default-token-k64tz        kubernetes.io/service-account-token   3      2m27s
    [root@master01 pki]# kubectl describe secret/cm-adapter-serving-certs -n monitoring
    Name:         cm-adapter-serving-certs
    Namespace:    monitoring
    Labels:       <none>
    Annotations:  <none>
    
    Type:  Opaque
    
    Data
    ====
    serving.crt:  977 bytes
    serving.key:  1679 bytes
    [root@master01 pki]# 
    

      提示:这里一定要使用generic类型创建secret,保持对应的名称为serving.key和serving.crt;创建secret的名称,必须同custom-metrics部署清单中的名称保持一致;

      部署prometheus

    [root@master01 pki]# cd /root/custom-metrics-server/k8s-prom-hpa/prometheus/
    [root@master01 prometheus]# ls
    prometheus-cfg.yaml  prometheus-dep.yaml  prometheus-rbac.yaml  prometheus-svc.yaml
    [root@master01 prometheus]# cat prometheus-dep.yaml 
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: prometheus
      namespace: monitoring
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: prometheus
      template:
        metadata:
          labels:
            app: prometheus
          annotations:
            prometheus.io/scrape: 'false'
        spec:
          serviceAccountName: prometheus
          containers:
          - name: prometheus
            image: prom/prometheus:v2.1.0
            imagePullPolicy: Always
            command:
              - prometheus
              - --config.file=/etc/prometheus/prometheus.yml
              - --storage.tsdb.retention=1h
            ports:
            - containerPort: 9090
              protocol: TCP
            resources:
              limits:
                memory: 2Gi
            volumeMounts:
            - mountPath: /etc/prometheus/prometheus.yml
              name: prometheus-config
              subPath: prometheus.yml
          volumes:
            - name: prometheus-config
              configMap:
                name: prometheus-config
                items:
                  - key: prometheus.yml
                    path: prometheus.yml
                    mode: 0644
    [root@master01 prometheus]# 
    

      更改rbac资源清单中的群组版本为 rbac.authorization.k8s.io/v1

    [root@master01 prometheus]# cat prometheus-rbac.yaml
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: prometheus
    rules:
    - apiGroups: [""]
      resources:
      - nodes
      - nodes/proxy
      - services
      - endpoints
      - pods
      verbs: ["get", "list", "watch"]
    - apiGroups:
      - extensions
      resources:
      - ingresses
      verbs: ["get", "list", "watch"]
    - nonResourceURLs: ["/metrics"]
      verbs: ["get"]
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: prometheus
      namespace: monitoring
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: prometheus
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: prometheus
    subjects:
    - kind: ServiceAccount
      name: prometheus
      namespace: monitoring
    [root@master01 prometheus]# 
    

      应用prometheus目录下的所有资源清单

    [root@master01 prometheus]# kubectl apply -f .
    configmap/prometheus-config created
    deployment.apps/prometheus created
    clusterrole.rbac.authorization.k8s.io/prometheus created
    serviceaccount/prometheus created
    clusterrolebinding.rbac.authorization.k8s.io/prometheus created
    service/prometheus created
    [root@master01 prometheus]# kubectl get pods -n monitoring
    NAME                          READY   STATUS    RESTARTS   AGE
    prometheus-5c5dc6d6d4-drrht   1/1     Running   0          26s
    [root@master01 prometheus]# kubectl get svc -n monitoring
    NAME         TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE
    prometheus   NodePort   10.99.1.110   <none>        9090:31190/TCP   35s
    [root@master01 prometheus]# 
    

      部署自定义指标服务,应用custom-metrics-server目录下的所有资源清单

    [root@master01 prometheus]# cd ../custom-metrics-api/
    [root@master01 custom-metrics-api]# ls
    custom-metrics-apiserver-auth-delegator-cluster-role-binding.yaml   custom-metrics-apiservice.yaml
    custom-metrics-apiserver-auth-reader-role-binding.yaml              custom-metrics-cluster-role.yaml
    custom-metrics-apiserver-deployment.yaml                            custom-metrics-config-map.yaml
    custom-metrics-apiserver-resource-reader-cluster-role-binding.yaml  custom-metrics-resource-reader-cluster-role.yaml
    custom-metrics-apiserver-service-account.yaml                       hpa-custom-metrics-cluster-role-binding.yaml
    custom-metrics-apiserver-service.yaml
    [root@master01 custom-metrics-api]# kubectl apply -f .
    clusterrolebinding.rbac.authorization.k8s.io/custom-metrics:system:auth-delegator created
    rolebinding.rbac.authorization.k8s.io/custom-metrics-auth-reader created
    deployment.apps/custom-metrics-apiserver created
    clusterrolebinding.rbac.authorization.k8s.io/custom-metrics-resource-reader created
    serviceaccount/custom-metrics-apiserver created
    service/custom-metrics-apiserver created
    apiservice.apiregistration.k8s.io/v1beta1.custom.metrics.k8s.io created
    clusterrole.rbac.authorization.k8s.io/custom-metrics-server-resources created
    configmap/adapter-config created
    clusterrole.rbac.authorization.k8s.io/custom-metrics-resource-reader created
    clusterrolebinding.rbac.authorization.k8s.io/hpa-controller-custom-metrics created
    [root@master01 custom-metrics-api]# kubectl get pods -n monitoring
    NAME                                        READY   STATUS    RESTARTS   AGE
    custom-metrics-apiserver-754dfc87c7-cdhqj   1/1     Running   0          18s
    prometheus-5c5dc6d6d4-drrht                 1/1     Running   0          6m9s
    [root@master01 custom-metrics-api]# kubectl get svc -n monitoring
    NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    custom-metrics-apiserver   ClusterIP   10.99.245.190   <none>        443/TCP          31s
    prometheus                 NodePort    10.99.1.110     <none>        9090:31190/TCP   6m21s
    [root@master01 custom-metrics-api]# 
    

      提示:应用上述清单前,请把所有rbac.authorization.k8s.io/v1beta1更改为rbac.authorization.k8s.io/v1,把apiservice中的版本为apiregistration.k8s.io/v1;如果是1.17之前的k8s,不用修改;

      验证:查看原生apiserver是否有custom.metrics.k8s.io的群组注册进来?

    [root@master01 custom-metrics-api]# kubectl api-versions|grep custom
    custom.metrics.k8s.io/v1beta1
    [root@master01 custom-metrics-api]# 
    

      验证:访问对应群组,看看是否能够请求到自定义资源指标?

    [root@master01 custom-metrics-api]# kubectl get --raw "/apis/metrics.k8s.io/v1beta1/" | jq .
    {
      "kind": "APIResourceList",
      "apiVersion": "v1",
      "groupVersion": "metrics.k8s.io/v1beta1",
      "resources": [
        {
          "name": "nodes",
          "singularName": "",
          "namespaced": false,
          "kind": "NodeMetrics",
          "verbs": [
            "get",
            "list"
          ]
        },
        {
          "name": "pods",
          "singularName": "",
          "namespaced": true,
          "kind": "PodMetrics",
          "verbs": [
            "get",
            "list"
          ]
        }
      ]
    }
    [root@master01 custom-metrics-api]# 
    

      提示:如果访问对应群组能够响应数据,表示自定义资源指标服务器没有问题;

      示例:创建podinfo pod,该pod输出http_requests资源指标

    [root@master01 custom-metrics-api]# cd ..
    [root@master01 k8s-prom-hpa]# ls
    custom-metrics-api  diagrams  ingress  LICENSE  Makefile  metrics-server  namespaces.yaml  podinfo  prometheus  README.md
    [root@master01 k8s-prom-hpa]# cd podinfo/
    [root@master01 podinfo]# ls
    podinfo-dep.yaml  podinfo-hpa-custom.yaml  podinfo-hpa.yaml  podinfo-ingress.yaml  podinfo-svc.yaml
    [root@master01 podinfo]# cat podinfo-dep.yaml 
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: podinfo
    spec:
      selector:
        matchLabels:
          app: podinfo
      replicas: 2
      template:
        metadata:
          labels:
            app: podinfo
          annotations:
            prometheus.io/scrape: "true"
        spec:
          containers:
            - name: podinfod
              image: stefanprodan/podinfo:0.0.1
              imagePullPolicy: Always
              command:
                - ./podinfo
                - -port=9898
                - -logtostderr=true
                - -v=2
              volumeMounts:
                - name: metadata
                  mountPath: /etc/podinfod/metadata
                  readOnly: true
              ports:
                - containerPort: 9898
                  protocol: TCP
              readinessProbe:
                httpGet:
                  path: /readyz
                  port: 9898
                initialDelaySeconds: 1
                periodSeconds: 2
                failureThreshold: 1
              livenessProbe:
                httpGet:
                  path: /healthz
                  port: 9898
                initialDelaySeconds: 1
                periodSeconds: 3
                failureThreshold: 2
              resources:
                requests:
                  memory: "32Mi"
                  cpu: "1m"
                limits:
                  memory: "256Mi"
                  cpu: "100m"
          volumes:
            - name: metadata
              downwardAPI:
                items:
                  - path: "labels"
                    fieldRef:
                      fieldPath: metadata.labels
                  - path: "annotations"
                    fieldRef:
                      fieldPath: metadata.annotations
    [root@master01 podinfo]# cat podinfo-svc.yaml 
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: podinfo
      labels:
        app: podinfo
    spec:
      type: NodePort
      ports:
        - port: 9898
          targetPort: 9898
          nodePort: 31198
          protocol: TCP
      selector:
        app: podinfo
    [root@master01 podinfo]# 
    

      应用资源清单

    [root@master01 podinfo]# kubectl apply -f podinfo-dep.yaml,./podinfo-svc.yaml
    deployment.apps/podinfo created
    service/podinfo created
    [root@master01 podinfo]# kubectl get svc
    NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          8d
    myapp-svc    NodePort    10.111.14.219   <none>        80:31154/TCP     4h35m
    podinfo      NodePort    10.111.10.211   <none>        9898:31198/TCP   17s
    [root@master01 podinfo]# kubectl get pods
    NAME                       READY   STATUS    RESTARTS   AGE
    myapp-779867bcfc-57zw7     1/1     Running   0          4h18m
    myapp-779867bcfc-657qr     1/1     Running   0          4h36m
    podinfo-56874dc7f8-5rb9q   1/1     Running   0          40s
    podinfo-56874dc7f8-t6jgn   1/1     Running   0          40s
    [root@master01 podinfo]#