많은 프로덕션 쿠버네티스 클러스터는 온디맨드(높은 SLA) 노드와 스팟/선점형(낮은 SLA) 노드를 혼합하여 사용합니다. 이는 중요한 워크로드의 안정성을 유지하면서 비용을 최적화하기 위함입니다. 플랫폼 팀은 대부분의 워크로드가 위험한 용량에서 멀리 떨어지도록 하는 안전한 기본값을 필요로 하며, 동시에 특정 워크로드는 "실패 확률이 최대 5%인 노드를 허용할 수 있습니다"와 같은 명시적인 임계값을 통해 옵트인할 수 있도록 해야 합니다.
현재 쿠버네티스 테인트와 톨러레이션은 정확한 값 일치 또는 존재 여부 확인이 가능하지만, 숫자 임계값을 비교할 수는 없습니다. 이를 위해서는 개별적인 테인트 범주를 만들거나, 외부 어드미션 컨트롤러를 사용하거나, 최적 이하의 배치 결정을 수용해야 했습니다.
쿠버네티스 v1.35에서는 알파 기능으로 확장된 톨러레이션 연산자를 소개합니다. 이 개선 사항은 spec.tolerations에 Gt(보다 큼) 및 Lt(보다 작음) 연산자를 추가하여, SLA 기반 배치, 비용 최적화, 성능 인식 워크로드 분산을 위한 새로운 가능성을 여는 임계값 기반 스케줄링 결정을 가능하게 합니다.
톨러레이션의 진화
역사적으로 쿠버네티스는 두 가지 주요 톨러레이션 연산자를 지원했습니다:
Equal: 테인트의 키와 값이 정확히 일치할 때 톨러레이션이 일치합니다.Exists: 값과 상관없이 키가 존재할 때 톨러레이션이 일치합니다.
이들은 범주형 시나리오에서는 잘 작동했지만, 숫자 비교에는 부족했습니다. v1.35부터는 이러한 격차를 해소합니다.
다음 실제 시나리오를 고려해 보십시오:
- SLA 요구사항: 특정 임계값 미만의 실패 확률을 가진 노드에만 고가용성 워크로드를 스케줄합니다.
- 비용 최적화: 특정 시간당 비용 값을 초과하는 저렴한 노드에서 비용에 민감한 배치 작업을 실행할 수 있도록 허용합니다.
- 성능 보장: 대기 시간에 민감한 애플리케이션이 최소 임계값 이상의 디스크 IOPS 또는 네트워크 대역폭을 가진 노드에서만 실행되도록 보장합니다.
숫자 비교 연산자가 없으면 클러스터 운영자는 여러 개의 개별적인 테인트 값을 만들거나 외부 어드미션 컨트롤러를 사용하는 등의 해결책에 의존해야 했으며, 이 방법들은 동적 임계값 기반 스케줄링에 필요한 유연성을 제공하거나 잘 확장되지 못했습니다.
NodeAffinity 대신 톨러레이션을 확장하는 이유
NodeAffinity는 이미 숫자 비교 연산자를 지원하는데, 왜 톨러레이션을 확장하는지 궁금할 수 있습니다. NodeAffinity가 파드 선호도를 표현하는 데 강력하지만, 테인트와 톨러레이션은 중요한 운영상의 이점을 제공합니다:
- 정책 지향성: NodeAffinity는 파드별로 적용되므로, 모든 워크로드가 위험한 노드에서 명시적으로 제외(opt-out)해야 합니다. 테인트는 제어 방식을 반전시킵니다. 노드가 자신의 위험 수준을 선언하고, 해당 톨러레이션을 가진 파드만 해당 노드에 배치될 수 있습니다. 이는 더 안전한 기본값을 제공합니다. 대부분의 파드는 명시적으로 옵트인하지 않는 한 스팟/선점형 노드에서 멀리 떨어져 있습니다.
- 축출(Eviction) 의미론: NodeAffinity는 축출 기능이 없습니다. 테인트는
tolerationSeconds와 함께NoExecute이펙트를 지원하여, 노드의 SLA가 저하되거나 스팟 인스턴스에 종료 알림이 수신될 때 운영자가 파드를 드레인하고 축출할 수 있도록 합니다. - 운영상의 인체 공학: 중앙 집중식 노드 측 정책은 디스크 압력 및 메모리 압력과 같은 다른 안전 테인트와 일관성을 유지하여 클러스터 관리를 더욱 직관적으로 만듭니다.
이 개선 사항은 테인트와 톨러레이션의 잘 이해된 안전 모델을 보존하면서, SLA를 인식하는 스케줄링을 위한 임계값 기반 배치를 가능하게 합니다.
Gt 및 Lt 연산자 소개
쿠버네티스 v1.35에서는 톨러레이션을 위한 두 가지 새로운 연산자를 소개합니다:
Gt(Greater Than): 테인트의 숫자 값이 톨러레이션의 값보다 클 때 톨러레이션이 일치합니다.Lt(Less Than): 테인트의 숫자 값이 톨러레이션의 값보다 작을 때 톨러레이션이 일치합니다.
파드가 Lt 연산자를 사용하여 테인트를 허용한다는 것은 '이 메트릭이 내 임계값(value)보다 작은 노드를 허용할 수 있다'는 의미입니다. 예를 들어, 톨러레이션의 value를 "5"로 설정하고 operator를 "Lt"로 설정하면, 테인트의 value가 5보다 작은 노드에 파드가 스케줄될 수 있습니다.
이 연산자들은 숫자형 테인트 값과 함께 작동하며, 스케줄러가 개별적인 범주가 아닌 연속적인 메트릭을 기반으로 정교한 배치 결정을 내릴 수 있도록 합니다.
참고:
Gt 및 Lt 연산자의 숫자 값은 선행 0이 없는 양의 64비트 정수여야 합니다. 예를 들어, "100"은 유효하지만, "0100" (선행 0 포함) 및 "0" (0 값)은 허용되지 않습니다.
Gt 및 Lt 연산자는 NoSchedule, NoExecute, PreferNoSchedule 등 모든 테인트 이펙트와 함께 작동합니다.
사용 사례 및 예시
확장된 톨러레이션 연산자가 실제 스케줄링 문제를 어떻게 해결하는지 살펴보겠습니다.
예시 1: SLA 임계값을 이용한 스팟 인스턴스 보호
많은 클러스터는 비용 최적화를 위해 온디맨드 노드와 스팟/선점형 노드를 혼합하여 사용합니다. 스팟 노드는 상당한 비용 절감 효과를 제공하지만, 실패율이 더 높습니다. 대부분의 워크로드는 기본적으로 스팟 노드를 피하고, 특정 워크로드만 명확한 SLA 경계를 가지고 옵트인할 수 있도록 하고자 합니다.
먼저, 스팟 노드를 해당 실패 확률(예: 연간 실패율 15%)로 테인트합니다:
apiVersion: v1
kind: Node
metadata:
name: spot-node-1
spec:
taints:
- key: "failure-probability"
value: "15"
effect: "NoExecute"
온디맨드 노드는 실패율이 훨씬 낮습니다:
apiVersion: v1
kind: Node
metadata:
name: ondemand-node-1
spec:
taints:
- key: "failure-probability"
value: "2"
effect: "NoExecute"
중요 워크로드는 엄격한 SLA 요구사항을 지정할 수 있습니다:
apiVersion: v1
kind: Pod
metadata:
name: payment-processor
spec:
tolerations:
- key: "failure-probability"
operator: "Lt"
value: "5"
effect: "NoExecute"
tolerationSeconds: 30
containers:
- name: app
image: payment-app:v1
이 파드는 failure-probability가 5 미만인 노드(즉, 2%인 ondemand-node-1에는 가능하지만 15%인 spot-node-1에는 불가능)에만 스케줄됩니다. tolerationSeconds: 30과 함께 NoExecute 이펙트를 사용하면, 노드의 SLA가 저하될 경우(예: 클라우드 제공업체가 테인트 값을 변경) 파드가 강제 축출되기 전에 30초 동안 정상적으로 종료할 수 있습니다.
반면에, 장애 허용 배치 작업은 스팟 인스턴스에 명시적으로 옵트인할 수 있습니다:
apiVersion: v1
kind: Pod
metadata:
name: batch-job
spec:
tolerations:
- key: "failure-probability"
operator: "Lt"
value: "20"
effect: "NoExecute"
containers:
- name: worker
image: batch-worker:v1
이 배치 작업은 실패 확률이 20%까지인 노드를 허용하므로, 온디맨드 노드와 스팟 노드 모두에서 실행될 수 있어 더 높은 위험을 감수하면서 비용 절감을 극대화합니다.
예시 2: GPU 티어를 이용한 AI 워크로드 배치
AI 및 머신러닝 워크로드는 종종 특정 하드웨어 요구사항을 가집니다. 확장된 톨러레이션 연산자를 사용하면 GPU 노드 티어를 생성하고 워크로드가 적절한 성능의 하드웨어에 배치되도록 할 수 있습니다.
GPU 노드를 컴퓨팅 스코어(compute capability score)로 테인트합니다:
apiVersion: v1
kind: Node
metadata:
name: gpu-node-a100
spec:
taints:
- key: "gpu-compute-score"
value: "1000"
effect: "NoSchedule"
---
apiVersion: v1
kind: Node
metadata:
name: gpu-node-t4
spec:
taints:
- key: "gpu-compute-score"
value: "500"
effect: "NoSchedule"
고성능 훈련 워크로드는 고성능 GPU를 요구할 수 있습니다:
apiVersion: v1
kind: Pod
metadata:
name: model-training
spec:
tolerations:
- key: "gpu-compute-score"
operator: "Gt"
value: "800"
effect: "NoSchedule"
containers:
- name: trainer
image: ml-trainer:v1
resources:
limits:
nvidia.com/gpu: 1
이는 훈련 파드가 컴퓨팅 스코어가 800보다 큰 노드(예: A100 노드)에만 스케줄되도록 보장하여, 훈련 속도를 늦출 수 있는 저성능 GPU에 배치되는 것을 방지합니다.
반면에, 요구사항이 덜 까다로운 추론 워크로드는 사용 가능한 모든 GPU를 사용할 수 있습니다:
apiVersion: v1
kind: Pod
metadata:
name: model-inference
spec:
tolerations:
- key: "gpu-compute-score"
operator: "Gt"
value: "400"
effect: "NoSchedule"
containers:
- name: inference
image: ml-inference:v1
resources:
limits:
nvidia.com/gpu: 1
예시 3: 비용 최적화 워크로드 배치
배치 처리 또는 비핵심 워크로드의 경우, 성능 특성이 낮더라도 저렴한 노드에서 실행하여 비용을 최소화하고 싶을 수 있습니다.
노드는 시간당 비용(cost rating)으로 테인트될 수 있습니다:
spec:
taints:
- key: "cost-per-hour"
value: "50"
effect: "NoSchedule"
비용에 민감한 배치 작업은 비싼 노드에 대한 허용 수준을 표현할 수 있습니다:
tolerations:
- key: "cost-per-hour"
operator: "Lt"
value: "100"
effect: "NoSchedule"
이 배치 작업은 시간당 100달러 미만의 비용이 드는 노드에 스케줄되지만, 더 비싼 노드는 피합니다. 이는 쿠버네티스 스케줄링 우선순위와 결합되어, 핵심 워크로드는 프리미엄 노드를 얻고 배치 워크로드는 예산 친화적인 리소스를 효율적으로 사용하는 정교한 비용 계층화 전략을 가능하게 합니다.
예시 4: 성능 기반 배치
스토리지 집약적인 애플리케이션은 종종 최소 디스크 성능 보장을 요구합니다. 확장된 톨러레이션 연산자를 사용하면 이러한 요구사항을 스케줄링 수준에서 강제할 수 있습니다.
tolerations:
- key: "disk-iops"
operator: "Gt"
value: "3000"
effect: "NoSchedule"
이 톨러레이션은 disk-iops가 3000을 초과하는 노드에만 파드가 스케줄되도록 보장합니다. Gt 연산자는 "이 최소값보다 더 높은 성능을 가진 노드가 필요하다"는 의미입니다.
이 기능 사용 방법
확장된 톨러레이션 연산자는 Kubernetes v1.35의 알파 기능입니다. 사용해 보려면 다음 단계를 따르십시오:
- API 서버와 스케줄러 모두에서 기능 게이트를 활성화하십시오:
--feature-gates=TaintTolerationComparisonOperators=true - 노드를 테인트하여 스케줄링 요구사항과 관련된 숫자 값을 나타내십시오:
kubectl taint nodes node-1 failure-probability=5:NoSchedule kubectl taint nodes node-2 disk-iops=5000:NoSchedule - 파드 스펙에서 새로운 연산자를 사용하십시오:
spec: tolerations: - key: "failure-probability" operator: "Lt" value: "1" effect: "NoSchedule"
참고:
알파 기능이므로, 확장된 톨러레이션 연산자는 향후 릴리스에서 변경될 수 있으며 프로덕션 환경에서는 주의해서 사용해야 합니다. 항상 비프로덕션 클러스터에서 먼저 철저히 테스트하십시오.
향후 계획
이번 알파 릴리스는 시작에 불과합니다. 커뮤니티로부터 피드백을 수집하면서, 다음을 계획하고 있습니다:
- 시맨틱 버전 비교를 포함하여 더욱 유연한 스케줄링 로직을 위해 톨러레이션 및 노드 어피니티에 CEL (Common Expression Language) 표현식 지원 추가
- 임계값 인식 용량 계획을 위한 클러스터 오토스케일링 통합 개선
- 기능을 베타 및 최종적으로 GA(General Availability)로 상향시켜 프로덕션 환경에서 사용할 수 있는 안정성 확보
특히 여러분의 사용 사례에 대해 듣고 싶습니다! 임계값 기반 스케줄링이 문제를 해결할 수 있는 시나리오가 있습니까? 추가적인 연산자나 기능을 보고 싶으신가요?
참여하기
이 기능은 SIG Scheduling 커뮤니티에 의해 주도됩니다. 이 기능 및 그 이상에 대한 아이디어와 피드백을 공유하고 커뮤니티와 연결하려면 저희와 함께하십시오.
이 기능의 관리자에게는 다음을 통해 연락할 수 있습니다:
- Slack: Kubernetes Slack의 #sig-scheduling
- 메일링 리스트: [email protected]
확장된 톨러레이션 연산자와 관련된 질문이나 특정 문의 사항이 있으면 SIG Scheduling 커뮤니티에 문의하십시오. 여러분의 의견을 기다리겠습니다!
더 알아보기
- 기본 사항 이해를 위한 테인트와 톨러레이션
Gt및Lt연산자 사용에 대한 자세한 내용은 숫자 비교 연산자- KEP-5471: 임계값 기반 배치를 위한 확장된 톨러레이션 연산자