Automatically Rotating Webhook TLS Credentials
By default, when Linkerd is installed with the Linkerd CLI or with the Linkerd Helm chart, TLS credentials are automatically generated for all of the webhooks. If these certificates expire or need to be regenerated for any reason, performing a Linkerd upgrade (using the Linkerd CLI or using Helm) will regenerate them.
This workflow is suitable for most users. However, if you need these webhook certificates to be rotated automatically on a regular basis, it is possible to use cert-manager to automatically manage them.
As a first step, and create the namespaces that cert-manager will use to store its webhook-related resources. For simplicity, we suggest using the defaule namespace linkerd uses:
Save the signing key pair as a Secret
Next, we will use the tool, to create a signing key pair which will be used to sign each of the webhook certificates:
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
# ignore if not using the jaeger extension
kubectl create secret tls webhook-issuer-tls --cert=ca.crt --key=ca.key --namespace=linkerd-jaeger
Issuing certificates and writing them to secrets
Finally, we can create cert-manager “Certificate” resources which use the Issuers to generate the desired certificates:
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
secretName: linkerd-sp-validator-k8s-tls
duration: 24h
renewBefore: 1h
issuerRef:
name: webhook-issuer
commonName: linkerd-sp-validator.linkerd.svc
dnsNames:
- linkerd-sp-validator.linkerd.svc
isCA: false
privateKey:
algorithm: ECDSA
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
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
secretName: tap-injector-k8s-tls
duration: 24h
renewBefore: 1h
issuerRef:
name: webhook-issuer
commonName: tap-injector.linkerd-viz.svc
dnsNames:
- tap-injector.linkerd-viz.svc
isCA: false
privateKey:
algorithm: ECDSA
usages:
- server auth
---
# ignore if not using the jaeger extension
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: jaeger-injector
namespace: linkerd-jaeger
spec:
secretName: jaeger-injector-k8s-tls
duration: 24h
renewBefore: 1h
issuerRef:
name: webhook-issuer
kind: Issuer
commonName: jaeger-injector.linkerd.svc
dnsNames:
- jaeger-injector.linkerd.svc
isCA: false
privateKey:
algorithm: ECDSA
usages:
- server auth
EOF
At this point, cert-manager can now use these Certificate resources to obtain TLS credentials, which are stored in the linkerd-proxy-injector-k8s-tls
, linkerd-sp-validator-k8s-tls
, tap-k8s-tls
, tap-injector-k8s-tls
and jaeger-injector-k8s-tls
secrets respectively.
Now we just need to inform Linkerd to consume these credentials.
To configure Linkerd to use the credentials from cert-manager rather than generating its own, we generate a supplemental config file:
linkerd install --values=config.yml | kubectl apply -f -
# ignore if not using the viz extension
linkerd viz install --values=config-viz.yml | kubectl apply -f -
# ignore if not using the jaeger extension
Installing with Helm
For Helm installation, we can configure the Helm values directly:
Note
When installing Linkerd with Helm, you must also provide the issuer trust root and issuer credentials as described in Installing Linkerd with Helm.
Note
See for details on how to do something similar for control plane credentials.