author
postNo
status
thumbnail
description
category
tags
createdAt
updatedAt
Kubernetes 클러스터 구축 가이드 (Ubuntu 22.04, Control-plane 1 + Worker 2)
이 문서는 Ubuntu 22.04(서버 3대)에서 kubeadm + containerd 기반의 쿠버네티스 클러스터를 구축하는 과정을 처음부터 끝까지 순서대로 설명합니다.
- 구성: 총 3대
- Control-plane: 1대
- Worker: 2대
- 컨테이너 런타임: containerd
- 설치 방식: kubeadm
- 네트워크 플러그인: Calico
표기 규칙: 모든 명령은 별도 표기가 없으면 모든 노드(Control-plane/Worker 공통)에서 실행합니다.<PLACEHOLDER>는 실제 값으로 바꿔 입력하세요.
권장 VM 스펙 (Proxmox/KVM 기준)
- 구성: VM 3대 (Control-plane 1:
cp110.10.0.100, Worker 2:wk110.10.0.101,wk210.10.0.102)
- Control-plane 권장: 4 vCPU, 8–16 GB RAM, 60–100 GB SSD/NVMe
- Worker 권장(각각): 4 vCPU, 8–16 GB RAM, 100–200 GB SSD/NVMe
- 가상화 옵션(권장):
- CPU Type: host
- QEMU Guest Agent: 활성화
- Disk Bus: VirtIO SCSI, IO Thread 활성화, SSD Emulation(가능 시)
- NIC Model: VirtIO (Paravirtualized), 브릿지
vmbr0(고정 IP) - MTU: 기본 1500 (특수 네트워크 요구가 없으면 기본 유지)
- 설치/운영 팁:
- Ubuntu 22.04 cloud-init 템플릿으로 VM 생성 후 hostname/IP를 사전 지정
- 아웃바운드 인터넷(apt, 컨테이너 이미지 pull) 가능해야 함
- 시간 동기화(NTP) 활성화, 디스크 성능은 NVMe/SSD 권장
- 고가용성 필요 시 Control-plane을 3대로 확장해 etcd 쿼럼 구성
0) 사전 점검 및 고정 값 준비
이 단계는 모든 노드(Control-plane/Worker)에서 수행합니다.
- 고정 IP와 호스트명(예시)
- Control-plane:
cp1/ 10.10.0.100 - Worker1:
wk1/ 10.10.0.101 - Worker2:
wk2/ 10.10.0.102
각 서버에서 호스트명 설정과
/etc/hosts 매핑을 해둡니다.- 각 노드는 자신의 호스트명으로 설정합니다(
cp1/wk1/wk2).
/etc/hosts매핑 내용은 세 노드 모두 동일하게 추가/유지합니다.
시간 동기화가 필요하면
chrony 또는 systemd-timesyncd를 활성화하세요.1) 공통 시스템 준비 (모든 노드)
필수 커널 모듈과 sysctl, 스왑, 방화벽 등을 정리합니다.
네트워크/보안 정책에 따라 UFW를 유지할 경우, 하단의 "포트/방화벽 참고"를 확인해 필요한 포트를 허용하세요.
2) containerd 설치 및 설정 (모든 노드)
3) Kubernetes 저장소 등록 및 패키지 설치 (모든 노드)
버전 트랙(v1.30)은 필요 시 최신 안정 버전으로 교체 가능합니다. 트랙을 바꿀 때는 모든 노드에서 동일하게 적용하세요.
4) Control-plane 초기화 (Control-plane 노드만)
먼저 이미지를 미리 받아두면 최초 초기화 시간이 단축됩니다(선택).
클러스터를 초기화합니다. Calico 기본값과 맞추기 위해
--pod-network-cidr=192.168.0.0/16를 사용합니다.성공 시
kubeadm join ... 명령이 출력됩니다. Worker 노드 합류에 사용하므로 복사해 보관하세요.관리자(kubectl) 설정:
네트워크 플러그인(CNI) 설치: Calico 사용
모든 CoreDNS/Calico 파드가
Running이 되고 Control-plane 노드가 Ready가 되면 다음 단계로 진행합니다.5) Worker 노드 조인 (각 Worker 노드에서)
Control-plane 초기화 시 출력된
kubeadm join 명령을 각 Worker에서 실행합니다. 예:토큰이 만료되었거나 잃어버렸다면 Control-plane에서 새 토큰을 생성할 수 있습니다.
6) 클러스터 상태 확인 (Control-plane)
3개 노드(Control-plane 1, Worker 2)가 모두
Ready 상태면 구축이 완료되었습니다.7) 선택/운영상 팁
- 여러 NIC/다중 IP 환경에서 노드 IP를 고정하려면(선택):
- kubectl 자동완성/alias(선택):
- 업그레이드 개요(요약):
- Control-plane에서
sudo apt-mark unhold kubeadm && sudo apt install -y kubeadm && sudo kubeadm upgrade plan && sudo kubeadm upgrade apply v1.xx.y - 각 노드에서
kubelet/kubectl패키지 업데이트 후systemctl restart kubelet - 완료 후 다시
apt-mark hold ...
8) 포트/방화벽 참고 (UFW/외부 방화벽 사용하는 경우)
- Control-plane 필요 포트(기본):
- 6443/tcp (Kubernetes API 서버)
- 2379-2380/tcp (etcd, Control-plane 내부)
- 10250/tcp (kubelet API)
- 10257/tcp (kube-controller-manager)
- 10259/tcp (kube-scheduler)
- Worker 필요 포트(기본):
- 10250/tcp (kubelet API)
- 30000-32767/tcp (NodePort 서비스)
내부망 테스트라면 UFW를 끄는 편이 간단합니다. 운영환경에서는 최소 허용 정책으로 필요한 포트만 개방하세요.
9) 문제 해결 및 리셋
- 조인 토큰 재발급:
kubeadm token create --print-join-command
- 네트워크 플러그인 재설치 전 정리(주의):
/etc/cni/net.d백업/삭제 후 재적용
- 클러스터 리셋(모든 노드, 신중히):
필요 시 재부팅 후 다시 1) 공통 시스템 준비 → 2) containerd → 3) 패키지 설치 → 4) 초기화/조인 순으로 재시도하세요.
클러스터 아키텍처 다이어그램
아래 다이어그램은 3대 서버(컨트롤 플레인 1, 워커 2)로 구성된 클러스터에서 Ingress → Service → Pod 경로와 모니터링 스택(Grafana/Prometheus), Calico CNI의 위치를 개략적으로 보여줍니다.
간단한 범례: Ingress는 도메인 기반 라우팅을 수행하고, Service는 L4 가상 IP로 파드에 로드밸런싱합니다. Prometheus는 노드/파드 메트릭을 수집하고, Grafana는 이를 시각화합니다. Calico는 노드 간 Pod 네트워킹을 제공합니다.
Fly QA 애플리케이션 배포 가이드 (Kubernetes)
사용 도구 개요와 필요성
- Helm: Kubernetes 패키지 관리자. 복잡한 리소스를 템플릿(차트)으로 묶어 버전/값 관리와 업그레이드를 쉽게 합니다. 모니터링 스택(kube-prometheus-stack), cert-manager 등 반복적 설치를 표준화합니다.
- Ingress Controller: L7(HTTP/HTTPS) 트래픽을 클러스터 내부 Service로 라우팅하는 컨트롤러(NGINX, Traefik 등). 도메인 기반 라우팅, TLS 종료, 리버스 프록시 기능을 제공합니다.
- Grafana: 메트릭/로그/트레이싱 데이터의 시각화 대시보드. Prometheus 데이터를 기반으로 시스템 상태를 직관적으로 모니터링할 수 있습니다.
- Prometheus: 시계열 메트릭 수집/저장 시스템. Kubernetes 컴포넌트/노드/파드의 성능 지표를 스크랩해 저장합니다.
- Alertmanager: Prometheus 경보를 집계/라우팅해 Slack/이메일 등으로 알림을 전송합니다.
- metrics-server:
kubectl top과 HPA의 실시간 리소스 사용량(메모리/CPU)을 제공하는 경량 메트릭 어그리게이터.
- cert-manager(선택): TLS 인증서(예: Let’s Encrypt)를 Kubernetes 네이티브 방식으로 자동 발급/갱신해 Ingress에 적용합니다.
아래는 본 저장소의 Fly QA를 Kubernetes에 배포하는 표준 절차입니다. 프론트엔드는 Vite로 빌드된 정적 파일을 Nginx 기반 컨테이너로 서비스하고, 백엔드는 NestJS(Playwright 포함) 이미지를 배포합니다. Ingress는 도메인 라우팅에 사용합니다.
전제: 개인/조직 컨테이너 레지스트리(예: Docker Hub, GHCR, ECR 등) 접근 권한이 있고, 클러스터에 Ingress Controller(예: NGINX Ingress)가 설치되어 있어야 합니다.
A) 환경 변수 설계
백엔드에서 필요로 하는 주요 환경 변수(예시):
PORT(기본 3000)
NODE_ENV(production)
DATABASE_HOST,DATABASE_PORT,DATABASE_USERNAME,DATABASE_PASSWORD,DATABASE_NAME
REDIS_HOST,REDIS_PORT
- 프런트엔드에서 API URL 사용 시:
VITE_API_URL(예: https://api.flyqa.me)
민감 정보는 Kubernetes
Secret으로 관리하고, 나머지는 ConfigMap 또는 Deployment env로 주입합니다.B) 컨테이너 이미지 빌드/푸시
레지스트리 네임스페이스/리포지토리를 다음과 같이 가정합니다.
- 백엔드 이미지:
<REGISTRY>/<NAMESPACE>/fly-qa-backend:<TAG>
- 프론트엔드 이미지:
<REGISTRY>/<NAMESPACE>/fly-qa-frontend:<TAG>
1) 백엔드 이미지 (Playwright 런타임 포함 Dockerfile 사용)
2) 프론트엔드 이미지 (Vite 정적 빌드 → Nginx 서빙)
아래 Dockerfile 예시를 임시 파일로 생성해 사용합니다(리포지토리에 포함하고 싶다면
apps/frontend/Dockerfile로 추가).Nginx 기본 설정 파일 예시(
server/nginx/default.conf):이제 프론트엔드 이미지를 빌드/푸시합니다.
C) Kubernetes 매니페스트 예시
네임스페이스 생성(선택):
1) Secret/Config (DB/Redis 자격증명)
2) Backend Deployment/Service
3) Frontend Deployment/Service
4) Ingress (예:
flyqa.me, api.flyqa.me)참고: WebSocket(Socke.IO) 타임아웃을 늘리는 애너테이션을 포함했습니다. 클러스터 Ingress Controller 구성에 따라 조정하세요.
D) 배포 실행
k8s/ 디렉터리에 위 예시들을 파일로 나누어 저장해두면 관리가 편리합니다.E) 새 버전 배포/롤링 업데이트
1) 코드 변경 → 버전 태그 지정 → 이미지 빌드/푸시
2) Deployment 이미지 태그 갱신(예:
kubectl set image)3) 롤아웃 상태 확인/되돌리기
F) 스토리지/아티팩트 보존(선택)
현재 예시는 실행 스크린샷/리포트를
emptyDir로 두어 파드 수명과 함께 사라집니다. 장기 보존이 필요하면 PVC로 교체하세요.부록) 빠른 실행 요약
- 모든 노드: 커널 모듈, sysctl, 스왑 비활성, containerd 설치/설정, kubeadm/kubelet/kubectl 설치
- Control-plane:
kubeadm init --apiserver-advertise-address=10.10.0.100 --pod-network-cidr=192.168.0.0/16
- Control-plane: kubeconfig 설정, Calico 적용
- Worker:
kubeadm join ...실행
- Control-plane:
kubectl get nodes로 Ready 확인
운영 모니터링: Grafana + Prometheus (kube-prometheus-stack)
Helm 차트
kube-prometheus-stack(Prometheus Operator 포함)을 사용해 클러스터 메트릭/알림과 대시보드를 손쉽게 구성합니다. Grafana에 Ingress를 붙여 외부에서 접근합니다.1) Helm 설치 (관리 단말에서 1회)
2) Helm 리포지토리 등록/갱신
3) 네임스페이스 생성
4) values.yaml 예시 작성 (Ingress, TLS, 퍼시스턴스)
아래 내용을
k8s/monitoring/values.yaml로 저장하세요. 도메인과 스토리지 클래스를 환경에 맞게 수정합니다.TLS 자동 발급을 쓸 경우 cert-manager 설치 후grafana-tls는 자동 관리되도록 애너테이션/ClusterIssuer를 추가하세요.
5) kube-prometheus-stack 설치
설치 후 리소스 확인:
Grafana접속:
https://grafana.flyqa.me (admin / <SET_STRONG_PASSWORD>)6) 기본 대시보드/데이터소스
- 기본으로 Kubernetes/Node/Pod/Cluster 대시보드가 포함됩니다.
- 데이터소스는 Prometheus가 자동으로 설정됩니다.
- 필요 시 Import 기능으로 Grafana.com의 대시보드 ID를 추가하세요.
7) metrics-server 설치 (HPA/오토스케일)
클러스터 네트워킹/인증서 이슈로 metrics-server가 실패할 경우,--kubelet-insecure-tls플래그를 추가한 배포 매니페스트를 사용하세요(운영환경에서는 권장하지 않음).
8) 알림(선택)
Alertmanager 수신자 구성 예시를 values에 추가하면 Slack/Email/PagerDuty 등으로 경보를 보낼 수 있습니다.
적용:
9) 접근 점검 체크리스트
- Grafana Ingress가
200 OK로 응답하는지
- 기본 대시보드에서 노드/파드 메트릭이 수집되는지
kubectl top nodes/pods가 동작하는지(metrics-server)
- 알림 테스트를 보냈을 때 수신되는지