본문 바로가기
Web/Infra

Kubernetes(쿠버네티스)를 소개합니다

by EricJeong 2020. 5. 31.

들어가며

이 글은 쿠버네티스가 무엇이고, 뭐가 좋은지 소개하는 글입니다. 자세한 내부 구조나 구현 방법보다는 쿠버네티스에 입문하는 분들을 대상으로 하고 있습니다. 도커와 컨테이너가 무엇인지 안다는 가정 하에 소개를 진행합니다. 컨테이너가 무엇이지? 도커가 뭐야?라는 생각이 드신다면 제 이전 소개글인 Docker를 소개합니다 를 참고해주세요.

 

쿠버네티스의 가장 큰 진입장벽은 용어입니다. Pod(파드), Service(서비스), Ingress(인그레스)등 처음 보는 생소한 단어가 튀어나오니 당황하게 되고 어떤 역할을 하는지도 파악하기가 참 어려웠습니다. 이번 포스팅에서는 이러한 용어들을 정리해서 쿠버네티스와 관련된 글을 읽을 수 있는 레벨까지 소개해드리는게 목표입니다.

 

쿠버네티스가 뭘까요?

도커와 컨테이너가 등장하며 애플리케이션의 배포와 관리 방식이 완전히 달라졌습니다. 서버에 직접 모든 세팅을 할 필요도 없어졌고 애플리케이션을 서버에서 컴파일할 필요도 없어졌습니다. 그저 만들어진 도커 이미지를 서버에서 실행시키기만 하면 모든 게 해결되기 시작했으니까요. 애플리케이션의 관리를 컨테이너 중심으로 관리하도록 생태계가 변화하였고, 이제 이 컨테이너를 관리해주는 도구가 필요해졌습니다. 쿠버네티스는 컨테이너들을 관리하는 관리자 역할을 담당합니다.

 

생소한 쿠버네티스의 용어부터 알아보기 전, 일단 쿠버네티스가 뭐하는 녀석인지 개념부터 파악해봅시다. 쿠버네티스는 정말 간단하게 말하면 애플리케이션의 배포와 관리를 도와주는 하나의 도구입니다. 도커 이미지를 가져와 직접 실행하기도 하고, 실행 중인 애플리케이션이 문제가 생겼을 때 이를 재빨리 되살려 장애를 방지하기도 합니다. 여러 서버를 쿠버네티스를 사용해 관리한다면 해당 서버의 자원을 파악하고 적절하게 애플리케이션을 분배해서 실행시키기도 합니다.

 

쿠버네티스를 적용한다면 더 이상 개발자가 직접 서버에 애플리케이션을 직접 설치하고 배포할 필요가 없어집니다. 쿠버네티스는 외부 저장소에서 애플리케이션의 이미지를 다운로드한 다음, 설정된 대로 애플리케이션을 생성합니다. 만약 사용자가 급격하게 몰리면 어떻게 할까요? 쿠버네티스에서는 auto-scail out을 통해 애플리케이션의 수평 확장을 지원합니다. 트래픽이 몰린다면 여러 애플리케이션으로 로드밸런싱을 해주기도 합니다.

 

기본 개념부터 잡고 갑시다

쿠버네티스에 대해 이야기하려면 우선 쿠버네티스에서 쓰는 용어를 먼저 알아야 합니다. Pod, ReplicaSet, Service, Ingress 등 해당 용어가 무엇을 뜻하고 어떤 기능을 담당하는지 알아봅시다. 어렵게 가지 말고 정말 간단하게만 알아보자고요.

지금부터 우리는 서비스를 하나 배포할겁니다. 배포할 때 필요한 것들 하나하나 개념을 잡고 각 단계마다 어떤 것이 만들어지고 어떤 기능이 추가되는지 살펴보겠습니다.

 

0. Cluster

 

쿠버네티스에서 관리하는 가장 큰 단위를 클러스터라고 부릅니다. 여러 서버를 논리적으로 하나로 묶어두었다고 보셔도 무방하죠. 이 클러스터 내부에는 실제로 서비스를 담당하는 Worker Node와 이 Worker Node를 관리하는 Master Node가 존재합니다. 마스터 노드나 워커 노드의 개수에 제한이 있지는 않습니다. 얼마든지 추가적으로 늘릴 수 있습니다. 우리가 직접적으로 컨트롤할 대상은 Worker Node, 워커 노드입니다. 지금부터 명명하는 노드는 모두 워커 노드라고 생각해도 좋아요. 자 그러면 대체 Node가 뭘까요?

 

 

1. Node

물리 서버, 가상 서버를 의미합니다. 1개의 노드는 곧 1대의 머신(가상 또는 물리)을 뜻하죠. 잘 이해가 안되신다고요? Node = 컴퓨터 한 대라고 이해하셔도 좋습니다!  서비스를 배포하려면 서버를 담당하는 장비가 최소 1개는 필요할 것입니다. 그 역할을 담당하는 것을 노드라고 이해하시면 됩니다. Node를 생성해보죠.

아무것도 설치되지 않은 노드가 하나 추가되었습니다.

 

2. Pod

이제 이 노드 내부에 어플리케이션을 설치해야겠네요. Docker로 해당 애플리케이션의 이미지를 생성한 후, Docker Hub에 업로드하였다면 쿠버네티스에서 애플리케이션 배포에 필요한 준비는 끝났습니다. 간단하게 애플리케이션 이미지가 있는 docker hub 링크를 설정해준 후 이 이미지를 기반으로 컨테이너를 가지고 있는 Pod를 생성할 수 있습니다. Pod는 하나 이상의 컨테이너를 묶어놓은 녀석입니다. 이제 이 노드 내부애서는 컨테이너가 돌아가고 있겠네요. 외부에서 접근할 수 있는 인터페이스는 아직 만들어지지 않았습니다.

 

Pod는 여러가지 특징이 있습니다. 쿠버네티스에서는 Pod를 언제든지 버리고 새로 만들 수 있는 개념으로 보고 있습니다. 그렇기 때문에 아래 사항을 조심해야 합니다. 

 

  1. Pod는 자신만의 가상 IP를 부여받습니다. Pod가 새로 생성될 때 이 IP는 바뀝니다. 즉 IP가 유동적으로 바뀌기 때문에 Pod를 독자적으로 배포한다면 IP를 설정하기가 까다롭습니다.
  2. 가상 IP를 가지고 있기 때문에  외부에서 Pod로 직접 접근할 수 없습니다. 접근할 수 있는 경로 설정이 필요합니다.
  3. Pod는 언제든지 장애가 발생하면 죽을 수 있습니다. 즉 애플리케이션이 중단될 가능성을 가지고 있습니다.
  4. 사용하는 Image를 새로운 버전으로 업데이트하고 싶다면? 모든 Pod를 새로운 애플리케이션으로 업데이트해야 합니다. 하지만 Pod는 이미 만들어진 컨테이너로만 작동하기 때문에 지금 존재하는 Pod를 제거하고 새로운 버전의 이미지를 가진 Pod를 생성해야 합니다.

이 문제들을 해결하기 위한 녀석들을 하나하나 살펴봅시다.

 

3. Service

언제든 바뀔 수 있는 Pod의 IP는 사용하기에 적합하지 않습니다. Pod를 참조할 수 있는 IP를 미리 정해두고 Pod의 IP가 변한다면 알아서 연동해준다면 정말 편리하지 않을까요? 그 역할을 담당하는 녀석이 바로 Service입니다. Service를 참조하면 Service는 자신이 관리하는 Pod에게 연결해줍니다. Service는 고정적인 가상 IP를 받습니다. 즉 이 IP는 서비스를 제거하지 않는 한 변하지 않으니 이 IP는 애플리케이션과 연동하기에 적합합니다.

 

그렇다면 Service에서는 어떻게 저 Pod가 자신이 관리해야하는 Pod인지 파악할까요? Pod를 생성할 때 특정 라벨을 붙여놓을 수 있습니다. 예를 들어 우리가 만든 애플리케이션에 라벨로 "app: eric_app" 이라고 라벨을 붙여둘 수 있다는 것이죠. 서비스를 생성할 때 selector로 해당 라벨을 설정해 준다면, 서비스는 이 라벨이 붙은 파드들을 찾아서 자신이 관리하는 녀석으로 등록합니다.

 

4. ReplicaSet

Pod는 언제든지 죽을 수 있습니다. Service가 Pod와 연결되어있지만 Service는 Pod와의 연결을 도와주는 역할을 할 뿐 Pod를 관리하고있지는 않습니다. Pod가 죽었을 때 누군가가 살려준다면 참 좋을 것 같네요.

그 역할을 하는 것이 바로 ReplicaSet입니다. ReplicaSet은 직접적으로 Pod를 관리합니다. Pod가 문제가 생기면 언제든지 새로운 Pod를 생성합니다. 한 번에 여러 Pod를 생성하기도 합니다. 똑같은 Pod를 한번에 1개, 3개, 10개도 만들어내는 Pod공장 역할을 수행합니다.

 

ReplicaSet이 Pod를 생성하기 위해서는 Pod와 관련된 생성 정보를 자신이 가지고 있어야 합니다. 그래서 ReplicaSet을 생성할 때 어떤 Pod를 만들어야 하는지 Pod 정보를 같이 설정해서 명세합니다. 이 명세를 Template이라고 합니다. 템플릿은 Pod를 생성하는데 필요한 모든 정보를 가지고 있습니다. 이 템플릿으로 ReplicaSet은 Pod공장 역할을 수행합니다. 이제 Pod가 죽어도 애플리케이션이 중단되지는 않겠네요. ReplicaSet이 바로 살려줄테니까요.

ReplicaSet은 Pod를 템플릿으로 가지고 있습니다.

 

 

5. Deployment

만들어진 애플리케이션의 새로운 버전을 배포해야 한다면 어떻게 할까요? 모든 파드들을 죽인 후 새로운 버전의 애플리케이션을 배포하는 일은 상당히 번거로운 일입니다. 파드가 죽어있는 동안 애플리케이션은 중단되어 있을 것이고 이는 곳 서비스 장애를 의미하기도 하죠. Deployment는 이러한 문제점을 해결해줍니다. 그리고 서비스가 중단되지 않고 업그레이드되는 '무중단 배포'도 지원합니다.

 

ReplicaSet이 Pod를 템플릿으로 가지고 있었다면, Deployment는 ReplicaSet을 템플릿으로 가지고 있습니다. 새로운 버전을 선언하는 명령어를 입력할 경우 Deployment는 자신이 가진 템플릿으로 새로운 버전의 ReplicaSet을 생성합니다. 그리고 순차적으로 이전 버전의 파드를 죽이고 새로운 버전의 파드를 생성합니다. Pod가 다 죽지 않고 하나하나 바뀌기 때문에 애플리케이션이 응답을 하지 못하는 경우는 없습니다.

 

물론 Deployment의 새로운 배포 생성 방식이 이 방식만 있는 것은 아닙니다. 한 번에 모든 파드를 죽이고 새로운 파드를 생성하는 방식, 파드를 시험적으로 생성해 본 후 새로운 버전이 문제가 없다면 신규 파드로 이전을 시작하는 방식 등 다양한 방식을 설정할 수 있습니다.

 

6. Ingress

쿠버네티스 클러스터로 들어오는 요청들을 URL별로 분산시켜주는 L7 로드밸런서라고 보면 됩니다. 같은 IP로 접근하더라도 어떤 URL을 가지고 접근하는지, 어떤 패스를 가지고 접근하는지에 따라 다른 서비스로 분산시켜주는 역할을 합니다. 로드밸런서에 대한 내용이 궁금하시다면 제 이전 포스팅인 로드밸런서의 종류와 동작 방식을 참고해주세요!

 

로드밸런서의 종류와 동작방식

로드밸런싱이 왜 필요할까? 서버가 단 하나만 존재할 때 수천만명의 사람들이 서버에 동시 접속하면 어떻게 될까요? 하나의 서버는 부하를 감당하지 못할 수도 있을 것입니다. 이를 해결하는 방

deveric.tistory.com

 

쿠버네티스로 할 수 있는 것들

자 이제 기본적인 용어 정리가 끝났습니다. 모든 것을 정리한 것은 아니지만 쿠버네티스가 뭘 하는 것인지에 대해 이해는 것을 시작할 준비는 되었어요. 쿠버네티스를 사용했을 때 무엇을 할 수 있을까요?: 위에서 쿠버네티스와 관련된 용어를 정리하며 어느 정도 개념을 잡으신 분들이 있을 수도 있겠네요. 우선 ReplicaSet을 사용한 기능입니다.

 

무중단 서비스

 

여러분이 만든 서비스가 서로 상호작용을 하는 여러 애플리케이션을 기반으로 만들어졌다고 가정해보겠습니다. 로그인을 담당하는 서비스, 검색을 담당하는 서비스, 파일 저장을 담당하는 서비스, 그리고 결제를 담당하는 서비스가 있을 겁니다. 이들 중 하나의 서비스가 갑자기 동작을 멈춘다면 어떻게 될까요? 예를 들어 로그인 서비스가 갑자기 죽어버렸고 더 이상 응답을 하지 못하는 상태가 되었다면 다른 서비스가 살아있음에도 불구하고 더이상 정상적으로 서비스를 유저에게 제공하기는 어려워질 겁니다.

 

이때 ReplicaSet에 해당 서비스의 템플릿 정보를 주었다면 ReplicaSet은 재빨리 그 서비스를 새로 생성하여 바꿔치기합니다. 새로운 서비스를 담당하는 파드를 만들고 이를 이용해 서비스에 더 이상 장애가 나지 않을 수 있도록 도와주죠. 이로써 여러분이 만든 서비스는 더이상 불의의 장애를 걱정하지 않아도 됩니다. 무슨 일이 생겨서 파드가 죽어버린다면 다시 되살려줄 테니까요!

 

 

무중단 배포 (Rolling Update)

여러분이 만든 애플리케이션을 새로운 버전으로 업데이트해야 한다면 어떻게 해야 할까요? 컨테이너 기반의 서비스 환경이라면 새로운 버전의 이미지를 가져온 다음, 이전 버전의 이미지를 사용하는 컨테이너를 삭제하고 새로운 버전의 이미지로 컨테이너를 다시 제작할 것입니다. 이렇게 할 경우 1. 이전 컨테이너를 삭제하고 2. 새로운 컨테이너를 생성하는 동안 서비스가 중단된 상태일 겁니다.

 

 

하지만 쿠버네티스의 Deployment를 사용한다면 여러분의 서비스는 중단되지 않습니다. 순차적으로 쿠버네티스는 새로운 버전의 파드를 생성한 후, 이전 버전의 파드를 제거하는 Rolling Update(롤링 업데이트)를 하니까요! 업데이트를 하는 동안 더 이상 서비스 중단이 일어나지 않습니다

 

 

유동적인 스케일 조정

 

여러분의 서비스가 특정 시간에 갑자기 엄청난 사용자가 몰려든다면 어떻게 될까요? 애플리케이션에서 더 이상 서비스를 받지 못해 순식간에 서비스를 못하는 장애가 발생할 수 있을 것니다. 순식간에 많은 사용자가 몰려든다면 더이상 여러분의 서비스가 버티지 못할 수 있으니까요. 쿠버네티스에서는 이러한 상황이 오면 템플릿을 사용해서 수평 확장(scale out)을 진행합니다. 트래픽이 몰릴 때 파드를 필요한 만큼 늘리고, 트래픽이 줄어들면 다시 원상태로 파드 개수를 줄입니다. 즉 유동적인 트래픽에 유연하게 대처할 수 있습니다.

 

 

마치며

쿠버네티스는 컨테이너 기반 관리를 유연하게 진행해줍니다. 이러한 관리를 컨테이너 오케스트레이션이라고 부르기도 하죠. 제 소개글을 보고 쿠버네티스에 대해 조금 더 관심이 생겼다면 쿠버네티스 공식문서를 읽어보시는 걸 추천드립니다. 무려 한글 번역이 되어있으니 용어를 조금만 안다면 읽어볼 만하죠. 간단한 반응형 튜토리얼도 제공하니 본격적으로 쿠버네티스를 어떻게 구성하는지 알아보신다면 꼭 들어가 보시길 바랍니다.

 

쿠버네티스 문서

쿠버네티스는 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화하기 위한 오픈소스 컨테이너 오케스트레이션 엔진이다. 오픈소스 프로젝트는 Cloud Native Computing Foundation에서 주관한다.

kubernetes.io

 

쿠버네티스는 강력한 관리 도구이지만 쿠버네티스가 꼭 필요하지 않은 경우도 있습니다. 위에서 말한 무중단 서비스, 무중단 배포, 유동적인 스케일 조정은 많은 사용자가 안정적으로 서비스를 사용해야 할 때 필요한 조치입니다. 이러한 조치가 필요하지 않은 작은 서비스들과 신뢰도가 필요하지 않은 서비스들에게는 이 쿠버네티스는 오버스펙이 될 수 있습니다. 오히려 쿠버네티스를 구성하고 관리하는 것이 서비스를 직접 관리하는 것보다 더 힘들 수도 있으니까요. 쿠버네티스의 도입은 내가 관리하는 서비스가 정말 이러한 기능이 필요한지 꼼꼼하게 검토해보고 하셨으면 합니다.

 

쿠버네티스에대한 소개는 여기에서 마치도록 하겠습니다.

댓글