[Kubernetes] Certified Kubernetes Administrator 연습 (4)
Q1. 인증 API를 staging namespace에 배포함. auth-api Pod이 잘 뜨도록 설정하고 prod namespace의 tester Pod에서 auth-svc로 접속되도록 하기.
cross-namespace 주소를 쓸 때는 namespace를 명시해 줘야 함.
k exec tester -n prod -- wget -qO- auth-svc.staging
└──┬──┘
namespace 붙임
Q2. init container가 설정 파일을 준비하고 nginx가 서빙하는 구조인데, Pod이 안 뜬다. web-init Pod가 정상 작동하도록 설정하고 nginx 페이지를 서빙할 것.
Init:0/1 STATUS는 컨테이너 1개 중 0개가 완료됨을 의미함.
아직 init 단계에 있다는거임. init이 끝나야 메인 컨테이너가 시작되는데 init에서 막혔다는것.
그런데 그냥 describe 해보면 다 나온다.
Q3. 리포트 API 배포했는데 안됨. report-api Pod 정상작동하도록 설정, app-sa 계정이 staging에서 ConfigMap 조회할 수있도록 설정, report-svc로 접속 가능해야 함, Pod는 minikube-m02 에서만 실행되도록 하기.
didn't match node affinity/selector 는 node의 selector를 확인해야 한다. Service Selector와 nodeSelector는 다른거임. 저 메세지는 특정 label이 달려있는 노드를 찾는다는건데 그 라벨이 달린 노드가 없어서 발생하는 오류임.
READY 0/1 도 정상 상태는 아니다. Readiness probe문제니까 edit deployment로 수정해주면 된다.
포트번호나 Health Check 주소를 바꿔주자.
권한을 점검할 때는 일단 어디가 틀렸는지를 먼저 확인해야 함.
1. 진짜 안되는지
k auth can-i get configmaps --as=system:serviceaccount:staging:app-sa -n staging
k auth can-i list configmaps --as=system:serviceaccount:staging:app-sa -n staging
2. Role이 뭘 주는지
k describe role cm-reader -n staging
3. RoleBinding은 뭐랑 연결되는지
k describe rolebinding app-sa-binding -n staging
4. Service Account 이름
k get sa -n staging
1번 말고는 그냥 describe랑 get 쓰는거임
--as=system:serviceaccount:staging:app-sa
앞에는 그냥 고정임 외워 + namespace + SA이름
k get role이랑 k get rolebinding으로 이름 알아낸 후 describe로 점검하고 edit으로 수정하면 된다.
Q4. 큐 워커 배포했는데 동작하지 않음. queue-worker Pod 4개가 모두 정상 작동하도록 설정하고 QUEUE_NAME, MAX_RETRY 환경변수로 확인할 수 있어야 함
Crash 뜨면 log를 봐야한다.
k logs podname -n staging --previous
replicas가 4개인데 Pod이 2개밖에 안되면 만들어지지 못한다는 것. 이것도 큰 힌트가 된다.
이럴 떄는 ReplicaSet의 Events를 봐야 함!!! 항상 안보고 있었음. Pod 개수가 부족할 때는 ReplicaSet을 확인해야 한다.
그냥 Pod의 log를 보면 그냥 제대로 작동한 것 같음. 단서가 없다.
request와 limit의 cpu와 메모리를 조작해주면 4개 모두 만들어지도록 설정할 수 있음.
commands에 무한루프 안걸어두면 작업 하고 죽어버리니 sleep infinity를 명시해주자. &&로 파이프라인 걸어두면 한 줄로 인식되도록 설정할 수 있다.
Q5. 정적 사이트를 배포했는데 서비스 접속이 안된다. static-web Pod이 3개가 되고 static-web-svc로 접속되도록 설정하기
containerPort는 그냥 메모일 뿐임. 엔진엑스는 80을 쓰니까 80으로 설정해야 한다.
실제 listen 포트를 deploy 포트와 svc 포트를 맞춰야 함.
그냥 앱의 기본 포트인 80을 여는게 편하긴 함. 아니면 컨테이너에서 확인하면 되긴 해
Q6. Killercoda Playground에서 진행. controlplane노드에 접속한 상태에서 etcdctl 을 백업하고 복원해보기.
/etc/kubernetes/manifests/ 여기에는 static pod이 배치됨. etcd.yaml, kube-apiserver.yaml 이건 외워야함
data-dir은 etcd가 실제 데이터를 저장하는 폴더.
cat /etc/kubernetes/manifests/etcd.yaml | grep data-dir
저기다가 복원하지는 않음. 원본을 덮어쓰면 위험하니까..
etcdctl snapshot save <저장할경로>
etcdctl로 etcd를 백업한다. etcdctl은 도구이고 etcd는 백업 대상
스냅샷을 저장할 때는 save, 복원할 때는 restore를 사용한다.
cat으로 얻은 정보를 바탕으로 etcdctl 커맨드를 작성한다.
그리고 백업 명령어는 docs에서 그대로 가져오면 된다.
ETCDCTL_API=3 etcdctl snapshot save /opt/etcd-backup.db \
--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
백업경로는 문제에서 지정한대로 씀. 나머지 4개는 cat으로 읽은걸 사용한다.
같은 노드에서 실행하니 127.0.0.1을 사용함.
etcdctl snapshot restore /opt/etcd-backup.db --data-dir=/var/lib/etcd-restore
스냅샷을 새 폴더에 풀어준다. 파일을 푸는 작업이니 인증서 옵션은 필요없음.
아 그런데 etcd 3.6에서는 snapshot restore가 없어지고 etcdutl을 사용해서 복원한다.
etcdctl은 실행 중인 etcd 서버와 통신하고, etcdutl은 파일을 직접 다루니 명령어를 구분해서 사용함.
etcdutl snapshot restore /opt/etcd-backup.db --data-dir=/var/lib/etcd-restore
이 명령어 실행 후 vim으로 yaml 수정해서 etcd-restore 바라보도록 설정해주면 됨.
command 부분과 volumes, volumeMounts 부분 모두 바꿔야 함.
바꿔주면 복원 끝. 근데 좀 기다려야 함
Q7. kubeadm 클러스터 업그레이드하기.
일단 kubeadm upgrade plan을 찍어본다. 버전 업그레이드가 가능함을 확인할 수 있음.
Control Plane 업그레이드는 kubeadm upgrade apply 가 알아서 해준다.
다만 kubelet은 자동으로 안되고 직접 올려줘야 함.
root@controlplane:~$ kubeadm upgrade plan
[preflight] Running pre-flight checks.
[upgrade/config] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[upgrade/config] Use 'kubeadm init phase upload-config kubeadm --config your-config-file' to re-upload it.
W0817 06:25:17.967022 4947 configset.go:77] Warning: No kubeproxy.config.k8s.io/v1alpha1 config is loaded. Continuing without it: configmaps "kube-proxy" not found
[upgrade] Running cluster health checks
[upgrade] Fetching available versions to upgrade to
[upgrade/versions] Cluster version: 1.35.1
[upgrade/versions] kubeadm version: v1.35.1
I0817 06:25:27.724414 4947 version.go:260] remote version is much newer: v1.36.3; falling back to: stable-1.35
[upgrade/versions] Target version: v1.35.7
[upgrade/versions] Latest version in the v1.35 series: v1.35.7
W0817 06:25:28.362557 4947 configset.go:77] Warning: No kubeproxy.config.k8s.io/v1alpha1 config is loaded. Continuing without it: configmaps "kube-proxy" not found
Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply':
COMPONENT NODE CURRENT TARGET
kubelet controlplane v1.35.1 v1.35.7
kubelet node01 v1.35.1 v1.35.7
Upgrade to the latest version in the v1.35 series:
COMPONENT NODE CURRENT TARGET
kube-apiserver controlplane v1.35.1 v1.35.7
kube-controller-manager controlplane v1.35.1 v1.35.7
kube-scheduler controlplane v1.35.1 v1.35.7
kube-proxy 1.35.1 v1.35.7
CoreDNS v1.13.1 v1.13.1
etcd controlplane 3.6.6-0 3.6.6-0
You can now apply the upgrade by executing the following command:
kubeadm upgrade apply v1.35.7
Note: Before you can perform this upgrade, you have to update kubeadm to v1.35.7.
_____________________________________________________________________
The table below shows the current state of component configs as understood by this version of kubeadm.
Configs that have a "yes" mark in the "MANUAL UPGRADE REQUIRED" column require manual config upgrade or
resetting to kubeadm defaults before a successful upgrade can be performed. The version to manually
upgrade to is denoted in the "PREFERRED VERSION" column.
API GROUP CURRENT VERSION PREFERRED VERSION MANUAL UPGRADE REQUIRED
kubeproxy.config.k8s.io - v1alpha1 no
kubelet.config.k8s.io v1beta1 v1beta1 no
_____________________________________________________________________
root@controlplane:~$
업그레이드 순서도 알려줬으니 따라하면 됨. docs 보고 따라하면 되긴 함.
apt update
apt-cache madison kubeadm | head -5
apt-mark uphold kubeadm
apt-get install -y kubeadm=1.35.7-1.1
apt-mark hold kubeadm
버전만 바꾼다.
kubeadm upgrade apply v1.35.7
kubeadm 을 깔았으니 업그레이드하자. 좀 오래걸림.. -y 옵션 주면 편하다.
서비스 중단 최소화를 위해 컴포넌트를 하나씩 교체한다.
kubectl drain controlplane --ignore-daemonsets
이제 kubectl을 업그레이드하는데, 그전에 drain으로 Pod를 대피시킨다. DaemonSet Pod는 그 노드에 있어야 해서 못옮김. 무시하자.
이후 계속 문서 보고 치면 된다.
apt-mark unhold kubelet kubectl
apt-get install -y kubelet=1.35.7-1.1 kubectl=1.35.7-1.1
apt-mark hold kubelet kubectl
systemctl daemon-reload
systemctl restart kubelet
kubectl uncordon controlplane
kubeadm -> upgrade apply -> drain -> kubelet/kubectl -> restart -> uncordon
순서 알아두고 명령어는 docs보고 치면 됨.
워커노드도 업그레이드하자.
ssh node01로 접속함. 중요 작업은 워커 노드에서만 해야 한다. (kubeadm, kubelet) 이 있기 때문.
kubeadm upgrade node
나머지 명령어는 똑같은데 apply 대신 node 쓴다. 버전도 안씀
순서가 고정이니 문서만 쭉 따라치면 된다.
Q8. node01이 NotReady니까 원인을 진단하고 복구하기.
describe해보면 응답 안하는거만 알지 왜 안하는지는 모른다.
그러니 노드에 직접 들어가 봐야 알 수 있음.
root@controlplane:~$ ssh node01
Last login: Mon Aug 17 07:02:41 2026 from 10.244.4.143
root@node01:~$ systemctl status kubelet
○ kubelet.service - kubelet: The Kubernetes Node Agent
Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled;>
Drop-In: /usr/lib/systemd/system/kubelet.service.d
└─10-kubeadm.conf
Active: inactive (dead) since Mon 2026-08-17 07:02:54 UTC; 3min 5>
Duration: 10min 2.277s
Docs: https://kubernetes.io/docs/
Process: 1635 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS >
Main PID: 1635 (code=exited, status=0/SUCCESS)
CPU: 5.653s
Aug 17 06:53:03 node01 kubelet[1635]: I0817 06:53:03.886861 1635 sc>
Aug 17 06:53:03 node01 kubelet[1635]: I0817 06:53:03.898634 1635 sc>
Aug 17 06:53:03 node01 kubelet[1635]: I0817 06:53:03.908758 1635 sc>
Aug 17 06:53:13 node01 kubelet[1635]: I0817 06:53:13.777688 1635 sc>
Aug 17 06:53:13 node01 kubelet[1635]: I0817 06:53:13.779216 1635 ku>
Aug 17 06:53:31 node01 kubelet[1635]: I0817 06:53:31.742916 1635 pr>
Aug 17 07:02:54 node01 systemd[1]: Stopping kubelet.service - kubelet:>
Aug 17 07:02:54 node01 systemd[1]: kubelet.service: Deactivated succes>
Aug 17 07:02:54 node01 systemd[1]: Stopped kubelet.service - kubelet: >
Aug 17 07:02:54 node01 systemd[1]: kubelet.service: Consumed 5.653s CP>
root@node01:~$
Active가 inactive(dead) 상태임. failed랑 다르게 그냥 멈췄다는것
Loaded에서 자동 시작이 설정되어있음. 이부분 중요함
로그를 보면 정상적으로 멈췄음을 알 수 있음 그냥 시작해주면 된다. systemctl start kubelet
'DevOps > Docker && Kubernetes' 카테고리의 다른 글
| [Kubernetes] kubectl 연습 - namespace와 Secret (0) | 2026.08.20 |
|---|---|
| [Kubernetes] Certified Kubernetes Administrator 연습 (3) (0) | 2026.08.06 |
| [Kubernetes] kubectl 연습 - RoleBinding (0) | 2026.07.26 |
| [Kubernetes] kubectl 연습 - Deployment ReplicaSet (0) | 2026.07.21 |
| [Kubernetes] Kubernetes Concept (0) | 2026.07.21 |
댓글
이 글 공유하기
다른 글
-
[Kubernetes] kubectl 연습 - namespace와 Secret
[Kubernetes] kubectl 연습 - namespace와 Secret
2026.08.20 -
[Kubernetes] Certified Kubernetes Administrator 연습 (3)
[Kubernetes] Certified Kubernetes Administrator 연습 (3)
2026.08.06 -
[Kubernetes] kubectl 연습 - RoleBinding
[Kubernetes] kubectl 연습 - RoleBinding
2026.07.26 -
[Kubernetes] kubectl 연습 - Deployment ReplicaSet
[Kubernetes] kubectl 연습 - Deployment ReplicaSet
2026.07.21