TIL

[Linkerd] mTLS 필수 개념 정리 및 간단 적용 가이드

하얀잔디 2026. 8. 7. 16:54

쿠버네티스 클러스터 구축하고 내부 통신 모니터링이나 보안 세팅하다 보면 꼭 마주치는 게 서비스 메쉬(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