Kubernetes Pod Resource CPU 설정
우리는 Kubernetes에서 Pod를 배포할 때 Node의 리소스 관리를 위하여 Resources에 CPU와 Memory의 사용량을 정의할 수 있습니다. 이때 Memory에 대한 설정은 명확하여 사용자가 알기 쉽지만 CPU에서는 "0.5"와 같은 설정이 가능하여 많은 사람들이 단순하게 "0.5"를 1/2 Core로 이해합니다. 하지만 Kubernetes에서 CPU는 Core가 아닌 CPU Share로 관리되며 CFS(Completely Fair Scheduler)와 밀접한 관계가 있습니다.
이번 문서에서는 Kubernetes Pod Resource CPU 설정과 CFS의 관계에 대해 알아보겠습니다.
resources:
requests:
cpu: "0.5"
limits:
cpu: "0.5"
CFS란 무엇인가?
CFS(Completely Fair Scheduler)는 리눅스 커널에서 CPU 자원을 여러 프로세스나 스레드에 공평하게 분배하기 위해 사용되는 CPU 스케줄링 알고리즘입니다. 리눅스 시스템에서 멀티태스킹 환경을 효율적으로 운영하려면, 여러 프로세스가 CPU를 공평하게 나누어 사용할 수 있도록 관리해야 합니다. CFS는 이를 위해 프로세스마다 가상 시간을 계산하고, 각 프로세스가 CPU를 사용하는 비율을 공정하게 유지하려고 합니다.
CFS의 작동 원리
- 프로세스가 실행하면 CFS는 프로세스마다 가상 시간을 계산하여 CPU를 공정하게 할당합니다.
- CPU가 할당되면, CFS는 프로세스의 가상 시간과 다른 프로세스들의 가상 시간을 비교하여, 가장 적은 가상 시간을 가진 프로세스를 먼저 실행합니다.
- CPU 자원 분배는 각 프로세스의 가상 시간에 따라 조정되며, 시스템 자원이 고르게 분배될 수 있도록 관리됩니다.
- CFS는 이를 위해 프로세스마다 가상 시간을 계산하고, 각 프로세스가 CPU를 사용하는 비율을 공정하게 유지하려고 합니다.
kubernetes pod 생성 흐름
kubernetes에서 CPU 리소스는 CFS를 기반으로 관리되며, CPU의 사용량을 조절하기 위해 CFS의 가상 시간과 실제 시간을 비교하여 스케줄링을 수행합니다. CFS는 각 프로세스에 대해 가상 시간을 계산하고, 이를 기반으로 CPU를 할당합니다. 이때, CPU의 사용량은 "CPU Share"라는 개념으로 표현됩니다.
Kubernetes Pod
↓
Kubelet
↓
CRI
↓
Linux Kernel
- namespace (Isolation)
- cgroup (Resource Control)
- CPU: CFS Quota/Period
- Memory: cgroup memory limit
cgroup v1에서는 cpu.cfs_quota_us와 cpu.cfs_period_us를 사용하여 CPU의 사용량을 조절합니다.
- cpu.cfs_quota_us : 프로세스가 사용할 수 있는 CPU 시간의 총량을 설정
- cpu.cfs_period_us : 동작하는 주기를 설정합니다. (기본값은 100,000us이며 100ms입니다.)
cgroup v2에서는 cpu.max를 사용하여 CPU의 사용량을 조절합니다.
- cpu.max : 프로세스가 사용할 수 있는 CPU 시간의 총량과 동작하는 주기를 설정합니다. (기본값은 100,000us이며 100ms입니다.)
여기서 우리가 알 수 있는 것은 Kubernetes에서 CPU를 0.5로 설정하였다는 것은 100,000us의 주기 동안 50,000us를 사용할 수 있다는 것입니다. 즉, 정확한 이해를 위해서는 CFS의 개념을 이해해야 합니다. CFS는 CPU를 공평하게 나누어 사용하기 위해 각 프로세스에 대해 가상 시간을 계산하고, 이를 기반으로 CPU를 할당합니다.
실습 예제를 통해 CFS값 확인하기
apiVersion: v1
kind: Pod
metadata:
labels:
run: test-nginx
name: test-nginx
spec:
containers:
- image: nginx:1.25
name: test-nginx
resources:
requests:
cpu: "0.5"
memory: "100Mi"
limits:
cpu: "0.5"
memory: "200Mi"
위와 같이 Pod를 생성합니다.
CFS확인하는 방법
# 파드의 노드, UID, QoS클래스 확인
kubectl get po test-nginx -o yaml | grep -E "nodeName:|uid:|qosClass:"
# 워커노드 접속 후 CFS 값을 확인합니다.
# 필자의 경우 cgroup v2를 사용하고 있어 cpu.max를 사용합니다.
cat /sys/fs/cgroup/kubepods/burstable/<pod_uid>/cpu.max
# 출력 결과
# quota = period * 0.5
# quota period 순서로 출력됩니다.
# 해당 파드는 매 100ms마다 50ms를 사용할 수 있습니다.
50000 100000
여기서 burstable는 QoS Class를 의미합니다. QoS Class는 Kubernetes에서 Pod의 리소스 requests와 limits를 기반으로 Pod의 우선순위를 결정하는 방법입니다.
QoS Class는 Kubernetes에서 Pod의 리소스 requests와 limits를 기반으로 Pod의 우선 순위를 결정하는 방법입니다. 이 QoS에 따라 시스템은 리소스 부족 상황에서 어떤 Pod을 먼저 죽일지(OOMKilled), 어떤 Pod을 보호할지 결정합니다.
QoS Class는 다음과 같이 세 가지로 나뉩니다.
- Guaranteed: 모든 컨테이너에 대해 requests와 limits가 동일하게 설정된 경우 (우선순위 가장 높음)
- Burstable: requests와 limits가 다르게 설정된 경우 (중간 우선순위)
- BestEffort: requests와 limits가 설정되지 않은 경우 (우선순위 가장 낮음)
마지막으로 결론
- Kubernetes의 cpu: 0.5 설정은 리눅스 CFS 스케줄러를 통해 실제 CPU 사용을 제한한다.
- 리눅스 cgroup(v2)에서는 cpu.max 파일을 통해 quota/period를 설정한다.
- cpu: 0.5 설정은 0.5Core라고 이해하지 말고 매 100ms 주기마다 50ms 동안만 CPU를 사용하게 한다고 이해하자.
- Kubernetes는 period를 기본 100,000us(100ms)로 고정하고 quota만 조정한다.
'DevOps' 카테고리의 다른 글
[Helm] helm hook 사용법 (0) | 2025.04.26 |
---|---|
[Terraform] 기본 개념과 기본 사용법 (0) | 2025.04.22 |
[CI/CD] GitHub Action을 이용한 CI 설정하기 (0) | 2025.04.19 |
[CI/CD] ArgoCD를 이용한 Application 배포 자동화 (0) | 2025.04.12 |
[CI/CD] Argo Rollouts을 사용한 배포 전략 (0) | 2025.04.08 |