1. 배경
해당 글은 서비스 메쉬에 대해 조사하며 Linkerd의 블로그를 읽고 서비스 메쉬에 대해 이해하기 좋은 거 같아 해당 글을 번역하고 추가로 조사하며 글을 작성하였습니다. 그렇기 때문에 Linkerd를 기준으로 서비스 메쉬를 설명합니다.
현재 많은 기업에서 서비스 메쉬를 도입하고 적용하려고 하지만, 이에 대한 많은 사례가 없어 어려움을 겪고 있습니다. 하지만 서비스 메쉬(Linkerd)의 전체 아키텍처를 크게 보면 간단합니다. 서비스 메쉬의 역할을 단순히 말하면 각 서비스에 사이드카 패턴을 사용해 프록시를 추가하여 서비스 간 통신 하도록 하고, 이러한 기능에 중점을 둡니다.(Proxy, Reverse Proxy의 역할) 이러한 영역을 Data Plane이라 하며, 데이터 플레인이 잘 동작하도록 서비스 디스커버리, 메트릭 집계, API Endpoint, mTLS를 위한 인증서 관리 등의 기능을 하는 Control Plane으로 구성되어있습니다.
서비스 메쉬는 서비스-서비스 간의 프록시 기능들을 구현하기 위해 설계되어 애플리케이션이 Monolth 구조의 경우 적합하지 않습니다.(물론 여러 VM에 서비스를 실행시켜 연결하는 구조도 가능하나 그럴 필요가 있을지 의문입니다). 또한 매우 많은 프록시로 이루어져 있고, 프록시(Linkerd-proxy)가 각각의 서비스에 모두 구성되기 때문에 다음과 같은 기능이 필요합니다.
- 각 프록시는 모든 호출에 Client/Server Side의 Proxy hop을 가지고 있기 때문에 매우 빠릅니다.
- 각 프록시는 Memory, CPU 사용량이 적고 가벼워야 됩니다.
- 모든 프록시를 배포하고 관리할 수 있는 기능이 필요합니다.
2. 서비스 메쉬를 왜 사용해야 하나?
서비스 메쉬를 도입하면 각 서비스에 프록시가 추가되기 때문에 애플리케이션의 지연율이 늘어날 수밖에 없고, 리소스 사용량이 추가로 들 수 밖에 없습니다. 그럼에도 불구하고 최근 많이 사용하는 이유에는 크게 두 가지가 있습니다.
- 클라우드 기술의 확장으로 인해 프록시를 배포하고, 운영하는 비용이 크게 줄었습니다.
- 서비스 간의 트래픽을 관리하는 로직을 애플리케이션의 영향 없이 관리하고 배포할 수 있습니다. 예를 들어 Linkerd는 기본적으로 HTTP/gRPC 등의 L7 기능을 지원하는데, Timeout, Retry 정책 설정, 트래픽 분할을 통한 Reliability(신뢰성), 서비스 토폴로지, 성공률 등의 메트릭을 통해 Observability(관찰성) , 또한 서비스 간의 MutalTLS, 접근 제한을 통해 Security(보안성)을 높일 수 있습니다.
예를 들어 Request Level의 기능을 보면, Foo 서비스에서 Bar 서비스로 요청이 발생했을 때 Foo에 설치된 Linkerd-proxy는 Bar 서비스의 Latency를 관찰하여 적절한 인스턴스를 찾아 로드밸런싱 하고, Bar 측에서 또한 허용되지 않은 요청이나, Rate limit 등을 기반으로 request를 거부할 수 있습니다. 이러한 트래픽은 기록되어 모니터링할 수 있습니다.
또한 프록시는 Connection Level에서도 다양한 기능을 지원합니다. Server/Client 측의 Linkerd Proxy는 상호 간의 유효한 TLS 인증서를 검사하여 유효성 검사를 합니다. 이는 단순히 서버와 클라이언트 간의 암호화된 통신뿐 아니라 서로가 누구인지 증명하는 신원 검사의 측면도 갖게 됩니다.
이와 같이 서비스메쉬의 주요 기능은 애플리케이션을 운영하는데 목적이 있습니다. 그렇게 때문에 request가 발생하는 도중의 데이터의 변경과 같은 payload를 조작하는 기능은 없습니다. 이러한 부분이 ESBs와 같은 미들웨어와 다른 점입니다.
현대 Server Side 개발은 각 서비스가 분리되어 동기식으로 통신하는 구조로 구축하는 추세입니다(MSA 구조) 이러한 구조에서 기능을 추가하고, 수정하는 등 운영하는 데에 있어 Service Mesh는 큰 강점을 제공합니다.
- 모든 스택에 관계없이 동일하게 관리할 수 있습니다 - 각 서비스가 어떤 언어, 어떤 라이브러리로 작성하고, 어떻게 배포되었는지와 관계없이 서비스 메쉬는 모든. 서비스에 동일하게 기능을 적용합니다. (컨테이너의 장점)
- 애플리케이션 코드와 분리되어 관리됩니다 - 서비스 메쉬는 어플리케이션 코드와 완전히 분리되어, 어플리케이션 코드를 수정할 필요 없이 서비스 메쉬의 모든 기능을 별개로 작업하며, 영향을 미치지 않습니다.
이러한 이유 때문에 개발자는 서비스 로직 개발에만 집중할 수 있어, 운영과 개발에 효율성을 높일 수 있습니다. 이전에 Spring Cloud 기반으로 MSA 구조를 개발할 때의 가장 큰 고민은 개발자가 쿠버네티스 레이어와 MSA 아키텍처를 알지 못하면 힘들다는 점이었습니다. 각 파드가 어떻게 연결되고, Cercuit Break, 메시지 브로커 등을 모두 고려하여 개발을 진행하고, 개발 후에는 TLS 설정, Retry 정책 등을 설정해야 하기 때문에 실제 로직 개발보다 더 큰 시간을 할애하게 됩니다. 이러한 문제를 서비스 메쉬는 개발 영역과의 독립적인 운영을 통해 해결할 수 있습니다.
3. 서비스 메쉬의 한계
하지만 이런 독립적인 구조로 인한 한계도 존재합니다. 단순히 트래픽의 성공률을 집계할 수 있지만 내부 메트릭은 애플리케이션에서 직접 측정해야합니다. 보안 측면에서도 mTLS의 기능을 제공하지만 실제 기업에서 어플리케이션을 운영할 때 필요한 보안 측면 기능은 부족합니다. 또한 서비스 메쉬는 동일한 요청에 대한 동일한 응답을 보장하는 멱등성을 가진 요청에는 재시도가 가능하지만, 실제 서비스가 다운되어 응답이 오지 않는 경우에는 서비스 메쉬가 응답할 수 있는 방법이 없기 때문에 어플리케이션 영역에서 장애 탐지 및 처리/ 백오프 및 재시도 등의 기능을 직접 구현해야 합니다.
4. 최근 들어 서비스 메쉬가 왜 인기 있을까?
이러한 서비스 메쉬의 장점을 보면 ‘이전에는 왜 각 서비스에 프록시를 구축하지 않고 이제서야 해당 구조를 적용할까’에 대한 의문이 생깁니다. 사실 이전에도 Monolith 구조의 어플리케이션의 한계를 느끼고 MSA 구조로의 전환의 필요성은 느끼며 많은 시도를 했습니다. Google,Netflix, Twitter와 같은 거대 기업은 공개적으로 실천하고 있었습니다. 하지만 그 당시에는 프록시를 통해 구현하지 않고 네트워크 통신용 라이브러리를 개발하여 서비스 메쉬의 기능과 동일하게 만들어 사용하였습니다. Netflix는 Hysterix를, Google은 Stubby, Twitter는 Finagle을 사용하였습니다. 하지만 이러한 라이브러리는 특정언어에 종속되어 있고, 이러한 몇 백 개의 서비스를 구현하기 위해서 많은 비용과 시간이 들어 작은 조직에서는 구현이 어려웠습니다.
하지만 현재는 이러한 비용이 획기적으로 줄었습니다. 결정적인 이유는 컨테이너 기술의 발전입니다. 도커와 같은 컨테이너를 통해 언어, 프레임워크와 관련 없이 패키징 하여 OS에 상관없이 서비스를 배포하고 사용할 수 있게 되었습니다. 또한 Kubernetes와 같은 컨테이너 오케스트레이션까지 사용하게 되면서 대규모의 컨테이너를 손쉽게 배포하고 운영할 수 있게 되었습니다.(쿠버네티스 상에서 10개나 100개의 서비스를 배포하는데 크게 다른 점은 없습니다.) 이러한 이유 때문에 현재 서비스 메쉬가 인기가 많아지게 되었습니다.
5. Linkerd VS Istio
서비스 메쉬를 이야기하면 일반적으로 istio를 생각하는 사람이 많습니다. 실제로 많이 사용하고 있는 추세이기도 합니다. 다만 이 글에서는 istio에 대해서는 부정적인 견해로 말합니다. 당연히 경쟁 제품이니 그럴 수 있을 거라 생각합니다. 가장 큰 부정적인 이유는 Google이 프로젝트를 맡으면서 서비스 메쉬에 대한 과대 홍보와, 프로젝트 운영이 좋지 않다는 의견입니다. 그렇다고 istio보다 Linkerd가 더 좋다는 이야기는 아닙니다. 당연히 각 제품의 장단점은 있고, 사용자의 환경에 따라 적절히 선택해야 합니다.
Linkerd는 Istio 보다 성능면에서 우수합니다. 이는 데이터 플레인의 프록시 기능을 Envoy를 사용하는 반면 Linkerd는 Rust 기반의 linkerd2-proxy를 사용하기 때문에 속도와 효율성의 면에서 더 우수하고, 리소스 사용량도 적습니다.(Linkerd가 Envoy를 사용하지 않는 이유) 다음 자료에 따르면 Linkerdrk Istio보다 성능이 확실히 좋은 것을 알 수 있습니다. (P99와 같은 메트릭의 의미는 일정 기간 동안 발생한 요청 중 99%의 요청이 완료되는 데 걸린 시간입니다.)
반면 Istio는 Linkerd보다 더 많은 기능을 제공합니다. Linkerd는 모든 TCP 트래픽에 대해 mTLS를 기본적으로 지원하지만 istio는 HTTP 또한 지원하며, 정책관리 또한 다양한 Provider와의 통합을 지원합니다. 또한 istio는 단순 트래픽 관리를 넘어서 고급 라우팅 기능, 오류 주입 등 과 같은 다양한 기능을 지원합니다.
다음과 같은 차이로 인해 Linkerd는 보다 간결한 아키텍처를 통해 쉽게 MSA 구조를 구축/운영할 수 있고, Istio는 다양한 기능과 설정을 지원하여 복잡한 아키텍처로 구성되어 있어 보다 사용하기에 어려움을 겪을 수 있습니다.
이러한 이유 때문에 각 사용자의 상황에 맞게 적절히 선택해서 사용해야 합니다. Linkerd는 서비스 간의 통신 성능이 최우선이기 때문에 속도가 중요한 애플리케이션에 적합 할 수 있고, 아키텍쳐가 단순하기 때문에 쉽게 사용할 수 있습니다. Istio는 고급 라우팅, 카나리 배포등의 다양한 기능을 지원하기 때문에 아키텍쳐가 복잡해 사용하기 어려우나, 고급 보안이나 트래픽 분산 등이 필요한 어플리케이션에 적합합니다.(Linkerd도 Canary 배포와 트래픽 분할 기능을 제공하긴 합니다). 또한 Istio는 Google/IBM이 지원하는 프로젝트 이기 때문에 Linkerd 보다 커뮤니티가 활성화되어있는 장점이 있습니다.
6. 결론
해당 글에서는 당연하게도 서비스 메쉬를 장점을 설명하며, 도입해야 된다는 주장을 강력하게 합니다. 특히 쿠버네티스 기반에서 애플리케이션을 운영할 경우 모놀리스 구조를 통해 운영할 거면 쿠버네티스를 사용할 필요가 없다는 어조로 말합니다. 하지만 실제로 사이트에 나가보면 많은 기업이 MSA 구조를 원하지만 다양한 이유로 인해 WAS/Fronted/Backend /DB 구조로 Pod 배포하여 운영하는 경우가 많습니다. 실제로 쿠버네티스를 잘 사용하기 위해 많은 고민이 필요할 거 같습니다. 향후에는 Linkerd를 직접 테스트하며 공부한 내용을 포스팅할 계획입니다.
'Kubernetes' 카테고리의 다른 글
Kubernetes Pod의 컨테이너는 어떻게 Localhost로 통신 할 수 있을까? (0) | 2024.02.04 |
---|---|
Kubernetes CSI Driver 란? (1) | 2024.01.21 |
Github Action/ Argo CD를 이용한 CI/CD 구성 (0) | 2024.01.14 |
ETCD MultiMaster Backup/Restore(CronJob 생성) (1) | 2023.11.14 |
Velero를 이용한 쿠버네티스 Backup (0) | 2023.10.12 |