Skip to content

KR_K8s_Workloads

somaz edited this page Jun 4, 2026 · 3 revisions

Kubernetes 워크로드 & 스케줄링

8. Kubernetes Autoscaling

Kubernetes Auto Scaling은 Kubernetes 클러스터가 워크로드에 따라 용량을 자동으로 조정하는 기능을 말한다.

파드(Pod)에 효율적으로 실행할 수 있는 충분한 리소스가 있는지 확인하는 동시에 낭비를 방지하기 위해 리소스 사용을 최적화하는 데 도움이 된다.

Kubernetes Autoscaler

일반적으로 stateless 서버는 HPA를 사용하는 것이 적합하다. VPA는 리소스를 변경하는 과정에서 pod의 재시작이 불가피하고, 하나의 node가 가질 수 있는 리소스(CPU, 메모리)에는 한계가 있기 때문이다.

  • HPA(Horizontal Pod Autoscaler): CPU 사용률 또는 메트릭을 기반으로 Replication Controller, Deployment, Replication set, Statefulset의 Pod 수를 자동으로 조정한다. 메트릭을 주기적으로 확인하고 관찰된 메트릭 값이 설정된 목표에서 벗어나는 경우 Replica 수를 조정한다. Scale out 하는 오토스케일러 이다.
  • VPA(Vertical Pod Autoscaler): Pod의 CPU 및 메모리 예약을 자동으로 조정하여 리소스 효율성을 보장한다. request 리소스 사용 기록을 기반으로 컨테이너의 값을 업데이트하여 각 파드가 효과적으로 실행하기에 충분한 리소스만 갖도록 한다. 변경 사항을 권장하거나 이러한 변경 사항을 자동으로 적용하도록 구성할 수 있다. Scale up 하는 오토스케일러 이다.
  • CA(Cluster Autoscaler): Kubernetes 클러스터 자체의 크기를 자동으로 조정한다. 리소스가 부족하여 실행에 실패한 클러스터에 파드가 있는 경우 더 많은 노드를 추가할 수 있다. 노드 사용률이 낮고 해당 파드가 다른 노드에서 예약될 수 있는 경우 이러한 노드를 제거할 수 있다.

Scale up vs Scale out

스케일업(수직 스케일링)과 스케일아웃(수평 스케일링)은 더 큰 부하나 수요를 처리하기 위해 시스템 용량을 증가시키기 위한 컴퓨팅 전략이다.

스케일업은 기존 서버에 CPU나 메모리 같은 리소스를 더 추가해 하드웨어나 소프트웨어의 용량을 늘리는 방식이다. 반면 스케일아웃은 노드나 인스턴스를 더 추가해 여러 서버에 부하를 효과적으로 분산하는 방식이다.

스케일업은 개별 구성 요소를 더 강력하게 만드는 데 초점을 맞추지만 스케일아웃은 더 큰 인프라에 워크로드를 분산시키는 것을 강조한다. 클라우드 컴퓨팅과 데이터 센터 관리에서 특히 중요한 개념이다. Scale UP and Scale Out

Reference


9. Kubernetes Probe

Kubernetes 프로브는 Kubernetes 클러스터 내의 Pod 상태를 관리하고 보장하는 데 중요한 구성 요소이다. 이를 통해 Kubernetes는 실행 중인 컨테이너에 대해 정기적인 검사를 수행하여 상태를 확인하고 애플리케이션의 상태에 따라 적절한 조치를 취할 수 있다.

Kubernetes가 사용하는 세 가지 주요 프로브 유형이 있다.

  • Liveness Probes: Liveness Probe는 컨테이너가 제대로 실행되고 있는지 확인한다. Liveness Probes가 실패하면 Kubernetes는 파드의 다시 시작 정책에 따라 컨테이너를 종료하고 새 컨테이너를 시작한다. 애플리케이션이 실행 중이지만 진행할 수 없는 상황(e.g., a deadlock)을 포착하고 처리하는 데 사용된다.
  • Readiness Probes: Readiness Probe는 컨테이너가 트래픽 수신을 시작할 준비가 되었는지 확인한다. Readiness Probes에 실패한 컨테이너는 Kubernetes Service로부터 트래픽을 수신하지 않는다. 이는 트래픽을 실제로 처리할 준비가 된 파드에만 트래픽이 전송되도록 하는 데 중요하며, 이는 시작 중이나 버전 업그레이드 후에 특히 유용하다.
  • Startup Probes: Startup Probe는 컨테이너 애플리케이션이 시작된 시기를 확인하는 데 사용된다. 파드를 시작하는 데 오랜 시간이 걸리는 경우(예: 긴 초기화 프로세스로 인해) 시작 프로브를 사용하여 파드가 시작 단계에서 활성 프로브에 의해 종료되는 것을 방지할 수 있다. Startup Probe가 처음으로 성공하면 자체적으로 비활성화되고 Liveness Probe가 후속 검사를 대신한다.

Configuring Probes

Probe는 파드 사양에서 구성될 수 있다.

각 Probe 유형은 검사를 수행하는 여러 가지 방법을 지원한다.

  • HTTP GET: Kubernetes는 컨테이너에 대해 HTTP GET 요청을 수행한다. 200~399 범위 내의 응답 코드는 성공을 나타낸다. 기타 응답 코드 또는 제한 시간 내에 연결에 실패하면 실패로 처리된다.
  • TCP Socket: Kubernetes는 컨테이너에 대한 TCP 소켓을 열려고 시도한다. 성공은 연결 설정 기능으로 표시되고, 실패는 제한 시간 내에 소켓을 열 수 없는 것으로 표시된다.
  • exec: Kubernetes는 컨테이너 내부에서 명령을 실행한다. 성공은 반환 코드 0으로 표시되고 다른 반환 코드는 실패를 나타낸다.
  • gRPC (Kubernetes 1.24+ GA): grpc.health.v1.Health 프로토콜로 gRPC Health Check를 수행한다. 별도의 HTTP /healthz 엔드포인트 없이 gRPC 네이티브 서비스(게임 서버, 마이크로서비스)에 적합하다.
livenessProbe:
  grpc:
    port: 50051
    service: my-service  # 선택 사항. 생략하면 서버 전체 상태를 확인한다.
  initialDelaySeconds: 10
  periodSeconds: 10

프로브 실패 시 동작 비교

프로브 실패 시 동작 영향 범위 복구
Startup Probe 컨테이너 재시작 (restartPolicy에 따름) 컨테이너 kubelet이 종료 후 재시작
Liveness Probe 컨테이너 재시작 컨테이너 kubelet이 종료 후 재시작
Readiness Probe Endpoint에서 Pod IP 제거 서비스 트래픽 프로브 성공 시 자동 복구

핵심 차이: Liveness 실패는 컨테이너를 재시작하지만, Readiness 실패는 트래픽만 차단한다.

구성 파라미터

  • initialDelaySeconds: 컨테이너 시작 후 첫 프로브까지의 대기 시간. 너무 짧으면 정상 컨테이너를 실패로 오판할 수 있다.
  • timeoutSeconds: 프로브 응답 최대 대기 시간. 느린 I/O 작업에는 값을 늘린다.
  • failureThreshold: 실패로 판정하기까지의 연속 실패 횟수. 민감도를 제어한다.
  • periodSeconds: 프로브 간격. 너무 짧으면 시스템 부하가 증가한다.

프레임워크별 권장 값

프레임워크 initialDelaySeconds periodSeconds timeoutSeconds failureThreshold
Spring Boot 30~60 10 5 3
Node.js (NestJS, Express) 5~10 5~10 3 3
Go (net/http) 3~5 10 3 3
Python (Django, FastAPI) 10~20 10 5 3

시작 시간이 예측 불가능한 앱은 initialDelaySeconds를 늘리는 대신 Startup Probe를 사용한다.

프로브 동작 순서

Kubernetes 프로브는 파드 사양(일반적으로 .spec.containers[] 필드 아래)에서 구성된다. Pod의 YAML 파일 내에서 각 프로브 유형을 구성하는 방법을 살펴보고 이러한 프로브가 작동하는 순서에 대해 알아본다.

apiVersion: v1
kind: Pod
metadata:
  name: my-application
spec:
  containers:
    - name: my-container
      image: my-image
      ports:
        - containerPort: 8080
      livenessProbe:
        httpGet:
          path: /healthz
          port: 8080
        initialDelaySeconds: 15
        timeoutSeconds: 2
        periodSeconds: 5
        failureThreshold: 3
      readinessProbe:
        httpGet:
          path: /ready
          port: 8080
        initialDelaySeconds: 5
        timeoutSeconds: 1
        periodSeconds: 5
        failureThreshold: 1
      startupProbe:
        exec:
          command:
            - cat
            - /app/initialized
        initialDelaySeconds: 5
        periodSeconds: 5
        failureThreshold: 30
  • 1. Startup Probe: Pod가 시작되면 Startup Probe는 정의된 조건을 확인하기 시작한다. Startup Probe가 성공할 때까지 활성 및 준비 프로브는 비활성화된다. 구성된 제한 시간 및 실패 임계값 내에 Startup Probe가 성공하지 못하면 컨테이너가 종료되고 파드의 다시 시작 정책에 따라 다시 예약된다.
  • 2. Readiness Probe: Startup Probe가 성공하면 Readiness Probe가 시작된다. Readiness Probe는 컨테이너가 요청을 받을 준비가 되었는지 확인한다. 실패하면 Readiness 확인을 통과할 때까지 컨테이너가 서비스의 로드 밸런서에서 제거된다.
  • 3. Liveness Probe: Readiness Probe와 함께 Liveness Probe는 컨테이너가 예상대로 계속 실행되고 있는지 확인한다. Liveness Probe가 실패하면(초기 지연 이후 및 실패 임계값 내에서) 컨테이너가 다시 시작된다.

Reference


10. Kubernetes Affinity and Scheduling

Kubernetes에서는 다음과 같은 여러 메커니즘을 통해 클러스터 내에서 파드가 배포되는 위치를 제어할 수 있다.

  • 노드 셀렉터(NodeSelector)
  • 어피니티(Affinity)
  • 테인트 & 톨러레이션(Taints & Toleration)
  • 커든(Cordon)
  • 드레인(Drain)

1. 노드 셀렉터(NodeSelector):

  • Kubernetes에서 가장 간단한 스케줄링 제약 조건이다.
  • 키-값 쌍을 사용하여 노드를 선택한다.
  • 예제:
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
      nodeSelector:
        disktype: ssd

2. 어피니티(Affinity):

  • 노드 셀렉터보다 고급이며, 특정 파드 배치에 대한 규칙을 설정한다.

  • 주요 유형: 노드 어피니티(Node Affinity) 및 파드 어피니티(Pod Affinity).

  • 노드 어피니티:

    • requiredDuringSchedulingIgnoredDuringExecution 또는 preferredDuringSchedulingIgnoredDuringExecution으로 설정할 수 있다.
    • 예제:
      apiVersion: v1
      kind: Pod
      metadata:
        name: nginx
      spec:
        affinity:
          nodeAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
              nodeSelectorTerms:
                - matchExpressions:
                    - key: disktype
                      operator: In
                      values:
                        - ssd
        containers:
          - name: nginx
            image: nginx
    • requiredDuringSchedulingIgnoredDuringExecution
      • 파드가 스케줄링될 때 반드시 충족해야 하는 요구사항을 정의한다. 규칙을 만족하는 노드에만 파드가 스케줄될 수 있다.
      • 특정 노드에 파드를 배치해야 할 때 사용한다. 예를 들어, 특정 라벨이 있는 노드에만 파드를 배치하고 싶은 경우 이 규칙을 사용할 수 있다.
      • 만약 이 규칙을 만족하는 노드가 없다면, 파드는 스케줄되지 않는다.
    • preferredDuringSchedulingIgnoredDuringExecution
      • 스케줄러에게 파드가 스케줄링될 때 선호되는(하지만 필수는 아닌) 요구사항을 알린다. 스케줄러는 이 규칙을 가능한 한 충족시키려고 시도하지만, 규칙을 만족하는 노드가 없어도 파드는 다른 노드에 스케줄될 수 있다.
      • 파드의 배치에 더 유연성을 제공하고자 할 때 사용한다. 예를 들어, 특정 노드에 파드를 선호적으로 배치하고 싶지만, 그러한 노드가 없거나 사용할 수 없는 경우 다른 노드에도 배치될 수 있도록 하고 싶을 때 사용할 수 있다.
      • 이 규칙을 만족하는 노드가 있으면 그 노드에 파드가 우선적으로 스케줄되지만, 만족하는 노드가 없어도 파드는 스케줄될 수 있다.
    • 요약하자면, requiredDuringSchedulingIgnoredDuringExecution은 파드를 스케줄링할 때 반드시 충족해야 하는 엄격한 요구사항을 정의하는 반면, preferredDuringSchedulingIgnoredDuringExecution은 선호되는 조건을 정의하지만, 이 조건이 충족되지 않더라도 파드가 스케줄될 수 있도록 유연성을 제공한다.
  • 노드 안티-어피니티:

    • 특정 노드의 속성이나 라벨을 기반으로 하여 파드를 해당 노드로부터 멀리 배치하고자 할 때 사용한다.
    • 노드 안티-어피니티는 노드 어피니티와 유사하게 작동하지만, 반대의 목적을 가지고 있다.
    • 예제 : 이 예제에서 requiredDuringSchedulingIgnoredDuringExecution은 disktype이 hdd가 아닌 노드에 파드를 배치하도록 요구한다. 즉, SSD 또는 다른 유형의 디스크를 사용하는 노드에만 파드가 배치될 수 있다. 또한, preferredDuringSchedulingIgnoredDuringExecution 설정은 cpu가 high가 아닌 노드를 선호하지만, 이는 필수 조건이 아다. weight는 이 선호도의 중요성을 나타낸다.
    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: disktype
                    operator: NotIn
                    values:
                      - hdd
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 1
              preference:
                matchExpressions:
                  - key: cpu
                    operator: NotIn
                    values:
                      - high
      containers:
        - name: mycontainer
          image: myimage
  • 파드 어피니티:

    • 다른 파드의 레이블을 기준으로 규칙을 설정하는 데 사용된다.
    • 역시 하드 어피니티와 소프트 어피니티 규칙을 정의할 수 있다.
    • 다른 파드와 가깝게 배치되기를 원할 때 사용한다.
    • 예제 : requiredDuringSchedulingIgnoredDuringExecution 예제에서, mypod는 app=database 레이블을 가진 다른 파드와 같은 호스트(kubernetes.io/hostname)에 배치되어야 한다.
    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - database
              topologyKey: "kubernetes.io/hostname"
        containers:
          - name: mycontainer
            image: myimage
  • 파드 안티-어피니티:

    • 파드를 특정 레이블을 가진 다른 파드로부터 멀리 배치하고자 할 때 사용한다.
    • 예제 : requiredDuringSchedulingIgnoredDuringExecution 예제에서, mypod는 app=webserver 레이블을 가진 다른 파드와는 다른 호스트(kubernetes.io/hostname)에 배치되어야 한다.
    apiVersion: v1
    kind: Pod
    metadata:
      name: mypod
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - webserver
              topologyKey: "kubernetes.io/hostname"
        containers:
          - name: mycontainer
            image: myimage
  1. 테인트 & 톨러레이션(Taints & Toleration):

    • 테인트는 특정 노드에 적용되어 톨러레이션을 갖지 않는 파드를 거부한다.
    • 톨러레이션은 테인트가 적용된 노드에 스케줄링될 수 있도록 파드에 설정한다.
    • 테인트 적용 예제:
      kubectl taint nodes 노드이름 키=값:효과
      
    • 톨러레이션 설정 예제:
      tolerations:
        - key: "key"
          operator: "Equal"
          value: "value"
          effect: "NoSchedule"
  2. 커든(Cordon):

    • 특정 노드를 스케줄 불가능 상태로 표시하여 새로운 파드가 해당 노드에 스케줄되지 않도록 하는 데 사용된다.
    • 예제 명령어:
      kubectl cordon 노드이름
      
  3. 드레인(Drain):

    • 노드에서 모든 파드를 추방하여 유지보수 또는 노드 폐기를 위해 사용된다.
    • PodDisruptionBudgets를 존중하며 --ignore-daemonsets=true 옵션이 사용되지 않는 한 DaemonSet으로 관리되는 파드는 제거하지 않는다.
    • 예제 명령어:
      kubectl drain 노드이름
      

Reference


12. Operator란? (With Kubernetes)

Kubernetes 생태계에서 Operator는 Kubernetes 애플리케이션을 패키징, 배포, 관리하는 방법이다. Kubernetes 애플리케이션은 Kubernetes에 배포되고 Kubernetes API 및 kubectl 도구를 사용하여 관리된다. Operator는 클러스터 상태를 감시한 다음 필요한 경우 변경을 수행하거나 요청하는 루프인 컨트롤러의 Kubernetes 원칙을 따른다. Operator는 Kubernetes를 확장하여 특정 애플리케이션의 전체 수명주기 관리를 자동화한다.

개념 및 작동 방식

Operator는 본질적으로 도메인별 지식이 내장된 맞춤형 컨트롤러이다. 특정 애플리케이션을 배포, 업그레이드, 구성, 복구 및 확장하는 방법을 알고 있다. Operator 패턴은 소프트웨어에서 애플리케이션을 관리하고, 일반적인 작업을 자동화하고, Kubernetes 기반 애플리케이션 관리 방법을 제공하는 방법에 대한 운영 지식을 포착하는 것을 목표로 한다.

Operator는 사용자 정의 리소스 세트(Custom Resource)와 해당 리소스에 대한 사용자 정의 컨트롤러(Custom Controllers)로 구현된다. 사용자 정의 리소스는 애플리케이션의 구성 스키마 역할을 하며 컨트롤러는 애플리케이션의 상태가 사용자 정의 리소스에 설명된 원하는 상태와 일치하도록 작동한다.

  • 사용자 정의 리소스(Custom Resource): 새로운 리소스 유형 생성을 허용하도록 Kubernetes API를 확장한다. 사용자 정의 리소스는 원하는 애플리케이션 상태를 정의한다.
  • 사용자 정의 컨트롤러(Custom Controllers): 사용자 정의 리소스를 관찰하고 애플리케이션의 실제 상태가 사용자 정의 리소스에 정의된 원하는 상태와 다르다는 것을 감지하면 차이점을 조정하기 위한 조치를 취한다.

수명주기(lifecycle) 관리

Operator는 애플리케이션을 관리하기 위해 Kubernetes의 control loop 개념을 사용한다. 애플리케이션의 상태를 지속적으로 모니터링하고 원하는 상태와의 불일치를 수정하기 위해 애플리케이션별 조치를 취한다.

  • 애플리케이션 배포 및 잠재적인 지원 서비스 자동 배포
  • 복잡한 상태 저장 애플리케이션을 포함하여 업그레이드 및 다운그레이드를 원활하게 처리
  • 애플리케이션 구성 및 비밀 관리
  • 로드 또는 기타 지표를 기반으로 자동 확장
  • 오류 복구, 비정상 인스턴스 자동 교체 또는 재구성
  • 백업 및 복원

오퍼레이터 개발

오퍼레이터를 개발하기 위한 프레임워크 및 도구들이 있다.

  • 오퍼레이터 SDK(Operator SDK): 오퍼레이터의 개발, 테스트, 패키징을 도와준다.
  • 오퍼레이터 생명주기 관리자(Operator Lifecycle Manager) (OLM): Kubernetes 클러스터 상의 오퍼레이터들을 관리하며, 오퍼레이터의 설치, 업데이트 및 생명주기 관리를 담당한다.
  • 오퍼레이터 미터링(Operator Metering): 오퍼레이터가 사용하는 자원에 대한 보고를 위한 것이다.

14. Kubernetes Custom Resource Definitions (CRDs)란?

Kubernetes 사용자 정의 리소스 정의(CRD)는 사용자 정의 리소스로 Kubernetes 기능을 확장할 수 있는 강력한 기능이다. CRD를 사용하면 파드, 배포 또는 서비스와 같은 표준 Kubernetes 리소스가 처리되는 방식과 유사한 방식으로 Kubernetes 클러스터 내에 고유한 특정 리소스를 생성할 수 있다. 이는 Kubernetes 플랫폼을 기반으로 맞춤형 애플리케이션이나 통합을 개발하는 데 매우 유용할 수 있다.

커스텀 리소스(Custom Resource)란?

사용자 정의 리소스는 기본 Kubernetes 설치에서 반드시 사용할 수 있는 것은 아닌 Kubernetes API의 확장이다. 이는 기본적으로 제공되는 리소스 외에 새로운 리소스를 추가하여 요구 사항에 맞게 Kubernetes를 사용자 정의하는 방법이다.

CRD를 사용하는 이유는 무엇일까?

  • 확장성(Extensibility): kubectl 및 기타 Kubernetes API 클라이언트와 함께 사용할 수 있는 자체 API로 Kubernetes를 확장할 수 있다.
  • 유연성(Flexibility): 기본 Kubernetes 리소스처럼 작동하는 새 리소스를 정의할 수 있다.
  • 통합(Integration): CRD는 사용자 지정 리소스를 기반으로 애플리케이션과 해당 구성 요소를 관리하는 사용자 지정 컨트롤러인 연산자를 구축하는 데 유용하다.

CRD는 어떻게 작동할까?

CRD를 구현하려면 다른 Kubernetes 리소스와 마찬가지로 YAML을 사용하여 정의한다. 이 정의는 새로운 종류의 리소스, 해당 이름 및 스키마를 지정한다. 스키마는 CRD(사용자 지정 리소스라고도 함) 인스턴스 구성의 유효성을 검사하는 데 사용된다.

CRD 정의의 기본 구조는 다음과 같다.

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # Name of the CRD
  name: crdtype.mycompany.com
spec:
  # Group name to which the CRD belongs
  group: mycompany.com
  # List of versions
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                myField:
                  type: string
  # Scope of the CRD (Namespaced or Cluster)
  scope: Namespaced
  names:
    # Plural name used in the URL
    plural: crdtypes
    # Singular name used as an alias
    singular: crdtype
    # Kind is the serialized kind of the resource
    kind: CrdType
    # ShortNames allow shorter string to match your resource on kubectl
    shortNames:
      - ct

라이프사이클 및 컨트롤러(Lifecycle and Controllers)

클러스터에서 CRD를 정의하고 적용한 후에는 Kubernetes의 다른 리소스와 마찬가지로 해당 인스턴스를 생성하고 관리할 수 있다.

다음은 사용자 정의 리소스의 기본 예이다.

apiVersion: mycompany.com/v1
kind: CrdType
metadata:
  name: example-crdtype
spec:
  myField: "Hello, world!"
  • 일반적으로 CRD는 CRD 자체와 사용자 정의 컨트롤러로 구성된 연산자의 일부이다. 컨트롤러는 사용자 지정 리소스와 관련된 이벤트를 감시하고 이에 따라 리소스를 생성, 업데이트, 삭제 또는 조정하여 반응한다.

모범 사례 및 고려 사항

  • 버전 관리(Versioning): 기존 리소스에 지장을 주지 않도록 CRD의 버전을 신중하게 관리하고 업그레이드 및 지원 중단을 신중하게 처리하는 것이 중요하다.
  • 검증(Validation): CRD 정의의 OpenAPI 스키마 사양을 사용하여 사용자 지정 리소스를 검증하고 Kubernetes API에 저장되기 전에 기대치를 충족하는지 확인한다.
  • 성능(Performance): 특히 대규모 클러스터에서 사용자 지정 컨트롤러가 성능에 미치는 영향을 주시한다.

15. Kubernetes Garbage Collection (GC)란?

Kubernetes GC(Garbage Collection)는 주로 파드, 컨테이너, 이미지 및 기타 Kubernetes 리소스와 같이 사용되지 않는 객체를 제거하는 데 중점을 두고 리소스 정리를 자동으로 관리하는 시스템이다. Kubernetes에는 3가지 주요 유형의 Garbage Collection이 있다.

  • Garbage Collection of Pods and Controllers
  • Container Image Garbage Collection
  • Resource Finalizers

Kubernetes Garbage Collection Workflow

flowchart TB
    api["API Server"] -- "Receives Updates and Watches" --> ct["Controller"]
    ct -- "Manages Resources" --> rs["ReplicaSet, Deployments, etc."]
    rs -- "Owns" --> pods["Pods"]

    ct -- "Detects Deletions & Updates" --> gc["Garbage Collector"]
    gc -- "Removes Orphans" --> pods

    kubelet["Kubelet"] -- "Manages Pod Lifecycle" --> node["Node"]
    kubelet -- "Performs Image GC" --> img["Container Images"]
Loading

워크로드 운영 Q&A (StatefulSet / CronJob / DaemonSet)

Q26. StatefulSet의 Headless Service와 Persistent Volume 관리는?

  • Headless Service(clusterIP: None)는 개별 Pod DNS(pod-0.service.namespace.svc.cluster.local)를 제공하여 StatefulSet Pod를 직접 접근한다.
  • volumeClaimTemplates는 각 Pod에 독립적인 PVC를 자동 생성하고, Pod 재시작 시 동일한 PVC를 재연결한다.
  • Pod 삭제 시 PVC는 보존되며, StatefulSet 삭제 시에도 수동 삭제가 필요하다.
  • 순서 보장: pod-0부터 순차 생성, 역순 삭제. podManagementPolicy: OrderedReady(순차) vs Parallel(병렬). partition을 사용한 Canary 업데이트가 가능하다.

Q27. CronJob의 시간대 문제와 실패 처리 전략은?

  • CronJob은 UTC 기준으로 동작하므로 한국 시간(KST, UTC+9) 고려가 필요하다. timeZone 필드(K8s 1.25+)로 명시적 설정 가능하다.
  • concurrencyPolicy: Allow(중복 실행 허용), Forbid(이전 Job 완료 전 skip), Replace(이전 Job 종료 후 실행).
  • startingDeadlineSeconds는 스케줄 놓쳤을 때 재시도 기한이다. 실패 처리: backoffLimit으로 재시도 횟수 제한,
  • restartPolicy: OnFailure로 Pod 재시작. 멱등성 보장이 중요하며, 분산 락(Redis, etcd)으로 중복 실행 방지한다.

Q28. DaemonSet의 업데이트 전략과 노드 선택 방법은?

  • DaemonSet은 모든(또는 특정) 노드에 정확히 1개 Pod를 실행한다.
  • updateStrategy: RollingUpdate(순차 업데이트, maxUnavailable로 제어) vs OnDelete(수동 삭제 시 업데이트).
  • RollingUpdate는 한 번에 하나씩 업데이트하여 안전하다.
  • 노드 선택: nodeSelector(단순), nodeAffinity(고급), tolerations(Taint 허용)를 조합한다.
  • 특정 노드 제외는 nodeName AntiAffinity로 설정한다.
  • Monitoring Agent(node-exporter), CNI, kube-proxy는 DaemonSet으로 배포하며, 마스터 노드도 포함하려면 Toleration을 추가한다.

참고

Clone this wiki locally