多執行個體部署可以最大程度的保證應用的穩定性,但同時也會造成閑時資源的浪費和高額成本。手動調節方式工作量大還存在一定程度的滯後性。通過Nginx Ingress對多個應用進行HPA,可以自動根據應用的負載情況動態調整Pod副本數量,從而在保障應用穩定性和響應能力的同時,最佳化資源使用,降低成本。本文介紹通過Nginx Ingress對多個應用進行HPA的方法。
前提條件
通過Nginx Ingress對多個應用進行HPA前,需要將阿里雲Prometheus指標轉換成HPA可用的指標,您需要部署相關組件。
已部署阿里雲Prometheus監控組件。具體操作,請參見阿里雲Prometheus監控。
已部署alibaba-cloud-metrics-adapter組件。具體操作,請參見基於阿里雲Prometheus指標的容器水平伸縮。
已安裝壓力測試工具Apache Benchmark。更多資訊,請參見Apache Benchmark。
背景資訊
在實際的生產中,您使用請求量來自動擴縮容時,可以通過註冊http_requests_total來透出請求量指標,同時推薦使用Ingress組件內建的指標來進行HPA。
Ingress是Kubernetes API中的標準資源類型之一。Ingress實現的功能是將用戶端請求的Host名稱或請求的URL路徑,轉寄到指定的Service資源中,即將Kubernetes叢集外部的請求轉寄至叢集內部的Service中,再被Service轉寄至Pod,處理用戶端的請求。
Nginx Ingress Controller是部署於叢集內部的Ingress控制器,可以為您提供效能更好,且定製性更高的使用方式。ACK叢集提供的Nginx Ingress Controller在社區版本的基礎上,整合了阿里雲產品的一系列功能,提供了更加便捷的使用體驗。
操作步驟
本教程包含兩個ClusterIP型服務,通過Nginx Ingress實現對外的流量路由。基於nginx_ingress_controller_requests
指標,為應用配置HPA,以實現隨著流量的變化為Pod擴縮容的功能。
使用以下YAML檔案建立業務Deployment和對應的Service。
建立nginx1.yaml檔案。然後執行命令
kubectl apply -f nginx1.yaml
,建立應用test-app和對應的Service。apiVersion: apps/v1 kind: Deployment metadata: name: test-app labels: app: test-app spec: replicas: 1 selector: matchLabels: app: test-app template: metadata: labels: app: test-app spec: containers: - image: skto/sample-app:v2 name: metrics-provider ports: - name: http containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: test-app namespace: default labels: app: test-app spec: ports: - port: 8080 name: http protocol: TCP targetPort: 8080 selector: app: test-app type: ClusterIP
建立nginx2.yaml檔案。然後執行命令
kubectl apply -f nginx2.yaml
,建立應用sample-app和對應的Service。apiVersion: apps/v1 kind: Deployment metadata: name: sample-app labels: app: sample-app spec: replicas: 1 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - image: skto/sample-app:v2 name: metrics-provider ports: - name: http containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: sample-app namespace: default labels: app: sample-app spec: ports: - port: 80 name: http protocol: TCP targetPort: 8080 selector: app: sample-app type: ClusterIP
建立ingress.yaml檔案。然後執行
kubectl apply -f ingress.yaml
命令,部署Ingress資源。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: test-ingress namespace: default spec: ingressClassName: nginx rules: - host: test.example.com http: paths: - backend: service: name: sample-app port: number: 80 path: / pathType: ImplementationSpecific - backend: service: name: test-app port: number: 8080 path: /home pathType: ImplementationSpecific
host:指定服務訪問網域名稱。本樣本使用
test.example.com
。path:指定訪問的URL路徑。請求到來之後會根據路由規則匹配相應的Service,然後通過Service訪問相應的Pod。
backend:由Service名稱和Service連接埠組成,指定當前
path
轉寄的Service。
執行以下命令,擷取Ingress資源。
kubectl get ingress -o wide
預期輸出:
NAME CLASS HOSTS ADDRESS PORTS AGE test-ingress nginx test.example.com 10.10.10.10 80 55s
部署成功後,可以通過
/
和/home
兩個路徑分別訪問Host地址。Nginx Ingress Controller會根據上方配置分別訪問sample-app和test-app。通過阿里雲Prometheus查詢指標nginx_ingress_controller_requests
,可以擷取各應用的請求情況。修改組件alibaba-cloud-metrics-adapter中的adapter.config檔案,將Prometheus中的指標轉換成HPA可用的指標。
說明在進行本步驟前,請確保已完成了組件alibaba-cloud-metrics-adapter的部署和prometheus.url的配置。
登入Container Service管理主控台,在左側導覽列選擇叢集。
在叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇 。
單擊ack-alibaba-cloud-metrics-adapter。
在資源地區,單擊adapter-config。
在adapter-config頁面,單擊頁面右上方的YAML 編輯。
用以下代碼替換值中的代碼,然後單擊頁面下方的確定。
關於以下配置項詳解,請參考基於阿里雲Prometheus指標的容器水平伸縮。
rules: - metricsQuery: sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) name: as: ${1}_per_second matches: ^(.*)_requests resources: namespaced: false overrides: controller_namespace: resource: namespace seriesQuery: nginx_ingress_controller_requests
執行以下命令,查看指標輸出。
kubectl get --raw "/apis/external.metrics.k8s.io/v1beta1/namespaces/*/nginx_ingress_controller_per_second" | jq .
查詢指標結果如下:
{ "kind": "ExternalMetricValueList", "apiVersion": "external.metrics.k8s.io/v1beta1", "metadata": {}, "items": [ { "metricName": "nginx_ingress_controller_per_second", "metricLabels": {}, "timestamp": "2022-03-31T10:11:37Z", "value": "0" } ] }
建立hpa.yaml檔案。然後執行
kubectl apply -f hpa.yaml
命令,對業務應用sample-app和test-app分別部署HPA。apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: sample-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: sample-app minReplicas: 1 maxReplicas: 10 metrics: - type: External external: metric: name: nginx_ingress_controller_per_second selector: matchLabels: #可以通過這個欄位對指標進行過濾,這裡設定的欄位會傳入adapter.config中的<<.LabelMatchers>>標籤。 service: sample-app #External指標類型下只支援Value和AverageValue類型的目標值。 target: type: AverageValue averageValue: 30 ---------- apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: test-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: test-app minReplicas: 1 maxReplicas: 10 metrics: - type: External external: metric: name: nginx_ingress_controller_per_second selector: matchLabels: #可以通過這個欄位對指標進行過濾,這裡設定的欄位會傳入adapter.config中的<<.LabelMatchers>>標籤。 service: test-app #External指標類型下只支援Value和AverageValue類型的目標值。 target: type: AverageValue averageValue: 30
執行以下命令,查看HPA部署情況。
kubectl get hpa
預期輸出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-app 0/30 (avg) 1 10 1 74s test-hpa Deployment/test-app 0/30 (avg) 1 10 1 59m
HPA部署成功後,進行壓測實驗,觀察業務應用是否會隨著請求增大而擴容。
執行以下命令,對Host下的
/home
路徑進行壓測。ab -c 50 -n 5000 test.example.com/home
執行以下命令,查看HPA情況。
kubectl get hpa
預期輸出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-app 0/30 (avg) 1 10 1 22m test-hpa Deployment/test-app 22096m/30 (avg) 1 10 3 80m
執行以下命令,對Host的根路徑進行壓測。
ab -c 50 -n 5000 test.example.com/
執行以下命令,查看HPA情況。
kubectl get hpa
預期輸出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE sample-hpa Deployment/sample-app 27778m/30 (avg) 1 10 2 38m test-hpa Deployment/test-app 0/30 (avg) 1 10 1 96m
從上述結果可以看到,業務應用在請求量增大超過閾值的情況下成功擴容。
相關文檔
多可用性區域均衡是資料類型業務在高可用情境下常用的部署方式。當業務壓力增大時,有多可用性區域均衡調度策略的應用希望可以自動擴容出多個可用性區域的執行個體來滿足叢集的調度水位。詳細資料,請參見多可用性區域同時快速彈性擴容。
構建自訂動作系統鏡像以提高複雜情境下Auto Scaling的便捷性,請參見彈性最佳化之自訂鏡像。