Kubernetes

[ DEVOCEAN OpenLab ] Kubernetes Architecture 구성요소 (k8s VS k3s)

jogaknabi_1023 2024. 5. 3. 06:22

k3s 란?

k3s는 Rancher 에서 개발한 경량 Kubernetes 버전이다. 소규모 서버, IoT 기기 등의 프로덕션용으로 생성되었으며, 바이너리는 50개월 미만으로 매우 작은 가상 머신에서 실행될 수 있다.

 

(출처 : https://docs.k3s.io/kr/architecture)

 

k8s   VS   k3s 

1. 기본적인 저장소의 차이

Kubernetes(k8s)의 기본 저장소: etcd
Kubernetes(k8s)의 기본 저장소는 etcd이다. etcd는 분산형 키-값 저장소로, Kubernetes 클러스터의 모든 상태 및 구성 정보를 저장하는 데 사용된다. 이 정보에는 파드, 서비스, 구성맵, 구성 파일 및 기타 Kubernetes 개체에 대한 모든 정보가 포함된다.

 

k3s의 기본 저장소: SQLite3
k3s의 기본 저장소는 SQLite3이다. k3s는 경량화된 Kubernetes 배포를 위해 설계되었으며, 이를 달성하기 위해 etcd 대신에 SQLite3를 사용하여 클러스터의 상태를 저장한다. SQLite3는 단일 파일에 모든 데이터를 저장하는 경량형 관계형 데이터베이스로, k3s의 구성 정보와 상태를 저장하는 데 사용된다.

 

2. 네트워크

Kubernetes(k8s):

일반적인 Kubernetes에서는 네트워크 구성에 대한 추가적인 설정이 필요하다. 보통은 CNI(Container Network Interface) 플러그인을 사용하여 네트워크를 구성한다.

 

k3s:
k3s에서는 기본적으로 flannel CNI 플러그인이 내장되어 있다.

 

3. Control Plane 구성

Kubernetes(k8s):
일반적인 Kubernetes에서는 Control Plane 구성 요소로는 API 서버, 스케줄러, 컨트롤러 매니저, etcd 가 있다.

이러한 구성 요소들은 각각 별도의 프로세스로 실행되는 독립적인 소프트웨어 컴포넌트이다.

k3s:

반면에 k3s에서는 단일 바이너리에 모든 Control Plane 구성 요소를 포함하여 경량화된 형태이다.

하나의 실행 파일로 묶어서 제공하기 때문에, k3s 바이너리를 실행하면 컴퓨터에서 API 서버, 스케줄러, 컨트롤러 매니저 등의 모든 구성 요소들이 단일 프로세스로 실행된다. 이 프로세스가 클러스터의 중앙 제어와 관리를 담당하며, 클러스터의 상태를 유지하고 리소스를 관리한다.

 

4. 컨테이너 런타임

Kubernetes(k8s):
일반적인 Kubernetes에서는 컨테이너 런타임으로 Docker를 주로 사용한다.

k3s:

k3s에서는 일반적으로 containerd를 사용하여 컨테이너를 관리한다.

 

 

그럼 경량화 k3s 대신 가장 기본적인 쿠버네티스(k8s) 아키텍처를 하나씩 공부해보자.

 

Kubernetes Control Plane(k8s) 구성요소

(출처: https://kubernetes.io/ko/docs/concepts/overview/components/)

 

쿠버네티스 기능 제어를 전체적으로 담당하는 컨트롤 플레인(Control Plane) 컴포넌트와 컨트롤 플레인 컴포넌트의 요청을 받아 각 노드에서 동작을 담당하는 노드(Node) 컴포넌트로 나누어볼 수 있다.

 

 

컨트롤 플레인(Control Plane) 컴포넌트

1) kube-apiserver

쿠버네티스 클러스터로 들어오는 요청을 가장 앞에서 접수하는 역할을 한다. kubectl을 사용한 명령 수행 시 모든 명령들은 kube-apiserver로 전송된다. 이렇게 전달된 요청에 대하여 kube-apiserver는 이 요청의 처리 흐름에 따라 적절한 컴포넌트로 요청을 전달하는 역할까지 맡고 있다.

 

2) etcd

쿠버네티스 클러스터가 동작하기 위해서는 클러스터 및 리소스의 구성 정보, 상태 정보 및 명세 정보 등이 필요하다. etcd는 이를 키-값(key-value) 형태로 저장하는 저장소이다. 안정적인 동작을 위해 자료를 분산해서 저장하는 구조를 채택하고 있는데, Raft 알고리즘을 사용하여 데이터를 분산 저장한다.

 

3) kube-scheduler

쿠버네티스의 기본 작업 단위인 pod는 여러 노드로 구성된 클러스터에서 특정 노드에 배치되어 동작한다.이때 새로 생성된 파드를 감지하여 어떤 노드로 배치할지 결정하는 작업을 스케줄링이라고 하는데, 이런 스케줄링을 담당하는 컴포넌트가 kube-scheduler 이다.

 

4) kube-controller-manager

클러스터의 상태를 모니터링하고 원하는 상태로 유지하기 위해 동작하기 위해 쿠버네티스 클러스터의 여러 컨트롤러를 실행하는 프로세스이다. 각각 제어장치의 별도의 프로세스이지만 복잡성을 줄이기 위해 모두 단일 바이너리로 컴파일되어 단일 프로세스에서 실행된다.

 

컨트롤러 예시)

  • Node controller: 노드가 다운되었을 때 이를 인지하고 대응하는 역할을 담당한다.
  • Job controller: 일회성 작업을 나타내는 Job 객체를 관찰한 다음 Pod를 생성하여 해당 작업을 완료한다.
  • EndpointSlice controller: 서비스와 Pod 간의 링크 제공한다. EndpointSlice는 특정 서비스의 엔드포인트를 나타내는 리소스.
  • ServiceAccount controller: 새 네임스페이스에 대한 기본 ServiceAccount를 만든다.

 

노드(Node) 컴포넌트

1) kubelet

노드에서 컨테이너가 동작하도록 관리해 주는 핵심 요소이며, 각 노드에서 파드를 생성하고 정상적으로 동작하는지 관리하는 역할을 담당하고 있다.

실제로 우리가 쿠버네티스의 워크로드를 관리하기 위해 내려지는 명령은 kubelet을 통해 수행된다고 볼 수 있다. 우리가 쿠버네티스 파드를 관리하기 위해 작성하는 YAML을 쿠버네티스 클러스터에 적용하기 위해 kubectl 명령어를 사용할 때, 이 YAML이 kube-apiserver로 전송된 후 kubelet으로 전달된다. kubelet은 이 YAML을 통해 전달된 파드를 생성 혹은 변경하고, 이후 이 YAML에 명시된 컨테이너가 정상적으로 실행되고 있는지 확인한다.

 

2) container runtime

컨테이너 런타임은 파드에 포함된 컨테이너 실행을 실질적으로 담당하는 애플리케이션을 의미한다.

단, 컨테이너 런타임은 쿠버네티스 구성 요소에 기본적으로 포함되어 있거나, 특정 소프트웨어를 지칭하는 것은 아니다. 쿠버네티스가 컨테이너를 제어하기 위해 제공하는 표준 규약인 컨테이너 런타임 인터페이스(CRI)를 준수하여 쿠버네티스와 함께 사용할 수 있는 외부 애플리케이션들을 의미한다. 이러한 규약을 따르는 대표적인 컨테이너 런타임은 containerd, CRI-O 등이 있습니다.

 

3) kube-proxy

쿠버네티스 클러스터 내부에서 네트워크 요청을 전달하는 역할을 한다.

Pod의 IP 주소를 동적으로 할당받기 때문에 IP가 자주 변경되는 문제를 해결하기 위해 서비스(Service) 리소스를 사용한다. 즉, 파드가 다시 시작될 때마다 IP 주소가 변경될 수 있는데, 이러한 문제는 외부에서 파드에 접근하기가 어렵게 만든다. 그래서 서비스를 사용하여 파드에 대한 고정적인 접근을 제공하는 것이다.

서비스는 파드 집합을 추상화한 것으로, 서비스에는 파드를 대표하는 가상 IP 주소가 할당된다. 이 가상 IP 주소는 파드 IP와는 별도로 관리되며, 서비스는 이 가상 IP 주소를 클라이언트에 노출하고 클라이언트가 서비스에 요청을 보낼 때 이 가상 IP 주소를 사용하여 요청을 전달한다.

이 때, 가상 IP 주소에 도착한 요청을 실제 파드로 전달하기 위해 kube-proxy라는 컴포넌트를 사용한다. 짧게 말해 서비스의 가상 IP 주소로 들어오는 요청을 실제 파드의 IP 주소로 전달하는 것이다.

 

 

 

자료출처:

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

https://www.samsungsds.com/kr/insights/kubernetes-3.html