본문 바로가기

Docker & Kubernetes

쿠버네티스(Kubernetes) - 이해하기

쿠버네티스

컨테이너 인프라 환경 이란, 리눅스 운영 체제의 커널 하나에서 여러 개의 컨테이너가 격리된 상태로 실행되는 인프라 환경이다. 컨테이너는 하나 이상의 목적을 위해 독립적으로 작동하는 프로세스이다. 개인 환경에서는 딱히 필요하지는 않겠지만, 기업 환경에서는 다수의 개발자 혹은 관리자들이 수백대에서 수천대의 서버를 관리하기 때문에 일관성을 유지하는 것이 매우 중요하다. 이러한 컨테이너 인프라 환경에서 사용할 수 있는 컨테이너 오케스트레이션중 하나가 쿠버네티스(Kubernetes)(이하 k8s)이다.

 

k8s는 다른 오케스트레이션 솔루션보다는 시작하는데 어려움이 있지만, 쉽게 사용할 수 있도록 도와주는 도구들이 있어서 설치가 쉬워지고 있다. 또한 다양한 형태의 k8s가 지속적으로 계속 발전되고 있어서 컨테이너 오케스트레이션을 넘어 IT인프라 자체를 컨테이너화하고, 컨테이너화된 인프라 제품군을 쿠버네티스 위에서 동작할 수 있게 만들어준다.

 

오케스트레이션(Orchestration)이란? 복잡한 단계를 관리하고 요소들의 유기적인 관계를 미리 정의해 손쉽게 사용하도록 서비스를 제공하는 것을 의미

 

= 가상화 환경 vs 컨테이너 환경

= 쿠버네티스영역 확인

출처: https://thebook.io/080241/ch03-01/

쿠버네티스 종류

1] 관리형 쿠버네티스

    - EKS (Amazon Elastic Kubernetes Service)

    - AKS(Azure Kubernetes Services)

    - GKE(GOogle Kubernetes Engine)

 

2] 설치형 쿠버네티스

    - Rancher

    - Openshift

 

3] 구성형 쿠버네티스

    - kubeadm

    - kops(Kubernetes Operations)

    - KRIB(Kubernetes Rebar Integrated Bootstrap)

    - kubespray

쿠버네티스 구성하기

Vagrantfile 설정 (Master 노드 + Worker 노드)과 shell config로 네트워크 구성설정하여 k8s 환경을 구성한다.

    - Vagrantfile: k8s의 각 노드를 설정

    - config.sh: kubeadm으로 k8s를 설치하기 위한 사전 조건을 설정하는 스크립트 파일

    - install_pkg.sh: 클러스터를 구성하기 위해 가상 머신에 설치돼야 하는 의존성 패키지를 작성

    - master_node.sh: 1개의 가상 머신을 k8s 마스터 노드로 구성하는 스크립트

k8s 클러스터를 구성할 때 꼭 선택해야 하는 컨테이너 네트워크 인터페이스(CNI)도 함께 구성

    - work_nodes.sh: 가상머신에 k8s 워커 노드를 구선하는 스크립트

    워커노드를 k8s 클러스터에 조인하는 정보를 입력

 

실습 코드확인: https://gitlab.com/nodo3482/ys-k8s

쿠버네티스의 구성 요소 간 통신

(0) kubectl: 쿠버네티스 클러스터에 명령을 내리는 역할을 수행.

(1) API 서버: 쿠버네티스 클러스터의 중심 역할을 하는 통로. 주로 상태 값을 저장하는 etcd와 통신하지만, 그 밖의 요소들 또한 API 서버를 중심에 두고 통신하므로 API서버의 역할이 매우 중요하다. (=관리자)

(2) etcd: 구성 요소들의 상태 값이 모두 저장되는 곳이다. etcd의 정보가 백업되어있으면 쿠버네티스 클러스터는 복구할 수 있다. 분산 저장이 가능한 key-value 저장소이므로 복제해서 여러 곳에 저장해두면 하나의 etcd에서 장애가 나더라도 시스템의 가용성을 확보할 수 있다.

(etcd는 etc 디렉터리 + distributed(퍼뜨렸다)의 합성어로 구성 정보를 퍼뜨려 저장하겠다는 의미)

(3) 컨트롤러 매니저: 쿠버네티스 클러스터의 오브젝트 상태를 관리한다. 워커 노드에서 통신이 되지 않는 경우, 상태 체크와 복구는 컨트롤러 매니저에 속한 노드 컨트롤러에서 이루어지고, 레플리카셋 컨트롤러는 레플리카셋에 요청받은 파드 개수대로 파드를 생성하는 등... 다양한 상태 값을 관리하는 주체들이 컨트롤러 매니저에 소속되어 각자의 역할을 한다.

(4) 스케줄러: 노드의 상태와 자원, 레이블, 요구 조건 등을 고려해 파드를 어떤 워커 노드에 생성할 것인지를 결정하고 할당한다. 파드를 조건에 맞는 워커 노드에 지정하고, 파드가 워커 노드에 할당되는 일정을 관리하는 역할을 담당

 

(5) kubelet: 파드의 구성 내용(PodSpec)을 받아서 컨테이너 런타임으로 전달하고, 파드 안의 컨테이너들이 정상적으로 작동하는지 모니터링

(6) 컨테이너 런타임(CRI, Container Runtime Interface): 파드를 이루는 컨테이너의 실행을 담당한다. 파드 안에서 다양한 종류의 컨테이너가 문제 없이 작동하게 만드는 표준 인터페이스

(7) 파드(Pod): 한 개 이상의 컨테이너로 단일 목적의 일을 하기 위해서 모인 단위. 즉, 웹 서버 역할을 할 수도 있고 로그나 데이터를 분석할 수도 있다.

(11) 네트워크 플러그인: 쿠버네티스 클러스터의 통신을 위해서 네트워크 플러그인을 선택하고 구성.

네트워크 플러그인은 일반적으로 CNI로 구성하는데 캘리코, 플래널, 실리움, 큐브 라우터, 로마다 등이 있다.

(CNI, Container Network Interface, 컨테이너 네트워크 인터페이스)

(12) CoreDNS: 클라우드 네이티브 컴퓨팅 재단에서 보증하는 프로젝트로 빠르고 유연한 DNS 서버이다. 쿠버네티스 클러스터에서 도메인 이름을 이용해 통신할 때 사용한다.

파드의 생명주기

1) kubectl을 통해 API서버에 파드 생성을 요청

2) (업데이트가 있을 때마다 매번) API 서버에 전달된 내용이 있으면 API 서버는 etcd에 전달된 내용으로 모두 기록해 클러스터의 상태 값을 최신으로 유지함. 따라서 각 요소가 상태를 업데이트할 때마다 모두 API서버를 통해 etcd에 기록됨

3) API 서버에 파드 생성이 요청된 것을 컨트롤러 매니저가 인지하면 컨트롤러 매니저는 파드를 생성하고 상태를 API서버에 전달함.

(이때 아직 어떤 워커 노드에 파드를 적용할지는 결정되지 않은 상태로 파드만 생성함)

4) API 서버에 파드가 생성됐다는 정보를 스케줄러가 인지하고 스케줄러는 생성된 파드를 어떤 워커 노드에 적용할지 조건을 고려해 결정하고 해당 워커 노드에 파드를 띄우도록 요청함

5) API 서버에 전달된 정보대로 지정한 워커 노드가 파드가 속해 있는지 스케줄러가 kubelet으로 확인

6) kubelet에서 컨테이너 런타임으로 파드 생성을 요청

7) 파드가 생성됨

8) 파드가 사용 가능한 상태가 됨

(!) 쿠버네티스는 작업을 순서대로 진행하는 워크플로 구조가 아닌 선언적인 시스템 구조를 가지고 있어서 각 요소가 추구하는 상태를 선언하면 현재 상태와 맞는지를 점검하고 그것에 맞추는 구조이다.

쿠버네티스의 기타 특징

1] 쿠버네티스는 거의 모든 부분이 자동 복구되도록 설계되었다. 제대로 작동하지 않는 컨테이너를 다시 시작하거나 교체해 파드가 정상적으로 작동하게하는 셀프힐링(Self-Healing)이 있다. (예를들면, nginx서버가 죽었을 경우 등)

2] 쿠버네티스는 파드 자체에 문제가 발생하면 파드를 자동 복구해서 파드가 항상 동작하도록 보장하는 기능이 있다. (파드가 죽었거나, 혹은 삭제했을 경우 등 자동 복구됨)

참고자료

= 서적 - 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커, 길벗 - 제 3장

= https://thebook.io/080241/ch03/01/04-02/