[Project] Multi-Tenant K8s Cluster on ARM64 - (12) Using Master Node Resource

developowl·2026년 3월 9일
post-thumbnail

마스터 노드의 리소스 구성은 CPU - 4.0 Core / RAM - 8GB / Storage - 256GB 입니다. 여기서 실제 마스터 노드 운영에 필요한 리소스를 제외하면 놀고 있는 리소스가 상당할 것으로 예상이 됩니다. 그래서 더 많은 리소스를 멀티 테넌트에 사용하고자 합니다.

1. 마스터 노드 작동에 필요한 리소스 견적

  • CPU: 1.0 Core
    • etcd, kube-apiserver 는 테넌트 파드가 많아질수록 데이터 통신량과 연산량이 급증.
    • 물리적인 1코어를 시스템 전용으로 박제해둠으로써, 테넌트 파드가 CPU를 100% 점유하려는 폭주 상황에서도 제어 신호가 밀리지 않고 클러스터 업무 처리가 가능
  • Memory: 2.0Gi ~ 2.5Gi
    • etcd 메모리 캐싱과 클러스터 상태 감시 프로세스가 차지하는 비중
    • 메모리 부족 시 지연이나 노드 이탈 현상 발생
  • Ephemeral Storage: 5Gi 이상
    • 로그와 컨테이너 이미지 레이어들이 쌓이는 공간
    • 여기가 꽉 차면 마스터 노드 자체가 DiskPressure 상태에 빠져 멈춤

일반적으로 마스터 노드는 최소 사양 2코어 이상을 권장하지만,, 리소스 제약(홈랩)을 고려하여 1.0 Core 를 물리적으로 예약(Reserved) 하는 방식을 채택했습니다!

2. 마스터 노드에 걸린 제한(Taint) 해제하기

  • 현재 마스터 노드에는 Taint가 붙어 있기 때문에 일반 파드가 배포되지 않는다.
# 마스터 노드의 NoSchedule 설정 제거 (명령어 끝의 '-'가 제거를 의미합니다)
kubectl taint nodes master node-role.kubernetes.io/control-plane:NoSchedule-

⚠️ 주의사항: NoSchedule- 을 사용하여 마스터 노드를 개방했습니다. 나중에 테넌트 파드가 배포될 때, 테넌트 파드가 CPU 스케줄링을 두고 경쟁을 하게 되고 이때 마스터 노드의 작업에 영향을 끼칠 수도 있습니다.
이에 대한 명시적 조치로 PriorityClass 와 NodeAffinity 라는 설정이 있습니다.

📌 PriorityClass & NodeAffinity

PriorityClass == “누구를 먼저 내보낼 것인가?”

쿠버네티스 노드에 자원이 부족해지면 커널은 어떤 파드를 죽여서 노드를 살릴 것인지 결정을 합니다. 이때 PriorityClass 는 파드에게 붙여주는 계급장 역할을 합니다.

  • 파드마다 숫자(value)를 부여하고, 숫자가 높은 파드일수록 제거 후순위가 됩니다.
  • 마스터 노드에서의 활용
    • 시스템 파드 (apiserver, etcd 등): 매우 높은 점수 (기본값으로 이미 높음)
    • 테넌트 파드: 낮은 점수
  • 기대 효과
    • 마스터 노드의 메모리가 꽉 차면, 쿠버네티스는 점수가 낮은 테넌트 파드를 먼저 kill 시켜서 마스터 노드의 생존을 최우선으로 보장한다

NodeAffinity == “어디에 위치하게 할 것인가?”

  • 파드가 배포될 때 라벨에 따라 선호/비선호를 지정하는 기능
  • 마스터 노드에서의 활용
    • 테넌트 파드들에게 약한 거부감(Preferred Scheduling)을 부여
    • 워커 노드에 공간이 있다면 워커 노드로 먼저 가고, 워커 노드가 꽉 찼을 때만 마스터 노드의 남는 자리를 쓰도록 유도

PriorityClass 리스트 확인하기

kubectl get priorityclasses

or

kubectl get pc

  • 현재 쿠버네티스 시스템의 priorityclass 만 값이 20억점대로 지정이 되어 있음을 확인할 수 있습니다.
  • 테넌트 파드들의 priorityclass 를 따로 지정하지 않았기 때문에 0점(Default)으로 작동 중입니다.
  • → 마스터 노드의 생존은 어느 정도 보장이 된 상태!

각 파드들의 PC 값을 한 번에 조회하기

kubectl get pods -A -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,PRIORITY-CLASS:.spec.priorityClassName,VALUE:.spec.priority"

  • 시스템 설정 관련 파드들은 모두 20억대의 값(value)을 갖고 있고, 일반 파드들은 기본값인 0을 부여받았음을 확인할 수 있습니다.

3. 리소스 예약 설정(마스터 노드 보호 설정)

  • 테넌트 파드가 마스터 노드의 자원을 다 사용하지 못하도록 Kubelet 설정 파일을 수정하여 관리자 전용 자원을 강제로 묶음

3-1. 설정 파일 열기

sudo nano /var/lib/kubelet/config.yaml

3-2. 리소스 예약 값 추가

  • kubeReserved (쿠버네티스 관리용) / systemReserved (OS 구동용)
  • kubelet/config.yaml 하단에 설정 추가
# 마스터 노드 보호를 위한 리소스 예약 설정
systemReserved:
  cpu: "300m"
  memory: "500Mi"
kubeReserved:
  cpu: "700m"      # 시스템과 합쳐서 총 1.0 Core 예약
  memory: "2000Mi"  # 시스템과 합쳐서 총 2.5Gi 예약
enforceNodeAllocatable: ["pods"]
evictionHard:
  memory.available: "500Mi" # 여유 메모리 500Mi 미만 시 테넌트 파드 자동 퇴거
  nodefs.available: "10%"   # 디스크 여유 10% 미만 시 경고 및 제한
  • systemReserved
    • 리눅스 운영체제 자체가 동작할 공간을 미리 떼어두는 설정
  • kubeReserved
    • 쿠버네티스 관리 객체(kubelet, container runtime 등)를 위한 전용 자원 설정
  • enforceNodeAllocatable
    • 노드에서 파드에게 실제로 나누어 줄 수 있는 자원(Allocatable)을 계산할 때, 위에서 예약한 자원들을 강제로 제외하겠다는 선언
    • 보통 [”pods”] 로 설정하며, 스케줄러는 이 계산된 값을 보고 파드를 배치함
  • evictionHard
    • 노드의 자원이 한계치에 도달했을 때, 파드를 강제로 즉시 종료 시켜 노드를 살리는 임계값

4. 마무리 및 설정 반영

4-1. Kubelet 재시작 (필수)

sudo systemctl restart kubelet

4-2. 마스터 노드 상태 및 자원 할당량 확인

kubectl describe node master | grep -A 5 "Allocatable:"

설정이 완료된 후 Allocatable 수치를 확인해 보면, 마스터 노드 예약 자원을 제외한 “실제 가용 범위" 를 확인할 수 있습니다.

  • cpu: 3
    • 4코어 중 시스템용으로 1코어를 예약했기 때문에 cpu - 3 가 출력
  • ephemeral-storage: 22536xxxxx
    • 256GB 스토리지 중 시스템 영역을 제외하고 파드들이 사용 가능한 저장 공간
  • memory: 581xxxxxKi
    • 전체 RAM 8GB 중, systemReserved + kubeReserved 로 설정한 2.5Gi 와 evictionHard 로 설정한 500Mi 등으로 제외한 수치
  • pods: 110
    • 해당 노드에 최대로 올릴 수 있는 파드의 개수 (쿠버네티스 기본값 == 110)

→ 마스터 노드 예약 리소스 설정 완료!😋

profile
Don’t get mad at the computer.

0개의 댓글