kubernetes upgrade v1.28.7 -> v1.30

beomjin·2025년 8월 26일

kubernetes는 EOL이 굉장히 빠르다.
그렇다면 EOL이되면 더 이상 못쓰는걸까?
정답을보면 아니다.
kubernetes 공식문서상으로보면 upgrade 를 지원하고있다.

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

그렇다면 실제로 그런지 확인을 해보겠습니다.

제가 검증하려는 환경은 다음과 같습니다.

$ sudo kubectl get node
NAME        STATUS   ROLES           AGE   VERSION
compute01   Ready    <none>          22d   v1.28.7
compute02   Ready    <none>          22d   v1.28.7
control01   Ready    control-plane   22d   v1.28.7
control02   Ready    control-plane   22d   v1.28.7
control03   Ready    control-plane   22d   v1.28.7

master 3대 cluster 2대의 서버입니다.
kubernetes version은 1.28.7

우선 전제적인 조건으로 "외부와의 통신이 되어야한다" 라는 점을 우선 깔고 가는게 좋을 것 같다.
그런 전제조건을 세운 이유는, 외부통신이 가능하다면, repo를 구성하지않아도 kubernetes repo에서 kubernetes 패키지를 가져 올 수 있기 때문이다.
다만, 외부통신이 안되는 보안이 엄격한 환경이라면 미리 repo를 준비해야둬야한다.

k8s의 version upgrade는 마이너버전을 올리는 식으로 진행할 예정이다.
따라서, 1.28.7의 다음 마이너버전의 마지막 1.29.10으로 업그레이드 할 예정이다.

우선 repo부터 구성해보겠습니다.

$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

repo를 구성하였다면, 설치되는 패키지를 보자.

$ sudo yum install  kubeadm-'1.29.10-*' kubelet-'1.29.10-*' kubectl-'1.29.10-*' --disableexcludes=kubernetes
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:08:59 ago on Wed Oct 30 13:12:48 2024.
Dependencies resolved.
==============================================================================================================================================================================================================
 Package                                       Architecture                                 Version                                                    Repository                                        Size
==============================================================================================================================================================================================================
Upgrading:
 kubeadm                                       x86_64                                       1.29.10-150500.1.1                                         kubernetes                                       9.8 M
 kubectl                                       x86_64                                       1.29.10-150500.1.1                                         kubernetes                                        10 M
 kubelet                                       x86_64                                       1.29.10-150500.1.1                                         kubernetes                                        19 M
 
 
Transaction Summary
==============================================================================================================================================================================================================
Upgrade  3 Package
 
Total download size: 9.8 M
Is this ok [y/N]: y
...
Complete!

kubeadm, kubectl kubelet 을 1.29.10으로 설치하였다면, kubernetes의 upgrade plan을 보자

$ sudo kubeadm upgrade plan
COMPONENT   CURRENT       TARGET
kubelet     2 x v1.28.7   v1.29.10
...
COMPONENT                 CURRENT   TARGET
kube-apiserver            v1.28.7   v1.29.10
kube-controller-manager   v1.28.7   v1.29.10
kube-scheduler            v1.28.7   v1.29.10
kube-proxy                v1.28.7   v1.29.10
CoreDNS                   v1.8.6    v1.11.1
 
You can now apply the upgrade by executing the following command:
 
        kubeadm upgrade apply v1.29.10
...

upgrade를 하기 전 kube-scheduler를 수정해야한다.
사유는 kubernets 1.28 버전 이후부터 kube-scheduler의 apiVersion이 변경되었기 때문이다.
이걸 미리 수정안하고 version upgrade를 하면...kube-scheduler가 동작을 하지못한다.

  • 이 작업은 모든 Master node 에서 진행한다.
[user@control-01 ~]$ sudo vi /etc/kubernetes/kubescheduler-config.yaml
-apiVersion: kubescheduler.config.k8s.io/v1beta3
+apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: "/etc/kubernetes/scheduler.conf"
leaderElection:
  leaseDuration: 15s
  renewDeadline: 10s

AS-IS : kubescheduler.config.k8s.io/v1beta3
TO-BE : kubescheduler.config.k8s.io/v1

이제 업그레이드 모의 테스트 및 업그레이드를 진행해보자.

[user@control-01 ~]$ sudo kubeadm upgrade apply v1.25.16 --certificate-renewal=false --dry-run |less
...
[upgrade/successful] Finished dryrunning successfully!

--certificate-renewal=false 옵션을 주어 인증서를 새로 갱신하지 않고 기존 것으로 사용하도록 하자.

kubernetes upgrade 진행

[user@control-01 ~]$ sudo kubeadm upgrade apply v1.29.10 --certificate-renewal=false
[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'
W1030 13:27:16.107257 3431200 utils.go:69] The recommended value for "clusterDNS" in "KubeletConfiguration" is: [10.233.0.10]; the provided value is: [169.254.25.10]
[preflight] Running pre-flight checks.
[upgrade] Running cluster health checks
[upgrade/version] You have chosen to change the cluster version to "v1.29.10"
[upgrade/versions] Cluster version: v1.28.7
[upgrade/versions] kubeadm version: v1.29.10
[upgrade] Are you sure you want to proceed? [y/N]: y
...
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
 
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.29.10". Enjoy!
 
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.

마찬가지로 모의 업데이트 했을때와 동일하게 --certificate-renewal=false 옵션을 주어 인증서를 새로 갱신하지 않고 기존 것으로 사용하도록 하자.
또한, 업그레이드 중에는 kube-apiserver가 중단될 수 있다. 이점은 미리 참고하자.

upgrade 간 pod가 재기동되는데, 이때 모니터링을 잘 해둬야한다.

[user@control01 ~]$ sudo kubectl get po -n kube-system -w

문제가 발생하면 언제든 돌아갈 수 있도록.

pod가 모두 정상적으로 동작한다면, kubelet 서비스를 재시작하자.

[user@control01 ~]$ sudo systemctl daemon-reload
[user@control01 ~]$ sudo systemctl restart kubelet

해당 작업 이후에도 모든 kube-system pod들이 재시작되므로 kubectl 명령어가 수행되지 않을 수 있습니다.(길게는 약 5분)
이 과정에서 공식문서는 drain을 통하여 안정적으로 진행하지만 금번 문서에서는 drain을 진행하지않고 한다.

version이 업그레이드가 잘 되었는지 확인하자.

[user@control01 ~]$ sudo kubectl get node
NAME        STATUS   ROLES           AGE   VERSION
compute01   Ready    <none>          23d   v1.28.7
compute02   Ready    <none>          23d   v1.28.7
control01   Ready    control-plane   23d   v1.29.10
control02   Ready    control-plane   23d   v1.28.7
control03   Ready    control-plane   23d   v1.28.7

control01의 master node의 버전이 v1.28.7 -> v1.29.10 으로 upgrade가 되었다.

이제 남은 Master node인 control2, contorl3도 동일하게 진행한다.

그럼 worker node는 어떻게 해야할까?

work node도 동일하게 우선 repo부터 구성하자.

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

kubeadm 패키지 설치

[user@compute01 ~]$ sudo yum install -y kubeadm-'1.29.10-*' kubelet-'1.29.10-*' --disableexcludes=kubernetes
...
Complete!

worker node의 kubeadm을 upgrade

[user@compute01 ~]$ sudo kubeadm upgrade node --certificate-renewal=false
[upgrade] Reading configuration from the cluster...
[upgrade] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
W1030 14:24:56.807820 1657159 utils.go:69] The recommended value for "clusterDNS" in "KubeletConfiguration" is: [10.233.0.10]; the provided value is: [169.254.25.10]
[preflight] Running pre-flight checks
[preflight] Skipping prepull. Not a control plane node.
[upgrade] Skipping phase. Not a control plane node.
[upgrade] Backing up kubelet config file to /etc/kubernetes/tmp/kubeadm-kubelet-config1361617122/config.yaml
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[upgrade] The configuration for this node was successfully updated!
[upgrade] Now you should go ahead and upgrade the kubelet package using your package manager.

완료되었다면 daemon 재시작!

[user@compute01 ~]$ sudo systemctl daemon-reload
[user@compute01 ~]$ sudo systemctl restart kubelet

worker node 버전 확인

[clex@control01 ~]$ sudo kubectl get node
NAME        STATUS     ROLES           AGE   VERSION
compute01   Ready      <none>          23d   v1.29.10
compute02   Ready      <none>          23d   v1.29.10
control01   Ready      control-plane   23d   v1.29.10
control02   Ready      control-plane   23d   v1.29.10
control03   Ready      control-plane   23d   v1.29.10

다들 v1.29.10 으로 잘 올라왔다.

그럼 이제 1.30으로 가보자
Master node부터 업그레이드를 진행한다.

$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

패키지 설치

[user@control01 ~]$ sudo yum install  kubeadm-'1.30.0-*' kubelet-'1.30.0-*' kubectl-'1.30.0-*' --disableexcludes=kubernetes
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:09:49 ago on Wed Oct 30 14:33:34 2024.
Dependencies resolved.
==============================================================================================================================================================================================================
 Package                                         Architecture                                 Version                                                  Repository                                        Size
==============================================================================================================================================================================================================
Upgrading:
 cri-tools                                       x86_64                                       1.30.1-150500.1.1                                        kubernetes                                       8.6 M
 kubeadm                                         x86_64                                       1.30.0-150500.1.1                                        kubernetes                                        10 M
 kubectl                                         x86_64                                       1.30.0-150500.1.1                                        kubernetes                                        10 M
 kubelet                                         x86_64                                       1.30.0-150500.1.1                                        kubernetes                                        17 M
 
Transaction Summary
==============================================================================================================================================================================================================
Upgrade  4 Packages
 
Total download size: 46 M
Is this ok [y/N]: y
 
...
Complete!

kubernets upgrade plan을 살펴보자

[user@control01 ~]$ sudo kubeadm upgrade plan
COMPONENT   NODE              CURRENT    TARGET
kubelet     control-01   v1.29.10   v1.30.6
kubelet     control-02   v1.29.10   v1.30.6
kubelet     control-03   v1.29.10   v1.30.6
 
Upgrade to the latest stable version:
 
COMPONENT                 NODE              CURRENT    TARGET
kube-apiserver            control-01   v1.29.10   v1.30.6
kube-controller-manager   control-01   v1.29.10   v1.30.6
kube-scheduler            control-01   v1.29.10   v1.30.6
kube-proxy                                  1.29.10    v1.30.6
CoreDNS                                     v1.8.6     v1.11.1
...
You can now apply the upgrade by executing the following command:
 
        kubeadm upgrade apply v1.30.6

모의 업그레이드 진행

[user@control01 ~]$ sudo kubeadm upgrade apply v1.30.0 --certificate-renewal=false --dry-run |less
...
[upgrade/successful] Finished dryrunning successfully!
  • --certificate-renewal=false 옵션을 주어 인증서를 새로 갱신하지 않고 기존 것으로 사용

kubernets upgrade


[user@control01 ~]$ sudo kubeadm upgrade apply v1.30.0 --certificate-renewal=false
[upgrade/config] Making sure the configuration is correct:
[preflight] Running pre-flight checks.
[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'
[upgrade] Running cluster health checks
[upgrade/version] You have chosen to change the cluster version to "v1.30.0"
[upgrade/versions] Cluster version: v1.29.10
[upgrade/versions] kubeadm version: v1.30.0
[upgrade] Are you sure you want to proceed? [y/N]:y
...
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
 
[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.30.0". Enjoy!
 
[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
  • --certificate-renewal=false 옵션을 주어 인증서를 새로 갱신하지 않고 기존 것으로 사용
  • 업그레이드 중 kube-apiserver 서비스가 중단될 수 있음

이전 upgrade 와 마찬가지로 pod monitoring 후 daemon을 재기동하자.

# pod 상태 확인
[user@control01 ~]$ sudo kubectl get po -n kube-system -w

# daemon 재기동
[user@control01 ~]$ sudo systemctl daemon-reload
[user@control01 ~]$ sudo systemctl restart kubelet

버전을 확인해보자.

[user@control01 ~]$ sudo kubectl get node
NAME        STATUS   ROLES           AGE   VERSION
compute01   Ready    <none>          23d   v1.29.10
compute02   Ready    <none>          23d   v1.29.10
control01   Ready    control-plane   23d   v1.30.0
control02   Ready    control-plane   23d   v1.29.10
control03   Ready    control-plane   23d   v1.29.10

음! 잘올라왔다.

자 이제 worker node를 진행해보자.
repo생성

cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

kubeadm 설치

[user@compute01 ~]$ sudo yum install -y kubeadm-'1.30.00-*' kubelet-'1.30.0-*' --disableexcludes=kubernetes
...
Complete!

upgrade kubeadm worker node

[user@compute01 ~]$ sudo kubeadm upgrade node --certificate-renewal=false
[upgrade] Reading configuration from the cluster...
[upgrade] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
W1030 14:24:56.807820 1657159 utils.go:69] The recommended value for "clusterDNS" in "KubeletConfiguration" is: [10.233.0.10]; the provided value is: [169.254.25.10]
[preflight] Running pre-flight checks
[preflight] Skipping prepull. Not a control plane node.
[upgrade] Skipping phase. Not a control plane node.
[upgrade] Backing up kubelet config file to /etc/kubernetes/tmp/kubeadm-kubelet-config1361617122/config.yaml
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[upgrade] The configuration for this node was successfully updated!
[upgrade] Now you should go ahead and upgrade the kubelet package using your package manager.

kubelet 재기동

[user@compute01 ~]$ sudo systemctl daemon-reload
[user@compute01 ~]$ sudo systemctl restart kubelet

kubernetes version확인

[user@control01 ~]$ sudo kubectl get node
NAME        STATUS   ROLES           AGE   VERSION
compute01   Ready    <none>          23d   v1.30.0
compute02   Ready    <none>          23d   v1.30.0
control01   Ready    control-plane   23d   v1.30.0
control02   Ready    control-plane   23d   v1.30.0
control03   Ready    control-plane   23d   v1.30.0

자 이러면 kubernets version이 1.28.7 -> 1.30으로 모두 올라왔다.
이제 안심하고 외부통신을 단절하면될까?
아니다. 절대 아니다.

이 작업이 완료되었으면 우린 가장 중요한 작업을 해야한다.
외부통신을 계속 열어둘 것이면 상관없지만, 다시 닫아야하는 경우엔 upgrade 된 이미지들을 모두 사설 registry로 옮겨야한다.
그렇지 않으면 pod가 imagepullbackoff이 발생하니까...

여기서 무슨 pod에 대해서 사설 registry로 바라보게 할거냐?
나는 이렇게 list를 짜보았다.

image list

kube-apiserver
kube-contoller-manager
kube-proxy
kube-scheduler
core-dns

해당 이미지들에 대해서 tagging과 push가 되었다면, 이제 동작중인 kubernetes 에서도 바라 볼 이미지를 바꿔줘야한다.

kube-apiserver

$ sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
...
    - --tls-private-key-file=/etc/kubernetes/ssl/apiserver.key
    image: registry.k8s.io/kube-apiserver:v1.30.0
    imagePullPolicy: IfNotPresent
    livenessProbe:
...

kube-controller-manager


$ sudo vi /etc/kubernetes/manifests/kube-controller-manager.yaml
...
    - --use-service-account-credentials=true
    image: registry.k8s.io/kube-controller-manager:v1.30.0
    imagePullPolicy: IfNotPresent
    livenessProbe:
...

kube-scheduler

$ sudo vi /etc/kubernetes/manifests/kube-scheduler.yaml
...
    - --leader-elect=true
    image: registry.k8s.io/kube-scheduler:v1.30.0
    imagePullPolicy: IfNotPresent
    livenessProbe:
      failureThreshold: 8
...

core-dns

$ sudo kubectl edit deploy -n kube-system coredns
...
      - args:
        - -conf
        - /etc/coredns/Corefile
        image: registry.k8s.io/coredns/coredns:v1.8.6
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 5
...

kube-proxy

$ sudo kubectl edit ds -n kube-system kube-proxy
...
              fieldPath: spec.nodeName
        image: registry.k8s.io/kube-proxy:v1.30.0
        imagePullPolicy: IfNotPresent
...

이미지 들을 모두 사설 registry로 바라보도록 수정한다면 외부통신이 단절되어도 pod는 정상적으로 돌게된다.

이로써 kuberntes upgrade 가 완료되었다.

0개의 댓글