본문 바로가기
WIKI 기술 지식 베이스

웹훅 TLS 자격 증명 자동 교체

원문 보기 위키 갱신

웹훅 TLS 자격 증명 자동 교체 (Automatically Rotating Webhook TLS Credentials)

Linkerd 컨트롤 플레인에는 웹훅(webhook)이라 불리는 여러 컴포넌트가 있는데, 이들은 Kubernetes 자체가 직접 호출해요. Kubernetes에서 Linkerd 웹훅으로 가는 트래픽은 TLS로 보호되며, 따라서 각 웹훅은 TLS 자격 증명이 담긴 시크릿(secret)을 필요로 해요. 이 인증서들은 Linkerd 프록시가 파드 간 통신을 보호할 때 쓰는 인증서와는 다른 것이며 완전히 별개의 신뢰 체인을 사용해요. Linkerd 프록시가 사용하는 TLS 자격 증명 교체에 대한 자세한 내용은 Automatically Rotating Control Plane TLS Credentials 문서를 참고하세요.

기본적으로 Linkerd를 Linkerd CLI나 Linkerd Helm 차트로 설치하면 모든 웹훅에 대해 TLS 자격 증명이 자동으로 생성돼요. 이 인증서가 만료되거나 어떤 이유로든 재생성이 필요하다면, Linkerd 업그레이드(Linkerd CLI 또는 Helm 사용)를 수행하면 재생성돼요.

이 워크플로우는 대부분의 사용자에게 적합해요. 하지만 웹훅 인증서를 정기적으로 자동 교체해야 한다면, cert-manager를 사용해 자동으로 관리할 수 있어요.

Linkerd 프로덕션 팁

이 페이지는 오픈소스 커뮤니티가 제공하는 최선의 노력(best-effort) 지침이에요. 미션 크리티컬 애플리케이션의 프로덕션 사용자는 Linkerd 프로덕션 자료를 숙지하고/또는 상용 Linkerd 제공업체와 연락하는 것이 좋아요.

출처: Linkerd Automatically Rotating Webhook TLS Credentials

본문

Cert manager 설치하기

첫 단계로 클러스터에 cert-manager를 설치하고, cert-manager가 웹훅 관련 리소스를 저장할 네임스페이스를 만들어 주세요. 간단하게 하려면 Linkerd가 기본으로 쓰는 네임스페이스를 사용하는 걸 권장해요:

`# control plane core
kubectl create namespace linkerd
kubectl label namespace linkerd \
  linkerd.io/is-control-plane=true \
  config.linkerd.io/admission-webhooks=disabled \
  linkerd.io/control-plane-ns=linkerd
kubectl annotate namespace linkerd linkerd.io/inject=disabled

# viz (ignore if not using the viz extension)
kubectl create namespace linkerd-viz
kubectl label namespace linkerd-viz linkerd.io/extension=viz
`

서명 키 쌍을 시크릿으로 저장하기

다음으로 step 도구를 사용해 각 웹훅 인증서를 서명할 때 쓸 서명 키 쌍을 만들겠어요:

`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

# ignore if not using the viz extension
kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd-viz
`

시크릿을 참조하는 Issuer 생성하기

시크릿이 준비됐다면, 이를 참조하는 cert-manager "Issuer" 리소스를 만들 수 있어요:

`kubectl apply -f - apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: webhook-issuer
  namespace: linkerd
spec:
  ca:
    secretName: webhook-issuer-tls
---
# ignore if not using the viz extension
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: webhook-issuer
  namespace: linkerd-viz
spec:
  ca:
    secretName: webhook-issuer-tls
EOF
`

인증서 발급 및 시크릿에 쓰기

마지막으로, Issuer를 사용해 원하는 인증서를 생성하는 cert-manager "Certificate" 리소스를 만들 수 있어요:

`kubectl apply -f - apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: linkerd-policy-validator
  namespace: linkerd
spec:
  secretName: linkerd-policy-validator-k8s-tls
  duration: 24h
  renewBefore: 1h
  issuerRef:
    name: webhook-issuer
    kind: Issuer
  commonName: linkerd-policy-validator.linkerd.svc
  dnsNames:
  - linkerd-policy-validator.linkerd.svc
  isCA: false
  privateKey:
    algorithm: ECDSA
    encoding: PKCS8
  usages:
  - server auth
---
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
    encoding: PKCS8
  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
    encoding: PKCS8
  usages:
  - server auth
---
# ignore if not using the viz extension
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: tap
  namespace: linkerd-viz
spec:
  secretName: tap-k8s-tls
  duration: 24h
  renewBefore: 1h
  issuerRef:
    name: webhook-issuer
    kind: Issuer
  commonName: tap.linkerd-viz.svc
  dnsNames:
  - tap.linkerd-viz.svc
  isCA: false
  privateKey:
    algorithm: ECDSA
    encoding: PKCS8
  usages:
  - server auth
---
# ignore if not using the viz extension
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: linkerd-tap-injector
  namespace: linkerd-viz
spec:
  secretName: tap-injector-k8s-tls
  duration: 24h
  renewBefore: 1h
  issuerRef:
    name: webhook-issuer
    kind: Issuer
  commonName: tap-injector.linkerd-viz.svc
  dnsNames:
  - tap-injector.linkerd-viz.svc
  isCA: false
  privateKey:
    algorithm: ECDSA
    encoding: PKCS8
  usages:
  - server auth
EOF
`

이 시점부터 cert-manager는 이 Certificate 리소스들을 사용해 TLS 자격 증명을 얻을 수 있으며, 이 자격 증명은 각각 linkerd-proxy-injector-k8s-tls, linkerd-sp-validator-k8s-tls, tap-k8s-tls, tap-injector-k8s-tls 시크릿에 저장돼요.

이제 Linkerd가 이 자격 증명을 사용하도록 알려 주기만 하면 돼요.

CLI 설치에서 이 자격 증명 사용하기

cert-manager의 자격 증명을 직접 생성하는 대신 사용하도록 Linkerd를 구성하려면:

`# first, install the Linkerd CRDs
linkerd install --crds | kubectl apply -f -

# install the Linkerd control plane, using the credentials
# from cert-manager
linkerd install \
  --set policyValidator.externalSecret=true \
  --set-file policyValidator.caBundle=ca.crt \
  --set proxyInjector.externalSecret=true \
  --set-file proxyInjector.caBundle=ca.crt \
  --set profileValidator.externalSecret=true \
  --set-file profileValidator.caBundle=ca.crt \
  | kubectl apply -f -

# ignore if not using the viz extension
linkerd viz install \
  --set tap.externalSecret=true \
  --set-file tap.caBundle=ca.crt \
  --set tapInjector.externalSecret=true \
  --set-file tapInjector.caBundle=ca.crt \
  | kubectl apply -f -
`

Helm으로 설치하기

Helm에서도 비슷한 패턴을 사용할 수 있어요:

`# first install the linkerd-crds chart
helm install linkerd-crds linkerd/linkerd-crds \
  -n linkerd --create-namespace

# then install the linkerd-control-plane chart
# (see note below)
helm install linkerd-control-plane \
  --set-file identityTrustAnchorsPEM=... \
  --set-file identity.issuer.tls.crtPEM=... \
  --set-file identity.issuer.tls.keyPEM=... \
  --set policyValidator.externalSecret=true \
  --set-file policyValidator.caBundle=ca.crt \
  --set proxyInjector.externalSecret=true \
  --set-file proxyInjector.caBundle=ca.crt \
  --set profileValidator.externalSecret=true \
  --set-file profileValidator.caBundle=ca.crt \
  linkerd/linkerd-control-plane \
  -n linkerd

# ignore if not using the viz extension
helm install linkerd-viz \
  --set tap.externalSecret=true \
  --set-file tap.caBundle=ca.crt \
  --set tapInjector.externalSecret=true \
  --set-file tapInjector.caBundle=ca.crt \
  linkerd/linkerd-viz \
  -n linkerd-viz --create-namespace
`

참고

linkerd-control-plane 차트를 설치할 때는 Installing Linkerd with Helm 문서에 설명된 대로 issuer 신뢰 루트와 issuer 자격 증명을 반드시 제공해야 해요.

컨트롤 플레인 자격 증명에 대해 비슷한 작업을 하는 방법은 Automatically Rotating Control Plane TLS Credentials 문서를 참고하세요.

더 알아보기 (Learn more)