[Docker] Kubernetes 요약
1. Kubernetes
1) 오케스트레이션 툴
도커 컨테이너는 하나의 애플리케이션처럼 동작하는 반면, 가상머신은 내부에 독자적인 게스트 운영체제가 존재하며 도커 컨테이너에 비해 성능을 발휘하기 어렵다.
기존에는 Dockerfile을 빌드하여 이미지를 만들고, 이미지를 저장소(Docker Hub)에 푸시한 뒤 애플리케이션이 실행될 곳에서 풀을 하고 이미지를 실행시키면 컨테이너가 된다. 그리고 이 과정은 Jenkins에서 빌드, 배포 스크립트를 하나하나 작성하여 진행하였다. 하지만 만약 배포될 서버가 추가될 경우, 해당 서버에 맞는 스크립트를 추가해주어야 한다. 더 나아가 배포 방식이 변경이 되면 배포 스크립트를 찾아 수정을 해주어야 한다. 이렇게 수정된 스크립트를 테스트하는 것은 어려워진다.
실제 서비스를 운영한다면, 이런 식으로 관리해야할 서버는 매우 많아진다. 이렇게 도커 컨테이너가 많아지면 인프라 관리에 어려움이 생기게 된다. 이러한 문제를 해결하는 툴이 바로 오케스트레이션 툴이다.
오케스트레이션 툴은 조금 더 범용적인 툴이다. 사실 우리는 모두 오케스트레이션 툴을 이미 경험해보았다. GCP에서 인스턴스를 만들거나 삭제할 때 구글에서는 해당 요청을 오케스트레이션 툴로 처리한다. 즉, 가상머신을 생성하거나 제거하는 등의 관리를 하는 것이다.
2) Kubernetes
여기서 도커와 같은 컨테이너들을 전문적으로 오케스트레이션 하는 툴로 컨테이너 오케스트레이션이 있다. 그중 가장 대표적이고 널리 사용되고 있는 것이 바로 Kubernetes이다.
Kubernetes는 배의 키를 잡는 사람인 조타수의 그리스어 단어라고 한다. 그리고 Kubernetes는 'K'와 's'의 사이에 8개의 글자가 있다는 의미로 K8s라고도 불린다. 이 프로젝트는 원래 구글 내부에서 컨테이너 오케스트레이션 툴로 사용하던 것을 오픈소스화 한 것이다.
3) 클러스터, Master 노드, Worker 노드
클러스터는 Worker 노드와 Master 노드로 이루어져 있다. 각각의 노드는 물리적인 서버일 수도 있고, 가상의 서버일 수도 있다. 결국, 네트워크로 구분되는 하나하나의 서버이다.
Master 노드는 클러스터 전체를 관리하며 직접 애플리케이션을 실행시키지는 않는다. Master 노드는 Worker 노드의 수에 따라서 3에서 7개 정도까지 달라지며 반드시 홀수여야한 한다. 테스트를 위한 클러스터일 경우 Master 노드가 1개여도 무관하다. 홀수로 이루어져 있어야 클러스터 상태를 관리할 때 컨센서스를 이룰 수 있다. 여기서 컨센서스는 합의라는 뜻으로 Master 노드간의 투표를 뜻한다. Master 노드의 개수가 짝수일 경우에는 동투표가 동점이 될 수 있기 때문에 홀수로 이루어져야 한다.
Worker 노드는 직접 애플리케이션을 실행시키는 노드이다. Master 노드의 관리를 받으며 Worker 노드의 개수가 몇 개가 되어도 무관하나 Kubernetes에서 제공하는 네트워크 플러그인에 따라서 수백에서 수천개 까지 제한이 있다.
4) Deployment
Deployment는 Master 노드에 생성이 되고 Worker 노드에 컨테이너화된 애플리케이션이 떠 있는지 모니터링한다. 만약 노드가 다운되거나 삭제되어서 애플리케이션이 동작하지 않는 경우 다른 노드에 애플리케이션을 생성한다. 이러한 기능은 Jenkins로 구현하기에는 어렵다. Deployment는 Yaml 파일로 간단하게 구현이 가능하다.
5) Pod
하나의 Pod에는 여러 개의 애플리케이션이 뜰 수 있다. (하나의 Pod는 한 개의 애플리케이션이 아니다.) 또한 Kubernetes에서 Pod부터는 클러스터 내부 IP를 가지게 된다. 단, 여기서 실행 중인 애플리케이션을 클러스터 외부로 서비스를 할 수 없다. 클러스터 외부로 서비스하기 위해서는 서비스가 필요하다. (Pod 단위로 스케일링)
6) Service
서비스는 Pod를 묶어서 외부에 노출시키며 간단한 라우팅만을 지원한다.
7) Ingress
Kubernetes로 클러스터를 구성하다 보면 다양하게 애플리케이션을 띄우게 되며 로드밸런싱과 HTTPS 처리가 필요할 때에는 Ingress를 사용한다. Ingress는 클러스터 외부에서 트래픽을 받고 라우팅 룰에 따라서 서비스로 라우팅을 수행해준다. 거의 NginX가 수행하는 역할과 동일하다고 생각하면 된다.