Part 18: CKA 시험 준비
Part 18: CKA 시험 준비
Part 18: CKA
CKA 시험 개요
시험 형식
- 시간: 2시간 (120분)
- 문제 수: 15-20개 (버전에 따라 변동)
- 합격 점수: 66%
- 시험 방식: 실습 기반 (Performance-Based Exam)
- 환경: 원격 감독 (PSI 브라우저)
- 재응시: 1회 무료 재응시 포함
- 유효기간: 3년
시험 환경
- 운영체제: Ubuntu 20.04 LTS
- Kubernetes 버전: 1.28-1.30 (시험 시점에 따라 변동)
- 클러스터: 4-6개 클러스터 (컨텍스트 전환 필요)
- 허용 도구: kubectl, vim, tmux
- 참고 자료: kubernetes.io 공식 문서만 허용
시험 도메인 및 배점
- Storage (10%)
- PersistentVolume, PersistentVolumeClaim
- StorageClass
- Troubleshooting (30%)
- 클러스터 및 애플리케이션 장애 해결
- Control Plane 및 Worker Node 문제 해결
- 네트워크 문제 해결
- Workloads & Scheduling (15%)
- Deployment, ConfigMap, Secret
- Resource Limits, 스케줄링
- Cluster Architecture, Installation & Configuration (25%)
- RBAC
- 클러스터 업그레이드
- etcd 백업/복원
- Services & Networking (20%)
- Service, Ingress
- NetworkPolicy
시험 전 준비사항
시험 환경 설정
시험 시작 전 필수 설정:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 1. Alias 설정 (시간 절약의 핵심!)
alias k=kubectl
alias kgp='kubectl get pods'
alias kgs='kubectl get svc'
alias kgn='kubectl get nodes'
alias kd='kubectl describe'
alias kdel='kubectl delete'
alias kaf='kubectl apply -f'
# ~/.bashrc 또는 ~/.bash_aliases에 저장
echo "alias k=kubectl" >> ~/.bashrc
source ~/.bashrc
# 2. kubectl 자동 완성
source <(kubectl completion bash)
complete -F __start_kubectl k # alias에도 자동 완성 적용
# 3. 현재 컨텍스트 확인 (프롬프트에 표시)
# .bashrc에 추가
export PS1='[\u@\h \W $(kubectl config current-context)]\$ '
# 4. vim 설정
cat <<EOF > ~/.vimrc
set number
set expandtab
set tabstop=2
set shiftwidth=2
set autoindent
EOF
tmux 기본 사용법
시험 환경에서 tmux를 사용하면 여러 작업을 동시에 진행할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# tmux 세션 시작
tmux
# 화면 분할
Ctrl+b % # 세로 분할
Ctrl+b " # 가로 분할
# 패널 이동
Ctrl+b 화살표
# 패널 닫기
exit 또는 Ctrl+d
# 세션 나가기 (백그라운드)
Ctrl+b d
# 세션 다시 연결
tmux attach
Imperative vs Declarative
Imperative 명령어 (시험에서 더 빠름!)
CKA 시험에서는 Imperative 명령어를 사용하는 것이 시간을 크게 절약할 수 있다.
Pod 생성:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 기본 Pod
kubectl run nginx --image=nginx
# 포트 지정
kubectl run nginx --image=nginx --port=80
# 환경변수 추가
kubectl run nginx --image=nginx --env="DNS_DOMAIN=cluster" --env="POD_NAMESPACE=default"
# Labels 추가
kubectl run nginx --image=nginx --labels="app=nginx,tier=frontend"
# Dry-run으로 YAML 생성 (중요!)
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
# 즉시 실행하지 않고 YAML만 생성
kubectl run nginx --image=nginx --dry-run=client -o yaml | kubectl apply -f -
Deployment 생성:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 기본 Deployment
kubectl create deployment nginx --image=nginx
# Replicas 지정
kubectl create deployment nginx --image=nginx --replicas=3
# YAML 생성
kubectl create deployment nginx --image=nginx --replicas=3 --dry-run=client -o yaml > deployment.yaml
# Scale
kubectl scale deployment nginx --replicas=5
# 이미지 업데이트
kubectl set image deployment/nginx nginx=nginx:1.21
# Autoscale
kubectl autoscale deployment nginx --min=2 --max=10 --cpu-percent=80
Service 생성:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# ClusterIP
kubectl expose pod nginx --port=80 --target-port=8080 --name=nginx-service
# NodePort
kubectl expose deployment nginx --port=80 --type=NodePort --name=nginx-service
# LoadBalancer
kubectl expose deployment nginx --port=80 --type=LoadBalancer
# YAML 생성
kubectl create service clusterip nginx --tcp=80:80 --dry-run=client -o yaml > service.yaml
# Deployment를 expose하며 생성
kubectl expose deployment nginx --port=80 --target-port=8080 --type=ClusterIP --name=nginx-svc
ConfigMap/Secret:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# ConfigMap from literal
kubectl create configmap app-config --from-literal=key1=value1 --from-literal=key2=value2
# ConfigMap from file
kubectl create configmap app-config --from-file=config.properties
# Secret from literal
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=secret
# Secret for Docker registry
kubectl create secret docker-registry regcred \
--docker-server=myregistry.com \
--docker-username=user \
--docker-password=pass \
--docker-email=email@example.com
# TLS Secret
kubectl create secret tls tls-secret --cert=path/to/cert.crt --key=path/to/key.key
Namespace:
1
2
3
4
5
6
7
8
# Namespace 생성
kubectl create namespace dev
# Namespace에 리소스 생성
kubectl run nginx --image=nginx -n dev
# 기본 네임스페이스 설정
kubectl config set-context --current --namespace=dev
ServiceAccount:
1
2
3
4
5
# ServiceAccount 생성
kubectl create serviceaccount app-sa
# YAML 생성
kubectl create serviceaccount app-sa --dry-run=client -o yaml > sa.yaml
Declarative 방식
파일 수정 후 적용:
1
2
3
4
5
6
7
8
9
10
11
# 적용
kubectl apply -f deployment.yaml
# 디렉토리 전체 적용
kubectl apply -f ./configs/
# 실행 중인 리소스 편집
kubectl edit deployment nginx
# YAML 추출
kubectl get deployment nginx -o yaml > deployment.yaml
kubectl 마스터하기
필수 플래그
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# -o wide: 추가 정보 출력
kubectl get pods -o wide
# NAME READY STATUS RESTARTS AGE IP NODE
# nginx 1/1 Running 0 5m 10.244.1.5 node01
# -o yaml: YAML 형식 출력
kubectl get pod nginx -o yaml
# -o json: JSON 형식 출력
kubectl get pod nginx -o json
# --dry-run=client: 실제 생성 없이 검증
kubectl run nginx --image=nginx --dry-run=client
# --force: 강제 삭제/재생성
kubectl delete pod nginx --force --grace-period=0
# -n: 네임스페이스 지정
kubectl get pods -n kube-system
# -A, --all-namespaces: 모든 네임스페이스
kubectl get pods -A
# --show-labels: 레이블 표시
kubectl get pods --show-labels
# -l: 레이블 셀렉터
kubectl get pods -l app=nginx
# --sort-by: 정렬
kubectl get pods --sort-by=.metadata.creationTimestamp
# --field-selector: 필드 필터
kubectl get pods --field-selector status.phase=Running
# -w, --watch: 실시간 모니터링
kubectl get pods -w
jsonpath 활용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 특정 필드만 추출
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
# 복합 출력
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.podIP}{"\n"}{end}'
# 조건부 필터
kubectl get pods -o jsonpath='{.items[?(@.status.phase=="Running")].metadata.name}'
# Node의 Internal IP 추출
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
# PV 용량 추출
kubectl get pv -o jsonpath='{.items[*].spec.capacity.storage}'
# Custom Columns
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,IP:.status.podIP
자주 사용하는 패턴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Pod 강제 삭제
kubectl delete pod nginx --force --grace-period=0
# 특정 레이블 Pod만 삭제
kubectl delete pods -l app=nginx
# 모든 리소스 삭제 (네임스페이스 내)
kubectl delete all --all
# 리소스 상태 확인 (Loop)
kubectl get pods -w
# 로그 스트리밍
kubectl logs -f <pod-name>
# 이전 컨테이너 로그
kubectl logs <pod-name> --previous
# 여러 컨테이너 중 특정 컨테이너 로그
kubectl logs <pod-name> -c <container-name>
# Pod에 명령 실행
kubectl exec <pod-name> -- ls /app
# 인터랙티브 쉘
kubectl exec -it <pod-name> -- /bin/bash
# 파일 복사
kubectl cp <pod-name>:/path/to/file ./local-file
kubectl cp ./local-file <pod-name>:/path/to/file
# Port Forwarding
kubectl port-forward pod/nginx 8080:80
# Describe (상세 정보 + 이벤트)
kubectl describe pod nginx
# Events 확인
kubectl get events --sort-by='.lastTimestamp'
# Top (리소스 사용량)
kubectl top nodes
kubectl top pods
시험 시간 관리 전략
1. 초반 10분: 환경 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Alias 설정
alias k=kubectl
source <(kubectl completion bash)
complete -F __start_kubectl k
# vim 설정
cat <<EOF > ~/.vimrc
set number
set expandtab
set tabstop=2
set shiftwidth=2
EOF
# 모든 클러스터 확인
kubectl config get-contexts
2. 문제 풀이 순서
- 점수 대비 시간이 짧은 문제 먼저
- 1-2분 안에 풀 수 있는 문제
- Imperative 명령어로 바로 해결 가능한 문제
- 배점이 높은 문제
- Troubleshooting (30%)
- Cluster Architecture (25%)
- 어려운 문제는 Flag
- 시험 인터페이스의 Flag 기능 활용
- 모든 문제를 한 번 훑은 후 다시 돌아오기
3. 각 문제당 시간 배분
- 쉬운 문제 (1-3점): 3-5분
- 중간 문제 (4-7점): 8-12분
- 어려운 문제 (8-10점): 15-20분
예시 시간표:
- 00:00-00:10: 환경 설정
- 00:10-00:50: 쉬운 문제 8개 (40분)
- 00:50-01:30: 중간 문제 5개 (40분)
- 01:30-01:50: 어려운 문제 2-3개 (20분)
- 01:50-02:00: Flag한 문제 재확인 (10분)
4. 시험 중 팁
컨텍스트 전환 필수:
1
2
3
4
5
# 문제마다 컨텍스트가 명시됨
kubectl config use-context <cluster-name>
# 항상 확인
kubectl config current-context
검증 습관화:
1
2
3
4
5
6
7
8
9
# 리소스 생성 후 항상 확인
kubectl get <resource>
kubectl describe <resource> <name>
# 로그 확인
kubectl logs <pod-name>
# 이벤트 확인
kubectl get events --sort-by='.lastTimestamp' | tail -10
빠른 YAML 편집:
1
2
3
4
5
6
7
# 기존 리소스 수정
kubectl edit <resource> <name>
# 또는 YAML 추출 후 수정
kubectl get <resource> <name> -o yaml > resource.yaml
vim resource.yaml
kubectl apply -f resource.yaml
공식 문서 활용
kubernetes.io 검색 전략
1. 검색 키워드:
- “pod example”
- “deployment yaml”
- “persistent volume”
- “rbac serviceaccount”
- “network policy example”
2. 자주 사용하는 문서 경로:
- Tasks: https://kubernetes.io/docs/tasks/
- Concepts: https://kubernetes.io/docs/concepts/
- Reference: https://kubernetes.io/docs/reference/
3. 빠른 네비게이션:
- Ctrl+F로 페이지 내 검색
- 예제 YAML 복사 → 붙여넣기 → 수정
4. 북마크 추천:
시험 중 북마크는 허용되지 않지만, 연습 시 다음 페이지를 자주 참고하세요:
- Pod: https://kubernetes.io/docs/concepts/workloads/pods/
- Service: https://kubernetes.io/docs/concepts/services-networking/service/
- Ingress: https://kubernetes.io/docs/concepts/services-networking/ingress/
- PV/PVC: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
- RBAC: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- NetworkPolicy: https://kubernetes.io/docs/concepts/services-networking/network-policies/
도메인별 베스트 프랙티스
1. Storage (10%)
빠른 PVC 생성:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# PVC 생성 (Imperative 불가, YAML 필요)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
EOF
# Pod에 PVC 마운트
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
# 수동으로 volumes 섹션 추가 후
kubectl apply -f pod.yaml
PV 확인:
1
2
3
kubectl get pv
kubectl get pvc
kubectl describe pvc myclaim
2. Troubleshooting (30%)
체크리스트:
- Pod 문제:
1 2 3 4
kubectl get pods kubectl describe pod <name> kubectl logs <name> kubectl logs <name> --previous - Service 문제:
1 2 3
kubectl get svc kubectl get endpoints <service-name> kubectl describe svc <service-name>
- Node 문제:
1 2 3 4 5
kubectl get nodes kubectl describe node <node-name> ssh <node> systemctl status kubelet journalctl -u kubelet - Control Plane 문제:
1 2 3
kubectl get pods -n kube-system kubectl logs -n kube-system <component-pod> cat /etc/kubernetes/manifests/<component>.yaml
3. Workloads & Scheduling (15%)
Resource Limits 설정:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Imperative (불가)
# Declarative 필요
kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
# pod.yaml 수정
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Node Selector:
1
2
3
4
5
6
7
# 노드에 레이블 추가
kubectl label node node01 disktype=ssd
# Pod에 NodeSelector 설정
spec:
nodeSelector:
disktype: ssd
4. Cluster Architecture (25%)
RBAC 설정:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Role 생성
kubectl create role pod-reader --verb=get,list,watch --resource=pods
# RoleBinding 생성
kubectl create rolebinding pod-reader-binding --role=pod-reader --user=jane
# ClusterRole 생성
kubectl create clusterrole node-reader --verb=get,list --resource=nodes
# ClusterRoleBinding
kubectl create clusterrolebinding node-reader-binding --clusterrole=node-reader --user=bob
# ServiceAccount 생성
kubectl create serviceaccount app-sa
# ServiceAccount에 Role 바인딩
kubectl create rolebinding app-sa-binding --role=pod-reader --serviceaccount=default:app-sa
kubeadm Upgrade:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Control Plane
apt-get update
apt-get install -y kubeadm=1.28.0-00
kubeadm upgrade apply v1.28.0
apt-get install -y kubelet=1.28.0-00 kubectl=1.28.0-00
systemctl daemon-reload
systemctl restart kubelet
# Worker Node
kubectl drain node01 --ignore-daemonsets
# node01에서
apt-get update
apt-get install -y kubeadm=1.28.0-00
kubeadm upgrade node
apt-get install -y kubelet=1.28.0-00
systemctl daemon-reload
systemctl restart kubelet
# Control Plane에서
kubectl uncordon node01
etcd Backup:
1
2
3
4
5
ETCDCTL_API=3 etcdctl snapshot save /tmp/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
5. Services & Networking (20%)
NetworkPolicy:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
Ingress:
1
2
3
# Ingress 생성 (YAML 필요)
kubectl create ingress myapp --rule="myapp.com/=myapp-svc:80" --dry-run=client -o yaml > ingress.yaml
kubectl apply -f ingress.yaml
실전 Mock Exam 접근법
문제 예시 1: Pod 생성 (쉬움, 2분)
문제: “nginx 이미지를 사용하는 Pod를 생성하고, 레이블 app=web을 추가하세요.”
풀이:
1
2
kubectl run nginx --image=nginx --labels="app=web"
kubectl get pods --show-labels
문제 예시 2: Deployment Scale (쉬움, 2분)
문제: “nginx Deployment의 Replica를 5개로 증가시키세요.”
풀이:
1
2
kubectl scale deployment nginx --replicas=5
kubectl get deployment nginx
문제 예시 3: Service 생성 (중간, 5분)
문제: “nginx Deployment를 ClusterIP 서비스로 노출하세요. 포트는 80이다.”
풀이:
1
2
3
kubectl expose deployment nginx --port=80 --type=ClusterIP --name=nginx-svc
kubectl get svc nginx-svc
kubectl get endpoints nginx-svc
문제 예시 4: Troubleshooting (어려움, 10분)
문제: “webapp Pod가 CrashLoopBackOff 상태이다. 원인을 찾아 수정하세요.”
풀이:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 상태 확인
kubectl get pods
# 2. 상세 정보
kubectl describe pod webapp
# 3. 로그 확인
kubectl logs webapp
kubectl logs webapp --previous
# 4. 원인 파악 (예: ConfigMap 누락)
kubectl get configmap
# 5. 수정 (ConfigMap 생성)
kubectl create configmap webapp-config --from-literal=key=value
# 6. Pod 재생성
kubectl delete pod webapp --force --grace-period=0
문제 예시 5: RBAC (어려움, 15분)
문제: “developer라는 사용자에게 dev 네임스페이스의 Pod에 대한 get, list 권한을 부여하세요.”
풀이:
1
2
3
4
5
6
7
8
9
# 1. Role 생성
kubectl create role pod-reader --verb=get,list --resource=pods -n dev
# 2. RoleBinding 생성
kubectl create rolebinding dev-pod-reader --role=pod-reader --user=developer -n dev
# 3. 검증
kubectl auth can-i get pods --as=developer -n dev
# yes
시험 당일 체크리스트
시험 시작 전
- 신분증 준비 (여권, 주민등록증)
- 시험 환경 정리 (책상 위 물건 제거)
- 웹캠, 마이크 테스트
- 안정적인 인터넷 연결 확인
- 조용한 환경 확보
시험 시작 후 (첫 10분)
- Alias 설정 (
alias k=kubectl) - kubectl 자동 완성 활성화
- vim 설정
- 모든 클러스터 컨텍스트 확인
- 모든 문제 훑어보기
문제 풀이 중
- 문제마다 컨텍스트 확인
- 리소스 생성 후 검증
- Flag 기능 활용 (어려운 문제)
- 시간 배분 체크
시험 종료 전 (마지막 10분)
- Flag한 문제 재확인
- 모든 답안 검증
- 불필요한 리소스 삭제 확인
추가 학습 리소스
공식 리소스
- Kubernetes 공식 문서: https://kubernetes.io/docs/
- CKA 시험 커리큘럼: https://github.com/cncf/curriculum
- kubectl Cheat Sheet: https://kubernetes.io/docs/reference/kubectl/cheatsheet/
연습 환경
- Killer.sh: CKA 시험 환경과 유사한 Mock Exam (시험 등록 시 2회 제공)
- Katacoda Kubernetes Playground
- Play with Kubernetes
Mock Exam 사이트
- Killer.sh (가장 추천)
- Udemy - Mumshad Mannambeth의 CKA 과정
- Linux Academy / A Cloud Guru
최종 정리
반드시 암기할 명령어
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# Pod 생성
kubectl run <name> --image=<image>
# Deployment 생성
kubectl create deployment <name> --image=<image> --replicas=<n>
# Service 노출
kubectl expose deployment <name> --port=<port> --type=<type>
# Scale
kubectl scale deployment <name> --replicas=<n>
# YAML 생성
--dry-run=client -o yaml
# 컨텍스트 전환
kubectl config use-context <context>
# Troubleshooting
kubectl describe <resource> <name>
kubectl logs <pod> [-c container] [--previous]
kubectl get events --sort-by='.lastTimestamp'
# Node 관리
kubectl drain <node> --ignore-daemonsets
kubectl uncordon <node>
# RBAC
kubectl create role <name> --verb=<verbs> --resource=<resources>
kubectl create rolebinding <name> --role=<role> --user=<user>
# etcd Backup
ETCDCTL_API=3 etcdctl snapshot save <file> --endpoints=<ep> --cacert=<ca> --cert=<cert> --key=<key>
시험 전략
- 시간 관리: 쉬운 문제로 점수 확보 후 어려운 문제 도전
- Imperative 명령어 숙달: –dry-run=client -o yaml 활용
- 검증 습관화: 모든 작업 후 kubectl get/describe로 확인
- 공식 문서 검색 연습: 빠르게 예제 찾아 적용
- Troubleshooting 집중: 30% 배점, describe + logs + events 순서로
- 컨텍스트 전환 확인: 매 문제마다 kubectl config use-context 확인
- Mock Exam 반복: Killer.sh를 최소 3회 이상 풀어보기
This post is licensed under CC BY 4.0 by the author.