Design Kubernetes - HA of ETCD

2026. 1. 6. 16:21·CKA

Kubernetes를 프로덕션 수준으로 운영하려면 컨트롤 플레인(마스터)을 다중화하는 것만으로는 부족합니다. 클러스터 상태의 “진짜 소스 오브 트루스(source of truth)”인 etcd 자체가 고가용성(HA)으로 구성되어야 컨트롤 플레인 HA가 의미를 갖습니다.

이번 글은 다음 HA 구성 강의의 전 단계로, etcd를 HA 모드로 이해하기 위한 핵심 개념(분산/일관성, Raft, 리더 선출, Quorum, 노드 수 추천, 네트워크 파티션 위험, 토폴로지 선택)을 깔끔하게 정리합니다.


1) etcd는 무엇인가?

etcd는 분산(distributed) + 신뢰성(reliable) + 빠른(fast) 키-값 저장소(key-value store) 입니다.

  • “키-값”이라고 해서 값이 반드시 단순 문자열일 필요는 없습니다.
  • 실제 운영에서는 JSON/YAML 같은 구조화된 문자열을 값(value)로 넣고 빼는 방식이 흔합니다.
    • 예: key=/registry/pods/..., value=pod spec(json) 같은 형태로 상태가 저장됩니다(쿠버네티스 내부 구현 관점).

스크립트에서 “문서/페이지 단위로 저장한다”는 표현이 있는데, etcd는 기본 모델이 key-value입니다. 다만 value에 JSON 문서를 넣는 방식으로 “문서 DB처럼” 활용할 수 있다는 의미로 이해하면 됩니다.


2) “분산 etcd”가 왜 필요한가? (일관성과 장애 대응)

단일 etcd 서버는 단순하지만 위험합니다.

  • etcd는 Kubernetes의 거의 모든 상태를 저장합니다.
  • etcd가 죽으면 클러스터 운영/복구가 사실상 멈춥니다.

그래서 etcd를 여러 서버(멤버)로 구성해, 데이터 복제와 장애 허용을 확보합니다.

2.1 읽기(Read)는 쉬운데, 쓰기(Write)는 어렵다

3대의 etcd 멤버가 있고 모두 동일한 데이터를 가진다고 해도, 쓰기 요청이 동시에 여러 노드로 들어오면 충돌이 생길 수 있습니다.

따라서 etcd는 “아무 노드나 쓰기 처리”를 하는 구조가 아닙니다.

  • etcd 클러스터는 리더(leader) 1대 + 팔로워(follower)들 구조로 동작합니다.
  • 쓰기(write)는 리더가 최종 처리합니다.
    • 팔로워로 요청이 들어오면 내부적으로 리더에게 전달됩니다.
  • 쓰기 성공은 “리더가 단독으로 저장”이 아니라, 클러스터 합의(consensus) 를 만족해야 완료됩니다.

이 합의를 구현하는 프로토콜이 Raft입니다.


3) Raft로 합의(consensus)하기: 리더 선출과 복제

3.1 리더 선출(Election)

클러스터 시작 시 리더가 없을 수 있습니다. Raft는 다음 흐름으로 리더를 정합니다.

  1. 각 노드는 랜덤한 election timeout을 가짐
  2. 가장 먼저 timeout이 끝난 노드가 “내가 리더 후보”라고 투표 요청
  3. 다른 노드들이 투표 → 과반수(Quorum)를 얻으면 리더가 됨
  4. 리더는 주기적으로 heartbeat를 보내 “내가 리더다”를 유지

리더 heartbeat가 끊기면 팔로워들이 재선거를 진행해 새 리더를 선출합니다.

3.2 쓰기 복제(Replication)와 “완료 조건”

리더는 쓰기 요청을 처리한 뒤, 팔로워에 로그를 복제합니다. 그리고 과반수(Quorum)가 복제에 동의/반영하면 해당 쓰기는 “완료”로 간주됩니다.

여기서 중요한 질문:

멤버 3개 중 1개가 죽어있으면 쓰기는 실패할까?

정답은: 과반수(Quorum)를 만족하면 성공합니다.


4) Quorum(정족수) 이해가 etcd HA의 전부다

4.1 Quorum 공식

클러스터 크기가 N일 때 Quorum(정족수)은:

  • Quorum = floor(N/2) + 1

예:

  • N=3 → quorum=2
  • N=5 → quorum=3
  • N=7 → quorum=4

4.2 “2노드 etcd는 의미가 없다”는 이유

N=2면 quorum은 2입니다.

  • 2개 중 1개라도 죽으면 남은 1개는 quorum(2)을 만족 못 함
  • 즉, 쓰기 불가 → 클러스터 기능상 멈춤

그래서 etcd는 최소 3개가 권장됩니다.

4.3 장애 허용(fault tolerance)

etcd에서 흔히 말하는 “몇 개까지 죽어도 되나”는 다음으로 계산합니다.

  • fault tolerance = floor((N-1)/2)

예:

  • N=3 → 1개까지 장애 허용
  • N=5 → 2개까지 장애 허용
  • N=7 → 3개까지 장애 허용

5) 왜 odd(홀수) 노드가 권장될까? (네트워크 파티션 관점)

스크립트에서 강조한 “홀수 선호”는 네트워크 파티션(network partition) 상황에서 특히 중요합니다.

5.1 짝수 노드의 문제: 반반 분리 시 “둘 다 과반수 없음”

예: N=6이면 quorum=4입니다.

  • 네트워크가 3 vs 3으로 갈라지면
    • 두 그룹 모두 4를 못 채움 → 둘 다 쓰기 불가
    • 결과: 클러스터가 “멈춘 것처럼” 보일 수 있음

5.2 홀수 노드의 장점: 어떤 식으로 갈라져도 한쪽이 과반수

예: N=7이면 quorum=4.

  • 파티션이 4 vs 3으로 갈라지면
    • 4 그룹은 quorum 만족 → 계속 동작
    • 3 그룹은 동작 불가(정상, split-brain 방지)

그래서 운영에서는 3 또는 5를 가장 많이 선택합니다.

“6보다 5가 낫다”는 요지는, 비용(노드 수)을 늘려도 장애 허용이 늘지 않는 경우가 많고, 파티션 리스크까지 고려하면 홀수가 더 합리적이라는 뜻입니다.
5와 6의 fault tolerance는 둘 다 2지만, 6은 quorum이 4라 운영 부담만 커집니다.


6) etcd 노드 수 추천: 보통 3, 더 필요하면 5

  • 3 노드: 최소 HA, 1노드 장애 허용
  • 5 노드: 2노드 장애 허용 (더 강한 내결함성)
  • 7 이상: 대부분 불필요 (합의/복제 비용이 늘어 성능/운영 복잡도가 증가)

스크립트의 결론처럼 “3이 기본, 더 높은 내결함성이 필요하면 5”가 실무적으로도 가장 흔한 선택입니다.


7) Kubernetes HA에서 etcd 토폴로지 2가지

7.1 Stacked control plane (스택드 토폴로지)

컨트롤 플레인 노드에 etcd 멤버도 같이 둡니다.

  • 장점: 구성 단순, 노드 수 적음
  • 단점: 컨트롤 플레인 노드 장애 = etcd 멤버도 같이 손실
    → 장애 도메인이 커짐

7.2 External etcd (외부 etcd 토폴로지)

etcd를 전용 노드로 분리합니다.

  • 장점: 컨트롤 플레인 장애가 etcd에 덜 영향을 줌(리스크 분리)
  • 단점: 노드 수 증가 + 인증서/네트워크 구성 난이도 상승

7.3 핵심 포인트: apiserver가 etcd를 바라보는 주소

어떤 토폴로지든 kube-apiserver가 etcd endpoints를 정확히 바라보게 해야 합니다.

  • kube-apiserver는 etcd 서버 목록을 여러 개 지정할 수 있음
  • etcd는 분산 시스템이라, API Server는 살아있는 멤버 중 하나로 연결해 읽기/쓰기를 수행할 수 있음

(개념 예시: kube-apiserver의 etcd 설정)

- --etcd-servers=https://10.0.0.21:2379,https://10.0.0.22:2379,https://10.0.0.23: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.key

8) etcd 클러스터 구성에서 중요한 설정(“피어 정보”)

스크립트에서 “initial cluster 옵션에 peer 정보가 들어간다”는 부분이 매우 중요합니다. etcd 멤버는 자기가 클러스터의 일부이고, 동료가 누구인지 알아야 합니다.

주요 옵션(이름만 봐도 목적이 드러납니다):

  • --name: 멤버 이름
  • --initial-cluster: 전체 멤버 목록(name=peerURL)
  • --initial-advertise-peer-urls: 다른 멤버가 나를 찾을 peer URL
  • --listen-peer-urls: 내가 peer 통신을 받아줄 주소
  • --advertise-client-urls: 클라이언트(apiserver/etcdctl)가 나를 찾을 URL
  • --listen-client-urls: 내가 클라이언트 요청을 받아줄 주소
  • --initial-cluster-state: new 또는 existing (초기 구성/추가 멤버링 시 중요)

(개념 예시)

ETCD_NAME=etcd1
ETCD_INITIAL_CLUSTER="etcd1=https://10.0.0.21:2380,etcd2=https://10.0.0.22:2380,etcd3=https://10.0.0.23:2380"

etcd \
  --name "${ETCD_NAME}" \
  --data-dir /var/lib/etcd \
  --listen-client-urls https://10.0.0.21:2379,https://127.0.0.1:2379 \
  --advertise-client-urls https://10.0.0.21:2379 \
  --listen-peer-urls https://10.0.0.21:2380 \
  --initial-advertise-peer-urls https://10.0.0.21:2380 \
  --initial-cluster "${ETCD_INITIAL_CLUSTER}" \
  --initial-cluster-state new \
  --client-cert-auth \
  --trusted-ca-file /etc/etcd/pki/ca.crt \
  --cert-file /etc/etcd/pki/etcd.crt \
  --key-file /etc/etcd/pki/etcd.key

9) etcdctl로 데이터 읽고 쓰기(정확한 명령어 예시)

스크립트의 “etcd cuddle”은 etcdctl을 말하는 것입니다.

9.1 단일 키 쓰기/읽기

export ETCDCTL_API=3

etcdctl \
  --endpoints=https://10.0.0.21:2379 \
  --cacert=/etc/etcd/pki/ca.crt \
  --cert=/etc/etcd/pki/client.crt \
  --key=/etc/etcd/pki/client.key \
  put name John

etcdctl \
  --endpoints=https://10.0.0.21:2379 \
  --cacert=/etc/etcd/pki/ca.crt \
  --cert=/etc/etcd/pki/client.crt \
  --key=/etc/etcd/pki/client.key \
  get name

9.2 모든 키 조회(프리픽스)

etcdctl \
  --endpoints=https://10.0.0.21:2379 \
  --cacert=/etc/etcd/pki/ca.crt \
  --cert=/etc/etcd/pki/client.crt \
  --key=/etc/etcd/pki/client.key \
  get / --prefix --keys-only

10) 강의의 설계 결론을 “현실적으로” 해석하기

강의에서는 최종적으로 이렇게 말합니다.

  • HA에서 etcd 최소 멤버 수는 3
  • odd(홀수) 추천 → 3/5/7…
  • 5 이상은 대부분 불필요
  • 그런데 “노트북 자원 제한” 때문에 실습에서는 마스터 2대로 간다

여기서 중요한 보정:

  • 마스터 2대(= stacked etcd 2멤버) 는 “etcd HA” 관점에서 HA가 아닙니다.
    • quorum(2)을 만족하려면 2대가 모두 살아야 하고,
    • 1대만 장애 나면 쓰기가 멈춥니다.
  • 따라서 2마스터 실습은 “개념 이해/구성 연습”용으로는 가능하지만,
    프로덕션 HA 설계라고 부르면 안 됩니다.
  • 진짜 HA를 하려면:
    • stacked 토폴로지라면 컨트롤 플레인 3대
    • external etcd라면 etcd 전용 3대 + 컨트롤 플레인 2~3대 같은 형태로 가야 합니다.

11) 다음 강의(HA 클러스터 구성)로 넘어가기 전 체크포인트

이 강의에서 반드시 가져가야 할 포인트는 3가지입니다.

  1. etcd는 리더 기반 쓰기 + Raft 합의로 일관성을 보장한다.
  2. HA의 핵심은 Quorum = floor(N/2)+1 이고, 최소 3/권장 3 또는 5다.
  3. Kubernetes HA에서 etcd 토폴로지는 Stacked vs External이며, 결국 kube-apiserver가 올바른 etcd endpoints를 바라봐야 한다.

'CKA' 카테고리의 다른 글

Deploy k8s - kubeadm으로 배포하기  (0) 2026.01.06
Deploy k8s  (0) 2026.01.06
Design Kubernetes - HA(High Availability)  (0) 2026.01.06
Design Kubernetes - Choosing Infrastructure  (0) 2026.01.06
Design Kubernetes  (0) 2026.01.06
'CKA' 카테고리의 다른 글
  • Deploy k8s - kubeadm으로 배포하기
  • Deploy k8s
  • Design Kubernetes - HA(High Availability)
  • Design Kubernetes - Choosing Infrastructure
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      reentarantlock
      @discriminatorvalue
      Target
      페치 조인
      자바
      hibernate5module
      Thread
      @args
      jdk 동적 프록시
      고급
      프록시
      jpq
      단방향 맵핑
      프록시 팩토리
      requset scope
      김영한
      @discriminatorcolumn
      락
      WAS
      양방향 맵핑
      @within
      조회 성능 최적화
      log trace
      JPQL
      cglib
      빈 후처리기
      typequery
      스레드
      gesingleresult
      버퍼
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    Design Kubernetes - HA of ETCD
    상단으로

    티스토리툴바