PDB
개요
Pod Distruption Budget.
파드 중단 예산은 클러스터 내에서 파드의 개수가 유연하게 스케일링되도록 제한 거는 역할을 한다.
가령 현재 Deployment에서 파드가 5개 관리되고 있는데 3개까지는 돌아가고 있어야 안정적이라면 이를 예산으로 걸어서 함부로 깨지지 않도록 하는 것이다.
이는 고가용성 설계에 있어 유리하다.
종료가 될 파드가 있어도 이 종료가 서비스에 영향이 가지 않도록, 리소스 낭비가 되지 않도록 고려할 수 있게 된다.
또한 클러스터 관리자 입장에서는 업그레이드나 오토스케일링 등의 클러스터 행위들을 자동화하는데 도움이 된다.
중단 주체에 따른 분류
먼저 중단이 어떤 식으로 이뤄지는지 종류를 따져보자.
비자발적 중단
파드는 기본적으로 함부로 없어지지 않지만, 하드웨어의 손상으로 인한 이슈가 발생할 수는 있다.
이런 류의 중단을 비자발적인 중단
이라고 따로 부른다.
- 하드웨어의 손상
- 실수로 클러스터 관리자가 VM을 내림..
- 클라우드 공급자가 VM을 가져감
- 커널 장애
- 클러스터 네트워크 상에서 노드가 사라짐
- 리소스 부족으로 파드가 축출되는 중
이런 상황은 최대한 방지해야 할 필요가 있다.
자발적 중단
반대로 관리자가 직접 파드를 중단되게 만드는 경우도 존재할 것이다.
- 파드를 관리하는 워크로드를 지우는 경우
- 재시작을 야기하는 파드 템플릿 업데이트
- 직접적으로 파드 지우기
- 클러스터 조작
- 오토스케일링, 업그레이드, 보수를 위한 노드 드레인
- 파드를 더 잘 맞는 노드에 넣기 위해 중단
이러한 상황들은 최대한 문서화시키고 예상되는 범주에 놓는 것이 좋을 것이다.
파드 중단 예산(PDB)
문서에서는 파드 distrucption budgets라고 그냥 번역을 안 했는데, 나는 해도 상관 없지 않나 싶다.
줄여서 PDB.
이게 뭐냐, 자발적 중단의 영역에서 그래도 고가용성을 고려해서 설정하는 기능을 이야기한다.
가령 Deployment에서 파드가 스케일 다운될 때, 한번에 동시에 줄어드는 파드의 개수를 제한한다.
클러스터 관리자는 PDB를 따르는 방식으로 파드를 관리해야만 한다.
가령 드레인 명령을 내리면 직접적으로 파드를 축출하는 명령은 일시적으로 거부될 수 있다.
레플리카가 5인데 pdb가 4를 허용한다면 자발적 중단을 한 번에 한 개 허용한다.
파드의 개수에 의도된 양은 담당하는 워크로드의 레플리카에 의해 결정된다.
비자발적 중단을 pdb로 막을 수는 없지만, 이런 중단도 체크된다.
워크로드에 의해 줄어드는 파드는 PDB에 계산된다.
그렇지만 워크로드는 작업할 때 PDB에 영향 받지 않는다.
대신 실패 대응이 워크로드에 정의된 것으로 한다.
AlwaysAllow
를 설정해서 노드 드레이닝 중 파드 오작동으로 축출이 지체되는 것을 대처하자
기본은 파드가 정상이 될 때까지 기다린다.
파드가 축출되고 있을 때는 파드 스펙에 정의된 terminationGracePeriodSeconds
를 따른다.
예시
문서의 예시는 이러하다.
기본적인 클러스터의 상태.
- 노드 1
- 파드 1 가능 상태
- 파드 x 가능 상태
- 노드 2
- 파드 2 가능 상태
- 노드 3
- 파드 3 가능 상태
x는 pdb와 연관이 없다.
pdb에서는 3개 중 최소 2개가 항상 가동 중이어야 한다고 명시하고 있다.
- 파드 3 가능 상태
이때 관리자가 노드들을 업데이트하고 싶어서 노드 1부터 드레인한다고 생각해보자.
그러면 해당 파드들은 축출될 것이다.
- 노드 1 드레인 중
- 파드 1 종료 중
- 파드 x 종료 중
- 노드 2
- 파드 2 가능 상태
- 노드 3
- 파드 3 가능 상태
디플로이먼트에서 파드가 종료된 것을 알아차리고, 새로운 파드 4를 만든다.
x의 대체제인 y도 만들어질 것이다.
드레인에는 cordon 과정이 있으므로 무조건 노드 1은 피해질 것이다.
- 노드 1 드레인 됨
- 노드 2
- 파드 2 가능 상태
- 파드 4 시작 중
- 노드 3
- 파드 3 가능 상태
- 파드 y 시작
참고로 StatefulSet이 아니니까 여기에서는 uid는 다를 것이다.
여기에서 관리자가 노드 2를 드레인하려고 해도 그것은 차단된다.
왜냐하면 PDB에 명시하기로 최소 2개의 앱이 가용 중이어야 하기 때문이다.
그럼 기다리다가 파드 4가 가능 상태가 된 후에 노드 2를 드레인한다면?
파드 2,4가 한꺼번에 없어지면 안 되기에 일단 파드 2의 대체제인 파드 5를 스케줄한다.
현재 클러스터 내부에 파드 5를 스케줄할 공간이 노드 3에 없다면, 파드 5는 생길 수 없기에 영원히 드레인은 차단되는 꼴이다.
위의 예시를 통해 pdb가 미치는 영향이 어떤 영역들인지 알 수 있다.
- 앱의 필요한 레플리카
- 우아한 종료에 걸리느 ㄴ시간
- 새로운 인스턴스가 시작되는데 걸리는 시간
- 컨트롤러 타입
- 클러스터 수용량
pdb 조건
무엇 때문에 중단되냐에 대한 원인을 확인할 수 있다.
이것은 실제 reason 필드에 들어간다.
- PreemptionByScheduler
- 파드가 다른 우선순위 높은 파드에 밀려 선점(preemption)될 때
- DeletionByTaintManager
- 파드가 테인트, 톨러레이션 매니저에 의해 삭제될 때.
NoExecute
면 바로 삭제된다.
- 파드가 테인트, 톨러레이션 매니저에 의해 삭제될 때.
- EvictionByEvictionAPI
- 축출 api에 의해 축출될 때
- DeletionByPodGC
- 파드 가비지 컬렉팅에 의해 더 이상 노드에 존재하지 않을 때
- TerminationByKubelet
- 노드의 셧다운, 시스템과 관련된 파드에 의해 선점 당해 종료될 때
중단 시나리오는 더 많을 수 있다.
그러나 그런 것들은 어차피 재시작을 하는 동작들이기에 여기에서 중단 타겟으로 지정되지는 않는다.
참고로 pdb 조건이 명시되었다고 반드시 해당 파드가 종료되었다는 것이 보장되지는 않는다.
사용 상황
운영 환경에 어플리케이션 소유자와 클러스터 관리자가 분리되어 있을 때 미리 설정해두는 것이 매우 유용하다.
클러스터 관리자가 관리 차원에서 노드를 드레인할 때 서비스에 지장이 가지 않도록 할 수 있다!
문서에서는 이렇게 책임이 분리돼 있지 않다면 필요 없을 수도 있다고 하는데, 나는 결국 사람이 관리하는 일이니까 함부로 서비스에 지장이 가지 않도록 이런 제한을 걸어두는 것이 좋다고 생각한다.
클러스터 업그레이드
클러스터의 노드들을 하나씩 업그레이드하는 상황을 생각해보자.
다음의 방법을 사용할 수 있다.
- 그냥 다운타임을 허용하고 천천히 업데이트
- 중단 배포하겠다는 것.
- 다른 복제본 클러스터를 활용
- 블루그린 서버를 두어 클러스터를 구성하니 리소스 비용과 전환에 따른 노력도 필요
- PDB를 쓰고 중단을 방지하는 애플리케이션 사용!
- 다운타임이 없다!
- 리소스 중복도 최소화!
- 클러스터 관리 더욱 자동화!
미완성된 글입니다!!
추가 작성해야 하는 글입니다!!!