지정 호스트에 접속하지 않음
작업 대상이 달라진다. 지문의 SSH 접속 명령으로 해당 호스트에 들어가서 푼다.
시험 시작 직후 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를 지정한 경우에 그 지시를 따른다.
아래는 명령 형태 예시다. <…>는 지문에 나온 값으로 바꾸고, 네임스페이스에 속하는 리소스에는
풀이·검산 명령 모두 같은 -n을 사용한다. Node·PV 같은 클러스터 범위 리소스에는 -n이 필요 없다.
# ① base에서 지문에 지정된 호스트로 접속ssh <지정된호스트>
# ② 대상 네임스페이스에서 현재 상태 확인 후 풀이kubectl get <리소스> -n <지정된ns>
# ③ 풀이 후 요구된 상태·동작 검증kubectl get <리소스> <이름> -n <지정된ns>
# 완료 후 base로 복귀exit# Podk run nginx --image=nginxk run nginx --image=nginx --port=80 --labels=app=webk run nginx --image=nginx --dry-run=client -o yaml > pod.yamlk 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 # 일회용 셸
# Deploymentk create deploy web --image=nginx --replicas=3k create deploy web --image=nginx --replicas=3 --dry-run=client -o yaml > deploy.yamlk scale deploy web --replicas=5k set image deploy/web nginx=nginx:1.28k rollout status deploy/webk rollout undo deploy/webk rollout restart deploy/web
# Job / CronJobk create job hello --image=busybox -- echo hik create job manual --from=cronjob/nightlyk create cronjob nightly --image=busybox --schedule="0 3 * * *" -- echo backup# Servicek expose deploy web --port=80 --target-port=8080 --name=web-svck expose deploy web --port=80 --type=NodePortk create svc clusterip web-svc --tcp=80:8080k create svc nodeport web-svc --tcp=80:8080 --node-port=30080
# Ingressk 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 / Secretk create cm app-config --from-literal=KEY=val --from-file=./conf/k create cm app-env --from-env-file=./app.envk create secret generic db --from-literal=password=s3cr3tk create secret tls web-tls --cert=./tls.crt --key=./tls.keyk create secret docker-registry regcred --docker-server=r.io --docker-username=u --docker-password=p
# 네임스페이스 / 쿼터k create ns devk create quota dev-quota --hard=cpu=4,memory=8Gi,pods=20 -n dev# ServiceAccountk create sa deploy-bot
# Role / ClusterRolek create role pod-reader --verb=get,list,watch --resource=pods -n devk create role pod-editor --verb=get,list,create,delete --resource=pods,deployments -n devk create clusterrole node-reader --verb=get,list,watch --resource=nodes
# Bindingk create rolebinding dev-rb --role=pod-reader --user=dev -n devk create rolebinding sa-rb --role=pod-reader --serviceaccount=dev:deploy-bot -n devk create clusterrolebinding ops-crb --clusterrole=cluster-admin --user=opsk create rolebinding dev-edit --clusterrole=edit --user=bob -n dev # ClusterRole + RoleBinding
# 검산 ★ 반드시 한다k auth can-i list pods -n dev --as=devk auth can-i create deploy -n dev --as=system:serviceaccount:dev:deploy-botk auth can-i --list -n dev# 기본k get pods -o widek get pods -Ak get all -n devk get pods --show-labelsk get pods -l env=prod --no-headers | wc -l # 개수 세기
# 정렬k get pods --sort-by=.metadata.creationTimestampk get events -A --sort-by=.lastTimestamp | tail -30k get nodes --sort-by=.metadata.name
# 필드 추출 — "파일에 저장하시오" 문제용k get pods -o custom-columns='NAME:.metadata.name,NODE:.spec.nodeName' --no-headersk 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=Runningk get pods --field-selector spec.nodeName=node01k get events --field-selector type=Warning# 순서: describe → logs → yamlk describe pod web | grep -A20 Eventsk logs web --previousk logs -l app=web --all-containers --prefix --tail=50k get pod web -o yaml
# 노드k describe node node01 | grep -A15 Conditionsk describe node node01 | grep -A10 'Allocated resources'k top nodes ; k top pods -A --sort-by=memory
# 노드 안에서sudo systemctl status kubeletsudo journalctl -u kubelet -n 100 --no-pagersudo crictl ps -asudo crictl logs <id>
# 네트워크k get endpoints web-svck run tmp --image=busybox:1.36 --rm -it --restart=Never -- nslookup web-svck run tmp --image=busybox:1.36 --rm -it --restart=Never -- wget -qO- http://web-svc# 노드 관리k drain node01 --ignore-daemonsets --delete-emptydir-datak uncordon node01k taint node node01 key=value:NoSchedulek 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 updatesudo apt-mark unhold kubeadm && sudo apt-get install -y kubeadm=1.35.1-1.1 && sudo apt-mark hold kubeadmsudo kubeadm upgrade plansudo 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 kubectlsudo systemctl daemon-reload && sudo systemctl restart kubelet
# 조인 / 인증서kubeadm token create --print-join-commandsudo kubeadm certs check-expirationsudo kubeadm certs renew all# 경로 확인 (추측하지 말 것)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-restoresudo vim /etc/kubernetes/manifests/etcd.yaml # volumes.hostPath.path 를 새 디렉터리로# → kubelet이 자동으로 etcd Pod을 다시 만든다. 1~2분 대기빈 파일에서 시작하지 않는 세 경로.
# 1) 명령형으로 뼈대를 뽑는다k run web --image=nginx --dry-run=client -o yaml > web.yamlk 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.resourcesk explain deployment.spec.strategy --recursive | head -30
# 4) 적용 전에 검증k apply -f web.yaml --dry-run=serverk diff -f web.yaml시험 원격 데스크톱의 VSCodium을 메모장처럼 사용한다. Applications 메뉴나 바탕화면 아이콘으로 열 수 있고 내장 터미널도 사용할 수 있다. 제공 도구와 단축키는 Linux Foundation 시험 UI 안내에 명시돼 있다(2026-09-12 확인). 확장 설치는 허용되지 않는다.
브라우저·편집 영역은 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 완료를 확인한 뒤 태그를 바꾼다.
"true"와 확장 필드의 true 구분initContainers + 컨테이너 수준 restartPolicy: Always, touch 후 tail -f--class → ingressClassName, 경로 끝 * → Prefix, 마지막에는 curlapply, 새 이미지·Ready 검증can-i| 유형 | 핵심 |
|---|---|
| 클러스터 업그레이드 | 저장소 URL → apply/node → kubelet |
| etcd 백업·복구 | 인증서 3종, 새 data-dir |
| 고장난 컨트롤 플레인 | /etc/kubernetes/manifests/ 의 값 하나 |
| 노드 NotReady | journalctl -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 |
표는 핵심만 적은 것이다. 지문을 받았을 때의 풀이 순서는 실전 과제 페이지에서 손으로 따라 해 본다.
그리고 완벽주의를 버려라. 66%면 합격이다. 어려운 두 문제를 포기하고 나머지를 확실히 하는 편이 낫다.
지정 호스트에 접속하지 않음
작업 대상이 달라진다. 지문의 SSH 접속 명령으로 해당 호스트에 들어가서 푼다.
네임스페이스 틀림
지정된 위치에 결과가 없다. 풀이와 검산에 같은 네임스페이스를 사용한다.
그 다음으로 비싼 것들 —
| 실수 | 대가 |
|---|---|
vim에 expandtab 없이 YAML 편집 | 탭 문자가 들어가 파싱 에러 — 문제 통째로 날림 |
노드에서 exit 안 하고 다음 문제 | 명령이 안 먹혀 시간 낭비 |
drain에 --ignore-daemonsets 누락 | 에러에서 헤맴 |
| 업그레이드 시 저장소 URL 안 바꿈 | 패키지를 못 찾아 막힘 |
| 만들고 확인 안 함 | 롤아웃 중인 상태로 넘어가 감점 |
| 한 문제에 20분 매달림 | 뒤의 쉬운 문제 3개를 못 품 |
호스트와 네임스페이스는 작업 전에 확인하고, 같은 대상에서 결과를 검증한다.
# 만들었으면 본다k get <리소스> -n <ns>k describe <리소스> <이름> -n <ns>
# 롤아웃은 끝날 때까지 기다린다k rollout status deploy/webk wait --for=condition=ready pod -l app=web --timeout=60s
# 연결은 실제로 해본다k get endpoints web-svck 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) |
|---|---|
| NetworkPolicy | network policies — deny-all 포함 예제 5종 |
| nodeAffinity / podAffinity | assign pods nodes |
| PV / PVC / StorageClass | persistent volumes |
| Ingress + TLS | ingress |
| RBAC Role/Binding | rbac |
| CSR | certificate signing requests |
| etcd 백업·복구 | operating etcd |
| 업그레이드 | upgrade kubeadm clusters |
| probe 문법 | configure liveness readiness startup probes |
| CronJob 스케줄 | cronjob |
| HTTPRoute | (Gateway API 사이트) http routing |
D-14 — killer.sh 1세션
무엇이 약한지만 확인한다. 점수는 신경 쓰지 말 것.
D-13 ~ D-8 — 틀린 영역 집중
특히 클러스터 업그레이드(라이프사이클) 을 반복한다.
D-7 ~ D-4 — killercoda 반복
업그레이드 · etcd 백업복구 · 컨트롤 플레인 복구를 각 5회.
D-3 — killer.sh 2세션
이번엔 시간 안에 푸는 연습.
D-2 — 요약과 치트시트
각 장의 요약 절만 훑고 치트시트를 손에 붙인다.
D-1 — 새 걸 공부하지 말 것
환경 점검(웹캠·신분증·책상)만 한다.
killer.sh는 실제 시험보다 어렵다. 거기서 60%를 받아도 실제로는 합격하는 경우가 많다. 점수에 낙담하지 말고 틀린 것의 해설을 전부 읽는 용도로 쓰자.
base로 돌아온다