Kubernetes 弹性伸缩全场景解析(三) - HPA 实践手册
在上一篇文章中,給大家介紹和剖析了 HPA 的實現原理以及演進的思路與歷程。本文我們將會為大家講解如何使用 HPA 以及一些需要注意的細節。
autoscaling/v1 實踐
v1 的模板可能是大家平時見到最多的也是最簡單的,v1 版本的 HPA 只支持一種指標 —— CPU。傳統意義上,彈性伸縮最少也會支持 CPU 與 Memory 兩種指標,為什么在 Kubernetes 中只放開了 CPU 呢?其實最早的 HPA 是計劃同時支持這兩種指標的,但是實際的開發測試中發現:內存不是一個非常好的彈性伸縮判斷條件。因為和 CPU不 同,很多內存型的應用,并不會因為 HPA 彈出新的容器而帶來內存的快速回收,很多應用的內存都要交給語言層面的 VM 進行管理,也就是說,內存的回收是由 VM 的 GC 來決定的。這就有可能因為 GC 時間的差異導致 HPA 在不恰當的時間點震蕩,因此在 v1 的版本中,HPA 就只支持了 CPU 這一種指標。
一個標準的 v1 模板大致如下:
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata:name: php-apachenamespace: default spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: php-apacheminReplicas: 1maxReplicas: 10targetCPUUtilizationPercentage: 50其中 scaleTargetRef 表示當前要操作的伸縮對象是誰。在本例中,伸縮的對象是一個 apps/v1 版本的 Deployment。 targetCPUUtilizationPercentage 表示:當整體的資源利用率超過 50% 的時候,會進行擴容。接下來我們做一個簡單的 Demo 來實踐下。
這樣一個使用 autoscaling/v1 的 HPA 就完成了。相對而言,這個版本的 HPA 目前是最簡單的,無論是否升級 Metrics-Server 都可以實現。
autoscaling/v2beta1 實踐
在前面的內容中為大家講解了 HPA 還有 autoscaling/v2beta1 和 autoscaling/v2beta2 兩個版本。這兩個版本的區別是 autoscaling/v1beta1 支持了 Resource Metrics 和 Custom Metrics。而在 autoscaling/v2beta2 的版本中額外增加了 External Metrics 的支持。對于 External Metrics 在本文中就不進行過多贅述,因為 External Metrics 目前在社區里面沒有太多成熟的實現,比較成熟的實現是 Prometheus Custom Metrics。
上面這張圖為大家展現了開啟 Metrics Server 后, HPA 如何使用不同類型的Metrics,如果需要使用 Custom Metrics ,則需要配置安裝相應的 Custom Metrics Adapter。在下文中,主要為大家介紹一個基于 QPS 來進行彈性伸縮的例子。
目前默認的阿里云容器服務 Kubernetes 集群使用還是 Heapster,容器服務計劃在 1.12 中更新 Metrics Server,這個地方需要特別說明下,社區雖然已經逐漸開始廢棄 Heapster,但是社區中還有大量的組件是在強依賴 Heapster 的 API,因此阿里云基于 Metrics Server 進行了 Heapster 完整的兼容,既可以讓開發者使用 Metrics Server 的新功能,又可以無需擔心其他組件的宕機。
在部署新的 Metrics Server 之前,我們首先要備份一下 Heapster 中的一些啟動參數,因為這些參數稍后會直接用在 Metrics Server 的模板中。其中重點關心的是兩個 Sink,如果需要使用 Influxdb 的開發者,可以保留第一個 Sink;如果需要保留云監控集成能力的開發者,則保留第二個 Sink。
將這兩個參數拷貝到 Metrics Server 的啟動模板中,在本例中是兩個都兼容,并下發部署。
apiVersion: v1 kind: ServiceAccount metadata:name: metrics-servernamespace: kube-system --- apiVersion: v1 kind: Service metadata:name: metrics-servernamespace: kube-systemlabels:kubernetes.io/name: "Metrics-server" spec:selector:k8s-app: metrics-serverports:- port: 443protocol: TCPtargetPort: 443 --- apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata:name: v1beta1.metrics.k8s.io spec:service:name: metrics-servernamespace: kube-systemgroup: metrics.k8s.ioversion: v1beta1insecureSkipTLSVerify: truegroupPriorityMinimum: 100versionPriority: 100 --- apiVersion: extensions/v1beta1 kind: Deployment metadata:name: metrics-servernamespace: kube-systemlabels:k8s-app: metrics-server spec:selector:matchLabels:k8s-app: metrics-servertemplate:metadata:name: metrics-serverlabels:k8s-app: metrics-serverspec:serviceAccountName: admincontainers:- name: metrics-serverimage: registry.cn-hangzhou.aliyuncs.com/ringtail/metrics-server:1.1imagePullPolicy: Alwayscommand:- /metrics-server- '--source=kubernetes:https://kubernetes.default'- '--sink=influxdb:http://monitoring-influxdb:8086'- '--sink=socket:tcp://monitor.csk.[region_id].aliyuncs.com:8093?clusterId=[cluster_id]&public=true'接下來我們修改下 Heapster 的 Service,將服務的后端從 Heapster 轉移到 Metrics Server。
如果此時從控制臺的節點頁面可以獲取到右側的監控信息的話,說明 Metrics Server 已經完全兼容 Heapster。
此時通過 kubectl get apiservice,如果可以看到注冊的 v1beta1.metrics.k8s.io 的 api,則說明已經注冊成功。
接下來我們需要在 kube-controller-manager 上切換 Metrics 的數據來源。kube-controller-manger 部署在每個 master 上,是通過 Static Pod 的托管給 kubelet 的。因此只需要修改 kube-controller-manager 的配置文件,kubelet 就會自動進行更新。kube-controller-manager 在主機上的路徑是 /etc/kubernetes/manifests/kube-controller-manager.yaml。
需要將 --horizontal-pod-autoscaler-use-rest-clients=true,這里有一個注意點,因為如果使用 vim 進行編輯,vim 會自動生成一個緩存文件影響最終的結果,所以比較建議的方式是將這個配置文件移動到其他的目錄下進行修改,然后再移回原來的目錄。至此,Metrics Server 已經可以為 HPA 進行服務了,接下來我們來做自定義指標的部分。
如集群中未部署 Prometheus,可以參考《阿里云容器Kubernetes監控(七) - Prometheus監控方案部署》先部署 Prometheus。接下來我們部署 Custom Metrics Adapter。
kind: Namespace apiVersion: v1 metadata:name: custom-metrics --- kind: ServiceAccount apiVersion: v1 metadata:name: custom-metrics-apiservernamespace: custom-metrics --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: custom-metrics:system:auth-delegator roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: system:auth-delegator subjects: - kind: ServiceAccountname: custom-metrics-apiservernamespace: custom-metrics --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata:name: custom-metrics-auth-readernamespace: kube-system roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: extension-apiserver-authentication-reader subjects: - kind: ServiceAccountname: custom-metrics-apiservernamespace: custom-metrics --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:name: custom-metrics-resource-reader rules: - apiGroups:- ""resources:- namespaces- pods- servicesverbs:- get- list --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: custom-metrics-apiserver-resource-reader roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: custom-metrics-resource-reader subjects: - kind: ServiceAccountname: custom-metrics-apiservernamespace: custom-metrics --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:name: custom-metrics-getter rules: - apiGroups:- custom.metrics.k8s.ioresources:- "*"verbs:- "*" --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: hpa-custom-metrics-getter roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: custom-metrics-getter subjects: - kind: ServiceAccountname: horizontal-pod-autoscalernamespace: kube-system --- apiVersion: apps/v1 kind: Deployment metadata:name: custom-metrics-apiservernamespace: custom-metricslabels:app: custom-metrics-apiserver spec:replicas: 1selector:matchLabels:app: custom-metrics-apiservertemplate:metadata:labels:app: custom-metrics-apiserverspec:tolerations:- key: beta.kubernetes.io/archvalue: armeffect: NoSchedule- key: beta.kubernetes.io/archvalue: arm64effect: NoScheduleserviceAccountName: custom-metrics-apiservercontainers:- name: custom-metrics-serverimage: luxas/k8s-prometheus-adapter:v0.2.0-beta.0args:- --prometheus-url=http://prometheus-k8s.monitoring.svc:9090- --metrics-relist-interval=30s- --rate-interval=60s- --v=10- --logtostderr=trueports:- containerPort: 443securityContext:runAsUser: 0 --- apiVersion: v1 kind: Service metadata:name: apinamespace: custom-metrics spec:ports:- port: 443targetPort: 443selector:app: custom-metrics-apiserver --- apiVersion: apiregistration.k8s.io/v1 kind: APIService metadata:name: v1beta1.custom.metrics.k8s.io spec:insecureSkipTLSVerify: truegroup: custom.metrics.k8s.iogroupPriorityMinimum: 1000versionPriority: 5service:name: apinamespace: custom-metricsversion: v1beta1 --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata:name: custom-metrics-server-resources rules: - apiGroups:- custom-metrics.metrics.k8s.ioresources: ["*"]verbs: ["*"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata:name: hpa-controller-custom-metrics roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: custom-metrics-server-resources subjects: - kind: ServiceAccountname: horizontal-pod-autoscalernamespace: kube-system這個壓測的應用暴露了一個 Prometheus 的接口。接口中的數據如下,其中 http_requests_total 這個指標就是我們接下來伸縮使用的自定義指標。
[root@iZwz99zrzfnfq8wllk0dvcZ manifests]# curl 172.16.1.160:8080/metrics # HELP http_requests_total The amount of requests served by the server in total # TYPE http_requests_total counter http_requests_total 3955684最后
這篇文章主要是給大家帶來一個對于 autoscaling/v1 和 autoscaling/v2beta1 的感性認知和大體的操作方式,對于 autoscaling/v1 我們不做過多的贅述,對于希望使用支持 Custom Metrics 的 autoscaling/v2beta1 的開發者而言,也許會認為整體的操作流程過于復雜難以理解,我們會在下一篇文章中為大家詳解 autoscaling/v2beta1 使用 Custom Metrics 的種種細節,幫助大家更深入地理解其中的原理與設計思路。
總結
以上是生活随笔為你收集整理的Kubernetes 弹性伸缩全场景解析(三) - HPA 实践手册的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解锁云原生 AI 技能 - 开发你的机器
- 下一篇: 大咖云集!Kubernetes and