2. 파드와 멀티 컨테이너

MAYFIFTH·2025년 6월 4일

K8S

목록 보기
2/10
post-thumbnail

파드(Pod)

애플리케이션 실행 단위를 구성하는 가장 작은 배포 객체 단위

  • 한 개 이상의 컨테이너, 저장소, 네트워크(IP 주소)의 묶음
    • 컨테이너가 안정적으로 통신하고 자원을 사용할 수 있도록 공유 환경 제공
    • 실행되어야 할 형태에 따라 initContainer, SideCar와 같은 특수한 패턴의 컨테이너도 함께 실행 가능
  • 파드는 장애 복구, 스케줄링, 사용자 요청 등에 의해 유동적으로 삭제, 재생성 된다.
  • 파드 배포 예시
  • nginx 컨테이너를 실행하는 파드 선언과 배포 후 정상 실행 확인

  • simple-pod.yaml

apiVersion: v1
kind: Pod
metadata:
	name: simple-pod
spec:
	containers:
	- name: nginx
		imgae: nginx:latest
kubectl apply -f simple-pod.yaml # 적용

kubectl get pods # 확인

Pod 라이프 사이클

파드는 애플리케이션의 생성부터 종료까지 여러 상태를 가진다.

  • 이러한 파드의 상태장애 진단운영 최적화에 필수적인 정보를 제공
  • 컨테이너의 준비 상태, 실행 여부, 종료 결과에 따라 파드의 상태를 대표하는 속성을 가짐
    • Pending, Running, Successed, Failed, Unknown

  1. Pending : 컨테이너 시작 전 대기 상태
  2. Running : 최소 1개 이상의 컨테이너가 정의되고 실행되고 있는 상태
  3. Successed : 모든 컨테이너가 정상적으로 종료된 상태
  4. Failed : 하나 이상의 컨테이너가 비정상적으로 종료된 상태
  5. Unknown : API Server가 응답하지 않는 상태

파드의 대표적인 상태 외에도 실행 과정, 컨테이너 상태에 따른 다른 속성도 존재한다.

  • 파드가 생성/실행되는 단계에서는 Condition 속성을 통해 단계와 상태를 알 수 있다.
  • 파드 내 컨테이너들은 State, Reason 속성 값을 통해 각 컨테이너들의 대표적 상태를 제공


파드 생성 과정

  • kubectl을 통한 파드 생성 요청 선언부터 스케줄러, API Server를 통한 가용 노드 탐색 후 배포
  • kubectl → API Server → Scheduler → API Server → kubelet

kubectl 을 이용해 파드가 배포되는 과정을 자세히 보자.

  1. kubectl apply 명령어를 실행해 쿠버네티스 클러스터에 리소스를 생성하라는 요청을 보낸다.
    • mydeployment.yaml 파일은 deployment 리소스를 정의한 manifest 파일
  2. API Server(쿠버네티스 API 서버)가 사용자가 보낸 요청을 처리
    • Deployment 리소스의 상태를 etcd에 기록(저장)
    • 기록되는 데이터에는 파드를 생성할 때 필요한 모든 정보가 포함
  3. API Server → Scheduler 에게 파드를 실행할 노드를 찾아달라고 요청
    • 스케줄러는 사용 가능한 노드들 중 적절한 노드를 선택
  4. 스케줄러가 Pod를 실행할 노드를 결정하면 API Server가 이를 다시 etcd에 기록
  5. Kubelet 은 주기적으로 API Server를 확인해 생성해야 되는 Pod 에 대한 정보를 체크
    • API 서버에서 Pod가 생성될 노드를 할당한 후, kubelet은 해당 노드에서 Pod를 실제로 실행

멀티 컨테이너 구조

메인 컨테이너와 네트워크, 스토리지를 통한 밀접한 공유가 필요한 다른 컨테이너를 운용해야할 때 멀티 컨테이너 구조를 사용한다.

  • 대표적인 파드 디자인 패턴들을 통해 구성(사이드 카, 어댑터, 앰배서더, InitContainer)

SideCar 컨테이너

  • 기존 파드의 기능을 향상시키기 위해 파드의 파일 시스템을 공유하는 형태의 보조 컨테이너
  • 해당 특성을 활용해 메인 컨테이너 대신
    • 로그 수집, 데이터 동기화, 네트워크 처리 등 역할 수행
    • 서비스 메시 아키텍처에서 네트워크 트래픽 처리 및 데이터 암호화 등의 보조 기능을 수행

  • 사이드카 컨테이너 예시
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-sidecar
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - name: logs
              mountPath: /var/log/nginx
        - name: sidecar-access
          image: busybox
          args: [/bin/sh, -c, 'tail -n+1 -f /var/log/nginx/access.log']
          volumeMounts:
            - name: logs
              mountPath: /var/log/nginx
      volumes:
        - name: logs
          emptyDir: {}
    

어댑터 컨테이너

  • 파드에 탑재된 특정 애플리케이션의 출력 규격 등을 조정하는 용도로 사용
  • 메인 컨테이너를 수정하지 않고 출력 호환성을 제공
  • (e.g Prometheus exporter, gPRC to REST 어댑터)

  • 어댑터 컨테이너 예시
    apiVersion: v1
    kind: Pod
    metadata:
      name: adapter-container-demo
    spec:
      containers:
        - name: main-container
          image: busybox
          command: ["/bin/sh"]
          args: ["-c", "while true; do echo $(date -u)'# Log' >> /var/log/file.log; sleep 5;done"]
          resources: {}
          volumeMounts:
            - name: var-logs
              mountPath: /var/log
        - name: adapter-container
          image: bbachin1/adapter-node-server
          imagePullPolicy: Always
          resources: {}
          ports:
            - containerPort: 3080
          volumeMounts:
            - name: var-logs
              mountPath: /var/log
      dnsPolicy: Default
      volumes:
        - name: var-logs
          emptyDir: {}

앰버서더 컨테이너

  • 파드 외부의 서비스에 대한 액세스를 간소화 하기 위한 유형의 컨테이너
  • 메인 컨테이너가 수행해야 할 네트워크 통신을 앰버서더 컨테이너가 대신 수행
    • 해당 특성을 활용하여 메인 컨테이너의 네트워크 프록시 역할로 사용
  • (e.g Redis Ambassador : Redis 클라이언트가 localhost:6379 에 접속하지만, 실제로는 외부 Redis 서버에 연결을 프록시함)

  • 앰버서더 컨테이너 예시
    apiVersion: v1
    kind: Pod
    metadata:
      name: ambassador-example
    spec:
      containers:
        - name: redis-client
          image: redis
        - name: ambassador
          image: malexer/twemproxy
          env:
            - name: REDIS_SERVERS
              value: redis-st-0.redis-svc.default.svc.cluster.local:6379:1 redis-st-1.redis-svc.default.svc.cluster.local:6379:1
          ports:
            - containerPort: 6380
    

초기화 컨테이너

  • 파드의 메인 컨테이너 실행 전 초기화 역할을 담당하는 컨테이너
  • 의도된 작업이 끝나면 메인 컨테이너가 실행되기 전 반드시 종료되어야 함
  • 초기화 컨테이너의 구동이 실패하면 kubelet이 구동에 성공할 때 까지 지속적으로 재시작
    • 이러한 특성을 활용해 애플리케이션에 의존성을 가진 파드를 배포할 때 사전 체크 용도로 활용

  • 초기화 컨테이너 예시
    apiVersion: v1
    kind: Pod
    metadata:
      name: myapp-pod
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp-container
          image: busybox:1.28
          command: ['sh', '-c', 'echo The app is running! && sleep 3600']
      initContainers:
        - name: init-myservice
          image: busybox:1.28
          command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
        - name: init-mydb
          image: busybox:1.28
          command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
    
profile
HARVEY

0개의 댓글