Vault Agent Injector TLS with Cert-Manager
The following instructions demonstrate how to configure the Vault Agent Injector to use certificates generated by cert-manager. This allows you to run multiple replicas of the Vault Agent Injector in a Kubernetes cluster.
Prerequisites
Install cert-manager if not already installed (see the cert-manager documentation). For example, with helm:
$ helm repo add jetstack https://charts.jetstack.io$ helm repo update$ helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --set installCRDs=true
Create a Certificate Authority (CA)
For this example we will bootstrap a self-signed certificate authority (CA) Issuer. If you already have a ClusterIssuer configured for your cluster, you may skip this step.
apiVersion: cert-manager.io/v1kind: Issuermetadata: name: selfsignedspec: selfSigned: {}---apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: injector-selfsigned-caspec: isCA: true commonName: Agent Inject CA secretName: injector-ca-secret duration: 87660h # 10 years privateKey: algorithm: ECDSA size: 256 issuerRef: name: selfsigned kind: Issuer group: cert-manager.io---apiVersion: cert-manager.io/v1kind: Issuermetadata: name: injector-ca-issuerspec: ca: secretName: injector-ca-secret
Save that to a file named ca-issuer.yaml
, and apply to your Kubernetes cluster:
$ kubectl apply -n vault -f ca-issuer.yamlissuer.cert-manager.io/selfsigned createdcertificate.cert-manager.io/injector-selfsigned-ca createdissuer.cert-manager.io/injector-ca-issuer created$ kubectl -n vault get issuers -o wideNAME READY STATUS AGEinjector-ca-issuer True Signing CA verified 7sselfsigned True 7s$ kubectl -n vault get certificates injector-selfsigned-ca -o wideNAME READY SECRET ISSUER STATUS AGEinjector-selfsigned-ca True injector-ca-secret selfsigned Certificate is up to date and has not expired 32s
Create the Vault Agent Injector Certificate
Next we can create a request for cert-manager to generate a certificate and key signed by the certificate authority above. This certificate and key will be used by the Vault Agent Injector for TLS communications with the Kubernetes API.
The Certificate request object references the CA issuer created above, and specifies the name of the Secret where the CA, Certificate, and Key will be stored by cert-manager.
apiVersion: cert-manager.io/v1kind: Certificatemetadata: name: injector-certificatespec: secretName: injector-tls duration: 24h renewBefore: 144m # roughly 10% of 24h dnsNames: - vault-agent-injector-svc - vault-agent-injector-svc.vault - vault-agent-injector-svc.vault.svc issuerRef: name: injector-ca-issuer commonName: Agent Inject Cert
Important Note: The dnsNames for the certificate must be configured to use the name of the Vault Agent Injector Kubernetes service and namespace where it is deployed.
In this example the Vault Agent Injector service name is vault-agent-injector-svc
in the vault
namespace.
This uses the pattern <k8s service name>.<k8s namespace>.svc
.
Save the Certificate yaml to a file and apply to your cluster:
$ kubectl -n vault apply -f injector-certificate.yamlcertificate.cert-manager.io/injector-certificate created$ kubectl -n vault get certificates injector-certificate -o wideNAME READY SECRET ISSUER STATUS AGEinjector-certificate True injector-tls injector-ca-issuer Certificate is up to date and has not expired 41s$ kubectl -n vault get secret injector-tlsNAME TYPE DATA AGEinjector-tls kubernetes.io/tls 3 6m59s
Configuration
Now that a certificate authority and a signed certificate have been created, we can now configure Helm and the Vault Agent Injector to use them.
Install the Vault Agent Injector with the following custom values:
$ helm install vault hashicorp/vault \ --namespace=vault \ --set injector.replicas=2 \ --set injector.leaderElector.enabled=false \ --set injector.certs.secretName=injector-tls \ --set injector.webhook.annotations="cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/injector-certificate"