쿠버네티스 도입 배경
쿠버네티스, 컨테이너 기술이 도입되기 전 대부분의 소프트웨어 애플리케이션은 하나의 프로세스 또는 몇 개의 서버에 분산된 프로세스로 실행하는 거대한 모놀리스였다. 이런 레거시 시스템은 릴리즈 주기가 느리고, 개발자는 전체 릴리즈 주기가 끝날 때마다 전체 시스템을 패키징 하고 운영팀에게 넘기고, 운영팀은 이를 운용 가능한 서버로 직접 마이그레이션 했다.
이런 거대한 모놀리스 레거시 애플리케이션은 점차 마이크로 서비스라는 독립적으로 실행되는 더 작은 구성요소로 세분화 됐다. 마이크로 서비스는 서로 분리돼 있기 때문에 서비스 개별적으로 개발, 배포, 업데이트, 확장할 수 있다. 하지만 세분화가 많이 될수록 관리해야 할 운영 포인트가 증가하여 이를 유지하는데 어려움이 생기게 됐다.
이런 구성 요소의 서버 배포를 자동으로 스케쥴링하고 구성, 관리, 장애 처리를 포함하는 자동화 구현을 위해 쿠버네티스가 등장하게 됐다.
쿠버네티스는 하드웨어 인프라를 추상화하고 데이터 센터 전체를 하나의 거대한 컴퓨팅 리소스로 제공한다. 실제 세세한 서버 정보를 알 필요 없이 애플리케이션 구성 요소를 배포하고 실행 할 수 있다.
쿠버네티스란 명칭은 키잡이(helmsman)나 파일럿을 뜻하는 그리스어에서 유래했다. K8s라는 표기는 “K”와 “s”와 그 사이에 있는 8글자를 나타내는 약식 표기이다. 구글이 2014년에 쿠버네티스 프로젝트를 오픈소스화했다. 쿠버네티스는 프로덕션 워크로드를 대규모로 운영하는 15년 이상의 구글 경험과 커뮤니티의 최고의 아이디어와 적용 사례가 결합되어 있다.
마이크로 서비스
쿠버네티스에 대해 자세히 살펴보기 전 애플리케이션의 개발과 배포 방식이 어떻게 바뀌었는지 살펴보자. 소프트웨어 애플리케이션을 작은 마이크로 서비스로 세분화하며 도커와 같은 컨테이너 기술을 사용하는 것의 이점을 더 잘알 수 있을 것이다.
모놀리스 애플리케이션은 아래와 같은 특징(문제)을 가지고 있다.
- 애플리케이션의 모든 것이 서로 강하게 결합돼 있다.
- 전체가 하나의 운영체제 프로세스로 실행되기 때문에 하나의 개체로 개발, 배포, 관리된다.
- 애플리케이션의 한 부분만 변경하더라도, 전체 애플리케이션을 재배포 해야한다.
- 시간이 지남에 따라 구성요소간 경계가 불분명해지고, 상호의존성의 제약이 증가하여 시스템 복잡성이 증가한다.
마이크로 서비스로 애플리케이션 분할
이런 특징들로 복잡한 모놀리스 애플리케이션을 마이크로서비스라는 독립적으로 배포할 수 있는 작은 구성요소로 분할해야 한다. 각 마이크로서비스는 독립적인 프로세스로 실행되며, 단순하고 잘 정의된 인터페이스로 다른 마이크로서비스와 통신한다.
마이크로서비스는 일반적으로 RESTful API를 제공하는 HTTP와 같은 동기 프로토콜과 AMQP와 같은 비동기 프토토콜로 통신한다. 이런 프로토콜은 단순하고 특정 개발언어에 종속적이지 않다. 각 마이크로 서비스는 대체로 적적인 외부 API를 제공하는 독립형 프로세스이기 떄문에 개별적으로 개발, 배포할 수 있다.
마이크로서비스 확장
전체 시스템을 확장해야 하는 모놀리스 시스템과 달리 마이크로서비스 확장은 서비스별로 수행되므로 리소스가 더 필요한 서비스만 별도로 확장할 수 있으며 다른 서비스는 그대로 유지해도 된다. 마이크로서비스는 수평, 수직 확장이 가능하다.
마이크로서비스 배포의 단점
마이크로서비스도 단점이 있다. 시스템 구성요소가 많아지면 배포 조합의 수 뿐만 아니라 구성요소 간의 상호 종속성 수가 훨씬 많아지므로 배포 관련 결정이 점점 어려워진다.
마이크로서비스는 여러 개가 서로 함께 작업을 수행하므로 서로를 찾아 통신해야 한다. 즉, 마이크로서비스를 배포할 때 각 각의 마이크로 서비스 전체가 하나의 시스템처럼 동작할 수 있도록 누군가 또는 무언가가 제대로 구성(연결)해야 한다.
또한 마이크로서비스는 여러 프로세스와 시스템에 분산돼 있기 때문에 실행 호출을 디버그하고 추적하기 어렵다. 다행히 이런 문제는 Zipkin과 같은 분산 추적 시스템으로 해결한다.
쿠버네티스 소개
쿠버네티스 기원
구글은 오랜 세월동안 보그라는 내부 시스템을 개발해 애플리케이션 개발자와 시스템 관리자가 수천 개의 애플리케이션과 서비스를 관리하는데 도움을 줬다. 보그는 개발과 관리를 단순화할 뿐만 아니라 인프라 활용률을 크게 높일 수 있었는데, 이는 조직이 그만큼 클 때 중요해진다. 수십만 대의 머신을 사용할 때, 사용률이 조금만 향상돼도 수백만 달러가 절약되므로 그러한 시스템을 개발할 동기는 분명하다.
구글은 10년 동안 보그를 비밀로 유지하다가 2014년 이러한 경험을 기반으로 하는 오픈소스 쿠버네티스를 출시했다.
쿠버네티스 이해하기
쿠버네티스는 컨테이너화된 애플리케이션을 쉽게 배포하고 관리할 수 있게 해주는 소프트웨어 시스템이다. 쿠버네티스를 사용하면 모든 노드가 하나의 거대한 컴퓨터인 것처럼 수천 대의 컴퓨터 노드에서 소프트웨어 애플리케이션을 실행시킬 수 있다. 클러스터에 노드가 몇 개, 수 천개가 있든 쿠버네티스에 애플리케이션을 배포하는 것은 항상 동일하다.
쿠버네티스 핵심 이해하기
위 그림은 쿠버네티스 시스템의 가장 간단한 모습이다. 쿠버네티스 클러스터는 마스터 노드와 여러개의 워커노드로 구성된다. 관리자가 애플리케이션 매니페스트를 쿠버네티스 마스터에게 게시하면 쿠버네티스는 해당 애플리케이션을 워커노드 클러스터에 배포하고 하나의 배포 단위를 Pod라고 한다.
하나의 Pod에 특정 애플리케이션이 함께 실행되도록 지정할 수도 있으며 Pod는 물리적으로 여러 클러스터(워커노드)에 걸쳐 분산되어 배포되지만 서로 통신할 수 있다.
쿠버네티스 클러스터 아키텍처 이해하기
쿠버네티스 클러스터는 자동화 되고 컨테이너 구조를 가진 애플리케이션의 호스팅과 배포된 애플리케이션 간의 통신 구성을 목적으로 하며 쿠버네티스의 클러스터는 마스터 노드, 워커노드의 집합으로 구성되어 있다.
노드의 특징 및 역할은 아래와 같다.
노드의 특징 및 역할
- 마스터 노드 마스터 노드는 애플리케이션 컨테이너를 워커노드에 배치, 배치 계획 수립, 워커 노드 모니터링, 노드에 대한 정보 저장 등을 수행한다.
- 구성 요소
- ETCD Cluster Node에 배치된 컨테이너의 정보, 로드 시간, 등의 정보 저장소
- kube-sceduler 컨테이너를 Node에 배치할 때 컨테이너와 Node의 상태를 파악하여 최적의 Node에 배치
- Controller-Manager
- Node-Controller 노드를 관리하는 컨트롤러, 새로운 노드의 가입, 해제 등의 역할 담당
- Replication-Controller 원하는 수 만큼의 컨테이너(Pod)가 작동하는지 감시하고, 대응 함
- Kube-apiserver 모든 컨트롤러의 오케스트레이션(제어)를 담당하는 곳, 컨트롤러 들과 API를 통해 소통함 외부, 클러스터 내부 노드들과도 소통하고, 모니터링을 통해 원하는 구성이 되도록 제어함
- 구성 요소
- 워커 노드 워커 노드는 애플리케이션 컨테이너를 적재하고, 실행시킨다.
- 구성요소
- kubelet kubelet은 모든 Node에 구성되어 있음 Kube-apiserver와 API 형태의 정보를 주고받으며, 명령을 전달 받거나, 현재 서버 상태를 전송한다. kube-proxy와 Container를 제어한다.
- kube-proxy 노드의 집합으로 구성된 클러스터 내 다른 노드들과의 통신을 지원하는 객체 예 :A node-web Pod, B node-DB Pod간의 통신
- 구성요소
쿠버네티스에서 애플리케이션 실행
쿠버네티스에서 애플리케이션을 실행하려면 먼저 하나 이상의 컨테이너 이미지로 패키징하고 해당 이미지를 이미지 레지스트리로 푸시한 다음 쿠버네티스 API 서버에 디스크립션을 게시해야 한다. 디스크립션 안에는 컨테이너 이미지, 애플리케이션 구성 요소가 포함된 이미지, 해당 구성요소가 통신하는 방법, 동일 서버에 함께 배치돼야 하는 구성 요소와 같은 정보가 포함된다. 또한 애플리케이션의 복제본 수를 지정할 수 있다.
디스크립션으로 컨테이너 실행하는 방법의 이해
API-Server는 멱등성을 보장한다. 만약 Nginx 라는 이름의 Pod를 배치하는 요청을 받은 경우 API-Server는 ETCD의 정보를 확인하고, Pod가 존재한다면, 별다른 행위를 하지 않고, ETCD로 부터 Nginx라는 Pod가 없다고 반환 받는다면 Controller에 Pod를 생성하라고 명령한다. 그러면 Controller는 Pod를 생성함과 동시에 API에게 생성 했다고 알리고, API-Server는 Scheduler에게 Pod를 배치하라고 명령한다.
Scheduler는 Pod를 배치 할 적절한 Node를 찾게 되면 해당 Worker Node의 Kubelet에게 Pod를 배치하라고 명령하고, Pod를 배치하게 된다.
Kubelet은 자신의 노드에 배치 된 Pod의 상태를 모니터링 한다, 만약 Pod가 죽으면 Kubelet은 API-Server에게 알리고, API-Server는 Controller → Scheduler에 Pod 배치를 명령하여 새로운 Pod를 배치하도록 해준다.
실행된 컨테이너 유지
쿠버네티스 클러스터는 관리자로 부터 디스크립션을 전달받아 애플리케이션을 배포한 후 지속적으로 디스크립션에 정의된 배포 내용과 일치하는지 확인한다. 예를 들어 항상 5개의 Pod를 실행하도록 선언 했다면 주기적으로 배포된 Pod 개수를 확인하여 항상 5개의 Pod가 실행되도록 한다.
마찬가지로 워커 노드 전체가 종료되거나 엑세스 할 수 없게 되면 쿠버네티스는 해당 노드에서 실행중이던 모든 Pod를 새로 스케쥴링하여 새로운 노드에서 실행되도록 관리한다.
복제본 수 스케일링
애플리케이션이 실행되는 동안 복제본 수를 늘릴지 줄일지 결정할 수 있으며 메트릭 서버를 구성하여 쿠버네티스가 동적으로 CPU 부하, 메모리 사용량, 초당 요청 수, 등을 기반으로 애플리케이션의 복제본 수를 자동으로 조정할 수 있다.(수평 확장, 축소)(Sale-out,Scale-in)
쿠버네티스 사용의 장점
애플리케이션 배포의 단순화
쿠버네티스는 모든 워커 노드를 하나의 배포 플랫폼으로 추상화 하여 제공하기 때문에 애플리케이션 개발자는 클러스터를 구성하는 서버에 대해 크게 알 필요가 없다. 개발자는 쿠버네티스 마스터에게 매니페스트 파일을 게시하면 해당 요구사항에 맞게 쿠버네티스 마스터가 배포를 진행할 것이다.
하드웨어 활용도 높이기
서버에 수동으로 애플리케이션을 실행하는 대신 쿠버네티스 클러스터를 구성하고 애플리케이션을 실행함으로써, 인프라와 애플리케이션을 분리할 수 있게된다. 또한 쿠버네티스 관리자는 요청받은 매니페스트에 정의된 리소스를 사용할 최적의 워커노드를 찾아 배포하기 때문에, 여러개의 워커노드 중에서 가장 최적의 리소스만을 사용하여 배포할 수 있으므로 하드웨어의 활용도를 최대한으로 높일 수 있다.
상태 확인과 자가치유
쿠버네티스는 애플리케이션 구성 요소와 이 애플리케이션이 구동중인 노드를 모니터링 하다가 장애 발생 시 자동으로 애플리케이션을 스케쥴링하여 재배포 한다. 이로써 운영 팀은 애플리케이션 구성 요소를 수동으로 마이그레이션할 필요가 없어지게 된다.
오토스케일링
쿠버네티스를 사용해 배포된 애플리케이션은 운영팀이 지속적으로 모니터링할 필요가 없음을 의미한다. 앞서 언급했듯이 쿠버네티스는 각 애플리케이션에서 사용하는 리소스를 모니터링하고 정의된 요구사항에 맞춰 애플리케이션 복제본을 늘이거나 줄임으로써 애플리케이션의 성능을 자동 유지할 수 있다.
'클라우드' 카테고리의 다른 글
[k8s] Deployment (0) | 2023.03.08 |
---|---|
[k8s]Replication Controller & Replicaset (0) | 2023.03.08 |
[docker]쉘 스크립트를 사용하여 도커 오토스케일링 구현하기 (0) | 2023.03.08 |
[k8s] Kubectl 명령어 자동완성 설정하기 (0) | 2023.03.08 |
[k8s] 클러스터 구성하기 (0) | 2023.03.08 |