콘텐츠로 이동
Study NoteCKA

시험 전략과 치트시트

결론부터
시험에서는 도움말과 공식 예제로 필요한 설정을 빠르게 만들고, 문제의 작업 조건과 실제 결과를 함께 검증한다.

지정 호스트에서 바로 풀이한다

섹션 제목: “지정 호스트에서 바로 풀이한다”

시험 시작 직후 base에서 할 준비는 없다. 모든 문제는 지문이 지정한 호스트에 ssh <호스트>로 들어가 풀고, k alias와 bash 자동완성은 그 호스트에 이미 켜져 있다. 공식 기술 지침은 base에 이 도구들이 없다고 명시한다(2026-09-27 확인). alias k=kubectl이나 개인 설정을 새로 만드는 준비 절차 없이 풀이를 시작해도 된다.

전체 옵션을 직접 입력하면 충분하다. 자주 쓰는 옵션은 시험 중 원격 데스크톱의 편집기에 적어 두고 복사해 사용해도 된다.

옵션용도
--dry-run=client -o yaml리소스를 실제 생성하지 않고 YAML 뼈대 출력
--force --grace-period=0즉시 강제 삭제가 필요한 상황에서만 사용

$do·$now 같은 단축 변수는 평소 익숙하다면 선택해서 쓴다. .bashrc에 저장할 필요는 없으며, 아래 예제는 단축 변수 없이 실행할 수 있도록 전체 옵션을 사용한다.

Tab 입력과 들여쓰기가 원하는 대로 동작하면 설정은 생략한다. 공백 처리나 들여쓰기 폭을 바꾸고 싶을 때만 다음 예에서 필요한 옵션을 적용한다.

:set et ts=2 sts=2 sw=2 ai

같은 보완을 반복해야 할 때만 기존 ~/.vimrc를 확인하고 필요한 항목을 추가하거나 수정한다. 옵션 의미와 호스트·사용자별 설정 범위는 Vim 설정을 따른다.

모든 키는 Esc로 일반 모드에 돌아온 뒤 사용한다. : 명령·검색은 마지막에 Enter를 누른다.

목적키
줄 맨 앞 / 첫 글자 / 맨 뒤0 / ^ / $
첫 글자 앞 / 줄 끝에서 입력I / A
검색 / 다음 / 반대 방향/문자열 / n / N
현재 줄 들여쓰기 / 내어쓰기>> / << — 같은 키를 두 번 연속
블록 이동V → j·k로 선택 → >·<, 다시 선택은 gv
숫자로 범위·횟수 지정 (sw=2)일반 모드 3>>: 3줄을 2칸씩 / 선택 후 3>: 선택한 줄을 6칸씩
취소 / 다시 실행u / Ctrl+r
저장 종료 / 변경 버리고 종료:wq / :q!

설정 의미·붙여넣기·모드 구분은 시험 안내 Vim 기본 조작을 참고한다.

① 지정 호스트에 SSH 접속 → ② 네임스페이스 확인 → ③ 풀이 후 검산을 반복한다. 현재 공식 지침은 문제 시작의 안내 상자에 적힌 호스트에서 작업하고, 완료하면 exit으로 base에 돌아오도록 한다. kubectl config use-context는 매 문제의 필수 준비 명령이 아니다. 지문에서 별도 컨텍스트나 kubeconfig를 지정한 경우에 그 지시를 따른다.

지정 호스트에 SSH 접속하고 네임스페이스를 확인한 뒤 풀이·검산하고 base로 돌아오는 흐름

아래는 명령 형태 예시다. <…>는 지문에 나온 값으로 바꾸고, 네임스페이스에 속하는 리소스에는 풀이·검산 명령 모두 같은 -n을 사용한다. Node·PV 같은 클러스터 범위 리소스에는 -n이 필요 없다.

터미널 창
# ① base에서 지문에 지정된 호스트로 접속
ssh <지정된호스트>
# ② 대상 네임스페이스에서 현재 상태 확인 후 풀이
kubectl get <리소스> -n <지정된ns>
# ③ 풀이 후 요구된 상태·동작 검증
kubectl get <리소스> <이름> -n <지정된ns>
# 완료 후 base로 복귀
exit
터미널 창
# Pod
k run nginx --image=nginx
k run nginx --image=nginx --port=80 --labels=app=web
k run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
k run busy --image=busybox --restart=Never -- sleep 3600 # -- 뒤는 args로 들어간다
k run busy --image=busybox --restart=Never --command -- sleep 3600 # command로 넣을 때
k run tmp --image=busybox --rm -it --restart=Never -- sh # 일회용 셸
# Deployment
k create deploy web --image=nginx --replicas=3
k create deploy web --image=nginx --replicas=3 --dry-run=client -o yaml > deploy.yaml
k scale deploy web --replicas=5
k set image deploy/web nginx=nginx:1.28
k rollout status deploy/web
k rollout undo deploy/web
k rollout restart deploy/web
# Job / CronJob
k create job hello --image=busybox -- echo hi
k create job manual --from=cronjob/nightly
k create cronjob nightly --image=busybox --schedule="0 3 * * *" -- echo backup

생성 치트시트 — 네트워크 · 설정

섹션 제목: “생성 치트시트 — 네트워크 · 설정”
터미널 창
# Service
k expose deploy web --port=80 --target-port=8080 --name=web-svc
k expose deploy web --port=80 --type=NodePort
k create svc clusterip web-svc --tcp=80:8080
k create svc nodeport web-svc --tcp=80:8080 --node-port=30080
# Ingress
k create ingress web --class=nginx --rule="example.com/*=web-svc:80"
k create ingress web --class=nginx \
--rule="example.com/api*=api-svc:8080" \
--rule="example.com/*=web-svc:80"
# ConfigMap / Secret
k create cm app-config --from-literal=KEY=val --from-file=./conf/
k create cm app-env --from-env-file=./app.env
k create secret generic db --from-literal=password=s3cr3t
k create secret tls web-tls --cert=./tls.crt --key=./tls.key
k create secret docker-registry regcred --docker-server=r.io --docker-username=u --docker-password=p
# 네임스페이스 / 쿼터
k create ns dev
k create quota dev-quota --hard=cpu=4,memory=8Gi,pods=20 -n dev
터미널 창
# ServiceAccount
k create sa deploy-bot
# Role / ClusterRole
k create role pod-reader --verb=get,list,watch --resource=pods -n dev
k create role pod-editor --verb=get,list,create,delete --resource=pods,deployments -n dev
k create clusterrole node-reader --verb=get,list,watch --resource=nodes
# Binding
k create rolebinding dev-rb --role=pod-reader --user=dev -n dev
k create rolebinding sa-rb --role=pod-reader --serviceaccount=dev:deploy-bot -n dev
k create clusterrolebinding ops-crb --clusterrole=cluster-admin --user=ops
k create rolebinding dev-edit --clusterrole=edit --user=bob -n dev # ClusterRole + RoleBinding
# 검산 ★ 반드시 한다
k auth can-i list pods -n dev --as=dev
k auth can-i create deploy -n dev --as=system:serviceaccount:dev:deploy-bot
k auth can-i --list -n dev
터미널 창
# 기본
k get pods -o wide
k get pods -A
k get all -n dev
k get pods --show-labels
k get pods -l env=prod --no-headers | wc -l # 개수 세기
# 정렬
k get pods --sort-by=.metadata.creationTimestamp
k get events -A --sort-by=.lastTimestamp | tail -30
k get nodes --sort-by=.metadata.name
# 필드 추출 — "파일에 저장하시오" 문제용
k get pods -o custom-columns='NAME:.metadata.name,NODE:.spec.nodeName' --no-headers
k get pods -o jsonpath='{.items[*].spec.containers[*].image}'
k get pv --sort-by=.spec.capacity.storage -o custom-columns='NAME:.metadata.name,SIZE:.spec.capacity.storage'
k get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'
# 필터
k get pods --field-selector status.phase=Running
k get pods --field-selector spec.nodeName=node01
k get events --field-selector type=Warning
터미널 창
# 순서: describe → logs → yaml
k describe pod web | grep -A20 Events
k logs web --previous
k logs -l app=web --all-containers --prefix --tail=50
k get pod web -o yaml
# 노드
k describe node node01 | grep -A15 Conditions
k describe node node01 | grep -A10 'Allocated resources'
k top nodes ; k top pods -A --sort-by=memory
# 노드 안에서
sudo systemctl status kubelet
sudo journalctl -u kubelet -n 100 --no-pager
sudo crictl ps -a
sudo crictl logs <id>
# 네트워크
k get endpoints web-svc
k run tmp --image=busybox:1.36 --rm -it --restart=Never -- nslookup web-svc
k run tmp --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://web-svc
터미널 창
# 노드 관리
k drain node01 --ignore-daemonsets --delete-emptydir-data
k uncordon node01
k taint node node01 key=value:NoSchedule
k taint node node01 key=value:NoSchedule-
k label node node01 disktype=ssd
# 업그레이드 (노드에서)
sudo sed -i 's/v1.34/v1.35/' /etc/apt/sources.list.d/kubernetes.list && sudo apt-get update
sudo apt-mark unhold kubeadm && sudo apt-get install -y kubeadm=1.35.1-1.1 && sudo apt-mark hold kubeadm
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.35.1 # 첫 컨트롤 플레인
sudo kubeadm upgrade node # 나머지 전부
sudo apt-mark unhold kubelet kubectl && sudo apt-get install -y kubelet=1.35.1-1.1 kubectl=1.35.1-1.1 && sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload && sudo systemctl restart kubelet
# 조인 / 인증서
kubeadm token create --print-join-command
sudo kubeadm certs check-expiration
sudo kubeadm certs renew all

etcd 백업·복구 — 통째로 외울 것

섹션 제목: “etcd 백업·복구 — 통째로 외울 것”
터미널 창
# 경로 확인 (추측하지 말 것)
sudo grep -E 'cert-file|key-file|trusted-ca-file|data-dir|listen-client-urls' \
/etc/kubernetes/manifests/etcd.yaml
# 백업
sudo ETCDCTL_API=3 etcdctl \
--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 \
snapshot save /opt/backup.db
# 확인
sudo ETCDCTL_API=3 etcdctl --write-out=table snapshot status /opt/backup.db
# 복구
sudo ETCDCTL_API=3 etcdctl snapshot restore /opt/backup.db --data-dir=/var/lib/etcd-restore
sudo vim /etc/kubernetes/manifests/etcd.yaml # volumes.hostPath.path 를 새 디렉터리로
# → kubelet이 자동으로 etcd Pod을 다시 만든다. 1~2분 대기

빈 파일에서 시작하지 않는 세 경로.

YAML 이 필요할 때 명령형 생성기 · 공식 문서 복사 · 기존 리소스 복사 세 경로를 거쳐 편집하고 dry-run 으로 검증하는 흐름, 빈 파일에 직접 타이핑을 피하는 이유
터미널 창
# 1) 명령형으로 뼈대를 뽑는다
k run web --image=nginx --dry-run=client -o yaml > web.yaml
k create deploy web --image=nginx --dry-run=client -o yaml > deploy.yaml
# 2) 기존 리소스를 복사해서 고친다
k get pod web -o yaml > new.yaml
# → metadata의 uid, resourceVersion, creationTimestamp, status 를 지운다
# 3) 필드 이름이 기억 안 나면
k explain pod.spec.containers.resources
k explain deployment.spec.strategy --recursive | head -30
# 4) 적용 전에 검증
k apply -f web.yaml --dry-run=server
k diff -f web.yaml

VSCodium에서 공식 명령을 수정하기

섹션 제목: “VSCodium에서 공식 명령을 수정하기”

시험 원격 데스크톱의 VSCodium을 메모장처럼 사용한다. Applications 메뉴나 바탕화면 아이콘으로 열 수 있고 내장 터미널도 사용할 수 있다. 제공 도구와 단축키는 Linux Foundation 시험 UI 안내에 명시돼 있다(2026-09-12 확인). 확장 설치는 허용되지 않는다.

  1. 원격 Firefox에서 허용된 공식 문서의 예제 명령·YAML을 복사한다.
  2. VSCodium의 새 파일에 붙여넣고 이름·namespace·이미지·경로를 수정한다.
  3. 수정한 명령을 문제에서 지정한 호스트에 SSH로 접속한 터미널에 붙여넣어 실행한다.
  4. YAML이라면 대상 호스트에 파일을 저장하고 적용·검증한다. 편집기에서 저장한 base의 파일이 SSH 호스트에 자동으로 생기지는 않는다.

브라우저·편집 영역은 Ctrl+C / Ctrl+V, 터미널은 Ctrl+Shift+C / Ctrl+Shift+V다. Mac으로 응시해도 원격 Linux 안에서는 이 단축키를 쓴다. 개인 컴퓨터의 별도 메모장 대신 시험에서 제공하는 편집기를 사용한다. 응시 환경·SSH 작업 지침도 함께 확인한다.

짧게 생성하되 문제의 작업 조건을 지킨다

섹션 제목: “짧게 생성하되 문제의 작업 조건을 지킨다”

kubectl create -h → kubectl create deployment -h로 생성 옵션을 찾고, YAML 필드는 kubectl explain으로 찾는다. --image 두 번으로 컨테이너 두 개의 뼈대를 만들 수 있지만, 네이티브 사이드카는 해당 블록을 initContainers로 옮겨야 한다.

“apply로 생성·업데이트”처럼 방법을 명시한 문제는 그 조건도 따른다. create --dry-run=client -o yaml로 파일만 만든 뒤 apply하는 것은 이 조건을 지킨다. 1.16 생성 후 1.17 업데이트라면 첫 버전의 rollout 완료를 확인한 뒤 태그를 바꾼다.

  • 기본 StorageClass: annotation의 "true"와 확장 필드의 true 구분
  • 네이티브 로그 사이드카: initContainers + 컨테이너 수준 restartPolicy: Always, touch 후 tail -f
  • Ingress 생성: --class → ingressClassName, 경로 끝 * → Prefix, 마지막에는 curl
  • apply 롤링 업데이트: 파일 수정 후 두 번째 apply, 새 이미지·Ready 검증
  • CSR와 RBAC: 실제 CSR 인코딩 → 승인·발급 → Role·Binding → can-i
유형핵심
클러스터 업그레이드저장소 URL → apply/node → kubelet
etcd 백업·복구인증서 3종, 새 data-dir
고장난 컨트롤 플레인/etc/kubernetes/manifests/ 의 값 하나
노드 NotReadyjournalctl -u kubelet
RBAC 생성Role + Binding + auth can-i 검산
CSR 승인certificate approve
PV/PVC 연결storageClassName·accessModes·용량
NetworkPolicy문서 복사, AND/OR 주의
Ingress / Gateway API문서 복사
스케줄링(taint·affinity)문서 복사
사이드카·initContainer 추가kubectl edit 또는 재생성
DNS 확인nslookup, CoreDNS ConfigMap
특정 조건의 Pod 찾아 파일에 저장-l, --sort-by, custom-columns
HPA 구성metrics-server + requests
노드 drain / 스케줄 제어--ignore-daemonsets

표는 핵심만 적은 것이다. 지문을 받았을 때의 풀이 순서는 실전 과제 페이지에서 손으로 따라 해 본다.

지정 호스트 접속부터 1차 순회 · 5분 룰 · 2차 순회를 거쳐 마지막 10분 검산까지의 시간 배분
  • 문제당 평균 7분. 하지만 균일하지 않다
  • 1차 순회 — 전체를 빠르게 훑으며 3분 안에 풀리는 것을 전부 처리
  • 막히면 5분 룰 — 5분 안에 실마리가 안 보이면 플래그 걸고 넘어간다
  • 2차 순회 — 남은 문제를 배점 순으로
  • 마지막 10분은 검산

그리고 완벽주의를 버려라. 66%면 합격이다. 어려운 두 문제를 포기하고 나머지를 확실히 하는 편이 낫다.

지정 호스트에 접속하지 않음

작업 대상이 달라진다. 지문의 SSH 접속 명령으로 해당 호스트에 들어가서 푼다.

네임스페이스 틀림

지정된 위치에 결과가 없다. 풀이와 검산에 같은 네임스페이스를 사용한다.

그 다음으로 비싼 것들 —

실수대가
vim에 expandtab 없이 YAML 편집탭 문자가 들어가 파싱 에러 — 문제 통째로 날림
노드에서 exit 안 하고 다음 문제명령이 안 먹혀 시간 낭비
drain에 --ignore-daemonsets 누락에러에서 헤맴
업그레이드 시 저장소 URL 안 바꿈패키지를 못 찾아 막힘
만들고 확인 안 함롤아웃 중인 상태로 넘어가 감점
한 문제에 20분 매달림뒤의 쉬운 문제 3개를 못 품

호스트와 네임스페이스는 작업 전에 확인하고, 같은 대상에서 결과를 검증한다.

터미널 창
# 만들었으면 본다
k get <리소스> -n <ns>
k describe <리소스> <이름> -n <ns>
# 롤아웃은 끝날 때까지 기다린다
k rollout status deploy/web
k wait --for=condition=ready pod -l app=web --timeout=60s
# 연결은 실제로 해본다
k get endpoints web-svc
k run tmp --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://web-svc
# 권한은 흉내내서 확인한다
k auth can-i <verb> <resource> -n <ns> --as=<user>
# 노드 작업은 최종 상태를 본다
k get nodes

“만들었다”와 “동작한다”는 다르다. 채점은 최종 상태만 보므로, 최종 상태를 본 사람만 점수를 가져간다.

공식 문서에서 바로 가져올 것들

섹션 제목: “공식 문서에서 바로 가져올 것들”

손으로 치면 틀리는 것들이다. 무조건 복사한다.

필요한 것검색어 (kubernetes.io/docs)
NetworkPolicynetwork policies — deny-all 포함 예제 5종
nodeAffinity / podAffinityassign pods nodes
PV / PVC / StorageClasspersistent volumes
Ingress + TLSingress
RBAC Role/Bindingrbac
CSRcertificate signing requests
etcd 백업·복구operating etcd
업그레이드upgrade kubeadm clusters
probe 문법configure liveness readiness startup probes
CronJob 스케줄cronjob
HTTPRoute(Gateway API 사이트) http routing
  1. D-14 — killer.sh 1세션

    무엇이 약한지만 확인한다. 점수는 신경 쓰지 말 것.

  2. D-13 ~ D-8 — 틀린 영역 집중

    특히 클러스터 업그레이드(라이프사이클) 을 반복한다.

  3. D-7 ~ D-4 — killercoda 반복

    업그레이드 · etcd 백업복구 · 컨트롤 플레인 복구를 각 5회.

  4. D-3 — killer.sh 2세션

    이번엔 시간 안에 푸는 연습.

  5. D-2 — 요약과 치트시트

    각 장의 요약 절만 훑고 치트시트를 손에 붙인다.

  6. D-1 — 새 걸 공부하지 말 것

    환경 점검(웹캠·신분증·책상)만 한다.

killer.sh는 실제 시험보다 어렵다. 거기서 60%를 받아도 실제로는 합격하는 경우가 많다. 점수에 낙담하지 말고 틀린 것의 해설을 전부 읽는 용도로 쓰자.

  • 지정 호스트에서 바로 풀이한다. 옵션은 직접 입력하고, 개인 단축·Vim 설정은 필요할 때만 보완한다
  • 문제마다 ① 지정 호스트에 SSH 접속 ② 네임스페이스 확인 ③ 검산을 반복하고, 완료 후 base로 돌아온다
  • 빈 파일에 YAML을 치지 말 것 — 생성기 / 문서 / 기존 리소스 복사
  • 빨리 풀리는 것부터. 5분 룰로 넘기고 2차 순회에서 돌아온다
  • 호스트·네임스페이스가 지문의 작업 대상과 일치하는지 확인한다
  • “만들었다”가 아니라 “동작한다”를 확인하고 넘어간다
  • 문서 복사 대상(NetworkPolicy·affinity·PV·etcd·업그레이드)은 경로를 미리 익혀둔다
  • 66%면 합격이다. 어려운 문제를 버리는 것도 전략이다