새소식

Recent Study/Kubernetes 학습과정

1. 쿠버네티스 시작

  • -

[ Introduction ]

 쿠버네티스를 큰 기업들이 꼭 써야하는 이유는 큰 기업들은 대규모의 서비스를 운영하고 있기 때문에 최대한 자원을 효율적으로 써야 비용적으로 유리하다. 서버 자원을 효율적으로 쓰기 위해서는 가상화기술에 대해 관심을 가질 수 밖에 없고, 쿠버네티스를 잘 이해하려면 가상화 기술들에 대한 히스토리를 알 필요가 있다. 

 

Linux에는 자원들이 격리해서 프로세스들이 독립적인 환경에서 돌아가게 해주는 기술들이 있었는데, 어려워서 대중적으로 잘 사용하지 않았다. 때문에 이후 VM 가상화 기술이 발전이 되었다. 하지만 하다보니 자동화는 되는거 같은데 생각보다 시스템 효율이 안나는 것을 느끼게 됩니다. 

 

가장 큰 원인을 제공하는것이 VM 가상화를 하기 위해서 무거운 OS를 띄워야 한다는 근본적인 부분이다. 가벼운 서비스를 하나 띄우기 위해 이보다 더 큰 OS를 띄워야 하는 경우가 생기게 되었다.

 

컨테이너 가상화 기술은 서비스간에 자원격리를 하는데 OS를 별도로 안 띄워도 되었고, OS 가동시간이 없기 때문에 자동화시 매우 빠르고, 자원 효율도 매우 높았다. 이때부터 도커는 유명세를 탔다. 근데 도커 자체는 하나의 서비스를 컨테이너로 가상화시켜서 배포를 하는거지 엄청 많은 서비스들을 운영할 때 그것을 일일이 배포하고 운영하는 역할을 해주지는 않는다. 이것을 도와주는 것이 컨테이너 오케스트레이터라는 개념입니다.

 

 

 

 여러 컨테이너들을 관리해주는 솔루션이라고 보면 되는데, 도커의 컨테이너 기술이 오픈소스이기 때문에 많은 회사들이 각자의 오케스트레이터를 내놓게 된다. 위의 색깔로 칠해진 부분만큼 이번 강좌에서 다루어 볼 예정이다.

 

 

Why Kubernetes

 한 회사에서 3개의 서비스를 오픈하고 있다. 이른 아침에 A서비스 접속량이 높고, 이를 위해 세대의 서버 자원량이 필요합니다. B,C는 이 시간대에 접속량이 낮지만, 정오가 되면 B서비스 접속량이 높고, 밤이 되면 C서비스 접속량이 높아짐을 예로 들어볼게요. A 서비스의 경우 다른 시간대에 트래픽이 적더라도 아침 시간에 서비스 운영을 위해서 어쩔 수 없이 3대의 서버가 할당되어 있고, 다른 서비스도 마찬가지라 결국 9대의 서버가 필요합니다.

 

 여기에서 k8s의 가상화 기술을 활용하면, 하루동안 평균 트래픽을 계산하면 4대의 서버가 필요합니다. 오토 스케일링 기능이 있기 때문에 새벽, 정오, 저녁이건 트래픽 양에 따라 알아서 서비스의 자원량을 변경시켜줍니다. 또한 기존 시스템의 경우 서버 장애 상황에 대비해서 한 대의 여분 서버가 필요한데 이렇게 각 서비스별로 백업 서버를 줘서 서버가 죽었을 때 즉각적인 대응을 할 수가 있다.

 

 또한 장애가 난 서버 위에 있는 서비스들이 다른 서버로 자동으로 옮겨주는 오토 힐링 기능이 있기 때문에 한 서버에 장애가 나더라도 여분의 서버가 한 대만 있으면 알아서 서비스를 유지시켜줍니다.

 

 업데이트의 경우, 서비스에 중단이 허용된다면 모든 서버를 내렸다가 업데이트 작업 후 다시 올릴거고, 무중단 서비스를 해야하는 경우 한 서버씩 내렸다가 업데이트 진행 후 서비스를 올리는 방식으로 진행된다. k8s는 deployment라는 오브젝트를 통해서 업데이트 방식에 대해 자동적으로 처리되도록 지원하고 있습니다. 

 

 

VM vs Container

 한 서버에는 기본적으로 어떤 운영체제가 됐건 호스트 OS가 올라갑니다. VM의 경우 호스트 OS 위에 VM을 가상화시켜주기 위해 여러 하이퍼바이저들이 있다. 이런 것들을 사용해서 또 원하는 운영체제로 게스트 OS를 올려서 여러 VM을 만들 수가 있다. 

 

 컨테이너의 경우 호스트 OS 설치까지는 동일, 이 os 위에 컨테이너 가상화를 시켜주는 여러가지 소프트웨어가 있다. 현재 docker를 가장 많이 사용합니다. docker가 컨테이너라는 것을 만들어주게 되는데 간단하게 아래에서 설명을 하겠습니다.

 

 

(컨테이너에 대한 간단한 설명)

 리눅스마다 버전이 있고, 이 버전에 따라 기본적으로 설치되는 라이브러리들이 다릅니다. 만약 리눅스 6버전에 설치되어 있는 OpenJDK 라이브러리를 자연스럽게 사용하게 된다. 개발이 완료되고 이를 리눅스 7버전에서 작동하게 되면, 버전차이에 따른 오류가 생길 수 있다. 그래서 도커를 설치하고 이걸 통해서 컨테이너 이미지를 만들 수 있는데, 이미지에는 한 서비스와 그 서비스가 돌아가는데 필요한 라이브러리들이 같이 있다.

 

 그래서 리눅스 7버전에 다른 라이브러리들이 있더라도 도커만 설치되어 있으면 이 컨테이너 이미지를 가져와서 사용했을 때 A서비스는 자신의 이미지 안에 있는 OpenStack 라이브러리를 사용하기 때문에 안정적으로 시스템을 구동할 수 있다. 또한 Docker가 해주는 일이 여러 컨테이너들 간에 호스트 자원을 분리해서 쓰도록 해줍니다. 이것이 Linux 고유 기술인 Namespace와 Cgroup을 사용해서 격리를 하는 것 입니다. Namespace커널에 관련된 영역을 분리해주고, Cgroup자원에 대한 영역을 분리해줍니다.

 

도커와 같이 컨테이너 가상화 솔루션들은 OS에서 제공하는 자원 격리 기술을 이용해 컨테이너라는 단위로 서비스를 분리 할 수 있게 만들어주고, 컨테이너 가상화가 깔려있는 OS에서는 개발 환경에 대한 걱정 없이 배포가 가능하게 됩니다.

 

일반적으로 한 서비스를 만들 때 한 가지 언어를 사용해서 여러 모듈들이 한 서비스로 같이 돌아갑니다. 만약 A,B 모듈은 괜찮은데 C모듈이 부하가 많이 가는 상황이라면, VM을 하나 더 생성해서 띄우게 됩니다. 게스트 OS가 2개가 됩니다. 하지만 컨테이너를 사용하면, 모듈별로 쪼개서 최적화된 개발 언어를 사용하면 더 좋습니다.

여기서 k8s는 여러 컨테이너들을 한 Pod라는 개념으로 묶을 수가 있고, 한 컨테이너만 파드에 담을 수 있는데, 한 Pod가 배포의 단위입니다. 내가 필요한 Pod만 확장이 가능하고, k8s는 이를 쉽게 해줍니다.

 

 

k8s Overview

 k8s는 서버 한대는 마스터로, 다른 서버는 노드라고 해서 한 마스터에 여러 노드들이 연결이 됩니다. 이것을 전체로 k8s 클러스터라고 부르고, 마스터는 k8s의 전반적인 기능들을 컨트롤하는 역할이고, 이 노드들은 자원을 제공하는 역할인데 만약 클러스터 전체 자원을 늘리고 싶다면 자원을 추가하면 됩니다. 클러스터 내에 Namespace라는 것이 k8s 오브젝트들을 독립된 공간으로 분리되게 만들어줍니다.

 

 Namespace에는 k8s 최소 배포 단위인 Pod가 있고, 이 Pod들에게 외부로부터 연결이 가능하도록 IP를 할당해주는 서비스가 있습니다. 하지만 서로 다른 Namespace에 있는 Pod들에게는 연결을 할 수 없습니다. 또한 Pod 안에는 여러 컨테이너들이 있는데, 컨테이너 하나당 하나의 앱이 동작하기 때문에 결국 Pod에는 여러 앱들이 돌아갈 수 있는 것입니다. 그런데 Pod에 문제가 생겨서 재생성이 되면 그 안에 데이터가 날라갑니다. 그래서 볼륨을 만들어서 Pod에 연결하면 데이터는 이곳에 별도로 조성이 가능하고, Pod가 재생성되어도 데이터가 날아갈 수 있는 문제를 해결할 수 있습니다. 

 

 Namespace에 ResourceQuota / LimitRange를 달아서 한 Namespace에서 사용할 수 있는 자원의 양을 한정할 수 있습니다. Pod의 개수를 제한하거나, Cpu, 메모리들도 제한시킬 수 있습니다. 또한 컨트롤러가 하드들을 관리해주는 일을 하는데 이 컨트롤러의 종류들이 많습니다. 각각의 사용 용도가 존재합니다.

 

 

 

1) Replication Controller와 ReplicaSet

: 가장 기본적인 컨트롤러입니다. Pod가 죽으면 감지해서 다시 되살리거나 Pod의 개수를 늘렸다가 줄일 수 있습니다. Scale-In-Out을 해주는 것입니다.

2) Deployment

: 배포 후에 Pod들을 새 버전으로 업그레이드를 해줍니다. DamonSet은 한 노드의 Pod가 하나씩만 유지가 되도록 도와줍니다.

3) Job

: 어떤 특정 작업만 하고 종료를 시켜야 하는 일을 할때 Pod가 그렇게 동작을 하도록 해줍니다. 그런 Job들을 주기적으로 실행해야 한다면 CronJob을 사용합니다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.