Kubernetes: Cluster API , Metadata API

JIWON·2025년 7월 12일

Kubernetes

목록 보기
26/32
post-thumbnail

클러스터 API와 메타데이터 API

쿠버네티스 API는 클러스터의 동작을 제어하는 클러스터 API와 컨테이너 기동에 관여하는 메타데이터 API로 나눌 수 있다.

1. 클러스터 API (Cluster API)

클러스터 전체의 동작, 보안, 자원 할당 등을 제어하는 리소스들이다. 사용자가 직접 생성하고 관리하는 경우가 많다.

  • 주요 리소스: Node, Namespace, PersistentVolume, ResourceQuota, ServiceAccount, Role, ClusterRole, RoleBinding, ClusterRoleBinding, NetworkPolicy 등

2. 메타데이터 API (Metadata API)

클러스터에 컨테이너를 배포하고 관리하는 데 사용되는 리소스들이다.

  • 주요 리소스: LimitRange, HorizontalPodAutoScaler, PodDisruptionBudget, CustomResourceDefinition 등

핵심 클러스터 리소스

1. 노드 (Node)

워커 머신(물리적 또는 가상 머신)을 나타내는 리소스이다. 사용자가 직접 생성하거나 삭제하기보다는, 클러스터에 노드가 추가되거나 제거될 때 쿠버네티스에 의해 자동으로 등록/해제된다.

노드 정보 확인:

  • 노드 전체 요약 정보: kubectl get nodes -o wide

  • 특정 노드 YAML 정보: kubectl get node <노드이름> -o yaml

  • 특정 노드 상세 정보 (이벤트 포함): kubectl describe node <노드이름>

2. 네임스페이스 (Namespace)

단일 물리 클러스터 내에서 여러 개의 가상 클러스터를 생성하는 논리적인 분리 기능이다. 리소스 그룹을 격리하여 관리할 수 있게 해준다.

  • 기본 네임스페이스:
    쿠버네티스 설치 시 default, kube-system, kube-public, kube-node-lease가 자동으로 생성된다.

  • 활용:
    네임스페이스별로 리소스 쿼터(ResourceQuota)를 설정하거나, RBAC(Role Based Access Control)을 통해 사용자 권한을 분리하는 데 사용된다.

생성 방법:

  • CLI: kubectl create namespace <네임스페이스이름>

  • 매니페스트:

apiVersion: v1
kind: Namespace
metadata:
  name: <네임스페이스이름>
  • 리소스 조회:

    • 특정 네임스페이스의 리소스 조회: kubectl get <리소스> -n <네임스페이스이름>

    • 모든 네임스페이스의 리소스 조회: kubectl get <리소스> --all-namespaces

  • 클러스터 식별:
    kube-system 네임스페이스는 클러스터의 핵심 구성요소가 동작하는 곳으로, 이 네임스페이스의 고유 ID(UID)는 클러스터를 식별하는 데 사용될 수 있다.

    • kubectl get namespace kube-system -o jsonpath="{.metadata.uid}"

리소스 관리와 오토스케일링

안정적인 클러스터 운영을 위해 파드와 컨테이너가 사용할 수 있는 컴퓨팅 자원(CPU, 메모리)을 제한하고 관리하는 것은 매우 중요하다.

1. 리소스 제한 (CPU/Memory)

파드 내 각 컨테이너별로 사용할 리소스의 최솟값(requests)최댓값(limits)을 설정할 수 있다.

  • CPU 단위: CPU는 클럭 수(GHz)가 아닌 논리적인 단위인 코어를 사용한다. 1은 1 vCPU를 의미하며, 1000m(millicores)와 같다.

  • requests (요청량): 컨테이너 실행에 필요한 최소 리소스 양을 지정한다. 스케줄러는 노드에 requests 만큼의 가용 자원이 있을 때만 해당 노드에 파드를 스케줄링한다.

  • limits (제한량): 컨테이너가 사용할 수 있는 최대 리소스 양을 지정한다. 이를 초과하면 컨테이너는 제재를 받는다 (CPU는 스로틀링, 메모리는 OOM-Killed).

설정 시나리오별 동작

  • requests만 설정: limits가 설정되지 않으면, 파드는 필요에 따라 노드의 가용 리소스를 한도 없이 사용하려 시도할 수 있다. 이는 '리소스 뺏기' 현상이나 메모리 부족(OOM)으로 인한 프로세스 강제 종료를 유발할 수 있다.

  • limits만 설정: requests 값이 자동으로 limits 값과 동일하게 설정된다.

  • 둘 다 미설정: 컨테이너는 자원 제한 없이 스케줄링되며, 노드 전체의 안정성을 해칠 수 있다.

YAML 예시: sample-resource-only-requests.yaml

apiVersion: v1
kind: Pod
metadata:
  name: sample-resource-only-requests
spec:
  containers:
  - name: nginx-container
    image: nginx:1.16
    resources:
      requests:
        memory: "256Mi"
        cpu: "200m"
  • 리소스 사용 현황 확인: 노드의 총 리소스(capacity)와 할당 가능한 리소스(allocatable)는 kubectl get nodes -o yaml로 확인 가능하지만, 현재 실제 사용량은 kubectl describe node <노드이름>을 통해 확인해야 한다.

2. 시스템 할당 리소스와 Eviction 매니저

노드의 리소스가 완전히 고갈되면 쿠버네티스 시스템 자체가 멈출 수 있다. 이를 방지하기 위해 각 노드에는 시스템 데몬을 위한 리소스가 예약되어 있다.

  • kube-reserved: Kubelet 등 쿠버네티스 컴포넌트를 위한 예약 공간.

  • system-reserved: OS 시스템 데몬 등을 위한 예약 공간.

  • Eviction Manager: 노드의 리소스(메모리, 디스크 등) 사용량이 임계치(Eviction Threshold)를 넘지 않도록 관리하는 Kubelet 내부 컴포넌트이다. 임계치를 초과하면 우선순위에 따라 파드를 축출(Evict)하여 노드의 안정성을 확보한다.

    • Eviction Threshold: softhard 두 가지 제한이 있다.

      • soft: 임계치 도달 시, 유예 시간(grace period) 후 SIGTERM 신호를 보내 파드를 정상 종료시킨다.

      • hard: 임계치 도달 시, 즉시 SIGKILL 신호를 보내 파드를 강제 종료시킨다.

    • Eviction 우선순위:

      • requests보다 많은 리소스를 사용하는 파드

      • PodPriority가 낮은 파드

      • requests 대비 초과 사용량이 더 많은 파드

3. GPU 등 특수 리소스 제한

Kubernetes 1.8부터 Device Plugins 기능이 도입되어 GPU, FPGA, TPU 등과 같은 특수 하드웨어도 CPU/메모리처럼 requests/limits를 설정할 수 있다. 단, 해당 장치를 사용하려면 노드에 적절한 드라이버가 설치되어 있어야 한다.

4. 오버커밋(Overcommit)과 리소스 부족

  • 리소스 부족: 파드가 스케줄링될 때 requests를 만족하는 노드가 없으면, 해당 파드는 Pending 상태로 대기한다.

  • 오버커밋: 파드의 limitsrequests보다 크게 설정된 경우, 노드에 할당된 모든 파드들의 requests 합은 노드 용량을 넘지 않지만, limits의 합은 노드 용량을 초과할 수 있다. 이를 오버커밋이라 한다. 부하가 급증하여 실제 사용량이 노드 용량을 초과하면 CPU 스로틀링이나 OOM-Kill이 발생할 수 있다.

5. 여러 컨테이너 사용 시 리소스 할당

파드에 여러 컨테이너와 초기화 컨테이너(initContainers)가 포함된 경우, 스케줄링에 필요한 리소스는 다음과 같이 계산된다.

파드의 총 requests = max(모든 일반 컨테이너의 requests 합, 모든 초기화 컨테이너 중 가장 큰 requests 값)


자동화된 리소스 관리 및 스케일링

1. Cluster AutoScaler와 리소스 부족

Cluster AutoScaler(CA)는 클러스터의 수요에 따라 노드 자체를 자동으로 추가하거나 제거하는 기능이다. GKE, EKS 등 대부분의 관리형 쿠버네티스 서비스에서 제공된다.

🔸동작 트리거:

CA는 클러스터의 평균 부하가 높을 때 확장되는 것이 아니라, Pending 상태의 파드가 발생했을 때 동작한다. 즉, 리소스 부족으로 스케줄링되지 못하는 파드가 생기면, 해당 파드를 수용할 수 있는 새 노드를 추가한다.

🔸requestslimits의 중요성:

CA의 동작은 requests 값에 크게 의존한다.

  • requestslimits의 차이가 너무 크면, 실제 리소스 사용량은 높은데 requests 합계는 낮아 CA가 스케일 아웃하지 않는 상황이 발생할 수 있다.

  • requests를 너무 낮게 설정하면, 실제 필요한 것보다 많은 파드가 노드에 배치되어 노드 장애를 유발할 수 있다.

  • 따라서 requestslimits는 가능한 한 비슷하게, 그리고 실제 사용량에 가깝게 설정하는 것이 중요하다.

2. LimitRange를 사용한 리소스 제한 정책

LimitRange는 네임스페이스 단위로 파드나 컨테이너가 사용할 수 있는 리소스의 기본값, 최솟값, 최댓값 등을 정책으로 강제하는 리소스이다.

🔸적용 대상:

네임스페이스에 LimitRange를 생성하면, 그 이후 해당 네임스페이스에 생성되는 신규 파드/컨테이너에만 적용된다.

🔸주요 설정 항목:

  • defaultRequest: 리소스 requests를 명시하지 않은 컨테이너에 적용될 기본값

  • default: 리소스 limits를 명시하지 않은 컨테이너에 적용될 기본값

  • min: 설정 가능한 리소스의 최솟값

  • max: 설정 가능한 리소스의 최댓값

  • maxLimitRequestRatio: limitsrequests의 최대 비율을 제한

YAML 예시: sample-limitrange-container.yaml

apiVersion: v1
kind: LimitRange
metadata:
  name: sample-limitrange-container
  namespace: default
spec:
  limits:
  - type: Container # 컨테이너에 적용될 제한
    default:
      memory: 512Mi
      cpu: 500m
    defaultRequest:
      memory: 256Mi
      cpu: 250m
    max:
      memory: 1024Mi
      cpu: "1"
    min:
      memory: 128Mi
      cpu: 125m
    maxLimitRequestRatio:
      memory: 2
      cpu: 2
  • 효과: 위 LimitRange가 적용된 네임스페이스에서 리소스 설정을 전혀 하지 않고 파드를 생성하면(kubectl apply -f sample-pod.yaml), 해당 파드를 조회했을 때(kubectl get pod sample-pod -o json) defaultRequestdefault 값이 자동으로 할당된 것을 확인할 수 있다. 이는 리소스 미설정으로 인한 클러스터 불안정성을 방지하는 중요한 역할을 한다.

0개의 댓글