Skip to content
Published on

Kubernetes CKA 자격증 실전 연습 문제 (55문제 + 실기 시뮬레이션 10개)

Authors

CKA 자격증 개요

CKA(Certified Kubernetes Administrator)는 CNCF(Cloud Native Computing Foundation)에서 주관하는 실기 중심의 Kubernetes 관리자 자격증입니다.

항목내용
시험 시간120분
문제 수17문제 (실기형)
합격 기준66% 이상
시험 방식온라인 원격 감독
유효 기간3년
Kubernetes 버전최신 안정 버전

도메인별 출제 비율

도메인비율
Cluster Architecture, Installation & Configuration25%
Workloads & Scheduling15%
Services & Networking20%
Storage10%
Troubleshooting30%

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 네임스페이스에 nginxbusybox 컨테이너로 구성된 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:"

시험 팁

  1. 컨텍스트 전환: 각 문제 시작 전 반드시 kubectl config use-context CONTEXT_NAME 확인
  2. imperative 명령어 활용: YAML보다 kubectl create/run/expose 명령어가 더 빠름
  3. --dry-run=client -o yaml: YAML 템플릿 생성 후 수정
  4. vim 설정: :set et ts=2 sw=2 nu로 YAML 편집 환경 최적화
  5. 별칭 설정: alias k=kubectl, export do="--dry-run=client -o yaml"
  6. 문서 활용: kubernetes.io/docs 공식 문서 북마크 허용