대규모 Consul 운영을 위한 권장 사항
대규모 Consul 운영을 위한 권장 사항 (Recommendations for Operating Consul at Scale)
이 페이지는 Consul의 아키텍처가 대규모 배포의 성능에 어떤 영향을 미치는지 설명하고, 대규모 프로덕션에서 Consul을 운영하기 위한 권장 사항을 공유해요.
출처: 문서
본문
개요 (Overview)
Consul은 사용자 워크로드 옆에 배치된 사이드카를 사용해 네트워크 활동을 조정하는 중앙 집중식 서버 집합으로 배포되는 분산 서비스 네트워킹 시스템이에요. Consul이 서비스 메시 기능으로 사용될 때 서버는 서비스 인스턴스 옆에서 실행되는 Envoy 프록시에 대한 구성도 생성해요. 이러한 프록시는 종단 간 mTLS 및 점진적(progressive) 배포 같은 서비스 메시 기능을 지원해요.
Consul은 단일 데이터 센터 또는 WAN 페더레이션 또는 피어링 연결을 구축해 여러 데이터 센터에 걸쳐 배포할 수 있어요. 이 맥락에서 데이터 센터는 호스트가 낮은 네트워킹 지연으로 통신할 수 있는 명명된 환경을 말해요. 일반적으로 사용자는 Consul 데이터 센터를 AWS us-east-1 또는 Azure East US 같은 클라우드 제공자 지역에 매핑해요.
일관성과 고가용성을 보장하기 위해 Consul 서버는 Raft 합의 프로토콜을 사용해 데이터를 공유해요. 데이터를 영구 저장할 때 Consul은 Raft 로그 저장에 BoltDB를 사용하고 상태 스냅샷에는 사용자 지정 파일 형식을 사용해요. 자세한 내용은 Consul 아키텍처를 참고해요.
일반 배포 권장 사항 (General deployment recommendations)
이 섹션은 대규모로 Consul을 운영하기 위한 일반적인 구성 및 모니터링 권장 사항을 제공해요.
데이터 플레인 복원력 (Data plane resiliency)
서비스 간 통신이 중단 및 장애에 대해 복원력이 있도록 하려면 서비스의 여러 서비스 인스턴스를 장애 도메인 전반에 걸쳐 분산할 것을 권장해요. 복원력 있는 배포는 다음의 배수(multiples)로 서비스를 분산시켜요:
- 인프라 수준의 가용성 영역
- Kubernetes 클러스터 같은 런타임 플랫폼 인스턴스
- Consul 데이터 센터
개별 도메인이 장애를 겪더라도 다른 도메인의 정상 인스턴스는 계속 검색될 수 있도록 서비스 장애 조치(failover)가 보장해요. Consul은 단일 admin partition 또는 데이터 센터 내의 인스턴스 간에 서비스 장애 조치를 자동으로 제공해요.
Consul 데이터 센터 간 서비스 장애 조치는 사용하기 전에 데이터 센터에서 구성해야 해요. 다음 방법 중 하나를 사용해 데이터 센터 간 장애 조치를 구성해요:
- Consul 서비스 메시를 사용하는 경우 : service-resolver 구성 항목을 사용해 장애 조치를 구현해요.
- 서비스 메시 없이 Consul 서비스 디스커버리를 사용하는 경우 : prepared queries를 사용한 지리적 중복 장애 조치를 구현해요.
컨트롤 플레인 복원력 (Control plane resiliency)
단일 데이터 센터에 많은 수의 서비스가 배포되면 Consul 서버가 더 느린 네트워크 성능을 경험할 수 있어요. 컨트롤 플레인을 성능 저하 및 중단에 대해 더 복원력 있게 만들려면 배포를 가용성 영역, 런타임, 데이터 센터에 분산시켜 개별 데이터 센터의 크기를 제한해요.
데이터 센터 크기 (Datacenter size)
복원력을 보장하기 위해 Consul 데이터 센터당 최대 5,000개의 Consul 클라이언트 에이전트로 배포를 제한할 것을 권장해요. 이 권장 사항에는 두 가지 이유가 있어요:
- 블래스트 반경 감소 (Blast radius reduction) : Consul이 데이터 센터나 지역에서 서버 중단을 겪을 때 블래스트 반경(blast radius) 은 그 결과로 더 이상 통신할 수 없는 해당 데이터 센터에 연결된 Consul 클라이언트 또는 데이터플레인의 수를 말해요. 블래스트 반경의 크기를 줄이기 위해 단일 Consul 데이터 센터에 연결된 총 클라이언트 수를 제한할 것을 권장해요. Consul은 10,000개 이상의 노드로 클러스터를 실행할 수 있지만, 중단 후 더 큰 배포를 다시 온라인 상태로 만드는 데 더 오래 걸리며 이는 복구 시간에 영향을 미쳐요.
- 에이전트 gossip 관리 (Agent gossip management) : Consul 에이전트는 gossip 프로토콜을 사용해 gossip 풀에서 멤버십 정보를 공유해요. 기본적으로 단일 Consul 데이터 센터의 모든 클라이언트 에이전트는 단일 gossip 풀에 있어요. 에이전트가 gossip 풀에 참여하거나 떠날 때마다 다른 에이전트가 해당 이벤트를 풀 전체에 전파해요. Consul 데이터 센터가 에이전트 변동(agent churn) 즉 에이전트가 단일 풀에 참여하고 떠나는 비율이 지속적으로 높은 경우, gossip 메시지가 전송될 수 있는 속도보다 빠르게 생성되어 클러스터 성능에 영향을 줄 수 있어요. 그 결과 메시지 대기열이 계속 증가해요.
이러한 위험을 완화하기 위해 단일 gossip 풀에 최대 5,000개의 Consul 클라이언트 에이전트를 권장해요. gossip 풀을 더 작게 만드는 몇 가지 전략이 있어요:
- 인프라의 각 호스트에서 정확히 하나의 Consul 에이전트를 실행해요.
- 단일 Consul 데이터 센터를 여러 개의 더 작은 데이터 센터로 분할해요.
- Enterprise 사용자는 네트워크 세그먼트를 정의해 Consul 데이터 센터의 단일 gossip 풀을 여러 개의 더 작은 풀로 나눌 수 있어요.
사용 사례에 적합하다면 단일 Consul 데이터 센터를 여러 개의 더 작은 데이터 센터로 분할할 것을 권장해요. 여러 데이터 센터를 실행하면 네트워크 세그먼트를 적용하는 것보다 네트워크의 블래스트 반경을 더 줄여요.
5,000이라는 숫자는 배포에 대한 경험적 수치(heuristic)라는 점에 유의해요. 데이터 센터당 배포하는 에이전트 수는 Consul 자체가 아니라 성능에 의해 제한돼요. gossip 안정성 위험은 노드 수 가 아니라 에이전트 변동 속도 에 의해 결정되므로, 대부분 정적인 노드로 구성된 gossip 풀은 5,000개 이상의 에이전트로도 효과적으로 작동할 수 있어요. 반면 스팟 플릿 인스턴스와 서버리스 함수처럼 매일 에이전트의 10%가 교체되는 매우 동적인 에이전트가 있는 gossip 풀은 5,000개 미만이어야 할 수 있어요.
이러한 권장 사항을 생성하기 위해 대규모 Consul 배포에서 수행한 특정 테스트에 대한 추가 정보는 HashiCorp 블로그의 Consul Scale Test Report to Observe Gossip Stability를 참고해요.
대부분의 사용 사례에서 5,000개 에이전트 제한이 적절해요. consul.serf.queue.Intent 메트릭이 지속적으로 높으면 gossip 풀이 지속적인 변동 수준을 따라잡지 못하고 있다는 표시예요. 이 상황에서는 데이터 센터당 에이전트 수를 줄여 변동을 줄여요.
Kubernetes별 지침 (Kubernetes-specific guidance)
Kubernetes에서는 같은 pod에서 실행되는 서비스 옆 pod 안에 Consul 에이전트를 배포하는 것이 가능하지만, 이 지원되지 않는 배포 패턴은 대규모에서 알려진 성능 문제가 있어요. 대규모에서 Kubernetes의 pod 등록 및 등록 해제는 gossip 불안정을 일으켜 서비스가 비정상으로 표시됨에 따라 연쇄적 장애로 이어질 수 있으며, 이는 추가 클러스터 변동을 초래해요.
Consul v1.14 이상에서 Consul on Kubernetes는 서비스 디스커버리와 서비스 메시를 위해 클러스터의 모든 노드에서 클라이언트 에이전트를 실행할 필요가 없어요. 이 배포 구성은 데이터 플레인의 Consul 리소스 사용량을 낮추지만, xDS 리소스를 처리하기 위해 컨트롤 플레인의 추가 리소스가 필요해요. 자세한 내용은 Consul Dataplane을 사용한 간소화된 서비스 메시 및 Consul의 xDS 로드 밸런싱을 참고해요.
Kubernetes와 Consul을 Vault의 백엔드로 사용하는 경우 : Consul 대신 Vault의 통합 스토리지(integrated storage) 백엔드를 사용해요. 런타임 의존성 충돌로 인해 Consul 데이터플레인이 Vault와 호환되지 않아요. Kubernetes 배포에서 Vault의 백엔드로 Consul v1.14 이상을 사용해야 한다면, 다른 Consul 서버와 페더레이션되거나 피어링되지 않은 별도의 Consul 데이터 센터를 만들어요. 필요에 따라 이 데이터 센터의 크기를 조정하고 Vault용 백엔드 스토리지로만 독점적으로 사용할 수 있어요.
Consul 서버 배포 권장 사항 (Consul server deployment recommendations)
Consul 서버 에이전트는 Consul 아키텍처의 중요한 부분이에요. 이 섹션은 관리형 및 자체 관리형 서버 실행의 차이점, 실행할 서버 수에 대한 권장 사항, 중복 영역에 서버를 배포하는 방법, 하드웨어 요구 사항, 클라우드 제공자 통합을 요약해요.
Consul 서버 런타임 (Consul server runtimes)
Consul 서버는 몇 가지 다른 런타임에 배포할 수 있어요:
- VM 또는 베어메탈 서버 (자체 관리형) . VM 또는 베어메탈 서버에서 Consul을 시작하려면 Deploy Consul server 튜토리얼을 참고해요. 전체 구성 옵션 목록은 Agents Overview를 참고해요.
- Kubernetes (자체 관리형) . Kubernetes에서 Consul을 시작하려면 Deploy Consul on Kubernetes 튜토리얼을 참고해요.
- Docker, Rancher, Mesos를 포함한 기타 컨테이너 환경 (자체 관리형) .
대규모로 Consul을 운영할 때 자체 관리형 VM 또는 베어메탈 서버 배포가 가장 유연성을 제공해요. 중복 영역 및 read replicas 같은 장애 허용성과 읽기 확장성을 향상시킬 수 있는 일부 Consul Enterprise 기능은 Kubernetes 런타임의 서버 에이전트에 사용할 수 없어요. 자세한 내용은 런타임별 Consul Enterprise 기능 가용성을 참고해요.
Consul 서버 수 (Number of Consul servers)
네트워크에 배포할 Consul 서버 수를 결정하는 데 두 가지 핵심 고려 사항이 있어요:
- 장애 허용성 (Fault tolerance) : 쿼럼을 유지하면서 배포가 견딜 수 있는 서버 중단 수. 서버를 추가하면 네트워크의 장애 허용성이 높아져요.
- 성능 확장성 (Performance scalability) : 더 많은 요청을 처리하려면 추가 서버가 지연을 만들고 쿼럼 프로세스를 느리게 해요. 서버가 너무 많으면 네트워크를 돕는 대신 방해해요.
장애 허용성이 얼마나 많은 Consul 서버 에이전트를 배포할지에 대한 초기 결정을 결정해야 해요. 배포할 서버 수에 대한 우리의 권장 사항은 Consul Enterprise 중복 영역에 접근할 수 있는지 여부에 따라 달라져요:
- 중복 영역 사용 시 : 3개의 가용성 영역에 6개의 Consul 서버를 배포해요. 이 배포는 3개 서버 배포의 성능과 7개 서버 배포의 장애 허용성을 제공해요.
- 중복 영역 없이 : 3개의 가용성 영역에 5개의 Consul 서버를 배포해요. 5개 서버 모두 read replicas가 아닌 투표(voting) 서버여야 해요.
자세한 내용은 Improving Consul Resilience를 참고해요.
서버 요구 사항 (Server requirements)
서버 노드가 충분한 크기인지 확인하려면 Consul 서버용 하드웨어 크기 조정을 검토할 것을 권장해요. 네트워크가 무거운 워크로드를 처리해야 하는 경우 읽기 집약적 워크로드 소스 및 해결책과 쓰기 집약적 워크로드 소스 및 해결책의 권장 사항을 참고해요.
파일 디스크립터 (File descriptors)
Consul의 에이전트는 다른 노드 및 에이전트와의 gossip 통신에 네트워크 소켓을 사용해요. 그 결과 서버는 클라이언트의 연결, 다른 서버의 연결, watch 핸들러, 헬스 체크, 로그 파일에 대한 파일 디스크립터를 만들어요. 쓰기 집약적인 클러스터의 경우 기본값인 1024에서 파일 디스크립터 수에 대한 크기 제한을 늘려야 해요. 클러스터의 예상 클라이언트 수보다 두 배 높은 숫자를 사용할 것을 권장해요.
오토 스케일링 그룹 (Auto scaling groups)
오토 스케일링 그룹(ASG)은 배포에 대해 특정 수의 복제본을 사용할 수 있도록 보장하는 데 사용되는 클라우드 제공자의 인프라 연결이에요. Consul 서버에 ASG를 사용할 때는 Raft 부트스트래핑과 쿼럼 유지에 대한 특정 요구 사항과 프로세스가 있어요.
클러스터 생성 중에는 bootstrap-expect 명령줄 플래그를 사용할 것을 권장해요. 그러나 클러스터에 추가할 새 서버를 생성하거나 서버를 업그레이드할 때 자동으로 부트스트랩하도록 구성하지 마세요. 이러한 복제본에 bootstrap-expect가 설정되어 있으면 별도의 Raft 시스템을 만들어 스플릿 브레인(split brain) 을 일으키고 오류와 전반적인 클러스터 불안정을 초래할 수 있어요.
경고 (Warning): 자동 제거되는 Consul 서버 노드와 함께 오토 스케일링 그룹을 사용하면 Consul 데이터 센터에 심각한 중단이 발생할 수 있어요. Consul 노드의 자동 확장과 관련된 위험을 완화하려면 'No cluster leader' 문제 방지를 참고해요.
NUMA 아키텍처 인식 (NUMA architecture awareness)
일부 클라우드 제공자는 NUMA(Non-Uniform Memory Access) 아키텍처를 가진 매우 큰 인스턴스 크기를 제공해요. Go 런타임이 NUMA를 인식하지 못하기 때문에 Consul은 NUMA를 인식하지 못해요. NUMA 아키텍처에서 Consul을 실행할 수는 있지만 다중 처리 기능을 활용하지는 않아요.
일관성 모드 (Consistency modes)
Consul은 DNS 및 HTTP API 모두에 대해 서로 다른 일관성 모드를 제공해요.
DNS
대규모로 운영할 때 성능을 일관성보다 우선시하려면 DNS 조회에 stale 일관성 모드를 사용할 것을 강력히 권장해요. 기본적으로 활성화되어 있으며 dns_config.allow_stale로 구성돼요.
또한 DNS 응답의 지연(staleness)을 제한하도록 dns_config.max_stale을 구성하지 않는 것을 권장해요. Consul 서버가 과부하되면 장기간 중단이 발생할 수 있기 때문이에요. 서비스에 경계가 있는 결과 일관성이 필요한 경우 DNS 조회 대신 일관된 서비스 디스커버리 HTTP API 쿼리를 사용하도록 서비스를 수정하는 것을 고려해요.
대규모로 Consul을 운영할 때 dns_config.use_cache를 사용하지 마세요. Consul 에이전트 캐시는 요청된 각 경로에 대해 메모리를 할당하고 각 할당은 최대 3일 동안 유지될 수 있으므로 심각한 메모리 문제가 발생할 수 있어요. DNS 캐싱을 구현하려면 대신 서비스 및 노드에 대한 TTL을 구성해 DNS 클라이언트가 Consul의 응답을 캐시하도록 하는 것을 권장해요.
HTTP API
기본적으로 모든 HTTP API 읽기 요청은 요청별로 재정의되지 않는 한 default 일관성 모드를 사용해요. HTTP API 요청의 기본 일관성 모드를 변경하지 않는 것을 권장해요.
또한 HTTP 응답의 지연을 제한하도록 http_config.discovery_max_stale을 구성하지 않는 것을 권장해요.
리소스 사용량 및 메트릭 권장 사항 (Resource usage and metrics recommendations)
Consul을 운영하는 동안 Consul 서버 에이전트의 CPU 부하를 모니터링하고 에이전트 텔레메트리의 메트릭을 사용해 원인을 파악해요. 과도한 리소스 사용을 완화하는 절차는 부하가 읽기 작업, 쓰기 작업 또는 Consul의 합의 프로토콜에 의해 발생하는지 여부에 따라 달라져요.
읽기 집약적 워크로드 소스 및 해결책 (Read-heavy workload sources and solutions)
가장 높은 CPU 부하는 일반적으로 현재 리더에 속해요. CPU 부하가 높으면 요청 부하가 주요 기여 요인일 가능성이 높아요. 다음 서버 헬스 메트릭을 확인해요:
consul.rpc.*- 기존 RPC 메트릭. 읽기 집약적인 워크로드에서 서버 CPU 부하를 이해하는 가장 관련성 높은 메트릭은consul.rpc.query와consul.rpc.queries_blocking이에요.consul.grpc.server.*- 서버가 처리하는 스트림 수에 대한 메트릭.consul.xds.server.*- 서버가 처리하는 Envoy xDS 리소스에 대한 메트릭. Consul v1.14 이상에서 이러한 메트릭은 상당한 읽기 부하의 원인이 될 수 있어요. 자세한 내용은 Consul dataplanes을 참고해요.
필요에 따라 다음 전략 중 하나를 선택해 서버 CPU 부하를 완화해요:
- 가장 빠른 완화 전략은 서버를 수직 확장(vertically scale)하는 것이에요. 그러나 이 전략은 컴퓨팅 비용을 증가시키고 무한정 확장되지 않아요.
- 가장 효과적인 장기 완화 전략은 가능한 한 많은 읽기 요청에 대해 stale 일관성 모드를 사용하는 것이에요. Consul v1.12 이상에서 운영자는
consul.rpc.server.call메트릭을 사용해 Consul 서버로 이루어진 가장 빈번한 읽기 요청 유형을 식별할 수 있어요. 결과를 각 엔드포인트의 HTTP API 문서와 교차 참조하고 stale 일관성을 지원하는 엔드포인트에 대해 stale 일관성을 사용해요. - 대부분의 읽기 요청이 이미 stale 일관성 모드를 사용하고 여전히 요청 부하를 줄여야 한다면 배포에 투표하지 않는(non-voting) 서버를 더 추가해요. 중복 영역 또는 read replicas를 사용해 쓰기 지연에 영향을 주지 않고 읽기를 확장할 수 있어요. 중복 영역에 서버를 더 추가할 것을 권장합니다. 장애 허용성과 stale 읽기 확장성을 모두 향상시키기 때문이에요.
- Consul v1.14 이상에서 서버는 Consul Dataplane 배포에 대한 Envoy XDS 스트림을 stale 일관성 모드로 처리해요. 그 결과 서버 일관성 모드는 구성할 수 없어요. XDS 스트림과 관련된 문제를 식별하려면
consul.xds.server.*메트릭을 사용해요.
쓰기 집약적 워크로드 소스 및 해결책 (Write-heavy workload sources and solutions)
Consul은 디스크 I/O에 의해 쓰기가 제한돼요. 쓰기 집약적인 워크로드의 경우 NVMe 디스크를 사용할 것을 권장해요.
시작점으로 하드웨어가 대규모 서버 클러스터에 대한 요구 사항(7500+ IOps 및 250+ MB/s 디스크 처리량)을 충족하는지 확인해야 해요. IOps는 예상 쓰기 속도의 약 5~10배여야 해요. 네트워크의 특정 요구를 이해하려면 디스크 크기 조정과 예상 쓰기 속도에 대해 추가 분석을 수행해요.
AWS EBS 같은 네트워크 스토리지를 사용하는 경우 프로비저닝된 I/O 볼륨을 권장해요. 범용 볼륨은 제대로 작동하지만 버스트 가능한 IOps로 인해 용량 계획이 더 어려워져요. 작은 쓰기 피크는 경보를 트리거하지 않을 수 있지만, 사용량이 증가함에 따라 버스트 한도가 소진되고 워크로드 성능이 저하되는 지점에 도달할 수 있어요.
자세한 내용은 서버 성능 읽기/쓰기 튜닝을 참고해요.
Raft 데이터베이스 성능 소스 및 해결책 (Raft database performance sources and solutions)
Consul 서버는 Raft 합의 프로토콜을 사용해 일관되고 장애 허용적인 상태를 유지해요. Raft는 대부분의 Consul 데이터를 인덱싱이 있는 인메모리 데이터베이스인 MemDB 데이터베이스에 저장해요. 재시작 및 정전을 견디기 위해 Consul은 BoltDB를 사용해 Raft 로그를 디스크에 기록해요. 쓰기 상태를 감지하기 위한 메트릭에 대한 자세한 내용은 Agent telemetry를 참고해요.
전체 트랜잭션 성능을 모니터링하려면 트랜잭션 타이밍 메트릭의 급증을 확인해요. Raft 복제 용량 문제 메트릭을 사용해 Raft 로그 스냅샷과 복원을 모니터링할 수도 있어요. 급증과 더 긴 지속 시간은 전체 쓰기 및 디스크 경합 문제의 증상일 수 있기 때문이에요.
Consul v1.11 이상에서는 consul.raft.boltdb.* 메트릭으로 Raft 성능을 모니터링할 수도 있어요. 정상 운영 패턴 이상으로 활동이 증가하는 consul.raft.boltdb.storeLogs를 모니터링할 것을 권장해요.
에이전트 메트릭 및 사용 방법에 대한 자세한 내용은 Consul agent telemetry를 참고해요.
Raft 데이터베이스 크기 (Raft database size)
Raft는 단일 성장 전용(grow-only) 파일로 설계된 BoltDB에 로그를 기록해요. 그 결과 1GB의 로그 항목을 추가한 다음 스냅샷을 찍으면 파일에 최근 로그 항목만 일부 표시될 수 있어요. 그러나 디스크의 실제 파일은 늘어난 1GB 크기보다 더 작아지지 않아요.
디스크 공간을 회수해야 하는 경우 bbolt CLI를 사용해 데이터를 새 데이터베이스에 복사하고 프로세스에서 새 데이터베이스를 가리키도록 다시 지정해요. 그러나 bbolt compact 명령은 새 데이터베이스를 가리키는 동안 데이터베이스가 오프라인 상태여야 한다는 점에 유의해요.
대규모 클러스터를 포함한 많은 경우 Raft 로그가 작은 GiB 수보다 더 커지는 경우가 거의 없기 때문에 디스크 공간은 주된 관심사가 아니에요. 그러나 여유 공간이 많은 커진 파일은 프리리스트(freelist) 관리 로 인해 전체 쓰기 성능을 크게 저하시켜요.
디스크에 기록된 후 Raft 로그는 결국 스냅샷에 캡처되고 로그 노드는 BoltDB에서 제거돼요. BoltDB는 제거된 노드의 페이지를 자체 프리리스트에 추적해요. BoltDB는 Raft 쓰기가 있을 때마다 이 프리리스트도 디스크에 기록해요. Raft 로그가 빠르게 커지다가 잘리면 프리리스트의 크기가 매우 커질 수 있어요. 우리에게 보고된 최악의 경우 프리리스트가 10MB를 초과했어요. 이 큰 프리리스트가 모든 Raft 커밋에서 디스크에 기록되면 작아야 할 Raft 커밋에 대해 큰 쓰기 증폭(write amplification)이 발생해요.
Consul 서버의 디스크 성능 문제가 BoltDB의 프리리스트 때문인지 파악하려면 다음 전략을 시도해요:
- 서버로의 인바운드 네트워크 대역폭을 디스크 쓰기 대역폭과 비교해요. 디스크 쓰기 대역폭 이 인바운드 네트워크 대역폭 의 5배 이상이면 디스크에 프리리스트 관리 성능 문제가 있을 가능성이 높아요. BoltDB 프리리스트는 5:1보다 낮은 비율에서도 문제를 일으킬 수 있지만, 높은 쓰기 대역폭 대 인바운드 대역폭 비율은 BoltDB 프리리스트가 문제를 일으키고 있다는 신뢰할 수 있는 지표예요.
consul.raft.leader.dispatchLog메트릭을 사용해 로그 배치를 디스크에 쓰는 데 걸리는 시간에 대한 정보를 얻어요.- Consul v1.13 이상에서는 Raft 스레드 포화 메트릭을 사용해 Raft가 디스크 제한으로 인해 백프레셔를 경험하고 새 작업을 수락할 수 없는지 파악할 수 있어요.
Consul v1.11 이상에서 raftboltdb.NoFreelistSync를 true로 설정해 BoltDB가 프리리스트를 디스크에 기록하는 것을 방지할 수 있어요. 이 설정은 BoltDB가 프리리스트를 메모리에 유지하도록 해요. 그러나 BoltDB가 다시 시작되면 프리리스트를 수동으로 만들기 위해 데이터베이스 파일을 스캔해야 한다는 점에 유의해요. 시작 시 작은 지연이 발생할 수 있어요. 빠른 디스크에서 250MiB의 사용 페이지만 있는 5GiB 크기의 raft.db 파일에 대해 이러한 지연을 수십 초 수준으로 측정했어요.
일반적으로 raftboltdb.NoFreelistSync를 true로 설정하면 다음과 같은 효과가 발생해요:
- 디스크에 기록되는 데이터 양을 줄임
- 시작 시 raft.db 파일을 로드하는 데 걸리는 시간을 늘림
운영자가 개별 우려 사항에 따라 네트워크를 최적화할 것을 권장해요. 예를 들어 서버가 디스크 성능 문제에 직면했지만 Consul 서버가 자주 다시 시작되지 않는 경우 raftboltdb.NoFreelistSync를 true로 설정하면 문제가 해결될 수 있어요. 그러나 같은 조치는 대용량 데이터베이스 파일과 잦은 서버 재시작이 있는 배포에는 문제를 일으켜요.
Raft 스냅샷 (Raft snapshots)
각 상태 변경은 Raft 로그 항목을 생성하고 각 Consul 서버는 동일한 로그 항목 시퀀스를 수신하므로 서버는 같은 상태를 공유해요. Raft 로그 시퀀스는 리더가 상태 기록의 스냅샷 으로 주기적으로 압축해요. 이러한 스냅샷은 Raft 내부에 있으며 Consul의 API를 통해 생성되는 스냅샷과는 다르지만, 동일한 데이터를 포함해요. Raft 스냅샷은 서버의 데이터 디렉터리 raft/ 폴더에 raft.db의 로그와 함께 저장돼요.
새 Consul 서버를 추가하면 현재 상태를 따라잡아야 해요. 리더에게서 최신 스냅샷을 받은 다음 해당 스냅샷과 리더의 현재 상태 사이의 로그 시퀀스를 받아요. 각 Raft 로그에는 시퀀스 번호가 있고 각 스냅샷에는 스냅샷에 포함된 마지막 시퀀스 번호가 포함돼요. 쓰기 집약적인 워크로드, 큰 상태, 혼잡한 네트워크 또는 바쁜 서버의 조합으로 인해 새 서버가 리더에게서 필요한 다음 로그가 이미 잘리기 전에 현재 상태를 따라잡기 어려울 수 있어요. 그 결과 스냅샷 설치 루프(snapshot install loop) 가 발생해요.
예를 들어 리더의 스냅샷 A가 인덱스 99를 갖고 현재 인덱스가 150이라면, 새 서버가 온라인 상태가 되면 리더는 스냅샷 A를 새 서버로 스트리밍해 복원하게 해요. 그러나 이 스냅샷은 새 서버가 인덱스 99까지만 따라잡을 수 있게 해요. 새 서버는 여전히 인덱스 150까지 따라잡아야 할 뿐만 아니라, 그 동안 리더는 계속 Raft 로그를 커밋해요.
리더가 인덱스 199에서 스냅샷 B를 찍으면 스냅샷 A와 스냅샷 B 사이에 축적된 로그를 잘라내는데, 즉 100에서 199 사이의 인덱스를 가진 Raft 로그를 잘라내요.
새 서버가 스냅샷 A를 복원했으므로 새 서버의 현재 인덱스는 99예요. 복제 복원 프로세스를 시작할 때 현재 인덱스가 150이었으므로 로그 100150을 요청해요. 이 시점에서 리더는 로그 200 이상만 가지고 있고 인덱스 100150에 대한 로그는 없음을 인식해요. 리더는 새 서버의 상태가 오래되었다고 판단하고 최신 스냅샷인 스냅샷 B를 새 서버에 보내 프로세스를 다시 시작해요.
Consul은 스냅샷 설치 루프가 반복되는 것을 방지하기 위해 구성 가능한 수의 Raft trailing logs를 유지해요. trailing logs는 스냅샷에 들어간 마지막 로그이며 새 서버는 이러한 로그를 사용해 현재 상태를 더 쉽게 따라잡을 수 있어요. 기본 Raft trailing logs 구성 값은 대부분의 배포에 적합해요.
Consul v1.10 이상에서 운영자는 Consul 서버의 consul.raft.rpc.installSnapshot 및 consul.raft.leader.oldestLogAge 타이밍 메트릭을 모니터링하고 비교해 스냅샷 설치 루프를 방지할 수 있어요. 다음 상황에 대해 이러한 메트릭을 모니터링해요:
- 잘린 후
consul.raft.leader.oldestLogAge의 최저 숫자는 항상consul.raft.rpc.installSnapshot의 최저 숫자보다 최소 2배는 높아야 해요. - 이러한 메트릭이 너무 가까우면 Raft trailing logs 수를 늘려
consul.raft.leader.oldestLogAge를 증가시켜요. 쓰기 처리량과 지연에 부정적인 영향을 줄 수 있으므로 Raft trailing logs를 필요 이상으로 높게 설정하지 마세요.
자세한 내용은 Raft Replication Capacity Issues를 참고해요.
특정 사용 사례에 대한 성능 고려 사항 (Performance considerations for specific use cases)
이 섹션은 우선시하는 기능과 사용 사례에 따른 Consul 배포에 대한 구성 및 모니터링 권장 사항을 제공해요.
서비스 디스커버리 (Service discovery)
서비스 디스커버리 성능을 최적화하려면 일관된 수의 서비스 인스턴스와 watch를 가진 여러 개의 작은 클러스터를 배포할 것을 권장해요.
주로 서비스 디스커버리 및 헬스 체크 기능에 사용될 때 대규모에서 Consul 성능에 영향을 주는 몇 가지 요소가 있어요. 사용자가 제어할 수 있는 요소는 다음과 같아요:
- 등록된 총 서비스 인스턴스 수
- DNS 쿼리에서 stale reads 사용
- 서비스의 인스턴스(등록 및 헬스 상태 포함) 변경을 위해 Consul을 모니터링하는 Consul 클라이언트 에이전트 또는 데이터플레인 구성 요소 같은 엔티티 수. 서비스 변경이 발생할 때마다 이러한 엔티티는 상태 변경을 처리하고 서비스에 대해 이전에 알려진 데이터와 조정해야 하므로 계산 비용이 발생해요. 또한 Consul 서버 에이전트도 이러한 업데이트를 보낼 때 계산 비용이 발생해요.
- 서비스 변경을 모니터링하는 watches 수.
- 다음 이벤트의 영향을 받는 카탈로그 업데이트 속도:
- 서비스 인스턴스의 헬스 체크 상태 변경
- 서비스 인스턴스의 노드가 Consul 서버에 대한 연결을 잃음
- 서비스 정의 파일의 내용 변경
- 서비스 인스턴스 등록 또는 등록 해제
- Kubernetes 또는 Nomad 같은 오케스트레이터가 서비스를 새 노드로 이동
이러한 요소는 서로 결합되어 발생할 수 있어요. 전반적으로 서버가 서비스 디스커버리를 위해 완료하는 작업량은 다음 요소의 곱이에요:
- 서비스 및 서비스 인스턴스 수가 증가함에 따라 변경되는 데이터 크기
- 카탈로그 업데이트 속도
- 활성 watch 수
클러스터가 성장함에 따라 이러한 요소가 증가하는 것이 일반적이므로 서버가 업데이트를 배포하는 데 필요한 CPU 및 네트워크 리소스가 결국 선형 성장을 초과할 수 있어요.
Consul에 등록하려는 서비스 인스턴스 옆에서 Consul 클라이언트 에이전트를 실행할 수 없는 상황(예: 외부 또는 레거시 인프라에 호스팅된 인스턴스)에서는 Consul ESM 사용을 권장해요.
Consul ESM은 외부 서비스에 대한 헬스 체크와 모니터링을 활성화해요. Consul ESM을 사용할 때 중복성을 보장하기 위해 여러 인스턴스를 실행할 것을 권장해요.
서비스 메시 (Service mesh)
Consul의 서비스 메시는 서비스 디스커버리 하위 시스템을 사용하므로 서비스 메시 성능도 일관된 수의 서비스 인스턴스와 watch를 가진 여러 개의 작은 클러스터를 배포함으로써 최적화돼요. 서비스 메시 성능은 다음 추가 요소의 영향을 받아요:
- 투명 프록시 기능은 클라이언트 에이전트가 하위 집합 대신 모든 서비스에 걸쳐 서비스 인스턴스 업데이트를 수신하도록 해요. 성능 문제를 방지하려면 투명 프록시 기능과 함께 관대한 의도(permissive intention)인
default: allow를 사용하지 말 것을 권장해요. 결합되면 모든 서비스 인스턴스 업데이트가 모든 프록시로 전파되어 추가 서버 부하를 일으켜요. - 내장 서비스 메시 CA 제공자를 사용할 때 Consul 리더는 서비스 메시 전반의 mTLS에 사용되는 인증서 서명을 담당해요. CPU 사용률에 미치는 영향은 총 서비스 인스턴스 수와 구성된 인증서 TTL에 따라 달라져요. CA 제공자 구성 옵션을 사용해 서버가 처리하는 요청 수를 제어할 수 있어요. 환경에 맞게
csr_max_concurrent와csr_max_per_second를 조정할 것을 권장해요.
K/V 저장소 (K/V store)
Consul의 K/V 저장소는 객체 저장소와 몇 가지 유사점이 있지만 기본 애플리케이션 데이터 저장소로 사용하지 말 것을 권장해요.
애플리케이션 구성 및 메타데이터에 Consul의 K/V 저장소를 사용할 때 성능을 최적화하려면 다음을 권장해요:
- 값은 512KB 미만이어야 하고 트랜잭션은 64개 작업 미만이어야 해요.
- 키스페이스(keyspace)가 잘 제한되어야 해요. 10,000개의 키는 성능에 영향을 미치지 않을 수 있지만 수백만 개의 키는 성능 문제를 일으킬 가능성이 더 높아요.
- 총 데이터 크기는 인덱스를 위한 추가 공간과 함께 메모리에 맞아야 해요. 인메모리 크기가 원시 키-값 크기의 3배가 되기를 권장해요.
- 총 데이터 크기는 1GB 미만으로 유지해야 해요. 더 큰 스냅샷은 적절히 빠른 하드웨어에서 가능하지만 복구 시간과 복제에 필요한 운영 복잡성을 크게 증가시켜요. 클러스터를 건강하게 유지하고 유지 관리 및 중단 중에 복구할 수 있도록 데이터 크기를 제한할 것을 권장해요.
- K/V 저장소는 읽기에 최적화되어 있어요. 서버 리소스와 용량을 변경해야 할 때를 알기 위해 클러스터 전체에서 초당 100회 업데이트를 초과한 후 업데이트 속도를 주의 깊게 모니터링할 것을 권장해요.
- K/V 저장소를 일반 목적 데이터베이스나 객체 저장소로 사용하지 말 것을 권장해요.
또한 K/V 저장소의 업데이트 속도가 높을 때 blocking query 메커니즘을 사용해 업데이트를 수신하지 말 것을 권장해요. K/V 결과가 너무 빨리 업데이트되면 blocking query 루프가 바쁜 루프(busy loop)로 저하돼요. 이러한 루프는 과도한 클라이언트 CPU를 소비하고 적절히 제한될 때까지 높은 서버 부하를 유발해요. 큰 키 접두사를 watch하는 것은 업데이트될 때마다 전체 키 접두사를 반환하는 것이 많은 대역폭을 빠르게 소비할 수 있으므로 문제를 해결할 가능성이 낮아요.
Vault용 백엔드 (Backend for Vault)
대규모에서 Vault용 백엔드로 Consul을 사용하면 Consul 서버의 메모리와 CPU 사용률이 증가해요. 또한 Vault에 저장되는 데이터 양과 데이터 업데이트 속도 모두에 비례하는 Consul 데이터 영구 계층의 무제한 증가를 생성해요.
Consul이 많은 양의 데이터를 처리하고 높은 쓰기 처리량을 가진 상황에서는 서버의 raft 복제 용량 및 상태에 대한 모니터링을 추가할 것을 권장해요. 저장된 데이터 크기가 충분히 커서 서버가 무거운 부하를 경험하면 팔로워가 복제를 따라잡지 못하고 재시작 후 투표자가 되지 못할 수 있어요. 이 상황은 서버가 디스크에서 복원하는 데 걸리는 시간이 리더가 새 스냅샷을 쓰고 로그를 자르는 데 걸리는 시간보다 길 때 발생해요. 자세한 내용은 Raft snapshots를 참고해요.
Vault v1.4 이상은 권장 스토리지 옵션으로 통합 스토리지(integrated storage)를 제공해요. 현재 Consul을 Vault의 스토리지 백엔드로 사용하고 있다면 통합 스토리지로 전환할 것을 권장해요. Vault의 통합 스토리지와 Vault용 백엔드로 Consul을 사용하는 것의 비교는 Vault 문서의 storage backends를 참고해요. Vault 백엔드를 Consul에서 Vault의 통합 스토리지로 마이그레이션하는 자세한 지침은 storage migration 튜토리얼을 참고해요. 통합 스토리지는 Consul 중단이 Vault 기능에도 영향을 주는 것을 방지해 복원력을 향상시켜요.
Raft 쿼럼 문제 방지 (Prevent Raft quorum issues)
Consul 서버는 클러스터 상태의 일관성 보장을 위해 Raft 합의 알고리즘에 의존해요.
그 결과 서버 에이전트를 한 번에 하나의 노드씩 롤링 방식으로 재구성해야 해요. 즉 각 노드를 영구적으로 제거하거나 추가한 후 다른 작업을 계속하기 전에 클러스터가 건강한 상태로 돌아오도록 허용해야 해요. 이상적으로 모든 노드가 건강해야 하지만 유효한 쿼럼은 다른 작업을 수행하기 전의 최소 요구 사항이에요.
예기치 않은 이벤트나 자동화가 이 규칙을 위반해 일시적인 사용 불가, 수동 복구가 필요한 쿼럼 상실, 심지어 데이터 손실을 포함한 다양한 문제를 초래할 수 있어요. Consul은 이 경우 'No cluster leader' 오류를 출력해요.
이 'No cluster leader' 오류를 생성할 수 있는 이벤트 및 자동화 예시는 다음과 같아요:
- 데이터 센터의 VM 장애
- K8s 클러스터의 노드 장애
- AWS Auto Scaling Group 및 Spot Instances
- Azure VM Scale Sets 및 Spot VMs
- GCP Managed Instance Group, SpotVms 및 Preemptible VMs
각 상황에서 Consul 서버 에이전트의 갑작스러운 제거로 인해 서버가 failed 상태로 이동할 수 있으며, 이는 Raft 피어 집합을 위험에 빠뜨려요.
Consul 데이터 센터를 이 오류에 대해 더 복원력 있게 만들려면 다음 모범 사례를 권장해요.
정기 백업 생성 (Create regular backups)
데이터의 최근 백업을 갖는 것은 중단이 없을 때조차 항상 최상의 상황이에요. 자세한 내용은 Consul 데이터 센터 백업 및 복원을 참고해요.
Enterprise
Enterprise 고객은 자동 백업을 사용해 정기 백업 계획을 수립할 수도 있어요.
Consul Autopilot 사용 (Use Consul Autopilot)
Enterprise
클러스터가 쿼럼을 잃지 않도록 방지하는 일부 로직과 결합되지 않는 한 부하 또는 사용량에 기반한 Consul 서버 노드의 자동 확장을 권장하지 않아요.
데이터 센터 복원력을 개선하고 자동 확장을 활용하는 한 가지 방법은 autopilot, read replicas 및 중복 영역을 사용하는 것이에요.
이러한 기능은 전체 클러스터의 안정성을 위험에 빠뜨리지 않으면서 읽기 집약적인 워크로드 기간을 지원해요.
leave_on_terminate 설정 (Set leave_on_terminate)
Consul 서버 에이전트가 leave_on_terminate를 true로 설정하면 TERM 신호를 받는 에이전트는 클러스터의 나머지에 leave 메시지를 보내고 정상적으로 떠나요.
이 설정은 노드가 정상적으로 떠날 기회 없이 항상 갑자기 실패할 수 있으므로 클러스터를 중단으로부터 완전히 보호하지는 못해요. 그러나 자동 확장 워크플로의 영향을 덜 하게 만들어요.
참고 (Note):
leave_on_terminate=true로 설정하면 모든 서버 인스턴스는 다시 기능하기 전에 클러스터를 떠나고, 다시 참여하고, 리더에게서 스냅샷을 다운로드해야 해요. 구성 변경을 적용하기 위해 Consul 에이전트 프로세스를 다시 시작하는 노드도 포함돼요. 그 결과 다시 시작이 더 느려질 수 있어요.
min_quorum 설정 (Set min_quorum)
프로덕션 환경에서 Consul Autopilot이 이 최소값에 도달하면 죽은 서버 가지치기를 중지하도록 Consul 데이터 센터의 min_quorum을 항상 설정해요.
중단에서 복구 (Recover from outages)
모든 완화 설정이 마련된 상태에서도 항상 수동 개입이 필요한 쿼럼 상실 상황에 처할 가능성이 있어요.
불일치 상태에서 Consul 데이터 센터를 복구하는 방법을 알아보려면 peers.json을 사용한 수동 복구를 참고해요.