Wave Karpenter CRDs
이 kind들은 CRD Mode에서 Wave Karpenter를 구성합니다. WaveKarpenterNodeWarmup은 Node Warmup에, WaveKarpenterSpotPlacement는 Spot Workload Placement에 사용합니다. 두 kind 모두 설치 환경에서 Wave Karpenter가 활성화되어 있어야 합니다.
WaveKarpenterNodeWarmup
WaveKarpenterNodeWarmup은 Karpenter NodePool에 대한 사전 노드 프로비저닝을 구성합니다. NodePool을 이름으로 지정하며, warmup 모드(warmupType)와 스케줄링 모드(scheduleType)를 조합해 세 가지 warmup 전략 중 하나를 선택합니다.
Scope: cluster-scoped(클러스터 범위). metadata.namespace가 필요하지 않습니다.
apiVersion: wavek8s.com/v1alpha1
kind: WaveKarpenterNodeWarmup
metadata:
name: checkout-warmup
spec:
nodepoolName: default-nodepool
warmupType: max_pod # max_pod | trigger
scheduleType: scheduled # always | scheduled
enabled: true
enableImagePrepull: true
options:
cronExpression: "0 0 9 * * 1-5 *"
cronDurationMin: 540
podSizeBufferPct: 20
consolidationDisabledMin: 30
useAllAzs: true
excludeStatefulsetPods: falseSpec 필드
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
nodepoolName | string | Yes | - | 대상 Karpenter NodePool의 이름입니다. Wave는 reconcile 시점에 이를 NodePool의 UID로 변환합니다. 해당 NodePool이 없으면 RefNotFound를 보고하고, 이후 NodePool이 나타나면 자동으로 복구됩니다. |
warmupType | string | Yes | - | Warmup 알고리즘입니다. max_pod(UI: Max Pod)는 NodePool 내 가장 큰 pod 크기에 맞춰 노드를 프로비저닝하고, trigger(UI: Trigger)는 명시적인 vCPU/memory/count 사양으로 노드를 프로비저닝합니다. 인식되지 않는 값은 거부되지 않고 조용히 max_pod로 처리되므로 철자를 다시 확인하세요. |
scheduleType | string | Yes | - | 활성화 스케줄입니다. always(UI: Always)는 계속 실행되고, scheduled(UI: Scheduled)는 cron 표현식에 따라 활성화됩니다. 인식되지 않는 값은 거부되지 않고 조용히 always로 처리되므로 철자를 다시 확인하세요. |
enabled | boolean | No | true | 이 warmup 규칙의 활성 여부입니다. CR을 삭제하지 않고 일시 중지하려면 false로 설정하세요. |
enableImagePrepull | boolean | No | false | 워밍된 노드에 컨테이너 이미지를 pre-pull하여 pod 시작 시 이미지 pull 지연을 없앱니다. |
options | object | See Notes | - | 모드별 구성입니다. 필수 필드는 (warmupType, scheduleType) 조합에 따라 다릅니다. 아래 조합별 표를 참고하세요. |
options 필드 · max_pod + always
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
podSizeBufferPct | integer | No | 10 | 프로비저닝할 노드를 결정할 때 관측된 max-pod 크기에 추가하는 안전 마진(%)입니다. |
consolidationDisabledMin | integer | No | 10 | 프로비저닝 이벤트 발생 후 해당 NodePool에서 Karpenter consolidation이 중지된 상태로 유지되는 시간(분)입니다. |
useAllAzs | boolean | No | false | 워밍된 노드를 모든 가용 영역에 분산 배치합니다. |
excludeStatefulsetPods | boolean | No | true | max-pod 크기 계산에서 StatefulSet pod를 제외합니다. |
options 필드 · max_pod + scheduled
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
cronExpression | string | Yes | - | warmup이 활성화되는 시점을 제어하는 7필드 cron 표현식(sec min hour dom month dow year)입니다. 예: "0 0 9 * * 1-5 *" (평일 09:00). |
cronDurationMin | integer | Yes | - | cron이 실행될 때마다 Karpenter가 회수하기 전까지 워밍된 노드가 프로비저닝된 상태로 유지되는 시간(분)입니다. |
podSizeBufferPct | integer | No | 10 | 관측된 max-pod 크기 대비 안전 마진(%)입니다. |
consolidationDisabledMin | integer | No | 10 | 윈도우가 종료된 후 consolidation이 중지 상태로 유지되는 시간(분)입니다. |
useAllAzs | boolean | No | false | 워밍된 노드를 모든 가용 영역에 분산 배치합니다. |
excludeStatefulsetPods | boolean | No | true | max-pod 크기 계산에서 StatefulSet pod를 제외합니다. |
options 필드 · trigger + scheduled
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
cronExpression | string | Yes | - | warmup이 트리거되는 시점을 제어하는 7필드 cron 표현식(sec min hour dom month dow year)입니다. |
nodeVcpus | number | Yes | - | 프로비저닝할 노드의 vCPU 수입니다. 지원되는 값이어야 합니다 (예: 8.0). |
nodeMemoryGi | number | Yes | - | 프로비저닝할 노드의 메모리(GiB)입니다. 지원되는 값이어야 합니다 (예: 32.0). |
nodeTargetCount | integer | Yes | - | 프로비저닝할 warm 노드 수입니다. |
consolidationDisabledMin | integer | No | 10 | 트리거 실행 후 consolidation이 중지 상태로 유지되는 시간(분)입니다. |
참고 사항
-
유효한
(warmupType, scheduleType)조합입니다. 세 가지 조합이 허용되며, 한 가지는 명시적으로 거부됩니다.warmupTypescheduleType결과 max_podalways기존 노드가 가장 큰 pod에 맞지 않을 때 지속적으로 모니터링하며 프로비저닝합니다 max_podscheduled위와 동일하지만 cron 윈도우 동안에만 동작합니다 triggerscheduledcron 일정에 따라 고정된 노드 사양으로 프로비저닝합니다 triggeralways거부됨: ValidationFailed를 보고합니다 -
options은 조건부 필수입니다.max_pod+always는options블록을 완전히 생략할 수 있습니다 (모든 필드에 기본값이 있음). 다른 모든 조합은 위 표에서 Required로 표시된 필드를 최소한 포함해야 하며, 생략하면ValidationFailed를 보고합니다. -
Cron 형식은 7필드입니다. cron 표현식은
sec min hour dom month dow year형식을 따릅니다. 예:"0 0 9 * * 1-5 *"는 매년 평일 09:00:00에 실행됩니다. -
nodeVcpus와nodeMemoryGi는 지원되는 값이어야 합니다. trigger 전략은 Wave가 명시적으로 지원하는 노드 타입만 프로비저닝합니다. 지원되지 않는 값은ValidationFailed를 보고합니다. -
동일한 NodePool에서 cron 윈도우가 겹치면 거부됩니다. 같은 NodePool을 대상으로 하는 두 개의
max_pod+scheduledwarmup의 cron 윈도우가 겹치면Conflicted를 보고합니다. cron 표현식이나 duration을 조정해 해결하세요. 이 검사는 서로 다른 NodePool 간에는 적용되지 않으며triggerwarmup에도 적용되지 않습니다. -
max_pod+always와max_pod+scheduled는 동일한 NodePool에서 공존할 수 없습니다.max_podwarmup은 NodePool당 하나의 schedule 타입(Always 또는 Scheduled)만 허용합니다. 다른scheduleType으로 두 번째를 추가하려고 하면Conflicted를 보고합니다. -
RefNotFound는 자동으로 복구됩니다.nodepoolName이 실제 존재하는 Karpenter NodePool과 일치하지 않아도kubectl apply는 성공합니다. Wave는.status.conditions에RefNotFound를 보고하고, 이후 NodePool이 나타나면 자동으로 reconcile합니다.
WaveKarpenterSpotPlacement
WaveKarpenterSpotPlacement는 단일 워크로드에 대해 On-Demand / Spot 레플리카 자동 분할을 구성합니다. Wave는 MutatingWebhookConfiguration을 통해 nodeAffinity 규칙을 주입하므로 워크로드 YAML을 변경할 필요가 없습니다.
Scope: namespaced(네임스페이스 범위). 대상 워크로드와 동일한 namespace에 생성해야 합니다.
apiVersion: wavek8s.com/v1alpha1
kind: WaveKarpenterSpotPlacement
metadata:
name: checkout-spot-placement
namespace: payment
spec:
targetRef:
kind: Deployment
name: checkout-api
podSplitThreshold: 5
placementStrategy: prefer
enabled: trueSpec 필드
| 필드 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
targetRef | object | Yes | - | spot placement를 관리할 대상 워크로드입니다. |
targetRef.kind | string | Yes | - | Deployment, Rollout(Argo Rollouts), 또는 DeploymentConfig(OpenShift)입니다. |
targetRef.name | string | Yes | - | CR과 동일한 namespace에 있는 워크로드의 이름입니다. |
podSplitThreshold | integer | Yes | - | UI에서는 Pod Spot Threshold로 표시됩니다. 순번(ordinal index)이 threshold 이하인 pod는 On-Demand에서, threshold 초과인 pod는 Spot에서 실행됩니다 (threshold가 5이면 pod 1~5는 On-Demand, 6 이상은 Spot). >= 1이어야 합니다. |
placementStrategy | string | Yes | - | prefer는 Spot을 우선 사용하고 사용할 수 없으면 On-Demand로 폴백합니다. require는 Spot만 강제하며, Spot 용량이 없으면 pod가 Pending 상태로 남습니다. 알 수 없는 값은 Wave가 reconcile 시점에 ValidationFailed를 보고합니다. |
enabled | boolean | No | true | 이 워크로드에 대해 webhook이 affinity 규칙을 주입할지 여부입니다. CR을 삭제하지 않고 비활성화하려면 false로 설정하세요. |
워크로드당 WaveKarpenterSpotPlacement는 하나만 허용됩니다. 동일한 워크로드(같은 namespace, name, kind)를 대상으로 하는 CR이 서로 다른 이름으로 두 개 존재하면 .status.conditions에 ValidationFailed가 보고됩니다. 먼저 reconcile된 CR이 활성 구성을 유지하고, 두 번째 CR은 충돌이 해결될 때까지 거부됩니다.
참고 사항
-
Namespaced: 대상 워크로드와 동일한 namespace에 CR을 생성하세요. CR과 워크로드는 namespace를 공유해야 하며, 다른 namespace를 대상으로 지정할 수 없습니다.
-
targetRef.kind는Deployment,Rollout,DeploymentConfig중 하나여야 합니다. 인식되지 않는 값은 거부되지 않고 조용히Deployment로 처리되므로 철자를 다시 확인하세요. -
podSplitThreshold는>= 1이어야 합니다.0을 지정하면ValidationFailed를 보고합니다. CRD 스키마는 API 서버 수준에서 최솟값을 강제하지 않으므로, 이 검사는 reconcile 시점에 실행됩니다. -
TargetNotFound는 자동으로 복구됩니다. 대상 워크로드가 아직 존재하지 않아도kubectl apply는 성공합니다. Wave는.status.conditions에TargetNotFound를 보고하고, 이후 워크로드가 나타나면 자동으로 reconcile합니다. apply 순서는 상관없습니다. -
Webhook TLS가 필요합니다. Spot Placement는 유효한 TLS 인증서를 가진 등록된 MutatingWebhookConfiguration에 의존합니다. TLS가 없으면 affinity 규칙이 전혀 주입되지 않습니다. TLS 설정 방법은 Getting Started를 참고하세요.
-
prefer대require. 대부분의 워크로드에는prefer를 사용하세요. Spot 용량이 없으면 pod가 On-Demand로 폴백합니다. On-Demand에서 절대 실행되면 안 되는 장애 허용 배치 작업에만require를 사용하세요.