全部產品
Search
文件中心

Container Service for Kubernetes:通過Nginx Ingress對多個應用進行HPA

更新時間:Jun 19, 2024

多執行個體部署可以最大程度的保證應用的穩定性,但同時也會造成閑時資源的浪費和高額成本。手動調節方式工作量大還存在一定程度的滯後性。通過Nginx Ingress對多個應用進行HPA,可以自動根據應用的負載情況動態調整Pod副本數量,從而在保障應用穩定性和響應能力的同時,最佳化資源使用,降低成本。本文介紹通過Nginx Ingress對多個應用進行HPA的方法。

前提條件

通過Nginx Ingress對多個應用進行HPA前,需要將阿里雲Prometheus指標轉換成HPA可用的指標,您需要部署相關組件。

背景資訊

在實際的生產中,您使用請求量來自動擴縮容時,可以通過註冊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擴縮容的功能。

  1. 使用以下YAML檔案建立業務Deployment和對應的Service。

    1. 建立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
    2. 建立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
  2. 建立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。

  3. 執行以下命令,擷取Ingress資源。

    kubectl get ingress -o wide

    預期輸出:

    NAME           CLASS   HOSTS              ADDRESS       PORTS   AGE                                                  
    test-ingress   nginx   test.example.com   10.10.10.10   80      55s
  4. 部署成功後,可以通過//home兩個路徑分別訪問Host地址。Nginx Ingress Controller會根據上方配置分別訪問sample-app和test-app。通過阿里雲Prometheus查詢指標nginx_ingress_controller_requests,可以擷取各應用的請求情況。

  5. 修改組件alibaba-cloud-metrics-adapter中的adapter.config檔案,將Prometheus中的指標轉換成HPA可用的指標。

    說明

    在進行本步驟前,請確保已完成了組件alibaba-cloud-metrics-adapter的部署和prometheus.url的配置。

    1. 登入Container Service管理主控台,在左側導覽列選擇叢集

    2. 叢集列表頁面,單擊目的地組群名稱,然後在左側導覽列,選擇應用 > Helm

    3. 單擊ack-alibaba-cloud-metrics-adapter

    4. 資源地區,單擊adapter-config

    5. adapter-config頁面,單擊頁面右上方的YAML 編輯

    6. 用以下代碼替換中的代碼,然後單擊頁面下方的確定

      關於以下配置項詳解,請參考基於阿里雲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
  6. 執行以下命令,查看指標輸出。

    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"
        }
      ]
    }
  7. 建立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
  8. 執行以下命令,查看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
  9. HPA部署成功後,進行壓測實驗,觀察業務應用是否會隨著請求增大而擴容。

    1. 執行以下命令,對Host下的/home路徑進行壓測。

      ab -c 50 -n 5000 test.example.com/home
    2. 執行以下命令,查看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
    3. 執行以下命令,對Host的根路徑進行壓測。

      ab -c 50 -n 5000 test.example.com/
    4. 執行以下命令,查看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的便捷性,請參見彈性最佳化之自訂鏡像