중단 복구

중단 복구 (Recover from an outage)

당황하지 마세요. 이것은 중요한 첫 단계예요.

배포 구성에 따라 클러스터를 사용할 수 없게 되는 데 서버 장애 하나만으로 충분할 수 있어요. 복구에는 운영자의 개입이 필요하지만 과정은 간단합니다.

이 가이드는 데이터센터의 서버 노드 다수가 유실되어 발생한 Nomad 중단 복구를 위한 것이에요. 서버를 추가하거나 제거하려면 bootstrapping guide를 참고하세요.

출처: 문서

본문

단일 서버 클러스터의 장애 (Failure of a single server cluster)

서버가 하나만 있었고 그것이 실패했다면, 재시작해 운영을 복원해 보세요. 단일 서버 구성은 -bootstrap-expect=1 플래그가 필요해요. 서버를 복구할 수 없으면 새 서버를 올려야 해요. 자세한 내용은 bootstrapping guide를 참고하세요.

단일 서버 클러스터에서 복구 불가능한 서버 장애가 발생하면 다른 서버에 데이터가 복제되지 않았으므로 데이터 유실은 불가피해요. 이것이 단일 서버 배포가 절대 권장되지 않는 이유예요.

멀티 서버 클러스터의 서버 장애 (Failure of a server in a multi-server cluster)

실패한 서버를 복구할 수 있다고 생각하면, 가장 쉬운 옵션은 그것을 다시 온라인으로 가져와 같은 IP 주소로 클러스터에 다시 합류시키는 것이에요. 이렇게 하면 클러스터가 완전히 건강한 상태로 돌아와요. 마찬가지로 실패한 노드를 대체하기 위해 새 Nomad 서버를 구축해야 해도 즉시 그렇게 하고 싶을 거예요. 재구축된 서버는 실패한 서버와 같은 IP 주소를 가져야 한다는 점을 명심하세요. 다시 말하지만, 이 서버가 온라인이 되어 다시 합류하면 클러스터는 완전히 건강한 상태로 돌아와요.

이 두 전략 모두 실패한 서버를 재부팅하거나 재구축하는 데 잠재적으로 오랜 시간이 걸려요. 이것이 비현실적이거나 같은 IP로 새 서버를 만드는 것이 선택지가 아니라면, 실패한 서버를 제거해야 해요. 일반적으로 실패한 서버가 여전히 클러스터의 구성원이라면 nomad server force-leave 명령을 실행해 제거할 수 있어요.

참고

raft 클러스터는 Raft 피어 정보에 대한 온라인 수정을 수행하려면 사용 가능한 노드의 쿼럼이 필요해요. 멤버십 변경은 Raft 로그에 쓰여지고, 모든 Raft 로그 쓰기는 쿼럼을 요구해요. 이것이 불가능하면 Multi-Server Cluster의 여러 서버 장애로 계속 진행하세요.

어떤 이유로든 Raft 구성이 여전히 오래된 구성원을 표시하면 nomad operator raft remove-peer 명령을 사용해 다운타임 없이 즉시 오래된 피어 서버를 제거할 수 있어요.

필요한 멤버십 변경을 마쳤으면 nomad operator raft list-peers 명령으로 현재 Raft 상태를 확인해야 해요:

$ nomad operator raft list-peers
Node                   ID               Address          State     Voter
nomad-server01.global  10.10.11.5:4647  10.10.11.5:4647  follower  true
nomad-server02.global  10.10.11.6:4647  10.10.11.6:4647  leader    true
nomad-server03.global  10.10.11.7:4647  10.10.11.7:4647  follower  true

멀티 서버 클러스터에서 여러 서버 장애 (Failure of multiple servers in a multi-server cluster)

여러 서버가 유실되어 쿼럼 유실과 완전한 중단이 발생했다면, 클러스터에 남은 서버의 데이터를 사용한 부분 복구가 가능해요. 여러 서버가 유실되었기 때문에 이 상황에는 데이터 유실이 있을 수 있어요. 커밋된 것이 무엇인지에 대한 정보가 불완전할 수 있기 때문이에요. 복구 프로세스는 모든 미결 Raft 로그 항목을 암시적으로 커밋하므로, 장애 전에 커밋되지 않았던 데이터도 커밋될 수 있어요.

아래 섹션에 복구 절차의 세부 사항이 있어요. 남은 서버를 raft/peers.json 복구 파일에 포함할 거예요. 남은 서버가 모두 동일한 raft/peers.json 구성으로 재시작되면 클러스터가 리더를 선출할 수 있어야 해요.

나중에 도입하는 새 서버는 완전히 깨끗한 데이터 디렉터리를 가진 새 것이어도 되고 server join 명령으로 합류할 수 있어요.

극단적인 경우 raft/peers.json 복구 파일에서 자신을 유일한 피어로 하여 단일 서버만으로 복구하는 것도 가능해야 해요.

raft/peers.json 복구 파일은 최종적이고, 섭취된 후 스냅샷이 찍히므로 복구된 구성으로 시작하는 것이 보장돼요. 이것은 모든 Raft 로그 항목을 암시적으로 커밋하므로 중단 복구에만 사용해야 해요. 하지만 어떤 클러스터 데이터가 사용 가능한 상황에서든 복구를 허용해야 해요.

peers.json으로 수동 복구 (Manual recovery using peers.json)

시작하려면 모든 남은 서버를 중지하세요. 우아한 leave를 시도할 수 있지만 대부분의 경우 작동하지 않아요. leave가 오류로 종료되더라도 걱정하지 마세요. 클러스터가 건강하지 않은 상태라서 이는 예상된 일이에요.

peers.json 파일은 기본적으로 존재하지 않으며 복구를 수행할 때만 사용돼요. 이 파일은 Nomad가 시작해 이 파일을 섭취한 후 삭제돼요.

Nomad는 시작 시 현재 Raft 버전에 있다는 것을 표시하기 위해 raft/peers.info 파일을 자동으로 만들어요. raft/peers.info 파일을 어떤 시점에도 제거하지 마세요.

복구에 raft/peers.json을 사용하면 커밋되지 않은 Raft 로그 항목이 암시적으로 커밋될 수 있으므로, 유실된 서버를 복구할 다른 선택지가 없는 중단 이후에만 사용해야 해요. peers 파일을 주기적으로 배치하는 자동화된 프로세스가 없는지 확인하세요.

다음 단계는 각 Nomad 서버의 -data-dir로 가는 것이에요. 그 디렉터리 안에는 raft/ 하위 디렉터리가 있을 거예요. raft/peers.json 파일을 만드세요. 그 내용은 클러스터의 raft 프로토콜 버전에 따라 다를 거예요.

Raft protocol 3 peers.json 스펙 (Raft protocol 3 peers.json specification)

[
  {
    "id": "adf4238a-882b-9ddc-4a9d-5b6758e4159e",
    "address": "10.1.0.1:4647",
    "non_voter": false
  },
  {
    "id": "8b6dda82-3103-11e7-93ae-92361f002671",
    "address": "10.1.0.2:4647",
    "non_voter": false
  },
  {
    "id": "97e17742-3103-11e7-93ae-92361f002671",
    "address": "10.1.0.3:4647",
    "non_voter": false
  }
]
  • id (string: **required**) - 서버의 node ID를 지정. 이것은 서버가 시작될 때 로그에서 찾을 수 있고, 서버의 데이터 디렉터리의 node-id 파일 안에서도 찾을 수 있어요.

  • address (string: **required**) - 서버의 IP와 포트를 ip:port 형식으로 지정. 포트는 클러스터 통신에 사용되는 서버의 RPC 포트로, 일반적으로 4647이에요.

  • non_voter (bool: _false_) - 일부 고급 Autopilot 구성에서 사용되는 non-voter인지 제어. 생략하면 false로 기본 설정되며, 대부분의 클러스터에서 일반적이에요.

alive 서버 목록으로 peers.json 파일을 만들기 위해 이 jq 필터를 사용할 수 있어요. 생성된 출력을 확인하고 필요한 변경을 하세요.

$ nomad server members -json | jq '[ .[] | select(.Status == "alive") | {id: .Tags.id, address: "\(.Tags.rpc_addr):\(.Tags.port)", non_voter: false} ]'

Raft protocol 2 peers.json 스펙 (Raft protocol 2 peers.json specification)

["10.0.1.8:4647", "10.0.1.6:4647", "10.0.1.7:4647"]

Raft 프로토콜 버전 2 peers.json 파일은 각 서버에 대한 IP:Port 주소 목록을 포함해요. 포트는 HTTP API 포트가 아닌 RPC 포트를 가리켜야 한다는 점에 유의하세요.

모든 서버 노드에 peers.json 배포 (Deploy peers.json to all server nodes)

모든 남은 서버에 대한 항목을 만드세요. 여기에 포함하지 않은 서버가 실제로 실패했고 나중에 클러스터에 다시 합류하지 않을 것임을 확인해야 해요.

이 파일을 모든 남은 서버 노드에서 동일하게 배포하세요.

서버 노드에서 키링 확인 (Verify keyring on server nodes)

경고

Nomad 1.9.0 이전에는 키 자재가 Raft에 저장된 적이 없었어요. 이는 nomad agent snapshot save 명령과 스냅샷 에이전트가 Nomad의 키링을 저장하지 않았다는 뜻이에요. 1.9.0 이전 버전을 사용하고 있다면 적어도 한 대 서버의 키링을 백업했는지 확인해야 해요.

각 Nomad 서버의 -data-dir로 가세요. 그 디렉터리 안에는 .nks.json 파일이 있는 keystore/ 하위 디렉터리가 있을 거예요. 계속하기 전에 이 파일들이 적어도 한 대 서버에 존재하는지 확인하세요.

클러스터 노드 재시작 (Restart cluster nodes)

이 시점에서 모든 남은 서버를 재시작할 수 있어요. 서버가 복구 파일을 섭취하면 로그 줄이 출력돼요:

...
2016/08/16 14:39:20 [INFO] nomad: found peers.json file, recovering Raft configuration...
2016/08/16 14:39:20 [INFO] nomad.fsm: snapshot created in 12.484µs
2016/08/16 14:39:20 [INFO] snapshot: Creating new snapshot at /tmp/peers/raft/snapshots/2-5-1471383560779.tmp
2016/08/16 14:39:20 [INFO] nomad: deleted peers.json file after successful recovery
2016/08/16 14:39:20 [INFO] raft: Restored from snapshot 2-5-1471383560779
2016/08/16 14:39:20 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:10.212.15.121:4647 Address:10.212.15.121:4647}]
...

어떤 서버가 우아한 leave를 수행했다면 server join 명령으로 클러스터에 다시 합류시켜야 할 수 있어요:

$ nomad server join <Node Address>
Successfully joined cluster by contacting 1 nodes.

기존 구성원이라면 gossip 프로토콜이 서버 노드를 발견하기 때문에 클러스터에 다시 합류하는 데 사용할 수 있다는 점에 유의하세요.

이 시점에서 클러스터는 다시 작동 가능한 상태가 돼야 해요. 노드 중 하나가 리더십을 주장하고 다음과 같은 로그를 출력해야 해요:

[INFO] nomad: cluster leadership acquired

nomad operator raft list-peers 명령으로 Raft 구성을 검사할 수 있어요:

$ nomad operator raft list-peers
Node                   ID               Address          State     Voter
nomad-server01.global  10.10.11.5:4647  10.10.11.5:4647  follower  true
nomad-server02.global  10.10.11.6:4647  10.10.11.6:4647  leader    true
nomad-server03.global  10.10.11.7:4647  10.10.11.7:4647  follower  true

더 알아보기 (Learn more)