Using external issuer certificates
As already explained in theAutomatic mTLS section, Linkerdstores the trust root, certificate and private key in a Kubernetes secret.The contents of this secret are used by the identity
service to sign thecertificate signing requests (CSR)that are issued by the proxy. The trust root, certificates and private keycan either be generated automatically by the CLI upon installation or canbe supplied by the user. If the latter is true, the necessity for providingthe user with more control over the life cycle of these credential arises.In order to do that Linkerd edge-19.10.5introduces the functionality to read and continuously monitor Kubernetessecrets for certificates change and to auto-reload the identity
component'sin-memory issuer certificate. In the following lines, we will demonstrate howthis allows integration with the external certificate management solutioncert-manager.
Prerequisites
You need to have cert-manager installed and running on your cluster. Thisis the software that will take care of creating and updating the certificatesand writing them into a secret of your choice. In order to install that on yourcluster follow theInstalling on Kubernetessection of the docs. You also need to have a signing key pair that will be usedby the cert manager Issuer to generate signed certificates. SeeGenerating the certificates with stepfor examples on how to create the CA trust root. All certificates must use theECDSA P-256 algorithm.
Create the namespace that Linkerd will reside in
As cert-manager issuers are namespace based, the linkerd
namespace needs toexist beforehand. This is where the rest of the cert-manager specific toLinkerd (but not part of its installation) resources need to live. For thatpurpose you can execute the following command:
kubectl create namespace linkerd
Save the signing key pair as a Secret
To allow the Issuer to reference the signing key pair, it needs to be stored ina Kubernetes secret, created in the linkerd
namespace. Let's name itlinkerd-trust-anchor
and use step
to generate certificates and store themin the secret:
step certificate create identity.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
Create an Issuer referencing the secret
Now that we have the secret in place, we can create an Issuer thatreferences it:
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1alpha2
kind: Issuer
metadata:
name: linkerd-trust-anchor
namespace: linkerd
spec:
ca:
secretName: linkerd-trust-anchor
EOF
As an alternative to Issuer
you can use a ClusterIssuer
. In order to avoidover-permissive RBAC settings we recommend to use the former.
Issuing certificates and writing them to a secret
We can now create a Certificate resource which will specify the desiredcertificate:
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: linkerd-identity-issuer
namespace: linkerd
spec:
secretName: linkerd-identity-issuer
duration: 24h
renewBefore: 1h
issuerRef:
name: linkerd-trust-anchor
kind: Issuer
commonName: identity.linkerd.cluster.local
isCA: true
keyAlgorithm: ecdsa
usages:
- cert sign
- crl sign
- server auth
- client auth
EOF
Once this resource is in place cert-manager will attempt to use it to obtaina certificate. If successful this operation will result in the certificatebeing stored in a secret named linkerd-identity-issuer
. This certificate willbe valid for 24 hours as specified by the duration
key. The renewBefore
keyindicates that cert-manager will attempt to issue a new certificate one hourbefore expiration of the current one. In order to see your newly issuedcertificate, you can execute:
kubectl get secret linkerd-identity-issuer -o yaml -n linkerd
Using the certificate in Linkerd
In order to use the externally managed certificates you need to install Linkerdwith the —identity-external-issuer
flag. Upon installation instead ofgenerating the trust root and certificates or reading them from a file, the CLIwill fetch them from the linkerd-identity-issuer
secret. Furthermore,whenever cert-manager updates the certificate and key stored in the secret, theidentity
service will automatically detect this change and reload the newlycreated credentials. In order to monitor this process you can check theIssuerUpdated
events emitted by the service:
kubectl get events --field-selector reason=IssuerUpdated -n linkerd
NoteLinkerd will work with any secret of type kubernetes.io/tls
, containingthe ca.crt
, tls.crt
and tls.key
data fields. The secret must be namedlinkerd-identity-issuer
. This allows for the use of other certificatemanagement solutions such as Vault.
Using Helm
Alternatively if you want to install through Helm, you need to make sure thatcert-manager
is installed and configured in the linkerd
namespace. You canconsult the Customizing the Namespacesection in order to ensure your namespace has all the required labels.When all of that is in place simply supply the trust root that is in yourlinkerd-identity-issuer
secret:
helm install \
--name=linkerd2 \
--set-file global.identityTrustAnchorsPEM=<your-trust-roots> \
--set identity.issuer.scheme=kubernetes.io/tls \
--set installNamespace=false \
linkerd/linkerd2
NoteIts important that global.identityTrustAnchorsPEM
matches the value ofca.crt
in your linkerd-identity-issuer
secret