이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.14 23:11
ETCD는 고가용성을 갖춘 강력한 일관성을 보장하는 분산 키-값 저장소이다. CoreOS에 의해 개발되었으며, 현재는 클라우드 네이티브 컴퓨팅 재단(CNCF)의 졸업 프로젝트로 관리된다. 주로 분산 시스템에서 구성 데이터, 서비스 디스커버리, 스케줄러 코디네이션과 같은 중요한 메타데이터를 안정적으로 저장하고 동기화하는 데 사용된다. 그 이름은 리눅스의 /etc 디렉토리와 분산 시스템("d")을 의미하는 "디렉토리"에서 유래하였다[1].
가장 널리 알려진 사용 사례는 쿠버네티스의 백엔드 저장소이다. 쿠버네티스 클러스터의 모든 클러스터 상태(파드, 노드, 구성 정보 등)를 ETCD에 저장하여 클러스터의 "단일 진실 공급원" 역할을 수행한다. 이는 쿠버네티스 컨트롤 플레인이 일관된 상태를 유지하고 고가용성을 실현하는 데 필수적이다.
ETCD는 Raft 합의 알고리즘을 구현하여 데이터의 강력한 일관성을 보장한다. 여러 노드로 구성된 클러스터에서도 모든 노드가 동일한 데이터 순서로 상태를 업데이트하도록 한다. 또한 와치(Watch) 기능을 통해 클라이언트가 특정 키의 변경 사항을 실시간으로 구독할 수 있고, 리스(Lease) 메커니즘을 이용한 키의 자동 만료(TTL)도 지원한다. 이러한 특성 덕분에 분산 락, 서비스 디스커버리, 선출 시스템 등 다양한 분산 코디네이션 작업의 기반이 된다.
ETCD는 CoreOS에서 개발한 고가용성의 분산 키-값 저장소이다. 분산 시스템에서 구성 데이터, 서비스 디스커버리, 스케줄링 정보와 같은 중요한 데이터를 안정적으로 저장하고 동기화하는 데 주로 사용된다. 내결함성을 갖춘 분산 합의 알고리즘을 구현하여 여러 노드에 걸쳐 데이터의 일관성을 보장하는 것이 핵심 목표이다.
시스템의 핵심은 Raft 합의 알고리즘에 기반한다. Raft는 이해와 구현이 비교적 간단한 합의 알고리즘으로, 리더 선출, 로그 복제, 안전성 보장 등의 메커니즘을 통해 클러스터 내 다수 노드 간의 상태 일관성을 유지한다. ETCD 클러스터는 일반적으로 홀수 개의 멤버(예: 3, 5, 7)로 구성되며, 쓰기 연산은 리더 노드를 통해 수행된 후 팔로워 노드들에게 복제된다. 대다수 노드에 쓰기가 성공해야 클라이언트에게 성공 응답이 반환된다.
데이터는 계층적인 키-값 저장소 구조로 조직된다. 키는 UTF-8 문자열이며, 슬래시(/)를 사용해 디렉터리와 같은 계층을 형성할 수 있다. 이 구조는 구성 데이터를 논리적으로 그룹화하는 데 유용하다. 데이터의 모든 변경 이력은 순차적으로 증가하는 리비전 번호와 함께 지속적으로 기록된다. 이는 감사 추적이나 특정 시점의 상태로 롤백하는 기능을 가능하게 한다.
클라이언트는 와치(Watch) 메커니즘을 통해 특정 키나 디렉터리에 대한 변경 사항을 실시간으로 구독할 수 있다. 또한 리스(Lease) 메커니즘은 키에 수명을 부여한다. 클라이언트는 일정 시간 동안 리스를 갱신하며, 갱신이 중단되면 리스와 연결된 모든 키가 자동으로 삭제된다. 이는 서비스 헬스 체크나 분산 락 구현과 같은 임시 세션 데이터 관리에 필수적이다.
Raft 합의 알고리즘은 분산 시스템에서 여러 서버 간에 상태를 일관되게 유지하기 위한 합의 알고리즘이다. Paxos 알고리즘의 복잡성을 해소하기 위해 설계되었으며, 이해하기 쉽고 구현이 용이하도록 만드는 데 중점을 두었다. etcd는 이 알고리즘을 핵심 엔진으로 채택하여 클러스터 내 데이터의 강력한 일관성과 고가용성을 보장한다.
Raft 알고리즘은 하나의 리더와 여러 팔로워로 구성된 노드들로 클러스터를 운영한다. 모든 클라이언트의 쓰기 요청은 리더 노드가 전담하여 처리하며, 팔로워 노드는 리더로부터의 복제 로그를 수신하여 상태를 동기화한다. 이 과정은 리더가 쓰기 요청을 로그에 추가한 후, 팔로워들에게 복제를 요청하고 과반수의 노드로부터 성공 응답을 받아야만 커밋(적용)되는 방식으로 진행된다. 이는 네트워크 분할이나 노드 장애가 발생하더라도, 과반수 이상의 노드가 살아 있다면 시스템이 정상적으로 운영될 수 있도록 한다.
리더 선출은 Raft의 핵심 메커니즘 중 하나이다. 각 노드는 무작위의 타임아웃 기간 동안 리더의 하트비트를 기다리며, 타임아웃이 만료되면 후보자가 되어 선거를 시작한다. 다른 노드들은 자신의 로그 상태를 비교해 가장 최신의 로그를 가진 후보자에게 투표하며, 과반수 이상의 표를 얻은 노드가 새로운 리더로 선출된다. 이 선출 과정을 통해 장애가 발생한 리더를 빠르게 대체할 수 있다.
Raft 알고리즘은 다음과 같은 주요 특성을 통해 etcd의 신뢰성을 뒷받침한다.
특성 | 설명 |
|---|---|
강한 일관성 | 모든 읽기/쓰기 연산이 리더를 통해 이루어져 선형화 가능한 일관성을 제공한다. |
리더 선출 | 장애 발생 시 자동으로 새로운 리더를 선출하여 가용성을 유지한다. |
로그 복제 | 모든 상태 변경은 로그 항목으로 순서대로 기록되고 복제되어 안전하게 저장된다. |
멤버십 변경 | 클러스터에 노드를 추가하거나 제거하는 동적인 구성 변경을 안전하게 지원한다. |
ETCD는 계층적 키-값 저장소를 제공한다. 모든 데이터는 바이트 배열 형태의 키와 값의 쌍으로 저장되며, 키 공간은 파일 시스템의 디렉토리 구조와 유사하게 설계되었다. 키는 슬래시(/)로 구분된 경로 형식을 사용하여 논리적인 네임스페이스를 구성한다. 예를 들어, /registry/pods/default/my-pod와 같은 키는 쿠버네티스에서 파드 정보를 저장하는 데 사용될 수 있다. 이 계층적 구조는 키를 그룹화하고 범위 기반 조회를 효율적으로 수행할 수 있게 한다.
저장소의 핵심은 지속적인 리비전 번호를 유지하는 MVCC 모델이다. 모든 쓰기 작업(생성, 수정, 삭제)은 새로운 리비전을 생성하며, 이전 리비전의 데이터는 변경되지 않고 유지된다. 이는 시스템에 강력한 스냅샷 및 감사 추적 기능을 제공한다. 클라이언트는 특정 리비전의 데이터를 일관되게 읽거나, 특정 리비전 이후의 변경 사항만 조회할 수 있다. 데이터는 내부적으로 B-트리 인덱스와 WAL을 결합하여 관리되어 빠른 조회와 데이터 지속성을 보장한다.
키-값 작업은 기본적인 CRUD 연산과 더불어 조건부 연산을 지원한다. 주요 연산은 다음과 같다.
연산 | 설명 |
|---|---|
Put | 키에 값을 설정하거나 업데이트한다. |
Get | 키 또는 키 범위에 대한 값을 조회한다. |
Delete | 키 또는 키 범위를 삭제한다. |
Txn | 여러 연산을 원자성을 보장하며 수행하는 트랜잭션을 제공한다. 트랜잭션 내에서 |
이 구조는 단순하면서도 효율적이어서, 분산 시스템에서 구성 데이터, 메타데이터, 서비스 디스커버리 정보 등을 저장하는 데 이상적이다. 데이터는 기본적으로 메모리에 보관되어 빠른 접근이 가능하며, 주기적으로 스냅샷 파일로 디스크에 지속된다.
와치 메커니즘은 클라이언트가 특정 키 또는 키 범위에 대한 변경 사항을 지속적으로 감시하고 실시간으로 알림을 받을 수 있게 해준다. 클라이언트는 키의 현재 상태를 폴링(polling)하는 대신, etcd 서버에 와치 요청을 생성한다. 이후 해당 키에 쓰기, 삭제 등의 변경이 발생하면 서버는 연결된 클라이언트에게 변경 이벤트를 스트리밍한다. 이는 쿠버네티스의 컨트롤러 루프나 서비스 디스커버리 시스템에서 구성 변경을 즉시 반영하는 데 핵심적인 역할을 한다.
리스 메커니즘은 키에 수명을 부여하는 데 사용된다. 클라이언트는 서버로부터 임대 기간(TTL, Time To Live)을 가진 리스를 생성하고, 해당 리스를 키에 첨부할 수 있다. 리스는 클라이언트가 주기적으로 갱신해야 하며, 갱신되지 않으면 리스가 만료되고 연결된 모든 키가 자동으로 삭제된다. 이는 분산 시스템에서 임시 노드 등록, 세션 관리, 락 획득과 같은 임시적이거나 상태 의존적인 데이터를 처리하는 데 유용하다.
두 메커니즘은 종종 함께 사용되어 강력한 기능을 제공한다. 예를 들어, 서비스 디스커버리 시나리오에서 서비스 인스턴스는 자신의 주소를 키로 등록하며, 해당 키에 짧은 TTL의 리스를 첨부한다. 상태 확인(health check)을 통해 리스를 주기적으로 갱신하며, 인스턴스에 장애가 발생해 갱신이 중단되면 리스가 만료되어 키가 삭제된다. 다른 클라이언트는 해당 서비스 디렉토리 키를 와치하고 있어, 인스턴스의 추가 또는 제거를 실시간으로 감지하고 사용 가능한 인스턴스 목록을 최신 상태로 유지할 수 있다.
와치와 리스의 주요 특성을 정리하면 다음과 같다.
메커니즘 | 주요 목적 | 동작 방식 |
|---|---|---|
와치(Watch) | 변경 사항 감지 | 클라이언트가 지정한 키의 변경 이벤트를 서버가 스트림으로 전송한다. |
리스(Lease) | 키 수명 관리 | TTL이 설정된 임대를 생성하고, 키에 부착하여 갱신 실패 시 자동 삭제를 보장한다. |
설치는 공식 바이너리 릴리스, 패키지 관리자([2]), 또는 도커 컨테이너를 통해 수행할 수 있다. 주요 구성 파일은 YAML 형식으로, 클러스터 구성원 목록, 데이터 디렉토리 위치, 클라이언트 및 피어 간 통신을 위한 네트워크 주소 등을 정의한다.
단일 노드 구성은 개발 또는 테스트 환경에 적합하다. 단일 서버에서 etcd 프로세스를 실행하며, 내결함성이 없다. 클러스터 구성은 일반적으로 홀수 개(3, 5, 7)의 노드로 구성하여 고가용성과 내결함성을 확보한다. 클러스터 구성 시 각 멤버는 고유한 이름, 클라이언트 요청을 받는 listen-client-urls, 다른 멤버와 통신하는 listen-peer-urls, 그리고 초기 클러스터 멤버십을 정의하는 initial-cluster 파라미터가 필요하다.
보안 설정은 운영 환경에서 필수적이다. TLS/SSL을 통한 통신 암호화, 클라이언트 및 피어 인증서 기반 인증을 구성할 수 있다. 역할 기반 접근 제어(RBAC)를 사용하여 특정 키 범위에 대한 읽기/쓰기 권한을 세밀하게 관리한다. 주요 보안 관련 구성 옵션은 다음과 같다.
구성 옵션 | 설명 |
|---|---|
| 서버 TLS 인증서와 키 파일 경로 |
| 클라이언트 인증서 검증 활성화 |
| 신뢰할 수 있는 CA 인증서 파일 경로 |
| 피어 간 통신 자동 TLS 생성 (실험적 기능) |
ETCD는 단일 노드로 실행하거나, 고가용성과 내결함성을 위해 여러 노드로 클러스터를 구성하여 실행할 수 있다. 단일 노드 구성은 개발, 테스트 또는 소규모 환경에서 간편하게 사용하기에 적합하다. 반면, 프로덕션 환경에서는 일반적으로 홀수 개의 노드(예: 3, 5, 7개)로 클러스터를 구성하여 데이터의 안정성과 서비스의 연속성을 보장한다.
클러스터 구성은 정적(Static) 구성 또는 동적 디스커버리 방식을 통해 이루어진다. 정적 구성은 각 멤버의 엔드포인트를 사전에 알고 있을 때 사용하며, 시작 시 --initial-cluster 플래그를 통해 모든 멤버 정보를 명시한다. 동적 디스커버리는 DNS SRV 레코드나 외부 디스커버리 서비스를 활용하여 클러스터를 부트스트랩하는 방식이다. 클러스터의 정족수(Quorum)는 (N/2 + 1)로 계산되며, 3노드 클러스터에서는 2개 노드가 정상이어야 쓰기 작업이 가능하다.
구성 시 주요 고려 사항은 다음과 같다.
구성 요소 | 설명 | 예시/권장값 |
|---|---|---|
노드 이름 | 클러스터 내 각 멤버의 고유 식별자 |
|
데이터 디렉토리 | 키-값 데이터와 워드 로그가 저장되는 경로 |
|
클라이언트 통신 | 클라이언트 요청을 수신하는 주소 |
|
피어 통신 | 클러스터 멤버 간 내부 통신 주소 |
|
초기 클러스터 | 클러스터의 모든 초기 멤버 목록 |
|
초기 클러스터 상태 | 새 클러스터 생성 또는 기존 클러스터 조인 |
|
클러스터를 운영 중에 멤버를 추가하거나 제거하는 작업은 etcdctl member 명령어를 통해 수행할 수 있다. 그러나 클러스터의 안정성을 위해 런타임 중 멤버 수를 자주 변경하는 것은 권장되지 않는다. 네트워크 대역폭, 디스크 I/O 성능, 그리고 노드 간의 지연 시간은 클러스터의 전반적인 성능과 안정성에 직접적인 영향을 미친다.
etcd 클러스터의 보안은 TLS(전송 계층 보안)를 통한 통신 암호화와 클라이언트 인증을 중심으로 구성됩니다. 기본적으로 비보안 모드로 실행되지만, 프로덕션 환경에서는 반드시 보안 설정을 적용해야 합니다. 보안 설정은 피어 간 통신(클러스터 멤버 간)과 클라이언트 간 통신으로 구분되어 적용됩니다.
TLS 설정에는 인증서 파일이 필요합니다. 주로 사용되는 인증서는 CA(인증 기관) 인증서, 서버 인증서, 피어 인증서, 그리고 클라이언트 인증서입니다. 서버/피어 인증서는 --cert-file과 --key-file 파라미터로 지정하며, 신뢰할 수 있는 CA 인증서는 --trusted-ca-file로 지정합니다. 피어 간 통신 암호화를 위해 --peer-cert-file, --peer-key-file, --peer-trusted-ca-file 파라미터를 사용합니다.
인증은 RBAC(역할 기반 접근 제어)을 통해 관리됩니다. etcd는 사용자, 역할, 권한의 개념을 제공합니다. etcdctl 명령어를 사용해 사용자를 생성하고(user add), 역할을 부여할 수 있습니다. 기본적으로 root 사용자는 모든 권한을 가지며, 새로운 사용자에게는 필요한 키 접두사 범위에 대한 읽기(read), 쓰기(write) 권한을 가진 역할을 생성하여 부여합니다. 인증이 활성화되면, 클라이언트는 유효한 사용자 이름과 비밀번호 또는 클라이언트 인증서를 제공해야 API 접근이 가능합니다.
설정 범주 | 주요 구성 요소 | 설명 및 일반적인 파라미터 예시 |
|---|---|---|
통신 암호화 (TLS) | 클라이언트 TLS |
|
피어 간 TLS |
| |
접근 제어 (인증) | 사용자/비밀번호 |
|
역할 및 권한 |
| |
클라이언트 인증서 인증 | TLS 인증서의 CN(Common Name)을 사용자 이름으로 매핑하여 사용 가능 |
보안 설정 적용 후에는 반드시 etcdctl 명령어도 --cacert, --cert, --key 옵션을 사용하거나 ETCDCTL_API=3 etcdctl --endpoints=<endpoints> --cacert=... --cert=... --key=... 형식으로 연결하여야 정상적으로 통신할 수 있습니다.
etcd는 gRPC를 기본 통신 프로토콜로 사용하는 동시에, RESTful HTTP/JSON API도 제공하여 다양한 클라이언트가 접근할 수 있게 한다. 주요 상호작용은 공식 클라이언트 도구인 etcdctl을 통해 이루어지며, gRPC 게이트웨이를 통해 HTTP API로도 동일한 작업을 수행할 수 있다.
etcdctl은 키-값 조작, 클러스터 상태 확인, 멤버 관리 등을 위한 포괄적인 명령어 집합을 제공한다. 주요 명령어 카테고리는 다음과 같다.
카테고리 | 명령어 예시 | 설명 |
|---|---|---|
키-값 작업 |
| 키 |
| 키 | |
| 키 | |
와치(Watch) |
| 키 |
리스(Lease) |
| 60초 동안 유효한 리스를 생성한다. |
| 생성된 리스와 함께 키를 저장한다. | |
클러스터 상태 |
| 클러스터 멤버 목록을 출력한다. |
| 각 엔드포인트의 상태를 확인한다. | |
스냅샷 |
| 현재 데이터의 스냅샷을 파일로 저장한다. |
HTTP API는 /v3/ 접두사를 가진 엔드포인트를 통해 접근한다. 예를 들어, 키-값 저장소는 /v3/kv/range (조회)와 /v3/kv/put (저장) 엔드포인트를 사용한다. etcd는 내부적으로 gRPC를 사용하지만, gRPC 게이트웨이 구성 요소가 자동으로 이 gRPC 서비스를 HTTP/1.1 JSON API로 변환하여 제공한다[3]. 이를 통해 curl과 같은 표준 HTTP 클라이언트로도 기본적인 작업을 수행할 수 있다. API 응답은 성공 여부를 나타내는 header와 실제 데이터를 담은 응답 본문으로 구조화되어 있다.
etcdctl은 etcd 클러스터와 상호작용하기 위한 공식 명령줄 클라이언트 도구이다. 이 도구는 클러스터 상태 확인, 키-값 조작, 클러스터 구성 관리 등 일상적인 운영 작업을 수행하는 데 사용된다. etcdctl은 v2 API와 v3 API를 모두 지원하지만, 현대적인 배포에서는 v3 API를 기본으로 사용한다.
주요 명령어는 키-값 저장소 조작, 클러스터 상태 관리, 스냅샷 작업으로 분류할 수 있다. 키-값 조작을 위한 기본 명령어는 다음과 같다.
명령어 | 설명 |
|---|---|
| 지정된 키에 값을 설정하거나 업데이트한다. |
| 지정된 키에 저장된 값을 조회한다. |
| 지정된 키를 삭제한다. |
| 지정된 키 또는 키 범위의 변경 사항을 실시간으로 감시한다. |
클러스터의 상태를 확인하고 구성원을 관리하는 명령어도 제공된다. etcdctl endpoint status는 클러스터 내 각 엔드포인트의 상태, 리더 정보, 데이터베이스 크기 등을 요약하여 보여준다. etcdctl member list는 클러스터에 속한 모든 멤버의 ID, 이름, 클라이언트 URL, 피어 URL 목록을 출력한다. 클러스터의 상태가 정상인지 확인하려면 etcdctl endpoint health 명령을 사용한다.
운영 및 유지보수를 위해 스냅샷 생성과 복원 기능이 중요하다. etcdctl snapshot save <파일경로> 명령어를 실행하면 현재의 etcd 데이터베이스 상태를 파일로 백업할 수 있다. 반대로, 장애 복구 시에는 etcdctl snapshot restore <파일경로> 명령어로 백업된 스냅샷 파일에서 새 클러스터를 초기화한다. 이러한 명령어를 사용할 때는 반드시 --endpoints 옵션으로 클러스터의 접속 주소를 명시해야 하며, 보안이 설정된 환경에서는 --cacert, --cert, --key 옵션을 통해 TLS 인증서 정보를 제공해야 한다.
etcd는 기본적으로 고성능 gRPC API를 통해 클라이언트와 통신한다. 또한, RESTful HTTP/JSON API에 대한 접근성을 제공하기 위해 내장된 gRPC 게이트웨이를 포함한다. 이 게이트웨이는 gRPC 서비스를 HTTP 요청으로 변환하여 처리한다.
주요 HTTP API 엔드포인트는 /v3/ 접두사를 사용한다. 키-값 작업을 위한 핵심 엔드포인트는 다음과 같다.
HTTP 메서드 | 경로 | 설명 |
|---|---|---|
POST | /v3/kv/range | 키 범위 조회 (읽기) |
POST | /v3/kv/put | 키에 값 쓰기 |
POST | /v3/kv/deleterange | 키 범위 삭제 |
POST | /v3/watch | 키 변경 사항 감시 (와치) |
예를 들어, 키 foo에 값 bar를 쓰려면 PUT 요청 대신 POST /v3/kv/put 엔드포인트에 {"key": "Zm9v", "value": "YmFy"}와 같은 JSON 본문을 전송한다. 여기서 키와 값은 Base64로 인코딩되어야 한다. 성공적인 응답은 {"header":{"revision":"2"}}와 같은 형태를 가진다.
gRPC 게이트웨이는 기본적으로 클라이언트 gRPC 포트(2379)와 동일한 포트에서 HTTP 요청을 수신한다. 이는 etcd --enable-grpc-gateway 플래그로 제어할 수 있다[4]. 따라서 curl이나 wget 같은 표준 HTTP 클라이언트 도구를 사용하여 etcd 클러스터와 상호작용하는 것이 가능해진다. 그러나 대부분의 프로덕션 환경에서는 낮은 지연 시간과 높은 처리량을 위해 네이티브 gRPC 클라이언트 라이브러리를 사용하는 것이 권장된다.
운영 중에는 정기적인 백업이 필수적이다. etcdctl snapshot save 명령어를 사용해 특정 시점의 키-값 저장소 상태를 스냅샷 파일로 저장할 수 있다. 백업 파일은 안전한 외부 저장소에 보관해야 한다. 복구는 etcdctl snapshot restore 명령어로 수행하며, 이 과정에서 새로운 클러스터 데이터 디렉토리가 생성된다. 복구 후에는 클러스터를 재구성하고 멤버를 다시 추가해야 한다.
성능 튜닝은 디스크 I/O와 네트워크 지연 시간에 크게 영향을 받는다. SSD 사용이 권장되며, --quota-backend-bytes 파라미터로 저장소 크기 할당량을 설정해 데이터베이스 크기 폭증을 방지할 수 있다. 주요 모니터링 지표는 다음과 같다.
지표 카테고리 | 주요 지표 | 설명 |
|---|---|---|
리더 및 합의 |
| 리더 변경 횟수. 빈번한 변경은 불안정함을 의미한다. |
저장소 |
| 백엔드 데이터베이스의 실제 크기. |
요청 성능 |
| 클라이언트 요청 처리 지연 시간. |
네트워크 |
| 클라이언트로부터 수신한 총 바이트 수. |
클러스터 멤버 관리는 etcdctl member 명령어 세트로 수행한다. 새로운 멤버 추가, 기존 멤버 제거, 멤버 목록 조회가 가능하다. 멤버를 제거할 때는 해당 멤버의 프로세스를 먼저 중지한 후 클러스터에서 제거 명령을 실행해야 한다. 클러스터의 피어 URL이 변경될 경우에는 etcdctl member update 명령으로 모든 멤버의 클라이언트 및 피어 통신 주소를 업데이트한다.
ETCD 클러스터의 데이터는 시스템 구성의 단일 진실 공급원 역할을 하므로 정기적인 백업은 재해 복구 계획의 필수 요소이다. 백업은 주로 두 가지 방식으로 수행된다. 첫째는 키-값 저장소의 전체 스냅샷을 파일로 생성하는 것이고, 둘째는 특정 시점 이후의 변경 내역만을 순차적으로 기록하는 증분 백업 방식이다. etcdctl snapshot save 명령어를 사용하면 현재 클러스터 상태의 스냅샷을 로컬 파일에 저장할 수 있다. 이 명령은 리더 노드에서 실행되어야 하며, 백업 과정에서 클러스터 성능에 일시적인 영향을 미칠 수 있다. 생성된 스냅샷 파일은 안전한 오프사이트 저장소에 보관해야 한다.
복구 작업은 주로 클러스터 전체가 실패했거나 데이터가 손상된 경우에 수행된다. 복구를 위해서는 먼저 모든 ETCD 멤버 프로세스를 중지하고 기존 데이터 디렉토리를 제거해야 한다. 그 후, etcdctl snapshot restore 명령어를 사용하여 백업된 스냅샷 파일로부터 새로운 클러스터를 부트스트랩한다. 이 명령은 스냅샷으로부터 새로운 데이터 디렉토리를 생성하고, 복구 후 사용할 새로운 클러스터 구성을 함께 지정해야 한다. 복구 후에는 클러스터의 정상 작동과 데이터 무결성을 반드시 검증해야 한다.
운영 모범 사례로는 백업 일정을 자동화하고, 백업 파일의 암호화 및 무결성 검사를 실시하며, 정기적인 복구 훈련을 통해 백업의 유효성을 확인하는 것이 포함된다. 특히 쿠버네티스와 같은 시스템에서 ETCD를 사용할 경우, 쿠버네티스 리소스의 선언적 상태를 완벽하게 복원하기 위해서는 ETCD 스냅샷과 함께 쿠버네티스 정적 파드 매니페스트 등의 구성 파일도 함께 백업해야 한다.
성능 튜닝은 etcd 클러스터의 안정성과 응답 속도를 보장하기 위한 핵심 작업이다. 주요 튜닝 요소는 디스크 I/O 성능, 네트워크 지연 시간, 그리고 적절한 하드웨어 스펙 선택이다. SSD 사용은 필수적이며, 네트워크 대역폭과 지연 시간을 최소화하는 구성이 중요하다. 또한, 클라이언트 요청 부하를 분산시키기 위해 적절한 리더 선출 시간과 하트비트 간격을 설정해야 한다. 메모리 할당량과 데이터베이스 크기 제한을 관리하여 장기적으로 성능 저하를 방지한다.
모니터링은 클러스터의 건강 상태를 지속적으로 확인하는 과정이다. etcd는 /metrics 엔드포인트를 통해 풍부한 지표를 제공한다. 핵심 모니터링 지표는 다음과 같이 분류할 수 있다.
지표 카테고리 | 주요 지표 예시 | 설명 |
|---|---|---|
리더 및 합의 |
| 리더 변경 횟수. 빈번한 변경은 불안정성을 의미한다. |
| 커밋된 제안(proposal) 수. 클러스터 쓰기 처리량을 나타낸다. | |
요청 처리 |
| 범위 조회(range read) 요청 수. |
| 쓰기(put) 요청 수. | |
| gRPC 요청 처리 수 및 상태 코드. | |
저장소 및 디스크 |
| WAL 로그 동기화(fsync) 지연 시간 히스토그램. 디스크 성능을 직접 반영한다. |
| 백엔드 데이터베이스의 총 크기. | |
네트워크 |
| 클라이언트로부터 수신한 gRPC 트래픽 양. |
이러한 지표를 기반으로 프로메테우스와 그라파나 같은 도구를 활용하여 대시보드를 구성하고, 특정 임계값을 초과할 경우 알람을 설정하는 것이 일반적이다. 예를 들어, WAL 동기화 지연 시간이 급격히 증가하면 디스크 병목 현상을 의심해야 한다. 또한, 리더 변경 횟수가 증가하거나 미처리된 제안(etcd_server_proposals_pending) 수가 지속적으로 높다면 네트워크 분할이나 노드 과부하를 조사해야 한다. 정기적인 지표 분석을 통해 잠재적인 문제를 사전에 예측하고 대응할 수 있다.
클러스터 멤버 관리는 etcd 클러스터의 구성원을 동적으로 추가, 제거 또는 업데이트하는 작업을 포함한다. 이는 클러스터의 가용성과 내결함성을 유지하는 데 필수적이다. 멤버 관리는 주로 etcdctl member 명령어 세트나 etcd의 관리 API를 통해 수행된다.
멤버 추가는 새로운 etcd 노드를 기존 클러스터에 합류시키는 과정이다. 일반적으로 etcdctl member add 명령을 사용하며, 새 멤버의 이름과 피어 통신 URL을 지정해야 한다. 명령 실행 후, 출력되는 초기 클러스터 구성 정보를 바탕으로 새 노드를 시작해야 정상적으로 클러스터에 참여한다. 멤버 제거는 etcdctl member remove 명령과 멤버 ID를 사용하여 수행된다. 제거된 멤버는 클러스터 합의 과정에서 더 이상 고려되지 않는다.
작업 | 주요 명령어 예시 | 비고 |
|---|---|---|
멤버 목록 조회 |
| 클러스터의 모든 멤버 ID, 이름, 상태, 클라이언트 URL을 표시한다. |
멤버 추가 |
| 새 멤버를 추가한다. 출력된 환경 변수를 새 노드 시작 시 사용해야 한다. |
멤버 제거 |
| 지정된 ID의 멤버를 클러스터에서 영구히 제거한다. |
멤버 정보 업데이트 |
| 기존 멤버의 피어 통신 URL을 변경한다. |
멤버의 피어 URL 변경이나 리더 선출 과정에서의 문제 해결도 관리 범주에 속한다. 클러스터가 정상적인 쿼럼을 유지하지 못하는 상황에서는 특수한 복구 절차가 필요할 수 있다. 모든 멤버 관리 작업은 클러스터의 안정성을 해치지 않도록 신중하게 수행해야 하며, 운영 중인 시스템에서는 한 번에 하나의 멤버만 변경하는 것이 권장된다.
ETCD는 분산 시스템에서 신뢰할 수 있는 키-값 저장소를 제공하는 데 특화되어 있으며, 그 강력한 일관성과 고가용성 덕분에 여러 핵심적인 사용 사례에서 표준적인 솔루션으로 자리 잡았다. 가장 대표적인 사례는 쿠버네티스의 백본 저장소 역할이다. 쿠버네티스 클러스터의 모든 구성 데이터, 예를 들어 파드, 서비스, 시크릿의 상태 정보, 그리고 클러스터 자체의 구성과 멤버십 정보를 저장한다. ETCD는 Raft 합의 알고리즘을 통해 이러한 중요한 데이터에 대한 강한 일관성을 보장하여, 쿠버네티스 컨트롤 플레인 컴포넌트들이 항상 동일한 클러스터 상태를 바라보고 결정을 내릴 수 있게 한다.
또 다른 주요 사용 사례는 서비스 디스커버리이다. 애플리케이션 서비스는 자신의 네트워크 위치(예: IP 주소와 포트)를 ETCD에 키로 등록할 수 있다. 클라이언트나 다른 서비스는 해당 키를 조회하거나 와치(Watch) 메커니즘을 통해 변경 사항을 실시간으로 감지하여 최신의 서비스 엔드포인트 정보를 얻을 수 있다. 이는 마이크로서비스 아키텍처에서 서비스 인스턴스의 동적 생성과 소멸에 유연하게 대응하는 데 필수적이다.
마지막으로, ETCD는 일반적인 분산 시스템 코디네이터로서의 역할도 수행한다. 분산 락, 리더 선출, 구성 관리, 분산 큐와 같은 코디네이션 작업을 구현하는 데 사용될 수 있다. 예를 들어, 리스(Lease) 메커니즘을 활용하면 특정 키에 임대 시간을 부여하여 분산 락을 구현하거나, 노드의 활성 상태를 확인하는 데 활용할 수 있다. 이러한 기능들은 복잡한 분산 애플리케이션을 구축할 때 공통적으로 필요한 패턴들을 안정적으로 제공한다.
쿠버네티스 클러스터의 모든 구성 데이터는 etcd에 중앙 집중식으로 저장된다. 이 데이터에는 클러스터 상태, 파드, 서비스, 디플로이먼트, 시크릿, 컨피그맵 등의 모든 API 오브젝트 정의가 포함된다. 쿠버네티스 API 서버는 유일하게 etcd와 직접 통신하는 컴포넌트이며, 다른 모든 컴포넌트(예: kubelet, 컨트롤러 매니저, 스케줄러)는 API 서버를 통해 etcd에 저장된 데이터를 간접적으로 조회하거나 변경한다. 이 구조는 etcd를 쿠버네티스의 "단일 진실 공급원"으로 만든다.
etcd는 쿠버네티스의 핵심 기능인 선언적 상태 관리와 자가 치유 능력을 뒷받침한다. 컨트롤러는 etcd에 저장된 오브젝트의 현재 상태(Actual State)를 지속적으로 관찰하고, 사용자가 정의한 원하는 상태(Desired State)와 비교한다. 두 상태가 불일치하면 컨트롤러는 조정 루프를 통해 실제 상태를 원하는 상태로 수렴시키기 위한 작업을 시작한다. 이 모든 과정의 기반은 etcd에 저장된 정확하고 일관된 상태 정보이다.
쿠버네티스가 etcd에 의존하는 주요 이유는 다음과 같다.
* 강력한 일관성: Raft 합의 알고리즘을 통해 제공하는 강한 일관성은 분산된 다수의 컨트롤러가 동일한 데이터를 바라보고 조정 작업을 수행할 수 있는 토대를 마련한다.
* 와치(Watch) 메커니즘: 쿠버네티스 API 서버와 컨트롤러는 etcd의 와치 기능을 활용해 특정 키나 디렉터리의 변경 사항을 실시간으로 구독한다. 이를 통해 폴링 방식보다 효율적으로 상태 변화에 반응할 수 있다.
* 고가용성: 클러스터 모드로 구성된 etcd는 장애 허용성을 제공하여 쿠버네티스 마스터 노드의 핵심 데이터 저장소로서의 신뢰성을 보장한다.
따라서 etcd 클러스터의 성능, 안정성 및 보안은 전체 쿠버네티스 클러스터의 건강 상태에 직접적인 영향을 미친다. etcd의 성능 저하나 데이터 손실은 쿠버네티스의 API 운영, 스케줄링, 배포 등 모든 기능의 중단으로 이어질 수 있다.
ETCD는 Raft 합의 알고리즘을 기반으로 한 강력한 일관성을 제공하는 분산 키-값 저장소로서, 서비스 디스커버리 시스템의 핵심 구성 요소로 널리 사용된다. 서비스 디스커버리는 마이크로서비스나 분산 애플리케이션 환경에서 서비스 인스턴스의 네트워크 위치(IP 주소와 포트)를 동적으로 등록하고 조회할 수 있는 메커니즘을 의미한다. etcd는 이 메커니즘을 구현하기 위해 필요한 안정적인 저장소와 실시간 변경 알림 기능을 제공한다.
서비스 디스커버리 패턴은 일반적으로 서비스 등록(Service Registration)과 서비스 조회(Service Discovery) 두 단계로 구성된다. 서비스 인스턴스는 시작 시 자신의 메타데이터(예: 서비스명, 주소, 상태)를 etcd에 특정 키(예: /registry/services/{service-name}/{instance-id})로 저장하여 등록한다. 클라이언트나 다른 서비스는 etcd에서 해당 서비스명의 키 디렉토리를 조회(GET)하여 현재 사용 가능한 모든 인스턴스 목록을 가져올 수 있다. etcd의 중요한 특징은 와치(Watch) 메커니즘으로, 클라이언트는 특정 키 또는 디렉토리에 대한 변경 사항을 구독할 수 있다. 서비스 인스턴스가 등록되거나 제거될 때 etcd는 이를 실시간으로 감지하고 구독자에게 알림을 보내므로, 클라이언트는 항상 최신의 서비스 인스턴스 목록을 유지할 수 있다.
이를 구현하는 일반적인 방법은 다음과 같다.
구성 요소 | 역할 | etcd 활용 방식 |
|---|---|---|
서비스 인스턴스 | 자신을 등록하고 주기적으로 신호를 보냄 | 시작 시 키를 생성(PUT). 리스(Lease)를 연결하여 TTL(Time-To-Live) 설정. 주기적으로 리스 갱신으로 건강 상태 표시. |
서비스 레지스트리 | 서비스 정보 저장소 (etcd 자체가 이 역할 수행) | 모든 서비스 등록 정보를 키-값 형태로 저장. |
서비스 디스커버리 클라이언트 | 사용 가능한 서비스 인스턴스를 찾음 | 특정 접두사(예: |
서비스 인스턴스는 리스(Lease)를 활용하여 건강 상태를 관리한다. 인스턴스는 etcd와 임대 계약을 맺고, 해당 임대가 연결된 키를 생성한다. 인스턴스가 정상적이라면 주기적으로 이 임대를 갱신한다. 만약 인스턴스에 장애가 발생하여 임대 갱신이 중단되면, 임대가 만료되고 etcd는 자동으로 연결된 키를 삭제한다. 이는 장애가 발생한 서비스 인스턴스가 레지스트리에서 자동으로 제거되는 것을 보장하여, 클라이언트가 죽은 인스턴스로 요청을 보내는 상황을 방지한다.
결과적으로, etcd를 기반으로 한 서비스 디스커버리는 시스템에 높은 가용성과 강한 일관성을 부여한다. 모든 서비스 정보가 중앙 집중식으로 관리되지 않고 분산된 etcd 클러스터에 안전하게 저장되며, 변경 사항이 실시간으로 전파된다. 이는 쿠버네티스가 파드와 서비스의 정보를 관리하는 방식의 근간이 되기도 한다.
ETCD는 분산 시스템에서 여러 노드 간의 상태 정보를 일관되게 유지하고 조정하는 코디네이터 역할을 수행한다. 이는 고가용성과 데이터 일관성이 요구되는 환경에서 시스템의 구성, 설정, 서비스 위치 정보, 락 관리, 리더 선출 등의 작업을 중앙에서 관리할 수 있는 기반을 제공한다. Raft 합의 알고리즘을 통해 클러스터 내 모든 노드가 동일한 데이터 뷰를 유지하도록 보장하며, 이는 코디네이터로서의 핵심 기능을 가능하게 한다.
주요 조정 기능으로는 분산 락, 리더 선출, 그리고 서비스 구성 관리가 있다. 애플리케이션은 ETCD의 리스(Lease) 메커니즘을 활용하여 특정 키에 임대 시간을 부여한 후, 해당 키를 소유함으로써 분산 락을 구현하거나 리더 역할을 주장할 수 있다. 또한, 시스템의 동적 구성 값(예: 데이터베이스 연결 문자열, 기능 플래그)을 키-값 쌍으로 저장하고, 와치(Watch) 메커니즘을 통해 구성 변경을 실시간으로 감지하여 모든 서비스 인스턴스에 즉시 적용할 수 있다.
다음은 ETCD가 코디네이터로서 처리하는 일반적인 작업과 그 구현 방식을 보여주는 표이다.
작업 | 설명 | ETCD에서의 구현 방식 |
|---|---|---|
분산 락 | 여러 프로세스가 공유 자원에 대한 배타적 접근을 조정한다. | 특정 키를 생성(Compare-and-Swap 연산)하고 리스를 연결하여 임대 기간 동안 락을 유지한다. |
리더 선출 | 클러스터 내에서 하나의 노드를 마스터 또는 리더로 선출한다. |
|
구성 관리 | 분산 애플리케이션의 설정을 중앙에서 저장하고 배포한다. | 구성 값을 키(예: |
서비스 레지스트리 | 사용 가능한 서비스 인스턴스와 그 네트워크 위치를 등록한다. | 각 서비스 인스턴스는 자신의 정보를 키(예: |
이러한 코디네이션 기능은 시스템의 복잡성을 숨기고 개발자에게 단순화된 추상화를 제공한다. 결과적으로 ETCD는 마이크로서비스 아키텍처, 컨테이너 오케스트레이션 플랫폼, 그리고 기타 분산 애플리케이션에서 신뢰할 수 있는 중앙 조정 허브 역할을 한다.
ETCD는 강력한 일관성과 신뢰성을 제공하는 분산 키-값 저장소이지만, 특정 사용 사례에 따라 고려해야 할 장점과 단점이 존재한다. 또한 Consul이나 Apache ZooKeeper와 같은 다른 분산 코디네이터와의 비교를 통해 적합한 도구를 선택할 수 있다.
ETCD의 주요 장점은 Raft 합의 알고리즘을 통해 달성하는 강한 일관성과 높은 가용성이다. 이는 쿠버네티스와 같은 시스템에서 구성 데이터와 같은 중요한 정보를 저장하는 데 필수적이다. 또한 비교적 단순한 키-값 저장소 모델과 직관적인 gRPC 및 HTTP API를 제공하여 사용과 통합이 용이하다. 성능 면에서도 쓰기 성능이 우수하며, 와치(Watch) 메커니즘을 통한 효율적인 변경 알림 기능을 갖추고 있다.
반면, 단점으로는 내장된 서비스 디스커버리 기능이 Consul에 비해 제한적이라는 점을 들 수 있다. 건강 검사(Health Check)나 다중 데이터센터 지원과 같은 고급 기능이 기본적으로 포함되어 있지 않다. 또한, 모든 데이터가 메모리에 저장되도록 설계되어 매우 큰 데이터셋을 처리하는 데는 적합하지 않을 수 있다. 운영 복잡성도 고려해야 하는데, 클러스터의 정기적인 유지 관리와 모니터링이 필요하며, 특히 클러스터 멤버를 변경할 때 주의가 요구된다.
다른 분산 코디네이터와의 비교는 다음과 같다.
도구 | 주요 강점 | 주요 약점 | 적합한 사용 사례 |
|---|---|---|---|
ETCD | 강한 일관성, 높은 쓰기 성능, 쿠버네티스와의 긴밀한 통합 | 대용량 데이터 저장 부적합, 서비스 디스커버리 기능 기본 한계 | 구성 관리, 분산 시스템 코디네이션, 쿠버네티스 |
강력한 내장 서비스 디스커버리, 건강 검사, 다중 데이터센터 지원 | 쓰기 성능이 ETCD에 비해 상대적으로 낮을 수 있음 | 서비스 메시, 다중 클라우드/데이터센터 서비스 디스커버리 | |
매우 안정적이고 검증됨, 풍부한 원시 기능(순차 노드, 임시 노드) | 관리 및 운영이 복잡함, 쓰기 처리량 제한 | Apache Kafka, Apache Hadoop과 같은 중앙 코디네이터가 필요한 대규모 분산 애플리케이션 |
결론적으로, ETCD는 강한 일관성이 가장 중요한 구성 저장소나 시스템 코디네이션에 최적화되어 있다. 반면, 서비스 디스커버리에 더 중점을 두고 있거나 다중 지역 배포가 필요한 경우에는 Consul이 더 나은 선택일 수 있다. ZooKeeper는 오랜 기간 검증된 솔루션이 필요하고, 그 복잡한 운영을 감당할 수 있는 환경에서 고려된다.
ETCD는 분산 시스템에서 구성 정보 저장과 서비스 디스커버리를 위한 키-값 저장소로 널리 사용되지만, Consul과 Apache ZooKeeper와 같은 다른 유명한 솔루션들과 비교했을 때 뚜렷한 차이점과 장단점을 가진다. 주로 Raft 합의 알고리즘을 사용하는 점은 Consul과 공통점이 있으나, 설계 목표와 제공하는 기능 면에서 차이가 있다.
아래 표는 세 시스템의 주요 특징을 비교한 것이다.
특성 | ETCD | Consul | ZooKeeper |
|---|---|---|---|
주요 사용 사례 | 구성 저장, 서비스 디스커버리 | 서비스 디스커버리, 구성 저장, 네트워크 세분화 | 구성 관리, 분산 코디네이션 |
합의 알고리즘 | Raft | ||
데이터 모델 | 계층적 키-값 저장소 | 키-값 저장소, 서비스 카탈로그 | 계층적 노드(znode) |
내장 서비스 디스커버리 | 간접적 지원 (와치 메커니즘 기반) | 직접적이고 강력한 지원 (헬스 체크 포함) | 직접 지원하지 않음 (애플리케이션 레벨 구현 필요) |
멀티 데이터센터 지원 | 제한적 | 강력한 네이티브 지원 | 제한적 |
통신 프로토콜 | gRPC (주력), HTTP/JSON 게이트웨이 | HTTP/JSON, DNS | 자체 바이너리 프로토콜 |
운영 복잡도 | 비교적 낮음 | 중간 | 비교적 높음[5] |
보안 | TLS, 역할 기반 접근 제어(RBAC) | TLS, ACL, 네트워크 세분화 | Kerberos, ACL |
쿠버네티스의 핵심 구성 요소로 채택되면서 ETCD는 단순성과 높은 일관성, 뛰어난 읽기/쓰기 성능에 최적화되었다. 이는 복잡한 분산 코디네이션 프리미티브보다는 신뢰할 수 있는 키-값 저장에 초점을 맞춘 결과이다. 반면 Consul은 서비스 디스커버리, 상태 확인, 멀티 데이터센터 연결을 일급 기능으로 제공하여 마이크로서비스 아키텍처에 더 포괄적인 솔루션을 제시한다. Apache ZooKeeper는 분산 락이나 리더 선출 같은 정교한 코디네이션 프리미티브를 제공하는 데 역사적으로 강점을 보였으나, 운영 및 튜닝이 상대적으로 복잡한 편이다.
선택은 사용 사례에 따라 달라진다. 쿠버네티스와 같은 클라우드 네이티브 스택의 핵심 저장소나 단순하고 고성능의 일관된 저장소가 필요하면 ETCD가 적합하다. 포괄적인 서비스 메시와 멀티 데이터센터 지원이 필요한 마이크로서비스 환경에서는 Consul이 더 나은 선택일 수 있다. 반면, 아파치 카프카나 아파치 하두프와 같이 ZooKeeper에 깊이 의존하는 기존 분산 애플리케이션 생태계를 유지해야 하는 경우에는 ZooKeeper가 여전히 표준이다.