관리 메뉴

피터의 개발이야기

[kubernetes] Cluster Maintenance - 리눅스 노드 업그레이드 본문

Kubernetes

[kubernetes] Cluster Maintenance - 리눅스 노드 업그레이드

기록하는 백앤드개발자 2023. 12. 21. 00:26
반응형

 

ㅁ 들어가며

  저는 kubernetes 버젼업 경험이 있지만 없습니다.

AWS EKS와 단독형 클러스터의 업그레이드 과정은 달랐기 때문입니다.

그래서 AWS EKS 버젼 업그레이드와 생 클러스터 버젼 업그레이드 차이점을 짧게 이야기하고,

kubeadm으로 생성된 리눅스 노드를 업그레이드하는 방법을 Play with Kubernetes에서 실습과정을 정리해 보도록 하겠습니다.

 

ㅁ AWS EKS와 직접 Cluster 관리의 차이

AWS는 대표적인 Cloud 서비스 입니다.

인프라를 서비스로 제공하여 사용할 수 있게 하고,

내부적인 관리나 운영은 AWS에서 책임을 지고 있죠.

그래서 서버를 직접 구성하여 Cluster을 직접관리하는 것과는 경험적 차이가 큽니다.

구체적으로 제가 EKS 버젼업그레이드 과정을 예로 들어 설명을 드리겠습니다.

 

AWS EKS 버젼 업그레이드를 진행하고 관련 글이 있습니다.

[EKS] Amazon EKS 버전 업그레이드, #1 EKS 클러스터
[EKS] Amazon EKS 버전 업그레이드, #2 WorkNode

 

 요약해서 말씀드리면,

 AWS EKS 버젼에 맞게 최적화된 Amazon Linux AMI 버전을 찾아

AutoScale그룹에 지정(정확히는 CloudFormation에 파라미터 수정)을 해주었습니다.

그래서 AWS 장점이자 단점으로 구체적인 Cluster의 관리를 직접적으로 해 볼 기회는 적었습니다.

모든 것은 콘솔에서 선택으로 이미 최적화가 이루어진 EKS 마스터 클러스터를 받아서 사용할 뿐 
사용자에게는 은닉화되어 있었습니다.

그래서 실질적으로 마스터노드가 Master-Slave-Slave로 3중화 되어 있는지도 몰랐는데요.

 

EKS 장애가 발생하면서 알게 되었죠.

EKS의 클러스터의 통신이 순단(1분동안)하여 장애가 발생하여 서비스 장애로 이어졌는데요.

AWS에 장애 상황에 대해 문의를 한 결과, EKS fail-over 상황이 발생한 것을 확인 할 수 있었습니다.

이 때 마스터노드가 3중화가 되어 있다는 걸 알게 되었죠. 

마스터 노드가 장애가 나서 자동으로 fail-over되면서 1분동안 통신이 되지 않았습니다.

자세한 내용은 [kubernetes] EKS fail-over 상황정리 및 방어방법에 정리한 내용입니다.

 

 EKS 마스터 노드를 들어갈 수도 없고, 장애조치가 어떻게 이루어지는 지도 몰랐던 상황이라 조금 당황을 했었지만

이게 IaaS구나 하는 생각이 들었습니다. 장애조치가 잘 되어 있어서요. 이걸 직접 관리한다면 엄청나게 많은 고민과 기술이 필요할테니깐요.

 

그래서 이번에 kubeadm으로 클러스터 버젼 업그레이드 하는 과정을 경험해 보기위해 실습을 진행하였습니다.

 

ㅁ Play with kubernetes 실습환경

                          WARNING!!!!

 This is a sandbox environment. Using personal credentials
 is HIGHLY! discouraged. Any consequences of doing so, are
 completely the user's responsibilites.

 You can bootstrap a cluster as follows:

 1. Initializes cluster master node:
 kubeadm init --apiserver-advertise-address $(hostname -i) --pod-network-cidr 10.5.0.0/16

 2. Initialize cluster networking:
 kubectl apply -f https://raw.githubusercontent.com/cloudnativelabs/kube-router/master/daemonset/kubeadm-kuberouter.yaml

 3. (Optional) Create an nginx deployment:
 kubectl apply -f https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/nginx-app.yaml

                          The PWK team.

 

 ㅇ 기본 환경을 구성을 위해 3개의 명령어를 실행합니다.

 ㅇ 테스트용으로 3번 nginx pod도 띄웠습니다.

 

ㅁ 현재 버젼 확인

$ kubectl version --short
Flag --short has been deprecated, and will be removed in the future. The --short output will become the default.
Client Version: v1.27.2
Kustomize Version: v5.0.1
Server Version: v1.27.8

 

 ㅇ 현재 1.27.8이기 때문에 1.28.x(여기 x는 최신버젼을 뜻함)으로 업그레이드 진행하도록 하겠습니다.

 

 

ㅁ 업그레이드할 버전 결정

$ yum list --showduplicates kubeadm --disableexcludes=kubernetes
# 목록에서 최신 버전(1.28)을 찾는다
# 1.28.x-0과 같아야 한다. 여기서 x는 최신 패치이다.

 ㅇ 1.28.2-0이 최신 패치입니다.

 

ㅁ kubeadm 업그레이드

$ yum install -y kubeadm-1.28.2-0 --disableexcludes=kubernetes

 

ㅁ 업그레이드 확인

$ kubeadm version         
kubeadm version: &version.Info{Major:"1", Minor:"28", GitVersion:"v1.28.2", GitCommit:"89a4ea3e1e4ddd7f7572286090359983e0387b2f", GitTreeState:"clean", BuildDate:"2023-09-13T09:34:32Z", GoVersion:"go1.20.8", Compiler:"gc", Platform:"linux/amd64"}
RTNETLINK answers: File exists

 

ㅁ 업그레이드 시도 및 실패 원인 분석

$ kubeadm upgrade apply v1.28.2 --v=5
I1220 09:56:23.048245   18192 apply.go:106] [upgrade/apply] verifying health of cluster
I1220 09:56:23.048343   18192 apply.go:107] [upgrade/apply] retrieving configuration from cluster
[upgrade/config] Making sure the configuration is correct:
[upgrade/config] Reading configuration from the cluster...
[upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
I1220 09:56:23.070119   18192 kubelet.go:74] attempting to download the KubeletConfiguration from ConfigMap "kubelet-config"
I1220 09:56:23.093476   18192 common.go:186] running preflight checks
[preflight] Running pre-flight checks.
I1220 09:56:23.093525   18192 preflight.go:77] validating if there are any unsupported CoreDNS plugins in the Corefile
I1220 09:56:23.101875   18192 preflight.go:109] validating if migration can be done for the current CoreDNS release.
[upgrade] Running cluster health checks
I1220 09:56:23.113395   18192 health.go:157] Creating Job "upgrade-health-check" in the namespace "kube-system"
I1220 09:56:23.127974   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:24.133342   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:25.133596   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:26.132567   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:27.132509   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:28.134823   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:29.133340   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:30.133100   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:31.133937   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:32.133310   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:33.132894   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:34.134216   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:35.132491   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:36.133164   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:37.133257   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:38.132922   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:38.136867   18192 health.go:187] Job "upgrade-health-check" in the namespace "kube-system" is not yet complete, retrying
I1220 09:56:38.136932   18192 health.go:200] Deleting Job "upgrade-health-check" in the namespace "kube-system"

 ㅇ 업그레이드를 수행하였지만, health check에서 문제가 발생하였다.

 

$ kubectl get po -n kube-system --field-selector=status.phase!=Running
NAME                       READY   STATUS    RESTARTS   AGE
coredns-5d78c9869d-nw985   0/1     Pending   0          127m
coredns-5d78c9869d-wt72w   0/1     Pending   0          127m

 ㅇ coredns가 pending 상태여서 통신문제가 발생하였다.

 

ㅁ Coredns Pending 상세원인분석

$ kubectl describe -n kube-system pod coredns-5d78c9869d-nw985 
Name:                 coredns-5d78c9869d-nw985
Namespace:            kube-system
~~~~~~~~~~ 중간생략 ~~~~~~~~~~
Events:
  Type     Reason            Age                    From               Message
  ----     ------            ----                   ----               -------
  Warning  FailedScheduling  3m24s (x26 over 128m)  default-scheduler  0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/not-ready: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling..

 ㅇ node.kubernetes.io/not-ready taint로 인해 노드에 스케줄링이 되지 않았다.

 

ㅁ Taint 확인 및 제거

$ kubectl get no -o yaml | grep -i taint -n5
21-    uid: 8ff7e669-7bc9-49e2-a527-d1c8b0bbc768
22-  spec:
23-    podCIDR: 10.5.0.0/24
24-    podCIDRs:
25-    - 10.5.0.0/24
26:    taints:
27-    - effect: NoSchedule
28-      key: node-role.kubernetes.io/control-plane <====제거 대상
29-    - effect: NoSchedule
30-      key: node.kubernetes.io/not-ready   <====제거 대상
31-  status:

 

$ kubectl taint no node2 node.kubernetes.io/not-ready:NoSchedule-
node/node2 untainted

$ kubectl taint no node2 node.kubernetes.io/not-ready:NoSchedule-
node/node2 untainted

 ㅇ taint를 제거 하기 위해 (-)를 마지막에 붙여 주었습니다.

 

ㅁ 업데이트 실습 실패...

$ kubectl logs -n kube-system coredns-5d78c9869d-nw985 
Error from server (BadRequest): container "coredns" in pod "coredns-5d78c9869d-nw985" is waiting to start: ContainerCreating

 ㅇ 실질적인 coredns pod는 생성이 되지를 않았습니다.

 

 ㅇ 제거 되어야 하는 taint가 제거가 되지 않았고, 반복적으로 제거명령을 내렸지만... 다시 생성되어 있었습니다.

 ㅇ 그래서 업그래이드 실습은 실패하였지만, 내용은 여기에 마저 정리하도록 하겠습니다.

 

ㅁ kubeadm upgrade 실행

$ kubeadm upgrade apply v1.28.2 --v=5

 ㅇ 1.28.2 버젼으로 클러스터를 업그레이드 합니다.

 ㅇ --v=5  =>  Error를 구체적으로 볼 수 있는 Debug 옵션입니다.

 

 

ㅁ WorkNode upgrade

kubeadm upgrade node

 

 ㅇ 워커 노드의 경우 로컬 kubelet 구성을 업그레이드 한다.

 

ㅁ kubelet과 kubectl 업그레이드

yum install -y kubelet-1.28.2-0 kubectl-1.28.2-0 --disableexcludes=kubernetes

 

kubelet 재기동

You may need to reload the daemon and restart kubelet service after it has been upgraded.

systemctl daemon-reload
systemctl restart kubelet

 

 

ㅁ 함께 보면 좋은 사이트

kubeadm 클러스터 업그레이드(v1.28)

쿠버네티스 리눅스 노드 업그레이드 문서

반응형

'Kubernetes' 카테고리의 다른 글

[kubernetes] 쿠버네티스 목차  (6) 2024.01.19
Comments