메뉴

문서정보

목차

Service Mesh

서비스 메쉬(Service Mesh)란 애플리케이션의 다양한 부분들이 서로 데이터를 공유하는 방식을 제어하는 방법이다. 서비스간 커뮤니케이션을 관리하는 다른 시스템과 달리, 서비스 메쉬는 애플리케이션에 구축된 전용 인프라 계층이다.

애플리케이션은 어떤 기능을 수행하기 위해서 다른 애플리케이션의 기능을 호출해야 하는 경우가 있다. 이커머스 애플리케이션에서 사용자가 제품 구매를 요청 할 경우 Order 서비스에 요청 한다. Order 서비스는 재고가 있는지를 확인하기 위해서 다른 애플리케이션과 커뮤니케이션해야 한다. 모놀리식에서는 하나의 애플리케이션이 모두 처리하겠으나 MSA에서는 네트워크로 분리된 다른 서비스를 호출해야 한다. 이 와중에 일부 서비스에 요청이 과도하게 몰릴 수 있으며, 어떤 서비스가 작동을 하지 않을 수도 있다. 서비스 메시를 이용하여 이러한 커뮤니케이션을 최적화 할 수 있다.

 Service Mesh

위 그림은 Service Mesh를 묘사하고 있다. 복잡하게 생각할 필요 없다. 서비스와 서비스를 연결하기 위한 네트워크를 구성 하는게 서비스 메시다. 서비스 메시는 대부분 HTTP 기반에서 작동을하기 때문에 서비스 메시 애플리케이션은 근본적으로 HTTP Proxy 애플리케이션이다.

서비스 메시는 성능측정, 분산추적, 고가용성, 로드밸런싱, 실패 대응(재시도, 타임아웃 등), Traffic Split 등의 기능을 제공하는데, 이를 이용해서 서비스간 커뮤니케이션을 관리/모니터링 할 수 있다.

Control Plane과 Data Plane

서비스 메시는 데이터 플레인과 컨트롤 플레인의 필수 요소로 구성된다. 생소한 단어가 들어가서 그렇지 아주 간단하다. 위의 서비스 메시 구성화면을 보면, 서비스 옆에 서비스 메시가 붙어 있는 것을 볼 수 있을 것이다. 이런 패턴을 사이드카(Sicecar) 패턴이라고 하는데, 데이터 플레인은 Proxy 형태로 서비스 옆에 붙는 구조를 가진다.

 사이드카 패턴

대표적인 데이터 플레인은 아래와 같다.

장점

서비스 메시는 사이트카 패턴으로 구축이 된다. 커뮤니케이션 기능이 애플리케이션으로 부터 분리된다는 의미다. 이제 애플리케이션은 요청을 다른 지점으로 보내기 위한 룰을 가질 필요가 없다. 이러한 기능은 서비스 메시가 가지고 있으며, 서비스 메시에 룰을 추가하거나 변경하는 것으로 커뮤니케이션을 관리 할 수 있다. 즉 "커뮤니케이션 기능의 인프라 계층으로 추상화" 한다.

서비스 메시가 없이 마이크로 서비스를 구축할 경우, 서비스간 커뮤니케이션의 구성은 개발자의 몫이 된다. 또한 커뮤니케이션을 통제하는 로직이 서비스 내부에 숨겨져 있기 때문에 커뮤니케이션 장애를 진단하기가 어려워진다.

서비스 메시는 자체적으로 성능 정보를 측정하기 때문에 이 정보를 모니터링 해서, 커뮤니케이션 환경을 최적화 할 수 있다. 아래는 Linkerd의 모니터링 화면이다. 전체 마이크로 서비스의 커뮤니케이션 상태를 확인 할 수 있다.

 linkerd dashboard

Linkerd 기반으로 서비스 메시를 구성해 보자.

linkerd를 이용한 service mesh 구성

구성 환경은 아래와 같다. minikube를 시작하고 kubectl로 확인한다.
# 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 아키텍처

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

아래와 같이 브라우저가 실행된다.

 linkerd dashboard

데모 앱 설치

emojivoto라는 독립 응용 프로그램을 이용해서, 데모를 해보자. 이 앱은 emoji 목록을 출력하고 사용자는 마음에 드는 emoji에 투표 할 수 있다. emojivoto 앱은 아래와 같이 구성되어 있다.

emojivote 앱을 설치한다.
# curl -sL https://run.linkerd.io/emojivoto.yml \
  | kubectl apply -f -

설치됐는지 확인한다.
# kubectl -n emojivoto get deployments
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
emoji      1/1     1            1           75m
vote-bot   1/1     1            1           75m
voting     1/1     1            1           75m
web        1/1     1            1           75m

로컬에서 접근 할 수 있도록 포트포워딩을 설정했다.
# kubectl -n emojivoto port-forward svc/web-svc 8080:80

이제 http://localhost:8080 을 방문하면 emoji 목록을 확인 할 수 있을 것이다.

 emoji web

하지만 투표를 하려고 emoji 를 선택하면(도넛을 선택하면) "404 page"가 출력된다. 디버깅을 위해서 의도한 결과이기 때문에 걱정할 필요는 없다.

linkerd를 설치하자.
# kubectl get -n emojivoto deploy -o yaml \
  | linkerd inject - \
  | kubectl apply -f -
Linkerd 서비스 메시를 성공적으로 설치했는지 확인해 보자.
linkerd -n emojivoto viz stat deploy
NAME       MESHED   SUCCESS      RPS   LATENCY_P50   LATENCY_P95   LATENCY_P99   TCP_CONN
emoji         1/1   100.00%   2.3rps           1ms           1ms           2ms          3
vote-bot      1/1   100.00%   0.3rps           1ms           3ms           3ms          1
voting        1/1    87.18%   1.3rps           1ms           1ms           1ms          3
web           1/1    94.07%   2.2rps           4ms           9ms          10ms          3

이제 투표 기능이 잘 작동하는 걸 확인 할 수 있을 것이다.

데모 앱 디버깅

Linkerd를 이용해서 애플리케이션을 디버깅해보자. 먼제 대시보드를 실행한다.
# linkerd dashboard                 
Command "dashboard" is deprecated, use instead 'linkerd viz dashboard [flags]'

.....

namespaces > emojivoto로 이동하면 아래와 같이 emojivoto의 deployment 상황을 확인 할 수 있다.

 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를 수정하면 이 문제가 해결될 것이다.

성능과 문제를 추적하고 문제를 해결하기 위한 모든 것이 있다.

정리

참고