istio 메트릭(Custom Metrics)을 사용하여 HPA(Horizontal Pod Autoscaler) 설정

안녕하세요. Lapi@dragoneena12입니다.
최근 SRE 인턴십주식회사 HERP은 아이티오의 도량에 따라 HPA를 설정할 기회가 생겼고, 특히 일본어의 경우 정보가 매우 제한적이어서 기사를 썼다.나는 가능한 한 상세하게 썼으니 참고가 되었으면 좋겠다.

HPA에 사용되는 양도의 종류


HPA는 특정 측정 값을 기준으로 Pod 수를 자동으로 증감하는 기능입니다.사용량은 다음과 같은 3가지Support for metrics APIs | Horizontal Pod Autoscaler user guide가 있다.
  • Resource Metrics
  • CPU 사용률, 스토리지 사용률 등
  • Custom Metrics
  • kubernetes 클러스터 내 리소스와 연관된 도량(requests per second, 99 percentile duration 등)
  • External Metrics
  • kubernetes 집단 내의 자원과 무관한 도량(외부 부하 평형기의 도량 등)
  • 이번에는 리퀘스트.per_second를 기반으로 HPA를 설정하고 싶어 커스텀 메트릭스를 사용하기로 했다.

    istio로 얻은 도량


    istio를 가져오면 각 서비스에 대해 Request Count 등 다양한 메트릭Istio Standard Metrics을 수집할 수 있습니다.이번에 이것istio_requests_total을 바탕으로 HPA를 설정했다.
    https://istio.io/latest/

    prometheus-adapter


    이른바 prometheus-adapter

    istio_requests_total 양도는prometheus에 수집되었지만 HPA에서 이 값을 사용하기 위해kubernetes의 음향 APIcustom.metrics.k8s.io에 로그인해야 한다.
    이것을 할 수 있는 것은 kubernetes-sigs/prometheus-adapter입니다.이전에는 DirectXMan12의 개인 창고최근에 Kubernetes-Sigs로 옮겼어요.였습니다.
    https://github.com/kubernetes-sigs/prometheus-adapter

    설치, 설정 방법


    helm에서 설치할 수 있습니다. values.yaml 에서 양도 API에promeetheus의 어떤 값을 등록할 수 있습니다.상세한 상황은 공식 창고Metrics Discovery and Presentation Configuration에 적혀 있으며, 간단하게 말하면 다음과 같은 4개로 구성되어 있다.
  • Discovery
  • seriesQuery로 설정된 부분
  • adapter가 등록된 재고 라벨을 확인한 조회
  • Association
  • resources로 설정된 부분
  • Kubbernetes의 어떤 자원과 연결된 메트릭을 설정합니다
  • Naming
  • name로 설정된 부분
  • 양도의 명명
  • Querying
  • metricsQuery로 설정된 부분
  • 실제 계산 도량치의 조회
  • 이번에는 이를 다음과 같은 내용으로 설정했다.
    rules:
      custom:
      - seriesQuery: 'istio_requests_total{reporter="destination", destination_service_namespace=~"ns1|ns2|ns3", destination_service_name=~"svc1|svc2|svc3"}'
        resources:
          overrides:
            destination_service_namespace: {resource: "namespace"}
            destination_service_name: {resource: "service"}
        name:
          as: "requests_per_second"
        metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>, reporter="destination"}[5m])) by (<<.GroupBy>>)'
    
    점으로 istio_requests_total는source와 destination 쌍방이 보고하기 때문에 reporter="destination"로 지정한다.또한 istio_requests_total는 각 서비스에 따라 계산되기 때문에 resources에서 측정치를 각 서비스와 연결시킨다.

    메트릭 등록 여부 확인


    다음 명령을 통해 음향도가 서비스와 관련이 있는지 확인할 수 있습니다.
    $ kubectl get --raw '/apis/custom.metrics.k8s.io/v1beta1/namespaces/ns1/services/svc1/requests_per_second' | jq
    {
      "kind": "MetricValueList",
      "apiVersion": "custom.metrics.k8s.io/v1beta1",
      "metadata": {
        "selfLink": "/apis/custom.metrics.k8s.io/v1beta1/namespaces/ns1/services/svc1/requests_per_second"
      },
      "items": [
        {
          "describedObject": {
            "kind": "Service",
            "namespace": "ns1",
            "name": "svc1",
            "apiVersion": "/v1"
          },
          "metricName": "requests_per_second",
          "timestamp": "2021-02-03T11:21:30Z",
          "value": "34857m",
          "selector": null
        }
      ]
    }
    

    HPA 설정


    Custom Metrics 기반 HPA 설정


    다음은 HPA의 선언문을 쓰겠습니다.이번 설정은 다음과 같다.
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
      name: hpa1
      namespace: ns1
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: deployment1
      minReplicas: 1
      maxReplicas: 10
      metrics:
      - type: Object
        object:
          describedObject:
            apiVersion: v1
            kind: Service
            name: svc1
          metric:
            name: requests_per_second
          target:
            type: AverageValue
            averageValue: 5
    
    spec.metrics.type은 다음 네 가지 유형을 설정할 수 있습니다.
  • Resource
  • CPU 사용률, 스토리지 사용률 등에 대한 재평가
  • Pods
  • 각 Pod와 연관된 음향 측정치
  • Object
  • Pod 이외의 연관된 음향 도량
  • External
  • kubernetes 집단 내의 자원과 무관한 도량
  • 그래서 이번에는 Object를 설정해야 합니다.describedObject에 음향 도량과 관련된 자원을 설정하고 metric에 도량 이름을 지정한다.target에서 측정 값을 기준으로 Pod 수를 증감하는 방법을 지정합니다.여기에는 ValueAverageValue 두 가지 지정 방법이 있습니다.
    양자는 양도치가 설정치보다 클 때 Pod를 증가하고 설정치보다 일정치가 낮을 때 Pod를 줄인다는 점에서 같다Value는 양도 API에서 얻은 값과 설정치를 직접 비교한다.AverageValue 메트릭 API에서 얻은 값이 현재 Pod 수로 나눈 값과 설정된 값을 비교하는 점에서 다릅니다.따라서 Pod 수 증가에 따라 감소한 값(99 Percentile duration 등)을 도량치Value로 사용하면 Pod 수와 무관한 값(서비스의 Requests count 등에 대한)을 도량치AverageValue로 사용하는 것이 적절하다.
    Object metrics support target types of both Value and AverageValue. With Value, the target is compared directly to the returned metric from the API. With AverageValue, the value returned from the custom metrics API is divided by the number of Pods before being compared to the target.
    https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/#autoscaling-on-multiple-metrics-and-custom-metrics

    Argo CD 사용 시 고려 사항


    deployment 등의 Replicas 지정 무시


    HPA 대상의 deployment 등에 있는replicas 설정값에 따라 개작되지만, Argo CD가 관리하면 원래 deployment는 OutOfSync로 바뀐다.이것은 아래 설정ignoreDifferences을 통해 피할 수 있다.
    ignoreDifferences:
      - group: apps
        kind: Deployment
        name: deployment1
        namespace: ns1
        jsonPointers:
        - /spec/replicas
    

    HPA 리소스가 항상 OutOfSync의 문제가 됨


    HPA Controller가 HPA 선언문을 새로 작성했기 때문에 Argo CD에 OutOfSync 문제가 자주 보고됩니다이쪽 isse..회답을 사용할 때 스펙트럼.metrics의 순서(memory가 먼저 cpu가 된 후)를 바꾸어 피할 수 있습니다.
    For Horizontal Pod Autoscaling (HPA) objects, the HPA controller is known to reorder spec.metrics in a specific order. See kubernetes issue #74099. To work around this, you can order spec.metrics in Git in the same order that the controller prefers.
    https://argoproj.github.io/argo-cd/user-guide/diffing/#diffing-customization
    하지만 음향 측정을 사용한 상황에서 스펙트럼.metrics는object.target.value는 HPA Controller에 의해 삽입되기 때문에 아래의 양수로 설정해야 합니다.이것에 관해서는 그다지 정보를 찾지 못했다.
    apiVersion: autoscaling/v2beta2
    kind: HorizontalPodAutoscaler
    metadata:
      name: hpa1
      namespace: ns1
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: deployment1
      minReplicas: 1
      maxReplicas: 10
      metrics:
      - type: Object
        object:
          describedObject:
            apiVersion: v1
            kind: Service
            name: svc1
          metric:
            name: requests_per_second
          target:
            type: AverageValue
            averageValue: 5
            value: 1  # HPA Controller によって自動的に差し込まれ、OutOfSyncとなるのを防ぐ設定
    

    HPA의 동작 확인


    이상에서 HPA를 설정할 수 있으므로 다음 명령을 통해 동작 상태를 확인할 수 있다.
    $ kubectl get hpa.v2beta2.autoscaling hpa1 -n ns1 -o yaml
    
    ...
    status:
      conditions:
        - lastTransitionTime: '2021-02-04T06:45:53Z'
          message: recommended size matches current size
          reason: ReadyForNewScale
          status: 'True'
          type: AbleToScale
        - lastTransitionTime: '2021-02-09T01:00:33Z'
          message: >-
            the HPA was able to successfully calculate a replica count from external
            metric requests_per_second(nil)
          reason: ValidMetricFound
          status: 'True'
          type: ScalingActive
        - lastTransitionTime: '2021-02-09T11:58:49Z'
          message: the desired replica count is less than the minimum replica count
          reason: TooFewReplicas
          status: 'True'
          type: ScalingLimited
      currentMetrics:
        - object:
            current:
              averageValue: 389m
              value: '0'
            describedObject:
              kind: ''
              name: ''
            metric:
              name: requests_per_second
          type: Object
      currentReplicas: 1
      desiredReplicas: 1
    

    끝말

    autoscaling/v2beta2 API에서 제공하는 등급별 연결 도량을 바탕으로 하는 HPA에 대해 우리는 Istioistio_requests_total를 이용하여 HPA를 이동하는 예를 설명하였다.또한 데이터독과 합작할 수 있어 자유도가 높고 편리한 시스템이므로 반드시 사용하시기 바랍니다.

    참고 문헌


    Horizontal Pod Autoscaler Walkthrough
    Horizontal Pod Autoscaler
    Horizontal Pod Autoscaler with Arbitrary Metrics
    Promeetheus Adapter를 사용한 Pod의 자동 배율

    좋은 웹페이지 즐겨찾기