Etcd 개요
Etcd 란 무엇인가?
Etcd 는 2013 년 CoreOS 팀에서 시작한 오픈소스 프로젝트로, 고가용성을 갖춘 분산 키 - 값 (Key-Value) 저장소를 구축하는 것을 목표로 합니다. 내부적으로 raft 합의 알고리즘을 사용하여 데이터 일관성을 보장하며, Go 언어로 구현되었습니다.
명칭의 유래는 Unix 시스템의 설정 폴더인 /etc 와 분산 시스템 (Distributed System) 의 d 를 결합한 것으로, 분산 환경의 구성 정보를 저장하는 서비스임을 의미합니다.
Kubernetes 와 Etcd 의 관계
2014 년 Google 에서 Kubernetes 프로젝트가 출시되면서 Etcd 는 중요한 역할을 하게 되었습니다. Go 언어 기반이라는 점, 고가용성, Watch 메커니즘, CAS (Compare And Swap), TTL (Time To Live) 지원 등의 기능은 Kubernetes 의 요구 사항과 완벽하게 부합했습니다. 초기 Kubernetes 0.4 버전은 Etcd v0.2 를 사용했습니다.
Kubernetes 는 Etcd v2 의 기능을 다음과 같이 활용합니다:
- Watch 메커니즘: 선언적 API 를 통해 서비스를 배포할 때, 컨트롤러가 리소스 변경 이벤트를 실시간으로 감지하여 실제 상태와 기대 상태를 일치시킵니다.
- CAS 메커니즘: 데이터 업데이트 시 동시성 환경에서 원자적 업데이트를 보장합니다.
- TTL 기능: Event 객체에 TTL 을 설정하여 만료 후 자동 삭제를 유도하며, 클러스터의 가시성을 높입니다.
기술적 적합성 외에도 CoreOS 가 Kubernetes 생태계의 핵심 멤버였다는 점도 채택 요인으로 작용했습니다.
버전演进 및 변화
Kubernetes 의 성장에 따라 Etcd v2 는 성능 및 안정성 한계에 부딪혔습니다. 이에 따라 2016 년 6 월 Etcd 3.0 이 출시되었고, Kubernetes 1.6 부터 기본 저장소로 채택되어 5000 개 노드 규모의 클러스터를 지원할 수 있게 되었습니다. v3 버전의 출시로 Etcd 는 기술적으로 성숙 단계에 진입했으며, 클라우드 네이티브 시대의 표준 메타데이터 저장소로 자리 잡았습니다.
아키텍처 및 핵심 개념
계층 구조
Etcd 는分层 모델에 따라 다음과 같은 계층으로 구성됩니다:
- Client 계층: v2 및 v3 API 클라이언트 라이브러리를 제공하며,负载均衡 및 장애 조치 기능을 통해 개발 복잡도를 낮춥니다.
- API 네트워크 계층: 클라이언트 - 서버 간 통신 (v2 는 HTTP/1.x, v3 는 gRPC 기반) 및 서버 간 Raft 통신 프로토콜을 처리합니다. v3 는 grpc-gateway 를 통해 HTTP 호환성을 제공합니다.
- Raft 알고리즘 계층: Leader 선출, 로그 복제, ReadIndex 등을 구현하여 다수 노드 간 데이터 일관성을 유지합니다.
- 기능 논리 계층: KVServer, MVCC, 인증 (Auth), Lease, Compactor 등 핵심 기능을 구현합니다. MVCC 는 treeIndex 와 boltdb 로 구성됩니다.
- 저장 계층: WAL(Pre-write Log), Snapshot, boltdb 를 포함합니다. WAL 은 장애 복구 시 데이터 손실을 방지하며, boltdb 는 실제 메타데이터와 사용자 데이터를 저장합니다.
주요 용어
- Raft: 분산 시스템의 강한 일관성을 보장하는 합의 알고리즘.
- Member: 단일 Etcd 인스턴스로, Node 를 관리하며 클라이언트 요청을 처리합니다.
- Cluster: 협력하여 작동하는 여러 Member 로 구성된 집단.
- Leader/Follower/Candidate: Raft 알고리즘 내 노드의 상태. Leader 는 모든 데이터 제출을 처리하며, Follower 는 복사본을 유지합니다.
- WAL/Snapshot: 데이터 지속성을 위한 로그 및 상태 스냅샷.
- Term: Leader 선출 주기.
운영 실무
etcdctl 주요 명령어
운영 환경에서 SSL 인증서를 사용한 연결 설정 예시는 다음과 같습니다.
환경 변수 설정
ETCD_SSL_CA="/opt/etcd/ssl/ca.pem"
ETCD_SSL_CERT="/opt/etcd/ssl/server.pem"
ETCD_SSL_KEY="/opt/etcd/ssl/server-key.pem"
NODE_ENDPOINT="https://10.0.0.1:2379"
상태 확인 예시
export ETCDCTL_API=3
etcdctl --cacert=${ETCD_SSL_CA} --cert=${ETCD_SSL_CERT} --key=${ETCD_SSL_KEY} \
--endpoints=${NODE_ENDPOINT} endpoint status -w table
키 - 값 조작
# 데이터 생성 및 수정
etcdctl put /config/serviceA "active"
# 단일 키 조회
etcdctl get /config/serviceA
# 접두사 기반 조회
etcdctl get /config --prefix
# 모든 키 목록 조회
etcdctl get "" --prefix --keys-only
# 데이터 삭제
etcdctl del /config/serviceA
# 트랜잭션 처리
etcdctl txn <<'EOF'
mod("lock/key1") > "0"
put lock/key1 "locked"
put lock/key2 "reserved"
EOF
# 데이터 압축
etcdctl compaction 5000
# 변경 사항 감시
etcdctl watch /config/serviceA
클러스터 유지보수
# 멤버 목록 조회
etcdctl member list
# 헬스 체크
etcdctl endpoint health
# 상태 확인
etcdctl endpoint status
# 알람 확인 및 해제
etcdctl alarm list
etcdctl alarm disarm
# 단편화 정리
etcdctl defrag
# 백업 및 복원
etcdctl snapshot save backup.db
etcdctl snapshot restore backup.db
etcdctl snapshot status backup.db
모니터링 전략
핵심 지표 분류
Etcd 모니터링은 건강 상태, USE 방법 (시스템 자원), RED 방법 (애플리케이션 성능) 으로 구분됩니다.
- 건강 상태: 노드 가용성, Leader/Follower 상태, Leader 변경 빈도, Heartbeat丢失率.
- RED 방법: QPS, 오류율, 요청 지연 시간,磁盘同步지연 (WAL/DB fsync), Proposal 실패 횟수, Snapshot 처리 시간, Watcher 연결 수.
- USE 방법: CPU 사용률, 메모리 사용량, 파일 디스크립터 수, 저장소 사용률.
특히磁盘동기화 지연 시간이 높을 경우 클러스터 불안정으로 이어질 수 있으므로 주의 깊게 관찰해야 합니다.
kube-prometheus 를 통한 지표 수집
HTTP 모드 설정
Etcd 설정에서 --listen-metrics-urls 를 수정하여 외부 노출을 허용합니다.
- --listen-metrics-urls=http://127.0.0.1:2381,http://192.168.1.10:2381
Prometheus 스택 배포 예시:
helm install monitoring-stack -n monitoring-system \
--set kubeEtcd.service.port=2381 \
--set kubeEtcd.service.targetPort=2381 \
--set prometheusOperator.admissionWebhooks.patch.image.sha=null ./
HTTPS 모드 설정
보안을 위해 인증서 기반 시크릿을 생성합니다.
kubectl create secret generic etcd-tls-secret -n monitoring-system \
--from-file=/opt/etcd/ssl/ca.pem \
--from-file=/opt/etcd/ssl/health-client.pem \
--from-file=/opt/etcd/ssl/health-client-key.pem
HTTPS 설정을 포함한 배포:
helm install monitoring-stack -n monitoring-system \
--set kubeEtcd.serviceMonitor.scheme=https \
--set kubeEtcd.serviceMonitor.caFile=/etc/prometheus/secrets/etcd-tls-secret/ca.pem \
--set kubeEtcd.serviceMonitor.certFile=/etc/prometheus/secrets/etcd-tls-secret/health-client.pem \
--set kubeEtcd.serviceMonitor.keyFile=/etc/prometheus/secrets/etcd-tls-secret/health-client-key.pem \
--set prometheus.prometheusSpec.secrets={etcd-tls-secret} \
--set prometheusOperator.admissionWebhooks.patch.image.sha=null ./
성능 벤치마크
SLI 및 SLO 정의
안정성을 측정하기 위해 SLI(서비스 수준 지표) 를 선정하고, 이를 기반으로 SLO(서비스 수준 목표) 를 설정합니다.
- 처리량 (Throughput): 초당 처리 요청 수 (예: 읽기 40,000, 쓰기 20,000).
- 응답 시간 (Latency): 요청의 99% 가 특정 시간 이내 완료 (예: 100ms).
Benchmark 도구 활용
환경 구축
Linux 환경에 Go 를 설치합니다.
wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
echo 'export GOPROXY=https://goproxy.cn' >> /etc/profile
source /etc/profile
Etcd 소스를 클론하여 benchmark 도구를 컴파일합니다.
git clone https://github.com/etcd-io/etcd.git --depth 1
cd etcd/
go install -v ./tools/benchmark
쓰기 성능 테스트
테스트용 키를 미리 생성합니다.
TEST_KEY="/benchmark/data"
etcdctl --endpoints=${NODE_ENDPOINT} --cacert=${ETCD_SSL_CA} \
--cert=${ETCD_SSL_CERT} --key=${ETCD_SSL_KEY} put ${TEST_KEY} init
Leader 노드 대상 쓰기 테스트:
./benchmark --endpoints=${NODE_ENDPOINT} --cacert=${ETCD_SSL_CA} \
--cert=${ETCD_SSL_CERT} --key=${ETCD_SSL_KEY} --target-leader \
--conns=50 --clients=500 put --key-size=10 --sequential-keys \
--total=50000 --val-size=512
전체 멤버 대상 쓰기 테스트:
./benchmark --endpoints=${NODE_ENDPOINT},${NODE_ENDPOINT_2},${NODE_ENDPOINT_3} \
--cacert=${ETCD_SSL_CA} --cert=${ETCD_SSL_CERT} --key=${ETCD_SSL_KEY} \
--conns=50 --clients=500 put --key-size=10 --sequential-keys \
--total=50000 --val-size=512
읽기 성능 테스트
일관성 수준 (Linearizable vs Serializable) 에 따른 읽기 성능을 측정합니다.
# 단일 연결 읽기
./benchmark --endpoints=${NODE_ENDPOINT} --cacert=${ETCD_SSL_CA} \
--cert=${ETCD_SSL_CERT} --key=${ETCD_SSL_KEY} --conns=1 --clients=1 \
range ${TEST_KEY} --consistency=l --total=5000
# 동시 읽기 요청
./benchmark --endpoints=${NODE_ENDPOINT} --cacert=${ETCD_SSL_CA} \
--cert=${ETCD_SSL_CERT} --key=${ETCD_SSL_KEY} --conns=50 --clients=500 \
range ${TEST_KEY} --consistency=s --total=50000
磁盘성능 검증 (FIO)
Etcd 성능은 네트워크 지연과磁盘지연에 크게 의존합니다. 다수 노드는 동일 데이터센터에 배치하여 네트워크 지연을 최소화해야 합니다.磁盘성능은 다음 지표로 확인합니다:
- 운영 중 지표:
etcd_disk_wal_fsync_duration_seconds의 99% 값이 10ms 미만인지 확인. - FIO 테스트: Etcd 사용 패턴을 모사하여 지연 시간을 측정.
mkdir -p /tmp/io-test
fio --rw=write --ioengine=sync --fdatasync=1 --directory=/tmp/io-test \
--size=22m --bs=2300 --name=disk-perf-check
성능 튜닝
磁盘최적화
SSD 사용은 필수이며, Etcd 프로세스에 높은 I/O 우선순위를 부여합니다.
sudo ionice -c2 -n0 -p $(pgrep etcd)
CPU 설정
CPU 거버너를 performance 모드로 설정하여 주파수 변동을 방지합니다.
echo performance | tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
구성 파라미터 조정
자동 압축 기능 활성화, Raft 메시지 최대 크기 조정, 저장소 최대 용량 제한 등의 파라미터를 환경에 맞게 수정합니다. 공식 문서의 Hardware Requirements 및 Tuning 가이드를 참조하여 구체적인 값을 결정하는 것이 좋습니다.