/ KUBERNETES

Pod와 Container

Container와 Pod의 기본개념을 확인해봅니다.

Container란 무엇인가?

컨테이너는 소프트웨어 서비스를 실행하는 데 필요한 특정 버전의 프로그래밍 언어 런타임 및 라이브러리와 같은 종속 항목과 애플리케이션 코드를 함께 포함하는 경량 패키지입니다.

컨테이너는 운영체제 수준에서 CPU, 메모리, 스토리지, 네트워크 리소스를 쉽게 공유할 수 있게 해주며 컨테이너가 실제로 실행되는 환경에서 애플리케이션을 추상화할 수 있는 논리 패키징 메커니즘을 제공합니다.

구글 클라우드는 컨테이너에 대해 위와 같이 설명합니다. 짧은 두 문장이지만, 컨테이너는 결국 경량 패지키, 논리 패키징 메커니즘라는 것 같습니다. 구체적으로 어떤 뜻일까요? 컨테이너를 활용하게되면, 개발자는 제공되는 컨테이너에서 애플리케이션을 개발하고, 배포합니다. 컨테이너에는 개발자에게 프로그래밍 언어, 런타임, 라이브러리와 같은 개발 환경이 이미 셋팅(경량 패키지)되어있습니다. 따라서 개발자는 이러한 개발 환경 셋팅과 디버깅 과정을 생략하고 애플리케이션 자체에 집중할 수 있습니다. 따라서 컨테이너에 대한 위 설명은 ‘개발과 배포를 하기 위해 필요한 모든 것을 준비해 놓았다!’ 정도로 이해할 수 있을 것 같습니다.

Conatiner가 개발자에게 주는 장점

대부분의 개발 프로세스가 오픈 소스 기반으로 이루어지고 있는 지금의 개발 환경에서, 이러한 컨테이너 기반의 개발은 매우 혁명적이었습니다. 컨테이너 기반의 개발 작업이 오픈 소스 기반 개발의 단점을 보완해줄 수 있었기 때문입니다.

오픈 소스를 기반으로 하는 애플리케이션 개발은 개발자가 직접 작성해야하는 코드의 양을 줄여 개발 생산성을 늘려주었습니다. 덕분에 개발자는 단기간에 높은 수준의 애플리케이션을 만들어낼 수 있었습니다. 그러나 오픈 소스를 기반 개발은 버전 관리라는 맹점이 존재합니다. 사용하는 오픈 소스 라이브러리의 버전업이 개발한 애플리케이션에 어떤 영향을 줄 지 예상이 불가능했고, 이는 다양한 버그와 호환성 문제를 야기했습니다. 즉 개발 생산성을 높이는 대신 애플리케이션의 안정성이 떨어지는 트레이드 오프가 발생했습니다.

컨테이너는 오픈소스 기반 애플리케이션 개발의 불안정성을 보완해주었습니다. 같은 컨테이너 내에서는 제공되는 언어, 런타임, 라이브러리, 종속 항목들이 고정되어 있으므로 애플리케이션 빌드나 배포 시에 오픈 소스 라이브러리의 버전업이나 수정, 패치에 영향받지 않습니다.

또한 컨테이너가 제공되고, 실행만 가능하다면 개인 노트북을 포함한 어떤 환경에서도 동일한 개발환경을 유지한 채 개발작업을 수행할 수 있습니다.

이외에도 컨테이너는 개발자와 인프라 운영팀의 책임을 분명히 구분해주는 책임 분리(Separation of responsibility), 실해되는 다른 애플리케이션으로부터 영향을 받지 않는 애플리케이션 격리라는 장점을 갖습니다.

Pod란 무엇인가?

파드(Pod) 는 쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위이다.
파드 (고래 떼(pod of whales)나 콩꼬투리(pea pod)와 마찬가지로)는 하나 이상의 컨테이너의 그룹이다. 이 그룹은 스토리지 및 네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다. 파드의 콘텐츠는 항상 함께 배치되고, 함께 스케줄되며, 공유 콘텍스트에서 실행된다. 파드는 애플리케이션 별 “논리 호스트”를 모델링한다. 여기에는 상대적으로 밀접하게 결합된 하나 이상의 애플리케이션 컨테이너가 포함된다. 클라우드가 아닌 콘텍스트에서, 동일한 물리 또는 가상 머신에서 실행되는 애플리케이션은 동일한 논리 호스트에서 실행되는 클라우드 애플리케이션과 비슷하다.

애플리케이션 컨테이너와 마찬가지로, 파드에는 파드 시작 중에 실행되는 초기화 컨테이너가 포함될 수 있다. 클러스터가 제공하는 경우, 디버깅을 위해 임시 컨테이너를 삽입할 수도 있다.

Kubernetes 공식문서에서는 Pod를 위와 같이 설명합니다. 요약해보자면, Pod를 아래와 같은 특징으로 요약될 수 있습니다.

  1. 파드는 쿠버네티스에서 생성/관리 가능한 가장 작은 컴퓨팅 단위이다
  2. 파드의 콘텐츠는 함께 배치, 스케줄, (공유 콘텍스트에서)실행된다
  3. 파드는 애플리케이션 별로 논리 호스트를 모델링한다
  4. 파드에는 초기화 컨테이너, 임시 컨테이너를 삽입할 수 있다

각 항목에 대해서 자세히 살펴보겠습니다.

가장 작은 컴퓨팅 단위

실제로 애플리케이션이 실행되는 것은 파드 내에 존재하는 컨테이너(Container)이지만, 쿠버네티스는 직접 컨테이너를 실행하지 않고, 파드를 실행합니다. 쿠버네티스에 의해 실행된 파드가 파드 내의 컨테이너를 관리합니다. 즉, 쿠버네티스 자체는 컨테이너에 직접적으로 관여하지 않습니다. 대신 컨트롤러(controller)를 이용하여 파드를 관리합니다.
한편, 파드는 LivenessProbe, ReadienessProbe를 설정하여 파드 내부의 컨테이너에서 실행되는 애플리케이션의 상태를 모니터링합니다.

파드의 콘텐츠는 배치, 스케줄, 콘텍스트를 공유

동일 파드 내에서 실행되는 컨테이너들은 모두 같은 노드에서 실행되며, 동일 파드에 의해 관리되는 여러 컨테이너들은 동일한 리소스 및 로컬 네트워크를 공유합니다. 따라서 파드 내 컨테이너들은 분리되어 실행되더라도 통신과 리소스 공유가 가능합니다. 공유 컨텍스트(shared context)란 동일 파드 내 컨테이너 간에는 System V 프로세스 통신이나 POSIX 공유 메모리를 사용하여 통신이 가능하고, 볼륨 마운트(Volume Mount)를 통하여 파일 시스템을 공유할 수 있음을 의미하는 것으로 보입니다.

애플리케이션 별로 논리 호스트를 모델링

추상적인 단어가 많아 이해하기가 어려운 개념이었습니다. 일단 원문을 다시 읽어보았습니다.

A Pod models an application-specific “logical host”: it contains one or more application containers which are relatively tightly coupled.

쿠버네티스 문서에서 제공하는 번역이 원문의 의미를 전달하지 못하고 있는 것 같습니다. 몇 가지 단어를 중심으로 의미를 풀어보고자 합니다.

  • aplication-specific이란 특정 어플리케이션을 위해서 작성되었다는 의미입니다(application-specific). 애플리케이션 별로로 번역되어 그 의미가 정확히 전달되지 못한 것 같습니다.
  • 논리 호스트로 번역된 logical host는 어플리케이션을 실행을 위해 필요로 하는 소프트웨어와 컴포넌트를 갖추고 있는 환경 자체를 의미합니다.

위의 두 가지 의미를 합쳐보면, Pod는 어플리케이션을 위해 작성된, 어플리케이션을 실행할 수 있는 환경 그 자체라고 해석할 수 있습니다. 나아가, Pod는 한 가지 어플리케이션만 실행하는 것이 아니라, 서로 관련 있는 여러 개의 어플리케이션을 포함할 수 있습니다.

초기화 컨테이너, 임시 컨테이너

Pod에는 초기화만을 담당하는 컨테이너를 설정할 수 있습니다. 이를 초기화 컨테이너(initContainer)라고 부르며 해당 컨테이너는 Pod 시작 후에 가장 먼저 시작되어 초기화 작업을 수행하고 이후 메인 컨테이너들이 실행됩니다. 이외에도 디버깅을 위해 임시 컨테이너(Ephemeral Container)를 설정할 수도 있습니다.

위의 4가지 특징 이외에도 Pod는 아래 특징을 가지고 있습니다.

Pod는 일시적인 존재

Pod는 일시적인 존재로 설계되어 Pod 내의 컨테이너는 이미지로부터 매번 생성되빈다. 따라서 같은 오브젝트 이름으로 재기동하여도, 이전 컨테이너의 실행기록(로그), 변경 사항은 남지 않고 초기 이미지 상태에서부터 재실행됩니다.
또한 Pod의 IP도 고정적이지 않습니다. Pod의 IP는 생성과 함께 부여된 뒤, 종료 시에 회수됩니다. 재시작하더라도 같은 IP를 부여하지 않습니다. 따라서 Pod에게 요청(request)를 보내고자 하는 경우에는 반드시 service를 이용하여 고정 IP를 제공해야합니다.

Controller

이러한 Pod는 워크로드 리소스(컨트롤러)에 의해 생성되고 관리됩니다. 컨트롤러는 파드 장애 시 복제 및 롤아웃과 자동복구를 처리합니다. 어떤 노드에서 장애가 발생했을 때, 컨트롤러는 장애 노드에서 실행되는 Pod들의 작동 중지를 인식하고, 다른 노드에서 대체 Pod를 생성하는 식으로 대응합니다. 이러한 컨트롤러에는 7가지가 있습니다.

  • Deployment 디플로이먼트
  • ReplicaSet 레플리카셋
  • StatefultSet 스테이트풀셋
  • DaemonSet 데몬셋
  • Job 잡
  • CronJob 크론잡
  • ReplicationController 레플리케이션 컨트롤러

Deployment의 템플릿 예시는 아래와 같습니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  # 여기서부터 파드 템플릿이다
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
   # 여기까지 파드 템플릿이다

간단하게 컨테이너와 파드의 개념에 대해 정리해보았고, 파드를 관리하는 컨트롤러가 무엇이 있는지까지만 알아보았습니다.
읽어주셔서 감사합니다 (_ _)

[참고]
GCP 컨테이너란?
Kubernetes 파드
RedHat 쿠버네티스 포드(Kubernetes pod)란?
15단계로 배우는 도커와 쿠버네티스