다시 정리하는 쿠버네티스 : 컴포넌트 개념 #1
개인적으로 공부한 내용을 정리하고 있는 글입니다. 글에 잘못된 부분이 있다면 인상을 쓰기보다는 제가 상처받지 않도록 부드럽고 자유롭게 의견 부탁드립니다. :-)
# 마스터, 노드, 파드(pod) 개념 잡기
쿠버네티스의 가장 큰 핵심 기능은 컨테이너 오케스트레이션이다. 여러 개의 컨테이너의 상태를 확인하고 관리한다는 의미인데 트래픽의 증가 처럼 리소스가 더 필요한 상황이 되면 컨테이너를 증설(일종의 스케일-아웃 / 수평 확장)하기도 하고, 비정상 상태에 빠진 컨테이너를 종료하거나 새로운 컨테이너를 생성하는 등의 역할을 수행한다는 개념이다. 오케스트라에서 지휘자가 단원들을 지휘 하듯이 말이다.
이렇게 컨테이너를 오케스트레이션 가능하게 만드는 첫 번째 개념이 컴포넌트 집합이라고 할 수 있겠는데 바로 "마스터 컴포넌트 집합(master components)"과 "노드 컴포넌트 집합(node components)"이다. 쿠버네티스를 공부하면 클러스터와 함께 제일 먼저 맞닥드리는 용어이다. 여기서 노드는 오케스트라의 단원처럼 취급되며 쿠버네티스 개념으로는 실제 서비스(애플리케이션 단위)가 돌아가는 공간이다. 즉, 워커-노드 라고 생각하면 쉽다. 한편 마스터 컴포넌트 집합(혹은 마스터 노드)은 워커-노드 들의 상태를 관리하기 위한 컴포넌트로 구성이 된다. 개념적으로 보면 하나의 노드는 물리적(혹은 가상의) 하드웨어 한 개로 취급되는데 요즘같은 퍼블릭 클라우드 세상에서 보면 노드와 가상머신( AWS로는 EC2, GCP는 GCE )는 1:1 매핑이라고 보면 된다. 이건 마스터건 워커-노드건 구분이 없다. 필요에 따라 워커-노드는 N개까지 증설(스케일-아웃)될 수 있는데[1] 이는 마스터 노드도 마찬가지 개념이다. 다만 역할의 차이가 있을 뿐. 다시 정리하자면 아래와 같다.
장황해보이지만 하나씩 정리해보자. 우선 쿠버네티스는 최소 3개의 노드가 권장되는데, 이에 맞도록 마스터를 1개, 워커노드를 2개로 구성한 그림이다. 그리고 컴포넌트 집합들 안에 있는 회색 배경의 박스는 컴포넌트 단위이다. 워커-노드를 살펴보면 큐브릿(kubelet), 프락시(proxy), 파드(pod) 컴포넌트로 구성된 것을 확인할 수 있다. 마스터 우측으로 kubectl 은 쿠버네티스를 설치하면 사용할 수 있는 CLI( command line interface )인데 이 명령어를 통해 우리는 쿠버네티스트 모든 기능을 사용하고 제어할 수 있게된다.
kubectl을 통해 입력되는 명령어는 마스터로 전달되고 REST 컴포넌트에서 각 워커노드의 kubelet에 의해 pod까지 전파된다. 예를들어 kubectl get pods 명령으로 전체 pods를 가져온다고 생각하면 다음과 같이 빨간색 화살표처럼 전파될 것이다. 이를통해 우리는 노드에 있는 kubelet이 각 파드의 상태를 알고 있으며 마스터와 통신해서 파드를 제어할 수 있게 해준다는 사실을 알 수 있다.
파드(pod)는 서로 다른 여러 개의 컨테이너를 갖을 수 있으며 pod 내부에 컨테이너는 가상 IP 대역과 포트 공간이 같다. 이 말은 localhost(127.0.0.1)이나 표준 IPC( inter-process communication )을 통해 서로 통신할 수 있다는 의미이다. 이걸 곱씹어보면 서로 다른 pod 는 포트 공간이 다르다는 의미로, 같은 노드 안에 있는 서로 다른 파드의 컨테이너가 동일한 포트를 열 수 있다는 뜻이다. 일반적으로 물리적인 한 개 서버에서 같은 포트를 두 개의 애플리케이션이 LISTEN하고 있는 것은 쉽게 상상이 되지 않지만 이런게 쿠버네티스 노드 안에서는 가능하다[2]. 또한 pod 내부에 모든 컨테이너는 pod가 구동되는 노드의 공유 저장소에 접근이 가능하며 이 저장소는 각 컨테이너로 마운트 된다. virtualbox로 예를 들자면 가상머신이 호스트머신의 특정 디렉터리를 공유 디렉터리로 사용할 수 있는 것과 유사한 맥락이다. docker가 친숙한 사람들에게는 호스트의 볼륨을 컨테이너를 생성할 때 마운트 시키는 것과 같다고 보면 된다. nfs( network file systems )를 생각하면 더 와닿을까? 굳이 그림으로 표현하자면 아래 빨간 테두리 범위쯤이 되겠다.
파드는 stateless 특성을 따르며 필요에 따라 언제든지 교체되거나 삭제될 수 있다. 이때는 pod 자체 저장소(노드의 공유 볼륨이 아닌)가 함께 사라지게 된다.
# 클러스터와 네임스페이스
클러스터는 이미 위에서 설명이 되었다. 바로 위 그림처럼 마스터-노드의 묶음이 클러스터 단위이며며 디스크 볼륨과 네트워크 등의 개념을 모두 아울러서 통칭된다. 공식문서에는 쿠버네티스 클러스터를 아래와 같이 표현한다.
클러스터가 이렇듯 물리적인 개념이라면 네임스페이스는 그 안에 들어있는 논리적인 분할 개념이 된다. 클러스터 안에는 N개의 네임스페이스가 존재할 수 있고, 논리적으로 나누어져있지만 공용 인터페이스를 통해 서로 다른 네임스페이스간 통신이 허용된다. 그럼 네임스페이스는 언제 사용하는게 좋을까? 거대한 클러스터 자원을 복수의 사용자가 나눠서 사용할 때 유용하다. 그렇지 않은 경우에는 네임스페이스는 고려할 필요가 전혀 없다. 한편 위에서 이야기한 대부분의 컴포넌트 단위는 네임스페이스에 종속되기 때문에 네임스페이스가 변경되면 접근이 안된다는 점을 인지해야 한다. 네임스페이스에 속하는지 여부는 kubectl api-resources --namespaced=true 혹은 --namespaced=false 로 확인 할 수 있다.
네임스페이스의 컨셉에 대한 글을 여기 공식문서를 통해 확인할 수 있고, 다음 글을 통해 조금 더 상세히 다루도록 하겠다.
# 마무리
항상 겉만 핥아오던 쿠버네티스를 사내 스터디를 통해 제대로 딥-다이브 해보기로 새해 목표를 잡았다. 현재의 배경 지식 수준을 이야기하자면 컨퍼런스 어딘가에 가서 쿠버네티스 이야기를 듣자면 어느정도는 고개를 끄덕일 수 있는 상태. 하지만 실제로 열어보면 심도 있는, 혹은 얕은 질문에도 정확한 답변을 할 수 없는 상태 되시겠다. 말하자면 "pod 는 하나 이상의 컨테이너를 갖을껄?" 처럼 말이다. 우선 이 글을 작성하기 위해 개념을 정리하는데 인터넷에서 흔히 접할 수 있는 개인 블로그 글은 가급적 피했다. 온라인상에 여러 고수의 고견도 좋지만 공식문서만 못하거니와 쉽게 풀어쓰다보니 잘못된 것도 많고 오히려 더 깊은 미로의 수렁에 빠지기 쉬웠기 때문이다. 말하자면 제대로 알지 못하는 상태에서 작성된 글이거나, 혹은 빠삭하게 설명은 하는 것 같은데 나와 같은 초보는 받아들이기 어려운 그런 글 말이다. 한편, 좋은 글인지 판단하는 잣대도 갖지 못한 상태였으니까.
이번 글에서는 쿠버네티스에서도 겉으로 드러나는 큰 개념들에 대해서만 다루었다. 그 뒤에 숨어 있는 서비스, 인그레스, 리플리케이션 등 쿠버네티스를 지탱하는 핵심 기술과 개념에 대해서는 차근차근 살펴보도록 하자. 최대한 어려운 용어는 배제하고 쉽게 비유해서 글을 작성하려고 노력했는데 나와 배경지식이 다른 사람에게는 어떻게 읽힐지 모르겠다. 아무튼 나 스스로를 포함해서 누군가에게는 도움이 되었기를 바란다.
[1] : 관리 대상인 워커-노드의 리소스 상태에 따라 Auto scaling 설정도 가능하다. 예를들면 워커-노드를 최소 3개, 최대 10개로 설정하고 그 범위 내에서 리소스 상태에 따라 오토 스케일링 시킬 수 있는 개념이다.
[2] : 포트 정보가 호스트 머신에서 감춰지는 부분에 대해서는 별도의 포스트를 통해 다루도록 한다.