[Kubernetes] 1. Container Deployment와 Kubernetes

저에게 있어 쿠버네티스는 Docker Swarm을 지나 이전부터 사용하고 있었던 컨테이너 오케스트레이션 툴이었습니다. 최근에 이직을 한 회사에서 쿠버네티스를 이용하여 시스템을 구성하고 서비스를 운영하게 되어 주 오케스트레이션 툴로 쿠버네티스를 사용하게 되었고, 이 때부터 Docker Swarm 보다는 Kubernetes로 시스템을 구성하는 일이 자주 생겨났습니다.

 

이 글은 Docker를 자주 사용하지만 Kubernetes에 대해서는 잘 모르고, 그리고 사용을 고려해보고 싶은 분들에게 드리는 글의 시작입니다. 

 

 

 

Container Deployment으로 거슬러 올라오기까지..

Kubernetes는 Go 언어를 기반으로 Google에서 개발하여 2014년에 공개된 Container Orchestration tool입니다. 먼저 컨테이너에 대해 간단히 이야기 하자면, 컨테이너는 OS의 자원을 공유한 형태로 애플리케이션을 배포하기 위해 그 환경을 만들어낸 형태를 말합니다. 

 

그렇다면 우리는 왜 이러한 환경을 거슬러 올라온 것일까요?

 

위 사진은 초기 우리가 서버 애플리케이션을 클라이언트에 배포하고자 할 때의 모습을 거쳐 가상 머신 -> 컨테이너로까지 변화하기의 과정입니다.

 

  • Traditional Deployment

    이전의 서버 애플리케이션은 모놀리틱 아키텍처로 구성되어 있었고, 모든 작업이 하나의 애플리케이션으로 개발되어, 물리적인 서버에서 실행하면 되는 구조였습니다. 그러나 클라이언트의 요구 사항이 점점 많아지고, 리소스가 방대해지면서 다른 애플리케이션이 한 물리 서버에 동작해야만 했는데, 그러면서 서로간의 리소스 점유 문제가 발생하게 됩니다.

  • Virtualized Deployment

    한 물리 서버에서 서로 다른 애플리케이션이 실행될 경우, 시스템의 자원을 서로가 가지려는 점유 문제 때문에 생겨난 것이 바로 가상화 환경입니다. 하드웨어 서버 한 대에서 CPU와 메모리 등의 시스템 자원을 분리하여 사용하고, 해당 공간에 애플리케이션을 분리 시켜 시스템 자원의 분배를 고르게 진행하고, 점유 문제를 막으려는 것이죠.

    더 좋은 것은 애플리케이션 실행 환경을 다시 구성할 때마다 운영체제 등의 시스템 소프트웨어를 수동으로 설치할 필요 없이 이미지를 저장하는 형태로 쉽게 배포할 수 있다는 점이 있고, 서버 운영을 위해 물리적인 서버를 한 대 더 둬야하는 비용을 확실하게 절감시켜주는 요소가 됩니다.

  • Container Deployment

    가상화 배포 방식을 통하여 서로 다른 서버 애플리케이션 간의 리소스 분쟁을 막고, 서버의 비용을 많이 줄이는 데는 큰 도움이 되었지만 가상화라는 기술의 한계가 있었습니다. 가상화 기술의 애플리케이션 별로 환경을 나누어 쓰는 방식이 하드웨어의 리소스를 독립시키는 데 까지 자원을 소모하기 때문에 시스템의 제 성능을 끌어올리지 못한다는 것입니다.

    리눅스 진영의 Xen이나 KVM, QEMU를 포함하여 윈도우 진영의 Hyper-V 모두 가상화 솔루션입니다. 그들 모두 시스템의 자원을 고르게 분배하지만 CPU 등의 주요 자원들을 나누지만 그들의 리소스를 할당 받기 위해 많은 자원을 소모합니다. 

    그래서 나타난 것이 바로 컨테이너 배포 방식입니다. 컨테이너는 가상화 배포 방식과 유사하지만 다른 점은 가상화 기술을 통해 새로운 가상희 하드웨어 환경을 만들기 보단, 로드된 운영체제 자원을 공유하여 새로운 운영체제 환경을 만들어내는 기술입니다. 


간단하지만 심층적으로 우리가 컨테이너의 서버 운영 방식을 만들기까지의 과정을 살펴봤습니다. 언듯 보기에는 가상화 배포 방식에서 성능 차이 극복을 위해서만 컨테이너 배포 방식이 도입된 것 뿐인 듯한데, 그 외에도 다른 장점이 있을 것 같네요. 어떠한 좋은 점이 있을까요?

 

  • 쉬운 이미지 생성

    가상화 솔루션에서 이미지를 만들기 위해서는 단순히 애플리케이션을 설치하고가 끝이 아닙니다. 내가 어떤 운영체제의 환경에서 어떤 운영체제의 설정을 가지고 해야하는지 등의 정보가 모두 담겨져 있어야 하며 이는 소프트웨어 엔지니어가 가진 역량보다 더 많은 역량을 요구합니다. 

    그러나 컨테이너 배포 방식에서는 이미 설치된 운영체제의 자원을 공유하여 새로운 환경을 만들기 때문에 운영체제와 그 설정은 모두 메인 운영체제를 따르게 됩니다. 여기서 시스템의 자원을 어디까지 사용하는 것인지를 조정하게 되는 것이죠.

    이렇게 하면 소프트웨어 엔지니어가 가진 소프트웨어 개발 기술과 정해진 환경 설정만 맞춰주면 쉽게 운영 서버 한 대를 만들 수 있게 됩니다.

  • 개발, 테스트, 운영 환경 어디서든 똑같은 환경에서 동작하는 일관성

    컨테이너 배포 방식은 어떤 이미지를 만들어도 메인 운영체제의 환경만 변하지 않는다면, 클라우드, 랩톱, 데스크톱 어디서든지 동일하게 구동된다는 장점이 있습니다.

    가상화 솔루션의 경우, 소프트웨어 엔지니어가 이를 테스트해보기 위해 솔루션 매니저 (Hyper-V 등)을 설치하고, 이 설정에 따라야 합니다. 

    그러나 컨테이너는 메인 운영체제만 같다면 개발자의 컴퓨터든, 운영자의 서버이든 어느 곳에서든지 같은 환경에 띄워지기 때문에 기존의 전통적인 배포와 가상환경에서의 배포처럼 서버의 설정이 달라져서 생기는 이슈를 대폭 줄일 수 있다는 장점이 있습니다.

  • 느슨한 운영이 가능한 마이크로서비스

    마이크로서비스는 각각 애플리케이션을 비즈닉스 로직별로 개발/운영하는 방식입니다. 각각의 서비스를 비즈니스 로직별로 나누기 때문에 배포 단위가 더 많아지게 되는데요. 컨테이너 방식은 가상화에 비해 배포 속도가 빠르고, 구성이 간단하기 떄문에 마이크로서비스에 있어 적합한 솔루션이라고 할 수 있습니다.

 

 

 

Container Orchestration Tool이 필요한 이유

우리가 컨테이너를 사용하는 이유는 위에서 봤던 것처럼 여러 개의 서버 애플리케이션을 효율적으로 운영하기 위함입니다. 예를 들어, 일반적인 홈페이지의 경우 파일로 데이터를 관리한다면, 운영체제에서 제공하는 파일 시스템과 웹 서버를 사용하면 되지만 현대의 서비스는 파일 시스템 보다도 더 관리가 쉽고, 더 많은 데이터를 효율적으로 관리하는 데이터베이스(DB)를 사용합니다.

 

그러나 데이터베이스를 사용하려면 데이터베이스를 운영할 수 있는 소프트웨어(미들웨어)가 필요하고, 이들 또한 역시 리소스를 사용하게 됩니다. 따라서 서버 애플리케이션이 포함된 이미지 하나를 배포하는 것만으로는 하나의 서비스가 만들어지지 않기 때문에 이러한 복합 구성의 컨테이너를 관리하기 위한 툴이 필요합니다.

 

일반적으로 컨테이너 매니저만이 존재할 경우, 자주 사용하는 컨테이너 이미지를 컨테이너 매니저가 보관해뒀다가 필요하면 꺼내 쓰는 방식으로 단일 서비스를 만들어낼 수 있습니다. 

 

그러나 사용자가 많아지고, 이에 따라서 로드 밸런싱 등을 수행하려면 어떻게 해야할까요? 컨테이너 매니저를 통해 내부 네트워크를 생성하고, 각각의 인스턴스를 만들어서 로드 밸런서를 구축하는 등 여러가지 작업을 해줘야 하는데, 이들을 구성하고, 다음에 재구성하려면 배보다 배꼽이 더 크겠죠?

 

Orchestration tool은 이러한 일련의 과정을 쉽고 빠르게 배포할 수 있도록 도와줍니다. 위의 그림은 Orchestration tool을 Kubernetes로 사용했을 떄의 모습입니다. 한 서비스 단위를 Deployment로 잡고, 인스턴스의 단위를 Worker 그리고 각각의 컨테이너 단위를 Pod라고 합니다. 자세한 내용은 Kubernetes 2번째 이야기에서 다뤄보도록 하겠습니다.

 

위와 같은 방식으로 한 서비스의 Deployment 구성을 이미지화하고, 서비스를 실행시에 해당 파일을 읽어 컨테이너 엔진에서 자동으로 생성할 수 있도록 구성하여 복잡하고 많은 리소스로 분할된 서비스 하나를 실행할 때도 쉽게 할 수 있도록 도와줍니다.

 

 

 

 

Kubernetes

쿠버네티스는 이러한 컨테이너의 운영을 원활히 하기 위해 만들어진 Container Orchestration tool 입니다. 컨테이너의 역사는 이전부터 계속 되었지만 활성화가 된 것은 아주 최근이며, 컨테이녀 오케스트레이션 도구 또한 쿠버네티스 이외에도 Docker Swarm 등 다양하게 존재해왔습니다.

 

Kubernetes는 다른 오케스트레이션 도구에 비해 기능이 굉장히 많습니다. 특히 제 경험에 있어서는 마이크로서비스에 적합한 도구라고 봐도 무방할 정도로 그 기능이 굉장히 많으며 최근에는 AWS, Google Cloud Platform, Azure 등 다양한 클라우드 플랫폼에서도 지원하여 이식성이 굉장히 높습니다. 

 

Kubernetes에서는 마이크로서비스를 하기 위한 모든 요소들이 포함되어 있습니다. 서비스 이용을 위해 도메인 네임을 설정할 때도 일반 컨테이너에서 운영한다면 별도의 nginx 웹 서버에서 제공하는 리버스 프록시, 가상 호스트를 설정해야 하지만 Kubernetes에서는 이러한 모든 기능을 지원하기 떄문에 이러한 웹 서버나 프록시를 별도로 구성힐 필요가 없습니다.

 

마이크로서비스에서는 비즈니스 로직별로 애플리케이션을 개발하기 때문에 로드 밸런싱을 한다면, 각각의 컨테이너가 어떤 서비스인지 알아야 할 필요가 있습니다. 그래서 사용하는 것이 바로 Service Discovery입니다. Spring Cloud에서는 이러한 Service Discovery로 Hystrix를 제공합니다. 

 

Kubernetes에서는 Service Discovery 또한 제공해주기 때문에 우리는 이를 가져다가 사용하기만 하면 됩니다. Spring Cloud가 Java 환경에 종속적이라면, Kubernetes는 어떤 언어, 플랫폼이든 종속받지 않는다는 것이 매력인 것이죠.

 

컨테이너를 사용함에 있어 특히 DB를 사용할 때 Persistence Layer 부분을 신경써야 해줘야 합니다. 단일 컨테이너를 사용할 때는 Volume을 별도로 만들어 영구 저장소를 별개로 만들었지요.

 

Kubernetes 또한 로컬 저장소 혹은 클라우드 공급자에서 제공하는 저장소처럼 원하는 Persistence Layer를 구축하고, 이를 쉽게 마운트 할 수 있습니다. 컨테이너가 소멸되더라도 별도의 볼륨을 사용한다면 영구 저장할 수 있다는 점이 매력이며 특히 데이터베이스에서는 DB 버전을 업그레이드 할 경우, 매번 DB를 Unmount하고, 다시 재마운트해야 하는 불편함을 덜어줍니다. 

 

 

 

 

마치며...

여기까지 컨테이너 배포 방식으로 서비스를 운영하고 배포하는 것부터 시작하여 쿠버네티스에 대해 간단히 살펴봤습니다. 컨테이너 배포 방식을 설명하면서 우리가 왜 Docker를 사용해야만 하는지, 그리고 Docker만으로도 충분했던 이 시점에 Kubernetes가 왜 화두가 되고 있는지를 이야기 해보기 위해 이 글을 쓰게 되었습니다.

 

Kubernetes를 회사에서 사용하게 되면서 MSA에 대해 선제 공부를 하고 사용했던 경험이 있었던 것이 굉장히 도움이 많이 되었습니다. Kubernetes의 대부분의 컴포넌트들은 마이크로서비스와 관련이 깊었고, 우리가 평소 인프라 환경에서 많이 불편하다고 생각했던 부분을 쉽게 만들려고 노력한 부분이 많이 눈에 띄었습니다.

 

그러나 Kubernetes는 여전히 그 기능이 방대하고 복잡합니다. 모든 기능을 다 사용해보고 소화해보려면 많은 서비스를 배포해봐야 하고, 특히 마이크로서비스 아키텍처에 대한 이해가 확실해야 합니다. 그리고 그것이 왜 필요한지, 우리 서비스에 적합한지를 검토해보는 것도 하나의 역량이라고 생각합니다.

 

다음 포스트에서는 Kubernetes의 주요 컴포넌트들에 대해 이야기해보도록 하겠습니다.

 

 

comments powered by Disqus

Tistory Comments 0