Linkerd의 핵심 개념과 기능에 대해 다뤘던 지난 시간에 이어서, 이번엔 Linkerd를 직접 설치하고 사용해보는 실습을 진행해보겠습니다.
컴팩트한 실습을 위해, Linkerd를 사용할 Kubernetes 클러스터는 minikube로 구성해서 진행하도록 하겠습니다. minikube는 이미 지난 글에서 계속 다뤘기 때문에 추가로 설명하진 않겠습니다.
Linkerd를 직접 사용해보기 전에, 효과적인 실습을 위해 Linkerd의 주요 구성요소를 좀 더 살펴볼게요.
🔎Linkerd의 주요 구성요소 좀 더 살펴보기
Linkerd의 Control Plane은 Service Mesh의 두뇌 역할을 하며 아래와 같은 핵심 컴포넌트로 구성됩니다.
controller
: 공용 API 제공destination
: 서비스 디스커버리와 라우팅 정보 관리identity
: mTLS를 위한 인증서 발급 및 관리proxy-injector
: Pod 생성 시 사이드카 프록시를 자동으로 주입
그리고 Linkerd의 Data Plane은 각 애플리케이션의 Pod에 함께 배포되는 초경량 사이드카 프록시인 linkerd-proxy
로 이루어집니다.
Linkerd 프록시는 해당 Pod로 들어오고 나가는 모든 TCP 트래픽(주로 HTTP, gRPC 등)을 투명하게 가로채는데요. 이렇게 가로챈 트래픽을 가지고 mTLS 암호화, 로드 밸런싱, 재시도, 타임아웃, 메트릭 수집 등의 기능을 수행합니다.
Linkerd CLI는 사용자가 로컬 머신에서 Linkerd Control Plane과 통신하고 Service Mesh를 관리할 수 있는 툴입니다.
CLI 환경에서 Linkerd 설치, 상태 확인, 리소스 통계 조회, 실시간 트래픽 확인, 프록시 주입 등 다양한 작업을 수행할 수 있는데요. Linkerd 운영 및 디버깅에 필수적인 툴이라고 할 수 있습니다.
마지막으로 Linkerd Viz는 Linkerd Service Mesh의 상태와 성능을 시작적으로 확인하고 분석할 수 있는 익스텐션(확장 기능 모음)입니다.
웹 기반 대시보드를 통해 실시간 트래픽, 성공률, 지연 시간 등을 모니터링할 수 있는데요. Prometheus 호환 메트릭 API를 제공하여 외부 모니터링 시스템과의 연동도 가능합니다.
🖥️실습 환경 준비: Linkerd CLI 설치
저는 WSL 환경에서 본 실습을 진행했습니다. 터미널에서 k8s-test라는 이름으로 minikube 클러스터를 먼저 실행할게요.
그 다음, 아래 Linkerd CLI 설치 명령어 실행합니다.
curl --proto '=https' --tlsv1.2 -sSfL https://run.linkerd.io/install-edge | sh
그럼 아래와 같이 Linkerd 설치 스크립트가 다운로드되고 설치가 진행됩니다.
아래 명령어를 실행하여 환경변수도 추가합니다.
export PATH=$HOME/.linkerd2/bin:$PATH
여기까지 완료되었다면 linkerd version
명령어로 Linkerd CLI가 설치되었는지 확인 가능합니다.
아직 minikue 클러스터에 Linkerd의 Control Plane이 배포되어 있지 않기 때문에 Server version은 unavailable
상태인데요. 밑에서 Control Plane까지 배포된 다음 다시 확인해보면 Server version도 업데이트될 겁니다.
Linkerd를 사용하려면 Kubernetes 클러스터에 Gateway API라는 CRD가 설치되어 있어야 합니다. CRD(Custom Resource Definition)란 Kubernetes 클러스터의 기본 리소스 타입(Deployment, StatefulSet 등) 외로 새로운 리소스 유형을 추가해 클러스터의 기능을 확장하는 걸 의미합니다.
Gateway API는 네트워크 트래픽과 관련된 리소스들을 정의하는 CRD인데요. 만약 기존에 설치되어 있지 않다면 아래 명령어를 실행하여 클러스터에 Gateway API를 설치할 수 있습니다.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml
그럼 아래와 같이 Gateway API를 구성하는 CRD들이 설치됩니다.
다음으로, 터미널에 linkerd check --pre
명령어를 실행하면 해당 클러스터가 Linkerd를 사용하는 데에 필요한 사전 조건들을 충족하는지 검증할 수 있습니다. Kubernetes API 상태와 버전부터 Linkerd CLI 버전까지 잠재적인 환경 이슈를 미리 파악 가능한 명령어입니다.
필요한 사전 조건이 모두 충족되었다고 하니, 이제 클러스터에 Linkerd의 Control Plane을 배포해보겠습니다.
🛠️minikube에 Linkerd Control Plane 배포하기
Linkerd의 Control Plane을 배포하려면, 먼저 아래 명령어로 Control Plane 동작에 필요한 CRD들을 설치해야 합니다.
linkerd install --crds | kubectl apply -f -
그 다음, 본격적으로 Linkerd의 Control Plane을 설치해봅시다. 아래 명령어를 실행하면 자동으로 Linkerd Control Plane을 구성하는 컴포넌트들이 설치됩니다.
linkerd install | kubectl apply -f -
만약 minikube가 Docker로 동작 중이라면...
Linkerd Control Plane 설치를 시도할 때 proxy-init 컨테이너가 반드시 root 유저로 동작해야 한다는 메시지와 함께 Linkerd 설치가 안 될 수 있습니다. 그럴 땐
linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -
명령어를 사용해서 Linkerd를 설치합니다.
저 역시 minikube가 Docker로 동작하기 때문에 아래와 같은 명령어로 Linkerd Control Plane을 설치했습니다.
그럼 Linkerd 동작에 필요한 모든 리소스가 linkerd
Namespace에 배포된 것을 확인할 수 있습니다. (kubectl -n linkerd get all
)
다음으로 linkerd check
명령어를 실행하면 Linkerd Control Plane 동작에 필요한 모든 리소스가 설치되었고 정상 동작 중인지 확인할 수 있습니다.
이제, Linkerd의 Observability 기능을 강화하는 viz 익스텐션을 설치해봅시다.
Linkerd viz가 설치되면 웹 대시보드, 온디맨드 탭 기능, Prometheus 호환 메트릭 API 등을 사용할 수 있게 되는데요. Service Mesh의 상태를 시각적으로 파악하고 분석하는 데에 유용합니다.
터미널에서 아래 Linkerd viz 익스텐션 설치 명령어를 실행하면…
linkerd viz install | kubectl apply -f -
아래와 같이 Linkerd viz 익스텐션 작동에 필요한 모든 리소스가 자동으로 설치됩니다.
Linkerd viz 익스텐션은 linkerd-viz
Namespace에 배포됩니다.
터미널에서 linkerd viz dashboard
명령어를 실행하면 아래와 같이 Linkerd viz 대시보드가 열렸다는 메시지가 나올 텐데요. 실습 중인 로컬 머신과 Linkerd 대시보드 Service 간의 포트 포워딩이 설정되어 Linkerd 대시보드에 접근 가능 상태가 된 것입니다.
메시지에서 알려주는 URL을 웹브라우저에서 실행하면…
이렇게 Linkerd viz 웹 대시보드를 확인하실 수 있습니다. Kubernetes 클러스터의 Namespace 별로 표시되는 트래픽에 대한 성공률, RPS, P99 등의 지표로 지금 Linkerd가 정상 동작하고 있음을 알 수 있습니다.
참고로, linkerd viz dashboard
명령어를 실행한 터미널을 계속 켜둬야 Linkerd viz 대시보드에 계속 접근할 수 있는 점 참고해주세요.
이제 우리의 minikube 클러스터에서 Linkerd 구성을 모두 마쳤습니다.🎉
다음으로 Linkerd 핵심 기능을 사용해보기 위해 데모용 Deployment 2개를 배포할 건데요. Linkerd Service mesh에 Deployment를 추가하는 방법도 아주 간단합니다!
🔗실습용 애플리케이션 배포 및 Service Mesh에 추가하기
우리가 지금 구성한 Linkerd Service mesh를 사용해서 트래픽을 관찰하려면 네트워크 트래픽이 발생하는 Service가 Linkerd Service mesh 안에 포함되어야겠죠? Linkerd는 이를 위해 크게 두 가지 방법을 제공합니다.
- linkerd inject 명령어로 이미 배포된 Kubernetes 리소스에 Linkerd proxy 주입
- Linkerd에서 인식 가능한 어노테이션을 특정 Namespace에 추가
우리가 최근까지 사용한 터미널은 linkerd viz dashboard
프로세스를 계속 실행 중이니, 별도의 터미널을 열어서 실습을 이어가주세요.
그리고 Linkerd 실습에 사용될 Kubernetes 리소스를 따로 배포하기 위해 linkerd-demo
란 이름의 Namespace를 먼저 생성해주세요.
1. linkerd inject 명령어 사용
linkerd inject
명령어를 직접 사용해보기 위해, 먼저 Linkerd 프록시가 없는 Nginx Deployment를 배포해보겠습니다. 아래 Deployment와 Service 매니페스트를 YAML파일로 저장한 다음 클러스터에 적용(apply
)해주세요.
# 1. Linkerd로 관찰할 '서버' 역할 Nginx Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world-server
namespace: linkerd-demo
spec:
replicas: 1
selector:
matchLabels:
app: hello-world-server
template:
metadata:
labels:
app: hello-world-server
spec:
containers:
- name: hello-world
image: nginx:alpine
ports:
- containerPort: 80
---
# 2. '서버' Nginx Deployment를 클러스터 내에서 호출할 수 있는 Service
apiVersion: v1
kind: Service
metadata:
name: hello-world-server
namespace: linkerd-demo
spec:
selector:
app: hello-world-server
ports:
- name: http
port: 80
targetPort: 80
그 다음 Linkerd viz 대시보드로 돌아와서 아까 생성한 linkerd-demo Namespace를 클릭해보면…
방금 우리가 배포한 hello-world-server Deployment 등이 표시되고는 있지만, 아직 메트릭이 아무것도 표시되고 있지 않죠? Linkerd 프록시가 해당 Deployment에 주입되지 않아서 Linkerd가 이 Deployment에 대한 트래픽 메트릭을 받아오지 못한 것입니다.
그리고 이미지에서 보이는 Meshed(메시화)는 현재 Service mesh에 포함된 리소스의 개수를 표시한 수치입니다. 지금은 메시화된 리소스가 하나도 없어서 각각 ‘0/1’로 표시된 거죠.
이렇게 Linkerd 사용 전부터 배포된 Kubernetes의 리소스, 정확히는 Pod 설정에 Linkerd 프록시컨테이너를 직접 추가하는 명령어가 바로 linkerd inject
입니다.
그렇다면 어떻게 지금 배포되어있는 Deployment에 Linkerd 프록시를 주입해서 다시 배포할 수 있을까요? 아래 명령어를 사용하면 됩니다.
kubectl -n linkerd-demo get deploy -o yaml | linkerd inject - | kubectl apply -f -
위 명령어는 다음과 같은 흐름으로 실행됩니다.
linkerd-demo
Namespace에 존재하는 모든 Deployment의 매니페스트를 YAML 양식으로 가져온다.- 가져온 매니페스트의 Pod 설정에 Linkerd 프록시 관련 어노테이션을 주입한다.
- 주입된 매니페스트를 다시 클러스터에 배포한다.
해당 명령어를 실행하면 아래와 같이 주입 및 설정이 변경되었다는 메시지가 뜨고,
해당 Deployment의 설정을 describe 명령어로 보면…
빨간 네모로 표시한 것처럼 Pod 설정 내에 Linkerd의 inject가 활성화되었다는 어노테이션이 추가된 것을 알 수 있습니다. 이제 Linkerd 웹 대시보드를 다시 확인해볼까요?
Meshed도 1/1로 업데이트되었고 각 메트릭도 정상적으로 표시되고 있네요!
이렇게 linkerd inject
명령어를 사용하면 기존에 배포되어있던 Kubernetes 리소스의 Pod도 쉽고 빠르게 Linkerd의 Service mesh에 편입시킬 수 있습니다.
2. Linkerd가 인식 가능한 어노테이션을 Namespace에 추가
만약 특정 Namespace에 배포되는 Pod는 생성되자마자 Linkerd Service mesh에 포함시키고 싶은 땐 어떻게 해야 할까요? 충분히 있을 수 있는 시나리오인데요.
이럴 땐 Linkerd의 어노테이션을 원하는 Namespace에 추가하기만 하면 됩니다. 간단한 내용이기 때문에 바로 실습해볼게요.
먼저 기존 Namespace(linkerd-demo
)의 설정을 확인해보겠습니다.
우리가 이 Namespace를 생성할 때 다른 설정을 추가하지 않았기 때문에 기본값만 가지고 있는데요. kubectl에는 리소스에 어노테이션을 추가하는 명령어(annotate
)를 지원하고 있기 때문에 아래 명령어로 Linkerd의 어노테이션을 추가해보겠습니다.
kubectl annotate namespace linkerd-demo linkerd.io/inject=enabled
그리고 다시 Namespace 설정을 확인해보면 아까 첫 번째 Inject 방식에서 추가된 것과 동일한 어노테이션이 추가되었는데요. 이제 linkerd-demo
Namespace에 추가되는 모든 Pod는 Linkerd 프록시 사이드카 컨테이너가 같이 되는 것입니다. 금방 끝났죠?
이제 아래 새로운 Deployment를 해당 Namespace에 배포해보겠습니다. 이 traffic-generator란 이름의 Deployment는 아까 우리가 배포했던 hello-world-server에 2초마다 HTTP 트래픽을 보내는데요. 이건 이따 Linkerd의 트래픽 관찰 기능에서도 살펴볼 예정입니다.
# '서버'로 꾸준히 트래픽을 발생시킬 '클라이언트' Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: traffic-generator
namespace: linkerd-demo
spec:
replicas: 1
selector:
matchLabels:
app: traffic-generator
template:
metadata:
labels:
app: traffic-generator
spec:
containers:
- name: traffic-curl
image: curlimages/curl:latest
# 2초마다 hello-world-server 서비스로 HTTP 요청 보냄
command: ["sh", "-c", "while true; do echo '--> Sending request to hello-world-server'; curl -s http://hello-world-server > /dev/null; echo 'Request sent.'; sleep 2; done"]
저는 위 YAML 파일을 client.yaml
이란 이름으로 저장 후 kubectl apply
명령어로 클러스터에 적용했습니다.
그리고 다시 Linkerd 웹 대시보드를 확인해보면…
방금 배포한 Deployment의 Pod도 Meshed 상태가 되고 트래픽 메트릭도 제대로 표시되고 있습니다! 이렇게 linkerd-demo
Namespace에 새로 생성되는 Pod는 이제 자동으로 Linkerd의 Service mesh에 편입됩니다.
지금까지 Linkerd의 Service mesh에 Pod를 편입시키는 두 가지 방법에 대해 알아봤는데요. Linkerd의 설계 철학인 ‘Keep it simple’과 ‘Just work’이 녹아든, 아주 간단한 방식입니다.
이제 우리의 Deployment도 Linkerd Service mesh에 잘 편입되었으니, Linkerd의 핵심 기능들을 실제로 사용해보겠습니다.
✨Linkerd 핵심 기능 직접 사용해보기
Linkerd의 핵심 기능들은 대부분 Linkerd 웹 대시보드에서도 접근할 수 있습니다. 하지만 터미널에서 특정 명령어로 원하는 부분만 바로 확인해야 하는 경우도 있기 때문에, 본 실습의 마무리로 Linkerd의 필수 기능에 대한 명령어 3가지를 같이 살펴보도록 하겠습니다.
1. linkerd viz stat
명령어로 현재 트래픽 통계 확인하기
linkerd viz stat
Linkerd Service Mesh 내 리소스들의 실시간 트래픽 통계를 요약하여 보여주는 도구입니다. 아래와 같이 사용하면 linkerd-demo
Namespace 내 모든 Deployment의 현재 초당 요청 수(RPS), 성공률(SR), 지연 시간(P99) 등을 확인할 수 있죠.
linkerd viz stat deploy -n linkerd-demo
2. linkerd viz tap
명령어로 실시간 요청 및 응답 스트림 관찰하기
linkerd viz tap
명령어는 특정 k8s 리소스(Deployment, Pod, Service 등)를 통과하는 실제 요청과 응답의 스트림을 실시간으로 캡처해서 보여주는 도구입니다. 개발자나 운영자는 이를 통해 개별 요청의 헤더, 본문, 상태 코드, 지연 시간 등을 직접 확인할 수 있기 때문에 문제 해결이나 트래픽 분석에 유용한데요.
아래와 같이 linkerd-demo
Namespace 내 모든 Deployment에서 발생하는 요청과 응답 스트림을 실시간으로 확인할 수 있습니다.
linkerd viz tap deploy -n linkerd-demo
3. linkerd viz edges
명령어로 서비스 간 mTLS 암호화 연결 상태 확인하기
Linkerd는 Service Mesh에 포함된 서비스 간의 모든 TCP 통신을 자동으로 mTLS로 암호화한다고 했죠. 이러한 mTLS 연결 상태는 Linkerd 대시보드의 토폴로지 뷰나 각 서비스 상세 화면에서 시각적으로 확인할 수 있는데요.
터미널에서 linkerd viz edges deploy -n {Namespace 이름}
와 같은 명령어를 통해서도 어떤 서비스들이 mTLS로 안전하게 통신하고 있는지 바로 확인 가능합니다. 아래와 같이 명령어를 실행하면 linkerd-demo
Namespace 내 모든 Deployment의 mTLS 연결 상태를 확인할 수 있는 겁니다.
linkerd viz edges deploy -n linkerd-demo
🔭마무리
지금까지 Linkerd 설치부터 Service mesh에 Deployment 편입, Linkerd의 핵심 명령어 3가지까지 살펴봤는데요. Linkerd란 무엇인지 조금 더 감이 잡히셨나요?
물론 실제 운영 환경에 Linkerd를 성공적으로 도입하기 위해서는 Control Plane과 Data Plane의 리소스 요구 사항 계획부터 고가용성을 위한 Control Plane 복제 구성 등 고려해야 할 사항이 더 있을 수 있습니다.
하지만 Linkerd와 같은 Service Mesh를 직접 설치하고 운영해보는 경험은 마이크로서비스 아키텍처의 복잡한 통신 문제를 해결하고, 서비스의 관찰 가능성, 신뢰성, 보안을 향상시키는 데에 필요한 실질적인 역량을 키워줍니다.
이런 경험은 단순히 하나의 도구를 배우는 것을 넘어, 클라우드 네이티브 환경에서의 시스템 운영 전반에 대한 이해도를 높이는 중요한 밑거름이 된다고 할 수 있습니다.
부디 이번 시리즈를 통해 Service mesh나 Linkerd에 대해 더 알고 싶으셨던 분들에게 좋은 첫 걸음이 되었길 바랍니다.
그럼 다음 아티클에서 더 흥미로운 주제로 찾아뵙겠습니다. 감사합니다!