Tech

숨고의 Karpenter 도입기

숨고의 AWS Warmpool 적용 이후, 알게된 것들과 개선을 위한 Actions

2024-04-02 Lyon Yi

Intro

안녕하세요. 숨고 DevOps Chapter에서 DevOps Engineer로 일하고 있는 Lyon입니다. 숨고의 안정적인 인프라와 트래픽을 만들고 건강한 개발 문화를 가져오기 위해 노력하고 있습니다.

이번 포스팅에서는 숨고에서 도입했던 'AWS Warm Pool'의 적용 이후 발견한 문제들을 개선하기 위한 여정에 대해 공유하고자 합니다.

운영 환경의 시스템 리소스 업그레이드 같은 Critical 한 작업이 발생하는 경우 DevOps가 작업에 참여하곤 하는데, 이와 같은 작업들이 발생하면 집중 모니터링 시간을 가지고자 노력하고 있습니다. 이 과정에서 AWS Warm Pool을 도입한 이후에 발생한 문제점을 포착할 수 있었습니다.



문제 발견과 해결 방안 탐색


발견한 문제점

이번에 발견한 문제점은 모니터링 도중에 “POD가 Ready 되는 데까지 왜 이렇게 오래 걸리지?”라는 점이었고, 기존 히스토리를 모르던 저는 숨고에서 적용한 AWS WarmPool에 대한 히스토리 파악부터 현재 상황까지 진단해 보았습니다. 그 결과 아쉽게도 유동적인 트래픽을 유연하게 대응하기 위한 대책은 방비되어 있지 않았습니다. 그 이유는 숨고에서 적용하여 사용 중이던 WarmPool을 Disabled 한 상태였기 때문이었습니다.

그래서 저는 WarmPool을 Disabled 하게 된 이유들과 어떤 문제점이 있었는지를 하나의 Objective로 잡고 이를 파헤치는 시간을 가졌습니다.


문제 해결을 위한 목표 설정

이번 문제를 해결하기 위해 DevOps. Chapter에서는 WarmPool 적용 이후 운영에서 발견된 문제점이나 Needs가 될 요소가 있었는지를 파악하고 개선을 위한 Kubernetes Cluster Autoscaling 방식을 검토하는 것으로 방향성을 잡았습니다.

현재 숨고에서는 WarmPool을 사용하고 있지 않습니다. 가장 큰 이유는 WarmPool로 생성된 노드가 Ready 된 후, 해당 노드에 POD가 생성되고, 종료될 때 POD가 Terminating 상태에서 벗어나지 못하여 노드가 스케줄링되지 못해 확장된 상태로 유지되는 문제가 있었기 때문입니다.

이는 안정성 및 신뢰성과 관리 측면에서 마이너스 요소로 판단되어 WarmPool을 Disabled 하게 되는 결과를 가져오게 되었습니다. 그 외의 다른 문제점들은 EKS 버전 업그레이드 시 WarmPool을 해제하고 업그레이드해야 하는 번거로움이 있었고, WarmPool의 노드 확보와 CAS(Cluster Autoscaler)의 노드 스케일 아웃이 동시에 발생하게 되었을 때 노드 생성 시간이 더 오래 걸리는 현상을 발견하게 되었습니다.


문제 해결을 위한 해결 방안 탐색

저는 노드 관리를 위한 쿠버네티스 오토스케일링 (Kubernetes Autoscaling) 방식들의 비교 및 분석을 진행하고자 하였습니다.

NetApp의 Spot.io을 사용해 본 경험이 있는 저는 Spot.io의 헤드룸에 대해 어느 정도 알고 있었고 노드그룹에서 다양한 인스턴스 타입을 사용하고 싶다거나, Spot Instance를 적용하여 비용 효율적인 운영구조를 갖추고자 하는 등의 Needs가 있어 보다 적극적으로 분석하는 자세에 임할 수 있었습니다.

Difference comparison analysis of Kubernetes Autoscaling

image

숨고의 개발용 클러스터를 기준으로 아래 3가지 유형의 클러스터 오토 스케일링의 특징과 장단점을 비교해 보았습니다.

  1. CAS(Cluster AutoScaling)와 WarmPool
  2. Karpenter
  3. Ocean Controller
비교 항목 CAS(Cluster AutoScaling) + Warmpool Karpenter Ocean Controller
특징 ASG 사용 자체 컨트롤러 사용 Spot 자체 VNG 사용
장점 • AWS 콘솔에서 간단하게 적용 가능 • Group-less 노드 프로비저닝 가능 (노드 그룹별 설정가능)
• 프로비저너 별 상세 설정 가능(노드 그룹별 설정 가능)
• 빠른 노드 생성 속도(직접 EC2의 인스턴스를 생성하여 노드를 프로비저닝하는 방식)
• node group의 인스턴스 유형과 상관 없이 해당 node group에 여러 인스턴스 유형을 추가 가능
• 직접적인 관리 불필요
단점 • ASG의 버그로 인해 웜풀 생성 과정이 매끄럽지 않음
• (issue message: You can't add a warm pool to an Auto Scaling group that has a mixed instances policy or a launch template or launch configuration that requests Spot Instances)
• Warm Pool에서 확보되지 않은 인스턴스의 스케일 아웃은 Warm Pool 미적용 기준 시간으로 봐야 함
• 최신 기술로 인한 별도의 학습 필요 • 절감 효과에 따른 수수료 발생
노드 생성 시간 • Warm Pool 미적용 시 약 40~ 50s 소요
• Warmpool 적용 시 약 30~40s 소요
• 약 30~40s 소요 • 판단 불가
• Headroom 설정을 통한 프로비저닝 비율 설정 가능
비용 최적화 • Warm Pool 적용 시 - Spot Instance 사용 불가
• 지정한 NodeGroup의 인스턴스 타입을 사용하여 POD의 Resources에 따른 선택 불가
• Spot Instance 비율 설정 가능
• POD의 Resources에 맞게 설정한 인스턴스 타입 내 가장 최적의 노드를 생성
• Only Spot Instance
장애 조치(Spot) • Spot 생성 불가 • Spot 용량이 부족하면 On-demand로 생성 가능 • 보장되어야 하는 POD는 PDB 사용 필요
노드 스케일 인 • On-demand 가능
• Spot 불가능
• 노드그룹별 스케일다운 시간 설정 불가능
• On-demand 가능
• Spot 설정에 따른 방법 가능
• 노드그룹별 스케일 다운 시간 및 지속적 통합 설정 가능
• 일정 주기에 대한 문의 필요
Spot 비율 조정 • 불가 • 가능
• capacity-spread와 weight 옵션으로 유연하게 조정 가능
• Only Spot Instance
운영 관점 고려 사항 • AWS에서 관리 • DevOps에서 관리
• CAS에서 마이그레이션
http://spot.io/ 콘솔에서 관리
• CAS에서 마이그레이션

정리한 자료를 통해 DevOps 구성원이 한자리에 모여 논의하는 시간을 통해 인프라의 확장성과 다양한 상황 속에서 유연한 대응이 가능한 환경을 고려해 애플리케이션 가용성 향상, 컴퓨팅 비용 절감 그리고 운영 오버헤드 최소화라는 특징을 가진 Karpenter를 도입해 보기로 결정하였습니다.



Karpenter 도입 여정기


Karpenter 작동 방식

'Just-in-time Nodes for Any Kubernetes Cluster’

image


Step 1. Karpenter 도입에 따른 우선순위와 목표 설정

Karpenter 도입 결정에 따라 우선적으로 주제와 목적을 도출하고 목표를 설정하였습니다.

주제: 노드 오토 스케일링 성능 개선과 안정성 확보를 위한 목표 설정

  • 목표 1. WarmPool에서의 문제점과 운영 상의 이슈를 고려해 CAS에서 Karpenter로 마이그레이션하여 운영의 오버헤드를 최소화한다.

  • 목표 2. 노드 오토스케일링 환경을 개선하여 노드 생성 시간을 감소시키고 이로 인한 트래픽 증가로부터 HPA가 유연하고 빠르게 작동할 수 있는 환경을 조성한다.

  • 목표 3. 리소스의 스펙에 맞는 적절한 노드를 생성함과 동시에 리소스의 요구사항 변화에 신속하고 자동으로 대응하는 유연한 워크 로드 운영을 확보함으로써 애플리케이션의 가용성을 향상시킨다.

  • 목표 4. 목적별 활용 가능한 노드를 유연하게 조정하며 저렴하고 효과적인 대안의 노드로 지속적인 교체를 통해 워크 로드를 효율적인 컴퓨팅 리소스로 통합하여 클러스터 컴퓨팅 비용을 절감한다.

목표 설정 후 CAS에서 Karpenter로 마이그레이션을 하며 Karpenter의 여러 기능들을 테스트하기 위한 작업을 진행하였습니다. 그리고 Karpenter의 Documents를 보며 기능적 이해도를 높여가는 시간을 가졌고 의문점들을 한곳에 모아 Karpenter 도입을 위한 검증 체크리스트를 작성하였습니다.


Step 2. Karpenter Validate CheckList

(1) Karpenter Provisioner를 적용하기 이전에, ASG에서 관리하던 노드에 대한 처리 가능 여부

  • Karpenter의 Provisioner로 생성되지 않은 노드는 별도의 관리가 필요함.
  • 이를 위해 ASG의 Desired size를 점진적으로 조정하여 Karpenter Provisioner 관리체계 노드로 마이그레이션이 필요함.
  • 또한 워크 로드의 유실을 방지하기 위해 Live Service의 구성 POD 요소들에 대해 PDB(Pod Disruption Budget)를 설정 후 마이그레이션 하는 것이 권장됨.

(2) Group-less node provisioning 컨셉을 가진 Karpenter의 Group node provisioning 가능 여부

  • Service를 위한 NodeGroup, System NodeGroup 등의 목적성에 따른 관리가 필요함. 이를 위해 적절한 taints and tolerations, affinity and nodeSelector 활용을 위한 선택을 목적으로 Group node provisioning이 유의미할 수 있음.

  • Provisioner의 설정으로 NodeSelector 등 노드의 Taints 설정이 가능함

(3) NodeGroup의 AWS 시작 템플릿의 필요 여부

  • Provisioner는 별도의 설정을 하지 않으면 클러스터의 Kubernetes 현재 버전의 latest ami로 자동 반영되어 Node를 생성함.

(4) NodeGroup의 Desired size를 0으로 변경 시 해당 NodeGroup에서 노드를 생성 할 수 있는지의 여부

  • 가능. Provisioner가 노드의 관리를 하기 때문에 Desired size의 영향을 받지 않음.

(5) Scale In, Out에 대한 문제 발생 가능성

  • 개발용 클러스터에 적용 이후 현재까지 아무런 문제 없이 정상적인 스케일인, 아웃이 되고 있고, 속도가 CAS에 비해 상대적으로 개선된 것 역시 확인 가능함.
  • CAS(Cluster Autoscaling): 약 48초
  • Karpenter: 약 37초
  • CAS 대비 약 20~25% 수준의 효과

(6) 소유권(Ownership)과 종료자(Finalizer)에 대한 설정 필요 여부

  • 노드가 Ownership과 Finalizer가 지정된 채로 생성되며, NTH(Node Termination Handler) 노드 종료 핸들러를 별도로 사용할 필요는 없음.

(7) 교체를 위한 Renaming 등 모종의 이유로 Provisioner를 삭제할 경우 처리 방안

  • Provisioner가 관리하던 노드가 일괄 종료됨.
  • 또한 Provisioner renaming 시에는 ttlSecondsUntilExpired 값을 조정하여 새로운 Provisioner에 이동되도록 하는 것이 안전함.

(8) NodeGroup의 Max size 지정 가능 여부

  • Karpenter의 컨셉 상 Size에 대한 개념은 없으나 Provisioner에 Limits cpu, memory 설정을 통해 인스턴스 생성을 제한 할 수 있음.
  • 그러므로 적절하게 특정 NodeGroup에서 사용할 Resources를 산정하여 관리하는 것이 바람직 하다고 판단됨.

(9) 싱글 클러스터 업그레이드 방식의 EKS 버전 업그레이드를 진행했을 때의 노드 버전 관리 방법

  • Kubernetes 버전이 업그레이드되면 Karpenter가 Kubernetes 버전에 맞는 노드의 버전으로 Drift 함.
  • 원활한 노드 Drift를 위해 이전 버전의 노드를 Cordon 설정하여 노드를 스케줄러에서 제외해 파드가 할당되지 않도록 해야 할 필요가 있음.

(10) Spot Instance에 대한 사용 방법

  • karpenter.sh/capacity-type에 spot을 등록하여 사용 가능함.
  • 예시: karpenter.sh/capacity-type: [spot]
  • on-demand와 같이 사용할 경우 capacity-spread의 배열 수로 설정하여 비율 조정 가능함.
    1 key: karpenter.sh/capacity-type
    2 operator: In
    3 values: [ on-demand ]
    4 key: karpenter.sh/capacity-spread
    5 operator: In
    6 values: [ "on-demand-1", "on-demand-2" ]
    7 ---
    8 key: karpenter.sh/capacity-type
    9 operator: In
    10 values: [ spot ]
    11 key: karpenter.sh/capacity-spread
    12 operator: In
    13 values: [ "spot-1", "spot-2", "spot-3" ]
    

(11) CAS에서의 전환 전략

  • Karpenter Policy 설정 및 Role 등록 과정과 Cluster의 Subnet과 SG에 Karpenter managing을 위한 Tagging을 포함하여 적용하고자 하는 Cluster에 Karpenter를 위한 Role 설정이 필요함.
  • Karpenter의 효율적인 Manifest 구조를 위한 선택으로 Helm으로만 제공되고 있는 Karpenter를 yaml로 변경하고 Kustomize 화 하였음.
  • 그리고 주요 항목 중 aws-node-templates는 기본적으로 subnet, sg, volume(default, ebs20, ebs50 ..)를 지정하고 그 외 필요한 사항에 대해 설정하여 활용하였고 목적별 노드그룹 매핑 구조(Services, CI/CD, System …)를 가진 Provisioner를 구성하여 Karpenter의 체계적인 구조를 완성함.

(12) Karpenter won’t launch capacity to run itself (log related to the karpenter.sh/provisioner-name DoesNotExist requirement) so it can’t provision for the second Karpenter pod.

  • Karpenter 자기 자신은 실행 용량을 체크하지 않음.
  • Karpenter의 노드 확보를 위한 별도의 NodeGroup을 사이즈에 맞도록 설정하여 Karpenter Deployment를 확보함.

체크리스트를 작성하며 테스트한 결과, CAS에서 Karpenter로 Migration 하는 것이 업무 효율성 측면에서 가장 큰 임팩트를 가져올 것이라 판단하였습니다. 대표적으로는 서비스의 특성에 따라 Spot Instance 사용, Instance Size 변경 등의 작업이 굉장히 편리해진다는 것이 있습니다.

검증된 결과를 토대로 숨고에서 마이그레이션하기 위한 시나리오를 작성하였고 신중하게 작업을 시작하였습니다.


Step3. Soomgo Cluster Karpenter Migrating from Cluster Autoscaler

image

This guide will show you how to switch from the Kubernetes Cluster Autoscaler to Karpenter for automatic node provisioning.

  • We will make the following assumptions in this guide.
  • You will use an existing EKS cluster.
  • You will use existing VPC and subnets.
  • You will use existing security groups.
  • Your nodes are part of one or more node groups.
  • Your workloads have pod disruption budgets that adhere to EKS best practices.
  • Your cluster has an OIDC provider for service accounts.
    This guide will also assume you have the aws CLI installed. You can also perform many of these steps in the console, but we will use the command line for simplicity. Migrating from Cluster Autoscaler

해당 가이드를 따라 진행하기 위한 시나리오를 작성하였고, 수월하게 Migration을 할 수 있었습니다.

Migration Scenario

(1) AWS Karpenter Policy & Role

  • KarpenterControllerRole
  • KarpenterNodeRole

(2) AWS EKS Cluster SG tagging

  • EKS connected SecurityGroup

(3) Added mapRoles - aws-auth.yaml

1 - groups:
2  - system:bootstrappers
3  - system:nodes
4  rolearn: arn:aws:iam::XXXXXXXXXXXX:role/KarpenterNodeRole-soomgo-cluster-xxxx
5  username: system:node:{{EC2PrivateDNSName}}

(4) Provisioner NodeGroup values per EKS NodeGroup

(5) AWSNodeTemplates SG

(6) AWSNodeTemplate with EBS size to use to provisioner providerRef

(7) Karpenter NodeGroup

(8) Create Karpenter

(9) Remove CAS(Cluster Autoscaler) replicas = 0

(10) NodeGroups desired size down

  • 10% - Obtain nodes created with Karpenter Provisioner
  • Check HPA, Deployment, PDB of Pod with min replicas of 1

(11) Verify Karpenter

  • Karpenter Node Scale-In Monitoring


Step 4. Troubleshooting

시나리오에 따라 작업을 진행하면서 발생했던 이슈들을 라이징하며 트러블슈팅 문서를 작성하였습니다.

Issue1. Karpenter는 권장 보안 모범 사례를 준수하여 기본값으로 IMDSv2 방식이 적용되어 있음

이로 인해 기존의 서비스들(apigateway, gateway-proxy ... 등)에서 권한을 취득 받지 못하여 CrashLoopBackOff이 지속적으로 발생하였습니다. IMDSv2 방식은 일시적인 Token 값을 받아와서 해당 Token 값으로 Metadata를 조회할 수 있게 만든 방식입니다. 해당 문제를 임시로 조치하기 위해 AWSNodeTemplate의 Spec을 업데이트를 진행하였고, 이후 권장 보안 모범 사례를 준수하기 위한 작업을 준비하였습니다.

1 metadataOptions:
2     httpTokens: optional


Issue2. 적용 후 Karpenter controller log에서 지속적으로 에러메시지 발생

TLS handshake error from xx: read tcp xx -> xx: read: connection reset by peer · Issue #718 · kubernetes-sigs/karpenter

Karpenter pod log를 보면 'webhook TLS handshake error'가 주기적으로 발생하는데, Karpenter가 동작하는 것에는 문제없다는 것을 확인하였습니다. karpenter-cert secret을 삭제하면 해당 에러 메시지가 발생하지 않을 수 있으나 성능 및 중요한 문제와 연관이 없으므로 현 상태를 유지하도록 하였습니다.

Issue3. Spot Instance disruption event occurs

스테이징의 서비스 불안정 상태가 발생하였고 이후 추가 발생으로 원인 분석 시작하였습니다. Replicas가 1인 POD의 노드가 Interruption 대상이 되는 문제 발견하였고 Karpenter가 해당 Event를 체크하여 스케일링할 수 있도록 설정하였습니다.


Step 5. Retrospective

Karpenter를 적용한 이후 여러 시간 동안 운영하며 부족했던 점들을 보완하고자 하였고 어떤 효과를 보았는지 점검하는 시간을 가졌습니다.

부족했던 부분에 대한 고찰

Karpenter 도입 목표 중 4번째 목표였던 ‘목적별 활용 가능한 노드를 유연하게 조정하며 저렴하고 효과적인 대안의 노드로 지속적인 교체를 통해 워크 로드를 효율적인 컴퓨팅 리소스로 통합하여 클러스터 컴퓨팅 비용을 절감한다.’는 부분에서 비용 증가라는 역효과를 경험하게 되었습니다.

뒤늦게 문제를 발견한 이유

아래와 같이 다섯 가지의 이유를 알게되었습니다.

  • Staging과 Test 환경에서의 Spot Instance 적용 테스트를 위한 작업에 집중하여 주기적으로 비용을 체크하지 못하였습니다.

  • 적용 후 모니터링을 하였고 비용이 증가한 것은 보았으나 일일 기준으로 큰 수치가 아니었고 단순 트래픽의 영향이라고 오판단 하였습니다.

  • 주말에는 Staging을 사용하지 않아 증가된 비용 지표가 드러났지만 대수롭지 않게 여겼습니다. 또한 노드의 리소스 커버리지를 측정하지 않았습니다.

  • POD가 모두 정상이며 Node의 수가 예상 범주 내였고 비용이 증가하지만 않으면 된다고 생각하였습니다.

  • 적용 후 기대효과를 위해 목표를 설정하였지만 중점적으로 보았던 것은 Warmpool의 문제점과 노드 생성 시간속도 개선이었기 때문에 비용적으로 소홀히 대했던 부분이 있었습니다.

비용 증가 원인

원인 1. 서비스 노드의 오염 격리를 위한 Taints 추가

노드에 여유 용량이 있을 경우 기존에는 서비스 노드 그룹에서도 사용되었지만 Taints 적용 이후 빈 용량을 사용하는 만큼의 POD가 새로운 노드를 생성하고 있었습니다. 기존에는 CAS에서 HPA를 통한 POD replicas, 상태 체크를 통해 자동으로 노드 확장 감소가 이루어지며 인스턴스 유형에 알맞은 리소스로 어느 정도 효율적인 노드 리소스 활용이 가능하였습니다.

하지만 Karpenter로 전환하면서 특정 서비스를 Rolling Update 했을 때 순간적으로 과도하게 확장된 POD로 인해 노드가 약 2배로 증가하였고 Rolling Update 완료 후 늘어난 노드 수만큼 종료된 것이 아니라 POD 2~3개가 들어갈 만큼의 노드 사이즈에 1개의 POD만 들어있는 상태가 발생하여 매주 진행하는 배포의 영향으로 과도한 확장 상태가 된 노드들로 인해 추가 비용이 발생하게 되었습니다.

이는 Test 환경에서 Consolidation의 검증 과정 도중 1개만 존재해야 하는 POD의 노드가 Termination 대상이 되면서 준비된 POD가 순간적으로 사라져 에러가 발생했고 Consolidation과 Karpenter 초기 도입과 맞물린 이해도 부족으로 미사용 결정을 내렸던 것이 비용 증가를 가져온 하나의 Reason이었던 것으로 판단하고 있습니다.

원인 2. CoreDNS의 지속적인 Failed drain으로 노드가 과도하게 확장된 상태로 유지

CoreDNS의 기본 affinity 설정으로 인해 CoreDNS를 포함하고 있는 노드가 스케줄링 되지 않는 문제가 발생하였습니다.

해결 방안

세 가지 방법을 토대로 문제를 해결할 수 있었습니다. 첫 번째로 Taints는 추후 ARM으로 전환해야 하는 조직의 목표에서 필요한 과정이기에 다시 빼는 것은 하지 않도록 하였습니다. 그리고 두 번째 방법으로 중복 이벤트 발생의 우려가 있는 POD들이 Karpenter의 자의적인 이벤트로 Termination 대상이 되지 않도록 설정하였습니다. 기본적으로 모든 API, TASK는 PDB가 설정되어 있지만 Karpenter의 유연한 스케일링을 위해 available이 아닌 maxUnavailable: 1로 설정해두었고, 1개만 존재하는 POD들은 maxUnavailable: 1의 영향을 받지 않아 종료 대상이 되면 POD의 Ready 상태가 보장되지 않았습니다. 그래서 Karpenter의 do-not-evict 어노테이션을 적용하고 고유성을 보장하기 위해 일부 중요도가 높은 Deployment는 StatefulSet으로 전환하였고, 안정성 확보 후 Consolidation 활성화하였습니다.

마지막으로는 CoreDNS가 karpeneter의 이벤트 발생 대상이 될 수 있도록 Advanced Configuration 설정하였습니다.


Karpenter 도입에 따른 효과

Karpenter를 도입한 결과 아래와 같이 6가지의 효과를 얻을 수 있었습니다.

(1) 크게 상승한 노드의 활용도

  • 기본적으로 Groupless의 콘셉트를 가지지만 활용에 따라 NodeGroup을 보다 효율적으로 관리할 수 있었습니다. 특정한 NodeGroup을 3개씩 같은 인스턴스 유형으로 묶는다거나, 스팟 인스턴스를 우선적으로 할당받도록 할 수 있고 노드의 자원을 최대한 효율적으로 사용할 수 있었고, 자연스럽게 비용 절감이라는 큰 효과도 얻을 수 있었습니다.
  • 애플리케이션의 리소스 요구 사항의 변화에 신속하게 대응 가능해졌습니다. 기존 NodeGroup에서는 하나의 인스턴스 유형, 타입만 사용할 수 있어 리소스가 증가할 경우 유연하게 대응하기가 어려웠는데요. Karpenter를 적용하면서 인스턴스 선택이 자유로워졌습니다.

(2) 노드 생성 시간 50~60% 감소

  • CAS를 사용했을 땐 약 60 ~ 100초 정도의 시간이 소요되었으나 Karpenter로 전환한 이후 30~40초 정도로 50%가량 감소하였습니다. 이로 인해 급증하는 트래픽 등의 상황에서 보다 신속하게 작동할 수 있는 환경을 조성할 수 있었습니다.

(3) 건강해진 노드

  • 클러스터를 운영하다 보면 오랜 기간 작동하고 있는 노드가 있을 수 있는데, Karpenter의 여러 설정들을 통해 자연스레 배출하고 새로운 노드를 장착할 수 있는 구조가 만들어졌습니다.
  • 노화된 노드에서 발생할 수 있는 예기치 못한 오류들에 대해 걱정을 덜었습니다.

(4) 비용 절감 효과

  • Consolidation 적용만으로 약 10%의 비용 감소 효과를 보았습니다.
  • 스팟 인스턴스 우선 적용 프로세스를 통해 적용한 환경에서 기존 대비 약 50%(스팟 인스턴스로 전환하였을 때 평균적으로 가져올 수 있는 감소율은 70% 정도이나, Savings Plan의 계약 기간이 남아있던 점과 스팟 인스턴스를 즉시 생성할 수 없을 때 온 디멘드로 생성하도록 한 설정을 고려한 수치 - 스팟 점유율 약 90%) 수준의 비용 감소 효과를 보았습니다.

(5) 테인트(Taints) 및 톨러레이션(Tolerations) 적용

  • 기존 숨고의 노드들은 오염되어 있지 않아 모든 파드를 허용하는 구조를 가지고 있었습니다.
  • 따라서 Karpenter를 통해 생성되는 노드들에 Taints를 설정하여 각 목적을 가진 Tolerations이 설정된 파드만 허용될 수 있도록 구성하여 더 이상 파드가 부적절한 노드에 예약되지 않는 결과를 가져올 수 있었습니다.

(6) 손쉬운 아키텍처 전환

  • 노드의 구성을 쉽게 설정할 수 있게 되어 ARM으로 전환하는 작업도 손쉽게 할 수 있게 되었습니다.
  • yaml 파일 하나만 생성해서 ARM으로의 전환 및 적용할 수 있게 되었습니다.



Outro

지금까지 숨고가 AWS Warmpool을 적용한 이후 알게 된 것들과 Karpenter 도입 과정, 인사이트에 대해 알아보았습니다. Karpenter를 도입하면서 다양한 문제들을 마주했지만, 도입 이후 가져온 많은 효과를 알 수 있었습니다.

Karpenter를 시작으로 ARM으로의 전환, 서비스 Startup Time 개선 등 다양한 연계 작업들에서 큰 이점을 가져오고 있습니다. 앞으로 Karpenter의 버전 업그레이드 등 효율적인 기능 활용을 위해 노력하며 더욱 건강한 데브옵스 개발 문화를 만들어가고자 합니다.

저의 4L Restospective 내용을 마지막으로 이 글을 마무리하려 합니다.

  • Like: 노드의 생성 시간 감소가 주 목적이었으나 다방면에서의 이점을 가져올 수 있었습니다.

  • Leaned: Karpenter의 숙련도에 따라 노드의 효율적인 활용 수준이 달라진다는 것을 알게 되었습니다.

  • Lacked: Deprovisioning 기능에 대해 이해도가 부족했던 점은 아쉬웠습니다.

  • Longed for: Karpenter의 버전 업그레이드 과정이 수월해지면 좋겠습니다.

지금까지 긴 글을 읽어주셔서 감사합니다.


참고자료

Amazon EKS 클러스터를 비용 효율적으로 오토스케일링하기 | Amazon Web Services

Lyon Yi Soomgo DevOps Engineer
숨고의 인프라를 책임지며 건강한 개발문화를 만들어가는 DevOps의 Lyon입니다.