들어가며
쿠버네티스를 공부하다 보면 Pod랑 Deployment라는 말을 정말 많이 듣게 된다. Deployment는 Pod를 관리해주는, 흔히 말하는 컨트롤러이다. 만약 Deployment가 없다면 무슨 일이 일어날까?
어떤 파드가 노드 A에서 실행되고 있다고 가정해보자. 만약 노드 A에 장애가 발생한다면 해당 노에서 돌고 있던 파드도 정상적으로 동작하지 않는다. 이 경우 쿠버네티스는 정상적인 노드B로 해당 파드를 새로 띄워주지 못한다. 결국 고가용성은 보장되지 못하고 직접 다시 수동으로 파드를 띄워야한다.
결국 이때 필요한 것이 디플로이먼트이다. 디플로이먼트는 노드 A에 장애가 발생해 파드가 정상적으로 동작하지 못한다면 다른 노드에 해당 파드를 생성한다. 그래서 실제로 사람이 직접 파드를 실행하는 경우는 드물다고 한다. 결국 디플로이먼트에 내가 만들고자 하는 파드에 대해서 설명해준다면 직접 파드를 실행시키지 않아도 된다.
Deployment와 Pod의 느슨한 연결
이 부분을 이해하기 위해서 먼저 알아야 할 것이 있다. 파드의 이름은 계속 바뀐다. 그렇다면 디플로이먼트 생성된 파드를 어떠한 기준으로 관리할까? 앞서 말했듯이, 파드의 이름은 매번 변하기 때문에 파드의 이름으로 관리하기는 어렵다. 그래서 디플로이먼트는 라벨(label)을 기준으로 파드를 관리한다. 이름으로 서로를 구별하는 것이 아닌 고정된 라벨로 서로가 연결되어 있기에 둘은 느슨한 연결을 이루고 있다고 한다. 파드가 삭제되고 새로 생성되더라도, 동일한 라벨을 가지고 있다면 ReplicaSet은 이를 동일한 그룹으로 인식하고 원하는 개수를 유지하도록 관리한다.

Deployment 생성
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
replicas를 3으로 설정했기에 3개의 파드가 생성된다. 파드 이름은 아래와 같이 디플로이먼트 이름 뒤에 무작위 문자열이 붙는 형태로 생성된다.
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 73s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-6f9664446b-hhxcp 1/1 Running 0 98s
nginx-deployment-6f9664446b-whwcc 1/1 Running 0 98s
nginx-deployment-6f9664446b-xcgfz 1/1 Running 0 98s
-l 옵션을 사용하여 특정 라벨(app=nginx)을 가진 파드들만 조회할 수 있다. 결국 디플로이먼트는 라벨을 통해 자신이 관리하는 파드들을 식별한다.
$ kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-6f9664446b-hhxcp 1/1 Running 1 (21h ago) 22h
nginx-deployment-6f9664446b-whwcc 1/1 Running 1 (21h ago) 22h
nginx-deployment-6f9664446b-xcgfz 1/1 Running 1 (21h ago) 22h
파드의 라벨을 변경한다면?
위에서 말했듯이, 디플로이먼트는 자신이 관리해야 할 파드를 라벨을 가지고 식별한다. 그렇기에 만약 중간에 파드의 라벨이 바뀐다면 디플로이먼트는 더 이상 해당 파드를 관리 대상으로 인식할 수 없다.
3개 중에 1개의 파드의 라벨을 app=wrong으로 변경한다면 무슨 일이 일어날까?
app=nginx 라벨을 가진 파드의 개수가 2개로 줄어들었기 때문에, 디플로이먼트는 원하는 개수인 3개를 유지하기 위해 새로운 파드를 하나 생성한다.
# app=wrong으로 라벨 변경
$ kubectl label pod nginx-deployment-6f9664446b-hhxcp app=wrong --overwrite
pod/nginx-deployment-6f9664446b-hhxcp labeled
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-6f9664446b-9nsnh 1/1 Running 0 9s
nginx-deployment-6f9664446b-hhxcp 1/1 Running 1 (21h ago) 22h
nginx-deployment-6f9664446b-whwcc 1/1 Running 1 (21h ago) 22h
nginx-deployment-6f9664446b-xcgfz 1/1 Running 1 (21h ago) 22h

각 파드의 라벨을 확인해보면, 가장 최근에 생성된 파드가 app=nginx의 라벨을 가지고 있는 것을 확인할 수 있다.
$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-6f9664446b-9nsnh 1/1 Running 0 58s app=nginx,pod-template-hash=6f9664446b
nginx-deployment-6f9664446b-hhxcp 1/1 Running 1 (21h ago) 22h app=wrong,pod-template-hash=6f9664446b
nginx-deployment-6f9664446b-whwcc 1/1 Running 1 (21h ago) 22h app=nginx,pod-template-hash=6f9664446b
nginx-deployment-6f9664446b-xcgfz 1/1 Running 1 (21h ago) 22h app=nginx,pod-template-hash=6f9664446b
파드를 삭제한다면?
현재 실행 중인 3개의 파드를 아래 명령어로 모두 삭제해보았다. 삭제되었다는 메시지는 나오지만, 다시 조회해보면 새로운 파드가 생성되면서 여전히 3개가 유지되는 것을 볼 수 있다.
$ kubectl delete pods --all
pod "nginx-deployment-6f9664446b-9nsnh" deleted from default namespace
pod "nginx-deployment-6f9664446b-hhxcp" deleted from default namespace
pod "nginx-deployment-6f9664446b-whwcc" deleted from default namespace
pod "nginx-deployment-6f9664446b-xcgfz" deleted from default namespace
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-6f9664446b-7clqh 0/1 ContainerCreating 0 3s
nginx-deployment-6f9664446b-gqmjs 0/1 ContainerCreating 0 3s
nginx-deployment-6f9664446b-ztjkt 0/1 ContainerCreating 0 3s

현재 3개의 파드는 디플로이먼트에 의해 생성된 것이기 때문에, 파드를 완전히 삭제하려면 상위 객체인 디플로이먼트를 먼저 삭제해야 한다 디플로이먼트를 삭제하면 파드도 수동으로 삭제해주지 않아도 자동으로 삭제된다.
$ kubectl delete deploy nginx-deployment
deployment.apps "nginx-deployment" deleted from default namespace
$ kubectl get pods
No resources found in default namespace.
Pod와 Deployment는 이름이 아닌 라벨을 기반으로 서로 느슨하게 연결되어있고, 트래픽이 많아지는 큰 서비스에서는 Deployment와 같은 컨트롤러 덕분에 쿠버네티스의 자동화된 운영이 가능하지 않을까라는 생각이 든다.
'Kubernetes' 카테고리의 다른 글
| VMware Fusion에 k3s 멀티 노드 클러스터 구축하기 (0) | 2026.05.02 |
|---|---|
| 디플로이먼트(Deployment) 스케일링과 업데이트의 동작방식 (0) | 2026.04.05 |
| Kubernetes Service는 왜 필요할까? (0) | 2026.01.06 |
| Ansible을 이용해 Kubernetes Cluster 구축해보기 (0) | 2025.12.25 |
| EKS를 안전하게 운영하는 방법(feat. IAM 계정 분리와 Bastion 연동) (3) | 2025.12.21 |
