241. Design a Kubernetes Cluster
클러스터 설계 고려사항
| 항목 | 고려 요소 |
|---|---|
| 목적 | 학습 / 개발 / 프로덕션 |
| 클라우드 vs 온프레미스 | 관리형(EKS, GKE, AKS) vs 자체 구축 |
| 워크로드 유형 | 웹 앱 / 빅데이터 / CI/CD |
| 노드 수 | 소규모(~10) / 대규모(5000+) |
| 스토리지 | SSD / 네트워크 스토리지 / 분산 스토리지 |
환경별 추천 구성
개발/학습:
- Minikube (단일 노드 올인원)
- kubeadm (단일 마스터)
- kind / k3s
프로덕션:
- 관리형 서비스 (EKS / GKE / AKS)
- kubeadm (멀티 마스터 HA)
- Kubernetes the Hard Way (학습용 수동 구성)
노드 규모 가이드
| 규모 | 노드 수 | 권장 구성 |
|---|---|---|
| 소규모 | ~10 | 마스터 1-2, 워커 여러 개 |
| 중규모 | ~100 | 마스터 3개 (HA), 전용 etcd 고려 |
| 대규모 | 5000+ | 마스터 5+, 외부 etcd 클러스터 분리 |
Kubernetes는 클러스터당 최대 5,000 노드, 150,000 Pod, 300,000 컨테이너 지원
242. Choosing Kubernetes Infrastructure
배포 옵션 비교
| 옵션 | 특징 | 적합한 상황 |
|---|---|---|
| Minikube | VM 기반 단일 노드, 간단한 설치 | 로컬 학습 |
| kubeadm | 표준 도구, 멀티 노드 지원 | 온프레미스 프로덕션 |
| k3s | 경량화, IoT/Edge 최적화 | 리소스 제한 환경 |
| kind | Docker 컨테이너 기반 클러스터 | CI/CD 테스트 |
| EKS (AWS) | 완전 관리형, IAM 통합 | AWS 환경 |
| GKE (GCP) | 완전 관리형, 자동 업그레이드 | GCP 환경 |
| AKS (Azure) | 완전 관리형, Azure AD 통합 | Azure 환경 |
턴키(Turnkey) vs 호스티드(Hosted)
- 턴키 솔루션 (사용자가 VM 관리): kubeadm, kops (AWS), OpenShift
- 호스티드 솔루션 (클라우드 제공자가 마스터 관리): GKE, EKS, AKS
243. Configure High Availability (HA)
HA가 왜 필요한가?
“마스터 노드 하나가 죽으면 클러스터 관리 기능이 모두 멈추기 때문”
정확히 뭐가 멈추나?
- 기존 Pod는 계속 동작 (워커 노드의 kubelet이 돌리고 있으므로)
- 하지만 새 배포 / Pod 재생성 / 오토스케일 /
kubectl명령 모두 불가 - 즉 현재 상태는 유지되지만 어떤 변화도 불가능
언제 HA가 필요한가?
- 프로덕션 환경 (거의 필수)
- 마스터 다운이 비즈니스 임팩트 있는 경우
- 반면 개발/학습 환경은 단일 마스터로 충분
HA의 기본 원칙:
- 마스터 최소 3개 (etcd의 Quorum 요구)
- 앞에 Load Balancer 놓고
kubectl은 LB로 접속 - Controller Manager/Scheduler는 Active-Passive (리더 1개만 동작)
- API Server는 Active-Active (모두 동시 서비스)
단일 마스터의 문제점
단일 마스터 → 장애 발생 → API Server 다운 → 새 Pod 스케줄 불가, kubectl 명령 불가 (기존 워커 Pod는 계속 실행)
마스터가 다운돼도 기존에 실행 중인 Pod는 계속 동작하지만, 새 배포 / 스케줄링 / 자동 복구는 불가능
HA 멀티 마스터 구성
- 로드밸런서 (nginx / HAProxy) — VIP
192.168.1.100:6443 - Master 1: API Server, Controller Manager, Scheduler + etcd (내장)
- Master 2: API Server, Controller Manager, Scheduler + etcd (내장)
- LB가 두 Master로 트래픽 분산
- 두 etcd는 클러스터 동기화 (Raft)
컴포넌트별 HA 동작 방식
| 컴포넌트 | HA 방식 | 설명 |
|---|---|---|
| API Server | Active-Active | 여러 인스턴스 동시 서비스, LB로 분산 |
| Controller Manager | Active-Passive | 리더 선출(Leader Election), 하나만 활성 |
| Scheduler | Active-Passive | 리더 선출, 하나만 활성 |
| etcd | Active-Active | 분산 합의(Raft 알고리즘) |
Controller Manager 리더 선출
# 리더 선출 옵션 (kube-controller-manager)
--leader-elect=true # 리더 선출 활성화 (기본 true)
--leader-elect-lease-duration=15s # 리더 임기
--leader-elect-renew-deadline=10s # 리더 갱신 데드라인
--leader-elect-retry-period=2s # 재시도 간격
# 현재 리더 확인
kubectl get endpoints kube-controller-manager -n kube-system -o yaml | grep holderIdentity
kubectl get leases -n kube-system | grep controller-managerkubeadm HA 구성 절차
# 1. 첫 번째 마스터 초기화 (로드밸런서 주소 사용)
kubeadm init \
--control-plane-endpoint "LOAD_BALANCER_IP:6443" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16
# 출력에서 join 명령어 확인
# → control-plane join 명령 (다른 마스터용)
# → worker join 명령 (워커 노드용)
# 2. 추가 마스터 노드 Join
kubeadm join LOAD_BALANCER_IP:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane \
--certificate-key <cert-key>
# 3. 워커 노드 Join
kubeadm join LOAD_BALANCER_IP:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>244. ETCD in HA
etcd 기본 개념
- 분산 Key-Value 스토어 — Kubernetes 클러스터의 모든 상태 저장
- Raft 합의 알고리즘으로 데이터 일관성 보장
- 쓰기는 반드시 **리더(Leader)**를 통해 처리
Raft 합의 알고리즘
sequenceDiagram participant L as Leader participant F1 as Follower 1 participant F2 as Follower 2 Note over L,F2: 쓰기 요청 수신 L->>F1: 로그 복제 전송 L->>F2: 로그 복제 전송 F1-->>L: ACK F2-->>L: ACK Note over L: 과반수(Quorum) 확인 L->>F1: Commit L->>F2: Commit Note over L,F2: 쓰기 완료
Quorum (정족수)
| 노드 수 | Quorum | 허용 장애 노드 |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 2 | 0 (권장 안 함) |
| 3 | 2 | 1 ← 최소 HA 구성 |
| 4 | 3 | 1 |
| 5 | 3 | 2 ← 프로덕션 권장 |
| 6 | 4 | 2 |
| 7 | 4 | 3 |
etcd는 홀수 노드 구성 권장 — 짝수는 Quorum 효율이 같으면서 노드만 더 필요
왜 홀수 노드여야 하나?
Split-Brain 방지 때문.
네트워크 장애로 클러스터가 두 조각으로 분리되는 상황을 생각해보자:
| 총 노드 | 조각 A | 조각 B | 어느 쪽이 리더가 될까? |
|---|---|---|---|
| 3 (홀수) | 2 | 1 | A만 과반수 확보 → 정상 동작 |
| 4 (짝수) | 2 | 2 | 양쪽 다 과반수 못 확보 → 둘 다 멈춤 (Split-brain) |
| 5 (홀수) | 3 | 2 | A만 과반수 확보 → 정상 |
| 6 (짝수) | 3 | 3 | 양쪽 다 과반수 못 확보 |
홀수를 유지하면 어떤 분할이든 한쪽만 과반수를 가질 수 있음. 짝수는 이 보장이 깨짐.
4대 = 3대와 동일한 장애 허용 (1대 고장 OK). 더 많이 쓰는데 이득 없음 → 홀수 선호.
etcd 구성 방식
Stacked etcd (기본): Master 1/2/3 노드 안에 API Server + etcd 함께 (각 마스터에 etcd 내장)
External etcd (고가용성): 별도 etcd 노드 3개를 두고, 모든 Master의 API Server가 etcd 클러스터를 공유
| 구성 | 장점 | 단점 |
|---|---|---|
| Stacked | 노드 수 적음, 간단 | 마스터 장애 시 etcd도 같이 손실 |
| External | etcd 독립 관리, 강한 격리 | 노드 수 증가, 복잡성 |
Stacked vs External 언제 선택?
| 상황 | 권장 | 이유 |
|---|---|---|
| 소규모 클러스터 (~50 노드) | Stacked | 운영 복잡도 낮음, kubeadm 기본값 |
| 중대규모 (~500 노드) | External 고려 | 마스터와 etcd의 리소스 경합 분리 |
| 대규모 (1000+ 노드) | External 필수 | etcd 전용 하드웨어 (SSD, 메모리) 할당 |
| 엄격한 SLA 요구 | External | 마스터 노드 재시작이 etcd에 영향 없도록 |
| 개발/학습 환경 | Stacked | 리소스 절약 |
kubeadm init은 기본값이 Stacked. External을 원하면 먼저 etcd 클러스터를 별도 구성 후kubeadm설정에서 외부 endpoint를 지정.
etcd 클러스터 설정
# etcd 서비스 옵션 (각 etcd 노드)
ExecStart=/usr/local/bin/etcd \
--name etcd-1 \
--initial-advertise-peer-urls https://192.168.1.11:2380 \
--listen-peer-urls https://192.168.1.11:2380 \
--listen-client-urls https://192.168.1.11:2379,https://127.0.0.1:2379 \
--advertise-client-urls https://192.168.1.11:2379 \
--initial-cluster-token etcd-cluster-token \
--initial-cluster etcd-1=https://192.168.1.11:2380,etcd-2=https://192.168.1.12:2380,etcd-3=https://192.168.1.13:2380 \
--initial-cluster-state new \
--cert-file=/etc/etcd/etcd.crt \
--key-file=/etc/etcd/etcd.key \
--peer-cert-file=/etc/etcd/etcd.crt \
--peer-key-file=/etc/etcd/etcd.key \
--trusted-ca-file=/etc/etcd/ca.crt \
--peer-trusted-ca-file=/etc/etcd/ca.crt \
--peer-client-cert-auth \
--client-cert-authetcd 상태 확인
# etcd 멤버 목록
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/etcd/ca.crt \
--cert=/etc/etcd/etcd.crt \
--key=/etc/etcd/etcd.key \
member list
# 리더 확인
ETCDCTL_API=3 etcdctl \
--endpoints=https://192.168.1.11:2379,https://192.168.1.12:2379,https://192.168.1.13:2379 \
--cacert=/etc/etcd/ca.crt \
--cert=/etc/etcd/etcd.crt \
--key=/etc/etcd/etcd.key \
endpoint status --write-out=table
# 클러스터 헬스 확인
ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://192.168.1.11:2379,https://192.168.1.12:2379,https://192.168.1.13:2379 \
--cacert=/etc/etcd/ca.crt \
--cert=/etc/etcd/etcd.crt \
--key=/etc/etcd/etcd.keyAPI Server → 외부 etcd 연결 설정
# /etc/kubernetes/manifests/kube-apiserver.yaml
spec:
containers:
- command:
- kube-apiserver
- --etcd-servers=https://192.168.1.11:2379,https://192.168.1.12:2379,https://192.168.1.13:2379
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key245. Kubernetes the Hard Way
- Kelsey Hightower의 kubernetes-the-hard-way 참고
- 모든 컴포넌트를 바이너리 수동 설치하여 Kubernetes 내부 구조를 깊이 이해하는 학습용 방법
- CKA 시험에는 kubeadm 방식이 출제됨 → 시험 목적이라면 kubeadm 숙지가 우선
수동 구성 vs kubeadm 비교
| 항목 | Hard Way (수동) | kubeadm |
|---|---|---|
| 인증서 | 직접 생성 | 자동 생성 |
| 컴포넌트 설치 | 바이너리 직접 설치 | 자동 설치 |
| etcd | 직접 구성 | 자동 구성 |
| 학습 가치 | 매우 높음 | 실무 사용 |
| 시험 출제 | ❌ | ✅ |
섹션 요약
- 클러스터 설계 — 목적 / 규모 / 환경 결정
- 인프라 선택 — kubeadm / 관리형 / k3s
- HA 구성 — 멀티 마스터 + 로드밸런서
- etcd HA — Stacked vs External, Raft 합의, 홀수 노드
- 설치 — kubeadm init/join 또는 Hard Way