파드란?
파드는 쿠버네티스가 컨테이너를 다루는 기본 단위라고 할 수 있습니다. 그리고 쿠버네티스 상에서 어플리케이션을 다양한 형태로 구성하고 운영할 수 있습니다. 그 떄 가장 기본이되는 단위입니다.
다양한 API Resource들이 있습니다. 예를 들면 Statefulset, Deployset, Daemonset, Job, CronJob, Replicaset,... 하지만 이들은 모두 Pod를 띄우게 됩니다. Pod는 1개 이상의 컨테이너로 구성된 컨테이너 집합이라고 할 수 있습니다. 도커랑 도커 컴포즈를 다룰 때, 가장 기본적인 단위가 컨테이너라고 했다면, 쿠버네티스에서는 이 컨테이너를 직접적으로 생산할 수 있는 방법은 없습니다.
어떻게든 컨테이너를 컨트롤 할 수 있는 방법은 Pod입니다. 또한 동일 파드 내 컨테이너는 여러 리눅스 네임스페이스를 공유합니다.
네임스페이스는 최근 유행하는 도커(docker)와 같은 컨테이너(container)기반의 가상화 기술의 기반이 되는 기능(feature)입니다. 네임스페이스는 동일한 시스템에서 별개의 독립된 공간을 격리된 환경에서 운영하는 가상화 기술입니다. 이는 아파트가 각 호실별로 격리된 주거환경을 제공하는 것과 비슷한 개념으로 생각하면 됩니다.
네임스페이스는 하이퍼바이저(hypervisor)와 비슷하다고 생각할 수 있지만 차이가 있습니다. 하이퍼바이저의 경우 하드웨어(hardware)자체를 가상화합니다. 하이퍼바이저는 하드웨어를 물리적으로 구분해서 가상화한다고 생각할 수 있습니다. 따라서 하이퍼바이저 위에 올라가는 게스트 OS는 서로 물리적으로 구분된 공간에서 돌아갑니다. 그러나 네임스페이스는 하드웨어를 분리하지는 않습니다. 동일한 OS및 커널(kernel)을 깔고 그 위에서 돌아갑니다.
따라서 파드 내의 컨테이너는 네트워크 네임스페이스를 공유하기 때문에 (동일 IP를 사용하게 됩니다)
아래 Pod1, 2, 3, 4를 보면 각각 다른 ip주소를 가지고 있는것을 보실 수 있습니다. Pod안에 컨테이너가 몇개든 그리고 볼륨이 몇개든 네트워크 IP는 하나임을 알아야 합니다.
그리고 또하나 중요한 점은 사용자가 파드를 직접 관리하는 경우는 거의 없다는 것입니다. 다만 위에서 말했던 Pod를 Wrapping하고 있는 High level의 리소스들인 Statefulset, Deployset, Daemonset, Job, Cronjob, Replicaset,...등을 저희가 다루게 됩니다.
파드 관련 kubectl 명령어
다음과 같이 minikube안에 아무것도 없음을 확인하고, 현재 폴더에 있는 pod.yaml을 보니 hello라는 Pod를 생성하는 것을 확인할 수 있고 image는 nginxdemos/hello:plain-text를 사용하는 것을 확인할 수 있고 해당 nginx컨테이너는 tcp프로토콜로 80번 포트를 연 것을 보실 수 있습니다.
kubectl explain을 통해 Pod가 뭔지 살펴보면, 컨테이너들의 집합이라는 것을 보실 수 있습니다. 그리고 무조건 같은 호스트어야 합니다.
이제 위에서 본 pod.yaml을 통해서 hello Pod를 하나 만들었습니다. kubectl get pod를 통해서 Pod안에있는 컨테이너의 수와 그 중 Ready상태에 있는 컨테이너의 수를 보실 수 있습니다.
다음과 같이 Pod의 내부 IP를 알아낸 다음에 curl요청을 보내보면 보내지지 않는 것을 보실 수 있습니다. 이 이유는 현재 ubuntu운영체제 안에 있지만 Cluster안에 있지 않기 때문입니다. 우리는 Ubuntu운영체제 안에 minikube로 cluster를 가상환경으로 구성했습니다. 그리고 cluster안에 172.00/0대역이 있는데, 해당 대역은 클러스터 안에서만 사용할 수 있는 Ip대역 입니다.
이것을 테스트 하기 위한 방법은 여러가지 입니다. 우선 minikube ssh를 통해서 minikube가 만든 클러스터의 노드로 쉘 접근을 할 수 있게 됩니다.
그리고 응답으로 Pod의 정보를 확인할 수 있습니다.
그 외에도 debug라는 컨테이너를 하나 실행하고 hello Pod에 요청을 보내보겠습니다.
당연히 이도 minikube안의 클러스이므로 요청이 가는 것을 보실 수 있습니다.
이 외에도 exec명령어를 통해서 Pod에서 sh명령어를 실행할 수 있습니다.
그리고 kubectl logs명령어를 통해서 Pod의 로그를 확인할 수도 있습니다.
멀티 컨테이너 파드와 사이드카 패턴
먼저 동일 파드에서 여러 컨테이너를 사용하더라도 모두 네임스페이스를 공유하기 때문에, 동일 Pod의 컨테이너는 클러스터를 구성하는 노드에 흩어지는 것이 아니라, 모두 같은 노드에 스케쥴링 되어 실행됩니다.
사이드카 패턴
또한 사이드카 패턴이란 실제 차에서의 역할과 비슷합니다. 메인 컨테이너를 보조하는 컨테이너와 같이 실행되는 구조입니다.
가장 많이 사용하는 유즈 케이스는 Filebeat와 같은 로그 에이전트로 파드 로그를 수집할 수 있습니다.
실습
이제 기존의 리소스들을 다 지우고 multi.yaml에 명시되어 있는 리소스들을 선언형으로 생성해보도록 하겠습니다.
이전과는 다르게 hello라는 Pod에 debug라는 컨테이너를 추가했습니다.
apply하고 확인하면 2/2로 잘 hello안에 nginx, debug컨테이너가 잘 돌아가고 있는 것을 보실 수 있습니다.
그 외에도 kubectl describe pod [ Pod name ]을 통해서 pod의 정보를 확인할 수 있는데, hello Pod에는 Containers >> nginx, debug가 있는 것을 확인할 수 있습니다.
그리고 exec로 명령어를 날릴 수 있는데 -c옵션을 주지 않으면 기본 컨테이너인 nginx컨테이너로 접근하게 돕니다. 그리고 이 둘은 같은 네임스페이스를 공유하기 때문에 80번 포트로 debug쉘에서 curl요청을 보내게되면 nginx웹서버가 잘 응답받아지는 것을 확인할 수 있습니다.
위는 간단한 구조라고 할 수 있습니다. 같은 네트워크를 공유하기 때문에 위와같은 결과가 가능한 것입니다.
그 외에도 logs과 -c옵션을 통해서 pod안의 컨테이너 로그를 확인할 수 있게 됩니다.