Architecture/k8s

Kubernetes 아주 조금만 알아보자 - Kubernetes란?

KOOCCI 2019. 5. 17. 01:48

※ 개인적으로 받았던 Kubernetes 교육을 정리한 내용입니다.

 

1편 > Kubernetes 아주 조금만 알아보자 - Kubernetes란? : 현재 Post

2편 > Kubernetes 아주 조금만 알아보자 - Kubernetes의 흐름 : https://koocci-dev.tistory.com/5

3편 > Kubernetes 아주 조금만 알아보자 - 마스터, 노드 : https://koocci-dev.tistory.com/6

4편 > Kubernetes 아주 조금만 알아보자 - Model, Declared State, Pod https://koocci-dev.tistory.com/10

5편 > Kubernetes 아주 조금만 알아보자 - ReplicaSets,Deployments : https://koocci-dev.tistory.com/11

6편 > Kubernetes 아주 조금만 알아보자 - Service : https://koocci-dev.tistory.com/12


Kubernetes 란?

먼저, 쿠버네티스의 정의를 적어보면, "컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼"이다.

 

그럼 위 정의를 하나씩 파해쳐보기 위해 쿠버네티스가 무엇이냐? 라고 하면 다음 단어들이 가장 먼저 떠오르게 된다.

  • Open Source
  • Google이 시작
  • Docker
  • Multi node orchestrator
  • MSA

모두 연관되어 있는 말이다.

그럼 이들을 연결하여 한 번 알아보도록 하자.

먼저 쿠버네티스 하면, Docker를 빼놓을 수 없다.

Image, Container 기술의 집약체라 할 수 있는 Docker를 알아야, 쿠버네티스도 이해할 수 있다. (물론, 요즘 쿠버네티스는 Docker뿐 아니라, 다른 것도 (Rocket 등) 가능하다)


아주 간단한 Docker 정리

아주 간단하게 Docker에 발만 담구어 보자.

흔히, VM과 헤깔려 하고 VM의 다음이 Docker다! 라고 이해하는 사람도 있을 수 있다.

그러나, 절대 VM 다음이 Docker인 것이 아니다. 위 두가지는 설계적으로 활용도가 다른 것으로, VM이 나쁜 것도, Docker가 더 좋다고도 할 수 없다.

 

흔히 Server의 Utility성을 위해 VM을 사용한다고 하면, Docker는 한 두가지 Application만 구동할 수 있는 환경을 제공하고 싶은 목적이 있다. (모든 Linux distribution을 가질 필요가 없다)

 

위와 같이 생각하면, VM은 Guest OS를 가지고, System Call이 2번 일어나게 되는 점을 이해할 수 있고, Docker는 Host OS, 즉 Host 커널 위에 가상화되어 올라가게 되어 ,System Call이 일어나게 된다는 것이 이해된다.

 

 

 

https://i.ytimg.com/vi/EeLCr-CUFKI/maxresdefault.jpg

DevOps라는 구성이 있다.

Dev(개발)과 Ops(운영)이 함께 어우러져, 문제점을 해결하는 하나의 방법론이다.

 

Docker에서 Image라 함은, Process 실행 환경이자 File System Contents의 패키지이며, 개발자들이 만드는 Dev 파트이다.

따라서, Image는 본인이 개발하거나, 함께 개발해 나갈 환경을 이미지 서버(Registry)에 올려, 허용된 사람만 Image를 가져와 사용할 수 있게 한다.

 

이렇게 만들어진 Image를 Registry에서 Pull을 통해,  Micro Service로 나누어 실행한다고 하자. (Docker는 한 두개의 App만 구동할 수 있게 한 환경이니까!)

 

예를 들어, AI 프로젝트가 있다고 하자.

Train App, Inference App, DB App 등으로 나누어 Docker Image로 올렸고, 이를 Pull 받아 Container로 만들었다.

이렇게 만들어진 Container는 결국 Ops 파트가 된다.

Docker With DevOps

위 예시 처럼 많은 Docker Container들이 만들어 졌다고 하자.

Docker는 Single Node Container인데, 하나의 온전한 서비스를 하려고 해도, 여러개의 Container가 필요하게 된다.

결국, 우리는 Multi Node가 필요해졌고 자연스럽게 Kubernetes가 만들어진 이유가 설명 된다.

그렇다면, Kubernetes는 DevOps중 어디에 속할까?

여러 Containered APP의 Orchestrator (Multi Node) 로서, Ops 라 할 수 있다.


아주 간단한 Kubernetes Feature 정리

위에 AI 서비스 한가지를 예시로 들었었다.

이를 그림으로 간단히 그려보면 다음과 같다.

 

AI Example Image

우리는 Architecture를 고민할 때, 생각해야할 것들이 많다. 첫번째로, Train App의 부하가 많다고 하자.

그럼 자연스럽게 Multi Node로 Scale Out이 떠오른다.

Scale Out이 된 Node들은 Load-balancing이 필요로 할 것이다.

그리고, 중요한 DB App은 2중화, 3중화를 고민하게 되고, Self-healing 기능을 생각하게 된다.

마지막으로, 하나하나 App들의 Update가 필요할 때, Rolling Update (새 버전 Update/ Roll Back 등) 이 필요로 하게 된다.

 

Kubernetes는 바로 위와 같은 부분들을 Supporting 해준다.

 

위 이미지를 다시 한번 보면, 각각의 App의 연결고리들을 연결해주는 선들이 있다. 이는 Network 로 볼 수 있는데,

이는 보통 Loosly Connection으로 연결하게 된다. 물리적으로 Tightly하게 하지 못하는 것이 아니라, Loosly Connection을 쓰는게 MSA(Micro Service Architecture) 의 핵심요소 중 하나와 이어지게 된다.


Cattle businessPet business 라는 것이 있다.

 

Cattle이라는 것은 가축이라는 뜻이고, Pet 알다시피 애완동물을 말한다.

 

비즈니스가 Pet처럼 애지중지 키우고, 항상 돌보며 다칠까봐 노심초사한 경우가 있는가 하면, 일반적으로 크게 신경을 쓰지 않고, Cattle처럼 야생에서 살도록 나두는 경우가 있다.

 

MSA는 바로 이런 Cattle business 라고 보면 된다. Stateless 인 것이다. 

전체 서비스에 문제가 없게 설계하여 신경을 최대한 쓰지않고, 죽으면 죽은대로, 새로운 걸 띄우는 방식으로 진행하게 만드는 것이다.

 

우리는 더 이상, 하나의 서비스가 잘 돌아가도록 운영단계에 올렸을 때, 하나라도 잘못된 프로세스가 나오면 전체 서비스가 제대로 구동되지 못하거나, 서로 간의 영향도가 높은 상황이 나오지 않기를 원한다는 것이다.

 

따라서, 서로의 Network는 Loosely Connection으로 가져가게 한다.

서로의 영향도를 줄이기 위해 상태를 저장하지 않고, 보낼 수 있게 느슨한 관계를 가지게 하는 것이다. (HTTP가 대표적으로 Stateless, Connectionless를 가진다는 걸 알면 Loosely Connection의 의미가 더 잘 와닿을 수 있다)

 

즉, 앞서 말한 Kubernetes의 특징처럼 잘게 나눈 서비스 중 하나가 죽더라도 전반적인 서비스에는 영향도가 미미하고, 타 프로세스에는 영향이 없으며, 죽은 프로세스를 살리기도 하는 과정을 Kubernetes가 도와준다.

 

그렇다면, Kubernetes는 이러한 일을 하기 위해 가장 열심히 생각하는 것이 무엇일까?

 

바로 Desire State를 Declare한다는 것이다.

 


Desire State 란?

Kubernetes는 이상적인 상태, 즉 사용자가 원하는 상태를 알고 있다. (정확히 말하면 사용자가 Kubernetes가 알도록 선언해둔다)

 

택배를 예시로 보자.

우리가 택배를 보낼 때, 어떤 택배회사가 어디에 갔다가 어떤 방법으로 도착을 하든 목적지만 송장에 적어두면 도착을 한다.

 

위 예시처럼, Kubernetes는 그 과정이 어떻게 되는 지는 생각하지 않는다.

현재 상태 (Actual State)사용자가 원하는 상태 (Desire State)를 비교해 그 Gap에만 신경을 쓴다.

 

즉, 중간에 어떤 앱이 죽었든 어떤 앱이 생겼든, 장애가 났든, 성공적으로 배치가 돌았든, 사용자가 원하는 상태와 달라지면 현재 상태에서 그 Gap을 없애기 위해 노력한다.

 

이런 방법을 보통 Declarative라고 하는데, 이와 상반되는 개념이 Imperative 다.

 

Imperative의 개념은 위 예시에 보태어 설명하면 쉽다.

 

우리는 택배를 보낼 때, 부산에서 대전으로 갔다가 수서에서 강남으로 가면 빠르다고 A 택배회사에게 알려주었다.

위 상황을 보면, 아마 택배는 우리가 아는 한 가장 빠른 방법으로 도착할 것이다. 하나하나 전부 다 지정해주었기 때문이다.

이 부분은 하나의 Kubernetes의 단점이기도 한데, 그 중간단계가 어떻게 되는지 모르기 때문에 지연이 얼마나 일어날 지 모른다.

 

다만, Declare State로 언젠가 간다는 보장만 한다.


Kubernetes의 역사?

구글은 쿠버네티스를 만들기 전에, 이미 자신들의 Container들을 관리할 수 있는 방법을 고안하고 Private하게 사용하고 있었다. (Google에서 사용하는 Container 갯수만 20억개 정도라고 한다.)

 

Borg/Omega 라고 하는 것이 바로 그러한 것들이고, 내부적으로 구글 프로세스에 특화되어있어, 어떻게 짜여져 있는지는 알지 못한다.

 

다만, 이 기술들을 최대한 많은 사람들이 사용할 수 있게 하여 Kubernetes라는 것을 만들었고 (Go 언어로 만들어졌고, Docker도 마찬가지로 Go 언어로 짜여졌다.), 이를 Open Source로 풀었다. 

 

이렇게 Kubernetes가 나오기 몇 년전  Docker는 이미 나와있었다. (Docker는 2013년에 처음 나왔고, Container 개념은 훨씬 옛날 부터 있었다.)

 

Docker는 Kubernetes의 container runtime (kuberlet)으로 일하고, 이 둘을 연결하는 Interface가 CRI(Container Runtime Interface)라고 한다.

 

조금 더 깊게 들어가면 OCI(Open Container Initiative:컨테이너 포맷과 실행환경의 표준) 스팩을 만족하는 Docker Engine을 Kubernetes와 통신하게 만든 규격CRI이다.

 

초기에는, Docker Engine에 있던 CRI를 Reference로 Kubernetes에서 사용하였으나, 이후, Kubernetes가 containerd로 점차 성장하자, Docker측도 containerd를 지원하게 되었다.

Docker

Docker에 대한 내용은 다음에 좀 더 자세히 알아보기로 하자, 다만 Docker 측은 Kubernetes와 같은 Multi Node에 대한 대응을 하지 않았을까? 라는 의문이 든다.

 

당연히, 먼저 시도했었다. Docker Swarm이 바로 그것인데, 초기 Docker Swarm이 있었으나, Kubernetes에 밀렸고, 이후에 새롭게 리뉴얼하여 다시 나왔지만, 결국 최근에는 Kubernetes를 공식 지원하기로 하였다.

다만, Kubernetes는 Clustering까지는 공식적으로 지원하지 않는다. 그러나, Docker Swarm은 Kubernetes 아래에 Clustering이 가능한 솔루션을 제공해준다.

 

이외에 좀더 자세한 내용은 다음 포스팅에서 진행하도록 하겠다.