본문 바로가기
Kubernetes (k8s)

[k8s] Cluster Maintenance

by moveho 2023. 4. 8.

OS Upgrades

software 업그레이드 또는 security patch 등 node를 내려야할 일이 있을 때, 어떻게 안정적으로 클러스터를 유지할까?

  • 노드가 5분(—pod-eviction-timeout) 안에 정상화되지 않을 경우 pod은 종료됨
  • replicaset 의 pod이었을 경우, 다른 노드에 재생성됨
  • 그냥 pod일 경우 사라지게됨

안전하게 노드를 작업하기 위해, drain을 통해 모든 workload를 다른 노드로 옮길 수 있음

  • kubectl drain node-1
  • 기존 노드에서 pod들이 종료되고, 다른 노드에서 재생성됨
  • 또한 노드가 cordon되고, unshedulable 로 마크됨
    • 제약을 삭제할 때까지, 아무 pod도 스케줄되지 않음
  • pod이 다른 노드에서 안전하면, 노드를 reboot할 수 있음
  • 다시 돌아왔을 때도, 노드가 unschedulable 하기 때문에, uncordon 해주어야함 → kubectl uncordon node-1
    • 이동했던 pod들이 자동으로 돌아오는 것은 아님
  • kubectl cordon node-2
    • cordon의 경우, 노드를 unschedulable로 마크하지만, drain과 다르게 pod을 종료/이동시키지 않음
    • 그저 새로운 pod이 더 이상 스케줄링 되지 않도록 처리

Cluster Upgrade Process

쿠버네티스의 구성요소들이 버전이 모두 같을 필요는 없지만,

kube api 서버는 control plane의 핵심 구성요소로, 다른 구성요소들은 kube api 서버보다 버전이 높으면 안됨

  • kube-apiserver 버전이 v1.10 일때
  • controller-manager과 kube-scheduler는 v1.9, v1.10 이 가능하고,
  • kubelet과 kube-proxy 는 그보다 하나씩 더 낮은 v1.8, v1.9, v1.10 까지 가능함

쿠버네티스는 새 버전이 릴리즈되면(v1.13), 두 버전 이전까지만 지원됨 (v1.13 ~ v1.11) → 이에 맞춰 버전을 업그레이드해주어야함

  • 업그레이드시에는, minor 버전 하나씩 올리는 것이 권장됨
    • 1.10 → 1.11 → 1.12

클러스터 업그레이드 방법

  1. master node 업그레이드
    • master node가 업그레이드 되는 동안, api server, scheduler, controller manager 등 control plane 구성요소들이 다운됨
    • master node가 다운된다는 것이 worker node나 application들이 영향받는다는 것은 아님
  2. worker node 업그레이드
    1. worker node들을 한번에 업그레이드
      • application 접근 불가
    2. worker node 하나씩 업그레이드
      • 업그레이드할 노드의 pod들을 옮겨놓고, 업그레이드 후 다시 옮김 → worker node 마다 반복
    3. 새 노드를 추가하고 원래 노드를 evict
      • 클라우드 환경에서 편리하게 가능

upgrade command

참고: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

업그레이드시 도움이 되는 정보

  • kubeadm upgrade plan

클러스터 업그레이드시 kubeadm 버전을 업그레이드 해준다

  • apt-get upgrade -y kubeadm=1.18.0-00

클러스터 업그레이드

  • kubeadm upgrade apply v1.18.0

→ 위 과정을 진행한 후, kubectl get nodes 시 클러스터 버전이 변하지 않은 걸 볼 수 있음 → api 서버 버전 자체가 아닌, api 서버에 등록된 kubelet 의 버전이기 때문

kubelet 업그레이드

  • apt-get upgrade -y kubelet=1.18.0-00
  • systemctl restart kubelet

worker node 업그레이드

  • worker node 하나씩 접속/진행
  • kubectl drain node1(--ignore-daemonsets) 을 통해 pod 이동
  • kubectl cordon node1 을 통해 pod을 unschedulable 로 마크
  • kubeadm 업그레이드(apt-get upgrade -y kubeadm=1.18.0-00)
  • kubelet 업그레이드 (apt-get upgrade -y kubelet=1.18.0-00)
  • 새로운 버전 설정 및 kubelet 재시작
    • kubeadm upgrade node config --kubelet-version v1.18.0
    • systemctl restart kubelet
  • kubectl uncordon node1 다시 스케줄될 수 있도록 설정
  • → worker node마다 과정 반복

→ 잘 안되면 apt install kubeadm=1.20.0-00 같이 apt install 로 설치

Backup and Restore Methods

declarative 방식 (파일로 object를 생성하는 것)이 backup 에 있어서는 imperative보다 선호됨

모든 리소스를 백업하는 방법으로 모든 object 를 yaml 파일로 남기는 방법이 있음

  • kubectl get all --all-namespaces -o yaml > all-deploy-services.yaml

ETCD

  • ETCD는 클러스터의 모든 정보를 저장하고 있음
  • 위 방법처럼 리소스를 백업하는 대신, ETCD 서버 자체를 백업하는 방법이 있음
  • ETCD 서버는 마스터 노드에 host 됨
  • 모든 데이터가 저장되는 data directory 는 etcd.service 에서 설정 가능 → --data-dir

ETCD Snapshot

스냅샷 생성

  • ETCDTL_API=3 etcdctl snapshot save snapshot.db
  • → ls 시 현재 dir에 스냅샷 파일이 생성된 것을 확인할 수 있음

스냅샷 상태 확인

  • ETCDTL_API=3 etcdctl snapshot status snapshot.db

ETCD Backup

참고: https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/

ETCDCTL_API=3 etcdctl \\\\
  --endpoints=https://[127.0.0.1]:2379 \\\\
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \\\\
  --cert=/etc/kubernetes/pki/etcd/server.crt \\\\
  --key=/etc/kubernetes/pki/etcd/server.key \\\\
  snapshot save /tmp/snapshot-pre-boot.db
  • 위 옵션은 etcd 프로세스에서 확인 가능
    • ps -aux | grep -i etcd
      • —cert-file
      • —key-file
      • —trusted-ca-file
    • 위 명령어로 나오지 않는다면, /etc/kubernetes/manifests/etcd.yaml 에 spec.containers.command 필드를 보면 ETCD 실행시 사용되는 parameter들을 확인할 수 있음

ETCD Restore

  1. kube-apiserver 중지
    • service kube-apiserver stop
  2. etcd restore→ etcd config 파일을 보면 해당 —data-dir 가 적용된 걸 볼 수 있음
    • ETCDCTL_API=3 etcdctl snapshot restore snapshot.db --data-dir /var/lib/etcd-from-backup
    • ETCDCTL_API=3 etcdctl \\ --endpoints=https://[127.0.0.1]:2379 \\ --cacert=/etc/kubernetes/pki/etcd/ca.crt \\ --cert=/etc/kubernetes/pki/etcd/server.crt \\ --key=/etc/kubernetes/pki/etcd/server.key \\ --name=master \\ --data-dir /var/lib/etcd-from-backup \\ --initial-cluster-token=etcd-cluster-1 \\ --initial-cluster=master=https://127.0.0.1:2380 \\ --initial-advertise-peer-urls=https://127.0.0.1:2380 \\ snapshot restore /tmp/snapshot-pre-boot.db # 백업파일경로
  3. systemctl daemon-reload
  4. service etcd restart
  5. service kube-apiserver start

참고: https://github.com/jonnung/cka-practice/blob/master/5-cluster-maintenance.md

  • ETCD POD은 기본적으로 static POD 이기 때문에, /etc/kubernetes/manifests/etcd.yaml 에 생성 파일이 존재함
  • 해당 yaml 에서 restore시 자신이 지정한 --data-dir /var/lib/etcd-from-backup 로 수정해주어야함
volumes:
- hostPath:
    path: /etc/kubernetes/pki/etcd
    type: DirectoryOrCreate
  name: etcd-certs
- hostPath:
    path: /var/lib/etcd-from-backup # 이 부분 수정
    type: DirectoryOrCreate
  name: etcd-data
  • 수정 후 저장하면 쿠버네티스가 ETCD POD을 재생성하고, data 디렉토리를 /var/lib/etcd-from-backup 를 바라보게 됨

댓글