중소기업 쿠버네티스(K3s) 프로덕션 클러스터 구축 — GitOps 기반 인프라

K3s 4노드 프로덕션 클러스터 — MetalLB · Ingress-NGINX · GitOps(ArgoCD) · S3(MinIO) · 무중단 배포

CATEGORY

인프라

TECH STACK

K3s · Kubernetes · MetalLB · Ingress-NGINX · ArgoCD · Gitea · MinIO · TrueNAS NFS · Flannel · Helm

CLIENT

중소기업 (익명)

PERIOD

중소기업이 자체 서비스를 안정적으로 운영하려면 컨테이너 오케스트레이션이 필요하지만, 정식 Kubernetes는 구성 요소가 많고 인프라 인력이 얇은 조직엔 부담입니다. GUNIQ는 K3s(경량 쿠버네티스)를 선택했습니다. 단일 바이너리로 설치되고 리소스 풋프린트가 작으면서도 쿠버네티스 API와 100% 호환되어, 번들 구성요소를 걷어내고 필요한 것만 갈아끼울 유연함이 있었기 때문입니다.

클러스터는 데이터센터 운영 서비스망(VLAN 120) 위에 4개 노드로 구성했습니다. 외부 진입은 앞서 구축한 OPNsense·Caddy 엣지를 그대로 재사용해, 네트워크·클러스터가 하나의 인프라로 이어집니다.

K3s 4노드 클러스터 구성(VLAN 120 운영 서비스망) — control-plane 1대(NoSchedule 테인트)·worker 3대(role=app 2·role=platform 1) · 진입 흐름: Caddy(TLS 종단)→MetalLB VIP→Ingress-NGINX · 스토리지 이원화: local-path(휘발성)·NFS(영속) · MinIO(NFS 백엔드 S3) · ArgoCD GitOps(Gitea 매니페스트)
전체 논리 구성도 — 진입(Caddy→MetalLB→Ingress) · 4노드 역할 분리 · 스토리지 이원화 · GitOps 파이프라인
4
클러스터 노드
L2
MetalLB 로드밸런서
GitOps
ArgoCD 자동 배포
S3
MinIO 오브젝트 스토리지

핵심 구현

① 4노드 역할 분리

control-plane 1대 + worker 3대로 구성하고, 마스터에는 워크로드가 뜨지 않도록 NoSchedule 테인트를 걸었습니다. 워커는 노드 라벨로 role=app 2대(프론트·API, HA 복제)와 role=platform 1대(ArgoCD·Headlamp·MinIO 등 관리 도구)로 나눠, 관리 도구가 서비스 리소스를 잠식하지 않게 격리했습니다.

② K3s 부트스트랩 — 번들을 걷어내고 갈아끼우다

K3s에 기본 포함된 Traefik과 ServiceLB를 비활성화하고, 널리 쓰이는 Ingress-NGINX(다중 도메인 라우팅)와 MetalLB(L2 로드밸런서)로 교체했습니다. 운영 네트워크 토폴로지와 IP 풀 관리에 더 잘 맞는 조합을 직접 선택한 것입니다.

③ 트래픽 진입 — 단일 TLS 종단

외부 요청은 OPNsense·Caddy에서 TLS를 한 번만 종단하고(와일드카드 인증서), 내부는 평문 HTTP로 흐릅니다. 요청은 MetalLB VIP(L2) → Ingress-NGINX(Host 헤더 라우팅) → Service → Pod 순으로 전달됩니다. 인증서를 여러 서비스에 배포하지 않고 엣지 한 곳에서 관리하니, 포트·프로토콜 충돌도 사라졌습니다.

④ 스토리지 이원화

성격에 맞게 스토리지를 둘로 나눴습니다. local-path 프로비저너(노드 로컬, 지연 바인딩)는 휘발성·비핵심 데이터에, TrueNAS NFS(Retain 정책)는 영속·핵심 데이터에 씁니다. S3 호환 오브젝트 스토리지 MinIO는 NFS 볼륨을 백엔드로 삼아, 파드가 어느 노드에서 재기동돼도 같은 데이터에 접근합니다.

⑤ GitOps 배포 자동화

자체 호스팅 Gitea를 매니페스트의 단일 원본(SoT)으로 두고, ArgoCD가 이를 감시하며 app-of-apps 패턴으로 배포를 관리합니다. prune·self-heal을 켜 클러스터 상태가 항상 Git과 일치하도록 했고(수동 변경은 자동 복원), 새 서비스 추가는 매니페스트 커밋만으로 끝납니다.

⑥ 레거시 연동과 실전 트러블슈팅

클러스터 밖 레거시 API를 Headless Service + 수동 Endpoints로 감싸 내부 서비스처럼 호출하게 했고, 외부 IP가 바뀌어도 Endpoints만 고치면 되게 만들었습니다. ‘ping은 되는데 TCP만 실패’하던 비대칭 라우팅 문제는 OPNsense SNAT 규칙으로 경로를 대칭화해 해결했고, 게이트웨이가 반환하던 503은 파드의 ConfigMap 키 누락까지 추적해 잡았습니다.

설계 원칙

단순함 우선
K3s·단일 마스터로 시작한다. 필요해지면 HA로 확장 — 과설계하지 않는다.
재현 가능성
모든 상태를 매니페스트로. GitOps와 명시적 IP·라벨 정책으로 언제든 재구성 가능하게.
운영의 명료성
TLS는 한 곳에서만 종단, 노드는 역할로 나눈다. 관리 도구와 서비스는 섞지 않는다.
비용 의식
오픈소스로 채운다 — MinIO(S3)·Headlamp·K3s. 분산 스토리지 대신 NFS로 실용적 균형.
실용적 통합
레거시·NAS 같은 비대칭 구성은 앱이 아니라 네트워크 레이어(SNAT·Endpoints)로 메운다.
교리가 아닌 판단
ArgoCD·HA·MFA는 배포 빈도와 조직 상황이 정당화할 때 도입한다.

기술 스택

오케스트레이션

K3sKubernetesFlannel CNIHelm
네트워킹 · 진입

MetalLB (L2)Ingress-NGINXOPNsense · Caddy와일드카드 TLS
스토리지

local-pathTrueNAS NFSMinIO (S3)PV / PVC
GitOps · 배포

ArgoCDGiteaapp-of-appsprune · self-heal
운영 · 관측

HeadlampServiceAccount · RBACchronyUbuntu 24.04

GUNIQ의 역할

도입 판단부터 클러스터 설계·부트스트랩, 진입 계층, 스토리지, GitOps 파이프라인, 레거시 연동까지 전 과정을 GUNIQ가 수행했습니다.

도입 판단
K8s vs K3s 비교 · SMB 적합성 · 확장 로드맵
클러스터 설계
4노드 역할 분리 · IP/라벨 정책 · 테인트
부트스트랩
K3s 설치 · 번들 교체(Ingress-NGINX·MetalLB)
진입 · TLS
Caddy 단일 종단 · MetalLB VIP · Ingress 라우팅
스토리지
local-path + NFS 이원화 · MinIO S3
GitOps · 연동
Gitea·ArgoCD 파이프라인 · SNAT·Endpoints 연동

OTHER PROJECTS

다른 프로젝트

비슷한 프로젝트가 필요하신가요?

기획부터 개발, 운영까지 함께 만들어 드립니다.