Linkerd SMI 확장 시작하기
경고
Linkerd SMI 확장은 더 이상 사용되지 않으며(deprecated) 향후 릴리스에서 제거될 예정이에요. 현재 이 기능을 사용 중이라면, SMI 확장이 필요 없는 동적 요청 라우팅으로 마이그레이션하는 것을 권장해요.
Service Mesh Interface(SMI)는 Kubernetes의 서비스 메시를 위한 표준 인터페이스예요. SMI를 구현하는 서비스 메시 전반에서 사용할 수 있는 리소스 집합을 정의해요. 자세한 내용은 스펙에서 확인할 수 있어요.
현재 Linkerd는 SMI의 TrafficSplit 스펙을 지원하며, 이를 사용해 서비스 간 트래픽 분할을 네이티브하게 수행할 수 있어요. 즉 추가 컴포넌트나 설정 없이 SMI 리소스를 적용할 수 있다는 뜻이에요. 하지만 SMI는 일종의 서비스 메시 기능의 최소 공통 분모이기 때문에, Linkerd가 여기에 특화된 추가 설정을 넣을 수 없다는 단점도 있어요.
이런 문제를 해결하기 위해 Linkerd는 SMI 스펙을 Linkerd가 이해하고 수행할 수 있는 네이티브 설정으로 변환하는 어댑터를 가질 수 있어요. 이렇게 하면 컨트롤 플레인과 SMI 리소스 간의 불필요한 네이티브 결합도 제거되고, 어댑터는 독립적으로 움직이며 자체 릴리스 주기를 가질 수 있어요. Linkerd SMI 확장이 바로 그 역할을 해요.
이 가이드에서는 SMI 확장을 설치하고 TrafficSplit 스펙을 구성해 서비스 간 트래픽 분할을 수행하는 방법을 단계별로 알아볼게요.
본문
사전 요구 사항
- 이 가이드를 사용하려면 클러스터에 Linkerd가 설치되어 있어야 해요. 아직 설치하지 않았다면 Installing Linkerd 가이드를 따르세요.
Linkerd-SMI 확장 설치
CLI
다음을 실행해 SMI 확장 CLI 바이너리를 설치해요:
curl -sL https://linkerd.github.io/linkerd-smi/install | sh
또는 릴리스 페이지에서 CLI를 직접 다운로드할 수도 있어요.
첫 번째 단계는 Linkerd-SMI 확장을 클러스터에 설치하는 것이에요. 이 확장은 SMI 리소스를 네이티브 Linkerd 리소스로 변환하는 SMI-Adaptor로 구성돼요.
Linkerd-SMI 확장을 설치하려면 다음 명령을 실행해요:
linkerd smi install | kubectl apply -f -
다음을 실행해 Linkerd-SMI 확장이 올바르게 설치됐는지 확인할 수 있어요:
linkerd smi check
Helm
linkerd-smi Helm 차트를 설치하려면 다음을 실행해요:
helm repo add l5d-smi https://linkerd.github.io/linkerd-smi
helm install l5d-smi/linkerd-smi --generate-name
샘플 애플리케이션 설치
먼저 샘플 애플리케이션을 설치해 볼게요.
# create a namespace for the sample application
kubectl create namespace trafficsplit-sample
# install the sample application
linkerd inject https://raw.githubusercontent.com/linkerd/linkerd2/main/test/integration/viz/trafficsplit/testdata/application.yaml | kubectl -n trafficsplit-sample apply -f -
이렇게 하면 간단한 클라이언트와 두 개의 서버 디플로이먼트가 설치돼요. 서버 디플로이먼트 중 하나인 failing-svc는 항상 500 오류를 반환하고, 다른 하나인 backend-svc는 항상 200을 반환해요.
kubectl get deployments -n trafficsplit-sample
NAME READY UP-TO-DATE AVAILABLE AGE
backend 1/1 1 1 2m29s
failing 1/1 1 1 2m29s
slow-cooker 1/1 1 1 2m29s
기본적으로 클라이언트는 backend-svc 서비스를 호출해요. 이는 edges 서브커맨드로 확인할 수 있어요.
linkerd viz edges deploy -n trafficsplit-sample
SRC DST SRC_NS DST_NS SECURED
prometheus backend linkerd-viz trafficsplit-sample √
prometheus failing linkerd-viz trafficsplit-sample √
prometheus slow-cooker linkerd-viz trafficsplit-sample √
slow-cooker backend trafficsplit-sample trafficsplit-sample √
TrafficSplit 구성
이제 backend-svc와 failing-svc 사이에 부하를 분산하도록 backend-svc에 Traffic Splitting을 수행하는 TrafficSplit 리소스를 적용해 볼게요.
kubectl apply -f - apiVersion: split.smi-spec.io/v1alpha2
kind: TrafficSplit
metadata:
name: backend-split
namespace: trafficsplit-sample
spec:
service: backend-svc
backends:
- service: backend-svc
weight: 500
- service: failing-svc
weight: 500
EOF
smi-adaptor가 TrafficSplit 리소스를 감시하기 때문에, 동일한 작업을 수행하는 해당 ServiceProfile 리소스를 자동으로 생성해요. 이는 ServiceProfile 리소스를 조회해 확인할 수 있어요.
kubectl describe serviceprofile -n trafficsplit-sample
Name: backend-svc.trafficsplit-sample.svc.cluster.local
Namespace: trafficsplit-sample
Labels:
Annotations:
API Version: linkerd.io/v1alpha2
Kind: ServiceProfile
Metadata:
Creation Timestamp: 2021-08-02T12:42:52Z
Generation: 1
Managed Fields:
API Version: linkerd.io/v1alpha2
Fields Type: FieldsV1
fieldsV1:
f:spec:
.:
f:dstOverrides:
Manager: smi-adaptor
Operation: Update
Time: 2021-08-02T12:42:52Z
Resource Version: 3542
UID: cbcdb74f-07e0-42f0-a7a8-9bbcf5e0e54e
Spec:
Dst Overrides:
Authority: backend-svc.trafficsplit-sample.svc.cluster.local
Weight: 500
Authority: failing-svc.trafficsplit-sample.svc.cluster.local
Weight: 500
Events:
볼 수 있듯이 TrafficSplit을 수행하기 위해 DstOverrides가 포함된 해당 ServiceProfile이 생성됐어요.
트래픽 분할은 edges 명령을 실행해 확인할 수 있어요.
linkerd viz edges deploy -n trafficsplit-sample
SRC DST SRC_NS DST_NS SECURED
prometheus backend linkerd-viz trafficsplit-sample √
prometheus failing linkerd-viz trafficsplit-sample √
prometheus slow-cooker linkerd-viz trafficsplit-sample √
slow-cooker backend trafficsplit-sample trafficsplit-sample √
slow-cooker failing trafficsplit-sample trafficsplit-sample √
이것은 TrafficSplit 리소스에 stat 서브커맨드를 실행해서도 확인할 수 있어요.
linkerd viz stat ts/backend-split -n traffic-sample
NAME APEX LEAF WEIGHT SUCCESS RPS LATENCY_P50 LATENCY_P95 LATENCY_P99
backend-split backend-svc backend-svc 500 100.00% 0.5rps 1ms 1ms 1ms
backend-split backend-svc failing-svc 500 0.00% 0.5rps 1ms 1ms 1ms
이것은 smi-adaptor 로그를 확인해서도 검증할 수 있어요.
kubectl -n linkerd-smi logs deploy/smi-adaptor smi-adaptor
time="2021-08-04T11:04:35Z" level=info msg="Using cluster domain: cluster.local"
time="2021-08-04T11:04:35Z" level=info msg="Starting SMI Controller"
time="2021-08-04T11:04:35Z" level=info msg="Waiting for informer caches to sync"
time="2021-08-04T11:04:35Z" level=info msg="starting admin server on :9995"
time="2021-08-04T11:04:35Z" level=info msg="Starting workers"
time="2021-08-04T11:04:35Z" level=info msg="Started workers"
time="2021-08-04T11:05:17Z" level=info msg="created serviceprofile/backend-svc.trafficsplit-sample.svc.cluster.local for trafficsplit/backend-split"
time="2021-08-04T11:05:17Z" level=info msg="Successfully synced 'trafficsplit-sample/backend-split'"
정리
다음을 실행해 trafficsplit-sample 리소스를 삭제해요.
kubectl delete namespace/trafficsplit-sample
결론
Linkerd가 현재 TrafficSplit 리소스를 직접 읽는 것을 지원하지만, ServiceProfiles는 항상 TrafficSplit 리소스보다 우선해요. TrafficSplit 리소스에 대한 지원은 향후 릴리스에서 제거될 예정이며, 그 시점에는 Linkerd에서 SMI 리소스를 사용하려면 linkerd-smi 확장이 필요하게 돼요.