사전 파드
개념

파드

gabury1

파드는 컨테이너 하나 이상을 한 묶음으로 다루는 단위입니다. 묶인 컨테이너들은 언제나 같은 자리에 함께 놓입니다. 저장소와 네트워크도 나눠 씁니다. 쿠버네티스가 만들고 관리하는 가장 작은 배포 단위가 이 묶음입니다.

상세

사무실 한 칸에 여럿이 같이 들어앉아 일합니다. 전화기도 가운데 책장도 그 방에 하나씩입니다. 누가 잠깐 나갔다 와도 방은 그대로 있습니다.

파드는 컨테이너 목록만 들고 있는 것이 아닙니다. 그 컨테이너들을 어떻게 돌릴지 적은 명세도 함께 들고 있습니다. 그래서 파드의 내용물은 언제나 한자리에 놓이고 함께 스케줄됩니다. 쿠버네티스 문서는 이 내용물이 하나의 공유 컨텍스트 안에서 돈다고 적습니다. 파드를 애플리케이션 전용 논리 호스트로 모형화한 것이라고도 적습니다. 안에 들어가는 것은 비교적 단단히 묶인 애플리케이션 컨테이너 하나 이상입니다. 클라우드가 아닌 자리에서 같은 물리 머신이나 가상 머신 위에서 도는 프로그램들에 견줄 수 있습니다.

공유 컨텍스트의 정체는 리눅스 네임스페이스와 cgroup(control group) 묶음입니다. 격리의 다른 측면들도 여기 들어갈 수 있습니다. 컨테이너 하나를 격리할 때 쓰는 것과 같은 장치입니다. 파드의 컨텍스트 안에서 각 애플리케이션에 더 좁은 격리가 걸릴 수도 있습니다.

flowchart TD
    N["노드"] --> P["파드 · 주소 하나"]
    P --> C1["컨테이너 A"]
    P --> C2["컨테이너 B"]
    P --> V["공유 볼륨"]
    C1 -.->|localhost| C2

그림의 순서대로 읽습니다. 노드 위에 파드가 놓입니다. 파드 안에 컨테이너들이 들어갑니다. 그 컨테이너들이 볼륨을 같이 봅니다. 서로 부를 때는 localhost 를 씁니다.

저장소

파드는 공유 볼륨 묶음을 명세할 수 있습니다. 파드 안의 모든 컨테이너가 그 볼륨에 접근합니다. 그래서 컨테이너끼리 데이터를 나눠 쓸 수 있습니다. 볼륨은 파드 안의 데이터가 살아남게 하는 자리이기도 합니다. 안의 컨테이너 하나가 다시 시작해야 할 때 데이터가 사라지지 않습니다.

네트워크

파드마다 주소 계열별로 고유한 IP(Internet Protocol) 주소가 하나씩 배정됩니다. 파드 안의 모든 컨테이너가 네트워크 네임스페이스를 공유합니다. 그 주소와 포트도 함께 공유합니다. 파드 안에서는, 그리고 그때만, 컨테이너끼리 localhost 로 서로를 부를 수 있습니다. 파드 밖과 통신할 때는 공유 자원인 포트를 어떻게 나눠 쓸지 컨테이너들이 서로 맞춰야 합니다.

두 가지 쓰임

파드는 두 가지로 쓰입니다. 하나는 컨테이너 한 개를 돌리는 파드입니다. 쿠버네티스 문서는 이 한 파드 한 컨테이너 모형을 가장 흔한 쓰임으로 적습니다. 이때 파드는 컨테이너 하나를 감싼 껍데기로 봐도 됩니다. 쿠버네티스는 컨테이너를 직접 관리하지 않고 파드를 관리합니다. 다른 하나는 함께 일해야 하는 컨테이너 여럿을 돌리는 파드입니다. 한자리에 놓이고 단단히 묶여 자원을 나눠 써야 하는 컨테이너들을 하나로 감쌉니다.

함께 들어가는 것

애플리케이션 컨테이너 말고 다른 것도 들어갑니다. 파드가 뜨는 동안만 도는 init 컨테이너를 넣을 수 있습니다. 돌고 있는 파드를 들여다보려고 임시 컨테이너를 밀어 넣을 수도 있습니다. 파드가 노드에서 돌려면 클러스터의 노드마다 컨테이너 런타임을 설치해야 합니다. kubelet 이 파드와 그 컨테이너를 띄울 수 있는 것도 그 런타임이 노드에서 돌고 있어서입니다. kubelet 과 컨테이너 런타임 사이 통신의 주된 프로토콜이 CRI(Container Runtime Interface, 컨테이너 런타임 인터페이스)입니다.

배경

프로그램 하나가 컨테이너 하나에 대응한다고 보면 이야기가 단순해집니다. 쿠버네티스 공동 설계자들이 쓴 회고 논문은 실제로는 그렇게 쓰지 않았다고 적습니다. 같은 머신 위에 함께 스케줄되는 중첩 컨테이너를 썼습니다. 바깥쪽 컨테이너가 자원 풀을 내줍니다. 안쪽 컨테이너들이 배포 격리를 맡습니다. 이렇게 묶어 쓰는 쓰임이 흔했습니다. 파드 하나가 복잡한 애플리케이션 한 벌을 담습니다. 애플리케이션의 주된 부분이 자식 컨테이너 하나에 들어갑니다. 다른 자식 컨테이너들은 로그 회전이나 클릭로그를 분산 파일 시스템으로 넘기는 일 같은 보조 기능을 맡습니다.

논문은 이 방식을 같은 기능을 바이너리 하나에 합치는 것과 견줍니다. 조각마다 만드는 팀을 따로 둘 수 있습니다. 주 애플리케이션이 멈춰도 넘기는 일은 계속 돕니다. 작은 보조 서비스는 자기 컨테이너가 내주는 사적인 실행 환경에서 도니 새로 붙이기 쉽습니다. 각 컨테이너가 자기 자원 안에서 돌아 로깅 시스템이 주 애플리케이션의 자원을 굶기지 못합니다. 반대도 못 합니다. 논문은 이 가운데 뒤의 셋을 각각 견고성 · 조립성 · 잘게 갈린 자원 격리라고 부릅니다.

이 바깥쪽 컨테이너를 부르는 이름이 시스템마다 달랐습니다. Borg 에서는 자원 할당, 줄여서 alloc 이라 불렀습니다. 쿠버네티스에서는 이것을 파드라고 부릅니다. Borg 는 최상위 애플리케이션 컨테이너가 alloc 밖에서 도는 것도 허용했습니다. 논문은 이것이 많은 불편의 원인이었다고 적습니다. 쿠버네티스는 이 자리를 정리했습니다. 파드가 컨테이너를 하나만 담더라도 애플리케이션 컨테이너는 언제나 최상위 파드 안에서 돕니다.

예시

쿠버네티스 매니페스트 한 벌

쿠버네티스 문서가 싣는 파드 한 벌입니다. nginx:1.14.2 이미지를 돌리는 컨테이너 하나로 이루어져 있습니다.

YAML
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

kind 가 이 리소스를 파드로 정합니다. spec.containers 가 파드에 담길 컨테이너 목록입니다. 목록의 항목마다 이름과 이미지가 붙습니다. containerPort 는 그 컨테이너가 여는 포트입니다. 문서는 위 파드를 만드는 명령도 함께 적습니다.

kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml

이 매니페스트는 파드를 직접 적어 내는 형태입니다. 문서는 파드를 보통 이렇게 직접 만들지 않는다고 적습니다. 워크로드 리소스를 써서 만듭니다.

Podman 의 파드

파드는 쿠버네티스 밖에도 있습니다. Podman 의 podman pod create 는 빈 파드를 만듭니다. 문서는 이것을 컨테이너 여럿의 단위라고 적습니다. 만들어 두고 나서 컨테이너를 붙입니다.

podman pod create --name test

이 파드에 컨테이너를 넣을 때는 podman create --pod <pod_id|pod_name> 을 씁니다. 파드를 띄울 때는 podman pod start <pod_id|pod_name> 을 씁니다. 무엇을 공유할지는 --share 가 정합니다. 고를 수 있는 커널 네임스페이스는 cgroup · ipc · net · pid · uts 입니다. 문서는 기본값이 쿠버네티스 기본값과 같다고 적습니다. ipc · net · uts 셋입니다.

동작

파드 하나는 만들어지는 순간 노드 하나에 붙습니다. 사람이 직접 만들 수도 있고 컨트롤러가 대신 만들 수도 있습니다. 어느 쪽이든 새 파드는 클러스터 안의 노드 하나에 스케줄됩니다. 파드는 그 노드에 머뭅니다.

그 노드에서 내려오는 자리는 넷입니다. 파드가 실행을 마치는 것이 하나입니다. 파드 객체가 지워지는 것이 둘입니다. 자원이 모자라 파드가 축출되는 것이 셋입니다. 노드가 죽는 것이 넷입니다. 넷 가운데 하나가 오기 전까지 파드는 그 노드에 남습니다.

flowchart TD
    M["파드 생성"] --> S["노드에 스케줄"]
    S --> R["그 노드에 머묾"]
    R --> E1["실행 마침"]
    R --> E2["파드 객체 삭제"]
    R --> E3["자원 부족으로 축출"]
    R --> E4["노드 장애"]

파드를 직접 적어 만드는 일이 드문 까닭이 여기 있습니다. 쿠버네티스 문서는 파드를 비교적 수명이 짧고 버려도 되는 것으로 설계했다고 적습니다. 그래서 파드 하나짜리라도 대개 직접 만들 일이 없습니다. 워크로드 리소스로 만듭니다. 문서가 이름을 드는 것은 디플로이먼트와 잡입니다. 상태를 추적해야 하는 파드라면 스테이트풀셋을 보라고 적습니다.

운영

쿠버네티스가 파드를 직접 다루는 것을 막지는 않습니다. 돌고 있는 파드의 일부 필드는 그 자리에서 고칠 수 있습니다. 다만 만질 수 있는 자리가 좁습니다.

파드 메타데이터의 대부분은 불변입니다. 네임스페이스 · 이름 · uid · 생성 시각은 못 바꿉니다. metadata.deletionTimestamp 가 찍혀 있으면 metadata.finalizers 목록에 새 항목을 넣지 못합니다.

갱신으로 바꿀 수 있는 필드도 목록이 정해져 있습니다. 컨테이너 이미지와 init 컨테이너 이미지를 가리키는 spec.containers[*].image · spec.initContainers[*].image 가 그 안에 있습니다. 나머지는 spec.activeDeadlineSeconds · spec.terminationGracePeriodSeconds · spec.tolerations · spec.schedulingGates 넷입니다. 이 목록 밖의 필드를 바꾸려면 파드를 갈아 끼워야 합니다.

워크로드 리소스에 맡긴 파드는 그 갈아 끼우기를 컨트롤러가 맡습니다. 파드 템플릿이 바뀌면 컨트롤러는 이미 있는 파드를 고치거나 기워 넣지 않습니다. 바뀐 템플릿으로 새 파드를 만듭니다.

flowchart TD
    T["파드 템플릿 변경"] --> C["컨트롤러"]
    C --> N["새 파드"]
    C -.->|하지 않는다| U["기존 파드 수정"]

경계

파드 안의 컨테이너를 다시 띄우면 파드를 다시 띄운 것인가. 아닙니다. 쿠버네티스 문서가 이 둘을 혼동하지 말라고 못 박습니다. 파드는 프로세스가 아닙니다. 컨테이너를 돌리는 환경입니다. 파드는 지워질 때까지 남습니다.

관련 항목

파드가 속하고 놓이는 계층

배포 · 클러스터 · 노드 · 컨테이너 런타임 · kubelet · 스케줄러 · CRI

파드를 만드는 컨트롤러와 워크로드 리소스

디플로이먼트 · 레플리카셋 · 데몬셋 · 잡 · 스테이트풀셋 · 컨트롤러 · 워크로드 리소스

파드를 이루는 구성 요소

컨테이너 · 컨테이너 이미지 · init 컨테이너 · 사이드카 컨테이너 · 임시 컨테이너 · 볼륨 · 네임스페이스 · cgroup · 격리 · 커널 · 메타데이터

파드 컨테이너들이 함께 쓰는 네트워크 자원

네트워크 · localhost · IP 주소

파드 개념의 다른 이름과 구현체

쿠버네티스 · Podman · Borg · 스태틱 파드

파드가 비유되는 컴퓨팅 환경

클라우드 · 가상 머신 · 물리 머신

다른 이름: Pod · Pods · 쿠버네티스 파드