Split View: Kubernetes CKA 자격증 실전 연습 문제 (55문제 + 실기 시뮬레이션 10개)
Kubernetes CKA 자격증 실전 연습 문제 (55문제 + 실기 시뮬레이션 10개)
CKA 자격증 개요
CKA(Certified Kubernetes Administrator)는 CNCF(Cloud Native Computing Foundation)에서 주관하는 실기 중심의 Kubernetes 관리자 자격증입니다.
| 항목 | 내용 |
|---|---|
| 시험 시간 | 120분 |
| 문제 수 | 17문제 (실기형) |
| 합격 기준 | 66% 이상 |
| 시험 방식 | 온라인 원격 감독 |
| 유효 기간 | 3년 |
| Kubernetes 버전 | 최신 안정 버전 |
도메인별 출제 비율
| 도메인 | 비율 |
|---|---|
| Cluster Architecture, Installation & Configuration | 25% |
| Workloads & Scheduling | 15% |
| Services & Networking | 20% |
| Storage | 10% |
| Troubleshooting | 30% |
kubectl 명령어 치트시트
# 클러스터 정보
kubectl cluster-info
kubectl get nodes -o wide
kubectl describe node NODE_NAME
# Pod 관리
kubectl run nginx --image=nginx --restart=Never
kubectl get pods -A -o wide
kubectl describe pod POD_NAME
kubectl logs POD_NAME -c CONTAINER_NAME
kubectl exec -it POD_NAME -- /bin/sh
# Deployment 관리
kubectl create deployment myapp --image=nginx --replicas=3
kubectl scale deployment myapp --replicas=5
kubectl rollout status deployment myapp
kubectl rollout undo deployment myapp
kubectl rollout history deployment myapp
# 서비스 노출
kubectl expose deployment myapp --port=80 --type=ClusterIP
kubectl expose deployment myapp --port=80 --type=NodePort
# 리소스 편집
kubectl edit deployment myapp
kubectl patch deployment myapp -p '{"spec":{"replicas":3}}'
# RBAC
kubectl create serviceaccount mysa
kubectl create clusterrole myrole --verb=get,list,watch --resource=pods
kubectl create clusterrolebinding mybinding --clusterrole=myrole --serviceaccount=default:mysa
# etcd 백업/복구
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot.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
# 노드 관리
kubectl cordon NODE_NAME
kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data
kubectl uncordon NODE_NAME
# 인증서 확인
kubeadm certs check-expiration
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A2 Validity
# jsonpath 예시 (중괄호는 따옴표 처리)
kubectl get pod mypod -o jsonpath='{.spec.nodeName}'
kubectl get nodes -o jsonpath='{.items[*].metadata.name}'
개념 이해 문제 (Q1 ~ Q55)
도메인 1: Cluster Architecture, Installation & Configuration
Q1. kubeadm init 명령어로 Kubernetes 클러스터를 초기화할 때, 기본으로 사용되는 포드 네트워크 CIDR은?
A) 10.0.0.0/8 B) 192.168.0.0/16 C) 별도 지정 필요 (기본값 없음) D) 172.16.0.0/12
정답: C
설명: kubeadm init은 기본 pod network CIDR을 자동으로 설정하지 않습니다. --pod-network-cidr 플래그로 직접 지정해야 합니다. CNI 플러그인에 따라 다르며, Calico는 보통 192.168.0.0/16, Flannel은 10.244.0.0/16을 사용합니다.
Q2. etcd 스냅샷 복구 시 사용하는 올바른 etcdctl 명령어는?
A) etcdctl snapshot load B) etcdctl snapshot restore C) etcdctl backup restore D) etcdctl cluster restore
정답: B
설명: ETCDCTL_API=3 etcdctl snapshot restore 명령어를 사용하여 etcd 스냅샷을 복구합니다. --data-dir 옵션으로 복구 위치를 지정하고, etcd 서비스를 재시작해야 합니다.
Q3. ClusterRole과 Role의 차이점으로 올바른 것은?
A) ClusterRole은 하나의 네임스페이스에만 적용된다 B) Role은 클러스터 전체 리소스에 접근할 수 있다 C) ClusterRole은 클러스터 범위 리소스 및 모든 네임스페이스에 적용 가능하다 D) ClusterRole과 Role은 기능적으로 동일하다
정답: C
설명: ClusterRole은 클러스터 범위 리소스(nodes, persistentvolumes 등)와 모든 네임스페이스의 네임스페이스 범위 리소스에 접근 권한을 부여할 수 있습니다. Role은 특정 네임스페이스 내에서만 유효합니다.
Q4. RoleBinding과 ClusterRoleBinding의 차이점은?
A) RoleBinding은 ClusterRole을 참조할 수 없다 B) ClusterRoleBinding은 특정 네임스페이스에만 적용된다 C) RoleBinding은 특정 네임스페이스 내에서 권한을 부여하고, ClusterRoleBinding은 클러스터 전체에 권한을 부여한다 D) 둘 다 동일한 범위에 적용된다
정답: C
설명: RoleBinding은 특정 네임스페이스 내의 리소스에 대한 권한을 부여합니다. ClusterRoleBinding은 클러스터 전체 범위에 권한을 부여합니다. RoleBinding이 ClusterRole을 참조하면, 해당 ClusterRole의 권한이 특정 네임스페이스에만 적용됩니다.
Q5. kubeadm으로 클러스터를 업그레이드할 때 올바른 순서는?
A) Control plane → Worker nodes → etcd B) etcd → Control plane → Worker nodes C) Worker nodes → Control plane → etcd D) kubeadm upgrade plan → kubeadm upgrade apply → kubelet/kubectl 업그레이드
정답: D
설명: 올바른 순서는 다음과 같습니다: 1) kubeadm upgrade plan으로 업그레이드 가능 버전 확인, 2) kubeadm upgrade apply vX.Y.Z로 control plane 업그레이드, 3) kubelet과 kubectl 업그레이드, 4) 각 worker node에서 kubeadm upgrade node 실행, 5) worker node의 kubelet 업그레이드.
Q6. Kubernetes API 서버 인증서의 기본 위치는?
A) /etc/ssl/kubernetes/ B) /var/lib/kubernetes/ C) /etc/kubernetes/pki/ D) /home/kubernetes/certs/
정답: C
설명: kubeadm으로 생성된 클러스터에서 인증서는 기본적으로 /etc/kubernetes/pki/ 디렉토리에 위치합니다. apiserver.crt, apiserver.key, ca.crt, ca.key 등이 이 디렉토리에 있습니다.
Q7. kubectl config use-context 명령어의 역할은?
A) 새로운 kubeconfig 파일을 생성한다 B) 현재 활성 컨텍스트를 변경한다 C) 클러스터에 새 사용자를 추가한다 D) 네임스페이스를 변경한다
정답: B
설명: kubectl config use-context CONTEXT_NAME 명령어는 kubeconfig 파일에서 현재 활성 컨텍스트를 변경합니다. CKA 시험에서 각 문제마다 다른 컨텍스트로 전환해야 하므로 매우 중요한 명령어입니다.
Q8. Node에 taint를 추가하는 올바른 명령어는?
A) kubectl label node NODE_NAME key=value:NoSchedule B) kubectl taint node NODE_NAME key=value:NoSchedule C) kubectl annotate node NODE_NAME key=value:NoSchedule D) kubectl mark node NODE_NAME key=value:NoSchedule
정답: B
설명: kubectl taint nodes NODE_NAME key=value:effect 명령어로 taint를 추가합니다. effect는 NoSchedule, PreferNoSchedule, NoExecute 중 하나입니다. 제거 시에는 마지막에 -를 붙입니다: kubectl taint nodes NODE_NAME key=value:NoSchedule-
Q9. Static Pod를 생성하는 올바른 방법은?
A) kubectl create pod 명령어 사용 B) kubelet이 감시하는 디렉토리(기본: /etc/kubernetes/manifests/)에 YAML 파일 배치 C) kube-apiserver에 직접 API 호출 D) etcd에 직접 데이터 저장
정답: B
설명: Static Pod는 kubelet이 감시하는 디렉토리(기본값: /etc/kubernetes/manifests/)에 Pod 매니페스트 파일을 배치하면 자동으로 생성됩니다. kubelet이 파일을 감지하고 Pod를 실행합니다. kube-apiserver, etcd, controller-manager, scheduler 등 control plane 컴포넌트가 이 방식으로 실행됩니다.
Q10. kubeadm join 명령어에서 --token과 --discovery-token-ca-cert-hash는 무슨 역할인가?
A) 클러스터 인증서를 생성한다 B) Worker node가 Control plane에 안전하게 참여하기 위한 인증 정보이다 C) 네트워크 CNI를 설정한다 D) etcd 클러스터에 참여한다
정답: B
설명: --token은 Bootstrap Token으로 worker node가 control plane과 통신하기 위한 임시 인증 토큰입니다. --discovery-token-ca-cert-hash는 CA 인증서의 해시값으로, man-in-the-middle 공격을 방지합니다. kubeadm token create --print-join-command로 재생성할 수 있습니다.
도메인 2: Workloads & Scheduling
Q11. Deployment에서 롤링 업데이트 중 동시에 사용 불가능한 Pod의 최대 수를 설정하는 필드는?
A) maxSurge B) maxUnavailable C) minReadySeconds D) revisionHistoryLimit
정답: B
설명: spec.strategy.rollingUpdate.maxUnavailable은 롤링 업데이트 중 동시에 사용 불가능한 Pod의 최대 수(또는 비율)를 지정합니다. maxSurge는 동시에 추가로 생성될 수 있는 Pod의 최대 수를 지정합니다. 기본값은 둘 다 25%입니다.
Q12. Pod의 QoS 클래스 중 requests와 limits가 동일하게 설정된 경우는?
A) BestEffort B) Burstable C) Guaranteed D) Reserved
정답: C
설명: Guaranteed QoS 클래스는 Pod의 모든 컨테이너에 CPU와 메모리의 requests와 limits가 설정되고 동일한 경우입니다. Burstable은 requests와 limits가 다르게 설정된 경우, BestEffort는 requests/limits가 전혀 설정되지 않은 경우입니다.
Q13. nodeSelector와 nodeAffinity의 차이점은?
A) nodeSelector는 더 복잡한 규칙을 지원한다 B) nodeAffinity는 required/preferred 규칙, 다양한 연산자(In, NotIn, Exists 등)를 지원한다 C) nodeSelector는 label이 아닌 annotation을 사용한다 D) nodeAffinity는 deprecated되었다
정답: B
설명: nodeAffinity는 nodeSelector보다 더 표현력이 있습니다. requiredDuringSchedulingIgnoredDuringExecution(하드 요구사항)과 preferredDuringSchedulingIgnoredDuringExecution(소프트 요구사항)을 지원하며, In, NotIn, Exists, DoesNotExist, Gt, Lt 연산자를 사용할 수 있습니다.
Q14. DaemonSet은 어떤 경우에 사용하는가?
A) 특정 수의 Pod 복제본을 항상 유지할 때 B) 모든 (또는 일부) 노드에 Pod를 하나씩 실행할 때 C) 순서가 있는 상태 저장 애플리케이션을 실행할 때 D) 배치 작업을 실행할 때
정답: B
설명: DaemonSet은 클러스터의 모든 노드(또는 nodeSelector로 선택된 노드)에 Pod를 하나씩 실행합니다. 노드 모니터링 에이전트, 로그 수집기, 네트워크 플러그인 등에 사용됩니다. 새로운 노드가 추가되면 자동으로 해당 노드에 Pod가 생성됩니다.
Q15. StatefulSet에서 Pod 이름의 형식은?
A) pod-random-suffix B) statefulset-name-0, statefulset-name-1, ... C) statefulset-name-random D) pod-0, pod-1, ...
정답: B
설명: StatefulSet의 Pod는 예측 가능한 이름을 가집니다: statefulset-이름-0, statefulset-이름-1, ... 와 같은 형식입니다. 이 안정적인 이름은 StatefulSet이 제공하는 핵심 기능 중 하나입니다.
Q16. Job의 completions와 parallelism 필드의 역할은?
A) completions: 동시 실행 Pod 수, parallelism: 완료해야 할 총 작업 수 B) completions: 완료해야 할 총 작업 수, parallelism: 동시에 실행되는 Pod 수 C) completions: 재시도 횟수, parallelism: 타임아웃 시간 D) 두 필드 모두 재시도와 관련된 설정이다
정답: B
설명: completions는 Job이 성공적으로 완료되어야 하는 총 Pod 수를 지정합니다. parallelism은 동시에 실행할 수 있는 Pod 수를 지정합니다. 예를 들어 completions=10, parallelism=3이면, 10개의 작업을 3개씩 병렬로 처리합니다.
Q17. CronJob에서 timezone 설정은 어떻게 하는가?
A) spec.schedule 필드에 시간대 정보 포함 B) spec.timeZone 필드에 IANA 시간대 이름 지정 (Kubernetes 1.27+) C) 클러스터 전체 설정으로만 가능 D) CronJob은 timezone을 지원하지 않는다
정답: B
설명: Kubernetes 1.27부터 spec.timeZone 필드가 GA(Generally Available)로 지원됩니다. "America/New_York", "Asia/Seoul" 등 IANA 시간대 이름을 지정할 수 있습니다. 이전 버전에서는 UTC 기준으로만 스케줄을 설정해야 했습니다.
Q18. Pod Affinity와 Pod Anti-Affinity의 차이는?
A) Pod Affinity는 특정 노드에, Pod Anti-Affinity는 특정 Pod와 같은 노드에 스케줄링 B) Pod Affinity는 특정 Pod와 같은 위치에, Pod Anti-Affinity는 특정 Pod와 다른 위치에 스케줄링 C) 두 개념은 동일하다 D) Pod Anti-Affinity는 deprecated되었다
정답: B
설명: Pod Affinity는 특정 레이블을 가진 Pod와 동일한 노드/존에 스케줄링하도록 합니다(예: 캐시와 앱을 같은 노드에 배치). Pod Anti-Affinity는 특정 레이블을 가진 Pod와 다른 노드/존에 스케줄링하도록 합니다(예: 가용성을 위해 복제본을 다른 노드에 분산).
Q19. kubectl get pod --field-selector=status.phase=Running 명령어에서 field-selector란?
A) 레이블 기반 필터링 B) 리소스의 특정 필드 값으로 필터링 C) 어노테이션 기반 필터링 D) 네임스페이스 필터링
정답: B
설명: --field-selector는 리소스 객체의 특정 필드 값으로 필터링합니다. --selector(또는 -l)가 레이블 기반인 것과 달리, field-selector는 status.phase, metadata.name, spec.nodeName 등 실제 리소스 필드를 기준으로 합니다.
Q20. Toleration을 사용하는 목적은?
A) Pod를 특정 노드에 강제 배치 B) Pod가 특정 taint가 있는 노드에 스케줄링될 수 있도록 허용 C) 특정 노드에서 Pod를 제거 D) 노드에 새로운 taint를 추가
정답: B
설명: Taint는 노드에 설정되어 특정 Pod가 스케줄링되지 않도록 합니다. Toleration은 Pod에 설정되어 특정 taint를 "견딜 수 있다"고 선언합니다. Toleration이 있다고 해서 해당 노드에 반드시 스케줄링되는 것은 아니며, 단지 스케줄링이 허용될 뿐입니다.
도메인 3: Services & Networking
Q21. ClusterIP 서비스의 특징은?
A) 클러스터 외부에서 접근 가능하다 B) 노드의 특정 포트를 통해 접근 가능하다 C) 클러스터 내부에서만 접근 가능한 가상 IP를 제공한다 D) 로드 밸런서를 자동으로 생성한다
정답: C
설명: ClusterIP 서비스는 클러스터 내부에서만 접근 가능한 가상 IP 주소(Cluster IP)를 할당합니다. 외부에서는 접근할 수 없으며, 클러스터 내부 서비스 간 통신에 사용됩니다. 기본 서비스 타입입니다.
Q22. NodePort 서비스에서 허용되는 포트 범위는?
A) 1-1024 B) 1024-65535 C) 30000-32767 D) 8000-9000
정답: C
설명: NodePort의 기본 포트 범위는 30000-32767입니다. kube-apiserver의 --service-node-port-range 플래그로 변경할 수 있습니다. 지정하지 않으면 이 범위 내에서 자동으로 포트가 할당됩니다.
Q23. CoreDNS에서 서비스 DNS 이름의 형식은?
A) service-name.cluster.local B) service-name.namespace.svc.cluster.local C) namespace.service-name.cluster.local D) service-name.default.kubernetes.local
정답: B
설명: Kubernetes에서 서비스의 완전한 DNS 이름은 service-name.namespace.svc.cluster.local 형식입니다. 같은 네임스페이스 내에서는 service-name만으로도 접근 가능합니다. Pod의 DNS는 pod-ip.namespace.pod.cluster.local 형식입니다(점을 대시로 변환).
Q24. NetworkPolicy를 적용하기 위한 전제 조건은?
A) kube-proxy가 IPVS 모드여야 한다 B) NetworkPolicy를 지원하는 CNI 플러그인이 필요하다 C) 클러스터가 cloud provider에서 실행되어야 한다 D) Ingress Controller가 설치되어 있어야 한다
정답: B
설명: NetworkPolicy는 CNI(Container Network Interface) 플러그인이 지원해야 적용됩니다. Calico, Cilium, WeaveNet 등이 NetworkPolicy를 지원합니다. Flannel은 기본적으로 NetworkPolicy를 지원하지 않습니다. CNI가 없으면 NetworkPolicy 리소스를 생성해도 트래픽 제어가 실제로 적용되지 않습니다.
Q25. Ingress 리소스가 작동하기 위한 전제 조건은?
A) NodePort 서비스가 있어야 한다 B) LoadBalancer 서비스가 있어야 한다 C) Ingress Controller가 클러스터에 배포되어 있어야 한다 D) kube-proxy가 실행 중이어야 한다
정답: C
설명: Ingress 리소스는 자체적으로 트래픽을 처리하지 않습니다. Nginx Ingress Controller, Traefik, HAProxy 등 Ingress Controller가 클러스터에 배포되어 있어야 Ingress 규칙이 적용됩니다. Ingress Controller는 Ingress 리소스를 감시하고 실제 라우팅을 처리합니다.
Q26. kube-proxy의 기본 모드는?
A) userspace B) iptables C) IPVS D) ebpf
정답: B
설명: kube-proxy의 기본 모드는 iptables입니다. IPVS 모드는 더 많은 로드 밸런싱 알고리즘을 지원하고 대규모 클러스터에서 더 나은 성능을 제공합니다. Cilium 같은 CNI는 kube-proxy 없이 eBPF로 서비스를 처리할 수 있습니다.
Q27. Service의 externalTrafficPolicy: Local 설정의 효과는?
A) 외부 트래픽을 차단한다 B) 트래픽을 수신한 노드의 Pod에만 전달하여 클라이언트 IP를 보존한다 C) 모든 노드에 균등하게 트래픽을 분산한다 D) LoadBalancer 서비스에만 적용 가능하다
정답: B
설명: externalTrafficPolicy: Local을 설정하면 외부 트래픽이 해당 Pod를 실행 중인 노드에만 전달됩니다. 원본 클라이언트 IP가 보존되는 장점이 있지만, Pod가 없는 노드에서는 연결이 거부될 수 있습니다. 기본값인 Cluster는 모든 노드로 트래픽을 SNAT하여 전달합니다.
Q28. CNI(Container Network Interface) 플러그인의 역할은?
A) 컨테이너 런타임을 관리한다 B) Pod 간 네트워크 연결 및 IP 주소 할당을 담당한다 C) Kubernetes API 서버와의 통신을 처리한다 D) 스토리지 볼륨을 마운트한다
정답: B
설명: CNI 플러그인은 Pod가 생성될 때 네트워크 인터페이스를 설정하고 IP 주소를 할당하며, Pod 간 통신이 가능하도록 네트워크 라우팅을 구성합니다. Flannel, Calico, Cilium, WeaveNet, Canal 등이 대표적인 CNI 플러그인입니다.
Q29. headless service (clusterIP: None)의 특징은?
A) 서비스가 외부에서 접근 불가능하다 B) 개별 Pod IP를 직접 DNS로 반환하여 클라이언트가 Pod를 직접 선택할 수 있다 C) 로드 밸런싱 없이 무작위로 Pod에 전달한다 D) StatefulSet에서만 사용 가능하다
정답: B
설명: Headless Service는 clusterIP: None으로 설정하며, 가상 IP 없이 DNS가 직접 Pod의 IP 목록을 반환합니다. StatefulSet과 함께 사용하면 각 Pod에 안정적인 DNS 이름(pod-0.service.namespace.svc.cluster.local)을 제공합니다.
Q30. NetworkPolicy에서 podSelector: (빈 셀렉터)의 의미는?
A) 어떤 Pod도 선택하지 않는다 B) 해당 네임스페이스의 모든 Pod를 선택한다 C) 모든 네임스페이스의 모든 Pod를 선택한다 D) 시스템 Pod만 선택한다
정답: B
설명: NetworkPolicy에서 podSelector: {}는 빈 셀렉터로, 해당 NetworkPolicy가 배포된 네임스페이스의 모든 Pod를 선택합니다. 모든 Pod에 네트워크 정책을 적용하거나 기본 차단 정책을 만들 때 사용합니다.
도메인 4: Storage
Q31. PersistentVolume의 Reclaim Policy 중 Retain의 동작은?
A) PVC 삭제 시 PV도 자동으로 삭제된다 B) PVC 삭제 시 PV의 데이터가 초기화된다 C) PVC 삭제 후에도 PV가 유지되며, 관리자가 수동으로 처리해야 한다 D) PVC 삭제 시 PV가 다른 PVC에 자동으로 바인딩된다
정답: C
설명: Retain 정책은 PVC가 삭제되어도 PV를 유지합니다. PV는 Released 상태가 되며, 데이터는 보존됩니다. 관리자가 수동으로 PV의 claimRef를 제거하거나 삭제해야 재사용할 수 있습니다. Delete는 PVC 삭제 시 PV도 삭제, Recycle은 deprecated되었습니다.
Q32. PVC의 accessMode인 ReadWriteMany(RWX)란?
A) 하나의 노드에서 읽기/쓰기 가능 B) 여러 노드에서 동시에 읽기만 가능 C) 여러 노드에서 동시에 읽기/쓰기 가능 D) 하나의 Pod에서만 읽기/쓰기 가능
정답: C
설명: ReadWriteMany(RWX)는 여러 노드에서 동시에 읽기/쓰기가 가능합니다. NFS, CephFS, Azure File 등이 지원합니다. ReadWriteOnce(RWO)는 하나의 노드에서 읽기/쓰기, ReadOnlyMany(ROX)는 여러 노드에서 읽기만 가능합니다.
Q33. StorageClass의 주요 역할은?
A) 기존 PV를 관리한다 B) 동적 PV 프로비저닝을 위한 스토리지 속성을 정의한다 C) Pod에 직접 스토리지를 할당한다 D) 네트워크 스토리지 접근을 차단한다
정답: B
설명: StorageClass는 PVC가 생성될 때 자동으로 PV를 동적으로 프로비저닝하는 방법을 정의합니다. provisioner(예: kubernetes.io/aws-ebs), reclaimPolicy, parameters 등을 지정합니다. volumeBindingMode: WaitForFirstConsumer는 Pod가 스케줄링될 때까지 PV 생성을 지연시킵니다.
Q34. emptyDir 볼륨의 특징은?
A) 노드가 재시작되어도 데이터가 유지된다 B) Pod가 삭제되면 데이터도 삭제되며, Pod 내 컨테이너 간 데이터 공유에 사용된다 C) 여러 Pod 간 데이터를 공유할 수 있다 D) PVC 없이 외부 스토리지에 접근한다
정답: B
설명: emptyDir는 Pod가 노드에 할당될 때 생성되고, Pod가 삭제되면 함께 삭제됩니다. Pod 내의 여러 컨테이너 간에 파일을 공유하는 데 유용합니다. 기본적으로 노드의 디스크를 사용하지만 medium: Memory로 tmpfs를 사용할 수도 있습니다.
Q35. ConfigMap을 볼륨으로 마운트하는 장점은?
A) 환경 변수로 주입하는 것보다 더 빠르다 B) 파일로 마운트되어 런타임 중 ConfigMap 변경이 자동으로 반영될 수 있다 C) 암호화된 데이터를 저장할 수 있다 D) 영구 스토리지처럼 데이터가 유지된다
정답: B
설명: ConfigMap을 볼륨으로 마운트하면 ConfigMap 업데이트 시 마운트된 파일이 자동으로 업데이트됩니다(kubelet의 syncFrequency에 따라). 환경 변수로 주입된 ConfigMap은 Pod 재시작 없이는 업데이트되지 않습니다.
도메인 5: Troubleshooting
Q36. Pod가 CrashLoopBackOff 상태일 때 첫 번째로 확인해야 할 것은?
A) kubectl get pod로 Pod 목록 확인 B) kubectl logs POD_NAME으로 컨테이너 로그 확인 C) kubectl delete pod로 Pod 재생성 D) Node 재시작
정답: B
설명: CrashLoopBackOff는 컨테이너가 계속 충돌하여 재시작되는 상태입니다. kubectl logs POD_NAME으로 컨테이너의 stdout/stderr 로그를 확인하고, 필요한 경우 kubectl logs POD_NAME --previous로 이전 충돌 로그를 확인합니다. kubectl describe pod로 이벤트도 확인합니다.
Q37. ImagePullBackOff 오류의 주요 원인과 해결 방법은?
A) Pod의 CPU/메모리 부족 B) 잘못된 이미지 이름/태그 또는 프라이빗 레지스트리 인증 정보 없음 C) 네트워크 PolicyMap 차단 D) PVC 바인딩 실패
정답: B
설명: ImagePullBackOff의 주요 원인: 1) 이미지 이름이나 태그가 잘못됨, 2) 이미지가 존재하지 않음, 3) 프라이빗 레지스트리에 대한 인증 정보(imagePullSecrets) 미설정, 4) 네트워크 연결 문제. kubectl describe pod의 Events 섹션에서 상세 오류 메시지를 확인할 수 있습니다.
Q38. Node가 NotReady 상태일 때 확인해야 할 사항은?
A) kube-apiserver 로그만 확인 B) kubelet 서비스 상태, 로그, 네트워크 연결, 디스크/메모리 상태 C) etcd 상태만 확인 D) Pod 삭제 후 재생성
정답: B
설명: Node NotReady 상태 진단: 1) systemctl status kubelet으로 kubelet 상태 확인, 2) journalctl -u kubelet -f로 kubelet 로그 확인, 3) 노드의 디스크 압력/메모리 압력/PID 압력 확인(kubectl describe node), 4) 네트워크 연결 확인, 5) 컨테이너 런타임(containerd/docker) 상태 확인.
Q39. etcd 클러스터의 health를 확인하는 명령어는?
A) kubectl get etcd B) etcdctl endpoint health C) systemctl status etcd D) kubectl describe etcd
정답: B
설명: ETCDCTL_API=3 etcdctl endpoint health --endpoints=https://127.0.0.1:2379 --cacert=... --cert=... --key=... 명령어로 etcd 클러스터의 상태를 확인합니다. etcdctl endpoint status는 각 멤버의 상태 및 leader 정보를 확인합니다.
Q40. kubectl exec를 사용하여 실행 중인 Pod에서 명령어를 실행하는 올바른 방법은?
A) kubectl exec POD_NAME COMMAND B) kubectl exec -it POD_NAME -- COMMAND C) kubectl run POD_NAME -- COMMAND D) kubectl attach POD_NAME -c COMMAND
정답: B
설명: kubectl exec -it POD_NAME -- /bin/sh 명령어로 Pod에 대화형 셸을 열 수 있습니다. -i는 stdin을 열고, -t는 TTY를 할당합니다. 특정 컨테이너를 지정하려면 -c CONTAINER_NAME을 추가합니다. 단일 명령 실행: kubectl exec POD_NAME -- ls /etc
Q41. Pod의 리소스 사용량을 확인하는 명령어는?
A) kubectl get pod --resources B) kubectl top pod C) kubectl describe pod --metrics D) kubectl stats pod
정답: B
설명: kubectl top pod는 Pod의 CPU와 메모리 사용량을 표시합니다. 이 명령어는 Metrics Server가 클러스터에 설치되어 있어야 작동합니다. kubectl top node는 노드의 리소스 사용량을 확인합니다.
Q42. Pod가 Pending 상태인 주요 원인은?
A) 컨테이너가 충돌하는 경우 B) 이미지를 찾을 수 없는 경우 C) 스케줄러가 적합한 노드를 찾지 못하거나 PVC가 바인딩되지 않은 경우 D) 네트워크 연결 문제
정답: C
설명: Pod Pending 상태의 주요 원인: 1) 리소스 부족(CPU/메모리)으로 스케줄링 불가, 2) taint/toleration 불일치, 3) nodeSelector/affinity 조건을 만족하는 노드 없음, 4) PVC가 바인딩되지 않음, 5) 스케줄러 미실행. kubectl describe pod의 Events에서 이유를 확인할 수 있습니다.
Q43. kube-apiserver 로그를 확인하는 방법은?
A) kubectl logs kube-apiserver -n default B) kubectl logs -n kube-system kube-apiserver-NODENAME C) systemctl logs kube-apiserver D) journalctl -u kubernetes
정답: B
설명: Static Pod로 실행되는 kube-apiserver의 로그는 kubectl logs -n kube-system kube-apiserver-controlplane으로 확인할 수 있습니다. Pod 이름은 노드 이름을 포함합니다. 또는 crictl logs CONTAINER_ID로도 확인 가능합니다.
Q44. 컨테이너가 OOMKilled 상태가 되는 이유와 해결책은?
A) CPU 한계 초과 - limits.cpu를 늘린다 B) 메모리 한계 초과 - limits.memory를 늘리거나 애플리케이션 메모리 사용 최적화 C) 디스크 공간 부족 - PVC 크기를 늘린다 D) 네트워크 타임아웃 - 재시도 설정 추가
정답: B
설명: OOMKilled(Out of Memory Killed)는 컨테이너가 limits.memory에 설정된 메모리 한계를 초과했을 때 발생합니다. 해결책: 1) limits.memory 값을 적절히 늘림, 2) 애플리케이션의 메모리 누수 확인 및 수정, 3) JVM의 경우 힙 크기(-Xmx) 조정.
Q45. Kubernetes 이벤트를 시간순으로 확인하는 명령어는?
A) kubectl get events B) kubectl get events --sort-by=.metadata.creationTimestamp C) kubectl describe events D) kubectl logs events
정답: B
설명: kubectl get events --sort-by=.metadata.creationTimestamp 명령어로 이벤트를 시간순으로 정렬하여 확인합니다. 특정 네임스페이스: kubectl get events -n NAMESPACE. 실시간 확인: kubectl get events --watch. kubectl describe pod 명령어의 Events 섹션에서도 Pod 관련 이벤트를 확인할 수 있습니다.
Q46. kubelet의 설정 파일 위치는?
A) /etc/kubernetes/kubelet.conf B) /var/lib/kubelet/config.yaml C) /etc/kubelet/config.yaml D) /usr/local/kubernetes/kubelet.conf
정답: B
설명: kubelet의 기본 설정 파일은 /var/lib/kubelet/config.yaml이며, 시스템 서비스 설정은 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 또는 /etc/default/kubelet에 있습니다. systemctl status kubelet으로 실행 중인 설정을 확인할 수 있습니다.
Q47. PersistentVolumeClaim이 Pending 상태인 이유는?
A) Pod가 실행 중이지 않기 때문 B) 요구 조건(storageClass, accessMode, capacity)을 만족하는 PV가 없거나 동적 프로비저닝에 실패 C) 네임스페이스가 잘못 설정되어 있기 때문 D) 노드에 디스크 공간이 부족하기 때문
정답: B
설명: PVC Pending 상태의 원인: 1) 요구하는 StorageClass가 없음, 2) 요구하는 accessMode를 지원하는 PV가 없음, 3) 요구하는 용량을 만족하는 PV가 없음, 4) 동적 프로비저닝 실패, 5) volumeBindingMode: WaitForFirstConsumer로 Pod 스케줄링 대기 중. kubectl describe pvc로 상세 원인 확인.
Q48. kubectl get pod -o wide 명령어에서 추가로 표시되는 정보는?
A) 컨테이너 로그 B) IP 주소, 노드 이름, 게이트웨이 C) 리소스 사용량 D) 환경 변수
정답: B
설명: -o wide 옵션은 기본 출력에 추가로 IP 주소, 노드 이름(NODE 컬럼), Nominated Node, Readiness Gates 정보를 표시합니다. Pod가 어느 노드에서 실행 중인지, 어떤 IP를 갖는지 빠르게 확인할 때 유용합니다.
Q49. kube-scheduler가 Pod를 스케줄링할 수 없는 경우 발생하는 이벤트 메시지는?
A) Error B) Warning FailedScheduling C) Normal SchedulingFailed D) Critical NoNodeAvailable
정답: B
설명: kube-scheduler가 Pod를 스케줄링할 수 없을 때 Warning FailedScheduling 이벤트가 생성됩니다. kubectl describe pod POD_NAME에서 Events 섹션을 확인하면 "0/3 nodes are available: 3 Insufficient memory" 등의 상세 메시지를 볼 수 있습니다.
Q50. kubectl rollout restart deployment DEPLOY_NAME 명령어의 동작은?
A) Deployment를 이전 버전으로 롤백한다 B) 롤링 방식으로 모든 Pod를 재시작한다 C) Deployment를 삭제하고 재생성한다 D) Pod를 일시 중지한다
정답: B
설명: kubectl rollout restart deployment는 Deployment의 Pod를 롤링 방식으로 재시작합니다. 이미지나 설정 변경 없이 ConfigMap이나 Secret 업데이트를 적용하거나 Pod를 갱신할 때 유용합니다. kubectl rollout status로 진행 상황을 모니터링할 수 있습니다.
Q51. ServiceAccount를 Pod에 연결하는 방법은?
A) kubectl attach B) spec.serviceAccountName 필드에 ServiceAccount 이름 지정 C) kubectl link D) Pod 레이블에 serviceaccount=NAME 추가
정답: B
설명: Pod 또는 Deployment의 spec.serviceAccountName 필드에 ServiceAccount 이름을 지정합니다. 지정하지 않으면 해당 네임스페이스의 default ServiceAccount가 자동으로 마운트됩니다. ServiceAccount 토큰은 /var/run/secrets/kubernetes.io/serviceaccount/ 경로에 마운트됩니다.
Q52. Kubernetes 클러스터에서 네트워크 디버깅을 위해 임시 Pod를 생성하는 방법은?
A) kubectl debug node B) kubectl run tmp --image=busybox --rm -it -- /bin/sh C) kubectl create pod debug D) kubectl network debug
정답: B
설명: kubectl run tmp --image=busybox --rm -it -- /bin/sh로 임시 디버깅 Pod를 생성합니다. --rm은 종료 후 자동 삭제, -it는 대화형 TTY를 의미합니다. nicolaka/netshoot 이미지는 다양한 네트워크 디버깅 도구를 포함하고 있어 유용합니다.
Q53. kubeconfig 파일에서 cluster, user, context의 관계는?
A) cluster와 user는 독립적이며 context와 관련이 없다 B) context는 cluster와 user(+ namespace)를 묶어서 어떤 클러스터에 어떤 자격증명으로 접근할지 정의한다 C) user가 cluster를 포함한다 D) cluster가 user와 context를 포함한다
정답: B
설명: kubeconfig 파일은 세 가지 섹션으로 구성됩니다: clusters(서버 주소 및 CA 정보), users(자격증명), contexts(cluster + user + namespace 조합). context는 특정 클러스터에 특정 자격증명으로 접근하는 방법을 정의합니다. kubectl config use-context로 활성 context를 변경합니다.
Q54. Pod에서 환경 변수를 확인하는 방법은?
A) kubectl get pod -o env B) kubectl exec POD_NAME -- env C) kubectl describe pod --env D) kubectl get configmap
정답: B
설명: kubectl exec POD_NAME -- env 명령어로 실행 중인 컨테이너의 환경 변수를 확인합니다. kubectl exec POD_NAME -- printenv VARIABLE_NAME으로 특정 환경 변수 값을 확인할 수도 있습니다. kubectl describe pod에서도 환경 변수 목록을 볼 수 있습니다.
Q55. 다음 중 Kubernetes 클러스터의 control plane 컴포넌트가 아닌 것은?
A) kube-apiserver B) kube-scheduler C) kubelet D) kube-controller-manager
정답: C
설명: kubelet은 각 노드(control plane 및 worker node)에서 실행되는 노드 에이전트로, control plane 컴포넌트가 아닙니다. Control plane 컴포넌트: kube-apiserver(API 서버), etcd(상태 저장소), kube-scheduler(Pod 스케줄링), kube-controller-manager(컨트롤러 관리). Worker node 컴포넌트: kubelet, kube-proxy, container runtime.
실기 시뮬레이션 (P1 ~ P10)
P1. etcd 백업 및 복구
시나리오: 컨트롤 플레인 노드에서 etcd 스냅샷을 /opt/etcd-backup.db에 저장하고, 복구하시오.
# etcd 백업
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
# 스냅샷 확인
ETCDCTL_API=3 etcdctl snapshot status /opt/etcd-backup.db --write-out=table
# etcd 복구 (새 데이터 디렉토리로 복구)
ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup.db \
--data-dir=/var/lib/etcd-restore \
--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
# etcd Pod 매니페스트 수정하여 새 데이터 디렉토리 사용
# /etc/kubernetes/manifests/etcd.yaml 에서 --data-dir 경로를 /var/lib/etcd-restore로 변경
# hostPath도 동일하게 변경
P2. RBAC 설정
시나리오: dev 네임스페이스에서 developer ServiceAccount가 pods와 deployments를 get, list, watch, create, update, delete할 수 있도록 RBAC를 설정하시오.
# 네임스페이스 생성
kubectl create namespace dev
# ServiceAccount 생성
kubectl create serviceaccount developer -n dev
# Role 생성 (네임스페이스 범위)
kubectl create role developer-role \
--verb=get,list,watch,create,update,delete \
--resource=pods,deployments \
-n dev
# RoleBinding 생성
kubectl create rolebinding developer-binding \
--role=developer-role \
--serviceaccount=dev:developer \
-n dev
# 검증
kubectl auth can-i get pods --as=system:serviceaccount:dev:developer -n dev
kubectl auth can-i delete deployments --as=system:serviceaccount:dev:developer -n dev
kubectl auth can-i get nodes --as=system:serviceaccount:dev:developer -n dev # No 확인
P3. 멀티 컨테이너 Pod에서 특정 컨테이너 로그 확인
시나리오: app 네임스페이스에 nginx와 busybox 컨테이너로 구성된 Pod를 생성하고, busybox 컨테이너에서 로그를 확인하시오.
# Pod 생성 (YAML 방식)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: multi-container
namespace: app
spec:
containers:
- name: nginx
image: nginx:latest
- name: busybox
image: busybox:latest
command: ['sh', '-c', 'while true; do echo "Hello from busybox $(date)"; sleep 5; done']
EOF
# busybox 컨테이너 로그 확인
kubectl logs multi-container -c busybox -n app
# 실시간 로그 확인
kubectl logs multi-container -c busybox -n app -f
# nginx 컨테이너에서 명령어 실행
kubectl exec -it multi-container -c nginx -n app -- nginx -v
P4. Node 유지보수 (drain & uncordon)
시나리오: worker-node-1을 유지보수 모드로 전환하고, 유지보수 후 다시 스케줄링 가능 상태로 복구하시오.
# 현재 노드 상태 확인
kubectl get nodes
# 노드를 스케줄 불가 상태로 표시
kubectl cordon worker-node-1
# 노드의 Pod를 안전하게 다른 노드로 이동
kubectl drain worker-node-1 \
--ignore-daemonsets \
--delete-emptydir-data \
--force
# Pod 이동 확인
kubectl get pods -o wide -A | grep worker-node-1
# 유지보수 완료 후 노드 다시 스케줄 가능하게
kubectl uncordon worker-node-1
# 노드 상태 확인
kubectl get nodes
P5. PersistentVolume 및 PersistentVolumeClaim 생성
시나리오: 10Gi 용량의 hostPath PV를 생성하고, 이를 사용하는 PVC와 Pod를 생성하시오.
# PersistentVolume 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /data/my-pv
EOF
# PersistentVolumeClaim 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
EOF
# PV-PVC 바인딩 확인
kubectl get pv my-pv
kubectl get pvc my-pvc
# PVC를 사용하는 Pod 생성
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: pvc-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: /data
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: my-pvc
EOF
P6. NetworkPolicy 설정
시나리오: backend 네임스페이스의 Pod들이 frontend 레이블을 가진 Pod에서 오는 트래픽만 포트 8080으로 받도록 NetworkPolicy를 설정하시오.
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: backend
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080
EOF
# NetworkPolicy 확인
kubectl get networkpolicy -n backend
kubectl describe networkpolicy backend-policy -n backend
P7. Deployment 업그레이드 및 롤백
시나리오: webapp Deployment를 nginx:1.25에서 nginx:1.26으로 업그레이드하고, 문제 발생 시 롤백하시오.
# Deployment 생성
kubectl create deployment webapp --image=nginx:1.25 --replicas=3
# 이미지 업데이트 (--record는 deprecated, annotation으로 대체)
kubectl set image deployment/webapp nginx=nginx:1.26
# 롤아웃 상태 확인
kubectl rollout status deployment/webapp
# 롤아웃 히스토리 확인
kubectl rollout history deployment/webapp
# 특정 리비전 상세 확인
kubectl rollout history deployment/webapp --revision=2
# 롤백 (이전 버전으로)
kubectl rollout undo deployment/webapp
# 특정 리비전으로 롤백
kubectl rollout undo deployment/webapp --to-revision=1
# 현재 이미지 확인
kubectl get deployment webapp -o jsonpath='{.spec.template.spec.containers[0].image}'
P8. CronJob 생성
시나리오: 매 5분마다 현재 시간을 출력하는 CronJob을 생성하시오.
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: CronJob
metadata:
name: print-time
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: time-printer
image: busybox
command:
- /bin/sh
- -c
- date; echo "CronJob executed successfully"
restartPolicy: OnFailure
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
EOF
# CronJob 확인
kubectl get cronjob print-time
# Job 실행 기록 확인
kubectl get jobs -l job-name=print-time
# 로그 확인
kubectl logs -l job-name=print-time
P9. Ingress 설정
시나리오: myapp-service (포트 80)에 대한 Ingress를 생성하여 myapp.example.com 도메인으로 접근 가능하게 하시오.
# 서비스 생성 (테스트용)
kubectl create deployment myapp --image=nginx --replicas=2
kubectl expose deployment myapp --port=80 --name=myapp-service
# Ingress 생성
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-service
port:
number: 80
EOF
# Ingress 확인
kubectl get ingress myapp-ingress
kubectl describe ingress myapp-ingress
P10. 인증서 갱신 및 클러스터 컴포넌트 상태 확인
시나리오: 클러스터 인증서 만료 일자를 확인하고 갱신하시오. 또한 클러스터 전체 상태를 점검하시오.
# 인증서 만료 일자 확인
kubeadm certs check-expiration
# 인증서 갱신
kubeadm certs renew all
# 개별 인증서 갱신
kubeadm certs renew apiserver
kubeadm certs renew apiserver-kubelet-client
# 인증서 직접 확인 (openssl)
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A2 Validity
# 클러스터 컴포넌트 상태 확인
kubectl get componentstatuses # deprecated but still works in some versions
kubectl get pods -n kube-system
kubectl cluster-info
# 모든 네임스페이스 Pod 상태 확인
kubectl get pods -A
kubectl get pods -A | grep -v Running | grep -v Completed
# 노드 상태 및 상세 정보
kubectl get nodes -o wide
kubectl describe nodes | grep -A5 "Conditions:"
시험 팁
- 컨텍스트 전환: 각 문제 시작 전 반드시
kubectl config use-context CONTEXT_NAME확인 - imperative 명령어 활용: YAML보다
kubectl create/run/expose명령어가 더 빠름 - --dry-run=client -o yaml: YAML 템플릿 생성 후 수정
- vim 설정:
:set et ts=2 sw=2 nu로 YAML 편집 환경 최적화 - 별칭 설정:
alias k=kubectl,export do="--dry-run=client -o yaml" - 문서 활용: kubernetes.io/docs 공식 문서 북마크 허용
Kubernetes CKA Certification Practice Exam (55 Questions + 10 Practical Simulations)
CKA Exam Overview
The CKA (Certified Kubernetes Administrator) is a hands-on, performance-based exam offered by CNCF (Cloud Native Computing Foundation).
| Item | Details |
|---|---|
| Duration | 120 minutes |
| Questions | 17 performance-based tasks |
| Passing Score | 66% or above |
| Format | Online, proctored |
| Validity | 3 years |
| Kubernetes Version | Latest stable release |
Domain Weights
| Domain | Weight |
|---|---|
| Cluster Architecture, Installation & Configuration | 25% |
| Workloads & Scheduling | 15% |
| Services & Networking | 20% |
| Storage | 10% |
| Troubleshooting | 30% |
kubectl Command Cheat Sheet
# Cluster info
kubectl cluster-info
kubectl get nodes -o wide
kubectl describe node NODE_NAME
# Pod management
kubectl run nginx --image=nginx --restart=Never
kubectl get pods -A -o wide
kubectl describe pod POD_NAME
kubectl logs POD_NAME -c CONTAINER_NAME
kubectl exec -it POD_NAME -- /bin/sh
# Deployment management
kubectl create deployment myapp --image=nginx --replicas=3
kubectl scale deployment myapp --replicas=5
kubectl rollout status deployment myapp
kubectl rollout undo deployment myapp
kubectl rollout history deployment myapp
# Expose services
kubectl expose deployment myapp --port=80 --type=ClusterIP
kubectl expose deployment myapp --port=80 --type=NodePort
# Edit resources
kubectl edit deployment myapp
kubectl patch deployment myapp -p '{"spec":{"replicas":3}}'
# RBAC
kubectl create serviceaccount mysa
kubectl create clusterrole myrole --verb=get,list,watch --resource=pods
kubectl create clusterrolebinding mybinding --clusterrole=myrole --serviceaccount=default:mysa
# etcd backup/restore
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot.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
# Node management
kubectl cordon NODE_NAME
kubectl drain NODE_NAME --ignore-daemonsets --delete-emptydir-data
kubectl uncordon NODE_NAME
# Certificate verification
kubeadm certs check-expiration
# jsonpath examples (curly braces must be quoted)
kubectl get pod mypod -o jsonpath='{.spec.nodeName}'
kubectl get nodes -o jsonpath='{.items[*].metadata.name}'
Multiple Choice Questions (Q1 ~ Q55)
Domain 1: Cluster Architecture, Installation & Configuration
Q1. When initializing a Kubernetes cluster with kubeadm init, what is the default pod network CIDR?
A) 10.0.0.0/8 B) 192.168.0.0/16 C) Must be explicitly specified (no default) D) 172.16.0.0/12
Answer: C
Explanation: kubeadm init does not automatically set a default pod network CIDR. You must specify it with the --pod-network-cidr flag. The value depends on your CNI plugin: Calico typically uses 192.168.0.0/16, while Flannel uses 10.244.0.0/16.
Q2. What is the correct etcdctl command to restore an etcd snapshot?
A) etcdctl snapshot load B) etcdctl snapshot restore C) etcdctl backup restore D) etcdctl cluster restore
Answer: B
Explanation: Use ETCDCTL_API=3 etcdctl snapshot restore to restore an etcd snapshot. Specify the restore location with --data-dir, then restart the etcd service with the new data directory configured.
Q3. What is the key difference between ClusterRole and Role?
A) ClusterRole applies to only one namespace B) Role can access cluster-wide resources C) ClusterRole can apply to cluster-scoped resources and across all namespaces D) ClusterRole and Role are functionally identical
Answer: C
Explanation: ClusterRole can grant access to cluster-scoped resources (nodes, persistentvolumes, etc.) and namespace-scoped resources across all namespaces. Role is valid only within a specific namespace.
Q4. What is the difference between RoleBinding and ClusterRoleBinding?
A) RoleBinding cannot reference a ClusterRole B) ClusterRoleBinding applies to a specific namespace only C) RoleBinding grants permissions within a specific namespace; ClusterRoleBinding grants permissions cluster-wide D) Both have identical scope
Answer: C
Explanation: RoleBinding grants access to resources within a specific namespace. ClusterRoleBinding grants access cluster-wide. When a RoleBinding references a ClusterRole, the ClusterRole's permissions apply only within that namespace.
Q5. What is the correct order for upgrading a cluster with kubeadm?
A) Control plane → Worker nodes → etcd B) etcd → Control plane → Worker nodes C) Worker nodes → Control plane → etcd D) kubeadm upgrade plan → kubeadm upgrade apply → upgrade kubelet/kubectl
Answer: D
Explanation: The correct upgrade sequence: 1) kubeadm upgrade plan to check available versions, 2) kubeadm upgrade apply vX.Y.Z to upgrade control plane, 3) Upgrade kubelet and kubectl, 4) Run kubeadm upgrade node on each worker, 5) Upgrade worker node kubelet.
Q6. What is the default location for Kubernetes API server certificates?
A) /etc/ssl/kubernetes/ B) /var/lib/kubernetes/ C) /etc/kubernetes/pki/ D) /home/kubernetes/certs/
Answer: C
Explanation: In kubeadm-provisioned clusters, certificates reside in /etc/kubernetes/pki/. This includes apiserver.crt, apiserver.key, ca.crt, ca.key, and other component certificates.
Q7. What does kubectl config use-context do?
A) Creates a new kubeconfig file B) Changes the currently active context C) Adds a new user to the cluster D) Changes the namespace
Answer: B
Explanation: kubectl config use-context CONTEXT_NAME switches the active context in the kubeconfig file. In the CKA exam, you must switch contexts for each question, making this a critical command.
Q8. What is the correct command to add a taint to a node?
A) kubectl label node NODE_NAME key=value:NoSchedule B) kubectl taint node NODE_NAME key=value:NoSchedule C) kubectl annotate node NODE_NAME key=value:NoSchedule D) kubectl mark node NODE_NAME key=value:NoSchedule
Answer: B
Explanation: Use kubectl taint nodes NODE_NAME key=value:effect to add a taint. Effects can be NoSchedule, PreferNoSchedule, or NoExecute. To remove: kubectl taint nodes NODE_NAME key=value:NoSchedule-
Q9. What is the correct way to create a Static Pod?
A) Use the kubectl create pod command B) Place a YAML manifest in the kubelet-watched directory (default: /etc/kubernetes/manifests/) C) Make a direct API call to kube-apiserver D) Write data directly to etcd
Answer: B
Explanation: Static Pods are created by placing Pod manifest files in the directory watched by kubelet (default: /etc/kubernetes/manifests/). kubelet detects the file and runs the Pod. Control plane components like kube-apiserver, etcd, controller-manager, and scheduler run as Static Pods.
Q10. In kubeadm join, what are --token and --discovery-token-ca-cert-hash used for?
A) Generating cluster certificates B) Authentication credentials for a worker node to securely join the control plane C) Configuring network CNI D) Joining the etcd cluster
Answer: B
Explanation: --token is a Bootstrap Token for temporary authentication between worker nodes and the control plane. --discovery-token-ca-cert-hash is a hash of the CA certificate that prevents man-in-the-middle attacks. Regenerate with kubeadm token create --print-join-command.
Domain 2: Workloads & Scheduling
Q11. Which field in a Deployment controls the maximum number of unavailable Pods during a rolling update?
A) maxSurge B) maxUnavailable C) minReadySeconds D) revisionHistoryLimit
Answer: B
Explanation: spec.strategy.rollingUpdate.maxUnavailable specifies the maximum number (or percentage) of Pods that can be unavailable during a rolling update. maxSurge specifies the maximum number of additional Pods that can be created above the desired count. Both default to 25%.
Q12. Which QoS class is assigned when a Pod's requests and limits are set to identical values?
A) BestEffort B) Burstable C) Guaranteed D) Reserved
Answer: C
Explanation: Guaranteed QoS requires all containers in the Pod to have CPU and memory requests equal to their limits. Burstable is when requests and limits differ. BestEffort is when no requests or limits are set at all.
Q13. What is the advantage of nodeAffinity over nodeSelector?
A) nodeSelector supports more complex rules B) nodeAffinity supports required/preferred rules and operators like In, NotIn, Exists, etc. C) nodeSelector uses annotations instead of labels D) nodeAffinity is deprecated
Answer: B
Explanation: nodeAffinity is more expressive: it supports requiredDuringSchedulingIgnoredDuringExecution (hard requirements) and preferredDuringSchedulingIgnoredDuringExecution (soft requirements), plus operators In, NotIn, Exists, DoesNotExist, Gt, Lt.
Q14. When should you use a DaemonSet?
A) To maintain a fixed number of Pod replicas B) To run one Pod on each (or selected) node C) To run stateful applications with ordered Pod management D) To run batch jobs
Answer: B
Explanation: DaemonSet ensures one Pod per node across all (or node-selector-matching) nodes. Common use cases include node monitoring agents, log collectors, and network plugins. New nodes automatically get a Pod when they join the cluster.
Q15. What is the naming format for Pods in a StatefulSet?
A) pod-random-suffix B) statefulset-name-0, statefulset-name-1, ... C) statefulset-name-random D) pod-0, pod-1, ...
Answer: B
Explanation: StatefulSet Pods have predictable names: statefulset-name-0, statefulset-name-1, and so on. These stable identities are one of the core features StatefulSet provides, enabling ordered deployment, scaling, and deletion.
Q16. What are the completions and parallelism fields in a Job?
A) completions: simultaneous Pods, parallelism: total tasks B) completions: total tasks to complete, parallelism: simultaneous Pod count C) completions: retry count, parallelism: timeout D) Both fields control retry behavior
Answer: B
Explanation: completions specifies the total number of Pods that must complete successfully. parallelism specifies how many Pods can run simultaneously. Example: completions=10, parallelism=3 processes 10 tasks 3 at a time.
Q17. How do you configure timezone in a CronJob?
A) Include timezone info in the spec.schedule field B) Use spec.timeZone with an IANA timezone name (Kubernetes 1.27+) C) Only possible via cluster-wide configuration D) CronJob does not support timezones
Answer: B
Explanation: Since Kubernetes 1.27 (GA), spec.timeZone accepts IANA timezone names like "America/New_York" or "Asia/Tokyo". Before 1.27, all schedules were UTC-only.
Q18. What is the difference between Pod Affinity and Pod Anti-Affinity?
A) Pod Affinity targets specific nodes; Pod Anti-Affinity targets Pods on specific nodes B) Pod Affinity schedules near specific Pods; Pod Anti-Affinity schedules away from specific Pods C) Both concepts are identical D) Pod Anti-Affinity is deprecated
Answer: B
Explanation: Pod Affinity schedules a Pod on the same node/zone as Pods with matching labels (e.g., co-locating a cache with its app). Pod Anti-Affinity schedules a Pod away from Pods with matching labels (e.g., spreading replicas across nodes for availability).
Q19. In kubectl get pod --field-selector=status.phase=Running, what does field-selector do?
A) Filters by label B) Filters by specific field values on the resource object C) Filters by annotation D) Filters by namespace
Answer: B
Explanation: --field-selector filters by actual resource field values like status.phase, metadata.name, or spec.nodeName. This differs from --selector / -l which filters by labels.
Q20. What is the purpose of a Toleration?
A) Forces a Pod to schedule on a specific node B) Allows a Pod to be scheduled on nodes with matching taints C) Removes Pods from a specific node D) Adds new taints to a node
Answer: B
Explanation: Taints on nodes repel Pods that don't tolerate them. Tolerations on Pods declare they can "tolerate" specific taints. Having a toleration doesn't guarantee the Pod will land on that node — it just permits scheduling there.
Domain 3: Services & Networking
Q21. What is the characteristic of a ClusterIP service?
A) Accessible from outside the cluster B) Accessible through a specific port on each node C) Provides a virtual IP accessible only within the cluster D) Automatically creates a load balancer
Answer: C
Explanation: ClusterIP services assign a virtual IP (the Cluster IP) that is only reachable within the cluster. They cannot be accessed externally and are used for inter-service communication. ClusterIP is the default service type.
Q22. What is the allowed port range for a NodePort service?
A) 1-1024 B) 1024-65535 C) 30000-32767 D) 8000-9000
Answer: C
Explanation: The default NodePort range is 30000-32767. This can be changed with the --service-node-port-range flag on kube-apiserver. If not specified, a port is automatically assigned within this range.
Q23. What is the DNS name format for a service in CoreDNS?
A) service-name.cluster.local B) service-name.namespace.svc.cluster.local C) namespace.service-name.cluster.local D) service-name.default.kubernetes.local
Answer: B
Explanation: The fully qualified DNS name for a service is service-name.namespace.svc.cluster.local. Within the same namespace, service-name alone is sufficient. Pod DNS follows the format pod-ip-dashes.namespace.pod.cluster.local.
Q24. What is a prerequisite for applying a NetworkPolicy?
A) kube-proxy must be in IPVS mode B) A CNI plugin that supports NetworkPolicy is required C) The cluster must run on a cloud provider D) An Ingress Controller must be installed
Answer: B
Explanation: NetworkPolicy enforcement requires a compatible CNI plugin. Calico, Cilium, and WeaveNet support NetworkPolicy. Flannel does not natively enforce NetworkPolicy. Without a compatible CNI, creating NetworkPolicy objects has no effect on traffic.
Q25. What is required for an Ingress resource to work?
A) A NodePort service must exist B) A LoadBalancer service must exist C) An Ingress Controller must be deployed in the cluster D) kube-proxy must be running
Answer: C
Explanation: An Ingress resource alone does not process traffic. An Ingress Controller (nginx, Traefik, HAProxy, etc.) must be deployed to watch Ingress resources and handle actual routing.
Q26. What is the default mode for kube-proxy?
A) userspace B) iptables C) IPVS D) ebpf
Answer: B
Explanation: The default kube-proxy mode is iptables. IPVS mode supports more load-balancing algorithms and offers better performance at scale. CNIs like Cilium can handle service routing via eBPF without kube-proxy.
Q27. What does setting externalTrafficPolicy: Local on a service do?
A) Blocks external traffic B) Routes traffic only to Pods on the receiving node, preserving the client IP C) Distributes traffic evenly across all nodes D) Only applies to LoadBalancer services
Answer: B
Explanation: With externalTrafficPolicy: Local, external traffic is delivered only to nodes that host the targeted Pod, preserving the original client IP. However, connections to nodes without the Pod are rejected. The default Cluster policy SNATs traffic and routes it to any node.
Q28. What is the role of a CNI (Container Network Interface) plugin?
A) Manages container runtimes B) Handles network connectivity between Pods and IP address assignment C) Manages communication with the Kubernetes API server D) Mounts storage volumes
Answer: B
Explanation: CNI plugins configure network interfaces when Pods are created, assign IP addresses, and set up routing for Pod-to-Pod communication. Flannel, Calico, Cilium, WeaveNet, and Canal are common CNI plugins.
Q29. What is the behavior of a headless service (clusterIP: None)?
A) The service cannot be accessed externally B) DNS returns individual Pod IPs directly, allowing clients to choose Pods C) Routes to a random Pod without load balancing D) Can only be used with StatefulSets
Answer: B
Explanation: A headless service with clusterIP: None has no virtual IP. DNS returns the actual Pod IPs directly. Combined with StatefulSet, each Pod gets a stable DNS name like pod-0.service.namespace.svc.cluster.local.
Q30. In a NetworkPolicy, what does podSelector: {} (empty selector) mean?
A) Selects no Pods B) Selects all Pods in the namespace C) Selects all Pods across all namespaces D) Selects only system Pods
Answer: B
Explanation: An empty podSelector: {} selects all Pods in the namespace where the NetworkPolicy is deployed. This is commonly used to apply a default-deny policy to all Pods in a namespace.
Domain 4: Storage
Q31. What happens with a PersistentVolume's Reclaim Policy of Retain when the PVC is deleted?
A) The PV is automatically deleted B) The PV data is wiped and reset C) The PV is retained and must be manually reclaimed by an admin D) The PV is automatically bound to another PVC
Answer: C
Explanation: With the Retain policy, the PV persists after the PVC is deleted. The PV enters the Released state and the data is preserved. An admin must manually delete or reconfigure the PV to make it available again. Delete removes the PV; Recycle is deprecated.
Q32. What does the ReadWriteMany (RWX) access mode mean?
A) Read/write from one node B) Read-only from multiple nodes simultaneously C) Read/write from multiple nodes simultaneously D) Read/write from only one Pod
Answer: C
Explanation: ReadWriteMany (RWX) allows the volume to be mounted read-write by multiple nodes simultaneously. NFS, CephFS, and Azure File support this mode. ReadWriteOnce (RWO) allows read-write from one node; ReadOnlyMany (ROX) allows read-only from multiple nodes.
Q33. What is the primary role of a StorageClass?
A) Manages existing PVs B) Defines storage properties for dynamic PV provisioning C) Directly assigns storage to Pods D) Blocks access to network storage
Answer: B
Explanation: StorageClass defines how PVs are dynamically provisioned when a PVC is created. It specifies the provisioner (e.g., kubernetes.io/aws-ebs), reclaimPolicy, and parameters. volumeBindingMode: WaitForFirstConsumer delays PV creation until a Pod is scheduled.
Q34. What are the characteristics of an emptyDir volume?
A) Data persists across node restarts B) Deleted when the Pod is removed; useful for sharing data between containers in a Pod C) Can be shared across multiple Pods D) Accesses external storage without a PVC
Answer: B
Explanation: emptyDir is created when a Pod is assigned to a node and deleted when the Pod is removed. It is useful for sharing files between containers within the same Pod. By default it uses node disk; with medium: Memory it uses tmpfs.
Q35. What is the advantage of mounting a ConfigMap as a volume instead of injecting it as environment variables?
A) Faster than environment variable injection B) Changes to the ConfigMap are automatically reflected in the mounted files at runtime C) Can store encrypted data D) Data persists like permanent storage
Answer: B
Explanation: When a ConfigMap is volume-mounted, updates to the ConfigMap are automatically propagated to the mounted files (within kubelet's syncFrequency). ConfigMaps injected as environment variables are not updated until the Pod is restarted.
Domain 5: Troubleshooting
Q36. When a Pod is in CrashLoopBackOff state, what should you check first?
A) Use kubectl get pod to list Pods B) Use kubectl logs to check container logs C) Delete and recreate the Pod D) Restart the node
Answer: B
Explanation: CrashLoopBackOff means the container is repeatedly crashing and being restarted. Check kubectl logs POD_NAME for stdout/stderr output. Use kubectl logs POD_NAME --previous for logs from the last crash. kubectl describe pod shows Events too.
Q37. What are the main causes of and solutions for an ImagePullBackOff error?
A) Insufficient CPU/memory for the Pod B) Incorrect image name/tag or missing credentials for a private registry C) NetworkPolicy blocking traffic D) PVC binding failure
Answer: B
Explanation: ImagePullBackOff causes: 1) wrong image name or tag, 2) image doesn't exist, 3) missing imagePullSecrets for private registry, 4) network connectivity issue. Check kubectl describe pod Events for the specific error message.
Q38. What should you check when a node is in NotReady state?
A) Only check kube-apiserver logs B) kubelet service status, logs, network connectivity, disk/memory pressure C) Only check etcd status D) Delete and recreate Pods
Answer: B
Explanation: Diagnosing NotReady: 1) systemctl status kubelet to check kubelet state, 2) journalctl -u kubelet -f for kubelet logs, 3) Check disk/memory/PID pressure in kubectl describe node, 4) Verify network connectivity, 5) Check container runtime (containerd/docker) status.
Q39. What command checks the health of an etcd cluster?
A) kubectl get etcd B) etcdctl endpoint health C) systemctl status etcd D) kubectl describe etcd
Answer: B
Explanation: ETCDCTL_API=3 etcdctl endpoint health --endpoints=https://127.0.0.1:2379 --cacert=... --cert=... --key=... checks cluster health. etcdctl endpoint status shows per-member status including leader information.
Q40. What is the correct way to run a command inside a running Pod?
A) kubectl exec POD_NAME COMMAND B) kubectl exec -it POD_NAME -- COMMAND C) kubectl run POD_NAME -- COMMAND D) kubectl attach POD_NAME -c COMMAND
Answer: B
Explanation: kubectl exec -it POD_NAME -- /bin/sh opens an interactive shell. -i keeps stdin open, -t allocates a TTY. Add -c CONTAINER_NAME for multi-container Pods. Single command: kubectl exec POD_NAME -- ls /etc
Q41. What command shows Pod resource usage?
A) kubectl get pod --resources B) kubectl top pod C) kubectl describe pod --metrics D) kubectl stats pod
Answer: B
Explanation: kubectl top pod displays CPU and memory usage per Pod. Requires Metrics Server installed in the cluster. kubectl top node shows node-level resource usage.
Q42. What are the main reasons a Pod stays in Pending state?
A) Container is crashing B) Image cannot be found C) Scheduler cannot find a suitable node, or PVC is not bound D) Network connectivity issue
Answer: C
Explanation: Pending Pod causes: 1) Insufficient resources (CPU/memory) on all nodes, 2) taint/toleration mismatch, 3) No node satisfying nodeSelector/affinity, 4) PVC not bound, 5) Scheduler not running. Check kubectl describe pod Events for specifics.
Q43. How do you check kube-apiserver logs?
A) kubectl logs kube-apiserver -n default B) kubectl logs -n kube-system kube-apiserver-NODENAME C) systemctl logs kube-apiserver D) journalctl -u kubernetes
Answer: B
Explanation: The kube-apiserver runs as a Static Pod. Access its logs with kubectl logs -n kube-system kube-apiserver-controlplane (where "controlplane" is the node name). Alternatively: crictl logs CONTAINER_ID.
Q44. Why does a container enter OOMKilled state and how do you fix it?
A) CPU limit exceeded — increase limits.cpu B) Memory limit exceeded — increase limits.memory or optimize app memory usage C) Disk space insufficient — increase PVC size D) Network timeout — add retry settings
Answer: B
Explanation: OOMKilled (Out of Memory Killed) occurs when a container exceeds its limits.memory. Solutions: 1) Increase limits.memory appropriately, 2) Check for memory leaks in the application, 3) For JVM apps, adjust heap size with -Xmx.
Q45. What command shows Kubernetes events sorted by time?
A) kubectl get events B) kubectl get events --sort-by=.metadata.creationTimestamp C) kubectl describe events D) kubectl logs events
Answer: B
Explanation: kubectl get events --sort-by=.metadata.creationTimestamp sorts events chronologically. Filter by namespace: kubectl get events -n NAMESPACE. Watch in real time: kubectl get events --watch. Pod events also appear in kubectl describe pod.
Q46. Where is the kubelet configuration file located?
A) /etc/kubernetes/kubelet.conf B) /var/lib/kubelet/config.yaml C) /etc/kubelet/config.yaml D) /usr/local/kubernetes/kubelet.conf
Answer: B
Explanation: The default kubelet configuration file is /var/lib/kubelet/config.yaml. Systemd service settings are in /etc/systemd/system/kubelet.service.d/10-kubeadm.conf or /etc/default/kubelet. systemctl status kubelet shows the active configuration.
Q47. Why would a PersistentVolumeClaim remain in Pending state?
A) No Pods are running B) No PV satisfies the requirements (storageClass, accessMode, capacity) or dynamic provisioning fails C) Namespace is incorrectly configured D) Node has insufficient disk space
Answer: B
Explanation: PVC Pending causes: 1) Required StorageClass doesn't exist, 2) No PV with the required accessMode, 3) No PV with sufficient capacity, 4) Dynamic provisioning failed, 5) Waiting for Pod scheduling with volumeBindingMode: WaitForFirstConsumer. Check with kubectl describe pvc.
Q48. What additional columns does kubectl get pod -o wide show?
A) Container logs B) IP address, node name, gateway C) Resource usage D) Environment variables
Answer: B
Explanation: The -o wide flag adds IP address, node name (NODE column), Nominated Node, and Readiness Gates to the standard output. Useful for quickly seeing which node a Pod runs on and what IP it has.
Q49. What event message appears when kube-scheduler cannot schedule a Pod?
A) Error B) Warning FailedScheduling C) Normal SchedulingFailed D) Critical NoNodeAvailable
Answer: B
Explanation: When kube-scheduler cannot schedule a Pod, a Warning FailedScheduling event is generated. Check kubectl describe pod POD_NAME Events section for details like "0/3 nodes are available: 3 Insufficient memory."
Q50. What does kubectl rollout restart deployment DEPLOY_NAME do?
A) Rolls back the deployment to the previous version B) Restarts all Pods in a rolling fashion C) Deletes and recreates the Deployment D) Pauses the Pods
Answer: B
Explanation: kubectl rollout restart deployment restarts all Pods in the Deployment using a rolling update strategy. Useful for applying ConfigMap/Secret updates without changing the image or spec. Monitor with kubectl rollout status.
Q51. How do you attach a ServiceAccount to a Pod?
A) kubectl attach B) Set the spec.serviceAccountName field to the ServiceAccount name C) kubectl link D) Add serviceaccount=NAME to Pod labels
Answer: B
Explanation: Set spec.serviceAccountName in the Pod or Deployment spec. If not specified, the default ServiceAccount of the namespace is automatically mounted. The token is available at /var/run/secrets/kubernetes.io/serviceaccount/.
Q52. How do you create a temporary Pod for network debugging in a Kubernetes cluster?
A) kubectl debug node B) kubectl run tmp --image=busybox --rm -it -- /bin/sh C) kubectl create pod debug D) kubectl network debug
Answer: B
Explanation: kubectl run tmp --image=busybox --rm -it -- /bin/sh creates a temporary debugging Pod. --rm auto-deletes it on exit, -it provides interactive TTY. The nicolaka/netshoot image includes extensive network debugging tools.
Q53. What is the relationship between cluster, user, and context in a kubeconfig file?
A) cluster and user are independent and unrelated to context B) A context combines a cluster and user (plus optional namespace) to define how to access a cluster with specific credentials C) A user contains a cluster D) A cluster contains users and contexts
Answer: B
Explanation: A kubeconfig has three sections: clusters (server address and CA), users (credentials), and contexts (cluster + user + namespace combinations). A context defines which cluster to connect to and with which credentials. kubectl config use-context changes the active context.
Q54. How do you check environment variables inside a running Pod?
A) kubectl get pod -o env B) kubectl exec POD_NAME -- env C) kubectl describe pod --env D) kubectl get configmap
Answer: B
Explanation: kubectl exec POD_NAME -- env lists all environment variables in the container. Use kubectl exec POD_NAME -- printenv VARIABLE_NAME for a specific variable. kubectl describe pod also shows the configured environment variables.
Q55. Which of the following is NOT a control plane component?
A) kube-apiserver B) kube-scheduler C) kubelet D) kube-controller-manager
Answer: C
Explanation: kubelet is a node agent running on every node (control plane and worker nodes), not a control plane component. Control plane components: kube-apiserver, etcd, kube-scheduler, kube-controller-manager. Node components: kubelet, kube-proxy, container runtime.
Practical Simulations (P1 ~ P10)
P1. etcd Backup and Restore
Scenario: Save an etcd snapshot to /opt/etcd-backup.db on the control plane node, then restore it.
# Backup etcd
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
# Verify snapshot
ETCDCTL_API=3 etcdctl snapshot status /opt/etcd-backup.db --write-out=table
# Restore to new data directory
ETCDCTL_API=3 etcdctl snapshot restore /opt/etcd-backup.db \
--data-dir=/var/lib/etcd-restore
# Edit /etc/kubernetes/manifests/etcd.yaml:
# Change --data-dir to /var/lib/etcd-restore
# Update hostPath volumes to match
P2. RBAC Configuration
Scenario: Configure RBAC so that the developer ServiceAccount in namespace dev can get, list, watch, create, update, and delete pods and deployments.
kubectl create namespace dev
kubectl create serviceaccount developer -n dev
kubectl create role developer-role \
--verb=get,list,watch,create,update,delete \
--resource=pods,deployments \
-n dev
kubectl create rolebinding developer-binding \
--role=developer-role \
--serviceaccount=dev:developer \
-n dev
# Verify
kubectl auth can-i get pods --as=system:serviceaccount:dev:developer -n dev
kubectl auth can-i delete deployments --as=system:serviceaccount:dev:developer -n dev
kubectl auth can-i get nodes --as=system:serviceaccount:dev:developer -n dev # should be no
P3. Multi-Container Pod Logging
Scenario: Create a Pod with nginx and busybox containers in namespace app, and retrieve logs from the busybox container.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: multi-container
namespace: app
spec:
containers:
- name: nginx
image: nginx:latest
- name: busybox
image: busybox:latest
command: ['sh', '-c', 'while true; do echo "Hello from busybox"; sleep 5; done']
EOF
kubectl logs multi-container -c busybox -n app
kubectl logs multi-container -c busybox -n app -f
kubectl exec -it multi-container -c nginx -n app -- nginx -v
P4. Node Maintenance (Drain and Uncordon)
Scenario: Put worker-node-1 into maintenance mode and restore it after maintenance.
kubectl get nodes
kubectl cordon worker-node-1
kubectl drain worker-node-1 \
--ignore-daemonsets \
--delete-emptydir-data \
--force
kubectl get pods -o wide -A | grep worker-node-1
# After maintenance is complete
kubectl uncordon worker-node-1
kubectl get nodes
P5. PersistentVolume and PersistentVolumeClaim
Scenario: Create a hostPath PV with 10Gi capacity, then create a PVC and Pod that use it.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /data/my-pv
EOF
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
EOF
kubectl get pv my-pv
kubectl get pvc my-pvc
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: pvc-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- mountPath: /data
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: my-pvc
EOF
P6. NetworkPolicy Configuration
Scenario: Configure a NetworkPolicy so that Pods in the backend namespace only accept traffic on port 8080 from Pods labeled role: frontend in the frontend namespace.
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-policy
namespace: backend
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: frontend
podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080
EOF
kubectl get networkpolicy -n backend
kubectl describe networkpolicy backend-policy -n backend
P7. Deployment Upgrade and Rollback
Scenario: Upgrade the webapp Deployment from nginx:1.25 to nginx:1.26, then roll back if issues arise.
kubectl create deployment webapp --image=nginx:1.25 --replicas=3
kubectl set image deployment/webapp nginx=nginx:1.26
kubectl rollout status deployment/webapp
kubectl rollout history deployment/webapp
kubectl rollout history deployment/webapp --revision=2
kubectl rollout undo deployment/webapp
kubectl rollout undo deployment/webapp --to-revision=1
# Verify current image
kubectl get deployment webapp -o jsonpath='{.spec.template.spec.containers[0].image}'
P8. CronJob Creation
Scenario: Create a CronJob that prints the current time every 5 minutes.
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: CronJob
metadata:
name: print-time
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: time-printer
image: busybox
command:
- /bin/sh
- -c
- date; echo "CronJob executed successfully"
restartPolicy: OnFailure
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
EOF
kubectl get cronjob print-time
kubectl get jobs
P9. Ingress Configuration
Scenario: Create an Ingress to make myapp-service (port 80) accessible at myapp.example.com.
kubectl create deployment myapp --image=nginx --replicas=2
kubectl expose deployment myapp --port=80 --name=myapp-service
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-service
port:
number: 80
EOF
kubectl get ingress myapp-ingress
kubectl describe ingress myapp-ingress
P10. Certificate Renewal and Cluster Health Check
Scenario: Check certificate expiration dates, renew them, and perform a full cluster health check.
# Check certificate expiration
kubeadm certs check-expiration
# Renew all certificates
kubeadm certs renew all
# Renew individual certificates
kubeadm certs renew apiserver
kubeadm certs renew apiserver-kubelet-client
# Verify with openssl
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A2 Validity
# Cluster health check
kubectl get pods -n kube-system
kubectl cluster-info
kubectl get nodes -o wide
kubectl get pods -A
kubectl get pods -A | grep -v Running | grep -v Completed
# Node conditions
kubectl describe nodes | grep -A5 "Conditions:"
Exam Tips
- Switch contexts: Always run
kubectl config use-context CONTEXT_NAMEat the start of each question - Use imperative commands: Faster than writing YAML for most tasks
- Template generation:
--dry-run=client -o yamlto generate and then edit YAML - vim setup:
:set et ts=2 sw=2 nufor YAML editing - Aliases:
alias k=kubectlandexport do="--dry-run=client -o yaml" - Documentation: kubernetes.io/docs bookmarks are permitted