기록/Kubenetes

Kubernetes (3)

YongE 2025. 4. 11. 11:44

Objects - Namespace, ResourceQuota, LimitRange


쿠버네티스 클러스터에서 자원 관리는 핵심적인 요소다. 기본적으로 쿠버네티스의 컨테이너는 제한 없이 클러스터 자원을 사용할 수 있어 한 애플리케이션이 전체 클러스터 자원을 독점할 위험이 있다. 이런 문제를 해결하기 위해 쿠버네티스는 Namespace, ResourceQuota, LimitRange라는 세 가지 핵심 오브젝트를 제공한다. 이 글에서는 이 세 가지 오브젝트의 개념, 활용법, 그리고 실제 구현 방식에 대해 자세히 알아본다.

Namespace 이해하기

네임스페이스는 쿠버네티스 클러스터 내에서 논리적으로 자원을 분리하는 가상 클러스터다. 네임스페이스를 통해 여러 팀이나 프로젝트가 동일한 클러스터를 공유하면서도 각자의 자원을 독립적으로 관리할 수 있다.

네임스페이스의 특징

  • 이름 중복 방지: 동일한 네임스페이스 내에서는 같은 종류의 오브젝트가 동일한 이름을 가질 수 없다
  • 자원 분리: 네임스페이스는 다른 네임스페이스와 자원이 분리되어 관리된다
  • 자원 삭제 연쇄: 네임스페이스를 삭제하면 그 안에 포함된 모든 자원도 함께 삭제된다
  • 공통 자원: Node와 PersistentVolume같은 일부 자원은 모든 네임스페이스에서 공통적으로 사용된다

네임스페이스 접근 제어

기본적으로 다른 네임스페이스의 Pod IP에는 접근이 가능하지만, Network Policy를 통해 이를 제한할 수 있다. 네임스페이스 간 자원 분리는 논리적 분리이며, 물리적 분리는 아니라는 점을 기억해야 한다.

네임스페이스 YAML 예시

네임스페이스를 생성하는 YAML은 간단하게 작성할 수 있다:

apiVersion: v1
kind: Namespace
metadata:
  name: nm-1

ResourceQuota로 자원 제한하기

ResourceQuota는 네임스페이스 내에서 사용할 수 있는 전체 자원의 양을 제한하는 오브젝트다. 이를 통해 특정 네임스페이스가 클러스터의 자원을 과도하게 사용하는 것을 방지할 수 있다.

ResourceQuota의 기능

  • 자원 총량 제한: 네임스페이스 내 모든 파드가 사용할 수 있는 메모리, CPU 등의 총량을 제한한다
  • 오브젝트 수 제한: 생성할 수 있는 파드, 서비스, 컨피그맵 등 오브젝트의 수를 제한할 수 있다
  • 스토리지 자원 제한: PersistentVolumeClaim에서 요청할 수 있는 스토리지 용량을 제한한다

ResourceQuota 사용 시 주의사항

  • 스펙 명시 필수: ResourceQuota가 설정된 네임스페이스에서는 모든 Pod에 리소스 요청과 제한을 명시해야 한다
  • 기존 파드 영향 없음: ResourceQuota 설정 이전에 이미 생성된 파드에는 제한이 적용되지 않는다
  • 복수 쿼터 지원: 하나의 네임스페이스에 여러 ResourceQuota를 적용해 다양한 자원을 제어할 수 있다

ResourceQuota YAML 예시

apiVersion: v1
kind: ResourceQuota
metadata:
  name: rq-1
  namespace: nm-3
spec:
  hard:
    requests.memory: 3Gi
    limits.memory: 6Gi
    pods: "10"
    services: "5"
    configmaps: "10"
    persistentvolumeclaims: "5"

LimitRange로 개별 리소스 제한하기

LimitRange는 네임스페이스 내에서 개별 컨테이너나 파드에 적용되는 리소스 제한을 설정한다. ResourceQuota가 네임스페이스 전체 자원을 제한한다면, LimitRange는 개별 오브젝트에 대한 제약을 설정한다.

LimitRange의 주요 설정 항목

  • min: 컨테이너나 파드가 가질 수 있는 최소 자원 요구량
  • max: 컨테이너나 파드가 가질 수 있는 최대 자원 요구량
  • defaultRequest: 명시되지 않은 경우 기본적으로 적용되는 요청 자원량
  • default: 명시되지 않은 경우 기본적으로 적용되는 제한 자원량
  • maxLimitRequestRatio: 요청(request)과 제한(limit) 사이의 최대 비율을 설정하며, 일반적으로 requests 값이 limits 값의 3배를 넘지 않도록 설정한다

LimitRange 사용 사례

  • 특정 네임스페이스에 들어오는 파드의 크기를 일정 수준 이하로 제한한다
  • 자원 명세가 없는 파드에 기본값을 설정하여 관리를 용이하게 한다
  • request와 limit의 비율을 제한하여 과도한 오버커밋을 방지한다

LimitRange YAML 예시

apiVersion: v1
kind: LimitRange
metadata:
  name: lr-1
  namespace: nm-3
spec:
  limits:
  - type: Container
    min:
      memory: 0.1Gi
    max:
      memory: 0.5Gi
    defaultRequest:
      memory: 0.2Gi
    default:
      memory: 0.3Gi
    maxLimitRequestRatio:
      memory: 3 # requests 값이 limits 값의 최대 3배까지만 허용됨.

세 오브젝트의 관계와 작동 원리

자원 관리 프로세스

  1. 관리자 설정: 관리자는 네임스페이스를 생성하고 해당 네임스페이스에 ResourceQuota와 LimitRange를 설정한다
  2. 사용자 생성: 사용자는 네임스페이스 내에 파드나 다른 오브젝트를 생성한다
  3. LimitRange 적용: 제일 먼저 LimitRange 어드미션 컨트롤러가 리소스 요청과, 제한이 설정되지 않은 파드에 기본값을 적용한다
  4. ResourceQuota 검증: ResourceQuota는 자원 사용이 네임스페이스에 설정된 한계를 초과하지 않는지 확인한다
  5. 제한 위반 처리: 자원 제한을 위반하는 생성/수정 요청은 HTTP 403 오류와 함께 거부된다

파드 설정 예시

LimitRange와 ResourceQuota가 적용된 네임스페이스에서 파드를 생성하려면, 다음과 같이 리소스 요청과 제한을 명시해야 한다:

apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  namespace: nm-3
spec:
  containers:
  - name: container
    image: nginx
    resources:
      requests:
        memory: 0.2Gi
        cpu: 200m
      limits:
        memory: 0.4Gi
        cpu: 400m # requests 값은 limits 값보다 작아야 하며 비율은 maxLimitRequestRatio 기준으로 검증됨.

실제 활용 시나리오

멀티 팀 클러스터

여러 팀이 하나의 쿠버네티스 클러스터를 공유할 때, 각 팀별로 네임스페이스를 할당하고 ResourceQuota를 설정해 클러스터 자원을 공정하게 분배할 수 있다.

개발/테스트/프로덕션 환경 분리

같은 애플리케이션의 개발, 테스트, 프로덕션 환경을 네임스페이스로 분리하고, 각 환경에 맞는 ResourceQuota와 LimitRange를 설정할 수 있다.

자원 사용 최적화

LimitRange를 통해 파드의 기본 자원 요청과 제한을 설정함으로써, 개발자가 명시적으로 설정하지 않아도 적절한 자원 할당이 이루어지게 할 수 있다.

쿠버네티스의 자원 제한 모범 사례

ResourceQuota 설정 전략

  • 컴퓨팅 자원 관리: CPU와 메모리에 대한 requests와 limits를 모두 설정한다.
  • 스토리지 관리: 각 스토리지 클래스별로 사용량을 제한한다.
  • 오브젝트 수 제한: 특히 서비스, 컨피그맵, 시크릿 등의 수를 제한해 API 서버 부하를 관리한다.

LimitRange 설정 전략

  • 기본값 설정: 모든 컨테이너에 적절한 기본 requests와 limits를 설정한다.
  • 비율 제한: maxLimitRequestRatio를 통해 requests 값이 limits 값을 초과하지 않도록 제어하며 일반적으로 최대 비율은 3으로 설정한다.
  • 최소/최대 제한: 너무 작거나 큰 파드를 방지해 스케줄링 효율성을 유지한다.

Controller - ReplicaSet(Template, Replicas, Selector)


ReplicaSet은 쿠버네티스에서 애플리케이션 가용성을 보장하고 자동 복구 및 스케일링 기능을 제공하는 중요한 컨트롤러다. 이를 통해 애플리케이션의 가용성을 보장하며, Pod가 삭제되거나 실패할 경우 자동으로 새로운 Pod를 생성해 원하는 상태를 유지한다.

ReplicaSet의 주요 구성 요소

Template

Template은 ReplicaSet이 생성할 Pod의 정의를 포함하는 필드다. 여기에는 Pod의 메타데이터와 스펙이 포함되며, 새로운 Pod를 생성할 때 이 템플릿을 기반으로 한다.

Template 필드 구성

  • metadata: 생성될 Pod에 적용될 레이블과 이름 등을 정의한다.
  • spec: 컨테이너 이미지, 리소스 요청 및 제한, 볼륨 등 Pod의 스펙을 정의한다.

Template YAML 예시

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app-container
        image: my-image:latest
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"

위 예시에서 templateapp-container라는 이름의 컨테이너를 포함한 Pod를 생성하도록 정의되어 있다.

Replicas

Replicas는 ReplicaSet이 유지하려는 Pod의 개수를 설정하는 필드다. 이 값에 따라 ReplicaSet은 Pod를 생성하거나 삭제하여 원하는 개수를 유지한다.

Replicas 설정

  • .spec.replicas 필드를 통해 원하는 Pod 개수를 설정할 수 있다.
  • 기본값은 1이며, 설정하지 않으면 하나의 Pod만 유지된다.
  • Replicas 값을 변경하면 자동으로 스케일링이 이루어진다.

Replicas YAML 예시

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend-replicaset
spec:
  replicas: 5 # 원하는 Pod 개수 설정
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend-container
        image: nginx:latest

위 예시는 replicas 값을 5로 설정하여 frontend-container라는 이름의 컨테이너를 포함한 5개의 Pod를 유지하도록 정의한다.

Selector

Selector는 ReplicaSet이 관리할 Pod를 선택하기 위한 조건을 정의하는 필드다. Selector는 레이블 기반으로 작동하며, 조건에 맞는 Pod만 관리 대상으로 포함된다.

Selector 종류

  • matchLabels: 특정 레이블 키와 값이 일치하는 Pod를 선택한다.
  • matchExpressions: 더 복잡한 조건을 정의할 수 있으며, 다음 연산자를 지원한다.
    • In: 특정 값 중 하나와 일치하는 경우.
    • NotIn: 특정 값 중 하나와 일치하지 않는 경우.
    • Exists: 키가 존재하는 경우.
    • DoesNotExist: 키가 존재하지 않는 경우.

Selector YAML 예시

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: advanced-replicaset
spec:
  replicas: 3
  selector:
    matchLabels:
      app: advanced-app
    matchExpressions:
    - {key: environment, operator: In, values: [dev, prod]}
    - {key: version, operator: Exists}
  template:
    metadata:
      labels:
        app: advanced-app
        environment: dev
        version: v1.0
    spec:
      containers:
      - name: advanced-container
        image: my-app:v1.0

위 예시는 matchLabelsmatchExpressions를 함께 사용하여 특정 조건을 만족하는 Pod만 관리하도록 설정한다.

ReplicaSet의 작동 원리

ReplicaSet은 다음과 같은 방식으로 작동한다:

  1. Pod 생성
    .spec.template에 정의된 템플릿을 기반으로 필요한 수만큼 새로운 Pod를 생성한다.
  2. Pod 모니터링
    현재 실행 중인 Pod의 상태를 지속적으로 확인하며, 실패하거나 삭제된 경우 새로운 Pod를 생성해 복구한다.
  3. Pod 삭제
    .spec.replicas 값이 감소하면 초과된 Pod를 삭제하여 원하는 개수로 맞춘다.
  4. Selector 조건 충족 여부 확인
    Selector 조건에 맞는 기존 Pod가 있다면 이를 관리 대상으로 포함하고, 조건에 맞지 않는 경우 제외한다.

ReplicaSet 활용 사례

자동 복구 및 가용성 보장

ReplicaSet은 노드 장애나 자발적인 삭제로 인해 발생하는 서비스 중단을 방지하기 위해 사용된다. 실패한 Pod를 즉시 복구하여 애플리케이션 가용성을 유지할 수 있다.

스케일링

애플리케이션 트래픽 변화에 따라 .spec.replicas 값을 조정하여 수평적 확장을 수행할 수 있다. 이를 통해 트래픽 증가 시 더 많은 인스턴스를 실행하거나 감소 시 비용을 절감할 수 있다.

고급 레이블 기반 관리

Selector를 활용하면 특정 환경(dev/prod)이나 버전(v1/v2)에 따라 다른 ReplicaSet을 운영할 수 있다. 이를 통해 다양한 애플리케이션 배포 전략을 구현할 수 있다.

ReplicaSet 모범 사례

  • 템플릿과 Selector 일치
    .spec.template.metadata.labels에 정의된 레이블이 .spec.selector 조건과 반드시 일치해야 한다. 그렇지 않으면 API 서버에서 오류가 발생한다.
  • Deployment와 함께 사용
    Deployment는 ReplicaSet보다 더 많은 기능(롤링 업데이트 등)을 제공하며, 일반적으로 Deployment 내부에서 ReplicaSet을 사용하는 것이 권장된다.
  • 스케일링 전략
    트래픽 변화에 따라 적절히 .spec.replicas 값을 조정하여 효율적인 리소스 관리를 수행한다.
728x90
반응형

'기록 > Kubenetes' 카테고리의 다른 글

Kubernetes (5)  (0) 2025.04.15
Kubernetes (4)  (0) 2025.04.14
Kubernetes (2)  (0) 2025.04.10
Kubernetes (1)  (0) 2025.04.08