공부하고 기록하는, 경제학과 출신 개발자의 노트

학습일지/kubernetes

CKA 대비 kubernetes 스터디 - 5. Cluster Maintenance

inspirit941 2022. 3. 14. 23:06
반응형

OS Upgrade

maintenance를 목적으로 (보안패치라던가, SW 업그레이드라던가) 클러스터의 특정 노드를 내려야 하는 경우.

스크린샷 2022-03-09 오후 11 57 23

  • 만약 특정 노드가 죽었을 경우
    • 노드가 금방 복구될 경우 -> kubelet은 이전에 돌고 있던 pod을 다시 시작시킨다. 큰 이상 없음.
    • 5분 이상 노드가 죽었을 경우 -> pod가 해당 노드에서 아예 제거된다. (dead로 간주함) 다시말해 마스터 노드는 특정 노드의 사망판정을 내리기까지 5분은 대기한다.
      • 만약 해당 pod가 replicaSet으로 관리되고 있다면, 다른 노드에서 pod를 재생성한다.
      • '5분' 인 이유는 pod Eviction time 때문이다. kube-controller-manager에서 설정된 값. --pod-eviction-timeout=5m0s

스크린샷 2022-03-09 오후 11 57 39

  • 5분 이상 다운된 노드는 복구됐을 때 어떤 pod도 올라가 있지 않게 된다. 따라서 예시에 있는 녹색 pod는 복원되지 못함.
    • 따라서, 만약 특정 노드를 업그레이드하거나 내렸을 때 복원까지의 기간이 5분 미만이거나
    • 해당 노드에 떠 있는 pod가 중요하지 않은 노드라면 quick upgrade / reboot 가 가능하다.

예측할 수 없거나, 장시간의 다운타임이 예상될 경우

  • kubectl drain node-1 와 같은 명령어로 해당 노드의 pod을 전부 다른 곳으로 reSchedule 진행한다.
    • 이렇게 된 노드를 cordoned / marked unscheduled node 라고 한다. 이 제한이 해제되기 전까지는 해당 노드에 어떤 pod도 할당될 수 없음.
  • kubectl uncordon node-1 으로, 업그레이드를 마치고 재부팅된 노드를 스케줄링 활성화할 수 있다. 활성화하는 것만으로는 pod가 자동으로 배분되는 것이 아니다.
  • kubectl cordon node-1 : 단순히 해당 노드를 unschedulable한 상태로 만드는 것. 해당 노드에 있는 pod는 건드리지 않는다.

k8s releases

스크린샷 2022-03-10 오전 1 33 29

  • 매달 minor release -> 기능 추가와 같은 작업
  • bug fix같은 추가는 patch을 올려서 반영한다.

스크린샷 2022-03-10 오전 1 36 04

  • 알파 버전: 버그 픽스 / 새로운 기능 추가가 최초로 반영되는 버전.
  • 베타 버전: 코드 테스트, 새로운 기능이 default로 반영됨
  • Stable: Release.

 

스크린샷 2022-03-10 오전 1 38 03

별개의 프로젝트로 사용되는 몇몇 컴포넌트는 버전이 다를 수 있다. kubectl이라던가 etcd라던가. extenal dependency들이 보통 해당됨.

 

Cluster Upgrade Process

스크린샷 2022-03-13 오후 8 56 05

  • kube-apiserver가 control plane의 핵심이기 때문에, control plane에 있는 컴포넌트들 - controller manager, kube-scheduler, kubelet, kube-proxy 등 - 의 버전은 kube-apiserver 버전을 넘을 수 없다.
    • controller manager, scheduler의 경우 1 낮은 버전도 허용되며, kubelet과 kube-proxy의 경우 한 단계 더 내려갈 수 있다.

하위 버전을 지원한다는 특성 때문에 live upgrade가 가능하다. 업그레이드가 필요한 컴포넌트만 진행할 수 있기 때문.

 

스크린샷 2022-03-13 오후 9 31 26

기본적으로 k8s는 {최신 버전 - 3} 까지만 지원하는 것이 원칙이다. 업그레이드 시에는 가급적이면 버전을 건너뛰지 않고 하나씩 업그레이드 하는 것을 권장하고 있다.

 

스크린샷 2022-03-14 오전 8 14 44

업그레이드 프로세스 자체는 "How your Cluster Setup"에 따라 다르다. GKE 같은 cloud provider는 옵션을 제공하고 있고, kubeadm을 활용한 업그레이드도 가능하며, custom cluster setup 상태라면 직접 업그레이드 방법을 찾아서 Manually 진행해야 한다.

 

스크린샷 2022-03-14 오전 8 26 50

업그레이드의 절차는

  1. Master Node 업그레이드
  2. Worker Node 업그레이드

순서로 이루어져야 한다.

  • 마스터 노드의 업그레이드를 위해, control plane에 있는 컴포넌트 (kube-apiserver, scheduler 등)가 잠깐 비활성화된다.
    • worker node에 올라가 있는 프로덕트는 이상없이 동작중임.
    • 대신, kubectl 같은 명령어로 worker node에 접근해서 리소스를 확인하는 등의 작업이 불가능하다.
    • 애플리케이션의 삭제, 옵션 변경 등의 작업도 불가능.
    • RelicationController도 정상 작동하지 않음. 특정 pod가 죽었을 경우 재시작하는 로직도 동작하지 않는다.

스크린샷 2022-03-14 오전 9 22 13

마스터노드를 업그레이드한 이후의 상태. 1 마이너 버전은 서로 호환되므로, worker node 버전이 낮아도 문제가 없다.

스크린샷 2022-03-14 오전 9 56 03스크린샷 2022-03-14 오전 9 55 56

  • 순차적으로 worker node를 업데이트해준다. 업데이트 방식에는 여러 가지가 있음
    • 전부 한번에 업그레이드 -> 사용자가 그동안 앱에 접근할 수 없다는 문제가 있음. (Downtime)
    • one node at a time -> 기존 노드를 하나씩 내리고, 업그레이드한 뒤 다시 올리는 방식. 그동안 애플리케이션 (pod) 은 다른 노드로 스케줄링한다.
    • 업그레이드 된 버전의 new node를 생성한 뒤 기존 노드를 업그레이드한다 -> 새로 노드를 provisioning하기 쉬운 환경일 때 사용 가능.
      • 새로운 노드로 기존 pod를 이동시킨 다음, 기존 노드를 제거하는 식으로... 모든 노드가 업그레이드될 때까지 진행한다.

 

KubeAdm 사용하기

스크린샷 2022-03-14 오전 10 06 41

  • kubeadm upgrade plan : cluster의 현재 버전, kubeAdm과 control plane 컴포넌트의 버전을 확인할 수 있다.
  • cluster 버전업이 끝나면, 각 노드의 kubelet도 버전을 올려야 한다. (kubeadm은 kubelet 버전업을 지원하지 않는다.)
  • 업그레이드를 진행하려면, 업그레이드할 버전의 kubeadm 설치가 선행되어야 한다.

 

스크린샷 2022-03-14 오전 10 40 36

  • kubeadm 업그레이드가 끝난 후에도 kubectl get nodes로 확인해보면 version이 그대로인 걸 볼 수 있음.
    • 이건 각 노드에 설치된 k8s버전을 의미한다. kube-apiserver 버전을 말하는 게 아님.

 

스크린샷 2022-03-14 오전 11 20 02

  • upgrade kubelet. (사용자가 설정을 어떻게 했느냐에 따라 kubelet이 master node에 없을 수도 있음.)
  • kubelet을 설치하면 node의 버전이 올라간 것으로 확인된다.

Worker Node 업그레이드하기

스크린샷 2022-03-14 오전 11 26 01

  • kubectl drain node-1 명령어. 해당 노드를 cordon 상태로 만들어 스케줄링에서 제외하는 동시에 기존 pod을 전부 다른 노드로 재배치한다.
  • 업그레이드를 진행할 노드에서 아래의 명령어들을 실행한다. 새 버전을 다운받고, 노드에 적용한 다음 재시작하는 로직.
    • apt-get upgrade -y kubeadm=<버전>
    • apt-get upgrade -y kubelet=<버전>
    • kubeadm upgrade node config --kubelet-version <버전>
    • systemctl restart kubelet
  • 버전업이 끝나면, 해당 노드의 cordon 상태를 제외하는 uncordon 명령어를 실행한다.
    • uncordon 자체로는 이전의 pod가 돌아오거나 하진 않는다. 다른 node에서 pod reschedule이 필요하거나 할 때 스케줄링 노드에 포함된다는 뜻.

Backup & Restore

스크린샷 2022-03-14 오후 2 41 38

백업에 필요한 것들?

  • deployments / service definition file 과 같은 resource Configuration
  • k8s cluster 관련 정보가 전부 포함되어 있는 ETCD cluster의 값.
  • persistent storage를 사용하고 있을 경우 storage

스크린샷 2022-03-14 오후 2 42 58

resource일 경우 Declarative - yaml 파일 형태로 관리하는 것이 좋다.

 

스크린샷 2022-03-14 오후 2 45 15

해당 리소스를 yaml 파일로 빼내 저장할 수 있고, 이런 서비스를 담당하는 회사들도 있다.

 

스크린샷 2022-03-14 오후 2 46 56

  • cluster / node 자체에 관련된 정보들은 etcd에 저장되어 있음. etcd의 경우 클러스터 자체를 백업해야 한다.
  • etcd.service의 data dir를 백업하면 됨.
  • built-in snapshot을 사용할 수 있다. etcdctl snapshot save snapshot.db 와 같은 명령어를 사용해서 저장해둘 수 있음. etcdctl snapshot status snapshot.db 로 스냅샷 상태 확인도 가능하다.

Restore 방법

 

스크린샷 2022-03-14 오후 2 50 45

  • kube-apiserver를 중지시키고, etcdctl 명령어로 특정 스냅샷을 restore한다.
  • etcdctl snapshot restore snapshot.db --data-dir /var/lib/etcd-from-backup 와 같은 명령어로 restore를 실행하면, 새로운 etcd 클러스터가 만들어지고 configured된다. 새로운 클러스터를 등록하고 기존 클러스터를 전부 정리하는데, 혹시나 생길지 모를 이전 클러스터와의 연결을 방지하기 위해서라고 함

스크린샷 2022-03-14 오후 2 53 55

  • 백업본이 사용할 새로운 data dir를 정의했으니 (etcd-from-backup), etcd service에도 data dir를 변경해준다.
  • 변경 후 daemon reload -> service etcd restart로 etcd를 재시작한다.
  • 마지막으로 kube-apiserver를 재시작한다. (service kube-apiserver start)

스크린샷 2022-03-14 오후 2 56 08

etcd 백업을 수행할 때에는 반드시 위 네 개의 필드에 정확한 값을 입력해야 한다.

  • endpoints
  • cacert
  • cert
  • key

etcd 클러스터 접근권한이 없을 경우 resource configuration을 사용하는 게 맞다.

반응형