먼저, 개념을 간단히 설명하면 "Conatiner를 오케스트레이션 하는 도구"이다.
뭔 말인지 1도 모르는 단어들의 나열이다. 이를 알기 위해서는 단어들에 대한 개념을 알 필요가 있다.
먼저, 중요하게 봐야할 점은 Docker 설명에서 "대표적인 것"이라는 의미이다.
사실, Kubernetes를 Docker 여러 개를 관리하기 위한 도구라고 알고 있는 경우도 많은데, 어디까지나 Docker는 Container Runtime의 대표적인 도구일 뿐이다.
즉, 다른 Container Runtime도 Kubernetes를 통해 관리받을 수 있다는 의미이다(물론, 대부분 Docker를 활용하는 것 같긴 하다)
Docker는 "대표적"인 도구일 뿐, 컨테이너 규격은 표준화되어 있기 때문에 Docker가 아닌 다른 컨테이너 런타임들도 도커로 만든 컨테이너를 활용할 수 있는 것이다
자, 마지막으로 쿠버네티스의 정의인 "Conatiner를 오케스트레이션 하는 도구"를 다시 읽어보자.
위 정의에 따르자면 쿠버네티스는 "여러 서버에 포함된, 앱과 환경을 감싼 객체를 관리하는 도구"를 의미한다
Container와 가장 많이 비교되는 것이 VM이다.
그렇다면 VM과 Container의 차이를 잘 알고, VM의 어떤 단점으로 Container가 출시되어 유행하는지가 쿠버네티스 이해의 첫걸음일 거시다.
전통적인 배포 방식이다.
컴퓨터 1개에 1개의 OS가 깔려 있고, 1개의 OS 위에 여러 프로그램을 설치하는 방식이다.
쉽게 말하자면, 우리가 활용하는 Local 컴퓨터를 생각하면 될 것이다.
이 배포 방식의 문제점은 무엇일까?
우리는 1개의 컴퓨터에 너무 많은 프로그램을 깔면 속도가 느려짐을 알 수 있다.
1대의 컴퓨터에서 너무 많은 기능을 처리하려다 보면 2개의 단점이 생긴다
서버에 배포되는 Product가 이런 문제를 가진다면, 큰 취약점을 가질 것이다.
이 방법의 해결책으로 나온 것이 VM으로, 컴퓨터 2대를 사서 1개에는 A 프로그램만, 1개에는 B 프로그램 역할만 맡긴다는 개념으로 도출된 개념이다.
VM(Virtual Machine;가상 머신)을 기반으로 배포하는 방법이다.
먼저 위 사진에서 나오는 새로운 개념부터 잡고 가자
가상화 배포에서는 VM(가상 머신)을 완전한 1개의 컴퓨터처럼 취급된다.
따라서, Virtual Machine마다 각각 다른 OS를 설치할 수도 있는 것이다.
과정은 아래와 같다
Host OS가 자원 제공 Hypervisor가 Virtual Machine마다 자원 분배 각 VM은 가지고 있는 App을 실행시킴
Guest OS끼리 완벽히 분리되어 있으므로, 1개의 Guest OS가 뚫렸어도 다른 Guest OS 및 Host OS에는 피해가 가지 않는다는 장점을 가진다.
하지만 단점도 존재하는데, VM마다 무거운 Guest OS를 띄우기 때문에 Container에 비해 속도가 느리다는 점이다.
VM과는 달리 프로그램 구동을 위해 OS를 매번 설치할 필요가 없다.
결국 개념적으로 보자면 1개의 Host OS를 활용하는 것이기 때문이다.
이를 반대로 생각하자면, VM과 달리 Host OS가 Windows라면 Guest OS로는 Linux를 활용할 수 없다는 의미이다.
배포된 Container들이 실행될 때, Container 사이에 간섭을 일으킬 수 없도록 장벽이 생겨, 마치 분리된 공간에서 실행되는 것처럼 수행된다.
VM은 "실제로" 분리된 공간에 존재하지만, Container는 Host OS를 공용으로 활용하지만, "Container끼리 분리"되어 있으므로, Container 관점에서 본다면 자기만 Host OS를 활용하는 것처럼 본다는 것이다.
이 부분에서 단점이 하나 더 생긴다.
Container끼리는 분리되어 있으므로, Container 자체에 문제가 발생해도 다른 Container에 영향을 끼치지는 않을 것이다.
문제는 Container의 문제가 Host OS에도 영향을 끼칠 때이다
Container가 Host OS에 영향을 끼친다면, Host OS는 공용이기 때문에 결국 다른 Container들도 문제가 발생한다는 것이다.
그렇다면, 대충 보기에 VM보다 Container는 가볍다라는 장점 외에 단점이 더 많은 것 같은데 왜 사용할까?
가장 중요한 점은 Container를 통해 서비스를 만들면 새로운 서비스를 만들 때마다 서비스에 대한 설정 필요 없이 Container만 전달하면 된다는 점이다.
VM에서 서버를 하나 늘려야 한다고 가정하자.
그렇다면, Guest OS를 하나 설치하고 해당 OS에 필요한 Library 및 환경들을 설정해주고 앱을 배포해야 할 것이다.
또한, 환경 충돌이 날 수 있기 때문에 버전 관리 및 실행 환경에 대해서도 조심히 관리해야 할 것이며 에러 발생 확률도 증가할 것이다.
Product Serving을 해본 사람은 알 수도 있는데, "내 컴퓨터에선 되는데 왜 저 컴퓨터에선 안되지?"의 경우가 많이 발생할 수 있다는 점이다.
Container를 활용하면 이런 문제점이 없다.
Container는 앱 뿐만이 아닌 "실행 환경" 또한 포함하고 있다. 즉, 원래 설정되어 있는 환경이 무엇이든 Container를 가져와서 실행시키면 내가 Produt를 실행시켰던 환경 그대로 가지고 와 실행시킬 수 있다는 점이다.
즉, 서버를 하나 늘릴 때 여러 설정 필요 없이 컴퓨터 1개를 가져다 놓고 Container들만 배포시키면 서버 증설이 끝나는 것이다.
또한 로드 밸런싱을 자동으로 해주기 때문에 VM보다 필요한 Server 컴퓨터의 수가 적게 필요하며 Version 관리를 할 때 중단 없이 수행할 수 있는 등 많은 장점을 가지고 있다.
아래 특징에서 더욱 자세히 설명할 것이다.
특징이 곧 장점이라 생각해도 될 것이다.
위 사진을 보면, A는 아침에만 많이 쓰이고 B는 점심에만 많이 쓰이고, C는 저녁에만 많이 사용된다(카카오 회사 관점에서 보면, A는 카카오 버스, B는 카카오톡, C는 카카오 택시라고 생각해보자)
VM은 사용량에 상관 없이 아침, 점심, 저녁 트래픽을 모두 만족시켜야하므로 총 9개의 Server 컴퓨터가 필요하다.
A Service Server 관점에서 저녁에 거의 사용되지 않는다고 해도 어쩔 수 없다.
그렇다고 Server 수를 줄여버리면 아침 트래픽을 만족시키지 못해 A Service User를 잃게 되기 때문이다.
하지만 Container를 활용하면 이런 단점을 없앨 수 있다.
A, B, C는 총 4개의 Server Computer만 존재하면 해결할 수 있는 트래픽이라고 가정되었다.
그렇다면, 우리는 4개(1개는 Back Up 컴퓨터) 컴퓨터만 가지고 있으면 된다. 그리고 Server마다 Container를 배포시켜 놓는다.
이후 트래픽에 따라 실행시키는 Container를 다르게 하는 것이다.
아침에는 A가 많이 활용되므로 A Container를 많이 실행시키고, B가 많이 활용되는 점심에는 B Container를 많이 실행시키는 것이다.
이런 방식으로 Auto Scaling을 통해 최소한의 자원으로 최대 트래픽 요구량을 충족시킬 수 있는 것이다
쿠버네티스는 Container를 지속적으로 모니터링하며, 컨테이너가 죽을 시 최대한 빨리 재시작시킨다.
Guest OS가 꺼졌을 경우 해당 VM을 다시 켜야 하지만, 쿠버네티스는 이 과정을 자동화해주므로 서버 관리에 수고가 덜 든다는 장점이 있다.
위 사진을 보면 VM에서 Server를 관리할 때는 모든 컴퓨터를 중단 시킨 후 Version Up을 시킨 뒤 다시 Server를 연결 가능하게 하거나 1개의 Server씩 중단 시켜 Version 관리를 하고 다시 Server를 운영하는 방식으로 관리한다.
즉, Version 관리를 위해 서비스를 중단해야할 필요가 있다.
따라서, 트래픽에 대한 장애를 최소화하기 위해 이전에는 Version 관리를 서비스를 잘 활용하지 않는 새벽에 진행시켜 서비스를 잠시 중단하여 Version 관리를 하는 경우가 많았다.
하지만, 쿠버네티스는 그럴 필요가 없다. 그저 Service를 제공하는 Pod를 교체함으로써 서비스 중단 없이 Version 관리가 가능해진다. 그리고 대표적인 3가지 방법은 "블루/그린 방법", "롤링 업데이트 방법", "카나리 배포 방법"이 존재한다.
대표적인 방법인 Rolling Update 방식에 대해서만 알아보자.
쿠버네티스는 Replica Set에서 연결된 POD 중 1개로 연결하여 Servic를 제공하는 형식을 가진다.
POD를 Update해야 할 때, 먼저 Replica Set을 하나 만든다.
이후, Replica Set에 새로운 Version의 Pod를 하나씩 연결시킨다.
그리고 새로운 Pod가 새로운 Replica Set에 연결되었다면, 이전 Replica Set과 연결된 오래된 Pod 하나를 삭제한다.
이런 방식으로 오래된 Pod를 새로운 Pod에 하나씩(혹은 N개씩) 교체하는 방식으로 서비스 중단 없이 Version 관리가 가능해진다.
순서를 간단히 보면 아래와 같다.
기존 Setting : Replica Set1에 Pod v1 3개가 연결됨
Replica Set2 생성
Pod v2를 Replica Set2에 연결
연결이 정상적으로 되었다면 Replica Set1에 연결된 Pod v1 중 1개 삭제
Pod v1 3개가 모두 삭제될 때 까지 2 ~ 3 과정 반복
Pod v1이 모두 삭제되었다면 Replica Set1을 삭제
최종적으로 남은 Setting : Replica Set2에 Pod v2 3개가 연결됨
이 과정에서 Pod는 항상 3개가 연결되어 있으므로, Service를 제공하는 Server가 중단될 필요는 없다.
물론, 배포 중간 과정에서 Pod v2와 Pod v1이 동시에 존재할 수 있다는 단점이 있다.
쿠버네티스는 Container를 기반으로 하는 오픈소스이므로 Host OS만 제대로 Setting되어 있다면 업체에 종속되지 않고 환경 및 서비스 이전이 가능하다.
즉, 별다른 환경 설정 없이 Scale Out(장비 추가를 통한 서버 확장) 및 Scale Up(장비 사양 증가를 통한 서버 확장)이 가능해지며, 이 과정에서 "내 컴퓨터에선 됐는데 왜 저 컴퓨터에선 안되지?" 문제가 덜 발생한다는 것이다
확장 방법은 간단하다
Container를 여러개로 만든 Service를 Pod라는 개념으로 묶는데, Pod를 추가만 하면 바로 확장이 된다
Docker는 1개의 Container Image를 Conainer에 띄우고 실행하는 기술이다.
이에 반해 쿠버네티스는 Container Runtime을 관리하는 기술이다.
만약 1개의 Container만 활용한다면 쿠버네티스까지는 필요 없을 것이다.
하지만, Container를 한 개만 활용하는 것은 진정한 의미로 Container를 활용한다 말할 수 없으며, 여러 개의 Container를 활용하기 위해 이를 관리해주는 툴이 필요해졌고 이 툴이 쿠버네티스인 것이다.
Docker는 Docker Hub에서 "환경"을 다운 받아 내가 원하는 서비스를 해당 환경에 포함시켜 1개의 Container를 만들 수 있다(물론, Container 자체를 불러올 수도 있다)
1개의 Container에 대해서 외부와 연결 가능한 Port가 존재하며, 이 Port를 통해 해당 Container와 통신할 수 있게 된다.
쿠버네티스는 Docker Hub에 올라와 있는 여러 개의 Container를 활용해 Service를 만들고, 여러 개의 Container들을 1개의 Pod에 담아 Service를 Pod라는 보관소에 저장한다.
이 Pod는 쿠버네티스 안에 존재하는 Service를 통해 Client와 통신할 수 있게 되는 것이다