AWS EKS MetricsServer + VPA + CAS 설정하기

Kubernetes Solutions | Deployment + Service(kind: LoadBalancer)
이민석's avatar
Jun 26, 2024
AWS EKS MetricsServer + VPA + CAS 설정하기

이 문서는 AWS EKS Cluster AutoScaler 도입과 관련한 문서입니다.
다수의 글을 참고하여 AWS EKS Cluster에 AutoScaler를 적용하기 위한 A to Z 설정법을 다루고 있습니다.

개요

이 문서에서는 단순하게 배포되어 있는 K8S 환경에 확장성을 더하는 법을 배우게 될 것입니다. 이 문서에서 저희는 NGINX를 확장성 있게 배포하기 위해 다음의 3가지 차트를 사용하게 됩니다.

  1. Metrics Server / metrics-server/metrics-server

  2. VPC Controller / autoscaler/vertical-pod-autoscaler

  3. CAS / cluster-autoscaler-

Metrics

K8s에서 다양항 Pod 확장 전략을 선택하기 위해서는 참고할 지표(Metric)이 필요합니다.

이번 장에서는 Metric이 필요한 이유부터 실제로 Metrics 수집 도구인 metrics-server를 사용해서 지표를 수집하는 방법을 알아봅니다.

  1. Metrics Server 필요한 이유

  2. Metrics Addons 비교

  3. Metrics Server 설치하기

Metrics 필요한 이유

Metrics Server는 2가지 역할을 합니다.

  1. HPA(Horizontal Pod Autoscaler)가 Pod를 스케일 인, 아웃 처리하기 위한 파드 매트릭 수집

  2. kubectl top 명령어를 수행하기 위한 노드 매트릭 수집

EKS Cluster에서 kubectl top 명령어를 사용하면 아래와 같은 오류가 발생합니다.

$ kubectl top node
error: Metrics API not available
$ kubectl top pod
error : Metrics API not available

이 경우, EKS 클러스터에 metrics-server 가 미설치된 상태라 메트릭을 수집할 수 없어서 발생하는 문제입니다.

— younsl (blog) | metrics-server helm chart

Metrics Addons 비교

Metrics Server 역할을 할 수 있는 애드온은 2가지가 존재합니다.

  1. kube-state-metrics / 모든 k8s object에 대한 정보 수집

  2. metrics-server / resource metrics api 등의 제한적인 범위만 수집

Metrics Server 설치하기

  1. Helm Repository 추가하기

    $ helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
    $ helm repo list
    $ helm repo update
  2. Helm Pakcage 가져오기

    $ helm pull metrics-server/metrics-server
  3. values.yaml 파일 작성하기

    # PrivateECR 권장
    image:
      repository: registry.k8s.io/metrics-server/metrics-server
      tag: ""
      pullPolicy: IfNotPresent
    
    # HA
    replicas: 2
    
    imagePullSecrets: []
    
    nameOverride: ""
    fullnameOverride: ""
    
    serviceAccount:
      create: true
      annotations: {}
      name: ""
      secrets: []
    
    rbac:
      create: true
      pspEnabled: false
    
    apiService:
      create: true
      annotations: {]
      insecureSkipTLSVerify: true
      caBundle: ""
    
    commonLables: {}
    podLabels: {}
    podAnnotations: {}
    
    podSecurityContext: {}
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      runAsUser: 1000
    
    priorityClassName: system-cluster-critical
    
    containerPort: 10250
    
    hostNetwork:
      enabled: false
    
    updateStrategy: {}
    
    podDisruptionBudget:
      # https://kubernetes.io/docs/tasks/run-application/configure-pdb/
      enabled: false
      minAvailable:
      maxUnavailable:
    
    defaultArgs:
      - --cert-dir=/tmp
      - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
      - --kubelet-use-node-status-port
      - --metric-resolution=15s
    
    args: []
    
    livenessProbe:
      httpGet:
        path: /livez
        port: https
        scheme: HTTPS
      initialDelaySeconds: 0
      periodSeconds: 10
      failureThreshold: 3
    
    readinessProbe:
      httpGet:
        path: /readyz
        port: https
        scheme: HTTPS
      initialDelaySeconds: 20
      periodSeconds: 10
      failureThreshold: 3
    
    service:
      type: ClusterIP
      port: 443
      annotations: {}
      labels: {}
    
    addonResizer:
      enabled: false
      image:
        repository: registry.k8s.io/autoscaling/addon-resizer
        tag: 1.8.14
      resources:
        limits:
          cpu: 40m
          memory: 25Mi
        requests:
          cpu: 40m
          memory: 25Mi
      nanny:
        cpu: 20m
        extraCpu: 1m
        extraMemory: 2Mi
        memory: 15Mi
        minClusterSize: 10
        pollPeriod: 300000
        threshold: 5
    
    metrics:
      enabled: false
    
    serviceMonitor:
      enabled: false
      additionalLabels: {}
      interval: 1m
      scrapeTimeout: 10s
      metricRelabelings: []
      relabelings: []
    
    # See https://github.com/kubernetes-sigs/metrics-server#scaling
    resources: {}
    
    extraVolumeMounts: []
    
    extraVolumes: []
    
    nodeSelector: {}
    
    tolerations: []
    
    affinity: {}
    
    topologySpreadConstraints: []
    
    # Annotations to add to the deployment
    deploymentAnnotations: {}
    
    schedulerName: ""
    
    
  4. Metrics Server Relaese 하기

    helm update                                              \
      --install metrics-server metrics-server/metrics-server \
      --namespace kube-system                                \
      --values. values.yaml                                  \
      --wait
  5. Metrics Server Release 체크하기

    helm status metrics-server -n kube-system
  6. Metirc Server Pods 체크하기

    kubectl get all                                \
      -l app.kubernetes.io/instance=metrics-server \
      -n kube-system

Pod Scaler

  1. Pod Scaler가 필요한 이유

  2. Pod Scaler의 종류

  3. Pod Scaler 별 사용 사례 및 분석

  4. HPA 설치하기…

  5. VPA, KEDA

Pod Scaler가 필요한 이유

사용자 활동에 따라서 Pod를 늘렸다가 줄였다가 하는 것은 비효율적입니다.

따라서 이를 자동으로 늘어나고 줄어들게 하는 것이 바로 Pod Scaler입니다.

Pod Scaler의 종류

Pod Scaler는 크게 다음의 3가지가 존재합니다.

  1. HPA(Horizontal Pod Autoscaler)/ 지표에 따라서 pods의 수량 조절

  2. VPA(Vertical Pod Autoscaler) / 지표에 따라서 pods의 CPU, MEM 등 제한 조절

  3. KEDA(Kubernetes Event Driven Autoscaler) / 이벤트 기반으로 HPA+VPA수행

Pod Scaler 별 사용 사례 및 특징 분석

구분

HPA

VPA

KEDA

방향

수평

수직

수평/수직

트리거

리소스 활용 지표

리소스 활용도 측정

외부/내부 트리거 기반

사용 사례

애플리케이션 로드 또는 트래픽 패턴 변화 처리

과잉 프로비저닝 방지를 위해서 리소스 활용도 최적화

이벤트(SQS, HTTP Reqeust) 기반

복잡성

간단한

복잡험

매우 복잡함

지원되는 워크로드

Stateless Workload

All kind of Workload

Stateless/Stateful
Workload

K8s 리소스 통합

Deployment, ReplicaSet, StatefulSet

Deployment,
ReplicaSet,
DaemonSet

+

도구

metrics-server ++

metrics-server와 VPA 내부 요소와 통합

KEDA Controller & EventSource 필요

HPA 설치하기…

기존에 서비스를 배포하기 위해서 작성한 Helm Chart안에 조건부로 HPA를 활성화하는 항목을 추가하면, 이를 바로 사용할 수 있을 것 같습니다.

Manifest 파일이므로 간단한 설명이나 감 정도만 잡는데 사용할 것입니다.

— SpectroCloud (Blog) | Kubernetes autoscaling patterns: HPA, VPA and KEDA

  1. HPA 설치하기

    apiVersion: autoscaling/v2
    
    kind: HorizontalPodAutoscaler
    metadata:
      name: <APP_NAME>
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
         kind: Deployment
         name: <APP_NAME>
      minReplicas: 2
      maxReplicas: 10
      metrics:
        - type: Resource
          resource:
            name: cpu
            target:
              type: Utilization
              averageUtilization: 50
  2. HPA 부하 테스트하기

    kubectl expoase deployment <APP_NAME> \
      --port=80                           \
      --type=ClusterIP                    \
      --name=nginx-service
    
    kubectl run              \
      --it                   \
      --rm load-generator    \
      --image=busybox /bin/sh
    
    while true; do wget -q -O- http://nginx-service:80; done
  3. HPA 모니터링

    kubectl get hpa
    kubectl get deployment <APP_NAME>

VPA,KEDA

VPA, KEDA는 별도 문서에서 다루겠습니다.

Node Scaler

  1. Node Scaler가 필요한 이유

  2. Node Scaler의 종류

  3. CAS(Cluster AutoScaler) 설치하기

Node Scaler가 필요한 이유

Pod Scaler를 통해서 확장성을 갖추더라도 근본적으로 Node의 수량은 변하지 않습니다.

따라서 Node의 수량을 늘리고 줄일 수 있는 Node Scaler가 필요합니다.

이를 통해서 다음과 같은 이점을 누릴 수 있습니다.

  1. 자동 확장 및 축소

  2. 비용 효율성

  3. 성능 유지

Node Scaler의 종류

Node Scaler에는 다음과 같이 2가지 종류가 존재합니다.

  1. AWS CAS(Cluster Autoscaler)

  2. Karpenter

이 중에서 더 고도화되고 빠른 확장성을 자랑하는 것은 Karpenter입니다.

하지만 이 문서에서는 AWS CAS(Cluster Autoscaler)를 다룰 예정입니다.

CAS(Cluster AutoScaler) 설치하기

  1. AWS CAS Repository 등록하기

    $ helm repo add autoscaler https://kubernetes.github.io/autoscaler
    $ helm repo update autoscaler
  2. AWS CAS Helm Chart Package 가져오기

    $ helm pull autoscaler/cluster-autoscaler
  3. values-dev.yaml 수정하기
    # https://github.com/terraform-aws-modules/terraform-aws-eks/issues/801#issuecomment-696733518

    clusterName: <CLUSTER_NAME>
    nodeSelector: <NODE_SELECTOR>
    awsRegion: <AWS_REGION>
    rbac:
      serviceAccount:
        name: cluster-autosclaer
        annotations:
          # IRSA Options add...
  4. AWS CAS Helm Chart Release 하기

    $ helm upgrade cluster-autoscaler autoscaler/cluster-autoscaler \
        --install -f values.yaml \
        --namespace kube-system
    
    $ helm upgrade cluster-autoscaler autoscaler/cluster-autoscaler \
        --f values.yaml \
        --namespace kube-system

참고 자료

  1. metrics-server

    1. younsl (Blog) | metrics-server helm

    2. kubernetes-sigs/metrics-server (GitHub) | main

    3. kubernetes-sigs/metrics-server (GitHub) / charts/metrics-server/values.yaml

    4. kubenetes-sigs/metrics-server (GitHub) | Differences between metrics-server repo and kube-state-metrics repo

  2. pod scaler (hpa, vpa, keda)

    1. Spectrocloud (Blog) | Kubernetes autoscaling patterns: HPA, VPA and KEDA

    2. 악분의 블로그 (Blog) | EKS 스터디 - 5주차 1편 - VPA

  3. node scaler (cas, karpenter)

    1. Devocean (Blog) | [AWS EKS-연재5] AWS EKS의 Cluster AutoScaler 설정

    2. ArtifactHUB (Blog) | cluster-autoscaler

    3. aws/eks-charts (GitHub) | [EKS 애드온 #2] Cluster AutoScaler Helm으로 설치하기

Share article

Unchaptered