쿠버네티스 클러스터 구축하고 내부 통신 모니터링이나 보안 세팅하다 보면 꼭 마주치는 게 서비스 메쉬(Service Mesh)랑 mTLS임.
매번 개념만 대충 알고 넘어가다가 이번에 Linkerd로 세팅하면서 정리해 봄.
mTLS가 왜 필요할까?
보통 외부에서 Ingress/Gateway 들어오는 구간만 HTTPS(TLS) 걸어두면 보안 끝났다고 생각하기 쉬움.
하지만 쿠버네티스 기본 Pod to Pod 통신은 암호화 안 된 순수 평문(HTTP)으로 돌아감.
만약 클러스터 내에 노드 하나가 뚫리거나 악성 컨테이너가 하나라도 뜨면?
내부 망에서 오가는 DB 패스워드, API 토큰, 사용자 데이터 전부 패킷 스니핑으로 그대로 노출됨.
- 일반 TLS (HTTPS): 클라이언트가 '이 서버 진짜 맞나?' 하고 서버만 검증
- mTLS (Mutual TLS): 서버도 "너 인가된 클라이언트/Pod 맞냐?" 하고 양방향 상호 검증 + 트래픽 암호화
즉, 내부망도 아무도 믿지 않는다(Zero Trust) 보안 모델을 적용하려면 필수라고 보면 됨.
인증서 직접 사야 하나?
결론부터 말하면 공인 인증서 살 필요 1도 없음.
외부 유저가 접속하는 Gateway 단이야 브라우저가 신뢰해야 하니 공인 인증서(Let's Encrypt 등)가 필요하지만, 클러스터 내부 Pod끼리 소통하는 mTLS는 외부 사용자가 접근하지 않음.
step CLI나 openssl 같은 도구로 직접 발급한 자체 서명(Self-Signed) 인증서를 써서 로컬/서버에서 무료로 찍어내면 끝임
K3s / HelmController 기준 초간단 배포 가이드
Rancher나 K3s 쓰는 환경이라면 HelmChart CRD 하나로 한 방에 배포 가능함.
① 인증서 생성 (step CLI 활용)
# Root CA 생성 (10년)
step certificate create root.linkerd.cluster.local ca.crt ca.key \
--profile root-ca --no-password --insecure --not-after=87600h
# Issuer 인증서 생성 (1년)
step certificate create identity.linkerd.cluster.local issuer.crt issuer.key \
--profile intermediate-ca --no-password --insecure \
--ca ca.crt --ca-key ca.key --not-after=8760h
Manifest 작성 (linkerd-helm.yaml)
생성된 ca.crt, issuer.crt, issuer.key 텍스트 내용을 YAML의 valuesContent에 포함시켜 줌. CRD 먼저 생성되고 Control Plane이 올라가야 하므로 dependsOn을 반드시 넣어줘야 에러가 안 남.
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: linkerd-crds
namespace: kube-system
spec:
repo: https://helm.linkerd.io/stable
chart: linkerd-crds
targetNamespace: linkerd
createNamespace: true
---
apiVersion: helm.cattle.io/v1
kind: HelmChart
metadata:
name: linkerd-control-plane
namespace: kube-system
spec:
repo: https://helm.linkerd.io/stable
chart: linkerd-control-plane
targetNamespace: linkerd
dependsOn:
- name: linkerd-crds
valuesContent: |
identityTrustAnchorsPEM: |
-----BEGIN CERTIFICATE-----
<ca.crt 내용 복붙>
-----END CERTIFICATE-----
identity:
issuer:
tls:
crtPEM: |
-----BEGIN CERTIFICATE-----
<issuer.crt 내용 복붙>
-----END CERTIFICATE-----
keyPEM: |
-----BEGIN EC PRIVATE KEY-----
<issuer.key 내용 복붙>
-----END EC PRIVATE KEY-----
crtExpiry: "2027-05-20T00:00:00Z"
배포 및 적용
kubectl apply -f linkerd-helm.yaml
Pod에 mTLS 적용하는 법
설치 완료 후 애플리케이션이 떠 있는 Namespace에 annotation만 붙여주면 됨.
# Namespace 전체 파드 자동 사이드카 주입
kubectl annotate namespace my-namespace linkerd.io/inject=enabled
이후 기존 Deployment들을 재기동(kubectl rollout restart deployment/...)하면,
Pod가 새로 떠오르면서 자동으로 linkerd-proxy 사이드카 컨테이너가 붙음 (READY 2/2 상태 확인).
이제 소스코드 수정 단 한 줄 없이 클러스터 내부 Pod 통신 전체에 mTLS 암호화가 완료됨.
'TIL' 카테고리의 다른 글
| Linkerd Canary 배포 (0) | 2026.08.17 |
|---|---|
| Linkerd TrafficSplit 기반 카나리 배포 원리 간단 정리. (0) | 2026.08.11 |
| Postgre HA 구성 용어 정리 (0) | 2026.08.07 |
| UFW Port DROP 문제 해결 (1) | 2026.08.07 |
| 스위칭 , 라우팅.. 왜있는거야? (0) | 2026.07.27 |