Computing

Pod (파드) 개념 (Pod vs. Container) 본문

Cloud/Kubernetes

Pod (파드) 개념 (Pod vs. Container)

jhson989 2022. 12. 5. 22:04

Pod 개념 

Pod(파드, 포드, 팟)는 쿠버네티스가 생성하고 관리하는 가장 작은 컴퓨팅 단위[1]이다. 파드는 한 개 이상의 리눅스 컨테이너로 구성되며, 애플리케이션(의 인스턴스)이 실행되는 논리적 호스트(컴퓨터)[2]라고 생각할 수도 있다. 파드는 물리 컴퓨터인 쿠버네티스 워커노드에 배치되어 실행되는데, 쿠버네티스의 목적이 바로 파드들을 안정적이고 효율적으로 클러스터 내에서 실행시키는 것이다.

 

애플리케이션은 하나의 프로세스(컨테이너, 파드)로 만들어질 수도 있지만, 여러 개의 프로세스(컨테이너)로 구성될 수도 있다. 특히 요즘은 마이크로서비스 아키텍처라고 해서, 대규모 애플리케이션을 작은 소규모 프로세스로 분리해서 개발하는 경우가 많아지고 있다. 블로그를 만들때도, 기본적으로 웹서버, DB, 웹 애플리케이션 분리해서 개발한다. 블로그 기능별로도 다른 프로세스로 구현할 수 있다. 이렇게 구현할 경우 블로그 글쓰기 기능에 버그가 발생하더라도 나머지 기능(읽기 등)은 정상 작동할 수 있다.

 

리눅스 컨테이너, 쿠버네티스가 대중화되기 이전에, 이러한 애플리케이션은 작은 프로세스(DB, 웹서버, 로거 등) 단위로 개발 및 운영되었다. 도커가 대중화되면서 개발자들은 리눅스 컨테이너 단위로 애플리케이션을 쪼개서 개발 및 운영하게 되었다. 쿠버네티스는 이들과 마찬가지로 파드 단위로 애플리케이션을 운영한다. 개발자는 애플리케이션을 이루는 파드(웹로직 파드들, DB 파드 등)들을 개발하고 이를 쿠버네티스에 이들 운영을 명령한다.

 

Fig 1. Kubernetes의 Pod 운영 [4]

 

Fig 1.은 쿠버네티스 내부에서 파드들이 어떻게 운영되는 지를 보여주는 그림이다. 쿠버네티스는 애플리케이션을 클러스터 내에 안정적이고 효율적으로 배포하는 소프트웨어이다. 쿠버네티스는 기본적으로 여러 대의 컴퓨터로 이루어진 클러스터(그림에서는 3대)를 타겟으로 하며, 이 클러스터 내에서 애플리케이션이 효율적으로 실행될 수 있도록 파드들을 클러스터에 분산 배치한다. 파드들은 쿠버네티스 노드(실제 컴퓨터, worker node)에 배치되어 그 노드에서 실행된다. (파드 한개는 하나의 노드에서 실행된다)

 

쿠버네티스는 자동으로 파드들을 운영(배포)한다. 개발자는 쿠버네티스에게 어떤 파드가 실행될지만(+추가적인 설정) 알려주면 된다. 그 정보를 바탕으로 쿠버네티스는 클러스 내에서 파드들을 운영한다. 예를 들면, 파드 3개를 실행시켜달라고 쿠버네티스에 명령하면, 쿠버네티스가 자동으로 파드 3개를 클러스터 내부에 배포한다. 파드에 버그가 발생하면 그 파드를 종료하고 새로운 파드를 재실행 시켜준다. 파드의 버전이 업그레이드가 되면 자연스럽게 예전 버전의 파드를 제거하고 새로운 버전의 파드가 실행될 수 있도록 해준다[5]. 이러한 파드 자동 배포 덕분에 개발자는 애플리케이션 운영에도 한결 자유로워 질 수 있다.

 

 

 

Pod와 Container

Fig 2.와 같이 파드는 한 개 이상의 리눅스 컨테이너로 구성된다. 앞서 말했듯 애플리케이션 종류에 따라서 한 애플리케이션이 여러 개의 컨테이너로 구성되게 개발하는 경우도 많다. 이때 이 컨테이너들을 하나의 파드에 묶어서 쿠버네티스에 실행을 명령할 수도 있고, 각각 다른 파드로 만들어 여러 개의 파드들을 쿠버네티스에 실행시켜달라고 명령할 수도 있다. 두 가지 방법 모두 사용되고 있는 개발 방식으로 각기 장단점이 존재하기에 자신의 애플리케이션에 어울리는 방식으로 개발하여야한다.

 

Fig 2. 파드와 컨테이너 관계

 

파드 내 컨테이너는 크게 3가지, 네트워크 네임스페이스, IPC 네임스페이스, 스토리지를 공유한다. Fig 2.와 같이 하나의 파드에는 기본적으로 하나의 private IP 주소가 부여된다. 파드 내 컨테이너들은 컨테이너가 속한 파드의 IP 주소를 이용해 접근할 수 있으며, 파드 내에 여러 컨테이너가 동시에 존재할 경우 이들간의 구별은 포트(port)를 통해서 이루어진다. IPC 네임스페이스를 공유하기에 같은 파드 내 컨테이너들끼리는 IPC 통신(shared memory, etc.)할 수도 있다. 또한 파드 내 컨테이너들에게만 공유되는 공유 스토리지를 지정할 수 있다.

 

일반적으로 애플리케이션의 개별 기능은 각각 파드로 따로 구현하는 것을 추천한다고 한다. 그래야 그 기능에 버그가 발생하더라도 다른 파드에 영향 없이 그 파드만 제거, 수정할 수 있게 된다. 각 파드(기능)들간의 통신은 파드의 private IP 주소를 통해서 이루어진다(REST API 등). (외부 사용자가 파드에 접근하기 위해서는 Service라는 쿠버네티스 리소스를 통해 접근하여야 한다.)

 

파드 내 여러 컨테이너가 함께 포함되는 경우는 한 기능을 여러 컨테이너로 구현하거나, 메인 기능이외에 부가적인 기능(debug를 위한 log 기능 등)을 같이 사용하는 경우이다. 파드 내 여러 컨테이너들을 동시에 사용할 경우 컨테이너는 위의 자원들을 공유하여 사용할 수 있기에 더욱 편리한 개발이 가능하다. 다만 파드 하나에 에러가 발생하면 그 파드 내 컨테이너들 모두 재시작되어야 한다거나, 컨테이너 이미지 수정이 필요한 경우에 파드 전체를 종료시키고 새로 만들어야 하기에 개발 과정이 복잡해지는 면도 존재한다.

 

참고로, 파드의 생명주기와 파드 내 컨테이너들의 생명주기가 같진 않다. 컨테이너 하나에 문제가 발생한다면 그 컨테이너만 재실행하면 되지 파드 자체를 재실행할 필요는 없다고 한다(Liveness probe 개념). 반대로 파드에 문제가 발생한다면 파드에 포함된 모든 컨테이너가 재실행된다.

 

 

 

Pod 실행

쿠버네티스에서 애플리케이션 실행을 위해 개발자가 해야할 역할은 크게 두 가지이다. 애플리케이션을 개발하는 것과 파드들을 어떻게 운영할 지를 쿠버네티스에게 구체적으로 알려주는 것.

 

개발자는 애플리케이션을 파드 단위로 개발하고 이를 쿠버네티스에 실행시켜달라고 요청한다. 이때 개발자는 쿠버네티스에 파드들을 어떻게 배포해야 하는지 구체적으로 알려줘야 한다. 쿠버네티스는 개발자의 실행 요청에 따라 클러스터 내에서 안정적이고 효율적으로 파드들을 스케쥴링(해당 파드를 어떤 워커 노드에서 실행 시킬 지 결정)한다. 클러스터의 개별 노드는 자신에게 할당된 파드들을 실행시킨다.

 

개발자는 선언적으로 쿠버네티스에 파드들이 어떻게 운영되야 하는 지 알려준다. 선언적이라는 말의 의미는 이 파드는 이렇게 운영되어야 한다고 개발자가 명시하는 방식이라는 것이다. 즉 개발자가 어떤 파일에 정보(yaml 파일, CPU는 이정도, 메모리는 이정도, 공유 스토리지는 어떻고 등등의 정보)들을 적어두면, 쿠버네티스가 그 파일을 읽어서 그 조건에 맞게 파드들을 실행시킨다.

 

apiVersion: v1
kind: Pod
metadata:
  name: name-pod
  labels:
    app: test
spec:
  containers:
    - name: myapp
      image: my.io/myapp:v1
      resources:
      	requests:
          memory: "512Mi"
          cpu: "500m"
      	limits:
          memory: "1024Mi"
          cpu: "1000m"
    - name: mydb
      image: mysql

 

위 코드는 파드를 생성하기 위한 정보 파일(yaml 파일)의 예시이다. 위 yaml 파일에 따라 쿠버네티스는 두 개의 컨테이너(my.io/myapp:v1, mysql)를 포함한 파드를 생성하며, myapp의 경우 CPU 500m(CPU 0.5개 사용. 1000m가 1개의 CPU 의미한다고 쉽게 생각해도 될 듯, 최대 1개), 메모리 512MB(최대 1024MB)를 할당한다. (mydb는 제한 없이 실행된다)

 

 

 

 

Reference

[1] https://kubernetes.io/ko/docs/concepts/workloads/pods/

[2] https://cloud.google.com/kubernetes-engine/docs/concepts/pod

[3] https://kubernetes.io/ko/docs/tutorials/kubernetes-basics/explore/explore-intro/

[4] https://www.suse.com/c/rancher_blog/understanding-the-kubernetes-node/

[5] https://kubernetes.io/docs/concepts/workloads/controllers/deployment/