[Kubernetes] 노드 자원 보호하기(Drain, Cordon, Uncordon)
안녕하세요, 달콤한달팽이입니다.🐌🙂
이번 시간에는 Pod이 배포되는 노드에 이상이 있을 경우 Pod를 유지한 채 노드를 유지보수할 수 있는 방법에 대하여 알아보겠습니다.
** 모든 실습은 AWS EKS 환경에서 진행하였습니다 **
Drain이란?
쿠버네티스를 사용하다 보면, 노드의 유지보수를 위해 노드를 꺼야하는 상황이 발생합니다.
이런 경우를 대비해 쿠버네티스는 Drain이라는 기능을 제공합니다.
Drain이란, 지정된 노드의 Pod를 모두 다른 노드로 이동시켜 해당 노드를 유지보수 할 수 있도록 도와줍니다.
[ Drain 사용법 ]
우선 디플로이먼트의 Pod 갯수를 3개에서 9개로 증가시켜 보도록 하겠습니다.
$ kubectl scale deployment nginx-deployment --replicas=9
약간의 시간이 지난 후, Pod의 상태를 확인하면 9개의 Pod가 3개의 노드에 골고루 생성된 것을 확인할 수 있습니다.
(10.0.11.231 * 4개, 10.0.10.210 * 2개, 10.0.10.185 * 3개)
$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
이 중 10.0.10.210 Pod에 유지보수가 필요하다고 가정하고 Drain 명령어를 수행해보겠습니다.
$ kubectl drain --ignore-daemonsets ip-10-0-10-210.ap-northeast-2.compute.internal
아까와 달리 2개의 노드에만 Pod가 생성되어있음을 확인할 수 있습니다.
(10.0.11.231 * 4개, 10.0.10.210 * 0개, 10.0.10.185 * 5개)
$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
이제 노드의 상태를 확인해보도록 합시다.
노드의 상태가 Ready와 더불어 SchedulingDisabled 상태가 추가되었음을 알 수 있습니다.
여기서 SchedulingDisabled 상태는 해당 노드가 더 이상 새로운 Pod를 스케줄링할 수 없음을 의미합니다.
$ kubectl get nodes -A
이제 다음 실습을 위해 SchedulingDisabled 상태를 해제하고, 다시 노드의 상태를 확인해보겠습니다.
아래의 결과에서 알 수 있듯이, uncordon은 SchedulingDisabled 상태를 해제하는 명령어입니다!
$ kubectl uncordon ip-10-0-10-210.ap-northeast-2.compute.internal
$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
이제 Cordon 실습을 진행하기 위해 Deployment를 삭제하고 다시 배포하겠습니다.
(Drain 이후 Uncordon을 수행해도 기존 노드로 Pod가 재시작되지 않기 때문입니다.)
Cordon & Uncordon이란?
노드를 껐다 켜도 될 경우 Drain을 사용하면 되지만,
어쩔 수 없이 문제 발생 가능성이 있는 노드를 사용해야하는 상황이 있을 수 있습니다.
이런 경우를 대비해 쿠버네티스는 Cordon이라는 기능을 제공합니다.
Cordon이란, 지정된 노드의 Pod를 모두 다른 노드로 이동시켜 해당 노드를 유지보수 할 수 있도록 도와줍니다.
[ Cordon 사용법 ]
Deployment를 배포한 후, 노드 상태를 확인해보도록 하겠습니다.
3개의 Pod가 3개의 노드에 하나씩 골고루 배포되어있음을 확인할 수 있습니다.
$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
이제 자주 문제가 생기는 노드를 10.0.10.185 노드라고 가정하고 cordon 명령어를 수행하고,
Pod의 수를 9개로 증가시켜보겠습니다!
$ kubectl cordon ip-10-0-10-185.ap-northeast-2.compute.internal
$ kubectl scale deployment nginx-deployment --replicas=9
Pod 상태를 확인해보았을 때, 10.0.10.185 노드에 생긴 Pod는 가장 처음 생성한 하나뿐인 것을 알 수 있습니다.
$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase,NODE:.spec.nodeName
이때의 노드 상태를 보면 Drain 실습때와 동일하게 SchedulingDisabled 상태임을 확인할 수 있습니다.
$ kubectl get nodes -A
이제 uncordon 명령어를 통해 SchedulingDisabled 상태를 해제하고 이번 실습을 마치도록 하겠습니다.
$ kubectl uncordon ip-10-0-10-185.ap-northeast-2.compute.internal
$ kubectl get nodes -A
지금까지 노드를 제어하여 Pod 배포를 제한시켜 노드 자원을 보호하는 방법을 알아보았습니다.
개발 환경에서는 굳이 필요하지 않은 작업일 수 있으나,
운영 환경에서 불필요한 서비스 중단을 예방할 수 있는 좋은 방법이라고 생각합니다.
감사합니다!