자동 제어평면 TLS 인증서 갱신
Linkerd의 자동 mTLS 기능은 신뢰 앵커, 발급자 인증서, 개인 키로 구성된 TLS 인증서를 사용하여 프록시에 TLS 자격 증명을 제공합니다. 데이터플레인 프록시의 TLS 인증서는 24시간마다 자동으로 갱신되지만, 인증서를 발급하는 데 사용되는 자격 증명 자체는 자동으로 갱신되지 않습니다. 이 문서에서는 cert-manager와 같은 외부 솔루션을 사용하여 발급자 인증서와 개인 키를 자동으로 갱신하는 방법을 설명합니다.
참고: 신뢰 앵커는 여전히 수동으로 갱신해야 합니다.
cert-manager 설치
먼저 클러스터에 cert-manager를 설치합니다. cert-manager 1.0 이상을 설치하려면 Kubernetes 1.16 이상이 필요합니다. 이전 버전의 cert-manager는 Linkerd와 호환되지 않는 RSA 키를 생성할 수 있습니다.
kubectl create namespace linkerd
서명 키 쌍을 Secret으로 저장
step 도구를 사용하여 서명 키 쌍을 생성하고, 생성된 네임스페이스에 Kubernetes Secret으로 저장합니다.
step certificate create root.linkerd.cluster.local ca.crt ca.key \
--profile root-ca --no-password --insecure &&
kubectl create secret tls \
linkerd-trust-anchor \
--cert=ca.crt \
--key=ca.key \
--namespace=linkerd
신뢰 앵커의 유효 기간을 더 길게 설정하려면 --not-after 플래그를 추가합니다 (예: --not-after=87600h).
Issuer 리소스 생성
Secret을 기반으로 cert-manager Issuer 리소스를 만듭니다.
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: linkerd-trust-anchor
namespace: linkerd
spec:
ca:
secretName: linkerd-trust-anchor
EOF
Certificate 리소스 생성
이제 Issuer를 사용하여 인증서를 생성하는 Certificate 리소스를 만듭니다. 이 인증서는 linkerd-identity-issuer Secret에 저장됩니다.
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linkerd-identity-issuer
namespace: linkerd
spec:
secretName: linkerd-identity-issuer
duration: 48h
renewBefore: 25h
issuerRef:
name: linkerd-trust-anchor
kind: Issuer
commonName: identity.linkerd.cluster.local
dnsNames:
- identity.linkerd.cluster.local
isCA: true
privateKey:
algorithm: ECDSA
usages:
- cert sign
- crl sign
- server auth
- client auth
EOF
위 YAML에서 duration은 인증서의 유효 기간(48시간)을, renewBefore는 만료 25시간 전에 갱신을 시도하도록 설정합니다. 생성된 인증서는 다음 명령어로 확인할 수 있습니다.
kubectl get secret linkerd-identity-issuer -o yaml -n linkerd
이제 Linkerd가 이 자격 증명을 사용하도록 설정해야 합니다.
참고: cert-manager 0.15와 실험적 컨트롤러를 사용하는 경우, 생성된 인증서가 Linkerd stable-2.8.1 이하와 호환되지 않을 수 있습니다. 이 경우 Linkerd를 edge-20.6.4 이상으로 업그레이드하거나, cert-manager 0.16 이상으로 업그레이드하는 것이 좋습니다.
다른 CA 제공자 사용
cert-manager를 CA로 사용하는 대신 Vault와 같은 다른 솔루션과 통합할 수도 있습니다. cert-manager 문서에서 다양한 Issuer 유형에 대한 설정 방법을 확인할 수 있습니다.
서드파티 인증서 관리 솔루션
Linkerd는 linkerd-identity-issuer Secret이 kubernetes.io/tls 타입이면 해당 내용을 TLS 자격 증명으로 사용합니다. 따라서 인증서를 이 Secret에 쓰는 모든 솔루션을 사용하여 동적 TLS 인증서 관리를 구현할 수 있습니다.
CLI 설치 시 자격 증명 사용
CLI로 Linkerd를 설치할 때는 --identity-external-issuer 플래그를 사용하여 linkerd-identity-issuer Secret에서 인증서를 읽도록 지시합니다. Secret이 업데이트되면 identity 서비스가 자동으로 이를 감지하고 새 자격 증명을 로드합니다.
kubectl get events --field-selector reason=IssuerUpdated -n linkerd
Helm 설치 시 자격 증명 사용
Helm으로 설치할 때는 identityTrustAnchorsPEM을 linkerd-identity-issuer Secret의 ca.crt 값으로 설정합니다.
helm install linkerd2 \
--set-file identityTrustAnchorsPEM=ca.crt \
--set identity.issuer.scheme=kubernetes.io/tls \
--set installNamespace=false \
linkerd/linkerd2 \
-n linkerd
자동 Webhook TLS 인증서 갱신
Linkerd 제어평면에는 Kubernetes가 직접 호출하는 webhook 컴포넌트가 포함되어 있습니다. 이 트래픽은 TLS로 보호되므로 각 webhook에 TLS 자격 증명이 포함된 Secret이 필요합니다. 기본적으로 Linkerd 설치 시 webhook용 TLS 인증서가 자동 생성됩니다. 만료되면 linkerd upgrade 명령어로 재생성할 수 있습니다. cert-manager를 사용하면 이 과정을 자동화할 수 있습니다.
cert-manager 설치 및 네임스페이스 생성
kubectl create namespace linkerd
kubectl create namespace linkerd-viz # viz 확장 사용 시
kubectl create namespace linkerd-jaeger # jaeger 확장 사용 시
서명 키 쌍을 Secret으로 저장
step certificate create webhook.linkerd.cluster.local ca.crt ca.key \
--profile root-ca --no-password --insecure --san webhook.linkerd.cluster.local
kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd
kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd-viz # 선택
kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd-jaeger # 선택
Issuer 리소스 생성
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: webhook-issuer
namespace: linkerd
spec:
ca:
secretName: webhook-issuer-tls
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: webhook-issuer
namespace: linkerd-viz
spec:
ca:
secretName: webhook-issuer-tls
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: webhook-issuer
namespace: linkerd-jaeger
spec:
ca:
secretName: webhook-issuer-tls
EOF
각 webhook용 Certificate 리소스 생성
각 webhook 컴포넌트에 대해 Certificate 리소스를 생성합니다. 아래는 예시입니다.
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linkerd-proxy-injector
namespace: linkerd
spec:
secretName: linkerd-proxy-injector-k8s-tls
duration: 24h
renewBefore: 1h
issuerRef:
name: webhook-issuer
kind: Issuer
commonName: linkerd-proxy-injector.linkerd.svc
dnsNames:
- linkerd-proxy-injector.linkerd.svc
isCA: false
privateKey:
algorithm: ECDSA
usages:
- server auth
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: linkerd-sp-validator
namespace: linkerd
spec:
secretName: linkerd-sp-validator-k8s-tls
duration: 24h
renewBefore: 1h
issuerRef:
name: webhook-issuer
kind: Issuer
commonName: linkerd-sp-validator.linkerd.svc
dnsNames:
- linkerd-sp-validator.linkerd.svc
isCA: false
privateKey:
algorithm: ECDSA
usages:
- server auth
EOF
필요에 따라 tap, tap-injector, jaeger-injector 등 다른 webhook에 대한 Certificate 리소스도 추가합니다.
CLI 설치 시 외부 Secret 사용
Linkerd가 cert-manager의 자격 증명을 사용하도록 설정 파일을 생성합니다.
CA=$(awk '{ print " " $0 }' ca.crt)
cat > config.yml <<EOF
proxyInjector:
externalSecret: true
caBundle: |
$CA
profileValidator:
externalSecret: true
caBundle: |
$CA
EOF
linkerd install --values=config.yml | kubectl apply -f -
viz 및 jaeger 확장도 비슷한 방식으로 설정합니다.
Helm 설치 시 외부 Secret 사용
helm install linkerd2 \
--set installNamespace=false \
--set proxyInjector.externalSecret=true \
--set-file proxyInjector.caBundle=ca.crt \
--set profileValidator.externalSecret=true \
--set-file profileValidator.caBundle=ca.crt \
linkerd/linkerd2 \
-n linkerd
Helm v3 이하에서는 --name 플래그를 명시적으로 전달해야 할 수 있습니다.