클라우드 컴퓨팅 & NoSQL/도커 & 쿠버네티스

쿠버네티스 - PodDisruptionBudget

Terry Cho 2019. 2. 11. 23:51


PodDisruptionBudget

조대협 (http://bcho.tistory.com)


Pod의 개수는 컨트롤러가 붙어 있을 경우에는 컨트롤러 스펙에 정의된 replica 수 만큼을 항상 유지 하도록 되어 있다. Pod의 수가 replica의 수를 유지 하지 못하고 줄어드는 경우가 있는데, 애플리케이션이 크래쉬 나거나, VM이 다운되는 등의 예상하지 못한 사고로 인한 경우가 있고, 또는 시스템 관리자가 업그레이드등의 이슈로 노드를 인위적으로 다운 시키는 것과 같이 예상 가능한 상황이 있다.

예상 가능한 상황에서 Pod가 없어지는 것을 Voluntary disruptions 라고 하고, 커널 패닉이나 VM 크래쉬같은 예기치 못한 상황에서 Pod가 없어지는 것을 Involuntary disruptions 라고 한다.


노드를 인위적으로 줄일 경우(Voluntary disruptions) 그 노드에 Pod가 여러개 돌고 있을 경우 순간적으로 Pod의 수가 줄어들 수 있다. 예를 들어 웹 서버 Pod가 노드1에 5개, 노드 2에 8개가 돌고 있을 때 노드1을 다운 시키면 순간적으로 Pod의 총 수가 8개가 된다. replica수에 의해서 복귀는 되겠지만, 성능을 유지하기 위해서 일정 수의 Pod 수를 유지해야 하거나, NoSQL 처럼 데이타 저장에 대한 안정성을 확보하기 위해서 쿼럼값만큼  최소 Pod를 유지해야 하는 경우 , 이런 노드 다운은 문제가 될 수 있다.


그래서 인위적인 노드 다운등과 같이 volutary disruption 상황에도 항상 최소한의 Pod수를 유지하도록 해주는 것이 PodDistruptionBudget (이하 PDB)이라는 기능이다.  PDB를 설정하면 관리자가 노드 업그레이드를 위해서 노드를 다운 시키거나 또는 오토스케일러에 의해서 노드가 다운될 경우, Pod수를 일정 수 를 유지하지 못하면 노드 다운이나 오토스케일러에 의한 스케일 다운등을 막고, Pod 수를 일정 수준으로 유지할 수 있을때 다시 그 동작을 하도록 한다.


예를 들어 nginx-pod가 2개가 유지되도록 PDB를 설정했다고 가정하자


node-1

node-2

node-3

nginx-pod-1

nginx-pod-2

nginx-pod-3


위와 같은 상태에서 시스템 관리자가 node-1에 대한 패치를 위해서 node-1을 다운 시키려고 node draining 명령을 실행했다고 하자. 그럼 node-1에 있는 nginx-pod-1은 다른 node로 옮겨진다.(이를 eviction이라고 한다. ) 구체적으로는 nginx-pod-1 은 terminate 되고, node-2나 node-3에 새로운 pod가 생기게 된다. 여기서는 node-2에 nginx-pod-4라는 이름으로 새로운 pod가 생성된다고 가정하자


node-1 (draining)

node-2

node-3

nginx-pod-1(terminating)

nginx-pod-2

nginx-pod-4 (starting)

nginx-pod-3


이때 마음급한 관리자가 nginx-pod-4가 기동되는 것을 기다리지 않고, node-2를 패치하기 위해서 node-3 를 다운 시키려고 draining 명령을 내렸다고 하자.

이 경우 nginx-pod-4가 아직 기동중인 상태이기 때문에, 현재 사용 가능한 pod는 nginx-pod-2 와 nginx-pod-3 2개 뿐인데, node-3를 다운 시키면 nginx-pod-2 하나 밖에 남지 않기 때문에, PDB에서 정의한 pod의 개수 2개를 충족하지 못하기 때문에, node-3에 대한 다운 작업은 블록 된다.


PDB는 YAML 파일을 이용해서 리소스로 정의될 수 있다.

PDB에서 정의 하는 방법은 minAvailable 정의할 경우 앞의 예제에서 설명한 바와 같이 최소한 유지해야 하는 Pod의 수를 정의할 수 있고 또는 maxUnavailable 을 정의해서 최대로 허용할 수 있는 Unhealthy한 Pod 의 수를 정의할 수 있다. 이 두 값은 Pod의 숫자로 정의할 수 도 있고 또는 %를 사용할 수 있다.


예를 들어

  • minAvailable 가 5이면, 최소한 5개의 Pod 는 항상 정상 상태로 유지하도록 한다.

  • minAvailable 가 10%이면,  Pod의 replica 수를 기준으로 10%의 Pod 는 항상 정상 상태로 유지하도록 한다.

  • maxUnavailable 가 1이면, 최대 한개의 Pod만 비정상 상태를 허용하도록 한다.


그러면 이렇게 정의한 값들은 어떻게 Pod에 적용할까, PDB를 만든후에, 이 PDB안에 label selector를 정의해서 PDB를 적용할 Pod를 선택할 수 있다.


완성된 예제는 다음과 같다.

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
 name: zk-pdb
spec:
 minAvailable: 2
 selector:
   matchLabels:
     app: zookeeper


< 출처 : https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget >


이 예제는 app: zookeeper라고 되어 있는 Pod 들을 최소 2개는 항상 유지할 수 있도록 하는 설정이다.

지금까지 간단하게 PDB에 대한 개념을 설명하였다. 일반적인 Stateless 애플리케이션에는 크게 문제가 없겠지만, 일정 성능 이상을 요하는 애플리케이션이나, NoSQL과 같은 일정 수의 쿼럼 유지가 필요한 애플리케이션등의 경우에는 PDB를 정의하는 것이 좋다.


참고로 현재 PDB는 베타 상태이고 정식 릴리즈 상태는 아니기 때문에, 운영 환경에는 아직 사용하지 않는 것이 좋다.

그리드형