
이번에 쿠버네티스 인 액션 책을 바탕으로 쿠버네티스에 관해서 공부하게 되어 관련 내용을 정리하려한다.
이전에 잠깐 쿠버네티스를 세팅하고, 운영했었지만, 그때는 잘 모르는 상태로, 주먹구구식으로 진행한 게 많아 아쉬운 점이 많았다. 이번에 다시 쿠버네티스를 사용할 일이 있어 조금 더 공부를 해보고 진행하려 한다.
이번 글에서는 쿠버네티스가 무엇인지, 왜 사용하는지 정리하고,
도커와 컨테이너에 대해서 정리하려 한다.

이전에는 대부분의 소프트웨어 애플리케이션은 모놀리스 아키텍처로 구성됐었다.
하나의 거대한 서버에 모든 기능이 들어가 있게 구성이 되어있었다.
이 경우 특정 서비스에 트래픽이 몰리는 경우 그 서버의 리소스를 증가시켜야 했고, 서버의 사소한 변경이 생기더라도 전에 서비스를 업데이트해야 하는 일이 발생했다.
이런 문제를 해결하기 위해 요즘은 소프트웨어 애플리케이션을 서비스별로 서버를 분리해 구성하는
마이크로 서비스 아키텍처 (Micro Service Architecher, 이하 MSA)를 사용하는 일이 많아졌다.
이렇게 분리된 MSA는 서비스별로 개발, 배포, 업데이트, 확장을 진행할 수 있어 급변하는 비즈니스 요구사항을 충족시킬 수 있도록 신속하게, 자주 업데이트를 진행할 수 있게 되었다.
(조금 더 자세한 MSA에 대한 글은 여기에서 확인할 수 있다)
다만 시스템을 구성하는 서버의 수가 많아지며 배포하고, 운영해야하는 일이 어려워지게 되었다.
많은 서버를 동시에 운영해야하고, 한 곳에서 문제가 발생하면 다른 곳에 영향을 끼치기에
모든 운용중인 서버를 자동으로 관리할 수 있는 해결방안이 필요했고, 쿠버네티스를 통해 이런 문제를 해결할 수 있게 되었다.
위에서 MSA로 구현된 시스템이 많은 서버를 가지게 되면 이를 자동으로 관리할 수 있게 하는게 쿠버네티스라고 하였다.
그럼 정확하게 쿠버네티스가 무엇을 하는지 정리해보았다.
특정 요소로의 트래픽이 많아지면, 그 트래픽을 로드밸런싱하고, 그 요소를 추가로 배포하여 트래픽을 분산할 수 있도록 한다.
변화하는 트래픽에 맞춰 안정적인 운영환경을 제공한다.
로컬 저장소, 공용 클라우드 공급자와 같이 원하는 저장소 시스템을 자동으로 탑재할 수 있다.
새로운 업데이트가 있는 경우 서비스를 중단하지 않고, 설정한 속도에 맞춰 변경할 수 있게한다.
특정 요소가 업데이트 되는 경우, 업데이트된 정보를 반영한 요소를 새로 만들고 기존의 요소를 제거하여 업데이트를 적용할 수 있게 한다.
이전 버전으로 롤백이 필요한 경우에도 동일한 방법으로 적용할 수 있다.
서비스를 구성하는 각 요소별로 필요한 자원들을 지정하고, 자동으로 관리한다.
각 요소가 필요로 하는 CPU와 RAM(메모리)를 쿠버네티스에 지시하고, 쿠버네티스는 이런 자원들을 잘 사용할 수 있게 해준다.
예기치 못하게 중단된 요소 같이 실패한 요소나, 응답이 없는 요소들을 다시 시작하고, 자동으로 실행한다. 그리고 이런 동작을 클라이언트에 보여주지 않는다.
다른 곳에 노출 되면 안되는, 주로 환경변수로 관리되는 암호, OAuth 토큰, SSH키, 데이터베이스 관련 정보를 저장하고 관리할 수 있다.
위에서 언급한 쿠버네티스가 관리하는 요소는 컨테이너를 의미한다.
쿠버네티스는 각 애플리케이션을 격리하는 기능을 제공하기 위해서 리눅스 컨테이너 기술을 사용한다.
쿠버네티스에 대해서 공부하기 전에 컨테이너에 대해서 알고 있어야 하므로, 여기서 정리하고 넘어가려한다.
초창기에는 애플리케이션을 배포하기 위해 직접 기계로 된 서버를 구입하여 그곳에서 실행했었다.
하나의 물리 서버에서 여러 애플리케이션을 배포할 때, 각 애플리케이션의 리소스를 정의할 방법이 없어 리소스 할당의 문제가 발생했다.
이를 해결하기 위해 가상화를 시작하였다. 하나의 물리 서버에서 여러 가상 시스템을 실행하여 각 애플리케이션을 격리할 수 있었고, 물리 서버의 리소스를 효율적으로 활용할 수 있다는 장점이 있었다.
이런 가상 시스템을 가상머신 (Virtual Machine, 이하 VM)이라 하며, 각 VM에는 자체 운영체제를 포함하여 모든 구성요소를 실행하는 하나의 완전한 머신이다.
다만 이 경우에도 애플리케이션이 작아지고, 수가 많아지는 경우 애플리케이션마다 VM을 구성하고 관리하기에는 작업자의 작업량도 늘어나고, 하드웨어 리소스도 낭비되는 문제가 발생했다.
이런 가상화의 문제를 해결한 것이 바로 리눅스 컨테이너 기술이다.
리눅스 컨테이너는 동일한 호스트 시스템에서 여러 개의 서비스를 실행할 수 있고, 동시에 서로 다른 환경을 만들어 줄 수 있으며, VM처럼 애플리케이션의 격리를 제공한다.
컨테이너의 도입으로 VM과 같은 장점을 제공해 주면서 더 적은 리소스로 여러 애플리케이션을 관리할 수 있게 되었다.

VM과 리눅스 컨테이너를 비교했을 때 그림이다.
VM을 사용하는 경우 Host OS위에 VM을 사용하기 위한 Hypervisor를 설치해야 하고,
그 위에 VM을 구성한다.
VM안에서도 App을 실행시킬 수 있는 Guest OS를 설치하고, 실행해야 한다.
반면 리눅스 컨테이너의 경우 Host OS위에서 실행되는 하나의 격리된 프로세스이기에 그저 Host OS만 있으면 된다. 리눅스 컨테이너 안에서도 App을 위한 Guest OS를 설치하지 않아도 되기에 VM을 사용한 경우보다 더 많은 App을 적재하고 실행할 수 있다.
자세한 건 추후 컨테이너에 대한 내용만 따로 정리하려 한다.
간단하게 정리하자면 리눅스 네임스페이스로 구분하는 것이다.
리눅스 시스템 안에서 여러 네임스페이스를 생성하고, 리소스를 구성할 수 있다.
프로세스가 실행될 때, 동일한 네임스페이스 안에 있는 리소스만 볼 수 있어 컨테이너 격리가 가능하다.

위에서 설명한 컨테이너 기술을 사용하기 위해 Docker를 사용할 수 있다.
Docker는 애플리케이션을 패키징하고, 배포, 실행하기 위한 플랫폼이다.
애플리케이션을 애플리케이션이 실행되기 위한 모든 것들을 포함하여 패키지화할 수 있다.
이렇게 애플리케이션을 패키징한 것을 이미지라 한다. 애플리케이션에서 사용할 수 있는 파일시스템과 이미지가 실행될 때 실행되어야 하는 실행파일 경로 같은 메타데이터들을 포함한다.
생성한 이미지를 저장하고, 다른 사람이나 컴퓨터에 쉽게 전할 수 있는 저장소를 레지스트리라고 한다.
애플리케이션을 패키징한 이미지를 바탕으로 실제로 실행한 것을 컨테이너(리눅스 컨테이너, 이하 컨테이너)라고 한다. 이때 이미지는 읽기 전용으로만 사용하고, 실행되며 발생하는 모든 변경 사항은 컨테이너에 저장된다.
실행 중인 컨테이너는 도커에서 실행하는 호스트에서 실행되는 프로세스이지만, 호스트와 호스트에서 실행 중인 다른 프로세스와 완전히 격리되어 있다.
이렇게 쿠버네티스가 왜 생겨났고, 어떤 기능을 제공하는지 먼저 알아보았다.
그리고 쿠버네티스에서 관리하는 컨테이너가 무엇이고, 왜 사용하는지, 주요 컨테이너 기술 플랫폼인 도커에 대해서 간단하게 알아보았다.
이후 쿠버네티스가 어떻게 구성되어 있는지 아키텍처를 알아보고, 쿠버네티스를 테스트해 볼 수 있는 환경을 구축해 보려 한다. 그리고 시간이 된다면 쿠버네티스의 Pod까지 정리해 보려 한다.