Istio를 사용하여 메가 트래픽 서비스 관리하는 방법
들어가며…
에스티씨랩은 실시간으로 대량의 접속 요청을 제어하고, 방대한 봇 매크로를 탐지하고 차단하는 메가 트래픽 SaaS 플랫폼을 운영하고 있습니다. 수 백만 개의 동시 접속을 처리하고 악성 봇을 실시간으로 식별하려면 인프라 운영의 안정성 확보가 필수입니다. 이를 위해 에스티씨랩은 Istio를 사용하고 있습니다.
Istio는 애플리케이션 네트워크 기능을 유연하고 쉽게 자동화할 수 있는 투명한 언어 독립적 방법을 제공하는, 현대화된 서비스 네트워킹 레이어인 서비스 메시로 정의*됩니다. 클라우드 네이티브 애플리케이션을 구성하는 다양한 마이크로 서비스를 관리하는데 널리 사용되는 솔루션입니다.(*출처: Istio란 무엇인가요? - Google Cloud)
Istio는 방대한 기능 생태계를 제공하지만, 이 글에서는 실제 운영 환경에서 가장 중요하다고 판단되는 몇 가지 핵심 기능에 초점을 맞춘 활용 방안을 말씀드리고자 합니다. Istio 도입을 검토 중이거나 실제 활용 사례를 찾고 계신다면, 이 글에서 소개하는 기능들이 유용한 참고 자료가 되기를 바랍니다.
왜 Istio를 선택해야 할까요?
Istio는 컨테이너와 함께 배포된 Envoy 프록시를 관리하는 컨트롤 타워 역할을 합니다. 모든 Istio 구성(VirtualService, DestinationRule, AuthorizationPolicy)은 Envoy의 기본 구성으로 변환됩니다.
이 구조가 중요한 이유는 두 가지입니다. 첫째, Istio의 추상화된 기능만으로도 대부분의 상황을 깔끔하게 처리할 수 있기 때문입니다. 둘째, 표준 기능만으로 부족할 때는 EnvoyFilter를 통해 Envoy의 기능을 직접 제어할 수 있기 때문입니다. 저희는 인프라 전반에 걸쳐 이 두 가지 방식을 적절히 병행하여 사용하고 있습니다.
Proxy Protocol을 활용한 실제 클라이언트 IP 유지
봇 탐지 및 차단 플랫폼에서 정확한 클라이언트 IP 식별은 생명과도 같습니다. IP 정보가 부정확하면 봇 탐지 정확도가 급격히 떨어지기 때문입니다.
문제는 AWS NLB(Network Load Balancer)를 거치면서 발생합니다. 트래픽이 NLB를 통과하는 과정에서 클라이언트의 원본 IP가 손실되는 현상입니다. 저희는 이 문제를 해결하기 위해 EnvoyFilter의 Proxy Protocol을 적용해 이 문제를 해결했습니다.
참고: 소스 IP 보존 및 네트워크 토폴로지 구성에 대한 더 자세한 기술적 내용은 Istio 공식 블로그 게시물인 “게이트웨이 네트워크 토폴로지 구성”을 참조하시기를 강력히 권장합니다.
보안상 중요한 작업의 경우 X-Forwarded-For 헤더보다 X-Envoy-External-Address 헤더를 우선적으로 사용합니다. XFF 헤더와 달리 이 헤더는 Envoy 자체에서 설정하므로 외부 클라이언트에서 위조할 수 없습니다.
IP 기반 접속 제어
Swagger 문서와 같은 내부 전용 API는 반드시 보호되어야 합니다. 저희는 AuthorizationPolicy를 활용하여, 사내 오피스 IP 주소에서 발생하는 요청만 허용하도록 접근 권한을 제한하고 있습니다.
notRemoteIpBlocks 의 DENY 액션은 명시적으로 허용된 IP만 접근할 수 있는 화이트리스트를 생성합니다. 간단하면서도 효과적입니다.
쿼리 매개변수 기반 라우팅
메가 트래픽의 진입을 제어하는 에스티씨랩의 가상 대기실 솔루션, 넷퍼넬은 대기열 상태를 인메모리(in-memory) 방식으로 관리합니다. 데이터 일관성을 유지하기 위해, 각 테넌트(Tenant)의 요청은 반드시 동일한 백엔드 인스턴스로 전달되어야 합니다. 저희는 쿼리 파라미터를 활용해 특정 인스턴스로 연결되도록 명시적 라우팅을 구현했습니다.
왜 자동 해싱 대신 이 방식을 선택했나
이는 애플리케이션 팀과 협의하여 결정되었습니다. 클라이언트가 sticky 파라미터를 통해 대상 인스턴스를 직접 지정하게 함으로써 다음과 같은 이점을 얻을 수 있습니다.
확정적 라우팅(Deterministic Routing): 클라이언트는 자신의 요청을 처리할 인스턴스가 어디인지 정확히 파악할 수 있습니다.
디버깅 격리(Debug Isolation): 특정 테넌트에서 문제가 발생했을 때, 해당 테넌트를 특정 인스턴스로 몰아넣고 조사할 수 있습니다.
유연한 마이그레이션(Graceful Migration): 유지보수 시 테넌트를 인스턴스 간에 자연스럽게 이동시킬 수 있습니다.
대안: 일관된 해싱(Consistent Hash)
데이터 일관성이 아주 엄격할 필요가 없는 서비스에는 '일관된 해싱'을 사용합니다.
이 방식은 동일한 tenant_id를 가진 요청을 자동으로 동일한 백엔드에 자동 라우팅합니다. 현재 저희는 넷퍼넬의 핵심 대기열 서비스에는 명시적 라우팅을, 그 외 부가 서비스에는 일관된 해싱을 병행하여 사용하고 있습니다.
이상치 탐지를 통한 장애 자동 격리
단 하나의 비정상적인 포드(Pod)가 서비스 전체의 품질을 저하시킬 수 있습니다. 저희는 Outlier Detection 기능을 활용해 장애가 발생한 인스턴스를 호출 대상에서 자동으로 제외하고 있습니다.
동작 방식:
5회 연속으로 5xx 에러 응답을 보낼 경우 해당 pod 격리
격리된 pod는 최소 30초 동안 호출 대상에서 제외
한 번에 격리되는 pod의 비율은 50%를 넘지 않도록 설정
실제 운영 사례: 최근 배포 과정에서 특정 pod 하나가 무한 재시작(Crash Loop)에 빠지는 이슈가 있었습니다. 이를 감지해 50초 이내에 해당 pod를 라우팅 경로에서 제거했습니다. 덕분에 별도의 수동 개입 없이도 트래픽이 정상 pod들로 안전하게 전환되었습니다.
장기 세션 보존을 위한 종료 시퀀스 최적화
게이트웨이는 10분 이상 지속되는 연결을 처리하기 때문에, 배포 시 연결이 갑자기 끊기면 테스트 실패로 이어지곤 했습니다.
여기서 가장 중요한 규칙은 terminationGracePeriodSeconds가 terminationDrainDuration보다 길어야 한다는 점입니다.
종료 프로세스
Pod가 종료 신호를 받습니다.
Envoy가 신규 연결 수락을 중단하고 헬스 체크에서 실패 상태를 반환합니다.
이미 연결된 세션은
terminationDrainDuration(600초) 설정값 만큼 유지됩니다.
EXIT_ON_ZERO_ACTIVE_CONNECTIONS옵션을 통해, 모든 연결이 일찍 종료되면 pod도 즉시 종료됩니다.설정된
terminationGracePeriodSeconds(660초)가 지나면 쿠버네티스가 SIGKILL을 보내 최종 종료합니다.
적용 결과:
배포 중에도 연결 끊김 현상 zero(0)
롤링 업데이트 중에도 부하 테스트가 오류 없이 성공적으로 완료
운영 중 얻은 핵심 인사이트
반드시 기억해야 할 Istio 운영 팁 몇 가지를 공유합니다.
가볍게 시작하세요: 첫날부터 모든 기능을 활성화할 필요는 없습니다. mTLS나 트레이싱(Tracing) 같은 복잡한 기능은 기술적 비용보다 비즈니스적 가치가 더 클 때 하나씩 추가하세요.
메트릭 카디널리티(Cardinality)를 경계하세요: Envoy는 방대한 텔레메트리 데이터를 생성하며, 이는 자칫 프로메테우스(Prometheus) 서버를 다운시킬 수 있습니다. 설정을 튜닝하여 정말 유의미한 메트릭만 수집하도록 관리해야 합니다.
EnvoyFilter는 주의해서 다루세요: 강력한 기능을 제공하지만, Istio 버전 업그레이드 시 충돌이 발생하기 쉽습니다. 철저한 문서화와 호환성 테스트는 선택이 아닌 필수입니다.
마치며…
Istio는 학습 곡선이 가파른 편입니다. 하지만 저희 에스티씨랩의 가상 대기실 솔루션, 넷퍼넬(NetFunnel)이나 악성 봇 탐지 및 차단 솔루션, 봇매니저(BotManager)처럼 대규모 트래픽을 처리하는 플랫폼에게 Istio가 제공하는 세밀한 제어 능력은 충분히 투자할 가치가 있습니다.
저희가 공유해 드린 원본 IP 보존을 위한 Proxy Protocol, 접근 제어를 위한 AuthorizationPolicy, 유연한 라우팅 전략, 회복 탄력성을 높여주는 이상치 탐지(Outlier Detection), 그리고 안전한 종료(Graceful Shutdown) 프로세스는 이제 저희 인프라의 핵심적인 요소가 되었습니다.
트래픽 관리, 보안, 그리고 신뢰성이 중요한 서비스를 운영하고 계신다면, Istio를 고려해보세요.