앞선 글에서 Kubernetes의 철학과 아키텍처, Pod, 워크로드 리소스까지 정리했다. 그런데 막상 실무에 들어가면 "k8s 씁니다"가 아니라 "k3s 씁니다", "EKS 씁니다", "GKE 씁니다" 같은 말을 더 자주 듣는다. Kubernetes가 하나의 단일 제품이 아니라 다양한 형태로 존재하기 때문이다. 이것들이 다 뭔지, 어떻게 다른지, 그리고 k3s는 특히 왜 쓰는지를 이어서 정리한다.
Kubernetes는 하나가 아니다
Kubernetes는 CNCF(Cloud Native Computing Foundation)가 관리하는 오픈소스 프로젝트다. 이 소스코드를 특정 환경에 맞게 최적화하거나 설치를 단순화하거나 기능을 추가한 형태들이 배포판(Distribution) 이다. Linux에 Ubuntu, CentOS, Arch가 있는 것과 같은 구조다.
Kubernetes upstream (CNCF 오픈소스)
│
├── 클라우드 매니지드 → EKS (AWS), GKE (GCP), AKS (Azure)
│ 컨트롤 플레인을 클라우드가 대신 운영해줌
│
├── 온프레미스 설치 → kubeadm, kubespray
│ 실제 서버에 직접 표준 k8s 구축
│
├── 로컬 개발용 → minikube, kind, Docker Desktop
│ 내 PC에서 테스트용으로 돌리는 용도
│
└── 경량 배포판 → k3s, k0s, MicroK8s
리소스가 제한된 환경을 위한 최적화 버전
어떤 배포판을 쓰든 Kubernetes API는 동일하다. kubectl apply -f deployment.yaml은 EKS에서도, k3s에서도 똑같이 동작한다. 차이는 어떤 환경을 타겟으로 최적화했느냐다.
클라우드 매니지드 (EKS, GKE, AKS)
AWS/GCP/Azure가 컨트롤 플레인을 직접 운영해주는 형태다. etcd, kube-apiserver, scheduler 같은 컨트롤 플레인 컴포넌트를 직접 관리할 필요가 없다. HA 구성, 업그레이드, 장애 복구를 클라우드가 알아서 처리한다. 대신 클라우드 종속성이 생기고 비용이 발생한다.
kubeadm
표준 k8s를 온프레미스 서버에 직접 구축할 때 쓰는 공식 설치 도구다. 컨트롤 플레인부터 워커 노드까지 전부 직접 세팅해야 한다. 설치와 운영 난이도가 높은 대신 완전한 제어권을 가진다.
로컬 개발용 (minikube, kind)
내 PC에서 k8s를 테스트할 때 쓴다. 실제 서버 배포용이 아니라 개발/학습 목적이다.
k3s
탄생 배경
표준 k8s를 그대로 올리려면 컨트롤 플레인 하나에만 CPU 2코어, RAM 2GB 이상이 권장 사양이다. 클라우드 서버라면 문제없지만 현실에는 그렇지 않은 환경이 많다.
- 공장 생산 라인의 엣지 서버
- IoT 디바이스와 라즈베리파이 클러스터
- 리소스가 제한된 소규모 온프레미스 서버
- 클라우드 비용이 부담되거나 데이터를 외부로 못 보내는 환경
이런 곳에서 표준 k8s를 올리는 건 서버 스펙이 안 받쳐주거나 운영 오버헤드가 너무 크다는 문제가 있었다. Rancher Labs(현 SUSE)가 2019년에 이 문제를 해결하기 위해 k3s를 만들었다. 목표는 단순했다. k8s를 최대한 작고 단순하게, 그러나 API는 완전히 호환되도록.
k3s란
정의: 리소스가 제한된 환경을 위해 설계된 경량 Kubernetes 배포판으로, 표준 k8s API를 완전히 지원하면서 바이너리 크기와 메모리 사용량을 대폭 줄인 것이다.
핵심 포인트:
- 이름의 의미: kubernetes에서 k와 s 사이 알파벳 8개를 숫자로 줄인 게 k8s다. k3s는 같은 방식으로 k와 s 사이를 3으로 줄인 것 — "k8s의 절반 크기"를 상징한다.
- 단일 바이너리 (~100MB) 하나가 컨트롤 플레인과 워커 노드 역할을 모두 한다.
- 표준 k8s API 완전 호환 — kubectl, Helm, 기존 YAML 매니페스트 그대로 동작한다.
- RAM 512MB로 동작 가능. 표준 k8s 최소 사양(2GB+) 대비 4분의 1 수준이다.
- 설치가 스크립트 한 줄로 끝난다. 60초 안에 클러스터가 구성된다.
curl -sfL https://get.k3s.io | sh -
# 이게 전부다. 60초 안에 단일 노드 k3s 클러스터 완성.
k3s가 어떻게 가벼워졌나
표준 k8s 대비 k3s가 내부적으로 무엇을 바꿨는지를 보면 설계 철학이 보인다.
etcd → SQLite
앞선 글에서 정리한 것처럼 etcd는 클러스터의 모든 상태를 저장하는 분산 합의 데이터베이스다. 안정적이지만 그만큼 무겁다. k3s는 기본값으로 SQLite를 쓴다. 단일 서버나 소규모 클러스터에서는 SQLite로 충분하고 훨씬 가볍다. 고가용성이 필요한 환경이라면 etcd나 외부 DB(MySQL, PostgreSQL)로 교체할 수 있다.
컨트롤 플레인 컴포넌트 단일 프로세스 통합
표준 k8s는 kube-apiserver, kube-scheduler, kube-controller-manager가 각각 별도 프로세스로 실행된다. k3s는 이것들을 하나의 프로세스(k3s server)로 통합했다. 프로세스 간 통신 오버헤드가 사라지고 메모리 사용량이 줄어든다.
불필요한 기능 제거
클라우드 프로바이더 전용 플러그인, 레거시 기능, 알파 단계 기능들을 전부 제거했다. 엣지/온프레미스 환경에서 쓸 일이 없는 것들이다.
containerd 내장
Docker를 별도로 설치할 필요 없이 containerd가 기본 컨테이너 런타임으로 내장되어 있다.
결과적으로 아키텍처가 이렇게 된다.
표준 k8s 컨트롤 플레인
├── kube-apiserver (별도 프로세스)
├── etcd (별도 프로세스 — 분산 합의 DB)
├── kube-scheduler (별도 프로세스)
└── kube-controller-manager (별도 프로세스)
→ RAM 최소 2GB 권장
k3s server
└── k3s server (단일 프로세스 — 위 4개 통합)
└── SQLite (경량 DB)
→ RAM 512MB로 동작 가능
k3s 아키텍처
k3s 클러스터는 server와 agent로 구성된다. server가 컨트롤 플레인 역할, agent가 워커 노드 역할을 한다.
┌──────────────────────────────────────────────────────┐
│ k3s server (컨트롤 플레인) │
│ ┌──────────────────────────────────────────────┐ │
│ │ 단일 프로세스 (k3s server) │ │
│ │ ├── API server 모든 통신의 중심 │ │
│ │ ├── scheduler Pod 배치 결정 │ │
│ │ ├── controller-manager 원하는 상태 유지 │ │
│ │ └── SQLite 클러스터 상태 저장 │ │
│ └──────────────────────────────────────────────┘ │
│ ↕ API │
│ k3s agent (워커 노드) │
│ ┌──────────────────────────────────────────────┐ │
│ │ kubelet 컨트롤 플레인 명령 수신, Pod 관리│ │
│ │ kube-proxy 네트워크/서비스 처리 │ │
│ │ containerd 컨테이너 런타임 (내장) │ │
│ │ │ │
│ │ ┌──Pod──┐ ┌──Pod──┐ ┌──Pod──┐ │ │
│ │ │컨테이너│ │컨테이너│ │컨테이너│ │ │
│ │ └───────┘ └───────┘ └───────┘ │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────┘
↑
kubectl (표준 k8s와 동일하게 사용)
단일 노드 구성도 가능하다. server와 agent를 같은 머신에서 실행하면 컨트롤 플레인과 워커 노드가 하나의 서버에 공존한다. 소규모 서비스나 개발 환경에서는 이 구성으로 충분하다.
k8s vs k3s
공통점 — 진짜 연결고리: API가 완전히 동일하다. k8s에서 쓰던 모든 YAML 매니페스트, kubectl 명령어, Helm chart가 k3s에서 그대로 동작한다. k8s를 알면 k3s는 그냥 쓸 수 있다.
차이점 — 왜 다른가: 타겟 환경이 다르다. k8s는 클라우드 또는 대규모 온프레미스 클러스터를 위해 설계됐고, k3s는 리소스가 제한된 환경에서 k8s와 동일한 경험을 제공하기 위해 설계됐다.
| k8s (표준) | k3s | |
| 타겟 환경 | 클라우드, 대규모 온프레미스 | 엣지, IoT, 소규모 온프레미스 |
| 최소 RAM | 2GB+ | 512MB |
| 저장소 기본값 | etcd | SQLite |
| 컴포넌트 구조 | 프로세스별 분리 | 단일 바이너리, 단일 프로세스 |
| 설치 난이도 | 높음 | 낮음 (스크립트 한 줄) |
| kubectl | 가능 | 가능 (완전 동일) |
| Helm | 가능 | 가능 (완전 동일) |
| 프로덕션 사용 | 가능 | 가능 |
핵심 인사이트: k3s는 k8s의 대체재가 아니라 k8s를 경량화한 배포판이다. "k8s냐 k3s냐"의 문제가 아니라 "어떤 환경에서 k8s를 돌리느냐"의 문제다.
경량 배포판 비교: k3s vs k0s vs MicroK8s
k3s 외에도 같은 목적의 경량 배포판이 있다. 셋 다 리소스 제한 환경을 타겟으로 하고 표준 k8s API와 호환된다.
k0s 는 Mirantis가 만들었다. k3s와 마찬가지로 단일 바이너리로 배포되고 설치가 단순하다. 컨트롤 플레인과 워커 노드의 분리 구조가 표준 k8s에 더 가깝다.
MicroK8s 는 Canonical(Ubuntu 만든 회사)이 만들었다. Ubuntu 환경에 최적화되어 있고 snap 패키지로 설치한다. microk8s enable dns, microk8s enable ingress 처럼 add-on을 명령어 하나로 활성화할 수 있는 게 특징이다.
| k3s | k0s | MicroK8s | |
| 만든 곳 | Rancher (SUSE) | Mirantis | Canonical |
| 설치 | curl 스크립트 | 바이너리 직접 | snap |
| 기본 저장소 | SQLite | SQLite | etcd |
| 특징 | 가장 널리 쓰임, 엣지 최적화 | 표준 k8s 구조에 가까움 | Ubuntu 최적화, add-on 편의성 |
셋 중 k3s가 커뮤니티 규모, 레퍼런스, 문서 면에서 가장 성숙해있다. 엣지/소규모 온프레미스에서 경량 k8s를 선택한다면 k3s가 첫 번째 선택지가 된다.
k3s가 쓰이는 환경
엣지 컴퓨팅 — 공장 생산 라인, 매장 POS 시스템, 물류 창고처럼 클라우드와 거리가 있는 현장 서버. 네트워크가 불안정하거나 끊겨도 로컬에서 자체적으로 돌아가야 한다. 리소스가 제한된 현장 서버에서 컨테이너 오케스트레이션이 필요할 때 k3s가 들어간다.
IoT / 라즈베리파이 — ARM 아키텍처 지원이 잘 되어 있고, 512MB RAM으로도 동작하기 때문에 라즈베리파이 기반 클러스터에서 많이 쓰인다.
소규모 온프레미스 — 클라우드 비용이 부담되거나 데이터를 외부로 보낼 수 없는 환경. EKS/GKE 같은 매니지드 서비스를 쓸 수 없는 상황에서 온프레미스 서버에 k8s가 필요할 때. 설치와 운영 난이도가 낮아서 작은 팀에서도 관리할 수 있다.
개발/스테이징 환경 — minikube보다 실제 프로덕션(k3s)과 동일한 환경을 재현하고 싶을 때.
실무 적용: 소규모 스타트업이나 리소스가 제한된 온프레미스 환경에서 Docker Compose로 로컬 개발을 하고 k3s로 실제 서버에 배포하는 구조가 일반적이다. docker compose up으로 개발하고, 검증된 이미지를 빌드해서 k3s 클러스터에 kubectl apply로 배포하는 흐름이다.
'Kubernetes' 카테고리의 다른 글
| 쿠버네티스 총 정리 (0) | 2026.02.11 |
|---|