웹사이트 검색

CoreOS의 분산 키-값 저장소인 Etcdctl 및 Etcd를 사용하는 방법


소개

CoreOS를 가능하게 하는 기술 중 하나는 전 세계적으로 분산된 키-값 저장소인 etcd입니다. 이 서비스는 개별 CoreOS 시스템에서 클러스터를 형성하고 전역적으로 액세스 가능한 데이터를 저장하는 플랫폼으로 사용됩니다.

이 가이드에서는 etcd 데몬과 이를 제어하는 데 사용할 수 있는 etcdctl 유틸리티 및 HTTP/JSON API를 탐색합니다.

전제 조건

이 가이드를 따르기 위해 DigitalOcean 개요에서 CoreOS 클러스터를 설정하는 방법에 대한 가이드로 CoreOS 시스템 클러스터가 있다고 가정합니다. 이렇게 하면 단일 클러스터에 3개의 서버가 남게 됩니다.

  • coreos-1
  • coreos-2
  • coreos-3

이러한 시스템을 가동하고 실행하면 이 가이드를 계속 진행할 수 있습니다.

Etcd 클러스터 검색 모델

etcd가 담당하는 가장 기본적인 작업 중 하나는 개별 시스템을 클러스터로 구성하는 것입니다. 이는 생성 시 전달되는 cloud-config 파일에 제공된 검색 주소에서 체크인하여 CoreOS가 부팅될 때 수행됩니다.

CoreOS에서 실행하는 검색 서비스는 https://discovery.etcd.io에서 액세스할 수 있습니다. /new 페이지를 방문하여 새 토큰을 얻을 수 있습니다. 거기에서 컴퓨터가 컴패니언 노드를 검색하는 데 사용할 수 있는 토큰을 얻을 수 있습니다. 다음과 같이 표시됩니다.

https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c

새 클러스터마다 새 토큰을 반드시 제공해야 합니다. 여기에는 동일한 IP 주소를 가질 수 있는 노드를 사용하여 클러스터를 재구축해야 하는 경우가 포함됩니다. etcd 인스턴스는 이로 인해 혼동을 일으키고 검색 주소를 재사용하는 경우 클러스터를 빌드하는 데 올바르게 작동하지 않습니다.

웹 브라우저에서 검색 주소를 방문하면 알려진 머신을 설명하는 JSON 개체를 다시 받게 됩니다. 처음 시작할 때 노드가 없습니다.

{"action":"get","node":{"key":"/_etcd/registry/dcadc5d4d42328488ecdcd7afae5f57c","dir":true,"modifiedIndex":102511104,"createdIndex":102511104}}

클러스터를 부트스트랩한 후 여기에서 자세한 정보를 볼 수 있습니다.

{"action":"get","node":{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda","dir":true,"nodes":[{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/2ddbdb7c872b4bc59dd1969ac166501e","value":"http://10.132.252.38:7001","expiration":"2014-09-19T13:41:26.912303668Z","ttl":598881,"modifiedIndex":102453704,"createdIndex":102453704},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/921a7241c31a499a97d43f785108b17c","value":"http://10.132.248.118:7001","expiration":"2014-09-19T13:41:29.602508981Z","ttl":598884,"modifiedIndex":102453736,"createdIndex":102453736},{"key":"/_etcd/registry/1edee33e6b03e75d9428eacf0ff94fda/27987f5eaac243f88ca6823b47012c5b","value":"http://10.132.248.121:7001","expiration":"2014-09-19T13:41:41.817958205Z","ttl":598896,"modifiedIndex":102453860,"createdIndex":102453860}],"modifiedIndex":101632353,"createdIndex":101632353}}

클러스터의 검색 URL을 찾아야 하는 경우 구성원인 컴퓨터 중 하나에서 찾을 수 있습니다. 이 정보는 /run 계층 구조 내에서 검색할 수 있습니다.

cat /run/systemd/system/etcd.service.d/20-cloudinit.conf
[Service]
Environment="ETCD_ADDR=10.132.248.118:4001"
Environment="ETCD_DISCOVERY=https://discovery.etcd.io/dcadc5d4d42328488ecdcd7afae5f57c"
Environment="ETCD_NAME=921a7241c31a499a97d43f785108b17c"
Environment="ETCD_PEER_ADDR=10.132.248.118:7001"

URL은 ETCD_DISCOVERY 항목 내에 저장됩니다.

etcd를 실행하는 시스템이 부팅되면 이 URL에서 정보를 확인합니다. 자체 정보를 제출하고 다른 회원에 대한 질문을 합니다. 클러스터의 첫 번째 노드는 분명히 다른 노드에 대한 정보를 찾지 못하므로 자신을 클러스터 리더로 지정합니다.

후속 머신도 해당 정보와 함께 검색 URL에 접속합니다. 그들은 이미 체크인한 머신에 대한 정보를 다시 받게 됩니다. 그런 다음 이러한 머신 중 하나를 선택하고 직접 연결하여 정상 클러스터 구성원의 전체 목록을 가져옵니다. 데이터 복제 및 배포는 Raft 합의 알고리즘을 통해 이루어집니다.

각 시스템에 대한 데이터는 etcd 내의 숨겨진 디렉토리 구조에 저장됩니다. 다음을 입력하여 etcd가 알고 있는 시스템에 대한 정보를 볼 수 있습니다.

etcdctl ls /_etcd/machines --recursive
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
/_etcd/machines/921a7241c31a499a97d43f785108b17c
/_etcd/machines/27987f5eaac243f88ca6823b47012c5b

etcd가 새 클러스터 구성원에게 전달하는 세부 정보는 이러한 키에 포함됩니다. etcdctl로 요청하여 개별 값을 볼 수 있습니다.

etcdctl get /_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
etcd=http%3A%2F%2F10.132.252.38%3A4001&raft=http%3A%2F%2F10.132.252.38%3A7001

나중에 etcdctl 명령에 대해 자세히 살펴보겠습니다.

Etcdctl 사용법

etcd와 상호 작용하는 두 가지 기본 방법이 있습니다. 포함된 etcdctl 유틸리티와 같은 HTTP/JSON API 및 클라이언트를 통해. etcdctl을 먼저 살펴보겠습니다.

키 및 디렉터리 보기

시작하려면 etcdctl이 현재 무엇을 저장하고 있는지 살펴보겠습니다. 다음을 입력하여 최상위 키를 볼 수 있습니다.

etcdctl ls /
/coreos.com

보시다시피 하나의 결과가 있습니다. 이 시점에서 이것이 디렉토리인지 키인지 명확하지 않습니다. 우리는 노드를 가져오기하여 키의 값을 보거나 디렉토리인지 확인할 수 있습니다.

etcdctl get /coreos.com
/coreos.com: is a directory

이 수동 재귀 프로세스를 피하기 위해 etcdctl에 다음을 입력하여 보이는 정보의 전체 계층 구조를 나열하도록 지시할 수 있습니다.

etcdctl ls / --recursive
/coreos.com
/coreos.com/updateengine
/coreos.com/updateengine/rebootlock
/coreos.com/updateengine/rebootlock/semaphore

보시다시피 초기 /coreos.com 노드 아래에 상당히 많은 디렉토리가 있습니다. 최종 끝점에서 정보를 요청하여 노드에서 실제 데이터를 가져오는 것이 어떤 것인지 확인할 수 있습니다.

etcdctl get /coreos.com/updateengine/rebootlock/semaphore
{"semaphore":1,"max":1,"holders":null}

여기에는 우리에게 매우 유용한 정보가 포함되어 있지 않습니다. -o extended 옵션을 전달하여 이 항목에 대한 추가 메타데이터를 얻을 수 있습니다. 이것은 전역 옵션이므로 get 명령 앞에 와야 합니다.

etcdctl -o extended get /coreos.com/updateengine/rebootlock/semaphore
Key: /coreos.com/updateengine/rebootlock/semaphore
Created-Index: 6
Modified-Index: 6
TTL: 0
Etcd-Index: 170387
Raft-Index: 444099
Raft-Term: 8

{"semaphore":1,"max":1,"holders":null}

키 설정 및 노드 생성

새 디렉터리를 만들려면 다음과 같이 mkdir 명령을 사용할 수 있습니다.

etcdctl mkdir /example

키를 만들려면 mk 명령을 사용할 수 있습니다.

etcdctl mk /example/key data
data

키가 이미 존재하지 않는 경우에만 작동합니다. 생성한 키의 값을 요청하면 설정한 데이터를 검색할 수 있습니다.

etcdctl get /example/key
data

기존 키를 업데이트하려면 update 명령을 사용하십시오.

etcdctl update /example/key turtles
turtles

디렉터리에 대한 동반 updatedir 명령은 디렉터리에 TTL 또는 TTL을 설정한 경우에만 유용할 것입니다. 이렇게 하면 TTL 시간이 전달된 시간으로 업데이트됩니다. --ttl # 인수를 전달하여 디렉터리 또는 키에 대한 TTL을 설정할 수 있습니다. 여기서 "#\는 유지할 시간(초)입니다.

etcdctl mkdir /here/you/go --ttl 120

그런 다음 updatedir로 TTL을 업데이트할 수 있습니다.

etcdctl updatedir /here/you/go --ttl 500

기존 키의 값을 변경하거나 존재하지 않는 경우 키를 생성하려면 set 명령을 사용하십시오. 이것을 mkupdate 명령의 조합으로 생각하십시오.

etcdctl set /example/key new
new

여기에는 존재하지 않는 경로가 포함될 수 있습니다. 경로 구성 요소는 동적으로 생성됩니다.

etcdctl set /a/b/c here
here

디렉토리에 대해 이와 동일한 존재하지 않는 경우 생성 기능을 사용하려면 setdir 명령을 사용할 수 있습니다.

etcdctl setdir /x/y/z

참고: setdir 명령은 현재 명시된 대로 작동하지 않습니다. 현재 빌드에서 사용법은 updatedir 명령을 미러링하며 디렉토리가 이미 있는 경우 실패합니다. 이 문제를 해결하기 위해 GitHub 리포지토리에 열린 문제가 있습니다.

항목 제거

기존 키를 제거하려면 rm 또는 rmdir 명령을 사용할 수 있습니다.

rm 명령을 사용하여 키를 제거할 수 있습니다.

etcdctl rm /a/b/c

디렉토리와 모든 하위 디렉토리를 제거하기 위해 재귀적으로 사용할 수도 있습니다.

etcdctl rm /a --recursive

빈 디렉터리 또는 키만 제거하려면 rmdir 명령을 사용하십시오.

etcdctl rmdir /x/y/z

이것은 계층의 끝점만 제거하고 있는지 확인하는 데 사용할 수 있습니다.

변경 사항 확인

특정 키 또는 전체 디렉토리에서 변경 사항을 볼 수 있습니다. etcdctl로 이들을 감시하면 감시 중인 모든 것에 어떤 이벤트가 발생할 때까지 작업이 중단됩니다.

키를 감시하려면 플래그 없이 키를 사용하십시오.

etcdctl watch /example/hello

시청을 중지하려면 CTRL-C를 누르십시오. 감시 중에 변경 사항이 감지되면 새 값이 반환됩니다.

전체 디렉토리 구조를 감시하려면 --recursive 플래그를 사용하십시오.

etcdctl watch --recursive /example

값의 상태를 지속적으로 모니터링하기 위해 간단한 루프 구성에 배치하여 이것이 얼마나 유용한지 확인할 수 있습니다.

while true; do etcdctl watch --recursive /example; done

변경이 감지될 때마다 명령을 실행하려면 exec-watch 명령을 사용하십시오.

etcdctl exec-watch --recursive  /example -- echo "hello"

이것은 해당 디렉토리의 값이 변경될 때마다 "hello\를 화면에 표시합니다.

숨겨진 가치

즉시 명백하지 않은 한 가지는 etcd 내에 숨겨진 디렉토리 구조가 있다는 것입니다. 밑줄로 시작하는 디렉토리 또는 키입니다.

기존의 etcdctl 도구로는 나열되지 않으며 이러한 항목을 찾으려면 무엇을 찾고 있는지 알아야 합니다.

예를 들어 fleet에 대한 일부 내부 정보를 포함하는 /_coreos.com이라는 숨겨진 디렉토리가 있습니다. 명시적으로 요청하여 계층 구조를 볼 수 있습니다.

etcdctl ls --recursive /_coreos.com 
/_coreos.com/fleet
/_coreos.com/fleet/states
/_coreos.com/fleet/states/apache@6666.service
/_coreos.com/fleet/states/apache@6666.service/2ddbdb7c872b4bc59dd1969ac166501e
/_coreos.com/fleet/states/apache@7777.service
/_coreos.com/fleet/states/apache@7777.service/921a7241c31a499a97d43f785108b17c
. . .

이러한 다른 디렉토리 구조는 /_etcd 내에 있습니다.

etcdctl ls --recursive /_etcd
/_etcd/machines
/_etcd/machines/27987f5eaac243f88ca6823b47012c5b
/_etcd/machines/2ddbdb7c872b4bc59dd1969ac166501e
/_etcd/machines/921a7241c31a499a97d43f785108b17c
/_etcd/config

이러한 기능은 일반 목록에 표시되지 않는다는 점만 제외하면 다른 항목과 동일하게 작동합니다. 키 또는 디렉터리 이름을 밑줄로 시작하기만 하면 만들 수 있습니다.

기타 HTTP/JSON API 사용

etcd와 상호 작용하는 다른 방법은 간단한 HTTP/JSON API를 사용하는 것입니다.

API에 액세스하려면 curl과 같은 간단한 HTTP 프로그램을 사용할 수 있습니다. 다시 전달되는 리디렉션을 따르려면 -L 플래그를 제공해야 합니다. 클러스터 내에서 대부분의 쿼리에 로컬 127.0.0.1 인터페이스와 포트 4001을 사용할 수 있습니다.

참고: Docker 컨테이너 내에서 etcd에 연결하려면 http://172.17.42.1:4001 주소를 사용할 수 있습니다. 이는 애플리케이션이 등록된 정보를 기반으로 구성을 업데이트하는 데 유용할 수 있습니다.

일반 키스페이스는 호스트 시스템에서 http://127.0.0.1:4001/v2/keys/로 이동하여 도달할 수 있습니다. 예를 들어 최상위 키/디렉토리 목록을 보려면 다음을 입력하십시오.

curl -L http://127.0.0.1:4001/v2/keys/
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"modifiedIndex":6,"createdIndex":6},{"key":"/services","dir":true,"modifiedIndex":333,"createdIndex":333}]}}

요청의 후행 슬래시는 필수입니다. 그것 없이는 올바르게 해결되지 않습니다.

일반 HTTP 동사를 사용하여 값을 설정하거나 검색할 수 있습니다.

이러한 작업의 동작을 수정하려면 ?flag=value 구문을 사용하여 요청 끝에 플래그를 전달할 수 있습니다. 여러 플래그는 & 문자로 구분할 수 있습니다.

예를 들어 모든 키를 재귀적으로 나열하려면 다음과 같이 입력할 수 있습니다.

curl -L http://127.0.0.1:4001/v2/keys/?recursive=true
{"action":"get","node":{"key":"/","dir":true,"nodes":[{"key":"/coreos.com","dir":true,"nodes":[{"key":"/coreos.com/updateengine","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock","dir":true,"nodes":[{"key":"/coreos.com/updateengine/rebootlock/semaphore","value":"{\"semaphore\":1,\"max\":1,\"holders\":null}","modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}. . .

일반 키스페이스 외부에서 액세스할 수 있는 또 다른 유용한 정보는 여기에서 액세스할 수 있는 버전 정보입니다.

curl -L http://127.0.0.1:4001/version
etcd 0.4.6

다음 엔드포인트를 방문하여 각 클러스터 리더와 각 팔로워의 관계에 대한 통계를 볼 수 있습니다.

curl -L http://127.0.0.1:4001/v2/stats/leader
{"leader":"921a7241c31a499a97d43f785108b17c","followers":{"27987f5eaac243f88ca6823b47012c5b":{"latency":{"current":1.607038,"average":1.3762888642395448,"standardDeviation":1.4404313533578545,"minimum":0.471432,"maximum":322.728852},"counts":{"fail":0,"success":98718}},"2ddbdb7c872b4bc59dd1969ac166501e":{"latency":{"current":1.584985,"average":1.1554367141497013,"standardDeviation":0.6872303198242179,"minimum":0.427485,"maximum":31.959235},"counts":{"fail":0,"success":98723}}}}

비슷한 작업을 사용하여 현재 사용 중인 컴퓨터에 대한 통계를 감지할 수 있습니다.

curl -L http://127.0.0.1:4001/v2/stats/self
{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","startTime":"2014-09-11T16:42:03.035382298Z","leaderInfo":{"leader":"921a7241c31a499a97d43f785108b17c","uptime":"1h19m11.469872568s","startTime":"2014-09-12T19:47:25.242151859Z"},"recvAppendRequestCnt":1944480,"sendAppendRequestCnt":201817,"sendPkgRate":40.403374523779064,"sendBandwidthRate":3315.096879676072}

수행된 작업에 대한 통계를 보려면 다음을 입력하십시오.

curl -L http://127.0.0.1:4001/v2/stats/store
{"getsSuccess":78823,"getsFail":14,"setsSuccess":121370,"setsFail":4,"deleteSuccess":28,"deleteFail":32,"updateSuccess":20468,"updateFail":4,"createSuccess":39,"createFail":102340,"compareAndSwapSuccess":51169,"compareAndSwapFail":0,"compareAndDeleteSuccess":0,"compareAndDeleteFail":0,"expireCount":3,"watchers":6}

이는 API를 통해 etcd를 제어하는 데 사용할 수 있는 작업 중 일부에 불과합니다.

기타 구성

etcd 서비스는 몇 가지 다른 방법으로 구성할 수 있습니다.

첫 번째 방법은 노드를 부트스트랩하는 데 사용하는 cloud-config 파일과 함께 매개변수를 전달하는 것입니다. 부트스트래핑 가이드에서 이 작업을 수행하는 방법에 대해 조금 보았습니다.

#cloud-config

coreos:
  etcd:
    discovery: https://discovery.etcd.io/<token>
    addr: $private_ipv4:4001
    peer-addr: $private_ipv4:7001
. . .

사용 가능한 옵션을 보려면 etcd와 함께 -h 플래그를 사용하십시오.

etcd -h

cloud-config에 이러한 옵션을 포함하려면 앞의 대시를 제거하고 등호 대신 콜론을 사용하여 값에서 키를 분리하기만 하면 됩니다. 따라서 -peer-addr=peer-addr: 가 됩니다.

cloud-config 파일을 읽으면 CoreOS는 이를 서비스 시작에 사용되는 스텁 단위 파일의 환경 변수로 변환합니다.

etcd의 설정을 조정하는 또 다른 방법은 API를 이용하는 것입니다. 이는 일반적으로 키 쿼리에 사용되는 표준 4001 대신 7001 포트를 사용하여 수행됩니다.

예를 들어 다음을 입력하여 현재 구성 값 중 일부를 가져올 수 있습니다.

curl -L http://127.0.0.1:7001/v2/admin/config
{"activeSize":9,"removeDelay":1800,"syncInterval":5}

PUT 작업을 통해 새 JSON을 데이터 페이로드로 전달하여 이러한 값을 변경할 수 있습니다.

curl -L http://127.0.0.1:7001/v2/admin/config -XPUT -d '{"activeSize":9,"removeDelay":1800,"syncInterval":5}'
{"activeSize":9,"removeDelay":1800,"syncInterval":5}

컴퓨터 목록을 가져오려면 /v2/admin/machines 끝점으로 이동할 수 있습니다.

curl -L http://127.0.0.1:7001/v2/admin/machines
[{"name":"27987f5eaac243f88ca6823b47012c5b","state":"follower","clientURL":"http://10.132.248.121:4001","peerURL":"http://10.132.248.121:7001"},{"name":"2ddbdb7c872b4bc59dd1969ac166501e","state":"follower","clientURL":"http://10.132.252.38:4001","peerURL":"http://10.132.252.38:7001"},{"name":"921a7241c31a499a97d43f785108b17c","state":"leader","clientURL":"http://10.132.248.118:4001","peerURL":"http://10.132.248.118:7001"}]

이는 DELETE 메소드를 사용하여 클러스터에서 시스템을 강제로 제거하는 데 사용할 수 있습니다.

결론

보시다시피 etcd는 클러스터의 모든 시스템에서 정보를 저장하거나 검색하는 데 사용할 수 있습니다. 이를 통해 데이터를 동기화할 수 있으며 서비스가 구성 데이터 및 연결 세부 정보를 찾을 수 있는 위치를 제공합니다.

이는 클러스터 내의 모든 위치에서 유효한 간단한 엔드포인트를 제공할 수 있기 때문에 분산 시스템을 구축할 때 특히 유용합니다. 이 리소스를 활용하여 서비스를 동적으로 구성할 수 있습니다.