Post

[Kubernetes] 파드 생성 및 관리

📌 들어가며

이번 글에서는 쿠버네티스의 기본 실행 단위인 파드(Pod)를 정리한다. 생성 방법(선언형·명령형), 라이프사이클, 멀티 컨테이너 설계 패턴(사이드카·init), Label/Selector, 노드 스케줄링, Probe까지 파드의 핵심을 훑는다.

Pod란? 쿠버네티스에서 애플리케이션이 실행되는 가장 작은 단위. 하나 이상의 컨테이너를 묶으며, 그 컨테이너들은 같은 네트워크 네임스페이스와 단일 IP를 공유한다.


1. 파드 생성 — 선언형 vs 명령형

방식특징
선언형(Declarative)YAML로 정의 → kubectl apply (권장, 재현 가능)
명령형(Imperative)kubectl run으로 즉시 생성 (빠른 테스트)
1
2
3
4
5
6
7
8
9
10
11
12
13
# 선언형 — myweb1-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myweb1
  labels:
    app: myweb1
spec:
  containers:
  - name: nginx-container
    image: nginx:1.25.3-alpine
    ports:
    - containerPort: 80
1
2
3
kubectl apply -f myweb1-pod.yaml          # 선언형
kubectl run myweb2 --image=nginx:1.25.3-alpine --port=80   # 명령형
kubectl get po -o wide | grep myweb1      # 확인

💡 실무는 선언형이 원칙이다. YAML로 관리하면 Git으로 버전 관리·리뷰가 되고, 같은 파일로 언제든 동일하게 재현할 수 있다. 명령형은 빠른 테스트·학습용으로만 쓴다.


2. 파드 라이프사이클

flowchart LR
    Pending["Pending<br/>(할당됨, 미실행)"]
    Running["Running<br/>(실행 중)"]
    Succeeded["Succeeded<br/>(정상 완료)"]
    Failed["Failed<br/>(실패)"]
    Pending --> Running
    Running --> Succeeded
    Running --> Failed
상태의미
Pending클러스터에 할당됐지만 아직 실행 전
Running정상 실행 중
Succeeded작업 완료(주로 Job)
Failed컨테이너 실패
1
2
kubectl get po -o wide          # 상태 확인
kubectl describe pod mypod      # 문제 원인(이벤트) 진단

3. 멀티 컨테이너 패턴 — Sidecar & Init

한 파드에 여러 컨테이너를 두어 역할을 나눈다.

Sidecar — 보조 컨테이너 (함께 실행)

로깅·모니터링 등 보조 작업을 담당한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata:
  name: log-pod
spec:
  containers:
  - name: app-container
    image: nginx:1.25.3
    volumeMounts:
    - name: html-log
      mountPath: /usr/share/nginx/html
  - name: sidecar-container
    image: debian:10
    volumeMounts:
    - name: html-log
      mountPath: /date-log
    command: ["/bin/sh", "-c"]
    args:
    - while true; do date >> /date-log/index.html; sleep 1; done
  volumes:
  - name: html-log
    emptyDir: {}

Init — 초기화 컨테이너 (먼저 실행)

메인 컨테이너 실행 전에 초기화(설정 다운로드 등)를 마친다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: Pod
metadata:
  name: weather-pod
spec:
  volumes:
  - name: weather-data
    emptyDir: {}
  initContainers:
  - name: download-config
    image: curlimages/curl:7.85.0
    args: ["https://api.open-meteo.com/v1/forecast?...", "-o", "/usr/share/nginx/html/index.html"]
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: weather-data
  containers:
  - name: nginx-container
    image: nginx:1.25.3-alpine
    ports:
    - containerPort: 80
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: weather-data

💡 Sidecar는 “함께”, Init은 “먼저”다. Init 컨테이너는 완료되어야 메인 컨테이너가 시작되고(순차), Sidecar는 메인과 나란히 계속 실행된다(병렬). 초기 데이터 준비는 Init, 상시 보조 작업은 Sidecar다.


4. Label & Selector

Label로 리소스를 그룹화하고, Selector로 필터링한다. 서비스가 파드를 찾는 것도 이 라벨 매칭이다.

1
2
3
4
5
metadata:
  name: label-pod
  labels:
    app: myapp
    tier: backend
1
kubectl get po --selector=app=myapp

5. 노드 스케줄링 & Probe

nodeSelector — 특정 노드 지정

1
2
3
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1

Probe — 컨테이너 상태 검사

1
2
3
4
5
6
readinessProbe:
  httpGet:
    path: /testpath
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10
Probe판단실패 시
Readiness트래픽 받을 준비됐나?서비스에서 제외
Liveness살아 있나?컨테이너 재시작

💡 Readiness와 Liveness는 목적이 다르다. Readiness 실패는 “아직 준비 안 됨”이라 트래픽만 끊고 기다리지만, Liveness 실패는 “죽었음”이라 컨테이너를 재시작한다. 둘을 혼동하면 정상 파드를 계속 재시작하는 문제가 생긴다.


📝 정리

1
2
3
4
5
6
Pod
├─ 생성   선언형(YAML·권장) vs 명령형(run)
├─ 수명   Pending→Running→Succeeded/Failed
├─ 패턴   Sidecar(함께) / Init(먼저)
├─ 그룹화 Label + Selector
└─ 스케줄 nodeSelector / Probe(Readiness·Liveness)
개념한 줄 정의
Pod최소 실행 단위(컨테이너 묶음)
Init/Sidecar먼저 / 함께 실행 컨테이너
Readiness/Liveness준비 / 생존 검사

파드의 핵심은 컨테이너를 묶는 최소 단위라는 점, 그리고 Label로 묶고 Probe로 상태를 관리한다는 점이다. 실무에서는 파드를 직접 만들기보다 Deployment 등으로 감싸 쓰지만, 그 안의 파드 설계 원리는 이 글의 내용이 그대로 적용된다.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.