1. 개요
- 프록시를 사용하여 서비스 또는 마이크로서비스 간의 서비스 간 통신을 용이하게 하기 위한 전용 인프라 계층
- 애플리케이션 트래픽을 관리, 추적 및 보안성을 강화하기 위해 플랫폼 레이어에 구성되는 네트워크 제어 방법
2. 마이크로 서비스와 서비스 매쉬
2.1 프록시
MSA 구조의 경우 수 백, 수 천개 이상의 서비스가 존재 할 수있으며, 서비스 → 서비스 호출 시 장애 전파 현상으로 원인을 찾기가 어려움. B Service에 장애가 날 경우, A Service에서도 응답을 제대로 받지 못해 장애가 전파 됨.
서비스 앞에 프록시를 이용하여 트래픽을 네트워크 단에서 통제 할 수 있다. 프록시에서 메시지 헤더를 보고 원하는 대상으로 라우팅(지능형 라우팅)을 할 수 있다.
ex. Client 필드가 Android이면, 안드로이드 서비스로 라우팅
서비스 수에 따라 프록시 수도 증가하기 때문에 프록시 설정이 어려워지며, 설정 정보를 중앙 집중화된 컨트롤러가 통제하는 구조를 취할 수 있다.
출처) https://bcho.tistory.com/1293
3. 서비스매시 솔루션
3.1 istio vs linkerd
서비스 매시를 구현하기 위해서는 사이드카 프록시가 필요하다.
istio 등장으로 서비스 매시 개념이 전파되었으며, 유연하고 범용적인 프록시인 엔보이를 사용한다. 엔보이는 인그레스, 이그레스, 서비스메시 사이트가 등 다양한 방법으로 사용할 가능하여 보다 복잡하고 사용이 까다롭다.
linkerd 에서는 linkerd2-proxy라는 프록시를 사용하며, 엔보이보다 가볍고 사용하기 쉽다.
엔보이는 오버플로우에 취약한 C++로 작성되었으며, linkerd2-proxy는 메모리 안전성이 특징인 Rush로 작성되어 보안적으로 유리할 것이라고 한다.
linkerd가 istio 보다 리소스 사용량이 훨씬 적으며, 네트워크 지연도 적게 발생.
아래 글을 보면 아키텍처 및 태생 언어에 대한 이유로 istio에 비해 linkerd가 더 작고 빠르고 보안에 뛰어나다고 한다.
4. Linkerd(링커디) 설치 및 사용법
4.1 Install the CLI
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install | sh
# Add the linkerd CLI to your path
export PATH=$PATH:/root/.linkerd2/bin
# linkerd version
Client version: stable-2.13.5
Server version: unavailable
4.2 Validate your Kubernetes cluster
root@edu03-master1:~# linkerd check --pre
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ 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
linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date
Status check results are √
4.3 Install Linkerd onto your cluster
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
root@edu03-master1:~# kubectl -n linkerd get pod
NAME READY STATUS RESTARTS AGE
linkerd-destination-8554fb9f7f-gglc7 4/4 Running 0 84s
linkerd-identity-8476c4dd4-grpfl 2/2 Running 0 85s
linkerd-proxy-injector-66875b9fd6-fpvqh 2/2 Running 0 84s
linkerd check
4.4 Install the demo app
(1) Emojivoto 데모 애플리케이션 설치
- Emojivoto is a simple standalone Kubernetes application that uses a mix of gRPC and HTTP calls to allow the user to vote on their favorite emojis.
- Install Emojivoto into the emojivoto namespace by running:
$ curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/emojivoto.yml \
| kubectl apply -f -
$ kubectl -n emojivoto edit svc web-svc
Change ServiceType : ClusterIP -> NodePort
$ kubectl -n emojivoto get svc | grep web-svc
web-svc NodePort 10.233.4.174 80:31873/TCP 5m13s
(2) 브라우저 접속 - http://192.168.110.31:31873/
(3) 도넛 이모지에 투표 할 경우, 404 에러 발생
(4) linkerd inject 수행
linkerd-proxy라는 이름의 사이트카 프록시 컨테이너 생성
inject 해도 서비스에 변경은 없으며, 사이드카 컨테이너가 추가 된 것을 볼 수 있다.
kubectl get -n emojivoto deploy -o yaml \
| linkerd inject - \
| kubectl apply -f -
4.5 linkerd 로 문제 파악하기
(1) 대시보드(viz extension) 설치
$ linkerd viz install | kubectl apply -f -
$ kubectl -n linkerd-viz get pod
NAME READY STATUS RESTARTS AGE
metrics-api-6d69f7fbfb-vzmv2 2/2 Running 0 56s
prometheus-7ddcdc4b5c-wchs8 2/2 Running 0 55s
tap-55c8f8b67b-8nmvl 2/2 Running 0 55s
tap-injector-55ddf4746-brsjt 2/2 Running 0 53s
web-6fd5fdf594-xxjzz 2/2 Running 0 54s
$ linkerd check
$ kubectl -n linkerd-viz edit svc web
Change ServiceType - ClusterIP to NodePort
(2) ingress 설정
apiVersion: v1
kind: Secret
type: Opaque
metadata:
name: web-ingress-auth
namespace: linkerd-viz
data:
auth: YWRtaW46JGFwcjEkbjdDdTZnSGwkRTQ3b2dmN0NPOE5SWWpFakJPa1dNLgoK
---
# apiVersion: networking.k8s.io/v1beta1 # for k8s < v1.19
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
namespace: linkerd-viz
annotations:
nginx.ingress.kubernetes.io/upstream-vhost: $service_name.$namespace.svc.cluster.local:8084
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Origin "";
proxy_hide_header l5d-remote-ip;
proxy_hide_header l5d-server-id;
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: web-ingress-auth
nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
spec:
ingressClassName: nginx
rules:
- host: dashboard.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8084
kubectl apply -f viz-ingress.yml
root@edu03-master1:~# kubectl -n ingress-nginx get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 10.233.27.166 <none> 80:32235/TCP,443:30030/TCP 7m17s
ingress-nginx-controller-admission ClusterIP 10.233.19.173 <none> 443/TCP 7m17s
(3) 브라우저 접속 - https://dashboard.example.com:30030/
hosts 파일 수정
protects it with basic auth using admin/admin
(4) 도넛 이모지에 투표하면(404에러 발생 시) SR(Success Rate)가 내려가는 것을 볼 수 있음.
deploy/emoji SR 100%이고, deploy/voting 이 100%가 아니기 때문에, deploy/web에서 voting 기능 일부 요청이 실패한 것으로 추측할 수 있다.
의존성이 있는 deploy 요청 실패는 웹이 반환하는 오류의 원인 일 수 있다.
(5) 위 캡처 중 [LIVE CALLS] 항목이 나오지 않은 이유는 linkerd 설치 후 서비스 파드가 재기동 되지 않았기 때문 이며, 서비스 파드 재기동 후 아래와 같이 Path가 보인다.
[LIVE CALLS] 내용 중 호출 된 URL을 보면 deploy/voting 서비스로 POST 메서드로 /emojivoto.v1.VotingService/VoteDoughnut 패스를 요청하는 부분에서 Success Rate가 0인 것을 확인 할 수 있다.
참고) https://github.com/linkerd/linkerd2