[K8s] 파드, 파드 라이프사이클

mjtwinsbbc·2025년 3월 25일

https://kubernetes.io/ko/docs/concepts/workloads/pods/
https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/

파드

쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위

파드는 하나 이상의 컨테이너 그룹이다. 이 그룹은 스토리지 및 네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다. 파드의 콘텐츠는 항상 함께 배치되고, 함께 스케줄되며, 공유 콘텍스트에서 실행된다.

1. 단일 컨테이너를 실행하는 파드

"파드 당 하나의 컨테이너" 모델은 가장 일반적인 쿠버네티스 유스케이스이다. 이 경우, 파드를 단일 컨테이너를 둘러싼 래퍼(wrapper)로 생각할 수 있다. 쿠버네티스는 컨테이너를 직접 관리하는 대신 파드를 관리한다.

2. 함께 작동해야 하는 여러 컨테이너를 실행하는 파드

파드는 밀접하게 결합되어 있고 리소스를 공유해야 하는 함께 배치된 여러 개의 컨테이너로 구성된 애플리케이션을 캡슐화할 수 있다. 이런 함께 배치된 컨테이너는 하나의 결합된 서비스 단위를 형성한다.

파드는 응집력있는 서비스 단위를 형성하는 여러 협력 프로세스(컨테이너)를 지원하도록 설계되었다. 파드의 컨테이너는 클러스터의 동일한 물리 또는 가상 머신에서 자동으로 같은 위치에 배치되고 함께 스케줄된다. 컨테이너는 리소스와 의존성을 공유하고, 서로 통신하고, 종료 시기와 방법을 조정할 수 있다.

다음 다이어그램에서와 같이 공유 볼륨의 파일에 대한 웹 서버 역할을 하는 컨테이너와, 원격 소스에서 해당 파일을 업데이트하는 별도의 "사이드카" 컨테이너가 있을 수 있다.

일부 파드에는 앱 컨테이너 뿐만 아니라 초기화 컨테이너를 갖고 있다. 초기화 컨테이너는 앱 컨테이너가 시작되기 전에 실행되고 완료된다.

파드와 컨트롤러

워크로드 리소스를 사용하여 여러 파드를 만들고 관리할 수 있다. 리소스에 대한 컨트롤러는 파드 장애 시 복제 및 롤아웃과 자동 복구를 처리한다. 예를 들어, 노드가 실패하면, 컨트롤러는 해당 노드의 파드가 작동을 중지했음을 인식하고 대체 파드를 생성한다. 스케줄러는 대체 파드를 정상 노드에 배치한다.

하나 이상의 파드를 관리하는 워크로드 리소스 예시

  • 디플로이먼트
    • 클러스터에서 복제된 애플리케이션 관리
  • 스테이트풀셋
    내구성이 있는 스토리지와 파드별로 지속성 식별자를 사용해 파드 집합의 디플로이먼트와 스케일링 관리
  • 데몬셋(DaemonSet)
    파드 복제본을 클러스터 노드 집합에서 동작하게 함

파드 템플릿

워크로드 리소스에 대한 컨트롤러는 파드 템플릿 에서 파드를 생성하고 사용자 대신 해당 파드를 관리한다.

파드템플릿(PodTemplate)은 파드를 생성하기 위한 명세이며, 디플로이먼트, 잡 및 데몬셋과 같은 워크로드 리소스에 포함된다.

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # 여기서부터 파드 템플릿이다
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure

위의 샘플은 하나의 컨테이너를 시작하는 template 이 있는 간단한 잡의 매니페스트이다. 해당 파드의 컨테이너는 메시지를 출력한 다음 일시 중지한다.

파드 템플릿을 수정하거나 새로운 파드 템플릿으로 바꿔도 이미 존재하는 파드에는 직접적인 영향을 주지 않는다. 워크로드 리소스의 파드 템플릿을 변경하는 경우, 해당 리소스는 수정된 템플릿을 사용하는 대체 파드를 생성해야 한다.

파드 갱신 및 교체

워크로드 리소스의 파드 템플릿이 바뀌면, 컨트롤러는 기존의 파드를 갱신하거나 패치하는 대신 갱신된 템플릿을 기반으로 신규 파드를 생성한다.

쿠버네티스는 사용자가 파드를 직접 관리하는 것을 막지는 않는다. 동작 중인 파드의 필드를 갱신하는 것도 가능하다. 그러나, patch 및 replace와 같은 파드 갱신 작업에는 다음과 같은 제약이 있다.

  • 파드에 대한 대부분의 메타데이터는 불변(immutable)이다. 사용자는 namespace, name, uid, 또는 creationTimestamp 필드를 변경할 수 없다.
  • metadata.deletionTimestamp 가 설정된 경우, metadata.finalizers 리스트에 새로운 항목이 추가될 수 없다.

리소스 공유와 통신

파드는 파드에 속한 컨테이너 간의 데이터 공유와 통신을 지원한다.

파드 스토리지

파드는 공유 스토리지 볼륨의 집합을 지정할 수 있다. 파드의 모든 컨테이너는 공유 볼륨에 접근할 수 있으므로, 해당 컨테이너가 데이터를 공유할 수 있다.

파드 네트워킹

각 파드에는 각 주소 패밀리에 대해 고유한 IP 주소가 할당된다. 파드의 모든 컨테이너는 네트워크 네임스페이스를 공유하며, 여기에는 IP 주소와 네트워크 포트가 포함된다.

파드 라이프사이클

파드는 정의된 라이프사이클을 따른다. Pending 단계에서 시작해서, 기본 컨테이너 중 적어도 하나 이상이 OK로 시작하면 Running 단계를 통과하고, 그런 다음 파드의 컨테이너가 실패로 종료되었는지 여부에 따라 Succeeded 또는 Failed 단계로 이동한다.

파드가 실행되는 동안, kubelet은 일종의 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있다. 파드 내에서, 쿠버네티스는 다양한 컨테이너 상태를 추적하고 파드를 다시 정상 상태로 만들기 위해 취할 조치를 결정한다.

파드는 파드의 수명 중 한 번만 스케줄된다. 파드가 노드에 스케줄(할당)되면, 파드는 중지되거나 종료될 때까지 해당 노드에서 실행된다.

파드 수명

개별 애플리케이션 컨테이너와 마찬가지로, 파드는 비교적 임시(계속 이어지는 것이 아닌) 엔티티로 간주된다. 파드가 생성되고, 고유 ID(UID)가 할당되고, 종료(재시작 정책에 따라) 또는 삭제될 때까지 남아있는 노드에 스케줄된다. 만약 노드가 종료되면, 해당 노드에 스케줄된 파드는 타임아웃 기간 후에 삭제되도록 스케줄된다.

파드는 자체적으로 자가 치유되지 않는다. 파드가 노드에 스케줄된 후에 해당 노드가 실패하면, 파드는 삭제된다. 마찬가지로, 파드는 리소스 부족 또는 노드 유지 관리 작업으로 인한 축출에서 살아남지 못한다. 쿠버네티스는 컨트롤러라 부르는 하이-레벨 추상화를 사용하여 상대적으로 일회용인 파드 인스턴스를 관리하는 작업을 처리한다.

UID로 정의된 특정 파드는 다른 노드로 절대 "다시 스케줄"되지 않는다. 대신, 해당 파드는 사용자가 원한다면 이름은 같지만, UID가 다른, 거의 동일한 새 파드로 대체될 수 있다.

파드 단계

파드의 status 필드는 phase 필드를 포함하는 PodStatus 오브젝트로 정의된다.

파드의 phase는 파드가 라이프사이클 중 어느 단계에 해당하는지 표현하는 간단한 고수준의 요약이다.

phase에 가능한 값

  • Pending
    파드가 쿠버네티스 클러스터에서 승인되었지만, 하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않았다. 여기에는 파드가 스케줄되기 이전까지의 시간 뿐만 아니라 네트워크를 통한 컨테이너 이미지 다운로드 시간도 포함된다.
  • Running
    파드가 노드에 바인딩되었고, 모든 컨테이너가 생성되었다. 적어도 하나의 컨테이너가 아직 실행 중이거나, 시작 또는 재시작 중에 있다.
  • Succeeded
    파드에 있는 모든 컨테이너들이 성공적으로 종료되었고, 재시작되지 않을 것이다.
  • Failed
    파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료되었다. 즉, 해당 컨테이너는 non-zero 상태로 빠져나왔거나(exited) 시스템에 의해서 종료(terminated)되었다.
  • Unknown
    어떤 이유에 의해서 파드의 상태를 얻을 수 없다. 이 단계는 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생한다.

노드가 죽거나 클러스터의 나머지와의 연결이 끊어지면, 쿠버네티스는 손실된 노드의 모든 파드의 phase 를 Failed로 설정하는 정책을 적용한다.

파드가 삭제될 때, 일부 kubectl 커맨드에서 Terminating 이 표시된다. 이 Terminating 상태는 파드의 단계에 해당하지 않는다. 파드에는 그레이스풀하게(gracefully) 종료되도록 기간이 부여되며, 그 기본값은 30초이다. 강제로 파드를 종료하려면 --force 플래그를 설정하면 된다.

컨테이너 상태

전체 파드의 단계뿐 아니라, 쿠버네티스는 파드 내부의 각 컨테이너 상태를 추적한다. 컨테이너 라이프사이클 훅(hook)을 사용하여 컨테이너 라이프사이클의 특정 지점에서 실행할 이벤트를 트리거할 수 있다.

일단 스케줄러가 노드에 파드를 할당하면, kubelet은 컨테이너 런타임을 사용하여 해당 파드에 대한 컨테이너 생성을 시작한다. 표시될 수 있는 세 가지 컨테이너 상태는 Waiting, Running 그리고 Terminated 이다.

  • Waiting
    만약 컨테이너가 Running 또는 Terminated 상태가 아니면, Waiting 상태이다. Waiting 상태의 컨테이너는 시작을 완료하는 데 필요한 작업(예를 들어, 컨테이너 이미지 레지스트리에서 컨테이너 이미지 가져오거나, 시크릿(Secret) 데이터를 적용하는 작업)을 계속 실행하고 있는 중이다. kubectl 을 사용하여 컨테이너가 Waiting 인 파드를 쿼리하면, 컨테이너가 해당 상태에 있는 이유를 요약하는 Reason 필드도 표시된다.

  • Running
    Running 상태는 컨테이너가 문제없이 실행되고 있음을 나타낸다. postStart 훅이 구성되어 있었다면, 이미 실행되고 완료되었다. kubectl 을 사용하여 컨테이너가 Running 인 파드를 쿼리하면, 컨테이너가 Running 상태에 진입한 시기에 대한 정보도 볼 수 있다.

  • Terminated
    Terminated 상태의 컨테이너는 실행을 시작한 다음 완료될 때까지 실행되었거나 어떤 이유로 실패했다. kubectl 을 사용하여 컨테이너가 Terminated 인 파드를 쿼리하면, 이유와 종료 코드 그리고 해당 컨테이너의 실행 기간에 대한 시작과 종료 시간이 표시된다.
    컨테이너에 구성된 preStop 훅이 있는 경우, 이 혹은 컨테이너가 Terminated 상태에 들어가기 전에 실행된다.

컨테이너 재시작 정책

파드의 spec 에는 restartPolicy 필드가 있다. 사용 가능한 값은 Always, OnFailure 그리고 Never이다. 기본값은 Always이다. restartPolicy는 파드의 모든 컨테이너에 적용된다.

파드 컨디션

파드는 하나의 PodStatus를 가지며, 그것은 파드가 통과했거나 통과하지 못한 PodConditions 배열을 가진다. kubelet은 다음 PodConditions를 관리한다.

  • PodScheduled: 파드가 노드에 스케줄됨
  • PodHasNetwork: (알파 기능; 반드시 명시적으로 활성화해야 함) 샌드박스가 성공적으로 생성되고 네트워킹이 구성됨
  • ContainersReady: 파드의 모든 컨테이너가 준비됨
  • Initialized: 모든 초기화 컨테이너가 성공적으로 완료(completed)됨
  • Ready: 파드는 요청을 처리할 수 있으며 일치하는 모든 서비스의 로드 밸런싱 풀에 추가되어야 함

파드 종료

파드는 클러스터의 노드에서 실행되는 프로세스를 나타내므로, 해당 프로세스가 더 이상 필요하지 않을 때 정상적으로 종료되도록 하는 것이 중요하다(KILL 시그널로 갑자기 중지되고 정리할 기회가 없는 것 보다).

일반적으로, 컨테이너 런타임은 각 컨테이너의 기본 프로세스에 TERM 신호를 전송한다. 많은 컨테이너 런타임은 컨테이너 이미지에 정의된 STOPSIGNAL 값을 존중하며 TERM 대신 이 값을 보낸다. 일단 유예 기간이 만료되면, KILL 시그널이 나머지 프로세스로 전송되고, 그런 다음 파드는 API 서버로부터 삭제된다. 프로세스가 종료될 때까지 기다리는 동안 kubelet 또는 컨테이너 런타임의 관리 서비스가 다시 시작되면, 클러스터는 전체 원래 유예 기간을 포함하여 처음부터 다시 시도한다.

파드 가비지 콜렉션

실패한 파드의 경우, API 오브젝트는 사람이나 컨트롤러 프로세스가 명시적으로 파드를 제거할 때까지 클러스터의 API에 남아 있다.

컨트롤 플레인에서의 컨트롤러 역할인 파드 가비지 콜렉터(PodGC)는, 파드 수가 구성된 임계값(kube-controller-manager에서 terminated-pod-gc-threshold 에 의해 결정됨)을 초과할 때 종료된 파드(Succeeded 또는 Failed 단계 포함)를 정리한다. 이렇게 하면 시간이 지남에 따라 파드가 생성되고 종료될 때 리소스 유출이 방지된다.

  1. 고아 파드 - 더이상 존재하지 않는 노드에 종속된 파드
  2. 스케줄되지 않은 종료 중인 파드
  3. NodeOutOfServiceVolumeDetach 기능 게이트가 활성화되어 있을 때, node.kubernetes.io/out-of-service에 테인트된 준비되지 않은 노드에 속한 종료 중인 파드

세 가지 조건 중 하나라도 만족한다면 PodGC는 정리를 시작한다.

0개의 댓글