Kubernetes

큰숲백과, 나무를 보지 말고 큰 숲을 보라.
Senouis (토론 | 기여)님의 2025년 6월 7일 (토) 23:18 판
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)


Kubenetes(쿠버네티스) 또는 k8s는 다수의 리눅스 컨테이너 이미지를 여러 개의 노드 서버에서 자동으로 분배하여 배포 및 실행할 수 있는 환경을 제공하는 오픈 소스 클라우드 구축 시스템이다. 현재는 리눅스 재단이 관리하고 있다.

개발 배경 및 쓰임[편집 | 원본 편집]

쿠버네티스는 구글이 자사의 수많은 서비스(지메일, 유튜브, 구글 드라이브 및 구글 독스, 구글 맵 및 기타)를 많은 서버에 적절히 분배하여 관리하기 위해 사내 엔지니어들이 만든 서비스 배포 시스템을 2014년 오픈 소스 프로젝트로 공개한 프로젝트다. 이후 수많은 대형 IT 회사들이 자사의 서비스들을 쉽게 관리하기 위한 사내 클라우드(On-premise Cloud) 시스템을 구축하기 위해 쿠버네티스를 채용하면서 2020년 이후 조금씩 파이가 커지고 있다.

구글이 만든 프로젝트인 만큼 구글 클라우드 플랫폼(GCP)에서는 GKE(Google Kubenetes Engine)이란 이름으로 자사 클라우드 서비스를 사용하는 회사들을 위해 각종 서비스들을 통합해서 관리하는 쿠버네티스 시스템 관리 서비스를 제공하고 있다.

리눅스의 운영체제 수준 가상화(컨테이너)를 활용한 기술인 만큼 리눅스에서만 지원되고 윈도우에서는 지원되지 않는다.

주요 개념[편집 | 원본 편집]

  • 마스터 노드와 워커 노드

쿠버네티스는 컴퓨터들의 묶음인 클러스터들 위에서 돌아가며, 클러스터 내 각 컴퓨터는 클러스터 별 작업 분배를 담당하는 마스터 노드와 실제로 작업 단위들을 받아 실행하는 워커 노드들로 이루어져 있다. 보통 쿠버네티스를 제대로 사용한다면 마스터 노드 2개 이상, 그리고 각 마스터마다 2~3개 이상의 워커는 있어야 한다. 그리고 이게 개인 및 소규모 회사들이 k8s를 공부하고 사용하기 어렵게 만드는 첫 번째 요인이다. 즉 대형 프로젝트를 굴리는 게 아니면 k8s가 쓸모가 없다는 것. 그나마 이 문제점을 개선한다고 k3s나 minikube 같은 파생 프로젝트들이 나왔긴 하나, 후술할 두 번째 이유로 여전히 공부하고 쓰기 어렵다...

  • 파드

컨테이너의 기본 작업 단위이다. 파드를 배포하기 위해 배포 유형별로 정해진 양식의 yml 파일을 만들어 가져올 컨테이너 이미지를 설정하고, 볼륨과 환경변수, 실행 커맨드들을 설정한다는 개념 측면에서는 도커 컴포즈로 배포하는 상황이랑 비슷하나, 도커 컴포즈에서 설정할 법한 옵션들은 spec이란 키 안에 전부 잡아 넣고 그 외에도 훨씬 많은 옵션들을 설정한다. 그리고 이 옵션들이 k8s를 개인 및 소규모 회사 내 직원들이 공부하고 채용하기 어렵게 만드는 두 번째 원인이다(...)

아예 설정용 YAML 양식을 자기 업무용 컴퓨터에 미리 써 놓고 복붙하며 배포하는 게 편하긴 하다. 그것도 귀찮으면 ChatGPT가 만든 기본 양식을 적당히 맞게 수정하여 쓰는 일도 있는듯...

다행히도 파드 별로 저런 설정을 넣는 것이 아니라, 보통 다음에 소개할 스테이트풀 셋이나 디플로이먼트에서 설정한 옵션을 파드가 대부분 상속받는 구조로 사용하게 설정된 것이 그나마 위안...

  • 데몬 셋, 리플리카 셋, 스테이트풀 셋

동일하게 복제된 여러 파드의 묶음인 작업 단위를 의미한다. 리플리카셋은 보통 후술할 디플로이먼트에 귀속된 경우가 많으며, 배포를 시작할 때 파드 배포 순서가 정해져 있지 않다. 스테이트풀 셋은 파드 배포 순서가 정해져 있으며, 보통 '(파드 배포 이름)-0'부터 뒤의 숫자가 올라가는 방식으로 파드 별 이름이 결정된다. 데몬 셋은 '반드시 모든 워커 노드에서 동일한 파드 하나씩' 실행하는 특수한 경우에 사용하는데, 보통 워커 노드들에 기능을 추가하는 쿠버네티스용 플러그인(예: Calico 같은 CNI, Longhorn 같은 볼륨 관련 플러그인)을 설치할 때 데몬셋 형태로 파드가 배포된다.

DBMS를 굳이 k8s로 배포하겠다고 하겠다면 스테이트풀 셋이 적당하다. 리플리케이션 순서를 정하게 하기 쉽다. 그러나 보통 DBMS는 k8s로 배포하는 경우가 많지 않는데, 어쩌다 워커 노드가 하나 맛이 갔는데 그 안에 DBMS 파드가 들어있었다면 데이터 동기화가 개판이 되기 때문. 특히 시스템의 규모가 클 수록 그 피해의 크기는 상상을 초월한다... 그래서 k8s 클러스터에서 DBMS는 보통 따로 분리해 별도의 물리 컴퓨터들에 설치하는 편이다.

  • 디플로이먼트

보통 웹 서비스를 개발하고 k8s에 컨테이너 이미지로 배포한다면 디플로이먼트 단위로 배포한다. 여기에 옵션들을 주고 컨테이너 이미지를 배포하면 리플리카 셋이 생성되고, 거기에 다시 파드들이 붙는다.

  • 서비스

어쨌든 k8s는 컴퓨터들의 클러스터에서 여러 프로젝트들이 돌아가는 구조이므로, 최소한의 네트워크 통신으로 파드로 올려진 컨테이너 간의 네트워크 통신이 필요하다. k8s는 이런 파드 간 네트워크 통신 관련 정보를 배포할 때에 '서비스'라는 단위로 배포한다. 서비스에서는 네트워크 통신을 위한 포트 설정이 필수적이다. 기본적으로 Kubenet이라는 내장 플러그인이 있긴 하나, 기능이 턱없이 부족해 Flannel, Calico 같은 서드 파티 CNI 플러그인이 많이 사용된다.

  • ClusterIP, NodePort, LoadBalancer: 보통 대형 IT 프로젝트가 k8s를 사용한다면 대부분의 서비스, 특히 백엔드 서비스는 보안을 위해 외부에 노출시키지 않는다. 그래서 보통 서비스들은 ClusterIP 타입으로 내부망에서 서비스 이름으로만 통신하도록 되어 있다. 그러나 이렇게만 하면 디버깅도 어렵고, 프론트엔드 서버처럼 외부 네트워크에 노출시켜야 하는 서버가 있을 것이다. 보통 서비스의 작동 여부를 확인할 때에는 NodePort 타입의 서비스를 설정하며, 영구적으로 외부에 노출시킬 때에는 CNI 플러그인을 설치해서 LoadBalancer 타입으로 적절한 파드(또는 복수의 파드)가 노출되도록 한다.
  • 퍼시스턴트 볼륨 및 퍼시스턴트 볼륨 클레임

도커 엔진을 쓸 때 볼륨으로 특정 디렉토리를 호스트에 마운트하여 원하는 파일을 컨테이너 내에 추가하고 수정할 수 있는 것처럼, k8s에도 퍼시스턴트 볼륨(Persistent Volume)이라는 개념으로 컨테이너 내에서 변화된 데이터를 노드에 영구적으로 저장할 수 있다. 문제는 클러스터 단위로 움직이는 k8s답게 어느 워커 노드에 어느 볼륨이 들어갈 지는 k8s 마스터 노드 마음대로이며, 파드를 잠시 내렸다 다시 마운트하려면 워커 노드를 찾아다니면서 수동으로 마운트/언마운트를 해야 하는 불편이 있다.

그래서 워커를 찾아다니며 볼륨 할당을 일일이 하는 것은 귀찮기 때문에, Longhorn 같은 볼륨 관리 플러그인과 연계해 퍼시스턴트 볼륨을 디플로이먼트/스테이트풀 셋 배포 단계에서 설정하는 퍼시스턴트 볼륨 클레임(PVC) 기능이 있다.

  • 메타데이터: 타입과 네임스페이스

이렇게 복잡한 k8s 배포 구조 때문에 종종 디플로이먼트/스테이트풀셋 등을 배포할 때 이름이 겹치거나 혼동하기 쉬운 이름들을 가진 여러 서비스들이 생길 수 있다. 이를 완화하기 위해 모든 k8s 작업 단위에는 메타데이터가 있으며, 그 안에서 작업 단위의 타입(예: frontend, backend)를 임의로 지정하거나 네임스페이스라는 단위로 아예 특정 서비스들을 위한 여러 작업 단위를 한꺼번에 분리할 수 있다.

k8s에 설치되는 플러그인들도 각기 네임스페이스로 격리되기 때문에, 운 나쁘게 배포한 디플로이먼트 내 파드 이름이 플러그인의 파드 이름과 겹쳐 배포가 실패하는 일은 일반적으로 없다. 기본적으로 k8s 클러스터 내에 생성되는 기본 네임스페이스의 이름은 'default'다.

  • 컨피그맵과 시크릿

도커 컴포즈로 컨테이너 이미지의 환경설정을 하는 것처럼 컨피그맵과 시크릿이란 단위로 특정 값 또는 데이터를 배포하여 디플로이먼트에 각각 'envFrom' 및 'secret' 키로 연결하게 할 수 있다. 주 용도는 컨테이너 이미지 내 환경 변수 설정 및 SSL 인증서 키 등록.

  • 인그레스

k8s는 일반적으로 대형 IT 회사의 웹 서비스 프로젝트에 사용한다고 하는데, 보통 이런 서비스는 마이크로서비스 아키텍처(Microservice Architecture, MSA) 형태를 가지고 있는 경우가 거의 전부라고 해도 좋다. 이 경우 별 다른 설정이 없다면 외부 사용자가 원하는 기능을 사용하기 위해서는 각 마이크로서비스가 k8s LoadBalancer 서비스 형태로 외부로 노출된 IP 및 포트를 클라이언트가 다 알고 찾아가야 한다.

이런 경우를 대비해 여러 IP 및 포트를 외부에 노출시키는 대신, 하나의 게이트웨이 IP 주소를 만들고 그 아래의 URI만 알면 클라이언트가 URI를 따라 k8s 서비스를 알아서 찾아가게 할 수 있는데, 이 기능을 인그레스(Ingress)라고 한다. MSA와 찰떡궁합이라는 특성이 있으며, SSL 설정이 필용할 때 인그레스가 설정된 경우 그 게이트웨이 IP 주소에만 TLS 설정을 걸면 끝난다! 다만 이 경우 시크릿으로 SSL 인증서 데이터를 업로드해야 하지만...

반대로 모든 서비스의 응답을 하나의 주소로 모아 클라이언트로 반환하는 이그레스(Egress)도 있긴 한데, 이건 나가는 트래픽까지 특정 포트로 강요해야 하는 아주 특별한 경우가 아니면 보통 잘 건드리지 않는다. 대부분의 공개 클라우드 서비스(AWS, Azure, GCP 및 기타) 위 퍼블릭 가상 네트워크가 방화벽 단에서 아웃바운드 트래픽을 무제한으로 허용하는 설정이 기본값인 것과 비슷하다.

도커와 쿠버네티스[편집 | 원본 편집]

도커와 쿠버네티스는 모두 리눅스 컨테이너 기술을 활용해 이미지를 만들어 배포할 때 사용하는 기술이다. 그러나 도커는 쿠버네티스와 같은 역할을 하지 않는다.

도커는 주로 컨테이너 이미지를 만드는 데에 초점이 맞추어져 있으며, 도커 엔진으로 그 이미지를 배포할 때에는 순전히 도커 사의 고유 엔진을 활용할 뿐, 쿠버네티스처럼 여러 엔진 중에 골라서 배포하지 않는다. 반면 쿠버네티스는 리눅스 컨테이너 이미지를 배포하는 데에 초점을 맞추며, containerd를 비롯한 여러 컨테이너 엔진을 활용하는 소프트웨어다.

심지어 쿠버네티스는 도커 엔진을 사용할 수 없다! 도커 사가 자꾸 자사만의 고유 규격을 추가한다고 쿠버네티스 1.20부터 도커 엔진 지원을 중단하였기 때문이다. 현재 k8s의 기본 컨테이너 엔진은 containerd인데, 한국에는 도커 엔진에 비해 많이 알려지지 않은 데다가 사용자가 대형 IT 회사 위주로 한정되어서, 소규모 회사들이 컨테이너 기술을 활용한다면 아직 도커 및 도커 엔진(+도커 컴포즈) 정도만 쓰고 있다.

한편 도커 사는 k8s에 대응하는 솔루션으로 도커 스웜(Docker swarm)을 보유하고 있다.

같이 보기[편집 | 원본 편집]