[K8s] 파드(Pod)를 구성하고 클러스터에 생성·삭제하기
지난 포스트
파드(Pod)란
파드(Pod)는 쿠버네티스에서 생성하고 관리할 수 있는 가장 작은 컴퓨팅 단위입니다. 파드는 하나 이상의 컨테이너로 이루어진 그룹이고, 그룹 내에서 스토리지와 네트워크를 공유합니다.
YAML 구성
쿠버네티스는 오브젝트(Object)들의 설정 파일을 YAML 형식으로 저장합니다. 명령줄 도구인 kubectl을 이용해 YAML 형식을 쿠버네티스 API server에 보내면 자동으로 REST API 형식으로 변환해 이를 처리합니다.
kubectl 명령어의 여러 옵션을 이용해 파드를 생성 할 수도 있지만, 명령어 작성 이전에 YAML 구성 파일을 미리 만들어 두고 kubectl 명령어에 “이 파일대로 생성해주세요”라고 YAML 구성 파일을 지정해 파드를 구성할 수도 있습니다. YAML 파일은 Github 같은 리포지포리에도 저장할 수 있으므로 설정을 다른이들과 공유하기에도 유용합니다.
또한 이미 클러스터 내부에서 실행되고 있는 개별 파드의 상태를 YAML 형식으로 조회하거나 YAML 형식 파일로 설정을 내보낼수도 있습니다.
# nginx.yaml 파일
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
tier: frontend
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
앞으로의 모든 쿠버네티스 구성 요소들의 YAML 설정 파일은 공통적으로 크게apiVersion
, kind
, metadata
, spec
키(key)를 갖습니다.
- 파드의
apiVersion
은 항상v1
으로 고정됩니다(v2
가 새로 나오지 않는 이상). 추후에 알아볼 Deployment나 ReplicaSet에서는apiVersion
에 값으로apps/v1
을 할당하는데, 언제v1
이고 언제apps/v1
인지 헷갈릴 수 있음에 주의합니다. kind
키는 오브젝트의 종류를 명시합니다. 파드의 경우 값을Pod
로 할당하는데, 대소문자에 엄격해pod
라고 할당하면 생성시 오류가 발생하니 주의합니다.metadata
키는 파드 자체의 정보를 담고 있습니다.metadata
아래의name
키는 파드의 이름을 할당하고label
키는 추후에 알아볼 Deployment, ReplicaSet, Service 등이 해당 파드를 지정해야 할 때 필터링할 수 있는 일종의 태그입니다.spec
키는 파드 내부의 정보를 담고 있습니다. 파드는 하나 이상의 컨테이너로 이루어져 있으므로container
키는 배열로 구성합니다(다만, 위 예시의 파드는 하나의 컨테이너로만 구성되었습니다).container
키의 아래에는 컨테이너의 이름을 나타내는name
, 컨테이너 이미지(도커 이미지)를 지정하는image
키를 지정할 수 있습니다.port
키는 파드에 Service를 연결해 사용해야 할 때 파드에 접근할 수 있는 포트 번호를 열어 Service가 파드에 접근할 수 있게 합니다.
파드 생성하기
명령어를 이용한 방법
kubectl 명령어와 각종 옵션을 이용해 간편하게 파드를 생성할 수 있습니다.
다음은 nginx:latest
컨테이너 이미지를 사용하는 nginx
라는 이름의 파드를 생성하는 명령어 입니다.
# nginx 파드 생성하기
kubectl run nginx --image nginx:latest
# 생성된 파드 조회하기
kubectl get pods
kubectl get pods
명령어로 현재 클러스터에서 실행되고 있는 파드들을 조회할 수 있습니다. 개별 파드에 대한 상세 정보를 알 수 있는 명령어는 다음과 같습니다.
# 상세 정보 조회 명령
kubectl describe {오브젝트} {이름}
# nginx 파드의 상세정보 보기
kubectl describe pod nginx
상세 정보에서는 파드의 상태, 소속 노드, 소속 네임스페이스, 컨테이너 상태, 설정 값, 로그 등을 확인할 수 있습니다.
kubectl describe
명령어 대신 생성된 파드의 상태를 YAML 형식으로 조회하거나 YAML 파일로 저장할 수 있습니다.
# nginx 파드의 상태를 YAML 형식으로 조회하기
kubectl get pod nginx -o yaml
# nginx 파드의 상태를 output.yaml 파일에 저장하기
kubectl get pod nginx -o yaml > output.yaml
클러스터에 파드를 생성하지 않은 상태에서 바로 파드의 YAML 구성 파일을 생성할 수도 있습니다. YAML 파일을 새로 작성할 때, 빈 문서를 생성해 처음부터 작성하는 것보다 파드 이름이나 이미지 같은 최소한의 정보로 양식을 생성하고 추가 정보를 입력할 수 있어 편리합니다.
--dry-run=client
옵션으로 생성 명령을 API 서버에 전달하지 않고 클라이언트단(段)에서 임시로 실행함을 명시하고 -o
옵션으로 실행 결과를 YAML 형식으로 출력한 것을 그대로 .yaml
파일로 내보냅니다.
# 파드를 생성하지 않고 임시 실행 결과를 YAML 형식으로 내보내기
kubectl run nginx --image nginx --dry-run=client -o yaml > output.yaml
# 생성된 YAML 파일 조회
cat output.yaml
YAML 구성 파일을 이용한 방법
# nginx.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx
name: nginx
spec:
containers:
- image: nginx:1.24.0
name: nginx
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
위의 nginx.yaml
파일을 이용해 클러스터에 파드를 생성하려고 합니다. 컨테이너 이미지가 nginx:1.24.0
으로 지정되어 있음에 주목합니다. 아래는 YAML 구성 파일을 이용해 파드를 생성하는 명령어입니다.
# nginx.yaml 파일을 이용해 파드 생성하기(명령적)
kubectl create -f nginx.yaml
# nginx.yaml 파일을 이용해 파드 생성하기(선언적)
kubectl apply -f nginx.yaml
kubectl create
명령어와 kubectl apply
명령어의 차이는 전자는 명령적(Imperative) 접근, 후자는 선언적(Declarative) 접근임에 있습니다.
명령적 접근은 프로그램에게 어떻게(How)를 요구하는데에 초점이 맞춰져 있습니다. kubectl create
명령어는 nginx.yaml
을 보여주고 “이대로 생성해주세요”라고 생성하는 행위 자체를 명령하는 뉘앙스로 프로그램은 전후사정을 막론하고 파드를 생성하는 행위에만 집중합니다. 따라서 이미 동일한 이름의 파드가 실행되고 있는 경우에는 중복 오류(AlreadyExists
)를 출력하며 명령 실행을 멈춥니다.
앞서 다루었던 명령어와 옵션을 이용한 방법도 프로그램에게 방법론을 제시하는(“이렇게, 저렇게 해주세요”) 명령적 접근이라고 볼 수 있습니다.
반면에, 선언적 접근은 프로그램에게 무엇(What)을 요구하는데에 초점이 맞춰져 있습니다. kubectl apply
명령어는 nginx.yaml
이라는 견적서를 가지고 “이대로 적용해주세요” 라고 결과물을 요구하는 뉘앙스로(“어떻게요?” — “그건 네가 알아서 해야지”) 프로그램은 자신의 역량을 이용해 어떻게든 결과를 내기 위해 노력합니다. 따라서 이미 동일한 이름의 파드가 실행되고 있는 경우에도 명령자가 원하는 결과물을 내기 위해 기존의 파드 설정값을 nginx.yaml
에 담긴 설정값으로 수정해줍니다.
파드 삭제하기
클러스터에서 실행되고 있는 파드를 삭제하는 명령어는 다음과 같습니다.
# 오브젝트 삭제 명령
kubectl delete {오브젝트} {이름}
# 클러스터에서 실행 중인 nginx 파드 삭제하기
kubectl delete pod nginx
마무리
실행 중인 파드를 편집하는 방법에는 앞서 소개한 kubectl apply
와 같은 선언적 접근법 말고도 kubectl edit
이나 kubectl scale
같은 명령적 접근법이 있지만, 프로덕션 환경에서 두 접근법을 혼용해서 사용하면 의도하지 않은 결과를 내거나 로그가 꼬일 수 있습니다. 이유에 대해서는 내용이 늘어지므로 차후 포스트로 다뤄보겠습니다.
이후 포스트에서는 쿠버네티스를 구성하는 다른 오브젝트인 Deployment, ReplicaSet, Service에 대해서도 하나씩 알아보려고 합니다.
참고자료
- “파드”. 쿠버네티스 문서. https://kubernetes.io/ko/docs/concepts/workloads/pods/.
- “API Conventions”. Github: kubernetes/community. 2023년 5월 17일(commit
f88bbba
). https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md. - 홍성진. “쿠버네티스에서 명령형 접근법과 선언형 접근법의 차이 이해하기”. seongjin.me. 2022년 3월 2일. https://seongjin.me/kubernetes-imparative-vs-declarative/.