Pod는 쿠버네티스에서 이용되는 Container의 관리단위로 생성/관리/배포가능한 가장 작은 단위의 유닛이며 Cluster내에서 실제 Application이 구동되는 Object이다.
Pod는 하나 이상의 컨테이너 그룹이다. 이 그룹은 저장소 및 네트워크(storage & network)를 공유하고 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다.
여러 개의 컨테이너를 담을 수 있고 심지어
Volume
도 내부 컨테이너끼리 공유해서 사용이 가능하다.
워크로드: 쿠버네티스 상에서 작동되는 애플리케이션
Docker에서는 Container들과의 통신을 위해 동일한 Network 상에 구성해야 하지만 Pod는 개별 IP를 가지며, pod내의 Container는 동일한 IP를 가진다. 즉, 내부적으로 할당받은 IP는 컨테이너로 분산되어 들어간다.
하지만 Pod는 언제든지 Scale Out/In이 가능하고, 삭제/복제가 가능하므로 자체IP를 가지고 있음에도 다른 Pod들과의 통신을 위해서는 반드시 Service Object를 통해 통신해야 한다.
도커의 컨테이너는 각 개별로 IP를 할당받아서 내부적으로 사용을 하지만, 쿠버네티스 같은 경우는 POD라는 개념으로 한 번 wrapping되어 상위에 IP가 할당된다.
워크로드 리소스에 대한 컨트롤러는 파드 템플릿
에서 파드를 생성하고 사용자 대신 해당 파드를 관리한다. PodTemplate(파드템플릿)
은 파드를 생성하기 위한 명세이며 Deployment(디플로이먼트)
, Job(잡)
, DemoneSet(데몬셋
과 같은 워크로드 리소스에 포함된다.
워크로드 리소스의 각 컨트롤러는 워크로드 오브젝트 내부의 PodTemplate
을 사용하여 실제 파드를 생성한다. PodTemplate
은 앱을 실행하는 데 사용되는 워크로드 리소스가 무엇이든지 원하는 상태의 일부이다.
아래의 샘플은 하나의 컨테이너를 시작하는 template
이 있는 간단한 잡의 매니페스트이다.
apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
# 여기서부터 파드 템플릿이다
spec:
containers:
- name: hello
image: busybox:1.28
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# 여기까지 파드 템플릿이다
파드 템플릿을 수정하거나 새로운 파드 템플릿으로 바꿔도 이미 존재하는 파드에는 직접적인 영향을 주지 않는다. 워크로드 리소스의 파드 템플릿을 변경하는 경우, 해당 리소스는 수정된 템플릿을 사용하는 대체 파드를 생성해야 한다.
각 워크로드 리소스는 파드 템플릿의 변경 사항을 처리하기 위한 자체 규칙을 구현한다.
노드에서 kubelet
은 파드 템플릿과 업데이트에 대한 상세 정보를 직접 관찰하거나 관리하지 않는다. 이러한 상세 내용은 추상화된다.
Pod는 위에서 보았듯이 Pod Object안에 여러개의 Container를 담을 수 있는 구조로 되어 있다. yaml
파일도 그에 맞게 Pod의 스펙으로 여러개의 Container
를 Spec
으로 구성할 수 있도록 되어있다.
apiVersion: v1
kind: Pod
metadata:
labels:
run: my-nginx
name: my-nginx
namespace: default
spec:
containers:
- image: nginx:1.14.1
imagePullPolicy: Always
name: my-nginx
ports:
- containerPort: 80
protocol: TCP
일반적으로 Pod
는 직접 생성하지는 않으며, 대신 워크로드 리소스를 사용하여 생성한다.
일반적으로 싱글톤(singleton) 파드를 포함하여 파드를 직접 만들 필요가 없다. 대신,deployment(디플로이먼트)
또는 job(잡)
과 같은 워크로드 리소스를 사용하여 생성한다. 파드가 상태를 추적해야 한다면, statefulSet
리소스를 고려한다.
쿠버네티스 클러스터의 파드는 두 가지 주요 방식으로 사용된다.
파드 당 하나의 컨테이너
모델은 가장 일반적인 쿠버네티스 유스케이스이다. 이 경우, 파드를 단일 컨테이너를 둘러싼 래퍼로 생각할 수 있다. 쿠버네티스는 컨테이너를 직접 관리하는 대신 파드를 관리한다.각 파드는 특정 애플리케이션의 단일 인스턴스를 실행하기 위한 것이다. 더 많은 인스턴스를 실행하여 더 많은 전체 리소스를 제공하기 위해 애플리케이션을 수평적으로 확장하려면, 각 인스턴스에 하나씩, 여러 파드를 사용해야 한다. 쿠버네티스에서는 이를 일반적으로 레플리케이션
이라고 한다. 복제된 파드는 일반적으로 워크로드 리소스와 해당 컨트롤러
에 의해 그룹으로 생성되고 관리된다.
파드는 응집력있는 서비스 단위를 형성하는 여러 협력 프로세스(컨테이너)를 지원하도록 설계되었다. 파드의 컨테이너는 클러스터의 동일한 물리 또는 가상 머신에서 자동으로 같은 위치에 배치되고 함께 스케줄 된다. 컨테이너는 리소스와 의존성을 공유학, 서로 통신하고, 종료 시기와 방법을 조정할 수 있다.
파드는 기본적으로 파드에 속한 컨테이너에 네트워킹과 스토리지라는 두가지 종류의 공유 리소스를 제공한다.
사용자가 쿠버네티스에서 직접 개별 파드를 만드는 경우는 거의 없다. 싱글톤 파드도 마찬가지이다. 이는 파드가 상대적으로 일시적인, 일회용 엔티티로 설계되었기 때문이다. 파드가 생성될 때, 새 파드는 클러스터의 노드에서 실행되도록 스케줄된다. 파드는 파드 실행이 완료되거나, 파드 오브젝트가 삭제되거나, 리소스 부족으로 인해 파드가 축출되거나, 노드가 실패할 때까지 해당 노드에 남아있다.
Pod
에서 컨테이너를 다시 시작하는 것과Pod
를 다시 시작하는 것을 혼동해서는 안된다.Pod
는 프로세스가 아니라 컨테이너를 실행하기 위한 환경이다.Pod
는 삭제 될 때까지 유지된다.
워크로드 리소스를 사용하여 여러 파드를 만들고 관리할 수 있다. 리소스에 대한 컨트롤러는 파드 장애 시 복제 및 롤아웃과 자동 복구 처리를 한다. (컨트롤러 - 노드 실패시 해당 노드의 파드가 작동을 중지했음을 인식하고 대체 파드 생성, 스케줄러- 대체 파드 정상 노드 배치)
예시 워크로드 리소스:
디플로이먼트
,스테이트풀셋
,데몬셋
k8s에서 Pod를 배포한 이후의 Pod의 라이프사이클에 대해 알아본다. k8s에서 Pod를 배포하고 kubectl get pod
명령어를 통해 배포된 결과를 조회하면 Pod의 상태를 볼 수 있는 필드를 볼 수 있다.
Value | Description |
---|---|
Pending | Pod 배포명령을 내린 직후 Pod의 상태를 조회해보면 Pending 이라는 상태이다. 이 상태를 Pod내의 Container 이미지가 다운로드 되기 전의 대기 상태를 말한다. |
Running | Pod의 Container가 Node에 정상적으로 생성되어 동작하는 상태 |
Succeeded | 주로 Job과 같은 Pod 리소스에서 확인할 수 있는 형태로 Pod의 Containers 컨테이너가 생성되어 프로세스를 실행하고 정상적으로 종료된 상태이다. 즉, 파드에 있는 모든 컨테이너들이 성공적으로 종료되었고, 재시작 되지 않을 것이다. |
Failed | Pod 안의 모든 Containers가 종료되었으나 한 개 이상의 Container가 정상적으로 종료되지 않은 상태이다. |
Unknown | Pod의 상태를 확인할 수 없는 상태로, 주로 Host 머신과의 통신에 문제가 발생했을때 표시된다. |
Kubernetes에서 Image 배포시 Kubelet에서는 기본 설정 값으로 배포하려는 Images가 Node에 존재할 경우 이미지 다운로드를 skip한다. 이러한 설정값은 Pod의 container spec에 imagePullPolicy 설정 값으로 정의할수 있다.
Pod
는 앱들을 실행하는 다수의 컨테이너를 포함할 수 있고, 또한 앱 컨테이너 실행 전에 동작되는 하나 이상의 초기화 컨테이ㅓㄴ도 포함할 수 있다.
만약 Pod의 초기화 컨테이너가 실패하면, Kubelet은 초기화 컨테이너가 성공할 때까지 반복적으로 재시작한다. (만약 restartPolicy
를 Never
로 지정시, 실패하면 전체 파드를 실패한 것으로 처리)
컨테이너를 초기화 컨테이너로 지정하기 위해서는, 파드 스펙에 initContainer
필드를 container
항목들의 배열로서 추가한다.