컨텍스트 전환 안 함
그 문제 전부 0점. 가장 흔하다.
아는 것을 2시간 안에 꺼내기
별칭과 단축 변수
alias k=kubectl # 보통 이미 있다export do='--dry-run=client -o yaml'export now='--force --grace-period=0'source <(kubectl completion bash)complete -F __start_kubectl kvim 설정 — 탭 문자로 YAML을 깨뜨리지 않기 위해
cat <<'EOF' > ~/.vimrcset expandtabset tabstop=2set shiftwidth=2set numberEOF이 30초가 남은 2시간의 속도를 정한다.
특히 $do는 거의 모든 문제에서 쓰게 된다.
flowchart LR
Q["문제를 연다"] --> S1["① 컨텍스트 전환<br/>지문의 명령을 그대로 복사"]
S1 --> S2["② 네임스페이스 확인<br/>지문이 지정했으면 반드시 -n"]
S2 --> SOLVE["푼다"]
SOLVE --> S3["③ 검산<br/>만든 것을 눈으로 확인"]
S3 --> NEXT["다음 문제"]
SKIP1["① 을 빠뜨리면"] -.->|"정답을 만들어도 0점 ❌"| S1
SKIP2["② 를 틀리면"] -.->|"그 문제 전부 0점 ❌"| S2
classDef key fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef bad fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
classDef ok fill:#dcfce7,stroke:#16a34a,color:#14532d
classDef mute fill:#f1f5f9,stroke:#94a3b8,color:#334155
class S1,S2 key
class SKIP1,SKIP2 bad
class S3 ok
class Q,SOLVE,NEXT mute
# ① 컨텍스트 전환kubectl config use-context k8s-c1-A
# ② 네임스페이스kubectl config set-context --current --namespace=<지정된ns>
# ③ 검산kubectl get <리소스> -n <ns># Podk run nginx --image=nginxk run nginx --image=nginx --port=80 --labels=app=webk run nginx --image=nginx $do > pod.yamlk run busy --image=busybox --restart=Never -- sleep 3600k run tmp --image=busybox --rm -it --restart=Never -- sh # 일회용 셸
# Deploymentk create deploy web --image=nginx --replicas=3k create deploy web --image=nginx --replicas=3 $do > 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분 대기빈 파일에서 시작하지 않는 세 경로.
flowchart LR
NEED["YAML 이 필요하다"] --> P1["① 명령형 생성기<br/>k create … $do > f.yaml"]
NEED --> P2["② 공식 문서 복사<br/>NetworkPolicy · affinity · PV …"]
NEED --> P3["③ 기존 리소스 복사<br/>k get pod web -o yaml > new.yaml"]
P3 --> CLEAN["uid · resourceVersion<br/>creationTimestamp · status 를 지운다"]
P1 --> EDIT["필요한 필드만 편집"]
P2 --> EDIT
CLEAN --> EDIT
EDIT --> V["k apply --dry-run=server<br/>k diff -f"]
BAD["빈 파일에 직접 타이핑"] -.->|"가장 느리고 가장 틀리기 쉽다 ❌"| NEED
classDef ok fill:#dcfce7,stroke:#16a34a,color:#14532d
classDef bad fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
classDef key fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef mute fill:#f1f5f9,stroke:#94a3b8,color:#334155
class P1,P2,P3 ok
class BAD bad
class V key
class NEED,EDIT,CLEAN mute
# 1) 명령형으로 뼈대를 뽑는다k run web --image=nginx $do > web.yamlk create deploy web --image=nginx $do > 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| 유형 | 핵심 |
|---|---|
| 클러스터 업그레이드 | 저장소 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 |
flowchart LR
S["시험 시작"] --> R0["30초 루틴<br/>alias · do · vimrc"]
R0 --> R1["1차 순회<br/>3분 안에 풀리는 것을 전부 처리"]
R1 --> RULE{"5분 룰"}
RULE -->|"실마리가 안 보인다"| FLAG["플래그 걸고 넘어간다"]
RULE -->|"풀린다"| SOLVE["푼다"]
FLAG --> R2["2차 순회<br/>남은 문제를 배점 순으로"]
SOLVE --> R2
R2 --> LAST["마지막 10분<br/>검산"]
classDef key fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef ok fill:#dcfce7,stroke:#16a34a,color:#14532d
classDef warn fill:#fef3c7,stroke:#d97706,color:#78350f
classDef mute fill:#f1f5f9,stroke:#94a3b8,color:#334155
class R0,RULE key
class LAST ok
class FLAG warn
class S,R1,R2,SOLVE mute
그리고 완벽주의를 버려라. 66%면 합격이다. 어려운 두 문제를 포기하고 나머지를 확실히 하는 편이 낫다.
컨텍스트 전환 안 함
그 문제 전부 0점. 가장 흔하다.
네임스페이스 틀림
그 문제 전부 0점. 두 번째로 흔하다.
vimrc 없이 YAML 편집
탭 문자가 들어가 파싱 에러. 문제를 통째로 날린다.
한 문제에 20분
뒤의 쉬운 문제 3개를 못 푼다.
| 실수 | 대가 |
|---|---|
| 컨텍스트 전환 안 함 | 그 문제 전부 0점 |
| 네임스페이스 틀림 | 그 문제 전부 0점 |
vim에 expandtab 없이 YAML 편집 |
파싱 에러로 문제 통째로 날림 |
노드에서 exit 안 하고 다음 문제 |
명령이 안 먹혀 시간 낭비 |
drain에 --ignore-daemonsets 누락 |
에러에서 헤맴 |
| 업그레이드 시 저장소 URL 안 바꿈 | 패키지를 못 찾아 막힘 |
| 만들고 확인 안 함 | 롤아웃 중인 상태로 넘어가 감점 |
| 한 문제에 20분 매달림 | 뒤의 쉬운 문제 3개를 못 품 |
위 8개 중 앞의 두 개가 압도적으로 많다. 이것만 안 해도 합격선에 가까워진다.
# 만들었으면 본다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 — 틀린 영역 집중
특히 15장(라이프사이클) 을 반복한다.
D-7 ~ D-4 — killercoda 반복
업그레이드 · etcd 백업복구 · 컨트롤 플레인 복구를 각 5회.
D-3 — killer.sh 2세션
이번엔 시간 안에 푸는 연습.
D-2 — 요약과 치트시트
각 장의 요약 절만 훑고 치트시트를 손에 붙인다.
D-1 — 새 걸 공부하지 말 것
환경 점검(웹캠·신분증·책상)만 한다.
killer.sh는 실제 시험보다 어렵다. 거기서 60%를 받아도 실제로는 합격하는 경우가 많다. 점수에 낙담하지 말고 틀린 것의 해설을 전부 읽는 용도로 쓰자.
$do · ~/.vimrc(expandtab) 를 만든다