NEW: Get project updates onTwitterandMastodon

csi-driver

csi-driver is a Container Storage Interface (CSI) driver plugin for Kubernetes which works alongside cert-manager.

Pods which mount the cert-manager csi-driver will request certificates from cert-manager without needing a Certificate resource to be created. These certificates will be mounted directly into the pod, with no intermediate Secret being created.

Why use csi-driver?

  • Ensure private keys never leave the node and are never sent over the network. Private keys are stored in memory, and shouldn't be written to disk.
  • Unique key and certificate per application replica
  • Fewer Certificate resources means writing less YAML
  • Keys and certificates are destroyed when an application terminates
  • No Secret resources needed for storing the certificate means less RBAC
  • Great for ephemeral, short-lived certificates which don't need to survive a restart (e.g. certificates for mTLS)

Why not use csi-driver?

  • If you need certificates to be persisted through a node restart
  • If you need the same certificate to be shared by multiple components

Installation

See the installation guide for instructions on how to install csi-driver.

Requesting and Mounting Certificates

Requesting a certificate using csi-driver means mounting a volume, with some attributes set to define exactly what you need to request.

The following example is a dummy app that mounts a key certificate pair to /tls, signed using a cert-manager issuer called ca-issuer with a DNS name valid for my-service.sandbox.svc.cluster.local.

apiVersion: v1
kind: Pod
metadata:
name: my-csi-app
namespace: sandbox
labels:
app: my-csi-app
spec:
containers:
- name: my-frontend
image: busybox
volumeMounts:
- mountPath: "/tls"
name: tls
command: [ "sleep", "1000000" ]
volumes:
- name: tls
csi:
driver: csi.cert-manager.io
volumeAttributes:
csi.cert-manager.io/issuer-name: ca-issuer
csi.cert-manager.io/dns-names: ${POD_NAME}.${POD_NAMESPACE}.svc.cluster.local

Once created, the CSI driver will generate a private key locally (for the pod), request a certificate from cert-manager based on the given attributes, and store the certificate ready for the pod to use.

The pod will remain in a pending state until issuance has been completed.

For more information on how to set up issuers for your cluster, refer to the cert-manager documentation here.

Note it is not possible to use SelfSigned Issuers with csi-driver because SelfSigned issuers are a special case.

Supported Volume Attributes

The csi-driver driver aims to have complete feature parity with all possible values available through the cert-manager API. It currently supports the following values:

AttributeDescriptionDefaultExample
csi.cert-manager.io/issuer-nameThe Issuer name to sign the certificate request.ca-issuer
csi.cert-manager.io/issuer-kindThe Issuer kind to sign the certificate request.IssuerClusterIssuer
csi.cert-manager.io/issuer-groupThe group name the Issuer belongs to.cert-manager.ioout.of.tree.foo
csi.cert-manager.io/common-nameCertificate common name (supports variables).my-cert.foo
csi.cert-manager.io/dns-namesDNS names the certificate will be requested for. At least a DNS Name, IP or URI name must be present (supports variables).a.b.foo.com,c.d.foo.com
csi.cert-manager.io/ip-sansIP addresses the certificate will be requested for.192.0.0.1,192.0.0.2
csi.cert-manager.io/uri-sansURI names the certificate will be requested for (supports variables).spiffe://foo.bar.cluster.local
csi.cert-manager.io/durationRequested duration the signed certificate will be valid for.720h1880h
csi.cert-manager.io/is-caMark the certificate as a certificate authority.falsetrue
csi.cert-manager.io/key-usagesSet the key usages on the certificate request.digital signature,key enciphermentserver auth,client auth
csi.cert-manager.io/key-encodingSet the key encoding format (PKCS1 or PKCS8).PKCS1PKCS8
csi.cert-manager.io/certificate-fileFile name to store the certificate file at.tls.crtfoo.crt
csi.cert-manager.io/ca-fileFile name to store the ca certificate file at.ca.crtfoo.ca
csi.cert-manager.io/privatekey-fileFile name to store the key file at.tls.keyfoo.key
csi.cert-manager.io/fs-groupSet the FS Group of written files. Should be paired with and match the value of the consuming container runAsGroup.2000
csi.cert-manager.io/renew-beforeThe time to renew the certificate before expiry. Defaults to a third of the requested duration.$CERT_DURATION/372h
csi.cert-manager.io/reuse-private-keyRe-use the same private when when renewing certificates.falsetrue
csi.cert-manager.io/pkcs12-enableEnable writing the signed certificate chain and private key as a PKCS12 file.true
csi.cert-manager.io/pkcs12-filenameFile location to write the PKCS12 file. Requires csi.cert-manager.io/keystore-pkcs12-enable be set to true.keystore.p12tls.p12
csi.cert-manager.io/pkcs12-passwordPassword used to encode the PKCS12 file. Required when PKCS12 is enabled (csi.cert-manager.io/keystore-pkcs12-enable: true).my-password

Variables

The following attributes support variables that are evaluated when a request is made for the mounting Pod. These variables are useful for constructing requests with SANs that contain values from the mounting Pod.

csi.cert-manager.io/common-name
csi.cert-manager.io/dns-names
csi.cert-manager.io/uri-sans

Variables follow the go os.Expand structure, which is generally what you would expect on a UNIX shell. The CSI driver has access to the following variables:

${POD_NAME}
${POD_NAMESPACE}
${POD_UID}
${SERVICE_ACCOUNT_NAME}

Example Usage

volumeAttributes:
csi.cert-manager.io/issuer-name: ca-issuer
csi.cert-manager.io/dns-names: "${POD_NAME}.${POD_NAMESPACE}.svc.cluster.local"
csi.cert-manager.io/uri-sans: "spiffe://cluster.local/ns/${POD_NAMESPACE}/pod/${POD_NAME}/${POD_UID}"
csi.cert-manager.io/common-name: "${SERVICE_ACCOUNT_NAME}.${POD_NAMESPACE}"

Requesting Certificates using the mounting Pod's ServiceAccount

If the flag --use-token-request is enabled on the csi-driver DaemonSet, the CertificateRequest resource will be created by the mounting Pod's ServiceAccount. This can be paired with approver-policy to enable advanced policy control on a per-ServiceAccount basis.

Ensure that you give permissions to Pod ServiceAccounts to create CertificateRequests with this flag enabled, i.e:

# WARNING: This RBAC will enable any identity in the cluster to create
# CertificateRequests and is dangerous to use in production. Instead, you should
# give permissions only to identities which need to be able to create certificates.
# This would be done via scoping the set of identities in the `ClusterRoleBinding` `subjects` stanza.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cert-manager-csi-driver-all-cr-create
rules:
- apiGroups: ["cert-manager.io"]
resources: ["certificaterequests"]
verbs: [ "create" ]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cert-manager-csi-driver-all-cr-create
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cert-manager-csi-driver-all-cr-create
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated