목차
3 장

kubectl과 첫 Pod

kubectl의 멘탈 모델을 잡고 첫 Pod를 띄웁니다. kubectl run의 명령형 한 사이클부터 YAML 매니페스트의 선언형, get / describe / logs / exec 일상 명령, Pod 라이프사이클과 ImagePullBackOff · CrashLoopBackOff 흔한 실패 패턴까지 다룹니다.

2장 로컬 환경에서 클러스터 한 대를 노트북 위에 올렸습니다. 이번 챕터에서는 그 클러스터에 처음으로 Pod 한 개를 올리고, 안에 들어가 보고, 로그를 읽고, 다시 깔끔하게 지우는 한 사이클을 다룹니다. 그 과정에서 kubectl의 기본 명령과 Pod의 역할도 함께 익힙니다.

이번 챕터의 끝에서는 kubectl의 일상 명령군이 손에 붙고, Pod라는 단위가 무엇인지 한 번 직접 만들어 본 상태가 됩니다. 이어 4장 Deployment와 ReplicaSet부터는 이 Pod를 사람이 직접 만들지 않고 컨트롤러에게 맡기는 이야기로 넘어갑니다.

Pod가 뭔가 #

1장 쿠버네티스란의 리소스 표에서 한 줄로 본 정의가 있었습니다 — Pod는 컨테이너 1개 또는 같이 동작하는 몇 개를 묶은 K8s의 최소 실행 단위입니다. 이걸 조금 더 풀어 봅니다.

Docker까지 와 본 독자라면 컨테이너라는 단위는 이미 익숙합니다. K8s는 그 위에 한 겹을 더 둡니다 — 컨테이너 한 개 또는 여러 개를 묶어 함께 스케줄·실행하는 단위가 Pod입니다. 같은 Pod 안의 컨테이너들은 다음을 공유합니다.

  • 네트워크 네임스페이스 — 같은 IP, 같은 포트 공간을 공유합니다. 한 Pod 안에서는 localhost로 서로를 부릅니다.
  • 일부 볼륨 — Pod에 정의된 볼륨을 여러 컨테이너가 같이 마운트할 수 있습니다.
  • 수명 — 같이 뜨고, 같이 죽습니다 (같은 노드 위에서).

도커의 컨테이너와 가장 헷갈리는 지점이 여기입니다. 도커에서는 “컨테이너 1개 = 실행 단위 1개” 였는데, K8s에서는 “Pod 1개 = 실행 단위 1개"이고 그 Pod 안에 컨테이너가 1개일 수도, 2개일 수도 있습니다. 머릿속 공식으로는 Pod ≈ “한 IP를 공유하는 컨테이너 그룹” 정도가 무난합니다.

다만 실무의 99% 이상은 1 Pod 1 컨테이너입니다. 같은 Pod에 컨테이너 두 개를 같이 두는 건 사이드카 (로그 수집기, 프록시 등)처럼 그 컨테이너가 메인 컨테이너에 붙어 다녀야 자연스러운 경우에 한정됩니다. 처음에는 “Pod = 컨테이너 한 개를 K8s가 굴리기 위해 한 겹 감싼 것"으로 이해해도 충분합니다.

한 가지 더 — 운영에서 직접 kind: Pod을 매니페스트로 적는 일은 거의 없습니다. 보통은 4장 Deployment가 대신 만들어 줍니다. 이번 챕터에서 Pod를 직접 다루는 것은 K8s를 이해하는 토대를 마련하기 위해서입니다. 사람이 매니페스트로 적는 단위는 거의 항상 Deployment · StatefulSet · Job 같은 컨트롤러이고, Pod는 그 컨트롤러가 만들어 내는 산물입니다.

kubectl 명령 한 표 #

손에 붙여 둘 일상 명령을 한 표로 정리합니다. 본 책 전체에서 반복해서 만나는 모양입니다.

명령무엇을 하는가
kubectl get <res>리소스 목록을 봅니다. 예: kubectl get pods, kubectl get nodes
kubectl get <res> <name>특정 리소스 한 개의 요약을 봅니다
kubectl get <res> -o wide기본 컬럼 외에 IP · 노드 등 추가 정보까지 표시합니다
kubectl get <res> <name> -o yaml그 리소스의 전체 정의를 YAML로 출력합니다
kubectl describe <res> <name>그 리소스의 상세와 최근 이벤트 (Events)를 함께 출력합니다
kubectl logs <pod>Pod 컨테이너의 stdout / stderr를 봅니다
kubectl logs -f <pod>follow — tail -f처럼 동작합니다
kubectl exec -it <pod> -- <cmd>떠 있는 Pod 컨테이너 안에서 명령을 실행합니다
kubectl apply -f file.yaml매니페스트를 클러스터에 반영합니다 (선언형)
kubectl delete -f file.yaml같은 매니페스트로 만들어진 리소스를 삭제합니다
kubectl delete <res> <name>이름으로 리소스를 삭제합니다
kubectl run <name> --image=<img>Pod 한 개를 명령형으로 즉석 생성합니다

이 표에서 <res> 부분에는 pods, pod, po, deployments, deploy, services, svc 같은 이름이 들어갑니다. 자주 쓰이는 리소스마다 단축형이 있어 입력량이 빠르게 줄어듭니다.

명령형 vs 선언형 #

kubectl로 클러스터를 다루는 길은 두 가지 결이 있습니다.

  • 명령형 (imperative)kubectl run, kubectl create deployment처럼 “지금 이걸 만들어라"라고 직접 명령합니다. 빠르고 손이 가볍지만, 그 명령을 다시 재현하려면 명령어 그 자체가 어딘가에 적혀 있어야 합니다.
  • 선언형 (declarative) — YAML 매니페스트에 “이런 모양이어야 한다"를 적고 kubectl apply -f file.yaml을 호출합니다. 매니페스트 파일이 곧 클러스터 상태의 기록이라 Git에 올리기 쉽고, 같은 파일을 다시 apply만 하면 동일 상태가 나옵니다.

실무는 거의 전부가 선언형입니다. 클러스터 상태가 코드로 기록된다는 점이 결정적입니다. 본 책도 첫 한 번만 명령형으로 Pod를 띄워 보고, 곧장 매니페스트로 넘어갑니다. 이 모델은 20장 GitOps에서 ArgoCD / Flux로 한 번 더 본격적으로 다룹니다.

명령형으로 첫 Pod — kubectl run #

먼저 가장 짧은 길로 Pod 한 개를 올려 봅시다. 이미지는 어디서나 받을 수 있는 nginx:1.27을 씁니다.

명령형으로 Pod 한 개 띄우기
kubectl run hello --image=nginx:1.27 --port=80
출력 예시
pod/hello created

--port=80은 정보성 플래그입니다. 외부에서 이 포트로 들어오게 만드는 일은 5장 Service에서 다룹니다. 지금 단계에서는 “Pod 안의 nginx가 80번을 듣는다"라는 메모 정도로 봐 주세요.

만들어진 결과를 확인합니다.

Pod 목록
kubectl get pods
출력 예시
NAME    READY   STATUS    RESTARTS   AGE
hello   1/1     Running   0          12s

READY 1/1은 Pod 안의 컨테이너 1개 중 1개가 준비됐다는 뜻이고, STATUS Running 이면 우리가 기대한 모양입니다. 컬럼명을 한 줄로 짚어 두면 — NAME / READY / STATUS / RESTARTS / AGE입니다. 본 책 끝까지 자주 보게 됩니다.

조금 더 자세한 정보가 필요할 때는 -o wide를 붙입니다.

추가 컬럼까지
kubectl get pods -o wide
출력 예시
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE                 NOMINATED NODE   READINESS GATES
hello   1/1     Running   0          25s   10.244.0.5   kind-control-plane   <none>           <none>

IP는 Pod에 할당된 클러스터 내부 IP, NODE는 어느 worker node에 떠 있는지를 보여 줍니다. 단일 노드 kind 클러스터라 kind-control-plane 한 곳에만 모이지만, 멀티 노드 클러스터라면 여기서 어떤 Pod가 어디로 흩어졌는지가 보입니다. NOMINATED NODEREADINESS GATES는 보통 비어 있고, 고급 스케줄링 / 조건을 쓸 때 채워집니다.

describe — 그 안에서 무슨 일이 있었나 #

목록만으로는 Pod가 어떻게 거기까지 왔는지 모릅니다. describe가 그 빈틈을 채워 줍니다.

Pod 상세
kubectl describe pod hello
출력 예시 — 일부 발췌
Name:         hello
Namespace:    default
Priority:     0
Node:         kind-control-plane/172.18.0.2
Start Time:   ...
Labels:       run=hello
...
Containers:
  hello:
    Image:          nginx:1.27
    Port:           80/TCP
    State:          Running
      Started:      ...
    Ready:          True
    Restart Count:  0
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  30s   default-scheduler  Successfully assigned default/hello to kind-control-plane
  Normal  Pulling    29s   kubelet            Pulling image "nginx:1.27"
  Normal  Pulled     25s   kubelet            Successfully pulled image "nginx:1.27"
  Normal  Created    25s   kubelet            Created container hello
  Normal  Started    25s   kubelet            Started container hello

위쪽에는 Pod의 정의 (노드, 라벨, 컨테이너, 상태)가, 아래쪽에는 Events가 시간 순으로 적혀 있습니다. 이 Events 섹션이 K8s 디버깅의 1차 출발점이 됩니다 — ScheduledPullingPulledCreatedStarted. 1장에서 그림으로만 봤던 흐름이 그대로 적혀 있습니다. scheduler가 노드를 정하고, 그 노드의 kubelet이 이미지를 받아 컨테이너를 만들고 시작하는 순서입니다.

뭔가 잘못됐을 때도 답은 거의 항상 이 Events 안에 있습니다. 이미지 이름을 잘못 적었으면 Failed to pull image가, 컨테이너가 시작 직후 죽으면 Back-off restarting failed container가 여기 올라옵니다. 이 진단 흐름의 완성된 버전은 27장 kubectl 디버깅 패턴에서 다룹니다.

logs — Pod가 무슨 말을 하는가 #

Pod 컨테이너의 stdout / stderr는 kubectl logs로 봅니다.

로그 보기
kubectl logs hello
출력 예시 — 일부 발췌
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
...
/docker-entrypoint.sh: Configuration complete; ready for start up
... [notice] start worker processes

도커의 docker logs와 1:1 대응되는 명령입니다. 자주 쓰는 변형도 같습니다.

유용한 형태
kubectl logs -f hello             # follow
kubectl logs --tail=100 hello     # 마지막 100줄
kubectl logs --since=10m hello    # 최근 10분
kubectl logs --previous hello     # 이전에 죽은 컨테이너의 로그

마지막 --previous는 K8s에서만 만나는 옵션이라 익숙해질 필요가 있습니다. 컨테이너가 한 번 죽고 다시 시작했다면, 죽기 직전의 로그는 현재 컨테이너의 stdout이 아니라 이전 컨테이너 인스턴스의 출력입니다. 크래시 원인을 추적할 때 자주 씁니다.

exec — Pod 안으로 들어가기 #

도커의 docker exec에 대응되는 명령입니다.

Pod 컨테이너 안으로
kubectl exec -it hello -- bash

-it은 인터랙티브 + TTY, 그 뒤의 --여기서부터는 Pod 안에서 실행할 명령이라는 구분자입니다. --를 빠뜨리면 kubectl이 뒤의 옵션을 자기 것으로 해석해 버려서 자주 실수가 납니다.

들어가서 nginx의 설정을 한 번 확인하고 나옵니다.

컨테이너 안에서
root@hello:/# curl -s localhost:80 | head -5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
root@hello:/# exit

단발 명령만 실행하고 싶다면 -it 없이도 됩니다.

단발 명령
kubectl exec hello -- nginx -v
# nginx version: nginx/1.27.x

첫 정리 #

여기까지가 명령형 한 사이클입니다. 깔끔하게 치웁니다.

Pod 삭제
kubectl delete pod hello
출력 예시
pod "hello" deleted

kubectl get pods로 비어 있는 것까지 확인하면 출발점으로 돌아옵니다.

선언형으로 다시 — YAML 매니페스트 #

같은 Pod를 이번에는 매니페스트로 적어 봅시다. 거의 모든 K8s 매니페스트는 네 개의 최상위 필드로 시작합니다.

필드의미
apiVersion이 리소스를 정의하는 K8s API의 버전입니다. Pod는 안정 그룹의 v1이라 v1입니다
kind리소스의 종류입니다. 여기서는 Pod입니다
metadata이름 · 라벨 · 네임스페이스 같은 식별 정보입니다
spec“이 리소스가 어떻게 돼야 하는지” 본체입니다. 리소스 종류마다 모양이 다릅니다

이 네 필드의 모양은 Pod 이든 Deployment 든 Service 든 동일합니다. 익혀 두면 모든 매니페스트의 척추가 됩니다.

hello-pod.yaml 파일을 다음과 같이 적습니다.

hello-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hello
  labels:
    app: hello
spec:
  containers:
    - name: web
      image: nginx:1.27
      ports:
        - containerPort: 80

같은 디렉터리에서 apply를 부릅니다.

YAML 들여쓰기 한 칸이나 따옴표 한 짝이 어긋나면 kubectl apply가 의도와 다른 에러를 뱉어, 원인을 클러스터 단에서 거꾸로 짚어 가게 됩니다. 매니페스트를 적용하기 전에 utilrepo의 YAML 검증기에 한 번 붙여 넣으면 구문 에러를 줄·열 번호로 짚어 줍니다. utilrepo는 브라우저에서 동작하는 가벼운 웹 유틸리티 모음으로, 비밀 정보가 외부로 나가지 않고 ---로 묶인 다중 문서 매니페스트와 탭·스페이스 혼용 같은 자주 만나는 함정까지 함께 잡아 줍니다. 이 책의 모든 매니페스트 실습에서 같은 방식으로 활용하실 수 있습니다.
매니페스트로 Pod 만들기
kubectl apply -f hello-pod.yaml
출력 예시
pod/hello created

kubectl get pods로 결과가 같은지 확인합니다 — 나오는 모양은 kubectl run과 똑같습니다. 차이는 클러스터 바깥에 있습니다.

매니페스트의 장점 #

  • Git에 올라갑니다. 클러스터 상태가 코드로 기록되므로, “이 환경의 모양"을 PR로 리뷰하고 히스토리로 남길 수 있습니다.
  • 다시 apply만 하면 동일 상태가 나옵니다. 명령형은 머릿속이나 터미널 히스토리에 의존하지만, 매니페스트는 파일 그 자체가 기록입니다.
  • apply는 멱등 (idempotent)입니다. 이미 존재하면 차이만 반영하고, 없으면 만듭니다. 이 성질이 CI / CD와 잘 맞습니다.
  • 컨트롤러로 자연스럽게 확장됩니다. 같은 매니페스트의 kindDeployment로 바꾸면 4장으로 곧장 넘어갑니다.

K8s가 채워 주는 필드들 #

매니페스트에는 우리가 적은 것만 들어갔는데, 실제로 클러스터에 들어간 객체에는 더 많은 필드가 붙어 있습니다. 한 번 들여다봅시다.

실제 객체를 YAML로 다시 보기
kubectl get pod hello -o yaml | head -40
출력 예시 — 일부 발췌
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "..."
  labels:
    app: hello
  name: hello
  namespace: default
  resourceVersion: "..."
  uid: ...-...-...-...-...
spec:
  containers:
    - image: nginx:1.27
      imagePullPolicy: IfNotPresent
      name: web
      ports:
        - containerPort: 80
          protocol: TCP
      ...
  nodeName: kind-control-plane
  ...
status:
  conditions:
    - ...
  phase: Running
  podIP: 10.244.0.5
  ...

우리가 적은 부분 (이름 · 라벨 · 이미지 · 포트)은 그대로 살아 있고, 거기에 K8s가 다음 같은 필드들을 채워 넣었습니다.

  • metadata.uid, metadata.resourceVersion, metadata.creationTimestamp — 이 객체의 신원
  • spec.nodeName — scheduler가 정한 노드
  • spec.containers[].imagePullPolicy: IfNotPresent 같은 기본값
  • status 블록 전체 — Phase, Pod IP, 컨디션 등 현재 상태

1장에서 본 desired state vs actual state가 한 객체 안에 같이 들어가 있는 게 바로 이 모양입니다. spec이 desired, status가 actual입니다. 컨트롤러는 끊임없이 둘을 비교합니다.

Pod 라이프사이클 한 번 #

Pod는 Phase라는 개념을 갖습니다. kubectl get pod 출력의 STATUS 컬럼이 비치는 게 대체로 이 Phase입니다. 정확한 값은 다섯 개입니다.

Phase의미
Pending객체는 만들어졌지만 아직 컨테이너가 시작되지 않은 상태입니다. 이미지 다운로드 중이거나 노드 배정 대기 중일 수 있습니다
Running노드에 배정됐고, 컨테이너 중 적어도 하나가 실행 중입니다
Succeeded모든 컨테이너가 성공적으로 종료됐습니다 (exit 0). 다시 시작되지 않습니다
Failed모든 컨테이너가 종료됐고, 그중 적어도 하나가 비정상 종료된 상태입니다
Unknownapiserver가 노드와 통신이 끊겨 상태를 알 수 없는 상태입니다

웹 서버처럼 계속 떠 있어야 하는 Pod는 일생을 Running에서 보냅니다. 배치 작업처럼 한 번 돌고 끝나야 하는 Pod는 SucceededFailed로 들어갑니다.

kubectl describe의 Events 섹션에서 이 흐름을 한 번 더 짚어 봅시다 — ScheduledPullingPulledCreatedStarted. 위에서 본 출력 그대로의 순서입니다. 이 다섯 단어 어디에서 멈추느냐가 디버깅의 첫 갈래길이 됩니다.

흔한 실패 두 가지 #

처음에 가장 자주 만나는 실패는 두 가지입니다.

ImagePullBackOff / ErrImagePull — 이미지를 받지 못한 상태입니다. 이름 오타거나, 비공개 레지스트리 인증을 빼먹었거나, 그 태그가 정말 없을 수 있습니다. kubectl describe pod <name>의 Events에 Failed to pull image "..." 메시지와 그 아래에 사유가 적혀 있습니다. 거기서부터 시작하시면 됩니다.

CrashLoopBackOff — 컨테이너가 시작 직후 죽고, K8s가 다시 시작했고, 또 죽고를 반복하는 상태입니다. 1차 단서는 kubectl logs <pod>이고, 직전에 죽은 컨테이너의 로그가 필요하면 kubectl logs --previous <pod>를 씁니다. RESTARTS 컬럼이 빠르게 올라가는 모양으로도 보입니다.

이 두 패턴은 본 책 내내 반복해서 만납니다. 첫 단서가 describe의 Events이고 두 번째 단서가 logs라는 순서만 손에 두면 9할은 풀립니다. 진단 트리의 완성된 버전은 27장 kubectl 디버깅 패턴에서 정리합니다.

Pod 한 개로는 왜 부족한가 #

여기까지 따라왔다면 자연스럽게 한 가지가 걸리기 시작합니다 — 이 Pod는 죽으면 어떻게 되지? 시험 삼아 강제로 한 번 지워 봅시다.

Pod를 강제로 지우면
kubectl delete pod hello
출력 예시
pod "hello" deleted
다시 확인
kubectl get pods
출력 예시
No resources found in default namespace.

그냥 사라집니다. 자동으로 다시 뜨지 않습니다. K8s 입장에서 우리는 “이 Pod가 있어야 한다"라고 어디에도 적어 두지 않았기 때문입니다. apply로 한 번 만든 객체를 사람이 지웠으니, 그 사람의 의도라고 본 것입니다.

1장에서 본 reconcile loop가 일하려면 “이게 N개 떠 있어야 한다"라는 상위의 선언이 있어야 합니다. 그걸 들고 있는 것이 다음 챕터의 주인공인 Deployment입니다. Deployment가 ReplicaSet을 만들고, ReplicaSet이 “이 Pod 템플릿으로 N개 유지"라는 책임을 집니다. 그래서 같은 실험을 Deployment로 하면, Pod를 지운 직후 새 Pod가 자동으로 다시 뜹니다.

K8s 공식 문서가 Pod를 두고 종종 쓰는 표현이 mortal입니다 — 언젠가 죽는 존재라는 뜻입니다. 노드가 죽거나, 컨테이너가 OOM으로 죽거나, 누가 실수로 지우면 Pod는 그냥 사라지고, 새로 띄워주는 누구도 따로 없습니다. 자동 재시작 · 재배치는 K8s가 거저 주지 않습니다 — 컨트롤러를 통해 제공합니다.

그래서 처음 했던 한 줄이 다시 옵니다 — 운영에서 kind: Pod을 직접 쓰는 일은 거의 없습니다. 디버깅용 임시 Pod, Job이 만들어 내는 일회성 Pod, DaemonSet이 노드마다 띄우는 Pod 같은 특수 케이스를 빼면 우리가 적는 매니페스트는 거의 항상 컨트롤러입니다. 이번 챕터의 Pod는 그 컨트롤러들이 안에서 무엇을 만들어 내는지 보기 위한 토대입니다.

정리·치우기 #

오늘의 실험 흔적을 깨끗이 지웁니다. 매니페스트로 만든 리소스는 같은 매니페스트로 지우는 편이 가장 확실합니다.

매니페스트로 정리
kubectl delete -f hello-pod.yaml
출력 예시
pod "hello" deleted

이름으로 직접 지우는 길도 있습니다.

이름으로 정리
kubectl delete pod hello

마지막으로 default 네임스페이스가 비어 있는지만 확인해 둡니다.

비어 있나
kubectl get pods
출력 예시
No resources found in default namespace.

2장에서 본 kube-system의 시스템 Pod 들은 그대로 떠 있습니다. 그쪽은 클러스터가 자기 운영을 위해 들고 있는 Pod 라 우리가 만든 워크로드와는 결이 다릅니다. 둘이 섞이지 않게 네임스페이스로 갈라 두는 이야기는 7장 Namespace와 라벨에서 다룹니다.

연습문제 #

  1. 위 본문대로 kubectl run hello --image=nginx:1.27로 명령형으로 Pod를 띄운 뒤, kubectl get pod hello -o yaml 출력을 자신이 적었던 hello-pod.yaml과 비교해 보세요. K8s가 채워 넣은 필드 (예: metadata.uid, spec.nodeName, spec.containers[].imagePullPolicy, status 블록)를 5개 골라 표로 정리하고, 각각이 desired인지 actual인지 표시합니다.
  2. 이미지 이름을 일부러 잘못 적어 봅시다 (예: nginx:9.99-no-such-tag). 만들어진 Pod의 kubectl describe pod Events와 kubectl get podsSTATUS가 어떻게 변하는지를 시간 순서대로 기록해 보세요. ImagePullBackOffErrImagePull이 어떤 단계에서 등장하는지를 §“흔한 실패 두 가지"와 비교합니다.
  3. 매니페스트로 만든 hello-pod.yaml의 Pod를 kubectl delete pod hello로 지운 뒤 kubectl get pods가 비어 있음을 확인해 보세요. 그 다음 같은 파일로 kubectl apply -f hello-pod.yaml을 다시 실행해 동일 Pod가 돌아오는지를 확인합니다. “매니페스트는 멱등"이라는 §“매니페스트의 장점"의 의미를 한 단락으로 자신의 표현으로 정리합니다.

한 줄 요약: Pod는 K8s의 최소 실행 단위이고, 일상 명령은 get / describe / logs / exec / apply / delete 여섯이 사실상 전부다. 명령형 (kubectl run)은 빠르지만 재현이 어렵고, 선언형 (YAML + apply)은 클러스터 상태를 코드로 기록한다. Pod는 mortal이라 죽으면 그냥 사라지고, 그래서 다음 챕터의 Deployment 같은 컨트롤러가 필요하다.

다음 챕터 #

이번 챕터의 마지막에서 본 한 가지 — Pod를 지우면 그냥 사라진다 — 가 다음 챕터의 출발점이 됩니다. 사람이 일일이 지켜보지 않아도 “이 Pod가 N개 떠 있어야 한다"를 K8s가 끊임없이 유지해 주는 추상화가 필요합니다.

4장 Deployment와 ReplicaSet에서는 ReplicaSet이 어떻게 Pod의 개수를 보장하는지, Deployment가 그 위에서 무엇을 더 해 주는지 (롤링 업데이트, 롤백), 같은 nginx Pod를 Deployment 매니페스트로 다시 적어 replicas: 3으로 띄우고 한 개를 지웠을 때 어떻게 자동 복구되는지를 다룹니다. 이번 챕터의 Pod 한 개가 거기서 진짜 워크로드처럼 행동하기 시작합니다.

X