Kubernetes
에서 Cluster
에 문제가 생겼을 경우 etcd
를 백업해놓은 상태라면 원래 상태로 복구가 가능합니다.
반대로 etcd
는 Kubernetes
의 모든 상태 정보들을 담고 있기 때문에 etcd
가 손상되었을 경우 Cluster
를 활용할 수 없게 됩니다.
그렇기 때문에 etcd
는 단일 환경에 구성하는 것이 아닌, 분산된 환경에 구성하는 것이 좋으며 분산된 환경에서 etcd
를 운영할 때 분산된 etcd
들이 정상적으로 동작하기 위한 방법을 마련해야 합니다.
etcd
에서는 Raft Algorithm
알고리즘을 이용해 이를 해결했습니다.
Raft Algorithm
은 voting
과 log entry
복제라는 방식으로 동작합니다.
분산된 환경에서 etcd
가 동작할 경우, 여러 Server
에서 CRUD
가 발생하게됩니다.
etcd
가 정상적으로 동작하기 위해서는 다른 Server
들에서 이벤트가 발생하더라도 모든 Server
의 etcd
들이 동일한 데이터를 저장하고 있는것이 보장되어야 합니다.
이렇게 똑같은 데이터를 여러 서버에 계속해서 복사하는 방식을 Replicated state machine
이라고 하며, Replicated state machine
에 어떤 데이터를 복사할지를 결정하는 알고리즘을 Consensus Algorithm
이라고 합니다.
Raft Algorithm
은 Consensus Algorithm
의 한 종류로 서로 다른 Server
들이 모종의 방법으로 합의를 통해 상태를 공유하는 알고리즘입니다.
Replicated state machine
의 핵심은 복제과정에서 발생할 수 있는 문제를 해결하기 위해 Consensus
를 확보해야 한다는 것입니다.
Consensus
를 확보하기 위해서는 몇가지 사항이 전제되어야 합니다.
- 항상 올바른 결과를 리턴해야 함
- 서버가 몇 대 다운되더라도 항상 응답해야 함
- 네트워크 지연이 발생하더라도 로그의 일관성이 깨져서는 안됨
- 모든 서버에 복제되지 않았더라도 조건을 만족하면 빠르게 요청에 응답해야 함
또한, Raft Algorithm
의 동작 원리를 이해하기 위해서는 몇 가지 용어에 대한 이해가 필요합니다.
쿼럼(Quorum)
Quorum
이란 정족수라는 의미로 etcd cluster
가 의사 결정을 하기 위한 최소한의 서버 수를 의미합니다. etcd cluster
는 분산된 etcd
서버 들 중 Quorum
의 숫자 만큼의 서버에 데이터의 복제가 일어나면 작업이 완료한 것으로 판단합니다.
상태(State)
State
란 etcd cluster
를 구성하는 Server
들이 가지게 되는 일종의 역할입니다.
모든 Server
들은 Leader
, Follower
, Candidate
라는 3개의 State
중 하나가 됩니다.
모든 Server
들은 마지막으로 log
가 저장된 위치(lastIndex
) 값을 가지고 있습니다.
이 때, Leader
는 추가적으로 현재 etcd cluster
의 Server
들이 log
를 저장할 다음 위치(nextIndex
)값을 가지고 있습니다.
etcd cluster
의 변경 내역은 Leader
를 통해서만 Follower
에게 전달되어 반영됩니다.
타이머(Timer)
etcd
의 Leader
가 된 Server
는 다른 모든 Server
들에게 주기적으로 heartbeat
를 전송해 Leader
가 존재하고 있음을 알립니다.
다른 Server
들은 Leader
가 존재하고 있을 때에는 Leader
에게 다음에 log
를 저장할 위치에 대한 nextIndex
값을 받으며 동작합니다.
만약, Leader
가 존재하지 않게 되어 heartbeat
가 전달되지 않을 경우 Server
들은 새로운 Leader
를 선출하기 위한 절차를 시작합니다.
Raft Algorithm
에서 etcd Cluster
환경을 구성하는 Server
들은 State
를 가지게 됩니다.
State
는 Leader
, Follower
, Candidate
가 있습니다.
Leader
는 etcd Cluster
를 구성하는 Server
들에게 주기적으로 heartbeat
를 전송하여 Leader
가 존재하고 있음을 알리며, Server
들의 값은 Leader
를 통해서만 변경됩니다.
Leader
를 선출하는 방법은 아래와 같습니다.
Cluster
구성시 모든Server
들은Follower
상태,Term=0
- 누구도
heartbeat
를 보내지 않으면Server
중 1대에서election timeout
발생election timeout
이 발생한Server
는State
를Candidate
로 변경하고Term
값을 1증가시킨 뒤 다른Server
들에게RequestVote RPC call
을 보냄Request Vote
를 받은 서버는 자신이 가진term
정보와log
를 비교해서candidate
보다 자신의 것이 크다면 거절, 크지 않다면 OK 응답Candidate
는 자기 자신을 포함하여 다른Server
로 부터 받은 OK응답의 숫자가Quorum
과 같으면Leader
가 됨Leader
는 다른 서버에게 주기적으로heartbeat
를 보냄, 이Append RPC call
에는Leader
의term
과log index
정보가 들어있음Leader
가 아닌 서버는Append RPC call
을 받았을 때, 자신의term
보다 높은 값인지 확인 후 자신의term
값을 해당 값으로 업데이트
etcd
는 log replication
을 통해 모든 etcd
의 값을 동일하게 유지합니다.
동작 방식은 아래와 같습니다.
- 각 서버는 자신이 가지고 있는
log
의lastIndex
값을 가지고 있으며,Leader
는 추가적으로Follower
들의 다음log
가 저장될 공간인nextIndex
값을 가지고 있음- 사용자로부터
log Append
요청을 받은Leader
는 자신의lastIndex
다음 위치에log
를 기록하고lastIndex
값을 증가시킴heartbeat
주기가 돌아오면 모든Server
에게AppendEntry RPC call
을 보내면서Follower
의nextindex
에 해당하는log
를 함께 보냄Follower
들은log
를entry
에 보관하고 잘 받았다는 응답을Leader
에 전송Leader
는log
를 잘 받았다고 응답한 숫자가Quorum
이 되면Quorum
숫자만큼의log replication
이 일어났다고 판단하고commit
을 수행- 이때부터
etcd
를 조회하면commit
된 값을 확인할 수 있음Follower
들은Leader
가 해당log
를commit
한 사실을 알게되면 각 서버의entry
에 보관중이던log
를commit
함
etcd
에서 기존에 Leader
였던 Server
에 문제가 생길 경우 다시 Leader
를 선출합니다.
Leader
가 다운되면heartbeat
이 전달되지 않으므로Follower
들 하나가election timeout
을 발생시키게되고 자신의term
값을 1 증가시키고Candidate
로 변경 후RequestVote RPC call
을 다른Server
들에게 전달Follower
들은 먼저 자신의term
값과RequestVote
를 통해 받은Candidate
의term
값을 비교
여기서 RequestVote RPC call
을 전송한 Candidate
의 term
값과 log
버전에 따라 해당 Candidate
가 Leader
가 될 수도, 되지 못할 수도 있습니다.
Leader가 될 수 있는 경우
3.Candidate
의term
값이 자신보다 크고log
가 자신이 가진log
와 버전이 같거나 더 최신인 경우 OK 응답
4. OK 응답의 갯수가Quorum
과 같아지면Leader
로 선출
Leader가 될 수 없는 경우
3.Candidate
의 값이 자신보다 작거나log
가 자신이 가진 것보다 오래된 버전이면 거절 응답
4. 거절 응답을 보낸Server
들 중 한대에서election timeout
발생하여Candidate
가 됨
5.Candidate
가 된Server
는RequestVote RPC call
을 전송
6. OK 응답의 갯수가Quorum
과 같아지면Leader
로 선출