해당 스터디는 90DaysOfDevOps
https://github.com/MichaelCade/90DaysOfDevOps
를 기반으로 진행한 내용입니다.
Day 17 - From Chaos to Resilience: Decoding the Secrets of Production Readiness
10여 년 전 Heroku가 제시한 '12-Factor App' 원칙 (설정 관리, 로그 관리, GitOps의 원형 등)은 성공적인 프로덕션 배포의 기준을 제시하였다.
쿠버네티스는 이러한 과거 '12-Factor App' 같은 성공적인 배포 철학들을 프레임워크 안에 모두 통합하여 견고한 기반을 제공하였다.
따라서, 개발자와 기업 모두에게 기술 투자 위험이 적고, 채용이 용이하며, 클라우드 제공업체(GKE, EKS, Azure 등) 간 이동이 자유롭다는 장점이 존재하여, 쿠버네티스는 오늘날 어플리케이션 배포의 '사실상 표준 (De Facto Standard)'가 되었다.
쿠버네티스는 본질적으로 컨테이너 오케스트레이션 프레임워크이기 때문에, 네트워크 관점에서는 Layer 4(IP와 포트) 수준까지만 이해한다.
이는 IP 주소 기반으로 동작하는 '네트워크 폴리시 (Network Policies)' 같은 기능이 IP가 변경될 수 있는 동적인 환경에서는 신뢰하기 어려운 추상화이다.
이러한 쿠버네티스의 네트워크 관련 격차를 메우기 위해 서비스 메시가 필요하며, Linkerd가 그 중 하나의 플랫폼으로 존재한다.
Linkerd는 각 애플리케이션 컨테이너 옆에 '사이드카 프록시'를 추가하는 방식으로 작동한다.
해당 프록시들이 Pod의 모든 인바운드/아웃바운드 네트워크 연결을 대신 처리한다.
따라서, 모든 트래픽을 제어하는 특권적인 위치에 있어 개발자가 직접 코드를 수정하지 않고도 보안, 관찰 가능성, 신뢰성과 관련된 고급 기능을 API를 통해 선언적으로 설정할 수 있도록 지원한다. (예: 접근 정책, 재시도, 타임아웃 등)
Linkerd는 크게 control plane과 data plane으로 나뉜다.
Control Plane: Linkerd에 대한 전반적인 제어 역할을 담당
destination (트래픽 라우팅 정보 제공) : linkerd-proxy와 통신하여 트래픽을 보낼 위치를 조회하고, 경로 별 metric, retry, timeout, serviceprofile 등과 같은 정보를 가져오는 역할
identity (mTLS 인증서 발급 기관) : linkerd-proxy에서 인증 요청을 수락하고 올바른 ID로 서명된 인증서를 반환하는 인증 기관 역할을 담당하며, 발급된 인증서를 proxy간 mTLS 통신에 사용
proxy-injector (사이드카 프록시 자동 주입) : Pod가 생성될 때의 annotation (linkerd.io/inject: enabled)을 검사하여 Admission webhook (mutating, validating) 요청을 받아 Pod에 init컨테이너 (linkerd-init)와 proxy컨테이너 (linkerd-proxy)를 추가하는 역할
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
metadata:
annotations:
# 해당 어노테이션 한 줄로 Linkerd가 자동으로 사이드카 프록시를 주입
linkerd.io/inject: enabled
spec:
containers:
- name: my-app-container
image: my-app-image
클러스터 경계 (Ingress)만 TLS로 암호화하고 방화벽을 설정하는 것은 클러스터 내부에 침투한 악성코드나 취약점으로 인해 더 큰 위협이 될 수 있다.
따라서, 해당 위협을 해결하기 위해서는 외부 경계만 보호하는 것이 아닌, 보안 경계를 최소 단위인 Pod 수준까지 좁혀야한다. 이러한 이유가 Linkerd가 노드당 하나의 프록시 모델보다 '사이드카 모델'을 고수하는 이유이다.
구현 방식:
mTLS (상호 TLS) : 별도 설정 없이 모든 서비스 간 통신을 자동으로 암호화함.
클라이언트와 서버가 서로의 신원을 암호학적으로 검증하여 내부 통신의 보안을 보장함.
고성능 및 보안 : Linkerd의 프록시는 Rust 언어로 작성됨.
Rust는 가비지 컬렉터가 없어 리소스 소모가 적고, 컴파일러 단에서 메모리 접근 오류를 방지하여 가장 흔한 보안 취약점 중 하나를 원천적으로 차단함.
안정적인 서비스 운영을 위해 시스템 상태를 파악하는 것은 필수이다.
Linkerd 프록시들은 모든 통신의 성공률, 지연 시간(latency) 등 상세한 네트워크 메트릭을 수집하여, 해당 데이터를 프로메테우스(Prometheus), 그라파나(Grafana) 같은 도구로 시각화하여 서비스의 문제점을 신속하게 파악하고 대응할 수 있다.
시스템은 언제나 실패할 수 있다는 가정하에 설계되어야 한다.
Linkerd는 서비스에 대한 타임아웃(Timeout)과 재시도(Retry) 정책을 코드를 변경하지 않고 선언적으로 설정할 수 있는 기능을 제공한다.
또한, 점진적 배포(Progressive Delivery)를 지원하여, 새 버전의 서비스를 배포할 때 트래픽을 서서히 옮기면서 안정성을 확인하고 문제가 생기면 자동으로 롤백할 수 있다.
쿠버네티스는 훌륭한 기반이지만, 그 자체만으로는 복잡한 마이크로서비스 환경의 보안, 관찰 가능성, 신뢰성을 완벽하게 해결하기 어렵다.
따라서, Linkerd와 같은 서비스 메시는 이러한 부족한 부분 (특히 네트워크 관련 격차)을 채워주어 개발자들이 더 안전하고 안정적인 서비스를 구축하고 운영할 수 있도록 돕는 핵심 도구이다.
"참고: Linkerd와 Istio"
서비스 메시의 대표적인 또 다른 주자인 Istio는 매우 풍부하고 강력한 기능을 제공하는 것을 목표로 한다.
반면, Linkerd는 '단순함(Simplicity)', '낮은 리소스 사용량', '성능'에 집중하는 철학을 가지고 있다.
따라서 사용자는 자신의 환경과 목표에 따라 '다재다능한 Istio'와 '가볍고 빠른 Linkerd' 사이에서 적절한 도구를 선택할 수 있다.