개발/backend

[Backend] 쿠버네티스(K8S)를 시작해보자(1) - 이론편

나인에스 2022. 3. 6. 16:22
이 글은 2020년 초에 최초 작성 되었고, 2021년에 일부 내용이 수정되었습니다.

개요

예전부터 가상머신이나 컨테이너화 된 워크로드 구성에 대해서는 널리 알려져 있고 많은 분야에서 사용되고 있었다. 특히 Docker가 등장하면서 이후 컨테이너화는 빠른 속도로 고도화가되었고, 이를 이용한 컨테이너 오케스트레이션인 쿠버네티스는 이제는 큰 회사부터 스타트업에 이르기까지 수많은 회사에서 도입을 하고 있는 상황이다.

가상머신(VM)과 컨테이터 둘모두 하나의 HW에서 여러개의 application을 독립적으로 실행할 수 있고 각각의 실행 환경은 격리 되어(sendboxing) 서로의 환경에 자유롭게 접근할 수 없는 형태가 되면서 자연스럽게 어느정도 높은 수준의 보안성을 제공해 주고 있다. 또한 두 환경 모두 만들어진 패키지를 실행 할 수 있는 환경만 있다면 어디든지 동일한 애플리캐이션을 실행 할 수 있고, MSA(Micro Service Architecture)를 구성하기에 적합한 형태를 가질수 있기 때문에 일부의 배포, 일부의 수정 혹은 개발 환경과 서비스 환경의 동기화 등 어려 장점을 모두 가지고 있다.

여기서, 두가지 환경의차이를 살펴 보면, 가상머신(VM)의 경우 패키징 되어 있는 환경이 운영체를 포함한 모든 내용을 포함하고 있어서 실행되는 단위가 하나의 완전한 머신이 된다. 컨테이너의 경우 가상머신과 비슷한 sendbox 형태를 보여주고 있으나 패키징 되어 있는 application간의 운영체제는 공유하는 형태이다. 기본적인 운영체제를 공유하기 때문에 가상머신(VM)보다는 패키징의 크기나 리소스 소모등 모든 면에서 가볍게 구성이 된다. 

쿠버네티스 (Kubernates, K8S) ??

쿠버네티스는 구글에서 2014년에 오픈소스로 공개한 프로젝트이고 컨테이너화된 워크로드와 서비스를 관리하기 용이한 방향으로 개발된 플랫폼이다. 확장성, 이식성, 자동화된 로드벨런싱, 스토리지 관리, 자동화된 복구등 구글이 다년간의 경험을 통해서 만들어진 내용이기 때문에 아주 많은 기능들을 제공하고, 아주 많은 extension, addon, 3rd Party tool등이 존재한다. 이는 사용 목적에 맞게 유연하게 사용할 수 있는 장점도 있으나 너무 많은 내용이 집약되어 있어서 잘 사용하기가 쉽지않다는 단점 또한 존재 한다.

쿠버네티스외에도 도커의 Swarm, Nomad, Marathon 등 여러 컨테이너 오케스트레이션 플랫폼이 있으나 최근 마이크로소프트, RedHat, IBM등 다수의 기업들이 쿠버네티스를 채용하고 있어서 컨테이너 부분에서는 압도적인 대세가 되었다. 이에 맞춰 대부분의 cloud 업체(AWS, GCP, Asure등)에서도 쿠버네티스를 managed형태의 서비스로 제공하고 있기 때문에 소규모의 스타트업에서도 채용할 정도로 대중화 되었다.

기본 구성 요소

쿠버네티스 클러스터

쿠버네티스는 클러스터 단위의 집합이라고 할 수 있고, 각 클러스터는 컨테이터화된 애플리캐이션을 실행하는 Worker Node들과 이를 상황에 맞게 실행, 관리, 모니터링 하는 Control Plane을 가지고 있다.

Control Plane

Control Plane은 클러스터가 동작하는 핵심 요소로 클러스터 전체의 상태, 실행, 설정, 스케쥴링등 모든 것을 관리한다. control plane는 단일 혹은 여러 Master Node 에서 실행되고 Master Node는 각 Worker Node들과 통신 하면서 이를 관리한다. 일반적으로 Master Node에 문제가 생길 경우 시스템 전체가 다운되기 때문에 3개의 마스터 노드를 실행해서 안정성을 높이고 있다.

kube-apiserver

API server는 쿠버네티스 내/외부 모든 요청을 처리하는 Control plane의 핵심 component다. 수평확장을 통해서 트래픽을 조절할 수 있도록 디자인되어 있다. REST 요청을 제공하고 이를 통해서 노드들의 state를 조회할 수 있다. 이외에도 실행 중인 Pod 컨테이너의 로그를 보고, command를 전달하는 등 troube shoting, 디버거 역활도 수행한다.

etcd

일종의 클러스터 데이터를 저장하는 저장소 역활을 한다. RAFT 알고리즘을 이용한 key-value 형태의 저장소이고, 분산/복제가 가능하기 때문에 안정성과 고가용성을 제공한다. key-value값을 읽고 저장하는 기능과 특정 key-value를 observe해서 변경될때 특정 action을 수행할 수 있는 기능도 있다. 클러스터 데이터의 설정이나 상태들을 모두 저장하기 때문에 문제 발생시 이 데이터를 복구해서 기존 클러스터 상태로 복구 할 수 있다.

kube-scheduler

Pod의 생성을 observe하고 rule, resource등의 조건에 맞게 적절한 Node를 선택 할당해주는 역활을 하는 component이다.

kube-controller-manager

쿠버네티스에서 동작하는 거의 모든 들의 상태를 관리 감독한다. Node가 다운되었을때 필요한 notifcation과 action에 대한 역활을 하는 Node controller, 적절한 수의 Pod를 유지 시켜주는 역활의 Job controller(Replication Controller), 서비스와 Pod를 연결 관리를 하는 endpoint controller, 계정과 access token을 생성 관리하는 service account-token controller 로 구성되어 있다.

cloud-controller-manager

Cloud Service(AWS, GCP, Azure등) 에 특화되어 있는 controller이다. 이 controller manager는 클러스터를 cloud service업체 API에 연결할 수 있게 해주고, 이를 통해서 Node를 생성, 삭제하거나 로드벨런싱, Volume 연결 등의 작업을 할 수 있다. 

Node

Node Comonent는 running중인 Pod를 유지/관리 하고, 쿠버네티스 runtime환경을 제공하며, 모든 Node상에서 동작한다.

kubelet

클러스터내의 모든 Node에서 실행되고 Pod에서 Container들이 동작하도록 관리한다. 또한 Node에 할당되어 있는 Pod의 lifecycle를 관리하고, Pod에서 동작중인 container의 상태를 모니터링해서 주기적으로 마스터 노드(Control Plane)에게 전달한다.

kube-proxy

클러스터내의 각 Node에서 실행되는 network proxy로 Pod으로 연결되는 네트워크를 관리 한다. network rules을 관리하고 이 rule에 따라 Pod와 통신을 하려고 하는 내부/외주에서의 네트워크 session을 허용하거나 block한다.

iptables를 이용해서 rule을 관리할 수 있으나 Pod가 많아짐에 따라 iptables의 rule 개수가 수백, 수천개가 넘어 갈 수 있고 이것을 일일이 관리 하는 것은 매우 힘든일이 된다. 이런 문제 때문에 최근 IPVS를 지원하고 사용하고 있다.

Container runtime

Container의 실행을 담당한다. 기본적으로 쿠버네티스는 여러 container 종류의 runtime (Docker, Containerd, CRI-O, Kubernates CRI)를 지원한다.

Master - Node 

Component 구성요소와 유사한 그림이나 이는 실제 클러스터가 동작할때의 개념을 추상화 한것이다. 클러스터를 관리하는 Master와 실제 애플리캐이션이 동작하기위한 Container가 배포되어 실행되는 Node로 구성되어 있고, 모든 command들은 Master의 API server를 에 전달하고 Node는 Master와 통신을 하면서 요구되는 작업을 실행하게 된다. 또한 각각의 Node들은 서로 통신하지 않고 Master의 API server를 통해서 필요한 작업이나 필요한 데이터를 요청, 실행하게 된다.

기본적인 Master-Node의 동작은 아래와 같은 동작 및 순서를 가진다.

  • kubectl과 같은 명령 tool을 이용해서 ReplicaSet을 생성해서 API Server로 전달
  • Kube Controller 이 ReplicaSet에 정의된 내용을 확인하고 만족하는 Pod이 있는지 확인
  • Pod가 없으면 정의된 Pod의 template을 보고 신규 Pod를 생성
  • Master의 Scheduler는 할당되지 않은 Pod가 있는지 체크하고 만약 있다면 해당 Pod의 조건에 맞는 Node를 확인해서 할당.
  • Node의 Kubelet는 Pod가 할당은 되었으나 아직 생성,실행 되고 있지 않는 Pod를 확인하고 있다면 Spec를 확인해서 Pod를 생성 및 실행.
  • Node의 Kubelet는 주기적으로 Master와 통신하면서 Pod의 상태 등을 전달한다.

Ref.

https://kubernetes.io/docs/concepts/overview/components/

 

Kubernetes Components

A Kubernetes cluster consists of the components that represent the control plane and a set of machines called nodes.

kubernetes.io