세션명: Karpenter로 쿠버네티스 클러스터 최적화: 비용 절감과 효율성 향상
일시: 2024.05.17 13:10 ~ 13:50
장소: 2F 아셈볼룸 202+203호(코엑스)
EKS는 노드의 수 조정을 위한 Node Group이라는 기능을 제공하지만, 이는 매우 느리고 옵션이 다양하지 않다는 단점이 있습니다. 이에 따라 Node Group 대신 Karpenter를 이용하는 경우가 많습니다. 이 세션에서는 Karpenter의 내부 동작에 대하여 deep dive하게 알려주기 때문에 꼭 들어야 한다고 생각했습니다.
Node Group에서 사용하는 클러스터 오토 스케일러는 수량 변경이 필요할 때, Auto Scaling Group API를 사용하여 수량 증설을 요청하고, 실제로는 Auto Scaling Group이 수량 조절을 수행함
카펜터는 Auto Scaling Group을 중간에 끼지 않고, fleet API를 통해 직접적으로 수량을 조절함
카펜터가 인스턴스를 생성하는 과정에서 참고하는 정보는 커스텀 리소스를 이용하여 선언적으로 관리함
각각의 파드들은 다양한 리소스 요구사항을 가지게 됨
카펜터를 이용하면 요구사항을 분석해여 100가지가 넘는 인스턴스 유형 중 가장 적합한 인스턴스를 프로비저닝 하도록 설정할 수 있음
아래와 같은 다양한 노드 풀 구성 전략을 구현할 수 있음
•
하나의 큰 노드 풀에서 워크로드별로 노드를 선택
•
부서별로 별도의 노드 풀을 생성하여 하드웨어/보안 요구사항을 분리
•
가중치 설정을 통해 Reserved Instance나 Savings plan 인스턴스를 우선 생성
카펜터는 노드 통합 기능을 통해 비용 최적화를 할 수 있음
기존 노드에 새 노드를 통합하거나, 기존 노드들을 제거하고 새로운 비용 효율적인 단일 노드로 대체함
노드 통합을 통해 클러스터 사용률이 높아지고 비용이 절감됨
카펜터는 노드 플릿 생성/관리, 클러스터 오토스케일링, 노드 중단 핸들러 등의 기능을 단일 창구에서 제공하여 운영 오버헤드를 최소화함
노드 중단 핸들러를 통해 스팟 인스턴스 중단 시 대체 노드를 생성하고 영향받는 파드를 마이그레이션하여 스팟 인스턴스의 중단으로 인한 인터럽션의 영향을 최소화함
이렇게 스팟 인스턴스를 적절히 활용함으로써 클러스터 비용을 효율화 할 수 있음
카펜터가 노드를 생성하는 방법은 크게 네 가지 단계로 구성됨(스케줄링, 배칭, 빈 패킹, 그리고 최종 의사결정 단계)
1.
스케줄링: 카펜터는 kube scheduler와 협력하여 작동함. 실제 파드의 스케줄링은 kube scheduler에 의해 이루어지며, 파드 스펙에 명시된 다양한 스케줄링 제약 조건을 만족하는 노드를 찾음. 만약 적절한 워커 노드를 찾지 못하면 스케줄링은 실패하고, 해당 파드는 Pending 상태로 남게 됩니다. 이때 카펜터는 워치 오퍼레이션을 통해 즉각적으로 대응함
2.
배칭: 카펜터는 보류 중인 파드를 하나의 배치로 묶어서 처리. 개별 파드에 대응할 경우 각 파드를 호스팅할 수 있는 노드만 생성되기 때문에, 카펜터는 보다 효율적인 배치를 위해 확장 윈도우 알고리즘을 사용함. 이 알고리즘에는 두 가지 주요 값이 있음
•
유휴 대기 시간: Pending Pod 이벤트 발생 후 추가로 대기하는 시간으로, 기본값은 1초
•
최대 확장 시간: 최대 10초 동안 Pending Pod를 단일 배치로 구성하는 시간으로, 기본값은 10초
3.
빈 패킹: 파드를 배치로 묶은 후, 카펜터는 어떤 인스턴스 타입을 선택할지를 결정하기 위해 시뮬레이션을 수행함. 이를 위해 EC2의 Describe API를 호출하여 인스턴스 유형을 검색하고 비용 순으로 나열. 시뮬레이션에서는 가상의 노드를 생성하고 첫 번째 파드를 넣어 인스턴스 타입의 수용 가능 여부를 확인함. 수용 가능하면 다음 파드도 같은 방식으로 확인하고, 불가능하면 다른 인스턴스 타입을 시도함. 특수한 제약 조건 때문에 동일 노드에 생성이 어려울 경우 새로운 가상의 노드를 만들어 다시 시뮬레이션.
4.
최종 의사결정: 비용 최적화를 주요 목적으로 하며, 스팟 인스턴스를 사용하는 경우 클러스터 사용률이 떨어지더라도 비용이 낮은 인스턴스를 선택함. 최종 인스턴스 런칭은 EC2 Fleet API를 통해 요청됨. 온디맨드 인스턴스의 경우 가장 저렴한 인스턴스 타입을, 스팟 인스턴스의 경우 가격과 용량을 최적화한 인스턴스를 선택
이와 같이, 카펜터는 유연하고 효율적으로 노드를 생성하여 비용을 최적화하고 클러스터의 자원 활용을 극대화함
카펜터 드리프트는 관리자가 선언한 노드 풀이나 노드 클래스의 값과 현재 운영 중인 워커 노드의 값이 일치하지 않을 때, 이를 재조정하는 작업을 의미함
드리프트 메커니즘의 예시를 들면 현재 노드 풀에는 m5.large 인스턴스 타입이 정의되어 있지만, 관리자가 이를 c5.large로 업데이트했다고 가정할 때, 카펜터는 드리프트 메커니즘을 통해 기존 m5.large 노드를 중단하기 전에 대체할 c5.large 노드를 먼저 생성하고, 그 다음에 m5.large 노드를 중단하는 작업을 수행. 이를 통해 워커 노드의 이미지 패치 및 업그레이드를 자동화할 수 있음
드리프트 기능을 이용하여 AMI 관리도 가능함
워커 노드가 사용하는 AMI는 EC2 노드 클래스에 정의됨. 기본 AMI를 사용하는 경우, EKS의 워커 노드는 EKS 버전별로 최적화된 AMI를 사용하게 되며, 카펜터는 해당 버전에 맞는 최신 AMI를 선택하도록 설계되어 있음. 만약 새로운 AMI가 릴리즈되면 파라미터 스토어에 업데이트되고, 카펜터는 이를 폴링하여 최신 정보를 적용함
클러스터 버전을 업그레이드 했을 때 전체 노드를 업데이트하는 작업도 자동적으로 수행됨
관리자가 Kubernetes 버전을 1.26에서 1.27로 업그레이드하면, 카펜터는 새로운 버전에 해당하는 AMI 정보를 파라미터 스토어에서 읽어오고, 드리프트를 감지하여 롤링 방식으로 업데이트를 수행함
이를 통해 관리자는 별도의 운영 노력 없이 항상 최신의 EKS AMI를 사용하며, 클러스터의 보안 취약성을 낮추고 운영 효율성을 높일 수 있음. 이러한 기능은 운영 효율화 측면에서 매우 유용함
카펜터는 자원을 효율적으로 사용하도록 파드의 위치를 재조정해 노드를 최소화하여 유지하는 동작을 함
위치를 최적화하여 N개의 노드를 전부 제거하거나, N개의 노드를 1개의 노드로 통합하는 등, 카펜터가 가진 최적화 알고리즘에 따라 적절하게 조절함
이 때, 파드 중단을 최소화하고, 생성된 지 얼마 되지 않은 파드는 최대한 보호하는 등으로 제거되는 노드를 결정함
위대한 상상은 아래와 같이 5가지 카테고리로 나눠서 노드 풀을 구성함
1.
시스템 노드 풀
인프라 시스템 (EC2나 Core, DNS 매트릭 서버 등)을 위해 사용
서비스와 격리되어 있으며, 매우 중요함
모두 그래비톤 인스턴스 사용
2.
온디맨드 인스턴스 노드 풀
온디맨드 인스턴스를 사용하는 노드 풀.
3.
스팟 인스턴스 노드 풀
스팟 인스턴스를 사용하는 노드 풀.
4.
배치 작업 노드 풀
에어플로우와 같은 배치 작업을 위해 따로 분리
서비스에 영향을 주지 않도록 관리.
5.
어드민 웹 서버 노드 풀
어드민성 웹 서버를 위해 따로 분리
스팟 인스턴스에 100% 할당하여 비용 최적화
스팟 인스턴스를 주로 사용하는 환경에서 서비스들의 그레이스풀 셧다운을 고려해야 했음
•
스팟 인스턴스와 그레이스풀 셧다운
스팟 인스턴스 인터럽션이 발생하면 120초의 유예 시간이 주어짐
이 시간 내에 파드 종료, 새로운 노드 생성, 파드 스케줄링, 헬스 체크까지 완료되어야 함
•
PDB (Pod Disruption Budget)
스팟 인스턴스 사용 시 PDB를 높게 설정(예: 30%)하여 파드가 빨리 빠질 수 있도록 함
온디맨드 인스턴스 사용 시 PDB를 낮게 설정(예: 5%)하여 서비스 안정화를 도모.
•
초기 CPU 사용량 관리
API 서버의 경우 초기 스케줄링 시 라이브러리 로딩과 초기 설정 작업으로 CPU 사용량이 100%까지 올라갈 수 있음
많은 파드가 동시에 스케줄링되면 CPU 100% 사용으로 타임아웃 발생 가능
이를 해결하기 위해 노드 오버 프로비저닝 전략을 도입.
•
노드 오버 프로비저닝 전략
파드 우선순위 클래스(Priority Class)를 0보다 작게 설정하여 우선순위가 낮은 더미 파드 생성, 노드에 공간이 없을 때 더미 파드를 먼저 제거하며 서비스 파드가 생성됨
멀티 AZ(Availability Zone)를 사용하여 톱콜로지 스프레드 제약 조건으로 모든 존에 골고루 배치하였고, 파드 안티 어피니티를 설정하여 한 노드에 하나의 더미 파드만 배치함
피크 시간에 더 많은 노드가 배치되도록 KEDA를 통해 스케줄링 조절
이러한 전략을 통해 스팟 인스턴스의 불확실성을 관리하고 서비스 안정성을 유지함
마치며
이번 세미나를 통해 Karpenter의 다양한 기능과 내부 동작 원리에 대해 깊이 이해할 수 있었습니다. 이를 바탕으로 Karpenter 구축 요건이 있을 때, 더욱 효율적이고 비용 절감 가능한 클러스터 운영이 가능하도록 가이드하는데 도움이 될 것 같습니다. 또한 구축 및 운영 과정에서 이슈가 발생하였을 때, 더욱 빠르게 문제의 원인을 파악하고 해결하는데 도움이 될 것 같습니다.