HPA

HPA全称Horizontal Pod Autoscaling ,可以实现pod的水平自动化扩缩容,比如当POD中业务负载上升的时候,可以创建新的POD来保证业务系统稳定运行,当POD中业务负载下降的时候,可以销毁POD来提高资源利用率。

HPA目前支持四种类型的指标,分别是Resource、Object、External、Pods。其中在稳定版本autoscaling/v1中只支持对CPU指标的动态伸缩,在测试版本autoscaling/v2beta2中支持memory和自定义指标的动态伸缩,并以annotation的方式工作在autoscaling/v1版本中。

refer: https://zhuanlan.zhihu.com/p/...

metrics-server

k8s api-server的支持

    - --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt    - --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key    - --requestheader-allowed-names=front-proxy-client    - --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt    - --requestheader-extra-headers-prefix=X-Remote-Extra-    - --requestheader-group-headers=X-Remote-Group    - --requestheader-username-headers=X-Remote-User
notes:如果你未在 master 节点上运行 kube-proxy,则必须确保 kube-apiserver 启动参数中包含--enable-aggregator-routing=true

部署

metrics-server.yaml 参见下文,部署时注意nodeSelector是否匹配

      nodeSelector:        kubernetes.io/os: linux        kubernetes.io/arch: "amd64"
kubectl create -f metrics-server.yaml

metrics api

手动获取指标

kubectl get --raw /apis/metrics.k8s.io/v1beta1/pods

or

[root@master01 hpa]# curl -H "Authorization: Bearer $toke" -k https://172.31.133.26:6443/apis/|grep metrics -C 5    {      "name": "metrics.k8s.io",      "versions": [        {          "groupVersion": "metrics.k8s.io/v1beta1",          "version": "v1beta1"        }      ],      "preferredVersion": {        "groupVersion": "metrics.k8s.io/v1beta1",        "version": "v1beta1"      }    }  ]}[root@master01 hpa]# curl -H "Authorization: Bearer $toke" -k https://172.31.133.26:6443/apis/metrics.k8s.io/v1beta1/pods |grep php -C 7    {      "metadata": {        "name": "php-apache-7bf64757b9-sh4rl",        "namespace": "default",        "selfLink": "/apis/metrics.k8s.io/v1beta1/namespaces/default/pods/php-apache-7bf64757b9-sh4rl",      },      "containers": [        {          "name": "php-apache",          "usage": {            "cpu": "31395n",            "memory": "11988Ki"          }        }      ]    },

CPU HPA

创建应用

kubectl run php-apache --image=k8s.gcr.io/hpa-example --requests=cpu=200m --expose --port=80

创建hpa

kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10

压测

kubectl run -i --tty load-generator --image=busybox /bin/shHit enter for command promptwhile true; do wget -q -O- http://php-apache; done

自动弹性

[root@master01 msxu]# kubectl get hpa -wNAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGEphp-apache   Deployment/php-apache   0%/50%    1         10        1          52mphp-apache   Deployment/php-apache   493%/50%   1         10        1          52mphp-apache   Deployment/php-apache   493%/50%   1         10        4          52mphp-apache   Deployment/php-apache   493%/50%   1         10        8          52mphp-apache   Deployment/php-apache   493%/50%   1         10        10         53mphp-apache   Deployment/php-apache   54%/50%    1         10        10         53mphp-apache   Deployment/php-apache   49%/50%    1         10        10         54mphp-apache   Deployment/php-apache   44%/50%    1         10        10         56mphp-apache   Deployment/php-apache   0%/50%     1         10        10         57mphp-apache   Deployment/php-apache   0%/50%     1         10        10         61mphp-apache   Deployment/php-apache   0%/50%     1         10        9          61mphp-apache   Deployment/php-apache   0%/50%     1         10        9          62mphp-apache   Deployment/php-apache   0%/50%     1         10        1          62m

MEM HPA

创建HPA

apiVersion: autoscaling/v2beta1kind: HorizontalPodAutoscalermetadata:  name: php-apache-hpa  namespace: defaultspec:  scaleTargetRef:    apiVersion: apps/v1beta1    kind: Deployment    name: php-apache  minReplicas: 1  maxReplicas: 3  metrics:  - type: Resource    resource:      name: memory      targetAverageUtilization: 30

查看

[root@master01 hpa]# kubectl get hpaNAME             REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGEphp-apache       Deployment/php-apache   0%/50%    1         10        1          5d17hphp-apache-hpa   Deployment/php-apache   11%/30%   1         3         1          5d17h[root@master01 hpa]# kubectl describe  hpa php-apache-hpa Name:                                                     php-apache-hpaNamespace:                                                defaultLabels:                                                   <none>Annotations:                                              <none>CreationTimestamp:                                        Thu, 30 Apr 2020 17:57:40 +0800Reference:                                                Deployment/php-apacheMetrics:                                                  ( current / target )  resource memory on pods  (as a percentage of request):  11% (11546624) / 30%Min replicas:                                             1Max replicas:                                             3Deployment pods:                                          1 current / 1 desiredConditions:  Type            Status  Reason              Message  ----            ------  ------              -------  AbleToScale     True    ReadyForNewScale    recommended size matches current size  ScalingActive   True    ValidMetricFound    the HPA was able to successfully calculate a replica count from memory resource utilization (percentage of request)  ScalingLimited  False   DesiredWithinRange  the desired count is within the acceptable rangeEvents:           <none>

yaml

metrics-server.yaml 0.3.6

apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  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: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: metrics-server:system:auth-delegatorroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: system:auth-delegatorsubjects:- kind: ServiceAccount  name: metrics-server  namespace: kube-system---apiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:  name: metrics-server-auth-reader  namespace: kube-systemroleRef:  apiGroup: rbac.authorization.k8s.io  kind: Role  name: extension-apiserver-authentication-readersubjects:- kind: ServiceAccount  name: metrics-server  namespace: kube-system---apiVersion: apiregistration.k8s.io/v1beta1kind: APIServicemetadata:  name: v1beta1.metrics.k8s.iospec:  service:    name: metrics-server    namespace: kube-system  group: metrics.k8s.io  version: v1beta1  insecureSkipTLSVerify: true  groupPriorityMinimum: 100  versionPriority: 100---apiVersion: v1kind: ServiceAccountmetadata:  name: metrics-server  namespace: kube-system---apiVersion: apps/v1kind: Deploymentmetadata:  name: metrics-server  namespace: kube-system  labels:    k8s-app: metrics-serverspec:  selector:    matchLabels:      k8s-app: metrics-server  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: k8s.gcr.io/metrics-server-amd64:v0.3.1        imagePullPolicy: IfNotPresent        args:          - --cert-dir=/tmp          - --secure-port=4443          - --kubelet-preferred-address-types=InternalIP          - --kubelet-insecure-tls        ports:        - name: main-port          containerPort: 4443          protocol: TCP        securityContext:          readOnlyRootFilesystem: true          runAsNonRoot: true          runAsUser: 1000        volumeMounts:        - name: tmp-dir          mountPath: /tmp      nodeSelector:        kubernetes.io/os: linux        kubernetes.io/arch: "amd64"---apiVersion: v1kind: Servicemetadata:  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---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:  name: system:metrics-serverrules:- apiGroups:  - ""  resources:  - pods  - nodes  - nodes/stats  - namespaces  - configmaps  verbs:  - get  - list  - watch---apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata:  name: system:metrics-serverroleRef:  apiGroup: rbac.authorization.k8s.io  kind: ClusterRole  name: system:metrics-serversubjects:- kind: ServiceAccount  name: metrics-server  namespace: kube-system