라이프사이클
쿠버네티스 공식문서를 확인하며 파드 라이프사이클에 대해서 기억해야 하는 부분을 기록한다.
- 파드는 정의된 라이프사이클을 따르며,
Pending
단계에서 시작해서, 기본 컨테이너 중 적어도 하나 이상이 OK로 시작하면Running
단계를 통과하고, 파드의 컨테이너가 실패로 종료되었는지 여부에 따라Succeeded
또는Failed
단계로 이동한다. - 파드가 실행되는 동안, kubelet은 일종의 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있다.
- 파드 내에서, 쿠버네티스는 다양한 컨테이너 상태를 추적하고 파드를 다시 정상 상태로 만들기 위해 취할 조치를 결정한다.
- 쿠버네티스 API에서 파드는 명세와 실제 상태를 모두 가지고 이러한 오브젝트의 상태는 일련의 파드 컨디션으로 구성된다.
- 사용자의 애플리케이션에 유용한 경우, 파드의 컨디션 데이터에 사용자 정의 준비성 정보를 삽입할 수도 있다.
- 파드는 파드의 수명 중 한 번만 스케줄된다. 파드가 노드에 스케줄(할당)되면, 파드는 중지되거나 종료될 때까지 해당 노드에서 실행된다.
[정리]
파드는 정해진 여러 단계의 라이프사이클을 따르고 파드가 실행되는 동안 컨테이너의 상태를 추적하여 원하는 상태를 만들기 위해 kubelet은 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있다.
파드는 명세와 실제 상태를 모두 가지고 있으며 오브젝트의 상태는 파드의 컨디션으로 구성된다. 이러한 컨디션에는 사용자가 정의한 정보를 삽입할 수 있다.
파드는 전체 수명 중 단 한번만 스케줄되고 중지되거나 종료될 때까지 실행된 노드에서만 실행된다.
파드의 수명
- 개별 애플리케이션 컨테이너와 마찬가지로, 파드는 비교적 임시 엔티티로 간주된다.
- 파드가 생성되고, 고유 ID(UID)가 할당되고, 종료(재시작 정책에 따라) 또는 삭제될 때까지 남아있는 노드에 스케줄된다.
- 만약 노드가 종료되면, 해당 노드에 스케줄된 파드는 타임아웃 기간 후에 삭제되도록 스케줄된다.
- 파드는 자체적으로 자가 치유되지 않고, 파드가 노드에 스케줄된 후에 해당 노드가 실패하면 파드는 삭제된다.
- 마찬가지로, 파드는 리소스 부족 또는 노드 유지 관리 작업으로 인한 축출에서 살아남지 못한다.
- 쿠버네티스는 컨트롤러라 부르는 하이-레벨 추상화를 사용하여 상대적으로 일회용인 파드 인스턴스를 관리하는 작업을 처리한다.
- UID로 정의된 특정 파드는 다른 노드로 절대 “다시 스케줄”되지 않는 대신 해당 파드는 사용자가 원한다면 이름은 같지만, UID가 다른 거의 동일한 새 파드로 대체될 수 있다.
- 볼륨과 같은 어떤 것이 파드와 동일한 수명을 갖는다는 것은, 특정 파드가 존재하는 한 어떠한 그것도 존재한다는 것을 의미한다.
- 이유를 불문하고 해당 파드가 삭제되고 동일한 파드가 생성되면, 동일한 수명을 갖는 그것도 폐기되고 새로 생성된다.
[정리]
파드는 컨테이너와 같이 한 번 사용되고 버려지는 일회성 임시 엔티티로 간주된다. 파드가 생성되고 삭제될 때까지 남아있는 노드에서 스케줄되고, 노드가 종료되면 일정 기간 후에 삭제된다. 파드는 자가 치유가 되지 않고 문제가 발생하면 이를 대체하는 새로운 파드가 생성된다.
UID로 정의된 파드와 동일한 이름의 파드를 생성할 수는 있지만 UID가 다른 거의 동일한 파드가 생성된다.
볼륨과 같이 파드와 생명 주기를 같이 하는 것들은 파드가 삭제될 때 같이 삭제된다. 또한, 파드가 삭제되었다가 재실행되었다면 볼륨 또한 삭제되었다가 재실행된다는 것을 의미한다.
파드의 단계(phase)
- 파드의
status
필드는phase
필드를 포함하는 PodStatus 오브젝트로 정의된다. - 파드의 phase는 파드가 라이프사이클 중 어느 단계에 해당하는지 표현하는 간단한 고수준의 요약이다.
- Phase는 컨테이너나 파드의 관측 정보에 대한 포괄적인 롤업이나, 포괄적인 상태 머신을 표현하도록 의도되지는 않았다.
- 파드 phase 값에서 숫자와 의미는 엄격하게 지켜지며 하단에 명시되어 있는 내용 이외에는 파드와 파드에 주어진
phase
값에 대해서 어떤 사항도 가정되어서는 안 된다.
값 | 의미 |
---|---|
Pending | 파드가 쿠버네티스 클러스터에서 승인되었지만, 하나 이상의 컨테이너가 설정되지 않았고 실행할 준비가 되지 않았다. 여기에는 파드가 스케줄되기 이전까지의 시간 뿐만 아니라 네트워크를 통한 컨테이너 이미지 다운로드 시간도 포함된다. |
Running | 파드가 노드에 바인딩되었고, 모든 컨테이너가 생성되었다. 적어도 하나의 컨테이너가 아직 실행 중이거나, 시작 또는 재시작 중에 있다. |
Success | 파드에 있는 모든 컨테이너들이 성공적으로 종료되었고, 재시작되지 않을 것이다. |
Failed | 파드에 있는 모든 컨테이너가 종료되었고, 적어도 하나 이상의 컨테이너가 실패로 종료되었다. |
즉, 해당 컨테이너는 non-zero 상태로 빠져나왔거나(exited) 시스템에 의해서 종료(terminated)되었다. | |
Unknown | 어떤 이유에 의해서 파드의 상태를 얻을 수 없다. 이 단계는 일반적으로 파드가 실행되어야 하는 노드와의 통신 오류로 인해 발생한다. |
- 파드가 삭제될 때, 일부 kubectl 커맨드에서 Terminating이 표시된다. 이 상태는 파드의 단계에 해당하지 않는다. | |
- 파드에는 그레이스풀하게(gracefully) 종료되도록 기간이 부여되며, 그 기본값은 30초이며 강제로 종료하려면 --force 플래그를 설정하면 된다. |
|
- 노드가 죽거나 클러스터의 나머지와의 연결이 끊어지면, 쿠버네티스는 손실된 노드의 모든 파드의 phase 를 Failed로 설정하는 정책을 적용한다. |
[정리]
파드의 status
필드는 PodStatus 오브젝트로 정의되고 어드 단계인지를 표현한다. 단계는 포괄적인 상태를 표현하도록 의도되지는 않았으며 공식문서에 정의되어 있는 값을 제외하고는 가정해서는 안된다. 예를 들어, 파드가 삭제될 때 잠시 terminating이라고 표시되는 데 이것은 파드의 상태가 아니라 파드가 그레이스풀하게 종료되기 위한 과정이기 때문이다.
컨테이너 상태
- 쿠버네티스는 전체 파드의 단계(phase) 뿐만 아니라 각 컨테이너 상태(status)를 추적한다.
- 컨테이너 라이프사이클 훅(hook)을 사용하여 컨테이너 라이프사이클의 특정 시점에서 실행할 이벤트를 트리거할 수 있다.
- 스케줄러가 노드에 파드를 할당하면, kubelet은 컨테이너 런타임을 사용하여 해당 파드에 대한 컨테이너 생성을 시작한다.
- 표시될 수 있는 세 가지 컨테이너 상태는
Waiting
,Running
,Terminated
이다. - 파드의 컨테이너 상태를 확인하려면,
kubelet describe pod <name-of-pod>
를 사용할 수 있고 출력 결과는 해당 파드 내의 각 컨테이너 상태가 표시된다.- Waiting: 컨테이너가
Running
또는Terminated
상태가 아니면,Waiting
상태다.Waiting
상태의 컨테이너는 이미지 레지스트리와 같은 곳에서 이미지를 Pull 하는 것과 같이 컨테이너를 실행하고 있는 중이다.kubelet
을 사용하여 컨테이너가Waiting
인 파드를 쿼리하면, 컨테이너가 해당 상태에 있는 이유를 요약하는 Reason 필드도 표시된다. - Running:
Running
상태는 컨테이너가 문제없이 실행되고 있음을 나타낸다.postStart
훅이 구성되어 있다면, 이미 실행되고 완료된 것이다.kubelet
을 사용하여 컨테이너가Running
인 파드를 쿼리하면, 컨테이너가Running
상태에 진입한 시기에 대한 정보도 볼 수 있다. - Terminated:
Terminated
상태의 컨테이너는 실행을 시작한 다음 완료될 때까지 실행되었거나 어떤 이유로 실패한 상태다.kubectl
을 사용하여 컨테이너가Terminated
인 파드를 쿼리하면, 이유와 종료 코드 그리고 해당 컨테이너의 실행 기간에 대한 시작과 종료 시간이 표시된다.
컨테이너에 구성된preStop
훅이 있는 경우, 이 훅은 컨테이너가Terminated
상태에 들어가기 전에 실행된다.
- Waiting: 컨테이너가
[정리]
컨테이너는 단계뿐만 아니라 상태까지 가지고 있으며 특정 라이프사이클 시점이 되었을 때 발생하는 이벤트를 트리거할 수 있다. 컨테이너가 표시할 수 있는 상태는 총 세개로 Waiting
, Running
, Terminated
가 있다.
컨테이너 재시작 정책
- 파드의
spec
에는restartPolicy
필드가 있으며 기본 값은 Always이고 추가로 사용 가능한 값으로는 OnFailure와 Never가 있다. restartPolicy
는 파드의 모든 컨테이너에 적용되며restartPolicy
는 동일한 노드에서 kubelet에 의한 컨테이너 재시작만을 의미한다.- 파드의 컨테이너가 종료된 후, kubelet은 5분으로 제한되는 지수 백오프 지연(10초 ,20초 ..)으로 컨테이너를 재시작한다.
- 컨테이너가 10분 동안 아무런 문제없이 실행되면, kubelet은 해당 컨테이너의 재시작 백오프 타이머를 재설정한다.
[정리]
파드의 spec
에 재시작 정책을 지정할 수 있으며 Always, OnFailure, Never 세 개의 값이 선택 가능하다. 선택된 정책은 모든 컨테이너에 적용된다.
파드의 컨디션
- 파드는 하나의 PodStatus를 가지며, 그것은 파드가 통과했거나 통과하지 못한 PodConditions 배열을 가진다.
PodScheduled
: 파드가 노드에 스케줄되었다.ContainersReady
: 파드의 모든 컨테이너가 준비되었다.Initialized
: 모든 초기화 컨테이너가 성공적으로 완료(completed)되었다.Ready
: 파드는 요청을 처리할 수 있으며 일치하는 모든 서비스의 로드 밸런싱 풀에 추가되어야 한다.
필드 이름 | 설명 |
---|---|
type | 이 파드 컨디션의 이름이다. |
status | 가능한 값이 “true”, “False”, 또는 “Unknown”으로, 해당 컨디션이 적용 가능한지 여부를 나타낸다. |
lastProbeTime | 파드 컨디션이 마지막으로 프로브된 시간의 타임스탬프이다. |
lastTransitionTime | 파드가 한 상태에서 다른 상태로 전환된 마지막 시간에 대한 타임스탬프이다. |
reason | 컨디션의 마지막 전환에 대한 이유를 나타내는 기계가 판독 가능한 UpperCamelCase 텍스트이다. |
message | 마지막 상태 전환에 대한 세부 정보를 나타내는 사람이 읽을 수 있는 메시지이다. |
[정리]
파드는 하나의 PodStatus를 가지고 있으며 파드의 상태를 확인하기 위한 정보를 포함하는 PodConditions 배열을 가지고 있다.
파드의 준비성(readiness)
- 애플리케이션은 추가 피드백 또는 신호를 PodStatus: Pod readiness와 같이 주입할 수 있고 주입을 위해서, kubelet이 파드의 준비성을 평가하기 위한 추가적인 컨디션들을 파드의
spec
내readnessGate
필드를 통해서 지정할 수 있다. - 준비성 게이트는 파드에 대한
**status.condition
필드의 현재 상태에 따라 결정되고,status.condition
필드에서 **해당하는 컨디션을 찾지 못하면 기본값인False
가 된다. 아래는 파드의 준비성을 확인하기 위한 예제이다.
kind: Pod
...
spec:
readinessGates:
- conditionType: "www.example.com/feature-1"
status:
conditions:
- type: Ready # 내장된 PodCondition이다
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
- type: "www.example.com/feature-1" # 추가적인 PodCondition
status: "False"
lastProbeTime: null
lastTransitionTime: 2018-01-01T00:00:00Z
containerStatuses:
- containerID: docker://abcd...
ready: true
...
- 추가하는 파드 상태에는 쿠버네티스 레이블 키 포맷을 충족하는 이름이 있어야 한다.
파드 준비성 상태
kubectl patch
명령어는 아직 오브젝트 상태 패치(patching)를 지원하지 않고**status.conditions
을 파드에 설정하려면 애플리케이션과 오퍼레이터의PATCH
액션**을 필요로 한다.- 쿠버네티스 클라이언트를 사용해서 파드 준비성에 대한 사용자 지정 파드 컨디션을 설정하는 코드를 작성할 수 있다.
- 사용자 지정 컨디션을 사용하는 파드의 경우, 아래의 두 가지 컨디션이 모두 적용되는 경우에만 해당 파드가 준비된 것으로 평가된다.
- 파드 내의 모든 컨테이너들이 준비 상태이다.
readinessGates
에 지정된 모든 컨디션들이True
이다.
- 파드의 컨테이너가 Ready나 적어도 한 개의 사용자 지정 컨디션이 빠졌거나
False
이면, kubelet은 파드의 컨디션을ContainerReady
로 설정한다.
[정리]
kubelet이 파드의 준비성을 평가하기 위해 추가적인 컨디션들을 파드의 spec
내 readnessGate
필드를 통해서 지정할 수 있다. 준비성 게이트는 파드에 대한 status.condition
필드의 현재 상태에 따라 결정되고, 해당하는 컨디션을 찾지 못하면 기본값인 False
가 된다.
사용자 지정 컨디션을 사용하는 파드의 경우, 모든 파드의 컨테이너가 준비되고 readnessGates
에 지정된 모든 컨디션들이 True
인 경우에만 파드가 준비된 것으로 평가된다.
컨테이너 프로브(probe)
- 프로브는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)이다. 진단을 수행하기 위해서, kubelet은 컨테이너 안에서 코드를 실행하거나 네트워크 요청을 전송한다.
체크 메커니즘
- “프로브”를 사용하여 컨테이너를 확인하는 방법에는 4가지가 있고 각 프로브는 아래의 메커니즘 중 단 하나만을 정의해야 한다.
exec
: 컨테이너 내에서 지정된 명령어를 실행한다. 명령어가 상태 코드 0으로 종료되면 진단이 성공한 것으로 간주한다.grpc
: gRPC를 사용하여 원격 프로시저 호출을 수행한다. 체크 대상이 gRPC 헬스 체크를 구현해야 한다. 응답의 status가 SERVING이면 진단이 성공했다고 간주한다. gRPC 프로브는 알파 기능이며 GRPCContainerProbe 기능 게이트를 활성화해야 사용할 수 있다.httpGet
: 지정한 포트 및 경로에서 컨테이너의 IP주소에 대한 HTTP GET 요청을 수행한다. 응답의 상태 코드가 200 이상 400 미만이면 진단이 성공한 것으로 간주한다.tcpSocket
: 지정된 포트에서 컨테이너의 IP주소에 대해 TCP 검사를 수행한다. 포트가 활성화되어 있다면 진단이 성공한 것으로 간주한다. 원격 시스템(컨테이너)가 연결을 연 이후 즉시 닫는 상황도 진단이 성공한 것으로 간주한다.
프로브 결과
- 각 probe는 아래의 세가지 결과 중 하나의 가진다.
Success
: 컨테이너가 진단을 통과함.Failure
: 컨테이너가 진단에 실패함.Unknown
: 진단 자체가 실패함. 추후 kubelet이 추가로 확인을 수행할 것.
프로브 종류
- kubelet은 실행 중인 컨테이너들에 대해서 선택적으로 세 가지 종류의 프로브를 수행하고 그에 반응할 수 있다.
livenessProbe
: 컨테이너가 동작 중인지 여부를 나타낸다. 만약 활성 프로브(liveness probe)에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 된다. 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는Success
이다.readinessProbe
: 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타낸다. 만약 준비성 프로브(readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다. 준비성 프로브의 초기 지연 이전의 기본 상태는Failure
이다. 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는Success
이다.startupProbe
: 컨테이너 내의 애플리케이션이 시작되었는지를 나타낸다. 스타트업 프로브(startup probe)가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다. 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고 컨테이너는 재시작 정책에 따라 처리된다. 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는Success
이다.
언제 활성 프로브를 사용해야 하는가?
- 만약 컨테이너 속 프로세스가 어떤 이슈에 직면하거나 건강하지 못한 상태(unhealthy)가 되는 등 프로세스 자체의 문제로 중단될 수 있더라도, 활성 프로브가 반드시 필요한 것은 아니다.
- kubelet이 파드이
restartPolicy
에 따라서 올바른 대처를 자동적으로 수행할 것이다. - 프로브가 실패한 후 컨테이너가 종료되거나 재시작되길 원한다면, 활성 프로브를 지정하고,
restartPolicy
를 항상(Always) 또는 실패 시(OnFailure)로 지정한다.
언제 준비성 프로브를 사용해야 하는가?
- 프로브가 성공한 경우에만 파드에 트래픽 전송을 시작하려고 한다면, 준비성 프로브를 지정하는 것이 좋다. 준비성 프로브가 활성 프로브와 유사해 보일 수도 있지만 스팩에 준비성 프로브가 존재한다는 것은 파드가 트래픽을 받지 않는 상태에서 시작되고 프로브가 성공하기 시작한 이후에만 트래픽을 받는다는 뜻이다.
- 컨테이너가 유지 관리를 위해서 자체 중단되게 하려면, 준비성 프로브를 지정하는 것이 좋다. 준비성 프로브는 활성 프로브와는 다르게 준비성에 특정된 엔드포인트를 확인한다.
- 애플리케이션이 백엔드 서비스에 엄격한 의존성이 있다면 활성 프로브, 준비성 프로브 모두 활용할 수도 있다. 활성 프로브는 애플리케이션 스스로가 건강한 상태면 통과하지만, 준비성 프로브는 추가적으로 요구되는 각 백-엔드 서비스가 가용한지 확인한다. 이를 통해, 오류 메시지만 응답하는 파드로 트래픽이 전달되는 것을 막을 수 있다.
- 컨테이너가 시동 시 대량 데이터를 로딩, 구성 파일, 마이그레이션에 대한 작업을 수행해야 한다면, 스타트업 프로브를 사용하는 것이 좋다. 만약 failed 애플리케이션과 시동 중에 아직 데이터를 처리하고 있는 애플리케이션을 구분하여 탐지하고 싶다면, 준비성 프로브를 사용하는 것이 더 적합할 것이다.
- 파드가 삭제될 때 요청들을 흘려 보내기(drain)위해 준비성 프로브가 꼭 필요한 것은 아니다.
- 파드는 프로브의 존재 여부와 무관하게 자동으로 스스로를 준비되지 않은 상태(unready)로 변경한다.
- 파드는 파드 내의 모든 컨테이너들이 중지될 때까지 준비되지 않은 상태로 남아 있다.
언제 스타트업 프로브를 사용해야 하는가?
- 스타트업 프로브는 시작하는 데 오랜 시간이 걸리는 컨테이너가 있는 파드에 유용하다. 긴 활성 간격을 설정하는 대신, 컨테이너가 시작될 때 프로브를 위한 별도의 구성을 설정하여, 활성 간격보다 긴 시간을 허용할 수 있다.
- 컨테이너가 보통
initialDelaySeconds + failureThreshold * periodSeconds
이후에 기동된다면, 스타트업 프로브가 활성화 프로브와 같은 엔드포인트를 확인하도록 지정해야 한다. periodSeconds
의 기본값은 10s이다. 컨테이너가 활성화 프로브의 기본값 변경 없이 기동되도록 하려면,failureThreashold
를 충분히 높게 설정해서 데드락(deadlock)을 방지하는데 도움이 된다.
[정리]
컨테이너에서 kubelet에 의해 주기적으로 진단하기 위해서 프로브를 사용한다. 이 때, 컨테이너 안에서 코드를 실행하거나 네트워크 요청을 전송한다. 프로브를 사용하는 방법에는 exec, grpc, http, tcp가 있다.
프로브의 종류는 총 세 가지가 있다.
“활성 프로브”는 컨테이너가 동작 중인지 확인하고 만약 동작 중이지 않다면 kubelet은 컨테이너를 재실행 대상으로 지정한다.
“준비성 프로브”는 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타낸다. 컨테이너의 준비여부가 아니라 컨테이너 내부의 애플리케이션이 요청을 처리 준비 여부가 다른 컨테이너 실행에 영향을 미치는 경우에 사용한다.
“스타트업 프로브”는 컨테이너 내의 애플리케이션이 시작되었는지 여부를 나타낸다. 실행하는 데 오랜 시간이 걸리는 컨테이너가 있는 파드에 유용하게 사용된다.
파드의 종류
- 파드는 클러스터의 노드에서 실행되는 프로세스를 나타내므로, 해당 프로세스가 더 이상 필요하지 않을 때 정상적으로 종료되도록 하는 것이 중요하다.
- 디자인 목표는 삭제를 요청하고 프로세스가 종료되는 시기를 알 수 있을 뿐만 아니라, 삭제가 결국 완료되도록 하는 것이다.
- 사용자가 파드의 삭제를 요청하면, 클러스터는 파드가 강제로 종료되기 전에 의도한 유예 기간을 기록하고 추적한다. 강제 종료 추적이 적용되면, kubelet은 정상 종료를 시도한다.
- 일반적으로, 컨테이너 런타임은 각 컨테이너의 기본 프로세스에 TERM 신호를 전송한다.
- 많은 컨테이너 런타임은 컨테이너 이미지에 정의된
STOPSIGNAL
값을 존중하며 TERM 대신 이 값을 보낸다. - 일단 유예 기간이 만료되면, KILL 시그널이 나머지 프로세스로 전송되고, 그런 다음 파드는 API 서버로부터 삭제된다.
- 프로세스가 종료될 때까지 기다리는 동안 kubelet 또는 컨테이너 런타임의 관리 서비스가 다시 시작되면, 클러스터는 전체 원래 유예 기간을 포함하여 처음부터 다시 시도한다.
- 플로우의 예시는 아래와 같다.
kubectl
도구를 사용하여 기본 유예 기간(30초)으로 특정 파드를 수동으로 삭제한다.- API 서버의 파드는 유예 기간과 함께 파드가 “dead”로 간주되는 시간으로 업데이트 된다.
kubectl describe
를 사용하여 삭제하려는 파드를 확인하면, 해당 파드가 “Terminating”으로 표시된다. 파드가 실행 중인 노드에서, kubelet이 파드가 종료된 것으로 표시되었음을 확인하는 즉시, kubelet은 로컬 파드의 종료 프로세스를 시작한다.- 파드의 컨테이너 중 하나가
preStop
훅을 정의한 경우, kubelet은 컨테이너 내부에서 해당 훅을 실행한다. 유예 기간이 만료된 후preStop
훅이 계속 실행되면, kubelet은 2초의 작은 일회성 유예 기간 연장을 요청한다.preStop
훅을 완료하는 데 기본 유예 기간이 허용하는 것보다 오랜 시간이 필요한 경우, 이에 맞게terminationGracePeriodSeconds
를 수정해야 한다. - kubelet은 컨테이너 런타임을 트리거하여 각 컨테이너 내부의 프로세스 1에 TERM 시그널을 보낸다. 파드의 컨테이너는 서로 다른 시간에 임의의 순서로 TERM 시그널을 수신한다. 종료 순서가 중요한 경우,
preStop
훅을 사용하여 동기화하는 것이 좋다.
- 파드의 컨테이너 중 하나가
- kubelet이 정상 종료를 시작하는 동시에, 컨트롤 플레인은 구성된 셀렉터가 있는 서비스를 나타내는 엔드포인트 오브젝트에서 종료된 파드를 제거한다. 레플리카셋과 기타 워크로드 리소스는 더 이상 종료된 파드를 유효한 서비스 내 복제본으로 취급하지 않는다. 로드 밸런서가 종료 유예 기간이 시작되는 즉시 엔드포인트 목록에서 파드를 제거하므로 느리게 종료되는 파드는 트래픽을 계속 제공할 수 없다.
- 유예 기간이 만료되면, kubelet은 강제 종료를 트리거한다. 컨테이너 런타임은
SIGKILL
을 파드의 모든 컨테이너에서 여전히 실행 중인 모든 프로세스로 전송한다. kubelet은 해당 컨테이너 런타임이 하나를 사용하는 경우 숨겨진pause
컨테이너도 정리한다. - kubelet은 유예 기간을 0(즉시 삭제)으로 설정하여, API 서버에서 파드 오브젝트의 강제 상제를 트리거한다.
- API 서버가 오브젝트를 삭제하면, 더 이상 클라이언트에서 볼 수 없다.
[정리]
파드는 일회용성으로 해당 프로세스가 더 이상 필요하지 않을 때 정상적으로 종료되고 종료되는 시기를 알 수 있는 것을 목표로 한다. 컨테이너 런타임은 컨테이너 이미지에 정의된 STOPSIGNAL을 통해 파드를 API 서버로 부터 삭제한다.
강제 파드 종료
- 강제 삭제는 일부 워크로드와 해당 파드에 대해서 잠재적으로 중단될 수 있다.
- 기본적으로, 모든 삭제는 30초 이내에 정상적으로 수행된다.
kubectl delete
명령은 기본값을 재정의하고 사용자의 고유한 값을 지정할 수 있는--grace-period=<seconds>
옵션을 지원한다. - 유예 기간을
0
으로 강제로 즉시 설정하면 API 서버에서 파드가 삭제된다. 파드가 노드에서 계속 실행 중인 경우, 강제 삭제는 kubelet을 트리거하여 즉시 정리를 시작한다. - 강제 삭제를 수행하려면
--grace-period=0
와 함께 추가 플래그--force
를 지정해야 한다. - 강제 삭제가 수행되면, API 서버는 실행 중인 노드에서 파드가 종료되었다는 kubelet의 확인을 기다리지 않는다.
- API에서 즉시 파드를 제거하므로 동일한 이름으로 새로운 파드를 생성할 수 있다. 노드에서 즉시 종료되도록 설정된 파드는 강제 종료되기 전에 작은 유예 기간이 계속 제공된다.
실패한 파드의 가비지 콜렉션
- 실패한 파드의 경우, API 오브젝트는 사람이나 컨트롤러 프로세스가 명시적으로 파드를 제거할 때까지 클러스터의 API에 남아 있다.
- 컨트롤 플레인은 파드 수가 구성된 임계값을 초과할 때 종료된 파드를 정리한다. 이렇게 하면 시간이 지남에 따라 파드가 생성되고 종료될 때 리소스 유출이 방지된다.
[정리]
파드의 강제 삭제는 일부 워크로드와 해당 파드에 대해서 잠재적으로 중단될 수 있다. 삭제 작업은 일반적으로 30초 이내에 정상적으로 수행되며 유예 기간을 0으로 설정하거나 그레이스풀 기간을 0으로 설정하면 그 즉시 삭제된다.
실행에 실패한 파드의 경우 오브젝트는 명시적으로 제거될 때까지 클러스터의 API에 남아 있다. 만약 리소스가 부족해지거나 파드 수가 임계값을 초과하는 경우 종료된 파드가 정리된다.
참고 자료
'Infrastructure > Kubernetes' 카테고리의 다른 글
[Pod] 중단(Disruption) (0) | 2022.10.18 |
---|---|
[Pod] 초기화 컨테이너 (0) | 2022.10.18 |
[Pod] 개념 (0) | 2022.10.14 |
[워크로드] 개념 (0) | 2022.10.14 |
[컨테이너] 환경변수와 라이프사이클 훅(Hook) (0) | 2022.10.14 |