중단(Disruption)
쿠버네티스 공식문서를 확인하며 파드의 중단에 대해서 기억해야 하는 부분을 기록한다.
- “파드의 중단”은 고가용성 애플리케이션을 구성하려는 소유자, 파드의 장애 유형을 이해하기 위한 소유자, 클러스터의 업그레이드와 오토스케일링과 같은 클러스터의 자동화 작업을 하려는 관리자들은 숙지하고 있어야 한다.
자발적 중단과 비자발적 중단
- 파드는 사람 또는 컨트롤러가 파괴하거나 불가피한 하드웨어 오류 또는 시스템 소프트웨어 오류가 아니면 사라지지 않는다.
- 아래와 같이 불가피한 상황에서 애플리케이션이 중단되는 것을 “비자발적 중단”이라고 부른다.
- 노드를 지원하는 물리 머신의 하드웨어 오류
- 클러스터 관리자의 실수로 VM 삭제
- 클라우드 공급자 또는 하이퍼바이저의 오류로 인한 VM 장애
- 커널 패닉
- 클러스터 네트워크 파티션의 발생으로 클러스터에서 노드가 사라짐
- 노드의 리소스 부족으로 파드가 축출됨
- 아래와 같은 상황을 “자발적 중단”이라고 부르며 애플리케이션 소유자의 작업과 클러스터 관리자의 작업이 모두 포함된다.
- 디플로이먼트 제거 또는 다른 파드를 관리하는 컨트롤러의 제거
- 재시작을 유발하는 디플로이먼트의 파드 템플릿 업데이트
- 파드를 직접 삭제
- 클러스터 관리자의 작업은 아래와 같은 내용을 포함한다.
- 복구 또는 업그레이드를 위한 노드 드레이닝
- 클러스터의 스케일 축소를 위한 노드 드레이닝
- 노드에 다른 무언가를 추가하기 위해 파드를 제거
- 이러한 작업은 클러스터 관리자가 직접 수행하거나 자동화를 통해 수행되고, 또는 클러스터 호스팅 공급자에 의해서도 수행된다.
- 클러스터에 자발적인 중단을 일으킬 수 있는 어떤 원인이 있는지 클러스터 관리자 또는 클라우드 공급자에게 문의해서 배포 문서를 확인해야 한다.
- “자발적인 중단”을 일으킬 수 있는 원인이 없다면 Pod Disruption Budge의 생성을 넘길 수 있다.
- 모든 “자발적인 중단”이 Pod Disruption Budget에 연관되는 것은 아니며 디플로이먼트 또는 파드의 삭제의 경우에는 Pod Disruption Budget을 무시한다.
[정리]
파드는 사람 또는 컨트롤러가 자발적으로 파괴하거나 불가피한 오류가 아니라면 사라지지 않는다. 파드는 사용자가 의도하지 않은 “비자발적 중단”과 사용자가 의도한 “자발적 중단”이 있다. 의도하지 않은 “자발적 중단”이 있었다면 클러스터 관리자 또는 클라우드 공급자에게 문의하고 원인이 발견되지 않는 경우 Pod Disruption Budge의 생성을 넘길 수 있다.
중단 다루기
- 아래는 “비자발적인 중단”으로 인한 영향을 줄이기 위한 몇 가지 방법이다.
- 파드가 필요로 하는 만큼의 리소스를 요청하는지 확인한다.
- 고가용성이 필요한 경우 애플리케이션을 복제하여 복제된 다중 애플리케이션을 운영한다.
- 복제된 애플리케이션의 구동 시 훨씬 더 높은 가용성을 위해 랙 전체 또는 영역 간에 애플리케이션을 분산해야 한다.
- 자발적 중단의 빈도는 다양하고 기본적인 쿠버네티스 클러스터에서는 자동화된 자발적 중단은 발생하지 않는다.
- 클러스터 관리자 또는 호스팅 공급자가 자발적 중단이 발생할 수 있는 일부 부가 서비스를 운영할 수 있다.
- 노드 소프트웨어의 업데이트를 출시하는 경우 자발적 중단이 발생할 수 있고 클러스터(노드) 오토스케일링의 일부 구현에서는 단편화를 제거하고 노드의 효율을 높이는 과정에서 자발적 중단을 야기할 수 있다.
- 클러스터 관리자 또는 호스팅 공급자는 예측 가능한 자발적 중단 수준에 대해 문서화해야 한다.
- 파드 스펙 안에 프라이어리티클래스 사용하기와 같은 특정 환경설정 옵션 또한 자발적 혹은 비자발적 중단을 유발할 수 있다.
[정리]
파드의 “비자발적인 중단”을 방지하기 위해 여러가지 방법이 있다. “자발적 중단”의 경우 빈도가 다양하지만 쿠버네티스 클러스터에서는 “자동화된 자발적 중단”은 발생하지 않고 클러스터의 오토스케일링이나 클러스터 관리자, 호스팅 공급자에 의해 자발적 중단이 발생할 수 있으므로 예측 가능한 자발적 중단에 대해서는 문서화를 해두어야 한다.
PDB(Pod disruption budgets)
- 쿠버네티스는 자발적인 중단이 자주 발생하는 경우에도 고가용성 애플리케이션을 실행하는 데 도움이 되는 기능을 제공한다.
- 애플리케이션 소유자로써, 사용자는 각 애플리케이션에 대해 PDB(PodDisruptionBudget)을 만들 수 있다.
- PDB는 자발적 중단으로 일시에 중지되는 복제된 애플리케이션 파드의 수를 제한한다. 실행중인 애플리케이션의 레플리카의 수가 일정 수치 이하로 떨어지지 않도록 한다.
- 클러스터 관리자와 호스팅 공급자는 직접적으로 파드나 디플로이먼트를 제거하는 대신 Eviction API로 불리는 PDB을 준수하는 도구를 이용해야 한다.
kubectl drain
하위 명령을 사용하면 노드를 서비스 중단으로 표시할 수 있다.kubectl drain
을 실행하면, 사용자가 서비스를 중단하는 노드의 모든 파드를 축출하려고 한다.kubectl
이 사용자를 대신하여 수행하는 축출 요청은 일시적으로 거부될 수 있으며, 도구는 대상 노드의 모든 파드가 종료되거나 설정 가능한 타임아웃이 도래할 때까지 주기적으로 모든 실패된 요청을 다시 시도한다.- PDB는 애플리케이션이 필요로 하는 레플리카의 수에 상대적으로 용인할 수 있는 레플리카의 수를 지정한다.
.spec.replicas: 5
의 값을 갖는 디플로이먼트는 어느 시점에든 5개의 파드를 가져야 한다. 만약 해당 디플로이먼트의 PDB가 특정 시점에 파드를 4개 허용한다면, Eviction API는 한 번에 1개의 파드의 자발적인 중단을 허용한다.- 파드 그룹은 레이블 셀렉터를 사용해서 지정한 애플리케이션으로 구성되며 애플리케이션 컨트롤러(디플로이먼트, 세트이트풀셋 등)을 사용한 것과 동일하다.
- 파드의 “의도”하는 수량은 해당 파드를 관리하는 워크로드 리소스의
.spec.replicas
를 기반으로 계산하고 컨트롤 플레인은 파드의.metadata.ownerReferences
를 검사하여 소유하는 워크로드 리소스를 발견한다. - “비자발적 중단”은 PDB로는 막을 수 없지만, 버짓(Budget)은 차감된다.
- 애플리케이션의 롤링 업데이트로 파드가 삭제되거나 사용할 수 없는 경우 중단 버짓에 영향을 주지만 워크로드 리소스는 롤링 업데이트 시 PDB 제한을 받지 않는다.
- Eviction API를 사용하여 파드를 축출하면, PodSpec의
terminationGracePeriodSeconds
설정을 준수하여 정상적으로 “종료됨” 상태가 된다.
[정리]
모든 애플리케이션에 대해 PDB를 만들 수 있으며 PDB를 통해 “자발적인 중단”으로 인해 서비스가 중단되는 것을 막을 수 있다. “비자발적 중단”의 경우 PDB로 제어할 수 없지만 “비자발적 중단”도 버짓을 차지하기 때문에 PDB에 의해 삭제될 수 있는 파드의 수에 영향을 준다.
PDB 예시
node-1, 2, 3
까지 세 개의 노드가 있는 클러스터가 있고 PDB와는 무관한 pod-x
가 있다고 가정해본다.
node-1 | node-2 | node-3 |
---|---|---|
pod-a available | pod-b available | pod-c available |
pod-x available | ||
- 전체 3개의 파드는 디플로이멈ㄴ트의 일부분으로 전체적으로 항상 3개의 파드 중 최소 2개의 파드를 사용할 수 있는 PDB를 가지고 있다. | ||
- 만약 사용자가 node-1 을 kubectl drain 명령어를 사용해서 비우려하면 kubectl 은 pod-a 와 pod-x 를 축출한다. 이 작업은 성공할 것이며 pod-a 와 pod-x 는 축출되고 아래와 같은 상태가 된다. |
node-1 draining | node-2 | node-3 |
---|---|---|
pod-a terminating | pod-b available | pod-c available |
pod-x terminating | ||
- 디플로이먼트는 한 개의 파드가 중지되는 것을 알게되고, pod-d 라는 대체 파드를 생성한다. node-1 은 차단되어 있어 다른 노드에 위치한다. 무언가 pod-x 의 대체 파드로 pod-y 도 생성되어 아래와 같은 상태가 된다. |
node-1 drained | node-2 | node-3 |
---|---|---|
pod-a terminating | pod-b available | pod-c available |
pod-x terminating | pod-d starting | pod-y |
- 어느 순간 node-1 의 파드가 종료되고, 클러스터는 아래와 같은 상태가 된다. |
node-1 drained | node-2 | node-3 |
---|---|---|
pod-b available | pod-c available | |
pod-d starting | pod-y | |
- pod-d 가 생성되는 시점에서 클러스터관리자가 node-2 또는 node-3 을 비우려고(drain) 한다면 PDB에 의해 차단되고 시작 중이었던 pod-d 가 실행된다. |
node-1 drained | node-2 | node-3 |
---|---|---|
pod-b available | pod-c available | |
pod-d available | pod-y | |
- 안정된 상태에서 관리자가 node-2 를 비우려고 하는 경우 파드가 최소한 두 개는 유지되어야 하기 때문에 차단되고 pod-b 만 종료된다. 또한 새로운 노드에 pod-e 가 pending 상태로 위치하는 상태로 종료된다. |
node-1 drained | node-2 | node-3 | no node |
---|---|---|---|
pod-b terminating | pod-c available | pod-e pending | |
pod-d available | pod-y | ||
- 쿠버네티스는 중단이 발생할 수 있는 비율을 어떻게 변화시키는지 아래의 사례를 통해 확인할 수 있다. | |||
- 애플리케이션에 필요한 레플리카의 수 | |||
- 인스턴스를 정상적으로 종료하는데 소요되는 시간 | |||
- 새 인스턴스를 시작하는데 소요되는 시간 | |||
- 컨트롤러의 유형 | |||
- 클러스터의 리소스 용량 |
[정리]
PDB의 경우 관리자의 실수가 서비스의 장애로 이어지는 것을 사전에 차단하기 위해 노력한다. 하지만 마지막 예시처럼 부득이한 경우 관리자가 새로운 노드를 생성하기를 대기하는 상태에 돌입할 수 있다.
클러스터 소유자와 애플리케이션 소유자의 역할 분리
- 보통 클러스터 매니저와 애플리케이션 소유자는 서로에 대한 지식이 부족한 별도의 역할로 생각하는 것이 유용하다.
- 이러한 책임의 분리가 아래의 시나리오에서 타당할 수 있다.
- 쿠버네티스 클러스터를 공유하는 애플리케이션 팀이 많고, 자연스럽게 역할이 나누어진 경우
- 타사 도구 또는 타사 서비스를 이용해서 클러스터 관리를 자동화 하는 경우
- PDB는 역할 분리에 따라 역할에 맞는 인터페이스를 제공한다.
- 만약 조직에 역할 분리에 따른 책임의 분리가 없다면 PDB를 사용할 필요가 없다.
[정리]
클러스터 매니저와 애플리케이션 소유자는 역할과 책임을 분리하는 것이 좋으며 이러한 상황에서 책임을 분리하기 위해 사용되는 것이 PDB의 역할이다. 만약 역할과 책임의 분리가 없는 조직이라면 PDB를 사용할 필요가 없다.
클러스터에서 중단이 발생할 수 있는 작업을 하는 방법
- 클러스터 관리자이며, 클러스터 전체 노드에 노드 또는 시스템 소프트웨어 업그레이드와 같은 중단이 발생할 수 있는 작업을 수행하는 경우 아래와 같은 옵션을 선택할 수 있다.
- 업그레이드 하는 동안 다운타임을 허용한다.
- 다른 레플리카 클러스터로 장애조치를 한다.
- 다운타임은 없지만, 노드 사본과 전환 작업을 조정하기 위한 인력 비용이 많이 발생할 수 있다.
- PDB를 이용해서 애플리케이션의 중단에 견디도록 작성한다.
- 다운타임 없음
- 최소한의 리소스 중복
- 클러스터 관리의 자동화 확대 적용
- 내결함성이 있는 애플리케이션의 작성은 까다롭지만 자발적 중단을 허용하는 작업의 대부분은 오토스케일링과 비자발적 중단을 지원하는 작업과 겹친다.
참고 자료
'Infrastructure > Kubernetes' 카테고리의 다른 글
[Pod] 사용자 네임스페이스 (0) | 2022.10.18 |
---|---|
[Pod] 임시(Ephemeral) 컨테이너 (0) | 2022.10.18 |
[Pod] 초기화 컨테이너 (0) | 2022.10.18 |
[Pod] 라이프사이클 (0) | 2022.10.18 |
[Pod] 개념 (0) | 2022.10.14 |