[Kubernetes] 쿠버네티스 Pod
<쿠버네티스 Pod>
안녕하세요.
개발자 김모씨입니다.
쿠버네티스 시리즈를 이어가고 있죠.
혹시 이전 포스팅 '쿠버네티스 구조'를 아직 안 보신 분은
얼렁 다녀오세요~
artist-developer.tistory.com/31
오늘은 쿠버네티스의 Pod에 대해서 알아볼 겁니다.
물론, 깊게 들어가면 오늘 볼 내용 외에도 수많은 오브젝트들이 있지만,
가장 기본적인 것들부터 천천히 알아볼게요~~
Pod이란?
저번 포스팅에도 잠깐 나왔었죠.
Pod에 대해 먼저 알아봅시다.
Pod는 쿠버네티스의 가장 기본적인 배포 단위 입니다.
마스터 노드에서는 워커노드로 pod을 전달하고, 워커노드에서는 pod을 수행하는 구조죠.
그래서 위 그림처럼, 한 개의 워커노드에는 N개의 Pod이 돌아가게 됩니다.
쿠버네티스는 컨테이너(Docker 등)를 개별적으로 배포하는 것이 아닌,
Pod 안에 컨테이너를 탑재하여 배포합니다.
이 때 Pod 안에는 1개 이상의 컨테이너가 탑재될 수 있습니다.(1 Pod = N Containers)
단일 컨테이너를 생성하는 Pod가 일반적인 사용법이긴 한데요.
꽤 많은 상황에서 여러 컨테이너를 실행하는 Pod가 배포되고 있습니다.
그렇다면 왜? Why? 여러개의 컨테이너를 Pod 단위로 묶어서 배포하는 걸까요?
1. Pod 내부 컨테이너 간의 IP 및 Port 공유를 통한 통신 용이성 향상
N개의 컨테이너가 한 개의 Pod에 탑재되어 배포된 어플리케이션을 고려해봅시다.
이 어플리케이션 안의 컨테이너 A, B끼리는 실시간으로 데이터를 교환하며, 그에 따라 상태를 업데이트해야 합니다.
이 때, 두 컨테이너 A, B는 별도의 IP 호출없이 localhost를 통해서 통신이 가능합니다.
예를 들어 컨테이너 A에 port 7080, 컨테이너 B에 port 8090이 할당되었을 경우,
컨테이너 A에서 컨테이너 B를 호출할 때는 localhost:8090,
반대로 컨테이너 B에서 컨테이너 A를 호출할 때는 localhost:7080 으로 접근할 수 있는 거죠.
이처럼, Pod 내부 컨테이너 간의 IP 및 Port를 공유함으로써
상호 동작해야 하는 컨테이너끼리의 통신 용이성을 향상시킨거죠.
2. Pod 내부 컨테이너 간의 디스크 볼륨 공유
Pod 내에 함께 배포된 컨테이너끼리는 디스크 볼륨을 공유할 수 있습니다.
위의 상황에서, A B가 볼륨을 공유하기 때문에, 컨테이너 A가 컨테이너 B의 파일을 읽어올 수 있는 거죠.
뿐만 아니라, 로그 수집기를 사이드카 패턴(side car pattern)을 통해 Pod에 탑재하여 배포할 경우,
Pod 내부 컨테이너들의 로그를 모두 수집할 수 있습니다.
(사이드카 패턴 관련해서는 다른 글에서 설명할 예정입니다.)
위와 같은 이유들을 통해서, 1개의 Pod에 여러개의 컨테이너를 탑재하여 배포하는 것은 큰 장점을 가지게 되죠.
이를 통해서 만들어진 Pod을 배포하면, 단일 인스턴스가 만들어집니다.
유저 유입 증가 등의 이유로 더 많은 리소스를 제공하기 위해 수평적으로 어플리케이션을 확장하려면,
단일 인스턴스를 만드는 Pod을 복제하는 레플리케이션을 수행해야 합니다.
(레플리케이션, 레플리카 관련해서도 다른 글에서 설명할 예정입니다.)
Pod 생성
pod의 생성은 yaml, Json 등의 template을 주로 사용합니다.
물론 kubectl create와 옵션의 조합을 통해 만들수도 있지만,
template을 통해 만들고, 수정이 필요하면 template를 업데이트하는 것이 더 좋은 방법이죠.
//Pod 생성 예제 : sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
기본적인 Pod 생성을 위한 yaml template는 위와 같습니다.
yaml 파일은 기존적으로 indentation(들여쓰기)를 기준으로 동작하니, 작성 시 주의해야 합니다.
각각의 의미를 알아보죠.
apiVersion: v1
apiVersion은 쿠버네티스 api의 버전 명세입니다.
이 예제에서는 v1을 사용하였지만, apps/v1 등 depth를 깊게 작성해주어야 할 때도 있습니다.
kind: Pod
생성할 쿠버네티스의 리소스 타입입니다.
Pod, deployment, statefulset 등 수많은 쿠버네티스 리소스는 yaml 등의 template을 통해 생성할 수 있습니다.
우리가 지금 정의하고 있는 것은 Pod입니다.
metadata:
name: myapp-pod
labels:
app: myapp
metadata 정의부입니다.
생성할 Pod의 이름과 label을 정하는 거죠.
label은 특정 쿠버네티스 리소스를 검색할 때 사용하는 Key-Value 형태의 데이터 입니다.
myapp이라는 app label을 통해 myapp-pod을 검색할 수 있는 거죠.
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
Pod의 구체적인 사양을 정의하는 Spec부 입니다.
하위로 수많은 항목들이 나열되는데, 이 예시에서는 containers만 사용하고 있습니다.
앞서 언급하였듯, 1개의 pod은 N개의 컨테이너를 탑재할 수 있는데요.
이 예시에서는 myapp-container라는 1개의 컨테이너만 정의했습니다.
컨테이너에는 image가 명세되어야 하죠.
이 예시에서는 busybox 이미지를 사용하고 있습니다.
docker registry를 구체적으로 명세하여 가져올 수도 있습니다.
본 예시에서는 registry를 명세하지 않아, docker hub의 docker 공식 registry에서 이미지를 가져오게 됩니다.
command는 컨테이너가 생성된 직후 실행되는 명령어를 명세합니다.
실행되자마자 command에 있는 명령어들이 실행되죠.
정리하자면, 위의 yaml file은
'Hello Kubernetes!' 문구를 출력하고, 1시간 동안 sleep 하는 어플리케이션을 배포하는 Pod 입니다.
$ kubectl apply -f sample-pod.yaml
kubectl apply 명령어를 통해,
yaml file로 명세한 pod을 배포할 수 있습니다.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 2s
생성된 pod의 배포 결과를 조회하기 위한 명령어 입니다.
2초 전에 myapp-pod가 성공적으로 배포되어 Running 상태임을 알 수 있죠.
$ kubectl logs pod/myapp-pod
Hello Kubernetes!
kubectl logs pod/{pod name} 명령어를 사용하면
해당 pod의 로그 데이터를 확인할 수 있습니다.
예제는 'Hello Kubernetes!' 문구를 출력하는 Pod이었으므로, 정상적으로 수행되었음 확인할 수 있죠.
한시간 동안 해당 Pod은 Sleep 상태로 대기한 뒤 종료될 것입니다.
Pod의 단계
위의 예시에서 Running 등의 Pod status를 보셨을 겁니다.
Pod의 status의 값들은 다음과 같습니다.
- Pending : Pod 배포 명령이 있었으나, Pod 내부 1개 이상의 컨테이너가 실행할 준비가 되지 않음. 실행까지 오류가 발생할 경우, Pending 상태에서 대기할 수 있음.
- Running : Pod가 워커노드에 바인딩되었고, 해당 Pod의 모든 컨테이너가 생성되었음. 정상 동작 상태.
- Succeeded : Pod의 모든 컨테이너들이 성공적으로 종료되었음.
- Failed : Pod의 모든 컨테이너가 종료되었으나, 한 개 이상의 컨테이너가 실패로 종료되었음.
- Unknown : 임의의 이유로 인해 Pod의 상태를 알 수 없음. 일반적으로는 해당 워커노드와 마스터노드의 통신 오류로 인해 발생함.
또한, Pod는 Pod 내부에서 각 컨테이너의 상태를 추적합니다.
$ kubectl describe pod <name-of-pod>
명령어를 통해서 Pod 내부 특정 컨테이너의 상태를 확인할 수 있습니다.
- Running : 컨테이너가 문제없이 실행되고 있음을 의미합니다.
- Terminated : 컨테이너가 실행을 시작한 다음 완료될때까지 모두 정상 실행되었거나, 특정한 이유로 실패하여 컨테이너가 종료된 상태입니다. kubectl describe 명령어를 통해 종료 코드 등을 확인할 수 있습니다.
- Waiting : 컨테이너가 Running, Terminated 상태가 아니면 모두 Waiting 상태입니다. 컨테이너를 시작하기 위해서 필요한 작업(이미지 레지스트리에서 이미지를 pulling 하거나 시크릿 데이터를 적용하는 등)을 실행하고 있는 중입니다.
일반적으로 Pod 내부 컨테이너는 Waiting → Running → Terminated의 상태 단계를 가집니다.
오늘은 이렇게
쿠버네티스의 가장 작은 기본적인 배포단위인, Pod에 대해 알아보았습니다.
시작이 반이다! 라는 말도 있죠.
천천히~ 쭉쭉 가봅시다!
구독과 댓글은 개발자김모씨에게 큰 힘이 됩니다.
감사합니당당당