준비된 쿼리로 지리적 장애 조치 자동화
준비된 쿼리로 지리적 장애 조치 자동화 (Automate Geo-Failover with Prepared Queries)
이 튜토리얼은 준비된 쿼리(prepared queries)를 사용해 지리적 장애 조치(geo failover) 정책을 구축하는 방법을 일련의 예시를 통해 보여줘요. 준비된 쿼리 템플릿을 사용해 장애 조치 과정을 단순화하는 방법도 포함돼요.
출처: 문서
본문
팁 (Tip)
이 튜토리얼의 내용은 HashiCorp Cloud(HCP)에서 호스팅되는 Consul 클러스터에도 적용돼요.
단일 데이터센터 내에서 Consul은 실패한 서비스 인스턴스를 DNS 조회에서 제외하고 API에서 서비스 헬스 정보를 제공함으로써 서비스에 대한 자동 장애 조치를 제공해요.
로컬 데이터센터에서 서비스 인스턴스를 더 이상 사용할 수 없을 때 다른 데이터센터로의 장애 조치 정책을 구현하는 것은 어려울 수 있는데, 일반적으로 그 논리를 각 애플리케이션에 작성해야 하기 때문이에요. 다행히 Consul에는 사용자가 장애 조치 정책을 중앙 방식으로 정의할 수 있는 기능을 제공하는 준비된 쿼리 API가 있어요. Consul의 DNS 인터페이스를 사용해 이를 애플리케이션에 쉽게 노출할 수 있으며 Consul의 API를 사용하는 애플리케이션에서도 사용할 수 있어요.
장애 조치 정책은 유연하며 다양한 방식으로 적용될 수 있어요:
- 대체 데이터센터의 완전히 정적인 목록.
- Consul의 네트워크 좌표(network coordinate) 하위 시스템을 사용하는 완전히 동적인 정책.
- 네트워크 왕복 시간을 기반으로 장애 조치할 다음 최적의 데이터센터를 자동으로 결정.
준비된 쿼리는 특정 서비스에 특화된 정책으로 만들 수 있고, 준비된 쿼리 템플릿을 사용하면 소수의 템플릿으로 하나의 정책이 많거나 심지어 모든 서비스에 적용될 수 있어요.
이 튜토리얼은 일련의 예시를 통해 준비된 쿼리를 사용해 지리 장애 조치 정책을 구축하는 방법을 보여줘요. 또한 준비된 쿼리 템플릿을 사용해 장애 조치 과정을 단순화하는 방법에 대한 정보도 포함해요.
사전 요구 사항 (Prerequisites)
이 튜토리얼을 완료하려면 세 개의 Consul 클러스터로 구성된 Consul WAN 페더레이션이 있어야 해요. 이 예시에서 로컬 Consul 데이터센터는 dc1이라고 하며 두 개의 원격 데이터센터(dc2와 dc3)와 페더레이션되었어요. 클러스터를 페더레이션하는 방법에 대한 자세한 내용은 여러 데이터센터 페더레이션 튜토리얼을 참고해요.
준비된 쿼리 소개 (Prepared query introduction)
준비된 쿼리는 데이터센터 수준에서 정의되는 객체예요. 한 번만 생성하면 되며 Consul 서버에 저장돼요. 이 방법은 Consul KV 저장소의 값과 유사해요.
준비된 쿼리는 생성되면 애플리케이션이 호출해 쿼리를 수행하고 최신 결과를 얻을 수 있어요.
다음은 준비된 쿼리를 생성하는 요청 예시예요:
$ curl http://127.0.0.1:8500/v1/query \
--request POST \
--data @- << EOF
{
"Name": "banking-app",
"Service": {
"Service": "banking-app",
"Tags": ["v1.2.3"]
}
}
EOF
이것은 "banking-app"이라는 준비된 쿼리를 생성하는데, "v1.2.3" 태그가 있는 "banking-app" 서비스의 모든 인스턴스를 조회해요. 이 정책은 "banking-app" 애플리케이션의 어느 버전을 사용해야 하는지를 중앙에서 제어하는 데 사용할 수 있어요. 이 준비된 쿼리를 업데이트해 "v1.2.4" 태그를 찾게 하면 아무것도 재구성하지 않고도 애플리케이션이 서비스의 새 버전을 찾기 시작할 수 있어요.
애플리케이션은 이 쿼리를 두 가지 방식으로 사용할 수 있어요.
- 준비된 쿼리에 이름을 주었으므로 단순히 "banking-app.service.consul" 대신 "banking-app.query.consul"에 대한 DNS 조회를 수행할 수 있어요. 이제 준비된 쿼리에서는 애플리케이션이 알 필요가 없는 추가 필터 정책이 백그라운드에서 작동해요.
- 쿼리는 Consul의 API와 직접 통합하는 애플리케이션을 위해 준비된 쿼리 실행 API를 사용해 실행할 수도 있어요.
장애 조치 정책 유형 (Failover policy types)
이 섹션의 기술을 사용해 장애 조치 정책이 있는 준비된 쿼리를 개발할 수 있어요. 그러면 애플리케이션 구성을 DNS를 통해 "banking-app.service.consul" 대신 "banking-app.query.consul"을 조회하도록 변경하는 것만으로 네트워크 왕복 시간이 증가하는 순서로 가장 가까운 다음 페더레이션 Consul 데이터센터로 자동 지리 장애 조치가 발생해요.
장애 조치는 준비된 쿼리의 또 다른 정책 선택일 뿐이며 이전 예시와 같은 방식으로 작동하고 애플리케이션에 동일하게 투명해요. 장애 조치 정책은 두 필드를 포함하며 둘 다 선택 사항인 Failover 구조를 사용해 구성돼요. 이 구조는 쿼리가 실행될 때 로컬 데이터센터에 정상 노드가 없으면 어떤 일이 발생하는지 결정해요.
NearestN(int: 0)— 네트워크 좌표를 사용해 추정된 네트워크 왕복 시간을 기준으로 쿼리가 최대NearestN개의 다른 데이터센터로 전달됨을 지정해요.Datacenters(array<string>: nil)— 로컬 데이터센터에 정상 노드가 없으면 쿼리를 전달할 원격 데이터센터의 고정 목록을 지정해요. 데이터센터는 목록에 주어진 순서대로 쿼리돼요.
다음 예시는 해당 필드를 사용해 다양한 지리 장애 조치 정책 방법을 구현해요.
정적 정책 (Static policy)
정적 장애 조치 정책은 로컬 데이터센터에 정상 인스턴스가 없으면 접촉할 데이터센터의 고정 목록을 포함해요.
소개 부분의 예시를 정적 장애 조치 정책으로 확장한 것이 여기 있어요:
$ curl http://127.0.0.1:8500/v1/query \
--request POST \
--data @- << EOF
{
"Name": "banking-app",
"Service": {
"Service": "banking-app",
"Tags": ["v1.2.3"],
"Failover": {
"Datacenters": ["dc2", "dc3"]
}
}
}
EOF
이 쿼리가 실행되면(예: "banking-app.query.consul"에 대한 DNS 조회) 다음 작업이 발생해요:
- 로컬 데이터센터의 Consul 서버가 필요한 태그가 있는 "banking-app" 서비스의 정상 인스턴스를 찾으려고 시도해요.
- 로컬에 사용 가능한 인스턴스가 없으면 Consul 서버는 "dc2"의 Consul 서버에 RPC 요청을 보내 그곳에서 쿼리를 수행해요.
- "dc2"에 사용 가능한 인스턴스가 없으면 "dc3"의 Consul 서버에 RPC를 보내 그곳에서 쿼리를 수행해요.
- 마지막으로 이 데이터센터 중 어느 곳에도 사용 가능한 인스턴스가 없으면 오류가 반환돼요.
동적 정책 (Dynamic policy)
많은 Consul 데이터센터가 있는 복잡한 페더레이션 환경에서는 정적 장애 조치 정책을 설정하기가 번거로울 수 있으므로, Consul은 네트워크 좌표 하위 시스템에 기반한 동적 옵션을 제공해요.
Consul은 로컬 데이터센터에서 페더레이션된 다른 데이터센터의 서버까지의 네트워크 왕복 시간의 추정치를 지속적으로 유지해요. 각 서버는 자신에서 원격 데이터센터의 서버까지의 중간 왕복 시간을 사용해요. 즉 장애 조치는 단순히 네트워크 왕복 시간이 증가하는 순서로 다른 원격 데이터센터를 시도할 수 있으며, 데이터센터가 생겼다 사라지거나 네트워크 문제를 겪으면 이 순서가 자동으로 조정돼요.
소개 부분의 예시를 동적 장애 조치 정책으로 확장한 것이 여기 있어요:
$ curl http://127.0.0.1:8500/v1/query \
--request POST \
--data @- << EOF
{
"Name": "banking-app",
"Service": {
"Service": "banking-app",
"Tags": ["v1.2.3"],
"Failover": {
"NearestN": 2
}
}
}
EOF
이 쿼리는 "dc1" 또는 "dc2", 또는 아마도 다른 데이터센터의 선택이 자동으로 이루어진다는 점을 제외하고는 이전 예시와 유사한 방식으로 해석돼요.
하이브리드 정책 (Hybrid policy)
동일한 정책에서 Datacenters와 NearestN을 결합하는 것이 가능해요. NearestN 쿼리가 먼저 수행되고 그 다음 Datacenters가 제공한 목록이 수행돼요.
$ curl http://127.0.0.1:8500/v1/query \
--request POST \
--data @- << EOF
{
"Name": "banking-app",
"Service": {
"Service": "banking-app",
"Tags": ["v1.2.3"],
"Failover": {
"NearestN": 2,
"Datacenters": ["dc2", "dc3"]
}
}
}
EOF
참고로, 어떤 데이터센터는 NearestN과 Datacenters 모두에 의해 선택되더라도 장애 조치 중에 한 번만 쿼리돼요. 이는 제한된 횟수의 왕복 시간 기반 시도를 허용한 다음 장애 조치할 알려진 데이터센터에 대한 정적 구성을 따르는 데 유용해요.
준비된 쿼리 템플릿 (Prepared query template)
많은 서비스가 있는 데이터센터에서는 각 서비스에 대한 지리 장애 조치 정책을 정의하는 것이 어려울 수 있어요. 이 어려움을 해소하기 위해 Consul은 하나의 준비된 쿼리가 많고 심지어 모든 서비스에 적용될 수 있게 하는 준비된 쿼리 템플릿을 제공해요.
템플릿은 접두사로 매칭하거나 전체 정규식을 사용해 어떤 서비스와 매칭되는지 결정할 수 있어요.
다음은 쿼리 조회(*.query.consul)로 접근되는 모든 서비스에 동적 지리 장애 조치의 catch-all 정책을 적용하는 준비된 쿼리 템플릿을 생성하는 요청 예시예요. name_prefix_match 유형과 빈 이름을 지정하면 이 쿼리 템플릿의 정책은 더 높은 우선 순위의 쿼리와 일치하지 않는 모든 이름(<name>.query.consul)에 적용돼요.
$ curl http://127.0.0.1:8500/v1/query \
--request POST \
--data @- << EOF
{
"Name": "",
"Template": {
"Type": "name_prefix_match"
},
"Service": {
"Service": "${name.full}",
"Failover": {
"NearestN": 2
}
}
}
EOF
참고 (Note)
여러 쿼리가 등록되면 가장 구체적인 쿼리가 선택되므로 이와 같은 템플릿을 catch-all로 사용한 다음 특정 서비스에 더 구체적인 정책을 적용하는 것이 가능해요.
이 하나의 준비된 쿼리 템플릿을 마련하면 애플리케이션 구성을 DNS를 통해 banking-app.service.consul 대신 banking-app.query.consul을 조회하도록 변경하기만 해도 네트워크 왕복 시간이 증가하는 순서로 가장 가까운 다음 페더레이션 Consul 데이터센터로 자동 지리 장애 조치가 발생해요.
다음 단계 (Next steps)
이 튜토리얼에서 Consul을 다른 애플리케이션과 통합할 때 준비된 쿼리를 장애 조치에 사용하는 방법을 배웠어요. 이제 가장 가까운 페더레이션 데이터센터 또는 보조 데이터센터 목록으로 장애 조치하도록 정책을 구성할 수 있어요. 또한 각 개별 서비스에 대한 정책을 만드는 복잡성을 줄이는 데 도움이 되는 준비된 쿼리 템플릿을 만들 수도 있어요.