쿠버네티스란?
쿠버네티스는 여러 서버로 구성된 클러스터 환경에서 컨테이너화된 프로세스를 관리하기 위한 컨테이너 오케스트레이션 플랫폼이다.
여기서 클러스터 환경은 성능 향상을 위해 한 컴퓨터 혹은 여러 컴퓨터에서 여러 개의 서비스를 실행할 수 있도록 집합을 만들어 놓은 것이라 볼 수 있다. 대표적인 클러스터 환경에는 수직 클러스터링과 수평 클러스터링이 있는데, 스케일 업/스케일 아웃과 일맥상통하는 개념을 가지고 있다.
https://www.ibm.com/docs/ko/imdm/11.6?topic=product-configure-cluster-environment
수직 클러스터링 - 스케일 업은 시스템을 구성하는 하드웨어의 성능을 업그레이드하여 시스템을 확장하는 방식이기 때문에 쿠버네티스가 수평 클러스터링 - 스케일 아웃을 지원하는 프로그램이라는 것도 이어서 생각해 볼 수 있다. 결과적으로 쿠버네티스는 도커와 같이 컨테이너화된 프로세스의 스케일 아웃을 위한 도구로 이해하면 될 것 같다.
- 컨테이너는 가상 머신과는 다르게 호스트 운영체제를 공유한다. 그래서 가상 머신에 비해 가볍다.
- 컨테이너는 이미지를 통해 실행 환경을 독립적으로 가져갈 수 있으면서도 손쉽게 복제, 배포가 가능하다.
- 쿠버네티스는 이러한 컨테이너를 여러 서버에 걸쳐 여러 개를 실행시키는 도구로 이를 컨테이너 오케스트레이션이라 한다.
컨테이너 오케스트레이션이란?
컨테이너 오케스트레이션은 여러 서버 위에서 컨테이너의 전반적인 라이프사이클을 관리해주는 플랫폼으로 쿠버네티스는 이러한 유형의 대표적인 플랫폼이다. 쿠버네티스가 컨테이너를 관리하기 위해 담당하는 역할은 다음과 같다.
- 컨테이너의 실행 및 배포
- 컨테이너의 이중화와 가용성을 보장
- 수평확장 및 축소
- 스케줄링
- 네트워크 설정
- health-check
- 설정값 관리
쿠버네티스와 운영체제
쿠버네티스는 여러 컴퓨터의 집합으로 이루어진 하나의 거대한 시스템을 추상적으로 제어할 수 있는 사용자 인터페이스를 제공하고 컨테이너화된 프로그램이 정상적으로 실행될 수 있게 여러 기능을 제공해준다.
이러한 측면에서 쿠버네티스는 데이터 센터, 클러스터 운영체제라고 볼 수 있는 것이다. 일반적인 PC의 운영체제에서 사용자는 자신이 직접 하드웨어 자원을 제어하지 않고도 운영체제의 도움을 받아 자신이 원하는 작업들을 실행할 수 있는데, 쿠버네티스를 사용하면 클러스터된 자원(여러 서버에서 컨테이너화된 프로세스들)을 쿠버네티스를 통해 제어할 수 있기 때문이다.
쿠버네티스의 기본 개념
쿠버네티스는 일반적인 운영체제와 비슷한 기능들을 지원한다.
- 사용자가 개별 서버를 직접 제어하지 않고 쿠버네티스라는 추상화된 레이어를 통해 클러스터를 제어할 수 있는 하드웨어 추상화 기능을 제공한다.
- 컨테이너(프로세스)의 스케줄링, 자원할당 관리를 제공한다.
- kubectl이라는 유저 인터페이스를 이용하여 쿠버네티스를 제어할 수 있다.
애완동물 vs 가축
쿠버네티스는 컨테이너라는 실행환경 덕분에 많은 수의 서버를 손쉽게 관리할 수 있다. 그래서 쿠버네티스가 관리하는 서버들을 가축이라고 비유할 수 있다.
- 쿠버네티스에서는 서버마다 특별한 이름을 부여하지 않는다. 이는 서버마다 특정한 역할이 정해져 있지 않다는 것을 의미한다. 특정 서버의 역할을 빌드 서버, 웹 서버, 모니터링 서버 등으로 구분하지 않고 모든 서버들은 워커 서버로 동일하다. 쿠버네티스 안에서는 모든 서버들이 마스터와 워커로만 구분된다.
- 마스터에서는 쿠버네티스 운용을 위한 필수적인 핵심 컴포넌트가 존재하고, 나머지 워커 노드들은 단순히 컨테이너를 실행하는 환경으로만 사용한다.
- 그래서 한두 개의 서버가 망가져도 문제가 없다. 컨테이너 덕분에 손쉽게 다른 서버에게 그 역할을 맡길 수 있기 때문이다.
바라는 상태(Desired State)
쿠버네티스에는 바라는 상태라는 개념이 있다. 쿠버네티스는 사용자의 요청에 따라 현재 상태가 바라는 상태와 동일해지도록 사전에 미리 정의된 특정 작업을 수행한다.
쿠버네티스에서 바라는 상태는 사용자가 생각하는 최종 애플리케이션 배포 상태를 말한다. 사용자는 자신이 원하는 애플리케이션 배포 상태를 쿠버네티스에게 알려주면 쿠버네티스가 자동으로 현재 상태를 바라는 상태로 변경하게 된다.
쿠버네티스에 장애가 발생하여 애플리케이션이 죽더라도 바라는 상태 덕분에 손쉽게 본래 바라는 상태로 배포 상태를 되돌릴 수가 있다.
컨트롤러(Controller)
사용자가 바라는 상태를 선언하면, 쿠버네티스는 현재 상태를 사용자가 바라는 상태로 변경시킨다고 했다. 이때, 현재 상태를 바라는 상태로 변경하는 주체를 컨트롤러라고 부른다. 컨트롤러는 control-loop라는 루프를 돌며 특정 리소스를 지속적으로 모니터링하다가, 사용자가 생성한 리소스의 이벤트에 따라 사전에 정의된 작업을 수행한다.
쿠버네티스 리소스
쿠버네티스에서는 모든 것이 리소스로 표현된다. Pod, ReplicaSet, Deployment 등 쿠버네티스에는 다양한 리소스가 존재하고 각각의 역할이 있다.
가장 기본적인 형태의 리소스는 Pod이다. Pod은 하나 이상의 컨테이너를 가지는 쿠버네티스의 최소 실행 단위이다. 그래서 쿠버네티스에서 프로세스(컨테이너)를 실행한다는 의미는 Pod이라는 리소스를 생성하는 것과 비슷하다고 볼 수 있다.
선언형 커맨드(Declarative Command)
쿠버네티스는 선언형 커맨드를 지향한다. 이는 사용자가 직접 시스템의 상태를 바꾸지 않고 바라는 상태를 선언적으로 기술하여 명령을 내리는 것을 의미한다.
쿠버네티스에서는 YAML 형식을 이용하여 선언형 명령을 내린다. 다음은 쿠버네티스에서 사용하는 YAML 형식의 리소스(Pod) 예시이다.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: nginx
name: nginx
이러한 형식의 리소스를 YAML 정의서라고 부른다. 사용자는 쿠버네티스에 어떤 명령을 전달하거나 옵션값을 수정할 때 YAML 정의서에 YAML property를 추가하거나 수정해야 한다. 사용자는 최소한의 필수값을 채워서 리소스를 생성하면 쿠버네티스에서는 나머지를 기본값으로 설정하여 리소스를 생성하게 된다.
네임스페이스(namespace)
쿠버네티스에서는 클러스터를 논리적으로 분리하는 네임스페이스라는 개념이 있다. 네임스페이스마다 서로 다른 권한을 설정할 수 있으며, 네트워크 정책 등을 설정할 수 있다. 쿠버네티스에서는 물리적으로 하나의 쿠버네티스 클러스터 위에서 논리적으로 서로 다른 네임스페이스를 사용하여 클러스터 환경을 나눌 수 있다.
쿠버네티스에서는 모든 리소스를 네임스페이스 레벨 리소스와 클러스터 레벨 리소스로 구분할 수 있다. 네임스페이스 리소스는 특정 네임스페이스 안에 존재한다. Pod, Deployment, Service와 같이 대부분의 쿠버네티스 리소스가 네임스페이스 안에 포함된다. 반면, Node, PersistentVolume, StorateClass와 같이 네임스페이스 영역에 상관없이 클러스터 레벨에서 존재하는 리소스도 있다. 네임스페이스는 사용자가 원하는대로 자유롭게 추가, 삭제가 가능하다.
라벨 & 셀렉터(Label & Selector)
쿠버네티스에는 독특한 리소스 질의 체계가 존재한다. 특정 리소스에 명령을 전달하거나 정보를 확인하고 싶을 때 라벨링 시스템을 사용한다. 라벨링 시스템을 이용하여 질의하기 위해서 먼저 리소스에 key-value 형식의 태그정보(라벨)을 붙인다. 그런 다음, 태깅한 리소스를 찾기 위해 셀럭터라는 것을 이용하여 특정 key-value를 가진 리소스만 추출할 수 있다.
서비스 탐색
쿠버네티스 클러스터내에서 통신하기 위해 노드 위치와는 상관없이 어디서든 접근할 수 있는 서비스 끝점(Service Endpoint)이 필요하다. 사용자(or Pod)는 서비스 끝점을 통해 다른 컨테이너와 통신할 수 있다. 이를 위해 사용자는 서비스에 접근하기 위한 끝점의 접속 정보를 알아야 한다. 이를 서비스 탐색이라 한다.
쿠버네티스에서는 DNS 기반의 서비스 탐색을 지원하기에 사용자가 매번 새로운 서비스의 IP를 찾을 필요 없이 도메인 주소를 기반으로 서비스에 접근할 수 있다. 쿠버네티스에서는 Service 리소스를 이용하여 서비스 탐색을 제공한다.
설정 관리
쿠버네티스에서는 컨테이너를 실행할 때 필요한 설정값 및 민감 정보를 플랫폼 레벨에서 관리할 수 있게 메커니즘을 제공한다. 덕분에 사용자는 서버마다 필요한 설정값을 저장하거나, 서버간의 설정값 동기화 문제를 직접 해결할 필요 없이 쿠버네티스 클러스터에서 제공하는 설정값 관리 기능을 활용할 수 있다. ConfigMap 또는 Secret이라는 리소스를 이용하여 컨테이너의 설정들을 관리한다.
아키텍처
쿠버네티스는 일반적인 클러스터 시스템과 비슷하게 크게 마스터와 워커 노드로 구분한다.
마스터
마스터에는 쿠버네티스 클러스터를 구성하는 핵심 컴포넌트들이 존재한다. 마스터는 단일 서버로 구성할 수 있고, 고가용성을 위해 여러 서버를 묶어 클러스터 마스터로도 구축할 수 있다. 다음은 마스터를 구성하는 핵심 컴포넌트들이다.
- kube-apiserver(API 서버) : 쿠버네티스의 핵심 역할을 담당한다. 다른 모든 컴포넌트에서 오는 이벤트를 받아 적절히 응답한다. API 서버가 중심이 되어 모든 컴포넌트가 서로 통신한다. 사용자는 kubectl을 이용하여 API 서버에 명령을 보내고 응답을 받을 수 있다. 쿠버네티스에서 마스터와 통신한다는 뜻은 바로 이 API 서버와 통신을 한다는 것을 의미한다.
- etcd(저장소) : 쿠버네티스 클러스터에 필요한 모든 데이터를 저장하는 DB 역할을 담당한다. 관계형 DB가 아닌 분산형 key-value 저장소이며, API 서버 백엔드에 위치하여 필요한 데이터를 API 서버에게 제공하거나 중요한 데이터를 key-value 형태로 저장한다. 고가용성을 위해 etcd 클러스터를 구축할 수 있다.
- kube-scheduler(컨테이너 스케줄러) : 클러스터의 전반적인 컨테이너 스케줄링을 수행한다. 아직 실행되지 못한 컨테이너가 없는지 확인하고 쿠버네티스 위에 새로운 컨테이너를 실행할 때 노드 상태, 요청 리소스량, 제약 조건에 따라 적절한 서버를 선택하여 컨테이너를 배치한다.
- kube-controller-manager(컨트롤러 집합) : control-loops를 돌며 현재 상태와 바라는 상태를 비교하여 현재 상태가 바라는 상태가 되도록 클러스터의 상태를 변경하는 역할을 한다. 쿠버네티스에는 리소스별로 개별적인 리소스 컨트롤러가 존재하는데, 이러한 컨트롤러를 하나의 컴포넌트로 합친 것이 kube-controller-manager이다.
- cloud-controller-manger(클라우드 컨트롤러) : 클라우드 플랫폼에 특화된 리소스를 제어하기 위해 쿠버네티스 마스터에는 따로 cloud-controller-manger가 존재한다.
노드
워커 노드에는 마스터로부터 명령을 전달 받아 컨테이너를 실행시키는 노드 관리자와 컨테이너가 정상적으로 실행될 수 있도록 도와주는 네트워크 프록시와 실행 환경이 있다.
- kubelet(노드 관리자) : 각 노드에서 실행되는 메인 컴포넌트이다. 마스터로부터 특정 컨테이너를 실행시키기 위해 상세 명세를 받아 실행시키고, 해당 컨테이너가 정상적으로 동작하는지 지속적으로 모니터링한다. 주기적으로 API 서버와 통신하며 마스터와 노드간에 필요한 정보를 서로 주고받는다.
- kube-proxy : 각 노드에 위치하며 쿠버네티스 서비스 네트워킹을 담당하는 컴포넌트이다. 서비스마다 개별 IP를 가질 수 있게 만들어 주고 클러스터 내/외부의 트래픽을 Pod으로 전달할 수 있도록 패킷을 라우팅한다.
- container runtime(컨테이너 실행환경) : 실제 컨테이너를 실행시키는 역할을 담당한다. 도커를 예로 들 수 있다. 쿠버네티스는 도커뿐만 아니라 CRI(Container Runtime Interface) 규약을 따른다면 어떠한 런타임도 쿠버네티스의 컨테이너 실행 환경으로 사용할 수 있다.
장점
실행 환경 고립화
쿠버네티스를 이용한다면 개별 실행 환경에 대해 고민할 필요 없이 프로세스를 어디서나 실행시킬 수 있다. 실행 환경 자체가 가상 환경으로 감싸져있기 때문에 컨테이너 런타임이 존재하는 어디에서든지 정상적으로 동작하는 것을 보장받을 수 있기 때문이다.
리소스 관리
쿠버네티스는 기본적으로 여러 서버를 통합해서 관리하게 해주는 클러스터 시스템이다. 여러 서버의 리소스를 직접 하나씩 관리해야 한다면, 운영하는 데 큰 어려움이 따를 것이다. 쿠버네티스에는 자체적으로 각 서버의 리소스를 체계적으로 관리할 수 있는 기능을 제공한다. 서버별 리소스 사용량 모니터링, 리소스 사용량 제한 등 클러스터 시스템의 전반적인 리소스를 관리할 수 있다.
스케줄링
쿠버네티스를 사용하면 직접 프로세스를 스케줄링할 필요 없이 쿠버네티스에게 맡길 수 있다. 쿠버네티스의 내장 스케줄러는 최적의 노드를 찾아 컨테이너에 배치해준다. 필요에 따라서는 사용자가 원하는 노드로 컨테이너가 할당될 수 있게 상세 스케줄링 정책을 설정할 수도 있다.
프로세스 관리
스케줄링된 이후의 컨테이너를 관리하는 작업 역시 쿠버네티스가 처리해준다. 쿠버네티스는 클러스터 레벨에서 프로세스 관리를 편리하게 할 수 있다. 사용자는 클러스터 내에서 실행되고 있는 모든 컨테이너를 명령 하나로 확인할 수 있다. 마스터 API 서버에 요청을 하면 손쉽게 제어가 가능하다.
통합 설정 관리
쿠버네티스를 이용하면 개별적인 서버에서 각자 설정값을 파일로 보관하는 대신 중앙에서 통합하여 설정값을 관리할 수 있다. 이를 통해 특정 서버와의 종속성 없이 어느 서버에서나 프로세스를 정상적으로 실행할 수 있다.
손쉬운 장애 대응
쿠버네티스에서는 프로세스마다 리소스 사용량을 제한시킬 수 있어 문제가 되는 프로세스에만 장애가 발생하고 나머지 프로세스에는 영향을 받지 않게 설정할 수 있다. 더 크게는 서버 자체에 장애가 발생하여 해당 서버에서 실행되고 있는 컨테이너 전부에 문제가 발생할 수도 있지만, 각 노드들은 특별한 역할을 가지고 있지 않기 때문에 새로운 노드로 대체하는 작업을 쉽게 할 수 있다.
자동 확장
기존에 프로비저닝한 리소스가 부족하여 새로운 자원이 필요한 경우에도 쿠버네티스를 이용하면 손쉽게 자동 확장 기능을 설정할 수 있다. 그래서 평소에는 최소한의 자원만 준비하고, 추후 필요한 경우에 자동으로 리소스를 추가함으로써 운영 비용을 최소화하고 안정성을 높힐 수 있다.
하이브리드 클라우드 운영
쿠버네티스는 클라우드 플랫폼 뿐만 아니라 온프레미스 환경에서도 구축할 수 있다.
자가 치유
바라는 상태와 현재 상태를 저장하여 컨테이너에 문제가 생겨 죽더라도, 바라는 상태와 현재 상태를 비교하여 죽은 컨테이너를 다시 살릴 수 있다.
데이터 스토리지 관리
쿠버네티스를 이용하면 다양한 데이터 저장소를 자동으로 관리할 수 있다. 가장 기본적으로는 로컬 스토리지가 될 수 있으며 클라우드 플랫폼에서 제공하는 저장소나 NFS와 같이 네트워크 스토리지를 손쉽게 연결하고 해제할 수 있는 기능을 내장하고 있다.
배포 자동화
쿠버네티스에 사용자가 바라는 상태를 저장하면 쿠버네티스가 자동으로 적절한 노드를 선택하여 컨테이너를 배치한다. 그래서 새로운 버전의 애플리케이션을 배포하거나 이전 버전으로 롤백할 때도 바라는 상태를 입력하여 이를 수행할 수 있다.
'쿠버네티스' 카테고리의 다른 글
쿠버네티스 네트워킹(Service 리소스) (0) | 2022.07.13 |
---|---|
Pod 살펴보기 (0) | 2022.06.30 |
쿠버네티스 기본 명령어 (0) | 2022.06.26 |
쿠버네티스 설치 (0) | 2022.06.24 |
도커 기초 (0) | 2022.05.31 |