컴퓨터과학/DevOps

[Kubernetes] Container, Pod, Deployment, Service, Node, Cluster

kykyky 2025. 5. 7. 17:45

 

 


container

✅사용 목적

Single Responsibility Principle에 따라 분리된 각각의 기능 (프로세스)를 격리된 환경에서 실행할 수 있음 

eg. "nginx", Database, 백엔드 각각이 container 하나씩 사용


pod 정의에 각 container 정의가 포함돼 있음. 예를 들어 nginx의 경우 그 내용은:

기반 OS: 보통 `debian`, `alpine`, `ubuntu` 중 하나.
nginx 바이너리: `/usr/sbin/nginx` 위치에 존재                                                   
nginx 설정 파일: `/etc/nginx/nginx.conf` 등                                                   
기본 static 콘텐츠: `/usr/share/nginx/html` 디렉터리 내
기타 라이브러리: glibc, openssl 등 nginx가 실행되기 위해 필요한 종속성들
Dockerfile 명령 기록: `ENTRYPOINT`, `CMD`, `ENV`, `EXPOSE`, `WORKDIR` 등 메타데이터 포함                  

 

container runtime 

: 컨테이너 빌드 & 실행

 

eg. Docker, containerd, ...


pod  

✅사용 목적

여러 container가 하나의 IP / localhost / 볼륨 등을 공유할 경우,

이들을 하나의 논리적 그룹 (= pod)으로 묶음 ☞ 하나의 Pod 안에서 병렬 실행

 

✅pod 생성 & 실행 

보통은 pod를 직접 보다는 deployment를 통해 생성 & 실행함

 

✅pod 조회

kubectl get pod

 

✅pod 내부 접속해 명령어 실행

kubectl exec -it <pod 이름> -- <명령어>


deployment

✅사용 목적

Pod의 (여러개도 가능)

- 생성

- auto-healing: pod가 삭제되더라도, 즉시 새 pod가 생성되어 pod 개수가 유지됨 

- scaling: kubectl scale deployment <deployment 이름> --replicas=<원하는 개수> ☞ pod 개수가 원하는 개수로 바뀌어 유지됨 

 

✅deployment 생성 & 실행 

my-deployment.yaml

apiVersion: apps/v1 # 사용하는 API 버전
kind: Deployment # 생성할 리소스 종류
metadata: # 메타데이터 (이름, 라벨 등)
name: my-deployment
spec: # 실제 동작 정의
replicas: 2 # 실행할 Pod 수
selector: # 어떤 Pod를 관리할지 지정
matchLabels: # 이 Deployment가 어떤 Pod를 "자기 소속"으로 여길지 정하는 기준. 아래 template.metadata.labels와 반드시 정확히 일치해야 합
app: my-app
template: # 생성할 Pod의 정의
metadata:
labels:
app: my-app
spec: # Pod 내부 스펙
containers:
- name: my-container
image: nginx:latest # Docker Hub에서 nginx:latest 이미지를 pull 받아 실행
ports:
- containerPort: 80

 

kubectl apply -f my-deployment.yaml

 

✅deployment 조회

kubectl get deployment


Service

이 글에선 NodePort 타입만 다룸

✅사용 목적

(service가 없을 경우) 궁극적인 목표 즉 cluster 외부 사용자가 이 어플리케이션을 사용하는 것이 불가능하다.

∵ 외부에서 node에 접근하는 트래픽은 보통 차단되어 있고, 또한 pod가 node에 포트 포워딩도 안되어있음.

service는 ☞ 외부에서 node ip에 접근할 수 있게 하고, 모든 node의 nodePort를 열어 외부 트래픽을 해당 pod의 targetPort에 전달해준다.

외부 사용자 → NodePort → Port → TargetPort

 

+ 여러 pod에 로드밸런싱까지 해줌

deployment에 의해 pod1~5가 생성되었고,
scheduler에 의해 pod1~3은 node1, pod4~5는 node2에 배치되었을 때
☞ service는 외부 사용자의 트래픽을 pod1~5에 랜덤으로 전달 

 

✅Service 생성 & 실행 

my-service.yaml

apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Cluster 내부에서 Service가 받는 포트
targetPort: 80 # Pod 안의 Container가 열고 있는 포트
nodePort: 30080 # Cluster 외부에서 접근 가능한 포트
type: NodePort

 

kubectl apply -f my-service.yaml

 

외부에서의 접근을 받기 위해서, minikube의 경우에는 아래 명령어가 필요하며, 다른 환경인 경우에도 추가적 조치가 필요하지만 이 글에선 다루지 않겠다.

minikube service my-service --url

☞ tunneling됨: localhost:임의포트 로 요청을 받아, cluster 내부에 있는 service 주소 (nodeIP:nodePort)에 전달함

 

- 외부 사용자: 위 url로 접속 가능  


node 

✅node = 서버 = 가상머신

각 node에는 Scheduler가 pod들을 적당히 배치해줌


cluster

✅의미: node의 집합

 

cluster 조회

kubectl config get-contexts