Cloud/클라우드 프로그래밍

[클라우드 프로그래밍] 11주차

승주우에요 2026. 6. 22. 19:55

파드와 컨테이너의 통신

파드는 하나 이상의 컨테이너가 공유하는 네트워크 및 파일 시스템을 제공하는 가상 환경이다. 파드에 속한 컨테이너는 모두 같은 노드에서 동작하며, 모든 컨테이너가 동일한 IP 주소(파드의 IP)를 갖는다. 같은 파드 내부의 컨테이너 간 통신에는 localhost 주소를 사용하며, 각 컨테이너는 서로 다른 포트를 주시해야 한다.

💡 시험 포인트: 멀티컨테이너 파드 내부 통신 주소는 localhost 또는 127.0.0.1이다. 외부 IP나 노드 IP가 아님에 주의.

spec:
  containers:
  - name: sleep
    image: kiamol/ch03-sleep
    volumeMounts:
    - name: data
      mountPath: /data-rw       # 읽기/쓰기로 마운트
  - name: file-reader
    image: kiamol/ch03-sleep
    volumeMounts:
    - name: data
      mountPath: /data-ro
      readOnly: true            # 읽기 전용으로 마운트
  volumes:
  - name: data
    emptyDir: {}                # 공유 볼륨

멀티컨테이너 파드에서 컨테이너 지정 로그 확인exec 명령 시에는 -c 컨테이너명 옵션을 사용해야 한다.

kubectl logs -l app=sleep -c server
kubectl exec deploy/sleep -c sleep -- cat /data-rw/hostname.txt

초기화 컨테이너 (Init Container)

초기화 컨테이너는 메인 애플리케이션 컨테이너가 실행되기 전에 먼저 실행되어 필요한 준비 환경을 조성하는 역할을 한다.

핵심 동작 규칙:

  • 파드 안에 여러 개를 정의할 수 있으며, 정의된 순서대로 하나씩 실행된다.
  • 각 초기화 컨테이너는 목표를 달성(성공 종료)해야 다음 컨테이너가 실행된다.
  • 초기화 컨테이너가 실패하면 애플리케이션 컨테이너는 시작되지 않는다.
  • 완료되면 프로세스가 완전히 종료되는 성격을 가진다.

⚠️ 자주 나오는 함정: "초기화 컨테이너가 실패해도 메인 컨테이너는 실행된다" → 틀림

spec:
  initContainers:
  - name: init-config
    image: kiamol/ch03-sleep
    command: ['sh', '-c', "cat /config-in/appsettings.json | jq ... > /config-out/appsettings.json"]
    volumeMounts:
    - name: config-map
      mountPath: /config-in
    - name: config-dir
      mountPath: /config-out
  containers:
  - name: app
    # ...

초기화 컨테이너 상태 확인:

kubectl get pod -l app=sleep -o jsonpath='{.items[0].status.initContainerStatuses[*].name}'
kubectl logs -l app=sleep -c init-html

어댑터 컨테이너 (Adapter Container)

사이드카 패턴의 일종으로, 메인 애플리케이션의 출력 형식이나 로그 포맷이 외부 시스템 규격과 다를 때 이를 단일한 표준 형태로 변환·표준화하는 역할을 수행하는 컨테이너 패턴이다.

예를 들어, 로그를 파일에만 기록하는 레거시 애플리케이션 옆에 logger 사이드카를 붙여 해당 파일을 tail -f로 읽어 표준 출력으로 내보내는 구조이다.

containers:
- name: timecheck
  volumeMounts:
  - name: logs-dir
    mountPath: /logs
- name: logger                    # 어댑터 사이드카
  image: kiamol/ch03-sleep
  command: ['sh', '-c', 'tail -f /logs-ro/timecheck.log']
  volumeMounts:
  - name: logs-dir
    mountPath: /logs-ro
    readOnly: true

💡 시험 포인트: 사이드카(Sidecar) / 어댑터(Adapter) / 앰배서더(Ambassador) 패턴의 차이를 구분할 것.


2차시: 스테이트풀셋 (StatefulSet)

스테이트풀셋의 특징

스테이트풀셋은 안정된 프레임워크에서 동작하는 애플리케이션에 스케일링 기능을 제공하는 파드 컨트롤러다. 데이터베이스처럼 주 인스턴스와 부 인스턴스가 구분되는 클러스터 애플리케이션에 적합하다.

디플로이먼트와의 핵심 차이점:

구분 디플로이먼트 스테이트풀셋

파드 이름 무작위 해시값 (pod-abc123) 규칙적인 순번 (pod-0, pod-1)
생성 순서 병렬(동시) 생성 순서대로 (0번이 Ready 후 1번 생성)
삭제 순서 임의 역순 (번호 큰 것부터 삭제)
스토리지 파드 간 공유 가능 파드마다 전용 PVC 자동 생성
DNS 개별 식별 불가 각 파드 고유 DNS 주소

⚠️ 자주 나오는 함정: "스테이트풀셋은 파드를 병렬로 생성한다" → 틀림. 0번이 Running이 된 후에야 1번 생성.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: todo-db
spec:
  selector:
    matchLabels:
      app: todo-db
  serviceName: todo-db          # 헤드리스 서비스 이름 (필수)
  replicas: 2
  template:
    # 파드 정의

헤드리스 서비스 (Headless Service)

스테이트풀셋은 반드시 헤드리스 서비스와 연결해야 한다. clusterIP: None으로 설정하면 IP가 부여되지 않고, 각 파드를 DNS로 직접 조회할 수 있다.

apiVersion: v1
kind: Service
metadata:
  name: todo-db
spec:
  selector:
    app: todo-db
  clusterIP: None              # 헤드리스: IP 주소 없음
  ports:
  # 포트 설정

파드 개별 DNS 형식: {파드명}.{서비스명}.{네임스페이스}.svc.cluster.local

  • 예: todo-db-0.todo-db.default.svc.cluster.local

volumeClaimTemplates

각 파드마다 독립된 전용 스토리지를 자동으로 생성하려면 volumeClaimTemplates 필드를 사용한다.

spec:
  # ...
  volumeClaimTemplates:          # 파드마다 PVC를 동적 생성
  - metadata:
      name: data
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 5Mi

💡 시험 포인트: volumeClaimTemplates는 스테이트풀셋 전용 필드다. 파드가 교체되어도 기존 PVC와 재연결된다.

kubectl get pvc
kubectl exec sleep-with-pvc-0 -- cat /data/pod.txt
# → 파드 교체 후에도 데이터 유지 확인

3차시: 롤아웃과 롤백을 이용한 애플리케이션 릴리스 관리

롤링 업데이트 vs 리크리에이트

디플로이먼트는 두 가지 업데이트 전략을 지원한다.

전략 설명 다운타임 롤링 업데이트 지원 리소스

RollingUpdate (기본) 파드를 점진적으로 교체 없음 Deployment, DaemonSet, StatefulSet
Recreate 기존 파드를 모두 종료 후 새 파드 생성 있음 Deployment만
spec:
  strategy:
    type: Recreate    # 또는 RollingUpdate (기본값)

⚠️ 자주 나오는 함정: "Recreate 전략은 무중단 배포를 제공한다" → 틀림. 다운타임 발생.


롤아웃 히스토리 및 롤백

# 롤아웃 히스토리 확인
kubectl rollout history deploy/vweb

# 현재 롤아웃 상태 확인
kubectl rollout status deploy/vweb

# 롤백 미리보기 (dry-run)
kubectl rollout undo deploy/vweb --dry-run

# 특정 리비전으로 롤백
kubectl rollout undo deploy/vweb --to-revision=2

# 이미지 직접 변경 (새 롤아웃 트리거)
kubectl set image deployment/vweb web=kiamol/ch09-vweb:v2

💡 시험 포인트: 디플로이먼트는 파드 정의에 변경이 있을 때만 롤아웃이 발생한다. 레플리카 수 변경만으로는 새 롤아웃이 일어나지 않는다.


롤링 업데이트 세부 설정

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1          # 의도한 파드 수보다 더 생성할 수 있는 최대 개수/비율
      maxUnavailable: 0    # 업데이트 중 사용 불가 상태가 될 수 있는 최대 개수/비율

⚠️ 자주 나오는 함정: maxSurge와 maxUnavailable은 동시에 0이 될 수 없다. 동시에 0이면 업데이트 자체가 불가능해진다.


📝 학습정리

  • 멀티컨테이너 파드 내 컨테이너 간 통신 → localhost
  • 초기화 컨테이너 → 순서대로 실행, 실패 시 메인 컨테이너 미실행
  • 어댑터 컨테이너 → 로그/출력 형식 표준화 역할의 사이드카
  • 스테이트풀셋 → 규칙적 파드 이름, 순서 생성/역순 삭제, volumeClaimTemplates
  • 헤드리스 서비스 → clusterIP: None, 스테이트풀셋의 필수 연결 서비스
  • 롤링 업데이트 → 무중단, Recreate → 다운타임 발생
  • maxSurge와 maxUnavailable 동시에 0 불가

🔑 핵심 키워드 정리

키워드 설명

localhost 멀티컨테이너 파드 내 컨테이너 간 통신 주소
initContainers YAML에서 초기화 컨테이너를 정의하는 필드
어댑터 컨테이너 출력 형식을 표준화하는 사이드카 패턴
StatefulSet 상태 있는 애플리케이션용 파드 컨트롤러
clusterIP: None 헤드리스 서비스 설정 (IP 미부여)
volumeClaimTemplates 스테이트풀셋에서 파드별 PVC 자동 생성 필드
RollingUpdate 무중단 점진적 교체 전략 (기본값)
Recreate 전체 삭제 후 재생성 전략 (다운타임 있음)
kubectl rollout undo 롤백 명령
maxSurge / maxUnavailable 롤링 업데이트 세부 조절 옵션