들어가며
이번 포스트는 저번 포스트에서 다뤘던 도커에 이어서 쿠버네티스에 대해 알아볼 것이다.
다음 글을 매우 많이 참고하였다!
쿠버네티스 시작하기 - Kubernetes란 무엇인가?
쿠버네티스는 컨테이너를 쉽고 빠르게 배포/확장하고 관리를 자동화해주는 오픈소스 플랫폼입니다. 1주일에 수십억 개의 컨테이너를 생성하는 구글이 내부 배포시스템으로 사용하던 borg를 기
subicura.com
등장 배경
2013년 등장한 도커는 인프라 세계를 컨테이너 세상으로 바꿔버렸다.
수많은 애플리케이션이 컨테이너로 배포되고, Dockerfile을 만들어 이미지를 빌드하고, 컨테이너를 배포하는 것이 개발 프로세스의 표준으로 자리 잡았습니다.
2019년 DockerCon 발표에서는 무려 1052억 번의 컨테이너 이미지 pull이 발생했다고 하니.. 도커의 위엄이 얼마 정도인지 알 수 있다.
도커 컨테이너를 여러 서버에 배포할 필요성이 증가하면서, 컨테이너 오케스트레이션이라는 툴이 등장하였다.
컨테이너 오케스트레이션이란, 여러 개의 서버에 컨테이너를 배포하고 운영하면서 서비스 간 연결을 쉽게 해주는 도구이다.
서버마다 app01, db01, cache01 같은 이름을 지어주고 하나하나 접속하여 관리하는 것이 아니라 server1, 2, 3, 4..를 하나로 묶어 적당한 서버를 자동으로 선택해 애플리케이션을 배포하고, 부하가 생기면 컨테이너를 늘리고, 일부 서버에 장애가 발생하면 정상 동작 중인 서버에 다시 띄워 장애를 방지하는 등의 다양한 기능을 지원한다.
여러 종류의 컨테이너 오케스트레이션 도구는 제각기 서로 다른 기능을 제공했고, 절대 강자 없이 한동안 컨테이너 오케스트레이션 춘추전국시대가 지속됐다고 한다.
이러한 상황에서 쿠버네티스가 등장한다.
쿠버네티스는 다른 컨테이너 오케스트레이션 도구보다 비교적 늦게 등장하였다.
그럼에도 불구하고, 쿠버네티스는 1~2년 사이에 컨테이너 오케스트레이션 춘추전국시대를 끝내고 절대 강자로 자리잡았다.
도대체 쿠버네티스는 정확히 무슨 일을 하고, 어떤 장점이 있길래 도커와 함께 슈퍼스타가 될 수 있었을까?
쿠버네티스란?
쿠버네티스는 구글에서 개발한 컨테이너를 쉽고 빠르게 배포 및 확장하고, 관리를 자동화해주는 오픈소스 플랫폼이다.
1주일에 수십억 개의 컨테이너를 생성하는 구글이 내부 배포 시스템으로 사용하던 borg를 기반으로 2014년 프로젝트를 시작하였다.
쿠버네티스는 단순한 컨테이너 플랫폼이 아니다.
마이크로서비스, 클라우드 플랫폼을 지향하고 컨테이너를 손쉽게 담고 관리할 수 있는 그릇 역할을 한다.
게다가 서버리스, CI/CD, 머신러닝 등의 다양한 기능도 지원한다.
동작 방식
쿠버네티스와 친해지기 위해 동작 방식부터 알아보자.
쿠버네티스에서 가장 중요한 것은 desired state(원하는 상태) 개념이다.
원하는 상태는 관리자가 바라는 환경을 의미하며.
얼마나 많은 웹 서버가 떠 있기를 원하는지, 몇 번 포트로 서비스하기를 원하는지 등을 말하는 것이다.
쿠버네티스는 복잡하고 다양한 작업을 하기로 정평이 나있지만, 자세히 들여다보면 단순히 현재 상태를 모니터링하면서 관리자가 설정한 원하는 상태를 유지하기 위해 이런저런 작업을 수행할 뿐이다.
쿠버네티스의 핵심은 상태이며, 쿠버네티스를 사용하려면 어떤 상태가 있고 어떻게 상태를 선언하는지를 알아야 한다.
이때, 상태는 오브젝트로 정외하여 관리된다.
쿠버네티스는 기본적으로 수십 가지의 오브젝트를 제공하며, 새로운 오브젝트를 추가하기가 매우 쉽기 때문에 확장성이 좋다.
다양한 오브젝트 중 주요 오브젝트는 다음과 같다.
- Pod
- 쿠버네티스에서 배포할 수 있는 가장 작은 단위
- 한 개 이상의 컨테이너, 스토리지, 네트워크 속성을 가진다.
- 하나의 Pod 내에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근할 수 있다.
- 컨테이너를 하나만 사용하더라도 반드시 Pod으로 감싸서 관리해야 한다.
- ReplicaSet
- Pod을 여러 개로 복제하여 관리하는 오브젝트
- Pod을 생성하고, 개수를 유지하기 위해서는 반드시 사용해야 한다.
- 복제할 개수, 개수를 체크할 라벨 선택자, 생성할 Pod의 설정값(템플릿) 등을 가진다.
- 직접적으로 사용하기 보다는 Deployment 등 다른 오브젝트에 의해 사용되는 경우가 많다.
- Service
- 네트워크와 관련된 오브젝트
- Pod을 외부 네트워크와 연결해주고, 여러 개의 Pod을 바라보는 내부 로드 밸런서를 생성할 때 사용한다.
- 내부 DNS에 서비스 이름을 도메인으로 등록하기 때문에, 서비스 디스커버리 역할도 수행한다.
- Volume
- 저장소와 관련된 오브젝트
- 호스트 디렉토리를 그대로 사용하고, EBS 같은 스토리지를 동적으로 생성하여 사용하게 해준다.
- 인기 있는 대부분의 저장 방식을 모두 지원한다.
오브젝트 명세(Spec)는 YAML 파일로 정의된다.
해당 파일에 오브젝트의 종류와 원하는 상태가 입력된다.
이러한 명세는 생성, 조회, 삭제로 관리할 수 있기 때문에, REST API로 쉽게 노출할 수 있다.
같은 개념을 적용하여, 누가 어떤 오브젝트에 어떤 요청을 할 수 있는지 접근 권한 설정도 정의할 수 있다.
배포
쿠버네티스 애플리케이션은 배포를 위해 다양한 오브젝트에 라벨을 붙여서 원하는 상태를 정의하고, API 서버에 전달하는 방식을 사용한다.
예를 들어, "컨테이너를 2개 배포하고, 80 포트로 오픈해줘"라는 간단한 작업이 필요하다고 해보자.
해당 작업을 위해서는 다음과 같은 구체적인 명령을 전달해야 한다.
컨테이너를 Pod으로 감싸고 type=app, app=web이라는 라벨을 달아줘.
type=app, app=web이라는 라벨이 달린 Pod이 2개 있는지 체크하고 없으면 Deployment Spec에 정의된 템플릿을 참고해서 Pod을 생성해줘.
그리고 해당 라벨을 가진 Pod을 바라보는 가상의 서비스 IP를 만들고 외부의 80 포트를 방금 만든 서비스 IP랑 연결해줘.
쿠버네티스는 정말 유용한 도구이다!
그러나, 위의 명령을 보면 알 수 있듯이, 그냥 사용하기 쉽지는 않다...
아키텍처
컨테이너는 아주 심플하고 우아하게 동작한다.
run을 하면 실행되고, stop을 하면 멈춘다.
쿠버네티스는 전체 클러스터를 관리하는 마스터와 컨테이너가 배포되는 노드로 구성되어 있다.
마스터는 API 서버와 상태 저장소를 가지고 있고, 각 노드는 컨테이너와 마스터와 통신하는 에이전트인 큐블릿(kubelet)을 가지고 있다.
모든 명령은 마스터의 API 서버를 호출하고, 노드는 마스터와 통신하며 필요한 작업을 수행한다.
특정 노드의 컨테이너에 명령할 때에는 노드에 직접 명령하는 것이 아니라, 마스터에 명령을 내리고 마스터가 노드에 접속하여 대신 결과를 응답한다.
Master
API 서버(kube-apiserver)는 모든 요청을 처리하는 마스터의 핵심 모듈이다.
쿠버네티스의 명령 CLI 도구인 kubectl 요청 뿐만 아니라, 내부 모듈의 요청도 처리한다.
권한 체크를 통해 요청을 거부할 수도 있으며, 노드에서 실행 주인 컨테이너의 로그를 보여주고 명령을 보내는 등의 디버거 역할도 수행할 수 있다.
하지만 결국, API 서버의 주 기능은 원하는 상태를 key-value 저장소에 저장하고 저장된 상태를 조회하는 것이다.
Pod을 노드에 할당하고 상태를 체크하는 일은 다른 모듈로 분리되어 있다.
이때, 상태를 저장하는 key-value 저장소는 RAFT 알고리즘을 이용한 분산 데이터 저장소 etcd이다.
여러 개로 분산하여 복제할 수 있기 때문에 안정성이 높고 속도도 빠른 편이다.
단순히 값을 저장하고 읽는 기능 뿐만 아니라, watch 기능이 있어 어떤 상태가 변경되면 바로 체크하여 로직을 실행할 수 있다.
etcd는 클러스터의 모든 설정, 상태 데이터를 전부 저장한다.
이외의 모듈은 전부 stateless하게 동작하기 때문에, etcd만 잘 백업해두면 언제든지 클러스터를 복구할 수 있다.
etcd는 오직 API 서버와만 통신하기 때문에, 다른 모듈이 etcd 데이터에 접근하려면 API 서버를 거쳐야 한다.
k3s 같은 초경량 쿠버네티스 배포판에서는 etcd 대신 sqlite를 사용하기도 한다고 한다.
API 서버는 요청을 받으면 etcd 저장소와 통신할 뿐, 실제로 상태를 바꾸는 것은 스케줄러와 컨트롤러가 수행한다.
현재 상태를 모니터링하다가 원하는 상태와 다르면, 각자 맡은 작업을 수행하고 상태를 갱신한다.
- 스케줄러 (kube-scheduler)
- 할당되지 않은 Pod을 여러 조건(필요한 자원, 라벨)에 따라 적절한 노드 서버에 할당해주는 모듈
- 큐브 컨트롤러 (kube-controller-manager)
- 쿠버네티스에 있는 거의 모든 오브젝트의 상태를 관리하는 모듈
- 클라우드 컨트롤러 (cloud-controller-manager)
- AWS, GCE, Azure 등 클라우드에 특화된 모듈
- 노드를 추가 및 삭제하고 로드 밸런서를 연겨라거나 볼륨을 붙일 수 있다.
- 각 클라우드 업체에서 제공하는 인터페이스에 맞춰 구현하면 되기 때문에, 확장성이 좋다.
Node
큐블릿(kubelet)은 노드에 할당된 Pod의 생명주기를 관리하며, 마스터와 통신하는 역할을 수행한다.
Pod을 생성하고 Pod 안의 컨테이너에 이상이 없는지 확인하면서, 주기적으로 마스터에 상태를 전달한다.
API 서버의 요청을 받아 컨테이너의 로그를 전달하거나 특정 명령을 대신 수행하기 도한다.
큐블릿이 Pod을 관리한다면, 프록시(Proxy)는 Pod으로 연결되는 네트워크를 관리한다.
TCP, UDP, SCTP 스트림을 포워딩하고 여러 개의 Pod을 Round-Robin 형태로 묶어 서비스를 제공할 수 있다.
하나의 Pod을 생성하는 과정은 위 그림과 같다.
흐름을 보면 각 모듈은 서로 통신하지 않고 오직 API 서버와 통신하는 것을 알 수 있다.
API 서버를 통해 etcd에 저장된 상태를 체크하고, 현재 상태와 원하는 상태가 다르면 필요한 작업을 수행하는 것이다.
각각의 모듈이 각자 담당한 상태를 체크하고 독립적으로 동작한다는 점에서 훌륭한 MSA 구조라고 할 수 있다!
장점
지금까지 쿠버네티스의 개념, 동작 방식, 아키텍처 등을 살펴보았다.
하지만 아직 한 가지 의문점이 남아 있다.
쿠버네티스는 어떠한 차별점이 있길래 다른 컨테이너 오케스트레이션 도구들을 제치고 절대 강자가 될 수 있었던 것일까?
쿠버네티스만이 가지는 장점은 다양하다.
하나씩 알아보자.
유명 기업들의 참여
쿠버네티스는 구글을 포함한 전 세계적으로 엄청난 기업들이 대거 참여하여 만들어진 기술이다.
전 세계적 스케일의 경험과 기술이 고스란히 녹아들어 있으며, 거대한 커뮤니티와 상태계가 존재한다.
그렇기 때문에, 대부분의 클라우드 네이티브 애플리케이션이 쿠버네티스와 호환이 수월하다.
다양한 배포 방식
인터넷 자료를 보면 컨테이너와 관련된 많은 예제가 웹(FE+BE) 애플리케이션을 다루고 있다.
그러나, 실제 세상에는 훨씬 다양한 형태의 애플리케이션이 존재한다.
쿠버네티스는 이러한 다양한 배포 방식을 지원한다.
Ingress 설정
쿠버네티스는 다양한 웹 애플리케이션을 하나의 로드밸런서로 서비스할 수 있도록 Ingress 기능을 제공한다.
웹 애플리케이션을 배포해본 적이 있다면, 애플리케이션에 직접 접근 가능하게 하는 대신에 애플리케이션을 내부망에 설치하고 외부에서 접근 가능한 ALB, Nginx, Apache 같은 프록시 서버를 활용한 경험이 있을 것이다.
프록시 서버는 도메인과 Path 조건에 따라 등록된 서버로 요청을 전달할 때, 서버가 바뀌거나 IP가 변경되면 매번 설정을 수정해줘야 하는 귀찮음이 있다.
하지만 쿠버네티스의 Ingress는 이를 자동화하면서 기존 프록시 서버에서 사용하는 설정을 거의 그대로 사용할 수 있게 해준다.
새로운 도메인을 추가하거나, 업로드 용량을 제한하기 위해 일일이 프록시 서버에 접속하여 설정을 변경할 필요가 없는 것이다.
또한, 하나의 클러스터에 여러 개의 Ingress 설정을 할 수 있어, 관리자 접속용 Ingress와 일반 접속용 Ingress를 따로 관리할 수 있다.
클라우드 지원
쿠버네티스는 부하에 따라 자동으로 서버를 늘리는 AutoScaling 기능을 지원한다.
또한, IP를 할당받아서 로드밸런서로 사용할 수도 있다.
외부 스토리지를 컨테이너 내부 디렉토리에 마운트하여 사용하는 방식은 일반적으로 많이 사용된다.
원래는 이를 위해 클라우드 별로 적절한 API를 사용하는 모듈이 필요하다.
하지만 쿠버네티스는 Cloud Controller를 이용하여 클라우드 연동을 손쉽게 확장할 수 있다.
AWS, 구글 클라우드, 마으크로소프트 Azure는 물론 수십 개의 클라우드 업체에서 모듈을 제공하기 때문에, 관리자는 동일한 설정 파일을 서로 다른 클라우드에서 동일하게 사용할 수 있다.
Namespace & Label
쿠버네티스는 하나의 클러스터를 논리적으로 구분하여 사용할 수 있게 해준다.
하나의 클러스터에 다양한 프레임워크와 애플리케이션을 설치하기 때문에, 기본적인 system, defulat 말고는 여러 개의 네임스페이스를 사용하는 것이 일반적이다.
더 세부적인 설정으로는 라벨 기능을 활용하여 유연하면서 확장성 있게 리소스를 관리할 수 있다.
RBAC (Role-based Access Control)
쿠버네티스는 RBAC라는 접근 권한 시스템을 사용한다.
각각의 리소스에 대해 사용자 별로 CRUD 권한을 손쉽게 지정할 수 있다.
클러스터 전체에 적용하거나 특정 네임스페이스에 적용하는 등, 권한 범위도 설정할 수 있다.
특히, AWS의 경우에는 IAM과의 연동도 가능하다.
기타
- CRD (Custom Resource Definition)
- 쿠버네티스가 제공하지 않는 기능을 기본 기능과 동일한 방식으로 적용하고 사용할 수 있게 해준다.
- 예를 들어, 쿠버네티스는 기본적으로 SSL 인증서 관리 기능을 제공하지 않지만, cert-manager를 설치하고 Certificate 리소스를 이용하면 익숙한 쿠버네티스 명령어로 인증서를 관리할 수 있다.
- 외부 도구의 새로운 방식을 익힐 필요 없이, 다양한 기능을 손쉽게 확장할 수 있다.
- Auto Scaling
- CPU, 메모리 사용량 뿐만 아니라, 현재 접속자 수와 같은 값에 따른 확장을 지원한다.
- 여러 방식을 지원한다.
- HPA (Horizontal Pod Autoscaler) : 컨테이너의 개수 조정
- VPA (Vertical Pod Autoscaler) : 컨테이너의 리소스 할당량 조정
- CA (Cluster Autoscaler) : 서버 개수 조정
- Federation, Multi Cluster
- 클라우드에 설치한 쿠버네티스 클러스터와 자체 서버에 설치한 쿠버네티스를 묶어서 하나로 사용할 수 있다.
- 구글의 Anthos를 이용하면 한 곳에서 여러 클라우드의 여러 클러스터를 관리할 수 있다.
단점
와 쿠버네티스 정말 좋네요?
이거이거 안쓰면 바보 아닌가요?
당신은 지금까지의 내용을 100% 완벽하게 이해했는가?
그렇다. 쿠버네티스의 최대 단점은 너무 복잡해서 개념을 이해하기 어렵다는 것이다.
YMAL 설정 파일은 너무 많고, 클러스터를 만드는 것도 쉽지 않다.
Cloud Code 플러그인이나, helm 패키지 매니저를 사용하면 그나마 낫지만... 그래도 어렵다.
마치며
지금까지 쿠버네티스의 개념, 특징, 장단점에 대해 알아보았다.
쿠버네티스와 관련된 생태계는 지금도 빠르게 변하고 발전하고 있다.
하지만 기본적인 동작 원리를 이해하고 있다면, 새로운 버전과 새로운 프레임워크가 등장해도 쉽게 이해하고 확장하여 사용할 수 있을 것이다!
참고:
'개발' 카테고리의 다른 글
고~뤠? (1) | 2025.07.16 |
---|---|
코끼리 아저씨는 코가 손이래 (0) | 2025.07.11 |
[ 우아한 기술블로그 ] 배민커넥트 배차시스템의 실거리 시스템 구축 (1) | 2025.07.10 |
페이지네이션 (Pagination) (0) | 2025.07.06 |
AST에 대한 고찰 (1) | 2025.06.28 |