Kubernetes HPA

317 阅读3分钟

HPA(Horizontal Pod Autoscaler)是kubernetes的一种资源对象,能够根据某些指标对在statefulSet、replicaController、replicaSet等集合中的pod数量进行动态伸缩,使运行在上面的服务对指标的变化有一定的自适应能力。

安装metric-server

确保安装metric-server,可以检测到集群的CPU和内存信息。

---
apiVersion: apiregistration.k8s.io/v1beta1
kind: APIService
metadata:
  name: v1beta1.metrics.k8s.io
spec:
  service:
    name: metrics-server
    namespace: kube-system
  group: metrics.k8s.io
  version: v1beta1
  insecureSkipTLSVerify: true
  groupPriorityMinimum: 100
  versionPriority: 100
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  selector:
    matchLabels:
      k8s-app: metrics-server
  strategy:
    rollingUpdate:
      maxUnavailable: 0
  template:
    metadata:
      name: metrics-server
      labels:
        k8s-app: metrics-server
    spec:
      serviceAccountName: metrics-server
      volumes:
      # mount in tmp so we can safely use from-scratch images and/or read-only containers
      - name: tmp-dir
        emptyDir: {}
      containers:
      - name: metrics-server
        image: gcr.io/k8s-staging-metrics-server/metrics-server:master
        imagePullPolicy: IfNotPresent
        command:
        - /metrics-server
        - --kubelet-insecure-tls
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        args:
          - --cert-dir=/tmp
          - --secure-port=4443
        ports:
        - name: main-port
          containerPort: 4443
          protocol: TCP
        readinessProbe:
          httpGet:
            path: /healthz
            port: main-port
            scheme: HTTPS
        securityContext:
          readOnlyRootFilesystem: true
          runAsNonRoot: true
          runAsUser: 1000
        volumeMounts:
        - name: tmp-dir
          mountPath: /tmp
      nodeSelector:
        kubernetes.io/os: linux
---
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    k8s-app: metrics-server
spec:
  minAvailable: 100%
  selector:
    matchLabels:
      k8s-app: metrics-server
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:aggregated-metrics-reader
  labels:
    rbac.authorization.k8s.io/aggregate-to-view: "true"
    rbac.authorization.k8s.io/aggregate-to-edit: "true"
    rbac.authorization.k8s.io/aggregate-to-admin: "true"
rules:
- apiGroups: ["metrics.k8s.io"]
  resources: ["pods", "nodes"]
  verbs: ["get", "list", "watch"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-server
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: metrics-server-auth-reader
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: extension-apiserver-authentication-reader
subjects:
  - kind: ServiceAccount
    name: metrics-server
    namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: metrics-server:system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
  - kind: ServiceAccount
    name: metrics-server
    namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:metrics-server
rules:
  - apiGroups:
      - ""
    resources:
      - pods
      - nodes
      - nodes/stats
      - namespaces
      - configmaps
    verbs:
      - get
      - list
      - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: system:metrics-server
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:metrics-server
subjects:
  - kind: ServiceAccount
    name: metrics-server
    namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
  name: metrics-server
  namespace: kube-system
  labels:
    kubernetes.io/name: "Metrics-server"
    kubernetes.io/cluster-service: "true"
spec:
  selector:
    k8s-app: metrics-server
  ports:
  - port: 443
    protocol: TCP
    targetPort: main-port

安装完成后可以通过kubectl top命令查看相应资源的CPU和内存使用情况

root@master01:~/yaml/hpa/WebBench# kubectl top node
NAME       CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%   
master01   390m         19%    2218Mi          57%       
worker01   89m          4%     1744Mi          45%       
worker02   1093m        54%    1536Mi          39%       
root@master01:~/yaml/hpa/WebBench# kubectl top pod
NAME                                      CPU(cores)   MEMORY(bytes)   
nfs-client-provisioner-6565b468fc-h46kx   2m           7Mi             
nginx-59f6b957d7-5kjph                    0m           1Mi  

部署服务

部署一个Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.6
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"

暴露这个服务

root@master01:~/yaml/hpa# kubectl expose deployment nginx  --port=80
service/nginx exposed

配置HPA

配置autoscale策略,Pod最大数量为10,最小数量为1,在cpu使用率超过80%的时候扩缩容。

root@master01:~/yaml/hpa# kubectl autoscale deployment nginx --max=10 --min=1 --cpu-percent=80
horizontalpodautoscaler.autoscaling/nginx autoscaled

测试验证

部署一个测试工具,用于发送请求

apt-get -y install gcc
git clone https://github.com/EZLippi/WebBench.git
cd WebBench 
make ; make install
root@master01:~/yaml/hpa/WebBench# webbench -c 1000 -t 60 http://10.103.27.138/  #ip地址是service的ip
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.

Request:
GET / HTTP/1.0
User-Agent: WebBench 1.5
Host: 10.103.27.138


Runing info: 1000 clients, running 60 sec.

Speed=220372 pages/min, 3098478 bytes/sec.
Requests: 220271 susceed, 101 failed.

可以看到Pod自动扩容了

Every 1.0s: kubectl get hpa && kubectl top pod && kubectl get pod                                                                            Sun May 10 15:06:45 2020

NAME    REFERENCE          TARGETS    MINPODS   MAXPODS   REPLICAS   AGE
nginx   Deployment/nginx   558%/80%   1         10        7          14m
NAME                                      CPU(cores)   MEMORY(bytes)
nginx-59f6b957d7-rr7zv                    558m         1Mi
NAME                                      READY   STATUS    RESTARTS   AGE                   
nginx-59f6b957d7-5kjph                    1/1     Running   0          49s
nginx-59f6b957d7-67q9n                    1/1     Running   0          49s
nginx-59f6b957d7-fzqnn                    1/1     Running   0          33s
nginx-59f6b957d7-gqmc4                    1/1     Running   0          49s
nginx-59f6b957d7-k9b78                    1/1     Running   0          34s
nginx-59f6b957d7-r52x9                    1/1     Running   0          33s
nginx-59f6b957d7-rr7zv                    1/1     Running   0          15m