Q1)
Upgrade the current version of kubernetes from 1.29.0 to 1.30.0 exactly using the kubeadm utility. Make sure that the upgrade is carried out one node at a time starting with the controlplane node. To minimize downtime, the deployment gold-nginx should be rescheduled on an alternate node before upgrading each node.
Upgrade controlplane node first and drain node node01 before upgrading it. Pods for gold-nginx should run on the controlplane node subsequently.
풀이)
1번 문제는 kubeadm을 통해서 클러스터 업그레이드를 할 수 있는지를 판단하는 문제이다. 요구사항은 다음과 같다.
- 쿠버네티스의 현재 버전을 1.29.0 에서 1.30.0 으로 업그레이드
- kubeadm을 이용할 것
- 컨트롤 노드 부터 시작하여 순차적으로 한 노드씩 진행할 것
- gold-nginx deployment를 각 노드가 업그레이드 되기 전에 다른 노드로 재배치 할 것
(즉, 결론적으로 두개의 노드이고 컨트롤플레인 노드 먼저 업그레이드를 진행하니, gold-nginx pod는 업그레이드 후에 controlplane 노드에 존재해야 한다.)
1)먼저 다음 명령어를 통해 kubeadm의 버전을 확인한다.
kubeadm version
처음 명령어 입력 시, v1.29.0 버전이 확인된다.
kubeadm을 이용해서 쿠버네티스의 버전을 업그레이드 하기 위해서는, kubeadm의 버전이 upgrade를 목표로 하는 버전보다, 높거나 동일해야 한다.
그러니, 일단 Kubeadm 버전 업그레이드를 먼저 진행한다.
2)kubeadm version upgrade
sudo apt-cache madison kubeadm
위 명령어를 통해 현재 upgrade 가능한 kubeadm 버전을 확인 가능하다.
아마, 1.29.x 버전만 확인 될 것이다.
/etc/apt/sources.list.d/kubernetes.list 파일을 확인해보면 다음과 같이, 현재 apt 패키지 관리자가 참조하는 버전이 1.29로 되어 있다. 해당 부분을 v1.30으로 수정 후 파일을 저장한다.
deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /
그 후, 다시 다음 명령어를 통해 업그레이드 가능한 버전을 확인한다.
sudo apt update
sudo apt-cache madison kubeadm
타깃 버전인 1.30.0-1.1로 kubeadm 버전을 업그레이드 한다.
(참고: 'sudo apt-mark unhold kubeadm'은 'kubeadm' 패키지의 버전 고정을 해제하는 명령어다. 이전에 'kubeadm' 패키지가 특정 버전으로 고정되어 있었다면, 이 명령어를 통해 그 고정을 해제할 수 있다.)
sudo apt-mark unhold kubeadm && \
sudo apt-get update && sudo apt-get install -y kubeadm='1.30.0-1.1' && \
sudo apt-mark hold kubeadm
##업그레이드 완료 후, 다시 버전확인
kubeam version
3)kuberntes version upgrade
버전이 1.30으로 올라갔음을 확인 후, 다음 명령어를 통해 현재 업그레이드 가능한 쿠버네티스 버전을 확인한다.
sudo kubeadm upgrade plan
아마 kubeadm 버전(1.30.0)보다 높은 kubernetes 버전이 나올 수도 있지만, 위에서 언급했듯이 더 높은 버전으로는 업그레이드 불가하다. 목표 버전인 1.30.0으로 업그레이드를 진행한다.
업그레이드 전에, 문제의 요구사항대로(gold-nginx를 각 노드가 업그레이드 되기 전에 다른 노드로 재배치 할 것) 다른 노드에 해당 pod를 재배치한다.
(controlplane->worker node)
###노드 이름 확인
kubectl get nodes
###드레인 명령어 실행
kubectl drain controlplane --ignore-daemonsets
위 명령어 실행 시, 해당 노드에 존재하는 파드를 다른 노드에 reschedule 한다.
이제, controlplane 노드를 업그레이드 한다.
sudo kubeadm upgrade apply v1.30.0
다음은 kubectl과 kubelet업그레이드가 필요하다. 쿠버네티스 버전과 동일한 버전으로 업그레이드를 진행한다.
해당 업그레이드를 진행하지 않으면, 정답 처리 되지않는다.
(server 버전 업그레이드후, client 버전도 업그레이드 하는 개념)
###kubectl 및 kubelet 버전 업그레이드
sudo apt-mark unhold kubelet kubectl && \
sudo apt-get update && sudo apt-get install -y kubelet='1.30.0-1.1*' kubectl='1.30.0-1.1*' && \
sudo apt-mark hold kubelet kubectl
###재시작
sudo systemctl daemon-reload
sudo systemctl restart kubelet
마지막으로, 업그레이드가 끝났으니, controlplane node에 다시 pod가 뜰 수 있도록 다음 명령어를 실행한다.
kubectl uncordon controlplane
controlpalne node의 업그레이드가 완료되었으니, 이제 worker node 업그레이드를 진행한다.
worker node 역시 동일한 순서로 진행한다.
1) worker node 접속 후, kubeadm 버전 업그레이드
###워커노드 접속
ssh node01
###패키지 버전 변경
vi /etc/apt/sources.list.d/kubernetes.list
###kubeadm 업그레이드 가능 버전확인
sudo apt update
sudo apt-cache madison kubeadm
###kubeadm upgrade
sudo apt-mark unhold kubeadm && \
sudo apt-get update && sudo apt-get install -y kubeadm='1.30.0-1.1' && \
sudo apt-mark hold kubeadm
2) kuberntes version upgrade
동일하게, upgrade전에 pod를 컨트롤플레인 노드로 재배치한다.
drain 명령어 실행 전, 일단 worker node에서 나간 뒤 명령어 실행한다.
###노드 이름 확인
kubectl get nodes
###드레인 명령어 실행
kubectl drain node01 --ignore-daemonsets
다시, worker node에 접속해서 kubernetes 버전을 업그레이드 한다.
이 때, 명령어는 초기 업그레이드 명령어인 'sudo kubeadm upgrade apply' 가 아닌, 'sudo kubeadm upgrade node'를 사용한다. 명령어 실행 시, 초기 버전과 동일한 버전으로 자동으로 맞춰서 업그레이드가 진행된다.
###worker node 재접속
ssh node01
###node upgrade
sudo kubeadm upgrade node
업그레이드가 완료 되면, kubelet과 kubectl을 업그레이드 한 뒤, worker node를 나가 서, uncordon 명령어를 실행한다.
###kubectl 및 kubelet 버전 업그레이드
sudo apt-mark unhold kubelet kubectl && \
sudo apt-get update && sudo apt-get install -y kubelet='1.30.0-1.1*' kubectl='1.30.0-1.1*' && \
sudo apt-mark hold kubelet kubectl
###재시작
sudo systemctl daemon-reload
sudo systemctl restart kubelet
Q2)
Print the names of all deployments in the admin2406 namespace in the following format:
DEPLOYMENT CONTAINER_IMAGE READY_REPLICAS NAMESPACE
<deployment name> <container image used> <ready replica count> <Namespace>
. The data should be sorted by the increasing order of the deployment name.
Example:
DEPLOYMENT CONTAINER_IMAGE READY_REPLICAS NAMESPACE
deploy0 nginx:alpine 1 admin2406
Write the result to the file /opt/admin2406_data.
이 문제는, 문제에서 정해진 형식으로 쿠버네티스 리소스를 출력하고 특정 파일에 저장할 수 있는지 확인하는 문제이다.
사실, 이 정도로 복잡한 형식이 실제 시험에 출제 될지는 의문이다.
그러면 어떤 방식으로 접근해서, 어떻게 풀어야 할지 알아보도록 하겠다.
1) 공식문서를 적극 이용한다.
https://kubernetes.io/docs/reference/kubectl/quick-reference/#viewing-and-finding-resources
내가 활용한 공식문서 링크이다. 사실, 누가 kubectl 관련 명령어를 모두 외우고 다니겠는가. 해당 문서에서 이 문제에서 필요한 명령어가 뭔지 찾아보자.
일단, 출력양식을 'DEPLOYMENT'와 같이 변경해야 하니, 'custom-columns'를 사용해야 한다.
공식문서에서 확인하니, 다음과 같이 사용하고 있다.
kubectl get node -o custom-columns='NODE_NAME:.metadata.name,STATUS:.status.conditions[?(@.type=="Ready")].status'
두 번째로는
'The data should be sorted by the increasing order of the deployment name.' 라는 문제의 조건을 충족시켜야 한다.
공식 문서를 확인하니 다음과 같은 명령어를 사용할 수 있을 것 같다.
# List Services Sorted by Name
kubectl get services --sort-by=.metadata.nam
이제 필요한 명령어는 모두 찾았으니, 출력만 하면 된다.
2) Jsonpath 확인
이제 출력만 하면 되는데, 출력을 하기 위해서는 jsonpath를 확인해야 한다. 확인을 위해 다음과 같은 명령어를 사용해보자.
kubectl get deployment -o json -n admin2406
명령어를 실행하면, deployment의 json path를 확인할 수 있고 문제에서 요구하는 데이터들이 json 형식으로 어떻게 존재하고 있는지 확인 가능하다.
(jsonpath가 뭔지 모르겠다면, 일단 검색해서 찾아보는 것 을 추천한다.)
우리에게 필요한 정보는 4가지다.
<deployment name> <container image used> <ready replica count> <Namespace> 각각의 데이터가 jsonpath로 어떻게 표현되는지 확인 후, 양식에 맞게 출력만 해주면 끝이다.
3) 출력
일단 기본적으로 admin2406 namespace의 deployment를 출력하는 것이니, 아래 명령어는 반드시 들어간다.
kubectl get deployment -n admin2406
그리고, 필요한 정보 4가지에 대한 jsonpath는 다음과 같다.(json 계위에 따라 '.'으로 구분한다고 생각하면 쉽다.)
DEPLOYMENT:.metadata.name,
CONTAINER_IMAGE:.spec.template.spec.containers[].image,
READY_REPLICAS:.status.readyReplicas,
NAMESPACE:.metadata.namespace
최종적으로, 1번단계에서 확인한 필요 명령어들과 조합해보면 다음과 같은 명령어가 나온다.
(마지막에 들어가는 ' > /opt/admin2406_data'는 앞부분의 출력값을 '>' 뒤의 경로에 저장하라는 의미이다.)
kubectl get deployment -n admin2406 -o custom-columns=DEPLOYMENT:.metadata.name,CONTAINER_IMAGE:.spec.template.spec.containers[].image,READY_REPLICAS:.status.readyReplicas,NAMESPACE:.metadata.namespace --sort-by=.metadata.name > /opt/admin2406_data
Q3)
A kubeconfig file called admin.kubeconfig has been created in /root/CKA. There is something wrong with the configuration. Troubleshoot and fix it.
해당문제는, kubeconfig 파일이 주어지고 해당 config 파일의 잘못된 점을 수정하는 문제이다.
(kubeconfig 파일은 쿠버네티스 클러스터에 접근하기 위한 설정 정보를 담고 있는 파일이다. 이 파일에는 클러스터의 주소, 사용자 인증 정보, 네임스페이스 설정 등이 포함되어 있다. kubectl과 같은 쿠버네티스 클라이언트 도구는 이 kubeconfig 파일을 참조하여 클러스터에 접속하고, 클러스터 내의 리소스를 관리한다.)
문제는 간단하지만, k8s를 잘 모르고 있다면 다음과 같은 의문점이 들수도 있다.
'문제 풀면서 여태 kubectl 명령어 잘 사용했는데? 왜 config 파일을 수정해야하지?'
이유는 간단하다. 문제에서 수정하라고 준 config 파일은 현재 kubectl이 참조하고 있는 config 파일이 아니기 때문이다.
그렇다면 현재 사용하고 있는 config 확인은 어떻게 할까?
다음 명령어를 사용한다.
kubectl config view
명령어 실행 시, 현재 참조하고 있는 config 파일 확인이 가능하다.
(실제 파일은 보통 '/.kube/config'에 존재한다.)
그리고 주어진 config 파일을 확인해보자.
확인해보니, 지금 현재 우리가 사용중인 config 파일과 다른 곳이 보일 것이다.
'server' 부분을 확인해보면, api server의 port가 '6443'이 아닌, 다른 port로 되어 있을 것이다. 해당 부분을 수정해주자.
추가적으로, 다음 명령어를 통해서 조금 더 명확하게 문제점을 확인할 수 있다.
하기 명령어는 명령어 사용 시, 사용 할 kubeconfig 파일을 지정하는 것인데 문제에서 제공 된 config 파일로 지정해서 명령어를 사용 후 나오는 에러를 보고 문제점이 무엇인지 확인 가능하다.
kubectl config view --kubeconfig=/root/CKA/admin.kubeconfig
--
kubectl get pods --kubeconfig=/root/CKA/admin.kubeconfig