쿠버네티스
쿠버네티스(Kubernetes) 는 컨테이너화된 애플리케이션을 자동으로 배포, 관리, 확장할 수 있는 오픈소스 플랫폼
으로, 컨테이너 오케스트레이션(container orchestration) 툴이다. 쿠버네티스를 k8s 라고 줄여서 쓰길래 왜 그렇게 쓰나 했더니 이름에서 k 와 s 사이에 글자가 8개라서(...) 이렇게 쓴다고 한다.
쿠버네티스의 특징
- 서버 자원 클러스터링, 마이크로서비스 구조의 컨테이너 배포, 서비스 장애 복구 등 컨테이너 기반의 서비스 운영에 필요한 대부분의 오케스트레이션 기능을 폭넓게 지원한다.
- 영속적 볼륨, 스케줄링, 장애 복구, 오토 스케일링 등 컨테이너 기반의 클라우드를 운영할 때 필요한 대부분의 기능과 컴포넌트를 사용자가 직접 커스터마이징 할 수 있다.
쿠버네티스 구성 요소
Pods
쿠버네티스에서 배포 및 실행이 가능한 가장 작은 구성 요소를 파드라고 한다. 파드는 하나 이상의 컨테이너로 이루어질 수 있고, 보통은 하나로 구성된다.
파드 하나당 고유한 IP 주소가 할당
되며 (컨테이너 하나당이 아니다) 같은 파드 내에 있는 컨테이너들은 localhost 로 통신하는데, 이는 각 파드가 하나의 네트워크 네임스페이스를 공유하기 때문이다. 파드의 내부 IP 주소를 통해 파드끼리의 통신이 가능하다.
파드의 주요한 특성 중 하나는 Ephemeral 하다는 것인데, 해당 단어의 사전적 의미인 수명이 짧다는 뜻에서 알 수 있듯이 파드는 일회용이고, 교체 가능한 자원이 되는 목적으로 생성
되었기 때문에 리소스 부족이나 장애, 버그로 인해 파드가 중단되면 해당 파드는 새로운 파드로 교체되고, IP 주소도 다시 할당된다.
Service
서비스는 파드에 변경 사항이 생기면서 IP 주소가 재할당되는 것을 방지하여 파드에 고정적으로 접근할 수 있게끔 한다. 서비스와 파드는 일대일로 연결되어 있는데, 생명 주기는 일치하지 않기 때문에 파드가 중단되더라도 서비스와 IP 주소는 변경되지 않게 된다.
또한 서비스는 로드 밸런서 기능을 수행하여 다수의 파드로 트래픽을 분산시키는 역할도 한다.
Ingress
인그레스는 클러스터 외부의 트래픽을 내부 서비스로 전달하는 역할
을 하며, 외부 요청의 라우팅 규칙을 설정하여 외부 요청을 어떤 서비스로 라우팅할지 정의한다. 또한 가상 호스트 기반의 요청 처리가 가능하여 같은 IP 에 대해 다른 도메인 이름으로 요청이 도착해도 처리할 수 있다.
ConfigMap
컨피그맵은 공개되어도 되는 환경 변수에 한해 키-값 형식으로 저장하는 데 사용되는 API 오브젝트
이다. 컨피그맵을 통해 컨테이너와 환경을 분리하여 관리할 수 있다.
컨피그맵을 사용하지 않으면서 환경 변수의 값을 변경하기 위해서는 보통 환경 변수가 정의된 파일을 수정 후, 레포지토리에 해당 파일을 푸시, 이미지 재빌드, 재배포하는 과정을 거쳐야 하지만 컨피그맵을 사용한다면 컨피그맵 수정만으로도 환경 변수 수정이 가능
하다.
Secret
컨피그맵은 기밀 데이터를 저장할 수 없기 때문에 비밀번호나 API 키 등의 기밀 데이터는 시크릿을 통해 저장한다. 시크릿은 데이터를 base64 인코딩을 통해 저장한다.
Volumes
컨테이너는 일반적으로 stateless 하다. 이러한 특성 덕분에 이식성이 뛰어나지만, 앱의 특성에 따라 데이터를 저장해야 하는 경우도 있다. 이럴 때 사용되는 것이 볼륨인데, k8s 에서 볼륨은 로컬 스토리지 혹은 외부 스토리지로 나뉜다. 단, k8s 에서 데이터를 관리하는 것이 아니기 때문에 주의해야 한다.
ReplicaSet
레플리카셋은 일정 개수의 파드를 유지
할 수 있도록 해준다. 정해진 수의 동일한 파드가 항상 실행되도록 관리하고, 장애 등의 이유로 파드가 중단된다면 파드를 재생성한다.
레플리카셋은 파드 개수를 관리하지만, 실제로 파드와 연결되어 있지는 않다. 파드와 레플리카셋은 라벨 셀렉터를 통해 느슨하게 연결
되어 있는데, 특정 라벨을 가진 파드의 개수가 정해진 항목의 개수와 일치하지 않는다면 부족한 파드를 생성하게 된다. 만약 파드의 개수가 설정된 값보다 많다면 불필요한 개수만큼의 파드를 삭제하게 된다.
Deployments
디플로이먼트는 파드 생성시 파드의 상태를 정의
할 때 사용된다. 즉, 사용자가 파드를 생성하는 것이 아닌, 디플로이먼트를 통해 정의한대로 파드가 생성되는 것이다. 사용자는 디플로이먼트를 통해 파드를 관리하고, 설정할 수 있다. 단, 디플로이먼트는 stateless 한 앱을 배포할 때 사용되기 때문에 데이터베이스처럼 상태 유지가 필요한 앱에는 적합하지 않다.
StatefulSets
따라서 상태 유지가 필요한 파드들은 스테이트풀세트를 통해 관리된다. 스테이트풀세트는 각 파드를 식별하기 위한 고유한 이름을 지정하여 파드에 랜덤하게 접근하는 것이 아닌, 개별적으로 접근
할 수 있도록 한다. 또한, 영구적인 볼륨 마운트를 통해 데이터가 휘발되지 않고 보존되도록 한다.
쿠버네티스 클러스터 구성 요소
Master Process
kube-apiserver, kube-scheduler, kube-controller-manager, etcd 등의 컴포넌트가 실행된다.
- kube-apiserver:
사용자와의 통신이 이루어지는 컴포넌트
로, 일종의 게이트웨이 역할을 한다. 사용자가 쿠버네티스 클러스터 내에 명령을 내리면 최초로 요청을 받고, 해당 요청의 인증이 유효한지 검증 후 적절한 컴포넌트로 요청을 전달하는 역할을 한다. - kube-scheduler:
사용자가 요청한 파드를 클러스터 내의 적절한 워커 노드에 배치
하는 역할을 한다. 요청을 처리할 때는 각 노드의 리소스(CPU, 메모리 등) 를 토대로 결정하며, 노드의 리소스를 가장 효율적으로 사용할 수 있도록 최적의 노드를 선택한다. - kube-controller-manager: 클러스터에서 여러 컨트롤러를 관리하는 컴포넌트로,
클러스터 상태를 유지
하는 역할을 한다. 파드의 상태를 모니터링하고 중단된 파드의 재배치를 스케줄러에 요청하기도 한다. -
etcd: 클러스터의 뇌와 같은 역할을 한다. 클러스터의 모든 변경 사항은 etcd 에 키-값 형태로 저장되는데, 이러한 데이터를 통해
클러스터의 모든 구성 요소가 상태 정보를 공유하고, 변경 사항을 반영
할 수 있다.- scheduler 는 etcd 에서 클러스터 상태를 읽고, 각 노드의 리소스를 확인하여 파드를 효율적으로 배치할 수 있다.
- controller-manager 는 etcd 에서 클러스터의 상태를 확인 후 필요한 컨트롤러에게 요청을 내리게 된다.
Node Process
Worker Node 라고도 하며, 실제로 컨테이너화된 앱이 실행되는 곳이다. 각 워커 노드는 여러 프로세스를 실행하며, 이를 통해 앱을 관리한다. container runtime, kube-proxy, kubelet 등의 프로세스가 실행된다.
- kubelet: 각 워커 노드에서 실행되는 에이전트로,
파드를 실행하고 관리
하는 역할을 한다. kubelet 은 노드에서 실행되는 컨테이너를 관리하며, 노드와 상호작용하여 파드의 상태를 지속적으로 모니터링한다. - kube-proxy: 네트워크 트래픽을 처리하는 프로세스로, 클러스터 내에서 서비스와 파드 간의 통신을 관리하며 로드 밸런싱 및 포트 포워딩 등을 담당한다.
- container runtime: 파드 내부에서 컨테이너가 실행되므로 컨테이너 런타임이 필요하다. 대표적인 예로는 Docker, containerd, CRI-O 등이 있다.
참고: 쿠버네티스 공식 문서