Skip to content

cert-manager setup

cert-manager issues and renews the TLS certificates used internally by Linkerd, Loki's gateway, and ClamAV, and optionally the public-facing certificate for APISIX. It is a prerequisite for several of the Domino Workspace Helm charts.

Install

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm upgrade --install cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

See the official installation guide for other install methods and version pinning.

Create an internal CA and ClusterIssuer

Several charts (for example ClamAV, which expects a ClusterIssuer named cluster-ca by default) issue their certificates from an internal CA rather than a public one. A self-signed root plus a ClusterIssuer backed by it covers this — apply with kubectl apply -f -:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cluster-ca
  namespace: cert-manager
spec:
  isCA: true
  commonName: cluster-ca
  secretName: cluster-ca-tls
  duration: 87600h    # 10 years
  renewBefore: 720h   # 30 days
  privateKey:
    algorithm: ECDSA
    size: 256
  issuerRef:
    name: selfsigned
    kind: ClusterIssuer
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: cluster-ca
spec:
  ca:
    secretName: cluster-ca-tls

Any chart that needs an internal certificate can then reference issuerRef.name: cluster-ca / kind: ClusterIssuer, or a different ClusterIssuer name set in that chart's own values.

Distribute the CA cluster-wide (trust-manager)

Some components need the internal CA's public certificate available as a ConfigMap in their own namespace — Linkerd for its trust roots, and Alloy for verifying Loki's gateway certificate. trust-manager automates that, and is required for Linkerd, and for Alloy when Loki's gateway uses the internal CA:

helm upgrade --install trust-manager jetstack/trust-manager \
  --namespace cert-manager \
  --set app.trust.namespace=cert-manager

Then define the bundle — apply with kubectl apply -f -:

apiVersion: trust.cert-manager.io/v1alpha1
kind: Bundle
metadata:
  name: cluster-ca-bundle
spec:
  sources:
    - secret:
        name: cluster-ca-tls
        key: ca.crt
  target:
    configMap:
      key: ca.crt
    namespaceSelector:
      matchExpressions:
        - key: kubernetes.io/metadata.name
          operator: Exists

This creates a cluster-ca-bundle ConfigMap containing ca.crt in every namespace.

Public-facing certificate

APISIX also needs a certificate for the public hostnames it serves (<domain>, *.<domain>). This can come from a public CA (for example via an ACME ClusterIssuer using whichever DNS-01 or HTTP-01 solver matches the DNS provider in use — see the ACME tutorials), or be supplied directly as a certificate/key pair to APISIX.

Verify

kubectl get pods -n cert-manager
kubectl get clusterissuer

All pods should be Running, and cluster-ca (and any ACME issuer configured) should show READY: True.