Pod
쿠버네티스의 핵심 오브젝트인 파드이다.
이번 포스팅에서는 파드의 생명주기, 생성과 삭제, 관리등을 다루겠다.
쿠버네티스에서는 컨테이너 어플리케이션의 기본 단위를 Pod라고 부른다.
Pod는 1개 이상의 컨테이너로 구성된 컨테이너들의 집합이라고 생각하면 된다.
낯설지 않다. 도커 스웜에서 다루었던 서비스와 비슷하다.
같은 컨테이너 오케스트레이션 툴로써, 복잡한 애플리케이션을 쉽게 다루기 위해 기본 단위를 바꾼것이다.
Pod를 정의하는 YAML
apiVersion: v1
kind: Pod
metadata:
name: my-nginx-pod
spec:
containers:
- name: my-nginx-container
image: nginx
ports:
- containerPort: 80
protocol: TCP
YAML 파일은 docker-compose에서 다루었어서 두렵지 않다.
하나하나 뜯어 보자.
apiVersion
YAML 파일에서 정의할 오브젝트의 API 버전을 나타낸다.
오브젝트의 API 버전? 그게 뭐지? 라고 생각할 수 있는데
간단하게 쿠버네티스의 버전이라고 생각하면 된다.
쿠버네티스의 버전이 업그레이드 될 때 마다 새로 생기는 오브젝트도 있을것이고, 사라지는 오브젝트도 있을 것이다.
해당 버전과의 호환성을 위해 명시하는 필드이다.
apiVersion은 다시 group과 version으로 나뉘게 되며 위의 예시는 group이 생략된 버전이다.
이는 Pod 오브젝트가 쿠버네티스의 기본 API 그룹인 core에 속해있기 때문인데,
core 그룹에 속한 오브젝트들은 group을 생략할 수 있다.
원래대로라면 core/v1 이라고 명시해야 한다.
그렇다면 core 그룹에 속하지 않은 오브젝트들도 있을텐데 어떻게 해야할까?
이는 Deployment 오브젝트를 다루면서 보여주겠다.
kind
오브젝트의 종류를 명시한다.
Pod, ReplicaSet, Deployment, Service등 여러가지 오브젝트를 명시할 수 있다.
metadata
라벨과 주석, 이름등 리소스의 부가 정보들을 입력하는 필드이다.
spec
리소스를 생성하기 위한 자세한 정보들을 입력한다.
이 정보를 바탕으로 kubelet이 CRI에게 실행해야 할 컨테이너 목록을 넘겨준다.
docker-compose로 단련된 우리는 크게 낯설지 않다.
YAML 파일로 Pod 생성하기
Pod를 생성하는 YAML 파일의 구조에 대해 알아보았다.
실제로 이 YAML 파일을 가지고 Pod를 어떻게 생성할 수 있을까?
답은 kubectl이다.
명령어로 바로 들어가자.
kubectl apply -f nginx-pod.yaml
apply 명령어의 의미를 생각해보면, 이 yaml 파일에 적힌 내용을 적용해줘! 라는 뜻이다.
적용해줘! 는 다시 말해 우리가 Desired 하는 State이다.
이전 포스팅에서 다루었던 컴포넌트를 다시 가져와 apply 명령어의 flow를 생각해보자.
- kubectl apply -f nginx.pod.yaml
- kube-apiserver가 이를 수신한다.
- kube-controller-manager가 Pod를 생성한다 (아직 노드에 할당되지 않은 상태)
- kube-schedulre는 생성된 Pod를 노드에 할당하도록 스케쥴링 한다 (아직 노드에 생성되지 않은 상태)
- kubelet은 할당 명령을 받고 전달 받은 PodSpec을 CRI에게 던진다 (아직 노드에 생성되지 않은 상태)
- CRI는 비로소 할당받은 Pod를 노드에 생성한다.
- kubectl은 Pod가 생성되었다고 결과값을 받는다.
복잡하지만 한번 정리해놓고 가면 이해할 수 있다.
명령어를 입력하니 바로 Pod가 만들어졌다고 나온다.
생성된 Pod를 조회해보자.
kubectl get pods
kubectl get pod
kubectl get pod -o wide
kubectl get pod my-pod -o yaml
pod는 pods의 alias로, 둘 중 어느것을 입력해도 상관없다.
-o 옵션은 output을 뜻하며 wide는 output을 좀 더 풍부하게 보겠다는 뜻이다.
wide 말고 yaml 인자를 던져보자.
우리가 생성한 Pod의 정보를 YAML 형식으로 볼 수 있다.
-o wide 옵션으로 본 Pod의 정보에서, IP와 NODE가 적혀있는것이 보인다.
Pod는 실제로 w3-k8s 노드에 할당되었고 IP도 부여받았다.
해당 IP는 클러스터 내부에서만 접근할 수 있는 사설 IP이다.
매니저 노드에서 해당 ip에 get 요청을 보내보자.
이번엔 실제 워커노드에 접속해 컨테이너가 실행되고 있나 보자.
Pod 접속하기
Pod도 IP가 있으므로 접속할 수 있다.
접속도 kubectl을 통해 이루어진다.
kubectl exec -it [Pod] [Command]
kubectl exec -it [Pod] -- [Command]
두 가지 버전이 있는데, 먼저 위에 명령어를 입력해보자.
Deprecate라는 메세지를 볼 수 있다.
command에 있는 '-'와 option에 붙는 '-'이 가끔씩 충돌이 되는 경우가 있어서 '--'로 구분지어줘야 한다.
빠져나와서 두 번째 명령어로 다시 입력해보자.
nginx 컨테이너가 잘 실행되고 있는지 확인해보자.
이처럼 docker exec 같이 Pod 내부에 접속할 수 있다.
Pod 삭제하기
Pod 생성 및 접속까지 알아보았고, 이번엔 삭제에 대해 알아보자.
삭제도 kubectl을 통해 이루어진다.
kubectl delete -f nginx-pod.yaml
다시 매니저 노드에서 pod를 조회해보면 아무것도 없는것을 볼 수 있다.
마찬가지로 워커 노드에서도 container를 조회해보면 nginx 컨테이너는 없다.
Pod vs Container
우리가 실습한 Pod는 nginx 컨테이너 하나로 이루어져있다.
이 정보에서, READY 항목은 (현재 실행중인 컨테이너 수) / (전체 컨테이너 수)를 뜻한다.
Pod는 1개 이상의 컨테이너를 담을 수 있는 단위라고 했다.
따라서 Pod에 nginx 컨테이너외에도 nginx config를 관리해주거나, 로깅을 담당하는 사이드카 컨테이너를 넣을수도 있다.
이 경우에는 네트워크 네임스페이스를 공유하므로 컨테이너간의 통신이 쉬워진다.
하지만 보통의 경우에는 확장성과, 단일 책임의 원칙에 의해 1개의 Pod에 1개의 컨테이너만 담는다.
'Infra > Kubernetes' 카테고리의 다른 글
[Kubernetes] 쿠버네티스 오브젝트 [Service] (0) | 2023.07.05 |
---|---|
[Kubernetes] 쿠버네티스 오브젝트 [Deployment] (0) | 2023.07.04 |
[Kubernetes] 쿠버네티스 오브젝트 [ReplicaSet] (0) | 2023.07.03 |
[Kubernetes] 쿠버네티스 구성 요소 (0) | 2023.07.03 |
[Kubernetes] 쿠버네티스 시작하기 (0) | 2023.07.03 |