서비스 메쉬(Service Mesh)란 애플리케이션의 다양한 부분들이 서로 데이터를 공유하는 방식을 제어하는 방법이다. 서비스간 커뮤니케이션을 관리하는 다른 시스템과 달리, 서비스 메쉬는 애플리케이션에 구축된 전용 인프라 계층이다.
애플리케이션은 어떤 기능을 수행하기 위해서 다른 애플리케이션의 기능을 호출해야 하는 경우가 있다. 이커머스 애플리케이션에서 사용자가 제품 구매를 요청 할 경우 Order 서비스에 요청 한다. Order 서비스는 재고가 있는지를 확인하기 위해서 다른 애플리케이션과 커뮤니케이션해야 한다. 모놀리식에서는 하나의 애플리케이션이 모두 처리하겠으나 MSA에서는 네트워크로 분리된 다른 서비스를 호출해야 한다. 이 와중에 일부 서비스에 요청이 과도하게 몰릴 수 있으며, 어떤 서비스가 작동을 하지 않을 수도 있다. 서비스 메시를 이용하여 이러한 커뮤니케이션을 최적화 할 수 있다.
위 그림은 Service Mesh를 묘사하고 있다. 복잡하게 생각할 필요 없다. 서비스와 서비스를 연결하기 위한 네트워크를 구성 하는게 서비스 메시다. 서비스 메시는 대부분 HTTP 기반에서 작동을하기 때문에 서비스 메시 애플리케이션은 근본적으로 HTTP Proxy 애플리케이션이다.
서비스 메시는 성능측정, 분산추적, 고가용성, 로드밸런싱, 실패 대응(재시도, 타임아웃 등), Traffic Split 등의 기능을 제공하는데, 이를 이용해서 서비스간 커뮤니케이션을 관리/모니터링 할 수 있다.
Control Plane과 Data Plane
서비스 메시는 데이터 플레인과 컨트롤 플레인의 필수 요소로 구성된다. 생소한 단어가 들어가서 그렇지 아주 간단하다.
데이터를 주고 받도는 Proxy가 필요 할 것이다. 이게 데이터 플레인이다.
프록시간의 네트워크를 구성/변경/관리/보안/모니터링 등의 관리 기능이 필요할 것이다. 이게 컨트롤 플레인이다.
위의 서비스 메시 구성화면을 보면, 서비스 옆에 서비스 메시가 붙어 있는 것을 볼 수 있을 것이다. 이런 패턴을 사이드카(Sicecar) 패턴이라고 하는데, 데이터 플레인은 Proxy 형태로 서비스 옆에 붙는 구조를 가진다.
대표적인 데이터 플레인은 아래와 같다.
Istio-Proxy
Linkerd
Consul Connect
Kuma
Network Service Mesh(NSM)
Nginx Service Mesh
AWS App Mesh
OpenShift Service Mesh by RedHat
장점
서비스 메시는 사이트카 패턴으로 구축이 된다. 커뮤니케이션 기능이 애플리케이션으로 부터 분리된다는 의미다. 이제 애플리케이션은 요청을 다른 지점으로 보내기 위한 룰을 가질 필요가 없다. 이러한 기능은 서비스 메시가 가지고 있으며, 서비스 메시에 룰을 추가하거나 변경하는 것으로 커뮤니케이션을 관리 할 수 있다. 즉 "커뮤니케이션 기능의 인프라 계층으로 추상화" 한다.
서비스 메시가 없이 마이크로 서비스를 구축할 경우, 서비스간 커뮤니케이션의 구성은 개발자의 몫이 된다. 또한 커뮤니케이션을 통제하는 로직이 서비스 내부에 숨겨져 있기 때문에 커뮤니케이션 장애를 진단하기가 어려워진다.
서비스 메시는 자체적으로 성능 정보를 측정하기 때문에 이 정보를 모니터링 해서, 커뮤니케이션 환경을 최적화 할 수 있다. 아래는 Linkerd의 모니터링 화면이다. 전체 마이크로 서비스의 커뮤니케이션 상태를 확인 할 수 있다.
Linkerd 기반으로 서비스 메시를 구성해 보자.
# kubectl version --short
Client Version: v1.22.1
Server Version: v1.21.2
CLI 인스톨
Linkerd CLI를 설치한다.
# curl -sL https://run.linkerd.io/install | sh
Downloading linkerd2-cli-stable-2.10.2-linux-amd64...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 646 100 646 0 0 2025 0 --:--:-- --:--:-- --:--:-- 2025
100 38.3M 100 38.3M 0 0 12.4M 0 0:00:03 0:00:03 --:--:-- 14.9M
Download complete!
Validating checksum...
Checksum valid.
Linkerd stable-2.10.2 was successfully installed
Add the linkerd CLI to your path with:
export PATH=$PATH:/home/yundream/.linkerd2/bin
....
PATH에 등록한다.
# export PATH=$PATH:/home/yundream/.linkerd2/bin
linkerd 버전과 상태를 확인해보자.
linkerd version
# Client version: stable-2.10.2
Server version: unavailable
Server version이 unavailable다. 뭔가 잘못 된 것 같지만 격정할 필요 없다. 아직 컨트롤 플레인이 설치되지 않아서 이다.
쿠버네티스 클러스터 검토
minikube가 제대로 설치되어 있다면, 아래와 같이 성공할 것이다.
# linkerd check --pre
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
W0915 13:54:30.669511 49559 warnings.go:67] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected
W0915 13:54:30.721136 49559 warnings.go:67] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
W0915 13:54:30.726230 49559 warnings.go:67] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
√ has NET_RAW capability
linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date
Status check results are √
Linkerd를 클러스터에 설치하기
Linkerd를 설치할 준비가 끝났다. 설치해보자.
# linkerd install | kubectl apply -f -
namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
....
잘 설치됐는지 확인해보자.
# linkerd check
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
......
......
Status check results are √
클러스터에 어떤 구성요소가 설치됐는지 확인해보자.
# kubectl -n linkerd get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
linkerd-controller 1/1 1 1 10m
linkerd-destination 1/1 1 1 10m
linkerd-identity 1/1 1 1 10m
linkerd-proxy-injector 1/1 1 1 10m
linkerd-sp-validator 1/1 1 1 10m
linkerd 시스템의 아키텍처는 아래와 같다.
Linkerd Dashboard
linkerd dashboard를 이용해서 클러스터 상태를 모니터링 할 수 있다. dashboard를 사용하기 위해서는 viz extension을 설치해야 한다.
# linkerd viz install | kubectl apply -f -
namespace/linkerd-viz created
dashboard를 실행한다.
# linkerd viz dashboard
Linkerd dashboard available at:
http://localhost:50750
Grafana dashboard available at:
http://localhost:50750/grafana
Opening Linkerd dashboard in the default browser
아래와 같이 브라우저가 실행된다.
데모 앱 설치
emojivoto라는 독립 응용 프로그램을 이용해서, 데모를 해보자. 이 앱은 emoji 목록을 출력하고 사용자는 마음에 드는 emoji에 투표 할 수 있다. emojivoto 앱은 아래와 같이 구성되어 있다.
web : HTTP 기반 REST API와 UI를 제공한다.
emoji : emoji 목록을 조회하기 위한 gRPC API를 제공한다.
voting : 투표를 위한 gRPC API를 제공한다.
bot : 트래픽을 발생하는 봇(자동프로그램)이다. web 서비스에 REST API를 호출한다.
이제 http://localhost:8080 을 방문하면 emoji 목록을 확인 할 수 있을 것이다.
하지만 투표를 하려고 emoji 를 선택하면(도넛을 선택하면) "404 page"가 출력된다. 디버깅을 위해서 의도한 결과이기 때문에 걱정할 필요는 없다.
linkerd를 설치하자.
linkerd intect. iject 명령은 kubernetes 매니페스트를 수정하는 일을 한다. 이 명령은 annotation에 linkerd.io/inject 가 추가된다. 그러면 proxy autoinjector가 각 pod에 Linkerd data plane proxy를 자동으로 추가한다.
kubectl apply로 변경사항을 적용한다. kubectl get, linkerd inject 는 쿠버네티스 매니페스트를 만드는(yaml 설정을 만드는) 작업만 할 뿐, 클러스터에 적용하지는 않는다. kubectl 로 적용을 해야 한다.
# linkerd dashboard
Command "dashboard" is deprecated, use instead 'linkerd viz dashboard [flags]'
.....
namespaces > emojivoto로 이동하면 아래와 같이 emojivoto의 deployment 상황을 확인 할 수 있다.
그래프로 서비스들의 커뮤니케이션 방향을 보자. emojivote 애플리케이션 구성을 그대로 따르고 있음을 알 수 있다. Deployments를 보면 각 deployment의 모니터링 정보가 나온다. web 을보면 96.38% 인데, 도넛을 선택할 경우 404 에러를 리턴하도록 애플리케이션이 전개되었기 때문이다. 성공율(Success Rate), 초당요청(RPS), 레이턴시를 출력한다.
현재 voting 과 web 에서 에러가 발생하는데, web이 클라이언트가 연결하는 접점이므로 web 부터 디버깅을 하기로 했다.
web Deployment에 왜 에러가 발생하는지 좀 더 자세히 디버깅해보자. web을 클릭하면 상세 정보가 출력된다.
deployment/web 화면에서, deploy/web은 deploy/voting와 deploy/emoji로 요청을 보내고 있다. 이 중 deploy/voting 요청에서 에러가 발생했다는 것을 확인 할 수 있다. 화면을 아래로 스크롤하면 요청 목록을 확인 할 수 있다.
deploy/vote-bot 이 /api/vote 에서 에러가 발생했는데, deploy/voting에 .../VoteDoughnut API를 호출 실패로 발생한 에러라는 걸 유추 할 수 있다. 개발자는 .../VoteDoughnut API를 수정하면 이 문제가 해결될 것이다.
성능과 문제를 추적하고 문제를 해결하기 위한 모든 것이 있다.
Contents
Service Mesh
Control Plane과 Data Plane
장점
linkerd를 이용한 service mesh 구성
CLI 인스톨
쿠버네티스 클러스터 검토
Linkerd를 클러스터에 설치하기
Linkerd Dashboard
데모 앱 설치
데모 앱 디버깅
정리
참고
Recent Posts
Archive Posts
Tags