노드 중 하나가 다운되면 어떻게 될까?
해당 노드의 파드에 접근이 불가능해질 것이다.
또한 파드를 어떻게 배치하느냐에 따라 사용자가 영향을 받는다.
만약 다운된 노드에 배치된 파드 중, 파란 파드는 복제본이 여러 개 있기 때문에 파란 앱에 액세스하는 사용자는 영향을 받지 않을 것이다. 온라인에 있는 다른 파란 파드를 통해 서비스되기 때문이다.
하지만 다운된 노드에 배치된 파드 중, 녹색 파드에 접속하는 사용자는 영향을 받을 것이다.
이는 녹색 파드가 녹색 앱을 실행하는 유일한 파드이기 때문이다.
노드가 즉시 온라인으로 돌아오면 kubelet 절차가 시작되고 파드가 온라인으로 돌아온다.
하지만 노드가 5분 이상 다운되면 해당 노드에서 파드가 종료된다.
쿠버네티스는 노드와 노드의 파드들이 죽은 것으로 여긴다.
파드가 레플리카셋의 일부라면 다른 노드에 재생성될 것이다.
노드가 죽었다고 간주되는 시간(pod-eviction-timeout)은 사용자에 의해 설정될 수 있다.
쿠버네티스는 해당 시간 동안 기다리고 노드가 죽었다고 간주한다.
후에 노드가 다시 온라인으로 돌아오면 노드는 공백 상태이다.
drain 작업을 통해 노드의 파드들을 정상적으로 종료하고 다른 노드에 재현시킬 수 있다.
노드의 제한을 제거하기 전까지는 노드에 파드를 스케줄할 수 없다.
이제 노드에 할당된 파드가 없기 때문에 노드를 안전하게 재부팅할 수 있다. 재부팅 후에도 제한이 여전히 걸려있기 때문에 노드에 파드를 계획할 수 없다.
파드를 다시 노드에 스케줄하기 위해서는 uncordon해야 한다.
다른 노드로 옮겨진 파드가 자동으로 돌아오지 않는다. 해당 파드가 삭제되거나 클러스터에 새 파드가 생성되면 이 노드에 스케줄될 수 있다.
drain, uncordon 이외에도 cordon 명령어가 존재한다.
cordon은 drain과 달리 기존 노드에서 파드를 종료시키거나 이동시키지 않는다.
cordon은 단순히 해당 노드에 새 파드가 스케줄링되지 않도록 한다.
drain: 배수구, 물빠짐
kubectl drain은 노드에 존재하는 모든 파드들을 제거하여 노드를 비우고, 파드들을 다른 노드에 새롭게 스케줄링하는 명령어이다.
kubectl drain이 적용된 노드는 SchadulingDisabled 상태가 되며, 이후 새롭게 생성되는 어떤 파드도 해당 노드에 생성되지 않는다.
cordon: 경계선
uncordon
kubectl drain이나 kubectl cordon 명령어를 적용한 노드는 SchedulingDisabled 상태가 되어 더 이상 파드가 스케줄링되지 않는다.
kubectl uncordon은 노드의 이러한 SchedulingDisabled 상태를 제거하여 노드에 파드가 정상적으로 스케줄링될 수 있도록 복구하는 명령이다.
쿠버네티스의 버전은 세 부분으로 나뉜다. 첫 번째가 주 버전이고 그 다음이 마이너 버전 그 다음이 패치 버전이다.
쿠버네티스도 표준 소프트웨어 릴리즈 버전 관리 절차를 따른다.
몇 달에 한 번씩 소규모 릴리즈를 통해 새로운 기능을 선보인다.
쿠버네티스는 베타와 알파 단계를 거쳐 정식으로 릴리즈된다.
컨트롤 플레인에는 버전 번호가 다른 구성 요소들이 있다.
ETCD Cluster와 CoreDNS는 각각 독자적인 버전을 갖는다.
컨트롤 플레인의 구성 요소는 각각 다른 릴리스 버전을 가질 수 있다.
kube-api server는 다른 모든 구성 요소와 통신하는 역할을 수행하며 컨트롤 플레인의 주요 구성 요소이다.
다른 어떤 구성 요소도 kube-api server보다 높은 버전에 있어서는 안된다.
controller-manager와 kube-scheduler는 kube-api server보다 한 버전 아래에 있을 수 있다.
kubelet과 kube-proxy는 kube-api server보다 두 버전 낮아질 수 있다.
필요하다면 부품별로 업그레이드할 수 있다.
kubectl은 kube-api server보다 1이 낮거나 동일하거나 1이 높은 버전을 가질 수 있다.
쿠버네티스는 가장 최근인 일부 버전만 지원한다. 그래서 버전 업그레이드가 필요하다.
버전을 업그레이드할 때 권장되는 방법은 한 번에 마이너 버전을 하나씩 업그레이드하는 것이다.
업그레이드 프로세스는 클러스터 설정에 달렸다.
구글과 같은 클라우드 서비스 공급자에 의해 클러스터가 배포되었다면 클릭 몇 번으로 클러스터를 쉽게 업그레이드할 수 있다.
kubeadm과 같은 도구를 이용해 클러스터를 배포했다면 도구를 통해 클러스터를 업그레이드할 수 있을 것이다.
처음부터 클러스터를 배포했다면 클러스터의 다양한 구성 요소를 수동으로 업그레이드해야 한다.
이번 강의에서는 kubeadm을 통해 클러스터를 배포한 경우에 어떻게 버전을 업그레이드하는지 알아본다.
클러스터 업그레이드에서 먼저 마스터 노드를 업그레이드 해야 한다. 그 다음 작업자 노드를 업그레이드 해야 한다.
마스터 노드가 업그레이드되는 동안 컨트롤 플레인의 구성 요소는 잠시 다운된다.
마스터 노드가 다운된다고 작업자 노드와 클러스터 상의 응용 프로그램이 영향을 받는 것은 아니다.
작업자 노드에 호스트된 모든 작업은 평소터럼 사용자를 돕는다. 마스터가 다운되었으니 관리 기능도 다운된다.
kube-controller이나 다른 쿠버네티스 API를 이용해 클러스터에 접근할 수 없다.
새 앱을 배포하거나 기존 앱을 삭제, 수정할 수도 없다. 컨트롤러 매니저도 작동하지 않는다.
파드가 망가지면 새 파드가 자동으로 생성되지 않는다.
하지만 작업자 노드와 파드가 작동하는 한 애플리케이션은 작동해야 하고 사용자는 영향을 받지 않는다.
마스터 노드의 업그레이드가 완료되고 클러스터가 백업되면 정상적으로 작동한다.
다음으로 작업자 노드를 업그레이드할 차례이다.
작업자 노드를 업그레이드하기 위한 다양한 전략이 있다.
첫번째 전략은 전부 한 번에 업그레이드하는 것이다.
파드가 전부 다운되므로 사용자가 앱에 접근할 수 없다.
업그레이드가 완료되면 노드가 백업되고 새 파드가 스케줄된다. 사용자는 앱에 접근할 수 있다.
이는 가동 중지 시간이 필요한 전략이다.
두 번째 전략은 한 번에 노드를 하나씩 업그레이드하는 것이다.(kubeadm의 전략)
첫 번째 노드를 업그레이드하면 앱이 두번째와 세번째 노드에서 호스팅된다.
일단 첫 번째 노드가 업그레이드되면 두 번째 노드를 업데이트한다. 앱은 첫 번째와 세 번째 노드에서 호스팅된다.
끝으로 세 번째 노드가 업데이트된다.
세 번째 전략은 클러스터에 새로운 소프트웨어 버전을 가진 새 노드를 추가하는 것이다.
이 전략은 클라우드 환경에서 특히 편리하다. 새 노드를 프로비전하고 오래된 것을 해체할 수 있기 때문이다.
새 소프트웨어 버전의 노드가 클러스터에 추가되면 앱을 새 노드로 옮겨서 호스팅한다.
옛날 노드는 제거한다.
모두 새로운 소프트웨어 버전을 갖게 될 때까지 해당 작업을 반복한다.
이제 kubeadm이 버전 1.11에서 1.13으로 어떻게 업그레이드되는지 보자.
kubeadm upgrade plan 명령을 실행하면 업그레이드에 대한 많은 정보를 얻을 수 있다.
클러스터를 업그레이드하기 전에 kubeadm 도구부터 업그레이드해야 한다.
kubeadm은 쿠버네티스와 같은 소프트웨어 버전을 사용한다.
먼저 kubeadm을 1.12로 업그레이드 한다.
그런 다음 클러스터를 1.12로 업그레이드한다. 필요한 이미지를 받아오고 클러스터 부품을 업그레이드한다. 완료되면 큐브 컨트롤 부품은 1.12가 된다.
그러나 큐브 컨트롤의 버전이 1.12인 것을 볼 수 있다.
왜냐하면 각각의 노드에서 kube-api server의 버전이 아닌 kubelet의 버전을 보여주고 있기 때문이다.
따라서, kubelet을 1.12로 업그레이드해줘야 한다.
우리의 셋업에 따라 마스터 노드에 kubelet이 실행될 수도 아닐 수도 있다.
kubeadm으로 배포된 클러스터는 마스터 노드에 kubelet이 있다.
마스터 노드의 kubelet은 컨트롤 플레인의 구성요소를 실행하는 데 사용된다.
다음은 작업자 노드를 하나씩 업그레이드한다.
먼저 첫 번째 작업자 노드의 작업을 다른 노드로 옮기기 위해 kubectl drain 명령을 실행한다.
그 다음 마스터 노드에서 했던 것처럼 작업자 노드에서 kubeadm과 kubelet 버전을 업그레이드한다. 그리고 새 kubelet 버전을 위한 노드 구성을 업데이트한다. 그 다음 kubelet 서비스를 다시 시작한다.
그러면 노드가 새 소프트웨어 버전과 함께 올라간다.
하지만 전에 실행한 drain 명령으로 인해 노드를 스케줄링할 수 없는 상태이기 때문에 kubectl uncordon 명령을 실행해서 스케줄링이 가능하도록 복구해야 한다.
다른 작업자 노드에도 동일한 작업을 수행하여 버전을 업그레이드해야 한다.
controlplane 버전 업그레이드하기
worker node 버전 업그레이드하기