1. 개요
etcd를 Ubuntu bionic 환경에 설치하고, 기본 동작 확인부터 간단한 key-value 저장/조회, 그리고 두 대의 서버로 클러스터를 구성하는 과정까지 정리한다. 이 글의 예시는 Ubuntu 패키지 저장소에서 설치되는 etcd 3.2.17 기준이며, etcdctl의 기본 API 버전이 2로 동작하는 환경이다.
2. 설치
sudo apt install etcd로 설치한다. 이 패키지는 서버와 클라이언트 도구를 함께 설치한다.
$ sudo apt install etcd Get:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic/universe amd64 pipexec amd64 2.5.5-1 [16.8 kB] Get:2 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic/universe amd64 etcd-client amd64 3.2.17+dfsg-1 [8137 kB] Get:3 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic/universe amd64 etcd-server amd64 3.2.17+dfsg-1 [4285 kB] Get:4 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu bionic/universe amd64 etcd all 3.2.17+dfsg-1 [2516 B] Fetched 12.4 MB in 2s (5531 kB/s) Selecting previously unselected package pipexec. (Reading database ... 84333 files and directories currently installed.) Preparing to unpack .../pipexec_2.5.5-1_amd64.deb ... Unpacking pipexec (2.5.5-1) ... Selecting previously unselected package etcd-client. Preparing to unpack .../etcd-client_3.2.17+dfsg-1_amd64.deb ... Unpacking etcd-client (3.2.17+dfsg-1) ... Selecting previously unselected package etcd-server. Preparing to unpack .../etcd-server_3.2.17+dfsg-1_amd64.deb ... Unpacking etcd-server (3.2.17+dfsg-1) ... Selecting previously unselected package etcd. Preparing to unpack .../etcd_3.2.17+dfsg-1_all.deb ... Unpacking etcd (3.2.17+dfsg-1) ... Processing triggers for ureadahead (0.100.0-21) ... Setting up pipexec (2.5.5-1) ... Setting up etcd-client (3.2.17+dfsg-1) ... Processing triggers for systemd (237-3ubuntu10.29) ... Processing triggers for man-db (2.8.3-2ubuntu0.1) ... Setting up etcd-server (3.2.17+dfsg-1) ... Adding system user `etcd' (UID 111) ... Adding new group `etcd' (GID 116) ... Adding new user `etcd' (UID 111) with group `etcd' ... Creating home directory `/var/lib/etcd/' ... Setting up etcd (3.2.17+dfsg-1) ... Processing triggers for systemd (237-3ubuntu10.29) ... Processing triggers for ureadahead (0.100.0-21) ...
3. 버전 확인
설치 후 etcdctl 버전을 확인한다. 아래 출력처럼 API version이 2로 표시되면 이후 예제의 set, get, cluster-health 명령을 그대로 사용할 수 있다.
$ etcdctl --version etcdctl version: 3.2.17 API version: 2
4. 프로세스 확인
설치가 끝나면 systemd에 의해 etcd 서버 프로세스가 실행된다.
$ ps -ef | grep etcd etcd 19854 1 0 14:00 ? 00:00:01 /usr/bin/etcd ubuntu 20034 19562 0 14:10 pts/0 00:00:00 grep --color=auto etcd
5. 포트 확인
기본 설정에서는 클라이언트 접속 포트인 2379가 로컬 주소(127.0.0.1)에서 대기한다.
$ sudo netstat -anp | grep 2379 tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 19854/etcd tcp 0 0 127.0.0.1:53088 127.0.0.1:2379 TIME_WAIT - tcp 0 0 127.0.0.1:53076 127.0.0.1:2379 ESTABLISHED 19854/etcd tcp 0 0 127.0.0.1:2379 127.0.0.1:53076 ESTABLISHED 19854/etcd
$ ps -ef | grep 19854 etcd 19854 1 0 14:00 ? 00:00:02 /usr/bin/etcd ubuntu 20087 19562 0 14:16 pts/0 00:00:00 grep --color=auto 19854
6. curl을 통한 모니터링
etcd는 HTTP API를 제공하므로 curl로도 기본 상태를 확인할 수 있다.
$ curl -L http://127.0.0.1:2379/version
{"etcdserver":"3.2.17","etcdcluster":"3.2.0"}
$ curl -L http://127.0.0.1:2379/health
{"health": "true"}
7. 이리저리 데이터 넣었다 빼기
간단한 key-value 데이터를 넣고 다시 조회해 본다. 먼저 etcdctl로 값을 저장한다.
$ etcdctl set name stdio stdio
$ etcdctl get name stdio
$ etcdctl set name helloworld helloworld
$ etcdctl get name helloworld
같은 데이터는 HTTP API로도 조회할 수 있다. 여기서는 보기 좋게 출력하기 위해 json_pp를 사용했다.
$ curl http://127.0.0.1:2379/v2/keys/name | json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 96 100 96 0 0 19200 0 --:--:-- --:--:-- --:--:-- 19200
{
"node" : {
"createdIndex" : 6,
"key" : "/name",
"modifiedIndex" : 6,
"value" : "helloworld"
},
"action" : "get"
}
이번에는 curl로 값을 변경하고, 다시 etcdctl과 HTTP API로 확인한다.
$ curl -L http://127.0.0.1:2379/v2/keys/name -XPUT -d value="sarc"
{"action":"set","node":{"key":"/name","value":"sarc","modifiedIndex":7,"createdIndex":7},"prevNode":{"key":"/name","value":"helloworld","modifiedIndex":6,"createdIndex":6}}
$ etcdctl get name sarc
$ curl http://127.0.0.1:2379/v2/keys/name | json_pp
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 90 100 90 0 0 90000 0 --:--:-- --:--:-- --:--:-- 90000
{
"action" : "get",
"node" : {
"modifiedIndex" : 7,
"key" : "/name",
"value" : "sarc",
"createdIndex" : 7
}
}
8. 클러스터 상태 확인
지금은 단일 노드에 설치한 것이라 클러스터를 봐도 큰 의미는 없다. 그래도 멤버와 헬스 체크 명령이 어떻게 보이는지 확인해 둔다.
$ etcdctl cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379 cluster is healthy
$ etcdctl member list 8e9e05c52164694d: name=ip-172-31-37-200 peerURLs=http://localhost:2380 clientURLs=http://localhost:2379 isLeader=true
일단 etcd 설정 파일이 /etc/default/etcd라는 것만 알아두자.
9. 이중화
etcd를 설치한 서버를 동일하게 복제하여 #2번 서버를 생성하였다. 그래서 다음과 같은 환경이 구성되었다.
- #1 서버: 172.31.37.200
- #2 서버: 172.31.33.222
주의: etcd는 과반수(quorum)가 살아 있어야 정상적으로 동작한다. 따라서 2대 구성은 한 대가 장애 나면 과반수를 만족하지 못해 실질적인 고가용성 구성이라고 보기 어렵다. 운영 환경에서 장애 허용을 목표로 한다면 보통 홀수 개의 멤버로 구성하는 편이 좋다. 여기서는 설정 방법을 확인하기 위한 예제로만 본다.
9.1. 설정 파일 수정
현재는 #1, #2 서버 모두 기본 etcd 설정(/etc/default/etcd)을 사용 중인 상태이다. 두 서버의 설정을 이렇게 수정한다.
< #1번 서버 >
ETCD_NAME="etcd-01" ETCD_DATA_DIR="/var/lib/etcd" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01" ETCD_INITIAL_CLUSTER="etcd-01=http://172.31.37.200:2380,etcd-02=http://172.31.33.222:2380" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.31.37.200:2380" ETCD_ADVERTISE_CLIENT_URLS="http://172.31.37.200:2379" ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" ETCD_LISTEN_CLIENT_URLS="http://172.31.37.200:2379,http://127.0.0.1:2379"
< #2번 서버 >
ETCD_NAME="etcd-02" ETCD_DATA_DIR="/var/lib/etcd" ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-01" ETCD_INITIAL_CLUSTER="etcd-01=http://172.31.37.200:2380,etcd-02=http://172.31.33.222:2380" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://172.31.33.222:2380" ETCD_ADVERTISE_CLIENT_URLS="http://172.31.33.222:2379" ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380" ETCD_LISTEN_CLIENT_URLS="http://172.31.33.222:2379,http://127.0.0.1:2379"
두 서버가 서로 통신해야 하므로 peer 포트인 2380과 client 포트인 2379가 방화벽이나 보안 그룹에서 막혀 있지 않은지도 함께 확인한다.
9.2. 각각 서비스 재기동
설정 파일을 수정한 뒤 두 서버에서 etcd 서비스를 재기동한다. 기존 단일 노드 데이터가 남아 있으면 새 클러스터 설정과 충돌할 수 있으므로, 테스트 환경이라면 데이터 디렉터리를 비우고 시작하는 것도 확인 대상이다. 단, 운영 데이터가 있는 환경에서는 삭제하면 안 된다.
$ sudo systemctl restart etcd $ sudo systemctl status etcd
9.3. 확인
재기동 후 멤버 목록을 조회하면 두 노드가 보인다.
$ etcdctl member list 8d70aeafa0bed77e: name=etcd-02 peerURLs=http://172.31.33.222:2380 clientURLs=http://172.31.33.222:2379 isLeader=false d81a31603e6f8367: name=etcd-01 peerURLs=http://172.31.37.200:2380 clientURLs=http://172.31.37.200:2379 isLeader=true
한쪽 노드에서 값을 저장한 뒤 다른 노드의 client URL로 조회해 보면 클러스터 동기화가 되는지도 간단히 확인할 수 있다.
$ etcdctl --endpoints=http://172.31.37.200:2379 set name cluster-test cluster-test $ etcdctl --endpoints=http://172.31.33.222:2379 get name cluster-test