쿠버네티스 컴포넌트와 오브젝트

2023. 11. 3. 22:08개발/Docker-K8s

AWS에서 고객사를 대상으로 진행하는 EKS 교육을 들었는데 거기서 나온 쿠버네티스 용어들을 간단히 정리해본다

 

쿠버네티스를 사용하는 이유

토이 프로젝트를 하면서 소수의 컨테이너를 관리하는데 큰 어려움이 없으나 기업 수준에서는 다수의 컨테이너를 띄워서 사용하게 된다. 이런 컨테이너를 수작업으로 운영 및 제어하기 위해선 많은 리소스가 필요하다.

 

따라서 컨테이너를 자동으로 관리해주는 컨테이너 오케스트레이션의 필요성이 대두 되었고 그 결과 Kubernetes가 등장하게 되었다. (물론 다른 오케스트레이션이 있긴하지만 K8s가 사실상 업계 표준으로 자리 잡았다.)

 

쿠버네티스 클러스터

기본적으로 "쿠버네티스를 사용한다"라는 말은 쿠버네티스의 클러스터를 구축하는것을 말한다. 

 

쿠버네티스 클러스터는 노드들의 집합이다. 노드는 크게 데이터 플레인 컨트롤 플레인으로 나뉜다.

- 데이터 플레인은 워커 노드들로 구성되어 있다. 워커 노드는 파드를 호스트한다. (일반적으로 파드의 집합이 노드라고 이해하면 편하다.)

- 컨트롤 플레인은 워커 노드와 클러스터 내에 있는 파드를 관리하고 제어한다. 여기서 잘 봐야될게 데이터 플레인은 파드를 호스팅만 하고 직접적인 관리나 제어는 컨트롤 플레인이 한다는 점이다.

쿠버네티스 클러스터 컴포넌트

쿠버네티스 컴포넌트는 클러스터를 구성하는 기본적인 요소들을 말한다. (Component와 Object를 명확히 구분해서 생각해야함)

 

쿠버네티스 클러스터를 구성하는 Component 목록

 

Kubernetes Components

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

kubernetes.io

Control Plane을 구성하는 Component

kube-apiserver

- control Plane과 Client가 통신할 수 있도록 해주는 API 서버이다.

- kube-apiserver는 수평적인 확장을 하도록 디자인 되었다. API 서버로 트래픽이 몰린다면 분산을 위해서 kube-apiserver 인스턴스의 수를 늘릴 수 있음을 의미한다.

etcd

- 지속적이며 고가용성을 가진 Key-Value 스토리지이다. 클러스터에서 발생한 데이터를 모두 이 Component에 저장한다.

- 클러스터 데이터 백업의 용도로도 많이 사용하며, 사용하려면 적절한 백업 계획을 세우자.

kube-scheduler

- 컨트롤 플레인은 아직 Node에 할당되지 못한 새로 생성된 Pod를 모니터링하다가 적잘한 Node가 있다면 해당 Node에 Pod를 배치시킨다. (내부적으로 몇 가지 factor들을 고려해서 적절한 Node를 선택함.)

kube-controller-manager

- controller란? K8s API Server로부터 Object 정보를 얻어서 Object를 제어하는 역할을 수행한다.

- kube-controller-manager는 이런 Controller의 집합을 의미한다. (Node controller, Job controller 등이 있음)

cloud-controller-manager

- Cloud provider의 API와 연동해서 작동하는 controller들의 집합을 의미한다.

- 이를 통해서 각 component가 Cloud provider의 API와 직접 통신하지 않도록 한다. (단일 end-point를 유지할 수 있게됨)

- 만약 온프레미스 환경이나 개인 PC에서 쿠버네티스를 구동한다면 cloud controller manager가 클러스터 내에 생성되지 않는다.

 

Node를 구성하는 Component

kubelet

- Pod 내 컨테이너가 올바르게 실행되도록 제어하는 역할을 한다.

- kubelet은 PodSpecs에 정의된 다양한 매커니즘에 따라서 컨테이너를 실행할 수 있도록 한다.

- kubelet은 쿠버네티스에 생성되지 않은 컨테이너에 대해서는 관리하지 않는다.

kube-proxy

- Node가 사용하는 네트워크 proxy를 의미한다.

- Node의 네트워크 규칙을 관리한다.

- 네트워크 규칙은 파드간의 통신뿐만아니라 클러스터 외부 통신에 대한 규칙도 정의할 수 있다.

- kube-proxy는 OS의 패킷 필터링 레이어가 존재하고 사용가능하다면 그것을 그대로 사용한다. 그렇지 않은 경우 kube-proxt가 자체적으로 트래픽을 포워딩하는 역할을 수행한다.

Container runtime

- 컨테이너를 효율적으로 실행하기 위한 가장 기본이 되는 component이다.

- 쿠버네티스 환경 내에 있는 컨테이너의 생명주기 관리와 실행을 담당한다.

- 쿠버네티스는 Container Runtime을 직접 구현하진 않았고, Container Runtime Interface(CRI)라는 명세만 제공한다.

- 흔히 사용하는 containerd, CRI-O 등은 다른 조직에서 만든 CRI의 구현체들이다. 즉, Container runtime을 사용하려면 이런 구현체들(CRI Plugin)이 설치되어야 한다.

 

 

쿠버네티스 오브젝트

쿠버네티스의 오브젝트란? 쿠버네티스 시스템상에 존재하는 영속적인 entity이다. 쿠버네티스는 이 entity를 통해서 클러스터의 상태를 나타내게 된다. 예를들면, 어떤 컨테이너 application이 구동되고 있는지, application이 사용가능한 리소스, application이 동작하는데 있어서 필요한 정책(업그레이드, 내장애성)과 같은 것들을 오브젝트 개념으로 관리한다.

 

쿠버네티스의 오브젝트는 바라는 상태(desired state)현재 상태(current state) 데이터를 가질 수 있다. 

컨트롤 플레인은 바라는 상태와 현재 상태가 일치 되도록 끊임없이 관리한다. 이를 Reconcile이라 부른다

사용자는 바라는 상태만 선언해두면 컨트롤 플레인이 알아서 현재 상태를 변경한다.

 

참고로 오브젝트는 Namespace 개념이 적용가능한 것과 적용이 불가능한 것이 있다. 

적용가능한 오브젝트로는 Pod, Service, Deployment 등이 있고, 불가능한 Object로는 Node, ClusterRole, ClusterRoleBinding 등이 있다.

 

대표적인 오브젝트들

Pod

- Pod는 1개 이상의 컨테이너의 묶음을 의미한다. Pod내 컨테이너는 storage, 네트워크 자원, 실행 정책을 공유한다.

- Pod는 쿠버네티스 클러스터에서 배포 가능한 최소한의 단위이다. 즉, 컨테이너 자체로 배포하는건 불가능하며, Pod를 생성해서 배포해야한다.

- Pod는 logical host 모델을 따른다. 내부적으론 복수개의 컨테이너가 있을지라도 외부에서 보면 Pod는 하나의 호스트처럼 보이도록 한다. (Pod를 구성할때 배포 사이클이 같고 강결합된 컨테이너끼리만 묶는게 좋겠다.)

- 아래는 yaml 문법을 사용한 Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

ReplicaSet

- Pod의 개수를 일정하게 유지하기 위해 사용한다.

- Deployment에서 Pod의 Replica수를 지정할 수 있기때문에 잘 사용하지 않는 오브젝트이다.

Deployment

- Pod와 ReplicaSet에 대한 선언적인 수정(또는 생성) 기능을 제공한다.

StatefulSet

- Pod의 순서와 유일성을 보장하기 위해서 사용한다.

- Deployment처럼 명시적으로 컨테이너의 스펙을 정의해서 배포할수 있지만, 특정 Pod를 인식할 수 있도록 하는점에서 차이가 있다.

- 보통 Pod의 경우 Stateless하게 사용되지만 예외적으로 상태를 기억해야하는 Pod들이 있는데 이때 StatefulSet을 사용한다.

DaemonSet

- Node가 복제된 Pod를 실행할 수 있도록 보장한다.

- 새로운 Node가 클러스터에 추가되었을때 Pod를 Node에 추가한다.

- Node가 제거되면 자동으로 추가된 Pod를 garbage collect한다.

- 주로 모든 Node에 공통적으로 구동되어야하는 로그나 모니터링용 Pod를 배치할때 사용한다.

Service

- Pod에 대한 외부접근을 가능하도록 하는 오브젝트이다.

- Service의 목적은 사용자가 네트워크 설정에 신경쓰지 않고 Pod를 배포할 수 있도록 하는데 있다. 환경이 바뀌는 경우 Pod를 그에 맞춰 수정해야하는 경우가 있는데 Service는 이를 최소화한다. (내용이 방대해서 별도로 정리해야할듯...)

Ingress

- 주로 HTTP를 통해 들어오는 외부 트래픽을 관리하는 API Object이다. (공식문서를 보니 Gateway API를 사용하라고 한다...)

- 로드 밸런싱, SLL 해독, 가상 호스팅을 제공할 수 있다.