문제 개요
대규모 Kubernetes 클러스터에서 수백 개의 CronJob이 실행되며, 각 Job은 반드시 특정 태그(group=batch-alpha
, group=batch-beta
, group=batch-gamma
)를 갖는 노드 풀에서만 실행되어야 합니다. 가장 중요한 요구사항은 동시에 병렬 실행이 절대로 발생해서는 안 된다는 점입니다.
일반적인 접근 방식의 한계
- CronJob을 3개로 나눠 실행 시간만 다르게 하면, 지연 시 병렬 실행 가능성 발생
hostname
을 affinity 조건으로 사용할 경우, 노드 교체 시 조건 불일치 위험topologySpreadConstraints
는 동시 실행 Pod 수가 없으면 무의미
최종 채택한 전략 요약
- 단일 CronJob만 유지
concurrencyPolicy: Forbid
로 병렬 실행 완전 차단- 노드에는
rotate-group=rotate-n
라벨을 사전 부여 - 실행 직전에 soft affinity 조건을
kubectl patch
로 회전 적용 group=batch-alpha
등 node group 라벨 기준으로 고정된 실행 범위 유지
실제 구성 요소
1. CronJob YAML 예시
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: group
operator: In
values:
- batch-alpha
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: rotate-group
operator: In
values:
- rotate-1
2. 노드 라벨 구성 예시
kubectl label node node-a group=batch-alpha rotate-group=rotate-1 --overwrite
kubectl label node node-b group=batch-alpha rotate-group=rotate-2 --overwrite
kubectl label node node-c group=batch-alpha rotate-group=rotate-3 --overwrite
3. soft affinity patch 스크립트
스크립트 실행 시 현재 시간 또는 index 기준으로 rotate-group
값을 순환 적용합니다.
#!/bin/bash
GROUP=batch-alpha
CRONJOB=my-batch-alpha-cronjob
NAMESPACE=batch-jobs
ROTATE_LIST=(rotate-1 rotate-2 rotate-3)
INDEX=$(( $(date +%s) / 300 % ${#ROTATE_LIST[@]} ))
ROTATE="${ROTATE_LIST[$INDEX]}"
kubectl patch cronjob "$CRONJOB" -n "$NAMESPACE" --type merge -p "{
\"spec\": {
\"jobTemplate\": {
\"spec\": {
\"template\": {
\"spec\": {
\"affinity\": {
\"nodeAffinity\": {
\"preferredDuringSchedulingIgnoredDuringExecution\": [
{
\"weight\": 100,
\"preference\": {
\"matchExpressions\": [
{
\"key\": \"rotate-group\",
\"operator\": \"In\",
\"values\": [\"$ROTATE\"]
}
]
}
}
]
}
}
}
}
}
}
}
}"
확장성
이 구조는 노드 수가 유동적이거나, 노드 그룹별 리소스 격리가 필요한 환경, 혹은 DevOps 협업 없이 독립적으로 CronJob 스케줄링을 제어해야 하는 상황에 매우 유용합니다.
결론
Kubernetes CronJob 실행에서 병렬을 철저히 방지하면서도, 지속적으로 동일한 노드만 사용하는 편중을 피하려면 rotate-group
기반 soft affinity 라벨 회전 전략이 가장 안정적이고 유연한 방법임을 확인했습니다.