파드 및 컨테이너 리소스 관리
파드를 지정할 때, 컨테이너에 필요한 각 리소스의 양을 선택적으로 지정할 수 있다. 지정할 가장 일반적인 리소스는 CPU와 메모리(RAM) 그리고 다른 것들이 있다.
파드에서 컨테이너에 대한 리소스 요청(request) 을 지정하면, kube-scheduler는 이 정보를 사용하여 파드가 배치될 노드를 결정한다. 컨테이너에 대한 리소스 제한(limit) 을 지정하면, kubelet은 실행 중인 컨테이너가 설정한 제한보다 많은 리소스를 사용할 수 없도록 해당 제한을 적용한다. 또한 kubelet은 컨테이너가 사용할 수 있도록 해당 시스템 리소스의 최소 요청 량을 예약한다.
리소스 요청(Request) 및 제한(Limit)
파드가 실행 중인 노드에 사용 가능한 리소스가 충분하면, 컨테이너가 해당 리소스에 지정한 request 보다 더 많은 리소스를 사용할 수 있도록 허용된다. 그러나, 컨테이너는 리소스 limit 보다 더 많은 리소스를 사용할 수는 없다.
예를 들어, 컨테이너에 대해 256MiB의 memory 요청을 설정하고, 해당 컨테이너가 8GiB의 메모리를 가진 노드로 스케줄된 파드에 있고 다른 파드는 없는 경우, 컨테이너는 더 많은 RAM을 사용할 수 있다.
해당 컨테이너에 대해 4GiB의 memory 제한을 설정하면, kubelet(그리고 컨테이너 런타임)이 제한을 적용한다. 런타임은 컨테이너가 구성된 리소스 제한을 초과하여 사용하지 못하게 한다. 예를 들어, 컨테이너의 프로세스가 허용된 양보다 많은 메모리를 사용하려고 하면, 시스템 커널은 메모리 부족(out of memory, OOM) 오류와 함께 할당을 시도한 프로세스를 종료한다.
제한은 반응적(시스템이 위반을 감지한 후에 개입)으로 또는 강제적(시스템이 컨테이너가 제한을 초과하지 않도록 방지)으로 구현할 수 있다. 런타임마다 다른 방식으로 동일한 제약을 구현할 수 있다.
- 리소스 설정 필드 예시
- spec.containers[].resources.requests.cpu
- spec.containers[].resources.requests.memory
- spec.containers[].resources.limits.cpu
- spec.containers[].resources.limits.memory
- spec.containers[].resources.requests.hugepages-<size>
리소스 타입과 기본 단위
- CPU: 컴퓨팅 처리 리소스, 쿠버네티스의 CPU 단위로 측정됨.
- 메모리: 바이트 단위로 측정됨.
추가 리소스
- Huge Page: 리눅스 커널이 기본 페이지 크기(예: 4KiB)보다 큰 메모리 블록을 할당할 수 있는 기능.
- 예시: hugepages-2Mi: 80Mi로 설정 시 40개(총 80MiB) 이상의 2MiB 페이지 할당 시 실패.
- 오버커밋 불가: CPU 및 메모리와 달리 Huge Page는 초과 할당이 불가능함
Kubernetes 리소스 단위
CPU 리소스 단위
- 측정 단위: cpu (1 CPU = 1 물리 코어 또는 1 가상 코어)
- 표현 방식
- 1 CPU = 1000m (밀리CPU)
- 예: 0.5 CPU = 500m (CPU 절반 사용)
주의 사항
- 1m보다 작은 CPU 단위는 설정할 수 없음.
- 0.005 대신 5m과 같이 밀리CPU 표기를 권장함.
메모리 리소스 단위
- 측정 단위: 바이트(Byte)
- 접미사 사용 예시
- 2의 거듭제곱: Ki, Mi, Gi, Ti, Pi, Ei
- 10의 거듭제곱: k, M, G, T, P, E
예시 값
- 128974848, 129e6, 129M = 약 129MB
- 123Mi = 약 123메비바이트
주의 사항
- 대소문자 구분 필수 (M ≠ m)
- 400m은 0.4바이트로 해석되므로, 400Mi 또는 400M으로 명시해야 올바름.
컨테이너 리소스 예제
다음 파드는 두 컨테이너로 구성된다. 각 컨테이너는 0.25 CPU와 64 MiB(226 바이트) 메모리 요청을 갖도록 정의되어 있다. 또한 각 컨테이너는 0.5 CPU와 128 MiB 메모리 제한을 갖는다. 이 경우 파드는 0.5 CPU와 128 MiB 메모리 요청을 가지며, 1 CPU와 256 MiB 메모리 제한을 갖는다.
---
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
리소스 사용량 확인 명령어
노드별 CPU & 메모리 사용량 확인
kubectl top node
노드 리소스 요청/제한 확인
kubectl describe nodes <노드_이름>
파드별 CPU & 메모리 사용량 확인
kubectl top pods # 현재 네임스페이스의 모든 파드 확인
kubectl top pods -A # 모든 네임스페이스의 모든 파드 확인
HPA(Horizontal Pod Autoscaler)
쿠버네티스에서, HorizontalPodAutoscaler 는 워크로드 리소스(예: 디플로이먼트 또는 스테이트풀셋)를 자동으로 업데이트하며, 워크로드의 크기를 수요에 맞게 자동으로 스케일링하는 것을 목표로 한다.
수평 스케일링은 부하 증가에 대해 파드를 더 배치하는 것을 뜻한다. 이는 수직 스케일링(쿠버네티스에서는, 해당 워크로드를 위해 이미 실행 중인 파드에 더 많은 자원(예: 메모리 또는 CPU)를 할당하는 것)과는 다르다.
부하량이 줄어들고, 파드의 수가 최소 설정값 이상인 경우, HorizontalPodAutoscaler는 워크로드 리소스(디플로이먼트, 스테이트풀셋, 또는 다른 비슷한 리소스)에게 스케일 다운을 지시한다.
Horizontal Pod Autoscaling은 크기 조절이 불가능한 오브젝트(예: 데몬셋)에는 적용할 수 없다.
HorizontalPodAutoscaler는 쿠버네티스 API 자원 및 컨트롤러 형태로 구현되어 있다. HorizontalPodAutoscaler API 자원은 컨트롤러의 행동을 결정한다. 쿠버네티스 컨트롤 플레인 내에서 실행되는 HPA 컨트롤러는 평균 CPU 사용률, 평균 메모리 사용률, 또는 다른 커스텀 메트릭 등의 관측된 메트릭을 목표에 맞추기 위해 목표물(예: 디플로이먼트)의 적정 크기를 주기적으로 조정한다.
- 수평 스케일링(Horizontal Scaling): 부하 증가 시 파드 수 증가.
- 수직 스케일링(Vertical Scaling): 실행 중인 파드의 자원 할당 증가.
알고리즘 세부 정보
가장 기본적인 관점에서, HorizontalPodAutoscaler 컨트롤러는 원하는(desired) 메트릭 값과 현재(current) 메트릭 값 사이의 비율로 작동한다.
원하는 레플리카 수 = ceil[현재 레플리카 수 * ( 현재 메트릭 값 / 원하는 메트릭 값 )]
예를 들어 현재 메트릭 값이 200m이고 원하는 값이 100m인 경우 200.0 / 100.0 == 2.0이므로 복제본 수가 두 배가 된다. 만약 현재 값이 50m 이면, 50.0 / 100.0 == 0.5 이므로 복제본 수를 반으로 줄일 것이다. 컨트롤 플레인은 비율이 1.0(기본값이 0.1인 -horizontal-pod-autoscaler-tolerance 플래그를 사용하여 전역적으로 구성 가능한 허용 오차 내)에 충분히 가깝다면 스케일링을 건너 뛸 것이다.
targetAverageValue 또는 targetAverageUtilization가 지정되면, currentMetricValue는 HorizontalPodAutoscaler의 스케일 목표 안에 있는 모든 파드에서 주어진 메트릭의 평균을 취하여 계산된다.
허용치를 확인하고 최종 값을 결정하기 전에, 컨트롤 플레인은 누락된 메트릭이 있는지, 그리고 몇 개의 파드가 Ready인지도 고려한다. 삭제 타임스탬프가 설정된 모든 파드(파드에 삭제 타임스탬프가 있으면 셧다운/삭제 중임을 뜻한다)는 무시되며, 모든 실패한 파드는 버려진다.
특정 파드에 메트릭이 누락된 경우, 나중을 위해 처리를 미뤄두는데, 이와 같이 누락된 메트릭이 있는 모든 파드는 최종 스케일 량을 조정하는데 사용된다.
CPU를 스케일할 때, 파드가 아직 Ready되지 않았거나(여전히 초기화중이거나, unhealthy하여서) 또는 파드의 최신 메트릭 포인트가 준비되기 전이라면, 마찬가지로 해당 파드는 나중에 처리된다.

안정화 윈도우 (Stabilization Window)
안정화 윈도우는 쿠버네티스 Horizontal Pod Autoscaler(HPA)가 파드 수를 조정할 때 빈번한 스케일링 변화(예: 스케일 인/아웃이 반복되는 현상)를 방지하기 위해 사용하는 대기 시간 설정이다.
HPA는 메트릭을 지속적으로 모니터링하고 기준값과 비교해 레플리카 수를 조정하지만, 메트릭이 급격하게 변화하는 경우 워크로드가 자주 스케일 인/아웃되면서 서비스의 안정성과 성능이 저하될 수 있다. 이를 방지하기 위해 안정화 윈도우를 설정해 일정 기간 동안의 과거 메트릭 기록을 참고하여 결정한다.
작동 방식
behavior:
scaleDown:
stabilizationWindowSeconds: 300
- 위 설정은 300초(5분) 동안 이전의 스케일 다운 제안을 기록한다. 이 기간 동안 계산된 가장 큰 레플리카 수를 선택하여 스케일 다운을 수행한다.
- 스케일 업과 다름: 안정화 윈도우는 기본적으로 스케일 다운 시에만 적용된다.
- 쿠버네티스는 기본값으로 300초(5분)을 사용하며, 필요 시 사용자 정의 가능하다.
- 예시 시나리오
- CPU 사용량이 일시적으로 급락했으나, 5분 이내에 다시 급등할 수 있다고 판단되면 즉시 스케일 다운하지 않고 5분을 대기 후 조정을 수행한다.
- 이 과정은 최대값 보존(rolling maximum) 로직을 통해 처리된다.
HPA Manifest 예시
Deployment 생성 (myweb-deploy.yml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: myweb-deploy
spec:
replicas: 2
selector:
matchLabels:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb-container
image: nginx:latest
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
ports:
- containerPort: 80
HPA 생성 (myweb-hpa.yml)
CPU 사용률이 50% 이상이면 스케일 아웃한다.
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: myweb-hpa
spec:
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myweb-deploy'kubernetes' 카테고리의 다른 글
| [Kubernetes] 고가용성 토폴로지에 대한 옵션 (0) | 2024.12.11 |
|---|---|
| [Kubernetes] 인증(RBAC) (0) | 2024.12.11 |
| [Kubernetes] StatefulSet (0) | 2024.12.10 |
| [kubernetes] deployment (0) | 2024.12.10 |
| [Kubernetes] DeamonSet & Job, Cronjob (0) | 2024.12.06 |