From 0e96aefb0b961774134ff1d3c058b0b37e81c7cd Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Thu, 3 Oct 2024 13:44:37 +0100 Subject: [PATCH 1/2] Fix the release-process instructions Signed-off-by: Richard Wall --- content/docs/contributing/release-process.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/docs/contributing/release-process.md b/content/docs/contributing/release-process.md index 870cbb27b3..4f5f1d122f 100644 --- a/content/docs/contributing/release-process.md +++ b/content/docs/contributing/release-process.md @@ -261,13 +261,13 @@ page if a step is missing or if it is outdated. and updating the `manifest.json` file: ```bash - cp -r content/docs content/v1.12-docs - rm -rf content/v1.12-docs/{installation/supported-releases,installation/upgrading,release-notes} - sed -i.bak 's|docs|v1.12-docs|g' content/v1.12-docs/manifest.json - cat content/v1.12-docs/manifest.json \ - | jq 'del(.. | select(.path? | select(.) | test(".*(installation/supported-releases.md|installation/upgrading|release-notes).*")))' \ - | jq 'del(.. | select(.routes? == []))' >/tmp/manifest \ - && mv /tmp/manifest content/v1.12-docs/manifest.json + export RELEASE=1.15 + cp -r content/docs content/v${RELEASE}-docs + rm -rf content/v${RELEASE}-docs/{release-notes,contributing} + sed -i.bak "s|/docs/|/v${RELEASE}-docs/|g" content/v${RELEASE}-docs/manifest.json + jq < content/v${RELEASE}-docs/manifest.json >/tmp/manifest \ + 'del(.routes[0].routes[] | select(.title | test("Releases|Contributing")))' + mv /tmp/manifest content/v${RELEASE}-docs/manifest.json ``` 6. (**final + patch releases**) Update the [API docs](https://cert-manager.io/docs/reference/api-docs/) and [CLI docs](https://cert-manager.io/docs/cli//): From b7c0d96a28a042cf7ef66dbf3c32b7c43c37496e Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Thu, 3 Oct 2024 13:26:25 +0100 Subject: [PATCH 2/2] Freeze the cert-manager 1.15 docs Following the instructions from the release process > (final release only) Freeze the docs/ folder by creating a copy , removing the > pages from that copy that don't make sense to be versioned, and updating the > manifest.json file: ```bash export RELEASE=1.15 cp -r content/docs content/v${RELEASE}-docs rm -rf content/v${RELEASE}-docs/{installation/supported-releases,installation/upgrading,release-notes,contributing} sed -i.bak "s|docs/|v${RELEASE}-docs/|g" content/v${RELEASE}-docs/manifest.json jq < content/v${RELEASE}-docs/manifest.json >/tmp/manifest \ 'del(.routes[0].routes[] | select(.title | test("Releases|Contributing")))' mv /tmp/manifest content/v${RELEASE}-docs/manifest.json ``` Signed-off-by: Richard Wall --- content/v1.15-docs/README.md | 26 + content/v1.15-docs/cli/README.md | 7 + content/v1.15-docs/cli/acmesolver.md | 17 + content/v1.15-docs/cli/cainjector.md | 42 + content/v1.15-docs/cli/cmctl.md | 33 + content/v1.15-docs/cli/controller.md | 82 + content/v1.15-docs/cli/startupapicheck.md | 24 + content/v1.15-docs/cli/webhook.md | 44 + content/v1.15-docs/concepts/README.md | 11 + .../concepts/acme-orders-challenges.md | 100 + content/v1.15-docs/concepts/ca-injector.md | 234 + content/v1.15-docs/concepts/issuer.md | 44 + content/v1.15-docs/concepts/webhook.md | 80 + content/v1.15-docs/configuration/README.md | 30 + .../v1.15-docs/configuration/acme/README.md | 391 + .../configuration/acme/dns01/README.md | 189 + .../configuration/acme/dns01/acme-dns.md | 220 + .../configuration/acme/dns01/akamai.md | 86 + .../configuration/acme/dns01/azuredns.md | 505 ++ .../configuration/acme/dns01/cloudflare.md | 108 + .../configuration/acme/dns01/digitalocean.md | 46 + .../configuration/acme/dns01/google.md | 243 + .../configuration/acme/dns01/rfc2136.md | 207 + .../configuration/acme/dns01/route53.md | 388 + .../configuration/acme/dns01/webhook.md | 32 + .../configuration/acme/http01/README.md | 393 + .../acme/http01/externalloadbalancer.md | 34 + content/v1.15-docs/configuration/ca.md | 94 + content/v1.15-docs/configuration/issuers.md | 145 + .../v1.15-docs/configuration/selfsigned.md | 213 + content/v1.15-docs/configuration/vault.md | 662 ++ content/v1.15-docs/configuration/venafi.md | 284 + content/v1.15-docs/devops-tips/backup.md | 200 + .../devops-tips/prometheus-metrics.md | 147 + .../devops-tips/scaling-cert-manager.md | 133 + .../syncing-secrets-across-namespaces.md | 109 + content/v1.15-docs/faq/README.md | 237 + content/v1.15-docs/getting-started/README.md | 47 + content/v1.15-docs/installation/README.md | 40 + .../v1.15-docs/installation/best-practice.md | 555 ++ .../v1.15-docs/installation/code-signing.md | 65 + .../v1.15-docs/installation/compatibility.md | 114 + .../installation/configuring-components.md | 100 + .../continuous-deployment-and-gitops.md | 115 + content/v1.15-docs/installation/helm.md | 206 + content/v1.15-docs/installation/kubectl.md | 230 + .../operator-lifecycle-manager.md | 244 + content/v1.15-docs/installation/reinstall.md | 33 + content/v1.15-docs/installation/uninstall.md | 14 + content/v1.15-docs/installation/upgrade.md | 99 + content/v1.15-docs/manifest.json | 500 ++ content/v1.15-docs/policy/README.md | 20 + content/v1.15-docs/policy/approval/README.md | 36 + .../policy/approval/approver-policy/README.md | 399 + .../approval/approver-policy/api-reference.md | 2085 +++++ .../approval/approver-policy/installation.md | 110 + content/v1.15-docs/policy/defaulting.md | 41 + content/v1.15-docs/policy/issuing.md | 21 + content/v1.15-docs/reference/README.md | 15 + content/v1.15-docs/reference/api-docs.md | 6791 +++++++++++++++++ content/v1.15-docs/reference/cmctl.md | 379 + .../v1.15-docs/reference/tls-terminology.md | 79 + content/v1.15-docs/releases/README.md | 342 + .../release-notes/release-notes-0.1.md | 26 + .../release-notes/release-notes-0.10.md | 143 + .../release-notes/release-notes-0.11.md | 242 + .../release-notes/release-notes-0.12.md | 183 + .../release-notes/release-notes-0.13.md | 62 + .../release-notes/release-notes-0.14.md | 128 + .../release-notes/release-notes-0.15.md | 133 + .../release-notes/release-notes-0.16.md | 91 + .../release-notes/release-notes-0.2.md | 19 + .../release-notes/release-notes-0.3.md | 129 + .../release-notes/release-notes-0.4.md | 100 + .../release-notes/release-notes-0.5.md | 53 + .../release-notes/release-notes-0.6.md | 104 + .../release-notes/release-notes-0.7.md | 86 + .../release-notes/release-notes-0.8.md | 102 + .../release-notes/release-notes-0.9.md | 195 + .../release-notes/release-notes-1.0.md | 216 + .../release-notes/release-notes-1.1.md | 52 + .../release-notes/release-notes-1.10.md | 163 + .../release-notes/release-notes-1.11.md | 160 + .../release-notes/release-notes-1.12.md | 644 ++ .../release-notes/release-notes-1.13.md | 282 + .../release-notes/release-notes-1.14.md | 659 ++ .../release-notes/release-notes-1.15.md | 124 + .../release-notes/release-notes-1.2.md | 86 + .../release-notes/release-notes-1.3.md | 108 + .../release-notes/release-notes-1.4.md | 379 + .../release-notes/release-notes-1.5.md | 416 + .../release-notes/release-notes-1.6.md | 162 + .../release-notes/release-notes-1.7.md | 222 + .../release-notes/release-notes-1.8.md | 201 + .../release-notes/release-notes-1.9.md | 130 + .../upgrading/ingress-class-compatibility.md | 102 + .../upgrading/remove-deprecated-apis.md | 29 + .../releases/upgrading/upgrading-0.10-0.11.md | 119 + .../releases/upgrading/upgrading-0.11-0.12.md | 29 + .../releases/upgrading/upgrading-0.12-0.13.md | 7 + .../releases/upgrading/upgrading-0.13-0.14.md | 30 + .../releases/upgrading/upgrading-0.14-0.15.md | 26 + .../releases/upgrading/upgrading-0.15-0.16.md | 16 + .../releases/upgrading/upgrading-0.16-1.0.md | 127 + .../releases/upgrading/upgrading-0.2-0.3.md | 129 + .../releases/upgrading/upgrading-0.3-0.4.md | 6 + .../releases/upgrading/upgrading-0.4-0.5.md | 21 + .../releases/upgrading/upgrading-0.5-0.6.md | 105 + .../releases/upgrading/upgrading-0.6-0.7.md | 6 + .../releases/upgrading/upgrading-0.7-0.8.md | 270 + .../releases/upgrading/upgrading-0.8-0.9.md | 21 + .../releases/upgrading/upgrading-0.9-0.10.md | 24 + .../releases/upgrading/upgrading-1.0-1.1.md | 7 + .../releases/upgrading/upgrading-1.1-1.2.md | 21 + .../releases/upgrading/upgrading-1.10-1.11.md | 25 + .../releases/upgrading/upgrading-1.11-1.12.md | 10 + .../releases/upgrading/upgrading-1.12-1.13.md | 21 + .../releases/upgrading/upgrading-1.13-1.14.md | 30 + .../releases/upgrading/upgrading-1.14-1.15.md | 20 + .../releases/upgrading/upgrading-1.2-1.3.md | 32 + .../releases/upgrading/upgrading-1.3-1.4.md | 31 + .../releases/upgrading/upgrading-1.4-1.5.md | 11 + .../releases/upgrading/upgrading-1.5-1.6.md | 30 + .../releases/upgrading/upgrading-1.6-1.7.md | 24 + .../releases/upgrading/upgrading-1.7-1.8.md | 91 + .../releases/upgrading/upgrading-1.8-1.9.md | 11 + .../releases/upgrading/upgrading-1.9-1.10.md | 17 + content/v1.15-docs/troubleshooting/README.md | 116 + content/v1.15-docs/troubleshooting/acme.md | 226 + content/v1.15-docs/troubleshooting/webhook.md | 1086 +++ content/v1.15-docs/trust/README.md | 29 + .../v1.15-docs/trust/trust-manager/README.md | 404 + .../trust/trust-manager/api-reference.md | 734 ++ .../trust/trust-manager/installation.md | 150 + content/v1.15-docs/tutorials/README.md | 36 + .../tutorials/acme/dns-validation.md | 169 + .../tutorials/acme/example/deployment.yaml | 20 + .../acme/example/ingress-tls-final.yaml | 24 + .../tutorials/acme/example/ingress-tls.yaml | 24 + .../tutorials/acme/example/ingress.yaml | 23 + .../acme/example/pomerium-certificates.yaml | 36 + .../example/pomerium-production-issuer.yaml | 19 + .../acme/example/pomerium-staging-issuer.yaml | 19 + .../acme/example/pomerium-values.yaml | 39 + .../acme/example/production-issuer.yaml | 18 + .../tutorials/acme/example/service.yaml | 11 + .../acme/example/staging-issuer.yaml | 18 + .../tutorials/acme/http-validation.md | 166 + .../acme/migrating-from-kube-lego.md | 232 + .../tutorials/acme/nginx-ingress.md | 602 ++ .../tutorials/acme/pomerium-ingress.md | 191 + .../tutorials/certificate-defaults/README.md | 571 ++ .../getting-started-aks-letsencrypt/README.md | 688 ++ .../getting-started-aws-letsencrypt/README.md | 652 ++ .../README.md | 779 ++ .../README.md | 603 ++ .../gatekeeper/deploy-novol.yaml | 29 + .../gatekeeper/deploy-withvol.yaml | 38 + .../gatekeeper-trust-pod-ca-volume.yaml | 29 + .../gatekeeper-trust-pod-ca-volumemount.yaml | 24 + .../trust/bundle-one-ca.yaml | 39 + .../trust/bundle-public.yaml | 13 + .../trust/deploy-auto.yaml | 40 + .../tutorials/istio-csr/example/DEPRECATED.md | 11 + .../istio-csr/example/example-issuer.yaml | 45 + .../example/istio-config-getting-started.yaml | 21 + content/v1.15-docs/tutorials/venafi/venafi.md | 585 ++ .../v1.15-docs/tutorials/zerossl/zerossl.md | 181 + content/v1.15-docs/usage/README.md | 30 + content/v1.15-docs/usage/certificate.md | 479 ++ .../v1.15-docs/usage/certificaterequest.md | 254 + .../usage/csi-driver-spiffe/README.md | 236 + .../usage/csi-driver-spiffe/installation.md | 128 + content/v1.15-docs/usage/csi-driver/README.md | 174 + .../usage/csi-driver/installation.md | 54 + content/v1.15-docs/usage/csi.md | 92 + content/v1.15-docs/usage/gateway.md | 445 ++ content/v1.15-docs/usage/ingress.md | 228 + content/v1.15-docs/usage/istio-csr/README.md | 98 + .../example/example-cluster-issuer.yaml | 46 + .../istio-csr/example/example-issuer.yaml | 45 + .../example/istio-config-getting-started.yaml | 21 + .../usage/istio-csr/installation.md | 407 + content/v1.15-docs/usage/kube-csr.md | 177 + content/v1.15-docs/variables.json | 3 + 185 files changed, 37425 insertions(+) create mode 100644 content/v1.15-docs/README.md create mode 100644 content/v1.15-docs/cli/README.md create mode 100644 content/v1.15-docs/cli/acmesolver.md create mode 100644 content/v1.15-docs/cli/cainjector.md create mode 100644 content/v1.15-docs/cli/cmctl.md create mode 100644 content/v1.15-docs/cli/controller.md create mode 100644 content/v1.15-docs/cli/startupapicheck.md create mode 100644 content/v1.15-docs/cli/webhook.md create mode 100644 content/v1.15-docs/concepts/README.md create mode 100644 content/v1.15-docs/concepts/acme-orders-challenges.md create mode 100644 content/v1.15-docs/concepts/ca-injector.md create mode 100644 content/v1.15-docs/concepts/issuer.md create mode 100644 content/v1.15-docs/concepts/webhook.md create mode 100644 content/v1.15-docs/configuration/README.md create mode 100644 content/v1.15-docs/configuration/acme/README.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/README.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/acme-dns.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/akamai.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/azuredns.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/cloudflare.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/digitalocean.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/google.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/rfc2136.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/route53.md create mode 100644 content/v1.15-docs/configuration/acme/dns01/webhook.md create mode 100644 content/v1.15-docs/configuration/acme/http01/README.md create mode 100644 content/v1.15-docs/configuration/acme/http01/externalloadbalancer.md create mode 100644 content/v1.15-docs/configuration/ca.md create mode 100644 content/v1.15-docs/configuration/issuers.md create mode 100644 content/v1.15-docs/configuration/selfsigned.md create mode 100644 content/v1.15-docs/configuration/vault.md create mode 100644 content/v1.15-docs/configuration/venafi.md create mode 100644 content/v1.15-docs/devops-tips/backup.md create mode 100644 content/v1.15-docs/devops-tips/prometheus-metrics.md create mode 100644 content/v1.15-docs/devops-tips/scaling-cert-manager.md create mode 100644 content/v1.15-docs/devops-tips/syncing-secrets-across-namespaces.md create mode 100644 content/v1.15-docs/faq/README.md create mode 100644 content/v1.15-docs/getting-started/README.md create mode 100644 content/v1.15-docs/installation/README.md create mode 100644 content/v1.15-docs/installation/best-practice.md create mode 100644 content/v1.15-docs/installation/code-signing.md create mode 100644 content/v1.15-docs/installation/compatibility.md create mode 100644 content/v1.15-docs/installation/configuring-components.md create mode 100644 content/v1.15-docs/installation/continuous-deployment-and-gitops.md create mode 100644 content/v1.15-docs/installation/helm.md create mode 100644 content/v1.15-docs/installation/kubectl.md create mode 100644 content/v1.15-docs/installation/operator-lifecycle-manager.md create mode 100644 content/v1.15-docs/installation/reinstall.md create mode 100644 content/v1.15-docs/installation/uninstall.md create mode 100644 content/v1.15-docs/installation/upgrade.md create mode 100644 content/v1.15-docs/manifest.json create mode 100644 content/v1.15-docs/policy/README.md create mode 100644 content/v1.15-docs/policy/approval/README.md create mode 100644 content/v1.15-docs/policy/approval/approver-policy/README.md create mode 100644 content/v1.15-docs/policy/approval/approver-policy/api-reference.md create mode 100644 content/v1.15-docs/policy/approval/approver-policy/installation.md create mode 100644 content/v1.15-docs/policy/defaulting.md create mode 100644 content/v1.15-docs/policy/issuing.md create mode 100644 content/v1.15-docs/reference/README.md create mode 100644 content/v1.15-docs/reference/api-docs.md create mode 100644 content/v1.15-docs/reference/cmctl.md create mode 100644 content/v1.15-docs/reference/tls-terminology.md create mode 100644 content/v1.15-docs/releases/README.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.1.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.10.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.11.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.12.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.13.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.14.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.15.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.16.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.2.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.3.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.4.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.5.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.6.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.7.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.8.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-0.9.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.0.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.1.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.10.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.11.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.12.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.13.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.14.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.15.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.2.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.3.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.4.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.5.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.6.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.7.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.8.md create mode 100644 content/v1.15-docs/releases/release-notes/release-notes-1.9.md create mode 100644 content/v1.15-docs/releases/upgrading/ingress-class-compatibility.md create mode 100644 content/v1.15-docs/releases/upgrading/remove-deprecated-apis.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.10-0.11.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.11-0.12.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.12-0.13.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.13-0.14.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.14-0.15.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.15-0.16.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.16-1.0.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.2-0.3.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.3-0.4.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.4-0.5.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.5-0.6.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.6-0.7.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.7-0.8.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.8-0.9.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-0.9-0.10.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.0-1.1.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.1-1.2.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.10-1.11.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.11-1.12.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.12-1.13.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.13-1.14.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.14-1.15.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.2-1.3.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.3-1.4.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.4-1.5.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.5-1.6.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.6-1.7.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.7-1.8.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.8-1.9.md create mode 100644 content/v1.15-docs/releases/upgrading/upgrading-1.9-1.10.md create mode 100644 content/v1.15-docs/troubleshooting/README.md create mode 100644 content/v1.15-docs/troubleshooting/acme.md create mode 100644 content/v1.15-docs/troubleshooting/webhook.md create mode 100644 content/v1.15-docs/trust/README.md create mode 100644 content/v1.15-docs/trust/trust-manager/README.md create mode 100644 content/v1.15-docs/trust/trust-manager/api-reference.md create mode 100644 content/v1.15-docs/trust/trust-manager/installation.md create mode 100644 content/v1.15-docs/tutorials/README.md create mode 100644 content/v1.15-docs/tutorials/acme/dns-validation.md create mode 100644 content/v1.15-docs/tutorials/acme/example/deployment.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/ingress-tls-final.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/ingress-tls.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/ingress.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/pomerium-certificates.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/pomerium-production-issuer.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/pomerium-staging-issuer.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/pomerium-values.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/production-issuer.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/service.yaml create mode 100644 content/v1.15-docs/tutorials/acme/example/staging-issuer.yaml create mode 100644 content/v1.15-docs/tutorials/acme/http-validation.md create mode 100644 content/v1.15-docs/tutorials/acme/migrating-from-kube-lego.md create mode 100644 content/v1.15-docs/tutorials/acme/nginx-ingress.md create mode 100644 content/v1.15-docs/tutorials/acme/pomerium-ingress.md create mode 100644 content/v1.15-docs/tutorials/certificate-defaults/README.md create mode 100644 content/v1.15-docs/tutorials/getting-started-aks-letsencrypt/README.md create mode 100644 content/v1.15-docs/tutorials/getting-started-aws-letsencrypt/README.md create mode 100644 content/v1.15-docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/README.md create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/gatekeeper/deploy-novol.yaml create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/gatekeeper/deploy-withvol.yaml create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/gatekeeper/gatekeeper-trust-pod-ca-volume.yaml create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/gatekeeper/gatekeeper-trust-pod-ca-volumemount.yaml create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/trust/bundle-one-ca.yaml create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/trust/bundle-public.yaml create mode 100644 content/v1.15-docs/tutorials/getting-started-with-trust-manager/trust/deploy-auto.yaml create mode 100644 content/v1.15-docs/tutorials/istio-csr/example/DEPRECATED.md create mode 100644 content/v1.15-docs/tutorials/istio-csr/example/example-issuer.yaml create mode 100644 content/v1.15-docs/tutorials/istio-csr/example/istio-config-getting-started.yaml create mode 100644 content/v1.15-docs/tutorials/venafi/venafi.md create mode 100644 content/v1.15-docs/tutorials/zerossl/zerossl.md create mode 100644 content/v1.15-docs/usage/README.md create mode 100644 content/v1.15-docs/usage/certificate.md create mode 100644 content/v1.15-docs/usage/certificaterequest.md create mode 100644 content/v1.15-docs/usage/csi-driver-spiffe/README.md create mode 100644 content/v1.15-docs/usage/csi-driver-spiffe/installation.md create mode 100644 content/v1.15-docs/usage/csi-driver/README.md create mode 100644 content/v1.15-docs/usage/csi-driver/installation.md create mode 100644 content/v1.15-docs/usage/csi.md create mode 100644 content/v1.15-docs/usage/gateway.md create mode 100644 content/v1.15-docs/usage/ingress.md create mode 100644 content/v1.15-docs/usage/istio-csr/README.md create mode 100644 content/v1.15-docs/usage/istio-csr/example/example-cluster-issuer.yaml create mode 100644 content/v1.15-docs/usage/istio-csr/example/example-issuer.yaml create mode 100644 content/v1.15-docs/usage/istio-csr/example/istio-config-getting-started.yaml create mode 100644 content/v1.15-docs/usage/istio-csr/installation.md create mode 100644 content/v1.15-docs/usage/kube-csr.md create mode 100644 content/v1.15-docs/variables.json diff --git a/content/v1.15-docs/README.md b/content/v1.15-docs/README.md new file mode 100644 index 0000000000..1a1b187716 --- /dev/null +++ b/content/v1.15-docs/README.md @@ -0,0 +1,26 @@ +--- +title: cert-manager +description: | + cert-manager creates TLS certificates for workloads in your Kubernetes or OpenShift cluster and renews the certificates before they expire. +--- + +cert-manager creates TLS certificates for workloads in your Kubernetes or OpenShift cluster +and renews the certificates before they expire. + +cert-manager can obtain certificates from a [variety of certificate authorities](configuration/issuers.md), including: +[Let's Encrypt](configuration/acme/README.md), [HashiCorp Vault](configuration/vault.md), +[Venafi](configuration/venafi.md) and [private PKI](configuration/ca.md). + +With cert-manager's [Certificate resource](usage/certificate.md), the private key and certificate are stored in a Kubernetes Secret +which is mounted by an application Pod or used by an Ingress controller. +With [csi-driver](usage/csi-driver/README.md), [csi-driver-spiffe](usage/csi-driver-spiffe/README.md), or [istio-csr](usage/istio-csr/README.md) , +the private key is generated on-demand, before the application starts up; +the private key never leaves the node and it is not stored in a Kubernetes Secret. + +![High level overview diagram explaining cert-manager architecture](/images/high-level-overview.svg) + +This website provides the full technical documentation for the project, and can be +used as a reference; if you feel that there's anything missing, please let us know +or [raise a PR](https://github.com/cert-manager/website/pulls) to add it. + + diff --git a/content/v1.15-docs/cli/README.md b/content/v1.15-docs/cli/README.md new file mode 100644 index 0000000000..0d1a516335 --- /dev/null +++ b/content/v1.15-docs/cli/README.md @@ -0,0 +1,7 @@ +--- +title: CLI reference +description: cert-manager CLI documentation +--- + +View the `--help` output from our various CLI tools, including those which run in containers in your cluster. +This might help if you need to tweak an option or if you need to check which values are valid! \ No newline at end of file diff --git a/content/v1.15-docs/cli/acmesolver.md b/content/v1.15-docs/cli/acmesolver.md new file mode 100644 index 0000000000..baee31aff4 --- /dev/null +++ b/content/v1.15-docs/cli/acmesolver.md @@ -0,0 +1,17 @@ +--- +title: acmesolver CLI reference +description: "cert-manager acmesolver CLI documentation" +--- +``` +HTTP server used to solve ACME challenges. + +Usage: + acmesolver [flags] + +Flags: + --domain string the domain name to verify + -h, --help help for acmesolver + --key string the challenge key to respond with + --listen-port int the port number to listen on for connections (default 8089) + --token string the challenge token to verify against +``` diff --git a/content/v1.15-docs/cli/cainjector.md b/content/v1.15-docs/cli/cainjector.md new file mode 100644 index 0000000000..fc8c598ad4 --- /dev/null +++ b/content/v1.15-docs/cli/cainjector.md @@ -0,0 +1,42 @@ +--- +title: cainjector CLI reference +description: "cert-manager cainjector CLI documentation" +--- +``` + +cert-manager CA injector is a Kubernetes addon to automate the injection of CA data into +webhooks and APIServices from cert-manager certificates. + +It will ensure that annotated webhooks and API services always have the correct +CA data from the referenced certificates, which can then be used to serve API +servers and webhook servers. + +Usage: + cainjector [flags] + +Flags: + --config string Path to a file containing a CAInjectorConfiguration object used to configure the controller + --enable-apiservices-injectable Inject CA data to annotated APIServices. This functionality is not required if cainjector is only used as cert-manager's internal component and setting it to false might reduce memory consumption (default true) + --enable-certificates-data-source Enable configuring cert-manager.io Certificate resources as potential sources for CA data. Requires cert-manager.io Certificate CRD to be installed. This data source can be disabled to reduce memory consumption if you only use cainjector as part of cert-manager's installation (default true) + --enable-customresourcedefinitions-injectable Inject CA data to annotated CustomResourceDefinitions. This functionality is not required if cainjecor is only used as cert-manager's internal component and setting it to false might slightly reduce memory consumption (default true) + --enable-mutatingwebhookconfigurations-injectable Inject CA data to annotated MutatingWebhookConfigurations. This functionality is required for cainjector to work correctly as cert-manager's internal component (default true) + --enable-profiling Enable profiling for controller. + --enable-validatingwebhookconfigurations-injectable Inject CA data to annotated ValidatingWebhookConfigurations. This functionality is required for cainjector to correctly function as cert-manager's internal component (default true) + --feature-gates mapStringBool A set of key=value pairs that describe feature gates for alpha/experimental features. Options are: + AllAlpha=true|false (ALPHA - default=false) + AllBeta=true|false (BETA - default=false) + ServerSideApply=true|false (ALPHA - default=false) + -h, --help help for cainjector + --kubeconfig string Paths to a kubeconfig. Only required if out-of-cluster. + --leader-elect If true, cainjector will perform leader election between instances to ensure no more than one instance of cainjector operates at a time (default true) + --leader-election-lease-duration duration The duration that non-leader candidates will wait after observing a leadership renewal until attempting to acquire leadership of a led but unrenewed leader slot. This is effectively the maximum duration that a leader can be stopped before it is replaced by another candidate. This is only applicable if leader election is enabled. (default 1m0s) + --leader-election-namespace string Namespace used to perform leader election. Only used if leader election is enabled (default "kube-system") + --leader-election-renew-deadline duration The interval between attempts by the acting master to renew a leadership slot before it stops leading. This must be less than or equal to the lease duration. This is only applicable if leader election is enabled. (default 40s) + --leader-election-retry-period duration The duration the clients should wait between attempting acquisition and renewal of a leadership. This is only applicable if leader election is enabled. (default 15s) + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logging-format string Sets the log format. Permitted formats: "json" (gated by LoggingBetaOptions), "text". (default "text") + --namespace string If set, this limits the scope of cainjector to a single namespace. If set, cainjector will not update resources with certificates outside of the configured namespace. + --profiler-address string The host and port that Go profiler should listen on, i.e localhost:6060. Ensure that profiler is not exposed on a public address. Profiler will be served at /debug/pprof. (default "localhost:6060") + -v, --v Level number for the log level verbosity + --vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format) +``` diff --git a/content/v1.15-docs/cli/cmctl.md b/content/v1.15-docs/cli/cmctl.md new file mode 100644 index 0000000000..88281c4a31 --- /dev/null +++ b/content/v1.15-docs/cli/cmctl.md @@ -0,0 +1,33 @@ +--- +title: cmctl CLI reference +description: "cert-manager cmctl CLI documentation" +--- +``` + +cmctl is a CLI tool manage and configure cert-manager resources for Kubernetes + +Usage: cmctl [command] + +Available Commands: + approve Approve a CertificateRequest + check Check cert-manager components + convert Convert cert-manager config files between different API versions + create Create cert-manager resources + deny Deny a CertificateRequest + experimental Interact with experimental features + help Help about any command + inspect Get details on certificate related resources + renew Mark a Certificate for manual renewal + status Get details on current status of cert-manager resources + upgrade Tools that assist in upgrading cert-manager + version Print the cert-manager CLI version and the deployed cert-manager version + +Flags: + -h, --help help for cmctl + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logging-format string Sets the log format. Permitted formats: "json" (gated by LoggingBetaOptions), "text". (default "text") + -v, --v Level[=2] number for the log level verbosity + --vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format) + +Use "cmctl [command] --help" for more information about a command. +``` diff --git a/content/v1.15-docs/cli/controller.md b/content/v1.15-docs/cli/controller.md new file mode 100644 index 0000000000..343cff2f13 --- /dev/null +++ b/content/v1.15-docs/cli/controller.md @@ -0,0 +1,82 @@ +--- +title: controller CLI reference +description: "cert-manager controller CLI documentation" +--- +``` + +cert-manager is a Kubernetes addon to automate the management and issuance of +TLS certificates from various issuing sources. + +It will ensure certificates are valid and up to date periodically, and attempt +to renew certificates at an appropriate time before expiry. + +Usage: + controller [flags] + +Flags: + --acme-http01-solver-image string The docker image to use to solve ACME HTTP01 challenges. You most likely will not need to change this parameter unless you are testing a new feature or developing cert-manager. (default "quay.io/jetstack/cert-manager-acmesolver:canary") + --acme-http01-solver-nameservers strings A list of comma separated dns server endpoints used for ACME HTTP01 check requests. This should be a list containing host and port, for example 8.8.8.8:53,8.8.4.4:53 + --acme-http01-solver-resource-limits-cpu string Defines the resource limits CPU size when spawning new ACME HTTP01 challenge solver pods. (default "100m") + --acme-http01-solver-resource-limits-memory string Defines the resource limits Memory size when spawning new ACME HTTP01 challenge solver pods. (default "64Mi") + --acme-http01-solver-resource-request-cpu string Defines the resource request CPU size when spawning new ACME HTTP01 challenge solver pods. (default "10m") + --acme-http01-solver-resource-request-memory string Defines the resource request Memory size when spawning new ACME HTTP01 challenge solver pods. (default "64Mi") + --acme-http01-solver-run-as-non-root Defines the ability to run the http01 solver as root for troubleshooting issues (default true) + --auto-certificate-annotations strings The annotation consumed by the ingress-shim controller to indicate a ingress is requesting a certificate (default [kubernetes.io/tls-acme]) + --cluster-issuer-ambient-credentials Whether a cluster-issuer may make use of ambient credentials for issuers. 'Ambient Credentials' are credentials drawn from the environment, metadata services, or local files which are not explicitly configured in the ClusterIssuer API object. When this flag is enabled, the following sources for credentials are also used: AWS - All sources the Go SDK defaults to, notably including any EC2 IAM roles available via instance metadata. (default true) + --cluster-resource-namespace string Namespace to store resources owned by cluster scoped resources such as ClusterIssuer in. This must be specified if ClusterIssuers are enabled. (default "kube-system") + --concurrent-workers int The number of concurrent workers for each controller. (default 5) + --config string Path to a file containing a ControllerConfiguration object used to configure the controller + --controllers strings A list of controllers to enable. '--controllers=*' enables all on-by-default controllers, '--controllers=foo' enables just the controller named 'foo', '--controllers=*,-foo' disables the controller named 'foo'. + All controllers: issuers, clusterissuers, certificates-metrics, ingress-shim, gateway-shim, orders, challenges, certificaterequests-issuer-acme, certificaterequests-approver, certificaterequests-issuer-ca, certificaterequests-issuer-selfsigned, certificaterequests-issuer-vault, certificaterequests-issuer-venafi, certificates-trigger, certificates-issuing, certificates-key-manager, certificates-request-manager, certificates-readiness, certificates-revision-manager (default [*]) + --copied-annotation-prefixes strings Specify which annotations should/shouldn't be copiedfrom Certificate to CertificateRequest and Order, as well as from CertificateSigningRequest to Order, by passing a list of annotation key prefixes.A prefix starting with a dash(-) specifies an annotation that shouldn't be copied. Example: '*,-kubectl.kuberenetes.io/'- all annotationswill be copied apart from the ones where the key is prefixed with 'kubectl.kubernetes.io/'. (default [*,-kubectl.kubernetes.io/,-fluxcd.io/,-argocd.argoproj.io/]) + --default-issuer-group string Group of the Issuer to use when the tls is requested but issuer group is not specified on the ingress resource. (default "cert-manager.io") + --default-issuer-kind string Kind of the Issuer to use when the tls is requested but issuer kind is not specified on the ingress resource. (default "Issuer") + --default-issuer-name string Name of the Issuer to use when the tls is requested but issuer name is not specified on the ingress resource. + --dns01-check-retry-period duration The duration the controller should wait between a propagation check. Despite the name, this flag is used to configure the wait period for both DNS01 and HTTP01 challenge propagation checks. For DNS01 challenges the propagation check verifies that a TXT record with the challenge token has been created. For HTTP01 challenges the propagation check verifies that the challenge token is served at the challenge URL.This should be a valid duration string, for example 180s or 1h (default 10s) + --dns01-recursive-nameservers : A list of comma separated dns server endpoints used for DNS01 and DNS-over-HTTPS (DoH) check requests. This should be a list containing entries of the following formats: : or `https://`. For example: `8.8.8.8:53,8.8.4.4:53` or `https://1.1.1.1/dns-query,https://8.8.8.8/dns-query`. To make sure ALL DNS requests happen through DoH, `dns01-recursive-nameservers-only` should also be set to true. + --dns01-recursive-nameservers-only When true, cert-manager will only ever query the configured DNS resolvers to perform the ACME DNS01 self check. This is useful in DNS constrained environments, where access to authoritative nameservers is restricted. Enabling this option could cause the DNS01 self check to take longer due to caching performed by the recursive nameservers. + --enable-certificate-owner-ref Whether to set the certificate resource as an owner of secret where the tls certificate is stored. When this flag is enabled, the secret will be automatically removed when the certificate resource is deleted. + --enable-gateway-api Whether gateway API integration is enabled within cert-manager. The ExperimentalGatewayAPISupport feature gate must also be enabled (default as of 1.15). + --enable-profiling Enable profiling for controller. + --feature-gates mapStringBool A set of key=value pairs that describe feature gates for alpha/experimental features. Options are: + AdditionalCertificateOutputFormats=true|false (BETA - default=true) + AllAlpha=true|false (ALPHA - default=false) + AllBeta=true|false (BETA - default=false) + ExperimentalCertificateSigningRequestControllers=true|false (ALPHA - default=false) + ExperimentalGatewayAPISupport=true|false (BETA - default=true) + LiteralCertificateSubject=true|false (BETA - default=true) + NameConstraints=true|false (ALPHA - default=false) + OtherNames=true|false (ALPHA - default=false) + SecretsFilteredCaching=true|false (BETA - default=true) + ServerSideApply=true|false (ALPHA - default=false) + StableCertificateRequestName=true|false (BETA - default=true) + UseCertificateRequestBasicConstraints=true|false (ALPHA - default=false) + ValidateCAA=true|false (ALPHA - default=false) + -h, --help help for controller + --issuer-ambient-credentials Whether an issuer may make use of ambient credentials. 'Ambient Credentials' are credentials drawn from the environment, metadata services, or local files which are not explicitly configured in the Issuer API object. When this flag is enabled, the following sources for credentials are also used: AWS - All sources the Go SDK defaults to, notably including any EC2 IAM roles available via instance metadata. + --kube-api-burst int the maximum burst queries-per-second of requests sent to the Kubernetes apiserver (default 50) + --kube-api-qps float32 indicates the maximum queries-per-second requests to the Kubernetes apiserver (default 20) + --kubeconfig string Paths to a kubeconfig. Only required if out-of-cluster. + --leader-elect If true, cert-manager will perform leader election between instances to ensure no more than one instance of cert-manager operates at a time (default true) + --leader-election-lease-duration duration The duration that non-leader candidates will wait after observing a leadership renewal until attempting to acquire leadership of a led but unrenewed leader slot. This is effectively the maximum duration that a leader can be stopped before it is replaced by another candidate. This is only applicable if leader election is enabled. (default 1m0s) + --leader-election-namespace string Namespace used to perform leader election. Only used if leader election is enabled (default "kube-system") + --leader-election-renew-deadline duration The interval between attempts by the acting master to renew a leadership slot before it stops leading. This must be less than or equal to the lease duration. This is only applicable if leader election is enabled. (default 40s) + --leader-election-retry-period duration The duration the clients should wait between attempting acquisition and renewal of a leadership. This is only applicable if leader election is enabled. (default 15s) + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logging-format string Sets the log format. Permitted formats: "json" (gated by LoggingBetaOptions), "text". (default "text") + --master string Optional apiserver host address to connect to. If not specified, autoconfiguration will be attempted. + --max-concurrent-challenges int The maximum number of challenges that can be scheduled as 'processing' at once. (default 60) + --metrics-dynamic-serving-ca-secret-name string name of the secret used to store the CA that signs serving certificates + --metrics-dynamic-serving-ca-secret-namespace string namespace of the secret used to store the CA that signs serving certificates + --metrics-dynamic-serving-dns-names strings DNS names that should be present on certificates generated by the dynamic serving CA + --metrics-dynamic-serving-leaf-duration duration leaf duration of serving certificates (default 168h0m0s) + --metrics-listen-address string The host and port that the metrics endpoint should listen on. (default "0.0.0.0:9402") + --metrics-tls-cert-file string path to the file containing the TLS certificate to serve with + --metrics-tls-cipher-suites strings Comma-separated list of cipher suites for the server. If omitted, the default Go cipher suites will be used. Possible values: TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_RC4_128_SHA + --metrics-tls-min-version string Minimum TLS version supported. If omitted, the default Go minimum version will be used. Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13 + --metrics-tls-private-key-file string path to the file containing the TLS private key to serve with + --namespace string If set, this limits the scope of cert-manager to a single namespace and ClusterIssuers are disabled. If not specified, all namespaces will be watched + --profiler-address string The host and port that Go profiler should listen on, i.e localhost:6060. Ensure that profiler is not exposed on a public address. Profiler will be served at /debug/pprof. (default "localhost:6060") + -v, --v Level number for the log level verbosity + --vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format) +``` diff --git a/content/v1.15-docs/cli/startupapicheck.md b/content/v1.15-docs/cli/startupapicheck.md new file mode 100644 index 0000000000..19a4beba33 --- /dev/null +++ b/content/v1.15-docs/cli/startupapicheck.md @@ -0,0 +1,24 @@ +--- +title: startupapicheck CLI reference +description: "cert-manager startupapicheck CLI documentation" +--- +``` +Check that cert-manager started successfully + +Usage: + startupapicheck [command] + +Available Commands: + check Check cert-manager components + completion Generate the autocompletion script for the specified shell + help Help about any command + +Flags: + -h, --help help for startupapicheck + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logging-format string Sets the log format. Permitted formats: "json" (gated by LoggingBetaOptions), "text". (default "text") + -v, --v Level[=2] number for the log level verbosity + --vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format) + +Use "startupapicheck [command] --help" for more information about a command. +``` diff --git a/content/v1.15-docs/cli/webhook.md b/content/v1.15-docs/cli/webhook.md new file mode 100644 index 0000000000..64b4d08e93 --- /dev/null +++ b/content/v1.15-docs/cli/webhook.md @@ -0,0 +1,44 @@ +--- +title: webhook CLI reference +description: "cert-manager webhook CLI documentation" +--- +``` + +cert-manager is a Kubernetes addon to automate the management and issuance of +TLS certificates from various issuing sources. + +The webhook component provides API validation, mutation and conversion +functionality for cert-manager. + +Usage: + webhook [flags] + +Flags: + --api-server-host string Optional apiserver host address to connect to. If not specified, autoconfiguration will be attempted. + --config string Path to a file containing a WebhookConfiguration object used to configure the webhook + --dynamic-serving-ca-secret-name string name of the secret used to store the CA that signs serving certificates + --dynamic-serving-ca-secret-namespace string namespace of the secret used to store the CA that signs serving certificates + --dynamic-serving-dns-names strings DNS names that should be present on certificates generated by the dynamic serving CA + --dynamic-serving-leaf-duration duration leaf duration of serving certificates (default 168h0m0s) + --enable-profiling Enable profiling for webhook. + --feature-gates mapStringBool A set of key=value pairs that describe feature gates for alpha/experimental features. Options are: + AdditionalCertificateOutputFormats=true|false (BETA - default=true) + AllAlpha=true|false (ALPHA - default=false) + AllBeta=true|false (BETA - default=false) + LiteralCertificateSubject=true|false (BETA - default=true) + NameConstraints=true|false (ALPHA - default=false) + OtherNames=true|false (ALPHA - default=false) + --healthz-port int32 port number to listen on for insecure healthz connections (default 6080) + -h, --help help for webhook + --kubeconfig string optional path to the kubeconfig used to connect to the apiserver. If not specified, in-cluster-config will be used + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + --logging-format string Sets the log format. Permitted formats: "json" (gated by LoggingBetaOptions), "text". (default "text") + --profiler-address string Address of the Go profiler (pprof). This should never be exposed on a public interface. If this flag is not set, the profiler is not run. (default "localhost:6060") + --secure-port int32 port number to listen on for secure TLS connections (default 6443) + --tls-cert-file string path to the file containing the TLS certificate to serve with + --tls-cipher-suites strings Comma-separated list of cipher suites for the server. If omitted, the default Go cipher suites will be used. Possible values: TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_RC4_128_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_RC4_128_SHA + --tls-min-version string Minimum TLS version supported. If omitted, the default Go minimum version will be used. Possible values: VersionTLS10, VersionTLS11, VersionTLS12, VersionTLS13 + --tls-private-key-file string path to the file containing the TLS private key to serve with + -v, --v Level number for the log level verbosity + --vmodule pattern=N,... comma-separated list of pattern=N settings for file-filtered logging (only works for text log format) +``` diff --git a/content/v1.15-docs/concepts/README.md b/content/v1.15-docs/concepts/README.md new file mode 100644 index 0000000000..48ed7e2377 --- /dev/null +++ b/content/v1.15-docs/concepts/README.md @@ -0,0 +1,11 @@ +--- +title: Concepts +description: cert-manager core concepts +--- + +There are several components and ideas that make up cert-manager. This section +describes them on a conceptual level, to aid with understanding how cert-manager +does its job. + +You probably don't want this section if you're just getting started; check out +a [tutorial](../tutorials/README.md) instead. \ No newline at end of file diff --git a/content/v1.15-docs/concepts/acme-orders-challenges.md b/content/v1.15-docs/concepts/acme-orders-challenges.md new file mode 100644 index 0000000000..f4e1d3e2a5 --- /dev/null +++ b/content/v1.15-docs/concepts/acme-orders-challenges.md @@ -0,0 +1,100 @@ +--- +title: ACME Orders and Challenges +description: 'cert-manager core concepts: ACME Orders and Challenges' +--- + +cert-manager supports requesting certificates from ACME servers, including from +[Let's Encrypt](https://letsencrypt.org/), with use of the [ACME +Issuer](../configuration/acme/README.md). These certificates are typically trusted on +the public Internet by most computers. To successfully request a certificate, +cert-manager must solve ACME Challenges which are completed in order to prove +that the client owns the DNS addresses that are being requested. + +In order to complete these challenges, cert-manager introduces two +`CustomResource` types; `Orders` and `Challenges`. + +## Orders + +`Order` resources are used by the ACME issuer to manage the lifecycle of an ACME +'order' for a signed TLS certificate. More details on ACME orders and domain +validation can be found on the Let's Encrypt website +[here](https://letsencrypt.org/how-it-works/). An order represents a single +certificate request which will be created automatically once a new +[`CertificateRequest`](../usage/certificaterequest.md) resource referencing an ACME +issuer has been created. `CertificateRequest` resources are created +automatically by cert-manager once a [`Certificate`](../usage/certificate.md) resource +is created, has its specification changed, or needs renewal. + +As an end-user, you will never need to manually create an `Order` resource. +Once created, an `Order` cannot be changed. Instead, a new `Order` resource must +be created. + +The `Order` resource encapsulates multiple ACME 'challenges' for that 'order', +and as such, will manage one or more `Challenge` resources. + +## Challenges + +`Challenge` resources are used by the ACME issuer to manage the lifecycle of an +ACME 'challenge' that must be completed in order to complete an 'authorization' +for a single DNS name/identifier. + +When an `Order` resource is created, the order controller will create +`Challenge` resources for each DNS name that is being authorized with the ACME +server. + +As an end-user, you will never need to manually create a `Challenge` resource. +Once created, a `Challenge` cannot be changed. Instead, a new `Challenge` +resource must be created. + +### Challenge Lifecycle + +After a `Challenge` resource has been created, it will be initially queued for +processing. Processing will not begin until the challenge has been 'scheduled' +to start. This scheduling process prevents too many challenges being attempted +at once, or multiple challenges for the same DNS name being attempted at once. +For more information on how challenges are scheduled, read the [challenge +scheduling](#challenge-scheduling). + +Once a challenge has been scheduled, it will first be 'synced' with the ACME +server in order to determine its current state. If the challenge is already +valid, its 'state' will be updated to 'valid', and will also set +`status.processing = false` to 'unschedule' itself. + +If the challenge is still 'pending', the challenge controller will 'present' the +challenge using the configured solver, one of HTTP01 or DNS01. Once the +challenge has been 'presented', it will set `status.presented = true`. + +Once 'presented', the challenge controller will perform a 'self check' to +ensure that the challenge has 'propagated' (i.e. the authoritative DNS servers +have been updated to respond correctly, or the changes to the ingress resources +have been observed and in-use by the ingress controller). + +If the self check fails, cert-manager will retry the self check with a fixed 10 +second retry interval. Challenges that do not ever complete the self check will +continue retrying until the user intervenes by either retrying the `Order` (by +deleting the `Order` resource) or amending the associated `Certificate` resource +to resolve any configuration errors. + +Once the self check is passing, the ACME 'authorization' associated with this +challenge will be 'accepted'. + +The final state of the authorization after accepting it will be copied across to +the Challenge's `status.state` field, as well as the 'error reason' if an error +occurred whilst the ACME server attempted to validate the challenge. + +Once a Challenge has entered the `valid`, `invalid`, `expired` or `revoked` +state, it will set `status.processing = false` to prevent any further processing +of the ACME challenge, and to allow another challenge to be scheduled if there +is a backlog of challenges to complete. + +### Challenge Scheduling + +Instead of attempting to process all challenges at once, challenges are +'scheduled' by cert-manager. + +This scheduler applies a cap on the maximum number of simultaneous challenges +as well as disallows two challenges for the same DNS name and solver type +(`HTTP01` or `DNS01`) to be completed at once. + +The maximum number of challenges that can be processed at a time is 60 as of +[`ddff78`](https://github.com/cert-manager/cert-manager/blob/ddff78f011558e64186d61f7c693edced1496afa/pkg/controller/acmechallenges/scheduler/scheduler.go#L31-L33). \ No newline at end of file diff --git a/content/v1.15-docs/concepts/ca-injector.md b/content/v1.15-docs/concepts/ca-injector.md new file mode 100644 index 0000000000..2c7c8dd638 --- /dev/null +++ b/content/v1.15-docs/concepts/ca-injector.md @@ -0,0 +1,234 @@ +--- +title: CA Injector +description: 'cert-manager core concepts: CA Injector' +--- + +`cainjector` helps to configure the CA certificates for: +[Mutating Webhooks], +[Validating Webhooks] +[Conversion Webhooks] and [API Services] + +In particular, `cainjector` populates the `caBundle` field of four API types: +`ValidatingWebhookConfiguration`, +`MutatingWebhookConfiguration` +`CustomResourceDefinition` and `APIService`. +The first three resource types are used to configure how the Kubernetes API server connects to webhooks. +This `caBundle` data is loaded by the Kubernetes API server and used to verify the serving certificates of webhook API servers. +`APIService` is used to represent an [Extension API Server]. `caBundle` of `APIService` can be populated with CA cert that can be used to validate the API server's serving certificate. + +We will refer to these four API types as *injectable* resources. + + +An *injectable* resource MUST have one of these annotations: +`cert-manager.io/inject-ca-from`, +`cert-manager.io/inject-ca-from-secret`, or +`cert-manager.io/inject-apiserver-ca`, depending on the injection *source*. +This is explained in more detail below. + +`cainjector` copies CA data from one of three *sources*: +a Kubernetes `Secret`, +a cert-manager `Certificate`, or from +the Kubernetes API server CA certificate (which `cainjector` itself uses to verify its TLS connection to the Kubernetes API server). + +If the *source* is a Kubernetes `Secret`, that resource MUST also have an `cert-manager.io/allow-direct-injection: "true"` annotation. +The three *source* types are explained in more detail below. + + +## Examples + +Here are examples demonstrating how to use the three `cainjector` *sources*. +In each case we use `ValidatingWebhookConfiguration` as the *injectable*, +but you can substitute `MutatingWebhookConfiguration` or `CustomResourceDefinition` definition instead. + +### Injecting CA data from a Certificate resource + +Here is an example of a `ValidatingWebhookConfiguration` +configured with the annotation `cert-manager.io/inject-ca-from`, +which will make `cainjector` populate the `caBundle` field using CA data from a cert-manager `Certificate`. + +NOTE: This example does not deploy a webhook server, +it only deploys a partial webhook configuration, +but it should be sufficient to help you understand what `cainjector` does: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: example1 + +--- + +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: webhook1 + annotations: + cert-manager.io/inject-ca-from: example1/webhook1-certificate +webhooks: +- name: webhook1.example.com + admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook1 + namespace: example1 + path: /validate + port: 443 + sideEffects: None + +--- + +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: webhook1-certificate + namespace: example1 +spec: + secretName: webhook1-certificate + dnsNames: + - webhook1.example1 + issuerRef: + name: selfsigned + +--- + +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned + namespace: example1 +spec: + selfSigned: {} +``` + +You should find that the `caBundle` value is now identical to the CA value in the `Secret` for the `Certificate`: + +``` +kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io webhook1 -o yaml | grep caBundle +kubectl -n example1 get secret webhook1-certificate -o yaml | grep ca.crt +``` + +And after a short time, the Kubernetes API server will read that new `caBundle` value and use it to verify a TLS connection to the webhook server. + +### Injecting CA data from a Secret resource + +Here is another example of a `ValidatingWebhookConfiguration` +this time configured with the annotation `cert-manager.io/inject-ca-from-secret`, +which will make `cainjector` populate the `caBundle` field using CA data from a Kubernetes `Secret`. + +NOTE: This example does not deploy a webhook server, +it only deploys a partial webhook configuration, +but it should be sufficient to help you understand what `cainjector` does: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: example2 + +--- + +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: webhook2 + annotations: + cert-manager.io/inject-ca-from-secret: example2/example-ca +webhooks: +- name: webhook2.example.com + admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook2 + namespace: example2 + path: /validate + port: 443 + sideEffects: None + +--- + +apiVersion: v1 +kind: Secret +metadata: + name: example-ca + namespace: example2 + annotations: + cert-manager.io/allow-direct-injection: "true" +type: kubernetes.io/tls +data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM5akNDQWQ2Z0F3SUJBZ0lRTkdJZ24yM3BQYVpNbk9MUjJnVmZHakFOQmdrcWhraUc5dzBCQVFzRkFEQVYKTVJNd0VRWURWUVFERXdwRmVHRnRjR3hsSUVOQk1CNFhEVEl3TURreU5ERTFOREEwTVZvWERUSXdNVEl5TXpFMQpOREEwTVZvd0ZURVRNQkVHQTFVRUF4TUtSWGhoYlhCc1pTQkRRVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFECmdnRVBBRENDQVFvQ2dnRUJBS2F3RzVoMzlreHdyNEl0WCtHaDNYVWQrdTVJc2ZlSFdoTTc4TTRQTmZFeXhQMXoKRmNLN1d0MHJFMkwwNUppYmQ4ZjNpb3k5OXNnQ3I4OEw2SWxYZTB0RnkzNysxenJ4TFluR2hDQnZzZjltd0hLbgpIVTEvNERwQjROZkhPbFllNE9tbHVoNE9HdmZINU1EbDh5OWZGMjhXRXVBQ2dwdmpCUWxvRDNlVjJ5UmJvQ2kyCmtSTDJWYTFZL0FQZEpWK21VYkFvZmg0bllmUmNLRTJsSUg0RG5ZdXFPU3JaaituZUQ2M2RTSktxcHQ5K2luN2YKNHljZ2pQYU93MmdyKzhLK291QTlSQTV1VDI3SVNJcUJDcEV6elRqbVBUUWNvUTYxZGF0aDZkc1lsTEU4aWZWUwp4RWZuVEdQKy94M0FXQXR4eU5lanVuZGFXbVNFL3h5OHh0K0FxblVDQXdFQUFhTkNNRUF3RGdZRFZSMFBBUUgvCkJBUURBZ0trTUE4R0ExVWRFd0VCL3dRRk1BTUJBZjh3SFFZRFZSME9CQllFRkowNkc5eEc2V1VBTHB6T3JYaHAKV2dsTm5qMkFNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUI3ZG9CZnBLR3o4VlRQSnc0YXhpdisybzJpMHE1SQpSRzU2UE81WnhKQktZQlRROElHQmFOSm1yeGtmNTJCV0ttUGp4cXlNSGRwWjVBU00zOUJkZVUzRGtEWHp4RkgwCjM5RU12UnhIUERyMGQ4cTFFbndQT0xZY1hzNjJhYjdidE11cTJUMFNNZzRYMkY5VmNKTW5YdjlrNnA0VGZNR3MKVThCQnJhVGhUZm53ejBsWXMyblFjdzNmZjZ1bG1wWlk4K3BTak1aVDNJZHZOMFA4Y2hOdUlmUFRHWDJmSlo2NQpxcUUrelRoU3hIeXFTOTVoczhsd1lRRUhGQlVsalRnMCtQZThXL0hOSXZBOU9TYWw1U3UvdlhydmcxN04xdHVyCk5XcWRyZU5OVm1ubXMvTFJodmthWTBGblRvbFNBRkNXWS9GSDY5ZzRPcThiMHVyK3JVMHZOZFFXCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + tls.key: "" + tls.crt: "" +``` + +You should find that the `caBundle` value is now identical to the `ca.crt` value in the `Secret`: + +``` +kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io webhook2 -o yaml | grep caBundle +``` + +And after a short time, the Kubernetes API server will read that new `caBundle` value and use it to verify a TLS connection to the webhook server. + +This `Secret` based injection mechanism can operate independently of the `Certificate` based mechanism described earlier. +It will work without the cert-manager CRDs installed +and it will work if the cert-manager CRDs and associated webhook servers are not yet configured. + +NOTE: For this reason, cert-manager uses the `Secret` based injection mechanism to bootstrap its own webhook server. +The cert-manager webhook server generates its own private key and self-signed certificate and places them in a `Secret` when it starts up. + +### Injecting the Kubernetes API Server CA + +Here is another example of a `ValidatingWebhookConfiguration` +this time configured with the annotation `cert-manager.io/inject-apiserver-ca: "true"`, +which will make `cainjector` populate the `caBundle` field using the same CA certificate used by the Kubernetes API server. + +NOTE: This example does not deploy a webhook server, +it only deploys a partial webhook configuration, +but it should be sufficient to help you understand what `cainjector` does: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: example3 + +--- + +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: webhook3 + annotations: + cert-manager.io/inject-apiserver-ca: "true" +webhooks: +- name: webhook3.example.com + admissionReviewVersions: + - v1 + clientConfig: + service: + name: webhook3 + namespace: example3 + path: /validate + port: 443 + sideEffects: None + +``` + +You should find that the `caBundle` value is now identical to the CA used in your `KubeConfig` file: + +``` +kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io webhook3 -o yaml | grep caBundle +kubectl config view --minify --raw | grep certificate-authority-data +``` + +And after a short time, the Kubernetes API server will read that new `caBundle` value and use it to verify a TLS connection to the webhook server. + +NOTE: In this case you will have to ensure that your webhook is configured to serve a TLS certificate that has been signed by the Kubernetes cluster CA. +The disadvantages of this mechanism are that: you will require access to the private key of the Kubernetes cluster CA and you will need to manually rotate the webhook certificate. + +[Validating Webhooks]: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook +[Mutating Webhooks]: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook +[Conversion Webhooks]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion +[API Services]: https://kubernetes.io/docs/reference/kubernetes-api/cluster-resources/api-service-v1/ +[Extension API Server]: https://kubernetes.io/docs/tasks/extend-kubernetes/setup-extension-api-server/ \ No newline at end of file diff --git a/content/v1.15-docs/concepts/issuer.md b/content/v1.15-docs/concepts/issuer.md new file mode 100644 index 0000000000..6293369992 --- /dev/null +++ b/content/v1.15-docs/concepts/issuer.md @@ -0,0 +1,44 @@ +--- +title: Issuer +description: 'cert-manager core concepts: Issuers and ClusterIssuers' +--- + +`Issuers`, and `ClusterIssuers`, are Kubernetes resources that represent +certificate authorities (CAs) that are able to generate signed certificates by honoring +certificate signing requests. All cert-manager certificates require a referenced +issuer that is in a ready condition to attempt to honor the request. + +An example of an `Issuer` type is `CA`. A simple `CA` `Issuer` is as follows: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-issuer + namespace: mesh-system +spec: + ca: + secretName: ca-key-pair +``` + +This is a simple `Issuer` that will sign certificates based on a private key. +The certificate stored in the secret `ca-key-pair` can then be used to trust +newly signed certificates by this `Issuer` in a Public Key Infrastructure (PKI) +system. + +## Namespaces + +An `Issuer` is a namespaced resource, and it is not possible to issue +certificates from an `Issuer` in a different namespace. This means you will need +to create an `Issuer` in each namespace you wish to obtain `Certificates` in. + +If you want to create a single `Issuer` that can be consumed in multiple +namespaces, you should consider creating a `ClusterIssuer` resource. This is +almost identical to the `Issuer` resource, however is non-namespaced so it +can be used to issue `Certificates` across all namespaces. + +## Supported Issuers + +cert-manager supports a number of 'in-tree', as well as 'out-of-tree' `Issuer` +types. An exhaustive list of these `Issuer` types can be found in the +cert-manager [configuration documentation](../configuration/README.md). diff --git a/content/v1.15-docs/concepts/webhook.md b/content/v1.15-docs/concepts/webhook.md new file mode 100644 index 0000000000..05345edf43 --- /dev/null +++ b/content/v1.15-docs/concepts/webhook.md @@ -0,0 +1,80 @@ +--- +title: All About the cert-manager Webhook +description: | + Learn about the webhook component of cert-manager, which validates, converts and sets default values for the cert-manager custom resources +--- + +cert-manager extends the Kubernetes API using Custom Resource Definitions. +It installs a webhook which has three main functions: + +- [Validation](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#validatingadmissionwebhook): + Ensures that when cert-manager resources are created or updated, they conform + to the rules of the API. This validation is more in depth than for example + ensuring resources conform to the OpenAPI schema, but instead contains logic such as + not allowing to specify more than one `Issuer` type per `Issuer` resource. The + validating admission is always called and will respond with a success or + failed response. +- [Mutation / Defaulting](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook): + Changes the contents of resources during create and update operations, for + example to set default values. +- [Conversion](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion): + The webhook is also responsible for implementing a conversion over versions + in the cert-manager `CustomResources` (`cert-manager.io`). This means that + multiple API versions can be supported simultaneously; from `v1alpha2` through to `v1`. + This makes it possible to rely on a particular version of our + configuration schema. + +> ℹ️ This is known as Dynamic Admission Control. +> Read more about [Dynamic Admission Control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) in the Kubernetes documentation. + +## Overview + +The webhook component is deployed as another pod that runs alongside the main +cert-manager controller and CA injector components. + +In order for the API server to communicate with the webhook component, the +webhook requires a TLS certificate that the apiserver is configured to trust. + +The webhook creates `secret/cert-manager-webhook-ca` in the namespace where the webhook is deployed. This secret contains a self-signed root CA certificate which is used to sign certificates for the webhook pod in order to fulfill this requirement. + +Then the webhook can be configured with either + +1. paths to a TLS certificate and key signed by the webhook CA, or +2. a reference to the CA Secret for dynamic generation of the certificate and key on webhook startup + +## Known Problems and Solutions + +### Webhook connection problems on GKE private cluster + +If errors occur around the webhook but the webhook is running then the webhook +is most likely not reachable from the API server. In this case, ensure that the +API server can communicate with the webhook by following the [GKE private +cluster explanation](../installation/compatibility.md#gke). + +### Webhook connection problems on AWS EKS + +When using a custom CNI (such as Weave or Calico) on EKS, the webhook cannot be reached by cert-manager. +This happens because the control plane cannot be configured to run on a custom CNI on EKS, +so the CNIs differ between control plane and worker nodes. +The solution is to [run the webhook in the host network](../installation/compatibility.md#aws-eks) so it can be reached by cert-manager. + +### Webhook connection problems shortly after cert-manager installation + +When you first install cert-manager, it will take a few seconds before the cert-manager API is usable. +This is because the cert-manager API requires the cert-manager webhook server, which takes some time to start up. +Here's why: + +* The webhook server performs a leader election at startup which may take a few seconds. +* The webhook server may take a few seconds to start up and to generate its self-signed CA and serving certificate and to publish those to a Secret. +* `cainjector` performs a leader election at start up which can take a few seconds. +* `cainjector`, once started, will take a few seconds to update the `caBundle` in all the webhook configurations. + +For these reasons, after installing cert-manager and when performing post-installation cert-manager API operations, +you will need to check for temporary API configuration errors and retry. + +You could also add a post-installation check which performs `kubectl --dry-run` operations on the cert-manager API. +Or you could add a post-installation check which automatically retries the [Installation Verification](../installation/kubectl.md#verify) steps until they succeed. + +### Other Webhook Problems + +If you encounter any other problems with the webhook, please refer to the [webhook troubleshooting guide](../troubleshooting/webhook.md). diff --git a/content/v1.15-docs/configuration/README.md b/content/v1.15-docs/configuration/README.md new file mode 100644 index 0000000000..85c5d1334f --- /dev/null +++ b/content/v1.15-docs/configuration/README.md @@ -0,0 +1,30 @@ +--- +title: Issuer Configuration +description: Learn about configuring cert-manager using Issuer and ClusterIssuer resources. +--- + +The first thing you'll need to configure after you've installed cert-manager is an `Issuer` or a `ClusterIssuer`. +These are resources that represent certificate authorities (CAs) +able to sign certificates in response to certificate signing requests. + +This section documents how the different issuer types can be configured. You might want to +[read more about `Issuer` and `ClusterIssuer` resources](../concepts/issuer.md). + +cert-manager comes with a number of built-in certificate issuers which are denoted by being in +the `cert-manager.io` group. You can also install external issuers in addition to the built-in types. +Built-in and external issuers are treated the same and are configured similarly. + +## Cluster Resource Namespace + +When using `ClusterIssuer` resource types, ensure you understand the purpose of the +Cluster Resource Namespace; this can be a common source +of issues for people getting started with cert-manager. + +The `ClusterIssuer` resource is cluster scoped. This means that when referencing +a secret via the `secretName` field, secrets will be looked for in the `Cluster +Resource Namespace`. By default, this namespace is `cert-manager` however it can be +changed via a flag on the cert-manager-controller component: + +```bash +--cluster-resource-namespace=my-namespace +``` diff --git a/content/v1.15-docs/configuration/acme/README.md b/content/v1.15-docs/configuration/acme/README.md new file mode 100644 index 0000000000..47eb22c9ee --- /dev/null +++ b/content/v1.15-docs/configuration/acme/README.md @@ -0,0 +1,391 @@ +--- +title: ACME +description: 'cert-manager configuration: ACME Issuers' +--- + +The ACME Issuer type represents a single account registered with the Automated +Certificate Management Environment (ACME) Certificate Authority server. When you +create a new ACME `Issuer`, cert-manager will generate a private key which is +used to identify you with the ACME server. + +Certificates issued by public ACME servers are typically trusted by client's +computers by default. This means that, for example, visiting a website that is +backed by an ACME certificate issued for that URL, will be trusted by default by +most client's web browsers. ACME certificates are typically free. + +## Solving Challenges + +In order for the ACME CA server to verify that a client owns the domain, or +domains, a certificate is being requested for, the client must complete +"challenges". This is to ensure clients are unable to request certificates for +domains they do not own and as a result, fraudulently impersonate another's +site. As detailed in the [RFC8555](https://tools.ietf.org/html/rfc8555), +cert-manager offers two challenge validations - HTTP01 and DNS01 challenges. + +[HTTP01](./http01/README.md) challenges are completed by presenting a computed +key, that should be present at a HTTP URL endpoint and is routable over the +internet. This URL will use the domain name requested for the certificate. Once +the ACME server is able to get this key from this URL over the internet, the +ACME server can validate you are the owner of this domain. When a HTTP01 +challenge is created, cert-manager will automatically configure your cluster +ingress to route traffic for this URL to a small web server that presents this +key. + +[DNS01](./dns01/README.md) challenges are completed by providing a computed key +that is present at a DNS TXT record. Once this TXT record has been propagated +across the internet, the ACME server can successfully retrieve this key via a +DNS lookup and can validate that the client owns the domain for the requested +certificate. With the correct permissions, cert-manager will automatically +present this TXT record for your given DNS provider. + +## Configuration + +### Creating a Basic ACME Issuer + +All ACME `Issuers` follow a similar configuration structure - a clients `email`, +a `server` URL, a `privateKeySecretRef`, and one or more `solvers`. Below is an +example of a simple ACME issuer: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + # You must replace this email address with your own. + # Let's Encrypt will use this to contact you about expiring + # certificates, and issues related to your account. + email: user@example.com + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + # Secret resource that will be used to store the account's private key. + name: example-issuer-account-key + # Add a single challenge solver, HTTP01 using nginx + solvers: + - http01: + ingress: + ingressClassName: nginx +``` + +Solvers come in the form of [`dns01`](./dns01/README.md) and +[`http01`](./http01/README.md) stanzas. For more information on how to configure +these solver types, visit their respective documentation - +[DNS01](./dns01/README.md), [HTTP01](./http01/README.md). + +### External Account Bindings + +cert-manager supports using External Account Bindings with your ACME account. +External Account Bindings are used to associate your ACME account with an +external account such as a CA custom database. This is typically not needed for +most cert-manager users unless you know it is explicitly needed. + +External Account Bindings require two fields on an ACME `Issuer` which +represents your ACME account. These fields are: + +- `keyID` - the key ID or account ID of which your external account binding is indexed by the +external account manager +- `keySecretRef` - the name and key of a secret containing a base 64 encoded +URL string of your external account symmetric MAC key + +> Note: In _most_ cases, the MAC key must be encoded in `base64URL`. The +> following command will base64-encode a key and convert it to `base64URL`: +> +> ```console +> $ echo 'my-secret-key' | base64 -w0 | sed -e 's/+/-/g' -e 's/\//_/g' -e 's/=//g' +> ``` +> +> You can then create the Secret resource with: +> +> ```console +> $ kubectl create secret generic eab-secret --from-literal \ +> secret={base64 encoded secret key} +> ``` + +An example of an ACME issuer with an External Account Binding is as follows. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: my-acme-server-with-eab +spec: + acme: + email: user@example.com + server: https://my-acme-server-with-eab.com/directory + externalAccountBinding: + keyID: my-keyID-1 + keySecretRef: + name: eab-secret + key: secret + privateKeySecretRef: + name: example-issuer-account-key + solvers: + - http01: + ingress: + ingressClassName: nginx +``` + +> Note: cert-manager versions pre-`v1.3.0` also required users to specify the +> MAC algorithm for EAB by setting +> `Issuer.spec.acme.externalAccountBinding.keyAlgorithm` field. This field is +> now deprecated because the upstream Go `x/crypto` library hardcodes the algorithm +> to `HS256`. (See related discussion upstream +> [`CL#41430`](https://github.com/golang/go/issues/41430)). +### Reusing an ACME Account + +You may want to reuse a single ACME account across multiple clusters. This +might especially be useful when using EAB. If the `disableAccountKeyGeneration` +field is set, cert-manager will not create a new ACME account and use the +existing key specified in `privateKeySecretRef`. Note that the +`Issuer`/`ClusterIssuer` will not be ready and will continue to retry until the +`Secret` is provided. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: my-acme-server-with-existing-acme-account +spec: + acme: + email: user@example.com + disableAccountKeyGeneration: true + privateKeySecretRef: + name: example-issuer-account-key +``` + + +### Adding Multiple Solver Types + +You may want to use different types of challenge solver configurations for +different ingress controllers, for example if you want to issue wildcard +certificates using `DNS01` alongside other certificates that are validated using +`HTTP01`. + +The `solvers` stanza has an optional `selector` field, that can be used to +specify which `Certificates`, and further, what DNS names *on those* +`Certificates` should be used to solve challenges. + +There are three selector types that can be used to form the requirements that a +`Certificate` must meet in order to be selected for a solver - `matchLabels`, +`dnsNames` and `dnsZones`. You can have any number of these three selectors on a +single solver. + + +#### Match Labels + +The `matchLabel` selector requires that all `Certificates` match all of +the labels that are defined in the string map list of that stanza. For example, +the following `Issuer` will only match on `Certificates` that have the labels +`"user-cloudflare-solver": "true"` and `"email": "user@example.com"`. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + ... + solvers: + - dns01: + cloudflare: + email: user@example.com + apiKeySecretRef: + name: cloudflare-apikey-secret + key: apikey + selector: + matchLabels: + "use-cloudflare-solver": "true" + "email": "user@example.com" +``` + +#### DNS Names + +The `dnsNames` selector is a list of exact DNS names that should be mapped to a +solver. This means that `Certificates` containing any of these DNS names will +be selected. If a match is found, a `dnsNames` selector will take precedence +over a [`dnsZones`](#dns-zones) selector. If multiple solvers match with the +same `dnsNames` value, the solver with the most matching labels in +[`matchLabels`](#match-labels) will be selected. If neither has more matches, +the solver defined earlier in the list will be selected. + +The following example will solve challenges of `Certificates` with DNS names +`example.com` and `*.example.com` for these domains. + +> Note: `dnsNames` take an exact match and do not resolve wildcards, meaning the +> following `Issuer` *will not* solve for DNS names such as `foo.example.com`. +> Use the [`dnsZones`](#dns-zones) selector type to match all subdomains within +> a zone. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + ... + solvers: + - dns01: + cloudflare: + email: user@example.com + apiKeySecretRef: + name: cloudflare-apikey-secret + key: apikey + selector: + dnsNames: + - 'example.com' + - '*.example.com' +``` + +#### DNS Zones + +The `dnsZones` stanza defines a list of DNS zones that can be solved by this +solver. If a DNS name is an exact match, or a subdomain of any of the specified +`dnsZones`, this solver will be used, unless a more specific +[`dnsNames`](#dns-names) match is configured. This means that `sys.example.com` +will be selected over one specifying `example.com` for the domain +`www.sys.example.com`. If multiple solvers match with the same `dnsZones` value, +the solver with the most matching labels in [`matchLabels`](#match-labels) will +be selected. If neither has more matches, the solver defined earlier in the list +will be selected. + +In the following example, this solver will resolve challenges for the domain +`example.com`, as well as all of its subdomains `*.example.com`. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + ... + solvers: + - dns01: + cloudflare: + email: user@example.com + apiKeySecretRef: + name: cloudflare-apikey-secret + key: apikey + selector: + dnsZones: + - 'example.com' +``` + +#### All Together + +Each solver is able to have any number of the three selector types defined. In +the following example, the `DNS01` solver for CloudFlare will be used to solve +challenges for domains for `Certificates` that contain the DNS names +`a.example.com` and `b.example.com`. The `DNS01` solver for Google CloudDNS will +be used to solve challenges for `Certificates` whose DNS names match +zone `test.example.com` and all of its subdomains (e.g. `foo.test.example.com`). + +For all other challenges, the `HTTP01` solver will be used *only* if the +`Certificate` also contains the label `"use-http01-solver": "true"`. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + ... + solvers: + - http01: + ingress: + ingressClassName: nginx + selector: + matchLabels: + "use-http01-solver": "true" + - dns01: + cloudflare: + email: user@example.com + apiKeySecretRef: + name: cloudflare-apikey-secret + key: apikey + selector: + dnsNames: + - 'a.example.com' + - 'b.example.com' + - dns01: + cloudDNS: + project: my-project-id + hostedZoneName: 'test-example.com' + serviceAccountSecretRef: + key: sa + name: gcp-sa-secret + selector: + dnsZones: + - 'test.example.com' # This should be the DNS name of the zone +``` + +Each individual selector block can contain more than one selector type for +example: + +```yaml +solvers: +- dns01: + cloudflare: + email: user@example.com + apiKeySecretRef: + name: cloudflare-apikey-secret + key: apikey + selector: + matchLabels: + 'email': 'user@example.com' + 'solver': 'cloudflare' + dnsZones: + - 'test.example.com' + - 'example.dev' +``` + +In this case the `DNS01` solver for Cloudflare will only be used to solve a +challenge for a DNS name if the `Certificate` has a label from +`matchLabels` _and_ the DNS name matches a zone from `dnsZones`. + +## Private ACME Servers + +cert-manager should also work with private or self-hosted ACME servers, as long as they follow the ACME spec. + +If your ACME server doesn't use a publicly trusted certificate, you can pass a trusted CA to use when creating your +issuer, from cert-manager 1.11 onwards: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: my-acme-server-issuer +spec: + acme: + server: https://my-acme-server.example.com + caBundle: + ... +``` + + +{/* The empty link below preserves old links to #alternative-certificate-chain", which matched the old title of this section */} + +## Alternative Certificate Chains + +It's possible to choose alternative certificate chains when fetching a certificate from an ACME server. This allows issuers to gracefully roll people over to a new root certificate during a transition period; the most famous example was the Let's Encrypt ["ISRG Root" changeover](https://community.letsencrypt.org/t/transition-to-isrgs-root-delayed-until-jan-11-2021/125516). + +This functionality is not exclusive to Let's Encrypt; if your ACME server supports signing by multiple CAs you can use `preferredChain` with the value of the Common Name of the chain you want in the Issuer part of the certificate. If the common name matches a difference chain, the server can choose to use and return that new chain. + +If the `preferredChain` does not match a certificate the server will return whatever it considers to be its default certificate. + +By way of an example, below is how a user would have requested an alternative chain before the (now completed) "ISRG Root" changeover, but note that since this change has already happened there's no need for this with Let's Encrypt any more: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + preferredChain: "ISRG Root X1" +``` diff --git a/content/v1.15-docs/configuration/acme/dns01/README.md b/content/v1.15-docs/configuration/acme/dns01/README.md new file mode 100644 index 0000000000..b7a12c3b91 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/README.md @@ -0,0 +1,189 @@ +--- +title: DNS01 +description: 'cert-manager configuration: ACME DNS-01 challenges overview' +--- + +## Configuring DNS01 Challenge Provider + +This page contains details on the different options available on the `Issuer` +resource's DNS01 challenge solver configuration. + +For more information on configuring ACME `Issuers` and their API format, read the +[ACME Issuers](../README.md) documentation. + +DNS01 provider configuration must be specified on the `Issuer` resource, similar +to the examples in the setting up documentation. + +You can read about how the DNS01 challenge type works on the [Let's Encrypt +challenge types +page](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge). + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + email: user@example.com + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: example-issuer-account-key + solvers: + - dns01: + cloudDNS: + project: my-project + serviceAccountSecretRef: + name: prod-clouddns-svc-acct-secret + key: service-account.json +``` + +Each issuer can specify multiple different DNS01 challenge providers, and +it is also possible to have multiple instances of the same DNS provider on a +single `Issuer` (e.g. two CloudDNS accounts could be set, each with their own +name). + +For more information on utilizing multiple solver types on a single `Issuer`, +read the multiple-solver-types section. + +## Setting Nameservers for DNS01 Self Check + +cert-manager will check the correct DNS records exist before attempting a DNS01 +challenge. By default cert-manager will use the recursive nameservers taken +from `/etc/resolv.conf` to query for the authoritative nameservers, which it will +then query directly to verify the DNS records exist. + +If this is not desired (for example with multiple authoritative nameservers or +split-horizon DNS), the cert-manager controller exposes two flags that allows +you alter this behavior: + +`--dns01-recursive-nameservers` Comma separated string with host and port of the +recursive nameservers cert-manager should query. + +`--dns01-recursive-nameservers-only` Forces cert-manager to only use the +recursive nameservers for verification. Enabling this option could cause the DNS01 +self check to take longer due to caching performed by the recursive nameservers. + + +Example usage: +```bash +--dns01-recursive-nameservers-only --dns01-recursive-nameservers=8.8.8.8:53,1.1.1.1:53 +``` + +If you're using the `cert-manager` helm chart, you can set recursive nameservers +through `.Values.extraArgs` or at the command at helm install/upgrade time +with `--set`: + +```bash +--set 'extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=8.8.8.8:53\,1.1.1.1:53}' +``` + +## Delegated Domains for DNS01 + +By default, cert-manager will not follow CNAME records pointing to subdomains. + +If granting cert-manager access to the root DNS zone is not desired, then the +`_acme-challenge.example.com` subdomain can instead be delegated to some other, +less privileged domain (`less-privileged.example.org`). This could be achieved in the following way. Say, one has two zones: + +* `example.com` +* `less-privileged.example.org` + +1. Create a CNAME record pointing to this less privileged domain: +``` +_acme-challenge.example.com IN CNAME _acme-challenge.less-privileged.example.org. +``` + +2. Grant cert-manager rights to update less privileged `less-privileged.example.org` zone + +3. Provide configuration/credentials for updating this less privileged zone +and add an additional field into the relevant `dns01` solver. Note that `selector` +field is still working for the original `example.com`, while credentials are provided for +`less-privileged.example.org` + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + ... +spec: + acme: + ... + solvers: + - selector: + dnsZones: + - 'example.com' + dns01: + # Valid values are None and Follow + cnameStrategy: Follow + route53: + region: eu-central-1 + accessKeyID: + hostedZoneID: + secretAccessKeySecretRef: + ... +``` + +If you have a multitude of (sub)domains requiring separate certificates, +it is possible to share an aliased less-privileged domain. To achieve it one should +create a CNAME record for each (sub)domain like this: + +```txt +_acme-challenge.example.com IN CNAME _acme-challenge.less-privileged.example.org. +_acme-challenge.www.example.com IN CNAME _acme-challenge.less-privileged.example.org. +_acme-challenge.foo.example.com IN CNAME _acme-challenge.less-privileged.example.org. +_acme-challenge.bar.example.com IN CNAME _acme-challenge.less-privileged.example.org. +``` + +With this configuration cert-manager will follow CNAME records recursively in order to determine +which DNS zone to update during DNS01 challenges. + + +## Supported DNS01 providers + +A number of different DNS providers are supported for the ACME `Issuer`. Below +is a listing of available providers, their `.yaml` configurations, along with +additional Kubernetes and provider specific notes regarding their usage. + +- [ACMEDNS](./acme-dns.md) +- [Akamai](./akamai.md) +- [AzureDNS](./azuredns.md) +- [CloudFlare](./cloudflare.md) +- [Google](./google.md) +- [Route53](./route53.md) +- [DigitalOcean](./digitalocean.md) +- [RFC2136](./rfc2136.md) + +## Webhook + +cert-manager also supports out of tree DNS providers using an external webhook. +Links to these supported providers along with their documentation are below: + +- [`AliDNS-Webhook`](https://github.com/pragkent/alidns-webhook) +- [`cert-manager-alidns-webhook`](https://github.com/DEVmachine-fr/cert-manager-alidns-webhook) +- [`cert-manager-webhook-civo`](https://github.com/okteto/cert-manager-webhook-civo) +- [`cert-manager-webhook-dnspod`](https://github.com/qqshfox/cert-manager-webhook-dnspod) +- [`cert-manager-webhook-dnsimple`](https://github.com/neoskop/cert-manager-webhook-dnsimple) +- [`cert-manager-webhook-gandi`](https://github.com/bwolf/cert-manager-webhook-gandi) +- [`cert-manager-webhook-infomaniak`](https://github.com/Infomaniak/cert-manager-webhook-infomaniak) +- [`cert-manager-webhook-inwx`](https://gitlab.com/smueller18/cert-manager-webhook-inwx) +- [`cert-manager-webhook-linode`](https://github.com/slicen/cert-manager-webhook-linode) +- [`cert-manager-webhook-oci`](https://gitlab.com/dn13/cert-manager-webhook-oci) (Oracle Cloud Infrastructure) +- [`cert-manager-webhook-scaleway`](https://github.com/scaleway/cert-manager-webhook-scaleway) +- [`cert-manager-webhook-selectel`](https://github.com/selectel/cert-manager-webhook-selectel) +- [`cert-manager-webhook-softlayer`](https://github.com/cgroschupp/cert-manager-webhook-softlayer) +- [`cert-manager-webhook-ibmcis`](https://github.com/jb-dk/cert-manager-webhook-ibmcis) +- [`cert-manager-webhook-loopia`](https://github.com/Identitry/cert-manager-webhook-loopia) +- [`cert-manager-webhook-arvan`](https://github.com/kiandigital/cert-manager-webhook-arvan) +- [`bizflycloud-certmanager-dns-webhook`](https://github.com/bizflycloud/bizflycloud-certmanager-dns-webhook) +- [`cert-manager-webhook-hetzner`](https://github.com/vadimkim/cert-manager-webhook-hetzner) +- [`cert-manager-webhook-yandex-cloud`](https://github.com/malinink/cert-manager-webhook-yandex-cloud) +- [`cert-manager-webhook-netcup`](https://github.com/aellwein/cert-manager-webhook-netcup) +- [`cert-manager-webhook-pdns`](https://github.com/zachomedia/cert-manager-webhook-pdns) +- [`cert-manager-webhook-zilore`](https://gitlab.com/zilore/cert-manager-webhook-zilore) +- [`stackit-cert-manager-webhook`](https://github.com/stackitcloud/stackit-cert-manager-webhook) +- [`cert-manager-webhook-vercel`](https://github.com/rhythmbhiwani/cert-manager-webhook-vercel) + +You can find more information on how to configure webhook providers [here](./webhook.md). + +To create a new unsupported DNS provider, follow the development documentation [here](../../../contributing/dns-providers.md). diff --git a/content/v1.15-docs/configuration/acme/dns01/acme-dns.md b/content/v1.15-docs/configuration/acme/dns01/acme-dns.md new file mode 100644 index 0000000000..968531bf5f --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/acme-dns.md @@ -0,0 +1,220 @@ +--- +title: ACMEDNS +description: 'cert-manager configuration: ACME DNS-01 challenges using ACMEDNS' +--- + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + solvers: + - dns01: + acmeDNS: + host: https://acme.example.com + accountSecretRef: + name: acme-dns + key: acmedns.json +``` + +In general, clients to ACMEDNS perform registration on the users behalf and +inform them of the CNAME entries they must create. This is not possible in +cert-manager, it is a non-interactive system. Registration must be carried out +beforehand and the resulting credentials JSON uploaded to the cluster as a +`Secret`. In this example, we use `curl` and the API endpoints directly. +Information about setting up and configuring ACMEDNS is available on the +[ACMEDNS project page](https://github.com/joohoi/acme-dns). + +1. First, register with the ACMEDNS server, in this example, there is one + running at `auth.example.com`. The command: + + ```sh + curl -X POST http://auth.example.com/register + ``` + + will return a JSON with credentials for your registration: + + ```json + { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": [] + } + ``` + + It is strongly recommended to restrict the update endpoint to the IP + range of your pods. This is done at registration time as follows: + + ```sh + curl -X POST http://auth.example.com/register \ + -H "Content-Type: application/json" \ + --data '{"allowfrom": ["10.244.0.0/16"]}' + ``` + + Make sure to update the `allowfrom` field to match your cluster + configuration. The JSON will now look like: + + ```json + { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": ["10.244.0.0/16"] + } + ``` + +2. Save this JSON to a file with the key as your domain. You can specify + multiple domains with the same credentials if you like. In our example, + the returned credentials can be used to verify ownership of + `example.com` and and `example.org`. + + ```json + { + "example.com": { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": ["10.244.0.0/16"] + }, + "example.org": { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": ["10.244.0.0/16"] + } + } + ``` + +3. Next, update your primary DNS server with the CNAME record that will tell the + verifier how to locate the challenge TXT record. This is obtained from the + `fulldomain` field in the registration: + + ``` + _acme-challenge.example.com CNAME d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com + _acme-challenge.example.org CNAME d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com + ``` + + The "name" of the record always has the _acme-challenge subdomain, and + the "value" of the record matches exactly the fulldomain field from + registration. + + At verification time, the domain name `d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com` will be a TXT + record that is set to your validation token. When the verifier queries `_acme-challenge.example.com`, it will + be directed to the correct location by this CNAME record. This proves that you control `example.com` + +4. Create a secret from the credentials JSON that was saved in step 2, this + secret is referenced in the `accountSecretRef` field of your DNS01 + issuer settings. When creating an `Issuer` both this `Issuer` and + `Secret` must be in the same namespace. However for a `ClusterIssuer` + (which does not have a namespace) the `Secret` must be placed in the + same namespace as where the cert-manager pod is running in (in the + default setup `cert-manager`). + + ```sh + kubectl create secret generic acme-dns --from-file acmedns.json + ``` + +## Limitation of the `acme-dns` server + +The [`acme-dns`](https://github.com/joohoi/acme-dns) server has a [known +limitation](https://github.com/cert-manager/cert-manager/issues/3610#issuecomment-849792721): +when a set of credentials is used with more than 2 domains, cert-manager +will fail solving the DNS01 challenges. + +Imagining that you have configured the ACMEDNS issuer with a single set of +credentials, and that the "subdomain" of this set of credentials is +`d420c923-bbd7-4056-ab64-c3ca54c9b3cf`: + +```yaml +kind: Secret +metadata: + name: auth-example-com +stringData: + acmedns.json: | + { + "example.com": { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": ["10.244.0.0/16"] + }, + } +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: my-acme-dns +spec: + acme: + solvers: + - dns01: + acmeDNS: + accountSecretRef: + name: auth-example-com + key: acmedns.json + host: auth.example.com +``` + +and imagine that you want to create a Certificate with three subdomains: + +```yaml +kind: Certificate +spec: + issuerRef: + name: issuer-1 + dnsNames: + - "example.com" + - "*.example.com" + - "foo.example.com" +``` + +cert-manager will only be able to solve 2 challenges out of 3 in a non +deterministic way. This limitation comes from a "feature" mentioned [this +acme-dns issue](https://github.com/joohoi/acme-dns/issues/76). + +One workaround is to issue one set of acme-dns credentials for each +domain that we want to be challenged, keeping in mind that each acme-dns +"subdomain" can only accept at most 2 challenged domains. For example, the +above secret would become: + +```yaml +kind: Secret +metadata: + name: auth-example-com +stringData: + acmedns.json: | + { + "example.com": { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": ["10.244.0.0/16"] + }, + "foo.example.com": { + "username": "eabcdb41-d89f-4580-826f-3e62e9755ef2", + "password": "pbAXVjlIOE01xbut7YnAbkhMQIkcwoHO0ek2j4Q0", + "fulldomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf.auth.example.com", + "subdomain": "d420c923-bbd7-4056-ab64-c3ca54c9b3cf", + "allowfrom": ["10.244.0.0/16"] + } +``` + +With this setup, we have: + +- `example.com` and `*.example.com` are registered in the acme-dns + "subdomain" `d420c923-bbd7-4056-ab64-c3ca54c9b3cf`. +- `foo.example.com` is registered in the acme-dns "subdomain" + `d420c923-bbd7-4056-ab64-c3ca54c9b3cf`. + +Another workaround is to use `--max-concurrent-challenges 2` when running +the `cert-manager-controller`. With this setting, acme-dns will only have 2 +TXT records in its database at any time, which mitigates the issue. \ No newline at end of file diff --git a/content/v1.15-docs/configuration/acme/dns01/akamai.md b/content/v1.15-docs/configuration/acme/dns01/akamai.md new file mode 100644 index 0000000000..271f7fd620 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/akamai.md @@ -0,0 +1,86 @@ +--- +title: Akamai +description: 'cert-manager configuration: ACME DNS-01 challenges using Akamai DNS' +--- + +## Edge DNS + +Use Edge DNS to solve DNS01 ACME challenges by creating a `Secret` using [Akamai API credentials](https://developer.akamai.com/getting-started/edgegrid) and an `Issuer` that references the `Secret` and sets the solver type. + +### Create a Secret + +The `Secret` should look like the following for the `Issuer` to reference. Replace `use_akamai_client_secret`, `use_akamai_access_token` and `use_akamai_client_token` with the respective Akamai API credential values. + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: akamai-secret +type: Opaque +stringData: + clientSecret: use_akamai_client_secret + accessToken: use_akamai_access_token + clientToken: use_akamai_client_token +``` + +### Create an Issuer + +To set Edge DNS for challenge tokens, `cert-manager` uses an `Issuer` that references the above `Secret` and other attributes such as the solver type. The `Issuer` should look like the following. Replace `use_akamai_host` with the Akamai API credential `host` value. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-akamai-dns +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: contact@me.com + privateKeySecretRef: + name: letsencrypt-akamai-issuer-account-key + solvers: + - dns01: + akamai: + serviceConsumerDomain: use_akamai_host + clientTokenSecretRef: + name: akamai-secret + key: clientToken + clientSecretSecretRef: + name: akamai-secret + key: clientSecret + accessTokenSecretRef: + name: akamai-secret + key: accessToken +``` + +### Create a Certificate + +The `Certificate` should look like the following and reference the Akamai Edge DNS `Issuer` above. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-zone +spec: + secretName: akamai-crt-secret + dnsNames: + - '*.example.zone' + issuerRef: + name: letsencrypt-akamai-dns + kind: Issuer +``` + +> Note: `cert-manager` will wait for challenge tokens to propagate across the Edge DNS network. Follow the `certificate` status with a command such as the following. + +```bash +kubectl describe certificate example-zone +``` + +### Troubleshooting + +Follow the `cert-manager` events to identify any issues with a command such as the following. + +```bash +cmctl status certificate example-zone +``` \ No newline at end of file diff --git a/content/v1.15-docs/configuration/acme/dns01/azuredns.md b/content/v1.15-docs/configuration/acme/dns01/azuredns.md new file mode 100644 index 0000000000..bc5de32fec --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/azuredns.md @@ -0,0 +1,505 @@ +--- +title: AzureDNS +description: 'cert-manager configuration: ACME DNS-01 challenges using AzureDNS' +--- + +cert-manager can create and then delete DNS-01 records in Azure DNS but it needs to authenticate to Azure first. +There are four authentication methods available: + +- [Managed Identity Using AAD Workload Identity](#managed-identity-using-aad-pod-identity) (recommended) +- [Managed Identity Using AAD Pod Identities](#managed-identity-using-aad-pod-identities) (deprecated) +- [Managed Identity Using AKS Kubelet Identity](#managed-identity-using-aks-kubelet-identity) +- [Service Principal](#service-principal) + +## Managed Identity Using AAD Workload Identity + +> ℹ️ This feature is available in cert-manager `>= v1.11.0`. +> +> 📖 Read the [AKS + LoadBalancer + Let's Encrypt tutorial](../../../tutorials/getting-started-aks-letsencrypt/README.md) for an end-to-end example of this authentication method. + +Azure AD workload identity (preview) on Azure Kubernetes Service (AKS) allows cert-manager to authenticate to Azure using a Kubernetes ServiceAccount Token and then to manage DNS-01 records in Azure DNS. +This is the recommended authentication method because it is more secure and easier to maintain than the other methods. + +### Reconfigure the cluster + +Enable the workload identity federation features on your cluster. +If you have an Azure AKS cluster you can use the following command: + +```bash +az aks update \ + --name ${CLUSTER} \ + --enable-oidc-issuer \ + --enable-workload-identity # ℹ️ This option is currently only available when using the aks-preview extension. +``` + +> ℹ️ You can [install the Azure workload identity extension on other managed and self-managed clusters](https://azure.github.io/azure-workload-identity/docs/installation.html) if you are not using Azure AKS. +> +> 📖 Read [Deploy and configure workload identity on an Azure Kubernetes Service (AKS) cluster](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster) for more information about the `--enable-workload-identity` feature. +> +### Reconfigure cert-manager + +Label the cert-manager controller Pod and ServiceAccount for the attention of the Azure Workload Identity webhook, +which will result in the cert-manager controller Pod having an extra volume containing a Kubernetes ServiceAccount token which it will use to authenticate with Azure. + +If you installed cert-manager using Helm, the labels can be configured using Helm values: + +```yaml +# values.yaml +podLabels: + azure.workload.identity/use: "true" +serviceAccount: + labels: + azure.workload.identity/use: "true" +``` + +If successful, the cert-manager Pod will have some new environment variables set, +and the Azure workload-identity ServiceAccount token as a projected volume: + +```bash +kubectl describe pod -n cert-manager -l app.kubernetes.io/component=controller +``` + +```terminal +Containers: + ... + cert-manager-controller: + ... + Environment: + ... + AZURE_CLIENT_ID: + AZURE_TENANT_ID: f99bd6a4-665c-41cf-aff1-87a89d5c62d4 + AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token + AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/ + Mounts: + /var/run/secrets/azure/tokens from azure-identity-token (ro) +Volumes: + ... + azure-identity-token: + Type: Projected (a volume that contains injected data from multiple sources) + TokenExpirationSeconds: 3600 +``` + +> 📖 Read about [the role of the Mutating Admission Webhook](https://azure.github.io/azure-workload-identity/docs/installation/mutating-admission-webhook.html) in Azure AD Workload Identity for Kubernetes. + + +### Create a Managed Identity + +In order for cert-manager to use the Azure API and manipulate the records in the Azure DNS zone, +it needs an Azure account and the best type of account to use is called a "Managed Identity". +This account does not come with a password or an API key and it is designed for use by machines rather than humans. + +Choose a managed identity name and create the Managed Identity: + +```bash +export IDENTITY_NAME=cert-manager +az identity create --name "${IDENTITY_NAME}" +``` + +Grant it permission to modify the DNS zone records: + +```bash +export IDENTITY_CLIENT_ID=$(az identity show --name "${IDENTITY_NAME}" --query 'clientId' -o tsv) +az role assignment create \ + --role "DNS Zone Contributor" \ + --assignee IDENTITY_CLIENT_ID \ + --scope $(az network dns zone show --name $DOMAIN_NAME -o tsv --query id) +``` + +> 📖 Read [What are managed identities for Azure resources?](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) +> for an overview of managed identities and their uses. +> +> 📖 Read [Azure built-in roles](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles) to learn about the "DNS Zone Contributor" role. +> +> 📖 Read more about [the `az identity` command](https://learn.microsoft.com/en-us/cli/azure/identity). + +### Add a Federated Identity + +Now associate a federated identity with the managed identity that you created earlier. +cert-manager will authenticate to Azure using a short lived Kubernetes ServiceAccount token, +and it will be able to impersonate the managed identity that you created in the previous step. + +```bash +export SERVICE_ACCOUNT_NAME=cert-manager # ℹ️ This is the default Kubernetes ServiceAccount used by the cert-manager controller. +export SERVICE_ACCOUNT_NAMESPACE=cert-manager # ℹ️ This is the default namespace for cert-manager. +export SERVICE_ACCOUNT_ISSUER=$(az aks show --resource-group $AZURE_DEFAULTS_GROUP --name $CLUSTER --query "oidcIssuerProfile.issuerUrl" -o tsv) +az identity federated-credential create \ + --name "cert-manager" \ + --identity-name "${IDENTITY_NAME}" \ + --issuer "${SERVICE_ACCOUNT_ISSUER}" \ + --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}" +``` + +- `--subject`: is the distinguishing name of the Kubernetes ServiceAccount. +- `--issuer`: is a URL from which the Azure will download the JWT signing certificate and other metadata + +> 📖 Read about [Workload identity federation](https://learn.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation) in the Microsoft identity platform documentation. +> +> 📖 Read more about [the `az identity federated-credential` command](https://learn.microsoft.com/en-us/cli/azure/identity/federated-credential). + +### Configure a ClusterIssuer + +For example: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + email: $EMAIL_ADDRESS + privateKeySecretRef: + name: letsencrypt-staging + solvers: + - dns01: + azureDNS: + hostedZoneName: $AZURE_ZONE_NAME + resourceGroupName: $AZURE_RESOURCE_GROUP + subscriptionID: $AZURE_SUBSCRIPTION_ID + environment: AzurePublicCloud + managedIdentity: + clientID: $IDENTITY_CLIENT_ID +``` + +The following variables need to be filled in. + +```bash +# An email address to which Let's Encrypt will send renewal reminders. +export EMAIL_ADDRESS= +# The Azure DNS zone in which the DNS-01 records will be created and deleted. +export AZURE_ZONE_NAME= +# The Azure resource group containing the DNS zone. +export AZURE_RESOURCE_GROUP= +# The Azure billing account name and ID for the DNS zone. +export AZURE_SUBSCRIPTION= +export AZURE_SUBSCRIPTION_ID=$(az account show --name $AZURE_SUBSCRIPTION --query 'id' -o tsv) +``` + +#### ⚠️ Using 'Ambient Credentials' with ClusterIssuer and Issuer resources + +This authentication method is an example of what cert-manager calls 'ambient credentials'. +Ambient credentials are enabled by default for ClusterIssuer resources, but disabled by default for Issuer resources. +This is to prevent unprivileged users, who have permission to create Issuer resources, from issuing certificates using credentials that cert-manager incidentally has access to. +ClusterIssuer resources are cluster scoped (not namespaced) and only platform administrators should be granted permission to create them. + +If you are using this authentication mechanism and ambient credentials are not enabled, you will see this error: + +```bash +error instantiating azuredns challenge solver: ClientID is not set but neither --cluster-issuer-ambient-credentials nor --issuer-ambient-credentials are set. +``` + +> ⚠️ It is possible (but not recommended) to enable this authentication mechanism for `Issuer` resources, by setting the `--issuer-ambient-credentials` flag on the cert-manager controller to true. + +## Managed Identity Using AAD Pod Identities + +> ⚠️ The [open source Azure AD pod-managed identity (preview) in Azure Kubernetes Service has been deprecated as of 10/24/2022](https://github.com/Azure/aad-pod-identity#-announcement). +> Use Workload Identity instead. + +[AAD Pod Identities](https://azure.github.io/aad-pod-identity) allows assigning a [Managed Identity](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) to a pod. This removes the need for adding explicit credentials into the cluster to create the required DNS records. + +> Note: When using Pod identity, even though assigning multiple identities to a single pod is allowed, currently cert-manager does not support this as it is not able to identify which identity to use. + +Firstly an identity should be created that has access to contribute to the DNS Zone. + +- Example creation using `azure-cli` and `jq`: + +```bash +# Choose a unique Identity name and existing resource group to create identity in. +IDENTITY=$(az identity create --name $IDENTITY_NAME --resource-group $IDENTITY_GROUP --output json) + +# Gets principalId to use for role assignment +PRINCIPAL_ID=$(echo $IDENTITY | jq -r '.principalId') + +# Used for identity binding +CLIENT_ID=$(echo $IDENTITY | jq -r '.clientId') +RESOURCE_ID=$(echo $IDENTITY | jq -r '.id') + +# Get existing DNS Zone Id +ZONE_ID=$(az network dns zone show --name $ZONE_NAME --resource-group $ZONE_GROUP --query "id" -o tsv) + +# Create role assignment +az role assignment create --role "DNS Zone Contributor" --assignee $PRINCIPAL_ID --scope $ZONE_ID +``` + +- Example creation using Terraform + +```terraform +variable resource_group_name {} +variable location {} +variable dns_zone_id {} + +# Creates Identity +resource "azurerm_user_assigned_identity" "dns_identity" { + name = "cert-manager-dns01" + resource_group_name = var.resource_group_name + location = var.location +} + +# Creates Role Assignment +resource "azurerm_role_assignment" "dns_contributor" { + scope = var.dns_zone_id + role_definition_name = "DNS Zone Contributor" + principal_id = azurerm_user_assigned_identity.dns_identity.principal_id +} + +# Client Id Used for identity binding +output "identity_client_id" { + value = azurerm_user_assigned_identity.dns_identity.client_id +} + +# Resource Id Used for identity binding +output "identity_resource_id" { + value = azurerm_user_assigned_identity.dns_identity.id +} +``` + +Next we need to ensure we have installed [AAD Pod Identity](https://azure.github.io/aad-pod-identity) using their walk-through. This will install the CRDs and deployment required to assign the identity. + +Now we can create the identity resource and binding using the below manifest as an example: + +```yaml +apiVersion: "aadpodidentity.k8s.io/v1" +kind: AzureIdentity +metadata: + annotations: + # recommended to use namespaced identites https://azure.github.io/aad-pod-identity/docs/configure/match_pods_in_namespace/ + aadpodidentity.k8s.io/Behavior: namespaced + name: certman-identity + namespace: cert-manager # change to your preferred namespace +spec: + type: 0 # MSI + resourceID: # Resource Id From Previous step + clientID: # Client Id from previous step +--- +apiVersion: "aadpodidentity.k8s.io/v1" +kind: AzureIdentityBinding +metadata: + name: certman-id-binding + namespace: cert-manager # change to your preferred namespace +spec: + azureIdentity: certman-identity + selector: certman-label # This is the label that needs to be set on cert-manager pods +``` + +Next we need to ensure the cert-manager pod has a relevant label to use the pod identity binding. This can be done by editing the deployment and adding the below into the `.spec.template.metadata.labels` field + +```yaml +spec: + template: + metadata: + labels: + aadpodidbinding: certman-label # must match selector in AzureIdentityBinding +``` + +Or by using the helm values `podLabels` + +```yaml +podLabels: + aadpodidbinding: certman-label +``` + +Lastly when we create the certificate issuer we only need to specify the `hostedZoneName`, `resourceGroupName` and `subscriptionID` fields for the DNS zone. Example below: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + azureDNS: + subscriptionID: AZURE_SUBSCRIPTION_ID + resourceGroupName: AZURE_DNS_ZONE_RESOURCE_GROUP + hostedZoneName: AZURE_DNS_ZONE + # Azure Cloud Environment, default to AzurePublicCloud + environment: AzurePublicCloud +``` + +This authentication mechanism is what cert-manager considers 'ambient credentials'. Use of ambient credentials is disabled by default for cert-manager `Issuer`s. This to ensure unprivileged users who have permission to create issuers cannot issue certificates using any credentials cert-manager incidentally has access to. To enable this authentication mechanism for `Issuer`s, you will need to set `--issuer-ambient-credentials` flag on cert-manager controller to true. (There is a corresponding `--cluster-issuer-ambient-credentials` flag which is set to `true` by default). + +If you are using this authentication mechanism and ambient credentials are not enabled, you will see this error: +```bash +error instantiating azuredns challenge solver: ClientID is not set but neither --cluster-issuer-ambient-credentials nor --issuer-ambient-credentials are set. +``` + +These are necessary to enable Azure Managed Identities. + +## Managed Identity Using AKS Kubelet Identity + +When creating an AKS cluster in Azure there is the option to use a managed identity that is assigned to the kubelet. This identity is assigned to the underlying node pool in the AKS cluster and can then be used by the cert-manager pods to authenticate to Azure Active Directory. + +There are some caveats with this approach, these mainly being: + +- Any permissions granted to this identity will also be accessible to all containers running inside the Kubernetes cluster. +- Using AKS extensions like `Kube Dashboard`, `Virtual Node`, or `HTTP Application Routing` (see full list [here](https://docs.microsoft.com/en-us/azure/aks/use-managed-identity#summary-of-managed-identities)) will create additional identities that are assigned to your node pools. If your node pools have more than one identity assigned, you will need to specify either `clientID` or `resourceID` to select the correct one. + +To set this up, firstly you will need to retrieve the identity that the kubelet is using by querying the AKS cluster. This can then be used to create the appropriate permissions in the DNS zone. + +- Example commands using `azure-cli`: + +```bash +# Get AKS Kubelet Identity +PRINCIPAL_ID=$(az aks show -n $CLUSTERNAME -g $CLUSTER_GROUP --query "identityProfile.kubeletidentity.objectId" -o tsv) + +# Get existing DNS Zone Id +ZONE_ID=$(az network dns zone show --name $ZONE_NAME --resource-group $ZONE_GROUP --query "id" -o tsv) + +# Create role assignment +az role assignment create --role "DNS Zone Contributor" --assignee $PRINCIPAL_ID --scope $ZONE_ID +``` + +- Example terraform: + +```terraform +variable dns_zone_id {} + +# Creating the AKS cluster, abbreviated. +resource "azurerm_kubernetes_cluster" "cluster" { + ... + # Creates Identity associated to kubelet + identity { + type = "SystemAssigned" + } + ... +} + +resource "azurerm_role_assignment" "dns_contributor" { + scope = var.dns_zone_id + role_definition_name = "DNS Zone Contributor" + principal_id = azurerm_kubernetes_cluster.cluster.kubelet_identity[0].object_id + skip_service_principal_aad_check = true # Allows skipping propagation of identity to ensure assignment succeeds. +} +``` + +Then when creating the cert-manager issuer we need to specify the `hostedZoneName`, `resourceGroupName` and `subscriptionID` fields for the DNS Zone. + +We also need to specify `managedIdentity.clientID` or `managedIdentity.resourceID` if multiple managed identities are assigned to the node pools. + +The value for `managedIdentity.clientID` can be fetched by running this command: + +```bash +az aks show -n $CLUSTERNAME -g $CLUSTER_GROUP --query "identityProfile.kubeletidentity.clientId" -o tsv +``` + +Example below: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + azureDNS: + subscriptionID: AZURE_SUBSCRIPTION_ID + resourceGroupName: AZURE_DNS_ZONE_RESOURCE_GROUP + hostedZoneName: AZURE_DNS_ZONE + # Azure Cloud Environment, default to AzurePublicCloud + environment: AzurePublicCloud + # optional, only required if node pools have more than 1 managed identity assigned + managedIdentity: + # client id of the node pool managed identity (can not be set at the same time as resourceID) + clientID: YOUR_MANAGED_IDENTITY_CLIENT_ID + # resource id of the managed identity (can not be set at the same time as clientID) + # resourceID: YOUR_MANAGED_IDENTITY_RESOURCE_ID +``` + +## Service Principal + +Configuring the AzureDNS DNS01 Challenge for a Kubernetes cluster requires +creating a service principal in Azure. + +To create the service principal you can use the following script (requires +`azure-cli` and `jq`): + +```bash +# Choose a name for the service principal that contacts azure DNS to present +# the challenge. +$ AZURE_CERT_MANAGER_NEW_SP_NAME=NEW_SERVICE_PRINCIPAL_NAME +# This is the name of the resource group that you have your dns zone in. +$ AZURE_DNS_ZONE_RESOURCE_GROUP=AZURE_DNS_ZONE_RESOURCE_GROUP +# The DNS zone name. It should be something like domain.com or sub.domain.com. +$ AZURE_DNS_ZONE=AZURE_DNS_ZONE + +$ DNS_SP=$(az ad sp create-for-rbac --name $AZURE_CERT_MANAGER_NEW_SP_NAME --output json) +$ AZURE_CERT_MANAGER_SP_APP_ID=$(echo $DNS_SP | jq -r '.appId') +$ AZURE_CERT_MANAGER_SP_PASSWORD=$(echo $DNS_SP | jq -r '.password') +$ AZURE_TENANT_ID=$(echo $DNS_SP | jq -r '.tenant') +$ AZURE_SUBSCRIPTION_ID=$(az account show --output json | jq -r '.id') +``` + +For security purposes, it is appropriate to utilize RBAC to ensure that you +properly maintain access control to your resources in Azure. The service +principal that is generated by this tutorial has fine-grained access to ONLY the +DNS Zone in the specific resource group specified. It requires this permission +so that it can read/write the \_acme\_challenge TXT records to the zone. + +Lower the Permissions of the service principal. + +```bash +$ az role assignment delete --assignee $AZURE_CERT_MANAGER_SP_APP_ID --role Contributor +``` + +Give Access to DNS Zone. + +```bash +$ DNS_ID=$(az network dns zone show --name $AZURE_DNS_ZONE --resource-group $AZURE_DNS_ZONE_RESOURCE_GROUP --query "id" --output tsv) +$ az role assignment create --assignee $AZURE_CERT_MANAGER_SP_APP_ID --role "DNS Zone Contributor" --scope $DNS_ID +``` + +Check Permissions. As the result of the following command, we would like to see just one object in the permissions array with "DNS Zone Contributor" role. + +```bash +$ az role assignment list --all --assignee $AZURE_CERT_MANAGER_SP_APP_ID +``` + +A secret containing service principal password should be created on Kubernetes to facilitate presenting the challenge to Azure DNS. You can create the secret with the following command: + +```bash +$ kubectl create secret generic azuredns-config --from-literal=client-secret=$AZURE_CERT_MANAGER_SP_PASSWORD +``` + +Get the variables for configuring the issuer. + +```bash +$ echo "AZURE_CERT_MANAGER_SP_APP_ID: $AZURE_CERT_MANAGER_SP_APP_ID" +$ echo "AZURE_CERT_MANAGER_SP_PASSWORD: $AZURE_CERT_MANAGER_SP_PASSWORD" +$ echo "AZURE_SUBSCRIPTION_ID: $AZURE_SUBSCRIPTION_ID" +$ echo "AZURE_TENANT_ID: $AZURE_TENANT_ID" +$ echo "AZURE_DNS_ZONE: $AZURE_DNS_ZONE" +$ echo "AZURE_DNS_ZONE_RESOURCE_GROUP: $AZURE_DNS_ZONE_RESOURCE_GROUP" +``` + +To configure the issuer, substitute the capital cased variables with the values +from the previous script. You can get the subscription id from the Azure portal. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + azureDNS: + clientID: AZURE_CERT_MANAGER_SP_APP_ID + clientSecretSecretRef: + # The following is the secret we created in Kubernetes. Issuer will use this to present challenge to Azure DNS. + name: azuredns-config + key: client-secret + subscriptionID: AZURE_SUBSCRIPTION_ID + tenantID: AZURE_TENANT_ID + resourceGroupName: AZURE_DNS_ZONE_RESOURCE_GROUP + hostedZoneName: AZURE_DNS_ZONE + # Azure Cloud Environment, default to AzurePublicCloud + environment: AzurePublicCloud +``` diff --git a/content/v1.15-docs/configuration/acme/dns01/cloudflare.md b/content/v1.15-docs/configuration/acme/dns01/cloudflare.md new file mode 100644 index 0000000000..b3f4ded449 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/cloudflare.md @@ -0,0 +1,108 @@ +--- +title: Cloudflare +description: 'cert-manager configuration: ACME DNS-01 challenges using Cloudflare DNS' +--- + +To use Cloudflare, you may use one of two types of tokens. **API Tokens** allow application-scoped keys bound to specific zones and permissions, while **API Keys** are globally-scoped keys that carry the same permissions as your account. + +**API Tokens** are recommended for higher security, since they have more restrictive permissions and are more easily revocable. + +## API Tokens + +Tokens can be created at **User Profile > API Tokens > API Tokens**. The following settings are recommended: + +- Permissions: + - `Zone - DNS - Edit` + - `Zone - Zone - Read` +- Zone Resources: + - `Include - All Zones` + +To create a new `Issuer`, first make a Kubernetes secret containing your new API token: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: cloudflare-api-token-secret +type: Opaque +stringData: + api-token: +``` + +Then in your `Issuer` manifest: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + cloudflare: + apiTokenSecretRef: + name: cloudflare-api-token-secret + key: api-token +``` + +## API Keys + +API keys can be retrieved at **User Profile > API Tokens > API Keys > Global API Key > View**. + +To create a new `Issuer`, first make a Kubernetes secret containing your API key: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: cloudflare-api-key-secret +type: Opaque +stringData: + api-key: +``` + +Then in your `Issuer` manifest: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + cloudflare: + email: my-cloudflare-acc@example.com + apiKeySecretRef: + name: cloudflare-api-key-secret + key: api-key +``` + +## Troubleshooting + +### Actor `com.cloudflare.api.token.xxxx` requires permission `com.cloudflare.api.account.zone.list` to list zones +If you get the error that your token does not have the correct permission to list zones there can be 2 causes. +1. The token lacks the `Zone - Zone - Read` permission +2. cert-manager identified the wrong zone name for the domain due to DNS issues. + +In the case of the 2nd issue you will see an error like below: +``` +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Started 6s cert-manager Challenge scheduled for processing + Warning PresentError 3s (x2 over 3s) cert-manager Error presenting challenge: Cloudflare API Error for GET "/zones?name=" + Error: 0: Actor 'com.cloudflare.api.token.xxxx' requires permission 'com.cloudflare.api.account.zone.list' to list zones +``` + +In this case we recommend [changing your DNS01 self-check nameservers](./README.md#setting-nameservers-for-dns01-self-check). + +## `Cloudflare API error for POST "/zones//dns_records` generic error + +You might be hitting this as Cloudflare blocks the use of the API to update DNS records for the following TLDs: `.cf`, `.ga`, `.gq`, `.ml` and `.tk`. +This is discussed in the [Cloudflare Community](https://community.cloudflare.com/t/unable-to-update-ddns-using-api-for-some-tlds/167228). +We recommend using an alternative DNS provider when using these TLDs. \ No newline at end of file diff --git a/content/v1.15-docs/configuration/acme/dns01/digitalocean.md b/content/v1.15-docs/configuration/acme/dns01/digitalocean.md new file mode 100644 index 0000000000..4d6c155863 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/digitalocean.md @@ -0,0 +1,46 @@ +--- +title: DigitalOcean +description: 'cert-manager configuration: ACME DNS-01 challenges using DigitalOcean DNS' +--- + +This provider uses a Kubernetes `Secret` resource to work. In the following +example, the `Secret` will have to be named `digitalocean-dns` and have a +sub-key `access-token` with the token in it. For example: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: digitalocean-dns +data: + # insert your DO access token here + access-token: "base64 encoded access-token here" + ``` + +The access token must have write access. + +To create a Personal Access Token, see [DigitalOcean documentation](https://docs.digitalocean.com/reference/api/create-personal-access-token/). + +Handy direct link: https://cloud.digitalocean.com/account/api/tokens/new + +To encode your access token into base64, you can use the following + +```bash +echo -n 'your-access-token' | base64 +``` + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + digitalocean: + tokenSecretRef: + name: digitalocean-dns + key: access-token +``` \ No newline at end of file diff --git a/content/v1.15-docs/configuration/acme/dns01/google.md b/content/v1.15-docs/configuration/acme/dns01/google.md new file mode 100644 index 0000000000..b9b6db839a --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/google.md @@ -0,0 +1,243 @@ +--- +title: Google CloudDNS +description: 'cert-manager configuration: ACME DNS-01 challenges using Google CloudDNS' +--- + +This guide explains how to set up an `Issuer`, or `ClusterIssuer`, to use Google +CloudDNS to solve DNS01 ACME challenges. It's advised you read the [DNS01 +Challenge Provider](./README.md) page first for a more general understanding of +how cert-manager handles DNS01 challenges. + +This guide assumes that your cluster is hosted on Google Cloud Platform (GCP) +and that you already have a domain set up with CloudDNS. + +You'll need to be using a **Public DNS Zone**, so that the ACME challenge checker +is able to access the DNS records that cert-manager will create. + +## Set up a Service Account + +cert-manager needs to be able to add records to CloudDNS in order to solve the +DNS01 challenge. To enable this, a GCP service account must be created with the +`dns.admin` role. + +> Note: For this guide the `gcloud` command will be used to set up the service +> account. Ensure that `gcloud` is using the correct project and zone before +> entering the commands. These steps could also be completed using the Cloud +> Console. + +```bash +PROJECT_ID=myproject-id +gcloud iam service-accounts create dns01-solver --display-name "dns01-solver" +``` + +In the command above, replace `myproject-id` with the ID of your project. + +```bash +gcloud projects add-iam-policy-binding $PROJECT_ID \ + --member serviceAccount:dns01-solver@$PROJECT_ID.iam.gserviceaccount.com \ + --role roles/dns.admin +``` + +> **Note**: The use of the `dns.admin` role in this example role is for convenience. +> If you want to ensure cert-manager runs under a least privilege service account, +> you will need to create a custom role with the following permissions: +> +> * `dns.resourceRecordSets.*` +> * `dns.changes.*` +> * `dns.managedZones.list` +> +> In case you do not use the `dns.admin` role, you will also need to make sure that the Service Account used by your GKE cluster (e.g. the Compute Engine default service account) has the `https://www.googleapis.com/auth/cloud-platform` access scope assigned to it. See [Access scopes in GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/access-scopes). +## Use Static Credentials + +Follow the instructions in the following sections to deploy cert-manager using +static credentials for the service account you created. You should rotate these +credentials periodically. + +### Create a Service Account Secret + +To access this service account, cert-manager uses a key stored in a Kubernetes +`Secret`. First, create a key for the service account and download it as a JSON +file, then create a `Secret` from this file. + +Keep the key file safe and do not share it, as it could be used to gain access +access to your cloud resources. The key file can be deleted once it has been +used to generate the `Secret`. + +If you did not create the service account `dns01-solver` before, you need to +create it first. + +```bash +gcloud iam service-accounts create dns01-solver +``` + +Replace instances of `$PROJECT_ID` with the ID of your project. +```bash +gcloud iam service-accounts keys create key.json \ + --iam-account dns01-solver@$PROJECT_ID.iam.gserviceaccount.com +kubectl create secret generic clouddns-dns01-solver-svc-acct \ + --from-file=key.json +``` + +> Note: If you have already added the `Secret` but get an error: `...due to +> error processing: error getting clouddns service account: secret "XXX" not +> found`, the `Secret` may be in the wrong namespace. If you're configuring a +> `ClusterIssuer`, move the `Secret` to the `Cluster Resource Namespace` which +> is `cert-manager` by default. If you're configuring an `Issuer`, the `Secret` +> should be stored in the same namespace as the `Issuer` resource. + +### Create an Issuer That Uses CloudDNS + +Next, create an `Issuer` (or `ClusterIssuer`) with a `cloudDNS` provider. An +example `Issuer` manifest can be seen below with annotations. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + cloudDNS: + # The ID of the GCP project + project: $PROJECT_ID + # This is the secret used to access the service account + serviceAccountSecretRef: + name: clouddns-dns01-solver-svc-acct + key: key.json +``` + +For more information about `Issuers` and `ClusterIssuers`, see +[Configuration](../../README.md). + +Once an `Issuer` (or `ClusterIssuer`) has been created successfully, a +`Certificate` can then be added to verify that everything works. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com + namespace: default +spec: + secretName: example-com-tls + issuerRef: + # The issuer created previously + name: example-issuer + dnsNames: + - example.com + - www.example.com +``` + +For more details about `Certificates`, see [Usage](../../../usage/README.md). + +## GKE Workload Identity + +If you are deploying cert-manager into a [Google Container Engine (GKE) +cluster](https://cloud.google.com/kubernetes-engine/) with workload identity +enabled, you can leverage workload identity to avoid creating and managing +static service account credentials. The [workload identity +how-to](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) +provides more detail on how workload identity functions, but briefly workload +identity allows you to link a Google service accounts (GSA) to Kubernetes +service accounts (KSA). This GSA/KSA linking is two-way, i.e., you must +establish the link in GCP _and_ Kubernetes. Once configured, workload identity +allows Kubernetes pods running under a KSA to access the GCP APIs with the +permissions of the linked GSA. The workload identity how-to also provides +detailed instructions on how to enable workload identity in your GKE cluster. +The instructions in the following sections assume you are deploying cert-manager +to a GKE cluster with workload identity already enabled. + +### Enable Ambient Credential Usage + +'Ambient Credentials' are credentials drawn from the environment, metadata services, or local files which are not explicitly configured in the ClusterIssuer API object. When this flag is enabled Cert-Manager will access the GKE Metadata server for credentials. By default this is enabled for ClusterIssuer resources but is disabled for Issuer resources. To enable it for Issuer resources set the `--issuer-ambient-credentials` flag. + +### Link KSA to GSA in GCP + +The cert-manager component that needs to modify DNS records is the pod created +as part of the cert-manager deployment. The [standard methods for deploying +cert-manager to Kubernetes](../../../installation/README.md) create the +cert-manager deployment in the cert-manager namespace and its pod spec specifies +it runs under the cert-manager service account. To link the GSA you created +above to the cert-manager KSA in the cert-manager namespace in your GKE cluster, +run the following command. + +```bash +gcloud iam service-accounts add-iam-policy-binding \ + --role roles/iam.workloadIdentityUser \ + --member "serviceAccount:$PROJECT_ID.svc.id.goog[cert-manager/cert-manager]" \ + dns01-solver@$PROJECT_ID.iam.gserviceaccount.com +``` + +If your cert-manager pods are running under a different service account, replace +`goog[cert-manager/cert-manager]` with `goog[NAMESPACE/SERVICE_ACCOUNT]`, where +`NAMESPACE` is the namespace of the service account and `SERVICE_ACCOUNT` is the +name of the service account. + +### Link KSA to GSA in Kubernetes + +After deploying cert-manager, add the proper workload identity annotation to the +cert-manager service account. + +```bash +kubectl annotate serviceaccount --namespace=cert-manager cert-manager \ + "iam.gke.io/gcp-service-account=dns01-solver@$PROJECT_ID.iam.gserviceaccount.com" +``` + +Again, if your cert-manager pods are running under a different service account, +replace `--namespace=cert-manager cert-manager` with `--namespace=NAMESPACE +SERVICE_ACCOUNT`, where `NAMESPACE` is the namespace of the service account and +`SERVICE_ACCOUNT` is the name of the service account. + +If you are deploying cert-manager using its helm chart, you can use the +`serviceAccount.annotations` configuration parameter to add the above workload +identity annotation to the cert-manager KSA. + +### Create an Issuer That Uses CloudDNS + +Next, create an `Issuer` (or `ClusterIssuer`) with a `clouddns` provider. An +example `Issuer` manifest can be seen below with annotations. Note that the +issuer does not include a `serviceAccountSecretRef` property. Excluding this +instructs cert-manager to use the default credentials provided by GKE workload +identity. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + cloudDNS: + # The ID of the GCP project + project: $PROJECT_ID +``` + +For more information about `Issuers` and `ClusterIssuers`, see +[Configuration](../../README.md). + +Once an `Issuer` (or `ClusterIssuer`) has been created successfully, a +`Certificate` can then be added to verify that everything works. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com + namespace: default +spec: + secretName: example-com-tls + issuerRef: + # The issuer created previously + name: example-issuer + dnsNames: + - example.com + - www.example.com +``` + +For more details about `Certificates`, see [Usage](../../../usage/README.md). diff --git a/content/v1.15-docs/configuration/acme/dns01/rfc2136.md b/content/v1.15-docs/configuration/acme/dns01/rfc2136.md new file mode 100644 index 0000000000..86e9dd32df --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/rfc2136.md @@ -0,0 +1,207 @@ +--- +title: RFC-2136 +description: 'cert-manager configuration: ACME DNS-01 challenges using RFC2136-compliant DNS providers' +--- + +The goal of this document is to provide a configuration overview of the various +facilities required to deploy cert-manager against a RFC2136 compliant DNS +server such as BIND `named`. This capability is also commonly known as “dynamic +DNS”. + +Unlike the peer of other cert-manager DNS integrations, `named` is a bit of a +“Swiss Army Knife” of domain name servers. Over the years, it has been highly +optimized to provide maximal vertical scalability for a single node, as well as +horizontal scalability with service provider interfaces. This flexibility makes +it impossible to go into every possible `named` deployment that a user may run +in to though. Instead, this document will try to make sure your server is ready +to accept requests from cert-manager using command line tools, then get on to +the making the two work together. + +## Transaction Signatures ⇒ TSIG + +Dynamic DNS updates are essentially server queries which otherwise might return +resource records (RRs). Since DNS servers are commonly exposed to the public +internet, being able to push an unauthenticated update to any server that +responds to queries would be immediately untenable. + +In the eyes of the `named` architects, the generic solution to this problem +space was twofold. The first is to require manual enablement of updates at a +zone level, such as `example.com`. In a naive network, there is no requirement +that zone updates have any security to them, and clients can be configured such +that they can provide updates without any authentication. An example of where +this is useful is for machines booting using DHCP, in this case the machines +know about themselves and the DNS server can be configured to accept updates +when they come from the address being configured. + +This clearly has limitations in situations such as cert-manager and the DNS01 +challenge. In this environment, a TXT RR must be created after coordination with +the ACME server. After negotiating with the ACME server, a the TXT RR that is +published on the domain validates that the domain is legitimately engaged with +the process of creating a certificate for it. In the bigger picture of DNS, this +means that an arbitrary actor (cert-manager, in this case) must be able to add +one of these KV mappings to the domain and delete it after the certificate has +been issued. `cert-manager` does not have a convenient physical characteristic +such as a DHCP allocation to validate it's requests. + +For cases like this, we need to be able to sign a request that is being sent to +the DNS server. We do that through TSIGs, or Transaction SIGnatures. + +### Configuration Step 1 - Set up your DNS server for secure dynamic updates + +There are many excellent tutorials on the net that walk through +preparing a basic `named` server for dynamic updates: + +- https://www.cyberciti.biz/faq/unix-linux-bind-named-configuring-tsig/ +- https://tomthorp.me/blog/using-tsig-enable-secure-zone-transfers-between-bind-9x-servers + +More complex `name` deployments will not use text files, but rather may use LDAP +or SQL for a database for resource records. An additional wrinkle is metadata +configuration, such as for zone metadata like enabling dynamic updates or access +control lists (ACLs) for a zone. There are too many configurations to go into +here, but you should be able to find the documentation to do so. + +Whatever your deployment is, the goal at this stage has nothing to do with +cert-manager and everything to do with a tool called `nsupdate` generating +updates signed with TSIG. Once this is out of the way, you can attack the +cert-manager configuration with far greater confidence. + +#### Using `nsupdate` + +Most paths to configuring BIND `named` will go through using `dnssec-keygen`. +This command-line tool generates a named private key that is used for signing +TSIG requests. When a request is signed, both the signature and the name of the +private key are attached to the request in an unencrypted form. In this manner, +when the request is received, the name of the private key can be used to by the +recipient to find the private key itself, build a new signature with it, and +compare the two for acceptance. + +Since there are dozens of ways to have your `named` server misconfigured, we’ll +use `nsupdate` to test that the server behaves as expected before we get there. +`https://debian-administration.org/article/591/Using_the_dynamic_DNS_editor_nsupdate` +is a solid breakdown of how to use the tool. + +To get started, we’ll simply run `nsupdate -k ` where `keyID` is the value +returned from `dnssec-keygen`. This will read the key from disk and provide a +command prompt to issue commands. In general, we want to write a simple TXT RR +and make sure we can delete it. + +```bash +$ nsupdate -k +update add www1.example.com 60 txt testing +send +… test here with `nslookup` +update delete www1.example.com txt +send +… test here with `nslookup` +``` + +Any failures to write, read or delete the record will mean that cert-manager +will not be able to do so either, no matter how well it is configured. + +### Configuration Step 2 - Set up cert-manager + +Now we get to the fun stuff, seeing everything work. Remember that we need to +set up the ACME DNS01 issuer and challenge mechanism as well as the `rfc2136` +provider. Since the documentation covers the other parts sufficiently, let’s +focus on the provider here. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + rfc2136: + nameserver:
+ tsigKeyName: + tsigAlgorithm: HMACSHA512 // should be matched to the algo you chose in `dnssec-keygen` + tsigSecretSecretRef: + name: + key: +``` + +For example: + +```yaml + rfc2136: + nameserver: 1.2.3.4:53 + tsigKeyName: example-com-secret + tsigAlgorithm: HMACSHA512 + tsigSecretSecretRef: + name: tsig-secret + key: tsig-secret-key +``` + +For this example configuration, we’ll need the following two commands. The +first, on your `named` server generates the key. Note how `example-com-secret` +is both in the `tsigKeyName` above and the `dnssec-keygen` command that follows. + +```bash +$ dnssec-keygen -r /dev/urandom -a HMAC-SHA512 -b 512 -n HOST example-com-secret +``` + +Also note how the `tsigAlgorithm` is provided in both the configuration and the +`keygen` command. They are listed at +`https://github.com/miekg/dns/blob/v1.0.12/tsig.go#L18-L23`. + +The second bit of configuration you need on the Kubernetes side is to create a +secret. Pulling the secret key string from the `.private` file generated +above, use the secret in the placeholder below: + +```bash +$ kubectl -n cert-manager create secret generic tsig-secret --from-literal=tsig-secret-key= +``` + +Note how the `tsig-secret` and `tsig-secret-key` match the configuration in the +`tsigSecretSecretRef` above. + +## Rate Limits + +The `rfc2136` provider waits until *all* nameservers to in your domain's SOA RR +respond with the same result before it contacts Let's Encrypt to complete the +challenge process. This is because the challenge server contacts a +non-authoritative DNS server that does a recursive query (a query for records it +does not maintain locally). If the servers in the SOA do not contain the correct +values, it's likely that the non-authoritative server will have bad information +as well, causing the request to go against rate limits and eventually locking +the process out. + +This process is in place to protect users from server misconfiguration creating +a more subtle lockout that persists after the server configuration has been +repaired. + +As documented elsewhere, it is prudent to fully debug configurations using the +ACME staging servers before using the production servers. The staging servers +have less aggressive rate limits, but the certificates they issue are not signed +with a root certificate trusted by browsers. + +## What’s next? + +This configuration so far will actually do nothing. You still have to request a +certificate as described [here](../../../usage/README.md). Once a certificate is +requested, the provider will begin processing the request. + +## Troubleshooting + +- Be sure that you have fully tested the DNS server updates using `nsupdate` + first. Ideally, this is done from a pod in the same namespace as the `rfc2136` + provider to ensure there are no firewall issues. +- The logs for the `cert-manager` pod are your friend. Additional logs can be + generated by adding the `--v=5` argument to the container launch. +- The TSIG key is encoded with `base64`, but the Kubernetes API server also + expects that key literals will be decoded before they are stored. In some + cases, a key must be double-encoded. (If you've tested using `nsupdate`, it's + pretty easy to spot when you are running into this.) +- Pay attention to the refresh time of the zone you are working with. For zones + with low traffic, it will not make a significant difference to reduce the + refresh time down to about five minutes while getting initial certificates. + Once the process is working, the beauty of `cert-manager` is it doesn't matter + if a renewal takes hours due to refresh times, it's all automated! +- Compared to the other providers that often use REST APIs to modify DNS RRs, + this provider can take a little longer. You can `watch kubectl certificate + yourcert` to get a display of what's going on. It's not uncommon for the process + to take five minutes in total. \ No newline at end of file diff --git a/content/v1.15-docs/configuration/acme/dns01/route53.md b/content/v1.15-docs/configuration/acme/dns01/route53.md new file mode 100644 index 0000000000..296ac1f197 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/route53.md @@ -0,0 +1,388 @@ +--- +title: Route53 +description: 'cert-manager configuration: ACME DNS-01 challenges using Amazon AWS Route53 DNS' +--- + +This guide explains how to set up an `Issuer`, or `ClusterIssuer`, to use Amazon +Route53 to solve DNS01 ACME challenges. It's advised you read the [DNS01 +Challenge Provider](./README.md) page first for a more general understanding of +how cert-manager handles DNS01 challenges. + +> ℹ️ This guide assumes that your cluster is hosted on Amazon Web Services +> (AWS) and that you already have a hosted zone in Route53. +> +> 📖 Read +> [Tutorial: Deploy cert-manager on Amazon Elastic Kubernetes (EKS) and use Let's Encrypt to sign a certificate for an HTTPS website](../../../tutorials/getting-started-aws-letsencrypt/README.md), +> which contains end-to-end instructions for those who are new to cert-manager and AWS. + +## Set up an IAM Role + +cert-manager needs to be able to add records to Route53 in order to solve the +DNS01 challenge. To enable this, create a IAM policy with the following +permissions: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "route53:GetChange", + "Resource": "arn:aws:route53:::change/*" + }, + { + "Effect": "Allow", + "Action": [ + "route53:ChangeResourceRecordSets", + "route53:ListResourceRecordSets" + ], + "Resource": "arn:aws:route53:::hostedzone/*" + }, + { + "Effect": "Allow", + "Action": "route53:ListHostedZonesByName", + "Resource": "*" + } + ] +} +``` + +> Note: The `route53:ListHostedZonesByName` statement can be removed if you +> specify the (optional) `hostedZoneID`. You can further tighten the policy by +> limiting the hosted zone that cert-manager has access to (e.g. +> `arn:aws:route53:::hostedzone/DIKER8JEXAMPLE`). + +## Credentials + +You have two options for the set up - either create a user or a role and attach +that policy from above. Using a role is considered best practice because you do +not have to store permanent credentials in a secret. + +cert-manager supports two ways of specifying credentials: + +- explicit by providing an `accessKeyID` or an `accessKeyIDSecretRef`, and a `secretAccessKeySecretRef` +- or implicit (using [metadata + service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) + or [environment variables or credentials + file](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials). + +cert-manager also supports specifying a `role` to enable cross-account access +and/or limit the access of cert-manager. Integration with +[`kiam`](https://github.com/uswitch/kiam) and +[`kube2iam`](https://github.com/jtblin/kube2iam) should work out of the box. + + +## Cross Account Access + +Example: Account Y manages Route53 DNS Zones. Now you want cert-manager running in Account X (or many other accounts) to be able to manage records in Route53 zones hosted in Account Y. + +First, create a role with the permissions policy above (let's call the role `dns-manager`) +in Account Y, and attach a trust relationship like the one below. + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::XXXXXXXXXXX:role/cert-manager" + }, + "Action": "sts:AssumeRole" + } + ] +} +``` + +Bear in mind, that you won't be able to define this policy until `cert-manager` role on account Y is created. If you are setting this up using a configuration language, you may want to define principal as: + +```json +"Principal": { + "AWS": "XXXXXXXXXXX" + } +``` +And restrict it, in a future step, after all the roles are created. + +This allows the role `cert-manager` in Account X to assume the `dns-manager` role in Account Y to manage the Route53 DNS zones in Account Y. For more information visit the [official +documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html). + +Second, create the cert-manager role in Account X; this will be used as a credentials source for the cert-manager pods running in Account X. Attach to the role the following **permissions** policy: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Resource": "arn:aws:iam::YYYYYYYYYYYY:role/dns-manager", + "Action": "sts:AssumeRole" + } + ] +} +``` + +And the following trust relationship (Add AWS `Service`s as needed): + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] +} +``` + +## Creating an Issuer (or `ClusterIssuer`) + +Here is an example configuration for a `ClusterIssuer`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-prod +spec: + acme: + ... + solvers: + + # example: cross-account zone management for example.com + # this solver uses ambient credentials (i.e. inferred from the environment or EC2 Metadata Service) + # to assume a role in a different account + - selector: + dnsZones: + - "example.com" + dns01: + route53: + region: us-east-1 + hostedZoneID: DIKER8JEXAMPLE # optional, see policy above + role: arn:aws:iam::YYYYYYYYYYYY:role/dns-manager + + # this solver handles example.org challenges + # and uses explicit credentials + - selector: + dnsZones: + - "example.org" + dns01: + route53: + region: eu-central-1 + # The AWS access key ID can be specified using the literal accessKeyID parameter + # or retrieved from a secret using the accessKeyIDSecretRef + # If using accessKeyID, omit the accessKeyIDSecretRef parameter and vice-versa + accessKeyID: AKIAIOSFODNN7EXAMPLE + accessKeyIDSecretRef: + name: prod-route53-credentials-secret + key: access-key-id + secretAccessKeySecretRef: + name: prod-route53-credentials-secret + key: secret-access-key + # you can also assume a role with these credentials + role: arn:aws:iam::YYYYYYYYYYYY:role/dns-manager +``` + +Note that, as mentioned above, the pod is using `arn:aws:iam::XXXXXXXXXXX:role/cert-manager` as a credentials source in Account X, but the `ClusterIssuer` ultimately assumes the `arn:aws:iam::YYYYYYYYYYYY:role/dns-manager` role to actually make changes in Route53 zones located in Account Y. + +## EKS IAM Role for Service Accounts (IRSA) + +While [`kiam`](https://github.com/uswitch/kiam) / [`kube2iam`](https://github.com/jtblin/kube2iam) work directly with cert-manager, some special attention is needed for using the [IAM Roles for Service Accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) feature available on EKS. + +This feature uses Kubernetes `ServiceAccount` tokens to authenticate with AWS using the [API_AssumeRoleWithWebIdentity](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html). + +> **Note**: For using IRSA with cert-manager you must first enable the feature for your cluster. You can do this by +> following the [official documentation(https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html). + +Because `ServiceAccount` tokens are used to authenticate there are two modes of operation, you can either use cert-manager's own `ServiceAccount` to authenticate or you can reference your own `ServiceAccount` within your `Issuer`/`ClusterIssuer` config. Each option is described below. + +### Using the cert-manager ServiceAccount + +In this configuration an IAM role is mapped to the cert-manager `ServiceAccount` allowing it to authenticate with AWS. The IAM role you map to the `ServiceAccount` will need permissions on any and all Route53 zones cert-manager will be using. + +#### IAM role trust policy + +The cert-manager role needs the following trust relationship attached to the role in order to use the IRSA method. Replace the following: + +- `` with the AWS account ID of the EKS cluster. +- `` with the region where the EKS cluster is located. +- `` with the hash in the EKS API URL; this will be a random 32 character hex string (example: `45DABD88EEE3A227AF0FA468BE4EF0B5`) +- `` with the namespace where cert-manager is running. +- `` with the name of the `ServiceAccount` object created by cert-manager. + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sts:AssumeRoleWithWebIdentity", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Condition": { + "StringEquals": { + "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" + } + } + } + ] +} +``` + +**Note:** If you're following the Cross Account example above, this trust policy is attached to the cert-manager role in Account X with ARN `arn:aws:iam::XXXXXXXXXXX:role/cert-manager`. The permissions policy is the same as above. + +#### Service annotation + +Annotate the `ServiceAccount` created by cert-manager: + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXX:role/cert-manager +``` + +You will also need to modify the cert-manager `Deployment` with the correct file system permissions, so the `ServiceAccount` token can be read. + +```yaml +spec: + template: + spec: + securityContext: + fsGroup: 1001 +``` + +The cert-manager Helm chart provides a variable for injecting annotations into cert-manager's `ServiceAccount` and `Deployment` object like so: + +```yaml +serviceAccount: + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXX:role/cert-manager +securityContext: + fsGroup: 1001 +``` + +**Note:** If you're following the Cross Account example above, modify the `ClusterIssuer` in the same way as above with the role from Account Y. + +### Referencing your own ServiceAccount within Issuer/ClusterIssuer config + +In this configuration you can reference your own `ServiceAccounts` within your `Issuer`/`ClusterIssuer` and cert-manager will issue itself temporary credentials using these `ServiceAccounts`. Because each issuer can reference a different `ServiceAccount` you can lock down permissions much more, with each `ServiceAccount` mapped to an IAM role that only has permission on the zones it needs for that particular issuer. + + +#### Creating a ServiceAccount + +In order to reference a `ServiceAccount` it must first exist. Unlike normal IRSA the `eks.amazonaws.com/role-arn` annotation is not required, however you may wish to set it as a reference. + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: + annotation: + eks.amazonaws.com/role-arn: +``` + +#### IAM role trust policy + +For every `ServiceAccount` you want to use for AWS authentication you must first set up a trust policy. Replace the following: + +- `` with the AWS account ID of the EKS cluster. +- `` with the region where the EKS cluster is located. +- `` with the hash in the EKS API URL; this will be a random 32 character hex string (example: `45DABD88EEE3A227AF0FA468BE4EF0B5`) +- `` with the namespace of the `ServiceAccount` object. +- `` with the name of the `ServiceAccount` object. + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sts:AssumeRoleWithWebIdentity", + "Principal": { + "Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/" + }, + "Condition": { + "StringEquals": { + "oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount::" + } + } + } + ] +} +``` + +**Note:** If you're following the Cross Account example above, this trust policy is attached to the cert-manager role in Account X with ARN `arn:aws:iam::XXXXXXXXXXX:role/cert-manager`. The permissions policy is the same as above. + +#### RBAC + +In order to allow cert-manager to issue a token using your `ServiceAccount` you must deploy some RBAC to the cluster. Replace the following: + +- `` name of the `ServiceAccount` object. +- `` namespace of the `ServiceAccount` object. +- `` name of cert-managers `ServiceAccount` object, as created during cert-manager installation. +- `` namespace that cert-manager is deployed into. + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: -tokenrequest + namespace: +rules: + - apiGroups: [''] + resources: ['serviceaccounts/token'] + resourceNames: [''] + verbs: ['create'] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: cert-manager--tokenrequest + namespace: +subjects: + - kind: ServiceAccount + name: + namespace: +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: -tokenrequest +``` + +#### Issuer/ClusterIssuer config + +Once you have completed the above you should have: +- An IAM role with permissions required to on the Route53 zone. +- A Kubernetes `ServiceAccount`. +- A trust policy to allow the Kubernetes `ServiceAccount` access to your IAM role. +- RBAC to allow cert-manager to issue a token using the Kubernetes `ServiceAccount`. + +You should be ready at this point to configure an Issuer to use the new `ServiceAccount`. You can see example config for this below: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example +spec: + acme: + ... + solvers: + - selector: + dnsZones: + - "example.com" + dns01: + route53: + region: us-east-1 + role: # This must be set so cert-manager what role to attempt to authenticate with + auth: + kubernetes: + serviceAccountRef: + name: # The name of the service account created +``` diff --git a/content/v1.15-docs/configuration/acme/dns01/webhook.md b/content/v1.15-docs/configuration/acme/dns01/webhook.md new file mode 100644 index 0000000000..d9a4339e39 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/dns01/webhook.md @@ -0,0 +1,32 @@ +--- +title: Webhook +description: 'cert-manager configuration: ACME DNS-01 challenges using External Webhook Solvers' +--- + +The webhook `Issuer` is a generic ACME solver. The actual work is done by an +external service. Look at the respective documentation of +[`dns-providers`](../../../contributing/dns-providers.md). + +View more webhook solvers at https://github.com/topics/cert-manager-webhook. + +Here is an example of how webhook providers are to be configured. All `DNS01` +providers will contain their own specific configuration however all require a +`groupName` and `solverName` field. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + ... + solvers: + - dns01: + webhook: + groupName: $WEBHOOK_GROUP_NAME + solverName: $WEBHOOK_SOLVER_NAME + config: + ... + +``` diff --git a/content/v1.15-docs/configuration/acme/http01/README.md b/content/v1.15-docs/configuration/acme/http01/README.md new file mode 100644 index 0000000000..5e7cdccb77 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/http01/README.md @@ -0,0 +1,393 @@ +--- +title: HTTP01 +description: 'cert-manager configuration: ACME HTTP-01 challenges' +--- + +
+ +📌 This page focuses on solving ACME HTTP-01 challenges. If you are looking for +how to automatically create Certificate resources by annotating Ingress or +Gateway resources, see [Securing Ingress Resources](../../../usage/ingress.md) and +[Securing Gateway Resources](../../../usage/gateway.md). + +
+ +cert-manager uses your existing Ingress or Gateway configuration in order to +solve HTTP01 challenges. + + +## Configuring the HTTP01 Ingress solver + +This page contains details on the different options available on the `Issuer` +resource's HTTP01 challenge solver configuration. For more information on +configuring ACME issuers and their API format, read the [ACME Issuers](../README.md) +documentation. + +You can read about how the HTTP01 challenge type works on the [Let's Encrypt +challenge types +page](https://letsencrypt.org/docs/challenge-types/#http-01-challenge). + +Here is an example of a simple `HTTP01` ACME issuer with more options for +configuration below: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: example-issuer +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: example-issuer-account-key + solvers: + - http01: + ingress: + ingressClassName: nginx +``` + +## Options + +The HTTP01 Issuer supports a number of additional options. For full details on +the range of options available, read the [reference +documentation](../../../reference/api-docs.md#acme.cert-manager.io/v1.ACMEChallengeSolverHTTP01). + +### `ingressClassName` + +
+ +📌 The field `ingressClassName` was added in cert-manager 1.12. + +
+ +If the `ingressClassName` field is specified, cert-manager will create new +`Ingress` resources in order to route traffic to the `acmesolver` pods, which +are responsible for responding to ACME challenge validation requests. + +This is the recommended way of configuring the Ingress controller. Most Ingress +controllers support `ingressClassName`, with the notable exception of +ingress-gce (as per the page [Configure Ingress for external load +balancing](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress)). + +### `class` + +If the `class` field is specified, a new Ingress resource with a randomly +generated name will be created in order to solve the challenge. This new +resource will have an annotation with key `kubernetes.io/ingress.class` and +value set to the value of the `class` field. + +This field is only recommended with ingress-gce. ingress-gce [doesn't support the +`ingressClassName` field](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress). + +### `name` + +If the `name` field is specified, cert-manager will edit the named +ingress resource in order to solve HTTP01 challenges. + +This is useful for compatibility with ingress controllers such as `ingress-gce`, +which utilize a unique IP address for each `Ingress` resource created. + +This mode should be avoided when using ingress controllers that expose a single +IP for all ingress resources, as it can create compatibility problems with +certain ingress-controller specific annotations. + +
+ +If `class` and `ingressClassName` are not specified, and `name` is also not +specified, cert-manager will default to create *new* `Ingress` resources but +will **not** set the ingress class on these resources, meaning *all* ingress +controllers installed in your cluster will serve traffic for the challenge +solver, potentially incurring additional cost. + +
+ + +### `serviceType` + +In rare cases it might be not possible/desired to use `NodePort` as type for the +HTTP01 challenge response service, e.g. because of Kubernetes limit +restrictions. To define which Kubernetes service type to use during challenge +response specify the following HTTP01 configuration: + +```yaml + http01: + ingress: + # Valid values are ClusterIP and NodePort + serviceType: ClusterIP +``` + +By default, type `NodePort` will be used when you don't set HTTP01 or when you set +`serviceType` to an empty string. Normally there's no need to change this. + + +### `podTemplate` + +You may wish to change or add to the labels and annotations of solver pods. +These can be configured under the `metadata` field under `podTemplate`. + +Similarly, you can set the `nodeSelector`, tolerations and affinity of solver +pods by configuring under the `spec` field of the `podTemplate`. No other +spec fields can be edited. + +An example of how you could configure the template is as so: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ... +spec: + acme: + server: ... + privateKeySecretRef: + name: ... + solvers: + - http01: + ingress: + podTemplate: + metadata: + labels: + foo: "bar" + env: "prod" + spec: + nodeSelector: + bar: baz +``` + +The added labels and annotations will merge on top of the cert-manager defaults, +overriding entries with the same key. + +No other fields of the `podTemplate` exist. + +### `ingressTemplate` + +It is possible to add labels and annotations to the solver ingress resources. +It can be really useful when you are managing several Ingress Controllers across your cluster and you want to make sure that the right one will pick up and expose the solver (for the upcoming challenge to resolve). +These can be configured under the `metadata` field under `ingressTemplate`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ... +spec: + acme: + server: ... + privateKeySecretRef: + name: ... + solvers: + - http01: + ingress: + ingressTemplate: + metadata: + labels: + foo: "bar" + annotations: + "nginx.ingress.kubernetes.io/whitelist-source-range": "0.0.0.0/0,::/0" + "nginx.org/mergeable-ingress-type": "minion" + "traefik.ingress.kubernetes.io/frontend-entry-points": "http" +``` + +The added labels and annotations will merge on top of the cert-manager defaults, +overriding entries with the same key. + +No other fields of the ingress can be edited. + +## Configuring the HTTP-01 Gateway API solver + +**FEATURE STATE**: cert-manager 1.15 [beta] + +The Gateway and HTTPRoute resources are part of the [Gateway API][gwapi], a set +of CRDs that you install on your Kubernetes cluster that provide various +improvements over the Ingress API. + +[gwapi]: https://gateway-api.sigs.k8s.io + +
+ +📌 This feature requires the installation of the [Gateway API bundle](https://gateway-api.sigs.k8s.io/guides/#installing-a-gateway-controller) and passing an +additional flag to the cert-manager controller. + +To install v1.5.1 Gateway API bundle (Gateway CRDs and webhook), run the following command: + +```sh +kubectl apply -f "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml" +``` + +To enable the feature in cert-manager, turn on the `GatewayAPI` feature gate: + +- If you are using Helm: + + ```sh + helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager \ + --set "extraArgs={--enable-gateway-api}" + ``` + +- If you are using the raw cert-manager manifests, add the following flag to the + cert-manager controller Deployment: + + ```yaml + args: + - --enable-gateway-api + ``` + +The Gateway API CRDs should either be installed before cert-manager starts or +the cert-manager Deployment should be restarted after installing the Gateway API +CRDs. This is important because some of the cert-manager components only perform +the Gateway API check on startup. You can restart cert-manager with the +following command: + +```sh +kubectl rollout restart deployment cert-manager -n cert-manager +``` + +
+ + +
+ +🚧 cert-manager 1.14+ is tested with v1 Kubernetes Gateway API. It should also work +with v1beta1 and v1alpha2 because of resource conversion, but has not been tested with it. +
+ +The Gateway API HTTPRoute HTTP-01 solver creates a temporary HTTPRoute using the +given labels. These labels must match a Gateway that contains a listener on port +80. + +Here is an example of a HTTP-01 ACME Issuer using the Gateway API: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt + namespace: default +spec: + acme: + solvers: + - http01: + gatewayHTTPRoute: + parentRefs: + - name: traefik + namespace: traefik + kind: Gateway +``` + +The Issuer relies on an existing Gateway present on the cluster. cert-manager +does not edit Gateway resources. + +For example, the following Gateway will allow the Issuer to solve the challenge: + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: traefik + namespace: traefik +spec: + gatewayClassName: traefik + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +``` + +In the above example, the Gateway has been specifically created for the purpose +of solving HTTP-01 challenges, but you can also choose to re-use your existing +Gateway, as long as it has a listener on port 80. + +The `labels` on your Issuer may reference a Gateway that is on a separate +namespace, as long as the Gateway's port 80 listener is configured with `from: +All`. Note that the Certificate will still be created on the same namespace as +the Issuer, which means that you won't be able to reference this Secret in the +above-mentioned Gateway. + +When the above Issuer is presented with a Certificate, cert-manager creates the +temporary HTTPRoute. For example, with the following Certificate: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-tls + namespace: default +spec: + issuerRef: + name: letsencrypt + dnsNames: + - example.net +``` + +You will see an HTTPRoute appear: + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: cm-acme-http-solver-gdhvg + namespace: default +spec: + parentRefs: + - name: traefik + namespace: traefik + kind: Gateway + hostnames: + - example.net + rules: + - backendRefs: + - port: 8089 + name: cm-acme-http-solver-gdhvg + weight: 1 + matches: + - path: + type: Exact + value: /.well-known/acme-challenge/YadC4gaAzqEPU1Yea0D2MrzvNRWiBCtUizCtpiRQZqI +``` + +After the Certificate is issued, the HTTPRoute is deleted. + + +### `labels` + +These labels are copied into the temporary HTTPRoute created by cert-manager for +solving the HTTP-01 challenge. These labels must match one of the Gateway +resources on your cluster. The matched Gateway have a listener on port 80. + +Note that when the labels do not match any Gateway on your cluster, cert-manager +will create the temporary HTTPRoute challenge and nothing will happen. + + +### `serviceType` + +This field has the same meaning as the +[`http01.ingress.serviceType`](#ingress-service-type). + + +## Setting Nameservers for HTTP-01 solver propagation checks + +cert-manager will perform reachability tests before attempting a HTT01 +challenge. By default cert-manager will use the recursive nameservers taken +from `/etc/resolv.conf` to query the challenge URL. + +If this is not desired (for example with split-horizon DNS), the cert-manager +controller exposes a flag that allows you alter this behavior: + +`--acme-http01-solver-nameservers` Comma separated string with host and port of the +recursive nameservers cert-manager should query. + + +Example usage: +```bash +--acme-http01-solver-nameservers="8.8.8.8:53,1.1.1.1:53" +``` + +If you're using the `cert-manager` helm chart, you can set recursive nameservers +through `.Values.extraArgs` or at the command at helm install/upgrade time +with `--set`: + +```bash +--set 'extraArgs={--acme-http01-solver-nameservers=8.8.8.8:53\,1.1.1.1:53}' +``` diff --git a/content/v1.15-docs/configuration/acme/http01/externalloadbalancer.md b/content/v1.15-docs/configuration/acme/http01/externalloadbalancer.md new file mode 100644 index 0000000000..a85966bd29 --- /dev/null +++ b/content/v1.15-docs/configuration/acme/http01/externalloadbalancer.md @@ -0,0 +1,34 @@ +--- +title: External Load Balancer +description: 'cert-manager configuration: ACME HTTP-01 challenges using External Load Balancers' +--- + +When you are using an external load balancer provided by any host, you can face several configuration issues to get it work with cert-manager. + +This documentation is intended to help configure the HTTP-01 challenge type for instances behind external load balancer. + +## NAT Loopback / Hairpin + +The first configuration point is NAT loopback. You can face check issues due to Load Balancer preventing instances behind it to access its external interface. + +Some Network Load Balancer have this kind of limitation for several reasons. It can be configured through `iptables` rerouting configuration known as `NAT loopback`. + +To check if you are facing this problem : + +1. Check that the endpoint of the challenge is accessible to the public : `curl ` +2. Check that the challenge endpoint is NOT accessible from inside behind the Load Balancer: use SSH to open a session on a node places behind the LB; then launch the same command than before : `curl ` + +The `HTTP-01` challenge's endpoint can be found in the logs when the `pre-check` fails. If it does not appear in the logs, you can check the challenge URL by `kubectl`command. + +`` is the URL used to test the HTTP-01 from the certificate `Issuer`. For Let's Encrypt for example, the URL is formed like `/.well-known/acme-challenge/` + + +## Load Balancer HTTP endpoints + +If you are using a Load Balancer (outside a managed Kubernetes service), you should be able to configure the Load Balancer protocol as HTTP, HTTPS, TCP, UDP. Several Load Balancer now offer free TLS certificates with Let's Encrypt. + +When using HTTP(s) protocols for your Load Balancer, it can intercept the challenge URL to replace the response's verification hash with their hash. + +In this case, cert-manager will fail `did not get expected response when querying endpoint, expected 'xxxx' but got: yyyy (truncated)`. + +This kind of error can be thrown for multiple reasons. This case shows a correctly formatted response, but not the expected one. The solution is to configure the Load Balancer with TCP protocol so that the HTTP request will not be intercepted by the host. \ No newline at end of file diff --git a/content/v1.15-docs/configuration/ca.md b/content/v1.15-docs/configuration/ca.md new file mode 100644 index 0000000000..c2a21a34f4 --- /dev/null +++ b/content/v1.15-docs/configuration/ca.md @@ -0,0 +1,94 @@ +--- +title: CA +description: 'cert-manager configuration: CA Issuers' +--- + +⚠️ CA issuers are generally either for trying cert-manager out or else for advanced users with +a good idea of how to run a PKI. To be used safely in production, CA issuers introduce complex +planning requirements around rotation, trust store distribution and disaster recovery. + +If you're not planning to run your own PKI, use a different issuer type. + +The CA issuer represents a Certificate Authority whose certificate and +private key are stored inside the cluster as a Kubernetes `Secret`. + +Certificates issued by a CA issuer will not be publicly trusted and so are unlikely to be trusted +by your applications without further configuration. + +Consider [trust-manager](../trust/trust-manager/README.md) for distributing your CA certificate safely +across your cluster! + +## Deployment + +CA Issuers must be configured with a certificate and private key stored in a Kubernetes +secret. You can create this externally if you wish, or you could bootstrap a root certificate +using a [`SelfSigned` issuer](./selfsigned.md#bootstrapping-ca-issuers). + +Your certificate's secret should reside in the same namespace as the `Issuer`, or otherwise +in the `Cluster Resource Namespace` in the case of a `ClusterIssuer`. + +The `Cluster Resource Namespace` is defaulted as being the `cert-manager` namespace, but +can be configured using the `--cluster-resource-namespace` flag on the cert-manager controller. + +Below is an example of a secret resource that will be used for signing. Take +note of the index keys used for each field as these are required in order for +cert-manager to find the certificate and key. Also note that, like all secrets, +data must be base64 encoded. The command `$ cat crt.pem | base64 -w0` should help you +on GNU-based systems (Debian, Ubuntu, etc.) and `$ cat crt.pem | base64 -b0` on BSD-based +systems (most notably macOS). + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: ca-key-pair + namespace: sandbox +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrVENDQWVHZ0F3SUJBZ0lKQUtQR3dLRGwvNUhuTUEwR0NTcUdTSWIzRFFFQkN3VUFNQk14RVRBUEJnTlYKQkFNTUNHcHZjMmgyWVc1c01CNFhEVEU1TURneU1qRTJNRFUxT0ZvWERUSTVNRGd4T1RFMk1EVTFPRm93RXpFUgpNQThHQTFVRUF3d0lhbTl6YUhaaGJtd3dnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCCkFRQ3doU0IvcVc2L2tMYjJ6cHUrRUp2RDl3SEZhcStRQS8wSkgvTGxseW83ekFGeCtISHErQ09BYmsrQzhCNHQKL0hVRXNuczVSTDA5Q1orWDRqNnBiSkZkS2R1UHhYdTVaVllua3hZcFVEVTd5ZzdPU0tTWnpUbklaNzIzc01zMApSNmpZbi9Ecmo0eFhNSkVmSFVEcVllU1dsWnIzcWkxRUZhMGM3ZlZEeEgrNHh0WnROTkZPakg3YzZEL3ZXa0lnCldRVXhpd3Vzc2U2S01PV2pEbnYvNFZyamVsMlFnVVlVYkhDeWVaSG1jdGkrSzBMV0Nmby9SZzZQdWx3cmJEa2gKam1PZ1l0MzBwZGhYME9aa0F1a2xmVURIZnA4YmpiQ29JMnRhWUFCQTZBS2pLc08zNUxBRVU3OUNMMW1MVkh1WgpBQ0k1VWppamEzVlBXVkhTd21KUEp5dXhBZ01CQUFHalVEQk9NQjBHQTFVZERnUVdCQlFtbDVkVEFaaXhGS2hqCjkzd3VjUldoYW8vdFFqQWZCZ05WSFNNRUdEQVdnQlFtbDVkVEFaaXhGS2hqOTN3dWNSV2hhby90UWpBTUJnTlYKSFJNRUJUQURBUUgvTUEwR0NTcUdTSWIzRFFFQkN3VUFBNElCQVFCK2tsa1JOSlVLQkxYOHlZa3l1VTJSSGNCdgpHaG1tRGpKSXNPSkhac29ZWGRMbEcxcFpORmpqUGFPTDh2aDQ0Vmw5OFJoRVpCSHNMVDFLTWJwMXN1NkNxajByClVHMWtwUkJlZitJT01UNE1VN3ZSSUNpN1VPbFJMcDFXcDBGOGxhM2hQT2NSYjJ5T2ZGcVhYeVpXWGY0dDBCNDUKdEhpK1pDTkhCOUZ4alNSeWNiR1lWaytUS3B2aEphU1lOTUdKM2R4REthUDcrRHgzWGNLNnNBbklBa2h5SThhagpOVSttdzgvdG1Sa1A0SW4va1hBUitSaTBxVW1Iai92d3ZuazRLbTdaVXkxRllIOERNZVM1TmtzbisvdUhsUnhSClY3RG5uMDM5VFJtZ0tiQXFONzJnS05MbzVjWit5L1lxREFZSFlybjk4U1FUOUpEZ3RJL0svQVRwVzhkWAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBc0lVZ2Y2bHV2NUMyOXM2YnZoQ2J3L2NCeFdxdmtBUDlDUi95NVpjcU84d0JjZmh4CjZ2Z2pnRzVQZ3ZBZUxmeDFCTEo3T1VTOVBRbWZsK0krcVd5UlhTbmJqOFY3dVdWV0o1TVdLVkExTzhvT3praWsKbWMwNXlHZTl0N0RMTkVlbzJKL3c2NCtNVnpDUkh4MUE2bUhrbHBXYTk2b3RSQld0SE8zMVE4Ui91TWJXYlRUUgpUb3grM09nLzcxcENJRmtGTVlzTHJMSHVpakRsb3c1Ny8rRmE0M3Bka0lGR0ZHeHdzbm1SNW5MWXZpdEMxZ242ClAwWU9qN3BjSzJ3NUlZNWpvR0xkOUtYWVY5RG1aQUxwSlgxQXgzNmZHNDJ3cUNOcldtQUFRT2dDb3lyRHQrU3cKQkZPL1FpOVppMVI3bVFBaU9WSTRvMnQxVDFsUjBzSmlUeWNyc1FJREFRQUJBb0lCQUNFTkhET3JGdGg1a1RpUApJT3dxa2UvVVhSbUl5MHlNNHFFRndXWXBzcmUxa0FPMkFDWjl4YS96ZDZITnNlanNYMEM4NW9PbmtrTk9mUHBrClcxVS94Y3dLM1ZpRElwSnBIZ09VNzg1V2ZWRXZtU3dZdi9Fb1V3eHFHRVMvcnB5Z1drWU5WSC9XeGZGQlg3clMKc0dmeVltbXJvM09DQXEyLzNVVVFiUjcrT09md3kzSHdUdTBRdW5FSnBFbWU2RXdzdWIwZzhTTGp2cEpjSHZTbQpPQlNKSXJyL1RjcFRITjVPc1h1Vm5FTlVqV3BBUmRQT1NrRFZHbWtCbnkyaVZURElST3NGbmV1RUZ1NitXOWpqCmhlb1hNN2czbkE0NmlLenUzR0YwRWhLOFkzWjRmeE42NERkbWNBWnphaU1vMFJVaktWTFVqbVlQSEUxWWZVK3AKMkNYb3dNRUNnWUVBMTgyaU52UEkwVVlWaUh5blhKclNzd1YrcTlTRStvVi90U2ZSUUNGU2xsV0d3KzYyblRiVwpvNXpoL1RDQW9VTVNSbUFPZ0xKWU1LZUZ1SWdvTEoxN1pvWjN0U1czTlVtMmRpT0lPSHorcTQxQzM5MDRrUzM5CjkrYkFtVmtaSFA5VktLOEMraS9tek5mSkdHZEJadGIweWtTM2t3OUIxTHdnT3o3MDhFeXFSQ2tDZ1lFQTBXWlAKbzF2MThnV2tMK2FnUDFvOE13eDRPZlpTN3dKY3E0Z0xnUWhjYS9pSkttY0x0RFN4cUJHckJ4UVo0WTIyazlzdQpzTFVrNEJobGlVM29iUUJNaUdtMGtITHVBSEFRNmJvdWZBMUJwZjN2VFdHSkhSRjRMeFJsNzc2akw4UXI4VnpxClpURVBtY0R0T0hpYjdwb2I1Z2IzSDhiVGhYeUhmdGZxRW55alhFa0NnWUVBdk9DdDZZclZhTlQrWThjMmRFYk4Kd3dJOExBaUZtdjdkRjZFUjlCODJPWDRCeGR0WTJhRDFtNTNqN2NaVnpzNzFYOE1TN25FcDN1dkFqaElkbDI3KwpZbTJ1dUUyYVhIbDN5VTZ3RzBETFpUcnVIU0Z5TVI4ZithbHRTTXBDd0s1NXluSGpHVFp6dXpYaVBBbWpwRzdmCk1XbVRncE1IK3puc3UrNE9VNFBHUW9FQ2dZQWNqdUdKbS84YzlOd0JsR2lDZTJIK2JGTHhSTURteStHcm16QkcKZHNkMENqOWF3eGI3aXJ3MytjRGpoRUJMWExKcjA5YTRUdHdxbStrdElxenlRTG92V0l0QnNBcjVrRThlTVVBcAp0djBmRUZUVXJ0cXVWaldYNWlaSTNpMFBWS2ZSa1NSK2pJUmVLY3V3aWZKcVJpWkw1dU5KT0NxYzUvRHF3Yk93CnRjTHAwUUtCZ0VwdEw1SU10Sk5EQnBXbllmN0F5QVBhc0RWRE9aTEhNUGRpL2dvNitjSmdpUmtMYWt3eUpjV3IKU25QSG1TbFE0aEluNGMrNW1lbHBDWFdJaklLRCtjcTlxT2xmQmRtaWtYb2RVQ2pqWUJjNnVGQ1QrNWRkMWM4RwpiUkJQOUNtWk9GL0hOcHN0MEgxenhNd1crUHk5Q2VnR3hhZ0ZCekxzVW84N0xWR2h0VFFZCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== +``` + +> Note: If your issuer represents an intermediate, ensure that `tls.crt` contains +> the issuer's full chain in the correct order: `issuer -> intermediate(s) -> root`. +> The root (self-signed) CA certificate is optional, but adding it will ensure that +> the correct CA certificate is stored in the secrets for issued `Certificate`s under +> the `ca.crt` key. If you fail to provide a complete chain, it might not be possible +> for consumers of issued `Certificate`s to verify whether they're trusted. + +Next is to deploy the CA issuer which references this `Secret`. This is done by +referencing the secret name under the `ca` stanza in the `Issuer` spec. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: ca-issuer + namespace: sandbox +spec: + ca: + secretName: ca-key-pair +``` + +Optionally, you can specify [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list) Distribution Points; an array of strings each of which identifies the location of the CRL from which the revocation of this certificate can be checked. + +```yaml +... +spec: + ca: + secretName: ca-key-pair + crlDistributionPoints: + - "http://example.com" +``` + +Once deployed, you can then check that the issuer has been successfully +configured by checking the ready status of the certificate. Replace `issuers` +here with `clusterissuers` if that is what has been deployed. + +```bash +$ kubectl get issuers ca-issuer -n sandbox -o wide +NAME READY STATUS AGE +ca-issuer True Signing CA verified 2m +``` + +Certificates are now ready to be requested by using the CA `Issuer` named +`ca-issuer` within the `sandbox` namespace. diff --git a/content/v1.15-docs/configuration/issuers.md b/content/v1.15-docs/configuration/issuers.md new file mode 100644 index 0000000000..9b9cd63faa --- /dev/null +++ b/content/v1.15-docs/configuration/issuers.md @@ -0,0 +1,145 @@ +--- +title: Issuers +description: 'cert-manager configuration: Issuers' +--- + +The following list contains all known cert-manager issuer integrations. + +
+ +| Tier | Controller | Docs | Issuer | cert-manager
version used
in tutorial[^1] | Released within
12 months[^2] | Is Open Source | +|------|-----------------------------|-------------------------------------|------------------------------------------------------------------------|---------------------------------------------------|-------------------------------------|----------------| +| 🥇 | acme-issuer (in-tree) | [📄][config:acme-issuer] | [ACME][ca:acme] | [latest][production:acme-issuer] | [✔️][release:cert-manager] | ✔️ | +| 🥇 | venafi-enhanced-issuer | [📄][config:venafi-enhanced-issuer] | [Venafi TLS Protect][ca:venafi-enhanced-issuer] | [v1.12.1][production:venafi-enhanced-issuer] | [✔️][release:venafi-enhanced-issuer] | ❌ | +| 🥈 | adcs-issuer | [📄][config:adcs-issuer] | [Microsoft Active Directory
Certificate Service][ca:adcs-issuer] | - | [✔️][release:adcs-issuer] | ✔️ | +| 🥈 | aws-privateca-issuer | [📄][config:aws-privateca-issuer] | [AWS Private Certificate Authority][ca:aws-privateca-issuer] | - | [✔️][release:aws-privateca-issuer] | ✔️ | +| 🥈 | ca-issuer (in-tree) | [📄][config:ca-issuer] | CA issuer | - | [✔️][release:cert-manager] | ✔️ | +| 🥈 | command-issuer | [📄][config:command-issuer] | [Keyfactor Command][ca:command-issuer] | - | [✔️][release:command-issuer] | ✔️ | +| 🥈 | cview-issuer | [📄][config:cview-issuer] | [CView-issuer][ca:cview-issuer] | - | [✔️][release:cview-issuer] | ❌ | +| 🥈 | ejbca-issuer | [📄][config:ejbca-issuer] | [EJBCA][ca:ejbca-issuer] | - | [✔️][release:ejbca-issuer] | ✔️ | +| 🥈 | google-cas-issuer | [📄][config:google-cas-issuer] | [Google Cloud Certificate
Authority Service][ca:google-cas-issuer] | - | [✔️][release:google-cas-issuer] | ✔️ | +| 🥈 | gs-atlas-issuer | [📄][config:gs-atlas-issuer] | [GlobalSign CA][ca:gs-atlas-issuer] | - | [✔️][release:gs-atlas-issuer] | ✔️ | +| 🥈 | horizon-issuer | [📄][config:horizon-issuer] | [EVERTRUST Horizon][ca:horizon-issuer] | - | [✔️][release:horizon-issuer] | ✔️ | +| 🥈 | ncm-issuer | [📄][config:ncm-issuer] | [Nokia Netguard Certificate Manager][ca:ncm-issuer] | - | [✔️][release:ncm-issuer] | ✔️ | +| 🥈 | selfsigned-issuer (in-tree) | [📄][config:selfsigned-issuer] | Self-Signed issuer | - | [✔️][release:cert-manager] | ✔️ | +| 🥈 | step-issuer | [📄][config:step-issuer] | [Certificate Authority server][ca:step-issuer] | - | [✔️][release:step-issuer] | ✔️ | +| 🥈 | tcs-issuer | [📄][config:tcs-issuer] | [Intel's SGX technology][ca:tcs-issuer] | - | [✔️][release:tcs-issuer] | ✔️ | +| 🥈 | vault-issuer (in-tree) | [📄][config:vault-issuer] | [HashiCorp Vault][ca:vault-issuer] | - | [✔️][release:cert-manager] | ✔️ | +| 🥈 | venafi-issuer (in-tree) | [📄][config:venafi-issuer] | [Venafi TLS Protect][ca:venafi-issuer] | - | [✔️][release:cert-manager] | ✔️ | +| 🥉 | cfssl-issuer | [📄][config:cfssl-issuer] | [CFSSL][ca:cfssl-issuer] | - | [❌][release:cfssl-issuer] | ✔️ | +| 🥉 | freeipa-issuer | [📄][config:freeipa-issuer] | [FreeIPA][ca:freeipa-issuer] | - | [❌][release:freeipa-issuer] | ✔️ | +| 🥉 | kms-issuer | [📄][config:kms-issuer] | [AWS KMS][ca:kms-issuer] | - | [❌][release:kms-issuer] | ✔️ | +| 🥉 | origin-ca-issuer | [📄][config:origin-ca-issuer] | [Cloudflare Origin CA][ca:origin-ca-issuer] | - | [❌][release:origin-ca-issuer] | ✔️ | + +
+ +[production:venafi-enhanced-issuer]: https://platform.jetstack.io/documentation/academy/issue-and-approve-certificates-with-venafi-control-plane +[production:acme-issuer]: ../tutorials/getting-started-aks-letsencrypt/README.md + +[//]: # (Configuration docs) + +[config:venafi-enhanced-issuer]: https://docs.venafi.cloud/vaas/k8s-components/t-vei-install/ +[config:acme-issuer]: ./acme/README.md +[config:aws-privateca-issuer]: https://github.com/cert-manager/aws-privateca-issuer +[config:selfsigned-issuer]: ./selfsigned.md +[config:ca-issuer]: ./ca.md +[config:vault-issuer]: ./vault.md +[config:venafi-issuer]: ./venafi.md +[config:step-issuer]: https://github.com/smallstep/step-issuer +[config:origin-ca-issuer]: https://github.com/cloudflare/origin-ca-issuer +[config:ncm-issuer]: https://github.com/nokia/ncm-issuer +[config:tcs-issuer]: https://github.com/intel/trusted-certificate-issuer +[config:google-cas-issuer]: https://github.com/jetstack/google-cas-issuer +[config:gs-atlas-issuer]: https://github.com/globalsign/atlas-cert-manager +[config:ejbca-issuer]: https://github.com/Keyfactor/ejbca-cert-manager-issuer +[config:command-issuer]: https://github.com/Keyfactor/command-cert-manager-issuer +[config:horizon-issuer]: https://github.com/evertrust/horizon-issuer +[config:kms-issuer]: https://github.com/Skyscanner/kms-issuer +[config:freeipa-issuer]: https://github.com/guilhem/freeipa-issuer +[config:adcs-issuer]: https://djkormo.github.io/adcs-issuer/ +[config:cfssl-issuer]: https://gerrit.wikimedia.org/r/plugins/gitiles/operations/software/cfssl-issuer +[config:cview-issuer]: https://secure-ly.github.io/cview-issuer-chart + +[//]: # (CA docs) + +[ca:acme]: https://datatracker.ietf.org/doc/html/rfc8555 +[ca:venafi-enhanced-issuer]: https://venafi.com/tls-protect/ +[ca:adcs-issuer]: https://docs.microsoft.com/en-us/windows-server/networking/core-network-guide/cncg/server-certs/install-the-certification-authority +[ca:aws-privateca-issuer]: https://aws.amazon.com/certificate-manager/private-certificate-authority/ +[ca:command-issuer]: https://www.keyfactor.com/products/command/ +[ca:ejbca-issuer]: https://www.ejbca.org/ +[ca:google-cas-issuer]: https://cloud.google.com/certificate-authority-service/ +[ca:gs-atlas-issuer]: https://www.globalsign.com/en/atlas +[ca:horizon-issuer]: https://evertrust.fr/horizon +[ca:ncm-issuer]: https://www.nokia.com/networks/security-portfolio/netguard/certificate-manager +[ca:step-issuer]: https://github.com/smallstep/certificates +[ca:tcs-issuer]: https://www.intel.com/content/www/us/en/developer/tools/software-guard-extensions/overview.html +[ca:vault-issuer]: https://www.vaultproject.io/ +[ca:venafi-issuer]: https://venafi.com/tls-protect/ +[ca:cfssl-issuer]: https://github.com/cloudflare/cfssl +[ca:freeipa-issuer]: https://www.freeipa.org +[ca:kms-issuer]: https://aws.amazon.com/kms/ +[ca:origin-ca-issuer]: https://developers.cloudflare.com/ssl/origin-configuration/origin-ca +[ca:cview-issuer]: https://secure-ly.github.io/cview-issuer-chart + +[//]: # (Release pages) + +[release:venafi-enhanced-issuer]: https://platform.jetstack.io/documentation/installation/venafi-enhanced-issuer/ +[release:cert-manager]: ../releases/README.md +[release:aws-privateca-issuer]: https://github.com/cert-manager/aws-privateca-issuer/releases +[release:step-issuer]: https://github.com/smallstep/step-issuer/releases +[release:origin-ca-issuer]: https://github.com/cloudflare/origin-ca-issuer/releases +[release:ncm-issuer]: https://github.com/nokia/ncm-issuer/releases +[release:tcs-issuer]: https://github.com/intel/trusted-certificate-issuer/releases +[release:google-cas-issuer]: https://github.com/jetstack/google-cas-issuer/releases +[release:gs-atlas-issuer]: https://github.com/globalsign/atlas-cert-manager/releases +[release:ejbca-issuer]: https://github.com/Keyfactor/ejbca-cert-manager-issuer/tags +[release:command-issuer]: https://github.com/Keyfactor/command-cert-manager-issuer/releases +[release:horizon-issuer]: https://github.com/evertrust/horizon-issuer/releases +[release:kms-issuer]: https://github.com/Skyscanner/kms-issuer/releases +[release:freeipa-issuer]: https://github.com/guilhem/freeipa-issuer/releases +[release:adcs-issuer]: https://github.com/djkormo/adcs-issuer/releases +[release:cfssl-issuer]: https://gerrit.wikimedia.org/r/plugins/gitiles/operations/software/cfssl-issuer/+refs +[release:cview-issuer]: https://github.com/secure-ly/cview-issuer-chart/releases + +- The issuers are sorted by their tier and then alphabetically. +- "in-tree" issuers are issuers that are shipped with cert-manager itself. +- These issuers are known to support and honor [approval](https://cert-manager.io/docs/concepts/certificaterequest/#approval). + +If you've created an issuer which you'd like to share, +[raise a Pull Request](https://github.com/cert-manager/website/pulls) to have it added here! + +## Issuer Tier system + +The cert-manager project has a tier system for issuers. This is to help users +understand the maturity of the issuer. +The tiers are 🥇, 🥈 and 🥉. + +NOTE: The cert-manager maintainers can decide to change the criteria and number +of tiers at any time. + +### 🥇 Tier (Production-ready) + +- 🥈 Tier criteria. +- The issuer has an end-to-end tutorial on how to set it up with cert-manager for use in production. +At the time of checking[^1], the used cert-manager version has to be still supported (see [Supported Releases](../releases/README.md)). +An end-to-end tutorial must include: + 1. a short explanation on how to install cert-manager (including the used version and a link to [https://cert-manager.io/docs/installation/](../installation/)) + 2. all required steps to install the issuer + 3. an explanation on how to configure the issuer's Custom Resources + 4. an explanation on how to issue a certificate using the issuer (using a Certificate resource) + +### 🥈 Tier (Maintained) + +- The issuer has had a release in the last 12 months (at the time of checking all issuers[^2]). + +### 🥉 Tier (Unmaintained) + +Other + +[^1]: checked on 12th of October 2023 +[^2]: checked on 12th of October 2023 + +## Building New External Issuers + +If you're interested in building a new external issuer, check the [development documentation](../contributing/external-issuers.md). diff --git a/content/v1.15-docs/configuration/selfsigned.md b/content/v1.15-docs/configuration/selfsigned.md new file mode 100644 index 0000000000..76c92a530e --- /dev/null +++ b/content/v1.15-docs/configuration/selfsigned.md @@ -0,0 +1,213 @@ +--- +title: SelfSigned +description: 'cert-manager configuration: SelfSigned Issuers' +--- + +⚠️ `SelfSigned` issuers are generally useful for bootstrapping a PKI locally, which +is a complex topic for advanced users. To be used safely in production, running a PKI +introduces complex planning requirements around rotation, trust store distribution and disaster recovery. + +If you're not planning to run your own PKI, use a different issuer type. + +The `SelfSigned` issuer doesn't represent a certificate authority as such, but +instead denotes that certificates will "sign themselves" using a given private +key. In other words, the private key of the certificate will be used to sign +the certificate itself. + +This `Issuer` type is useful for bootstrapping a root certificate for a +custom PKI (Public Key Infrastructure), or for otherwise creating simple +ad-hoc certificates for a quick test. + +There are important [caveats](#caveats) - including security issues - to +consider with `SelfSigned` issuers; in general you'd likely want to use a +[`CA`](./ca.md) issuer rather than a `SelfSigned` issuer. That said, +`SelfSigned` issuers are really useful for initially [bootstrapping](#bootstrapping-ca-issuers) +a `CA` issuer. + +> Note: a `CertificateRequest` that references a self-signed certificate _must_ +> also contain the `cert-manager.io/private-key-secret-name` annotation since +> the private key corresponding to the `CertificateRequest` is required to +> sign the certificate. This annotation is added automatically by the +> `Certificate` controller. + +## Deployment + +Since the `SelfSigned` issuer has no dependency on any other resource, it is +the simplest to configure. Only the `SelfSigned` stanza is required to be +present in the issuer spec, with no other configuration required: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: sandbox +spec: + selfSigned: {} +``` + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-cluster-issuer +spec: + selfSigned: {} +``` + +Once deployed, you should be able to see immediately that the issuer is ready +for signing: + +```bash +$ kubectl get issuers -n sandbox -o wide selfsigned-issuer +NAME READY STATUS AGE +selfsigned-issuer True 2m + +$ kubectl get clusterissuers -o wide selfsigned-cluster-issuer +NAME READY STATUS AGE +selfsigned-cluster-issuer True 3m +``` + +### Bootstrapping `CA` Issuers + +One of the ideal use cases for `SelfSigned` issuers is to bootstrap a custom +root certificate for a private PKI, including with the cert-manager [`CA`](./ca.md) +issuer. + +The YAML below will create a `SelfSigned` issuer, issue a root certificate and +use that root as a `CA` issuer: + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: sandbox +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: my-selfsigned-ca + namespace: sandbox +spec: + isCA: true + commonName: my-selfsigned-ca + secretName: root-secret + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-issuer + kind: ClusterIssuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: my-ca-issuer + namespace: sandbox +spec: + ca: + secretName: root-secret +``` + +Alternatively, if you are looking to use `ClusterIssuer` for signing `Certificates` anywhere in your cluster with the `SelfSigned` `Certificate` CA, use the YAML below (slight modification to the last step): + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: sandbox +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-issuer +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: my-selfsigned-ca + namespace: cert-manager +spec: + isCA: true + commonName: my-selfsigned-ca + secretName: root-secret + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-issuer + kind: ClusterIssuer + group: cert-manager.io +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: my-ca-issuer +spec: + ca: + secretName: root-secret +``` +The "selfsigned-issuer" `ClusterIssuer` is used to issue the Root CA Certificate. Then, "my-ca-issuer" `ClusterIssuer` is used to issue but also sign certificates using the newly created Root CA `Certificate`, which is what you will use for future certificates cluster-wide. + +### CRL Distribution Points + +You may also optionally specify [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list) +Distribution Points as an array of strings, each of which identifies the location of a CRL in +which the revocation status of issued certificates can be checked: + +```yaml +... +spec: + selfSigned: + crlDistributionPoints: + - "http://example.com" +``` + +## Caveats + +### Trust + +Clients consuming `SelfSigned` certificates have _no way_ to trust them +without already having the certificates beforehand, which can be hard to +manage when the client is in a different namespace to the server. + +This limitation can be tackled by using [trust-manager](../trust/trust-manager/README.md) to distribute `ca.crt` +to other namespaces. + +There is no secure alternative to solving the problem of distributing trust stores; it's possible +to "TOFU" (trust-on-first-use) a certificate, but that approach is vulnerable to man-in-the-middle attacks. + +### Certificate Validity + +One side-effect of a certificate being self-signed is that its Subject DN and +its Issuer DN are identical. The X.509 [RFC 5280, section 4.1.2.4](https://tools.ietf.org/html/rfc5280#section-4.1.2.4) +requires that: + +> The issuer field MUST contain a non-empty distinguished name (DN). + +However, self-signed certs don't have a subject DN set by default. Unless you +manually set a certificate's Subject DN, the Issuer DN will be empty +and the certificate will technically be invalid. + +Validation of this specific area of the spec is patchy and varies between TLS +libraries, but there's always the risk that a library will improve its +validation - entirely within spec - in the future and break your app if you're +using a certificate with an empty Issuer DN. + +To avoid this, be sure to set a Subject for `SelfSigned` certs. This can be +done by setting the `spec.subject` on a cert-manager `Certificate` object +which will be issued by a `SelfSigned` issuer. + +Starting in version 1.3, cert-manager will emit a Kubernetes [warning event](https://github.com/cert-manager/cert-manager/blob/45befd86966c563663d18848943a1066d9681bf8/pkg/controller/certificaterequests/selfsigned/selfsigned.go#L140) +of type `BadConfig` if it detects that a certificate is being created +by a `SelfSigned` issuer which has an empty Issuer DN. diff --git a/content/v1.15-docs/configuration/vault.md b/content/v1.15-docs/configuration/vault.md new file mode 100644 index 0000000000..a02ef6cac6 --- /dev/null +++ b/content/v1.15-docs/configuration/vault.md @@ -0,0 +1,662 @@ +--- +title: Vault +description: 'cert-manager configuration: Vault Issuers' +--- + +The `Vault` `Issuer` represents the certificate authority +[Vault](https://www.vaultproject.io/) - a multi-purpose secret store that can be +used to sign certificates for your Public Key Infrastructure (PKI). Vault is an +external project to cert-manager and as such, this guide will assume it has been +configured and deployed correctly, ready for signing. You can read more on how +to configure Vault as a certificate authority +[here](https://www.vaultproject.io/docs/secrets/pki/). + +This `Issuer` type is typically used when Vault is already being used within +your infrastructure, or you would like to make use of its feature set where the +CA issuer alone cannot provide. + +## Deployment + +All Vault issuers share common configuration for requesting certificates, +namely the server, path, and CA bundle: + +- Server is the URL whereby Vault is reachable. +- Path is the Vault path that will be used for signing. Note that the path + *must* use the `sign` endpoint. +- CA bundle denotes an optional field containing a base64 encoded string of the + Certificate Authority to trust the Vault connection. This is typically + _always_ required when using an `https` URL. + +Below is an example of a configuration to connect a Vault server. + +> **Warning**: This configuration is incomplete as no authentication methods have +> been added. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vault-issuer + namespace: sandbox +spec: + vault: + path: pki_int/sign/example-dot-com + server: https://vault.local + caBundle: + auth: + ... +``` + +### Accessing a Vault Server with mTLS enforced + +In certain use cases, the [Vault Server could be configured to enforce clients to present a +client certificates](https://developer.hashicorp.com/vault/docs/configuration/listener/tcp#tls_require_and_verify_client_cert), those client certificates are just a transport layer enforcement, +it does not provide any authentication and authorization mechanism to the Vault APIs itself. + +> 📖 Read about [configuring the Vault server TCP listener](https://developer.hashicorp.com/vault/docs/configuration/listener/tcp). + +Please follow the steps below to configure Vault with mTLS enforced: +- Generate the bundle CA and the server TLS certificate: +```shell +step certificate create "Example Server Root CA" server_ca.crt server_ca.key \ + --profile root-ca \ + --not-after=87600h \ + --no-password \ + --insecure + + +step certificate create vault.vault server.crt server.key \ + --profile leaf \ + --not-after=8760h \ + --ca ./server_ca.crt \ + --ca-key server_ca.key \ + --no-password \ + --insecure +``` +- Generate Vault client certificate and CA: +```shell +step certificate create "Example Client Root CA" client_ca.crt client_ca.key \ + --profile root-ca \ + --not-after=87600h \ + --no-password \ + --insecure + +step certificate create client.vault client.crt client.key \ + --profile leaf \ + --not-after=8760h \ + --ca ./client_ca.crt \ + --ca-key client_ca.key \ + --no-password \ + --insecure +``` +- Prepare the Vault installation, assuming you would be installing Vault in the Kubernetes cluster using the [official Helm chart](https://github.com/hashicorp/vault-helm): + - Create the Vault namespace +```shell +kubectl create ns vault +``` + - Create a Kubernetes Secret in the same namespace where Vault will be installed and add the generated PKI files as following: +```shell +kubectl create secret generic vault-tls \ + --namespace vault \ + --from-file=server.key \ + --from-file=server.crt \ + --from-file=client_ca.crt \ + --from-file=client.crt \ + --from-file=client.key +``` + - Deploy Vault using the following values file: + + > ⚠️ These settings are designed for quick local testing only. They are insecure and not suitable for production use. +```yaml +# vault-values.yaml +global: + tlsDisable: false +injector: + enabled: false +server: + dataStorage: + enabled: false + standalone: + enabled: true + config: | + listener "tcp" { + address = "[::]:8200" + cluster_address = "[::]:8201" + tls_disable = false + tls_client_ca_file = "/vault/tls/client_ca.crt" + tls_cert_file = "/vault/tls/server.crt" + tls_key_file = "/vault/tls/server.key" + tls_require_and_verify_client_cert = true + } + extraArgs: "-dev-tls -dev-listen-address=[::]:8202" + extraEnvironmentVars: + VAULT_TLSCERT: /vault/tls/server.crt + VAULT_TLSKEY: /vault/tls/server.key + VAULT_CLIENT_CERT: /vault/tls/client.crt + VAULT_CLIENT_KEY: /vault/tls/client.key + volumes: + - name: vault-tls + secret: + defaultMode: 420 + secretName: vault-tls + volumeMounts: + - mountPath: /vault/tls + name: vault-tls + readOnly: true +``` + +```shell +helm upgrade vault hashicorp/vault --install --namespace vault --create-namespace --values vault-values.yaml +``` + +- Configure Vault server for Kubernetes auth +```shell +kubectl -n vault exec pods/vault-0 -- \ + vault auth enable --tls-skip-verify kubernetes + +kubectl -n vault exec pods/vault-0 -- \ + vault write --tls-skip-verify \ + auth/kubernetes/role/vault-issuer \ + bound_service_account_names=vault-issuer \ + bound_service_account_namespaces=application-1 \ + audience="vault://application-1/vault-issuer" \ + policies=vault-issuer \ + ttl=1m + +kubectl -n vault exec pods/vault-0 -- \ + vault write --tls-skip-verify \ + auth/kubernetes/config \ + kubernetes_host=https://kubernetes.default +``` +- Create application namespace +```shell +kubectl create ns application-1 +``` +- Create Service account +```shell +kubectl create serviceaccount -n application-1 vault-issuer +``` +- Create Role and Binding +```yaml +# rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: vault-issuer + namespace: application-1 +rules: + - apiGroups: [''] + resources: ['serviceaccounts/token'] + resourceNames: ['vault-issuer'] + verbs: ['create'] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: vault-issuer + namespace: application-1 +subjects: + - kind: ServiceAccount + name: cert-manager + namespace: cert-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: vault-issuer +``` +```shell +kubectl apply -f rbac.yaml +``` +- Create Vault client certificate secret +```shell +kubectl create secret generic vault-client-tls \ + --namespace application-1 \ + --from-file=client.crt \ + --from-file=client.key \ + --from-file=server_ca.crt +``` +- Create Issuer +```yaml +# vault-issuer.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vault-issuer + namespace: application-1 +spec: + vault: + path: pki_int/sign/application-1 + server: https://vault.vault:8200 + caBundleSecretRef: + key: server_ca.crt + name: vault-client-tls + clientCertSecretRef: + name: vault-client-tls + key: client.crt + clientKeySecretRef: + name: vault-client-tls + key: client.key + auth: + kubernetes: + role: vault-issuer + mountPath: /v1/auth/kubernetes + serviceAccountRef: + name: vault-issuer +``` +```shell +kubectl apply -f vault-issuer.yaml +``` +- Check Issuer status +```shell +kubectl describe issuer -n application-1 +``` + +## Authenticating + +In order to request signing of certificates by Vault, the issuer must be able to +properly authenticate against it. cert-manager provides multiple approaches to +authenticating to Vault which are detailed below. + +| Vault auth type | cert-manager issuer configuration | +| ------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | +| [AppRole](https://developer.hashicorp.com/vault/docs/auth/approle) | [A. Authenticating with a Vault AppRole](#a-authenticating-via-an-approle) | +| [Token](https://developer.hashicorp.com/vault/docs/auth/token) | [B. Authenticating with a Vault Token](#b-authenticating-with-a-token) | +| [JWT/OIDC](https://developer.hashicorp.com/vault/docs/auth/jwt/oidc-providers/kubernetes) | [C. Authenticating with Kubernetes Service Accounts](#c-authenticating-with-kubernetes-service-accounts) > [Use JWT/OIDC Auth](#option-1-vault-authentication-method-use-jwtoidc-auth) | +| [Kubernetes](https://developer.hashicorp.com/vault/docs/auth/kubernetes) | [C. Authenticating with Kubernetes Service Accounts](#c-authenticating-with-kubernetes-service-accounts) > [Use Kubernetes Auth](#option-2-vault-authentication-method-use-kubernetes-auth) | + +### A. Authenticating via an AppRole + +An [AppRole](https://www.vaultproject.io/docs/auth/approle.html) is a method of +authenticating to Vault through use of its internal role policy system. This +authentication method requires that the issuer has possession of the `SecretID` +secret key, the `RoleID` of the role to assume, and the app role path. Firstly, +the secret ID key must be stored within a Kubernetes `Secret` that resides in the +same namespace as the `Issuer`, or otherwise inside the `Cluster Resource +Namespace` in the case of a `ClusterIssuer`. + +```yaml +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: cert-manager-vault-approle + namespace: sandbox +data: + secretId: "MDI..." +``` + +Once the `Secret` has been created, the `Issuer` is ready to be deployed which +references this `Secret`, as well as the data key of the field that stores the +secret ID. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vault-issuer + namespace: sandbox +spec: + vault: + path: pki_int/sign/example-dot-com + server: https://vault.local + caBundle: + auth: + appRole: + path: approle + roleId: "291b9d21-8ff5-..." + secretRef: + name: cert-manager-vault-approle + key: secretId +``` + +### B. Authenticating with a Token + +This method of authentication uses a token string that has been generated from +one of the many authentication backends that Vault supports. These tokens have +an expiry and so need to be periodically refreshed. You can read more on Vault +tokens [here](https://www.vaultproject.io/docs/concepts/tokens.html). + +> **Note**: cert-manager does not refresh these token automatically and so another +> process must be put in place to do this. + +Firstly, the token is be stored inside a Kubernetes `Secret` inside the same +namespace as the `Issuer` or otherwise in the `Cluster Resource Namespace` in +the case of using a `ClusterIssuer`. + +```yaml +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: cert-manager-vault-token + namespace: sandbox +data: + token: "MjI..." +``` + +Once submitted, the Vault issuer is able to be created using token +authentication by referencing this `Secret` along with the key of the field the +token data is stored at. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vault-issuer + namespace: sandbox +spec: + vault: + path: pki_int/sign/example-dot-com + server: https://vault.local + caBundle: + auth: + tokenSecretRef: + name: cert-manager-vault-token + key: token +``` + +### C. Authenticating with Kubernetes Service Accounts + +ℹ️ This documentation works for cert-manager >= v1.12.0. + +The [Vault JWT/OIDC Auth](https://developer.hashicorp.com/vault/docs/auth/jwt/oidc-providers/kubernetes) and the [Vault Kubernetes Auth](https://developer.hashicorp.com/vault/docs/auth/kubernetes) allow +cert-manager to authenticate to Vault using a Kubernetes Service Account Token +in order to issue certificates using Vault as a certification authority. + +Vault Authentication Method: +- [Option 1. Use JWT/OIDC Auth](#option-1-vault-authentication-method-use-jwtoidc-auth) +- [Option 2. Use Kubernetes Auth](#option-2-vault-authentication-method-use-kubernetes-auth) + +#### Option 1. Vault Authentication Method: Use JWT/OIDC Auth + +The [JWT/OIDC auth method](https://developer.hashicorp.com/vault/docs/auth/jwt/oidc-providers/kubernetes) should be used instead of the [Kubernetes auth method](#option-2-vault-authentication-method-use-kubernetes-auth) when: +- Your Kubernetes' cluster OIDC discovery endpoint is reachable from the Vault server (this is likely not the case if you are running a self-hosted Kubernetes or OpenShift cluster). +- Your Vault server is not running inside the Kubernetes cluster. + +> **Note:** By using the JWT auth instead of the Kubernetes auth, the revocation of tokens will no longer be checked: +> *"Note: The JWT auth engine does not use Kubernetes' TokenReview API during authentication, and instead uses public key cryptography to verify the contents of JWTs. This means tokens that have been revoked by Kubernetes will still be considered valid by Vault until their expiry time. To mitigate this risk, use short TTLs for service account tokens or use Kubernetes auth which does use the TokenReview API."* +> That's not a problem because cert-manager uses short-lived tokens that expire after 10 minutes. + +The steps below will guide you through the configuration of the JWT auth method (based on [the Vault documentation](https://developer.hashicorp.com/vault/docs/auth/jwt/oidc-providers/kubernetes)) and how to use it with cert-manager. + +To configure Vault's JWT auth, you will need to fetch the issuer URL. + +```bash +ISSUER="$(kubectl get --raw /.well-known/openid-configuration | jq -r '.issuer')" +``` + +Check that the URL works and is accessible from the Vault server. For example, the response should look something like this: + +```console +$ curl "$ISSUER/.well-known/openid-configuration" +{ + "issuer": "https://container.googleapis.com/v1/projects/project001/locations/europe-west1-b/clusters/cert-manager-cluster", + "jwks_uri": "https://container.googleapis.com/v1/projects/project001/locations/europe-west1-b/clusters/cert-manager-cluster/jwks", + ... +} + +$ curl "" +{ + "keys": [ + { + "kty": "RSA", + "e": "AQAB", + "use": "sig", + "kid": "key-id", + "alg": "RS256", + "n": "..." + } + ] +} +``` + +The next step is to configure the JWT auth in Vault. You will need to create one JWT auth path per Kubernetes cluster since each cluster has its own JSON Web Key Set and OIDC discovery endpoint. + +```bash +vault auth enable -path=jwt-cluster001 jwt +kubectl config view --minify --flatten -ojson \ + | jq -r '.clusters[].cluster."certificate-authority-data"' \ + | base64 -d >/tmp/cacrt +vault write auth/jwt-cluster001/config \ + oidc_discovery_url="${ISSUER}" \ + oidc_discovery_ca_pem=@/tmp/cacrt +``` + +Then, create a Kubernetes Service Account and a matching Vault role: + +```sh +kubectl create serviceaccount -n sandbox vault-issuer +``` + +Then add an RBAC Role so that cert-manager can get tokens for the +ServiceAccount: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: vault-issuer + namespace: sandbox +rules: + - apiGroups: [''] + resources: ['serviceaccounts/token'] + resourceNames: ['vault-issuer'] + verbs: ['create'] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: vault-issuer + namespace: sandbox +subjects: + - kind: ServiceAccount + name: cert-manager + namespace: cert-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: vault-issuer +``` + +Then, create the Vault role: + +```bash +vault write auth/jwt-cluster001/role/vault-issuer-role \ + role_type="jwt" \ + bound_audiences="vault://sandbox/vault-issuer" \ + user_claim="sub" \ + bound_subject="system:serviceaccount:sandbox:vault-issuer" \ + policies="default" \ + ttl=1m +``` + +It is recommended to use a different Vault role each per Issuer or +ClusterIssuer. The `audience` allows you to restrict the Vault role to a single +Issuer or ClusterIssuer. The syntax is the following: + +```yaml +"vault:///" # For an Issuer. +"vault://" # For a ClusterIssuer. +``` + +Finally, you can create your Issuer: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vault-issuer + namespace: sandbox +spec: + vault: + path: pki_int/sign/example-dot-com + server: https://vault.local + auth: + kubernetes: + role: vault-issuer-role + mountPath: /v1/auth/jwt-cluster001 + serviceAccountRef: + name: vault-issuer +``` + +#### Option 2. Vault Authentication Method: Use Kubernetes Auth + +The [Kubernetes auth method](https://developer.hashicorp.com/vault/docs/auth/kubernetes) should be used when: +- Your Vault server is running inside the Kubernetes cluster. +- Or, your Kubernetes' cluster OIDC discovery endpoint is not reachable from the Vault server, but Vault can reach the Kubernetes API server. + +The steps below will guide you through the configuration of the Kubernetes auth method (based on [the Vault documentation](https://developer.hashicorp.com/vault/docs/auth/kubernetes)) and how to use it with cert-manager. + +The Kubernetes auth method requires a `token_reviewer_jwt`, which is a JWT token that is used +by Vault to call the TokenReview API of the Kubernetes API server. This endpoint is then used to verify the +JWT token that is provided by cert-manager. There are three ways to provide this `token_reviewer_jwt` token: +1. When running Vault inside the Kubernetes cluster, you can use the Kubernetes service account token that is mounted + into the Vault pod. + ✅ is enabled when Vault auto-detects that it is running in a Kubernetes cluster +2. When running Vault outside the Kubernetes cluster, you can create a long-lived service account token and provide + it to Vault. + ✅ is enabled when you set the `token_reviewer_jwt` parameter +3. When running Vault outside the Kubernetes cluster, you can re-use the JWT token that is provided by cert-manager + to authenticate to Vault. In this case, the audiences of that JWT token must also include the Kubernetes API server audience. + ✅ is enabled when the `token_reviewer_jwt` parameter is omitted and Vault is not running in a Kubernetes cluster + +```bash +vault auth enable -path=kubernetes-cluster001 kubernetes +kubectl config view --minify --flatten -ojson \ + | jq -r '.clusters[].cluster."certificate-authority-data"' \ + | base64 -d >/tmp/cacrt +vault write auth/kubernetes-cluster001/config \ + kubernetes_host= \ + kubernetes_ca_cert=@/tmp/cacrt +``` + +> **Note**: If vault is running outside the Kubernetes cluster, you can provide a `token_reviewer_jwt` token which will +> be used by Vault to authenticate to the Kubernetes API server. This token can be a long-lived service account token +> that can [be obtained as explained here](https://kubernetes.io/docs/concepts/configuration/secret/#serviceaccount-token-secrets). +> Make sure the token is linked to a service account that has the necessary permissions to call the TokenReview API. +> The vault command will look like this: +> ```bash +> vault write auth/kubernetes-cluster001/config \ +> token_reviewer_jwt="" +> kubernetes_host= \ +> kubernetes_ca_cert=@/tmp/cacrt +> ``` + +Then, create a Kubernetes Service Account and a matching Vault role: + +```sh +kubectl create serviceaccount -n sandbox vault-issuer +``` + +Then add an RBAC Role so that cert-manager can get tokens for the +ServiceAccount: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: vault-issuer + namespace: sandbox +rules: + - apiGroups: [''] + resources: ['serviceaccounts/token'] + resourceNames: ['vault-issuer'] + verbs: ['create'] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: vault-issuer + namespace: sandbox +subjects: + - kind: ServiceAccount + name: cert-manager + namespace: cert-manager +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: vault-issuer +``` + +Then, create the Vault role: + +```bash +vault write auth/kubernetes/role/vault-issuer-role \ + bound_service_account_names=vault-issuer \ + bound_service_account_namespaces=sandbox \ + audience="vault://sandbox/vault-issuer" \ + policies=default \ + ttl=1m +``` + +It is recommended to use a different Vault role each per Issuer or +ClusterIssuer. The `audience` allows you to restrict the Vault role to a single +Issuer or ClusterIssuer. The syntax is the following: + +```yaml +"vault:///" # For an Issuer. +"vault://" # For a ClusterIssuer. +``` + +Finally, you can create your Issuer: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vault-issuer + namespace: sandbox +spec: + vault: + path: pki_int/sign/example-dot-com + server: https://vault.local + auth: + kubernetes: + role: vault-issuer-role + mountPath: /v1/auth/kubernetes-cluster001 + serviceAccountRef: + name: vault-issuer +``` + +> **Note**: If you are re-using the JWT token that is provided by cert-manager to authenticate to Vault, you +> can omit the `token_reviewer_jwt` parameter when configuring the Kubernetes Vault auth method. But you must +> additionally configure cert-manager to include the Kubernetes API server audience in the JWT token. This is +> done by setting the `audiences` field in the `serviceAccountRef` field. This option is only available in +> cert-manager >= v1.15.0. +> +> ```bash +> KUBE_API_AUDIENCE="$(kubectl create token default | jq -R 'gsub("-";"+") | gsub("_";"/") | split(".") | .[1] | @base64d | fromjson | .aud[0]')" +> ``` +> +> ```yaml +> ... +> kubernetes: +> ... +> serviceAccountRef: +> name: vault-issuer +> audiences: [ $KUBE_API_AUDIENCE ] +> ``` +> +> When using `audiences`, the JWT will still include the generated audience +> `vault://namespace/issuer-name` or `vault://cluster-issuer`. The generated +> audience is useful for restricting access to a Vault role to a certain issuer. + +## Verifying the issuer Deployment + +Once the Vault issuer has been deployed, it will be marked as ready if the +configuration is valid. Replace `issuers` below with `clusterissuers` if that is what has +been deployed. + +The Vault issuer tests your Vault instance by querying the `v1/sys/health` +endpoint, to ensure your Vault instance is unsealed and initialized before +requesting certificates. The result of that query will populate the `STATUS` +column. + +```bash +$ kubectl get issuers vault-issuer -n sandbox -o wide +NAME READY STATUS AGE +vault-issuer True Vault verified 2m +``` + +Certificates are now ready to be requested by using the Vault issuer named +`vault-issuer` within the `sandbox` namespace. diff --git a/content/v1.15-docs/configuration/venafi.md b/content/v1.15-docs/configuration/venafi.md new file mode 100644 index 0000000000..17e77a29fc --- /dev/null +++ b/content/v1.15-docs/configuration/venafi.md @@ -0,0 +1,284 @@ +--- +title: Venafi +description: 'cert-manager configuration: Venafi Issuers' +--- + +## Introduction + +The Venafi `Issuer` types allows you to obtain certificates from [Venafi +as a Service (VaaS)](https://vaas.venafi.com/jetstack) and [Venafi Trust Protection +Platform (TPP)](https://www.venafi.com/platform/tls-protect) instances. + +You can have multiple different Venafi `Issuer` types installed within the same +cluster, including mixtures of Venafi as a Service and TPP issuer types. This allows +you to be flexible with the types of Venafi account you use. + +Automated certificate renewal and management are provided for `Certificates` +using the Venafi `Issuer`. + +A single Venafi `Issuer` represents a single Venafi 'zone' so you must create one +`Issuer` resource for each zone you want to use. A zone is a single entity that +combines the policy that governs certificate issuance with information about how +certificates are organized in Venafi to identify the business application and +establish ownership. + +You can configure your `Issuer` resource to either issue certificates only +within a single namespace, or cluster-wide (using a `ClusterIssuer` resource). +For more information on the distinction between `Issuer` and `ClusterIssuer` +resources, read the [Namespaces](../concepts/issuer.md#namespaces) section. + +## Creating a Venafi as a Service Issuer + +If you haven't already done so, create your Venafi as a Service account on this +[page](https://vaas.venafi.com/jetstack) and copy the API key from your user +preferences. Then you may want to create a custom CA Account and Issuing Template +or choose instead to use defaults that are automatically created for testing +("Built-in CA" and "Default", respectively). Lastly you'll need to create an +Application for establishing ownership of all the certificates requested by your +cert-manager Issuer, and assign to it the Issuing Template. + +> Make a note of the Application name and API alias of the Issuing Template because +> together they comprise the 'zone' you will need for your `Issuer` configuration. + +In order to set up a Venafi as a Service `Issuer`, you must first create a Kubernetes +`Secret` resource containing your Venafi as a Service API credentials: + +```bash +$ kubectl create secret generic \ + vaas-secret \ + --namespace='NAMESPACE OF YOUR ISSUER RESOURCE' \ + --from-literal=apikey='YOUR_VAAS_API_KEY_HERE' +``` + +> **Note**: If you are configuring your issuer as a `ClusterIssuer` resource in +> order to serve `Certificates` across your whole cluster, you must set the +> `--namespace` parameter to `cert-manager`, which is the default `Cluster +> Resource Namespace`. The `Cluster Resource Namespace` can be configured +> through the `--cluster-resource-namespace` flag on the cert-manager controller +> component. + +This API key will be used by cert-manager to interact with Venafi as a Service +on your behalf. + +Once the API key `Secret` has been created, you can create your `Issuer` or +`ClusterIssuer` resource. If you are creating a `ClusterIssuer` resource, you +must change the `kind` field to `ClusterIssuer` and remove the +`metadata.namespace` field. + +Save the below content after making your amendments to a file named +`vaas-issuer.yaml`. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: vaas-issuer + namespace: +spec: + venafi: + zone: "My Application\My CIT" # Set this to \ + cloud: + apiTokenSecretRef: + name: vaas-secret + key: apikey +``` + +You can then create the Issuer using `kubectl create`. + +```bash +$ kubectl create -f vaas-issuer.yaml +``` + +Verify the `Issuer` has been initialized correctly using `kubectl describe`. + +```bash +$ kubectl get issuer vaas-issuer --namespace='NAMESPACE OF YOUR ISSUER RESOURCE' -o wide +NAME READY STATUS AGE +vaas-issuer True Venafi issuer started 2m +``` + +You are now ready to issue certificates using the newly provisioned Venafi +`Issuer` and Venafi as a Service. + +Read the [Requesting Certificates](../usage/certificate.md) document for +more information on how to create Certificate resources. + + +## Creating a Venafi Trust Protection Platform Issuer + +The Venafi Trust Protection Platform integration allows you to obtain certificates +from a properly configured Venafi TPP instance. + +The setup is similar to the Venafi as a Service configuration above, however some +of the connection parameters are slightly different. + +> **Note**: You *must* allow "User Provided CSRs" as part of your TPP policy, as +> this is the only type supported by cert-manager at this time. +> +> More specifically, the valid configurations of the "CSR handling" are: +> +> - "User Provided CSRs" selected and unlocked, +> - "User Provided CSRs" selected and locked, +> - "Service Generated CSRs" selected and unlocked. +> +> When using "Service Generated CSRs" selected and unlocked, the default CSR +> configuration present in your policy folder will override the configuration of +> your Certificate resource. The subject DN, key algorithm, and key size will be +> overridden by the values set in the policy folder. +> +> With "Service Generated CSRs" selected and locked, the certificate issuance +> will systematically fail with the following message: +> +> ```plain +> 400 PKCS#10 data will not be processed. Policy "\VED\Policy\foo" is locked to a Server Generated CSR. +> ``` + +In order to set up a Venafi Trust Protection Platform `Issuer`, you must first +create a Kubernetes `Secret` resource containing your Venafi TPP API +credentials. + +### Access Token Authentication + +1. [Set up token authentication](https://docs.venafi.com/Docs/23.1/TopNav/Content/SDK/AuthSDK/t-SDKa-Setup-OAuth.php). + + NOTE: Do not select "Refresh Token Enabled" and set a *long* "Token Validity + (days)". The Refresh Token feature is not supported by cert-manager's Venafi + `Issuer`. + +2. Create a new user with sufficient privileges to manage and revoke certificates in a particular policy folder (zone). + + E.g. `k8s-xyz-automation` + +3. [Create a new application integration](https://docs.venafi.com/Docs/21.4/TopNav/Content/API-ApplicationIntegration/t-APIAppIntegrations-creatingNew-Aperture.php) + + Create an application integration with name and ID `cert-manager`. + Set the "API Access Settings" to `Certificates: Read,Manage,Revoke`. + + "Edit Access" to the new application integration, and allow it to be used by the user you created earlier. + +4. [Generate an access token](https://github.com/Venafi/vcert/blob/master/README-CLI-PLATFORM.md#obtaining-an-authorization-token) + + ``` + vcert getcred \ + --username k8s-xyz-automation \ + --password somepassword \ + -u https://tpp.example.com/vedsdk \ + --client-id cert-manager \ + --scope "certificate:manage,revoke" + ``` + + This will print an access-token to `stdout`. E.g. + + ``` + vCert: 2020/10/07 16:34:27 Getting credentials + access_token: I69n.............y1VjNJT3o9U0Wko19g== + access_token_expires: 2021-01-05T15:34:30Z + ``` + +5. Save the access-token to a Secret in the Kubernetes cluster + +```bash +$ kubectl create secret generic \ + tpp-secret \ + --namespace= \ + --from-literal=access-token='YOUR_TPP_ACCESS_TOKEN' +``` + +### Username / Password Authentication + +> ⚠️ When you supply a Venafi TPP username and password, +> cert-manager uses an older authentication method which is called "API Keys", +> which has been deprecated since Venafi TPP `19.2`. +> +> Beginning in Venafi TPP `22.2`, "API Keys" are disabled by default. +> You will need to contact Venafi customer support for a special license key which will allow you to re-enable the "API Keys" feature, +> so that you can continue to use username and password authentication with cert-manager. +> +> In Venafi TPP `22.3`, the "API Keys" feature will be permanently removed, +> and you will need to use access-token authentication instead. +> +> 📖 Read [Deprecated functionality from Venafi Platform](https://docs.venafi.com/22.3/deprecation-list-current) +> and [Functionality Scheduled for Deprecation](https://support.venafi.com/hc/en-us/articles/115001662292) for more information. + +```bash +$ kubectl create secret generic \ + tpp-secret \ + --namespace= \ + --from-literal=username='YOUR_TPP_USERNAME_HERE' \ + --from-literal=password='YOUR_TPP_PASSWORD_HERE' +``` + +> Note: If you are configuring your issuer as a `ClusterIssuer` resource in +> order to issue `Certificates` across your whole cluster, you must set the +> `--namespace` parameter to `cert-manager`, which is the default `Cluster +> Resource Namespace`. The `Cluster Resource Namespace` can be configured +> through the `--cluster-resource-namespace` flag on the cert-manager controller +> component. + +These credentials will be used by cert-manager to interact with your Venafi TPP +instance. Username attribute must be adhere to the `:` format. For example: `local:admin`. + +Once the Secret containing credentials has been created, you can create your +`Issuer` or `ClusterIssuer` resource. If you are creating a `ClusterIssuer` +resource, you must change the `kind` field to `ClusterIssuer` and remove the +`metadata.namespace` field. + +Save the below content after making your amendments to a file named +`tpp-issuer.yaml`. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: tpp-issuer + namespace: +spec: + venafi: + zone: \VED\Policy\devops\cert-manager # Set this to the Venafi policy folder you want to use + tpp: + url: https://tpp.venafi.example/vedsdk # Change this to the URL of your TPP instance + caBundle: + credentialsRef: + name: tpp-secret +``` + +You can then create the `Issuer` using `kubectl create -f`. + +```bash +$ kubectl create -f tpp-issuer.yaml +``` + +Verify the `Issuer` has been initialized correctly using `kubectl describe`. + +```bash +$ kubectl describe issuer tpp-issuer --namespace='NAMESPACE OF YOUR ISSUER RESOURCE' +``` + +You are now ready to issue certificates using the newly provisioned Venafi +`Issuer` and Trust Protection Platform. + +Read the [Requesting Certificates](../usage/certificate.md) document for +more information on how to create Certificate resources. + +## Issuer specific annotations + +### Custom Fields + +Starting `v0.14` you can pass custom fields to Venafi (TPP version `v19.2` and higher) using the `venafi.cert-manager.io/custom-fields` annotation on Certificate resources. +The value is a JSON encoded array of custom field objects having a `name` and `value` key. +For example: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com-certificate + annotations: + venafi.cert-manager.io/custom-fields: |- + [ + {"name": "field-name", "value": "field value"}, + {"name": "field-name-2", "value": "field value 2"} + ] +... +``` diff --git a/content/v1.15-docs/devops-tips/backup.md b/content/v1.15-docs/devops-tips/backup.md new file mode 100644 index 0000000000..6fa08ef954 --- /dev/null +++ b/content/v1.15-docs/devops-tips/backup.md @@ -0,0 +1,200 @@ +--- +title: Backup and Restore Resources +description: 'cert-manager tutorials: Backing up your cert-manager installation' +--- + +If you need to uninstall cert-manager, or transfer your installation to a new +cluster, you can backup all of cert-manager's configuration in order to later +re-install. + +## Backing up cert-manager resource configuration + +The following commands will back up the configuration of `cert-manager` +resources. Doing that might be useful before upgrading `cert-manager`. As +this backup does not include the `Secrets` containing the X.509 +certificates, restoring to a cluster that does not already have those +`Secret` objects will result in the certificates being reissued. + +### Backup + +To backup all of your cert-manager configuration resources, run: + +```bash +kubectl get --all-namespaces -oyaml issuer,clusterissuer,cert > backup.yaml +``` + +If you are transferring data to a new cluster, you may also need to copy across +additional `Secret` resources that are referenced by your configured Issuers, such +as: + +#### CA Issuers + +- The root CA `Secret` referenced by `issuer.spec.ca.secretName` + +#### Vault Issuers + +- The token authentication `Secret` referenced by + `issuer.spec.vault.auth.tokenSecretRef` +- The AppRole configuration `Secret` referenced by + `issuer.spec.vault.auth.appRole.secretRef` + +#### ACME Issuers + +- The ACME account private key `Secret` referenced by `issuer.acme.privateKeySecretRef` +- Any `Secret`s referenced by DNS providers configured under the + `issuer.acme.dns01.providers` and `issuer.acme.solvers.dns01` fields. + +### Restore + +In order to restore your configuration, you can `kubectl apply` the files +created above after installing cert-manager, with the exception of the +`uid` and `resourceVersion` fields that do not need to be restored: + +```bash +kubectl apply -f <(awk '!/^ *(resourceVersion|uid): [^ ]+$/' backup.yaml) +``` + +## Full cluster backup and restore + +This section refers to backing up and restoring 'all' Kubernetes resources in a +cluster — including some `cert-manager` ones — for scenarios such as disaster +recovery, cluster migration etc. + +*Note*: We have tested this process on simple Kubernetes test clusters with a limited set of Kubernetes releases. To avoid data loss, please test both the backup and the restore strategy on your own cluster before depending upon it in production. If you encounter any errors, please open a GitHub issue or a PR to document variations on this process for different Kubernetes environments. + +### Avoiding unnecessary certificate reissuance + +#### Order of restore + +If `cert-manager` does not find a Kubernetes `Secret` with an X.509 certificate +for a `Certificate`, reissuance will be triggered. To avoid unnecessary +reissuance after a restore, ensure that `Secret`s are restored before +`Certificate`s. Similarly, `Secret`s should be restored before `Ingress`es if you +are using [`ingress-shim`](../usage/ingress.md). + +#### Excluding some cert-manager resources from backup + +`cert-manager` has a number of custom resources that are designed to represent a +point-in-time operation. An example would be a `CertificateRequest` that +represents a one-time request for an X.509 certificate. The status of these +resources can depend on other ephemeral resources (such as a temporary `Secret` +holding a private key) so `cert-manager` might not be able to correctly recreate +the state of these resources at a later point. + +In most cases backup and restore tools will not restore the statuses of custom resources, +so including such one-time resources in a backup can result in an unnecessary reissuance +after a restore as without the status fields `cert-manager` will not be able to tell that, +for example, an `Order` has already been fulfilled. +To avoid unnecessary reissuance, we recommend that `Order`s and `Challenge`s are excluded +from the backup. We also don't recommend backing up `CertificateRequest`s, see [Backing up CertificateRequests](#backing-up-certificaterequests) + +### Restoring Ingress Certificates + +A `Certificate` created for an `Ingress` via [`ingress-shim`](../usage/ingress.md) will have an [owner +reference](https://kubernetes.io/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents) +pointing to the `Ingress` resource. `cert-manager` uses the owner reference to +verify that the `Certificate` 'belongs' to that `Ingress` and will not attempt to +create/correct it for an existing `Certificate`. After a full +cluster recreation, a restored owner reference would probably be incorrect +(`Ingress` UUID will have changed). The incorrect owner reference could lead +to a situation where updates to the `Ingress` (i.e a new DNS name) are not +applied to the `Certificate`. + +To avoid this issue, in most cases `Certificate`s created via `ingress-shim` +should be excluded from the backup. Given that the restore happens +in the correct order (`Secret` with the X.509 certificate restored before +the `Ingress`) `cert-manager` will be able to create a new `Certificate` +for the `Ingress` and determine that the existing `Secret` is for that `Certificate`. + +### Velero + +We have tested backup and restore with `velero` `v1.12.2` and `cert-manager` version `v1.13.2`. + +A few potential edge cases: + +- Ensure that the backups include `cert-manager` CRDs. + For example, we have seen that if `--exclude-namespaces` flag is passed to + `velero backup create`, CRDs for which there are no actual resources to be + included in the backup might also not be included in backup unless + `--include-cluster-resources=true` flag is also passed to the backup command. + +- Velero does not restore statuses of custom resources, so you should probably + exclude `Order`s, `Challenge`s and `CertificateRequest`s from the backup, see + [Excluding some cert-manager resources from backup](#excluding-some-cert-manager-resources-from-backup). + +- Velero's [default restore order](https://github.com/vmware-tanzu/velero/blob/a318e1da995a390c9f10e4aef7df356594944377/pkg/cmd/server/server.go#L511-L543) (`Secrets` before `Ingress`es, Custom Resources + restored last), should ensure that there is no unnecessary certificate reissuance + due to the order of restore operation, see [Order of restore](#order-of-restore). + +- When restoring the deployment of `cert-manager` itself, it may be necessary to + restore `cert-manager`'s RBAC resources before the rest of the deployment. + This is because `cert-manager`'s controller needs to be able to create + `Certificate`'s for the `cert-manager`'s webhook before the webhook can become + ready. In order to do this, the controller needs the right permissions. Since + Velero by default restores pods before RBAC resources, the restore might get + stuck waiting for the webhook pod to become ready. + +- Velero does not restore owner references, so it may be necessary to exclude + `Certificate`s created for `Ingress`es from the backup even when not + re-creating the `Ingress` itself. See [Restoring Ingress Certificates](#restoring-ingress-certificates). + + +#### Example backup and restore using Velero + +The following command will create a backup of all Kubernetes resources in the +default and cert-manager namespaces, excluding `Order`s, `Challenge`s and +`CertificateRequest`s (see above): +```bash +velero backup create \ + full-backup \ + --include-namespaces cert-manager,default \ + --include-cluster-resources=true \ + --exclude-resources challenges.acme.cert-manager.io,orders.acme.cert-manager.io,certificaterequests.cert-manager.io +``` + +To workaround Velero not restoring owner references, you can restore the backup +in two steps: first restore the `Secret`s and `Ingress`es and the `cert-manager` +deployment, second restore the `Certificate` resources. This will allow `cert-manager`'s +controller to create the `Certificate` for the ingresses and set the owner reference. +The second restore will then restore the manually created `Certificate`s and detect that +the generated `Certificate`s for the `Ingress`es already exist and will not attempt to +recreate them. + +1. Restore everything except `Certificate` resources: +```bash +velero restore create \ + --from-backup full-backup \ + --exclude-resources certificates.cert-manager.io +``` + +2. Wait for cert-manager to create the `Certificate`s for the `Ingress`es (if cert-manager is having RBAC/ webhook issues, you might have to manually restart the deployments). After the auto-generated `Certificate`s are created, restore the manually created `Certificate`s: +```bash +velero restore create \ + --from-backup full-backup +``` + +## Backing up CertificateRequests + + We no longer recommend including `CertificateRequest` resources in a backup + for most scenarios. + `CertificateRequest`s are designed to represent a one-time + request for an X.509 certificate. Once the request has been fulfilled, + `CertificateRequest` can usually be safely deleted[^1]. In most cases (such as when + a `CertificateRequest` has been created for a `Certificate`) a new + `CertificateRequest` will be created when needed (i.e at a time of a renewal + of a `Certificate`). + In `v1.3.0` , as part of our work towards [policy + implementation](https://github.com/cert-manager/cert-manager/pull/3727) we + introduced identity fields for `CertificateRequest` resources where, at a time + of creation, `cert-mananager`'s webhook updates `CertificateRequest`'s spec + with immutable identity fields, representing the identity of the creator of + the `CertificateRequest`. + This introduces some extra complexity for backing up + and restoring `CertificateRequest`s as the identity of the restorer might + differ from that of the original creator and in most cases a restored + `CertificateRequest` would likely end up with incorrect state. + + [^1]: there is an edge case where certain changes to `Certificate` spec may not + trigger re-issuance if there is no `CertificateRequest` for that + `Certificate`. See [documentation on when do certificates get + re-issued](../faq/README.md#when-do-certs-get-re-issued). \ No newline at end of file diff --git a/content/v1.15-docs/devops-tips/prometheus-metrics.md b/content/v1.15-docs/devops-tips/prometheus-metrics.md new file mode 100644 index 0000000000..d3d897798e --- /dev/null +++ b/content/v1.15-docs/devops-tips/prometheus-metrics.md @@ -0,0 +1,147 @@ +--- +title: Prometheus Metrics +description: 'cert-manager usage: Prometheus metrics' +--- + +To help with operations and insights into cert-manager activities, cert-manager exposes metrics in the [Prometheus](https://prometheus.io/) format from the controller component. These are available at the standard `/metrics` path of the controller component's configured HTTP port. + +## Scraping Metrics + +How metrics are scraped will depend how you're operating your Prometheus server(s). These examples presume the [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) is being used to run Prometheus, and configure Pod or Service Monitor CRDs. + +### Helm + +If you're deploying cert-manager with helm, a `ServiceMonitor` resource can be configured. This configuration should enable metric scraping, and the configuration can be further tweaked as described in the [Helm configuration documentation](https://github.com/cert-manager/cert-manager/blob/master/deploy/charts/cert-manager/README.template.md#configuration). + +```yaml +prometheus: + enabled: true + servicemonitor: + enabled: true +``` + +### Regular Manifests + +If you're not using helm to deploy cert-manager and instead using the provided regular YAML manifests, this example `PodMonitor` and deployment patch should be all you need to start ingesting cert-manager metrics. + +1. [Apply the following patch](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#use-a-strategic-merge-patch-to-update-a-deployment) to your cert-manager deployment + +```yaml +spec: + template: + spec: + containers: + - name: cert-manager-controller + ports: + - containerPort: 9402 + name: http + protocol: TCP +``` + +2. Create the following `PodMonitor` + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: cert-manager + namespace: cert-manager + labels: + app: cert-manager + app.kubernetes.io/name: cert-manager + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "controller" +spec: + jobLabel: app.kubernetes.io/name + selector: + matchLabels: + app: cert-manager + app.kubernetes.io/name: cert-manager + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "controller" + podMetricsEndpoints: + - port: http-metrics + honorLabels: true +``` + +### TLS + +TLS can be enabled on the metrics endpoint for end-to-end encryption. This is achieved either using pre-signed static certificates, or using the internal dynamic certificate signing. + +#### Static certificates + +Static certificates can be provided to the cert-manager controller to use when listening on the metric endpoint. If the certificate files are changed then cert-manager will reload the certificates for zero-downtime rotation. + +Static certificates can be specified via the flags `--metrics-tls-cert-file` and `--metrics-tls-private-key-file` or the corresponding config file parameters `metricsTLSConfig.filesystem.certFile` and `metricsTLSConfig.filesystem.keyFile`. + +The certificate and private key must be mounted into the controller pod for this to work, if cert-manager is deployed using helm the `.volumes[]` and `.mounts[]` properties can facilitate this. + +An example config file would be: + +```yaml +apiVersion: controller.config.cert-manager.io/v1alpha1 +kind: ControllerConfiguration +metricsTLSConfig: + filesystem: + certFile: "/path/to/cert.pem" + keyFile: "/path/to/key.pem" +``` + +#### Dynamic certificates + +In this mode cert-manager will create a CA in a named secret, then use this CA to sign the metrics endpoint certificate. This mode will also take care of rotation, auto rotating the certificate as required. + +Dynamic certificates can be specified via the flags `--metrics-dynamic-serving-ca-secret-namespace`, `--metrics-dynamic-serving-ca-secret-name` and `--metrics-dynamic-serving-dns-names` or the corresponding config file parameters `metricsTLSConfig.dynamic.secretNamespace`, `metricsTLSConfig.dynamic.secretName` and `metricsTLSConfig.dynamic.dnsNames`. + +An example config file would be: + +```yaml +apiVersion: controller.config.cert-manager.io/v1alpha1 +kind: ControllerConfiguration +metricsTLSConfig: + dynamic: + secretNamespace: "cert-manager" + secretName: "cert-manager-metrics-ca" + dnsNames: + - cert-manager-metrics + - cert-manager-metrics.cert-manager + - cert-manager-metrics.cert-manager.svc +``` + +When using Prometheus the CA generated by the generated certificate authority can be trusted as part of the `PodMonitor` or `ServiceMonitor` spec: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: cert-manager + namespace: cert-manager + labels: + app: cert-manager + app.kubernetes.io/name: cert-manager + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "controller" +spec: + jobLabel: app.kubernetes.io/name + selector: + matchLabels: + app: cert-manager + app.kubernetes.io/name: cert-manager + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "controller" + podMetricsEndpoints: + - port: http-metrics + scheme: https + honorLabels: true + # TLS config trusting the CA and specifying the server name + tlsConfig: + serverName: cert-manager-metrics + ca: + secret: + name: cert-manager-metrics-ca + key: "tls.crt" +``` + +## Monitoring Mixin + +Monitoring mixins are a way to bundle common alerts, rules, and dashboards for an application in a configurable and extensible way, using the Jsonnet data templating language. A cert-manager monitoring mixin can be found here https://gitlab.com/uneeq-oss/cert-manager-mixin. Documentation on usage can be found with the `cert-manager-mixin` project. diff --git a/content/v1.15-docs/devops-tips/scaling-cert-manager.md b/content/v1.15-docs/devops-tips/scaling-cert-manager.md new file mode 100644 index 0000000000..c12185dc19 --- /dev/null +++ b/content/v1.15-docs/devops-tips/scaling-cert-manager.md @@ -0,0 +1,133 @@ +--- +title: Scaling cert-manager +description: | + Learn how to optimize cert-manager for your cluster. +--- + +Learn how to optimize cert-manager for your cluster. + +## Overview + +The defaults in the Helm chart and YAML manifests are intended for general use. +You may want to modify the configuration to suit the size and usage of your Kubernetes cluster. + +## Set appropriate memory requests and limits + +**When Certificate resources are the dominant use-case**, +such as when workloads need to mount the TLS Secret or when gateway-shim is used, +the memory consumption of the cert-manager controller will be roughly +proportional to the total size of those Secret resources that contain the TLS +key pairs. +Why? Because the cert-manager controller caches the entire content of these Secret resources in memory. +If large TLS keys are used (e.g. RSA 4096) the memory use will be higher than if smaller TLS keys are used (e.g. ECDSA). + +The other Secrets in the cluster, such as those used for Helm chart configurations or for other workloads, +will not significantly increase the memory consumption, because cert-manager will only cache the metadata of these Secrets. + +**When `CertificateRequest` resources are the dominant use-case**, +such as with csi-driver or with istio-csr, +the memory consumption of the cert-manager controller will be much lower, +because there will be fewer TLS Secrets and fewer resources to be cached. + +> 📖️ Read [What Everyone Should Know About Kubernetes Memory Limits](https://home.robusta.dev/blog/kubernetes-memory-limit), +> to learn how to right-size the memory requests. + +## Disable client-side rate limiting for Kubernetes API requests + +By default cert-manager [throttles the rate of requests to the Kubernetes API server](https://github.com/cert-manager/cert-manager/blob/b61de55abda95a4c273be0c8d3e6025fe8511573/internal/apis/config/controller/v1alpha1/defaults.go#L59-L60) to 20 queries per second. +Historically this was intended to prevent cert-manager from overwhelming the Kubernetes API server, +but modern versions of Kubernetes implement [API Priority and Fairness](https://kubernetes.io/docs/concepts/cluster-administration/flow-control/), +which obviates the need for client side throttling. +You can increase the threshold of the client-side rate limiter using the following helm values: + +```yaml +# helm-values.yaml +config: + apiVersion: controller.config.cert-manager.io/v1alpha1 + kind: ControllerConfiguration + kubernetesAPIQPS: 10000 + kubernetesAPIBurst: 10000 +``` + +> ℹ️ This does not technically disable the client-side rate-limiting but configures the QPS and Burst values high enough that they are never reached. +> +> 🔗 Read [`cert-manager#6890`: Allow client-side rate-limiting to be disabled](https://github.com/cert-manager/cert-manager/issues/6890); +> a proposal for a cert-manager configuration option to disable client-side rate-limiting. +> +> 🔗 Read [`kubernetes#111880`: Disable client-side rate-limiting when AP&F is enabled](https://github.com/kubernetes/kubernetes/issues/111880); +> a proposal that the `kubernetes.io/client-go` module should automatically use server-side rate-limiting when it is enabled. +> +> 🔗 Read about other projects that disable client-side rate limiting: [Flux](https://github.com/fluxcd/pkg/issues/269). +> +> 📖 Read [API documentation for ControllerConfiguration](../reference/api-docs.md#controller.config.cert-manager.io/v1alpha1.ControllerConfiguration) for a description of the `kubernetesAPIQPS` and `kubernetesAPIBurst` configuration options. + +## Restrict the use of large RSA keys + +Certificates with large RSA keys cause cert-manager to use more CPU resources. +When there are insufficient CPU resources, the reconcile queue length grows, +which delays the reconciliation of all Certificates. +A user who has permission to create a large number of RSA 4096 certificates, +might accidentally or maliciously cause a denial of service for other users on the cluster. + +> 📖 Learn [how to enforce an Approval Policy](../policy/approval/README.md), to prevent the use of large RSA keys. +> +> 📖 Learn [how to set Certificate defaults automatically](../tutorials/certificate-defaults/README.md), using tools like Kyverno. + + +## Set `revisionHistoryLimit: 1` on all Certificate resources + +By default, cert-manager will keep all the `CertificateRequest` resources that **it** creates +([`revisionHistoryLimit`](../reference/api-docs.md#cert-manager.io/v1.CertificateSpec)): + +> The maximum number of `CertificateRequest` revisions that are maintained in +> the Certificate's history. Each revision represents a single +> `CertificateRequest` created by this Certificate, either when it was +> created, renewed, or Spec was changed. Revisions will be removed by oldest +> first if the number of revisions exceeds this number. +> If set, `revisionHistoryLimit` must be a value of `1` or greater. If unset +> (`nil`), revisions will not be garbage collected. Default value is `nil`. + +On a busy cluster these will eventually overwhelm your Kubernetes API server; +because of the memory and CPU required to cache them all and the storage required to save them. + +Use a tool like Kyverno to override the `Certificate.spec.revisionHistoryLimit` for all namespaces. + +> 📖 Adapt [the Kyverno policies in the tutorial: how to set Certificate defaults automatically](../tutorials/certificate-defaults/README.md), +> to override rather than default the `revisionHistoryLimit` field. +> +> 📖 Learn [how to set `revisionHistoryLimit` when using Annotated Ingress resources](../usage/ingress.md#supported-annotations). +> +> 🔗 Read [`cert-manager#3958`: Sane defaults for Certificate revision history limit](https://github.com/cert-manager/cert-manager/issues/3958); +> a proposal to change the default `revisionHistoryLimit`, which will obviate this particular recommendation. + +## Enable Server-Side Apply + +By default, cert-manager [uses Update requests](https://kubernetes.io/docs/reference/using-api/api-concepts/#update-mechanism-update) +to create and modify resources like `CertificateRequest` and `Secret`, +but on a busy cluster there will be frequent conflicts as the control loops in cert-manager each try to update the status of various resources. + +You will see errors, like this one, in the logs: + +> `I0419 14:11:51.325377 1 controller.go:162] "re-queuing item due to optimistic locking on resource" logger="cert-manager.certificates-trigger" key="team-864-p6ts6/app-7" error="Operation cannot be fulfilled on certificates.cert-manager.io \"app-7\": the object has been modified; please apply your changes to the latest version and try again"` + +This error is relatively harmless because the update attempt is retried, +but it slows down the reconciliation because each error triggers an exponential back off mechanism, +which causes increasing delays between retries. + +The solution is to turn on the [Server-Side Apply Feature](../installation/configuring-components.md#feature-gates), +which causes cert-manager to use [HTTP PATCH using Server-Side Apply](https://kubernetes.io/docs/reference/using-api/api-concepts/#update-mechanism-server-side-apply) when ever it needs to modify an API resource. +This avoids all conflicts because each cert-manager controller sets only the fields that it owns. + +You can enable the server-side apply feature gate with the following Helm chart values: + +```yaml +# helm-values.yaml +config: + apiVersion: controller.config.cert-manager.io/v1alpha1 + kind: ControllerConfiguration + featureGates: + ServerSideApply: true +``` + +> 📖 Read [Using Server-Side Apply in a controller](https://kubernetes.io/docs/reference/using-api/server-side-apply/#using-server-side-apply-in-a-controller), +> to learn about the advantages of server-side apply for software like cert-manager. diff --git a/content/v1.15-docs/devops-tips/syncing-secrets-across-namespaces.md b/content/v1.15-docs/devops-tips/syncing-secrets-across-namespaces.md new file mode 100644 index 0000000000..6db7ed85d0 --- /dev/null +++ b/content/v1.15-docs/devops-tips/syncing-secrets-across-namespaces.md @@ -0,0 +1,109 @@ +--- +title: Syncing Secrets Across Namespaces +description: | + Learn how to synchronize Kubernetes Secret resources across namespaces + using extensions such as: reflector and kubernetes-replicator. +--- + +It may be required for multiple components across namespaces to consume the same +`Secret` that has been created by a single `Certificate`. The recommended way to +do this is to use extensions such as: + - [reflector](https://github.com/emberstack/kubernetes-reflector) with support + for auto secret reflection + - [kubernetes-replicator](https://github.com/mittwald/kubernetes-replicator) secret replication + +## Serving a wildcard to ingress resources in different namespaces (default SSL certificate) + +Most ingress controllers, including [ingress-nginx](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#default-ssl-certificate), [Traefik](https://docs.traefik.io/https/tls/#default-certificate), and [Kong](https://docs.konghq.com/2.0.x/configuration/#ssl_cert) support specifying a _single_ certificate to be used for ingress resources which request TLS but do not specify `tls.[].secretName`. This is often referred to as a "default SSL certificate". As long as this is correctly configured, ingress resources in any namespace will be able to use a single wildcard certificate. Wildcard certificates are not supported with HTTP01 validation and require DNS01. + +Sample ingress snippet: + +``` +apiVersion: networking.k8s.io/v1 +kind: Ingress +#[...] +spec: + rules: + - host: service.example.com + #[...] + tls: + - hosts: + - service.example.com + #secretName omitted to use default wildcard certificate +``` + + +## Syncing arbitrary secrets across namespaces using extensions + +In order for the target Secret to be synced, you can use the `secretTemplate` field +for annotating the generated secret with the extension specific annotation (See [CertificateSecretTemplate]). + + +### Using `reflector` + The example below shows syncing a certificate's secret from the `cert-manager` namespace to multiple namespaces (i.e. `dev`, `staging`, `prod`). + Reflector will ensure that any namespace (existing or new) matching the allowed condition (with regex support) will get a copy of the certificate's secret and will keep it up to date. + You can also sync other secrets (different name) using `reflector` (consult the extension's [README](https://github.com/emberstack/kubernetes-reflector/blob/main/README.md)). + +```yaml +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: source + namespace: cert-manager +spec: + secretName: source-tls + commonName: source + issuerRef: + name: source-ca + kind: Issuer + group: cert-manager.io + secretTemplate: + annotations: + reflector.v1.k8s.emberstack.com/reflection-allowed: "true" + reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "dev,staging,prod" # Control destination namespaces + reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true" # Auto create reflection for matching namespaces + reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "dev,staging,prod" # Control auto-reflection namespaces +``` + +### Using `kubernetes-replicator` +Replicator supports both push- and pull-based replication. Push-based +replication will "push out" the TLS secret into namespaces when new ones are +created, or when the secret changes. Pull-based replication makes it possible +to create an empty TLS secret in the destination namespace and select a +"source" resource from which the data is replicated from. The following example +shows the pull-based approach: +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: source + namespace: cert-manager +spec: + secretName: source-tls + commonName: source + issuerRef: + name: source-ca + kind: Issuer + secretTemplate: + annotations: + replicator.v1.mittwald.de/replication-allowed: "true" # permit replication + replicator.v1.mittwald.de/replication-allowed-namespaces: "dev,test,prod-[0-9]*" # comma separated list of namespaces or regular expressions +--- +apiVersion: v1 +kind: Secret +metadata: + name: tls-secret-replica + namespace: prod-1 + annotations: + replicator.v1.mittwald.de/replicate-from: cert-manager/source-tls +type: kubernetes.io/tls +# Normally, we'd create an empty destination secret, but secrets of type +# 'kubernetes.io/tls' are treated in a special way and need to have properties +# data["tls.crt"] and data["tls.key"] to begin with, though they may be empty. +data: + tls.key: "" + tls.crt: "" +``` + +[CertificateSecretTemplate]: ../reference/api-docs.md#cert-manager.io/v1.CertificateSecretTemplate diff --git a/content/v1.15-docs/faq/README.md b/content/v1.15-docs/faq/README.md new file mode 100644 index 0000000000..577cfdc261 --- /dev/null +++ b/content/v1.15-docs/faq/README.md @@ -0,0 +1,237 @@ +--- +title: Frequently Asked Questions (FAQ) +description: Find answers to some frequently asked questions about cert-manager +--- + +On this page you will find answers to some frequently asked questions about cert-manager. + +## Terminology + +### What does `publicly trusted` and `self-signed` mean? + +These terms are defined in the [TLS Terminology page](../reference/tls-terminology.md). + +### What do the terms `root`, `intermediate` and `leaf` _certificate_ mean? + +These terms are defined in the [TLS Terminology page](../reference/tls-terminology.md). + +## Certificates + +### Can I trigger a renewal from cert-manager at will? + +This is a feature in cert-manager starting in `v0.16` using the `cmctl` CLI. More information can be found on [the renew command's page](../reference/cmctl.md#renew) + +### When do certs get re-issued? + +To determine if a certificate needs to be re-issued, cert-manager looks at the the spec of `Certificate` resource and latest `CertificateRequest`s as well as the data in `Secret` containing the X.509 certificate. + +The issuance process will always get triggered if the: + +- `Secret` named on `Certificate`'s spec, does not exist, is missing private key or certificate data or contains corrupt data +- private key stored in the `Secret` does not match the private key spec on `Certificate` +- public key of the issued certificate does not match the private key stored in the `Secret` +- cert-manager issuer annotations on the `Secret` do not match the issuer specified on the `Certificate` +- DNS names, IP addresses, URLS or email addresses on the issued certificate do not match those on the `Certificate` spec +- certificate needs to be renewed (because it has expired or the renewal time is now or in the past) +- certificate has been marked for renewal manually [using `cmctl`](../reference/cmctl.md#renew) + +Additionally, if the latest `CertificateRequest` for the `Certificate` is found, cert-manager will also re-issue if: + +- the common name on the CSR found on the `CertificateRequest` does not match that on the `Certificate` spec +- the subject fields on the CSR found on the `CertificateRequest` do not match the subject fields of the `Certificate` spec +- the duration on the `CertificateRequest` does not match the duration on the `Certificate` spec +- `isCA` field value on the `Certificate` spec does not match that on the `CertificateRequest` +- the DNS names, IP addresses, URLS or email addresses on the `CertificateRequest` spec do not match those on the `Certificate` spec +- key usages on the `CertificateRequest` spec do not match those on the `Certificate` spec + +Note that for certain fields re-issuance on change gets triggered only if there +is a `CertificateRequest` that cert-manager can use to determine whether +`Certificate`'s spec has changed since the previous issuance. This is because +some issuers may not respect the requested values for these fields, so we cannot +rely on the values in the issued X.509 certificates. One such field is +`.spec.duration`- change to this field will only trigger re-issuance if there is +a `CertificateRequest` to compare with. In case where you need to re-issue, but +re-issuance does not get triggered automatically due to there being no +`CertificateRequest` (i.e after backup and restore), you can use [`cmctl +renew`](../reference/cmctl.md#renew) to trigger it manually. + +### Why isn't my root certificate in my issued Secret's `tls.crt`? + +Occasionally, people work with systems which have made a flawed choice regarding TLS chains. The [TLS spec](https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.2) +has the following section for the "Server Certificate" section of the TLS handshake: + +> This is a sequence (chain) of certificates. The sender's +> certificate MUST come first in the list. Each following +> certificate MUST directly certify the one preceding it. Because +> certificate validation requires that root keys be distributed +> independently, the self-signed certificate that specifies the root +> certificate authority MAY be omitted from the chain, under the +> assumption that the remote end must already possess it in order to +> validate it in any case. + +In a standard, secure and correctly configured TLS environment, adding a root certificate to the chain is +almost always unnecessary and wasteful. + +There are two ways that a certificate can be trusted: + +- explicitly, by including it in a trust store. +- through a signature, by following the certificate's chain back up to an explicitly trusted certificate. + +Crucially, root certificates are by definition self-signed and they cannot be validated through a signature. + +As such, if we have a client trying to validate the certificate chain sent by the server, the client must already have the +root before the connection is started. If the client already has the root, there was no point in it being sent by the server! + +The same logic with not sending root certificates applies for servers trying to validate client certificates; +the [same justification](https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.6) is given in the TLS RFC. + + +### Why isn't my certificate's chain in my issued Secret's `ca.crt`? + +Users frequently ask us about changing `ca.crt` to include more certs or different certs. We tend to push back on these requests +for the simple reason that we believe `ca.crt` to most often be a risk for any user. + +`ca.crt` is filled by cert-manager with a "best guess" of what the issuing CA was. Importantly, cert-manager can often only guess; +if the issuer doesn't provide the full chain including the root certificate, there might be no way for cert-manager to know what the +root of the chain is. In that case, cert-manager will make a best-effort attempt to use the issuer deepest in the chain. + +That "best effort" attempt is one of the reasons that `ca.crt` can be risky; it might not be correct, and it might change when the issuer +changes even if nothing in cert-manager changes. + +The other issue with `ca.crt` is fundamental - it's updated when the certificate is updated. Some users can be tempted to use `ca.crt` +for trust purposes, but rotating trusted certificates safely relies on being able to have both the old and new CA certificates trusted at the same time. + +By consuming the CA directly from your Secret, it becomes impossible to do this; `ca.crt` will only ever contain the best effort guess +for the CA for the current certificate, and will never include an older or a new CA. + +### How can I see all the historic events related to a certificate object? + +cert-manager publishes all events to the Kubernetes events mechanism, you can get the events for your specific resources using `kubectl describe `. + +Due to the nature of the Kubernetes event mechanism these will be purged after a while. If you're using a dedicated logging system it might be able or is already also storing Kubernetes events. + +{/* This empty link preserves old links to #what-happens-if-a-renewal-doesn't happen?-will-it-be-tried-again-after-some-time?", which matched the old title of this section */} + +### What happens if issuance fails? Will it be retried? + +cert-manager will retry a failed issuance except for a few rare edge cases where +manual intervention is needed. + +We aim to retry after a short delay in case of ephemeral failures such as +network connection errors and with a longer exponentially increasing delay after +'terminal' failures. + +You can observe that latest issuance has terminally failed if the `Certificate` +has `Issuing` condition set to false and has `status.lastFailureTime` set. In +this case the issuance will be retried after an exponentially increasing delay +(1 to 32 hours) by creating a new `CertficateRequest`. You can trigger an +immediate renewal using the [`cmctl renew` +command](../reference/cmctl.md#renew). Terminal failures occur if the issuer +sets the `CertificateRequest` to failed (for example if CA rejected the request +due to a rate limit being reached) or invalid or if the `CertificateRequest` +gets denied by an approver. + +Ephemeral failures result in the same `CertificateRequest` being re-synced after +a short delay (up to 5 minutes). Typically they can only be observed in +cert-manager controller logs. + +If it appears the issuance has got stuck and `cmctl renew` does not work, you +can delete the latest `CertificateRequest`. This is mostly a harmless action +(the worst that could happen is duplicate issuance if there was a potentially +successful one in progress), but we do aim for this to not be part of user flow- +do reach out if you think you have found a case where the flow could be +improved. + +### Is ECC (elliptic-curve cryptography) supported? + +cert-manager supports ECDSA key pairs! You can set your certificate to use ECDSA in the `privateKey` part of your Certificate resource. + +For example: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: ecdsa +spec: + secretName: ecdsa-cert + isCA: false + privateKey: + algorithm: ECDSA + size: 256 + dnsNames: + - ecdsa.example.com + issuerRef: + [...] +``` + +### If `renewBefore` or `duration` is not defined, what will be the default value? + +Default `duration` is [90 days](https://github.com/cert-manager/cert-manager/blob/v1.13.3/pkg/apis/certmanager/v1/const.go#L26). If `renewBefore` has not been set, `Certificate` will be renewed 2/3 through its _actual_ duration. + + +### Why are passwords on JKS or PKCS#12 files not helpful? + +This question comes in many forms, including: + +- "Why is it OK to hard code these passwords?" +- "Do I need to keep these passwords secure?" +- "Are these passwords used in a secure way?" + +Specifically, this FAQ talks about passwords for PKCS#12 and JKS "keystores". + +#### Simple Answer + +"Passwords" on PKCS#12 or JKS files are almost always security theater, and they're only needed to support applications which are unable to parse password-less versions of these files. Even if you use a secure password for these files (which is rare), weak encryption algorithms and the management of the underlying material usually invalidate the secure password. + +We recommend that you treat these passwords as legacy implementation details, and use short hard-coded strings for these passwords when you're +forced to use one. Don't spend time trying to generate or handle "secure" passwords for these files - simply choose a constant such as `changeit` or `notapassword123` and use that for every PKCS#12 or JKS bundle you generate. + +#### Longer Answer + +Lots of people see the word "password" when handling JKS or PKCS#12 bundles and they draw the obvious +conclusion that it's a valuable security resource which needs to be handled carefully. + +This is generally not the case - not only are these passwords not really passwords, but they're also vanishingly unlikely to be meaningful for security of any kind. + +Mostly, these passwords exist only because some applications require some password to be set. That requirement is the sole reason for cert-manager and its sub-projects supporting setting a password on these types of bundles. + +There are several main reasons why we don't consider these passwords to be security critical: + +1. Most applications which use these passwords will mount the file containing the password in plain text right next to the bundle which uses it, with the same permissions and access control. This would make even the most secure password completely pointless as a security measure. +2. Most PKCS#12 and JKS bundles which are encrypted use extremely old encryption algorithms which are fundamentally insecure +3. The word "password" leads people to think of human-memorable passwords, which are not appropriate for this kind of encryption. This means that the passwords used are often themselves insecure in this context. +4. When we generate PKCS#12 or JKS files, they almost always live in the same Secret as an unencrypted private key anyway! + +Without a very detailed threat model and putting serious time into your system's architecture in an extremely paranoid way, spending time on these "passwords" is going to be a red herring time sink with little to no return. Your efforts would almost always be better spent on securing systems through other methods. + +See "simple answer" above for usage guidelines for these "passwords". + +## Miscellaneous + +### Kubernetes has a builtin `CertificateSigningRequest` API. Why not use that? + +Kubernetes has a [Certificate Signing Requests API], +and a [`kubectl certificates` command] which allows you to approve certificate signing requests +and have them signed by the certificate authority (CA) of the Kubernetes cluster. + +This API and CLI have occasionally been misused to sign certificates for use by non-control-plane Pods but this is a mistake. +For the security of the Kubernetes cluster, it is important to limit access to the Kubernetes certificate authority, +and it is important that you do not use that certificate authority to sign certificates which are used outside of the control-plane, +because such certificates increase the opportunity for attacks on the Kubernetes API server. + +In Kubernetes 1.19 the [Certificate Signing Requests API] has reached V1 +and it can be used more generally by following (or automating) the [Request Signing Process]. + +cert-manager currently has some [limited experimental support] for this resource. + +[Certificate Signing Requests API]: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#certificatesigningrequest-v1-certificates-k8s-io +[`kubectl certificates` command]: https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#certificate +[Request signing process]: https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#request-signing-process +[limited experimental support]: ../usage/kube-csr.md + +### How to write "cert-manager" + +cert-manager should always be written in lowercase. Even when it would normally be +capitalized such as in titles or at the start of sentences. A hyphen should always be +used between the words, don't replace it with a space and don't remove it. diff --git a/content/v1.15-docs/getting-started/README.md b/content/v1.15-docs/getting-started/README.md new file mode 100644 index 0000000000..fdfff463b9 --- /dev/null +++ b/content/v1.15-docs/getting-started/README.md @@ -0,0 +1,47 @@ +--- +title: Getting Started with cert-manager +description: Quick start guides for cert-manager +--- + + NGINX Ingress Controller icon + Let's Encrypt icon 292Jacob, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons + Learn how to deploy cert-manager and how to configure it to get certificates for the **NGINX Ingress controller** from **Let's Encrypt**. + + + + Google Kubernetes Engine icon + Let's Encrypt icon 292Jacob, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons + Learn how to deploy cert-manager on **Google Kubernetes Engine** and how to configure it to get certificates for Ingress, from **Let's Encrypt**. + + + + Azure Kubernetes Services icon + Let's Encrypt icon 292Jacob, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons + Learn how to deploy cert-manager on **Azure Kubernetes Service (AKS)** and how to configure it to get certificates for an HTTPS web server, from **Let's Encrypt**. + + + + Amazon Elastic Kubernetes Services icon + Let's Encrypt icon 292Jacob, CC BY-SA 4.0 <https://creativecommons.org/licenses/by-sa/4.0>, via Wikimedia Commons + Learn how to deploy cert-manager on **Amazon Elastic Kubernetes Service (EKS)** and how to configure it to get certificates for an HTTPS web server, from **Let's Encrypt**. + diff --git a/content/v1.15-docs/installation/README.md b/content/v1.15-docs/installation/README.md new file mode 100644 index 0000000000..1bde83069e --- /dev/null +++ b/content/v1.15-docs/installation/README.md @@ -0,0 +1,40 @@ +--- +title: Installation +description: Learn about the various ways you can install cert-manager and how to choose between them +--- + +Learn about the various ways you can install cert-manager and how to choose between them. + +## Default static install + +> You don't require any tweaking of the cert-manager install parameters. + +The default static configuration can be installed as follows: + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/[[VAR::cert_manager_latest_version]]/cert-manager.yaml +``` + +📖 Read more about [installing cert-manager using kubectl apply and static manifests](./kubectl.md). + +## Getting started + +> You quickly want to learn how to use cert-manager and what it can be used for. + +📖 **kubectl apply**: For new users we recommend [installing cert-manager using kubectl apply and static manifests](./kubectl.md). + +📖 **helm**: You can [use helm to install cert-manager](./helm.md) and this also allows you to customize the installation if necessary. + +📖 **OperatorHub**: If you have an OpenShift cluster, consider [installing cert-manager via OperatorHub](./operator-lifecycle-manager.md), +which you can do from the OpenShift web console. + +🚧 **cmctl**: Try the [experimental `cmctl x install` command](../reference/cmctl.md#install) to quickly install cert-manager. + +## Continuous deployment + +> If you know how to configure your cert-manager setup and want to automate this, +> you can use the cert-manager Helm chart directly with tools like Flux, ArgoCD and Anthos. +> Or you can output YAML using `helm template` to generate customized cert-manager installation manifests, +> which can be piped into your preferred deployment tool. + +📖 **Continuous Deployment**: Learn [how to automate the installation of cert-manager using tools like Flux and Argo CD](./continuous-deployment-and-gitops.md). diff --git a/content/v1.15-docs/installation/best-practice.md b/content/v1.15-docs/installation/best-practice.md new file mode 100644 index 0000000000..20a65fe197 --- /dev/null +++ b/content/v1.15-docs/installation/best-practice.md @@ -0,0 +1,555 @@ +--- +title: Best Practice +description: | + Learn about best practices for deploying cert-manager in production, + and how to configure cert-manager to comply with popular security standards + such as those produced by the CIS, NSA, and BSI. +--- + +In this section you will learn how to configure cert-manager to comply with popular security standards such as +the [CIS Kubernetes Benchmark](https://www.cisecurity.org/benchmark/kubernetes/), +the [NSA Kubernetes Hardening Guide](https://media.defense.gov/2022/Aug/29/2003066362/-1/-1/0/CTR_KUBERNETES_HARDENING_GUIDANCE_1.2_20220829.PDF), or +the [BSI Kubernetes Security Recommendations](https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Grundschutz/International/bsi_it_gs_comp_2022.pdf?__blob=publicationFile&v=2#page=475). + +And you will learn about best practices for deploying cert-manager in production; +such as those enforced by tools like [Datree and its built in rules](https://hub.datree.io/built-in-rules), +and those documented by the likes of [Learnk8s in their "Kubernetes production best practices" checklist](https://learnk8s.io/production-best-practices/). + +## Overview + +The default cert-manager resources in the Helm chart or YAML manifests (Deployment, Pod, ServiceAccount etc) +are designed for backwards compatibility rather than for best practice or maximum security. +You may find that the default resources do not comply with the security policy on your Kubernetes cluster +and in that case you can modify the installation configuration using Helm chart values to override the defaults. + +## Network Requirements and Network Policy + +The network requirements of each cert-manager Pod are summarized below. +Some network requirements depend on specific Issuer / ClusterIssuer configurations +and / or specific configuration options. + +When you have understood the network requirements of **your** cert-manager installation, +you should consider implementing a "least privilege" network policy, +using a [Kubernetes Network (CNI) Plugin](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/) such as [Calico](https://www.tigera.io/project-calico/). + +The network policy should prevent untrusted clients from connecting to the cert-manager Pods +and it should prevent cert-manager from connecting to untrusted servers. + +An example of this recommendation is found in the Calico Documentation: +> We recommend creating an implicit default deny policy for your Kubernetes pods, regardless of whether you use Calico or Kubernetes network policy. This ensures that unwanted traffic is denied by default. +> +> 📖 [Calico Best practice: implicit default deny policy](https://docs.tigera.io/calico/latest/network-policy/get-started/kubernetes-default-deny#best-practice-implicit-default-deny-policy). + +You can use the Kubernetes builtin `NetworkPolicy` resource, +which is portable because it is recognized by any of the [Kubernetes Network (CNI) Plugins](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/). +Or you may prefer to use the custom resources provided by your CNI software. + +> 📖 Learn about the [Kubernetes builtin NetworkPolicy API](https://kubernetes.io/docs/concepts/services-networking/network-policies/) +> and see [some example policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/#default-policies). + +### Network Requirements + +Here is an overview of the network requirements: + +1. **UDP / TCP: cert-manager (all) -> Kubernetes DNS**: + All cert-manager components perform UDP DNS queries for both cluster and external domain names. + Some DNS queries may use TCP. + +1. **TCP: Kubernetes (API server) -> cert-manager (webhook)**: + The Kubernetes API server establishes HTTPS connections to the [cert-manager webhook component](../concepts/webhook.md). + Read the cert-manager [webhook troubleshooting guide](../troubleshooting/webhook.md) + to understand the webhook networking requirements. + +1. **TCP: cert-manager (webhook, controller, cainjector, startupapicheck) -> Kubernetes API server**: + The cert-manager webhook, controller, cainjector and startupapicheck + establish HTTPS connections to the Kubernetes API server, + to interact with cert-manager custom resources and Kubernetes resources. + The cert-manager webhook is a special case; + it connects to the Kubernetes API server to use the `SubjectAccessReview` API, + to verify clients attempting to modify `Approved` or `Denied` conditions of `CertificateRequest` resources. + +1. **TCP: cert-manager (controller) -> HashiCorp Vault (authentication and resource API endpoints)**: + The cert-manager controller may establish HTTPS connections to one or more Vault API endpoints, + if you are using the [Vault Issuer](../configuration/vault.md). + The target host and port of the Vault endpoints + are configured in Issuer or ClusterIssuer resources. + +1. **TCP: cert-manager (controller) -> Venafi TLS Protect (authentication and resource API endpoints)**: + The cert-manager controller may establish HTTPS connections to one or more Venafi API endpoints, + if you are using the [Venafi Issuer](../configuration/venafi.md). + The target host and port of the Venafi API endpoints + are configured in Issuer or ClusterIssuer resources. + +1. **TCP: cert-manager (controller) -> DNS API endpoints (for ACME DNS01)**: + The cert-manager controller may establish HTTPS connections to DNS API endpoints such as Amazon Route53, + and to any associated authentication endpoints, + if you are using the [ACME Issuer with DNS01 solvers](../configuration/acme/dns01/README.md#supported-dns01-providers). + +1. **UDP / TCP: cert-manager (controller) -> External DNS**: + If you use the ACME Issuer, the cert-manager controller may send + DNS queries to recursive DNS servers, + as part of the ACME challenge self-check process. + It does this to ensure that the DNS01 or HTTP01 challenge is resolvable, + before asking the ACME server to perform its checks. + + In the case of DNS01 it may also perform a series of DNS queries to authoritative DNS servers, + to compute the DNS zone in which to add the DNS01 challenge record. + In the case of DNS01, cert-manager also [supports DNS over HTTPS](../releases/release-notes/release-notes-1.13.md#dns-over-https-doh-support). + + You can choose the host and port of the DNS servers, using the following [controller flags](../cli/controller.md): + `--acme-http01-solver-nameservers`, + `--dns01-recursive-nameservers`, and + `--dns01-recursive-nameservers-only`. + +1. **TCP: ACME (Let's Encrypt) -> cert-manager (acmesolver)**: + If you use an ACME Issuer configured for HTTP01, + cert-manager will deploy an `acmesolver` Pod, a Service and an Ingress (or Gateway API) resource + in the namespace of the Issuer + or in the cert-manager namespace if it is a ClusterIssuer. + The ACME implementation will establish an HTTP connection to this Pod via your chosen ingress load balancer, + so your network policy must allow this. + + > ℹ️ The acmesolver Pod **does not** require access to the Kubernetes API server. + +1. **TCP: Metrics Server -> cert-manager (controller)**: + The cert-manager controller has a metrics server which listens for HTTP connections on TCP port 9402. + Create a network policy which allows access to this service from your chosen metrics collector. + +## Isolate cert-manager on dedicated node pools + +cert-manager is a cluster scoped operator and you should treat it as part of your platform's control plane. +The cert-manager controller creates and modifies Kubernetes Secret resources +and the controller and cainjector both cache TLS Secret resources in memory. +These are two reasons why you should consider isolating the cert-manager components from +other less privileged workloads. +For example, if an untrusted or malicious workload runs on the same Node as the cert-manager controller, +and somehow gains root access to the underlying node, +it may be able to read the private keys in Secrets that the controller has cached in memory. + +You can mitigate this risk by running cert-manager on nodes that are reserved for trusted platform operators. + +The Helm chart for cert-manager has parameters to configure the Pod `tolerations` and `nodeSelector` for each component. +The exact values of these parameters will depend on your particular cluster. + +> 📖 Read [Assigning Pods to Nodes](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) +> in the [Kubernetes documentation](https://kubernetes.io/docs/). +> +> 📖 Read about [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) +> in the [Kubernetes documentation](https://kubernetes.io/docs/). + +### Example + +This example demonstrates how to use: +`taints` to *repel* non-platform Pods from Nodes which you have reserved for your platform's control-plane, +`tolerations` to *allow* cert-manager Pods to run on those Nodes, and +`nodeSelector` to *place* the cert-manager Pods on those Nodes. + +Label the Nodes: + +```bash +kubectl label node ... node-restriction.kubernetes.io/reserved-for=platform +``` + +Taint the Nodes: + +```bash +kubectl taint node ... node-restriction.kubernetes.io/reserved-for=platform:NoExecute +``` + +Then install cert-manager using the following Helm chart values: + +```yaml +nodeSelector: + kubernetes.io/os: linux + node-restriction.kubernetes.io/reserved-for: platform +tolerations: +- key: node-restriction.kubernetes.io/reserved-for + operator: Equal + value: platform + +webhook: + nodeSelector: + kubernetes.io/os: linux + node-restriction.kubernetes.io/reserved-for: platform + tolerations: + - key: node-restriction.kubernetes.io/reserved-for + operator: Equal + value: platform + +cainjector: + nodeSelector: + kubernetes.io/os: linux + node-restriction.kubernetes.io/reserved-for: platform + tolerations: + - key: node-restriction.kubernetes.io/reserved-for + operator: Equal + value: platform + +startupapicheck: + nodeSelector: + kubernetes.io/os: linux + node-restriction.kubernetes.io/reserved-for: platform + tolerations: + - key: node-restriction.kubernetes.io/reserved-for + operator: Equal + value: platform +``` + +> ℹ️ This example uses `nodeSelector` to *place* the Pods but you could also use `affinity.nodeAffinity`. +> `nodeSelector` is chosen here because it has a simpler syntax. +> +> ℹ️ The default `nodeSelector` value `kubernetes.io/os: linux` [avoids placing cert-manager Pods on Windows nodes in a mixed OS cluster](https://github.com/cert-manager/cert-manager/pull/3605), +> so that must be explicitly included here too. +> +> 📖 Read the [Guide to isolating tenant workloads to specific nodes](https://aws.github.io/aws-eks-best-practices/security/docs/multitenancy/#isolating-tenant-workloads-to-specific-nodes) +> in the [EKS Best Practice Guides](https://aws.github.io/aws-eks-best-practices/), +> for an in-depth explanation of these techniques. +> +> 📖 Learn how to [Isolate your workloads in dedicated node pools](https://cloud.google.com/kubernetes-engine/docs/how-to/isolate-workloads-dedicated-nodes) on [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/docs/). +> +> 📖 Learn about [Placing pods on specific nodes using node selectors, with RedHat OpenShift](https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-node-selectors.html). +> +> 📖 Read more about the [`node-restriction.kubernetes.io/` prefix and the `NodeRestriction` admission plugin](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction). +> +> ℹ️ On a multi-tenant cluster, +> consider enabling the [`PodTolerationRestriction` plugin](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#podtolerationrestriction) +> to limit which tolerations tenants may add to their Pods. +> You may also use that plugin to add default tolerations to the `cert-manager` namespace, +> which obviates the need to explicitly set the tolerations in the Helm chart. +> +> ℹ️ Alternatively, you could use [Kyverno](https://kyverno.io/docs/) to limit which tolerations Pods are allowed to use. +> Read [Restrict control plane scheduling](https://kyverno.io/policies/other/res/restrict-controlplane-scheduling/restrict-controlplane-scheduling/) as a starting point. + +## High Availability + +cert-manager has three long-running components: controller, cainjector, and webhook. +Each of these components has a Deployment and by default each Deployment has 1 replica +but this does not provide high availability. +The Helm chart for cert-manager has parameters to configure the `replicaCount` for each Deployment. +In production we recommend the following `replicaCount` parameters: + +```yaml +replicaCount: 2 +webhook: + replicaCount: 3 +cainjector: + replicaCount: 2 +``` + +### controller and cainjector + +The controller and cainjector components use [leader election](https://pkg.go.dev/k8s.io/client-go/tools/leaderelection) +to ensure that only one replica is active. +This prevents conflicts which would arise if multiple replicas were reconciling the same API resources. +So in these components you can use multiple replicas to achieve high availability but not for horizontal scaling. + +Use two replicas to ensures that there is a standby Pod scheduled to a Node which is ready to take leadership, +should the current leader encounter a disruption. +For example, when the leader Pod is drained from its node. +Or, if the leader Pod encounters an unexpected deadlock. + +There is little justification for using more than 2 replicas of these components. + +### webhook + +By default the cert-manager webhook Deployment has 1 replica, but in production you should use 3 or more. +If the cert-manager webhook is unavailable, all API operations on cert-manager custom resources will fail, +and this will disrupt any software that creates, updates or deletes cert-manager custom resources (including cert-manager itself), +and it may cause other disruptions to your cluster. +So it is *especially* important to keep at multiple replicas of the cert-manager webhook running at all times. + +> ℹ️ By contrast, if there is only a single replica of the cert-manager controller, there is less risk of disruption. +> For example, if the Node hosting the single cert-manager controller manager Pod is drained, +> there will be a delay while a new Pod is started on another Node, +> and any cert-manager resources that are created or changed during that time will not be reconciled until the new Pod starts up. +> But the controller manager works asynchronously anyway, so any applications which depend on the cert-manager custom resources +> will be designed to tolerate this situation. +> That being said, the best practice is to run 2 or more replicas of each controller if the cluster has sufficient resources. +> +> 📖 Read [Ensure control plane stability when using webhooks](https://cloud.google.com/kubernetes-engine/docs/how-to/optimize-webhooks) +> in the Google Kubernetes Engine (GKE) documentation, +> for examples of how webhook disruptions might disrupt your cluster. +> +> 📖 Read [The dark side of Kubernetes admission webhooks](https://techblog.cisco.com/blog/dark-side-of-kubernetes-admission-webhooks) +> on the Cisco Tech Blog, to learn more about potential issues caused by webhooks and how you can avoid them. + +### Topology Spread Constraints + +Consider using [Topology Spread Constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/), +to ensure that a disruption of a node or data center does not degrade the operation of cert-manager. + +For high availability you do not want the replica Pods to be scheduled on the same Node, +because if that node fails, both the active and standby Pods will exit, +and there will be no further reconciliation of the resources by that controller, +until there is another Node with sufficient free resources to run a new Pod, +and until that Pod has become Ready. + +It is also desirable for the Pods to be running in separate data centers (availability zones), +if the cluster has nodes distributed between zones. +Then, in the event of a failure at the data center hosting the active Pod , +the standby Pod will immediately be available to take leadership. + +Fortunately you may not need to do anything to achieve these goals +because [Kubernetes >= 1.24 has Built-in default constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/#internal-default-constraints) +which should mean that the high availability scheduling described above will happen implicitly. + +> ℹ️ In case your cluster does not use Built-in default constraints. +> You can add [Topology Spread Constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) +> to each of the cert-manager components using Helm chart values. + +### PodDisruptionBudget + +For high availability you should also deploy a `PodDisruptionBudget` resource with `minAvailable=1`. + +This ensures that a *voluntary* disruption, such as the draining of a Node, cannot proceed +until at least one other replica has been successfully scheduled and started on another Node. +The Helm chart has parameters to enable and configure a PodDisruptionBudget +for each of the long-running cert-manager components. +We recommend the following parameters: + +```yaml +podDisruptionBudget: + enabled: true + minAvailable: 1 +webhook: + podDisruptionBudget: + enabled: true + minAvailable: 1 +cainjector: + podDisruptionBudget: + enabled: true + minAvailable: 1 +``` + +> 📖 Read about [Specifying a Disruption Budget for your Application](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) in the Kubernetes documentation. +> +> ⚠️ These PodDisruptionBudget settings are only suitable for high availability deployments. +> You must increase the `replicaCount` of each Deployment to more than the `minAvailable` value, +> otherwise the PodDisruptionBudget will prevent you from draining cert-manager Pods. + +### Priority Class Name + +The reason for setting a priority class is summarized as follows in the Kubernetes blog [Protect Your Mission-Critical Pods From Eviction With `PriorityClass`](https://kubernetes.io/blog/2023/01/12/protect-mission-critical-pods-priorityclass/): +> Pod priority and preemption help to make sure that mission-critical pods are up in the event of a resource crunch by deciding order of scheduling and eviction. + +If cert-manager is mission-critical to your platform, +then set a `priorityClassName` on the cert-manager Pods +to protect them from [preemption](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#preemption), +in situations where a Kubernetes node becomes starved of resources. +Without a `priorityClassName` the cert-manager Pods may be evicted to free up resources for other Pods, +and this may cause disruption to any applications that rely on cert-manager. + +Most Kubernetes clusters will come with two builtin priority class names: +`system-cluster-critical` and `system-node-critical`, +which are used for Kubernetes core components. +These [can also be used for critical add-ons](https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/), +such as cert-manager. + +We recommend using the following Helm chart values to set `priorityClassName: system-cluster-critical`, for all cert-manager Pods: + +```yaml +global: + priorityClassName: system-cluster-critical +``` + +On some clusters the [`ResourceQuota` admission controller](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#resourcequota) may be configured to [limit the use of certain priority classes to certain namespaces](https://kubernetes.io/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default). +For example, Google Kubernetes Engine (GKE) will only allow `priorityClassName: system-cluster-critical` for Pods in the `kube-system` namespace, +by default. + +> 📖 Read [Kubernetes PR #93121](https://github.com/kubernetes/kubernetes/pull/93121) to see how and why this was implemented. + +In such cases you will need to create a `ResourceQuota` in the `cert-manager` namespace: + +```yaml +# cert-manager-resourcequota.yaml +apiVersion: v1 +kind: ResourceQuota +metadata: + name: cert-manager-critical-pods + namespace: cert-manager +spec: + hard: + pods: 1G + scopeSelector: + matchExpressions: + - operator: In + scopeName: PriorityClass + values: + - system-node-critical + - system-cluster-critical +``` + +```sh +kubectl apply -f cert-manager-resourcequota.yaml +``` + +> 📖 Read [Protect Your Mission-Critical Pods From Eviction With `PriorityClass`](https://kubernetes.io/blog/2023/01/12/protect-mission-critical-pods-priorityclass/), a Kubernetes blog post about how Pod priority and preemption help to make sure that mission-critical pods are up in the event of a resource crunch by deciding order of scheduling and eviction. +> +> 📖 Read [Guaranteed Scheduling For Critical Add-On Pods](https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/) to learn why `system-cluster-critical` should be used for add-ons that are critical to a fully functional cluster. +> +> 📖 Read [Limit Priority Class consumption by default](https://kubernetes.io/docs/concepts/policy/resource-quotas/#limit-priority-class-consumption-by-default), to learn why platform administrators might restrict usage of certain high priority classes to a limited number of namespaces. +> +> 📖 Some examples of other critical add-ons that use the `system-cluster-critical` priority class name: +> [NVIDIA GPU Operator](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/google-gke.html), +> [OPA Gatekeeper](https://github.com/open-policy-agent/gatekeeper/pull/1282), +> [Cilium](https://github.com/cilium/cilium/pull/13878). + +## Scalability + +cert-manager has three long-running components: controller, cainjector, and webhook. +The Helm chart does not include resource requests and limits for any of these, +so you should supply resource requests and limits which are appropriate for your cluster. + +### controller and cainjector + +The controller and cainjector components use leader election to ensure that only one replica is active. +This prevents conflicts which would arise if multiple replicas were reconciling the same API resources. +You cannot use horizontal scaling for these components. +Use vertical scaling instead. + +#### Memory + +Use vertical scaling to assign sufficient memory resources to these components. +The memory requirements will be higher on clusters with very many API resources or with large API resources. +This is because each of the components reconciles one or more Kubernetes API resources, +and each component will cache the metadata and sometimes the entire resource in memory, +so as to reduce the load on the Kubernetes API server. + +If your cluster contains a high volume of `CertificateRequest` resources such as when using many ephemeral or short lived certificates rotated frequently, +you will need to increase the memory limit of the controller Pod. + +You can also reduce the memory consumption of `cainjector` +by configuring it to only watch resources in the `cert-manager` namespace, +and by configuring it to **not** watch `Certificate` resources. +Here's how to configure the [cainjector command line flags](../cli/cainjector.md) using Helm chart values: + +```yaml +cainjector: + extraArgs: + - --namespace=cert-manager + - --enable-certificates-data-source=false +``` + +> ⚠️️ This optimization is only appropriate if `cainjector` is being used exclusively for the the cert-manager webhook. +> It is not appropriate if `cainjector` is also being used to manage the TLS certificates for webhooks of other software. +> For example, some Kubebuilder derived projects may depend on `cainjector` +> to [inject TLS certificates for their webhooks](https://book.kubebuilder.io/cronjob-tutorial/running-webhook.html#cert-manager). + +#### CPU + +Use vertical scaling to assign sufficient CPU resources to the these components. +The CPU requirements will be higher on clusters where there are very frequent updates to the resources which are reconciled by these components. +Whenever a resource changes, it will be queued to be re-reconciled by the component. +Higher CPU resources allow the component to process the queue faster. + +### webhook + +The cert-manager webhook does not use leader election, so you *can* scale it horizontally by increasing the number of replicas. +When the Kubernetes API server connects to the cert-manager webhook it does so via a Service which load balances the connections +between all the Ready replicas. +For this reason, there is a clear benefit to increasing the number of webhook replicas to 3 or more, +on clusters where there is a high frequency of cert-manager custom resource interactions. +Furthermore, the webhook has modest memory requirements because it does not use a cache. +For this reason, the resource cost of scaling out the webhook is relatively low. + +## Use Liveness Probes + +An example of this recommendation is found in the Datree Documentation: +[Ensure each container has a configured liveness probe](https://hub.datree.io/built-in-rules/ensure-liveness-probe): +> Liveness probes allow Kubernetes to determine when a pod should be replaced. +> They are fundamental in configuring a resilient cluster architecture. + +The cert-manager webhook and controller Pods do have liveness probes. +The cainjector Pod does not have a liveness probe, yet. +More information below. + +### webhook + +The [cert-manager webhook](../concepts/webhook.md) has a [liveness probe which is enabled by default](https://github.com/cert-manager/cert-manager/blob/eafe0d0aae4b7a9411825424f6b43fb623e1ba65/deploy/charts/cert-manager/templates/webhook-deployment.yaml#L108C1-L121) +and the [timings and thresholds can be configured using Helm values](https://github.com/cert-manager/cert-manager/blob/eafe0d0aae4b7a9411825424f6b43fb623e1ba65/deploy/charts/cert-manager/README.template.md?plain=1#L181-L185). + +### controller + +> 📢 The cert-manager controller liveness probe was introduced in cert-manager release `1.12` and +> enabled by default in release `1.14`. In case it causes problems in the field, +> [Please get in touch](../contributing/README.md). + +The liveness probe for the cert-manager controller is an HTTP probe which connects +to the `/livez` endpoint of a healthz server which listens on port 9443 and runs in its own thread. +The `/livez` endpoint currently reports the combined status of the following sub-systems +and each sub-system has its own `/livez` endpoint. These are: + +* `/livez/leaderElection`: Returns an error if the leader election record has not been renewed + or if the leader election thread has exited without also crashing the parent process. +* `/livez/clockHealth`: Returns an error if a clock skew is detected between the system clock + and the monotonic clock used by Go to schedule timers. + +> ℹ️ In future more sub-systems could be checked by the `/livez` endpoint, +> similar to how Kubernetes [ensure logging is not blocked](https://github.com/kubernetes/kubernetes/pull/64946) +> and have [health checks for each controller](https://github.com/kubernetes/kubernetes/pull/104667). +> +> 📖 Read about [how to access individual health checks and verbose status information](https://kubernetes.io/docs/reference/using-api/health-checks/) (cert-manager uses the same healthz endpoint multiplexer as Kubernetes). + +### cainjector + +The cainjector Pod does not have a liveness probe or a `/livez` healthz endpoint, +but there is justification for it in the GitHub issue: +[cainjector in a zombie state after attempting to shut down](https://github.com/cert-manager/cert-manager/issues/5889). +Please add your remarks to that issue if you have also experienced this specific problem, +and add your remarks to [Helm: Allow configuration of readiness, liveness and startup probes for all created Pods](https://github.com/cert-manager/cert-manager/issues/5626) if you have a general request for a liveness probe in cainjector. + +### Background Information + +The cert-manager `controller` process and the `cainjector` process, +both use the Kubernetes [leader election library](https://pkg.go.dev/k8s.io/client-go/tools/leaderelection), +to ensure that only one replica of each process can be active at any one time. +The Kubernetes control-plane components also use this library. + +The leader election code runs in a loop in a separate thread (go routine). +If it initially wins the leader election race and if it later fails to renew its leader election lease, it exits. +If the leader election thread exits, all the other threads are gracefully shutdown and then the process exits. +Similarly, if any of the other main threads exit unexpectedly, +that will trigger the orderly shutdown of the remaining threads and the process will exit. + +This adheres to the principle that [Containers should crash when there's a fatal error](https://blog.colinbreck.com/kubernetes-liveness-and-readiness-probes-revisited-how-to-avoid-shooting-yourself-in-the-other-foot/#letitcrash). +Kubernetes will restart the crashed container, and if it crashes repeatedly, +there will be increasing time delays between successive restarts. + +For this reason, the liveness probe should only be needed if there is a bug in this orderly shutdown process, +or if there is a bug in one of the other threads which causes the process to deadlock and not shutdown. + +> 📖 Read [Configure Liveness, Readiness and Startup Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#before-you-begin) in the Kubernetes documentation, paying particular attention to the notes and cautions in that document. +> +> 📖 Read [Shooting Yourself in the Foot with Liveness Probes](https://blog.colinbreck.com/kubernetes-liveness-and-readiness-probes-how-to-avoid-shooting-yourself-in-the-foot/#shootingyourselfinthefootwithlivenessprobes) for more cautionary information about liveness probes. + +## Restrict Auto-Mount of Service Account Tokens + +This recommendation is described in the [Kyverno Policy Catalogue](https://kyverno.io/policies/other/res/restrict-automount-sa-token/restrict-automount-sa-token/) as follows: +> Kubernetes automatically mounts ServiceAccount credentials in each Pod. The +> ServiceAccount may be assigned roles allowing Pods to access API resources. +> Blocking this ability is an extension of the least privilege best practice and +> should be followed if Pods do not need to speak to the API server to function. +> This policy ensures that mounting of these ServiceAccount tokens is blocked + +The cert-manager components *do* need to speak to the API server but we still recommend setting `automountServiceAccountToken: false` for the following reasons: +1. Setting `automountServiceAccountToken: false` will allow cert-manager to be installed on clusters where Kyverno (or some other policy system) is configured to deny Pods that have this field set to `true`. The Kubernetes default value is `true`. +2. With `automountServiceAccountToken: true`, *all* the containers in the Pod will mount the ServiceAccount token, including side-car and init containers that might have been injected into the cert-manager Pod resources by Kubernetes admission controllers. + The principle of least privilege suggests that it is better to explicitly mount the ServiceAccount token into the cert-manager containers. + +So it is recommended to set `automountServiceAccountToken: false` and manually add a projected `Volume` to each of the cert-manager Deployment resources, containing the ServiceAccount token, CA certificate and namespace files that would normally be [added automatically by the Kubernetes ServiceAccount controller](https://github.com/kubernetes/kubernetes/blob/3992eda8e61725c470fb6141a7fe4e7f9ee31ea5/plugin/pkg/admission/serviceaccount/admission.go#L421-L460), +and to explicitly add a read-only `VolumeMount` to each of the cert-manager containers. + +An example of this configuration is included in the Helm Chart Values file below. + +## Best Practice Helm Chart Values + +Download the following Helm chart values file and supply it to `helm install`, `helm upgrade`, or `helm template` using the `--values` flag: + +🔗 `values.best-practice.yaml` +```yaml file=../../../public/docs/installation/best-practice/values.best-practice.yaml +``` + +## Other + +This list of recommendations is a work-in-progress. +If you have other best practice recommendations please [contribute to this page](../contributing/contributing-flow.md). diff --git a/content/v1.15-docs/installation/code-signing.md b/content/v1.15-docs/installation/code-signing.md new file mode 100644 index 0000000000..1063bb6eb6 --- /dev/null +++ b/content/v1.15-docs/installation/code-signing.md @@ -0,0 +1,65 @@ +--- +title: cert-manager Signature Verification +description: 'cert-manager installation: Code signing' +--- + +To help prevent [supply chain attacks](https://en.wikipedia.org/wiki/Supply_chain_attack), some cert-manager release +artifacts are cryptographically signed so you can be sure that the version of cert-manager you're about to install +is actually built by and provided by the cert-manager maintainers. + +This signing is vitally important if for any reason you need to use a mirrored version of cert-manager; it allows you +to confirm that the mirror hasn't tampered with the code you're about to install. + +Signing keys required for verification are all available on this website, but the actual key that you need might depend +on the artifact you're trying to validate in the future. At the time of writing, all signing is done using the same underlying +key. + +## Container Images / Cosign + +For all cert-manager versions from `v1.8.0` and later, cert-manager container images are signed and verifiable using [`cosign`](https://docs.sigstore.dev/cosign/overview). + +```console +IMAGE_TAG=[[VAR::cert_manager_latest_version]] # change as needed +KEY=https://cert-manager.io/public-keys/cert-manager-pubkey-2021-09-20.pem +cosign verify --signature-digest-algorithm sha512 --insecure-ignore-tlog --key $KEY quay.io/jetstack/cert-manager-acmesolver:$IMAGE_TAG +cosign verify --signature-digest-algorithm sha512 --insecure-ignore-tlog --key $KEY quay.io/jetstack/cert-manager-cainjector:$IMAGE_TAG +cosign verify --signature-digest-algorithm sha512 --insecure-ignore-tlog --key $KEY quay.io/jetstack/cert-manager-ctl:$IMAGE_TAG +cosign verify --signature-digest-algorithm sha512 --insecure-ignore-tlog --key $KEY quay.io/jetstack/cert-manager-startupapicheck:$IMAGE_TAG +cosign verify --signature-digest-algorithm sha512 --insecure-ignore-tlog --key $KEY quay.io/jetstack/cert-manager-controller:$IMAGE_TAG +cosign verify --signature-digest-algorithm sha512 --insecure-ignore-tlog --key $KEY quay.io/jetstack/cert-manager-webhook:$IMAGE_TAG +``` + +For a more fully-featured signature verification process in Kubernetes, check out [`connaisseur`](https://sse-secure-systems.github.io/connaisseur/). + +- PEM-encoded public key: [`cert-manager-pubkey-2021-09-20.pem`](https://cert-manager.io/public-keys/cert-manager-pubkey-2021-09-20.pem) + +### Why `--insecure-ignore-tlog`? + +We'd rather not have an flag which says `insecure` in the verification command and it's our intention to fix that some time in the future. For now, +ignoring the transparency log makes verification work. + +Note that the cert-manager key is stored in Google Cloud KMS, and is used by Google Cloud Build only when a cert-manager release is being signed. + +## Helm Charts + +
+Helm requires the use of PGP for verification; the key format is different. + +Trying to use "plain" PEM encoded public keys during verification will fail. +
+ +For all cert-manager versions from `v1.6.0` and later, Helm charts are signed and verifiable through the Helm CLI. + +The easiest way to verify is to grab the GPG keyring directly, which can then be passed into `helm verify` like so: + +```console +curl -sSL https://cert-manager.io/public-keys/cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg > cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg +helm verify --keyring cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg /path/to/cert-manager-vx.y.z.tgz +``` + +- GPG keyring: [`cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg`](https://cert-manager.io/public-keys/cert-manager-keyring-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.gpg) + +If you know what you're doing and you want the signing key in a format that's easy to import into GPG, +it's available in an ASCII armored version: + +- ASCII-armored signing key: [`cert-manager-pgp-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.asc`](https://cert-manager.io/public-keys/cert-manager-pgp-2021-09-20-1020CF3C033D4F35BAE1C19E1226061C665DF13E.asc) diff --git a/content/v1.15-docs/installation/compatibility.md b/content/v1.15-docs/installation/compatibility.md new file mode 100644 index 0000000000..516bc941a0 --- /dev/null +++ b/content/v1.15-docs/installation/compatibility.md @@ -0,0 +1,114 @@ +--- +title: Compatibility with Kubernetes Platform Providers +description: 'cert-manager installation: Cloud provider compatibility' +--- + +Below you will find details on various compatibility issues and quirks that you +may be affected by when deploying cert-manager. If you believe we've missed something +please feel free to raise an issue or a pull request with the details! + +
+If you're using AWS Fargate or else if you've specifically configured +cert-manager to run the host's network, be aware that kubelet listens on port +`10250` by default which clashes with the default port for the cert-manager +webhook. + +As such, you'll need to change the webhook's port when setting up cert-manager. + +For installations using Helm, you can set the `webhook.securePort` parameter +when installing cert-manager either using a command line flag or an entry in +your `values.yaml` file. + +If you have a port clash, you could see confusing error messages regarding +untrusted certs. See [#3237](https://github.com/cert-manager/cert-manager/issues/3237) +for more details. +
+ +## GKE + +When Google configure the control plane for private clusters, they automatically +configure VPC peering between your Kubernetes cluster's network and a separate +Google-managed project. + +In order to restrict what Google are able to access within your cluster, the +firewall rules configured restrict access to your Kubernetes pods. This means +that the webhook won't work, and you'll see errors such as +`Internal error occurred: failed calling admission webhook ... the server is +currently unable to handle the request`. + +In order to use the webhook component with a GKE private cluster, you must +configure an additional firewall rule to allow the GKE control plane access to +your webhook pod. + +You can read more information on how to add firewall rules for the GKE control +plane nodes in the [GKE +docs](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules). + + +### GKE Autopilot + +GKE Autopilot mode with Kubernetes < 1.21 does not support cert-manager, +due to a [restriction on mutating admission webhooks](https://github.com/cert-manager/cert-manager/issues/3717). + +As of October 2021, only the "rapid" Autopilot release channel has rolled +out version 1.21 for Kubernetes masters. Installation via the helm chart +may end in an error message but cert-manager is reported to be working by +some users. Feedback and PRs are welcome. + +**Problem**: GKE Autopilot does not allow modifications to the `kube-system`-namespace. + +Historically we've used the `kube-system` namespace to prevent multiple installations of cert-manager in the same cluster. + +Installing cert-manager in these environments with default configuration can cause issues with bootstrapping. +Some signals are: + +* `cert-manager-cainjector` logging errors like: + +```text +E0425 09:04:01.520150 1 leaderelection.go:334] error initially creating leader election record: leases.coordination.k8s.io is forbidden: User "system:serviceaccount:cert-manager:cert-manager-cainjector" cannot create resource "leases" in API group "coordination.k8s.io" in the namespace "kube-system": GKEAutopilot authz: the namespace "kube-system" is managed and the request's verb "create" is denied +``` + +* `cert-manager-startupapicheck` not completing and logging messages like: + +```text +Not ready: the cert-manager webhook CA bundle is not injected yet +``` + +**Solution**: Configure cert-manager to use a different namespace for leader election, like this: + +```console +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version ${CERT_MANAGER_VERSION} --set global.leaderElection.namespace=cert-manager +``` + +The implication for a `kubectl apply` type installation is then either "you must manually update the manifests prior to installation by replacing `kube-system` with cert-manager" or "Don't install cert-manager using kubectl apply. Helm is the recommended solution". + +## AWS EKS + +When using a custom CNI (such as Weave or Calico) on EKS, the webhook cannot be +reached by cert-manager. This happens because the control plane cannot be +configured to run on a custom CNI on EKS, so the CNIs differ between control +plane and worker nodes. + +To address this, the webhook can be run in the host network so it can be reached +by cert-manager, by setting the `webhook.hostNetwork` key to true on your +deployment, or, if using Helm, configuring it in your `values.yaml` file. + +Note that running on the host network will necessitate changing the webhook's +port; see the warning at the top of the page for details. + +### AWS Fargate + +It's worth noting that using AWS Fargate doesn't allow much network configuration and +will cause the webhook's port to clash with the kubelet running on port 10250, as seen +in [#3237](https://github.com/cert-manager/cert-manager/issues/3237). + +When deploying cert-manager on Fargate, you _must_ change the port on which +the webhook listens. See the warning at the top of this page for more details. + +Because Fargate forces you to use its networking, you cannot manually set the networking +type and options such as `webhook.hostNetwork` on the helm chart will cause your +cert-manager deployment to fail in surprising ways. diff --git a/content/v1.15-docs/installation/configuring-components.md b/content/v1.15-docs/installation/configuring-components.md new file mode 100644 index 0000000000..20f90436f0 --- /dev/null +++ b/content/v1.15-docs/installation/configuring-components.md @@ -0,0 +1,100 @@ +--- +title: cert-manager component configuration +description: 'Configure cert-manager components using CLI flags or a configuration file' +--- + +To configure the cert-manager components, you can use CLI flags or a configuration file. +The CLI flags take precedence over the configuration file. + +## CLI flags + +An overview of the available CLI flags for each component can be found on the following pages: +- cert-manager controller: [controller CLI flags](../cli/controller.md) +- cert-manager webhook: [webhook CLI flags](../cli/webhook.md) +- cert-manager cainjector: [cainjector CLI flags](../cli/cainjector.md) +- cert-manager acmesolver: [acmesolver CLI flags](../cli/acmesolver.md) +- cert-manager cmctl: [cmctl CLI flags](../cli/cmctl.md) + +When using the Helm chart, the CLI flags can be specified in the `extraArgs`, `webhook.extraArgs`, `cainjector.extraArgs` and `acmesolver.extraArgs` values. + +## Configuration file + +The configuration file is a YAML file that contains the configuration for the cert-manager components. +The configuration file can be specified using the `--config` CLI flag. When using the Helm chart, the +configuration file can be specified in the `config` and `webhook.config` values. + +### Controller configuration file + +The webhook configuration API documentation can be found on the [ControllerConfiguration](../reference/api-docs.md#controller.config.cert-manager.io/v1alpha1.ControllerConfiguration) page. + +This is an example configuration file for the controller component: + +```yaml +apiVersion: controller.config.cert-manager.io/v1alpha1 +kind: ControllerConfiguration + +logging: + verbosity: 2 + format: text + +leaderElectionConfig: + namespace: my-namespace + +kubernetesAPIQPS: 10 +kubernetesAPIBurst: 50 + +numberOfConcurrentWorkers: 200 + +enableGatewayAPI: true + +featureGates: + AdditionalCertificateOutputFormats: true + ExperimentalCertificateSigningRequestControllers: true + ServerSideApply: true + LiteralCertificateSubject: true + UseCertificateRequestBasicConstraints: true + OtherNames: true + NameConstraints: true +``` + +> **Note:** This is included as an example only and not intended to be used as default settings. + +### Webhook configuration file + +The webhook configuration API documentation can be found on the [WebhookConfiguration](../reference/api-docs.md#webhook.config.cert-manager.io/v1alpha1.WebhookConfiguration) page. + +Here is an example configuration file for the webhook component: + +```yaml +apiVersion: webhook.config.cert-manager.io/v1alpha1 +kind: WebhookConfiguration + +logging: + verbosity: 2 + format: text + +securePort: 6443 +healthzPort: 6080 + +featureGates: + AdditionalCertificateOutputFormats: true + LiteralCertificateSubject: true + OtherNames: true + NameConstraints: true +``` + +> **Note:** This is included as an example only and not intended to be used as default settings. + +## Feature gates + +Feature gates can be used to enable or disable experimental features in cert-manager. + +There are 2 levels of feature gates (more details in [Kubernetes definition of feature stages](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-stages)): +- **Alpha:** feature is not yet stable and might be removed or changed in the future. Alpha features are disabled by default and need to be explicitly enabled by the user (to test the feature). +- **Beta:** feature is almost stable but might still change in the future. Beta features are enabled by default and can be disabled by the user (if any issues are encountered). + +Each cert-manager component has its own set of feature gates. They can be enabled/ disabled using the `--feature-gates` flag or the `featureGates` value in the config file. The available feature gates for each component can be found on the following pages: + +- cert-manager controller: [controller feature gates](https://github.com/cert-manager/cert-manager/blob/master/internal/controller/feature/features.go) +- cert-manager webhook: [webhook feature gates](https://github.com/cert-manager/cert-manager/blob/master/internal/webhook/feature/features.go) +- cert-manager cainjector: [cainjector feature gates](https://github.com/cert-manager/cert-manager/blob/master/internal/cainjector/feature/features.go) diff --git a/content/v1.15-docs/installation/continuous-deployment-and-gitops.md b/content/v1.15-docs/installation/continuous-deployment-and-gitops.md new file mode 100644 index 0000000000..d5c619d5be --- /dev/null +++ b/content/v1.15-docs/installation/continuous-deployment-and-gitops.md @@ -0,0 +1,115 @@ +--- +title: Continuous Deployment +description: Learn how to automate the installation of cert-manager using tools like Flux and Argo CD +--- + +Learn how to automate the installation of cert-manager using tools like Flux and Argo CD. + +## Introduction + +You can use [the cert-manager Helm chart](./helm.md) directly with tools like Flux, ArgoCD and Anthos, +and you can [output YAML using helm template](./helm.md#output-yaml) to generate customized cert-manager installation manifests, +which can be piped into your preferred deployment tool. + +This page contains notes about how to install cert-manager with *some* of these tools. + +> 📢 Please help us improve this page +> by contributing notes or short tutorials about using cert-manager with common GitOps and continuous deployment tools. + +## Using the Flux Helm Controller + +The cert-manager Helm chart can be installed by the [Flux Helm Controller](https://fluxcd.io/flux/components/helm/). + +First create a [`HelmRepository` resource](https://fluxcd.io/flux/components/source/helmrepositories/), +configured with URL of the cert-manager Helm repository. +Then create a [`HelmRelease` resource](https://fluxcd.io/flux/components/helm/helmreleases/), +configured with your desired cert-manager chart values and release. + +Here is an example which installs the latest patch version of the cert-manager 1.12 release, +and then upgrades to the latest patch version of the 1.13 release. + +> ⚠️ This is a simple example which may not be suitable for production use. +> You should also refer to the [official Flux example repo](https://github.com/fluxcd/flux2-kustomize-helm-example), +> where cert-manager is now fully integrated. +> It shows how to deploy ClusterIssuer resources in the right order, +> after cert-manager CRDs and controller have been installed. + +### Prerequisites + +You'll need the [`flux` CLI](https://fluxcd.io/flux/cmd/) +and a Kubernetes cluster with [Flux installed](https://fluxcd.io/flux/installation/). + +Here's how to quickly install Flux on a [Kind](https://kind.sigs.k8s.io/) cluster: + +```bash +kind create cluster +flux check --pre +flux install +flux check +``` + +### Create a `HelmRepository` resource + +```bash +flux create source helm cert-manager --url https://charts.jetstack.io +``` + +### Create a `HelmRelease` resource + +Put your Helm chart values in a `values.yaml` file. +Use the `crds.enabled` value, so that Flux can install and upgrade the CRD resources. + +```yaml +# values.yaml +crds: + enabled: true +``` + +```bash +flux create helmrelease cert-manager \ + --chart cert-manager \ + --source HelmRepository/cert-manager.flux-system \ + --release-name cert-manager \ + --target-namespace cert-manager \ + --create-target-namespace \ + --values values.yaml \ + --chart-version 1.12.x +``` + +### Updates and Upgrades + +And when you want to upgrade to the cert-manager 1.13 release, +you can simply update the partial semantic version in the chart version: + +```bash +flux create helmrelease cert-manager \ + --chart cert-manager \ + --source HelmRepository/cert-manager.flux-system \ + --release-name cert-manager \ + --target-namespace cert-manager \ + --create-target-namespace \ + --values values.yaml \ + --chart-version 1.13.x +``` + +### Troubleshooting + +Check Flux events and logs for warnings and errors: + +```bash +flux events +flux logs +``` + +Use `cmctl` to check for problems with the cert-manager webhook or CRDs: + +```bash +cmctl check api +cmctl version -o yaml +``` + +Check the cert-manager logs for warnings and errors: + +```bash +kubectl logs -n cert-manager -l app.kubernetes.io/instance=cert-manager --prefix --all-containers +``` diff --git a/content/v1.15-docs/installation/helm.md b/content/v1.15-docs/installation/helm.md new file mode 100644 index 0000000000..444d45e21b --- /dev/null +++ b/content/v1.15-docs/installation/helm.md @@ -0,0 +1,206 @@ +--- +title: Helm +description: 'cert-manager installation: Using Helm' +--- + +## Installing with Helm + +cert-manager provides Helm charts as a first-class method of installation on both Kubernetes and OpenShift. + +Be sure never to embed cert-manager as a sub-chart of other Helm charts; cert-manager manages +non-namespaced resources in your cluster and care must be taken to ensure that it is installed exactly once. + +### Prerequisites + +- [Install Helm version 3 or later](https://helm.sh/docs/intro/install/). +- Install a [supported version of Kubernetes or OpenShift](../releases/README.md). +- Read [Compatibility with Kubernetes Platform Providers](./compatibility.md) if you are using Kubernetes on a cloud platform. + +### Installing cert-manager + +#### 1. Add the Helm repository + +This repository is the only supported source of cert-manager charts. There are some other mirrors and copies across the internet, but those are entirely unofficial and could present a security risk. + +Notably, the "Helm stable repository" version of cert-manager is deprecated and should not be used. + +```bash +helm repo add jetstack https://charts.jetstack.io --force-update +``` + +#### 2. Install cert-manager + +To install the cert-manager Helm chart, use the [Helm install command](https://helm.sh/docs/helm/helm_install/) as described below. + +```bash +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version [[VAR::cert_manager_latest_version]] \ + --set crds.enabled=true +``` + +#### 3. (optional) Verify installation + +Once you have deployed cert-manager, you can [verify](./kubectl.md#verify) the installation. + +### Installation options + +A full list of available Helm values is on [cert-manager's ArtifactHub page](https://artifacthub.io/packages/helm/cert-manager/cert-manager). + +The example below shows how to tune the cert-manager installation by overwriting the default Helm values: + +```bash +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version [[VAR::cert_manager_latest_version]] \ + --set crds.enabled=true \ + --set prometheus.enabled=false \ # Example: disabling prometheus using a Helm parameter + --set webhook.timeoutSeconds=4 # Example: changing the webhook timeout using a Helm parameter +``` + +### Installing cert-manager as subchart + +If you have configured cert-manager as a subchart all the components of cert-manager will be installed into the namespace of the helm release you are installing. + +There may be a situation where you want to specify the namespace to install cert-manager different to the umbrella chart's namespace. + +This is a [known issue](https://github.com/helm/helm/issues/5358) with helm and subcharts, that you can't specify the namespace for the subchart and is being solved by most public charts by allowing users to set the namespace via the values file, but needs to be a capability added to the chart by the maintainers. + +This capability is now available in the cert-manager chart and can be set either in the values file or via the `--set` switch. + +#### Example usage + +Below is an example `Chart.yaml` with cert-manager as a subchart + +```yaml +apiVersion: v2 +name: example_chart +description: A Helm chart with cert-manager as subchart +type: application +version: 0.1.0 +appVersion: "0.1.0" +dependencies: + - name: cert-manager + version: [[VAR::cert_manager_latest_version]] + repository: https://charts.jetstack.io + alias: cert-manager + condition: cert-manager.enabled +``` + +You can then override the namespace in 2 ways: + +1. In `Values.yaml` file +```yaml +cert-manager: #defined by either the name or alias of your dependency in Chart.yaml + namespace: security +``` + +2. In the helm command using `--set` +```bash +helm install example example_chart \ + --namespace example \ + --create-namespace \ + --set cert-manager.namespace=security +``` + +The above example will install cert-manager into the security namespace. + +## Output YAML + +Instead of directly installing cert-manager using Helm, a static YAML manifest can be created using the [Helm template command](https://helm.sh/docs/helm/helm_template/). +This static manifest can be tuned by providing the flags to overwrite the default Helm values: + +```bash +helm template \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --version [[VAR::cert_manager_latest_version]] \ + --set crds.enabled=true \ + # --set prometheus.enabled=false \ # Example: disabling prometheus using a Helm parameter + > cert-manager.custom.yaml +``` + +> ℹ️ The `helm template` command will not output a Namespace resource and ignores the `--create-namespace` flag. You must ensure the namespace you are deploying the generated YAML to exists. + +## Uninstalling + +> **Warning**: To uninstall cert-manager you should always use the same process for +> installing but in reverse. Deviating from the following process whether +> cert-manager has been installed from static manifests or Helm can cause issues +> and potentially broken states. Please ensure you follow the below steps when +> uninstalling to prevent this happening. + +Before continuing, ensure that all cert-manager resources that have been created +by users have been deleted. You can check for any existing resources with the +following command: + +```bash +kubectl get Issuers,ClusterIssuers,Certificates,CertificateRequests,Orders,Challenges --all-namespaces +``` + +Once all these resources have been deleted you are ready to uninstall +cert-manager using the procedure determined by how you installed. + +### Uninstalling with Helm + +Uninstalling cert-manager from a `helm` installation is a case of running the +installation process, *in reverse*, using the delete command on both `kubectl` +and `helm`. + +```terminal +$ helm uninstall cert-manager -n cert-manager + +These resources were kept due to the resource policy: +[CustomResourceDefinition] certificaterequests.cert-manager.io +[CustomResourceDefinition] certificates.cert-manager.io +[CustomResourceDefinition] challenges.acme.cert-manager.io +[CustomResourceDefinition] clusterissuers.cert-manager.io +[CustomResourceDefinition] issuers.cert-manager.io +[CustomResourceDefinition] orders.acme.cert-manager.io + +release "cert-manager" uninstalled +``` + +As shown in the output, the `CustomResourceDefinition` for `Issuers`,`ClusterIssuers`,`Certificates`,`CertificateRequests`,`Orders` and `Challenges` are not removed by the Helm uninstall command. +This is to prevent data loss, as removing the `CustomResourceDefinition` would also remove all instances of those resources. + +> ☢️ This will remove all `Issuers`,`ClusterIssuers`,`Certificates`,`CertificateRequests`,`Orders` and `Challenges` resources from the cluster: +> +> ```terminal +> kubectl delete crd \ +> issuers.cert-manager.io \ +> clusterissuers.cert-manager.io \ +> certificates.cert-manager.io \ +> certificaterequests.cert-manager.io \ +> orders.acme.cert-manager.io \ +> challenges.acme.cert-manager.io +> ``` + +> ⚠️ cert-manager versions prior to `v1.15.0` do not keep the `CustomResourceDefinition` on uninstall +> and will remove all `Issuers`,`ClusterIssuers`,`Certificates`,`CertificateRequests`,`Orders` and `Challenges` +> resources from the cluster. Make sure to back up your cert-manager resources +> before uninstalling cert-manager if you are using a version prior to `v1.15.0`. Or upgrade to `v1.15.0` +> before uninstalling. + +### Namespace Stuck in Terminating State + +If the namespace has been marked for deletion without deleting the cert-manager +installation first, the namespace may become stuck in a terminating state. This +is typically due to the fact that the [`APIService`](https://kubernetes.io/docs/tasks/access-kubernetes-api/setup-extension-api-server) resource still exists +however the webhook is no longer running so is no longer reachable. To resolve +this, ensure you have run the above commands correctly, and if you're still +experiencing issues then run: + +```bash +kubectl delete apiservice v1beta1.webhook.cert-manager.io +``` + +## Using the Flux Helm Controller + +The cert-manager Helm chart can be installed and upgraded by the Flux Helm Controller. + +> 📖 Read more at [Continuous Deployment: Using the Flux Helm Controller](./continuous-deployment-and-gitops.md). diff --git a/content/v1.15-docs/installation/kubectl.md b/content/v1.15-docs/installation/kubectl.md new file mode 100644 index 0000000000..81d9b91132 --- /dev/null +++ b/content/v1.15-docs/installation/kubectl.md @@ -0,0 +1,230 @@ +--- +title: kubectl apply +description: Learn how to install cert-manager using kubectl and static manifests +--- + +Learn how to install cert-manager using kubectl and static manifests. + +## Prerequisites + +- [Install `kubectl` version `>= v1.19.0`](https://kubernetes.io/docs/tasks/tools/). (otherwise, you'll have issues updating the CRDs - see [v0.16 upgrade notes](../releases/upgrading/upgrading-0.15-0.16.md#issue-with-older-versions-of-kubectl)) +- Install a [supported version of Kubernetes or OpenShift](../releases/README.md). +- Read [Compatibility with Kubernetes Platform Providers](./compatibility.md) if you are using Kubernetes on a cloud platform. + +## Steps + +### 1. Install from the cert-manager release manifest + +All resources (the CustomResourceDefinitions and the cert-manager, cainjector and webhook components) +are included in a single YAML manifest file: + +Install all cert-manager components: + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/[[VAR::cert_manager_latest_version]]/cert-manager.yaml +``` + +By default, cert-manager will be installed into the `cert-manager` +namespace. It is possible to run cert-manager in a different namespace, although +you'll need to make modifications to the deployment manifests. + +Once you've installed cert-manager, you can verify it is deployed correctly by +checking the `cert-manager` namespace for running pods: + +```console +$ kubectl get pods --namespace cert-manager + +NAME READY STATUS RESTARTS AGE +cert-manager-5c6866597-zw7kh 1/1 Running 0 2m +cert-manager-cainjector-577f6d9fd7-tr77l 1/1 Running 0 2m +cert-manager-webhook-787858fcdb-nlzsq 1/1 Running 0 2m +``` + +You should see the `cert-manager`, `cert-manager-cainjector`, and +`cert-manager-webhook` pods in a `Running` state. The webhook might take a +little longer to successfully provision than the others. + +If you experience problems, first check the [FAQ](../faq/README.md). + +### 2. (optional) Wait for cert-manager webhook to be ready + +The webhook component can take some time to start, and make the Kubernetes API server trust the webhook's certificate. + +First, make sure that [cmctl is installed](../reference/cmctl.md#installation). + +cmctl performs a dry-run certificate creation check against the Kubernetes cluster. +If successful, the message `The cert-manager API is ready` is displayed. + +```console +$ cmctl check api +The cert-manager API is ready +``` + +The command can also be used to wait for the check to be successful. +Here is an output example of running the command at the same time that cert-manager is being installed: + +```console +$ cmctl check api --wait=2m +Not ready: the cert-manager CRDs are not yet installed on the Kubernetes API server +Not ready: the cert-manager CRDs are not yet installed on the Kubernetes API server +Not ready: the cert-manager webhook deployment is not ready yet +Not ready: the cert-manager webhook deployment is not ready yet +Not ready: the cert-manager webhook deployment is not ready yet +Not ready: the cert-manager webhook deployment is not ready yet +The cert-manager API is ready +``` + + +### 2. (optional) End-to-end verify the installation + +Best way to fully verify the installation is to issue a test certificate. For this, we will create a self-signed issuer and a certificate resource in a test namespace. + + +```bash +cat < test-resources.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: cert-manager-test +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: test-selfsigned + namespace: cert-manager-test +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: selfsigned-cert + namespace: cert-manager-test +spec: + dnsNames: + - example.com + secretName: selfsigned-cert-tls + issuerRef: + name: test-selfsigned +EOF +``` + +Create the test resources. +```bash +kubectl apply -f test-resources.yaml +``` + +Check the status of the newly created certificate. You may need to wait a few +seconds before cert-manager processes the certificate request. + +```console +$ kubectl describe certificate -n cert-manager-test + +... +Spec: + Common Name: example.com + Issuer Ref: + Name: test-selfsigned + Secret Name: selfsigned-cert-tls +Status: + Conditions: + Last Transition Time: 2019-01-29T17:34:30Z + Message: Certificate is up to date and has not expired + Reason: Ready + Status: True + Type: Ready + Not After: 2019-04-29T17:34:29Z +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal CertIssued 4s cert-manager Certificate issued successfully +``` + +Clean up the test resources. + +```bash +kubectl delete -f test-resources.yaml +``` + +If all the above steps have completed without error, you're good to go! + +## Uninstalling +> **Warning**: To uninstall cert-manager you should always use the same process for +> installing but in reverse. Deviating from the following process whether +> cert-manager has been installed from static manifests or Helm can cause issues +> and potentially broken states. Please ensure you follow the below steps when +> uninstalling to prevent this happening. + +Before continuing, ensure that unwanted cert-manager resources that have been created +by users have been deleted. You can check for any existing resources with the +following command: + +```bash +kubectl get Issuers,ClusterIssuers,Certificates,CertificateRequests,Orders,Challenges --all-namespaces +``` +It is recommended that you delete all these resources before uninstalling cert-manager. +If you plan on reinstalling later and don't want to lose some custom resources, you can keep them. +However, this can potentially lead to problems with finalizers. Some resources, like +`Challenges`, should be deleted to avoid [getting stuck in a pending state](#namespace-stuck-in-terminating-state). + +Once the unneeded resources have been deleted, you are ready to uninstall +cert-manager using the procedure determined by how you installed. + +> **Warning**: Uninstalling cert-manager or simply deleting a `Certificate` resource can result in +> TLS `Secret`s being deleted if they have `metadata.ownerReferences` set by cert-manager. +> You can control whether owner references are added to `Secret`s using the `--enable-certificate-owner-ref` controller flag. +> By default, this flag is set to false, which means that no owner references are added. +> However, in cert-manager v1.8 and older, changing the flag's value from true to false _did not_ +> result in existing owner references being removed. This behavior was fixed in cert-manager v1.8. +> Do check the owner references to confirm that they actually are removed. + +### Uninstalling with regular manifests + +Uninstalling from an installation with regular manifests is a case of running +the installation process, *in reverse*, using the delete command of `kubectl`. + +Delete the installation manifests using a link to your currently running version +`vX.Y.Z` like so: +> **Warning**: This command will also remove installed cert-manager CRDs. All +> cert-manager resources (e.g. `certificates.cert-manager.io` resources) will +> be removed by Kubernetes' garbage collector. +> You cannot keep any custom resources if you delete the `CustomResourceDefinition`s. +> If you want to keep resources, you should manage `CustomResourceDefinition`s separately. + +```bash +kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/vX.Y.Z/cert-manager.yaml +``` + +### Namespace Stuck in Terminating State + +If the namespace has been marked for deletion without deleting the cert-manager +installation first, the namespace may become stuck in a terminating state. This +is typically due to the fact that the [`APIService`](https://kubernetes.io/docs/tasks/access-kubernetes-api/setup-extension-api-server) resource still exists +however the webhook is no longer running so is no longer reachable. To resolve +this, ensure you have run the above commands correctly, and if you're still +experiencing issues then run: + +```bash +kubectl delete apiservice v1beta1.webhook.cert-manager.io +``` + +#### Deleting pending challenges + +`Challenge`s can get stuck in a pending state when the finalizer is unable to complete +and Kubernetes is waiting for the cert-manager controller to finish. +This happens when the controller is no longer running to remove the flag, +and the resources are defined as needing to wait. +You can fix this problem by doing what the controller does manually. + +First, delete existing cert-manager webhook configurations, if any: + +```bash +kubectl delete mutatingwebhookconfigurations cert-manager-webhook +kubectl delete validatingwebhookconfigurations cert-manager-webhook +``` + +Then change the `.metadata.finalizers` field to an empty list by editing the challenge resource: + +```bash +kubectl edit challenge +``` diff --git a/content/v1.15-docs/installation/operator-lifecycle-manager.md b/content/v1.15-docs/installation/operator-lifecycle-manager.md new file mode 100644 index 0000000000..1ad94926bf --- /dev/null +++ b/content/v1.15-docs/installation/operator-lifecycle-manager.md @@ -0,0 +1,244 @@ +--- +title: Operator Lifecycle Manager +description: 'cert-manager installation: Using OLM' +--- + +## Installation managed by OLM + +### Prerequisites + +- Install a [supported version of Kubernetes or OpenShift](../releases/README.md). +- Read [Compatibility with Kubernetes Platform Providers](./compatibility.md) if you are using Kubernetes on a cloud platform. + +### Option 1: Installing from OperatorHub Web Console on OpenShift + +cert-manager is in the [Red Hat-provided Operator catalog][] called "community-operators". +On OpenShift 4 you can install cert-manager from the [OperatorHub web console][] or from the command line. +These installation methods are described in Red Hat's [Adding Operators to a cluster][] documentation. + +> ⚠️ In cert-manager 1.10 the [secure computing (seccomp) profile](https://kubernetes.io/docs/tutorials/security/seccomp/) for all the Pods +> is set to `RuntimeDefault`. +> On some versions and configurations of OpenShift this can cause the Pod to be rejected by the +> [Security Context Constraints admission webhook](https://docs.openshift.com/container-platform/4.10/authentication/managing-security-context-constraints.html#admission_configuring-internal-oauth). +> +> 📖 Read the [Breaking Changes section in the 1.10 release notes](https://cert-manager.io/docs/release-notes/release-notes-1.10/#on-openshift-the-cert-manager-pods-may-fail-until-you-modify-security-context-constraints) before installing or upgrading from an older version to 1.10 or newer. + +[Red Hat-provided Operator catalog]: https://docs.openshift.com/container-platform/4.7/operators/understanding/olm-rh-catalogs.html#olm-rh-catalogs_olm-rh-catalogs +[OperatorHub web console]: https://docs.openshift.com/container-platform/4.7/operators/understanding/olm-understanding-operatorhub.html +[Adding Operators to a cluster]: https://docs.openshift.com/container-platform/4.7/operators/admin/olm-adding-operators-to-cluster.html + + +### Option 2: Installing from OperatorHub.io + +Browse to the [cert-manager page on OperatorHub.io](https://operatorhub.io/operator/cert-manager), +click the "Install" button and follow the installation instructions. + +### Option 3: Manual install via `kubectl operator` plugin + +[Install OLM][] and [install the `kubectl operator` plugin][] +from the [Krew Kubectl plugins index][] and then use that to install the cert-manager as follows: + +```sh +operator-sdk olm install +kubectl krew install operator +kubectl create ns cert-manager +kubectl operator install cert-manager -n cert-manager --channel stable --approval Automatic --create-operator-group +``` + +You can monitor the progress of the installation as follows: + +```sh +kubectl get events -w -n operators +``` + +And you can see the status of the installation with: + +```sh +kubectl operator list +``` + +[install OLM]: https://sdk.operatorframework.io/docs/installation/ +[install the `kubectl operator` plugin]: https://github.com/operator-framework/kubectl-operator#install +[Krew Kubectl plugins index]: https://krew.sigs.k8s.io/plugins/#:~:text=cert-manager + +## Release Channels + +Whichever installation method you chose, there will now be an [OLM Subscription resource][] for cert-manager, +tracking the "stable" release channel. E.g. + +```console +$ kubectl get subscription cert-manager -n operators -o yaml +... +spec: + channel: stable + installPlanApproval: Automatic + name: cert-manager +... +status: + currentCSV: cert-manager.[[VAR::cert_manager_latest_version]] + state: AtLatestKnown +... +``` + +This means that OLM will discover new cert-manager releases in the stable channel, +and, depending on the Subscription settings it will upgrade cert-manager automatically, +when new releases become available. +Read [Manually Approving Upgrades via Subscriptions][] for information about automatic and manual upgrades. + +[OLM Subscription resource]: https://olm.operatorframework.io/docs/concepts/crds/subscription/ +[Manually Approving Upgrades via Subscriptions]: https://olm.operatorframework.io/docs/concepts/crds/subscription/#manually-approving-upgrades-via-subscriptions + +**NOTE:** There is a single release channel called "stable" which will contain all cert-manager releases, shortly after they are released. +In future we may introduce other release channels with alternative release schedules, +in accordance with [OLM's Recommended Channel Naming][]. + +[OLM's Recommended Channel Naming]: https://olm.operatorframework.io/docs/best-practices/channel-naming/#recommended-channel-naming + +## Debugging installation issues + +If you have any issues with your installation, please refer to the +[FAQ](../faq/README.md). + +## Configuration + +The configuration options are quite limited when you install cert-manager using OLM. +There are a few Deployment settings which can be overridden permanently in the Subscription +and most other elements of the cert-manager manifests can be changed by editing the ClusterServiceVersion, +but changes to the ClusterServiceVersion are temporary and will be lost if OLM upgrades cert-manager, +because an upgrade results in a new ClusterServiceVersion resource. + +### Configuration Via Subscription + +When you create an OLM Subscription you can override **some** of the cert-manager Deployment settings, +but the options are quite limited. +The configuration which you add to the Subscription will be applied immediately to the current cert-manager Deployments. +It will also be re-applied if OLM upgrades cert-manager. + +> 🔰 Read the [Configuring Operators deployed by OLM](https://github.com/operator-framework/operator-lifecycle-manager/blob/master/doc/design/subscription-config.md#configuring-operators-deployed-by-olm) design doc in the OLM repository. +> +> 🔰 Refer to the [Subscription API documentation](https://pkg.go.dev/github.com/operator-framework/api@v0.14.0/pkg/operators/v1alpha1#Subscription). + +Here are some examples of configuration that can be achieved by modifying the Subscription resource. +In each case we assume that you are starting with the following [default Subscription from OperatorHub.io](https://operatorhub.io/install/cert-manager.yaml): + +```yaml +# cert-manager.yaml +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: my-cert-manager + namespace: operators +spec: + channel: stable + name: cert-manager + source: operatorhubio-catalog + sourceNamespace: olm +``` + +```bash +kubectl create -f https://operatorhub.io/install/cert-manager.yaml +``` + +#### Change the Resource Requests and Limits + +It is possible to change the resource requests and limits by adding a `config` stanza to the Subscription: + +```yaml +# resources-patch.yaml +spec: + config: + resources: + requests: + memory: "64Mi" + cpu: "250m" + limits: + memory: "128Mi" + cpu: "500m" +``` + + +```bash +kubectl -n operators patch subscription my-cert-manager --type merge --patch-file resources-patch.yaml +``` + +You will see **all** the cert-manager Pods are restarted with the new resources: + +```console +$ kubectl -n operators get pods -o "custom-columns=name:.metadata.name,mem:.spec.containers[*].resources" +name mem +cert-manager-669867589c-n8dcn map[limits:map[cpu:500m memory:128Mi] requests:map[cpu:250m memory:100Mi]] +cert-manager-cainjector-7b7fff8b9c-dxw6b map[limits:map[cpu:500m memory:128Mi] requests:map[cpu:250m memory:100Mi]] +cert-manager-webhook-975bc87b5-tqdj4 map[limits:map[cpu:500m memory:128Mi] requests:map[cpu:250m memory:100Mi]] +``` + +> ⚠️ This configuration will apply to **all** the cert-manager Deployments. +> This is a known limitation of OLM which [does not support configuration of individual Deployments](https://github.com/operator-framework/operator-lifecycle-manager/issues/1794). + +#### Change the NodeSelector + +It is possible to change the `nodeSelector` for cert-manager Pods by adding the following stanza to the Subscription: + +```yaml +# nodeselector-patch.yaml +spec: + config: + nodeSelector: + kubernetes.io/arch: amd64 +``` + +```bash +kubectl -n operators patch subscription my-cert-manager --type merge --patch-file nodeselector-patch.yaml +``` + +You will see **all** the cert-manager Pods are restarted with the new `nodeSelector`: + +```console +$ kubectl -n operators get pods -o "custom-columns=name:.metadata.name,nodeselector:.spec.nodeSelector" +name nodeselector +cert-manager-5b6b8f7d74-k7l94 map[kubernetes.io/arch:amd64 kubernetes.io/os:linux] +cert-manager-cainjector-b89cd6f46-kdkk2 map[kubernetes.io/arch:amd64 kubernetes.io/os:linux] +cert-manager-webhook-8464bc7cc8-64b4w map[kubernetes.io/arch:amd64 kubernetes.io/os:linux] +``` + +> ⚠️ This configuration will apply to **all** the cert-manager Deployments. +> This is a known limitation of OLM which [does not support configuration of individual Deployments](https://github.com/operator-framework/operator-lifecycle-manager/issues/1794). + +### Configuration Via ClusterServiceVersion (CSV) + +The ClusterServiceVersion (CSV) resource contains the templates for all the cert-manager Deployments. +If you patch these templates, OLM will immediately roll out the changes to the Deployments. + +> ⚠️ If OLM upgrades cert-manager your changes will be lost because it will create a new CSV with default Deployment templates. + +Nevertheless, editing (patching) the CSV can be a useful way to override certain cert-manager settings. An example: + +#### Change the log level of cert-manager components + +The following JSON patch will append `-v=6` to command line arguments of the cert-manager controller-manager +(the first container of the first Deployment). + +```bash +kubectl patch csv cert-manager.[[VAR::cert_manager_latest_version]] \ + --type json \ + -p '[{"op": "add", "path": "/spec/install/spec/deployments/0/spec/template/spec/containers/0/args/-", "value": "-v=6" }]' +``` + +You will see the controller-manager Pod is restarted with the new arguments. + +```console +$ kubectl -n operators get pods -o "custom-columns=name:.metadata.name,args:.spec.containers[0].args" +name args +cert-manager-797979cbdb-g444r [-v=2 --cluster-resource-namespace=$(POD_NAMESPACE) --leader-election-namespace=kube-system -v=6] +... +``` + +> 🔰 Refer to the [ClusterServiceVersion API documentation](https://pkg.go.dev/github.com/operator-framework/api@v0.14.0/pkg/operators/v1alpha1#ClusterServiceVersion). + +## Uninstall + +Below is the processes for uninstalling cert-manager on OpenShift. + +> ⚠️ To uninstall cert-manager you should always use the same process for +> installing but in reverse. Deviating from the following process can cause +> issues and potentially broken states. Please ensure you follow the below steps +> when uninstalling to prevent this happening. diff --git a/content/v1.15-docs/installation/reinstall.md b/content/v1.15-docs/installation/reinstall.md new file mode 100644 index 0000000000..9c544b3723 --- /dev/null +++ b/content/v1.15-docs/installation/reinstall.md @@ -0,0 +1,33 @@ +--- +title: Reinstalling cert-manager +description: 'cert-manager installation: Reinstalling cert-manager overview' +--- + +In some cases there may be a need to do a full uninstall and re-install of +cert-manager. An example could be when a very old cert-manager version needs to +be brought up to date and it isn't feasible to upgrade one minor version at a +time, which is our default recommended upgrade strategy. + +If cert-manager `CustomResourceDefinition`s are also uninstalled, this will mean +loss of associated cert-manager custom resources such as `Certificate`s. The +main concern associated with this is application downtime and unnecessary +certificate reissuance, that could happen if `Secret`s with the X.509 +certificates get deleted. You can use [`--enable-certificate-owner-ref` +flag](https://cert-manager.io/docs/cli/controller/) +on the cert-manager controller to configure whether the `Secret`s should be deleted. +If this flag is set to true, each `Secret` will have an owner reference to the +`Certificate` for which it was created and when the `Certificate` is deleted, +the `Secret` will be garbage collected. The default value for this flag is +false. If the `Certificate`s get deleted and re-applied, but the `Secret`s remain +in the cluster, the newly applied `Certificate`s should be able to pick up the +same `Secret`s and should not unnecessarily reissue the X.509 certs. + +When uninstalling and re-installing in order to upgrade, you should still read +through the release notes for each skipped version. + +Some things to look out for when considering uninstalling and re-installing +cert-manager _including the CRDs_: + +- Is `--enable-certificate-owner-ref` flag currently set to true or could it have been set to true at some point previously? Due to an earlier bug, the owner reference that gets added to `Secret`s is _not_ removed when the value of `--enable-certificate-owner-ref` is changed from true to false, see [`cert-manager#4788`](https://github.com/cert-manager/cert-manager/issues/4788) +- Are there currently any certificate issuances in progress? If so, with the custom resources deleted, the progress will be lost. This could potentially cause duplicated issuances. +- Is there a need to convert cert-manager custom resource manifests to v1 API? You can use [`cmctl convert` command](../reference/cmctl.md#convert) to do that. diff --git a/content/v1.15-docs/installation/uninstall.md b/content/v1.15-docs/installation/uninstall.md new file mode 100644 index 0000000000..3ffc30772c --- /dev/null +++ b/content/v1.15-docs/installation/uninstall.md @@ -0,0 +1,14 @@ +--- +title: Uninstalling cert-manager +description: 'cert-manager installation: Uninstalling cert-manager' +--- + +cert-manager supports running on [Kubernetes](https://kubernetes.io) and +[OpenShift](https://www.openshift.com). The uninstallation process between the +two platforms is similar. Select the method that was used for installing +cert-manager to go to the relevant uninstall documentation. + +- [kubectl](./kubectl.md#uninstalling) +- [helm](./helm.md#uninstalling) + +If you need to preserve cert-manager custom resources (`Certificate`s, `Issuer`s etc), that are not version controlled or backed up by other means, take a look at our [backup and restore guide](../devops-tips/backup.md). diff --git a/content/v1.15-docs/installation/upgrade.md b/content/v1.15-docs/installation/upgrade.md new file mode 100644 index 0000000000..7db968da23 --- /dev/null +++ b/content/v1.15-docs/installation/upgrade.md @@ -0,0 +1,99 @@ +--- +title: Upgrading cert-manager +description: 'cert-manager installation: Upgrading cert-manager overview' +--- + +In the [releases section](../releases/README.md) of the documentation, you can find the release notes +and upgrade instructions for each release of cert-manager. It also contains +information on the breaking changes between each release and things to look out +for when upgrading. + +> Note: Before performing upgrades of cert-manager, it is advised to take a +> backup of all your cert-manager resources just in case an issue occurs whilst +> upgrading. You can read how to backup and restore cert-manager in the [backup +> and restore](../devops-tips/backup.md) guide. + +We recommend that you upgrade cert-manager one minor version at a time, always +choosing the latest patch version for the minor version. You should always read +the release notes for the minor version to which you are upgrading. In cases +where a large version jump is needed to get an installation up to date, it may +be possible to do a full uninstall and re-install of cert-manager without application +downtime and/or unnecessary re-issuances, however we do not guarantee that this will +work for your particular setup see [Reinstalling cert-manager](#reinstalling-cert-manager). + +## Upgrading with Helm + +If you installed cert-manager using Helm, you can easily upgrade using the Helm +CLI. + +> Note: Before upgrading, please read the relevant instructions at the links +> below for your from and to version. + +Once you have read the relevant upgrading notes and taken any appropriate +actions, you can begin the upgrade process like so - replacing `` +with the name of your Helm release for cert-manager (usually this is +`cert-manager`) and replacing `` with the version number you want to +install. + +Add the Jetstack Helm repository (if you haven't already) and update it. + +```bash +helm repo add jetstack https://charts.jetstack.io --force-update +``` + +The helm upgrade command will upgrade cert-manager to the specified or latest version of cert-manager, as listed on the +[cert-manager Helm chart documentation page](https://artifacthub.io/packages/helm/cert-manager/cert-manager). + +> Note: You can find out your release name using `helm list | grep cert-manager`. + +### CRDs managed using helm + +If you have installed the CRDs together with the helm install command (using `--set crds.enabled=true`), +Helm will upgrade the CRDs automatically when you upgrade the cert-manager Helm chart: + +```bash +helm upgrade --reset-then-reuse-values --version jetstack/cert-manager +``` + +### CRDs managed separately + +If you have installed the CRDs separately (instead of with the `--set crds.enabled=true` +option added to your Helm install command), you should upgrade your CRD resources first: + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download//cert-manager.crds.yaml +``` + +And then upgrade the Helm chart: + +```bash +helm upgrade --reset-then-reuse-values --version jetstack/cert-manager +``` + +## Upgrading using static manifests + +If you installed cert-manager using the static deployment manifests published +on each release, you can upgrade them in a similar way to how you first +installed them. + +> Note: Before upgrading, please read the relevant instructions at the links +> below Note: for your from and to version. + +Once you have read the relevant notes and taken any appropriate actions, you can +begin the upgrade process like so - replacing `` with the version +number you want to install: + +```bash +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download//cert-manager.yaml +``` + +Once you have deployed the new version of cert-manager, you can [verify](kubectl.md#verify) the installation. + +## Reinstalling cert-manager + +In some cases there may be a need to do a full uninstall and re-install of +cert-manager. An example could be when a very old cert-manager version needs to +be brought up to date and it isn't feasible to upgrade one minor version at a +time, which is our default recommended upgrade strategy. + +See [Reinstalling cert-manager](reinstall.md) for a full guide on how to do this without any issues. diff --git a/content/v1.15-docs/manifest.json b/content/v1.15-docs/manifest.json new file mode 100644 index 0000000000..5df8d23292 --- /dev/null +++ b/content/v1.15-docs/manifest.json @@ -0,0 +1,500 @@ +{ + "routes": [ + { + "title": "cert-manager", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/README.md" + }, + { + "title": "Getting Started", + "path": "/v1.15-docs/getting-started/README.md" + }, + { + "title": "0. Installation", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/installation/README.md" + }, + { + "title": "a. kubectl apply", + "path": "/v1.15-docs/installation/kubectl.md" + }, + { + "title": "b. Helm", + "path": "/v1.15-docs/installation/helm.md" + }, + { + "title": "c. OperatorHub (OLM)", + "path": "/v1.15-docs/installation/operator-lifecycle-manager.md" + }, + { + "title": "d. Continuous Deployment", + "path": "/v1.15-docs/installation/continuous-deployment-and-gitops.md" + }, + { + "title": "Configuring Components", + "path": "/v1.15-docs/installation/configuring-components.md" + }, + { + "title": "Upgrade", + "path": "/v1.15-docs/installation/upgrade.md" + }, + { + "title": "Reinstall", + "path": "/v1.15-docs/installation/reinstall.md" + }, + { + "title": "Uninstall", + "path": "/v1.15-docs/installation/uninstall.md" + }, + { + "title": "Signature Verification", + "path": "/v1.15-docs/installation/code-signing.md" + } + ] + }, + { + "title": "1. Configuring Issuers", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/configuration/README.md" + }, + { + "title": "Issuers", + "path": "/v1.15-docs/configuration/issuers.md" + }, + { + "title": "In-tree Issuer Config", + "routes": [ + { + "title": "SelfSigned", + "path": "/v1.15-docs/configuration/selfsigned.md" + }, + { + "title": "CA", + "path": "/v1.15-docs/configuration/ca.md" + }, + { + "title": "Vault", + "path": "/v1.15-docs/configuration/vault.md" + }, + { + "title": "Venafi", + "path": "/v1.15-docs/configuration/venafi.md" + }, + { + "title": "ACME", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/configuration/acme/README.md" + }, + { + "title": "HTTP01", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/configuration/acme/http01/README.md" + }, + { + "title": "External Load Balancer", + "path": "/v1.15-docs/configuration/acme/http01/externalloadbalancer.md" + } + ] + }, + { + "title": "DNS01", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/configuration/acme/dns01/README.md" + }, + { + "title": "ACMEDNS", + "path": "/v1.15-docs/configuration/acme/dns01/acme-dns.md" + }, + { + "title": "Akamai", + "path": "/v1.15-docs/configuration/acme/dns01/akamai.md" + }, + { + "title": "AzureDNS", + "path": "/v1.15-docs/configuration/acme/dns01/azuredns.md" + }, + { + "title": "Cloudflare", + "path": "/v1.15-docs/configuration/acme/dns01/cloudflare.md" + }, + { + "title": "DigitalOcean", + "path": "/v1.15-docs/configuration/acme/dns01/digitalocean.md" + }, + { + "title": "Google CloudDNS", + "path": "/v1.15-docs/configuration/acme/dns01/google.md" + }, + { + "title": "RFC-2136", + "path": "/v1.15-docs/configuration/acme/dns01/rfc2136.md" + }, + { + "title": "Route53", + "path": "/v1.15-docs/configuration/acme/dns01/route53.md" + }, + { + "title": "Webhook", + "path": "/v1.15-docs/configuration/acme/dns01/webhook.md" + } + ] + } + ] + } + ] + } + ] + }, + { + "title": "2. Requesting Certificates", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/usage/README.md" + }, + { + "title": "Certificate", + "path": "/v1.15-docs/usage/certificate.md" + }, + { + "title": "CertificateRequest", + "path": "/v1.15-docs/usage/certificaterequest.md" + }, + { + "title": "Ingress", + "path": "/v1.15-docs/usage/ingress.md" + }, + { + "title": "Gateway", + "path": "/v1.15-docs/usage/gateway.md" + }, + { + "title": "CertificateSigningRequests", + "path": "/v1.15-docs/usage/kube-csr.md" + }, + { + "title": "Service Mesh", + "routes": [ + { + "title": "istio-csr", + "routes": [ + { + "title": "Installation", + "path": "/v1.15-docs/usage/istio-csr/installation.md" + }, + { + "title": "Usage", + "path": "/v1.15-docs/usage/istio-csr/README.md" + } + ] + } + ] + }, + { + "title": "CSI Driver", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/usage/csi.md" + }, + { + "title": "csi-driver", + "routes": [ + { + "title": "Installation", + "path": "/v1.15-docs/usage/csi-driver/installation.md" + }, + { + "title": "Usage", + "path": "/v1.15-docs/usage/csi-driver/README.md" + } + ] + }, + { + "title": "csi-driver-spiffe", + "routes": [ + { + "title": "Installation", + "path": "/v1.15-docs/usage/csi-driver-spiffe/installation.md" + }, + { + "title": "Usage", + "path": "/v1.15-docs/usage/csi-driver-spiffe/README.md" + } + ] + } + ] + } + ] + }, + { + "title": "3. Distributing Trust", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/trust/README.md" + }, + { + "title": "trust-manager", + "routes": [ + { + "title": "Installation", + "path": "/v1.15-docs/trust/trust-manager/installation.md" + }, + { + "title": "Usage", + "path": "/v1.15-docs/trust/trust-manager/README.md" + }, + { + "title": "API Reference", + "path": "/v1.15-docs/trust/trust-manager/api-reference.md" + } + ] + } + ] + }, + { + "title": "4. Defining Policy", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/policy/README.md" + }, + { + "title": "Defaulting", + "path": "/v1.15-docs/policy/defaulting.md" + }, + { + "title": "Approval", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/policy/approval/README.md" + }, + { + "title": "approver-policy", + "routes": [ + { + "title": "Installation", + "path": "/v1.15-docs/policy/approval/approver-policy/installation.md" + }, + { + "title": "Usage", + "path": "/v1.15-docs/policy/approval/approver-policy/README.md" + }, + { + "title": "API Reference", + "path": "/v1.15-docs/policy/approval/approver-policy/api-reference.md" + } + ] + } + ] + }, + { + "title": "Issuing", + "path": "/v1.15-docs/policy/issuing.md" + } + ] + }, + { + "title": "Tutorials", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/tutorials/README.md" + }, + { + "title": "Securing NGINX-ingress", + "path": "/v1.15-docs/tutorials/acme/nginx-ingress.md" + }, + { + "title": "GKE + Ingress + Let's Encrypt", + "path": "/v1.15-docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md" + }, + { + "title": "AKS + LoadBalancer + Let's Encrypt", + "path": "/v1.15-docs/tutorials/getting-started-aks-letsencrypt/README.md" + }, + { + "title": "AWS + LoadBalancer + Let's Encrypt", + "path": "/v1.15-docs/tutorials/getting-started-aws-letsencrypt/README.md" + }, + { + "title": "Migrating from Kube-LEGO", + "path": "/v1.15-docs/tutorials/acme/migrating-from-kube-lego.md" + }, + { + "title": "DNS Validation", + "path": "/v1.15-docs/tutorials/acme/dns-validation.md" + }, + { + "title": "HTTP Validation", + "path": "/v1.15-docs/tutorials/acme/http-validation.md" + }, + { + "title": "Pomerium Ingress", + "path": "/v1.15-docs/tutorials/acme/pomerium-ingress.md" + }, + { + "title": "EKS + Ingress + Venafi", + "path": "/v1.15-docs/tutorials/venafi/venafi.md" + }, + { + "title": "Securing Ingresses with ZeroSSL", + "path": "/v1.15-docs/tutorials/zerossl/zerossl.md" + }, + { + "title": "Managing public trust in kubernetes with trust-manager", + "path": "/v1.15-docs/tutorials/getting-started-with-trust-manager/README.md" + }, + { + "title": "Setting default certificate values", + "path": "/v1.15-docs/tutorials/certificate-defaults/README.md" + } + ] + }, + { + "title": "DevOps Tips", + "routes": [ + { + "title": "Installing on a Cloud Provider", + "path": "/v1.15-docs/installation/compatibility.md" + }, + { + "title": "Prometheus Metrics", + "path": "/v1.15-docs/devops-tips/prometheus-metrics.md" + }, + { + "title": "Backup and Restore Resources", + "path": "/v1.15-docs/devops-tips/backup.md" + }, + { + "title": "Syncing Secrets Across Namespaces", + "path": "/v1.15-docs/devops-tips/syncing-secrets-across-namespaces.md" + }, + { + "title": "Best Practice Installation Options", + "path": "/v1.15-docs/installation/best-practice.md" + }, + { + "title": "Scaling cert-manager", + "path": "/v1.15-docs/devops-tips/scaling-cert-manager.md" + } + ] + }, + { + "title": "Troubleshooting & FAQ", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/troubleshooting/README.md" + }, + { + "title": "Frequently Asked Questions", + "path": "/v1.15-docs/faq/README.md" + }, + { + "title": "Troubleshooting ACME / Let's Encrypt Certificates", + "path": "/v1.15-docs/troubleshooting/acme.md" + }, + { + "title": "Troubleshooting webhook", + "path": "/v1.15-docs/troubleshooting/webhook.md" + } + ] + }, + { + "title": "Reference", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/reference/README.md" + }, + { + "title": "Command Line Tool (cmctl)", + "path": "/v1.15-docs/reference/cmctl.md" + }, + { + "title": "TLS Terminology", + "path": "/v1.15-docs/reference/tls-terminology.md" + }, + { + "title": "Components / Docker Images", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/cli/README.md" + }, + { + "title": "acmesolver", + "path": "/v1.15-docs/cli/acmesolver.md" + }, + { + "title": "cainjector", + "path": "/v1.15-docs/cli/cainjector.md" + }, + { + "title": "cmctl", + "path": "/v1.15-docs/cli/cmctl.md" + }, + { + "title": "controller", + "path": "/v1.15-docs/cli/controller.md" + }, + { + "title": "webhook", + "path": "/v1.15-docs/cli/webhook.md" + }, + { + "title": "startupapicheck", + "path": "/v1.15-docs/cli/startupapicheck.md" + } + ] + }, + { + "title": "API Reference", + "path": "/v1.15-docs/reference/api-docs.md" + }, + { + "title": "Concepts", + "routes": [ + { + "title": "Introduction", + "path": "/v1.15-docs/concepts/README.md" + }, + { + "title": "Issuer", + "path": "/v1.15-docs/concepts/issuer.md" + }, + { + "title": "ACME Orders and Challenges", + "path": "/v1.15-docs/concepts/acme-orders-challenges.md" + }, + { + "title": "Webhook", + "path": "/v1.15-docs/concepts/webhook.md" + }, + { + "title": "CA Injector", + "path": "/v1.15-docs/concepts/ca-injector.md" + } + ] + } + ] + } + ] + } + ] +} diff --git a/content/v1.15-docs/policy/README.md b/content/v1.15-docs/policy/README.md new file mode 100644 index 0000000000..c9529fdfbb --- /dev/null +++ b/content/v1.15-docs/policy/README.md @@ -0,0 +1,20 @@ +--- +title: Policy +description: 'Rules for guiding certificate self-service.' +--- + +![issuance flow: policy](/images/issuance-flow-policy.png) + +To scale certificate management, it is critical to distribute the responsibility of +managing certificates to the teams that need them. To do this effectively, often a +self-service model is used, teams are considered "customers" of a platform team that +provides the Kubernetes infrastructure (including certificate management). This multi-tenant +model removes the bottleneck of a single team managing certificates for everyone. + +However, to be successful, the platform team should guide its customers to follow best +practices, and ensure that certificates are issued in a secure and consistent way. These +best practices and rules are what we call "policy". Currently, cert-manager distinguishes +between three types of policy: +- [Defaulting Policy](defaulting.md): Defining defaults for Certificate properties. +- [Approval Policy](approval): Restricting who can request which certificates. +- [Issuing Policy](issuing.md): Configuring how requests are mapped to Certificates. diff --git a/content/v1.15-docs/policy/approval/README.md b/content/v1.15-docs/policy/approval/README.md new file mode 100644 index 0000000000..9374fbb374 --- /dev/null +++ b/content/v1.15-docs/policy/approval/README.md @@ -0,0 +1,36 @@ +--- +title: Approval Policy +description: 'Restricting who can request which certificates.' +--- + +![issuance flow: policy](/images/issuance-flow-policy.png) + +In the issuance flow, there are typically two places where non-conforming certificate +requests can be rejected: before sending the X.509 Certificate Signing Request (CSR) to the +issuer, and after receiving the X.509 Certificate by the issuer. In the first case, +it is cert-manager that rejects the request. In the second case, it is the issuer +that rejects the request. + +## Rejecting requests before sending the X.509 Certificate Signing Request (CSR) to the issuer + +cert-manager requires that a [CertificateRequest](../../usage/certificaterequest.md) +is approved before it is sent to the issuer. Also, CertificateSigningRequests must +be approved before they are sent to the issuer. This approval is done by adding an +[approval condition](../../usage/certificaterequest.md#approval) to the resource. + +In a default installation, cert-manager automatically approves all CertificateRequests +and CertificateSigningRequests that use any of its built-in issuers. This is done to +simplify the first-time experience of using cert-manager. However, this is not +recommended for production environments. Instead, you should configure a more strict +auto-approver that limits who can request which certificates. [approver-policy](approver-policy) +is an example of such an auto-approver. + +## Rejecting requests after receiving the X.509 Certificate Signing Request (CSR) by the issuer + +After receiving the X.509 Certificate Signing Request (CSR), the logic to reject requests +is up to the issuer. cert-manager supports a large number of issuers, each issuer +has full autonomy over what requests are rejected and what error messages are returned. +Additionally, an issuer could also choose accept all requests and instead +override the non-conforming properties in the CSR. More generally, +the issuer is free to use any logic to map the properties in the X.509 Certificate Signing Request (CSR) +to the properties in the X.509 Certificate (see [Issuing Policy](../issuing.md). diff --git a/content/v1.15-docs/policy/approval/approver-policy/README.md b/content/v1.15-docs/policy/approval/approver-policy/README.md new file mode 100644 index 0000000000..07205e031a --- /dev/null +++ b/content/v1.15-docs/policy/approval/approver-policy/README.md @@ -0,0 +1,399 @@ +--- +title: approver-policy +description: 'Policy plugin for cert-manager' +--- + +approver-policy is a cert-manager +[approver](../../../usage/certificaterequest.md#approval) +that will approve or deny CertificateRequests based on policies defined in +the `CertificateRequestPolicy` custom resource. + +## Installation + +See the [installation guide](./installation.md) for instructions on how to +install approver-policy. + +## Configuration + +> Example policy resources can be found +> [here](https://github.com/cert-manager/approver-policy/tree/main/docs/examples). + +When a CertificateRequest is created, approver-policy will evaluate whether the +request is appropriate for any existing policy, and if so, evaluate whether it +should be approved or denied. + +For a CertificateRequest to be appropriate for a policy and therefore be +evaluated by it, it must be both bound via RBAC _and_ be selected by the policy +selector. CertificateRequestPolicy currently only supports `issuerRef` as a +selector. + +**If at least one policy permits the request, the request is approved. If at +least one policy is appropriate for the request but none of those permit the +request, the request is denied.** + +A denied CertificateRequest is considered to be permanently failed. If it was +created for a Certificate resource, the issuance will be retried with +[exponential backoff](../../../faq/README.md#what-happens-if-issuance-fails-will-it-be-retried) +like all other permanent issuance failures. A CertificateRequest that is neither +approved nor denied (because no matching policy was found) will not be further +processed by cert-manager until it gets either approved or denied. + +CertificateRequestPolicies are cluster scoped resources that can be thought of +as "policy profiles". They describe any request that is approved by that +policy. Policies are bound to Kubernetes users and ServiceAccounts using RBAC. + +Below is an example of a policy that is bound to all Kubernetes users who may +only request certificates that have the common name of `"hello.world"`. + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: test-policy +spec: + allowed: + commonName: + value: "hello.world" + required: true + selector: + # Select all IssuerRef + issuerRef: {} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: cert-manager-policy:hello-world +rules: + - apiGroups: ["policy.cert-manager.io"] + resources: ["certificaterequestpolicies"] + verbs: ["use"] + # Name of the CertificateRequestPolicies to be used. + resourceNames: ["test-policy"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cert-manager-policy:hello-world +roleRef: +# ClusterRole or Role _must_ be bound to a user for the policy to be considered. + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cert-manager-policy:hello-world +subjects: +# The users who should be bound to the policies defined. +# Note that in the case of users creating Certificate resources, cert-manager +# is the entity that is creating the actual CertificateRequests, and so the +# cert-manager controller's +# Service Account should be bound instead. +- kind: Group + name: system:authenticated + apiGroup: rbac.authorization.k8s.io +``` + +## Behavior + +CertificateRequestPolicy are split into 4 parts; `allowed`, `contraints`, +`selector`, and `plugins`. + +### Allowed + +Allowed is the block that defines attributes that match against the +corresponding attribute in the request. A request is permitted by the policy if +the request omits an allowed attribute, but will _deny_ the request if it +contains an attribute which is _not_ present in the allowed block. + +An allowed attribute can be marked as `required`, which if true, will enforce +that the attribute has been defined in the request. A field can only be marked +as `required` if the corresponding field is also defined. The `required` field +is not available for `isCA` or `usages`. + +In the following CertificateRequestPolicy, a request will be permitted if it +does not request a DNS name, requests the DNS name `"example.com"`, but will be +denied when requesting `"bar.example.com"`. + +```yaml +spec: + ... + allowed: + dnsNames: + values: + - "example.com" + - "foo.example.com" + ... +``` + +In the following, a request will be denied if the request contains no Common +Name, but will permit requests whose Common Name ends in ".com". + +```yaml +spec: + ... + allowed: + commonName: + value: "*.com" + required: true + ... +``` + +If an allowed field is omitted, that attribute is considered "deny all" for +requests. + +Allowed string fields accept wildcards "\*" within its values. Wildcards "\*" in +patterns represent any string that has a length of 0 or more. A pattern +containing only "\*" will match anything. A pattern containing `"\*foo"` will +match `"foo"` as well as any string which ends in `"foo"` (e.g. `"bar-foo"`). A +pattern containing `"\*.foo"` will match `"bar-123.foo"`, but not `"barfoo"`. + +Allowed fields that are lists will permit requests that are a subset of that +list. This means that if `usages` contains `["server auth", "client auth"]`, +then a request containing only `["server auth"]` would be permitted, but not +`["server auth", "cert sign"]`. + +Below is an example including all supported allowed fields of +CertificateRequestPolicy. + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: my-policy +spec: + allowed: + commonName: + value: "example.com" + dnsNames: + values: + - "example.com" + - "*.example.com" + ipAddresses: + values: + - "1.2.3.4" + - "10.0.1.*" + uris: + values: + - "spiffe://example.org/ns/*/sa/*" + emailAddresses: + values: + - "*@example.com" + required: true + isCA: false + usages: + - "server auth" + - "client auth" + subject: + organizations: + values: ["hello-world"] + countries: + values: ["*"] + organizationalUnits: + values: ["*"] + localities: + values: ["*"] + provinces: + values: ["*"] + streetAddresses: + values: ["*"] + postalCodes: + values: ["*"] + serialNumber: + value: "*" + ... +``` + +#### Validations + +Since approver-policy 0.11.0 it is now possible to define more advanced allowed +request attribute validation rules using +[Common Expression Language (CEL)](https://kubernetes.io/docs/reference/using-api/cel/). +The main motivation for adding this feature was to enable allowed request +attribute values as a function of the request namespace. But since CEL is a +small programming language, validation rules can also complement or replace the +basic wildcard support in `allowed` attribute value specification. + +The request attribute value is made available to the expression in the `self` variable. +For multi-valued request attributes, the validation will be performed once per value. +Similarly to the `self` variable, approver-policy provides the `cr` variable representing +the request to validate. This variable is of object type, and at time of writing it has +just two fields: `namespace` and `name`. + +In the following, we use approver-policy CEL validation rules to ensure +[X.509 SVID certificates](https://github.com/spiffe/spiffe/blob/890b9266095d37bad189529367f31de9be2504b6/standards/X509-SVID.md) +are issued with a [SPIFFE ID](https://github.com/spiffe/spiffe/blob/890b9266095d37bad189529367f31de9be2504b6/standards/SPIFFE-ID.md) +(X.509 URI SAN) identifying the namespace (and service account). + +```yaml +spec: + ... + allowed: + uris: + validations: + - rule: self.startsWith('spiffe://trust.domain/ns/' + cr.namespace + '/sa/') + message: only URIs representing the current namespace in the SPIFFE ID are allowed. + ... +``` + +For details on where CEL validations can be used, please refer to the approver-policy +[API reference documentation](./api-reference.md). +And for writing CEL expression the +[CEL language definition](https://github.com/google/cel-spec/blob/master/doc/langdef.md) +might be useful. + +### Constraints + +Constraints is the block that is used to limit what attributes the request can +have. If a constraint is not defined, then the attribute is considered "allow +all". + +Below is an example containing all supported constraints fields of +CertificateRequestPolicy. + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: my-policy +spec: + ... + constraints: + minDuration: 1h + maxDuration: 24h + privateKey: + algorithm: RSA + minSize: 2048 + maxSize: 4096 + ... +``` + +### Selector + +Selector is a required field that is used for matching +CertificateRequestPolicies against CertificateRequests for evaluation. A +CertificateRequestPolicy must select, and therefore match, a CertificateRequest +for it to be considered for evaluation of the request. + +> ⚠️ Note that the user must still be bound by [RBAC](#configuration) for +> the policy to be considered for evaluation against a request. + +approver-policy supports selecting over the `issuerRef` and the `namespace` of a +request. + +At least either an `issuerRef` *or* `namespace` selector must be defined, even +if set to empty (`{}`). **Both** selectors must match on a CertificateRequest +for the request to evaluated by the policy if both are defined. + +#### `issuerRef` + +The `issuerRef` CertificateRequestPolicy selector selects on the corresponding +`issuerRef` stanza on the CertificateRequest. + +`issuerRef` values accept wildcards "\*". If an `issuerRef` is set to an empty +object `{}`, then the policy will match against _all_ requests. + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: my-policy +spec: + ... + selector: + issuerRef: + name: "my-ca" + kind: "*Issuer" + group: "cert-manager.io" +``` + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: match-all-requests +spec: + ... + selector: + issuerRef: {} +``` + +#### `namespace` + +The `namespace` CertificateRequestPolicy selector selects on the Namespace to +which the CertificateRequest was created in. The selector can be defined with +either `matchNames` or `matchLabels`. + +`matchNames` takes a list of strings which match the _name_ of the Namespace. +Accepts wildcards "\*". + +`matchLabels` takes a list of key value strings which match on the labels of the +Namespace that the CertificateRequest was created in. Please see the [Kubernetes +documentation][] for more information on `matchLabels` behavior. + +If a `namespace` is set to an empty object `{}`, then the policy will match +against _all_ requests. + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: my-policy +spec: + ... + selector: + namespace: + matchNames: + - "default" + - "app-team-*" + matchLabels: + foo: bar + team: dev +``` + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: match-all-requests +spec: + ... + selector: + namespace: {} +``` + +[Kubernetes documentation]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#resources-that-support-set-based-requirements + +### Plugins + +Plugins are external approvers that are built into approver-policy at compile +time. Plugins are designed to be used as extensions to the existing policy +checks where the user requires special functionality that the existing checks +can't provide. + +Plugins are defined as a block on the CertificateRequestPolicy `spec`. + +```yaml +apiVersion: policy.cert-manager.io/v1alpha1 +kind: CertificateRequestPolicy +metadata: + name: plugins +spec: + ... + plugins: + my-plugin: + values: + val-1: key-1 +``` + +## Known Plugins from the Community + +- ~~[CEL approver-policy plugin](https://github.com/erikgb/cel-approver-policy-plugin)~~ + (archived; CEL support in approver-policy now) + +If you want to implement an external approver policy plugin take a look at the +example implementation at +https://github.com/cert-manager/example-approver-policy-plugin. + +Have you implemented a plugin for approver-policy? Feel free to add a link to your plugin from this page by +opening a pull request in the [cert-manager website project](https://github.com/cert-manager/website). + +## API Reference + +> 📖 Read the [approver-policy API reference](api-reference.md). diff --git a/content/v1.15-docs/policy/approval/approver-policy/api-reference.md b/content/v1.15-docs/policy/approval/approver-policy/api-reference.md new file mode 100644 index 0000000000..397d85aac4 --- /dev/null +++ b/content/v1.15-docs/policy/approval/approver-policy/api-reference.md @@ -0,0 +1,2085 @@ +--- +title: approver-policy API Reference +description: "approver-policy API documentation" +--- + +Packages: + +- [`policy.cert-manager.io/v1alpha1`](#policycert-manageriov1alpha1) + +# `policy.cert-manager.io/v1alpha1` + +Resource Types: + + +- [CertificateRequestPolicy](#certificaterequestpolicy) + + + + +## `CertificateRequestPolicy` + + + + + +CertificateRequestPolicy is an object for describing a "policy profile" that +makes decisions on whether applicable CertificateRequests should be approved +or denied. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
apiVersionstringpolicy.cert-manager.io/v1alpha1true
kindstringCertificateRequestPolicytrue
metadataobjectRefer to the Kubernetes API documentation for the fields of the `metadata` field.true
specobject + CertificateRequestPolicySpec defines the desired state of +CertificateRequestPolicy. +
+
false
statusobject + CertificateRequestPolicyStatus defines the observed state of the +CertificateRequestPolicy. +
+
false
+ + +### `CertificateRequestPolicy.spec` + + +CertificateRequestPolicySpec defines the desired state of +CertificateRequestPolicy. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
selectorobject + Selector is used for selecting over which CertificateRequests this +CertificateRequestPolicy is appropriate for and so will be used for its +approval evaluation. +
+
true
allowedobject + Allowed defines the allowed attributes for a CertificateRequest. +A CertificateRequest can request _less_ than what is allowed, +but _not more_, i.e. a CertificateRequest can request a subset of what +is declared as allowed by the policy. +Omitted fields declare that the equivalent CertificateRequest +field _must_ be omitted or have an empty value for the request to be +permitted. +
+
false
constraintsobject + Constraints define fields that _must_ be satisfied by a +CertificateRequest for the request to be allowed by this policy. +Omitted fields place no restrictions on the corresponding +attribute in a request. +
+
false
pluginsmap[string]object + Plugins are approvers that are built into approver-policy at +compile-time. This is an advanced feature typically used to extend +approver-policy core features. This field define plugins and their +configuration that should be executed when this policy is evaluated +against a CertificateRequest. +
+
false
+ + +### `CertificateRequestPolicy.spec.selector` + + +Selector is used for selecting over which CertificateRequests this +CertificateRequestPolicy is appropriate for and so will be used for its +approval evaluation. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
issuerRefobject + IssuerRef is used to match by issuer, meaning the +CertificateRequestPolicy will only evaluate CertificateRequests +referring to matching issuers. +CertificateRequests will not be processed if the issuer does not match, +regardless of whether the requestor is bound by RBAC. + + +The following value will match _all_ issuers: +``` +issuerRef: {} +``` +
+
false
namespaceobject + Namespace is used to match by namespace, meaning the +CertificateRequestPolicy will only match CertificateRequests +created in matching namespaces. +If this field is omitted, resources in all namespaces are checked. +
+
false
+ + +### `CertificateRequestPolicy.spec.selector.issuerRef` + + +IssuerRef is used to match by issuer, meaning the +CertificateRequestPolicy will only evaluate CertificateRequests +referring to matching issuers. +CertificateRequests will not be processed if the issuer does not match, +regardless of whether the requestor is bound by RBAC. + + +The following value will match _all_ issuers: +``` +issuerRef: {} +``` + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
groupstring + Group is the wildcard selector to match the `spec.issuerRef.group` field +on requests. +Accepts wildcards "*". +An omitted field matches all groups. +
+
false
kindstring + Kind is the wildcard selector to match the `spec.issuerRef.kind` field +on requests. +Accepts wildcards "*". +An omitted field matches all kinds. +
+
false
namestring + Name is a wildcard enabled selector that matches the +`spec.issuerRef.name` field of requests. +Accepts wildcards "*". +An omitted field matches all names. +
+
false
+ + +### `CertificateRequestPolicy.spec.selector.namespace` + + +Namespace is used to match by namespace, meaning the +CertificateRequestPolicy will only match CertificateRequests +created in matching namespaces. +If this field is omitted, resources in all namespaces are checked. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
matchLabelsmap[string]string + MatchLabels is the set of Namespace labels that select on +CertificateRequests which have been created in a namespace matching the +selector. +
+
false
matchNames[]string + MatchNames is the set of namespace names that select on +CertificateRequests that have been created in a matching namespace. +Accepts wildcards "*". +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed` + + +Allowed defines the allowed attributes for a CertificateRequest. +A CertificateRequest can request _less_ than what is allowed, +but _not more_, i.e. a CertificateRequest can request a subset of what +is declared as allowed by the policy. +Omitted fields declare that the equivalent CertificateRequest +field _must_ be omitted or have an empty value for the request to be +permitted. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
commonNameobject + CommonName defines the X.509 Common Name that may be requested. +
+
false
dnsNamesobject + DNSNames defines the X.509 DNS SANs that may be requested. +
+
false
emailAddressesobject + EmailAddresses defines the X.509 Email SANs that may be requested. +
+
false
ipAddressesobject + IPAddresses defines the X.509 IP SANs that may be requested. +
+
false
isCAboolean + IsCA defines if a CertificateRequest is allowed to set the `spec.isCA` +field set to `true`. +If `true`, the `spec.isCA` field can be `true` or `false`. +If `false` or unset, the `spec.isCA` field must be `false`. +
+
false
subjectobject + Subject declares the X.509 Subject attributes allowed in a +CertificateRequest. An omitted field forbids any Subject attributes +from being requested. +A CertificateRequest can request a subset of the allowed X.509 Subject +attributes. +
+
false
urisobject + URIs defines the X.509 URI SANs that may be requested. +
+
false
usages[]enum + Usages defines the key usages that may be included in a +CertificateRequest `spec.keyUsages` field. +If set, `spec.keyUsages` in a CertificateRequest must be a subset of the +specified values. +If `[]` or unset, no `spec.keyUsages` are allowed. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.commonName` + + +CommonName defines the X.509 Common Name that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required marks that the related field must be provided and not be an +empty string. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute value present on request beyond what is possible +to express using value/required. +An attribute value on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
valuestring + Value defines the allowed attribute value on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field must match the specified pattern. + + +NOTE:`value: ""` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.commonName.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.dnsNames` + + +DNSNames defines the X.509 DNS SANs that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.dnsNames.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.emailAddresses` + + +EmailAddresses defines the X.509 Email SANs that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.emailAddresses.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.ipAddresses` + + +IPAddresses defines the X.509 IP SANs that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.ipAddresses.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject` + + +Subject declares the X.509 Subject attributes allowed in a +CertificateRequest. An omitted field forbids any Subject attributes +from being requested. +A CertificateRequest can request a subset of the allowed X.509 Subject +attributes. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
countriesobject + Countries define the X.509 Subject Countries that may be requested. +
+
false
localitiesobject + Localities defines the X.509 Subject Localities that may be requested. +
+
false
organizationalUnitsobject + OrganizationalUnits defines the X.509 Subject Organizational Units that +may be requested. +
+
false
organizationsobject + Organizations define the X.509 Subject Organizations that may be +requested. +
+
false
postalCodesobject + PostalCodes defines the X.509 Subject Postal Codes that may be requested. +
+
false
provincesobject + Provinces defines the X.509 Subject Provinces that may be requested. +
+
false
serialNumberobject + SerialNumber defines the X.509 Subject Serial Number that may be +requested. +
+
false
streetAddressesobject + StreetAddresses defines the X.509 Subject Street Addresses that may be +requested. +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.countries` + + +Countries define the X.509 Subject Countries that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.countries.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.localities` + + +Localities defines the X.509 Subject Localities that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.localities.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.organizationalUnits` + + +OrganizationalUnits defines the X.509 Subject Organizational Units that +may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.organizationalUnits.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.organizations` + + +Organizations define the X.509 Subject Organizations that may be +requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.organizations.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.postalCodes` + + +PostalCodes defines the X.509 Subject Postal Codes that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.postalCodes.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.provinces` + + +Provinces defines the X.509 Subject Provinces that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.provinces.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.serialNumber` + + +SerialNumber defines the X.509 Subject Serial Number that may be +requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required marks that the related field must be provided and not be an +empty string. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute value present on request beyond what is possible +to express using value/required. +An attribute value on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
valuestring + Value defines the allowed attribute value on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field must match the specified pattern. + + +NOTE:`value: ""` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.serialNumber.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.streetAddresses` + + +StreetAddresses defines the X.509 Subject Street Addresses that may be +requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.subject.streetAddresses.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.uris` + + +URIs defines the X.509 URI SANs that may be requested. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
requiredboolean + Required controls whether the related field must have at least one value. +Defaults to `false`. +
+
false
validations[]object + Validations applies rules using Common Expression Language (CEL) to +validate attribute values present on request beyond what is possible +to express using values/required. +ALL attribute values on the related CertificateRequest field must pass +ALL validations for the request to be granted by this policy. +
+
false
values[]string + Values defines allowed attribute values on the related CertificateRequest field. +Accepts wildcards "*". +If set, the related field can only include items contained in the allowed values. + + +NOTE:`values: []` paired with `required: true` establishes a policy that +will never grant a `CertificateRequest`, but other policies may. +TODO: add x-kubernetes-list-type: set in v1alpha2 +
+
false
+ + +### `CertificateRequestPolicy.spec.allowed.uris.validations[index]` + + +ValidationRule describes a validation rule expressed in CEL. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
rulestring + Rule represents the expression which will be evaluated by CEL. +ref: https://github.com/google/cel-spec +The Rule is scoped to the location of the validations in the schema. +The `self` variable in the CEL expression is bound to the scoped value. +To enable more advanced validation rules, approver-policy provides the +`cr` (map) variable to the CEL expression containing `namespace` and +`name` of the `CertificateRequest` resource. + + +Example (rule for namespaced DNSNames): +``` +rule: self.endsWith(cr.namespace + '.svc.cluster.local') +``` +
+
true
messagestring + Message is the message to display when validation fails. +Message is required if the Rule contains line breaks. Note that Message +must not contain line breaks. +If unset, a fallback message is used: "failed rule: ``". +e.g. "must be a URL with the host matching spec.host" +
+
false
+ + +### `CertificateRequestPolicy.spec.constraints` + + +Constraints define fields that _must_ be satisfied by a +CertificateRequest for the request to be allowed by this policy. +Omitted fields place no restrictions on the corresponding +attribute in a request. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
maxDurationstring + MaxDuration defines the maximum duration for a certificate request. +for. +Values are inclusive (i.e. a value of `1h` will accept a duration of +`1h`). MinDuration and MaxDuration may be the same value. +If set, a duration _must_ be requested in the CertificateRequest. +An omitted field applies no maximum constraint for duration. +
+
false
minDurationstring + MinDuration defines the minimum duration for a certificate request. +Values are inclusive (i.e. a value of `1h` will accept a duration of +`1h`). MinDuration and MaxDuration may be the same value. +If set, a duration _must_ be requested in the CertificateRequest. +An omitted field applies no minimum constraint for duration. +
+
false
privateKeyobject + PrivateKey defines constraints on the shape of private key +allowed for a CertificateRequest. +An omitted field applies no private key shape constraints. +
+
false
+ + +### `CertificateRequestPolicy.spec.constraints.privateKey` + + +PrivateKey defines constraints on the shape of private key +allowed for a CertificateRequest. +An omitted field applies no private key shape constraints. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
algorithmenum + Algorithm defines the allowed crypto algorithm for the private key +in a request. +An omitted field permits any algorithm. +
+
+ Enum: RSA, ECDSA, Ed25519
+
false
maxSizeinteger + MaxSize defines the maximum key size for a private key. +Values are inclusive (i.e. a min value of `2048` will accept a size +of `2048`). MaxSize and MinSize may be the same value. +An omitted field applies no maximum constraint on size. +
+
false
minSizeinteger + MinSize defines the minimum key size for a private key. +Values are inclusive (i.e. a min value of `2048` will accept a size +of `2048`). MinSize and MaxSize may be the same value. +An omitted field applies no minimum constraint on size. +
+
false
+ + +### `CertificateRequestPolicy.spec.plugins[key]` + + +CertificateRequestPolicyPluginData is configuration needed by the plugin +approver to evaluate a CertificateRequest on this policy. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
valuesmap[string]string + Values define a set of well-known, to the plugin, key value pairs that +are required for the plugin to successfully evaluate a request based on +this policy. +
+
false
+ + +### `CertificateRequestPolicy.status` + + +CertificateRequestPolicyStatus defines the observed state of the +CertificateRequestPolicy. + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
conditions[]object + List of status conditions to indicate the status of the +CertificateRequestPolicy. +Known condition types are `Ready`. +
+
false
+ + +### `CertificateRequestPolicy.status.conditions[index]` + + +CertificateRequestPolicyCondition contains condition information for a +CertificateRequestPolicyStatus. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
statusstring + Status of the condition, one of ('True', 'False', 'Unknown'). +
+
true
typestring + Type of the condition, known values are (`Ready`). +
+
true
lastTransitionTimestring + LastTransitionTime is the timestamp corresponding to the last status +change of this condition. +
+
+ Format: date-time
+
false
messagestring + Message is a human readable description of the details of the last +transition, complementing reason. +
+
false
observedGenerationinteger + If set, this represents the .metadata.generation that the condition was +set based upon. +For instance, if .metadata.generation is currently 12, but the +.status.condition[x].observedGeneration is 9, the condition is out of +date with respect to the current state of the CertificateRequestPolicy. +
+
+ Format: int64
+
false
reasonstring + Reason is a brief machine readable explanation for the condition's last +transition. +
+
false
diff --git a/content/v1.15-docs/policy/approval/approver-policy/installation.md b/content/v1.15-docs/policy/approval/approver-policy/installation.md new file mode 100644 index 0000000000..9204c45421 --- /dev/null +++ b/content/v1.15-docs/policy/approval/approver-policy/installation.md @@ -0,0 +1,110 @@ +--- +title: Installing approver-policy +description: 'Installation guide for the approver-policy policy plugin for cert-manager' +--- + +## Installation Steps + +### 1. Install cert-manager + +[cert-manager must be installed](../../../installation/README.md), and +the [the default approver in cert-manager must be disabled](../../../usage/certificaterequest.md#approver-controller). + +> ⚠️ If the default approver is not disabled in cert-manager, approver-policy will +> race with cert-manager and policy will be ineffective. + +If you install cert-manager using `helm install` or `helm upgrade`, +you can disable the default approver by [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing) using the `--set` or `--values` command line flags: + +``` +# ⚠️ This Helm option is only available in cert-manager v1.15.0 and later. + +# Example --set value +--set disableAutoApproval=true +``` + +```yaml +# ⚠️ This Helm option is only available in cert-manager v1.15.0 and later. + +# Example --values file content +disableAutoApproval: true +``` + +Here's a example which reconfigure an installed cert-manager to run without auto-approver: + +```terminal +# ⚠️ This Helm option is only available in cert-manager v1.15.0 and later. + +existing_cert_manager_version=$(helm get metadata -n cert-manager cert-manager | grep '^VERSION' | awk '{ print $2 }') +helm upgrade cert-manager jetstack/cert-manager \ + --reuse-values \ + --namespace cert-manager \ + --version $existing_cert_manager_version \ + --set disableAutoApproval=true +``` + +### 2. Install approver-policy + +To install approver-policy: + +```terminal +helm repo add jetstack https://charts.jetstack.io --force-update + +helm upgrade cert-manager-approver-policy jetstack/cert-manager-approver-policy \ + --install \ + --namespace cert-manager \ + --wait +``` + +If you are using approver-policy with [external +issuers](../../../configuration/issuers.md), you _must_ +include their signer names so that approver-policy has permissions to approve +and deny CertificateRequests that +[reference them](../../../usage/certificaterequest.md#rbac-syntax). +For example, if using approver-policy for the internal issuer types, along with +[google-cas-issuer](https://github.com/jetstack/google-cas-issuer), and +[aws-privateca-issuer](https://github.com/cert-manager/aws-privateca-issuer), +set the following values when installing: + +```terminal +helm upgrade cert-manager-approver-policy jetstack/cert-manager-approver-policy \ + --install \ + --namespace cert-manager \ + --wait \ + --set app.approveSignerNames="{\ +issuers.cert-manager.io/*,clusterissuers.cert-manager.io/*,\ +googlecasclusterissuers.cas-issuer.jetstack.io/*,googlecasissuers.cas-issuer.jetstack.io/*,\ +awspcaclusterissuers.awspca.cert-manager.io/*,awspcaissuers.awspca.cert-manager.io/*\ +}" +``` + +## Uninstalling + +To uninstall approver-policy installed via Helm, run: + +```terminal +$ helm uninstall cert-manager-approver-policy --namespace cert-manager +These resources were kept due to the resource policy: +[CustomResourceDefinition] certificaterequestpolicies.policy.cert-manager.io + +release "cert-manager-approver-policy" uninstalled +``` + +As shown in the output, the `CustomResourceDefinition` for `CertificateRequestPolicy` +is not removed by the Helm uninstall command. This to prevent data loss, as removing +the `CustomResourceDefinition` will also remove all `CertificateRequestPolicy` resources. + +> ☢️ This will remove all `CertificateRequestPolicy` resources from the cluster: +> +> ```terminal +> $ kubectl delete crd certificaterequestpolicies.policy.cert-manager.io +> ``` + +> ⚠️ approver-policy versions prior to `v0.13.0` do not keep the `CustomResourceDefinition` on uninstall +> and will remove all `CertificateRequestPolicy` resources from the cluster. Make sure to back up your +> `CertificateRequestPolicy` resources before uninstalling approver-policy if you are using a version +> prior to `v0.13.0`. Or upgrade to `v0.13.0` before uninstalling. + +## Usage + +> 📖 Read the [approver-policy docs](./README.md). diff --git a/content/v1.15-docs/policy/defaulting.md b/content/v1.15-docs/policy/defaulting.md new file mode 100644 index 0000000000..ee885aa9d4 --- /dev/null +++ b/content/v1.15-docs/policy/defaulting.md @@ -0,0 +1,41 @@ +--- +title: Defaulting Policy +description: 'Defining defaults for Certificate properties.' +--- + +![issuance flow: policy](/images/issuance-flow-policy.png) + +In the issuance flow, there are two places where defaults can be applied: before the X.509 +CertificateSigningRequest is created, and before the X.509 Certificate is created. In +the first case, it is cert-manager that applies the defaults. In the second case, it is the +issuer that applies the defaults. + +An important difference between these two cases is that in the first case, there are more +properties that can be defaulted. For example, since the private key still has to be generated, +all the properties of the private key can be defaulted. In the second case, the private key +has already been generated. Also, the issuer reference itself can be defaulted in the first +case, but not in the second case. For example, in a specific namespace, the issuer can be +defaulted to a specific issuer. + +Defaulting is done to simplify the experience of the person requesting the certificate. It +does not prevent the person from overriding the defaults. Therefore, an approval policy can +be used (see [Approval Policy](approval) for more details). + +## Defaults applied by cert-manager: before creating the X.509 Certificate Signing Request (CSR) + +To apply defaults before the X.509 Certificate Signing Request (CSR) is created, defaults must be +applied to the inputs used to create the CSR. After the CSR is created, it cannot be modified without +invalidating the its signature. This means that defaults cannot be applied to any of the properties of +the CSR included in the CertificateRequest or CertificateSigningRequest resource. + +Instead, defaults must be applied to the Certificate resource that is used to create the CertificateSigningRequest. +When using a CSI driver, defaults must be applied to CSI annotations or CSI driver configuration. +To dynamically apply defaults to these resources, you can use tools like [`kyverno`](https://kyverno.io/). +CI/CD tools like Helm, kustomize, ... can also be used to template and apply defaults to these resources. + +## Defaults applied by the issuer: before creating the X.509 Certificate + +Before creating the X.509 Certificate, the issuer can use default values for properties in +the resulting certificate. More generally, the issuer is free to use any logic to map the +properties in the X.509 Certificate Signing Request (CSR) to the properties in the X.509 Certificate +(see [Issuing Policy](issuing.md) for more details). diff --git a/content/v1.15-docs/policy/issuing.md b/content/v1.15-docs/policy/issuing.md new file mode 100644 index 0000000000..b573a5b1a7 --- /dev/null +++ b/content/v1.15-docs/policy/issuing.md @@ -0,0 +1,21 @@ +--- +title: Issuing Policy +description: 'Configuring how requests are mapped to Certificates.' +--- + +![issuance flow: policy](/images/issuance-flow-policy.png) + +cert-manager integrates with a large number of different certificate issuers, each +issuer has full autonomy over what issued certificates look like and what properties +they have. cert-manager does not require or enforce any specific relationship between +the properties in a CertificateRequest/ CertificateSigningRequest and the properties +in the issued certificate (except for the public key which must match). + +For the core [SelfSigned](../configuration/selfsigned.md) and [CA](../configuration/ca.md) issuers, +cert-manager implements its own issuing policy. This policy is very simple and is not configurable. +All the requested properties will be copied into the issued certificate. + +Another example is the [Let's Encrypt CA issuer](https://letsencrypt.org/) which also implements its own issuing policy. This policy is more complex than a 1:1 +copy of the requested properties. For example, the Let's Encrypt issuer will always +[issue certificates with a 90 day validity period](https://letsencrypt.org/2015/11/09/why-90-days). +Also, it only supports a [limited set of (extended) key usages](https://community.letsencrypt.org/t/custom-extendedkeyusage-stripped-from-csr-while-generating-cert/17759/2). \ No newline at end of file diff --git a/content/v1.15-docs/reference/README.md b/content/v1.15-docs/reference/README.md new file mode 100644 index 0000000000..473828e355 --- /dev/null +++ b/content/v1.15-docs/reference/README.md @@ -0,0 +1,15 @@ +--- +title: Reference +description: Reference material including TLS terminology, API documentation, and information about the command line flags of the cert-manager components. +--- + +This section contains reference material including TLS terminology, API documentation, and information about the command line flags of the cert-manager components. + +* [TLS Terminology](./tls-terminology.md): + Learn about the TLS terminology used in the cert-manager documentation such as `publicly trusted`, `self-signed`, `root`, `intermediate` and `leaf` _certificate_. + +* [Components / Docker Images](../cli/README.md): + Learn about the command line flags of the cert-manager Docker images: `controller`, `webhook`, `cainjector`, `acmesolver`, which run in containers in your cluster. + +* [API Reference](./api-docs.md): + Learn about the cert-manager API which includes Custom Resources such as Certificate, CertificateRequest, Issuer and ClusterIssuer. diff --git a/content/v1.15-docs/reference/api-docs.md b/content/v1.15-docs/reference/api-docs.md new file mode 100644 index 0000000000..eb030dfcc2 --- /dev/null +++ b/content/v1.15-docs/reference/api-docs.md @@ -0,0 +1,6791 @@ +--- +title: API Reference +description: >- + cert-manager API documentation, including Custom Resources such as + Certificate, CertificateRequest, Issuer and ClusterIssuer +--- +

cert-manager API documentation, including various Custom Resource Definitions

+

Packages:

+ +

acme.cert-manager.io/v1

+
+

Package v1 is the v1 version of the API.

+
+

Resource Types:

+ +

Challenge

+
+

Challenge is a type to represent a Challenge request with an ACME server

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ apiVersion +
+ string +
+ acme.cert-manager.io/v1 +
+ kind +
+ string +
+ Challenge +
+ metadata +
+ + Kubernetes meta/v1.ObjectMeta + +
+ Refer to the Kubernetes API documentation for the fields of the + metadata field. +
+ spec +
+ + ChallengeSpec + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ url +
+ string +
+

The URL of the ACME Challenge resource for this challenge. This can be used to lookup details about the status of this challenge.

+
+ authorizationURL +
+ string +
+

The URL to the ACME Authorization resource that this challenge is a part of.

+
+ dnsName +
+ string +
+

dnsName is the identifier that this challenge is for, e.g. example.com. If the requested DNSName is a ‘wildcard’, this field MUST be set to the non-wildcard domain, e.g. for *.example.com, it must be example.com.

+
+ wildcard +
+ bool +
+ (Optional) +

wildcard will be true if this challenge is for a wildcard identifier, for example ‘*.example.com’.

+
+ type +
+ + ACMEChallengeType + +
+

The type of ACME challenge this resource represents. One of “HTTP-01” or “DNS-01”.

+
+ token +
+ string +
+

The ACME challenge token for this challenge. This is the raw value returned from the ACME server.

+
+ key +
+ string +
+

+ The ACME challenge key for this challenge For HTTP01 challenges, this is the value that must be responded with to complete the HTTP01 challenge in the format: + <private key JWK thumbprint>.<key from acme server for challenge>. For DNS01 challenges, this is the base64 encoded SHA256 sum of the + <private key JWK thumbprint>.<key from acme server for challenge> + text that must be set as the TXT record content. +

+
+ solver +
+ + ACMEChallengeSolver + +
+

Contains the domain solving configuration that should be used to solve this challenge resource.

+
+ issuerRef +
+ + ObjectReference + +
+

References a properly configured ACME-type Issuer which should be used to create this Challenge. If the Issuer does not exist, processing will be retried. If the Issuer is not an ‘ACME’ Issuer, an error will be returned and the Challenge will be marked as failed.

+
+
+ status +
+ + ChallengeStatus + +
+ (Optional) +
+

Order

+
+

Order is a type to represent an Order with an ACME server

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ apiVersion +
+ string +
+ acme.cert-manager.io/v1 +
+ kind +
+ string +
+ Order +
+ metadata +
+ + Kubernetes meta/v1.ObjectMeta + +
+ Refer to the Kubernetes API documentation for the fields of the + metadata field. +
+ spec +
+ + OrderSpec + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ request +
+ []byte +
+

Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order.

+
+ issuerRef +
+ + ObjectReference + +
+

IssuerRef references a properly configured ACME-type Issuer which should be used to create this Order. If the Issuer does not exist, processing will be retried. If the Issuer is not an ‘ACME’ Issuer, an error will be returned and the Order will be marked as failed.

+
+ commonName +
+ string +
+ (Optional) +

CommonName is the common name as specified on the DER encoded CSR. If specified, this value must also be present in dnsNames or ipAddresses. This field must match the corresponding field on the DER encoded CSR.

+
+ dnsNames +
+ []string +
+ (Optional) +

DNSNames is a list of DNS names that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR.

+
+ ipAddresses +
+ []string +
+ (Optional) +

IPAddresses is a list of IP addresses that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR.

+
+ duration +
+ + Kubernetes meta/v1.Duration + +
+ (Optional) +

Duration is the duration for the not after date for the requested certificate. this is set on order creation as pe the ACME spec.

+
+
+ status +
+ + OrderStatus + +
+ (Optional) +
+

ACMEAuthorization

+

(Appears on: OrderStatus)

+
+

ACMEAuthorization contains data returned from the ACME server on an authorization that must be completed in order validate a DNS name on an ACME Order resource.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ url +
+ string +
+

URL is the URL of the Authorization that must be completed

+
+ identifier +
+ string +
+ (Optional) +

Identifier is the DNS name to be validated as part of this authorization

+
+ wildcard +
+ bool +
+ (Optional) +

Wildcard will be true if this authorization is for a wildcard DNS name. If this is true, the identifier will be the non-wildcard version of the DNS name. For example, if ‘*.example.com’ is the DNS name being validated, this field will be ‘true’ and the ‘identifier’ field will be ‘example.com’.

+
+ initialState +
+ + State + +
+ (Optional) +

InitialState is the initial state of the ACME authorization when first fetched from the ACME server. If an Authorization is already ‘valid’, the Order controller will not create a Challenge resource for the authorization. This will occur when working with an ACME server that enables ‘authz reuse’ (such as Let’s Encrypt’s production endpoint). If not set and ‘identifier’ is set, the state is assumed to be pending and a Challenge will be created.

+
+ challenges +
+ + []ACMEChallenge + +
+ (Optional) +

Challenges specifies the challenge types offered by the ACME server. One of these challenge types will be selected when validating the DNS name and an appropriate Challenge resource will be created to perform the ACME challenge process.

+
+

ACMEChallenge

+

(Appears on: ACMEAuthorization)

+
+

Challenge specifies a challenge offered by the ACME server for an Order. An appropriate Challenge resource can be created to perform the ACME challenge process.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ url +
+ string +
+

URL is the URL of this challenge. It can be used to retrieve additional metadata about the Challenge from the ACME server.

+
+ token +
+ string +
+

Token is the token that must be presented for this challenge. This is used to compute the ‘key’ that must also be presented.

+
+ type +
+ string +
+

Type is the type of challenge being offered, e.g. ‘http-01’, ‘dns-01’, ‘tls-sni-01’, etc. This is the raw value retrieved from the ACME server. Only ‘http-01’ and ‘dns-01’ are supported by cert-manager, other values will be ignored.

+
+

ACMEChallengeSolver

+

(Appears on: ACMEIssuer, ChallengeSpec)

+
+

An ACMEChallengeSolver describes how to solve ACME challenges for the issuer it is part of. A selector may be provided to use different solving strategies for different DNS names. Only one of HTTP01 or DNS01 must be provided.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ selector +
+ + CertificateDNSNameSelector + +
+ (Optional) +

Selector selects a set of DNSNames on the Certificate resource that should be solved using this challenge solver. If not specified, the solver will be treated as the ‘default’ solver with the lowest priority, i.e. if any other solver has a more specific match, it will be used instead.

+
+ http01 +
+ + ACMEChallengeSolverHTTP01 + +
+ (Optional) +

Configures cert-manager to attempt to complete authorizations by performing the HTTP01 challenge flow. It is not possible to obtain certificates for wildcard domain names (e.g. *.example.com) using the HTTP01 challenge mechanism.

+
+ dns01 +
+ + ACMEChallengeSolverDNS01 + +
+ (Optional) +

Configures cert-manager to attempt to complete authorizations by performing the DNS01 challenge flow.

+
+

ACMEChallengeSolverDNS01

+

(Appears on: ACMEChallengeSolver)

+
+

Used to configure a DNS01 challenge provider to be used when solving DNS01 challenges. Only one DNS provider may be configured per solver.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ cnameStrategy +
+ + CNAMEStrategy + +
+ (Optional) +

CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones.

+
+ akamai +
+ + ACMEIssuerDNS01ProviderAkamai + +
+ (Optional) +

Use the Akamai DNS zone management API to manage DNS01 challenge records.

+
+ cloudDNS +
+ + ACMEIssuerDNS01ProviderCloudDNS + +
+ (Optional) +

Use the Google Cloud DNS API to manage DNS01 challenge records.

+
+ cloudflare +
+ + ACMEIssuerDNS01ProviderCloudflare + +
+ (Optional) +

Use the Cloudflare API to manage DNS01 challenge records.

+
+ route53 +
+ + ACMEIssuerDNS01ProviderRoute53 + +
+ (Optional) +

Use the AWS Route53 API to manage DNS01 challenge records.

+
+ azureDNS +
+ + ACMEIssuerDNS01ProviderAzureDNS + +
+ (Optional) +

Use the Microsoft Azure DNS API to manage DNS01 challenge records.

+
+ digitalocean +
+ + ACMEIssuerDNS01ProviderDigitalOcean + +
+ (Optional) +

Use the DigitalOcean DNS API to manage DNS01 challenge records.

+
+ acmeDNS +
+ + ACMEIssuerDNS01ProviderAcmeDNS + +
+ (Optional) +

Use the ‘ACME DNS’ (https://github.com/joohoi/acme-dns) API to manage DNS01 challenge records.

+
+ rfc2136 +
+ + ACMEIssuerDNS01ProviderRFC2136 + +
+ (Optional) +

Use RFC2136 (“Dynamic Updates in the Domain Name System”) (https://datatracker.ietf.org/doc/rfc2136/) to manage DNS01 challenge records.

+
+ webhook +
+ + ACMEIssuerDNS01ProviderWebhook + +
+ (Optional) +

Configure an external webhook based DNS01 challenge solver to manage DNS01 challenge records.

+
+

ACMEChallengeSolverHTTP01

+

(Appears on: ACMEChallengeSolver)

+
+

ACMEChallengeSolverHTTP01 contains configuration detailing how to solve HTTP01 challenges within a Kubernetes cluster. Typically this is accomplished through creating ‘routes’ of some description that configure ingress controllers to direct traffic to ‘solver pods’, which are responsible for responding to the ACME server’s HTTP requests. Only one of Ingress / Gateway can be specified.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ ingress +
+ + ACMEChallengeSolverHTTP01Ingress + +
+ (Optional) +

The ingress based HTTP01 challenge solver will solve challenges by creating or modifying Ingress resources in order to route requests for ‘/.well-known/acme-challenge/XYZ’ to ‘challenge solver’ pods that are provisioned by cert-manager for each Challenge to be completed.

+
+ gatewayHTTPRoute +
+ + ACMEChallengeSolverHTTP01GatewayHTTPRoute + +
+ (Optional) +

The Gateway API is a sig-network community API that models service networking in Kubernetes (https://gateway-api.sigs.k8s.io/). The Gateway solver will create HTTPRoutes with the specified labels in the same namespace as the challenge. This solver is experimental, and fields / behaviour may change in the future.

+
+

ACMEChallengeSolverHTTP01GatewayHTTPRoute

+

(Appears on: ACMEChallengeSolverHTTP01)

+
+

The ACMEChallengeSolverHTTP01GatewayHTTPRoute solver will create HTTPRoute objects for a Gateway class routing to an ACME challenge solver pod.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ serviceType +
+ + Kubernetes core/v1.ServiceType + +
+ (Optional) +

Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort.

+
+ labels +
+ map[string]string +
+ (Optional) +

Custom labels that will be applied to HTTPRoutes created by cert-manager while solving HTTP-01 challenges.

+
+ parentRefs +
+ []sigs.k8s.io/gateway-api/apis/v1.ParentReference +
+

+ When solving an HTTP-01 challenge, cert-manager creates an HTTPRoute. cert-manager needs to know which parentRefs should be used when creating the HTTPRoute. Usually, the parentRef references a Gateway. See: + https://gateway-api.sigs.k8s.io/api-types/httproute/#attaching-to-gateways +

+
+

ACMEChallengeSolverHTTP01Ingress

+

(Appears on: ACMEChallengeSolverHTTP01)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ serviceType +
+ + Kubernetes core/v1.ServiceType + +
+ (Optional) +

Optional service type for Kubernetes solver service. Supported values are NodePort or ClusterIP. If unset, defaults to NodePort.

+
+ ingressClassName +
+ string +
+ (Optional) +

This field configures the field ingressClassName on the created Ingress resources used to solve ACME challenges that use this challenge solver. This is the recommended way of configuring the ingress class. Only one of class, name or ingressClassName may be specified.

+
+ class +
+ string +
+ (Optional) +

This field configures the annotation kubernetes.io/ingress.class when creating Ingress resources to solve ACME challenges that use this challenge solver. Only one of class, name or ingressClassName may be specified.

+
+ name +
+ string +
+ (Optional) +

The name of the ingress resource that should have ACME challenge solving routes inserted into it in order to solve HTTP01 challenges. This is typically used in conjunction with ingress controllers like ingress-gce, which maintains a 1:1 mapping between external IPs and ingress resources. Only one of class, name or ingressClassName may be specified.

+
+ podTemplate +
+ + ACMEChallengeSolverHTTP01IngressPodTemplate + +
+ (Optional) +

Optional pod template used to configure the ACME challenge solver pods used for HTTP01 challenges.

+
+ ingressTemplate +
+ + ACMEChallengeSolverHTTP01IngressTemplate + +
+ (Optional) +

Optional ingress template used to configure the ACME challenge solver ingress used for HTTP01 challenges.

+
+

ACMEChallengeSolverHTTP01IngressObjectMeta

+

(Appears on: ACMEChallengeSolverHTTP01IngressTemplate)

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ annotations +
+ map[string]string +
+ (Optional) +

Annotations that should be added to the created ACME HTTP01 solver ingress.

+
+ labels +
+ map[string]string +
+ (Optional) +

Labels that should be added to the created ACME HTTP01 solver ingress.

+
+

ACMEChallengeSolverHTTP01IngressPodObjectMeta

+

(Appears on: ACMEChallengeSolverHTTP01IngressPodTemplate)

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ annotations +
+ map[string]string +
+ (Optional) +

Annotations that should be added to the create ACME HTTP01 solver pods.

+
+ labels +
+ map[string]string +
+ (Optional) +

Labels that should be added to the created ACME HTTP01 solver pods.

+
+

ACMEChallengeSolverHTTP01IngressPodSpec

+

(Appears on: ACMEChallengeSolverHTTP01IngressPodTemplate)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ nodeSelector +
+ map[string]string +
+ (Optional) +

NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

+
+ affinity +
+ + Kubernetes core/v1.Affinity + +
+ (Optional) +

If specified, the pod’s scheduling constraints

+
+ tolerations +
+ + []Kubernetes core/v1.Toleration + +
+ (Optional) +

If specified, the pod’s tolerations.

+
+ priorityClassName +
+ string +
+ (Optional) +

If specified, the pod’s priorityClassName.

+
+ serviceAccountName +
+ string +
+ (Optional) +

If specified, the pod’s service account

+
+ imagePullSecrets +
+ + []Kubernetes core/v1.LocalObjectReference + +
+ (Optional) +

If specified, the pod’s imagePullSecrets

+
+

ACMEChallengeSolverHTTP01IngressPodTemplate

+

(Appears on: ACMEChallengeSolverHTTP01Ingress)

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ metadata +
+ + ACMEChallengeSolverHTTP01IngressPodObjectMeta + +
+ (Optional) +

ObjectMeta overrides for the pod used to solve HTTP01 challenges. Only the ‘labels’ and ‘annotations’ fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values.

+
+ spec +
+ + ACMEChallengeSolverHTTP01IngressPodSpec + +
+ (Optional) +

PodSpec defines overrides for the HTTP01 challenge solver pod. Check ACMEChallengeSolverHTTP01IngressPodSpec to find out currently supported fields. All other fields will be ignored.

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ nodeSelector +
+ map[string]string +
+ (Optional) +

NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/

+
+ affinity +
+ + Kubernetes core/v1.Affinity + +
+ (Optional) +

If specified, the pod’s scheduling constraints

+
+ tolerations +
+ + []Kubernetes core/v1.Toleration + +
+ (Optional) +

If specified, the pod’s tolerations.

+
+ priorityClassName +
+ string +
+ (Optional) +

If specified, the pod’s priorityClassName.

+
+ serviceAccountName +
+ string +
+ (Optional) +

If specified, the pod’s service account

+
+ imagePullSecrets +
+ + []Kubernetes core/v1.LocalObjectReference + +
+ (Optional) +

If specified, the pod’s imagePullSecrets

+
+
+

ACMEChallengeSolverHTTP01IngressTemplate

+

(Appears on: ACMEChallengeSolverHTTP01Ingress)

+
+ + + + + + + + + + + + + +
FieldDescription
+ metadata +
+ + ACMEChallengeSolverHTTP01IngressObjectMeta + +
+ (Optional) +

ObjectMeta overrides for the ingress used to solve HTTP01 challenges. Only the ‘labels’ and ‘annotations’ fields may be set. If labels or annotations overlap with in-built values, the values here will override the in-built values.

+
+

ACMEChallengeType (string alias)

+

(Appears on: ChallengeSpec)

+
+

The type of ACME challenge. Only HTTP-01 and DNS-01 are supported.

+
+ + + + + + + + + + + + + + + + + +
ValueDescription
+

"DNS-01"

+
+

ACMEChallengeTypeDNS01 denotes a Challenge is of type dns-01 More info: https://letsencrypt.org/docs/challenge-types/#dns-01-challenge

+
+

"HTTP-01"

+
+

ACMEChallengeTypeHTTP01 denotes a Challenge is of type http-01 More info: https://letsencrypt.org/docs/challenge-types/#http-01-challenge

+
+

ACMEExternalAccountBinding

+

(Appears on: ACMEIssuer)

+
+

ACMEExternalAccountBinding is a reference to a CA external account of the ACME server.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ keyID +
+ string +
+

keyID is the ID of the CA key that the External Account is bound to.

+
+ keySecretRef +
+ + SecretKeySelector + +
+

keySecretRef is a Secret Key Selector referencing a data item in a Kubernetes Secret which holds the symmetric MAC key of the External Account Binding. The key is the index string that is paired with the key data in the Secret and should not be confused with the key data itself, or indeed with the External Account Binding keyID above. The secret key stored in the Secret must be un-padded, base64 URL encoded data.

+
+ keyAlgorithm +
+ + HMACKeyAlgorithm + +
+ (Optional) +

Deprecated: keyAlgorithm field exists for historical compatibility reasons and should not be used. The algorithm is now hardcoded to HS256 in golang/x/crypto/acme.

+
+

ACMEIssuer

+

(Appears on: IssuerConfig)

+
+

ACMEIssuer contains the specification for an ACME issuer. This uses the RFC8555 specification to obtain certificates by completing ‘challenges’ to prove ownership of domain identifiers. Earlier draft versions of the ACME specification are not supported.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ email +
+ string +
+ (Optional) +

Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.

+
+ server +
+ string +
+

Server is the URL used to access the ACME server’s ‘directory’ endpoint. For example, for Let’s Encrypt’s staging endpoint, you would use: “https://acme-staging-v02.api.letsencrypt.org/directory”. Only ACME v2 endpoints (i.e. RFC 8555) are supported.

+
+ preferredChain +
+ string +
+ (Optional) +

PreferredChain is the chain to use if the ACME server outputs multiple. PreferredChain is no guarantee that this one gets delivered by the ACME endpoint. For example, for Let’s Encrypt’s DST crosssign you would use: “DST Root CA X3” or “ISRG Root X1” for the newer Let’s Encrypt root CA. This value picks the first certificate bundle in the combined set of ACME default and alternative chains that has a root-most certificate with this value as its issuer’s commonname.

+
+ caBundle +
+ []byte +
+ (Optional) +

Base64-encoded bundle of PEM CAs which can be used to validate the certificate chain presented by the ACME server. Mutually exclusive with SkipTLSVerify; prefer using CABundle to prevent various kinds of security vulnerabilities. If CABundle and SkipTLSVerify are unset, the system certificate bundle inside the container is used to validate the TLS connection.

+
+ skipTLSVerify +
+ bool +
+ (Optional) +

INSECURE: Enables or disables validation of the ACME server TLS certificate. If true, requests to the ACME server will not have the TLS certificate chain validated. Mutually exclusive with CABundle; prefer using CABundle to prevent various kinds of security vulnerabilities. Only enable this option in development environments. If CABundle and SkipTLSVerify are unset, the system certificate bundle inside the container is used to validate the TLS connection. Defaults to false.

+
+ externalAccountBinding +
+ + ACMEExternalAccountBinding + +
+ (Optional) +

ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.

+
+ privateKeySecretRef +
+ + SecretKeySelector + +
+

PrivateKey is the name of a Kubernetes Secret resource that will be used to store the automatically generated ACME account private key. Optionally, a key may be specified to select a specific entry within the named Secret resource. If key is not specified, a default of tls.key will be used.

+
+ solvers +
+ + []ACMEChallengeSolver + +
+ (Optional) +

Solvers is a list of challenge solvers that will be used to solve ACME challenges for the matching domains. Solver configurations must be provided in order to obtain certificates from an ACME server. For more information, see: https://cert-manager.io/docs/configuration/acme/

+
+ disableAccountKeyGeneration +
+ bool +
+ (Optional) +

Enables or disables generating a new ACME account key. If true, the Issuer resource will not request a new account but will expect the account key to be supplied via an existing secret. If false, the cert-manager system will generate a new ACME account key for the Issuer. Defaults to false.

+
+ enableDurationFeature +
+ bool +
+ (Optional) +

Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let’s Encrypt. If set to true when the ACME server does not support it, it will create an error on the Order. Defaults to false.

+
+

ACMEIssuerDNS01ProviderAcmeDNS

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderAcmeDNS is a structure containing the configuration for ACME-DNS servers

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ host +
+ string +
+ accountSecretRef +
+ + SecretKeySelector + +
+

ACMEIssuerDNS01ProviderAkamai

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderAkamai is a structure containing the DNS configuration for Akamai DNS—Zone Record Management API

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ serviceConsumerDomain +
+ string +
+ clientTokenSecretRef +
+ + SecretKeySelector + +
+ clientSecretSecretRef +
+ + SecretKeySelector + +
+ accessTokenSecretRef +
+ + SecretKeySelector + +
+

ACMEIssuerDNS01ProviderAzureDNS

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderAzureDNS is a structure containing the configuration for Azure DNS

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ clientID +
+ string +
+ (Optional) +

Auth: Azure Service Principal: The ClientID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientSecret and TenantID must also be set.

+
+ clientSecretSecretRef +
+ + SecretKeySelector + +
+ (Optional) +

Auth: Azure Service Principal: A reference to a Secret containing the password associated with the Service Principal. If set, ClientID and TenantID must also be set.

+
+ subscriptionID +
+ string +
+

ID of the Azure subscription

+
+ tenantID +
+ string +
+ (Optional) +

Auth: Azure Service Principal: The TenantID of the Azure Service Principal used to authenticate with Azure DNS. If set, ClientID and ClientSecret must also be set.

+
+ resourceGroupName +
+ string +
+

resource group the DNS zone is located in

+
+ hostedZoneName +
+ string +
+ (Optional) +

name of the DNS zone that should be used

+
+ environment +
+ + AzureDNSEnvironment + +
+ (Optional) +

name of the Azure environment (default AzurePublicCloud)

+
+ managedIdentity +
+ + AzureManagedIdentity + +
+ (Optional) +

Auth: Azure Workload Identity or Azure Managed Service Identity: Settings to enable Azure Workload Identity or Azure Managed Service Identity If set, ClientID, ClientSecret and TenantID must not be set.

+
+

ACMEIssuerDNS01ProviderCloudDNS

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderCloudDNS is a structure containing the DNS configuration for Google Cloud DNS

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ serviceAccountSecretRef +
+ + SecretKeySelector + +
+ (Optional) +
+ project +
+ string +
+ hostedZoneName +
+ string +
+ (Optional) +

HostedZoneName is an optional field that tells cert-manager in which Cloud DNS zone the challenge record has to be created. If left empty cert-manager will automatically choose a zone.

+
+

ACMEIssuerDNS01ProviderCloudflare

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderCloudflare is a structure containing the DNS configuration for Cloudflare. One of apiKeySecretRef or apiTokenSecretRef must be provided.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ email +
+ string +
+ (Optional) +

Email of the account, only required when using API key based authentication.

+
+ apiKeySecretRef +
+ + SecretKeySelector + +
+ (Optional) +

API key to use to authenticate with Cloudflare. Note: using an API token to authenticate is now the recommended method as it allows greater control of permissions.

+
+ apiTokenSecretRef +
+ + SecretKeySelector + +
+ (Optional) +

API token used to authenticate with Cloudflare.

+
+

ACMEIssuerDNS01ProviderDigitalOcean

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderDigitalOcean is a structure containing the DNS configuration for DigitalOcean Domains

+
+ + + + + + + + + + + + + +
FieldDescription
+ tokenSecretRef +
+ + SecretKeySelector + +
+

ACMEIssuerDNS01ProviderRFC2136

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderRFC2136 is a structure containing the configuration for RFC2136 DNS

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ nameserver +
+ string +
+

The IP address or hostname of an authoritative DNS server supporting RFC2136 in the form host:port. If the host is an IPv6 address it must be enclosed in square brackets (e.g [2001:db8::1]) ; port is optional. This field is required.

+
+ tsigSecretSecretRef +
+ + SecretKeySelector + +
+ (Optional) +

The name of the secret containing the TSIG value. If tsigKeyName is defined, this field is required.

+
+ tsigKeyName +
+ string +
+ (Optional) +

The TSIG Key name configured in the DNS. If tsigSecretSecretRef is defined, this field is required.

+
+ tsigAlgorithm +
+ string +
+ (Optional) +

The TSIG Algorithm configured in the DNS supporting RFC2136. Used only when tsigSecretSecretRef and tsigKeyName are defined. Supported values are (case-insensitive): HMACMD5 (default), HMACSHA1, HMACSHA256 or HMACSHA512.

+
+

ACMEIssuerDNS01ProviderRoute53

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderRoute53 is a structure containing the Route 53 configuration for AWS

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ auth +
+ + Route53Auth + +
+ (Optional) +

Auth configures how cert-manager authenticates.

+
+ accessKeyID +
+ string +
+ (Optional) +

The AccessKeyID is used for authentication. Cannot be set when SecretAccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials

+
+ accessKeyIDSecretRef +
+ + SecretKeySelector + +
+ (Optional) +

The SecretAccessKey is used for authentication. If set, pull the AWS access key ID from a key within a Kubernetes Secret. Cannot be set when AccessKeyID is set. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials

+
+ secretAccessKeySecretRef +
+ + SecretKeySelector + +
+ (Optional) +

The SecretAccessKey is used for authentication. If neither the Access Key nor Key ID are set, we fall-back to using env vars, shared credentials file or AWS Instance metadata, see: https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials

+
+ role +
+ string +
+ (Optional) +

Role is a Role ARN which the Route53 provider will assume using either the explicit credentials AccessKeyID/SecretAccessKey or the inferred credentials from environment variables, shared credentials file or AWS Instance metadata

+
+ hostedZoneID +
+ string +
+ (Optional) +

If set, the provider will manage only this zone in Route53 and will not do an lookup using the route53:ListHostedZonesByName api call.

+
+ region +
+ string +
+

Always set the region when using AccessKeyID and SecretAccessKey

+
+

ACMEIssuerDNS01ProviderWebhook

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

ACMEIssuerDNS01ProviderWebhook specifies configuration for a webhook DNS01 provider, including where to POST ChallengePayload resources.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ groupName +
+ string +
+

The API group name that should be used when POSTing ChallengePayload resources to the webhook apiserver. This should be the same as the GroupName specified in the webhook provider implementation.

+
+ solverName +
+ string +
+

The name of the solver to use, as defined in the webhook provider implementation. This will typically be the name of the provider, e.g. ‘cloudflare’.

+
+ config +
+ + Kubernetes apiextensions/v1.JSON + +
+ (Optional) +

Additional configuration that should be passed to the webhook apiserver when challenges are processed. This can contain arbitrary JSON data. Secret values should not be specified in this stanza. If secret values are needed (e.g. credentials for a DNS service), you should use a SecretKeySelector to reference a Secret resource. For details on the schema of this field, consult the webhook provider implementation’s documentation.

+
+

ACMEIssuerStatus

+

(Appears on: IssuerStatus)

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ uri +
+ string +
+ (Optional) +

URI is the unique account identifier, which can also be used to retrieve account details from the CA

+
+ lastRegisteredEmail +
+ string +
+ (Optional) +

LastRegisteredEmail is the email associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer

+
+ lastPrivateKeyHash +
+ string +
+ (Optional) +

LastPrivateKeyHash is a hash of the private key associated with the latest registered ACME account, in order to track changes made to registered account associated with the Issuer

+
+

AzureDNSEnvironment (string alias)

+

(Appears on: ACMEIssuerDNS01ProviderAzureDNS)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription
+

"AzureChinaCloud"

+
+

"AzureGermanCloud"

+
+

"AzurePublicCloud"

+
+

"AzureUSGovernmentCloud"

+
+

AzureManagedIdentity

+

(Appears on: ACMEIssuerDNS01ProviderAzureDNS)

+
+

AzureManagedIdentity contains the configuration for Azure Workload Identity or Azure Managed Service Identity If the AZURE_FEDERATED_TOKEN_FILE environment variable is set, the Azure Workload Identity will be used. Otherwise, we fall-back to using Azure Managed Service Identity.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ clientID +
+ string +
+ (Optional) +

client ID of the managed identity, can not be used at the same time as resourceID

+
+ resourceID +
+ string +
+ (Optional) +

resource ID of the managed identity, can not be used at the same time as clientID Cannot be used for Azure Managed Service Identity

+
+

CNAMEStrategy (string alias)

+

(Appears on: ACMEChallengeSolverDNS01)

+
+

CNAMEStrategy configures how the DNS01 provider should handle CNAME records when found in DNS zones. By default, the None strategy will be applied (i.e. do not follow CNAMEs).

+
+

CertificateDNSNameSelector

+

(Appears on: ACMEChallengeSolver)

+
+

CertificateDNSNameSelector selects certificates using a label selector, and can optionally select individual DNS names within those certificates. If both MatchLabels and DNSNames are empty, this selector will match all certificates and DNS names within them.

+
+ + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ matchLabels +
+ map[string]string +
+ (Optional) +

A label selector that is used to refine the set of certificate’s that this challenge solver will apply to.

+
+ dnsNames +
+ []string +
+ (Optional) +

List of DNSNames that this solver will be used to solve. If specified and a match is found, a dnsNames selector will take precedence over a dnsZones selector. If multiple solvers match with the same dnsNames value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected.

+
+ dnsZones +
+ []string +
+ (Optional) +

List of DNSZones that this solver will be used to solve. The most specific DNS zone match specified here will take precedence over other DNS zone matches, so a solver specifying sys.example.com will be selected over one specifying example.com for the domain www.sys.example.com. If multiple solvers match with the same dnsZones value, the solver with the most matching labels in matchLabels will be selected. If neither has more matches, the solver defined earlier in the list will be selected.

+
+

ChallengeSpec

+

(Appears on: Challenge)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ url +
+ string +
+

The URL of the ACME Challenge resource for this challenge. This can be used to lookup details about the status of this challenge.

+
+ authorizationURL +
+ string +
+

The URL to the ACME Authorization resource that this challenge is a part of.

+
+ dnsName +
+ string +
+

dnsName is the identifier that this challenge is for, e.g. example.com. If the requested DNSName is a ‘wildcard’, this field MUST be set to the non-wildcard domain, e.g. for *.example.com, it must be example.com.

+
+ wildcard +
+ bool +
+ (Optional) +

wildcard will be true if this challenge is for a wildcard identifier, for example ‘*.example.com’.

+
+ type +
+ + ACMEChallengeType + +
+

The type of ACME challenge this resource represents. One of “HTTP-01” or “DNS-01”.

+
+ token +
+ string +
+

The ACME challenge token for this challenge. This is the raw value returned from the ACME server.

+
+ key +
+ string +
+

+ The ACME challenge key for this challenge For HTTP01 challenges, this is the value that must be responded with to complete the HTTP01 challenge in the format: + <private key JWK thumbprint>.<key from acme server for challenge>. For DNS01 challenges, this is the base64 encoded SHA256 sum of the + <private key JWK thumbprint>.<key from acme server for challenge> + text that must be set as the TXT record content. +

+
+ solver +
+ + ACMEChallengeSolver + +
+

Contains the domain solving configuration that should be used to solve this challenge resource.

+
+ issuerRef +
+ + ObjectReference + +
+

References a properly configured ACME-type Issuer which should be used to create this Challenge. If the Issuer does not exist, processing will be retried. If the Issuer is not an ‘ACME’ Issuer, an error will be returned and the Challenge will be marked as failed.

+
+

ChallengeStatus

+

(Appears on: Challenge)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ processing +
+ bool +
+ (Optional) +

Used to denote whether this challenge should be processed or not. This field will only be set to true by the ‘scheduling’ component. It will only be set to false by the ‘challenges’ controller, after the challenge has reached a final state or timed out. If this field is set to false, the challenge controller will not take any more action.

+
+ presented +
+ bool +
+ (Optional) +

presented will be set to true if the challenge values for this challenge are currently ‘presented’. This does not imply the self check is passing. Only that the values have been ‘submitted’ for the appropriate challenge mechanism (i.e. the DNS01 TXT record has been presented, or the HTTP01 configuration has been configured).

+
+ reason +
+ string +
+ (Optional) +

Contains human readable information on why the Challenge is in the current state.

+
+ state +
+ + State + +
+ (Optional) +

Contains the current ‘state’ of the challenge. If not set, the state of the challenge is unknown.

+
+

HMACKeyAlgorithm (string alias)

+

(Appears on: ACMEExternalAccountBinding)

+
+

HMACKeyAlgorithm is the name of a key algorithm used for HMAC encryption

+
+ + + + + + + + + + + + + + + + + + + + + +
ValueDescription
+

"HS256"

+
+

"HS384"

+
+

"HS512"

+
+

OrderSpec

+

(Appears on: Order)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ request +
+ []byte +
+

Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order.

+
+ issuerRef +
+ + ObjectReference + +
+

IssuerRef references a properly configured ACME-type Issuer which should be used to create this Order. If the Issuer does not exist, processing will be retried. If the Issuer is not an ‘ACME’ Issuer, an error will be returned and the Order will be marked as failed.

+
+ commonName +
+ string +
+ (Optional) +

CommonName is the common name as specified on the DER encoded CSR. If specified, this value must also be present in dnsNames or ipAddresses. This field must match the corresponding field on the DER encoded CSR.

+
+ dnsNames +
+ []string +
+ (Optional) +

DNSNames is a list of DNS names that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR.

+
+ ipAddresses +
+ []string +
+ (Optional) +

IPAddresses is a list of IP addresses that should be included as part of the Order validation process. This field must match the corresponding field on the DER encoded CSR.

+
+ duration +
+ + Kubernetes meta/v1.Duration + +
+ (Optional) +

Duration is the duration for the not after date for the requested certificate. this is set on order creation as pe the ACME spec.

+
+

OrderStatus

+

(Appears on: Order)

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldDescription
+ url +
+ string +
+ (Optional) +

URL of the Order. This will initially be empty when the resource is first created. The Order controller will populate this field when the Order is first processed. This field will be immutable after it is initially set.

+
+ finalizeURL +
+ string +
+ (Optional) +

FinalizeURL of the Order. This is used to obtain certificates for this order once it has been completed.

+
+ authorizations +
+ + []ACMEAuthorization + +
+ (Optional) +

Authorizations contains data returned from the ACME server on what authorizations must be completed in order to validate the DNS names specified on the Order.

+
+ certificate +
+ []byte +
+ (Optional) +

Certificate is a copy of the PEM encoded certificate for this Order. This field will be populated after the order has been successfully finalized with the ACME server, and the order has transitioned to the ‘valid’ state.

+
+ state +
+ + State + +
+ (Optional) +

State contains the current state of this Order resource. States ‘success’ and ‘expired’ are ‘final’

+
+ reason +
+ string +
+ (Optional) +

Reason optionally provides more information about a why the order is in the current state.

+
+ failureTime +
+ + Kubernetes meta/v1.Time + +
+ (Optional) +

FailureTime stores the time that this order failed. This is used to influence garbage collection and back-off.

+
+

Route53Auth

+

(Appears on: ACMEIssuerDNS01ProviderRoute53)

+
+

Route53Auth is configuration used to authenticate with a Route53.

+
+ + + + + + + + + + + + + +
FieldDescription
+ kubernetes +
+ + Route53KubernetesAuth + +
+

Kubernetes authenticates with Route53 using AssumeRoleWithWebIdentity by passing a bound ServiceAccount token.

+
+

Route53KubernetesAuth

+

(Appears on: Route53Auth)

+
+

Route53KubernetesAuth is a configuration to authenticate against Route53 using a bound Kubernetes ServiceAccount token.

+
+ + + + + + + + + + + + + +
FieldDescription
+ serviceAccountRef +
+ + ServiceAccountRef + +
+

A reference to a service account that will be used to request a bound token (also known as “projected token”). To use this field, you must configure an RBAC rule to let cert-manager request a token.

+
+

ServiceAccountRef

+

(Appears on: Route53KubernetesAuth)

+
+

ServiceAccountRef is a service account used by cert-manager to request a token. The expiration of the token is also set by cert-manager to 10 minutes.

+
+ + + + + + + + + + + + + + + + + +
FieldDescription
+ name +
+ string +
+

Name of the ServiceAccount used to request a token.

+
+ audiences +
+ []string +
+ (Optional) +

TokenAudiences is an optional list of audiences to include in the token passed to AWS. The default token consisting of the issuer’s namespace and name is always included. If unset the audience defaults to sts.amazonaws.com.

+
+

State (string alias)

+

(Appears on: ACMEAuthorization, ChallengeStatus, OrderStatus)

+
+

+ State represents the state of an ACME resource, such as an Order. The possible options here map to the corresponding values in the ACME specification. Full details of these values can be found here: https://tools.ietf.org/html/draft-ietf-acme-acme-15#section-7.1.6 + Clients utilising this type must also gracefully handle unknown values, as the contents of this enumeration may be added to over time. +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDescription
+

"errored"

+
+

Errored signifies that the ACME resource has errored for some reason. This is a catch-all state, and is used for marking internal cert-manager errors such as validation failures. This is a final state.

+
+

"expired"

+
+

Expired signifies that an ACME resource has expired. If an Order is marked ‘Expired’, one of its validations may have expired or the Order itself. This is a final state.

+
+

"invalid"

+
+

Invalid signifies that an ACME resource is invalid for some reason. If an Order is marked ‘invalid’, one of its validations be have invalid for some reason. This is a final state.

+
+

"pending"

+
+

Pending signifies that an ACME resource is still pending and is not yet ready. If an Order is marked ‘Pending’, the validations for that Order are still in progress. This is a transient state.

+
+

"processing"

+
+

Processing signifies that an ACME resource is being processed by the server. If an Order is marked ‘Processing’, the validations for that Order are currently being processed. This is a transient state.

+
+

"ready"

+
+

Ready signifies that an ACME resource is in a ready state. If an order is ‘ready’, all of its challenges have been completed successfully and the order is ready to be finalized. Once finalized, it will transition to the Valid state. This is a transient state.

+
+

""

+
+

Unknown is not a real state as part of the ACME spec. It is used to represent an unrecognised value.

+
+

"valid"

+
+

Valid signifies that an ACME resource is in a valid state. If an order is ‘valid’, it has been finalized with the ACME server and the certificate can be retrieved from the ACME server using the certificate URL stored in the Order’s status subresource. This is a final state.

+
+
+

cainjector.config.cert-manager.io/v1alpha1

+
+

Package v1alpha1 is the v1alpha1 version of the cainjector config API.

+
+

Resource Types:

+
    +

    CAInjectorConfiguration

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + kubeConfig +
    + string +
    +

    kubeConfig is the kubeconfig file used to connect to the Kubernetes apiserver. If not specified, the cainjector will attempt to load the in-cluster-config.

    +
    + namespace +
    + string +
    +

    If set, this limits the scope of cainjector to a single namespace. If set, cainjector will not update resources with certificates outside of the configured namespace.

    +
    + leaderElectionConfig +
    + github.com/cert-manager/cert-manager/pkg/apis/config/shared/v1alpha1.LeaderElectionConfig +
    +

    LeaderElectionConfig configures the behaviour of the leader election

    +
    + enableDataSourceConfig +
    + + EnableDataSourceConfig + +
    +

    EnableDataSourceConfig determines whether cainjector’s control loops will watch cert-manager resources as potential sources of CA data.

    +
    + enableInjectableConfig +
    + + EnableInjectableConfig + +
    +

    EnableInjectableConfig determines whether cainjector’s control loops will watch cert-manager resources as potential targets for CA data injection.

    +
    + enablePprof +
    + bool +
    +

    Enable profiling for cainjector.

    +
    + pprofAddress +
    + string +
    +

    The host and port that Go profiler should listen on, i.e localhost:6060. Ensure that profiler is not exposed on a public address. Profiler will be served at /debug/pprof.

    +
    + logging +
    + k8s.io/component-base/logs/api/v1.LoggingConfiguration +
    +

    + logging configures the logging behaviour of the cainjector. + https://pkg.go.dev/k8s.io/component-base@v0.27.3/logs/api/v1#LoggingConfiguration +

    +
    + featureGates +
    + map[string]bool +
    + (Optional) +

    featureGates is a map of feature names to bools that enable or disable experimental features.

    +
    +

    EnableDataSourceConfig

    +

    (Appears on: CAInjectorConfiguration)

    +
    + + + + + + + + + + + + + +
    FieldDescription
    + certificates +
    + bool +
    +

    Certificates detemines whether cainjector’s control loops will watch cert-manager Certificate resources as potential sources of CA data. If not set, defaults to true.

    +
    +

    EnableInjectableConfig

    +

    (Appears on: CAInjectorConfiguration)

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + validatingWebhookConfigurations +
    + bool +
    +

    ValidatingWebhookConfigurations determines whether cainjector will spin up a control loop to inject CA data to annotated ValidatingWebhookConfigurations If not set, defaults to true.

    +
    + mutatingWebhookConfigurations +
    + bool +
    +

    MutatingWebhookConfigurations determines whether cainjector will spin up a control loop to inject CA data to annotated MutatingWebhookConfigurations If not set, defaults to true.

    +
    + customResourceDefinitions +
    + bool +
    +

    CustomResourceDefinitions determines whether cainjector will spin up a control loop to inject CA data to annotated CustomResourceDefinitions If not set, defaults to true.

    +
    + apiServices +
    + bool +
    +

    APIServices determines whether cainjector will spin up a control loop to inject CA data to annotated APIServices If not set, defaults to true.

    +
    +
    +

    cert-manager.io/v1

    +
    +

    Package v1 is the v1 version of the API.

    +
    +

    Resource Types:

    + +

    Certificate

    +
    +

    A Certificate resource should be created to ensure an up to date and signed X.509 certificate is stored in the Kubernetes Secret resource named in spec.secretName.

    +

    The stored certificate will be renewed before it expires (as configured by spec.renewBefore).

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + apiVersion +
    + string +
    + cert-manager.io/v1 +
    + kind +
    + string +
    + Certificate +
    + metadata +
    + + Kubernetes meta/v1.ObjectMeta + +
    + (Optional) +

    Standard object’s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

    + Refer to the Kubernetes API documentation for the fields of the + metadata field. +
    + spec +
    + + CertificateSpec + +
    + (Optional) +

    + Specification of the desired state of the Certificate resource. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + subject +
    + + X509Subject + +
    + (Optional) +

    Requested set of X509 certificate subject attributes. More info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6

    +

    The common name attribute is specified separately in the commonName field. Cannot be set if the literalSubject field is set.

    +
    + literalSubject +
    + string +
    + (Optional) +

    Requested X.509 certificate subject, represented using the LDAP “String Representation of a Distinguished Name” [1]. Important: the LDAP string format also specifies the order of the attributes in the subject, this is important when issuing certs for LDAP authentication. Example: CN=foo,DC=corp,DC=example,DC=com More info [1]: https://datatracker.ietf.org/doc/html/rfc4514 More info: https://github.com/cert-manager/cert-manager/issues/3203 More info: https://github.com/cert-manager/cert-manager/issues/4424

    +

    Cannot be set if the subject or commonName field is set.

    +
    + commonName +
    + string +
    + (Optional) +

    Requested common name X509 certificate subject attribute. More info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6 NOTE: TLS clients will ignore this value when any subject alternative name is set (see https://tools.ietf.org/html/rfc6125#section-6.4.4).

    +

    Should have a length of 64 characters or fewer to avoid generating invalid CSRs. Cannot be set if the literalSubject field is set.

    +
    + duration +
    + + Kubernetes meta/v1.Duration + +
    + (Optional) +

    Requested ‘duration’ (i.e. lifetime) of the Certificate. Note that the issuer may choose to ignore the requested duration, just like any other requested attribute.

    +

    If unset, this defaults to 90 days. Minimum accepted duration is 1 hour. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration.

    +
    + renewBefore +
    + + Kubernetes meta/v1.Duration + +
    + (Optional) +

    How long before the currently issued certificate’s expiry cert-manager should renew the certificate. For example, if a certificate is valid for 60 minutes, and renewBefore=10m, cert-manager will begin to attempt to renew the certificate 50 minutes after it was issued (i.e. when there are 10 minutes remaining until the certificate is no longer valid).

    +

    NOTE: The actual lifetime of the issued certificate is used to determine the renewal time. If an issuer returns a certificate with a different lifetime than the one requested, cert-manager will use the lifetime of the issued certificate.

    +

    If unset, this defaults to 13 of the issued certificate’s lifetime. Minimum accepted value is 5 minutes. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration.

    +
    + dnsNames +
    + []string +
    + (Optional) +

    Requested DNS subject alternative names.

    +
    + ipAddresses +
    + []string +
    + (Optional) +

    Requested IP address subject alternative names.

    +
    + uris +
    + []string +
    + (Optional) +

    Requested URI subject alternative names.

    +
    + otherNames +
    + + []OtherName + +
    + (Optional) +

    otherNames is an escape hatch for SAN that allows any type. We currently restrict the support to string like otherNames, cf RFC 5280 p 37 Any UTF8 String valued otherName can be passed with by setting the keys oid: x.x.x.x and UTF8Value: somevalue for otherName. Most commonly this would be UPN set with oid: 1.3.6.1.4.1.311.20.2.3 You should ensure that any OID passed is valid for the UTF8String type as we do not explicitly validate this.

    +
    + emailAddresses +
    + []string +
    + (Optional) +

    Requested email subject alternative names.

    +
    + secretName +
    + string +
    +

    Name of the Secret resource that will be automatically created and managed by this Certificate resource. It will be populated with a private key and certificate, signed by the denoted issuer. The Secret resource lives in the same namespace as the Certificate resource.

    +
    + secretTemplate +
    + + CertificateSecretTemplate + +
    + (Optional) +

    Defines annotations and labels to be copied to the Certificate’s Secret. Labels and annotations on the Secret will be changed as they appear on the SecretTemplate when added or removed. SecretTemplate annotations are added in conjunction with, and cannot overwrite, the base set of annotations cert-manager sets on the Certificate’s Secret.

    +
    + keystores +
    + + CertificateKeystores + +
    + (Optional) +

    Additional keystore output formats to be stored in the Certificate’s Secret.

    +
    + issuerRef +
    + + ObjectReference + +
    +

    Reference to the issuer responsible for issuing the certificate. If the issuer is namespace-scoped, it must be in the same namespace as the Certificate. If the issuer is cluster-scoped, it can be used from any namespace.

    +

    The name field of the reference must always be specified.

    +
    + isCA +
    + bool +
    + (Optional) +

    Requested basic constraints isCA value. The isCA value is used to set the isCA field on the created CertificateRequest resources. Note that the issuer may choose to ignore the requested isCA value, just like any other requested attribute.

    +

    If true, this will automatically add the cert sign usage to the list of requested usages.

    +
    + usages +
    + + []KeyUsage + +
    + (Optional) +

    Requested key usages and extended key usages. These usages are used to set the usages field on the created CertificateRequest resources. If encodeUsagesInRequest is unset or set to true, the usages will additionally be encoded in the request field which contains the CSR blob.

    +

    If unset, defaults to digital signature and key encipherment.

    +
    + privateKey +
    + + CertificatePrivateKey + +
    + (Optional) +

    Private key options. These include the key algorithm and size, the used encoding and the rotation policy.

    +
    + encodeUsagesInRequest +
    + bool +
    + (Optional) +

    Whether the KeyUsage and ExtKeyUsage extensions should be set in the encoded CSR.

    +

    This option defaults to true, and should only be disabled if the target issuer does not support CSRs with these X509 KeyUsage/ ExtKeyUsage extensions.

    +
    + revisionHistoryLimit +
    + int32 +
    + (Optional) +

    + The maximum number of CertificateRequest revisions that are maintained in the Certificate’s history. Each revision represents a single CertificateRequest + created by this Certificate, either when it was created, renewed, or Spec was changed. Revisions will be removed by oldest first if the number of revisions exceeds this number. +

    +

    If set, revisionHistoryLimit must be a value of 1 or greater. If unset (nil), revisions will not be garbage collected. Default value is nil.

    +
    + additionalOutputFormats +
    + + []CertificateAdditionalOutputFormat + +
    + (Optional) +

    Defines extra output formats of the private key and signed certificate chain to be written to this Certificate’s target Secret.

    +

    + This is a Beta Feature enabled by default. It can be disabled with the + --feature-gates=AdditionalCertificateOutputFormats=false option set on both the controller and webhook components. +

    +
    + nameConstraints +
    + + NameConstraints + +
    + (Optional) +

    x.509 certificate NameConstraint extension which MUST NOT be used in a non-CA certificate. More Info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10

    +

    + This is an Alpha Feature and is only enabled with the + --feature-gates=NameConstraints=true option set on both the controller and webhook components. +

    +
    +
    + status +
    + + CertificateStatus + +
    + (Optional) +

    Status of the Certificate. This is set and managed automatically. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

    +
    +

    CertificateRequest

    +
    +

    A CertificateRequest is used to request a signed certificate from one of the configured issuers.

    +

    All fields within the CertificateRequest’s spec are immutable after creation. A CertificateRequest will either succeed or fail, as denoted by its Ready status condition and its status.failureTime field.

    +

    A CertificateRequest is a one-shot resource, meaning it represents a single point in time request for a certificate and cannot be re-used.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + apiVersion +
    + string +
    + cert-manager.io/v1 +
    + kind +
    + string +
    + CertificateRequest +
    + metadata +
    + + Kubernetes meta/v1.ObjectMeta + +
    + (Optional) +

    Standard object’s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

    + Refer to the Kubernetes API documentation for the fields of the + metadata field. +
    + spec +
    + + CertificateRequestSpec + +
    + (Optional) +

    + Specification of the desired state of the CertificateRequest resource. + https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + duration +
    + + Kubernetes meta/v1.Duration + +
    + (Optional) +

    Requested ‘duration’ (i.e. lifetime) of the Certificate. Note that the issuer may choose to ignore the requested duration, just like any other requested attribute.

    +
    + issuerRef +
    + + ObjectReference + +
    +

    Reference to the issuer responsible for issuing the certificate. If the issuer is namespace-scoped, it must be in the same namespace as the Certificate. If the issuer is cluster-scoped, it can be used from any namespace.

    +

    The name field of the reference must always be specified.

    +
    + request +
    + []byte +
    +

    The PEM-encoded X.509 certificate signing request to be submitted to the issuer for signing.

    +

    If the CSR has a BasicConstraints extension, its isCA attribute must match the isCA value of this CertificateRequest. If the CSR has a KeyUsage extension, its key usages must match the key usages in the usages field of this CertificateRequest. If the CSR has a ExtKeyUsage extension, its extended key usages must match the extended key usages in the usages field of this CertificateRequest.

    +
    + isCA +
    + bool +
    + (Optional) +

    Requested basic constraints isCA value. Note that the issuer may choose to ignore the requested isCA value, just like any other requested attribute.

    +

    NOTE: If the CSR in the Request field has a BasicConstraints extension, it must have the same isCA value as specified here.

    +

    If true, this will automatically add the cert sign usage to the list of requested usages.

    +
    + usages +
    + + []KeyUsage + +
    + (Optional) +

    Requested key usages and extended key usages.

    +

    NOTE: If the CSR in the Request field has uses the KeyUsage or ExtKeyUsage extension, these extensions must have the same values as specified here without any additional values.

    +

    If unset, defaults to digital signature and key encipherment.

    +
    + username +
    + string +
    + (Optional) +

    Username contains the name of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    + uid +
    + string +
    + (Optional) +

    UID contains the uid of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    + groups +
    + []string +
    + (Optional) +

    Groups contains group membership of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    + extra +
    + map[string][]string +
    + (Optional) +

    Extra contains extra attributes of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    +
    + status +
    + + CertificateRequestStatus + +
    + (Optional) +

    Status of the CertificateRequest. This is set and managed automatically. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

    +
    +

    ClusterIssuer

    +
    +

    A ClusterIssuer represents a certificate issuing authority which can be referenced as part of issuerRef fields. It is similar to an Issuer, however it is cluster-scoped and therefore can be referenced by resources that exist in any namespace, not just the same namespace as the referent.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + apiVersion +
    + string +
    + cert-manager.io/v1 +
    + kind +
    + string +
    + ClusterIssuer +
    + metadata +
    + + Kubernetes meta/v1.ObjectMeta + +
    + Refer to the Kubernetes API documentation for the fields of the + metadata field. +
    + spec +
    + + IssuerSpec + +
    +

    Desired state of the ClusterIssuer resource.

    +
    +
    + + + + + +
    + IssuerConfig +
    + + IssuerConfig + +
    +

    (Members of IssuerConfig are embedded into this type.)

    +
    +
    + status +
    + + IssuerStatus + +
    + (Optional) +

    Status of the ClusterIssuer. This is set and managed automatically.

    +
    +

    Issuer

    +
    +

    An Issuer represents a certificate issuing authority which can be referenced as part of issuerRef fields. It is scoped to a single namespace and can therefore only be referenced by resources within the same namespace.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + apiVersion +
    + string +
    + cert-manager.io/v1 +
    + kind +
    + string +
    + Issuer +
    + metadata +
    + + Kubernetes meta/v1.ObjectMeta + +
    + Refer to the Kubernetes API documentation for the fields of the + metadata field. +
    + spec +
    + + IssuerSpec + +
    +

    Desired state of the Issuer resource.

    +
    +
    + + + + + +
    + IssuerConfig +
    + + IssuerConfig + +
    +

    (Members of IssuerConfig are embedded into this type.)

    +
    +
    + status +
    + + IssuerStatus + +
    + (Optional) +

    Status of the Issuer. This is set and managed automatically.

    +
    +

    CAIssuer

    +

    (Appears on: IssuerConfig)

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + secretName +
    + string +
    +

    SecretName is the name of the secret used to sign Certificates issued by this Issuer.

    +
    + crlDistributionPoints +
    + []string +
    + (Optional) +

    The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set, certificates will be issued without distribution points set.

    +
    + ocspServers +
    + []string +
    + (Optional) +

    The OCSP server list is an X.509 v3 extension that defines a list of URLs of OCSP responders. The OCSP responders can be queried for the revocation status of an issued certificate. If not set, the certificate will be issued with no OCSP servers set. For example, an OCSP server URL could be “http://ocsp.int-x3.letsencrypt.org”.

    +
    + issuingCertificateURLs +
    + []string +
    + (Optional) +

    IssuingCertificateURLs is a list of URLs which this issuer should embed into certificates it creates. See https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1 for more details. As an example, such a URL might be “http://ca.domain.com/ca.crt”.

    +
    +

    CertificateAdditionalOutputFormat

    +

    (Appears on: CertificateSpec)

    +
    +

    CertificateAdditionalOutputFormat defines an additional output format of a Certificate resource. These contain supplementary data formats of the signed certificate chain and paired private key.

    +
    + + + + + + + + + + + + + +
    FieldDescription
    + type +
    + + CertificateOutputFormatType + +
    +

    Type is the name of the format type that should be written to the Certificate’s target Secret.

    +
    +

    CertificateCondition

    +

    (Appears on: CertificateStatus)

    +
    +

    CertificateCondition contains condition information for an Certificate.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + type +
    + + CertificateConditionType + +
    +

    Type of the condition, known values are (Ready, Issuing).

    +
    + status +
    + + ConditionStatus + +
    +

    Status of the condition, one of (True, False, Unknown).

    +
    + lastTransitionTime +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    LastTransitionTime is the timestamp corresponding to the last status change of this condition.

    +
    + reason +
    + string +
    + (Optional) +

    Reason is a brief machine readable explanation for the condition’s last transition.

    +
    + message +
    + string +
    + (Optional) +

    Message is a human readable description of the details of the last transition, complementing reason.

    +
    + observedGeneration +
    + int64 +
    + (Optional) +

    If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Certificate.

    +
    +

    CertificateConditionType (string alias)

    +

    (Appears on: CertificateCondition)

    +
    +

    CertificateConditionType represents an Certificate condition value.

    +
    + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "Issuing"

    +
    +

    + A condition added to Certificate resources when an issuance is required. This condition will be automatically added and set to true if: * No keypair data exists in the target Secret * The data stored in the Secret cannot be decoded * The private key and certificate do not have matching public keys * If a CertificateRequest for the current revision exists and the certificate data stored in the Secret does not match the + status.certificate on the CertificateRequest. * If no CertificateRequest resource exists for the current revision, the options on the Certificate resource are compared against the X.509 data in the Secret, similar to what’s done in earlier versions. If there is a mismatch, an issuance is triggered. This condition may also be added by external API consumers to trigger a re-issuance manually for any other reason. +

    +

    It will be removed by the ‘issuing’ controller upon completing issuance.

    +
    +

    "Ready"

    +
    +

    CertificateConditionReady indicates that a certificate is ready for use. This is defined as: - The target secret exists - The target secret contains a certificate that has not expired - The target secret contains a private key valid for the certificate - The commonName and dnsNames attributes match those specified on the Certificate

    +
    +

    CertificateKeystores

    +

    (Appears on: CertificateSpec)

    +
    +

    CertificateKeystores configures additional keystore output formats to be created in the Certificate’s output Secret.

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    + jks +
    + + JKSKeystore + +
    + (Optional) +

    + JKS configures options for storing a JKS keystore in the + spec.secretName Secret resource. +

    +
    + pkcs12 +
    + + PKCS12Keystore + +
    + (Optional) +

    + PKCS12 configures options for storing a PKCS12 keystore in the + spec.secretName Secret resource. +

    +
    +

    CertificateOutputFormatType (string alias)

    +

    (Appears on: CertificateAdditionalOutputFormat)

    +
    +

    + CertificateOutputFormatType specifies which additional output formats should be written to the Certificate’s target Secret. Allowed values are DER or CombinedPEM. When Type is set to DER an additional entry key.der will be written to the Secret, containing the binary format of the private key. When Type is set to CombinedPEM an additional entry tls-combined.pem + will be written to the Secret, containing the PEM formatted private key and signed certificate chain (tls.key + tls.crt concatenated). +

    +
    + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "CombinedPEM"

    +
    +

    + CertificateOutputFormatCombinedPEM writes the Certificate’s signed certificate chain and private key, in PEM format, to the + tls-combined.pem target Secret Data key. The value at this key will include the private key PEM document, followed by at least one new line character, followed by the chain of signed certificate PEM documents (<private key> + \n + <signed certificate chain>). +

    +
    +

    "DER"

    +
    +

    CertificateOutputFormatDER writes the Certificate’s private key in DER binary format to the key.der target Secret Data key.

    +
    +

    CertificatePrivateKey

    +

    (Appears on: CertificateSpec)

    +
    +

    CertificatePrivateKey contains configuration options for private keys used by the Certificate controller. These include the key algorithm and size, the used encoding and the rotation policy.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + rotationPolicy +
    + + PrivateKeyRotationPolicy + +
    + (Optional) +

    RotationPolicy controls how private keys should be regenerated when a re-issuance is being processed.

    +

    If set to Never, a private key will only be generated if one does not already exist in the target spec.secretName. If one does exists but it does not have the correct algorithm or size, a warning will be raised to await user intervention. If set to Always, a private key matching the specified requirements will be generated whenever a re-issuance occurs. Default is Never for backward compatibility.

    +
    + encoding +
    + + PrivateKeyEncoding + +
    + (Optional) +

    The private key cryptography standards (PKCS) encoding for this certificate’s private key to be encoded in.

    +

    If provided, allowed values are PKCS1 and PKCS8 standing for PKCS#1 and PKCS#8, respectively. Defaults to PKCS1 if not specified.

    +
    + algorithm +
    + + PrivateKeyAlgorithm + +
    + (Optional) +

    Algorithm is the private key algorithm of the corresponding private key for this certificate.

    +

    If provided, allowed values are either RSA, ECDSA or Ed25519. If algorithm is specified and size is not provided, key size of 2048 will be used for RSA key algorithm and key size of 256 will be used for ECDSA key algorithm. key size is ignored when using the Ed25519 key algorithm.

    +
    + size +
    + int +
    + (Optional) +

    Size is the key bit size of the corresponding private key for this certificate.

    +

    If algorithm is set to RSA, valid values are 2048, 4096 or 8192, and will default to 2048 if not specified. If algorithm is set to ECDSA, valid values are 256, 384 or 521, and will default to 256 if not specified. If algorithm is set to Ed25519, Size is ignored. No other values are allowed.

    +
    +

    CertificateRequestCondition

    +

    (Appears on: CertificateRequestStatus)

    +
    +

    CertificateRequestCondition contains condition information for a CertificateRequest.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + type +
    + + CertificateRequestConditionType + +
    +

    Type of the condition, known values are (Ready, InvalidRequest,Approved, Denied).

    +
    + status +
    + + ConditionStatus + +
    +

    Status of the condition, one of (True, False, Unknown).

    +
    + lastTransitionTime +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    LastTransitionTime is the timestamp corresponding to the last status change of this condition.

    +
    + reason +
    + string +
    + (Optional) +

    Reason is a brief machine readable explanation for the condition’s last transition.

    +
    + message +
    + string +
    + (Optional) +

    Message is a human readable description of the details of the last transition, complementing reason.

    +
    +

    CertificateRequestConditionType (string alias)

    +

    (Appears on: CertificateRequestCondition)

    +
    +

    CertificateRequestConditionType represents an Certificate condition value.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "Approved"

    +
    +

    + CertificateRequestConditionApproved indicates that a certificate request is approved and ready for signing. Condition must never have a status of + False, and cannot be modified once set. Cannot be set alongside Denied. +

    +
    +

    "Denied"

    +
    +

    + CertificateRequestConditionDenied indicates that a certificate request is denied, and must never be signed. Condition must never have a status of + False, and cannot be modified once set. Cannot be set alongside Approved. +

    +
    +

    "InvalidRequest"

    +
    +

    CertificateRequestConditionInvalidRequest indicates that a certificate signer has refused to sign the request due to at least one of the input parameters being invalid. Additional information about why the request was rejected can be found in the reason and message fields.

    +
    +

    "Ready"

    +
    +

    CertificateRequestConditionReady indicates that a certificate is ready for use. This is defined as: - The target certificate exists in CertificateRequest.Status

    +
    +

    CertificateRequestSpec

    +

    (Appears on: CertificateRequest)

    +
    +

    CertificateRequestSpec defines the desired state of CertificateRequest

    +

    NOTE: It is important to note that the issuer can choose to ignore or change any of the requested attributes. How the issuer maps a certificate request to a signed certificate is the full responsibility of the issuer itself. For example, as an edge case, an issuer that inverts the isCA value is free to do so.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + duration +
    + + Kubernetes meta/v1.Duration + +
    + (Optional) +

    Requested ‘duration’ (i.e. lifetime) of the Certificate. Note that the issuer may choose to ignore the requested duration, just like any other requested attribute.

    +
    + issuerRef +
    + + ObjectReference + +
    +

    Reference to the issuer responsible for issuing the certificate. If the issuer is namespace-scoped, it must be in the same namespace as the Certificate. If the issuer is cluster-scoped, it can be used from any namespace.

    +

    The name field of the reference must always be specified.

    +
    + request +
    + []byte +
    +

    The PEM-encoded X.509 certificate signing request to be submitted to the issuer for signing.

    +

    If the CSR has a BasicConstraints extension, its isCA attribute must match the isCA value of this CertificateRequest. If the CSR has a KeyUsage extension, its key usages must match the key usages in the usages field of this CertificateRequest. If the CSR has a ExtKeyUsage extension, its extended key usages must match the extended key usages in the usages field of this CertificateRequest.

    +
    + isCA +
    + bool +
    + (Optional) +

    Requested basic constraints isCA value. Note that the issuer may choose to ignore the requested isCA value, just like any other requested attribute.

    +

    NOTE: If the CSR in the Request field has a BasicConstraints extension, it must have the same isCA value as specified here.

    +

    If true, this will automatically add the cert sign usage to the list of requested usages.

    +
    + usages +
    + + []KeyUsage + +
    + (Optional) +

    Requested key usages and extended key usages.

    +

    NOTE: If the CSR in the Request field has uses the KeyUsage or ExtKeyUsage extension, these extensions must have the same values as specified here without any additional values.

    +

    If unset, defaults to digital signature and key encipherment.

    +
    + username +
    + string +
    + (Optional) +

    Username contains the name of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    + uid +
    + string +
    + (Optional) +

    UID contains the uid of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    + groups +
    + []string +
    + (Optional) +

    Groups contains group membership of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    + extra +
    + map[string][]string +
    + (Optional) +

    Extra contains extra attributes of the user that created the CertificateRequest. Populated by the cert-manager webhook on creation and immutable.

    +
    +

    CertificateRequestStatus

    +

    (Appears on: CertificateRequest)

    +
    +

    CertificateRequestStatus defines the observed state of CertificateRequest and resulting signed certificate.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + conditions +
    + + []CertificateRequestCondition + +
    + (Optional) +

    List of status conditions to indicate the status of a CertificateRequest. Known condition types are Ready, InvalidRequest, Approved and Denied.

    +
    + certificate +
    + []byte +
    + (Optional) +

    + The PEM encoded X.509 certificate resulting from the certificate signing request. If not set, the CertificateRequest has either not been completed or has failed. More information on failure can be found by checking the + conditions field. +

    +
    + ca +
    + []byte +
    + (Optional) +

    The PEM encoded X.509 certificate of the signer, also known as the CA (Certificate Authority). This is set on a best-effort basis by different issuers. If not set, the CA is assumed to be unknown/not available.

    +
    + failureTime +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    FailureTime stores the time that this CertificateRequest failed. This is used to influence garbage collection and back-off.

    +
    +

    CertificateSecretTemplate

    +

    (Appears on: CertificateSpec)

    +
    +

    CertificateSecretTemplate defines the default labels and annotations to be copied to the Kubernetes Secret resource named in CertificateSpec.secretName.

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    + annotations +
    + map[string]string +
    + (Optional) +

    Annotations is a key value map to be copied to the target Kubernetes Secret.

    +
    + labels +
    + map[string]string +
    + (Optional) +

    Labels is a key value map to be copied to the target Kubernetes Secret.

    +
    +

    CertificateSpec

    +

    (Appears on: Certificate)

    +
    +

    CertificateSpec defines the desired state of Certificate.

    +

    NOTE: The specification contains a lot of “requested” certificate attributes, it is important to note that the issuer can choose to ignore or change any of these requested attributes. How the issuer maps a certificate request to a signed certificate is the full responsibility of the issuer itself. For example, as an edge case, an issuer that inverts the isCA value is free to do so.

    +

    A valid Certificate requires at least one of a CommonName, LiteralSubject, DNSName, or URI to be valid.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + subject +
    + + X509Subject + +
    + (Optional) +

    Requested set of X509 certificate subject attributes. More info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6

    +

    The common name attribute is specified separately in the commonName field. Cannot be set if the literalSubject field is set.

    +
    + literalSubject +
    + string +
    + (Optional) +

    Requested X.509 certificate subject, represented using the LDAP “String Representation of a Distinguished Name” [1]. Important: the LDAP string format also specifies the order of the attributes in the subject, this is important when issuing certs for LDAP authentication. Example: CN=foo,DC=corp,DC=example,DC=com More info [1]: https://datatracker.ietf.org/doc/html/rfc4514 More info: https://github.com/cert-manager/cert-manager/issues/3203 More info: https://github.com/cert-manager/cert-manager/issues/4424

    +

    Cannot be set if the subject or commonName field is set.

    +
    + commonName +
    + string +
    + (Optional) +

    Requested common name X509 certificate subject attribute. More info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6 NOTE: TLS clients will ignore this value when any subject alternative name is set (see https://tools.ietf.org/html/rfc6125#section-6.4.4).

    +

    Should have a length of 64 characters or fewer to avoid generating invalid CSRs. Cannot be set if the literalSubject field is set.

    +
    + duration +
    + + Kubernetes meta/v1.Duration + +
    + (Optional) +

    Requested ‘duration’ (i.e. lifetime) of the Certificate. Note that the issuer may choose to ignore the requested duration, just like any other requested attribute.

    +

    If unset, this defaults to 90 days. Minimum accepted duration is 1 hour. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration.

    +
    + renewBefore +
    + + Kubernetes meta/v1.Duration + +
    + (Optional) +

    How long before the currently issued certificate’s expiry cert-manager should renew the certificate. For example, if a certificate is valid for 60 minutes, and renewBefore=10m, cert-manager will begin to attempt to renew the certificate 50 minutes after it was issued (i.e. when there are 10 minutes remaining until the certificate is no longer valid).

    +

    NOTE: The actual lifetime of the issued certificate is used to determine the renewal time. If an issuer returns a certificate with a different lifetime than the one requested, cert-manager will use the lifetime of the issued certificate.

    +

    If unset, this defaults to 13 of the issued certificate’s lifetime. Minimum accepted value is 5 minutes. Value must be in units accepted by Go time.ParseDuration https://golang.org/pkg/time/#ParseDuration.

    +
    + dnsNames +
    + []string +
    + (Optional) +

    Requested DNS subject alternative names.

    +
    + ipAddresses +
    + []string +
    + (Optional) +

    Requested IP address subject alternative names.

    +
    + uris +
    + []string +
    + (Optional) +

    Requested URI subject alternative names.

    +
    + otherNames +
    + + []OtherName + +
    + (Optional) +

    otherNames is an escape hatch for SAN that allows any type. We currently restrict the support to string like otherNames, cf RFC 5280 p 37 Any UTF8 String valued otherName can be passed with by setting the keys oid: x.x.x.x and UTF8Value: somevalue for otherName. Most commonly this would be UPN set with oid: 1.3.6.1.4.1.311.20.2.3 You should ensure that any OID passed is valid for the UTF8String type as we do not explicitly validate this.

    +
    + emailAddresses +
    + []string +
    + (Optional) +

    Requested email subject alternative names.

    +
    + secretName +
    + string +
    +

    Name of the Secret resource that will be automatically created and managed by this Certificate resource. It will be populated with a private key and certificate, signed by the denoted issuer. The Secret resource lives in the same namespace as the Certificate resource.

    +
    + secretTemplate +
    + + CertificateSecretTemplate + +
    + (Optional) +

    Defines annotations and labels to be copied to the Certificate’s Secret. Labels and annotations on the Secret will be changed as they appear on the SecretTemplate when added or removed. SecretTemplate annotations are added in conjunction with, and cannot overwrite, the base set of annotations cert-manager sets on the Certificate’s Secret.

    +
    + keystores +
    + + CertificateKeystores + +
    + (Optional) +

    Additional keystore output formats to be stored in the Certificate’s Secret.

    +
    + issuerRef +
    + + ObjectReference + +
    +

    Reference to the issuer responsible for issuing the certificate. If the issuer is namespace-scoped, it must be in the same namespace as the Certificate. If the issuer is cluster-scoped, it can be used from any namespace.

    +

    The name field of the reference must always be specified.

    +
    + isCA +
    + bool +
    + (Optional) +

    Requested basic constraints isCA value. The isCA value is used to set the isCA field on the created CertificateRequest resources. Note that the issuer may choose to ignore the requested isCA value, just like any other requested attribute.

    +

    If true, this will automatically add the cert sign usage to the list of requested usages.

    +
    + usages +
    + + []KeyUsage + +
    + (Optional) +

    Requested key usages and extended key usages. These usages are used to set the usages field on the created CertificateRequest resources. If encodeUsagesInRequest is unset or set to true, the usages will additionally be encoded in the request field which contains the CSR blob.

    +

    If unset, defaults to digital signature and key encipherment.

    +
    + privateKey +
    + + CertificatePrivateKey + +
    + (Optional) +

    Private key options. These include the key algorithm and size, the used encoding and the rotation policy.

    +
    + encodeUsagesInRequest +
    + bool +
    + (Optional) +

    Whether the KeyUsage and ExtKeyUsage extensions should be set in the encoded CSR.

    +

    This option defaults to true, and should only be disabled if the target issuer does not support CSRs with these X509 KeyUsage/ ExtKeyUsage extensions.

    +
    + revisionHistoryLimit +
    + int32 +
    + (Optional) +

    + The maximum number of CertificateRequest revisions that are maintained in the Certificate’s history. Each revision represents a single CertificateRequest + created by this Certificate, either when it was created, renewed, or Spec was changed. Revisions will be removed by oldest first if the number of revisions exceeds this number. +

    +

    If set, revisionHistoryLimit must be a value of 1 or greater. If unset (nil), revisions will not be garbage collected. Default value is nil.

    +
    + additionalOutputFormats +
    + + []CertificateAdditionalOutputFormat + +
    + (Optional) +

    Defines extra output formats of the private key and signed certificate chain to be written to this Certificate’s target Secret.

    +

    + This is a Beta Feature enabled by default. It can be disabled with the + --feature-gates=AdditionalCertificateOutputFormats=false option set on both the controller and webhook components. +

    +
    + nameConstraints +
    + + NameConstraints + +
    + (Optional) +

    x.509 certificate NameConstraint extension which MUST NOT be used in a non-CA certificate. More Info: https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10

    +

    + This is an Alpha Feature and is only enabled with the + --feature-gates=NameConstraints=true option set on both the controller and webhook components. +

    +
    +

    CertificateStatus

    +

    (Appears on: Certificate)

    +
    +

    CertificateStatus defines the observed state of Certificate

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + conditions +
    + + []CertificateCondition + +
    + (Optional) +

    List of status conditions to indicate the status of certificates. Known condition types are Ready and Issuing.

    +
    + lastFailureTime +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    LastFailureTime is set only if the lastest issuance for this Certificate failed and contains the time of the failure. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1). If the latest issuance has succeeded this field will be unset.

    +
    + notBefore +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    The time after which the certificate stored in the secret named by this resource in spec.secretName is valid.

    +
    + notAfter +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    The expiration time of the certificate stored in the secret named by this resource in spec.secretName.

    +
    + renewalTime +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    RenewalTime is the time at which the certificate will be next renewed. If not set, no upcoming renewal is scheduled.

    +
    + revision +
    + int +
    + (Optional) +

    The current ‘revision’ of the certificate as issued.

    +

    + When a CertificateRequest resource is created, it will have the + cert-manager.io/certificate-revision set to one greater than the current value of this field. +

    +

    Upon issuance, this field will be set to the value of the annotation on the CertificateRequest resource used to issue the certificate.

    +

    Persisting the value on the CertificateRequest resource allows the certificates controller to know whether a request is part of an old issuance or if it is part of the ongoing revision’s issuance by checking if the revision value in the annotation is greater than this field.

    +
    + nextPrivateKeySecretName +
    + string +
    + (Optional) +

    + The name of the Secret resource containing the private key to be used for the next certificate iteration. The keymanager controller will automatically set this field if the + Issuing condition is set to True. It will automatically unset this field when the Issuing condition is not set or False. +

    +
    + failedIssuanceAttempts +
    + int +
    + (Optional) +

    The number of continuous failed issuance attempts up till now. This field gets removed (if set) on a successful issuance and gets set to 1 if unset and an issuance has failed. If an issuance has failed, the delay till the next issuance will be calculated using formula time.Hour * 2 ^ (failedIssuanceAttempts - 1).

    +
    +

    GenericIssuer

    +
    +

    IssuerCondition

    +

    (Appears on: IssuerStatus)

    +
    +

    IssuerCondition contains condition information for an Issuer.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + type +
    + + IssuerConditionType + +
    +

    Type of the condition, known values are (Ready).

    +
    + status +
    + + ConditionStatus + +
    +

    Status of the condition, one of (True, False, Unknown).

    +
    + lastTransitionTime +
    + + Kubernetes meta/v1.Time + +
    + (Optional) +

    LastTransitionTime is the timestamp corresponding to the last status change of this condition.

    +
    + reason +
    + string +
    + (Optional) +

    Reason is a brief machine readable explanation for the condition’s last transition.

    +
    + message +
    + string +
    + (Optional) +

    Message is a human readable description of the details of the last transition, complementing reason.

    +
    + observedGeneration +
    + int64 +
    + (Optional) +

    If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Issuer.

    +
    +

    IssuerConditionType (string alias)

    +

    (Appears on: IssuerCondition)

    +
    +

    IssuerConditionType represents an Issuer condition value.

    +
    + + + + + + + + + + + + + +
    ValueDescription
    +

    "Ready"

    +
    +

    IssuerConditionReady represents the fact that a given Issuer condition is in ready state and able to issue certificates. If the status of this condition is False, CertificateRequest controllers should prevent attempts to sign certificates.

    +
    +

    IssuerConfig

    +

    (Appears on: IssuerSpec)

    +
    +

    The configuration for the issuer. Only one of these can be set.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + acme +
    + + ACMEIssuer + +
    + (Optional) +

    ACME configures this issuer to communicate with a RFC8555 (ACME) server to obtain signed x509 certificates.

    +
    + ca +
    + + CAIssuer + +
    + (Optional) +

    CA configures this issuer to sign certificates using a signing CA keypair stored in a Secret resource. This is used to build internal PKIs that are managed by cert-manager.

    +
    + vault +
    + + VaultIssuer + +
    + (Optional) +

    Vault configures this issuer to sign certificates using a HashiCorp Vault PKI backend.

    +
    + selfSigned +
    + + SelfSignedIssuer + +
    + (Optional) +

    SelfSigned configures this issuer to ‘self sign’ certificates using the private key used to create the CertificateRequest object.

    +
    + venafi +
    + + VenafiIssuer + +
    + (Optional) +

    Venafi configures this issuer to sign certificates using a Venafi TPP or Venafi Cloud policy zone.

    +
    +

    IssuerSpec

    +

    (Appears on: ClusterIssuer, Issuer)

    +
    +

    IssuerSpec is the specification of an Issuer. This includes any configuration required for the issuer.

    +
    + + + + + + + + + + + + + +
    FieldDescription
    + IssuerConfig +
    + + IssuerConfig + +
    +

    (Members of IssuerConfig are embedded into this type.)

    +
    +

    IssuerStatus

    +

    (Appears on: ClusterIssuer, Issuer)

    +
    +

    IssuerStatus contains status information about an Issuer

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    + conditions +
    + + []IssuerCondition + +
    + (Optional) +

    List of status conditions to indicate the status of a CertificateRequest. Known condition types are Ready.

    +
    + acme +
    + + ACMEIssuerStatus + +
    + (Optional) +

    ACME specific status options. This field should only be set if the Issuer is configured to use an ACME server to issue certificates.

    +
    +

    JKSKeystore

    +

    (Appears on: CertificateKeystores)

    +
    +

    + JKS configures options for storing a JKS keystore in the spec.secretName + Secret resource. +

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + create +
    + bool +
    +

    + Create enables JKS keystore creation for the Certificate. If true, a file named keystore.jks will be created in the target Secret resource, encrypted using the password stored in passwordSecretRef. The keystore file will be updated immediately. If the issuer provided a CA certificate, a file named truststore.jks will also be created in the target Secret resource, encrypted using the password stored in passwordSecretRef + containing the issuing Certificate Authority +

    +
    + passwordSecretRef +
    + + SecretKeySelector + +
    +

    PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the JKS keystore.

    +
    + alias +
    + string +
    + (Optional) +

    Alias specifies the alias of the key in the keystore, required by the JKS format. If not provided, the default alias certificate will be used.

    +
    +

    KeyUsage (string alias)

    +

    (Appears on: CertificateRequestSpec, CertificateSpec)

    +
    +

    + KeyUsage specifies valid usage contexts for keys. See: + https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + https://tools.ietf.org/html/rfc5280#section-4.2.1.12 +

    +

    Valid KeyUsage values are as follows: “signing”, “digital signature”, “content commitment”, “key encipherment”, “key agreement”, “data encipherment”, “cert sign”, “crl sign”, “encipher only”, “decipher only”, “any”, “server auth”, “client auth”, “code signing”, “email protection”, “s/mime”, “ipsec end system”, “ipsec tunnel”, “ipsec user”, “timestamping”, “ocsp signing”, “microsoft sgc”, “netscape sgc”

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "any"

    +
    +

    "crl sign"

    +
    +

    "cert sign"

    +
    +

    "client auth"

    +
    +

    "code signing"

    +
    +

    "content commitment"

    +
    +

    "data encipherment"

    +
    +

    "decipher only"

    +
    +

    "digital signature"

    +
    +

    "email protection"

    +
    +

    "encipher only"

    +
    +

    "ipsec end system"

    +
    +

    "ipsec tunnel"

    +
    +

    "ipsec user"

    +
    +

    "key agreement"

    +
    +

    "key encipherment"

    +
    +

    "microsoft sgc"

    +
    +

    "netscape sgc"

    +
    +

    "ocsp signing"

    +
    +

    "s/mime"

    +
    +

    "server auth"

    +
    +

    "signing"

    +
    +

    "timestamping"

    +
    +

    NameConstraintItem

    +

    (Appears on: NameConstraints)

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + dnsDomains +
    + []string +
    + (Optional) +

    DNSDomains is a list of DNS domains that are permitted or excluded.

    +
    + ipRanges +
    + []string +
    + (Optional) +

    IPRanges is a list of IP Ranges that are permitted or excluded. This should be a valid CIDR notation.

    +
    + emailAddresses +
    + []string +
    + (Optional) +

    EmailAddresses is a list of Email Addresses that are permitted or excluded.

    +
    + uriDomains +
    + []string +
    + (Optional) +

    URIDomains is a list of URI domains that are permitted or excluded.

    +
    +

    NameConstraints

    +

    (Appears on: CertificateSpec)

    +
    +

    NameConstraints is a type to represent x509 NameConstraints

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + critical +
    + bool +
    + (Optional) +

    if true then the name constraints are marked critical.

    +
    + permitted +
    + + NameConstraintItem + +
    + (Optional) +

    Permitted contains the constraints in which the names must be located.

    +
    + excluded +
    + + NameConstraintItem + +
    + (Optional) +

    Excluded contains the constraints which must be disallowed. Any name matching a restriction in the excluded field is invalid regardless of information appearing in the permitted

    +
    +

    OtherName

    +

    (Appears on: CertificateSpec)

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    + oid +
    + string +
    +

    OID is the object identifier for the otherName SAN. The object identifier must be expressed as a dotted string, for example, “1.2.840.113556.1.4.221”.

    +
    + utf8Value +
    + string +
    +

    utf8Value is the string value of the otherName SAN. The utf8Value accepts any valid UTF8 string to set as value for the otherName SAN.

    +
    +

    PKCS12Keystore

    +

    (Appears on: CertificateKeystores)

    +
    +

    + PKCS12 configures options for storing a PKCS12 keystore in the + spec.secretName Secret resource. +

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + create +
    + bool +
    +

    Create enables PKCS12 keystore creation for the Certificate. If true, a file named keystore.p12 will be created in the target Secret resource, encrypted using the password stored in passwordSecretRef. The keystore file will be updated immediately. If the issuer provided a CA certificate, a file named truststore.p12 will also be created in the target Secret resource, encrypted using the password stored in passwordSecretRef containing the issuing Certificate Authority

    +
    + passwordSecretRef +
    + + SecretKeySelector + +
    +

    PasswordSecretRef is a reference to a key in a Secret resource containing the password used to encrypt the PKCS12 keystore.

    +
    + profile +
    + + PKCS12Profile + +
    + (Optional) +

    Profile specifies the key and certificate encryption algorithms and the HMAC algorithm used to create the PKCS12 keystore. Default value is LegacyRC2 for backward compatibility.

    +

    + If provided, allowed values are: + LegacyRC2: Deprecated. Not supported by default in OpenSSL 3 or Java 20. LegacyDES: Less secure algorithm. Use this option for maximal compatibility. Modern2023: Secure algorithm. Use this option in case you have to always use secure algorithms (eg. because of company policy). Please note that the security of the algorithm is not that important in reality, because the unencrypted certificate and private key are also stored in the Secret. +

    +
    +

    PKCS12Profile (string alias)

    +

    (Appears on: PKCS12Keystore)

    +
    + + + + + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "LegacyDES"

    +
    +

    see: https://pkg.go.dev/software.sslmate.com/src/go-pkcs12#LegacyDES

    +
    +

    "LegacyRC2"

    +
    +

    see: https://pkg.go.dev/software.sslmate.com/src/go-pkcs12#LegacyRC2

    +
    +

    "Modern2023"

    +
    +

    see: https://pkg.go.dev/software.sslmate.com/src/go-pkcs12#Modern2023

    +
    +

    PrivateKeyAlgorithm (string alias)

    +

    (Appears on: CertificatePrivateKey)

    +
    + + + + + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "ECDSA"

    +
    +

    ECDSA private key algorithm.

    +
    +

    "Ed25519"

    +
    +

    Ed25519 private key algorithm.

    +
    +

    "RSA"

    +
    +

    RSA private key algorithm.

    +
    +

    PrivateKeyEncoding (string alias)

    +

    (Appears on: CertificatePrivateKey)

    +
    + + + + + + + + + + + + + + + + + +
    ValueDescription
    +

    "PKCS1"

    +
    +

    PKCS1 private key encoding. PKCS1 produces a PEM block that contains the private key algorithm in the header and the private key in the body. A key that uses this can be recognised by its BEGIN RSA PRIVATE KEY or BEGIN EC PRIVATE KEY header. NOTE: This encoding is not supported for Ed25519 keys. Attempting to use this encoding with an Ed25519 key will be ignored and default to PKCS8.

    +
    +

    "PKCS8"

    +
    +

    PKCS8 private key encoding. PKCS8 produces a PEM block with a static header and both the private key algorithm and the private key in the body. A key that uses this encoding can be recognised by its BEGIN PRIVATE KEY header.

    +
    +

    PrivateKeyRotationPolicy (string alias)

    +

    (Appears on: CertificatePrivateKey)

    +
    +

    Denotes how private keys should be generated or sourced when a Certificate is being issued.

    +
    +

    SelfSignedIssuer

    +

    (Appears on: IssuerConfig)

    +
    +

    Configures an issuer to ‘self sign’ certificates using the private key used to create the CertificateRequest object.

    +
    + + + + + + + + + + + + + +
    FieldDescription
    + crlDistributionPoints +
    + []string +
    + (Optional) +

    The CRL distribution points is an X.509 v3 certificate extension which identifies the location of the CRL from which the revocation of this certificate can be checked. If not set certificate will be issued without CDP. Values are strings.

    +
    +

    ServiceAccountRef

    +

    (Appears on: VaultKubernetesAuth)

    +
    +

    ServiceAccountRef is a service account used by cert-manager to request a token. Default audience is generated by cert-manager and takes the form vault://namespace-name/issuer-name for an Issuer and vault://issuer-name for a ClusterIssuer. The expiration of the token is also set by cert-manager to 10 minutes.

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    + name +
    + string +
    +

    Name of the ServiceAccount used to request a token.

    +
    + audiences +
    + []string +
    + (Optional) +

    TokenAudiences is an optional list of extra audiences to include in the token passed to Vault. The default token consisting of the issuer’s namespace and name is always included.

    +
    +

    VaultAppRole

    +

    (Appears on: VaultAuth)

    +
    +

    VaultAppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + path +
    + string +
    +

    Path where the App Role authentication backend is mounted in Vault, e.g: “approle”

    +
    + roleId +
    + string +
    +

    RoleID configured in the App Role authentication backend when setting up the authentication backend in Vault.

    +
    + secretRef +
    + + SecretKeySelector + +
    +

    Reference to a key in a Secret that contains the App Role secret used to authenticate with Vault. The key field must be specified and denotes which entry within the Secret resource is used as the app role secret.

    +
    +

    VaultAuth

    +

    (Appears on: VaultIssuer)

    +
    +

    VaultAuth is configuration used to authenticate with a Vault server. The order of precedence is [tokenSecretRef, appRole or kubernetes].

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + tokenSecretRef +
    + + SecretKeySelector + +
    + (Optional) +

    TokenSecretRef authenticates with Vault by presenting a token.

    +
    + appRole +
    + + VaultAppRole + +
    + (Optional) +

    AppRole authenticates with Vault using the App Role auth mechanism, with the role and secret stored in a Kubernetes Secret resource.

    +
    + kubernetes +
    + + VaultKubernetesAuth + +
    + (Optional) +

    Kubernetes authenticates with Vault by passing the ServiceAccount token stored in the named Secret resource to the Vault server.

    +
    +

    VaultIssuer

    +

    (Appears on: IssuerConfig)

    +
    +

    Configures an issuer to sign certificates using a HashiCorp Vault PKI backend.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + auth +
    + + VaultAuth + +
    +

    Auth configures how cert-manager authenticates with the Vault server.

    +
    + server +
    + string +
    +

    Server is the connection address for the Vault server, e.g: “https://vault.example.com:8200”.

    +
    + path +
    + string +
    +

    Path is the mount path of the Vault PKI backend’s sign endpoint, e.g: “my_pki_mount/sign/my-role-name”.

    +
    + namespace +
    + string +
    + (Optional) +

    Name of the vault namespace. Namespaces is a set of features within Vault Enterprise that allows Vault environments to support Secure Multi-tenancy. e.g: “ns1” More about namespaces can be found here https://www.vaultproject.io/docs/enterprise/namespaces

    +
    + caBundle +
    + []byte +
    + (Optional) +

    Base64-encoded bundle of PEM CAs which will be used to validate the certificate chain presented by Vault. Only used if using HTTPS to connect to Vault and ignored for HTTP connections. Mutually exclusive with CABundleSecretRef. If neither CABundle nor CABundleSecretRef are defined, the certificate bundle in the cert-manager controller container is used to validate the TLS connection.

    +
    + caBundleSecretRef +
    + + SecretKeySelector + +
    + (Optional) +

    Reference to a Secret containing a bundle of PEM-encoded CAs to use when verifying the certificate chain presented by Vault when using HTTPS. Mutually exclusive with CABundle. If neither CABundle nor CABundleSecretRef are defined, the certificate bundle in the cert-manager controller container is used to validate the TLS connection. If no key for the Secret is specified, cert-manager will default to ‘ca.crt’.

    +
    + clientCertSecretRef +
    + + SecretKeySelector + +
    + (Optional) +

    Reference to a Secret containing a PEM-encoded Client Certificate to use when the Vault server requires mTLS.

    +
    + clientKeySecretRef +
    + + SecretKeySelector + +
    + (Optional) +

    Reference to a Secret containing a PEM-encoded Client Private Key to use when the Vault server requires mTLS.

    +
    +

    VaultKubernetesAuth

    +

    (Appears on: VaultAuth)

    +
    +

    Authenticate against Vault using a Kubernetes ServiceAccount token stored in a Secret.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + mountPath +
    + string +
    + (Optional) +

    The Vault mountPath here is the mount path to use when authenticating with Vault. For example, setting a value to /v1/auth/foo, will use the path /v1/auth/foo/login to authenticate with Vault. If unspecified, the default value “/v1/auth/kubernetes” will be used.

    +
    + secretRef +
    + + SecretKeySelector + +
    + (Optional) +

    The required Secret field containing a Kubernetes ServiceAccount JWT used for authenticating with Vault. Use of ‘ambient credentials’ is not supported.

    +
    + serviceAccountRef +
    + + ServiceAccountRef + +
    + (Optional) +

    A reference to a service account that will be used to request a bound token (also known as “projected token”). Compared to using “secretRef”, using this field means that you don’t rely on statically bound tokens. To use this field, you must configure an RBAC rule to let cert-manager request a token.

    +
    + role +
    + string +
    +

    A required field containing the Vault Role to assume. A Role binds a Kubernetes ServiceAccount with a set of Vault policies.

    +
    +

    VenafiCloud

    +

    (Appears on: VenafiIssuer)

    +
    +

    VenafiCloud defines connection configuration details for Venafi Cloud

    +
    + + + + + + + + + + + + + + + + + +
    FieldDescription
    + url +
    + string +
    + (Optional) +

    URL is the base URL for Venafi Cloud. Defaults to “https://api.venafi.cloud/v1”.

    +
    + apiTokenSecretRef +
    + + SecretKeySelector + +
    +

    APITokenSecretRef is a secret key selector for the Venafi Cloud API token.

    +
    +

    VenafiIssuer

    +

    (Appears on: IssuerConfig)

    +
    +

    Configures an issuer to sign certificates using a Venafi TPP or Cloud policy zone.

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + zone +
    + string +
    +

    Zone is the Venafi Policy Zone to use for this issuer. All requests made to the Venafi platform will be restricted by the named zone policy. This field is required.

    +
    + tpp +
    + + VenafiTPP + +
    + (Optional) +

    TPP specifies Trust Protection Platform configuration settings. Only one of TPP or Cloud may be specified.

    +
    + cloud +
    + + VenafiCloud + +
    + (Optional) +

    Cloud specifies the Venafi cloud configuration settings. Only one of TPP or Cloud may be specified.

    +
    +

    VenafiTPP

    +

    (Appears on: VenafiIssuer)

    +
    +

    VenafiTPP defines connection configuration details for a Venafi TPP instance

    +
    + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + url +
    + string +
    +

    URL is the base URL for the vedsdk endpoint of the Venafi TPP instance, for example: “https://tpp.example.com/vedsdk”.

    +
    + credentialsRef +
    + + LocalObjectReference + +
    +

    CredentialsRef is a reference to a Secret containing the username and password for the TPP server. The secret must contain two keys, ‘username’ and ‘password’.

    +
    + caBundle +
    + []byte +
    + (Optional) +

    Base64-encoded bundle of PEM CAs which will be used to validate the certificate chain presented by the TPP server. Only used if using HTTPS; ignored for HTTP. If undefined, the certificate bundle in the cert-manager controller container is used to validate the chain.

    +
    +

    X509Subject

    +

    (Appears on: CertificateSpec)

    +
    +

    X509Subject Full X509 name specification

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    + organizations +
    + []string +
    + (Optional) +

    Organizations to be used on the Certificate.

    +
    + countries +
    + []string +
    + (Optional) +

    Countries to be used on the Certificate.

    +
    + organizationalUnits +
    + []string +
    + (Optional) +

    Organizational Units to be used on the Certificate.

    +
    + localities +
    + []string +
    + (Optional) +

    Cities to be used on the Certificate.

    +
    + provinces +
    + []string +
    + (Optional) +

    State/Provinces to be used on the Certificate.

    +
    + streetAddresses +
    + []string +
    + (Optional) +

    Street addresses to be used on the Certificate.

    +
    + postalCodes +
    + []string +
    + (Optional) +

    Postal codes to be used on the Certificate.

    +
    + serialNumber +
    + string +
    + (Optional) +

    Serial number to be used on the Certificate.

    +
    +
    +

    controller.config.cert-manager.io/v1alpha1

    +
    +

    Package v1alpha1 is the v1alpha1 version of the controller config API.

    +
    +

    Resource Types:

    +
      +

      ACMEDNS01Config

      +

      (Appears on: ControllerConfiguration)

      +
      + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      + recursiveNameservers +
      + []string +
      +

      Each nameserver can be either the IP address and port of a standard recursive DNS server, or the endpoint to an RFC 8484 DNS over HTTPS endpoint. For example, the following values are valid: - “8.8.8.8:53” (Standard DNS) - “https://1.1.1.1/dns-query” (DNS over HTTPS)

      +
      + recursiveNameserversOnly +
      + bool +
      +

      When true, cert-manager will only ever query the configured DNS resolvers to perform the ACME DNS01 self check. This is useful in DNS constrained environments, where access to authoritative nameservers is restricted. Enabling this option could cause the DNS01 self check to take longer due to caching performed by the recursive nameservers.

      +
      + checkRetryPeriod +
      + github.com/cert-manager/cert-manager/pkg/apis/config/shared/v1alpha1.Duration +
      +

      The duration the controller should wait between a propagation check. Despite the name, this flag is used to configure the wait period for both DNS01 and HTTP01 challenge propagation checks. For DNS01 challenges the propagation check verifies that a TXT record with the challenge token has been created. For HTTP01 challenges the propagation check verifies that the challenge token is served at the challenge URL. This should be a valid duration string, for example 180s or 1h

      +
      +

      ACMEHTTP01Config

      +

      (Appears on: ControllerConfiguration)

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      + solverImage +
      + string +
      +

      The Docker image to use to solve ACME HTTP01 challenges. You most likely will not need to change this parameter unless you are testing a new feature or developing cert-manager.

      +
      + solverResourceRequestCPU +
      + string +
      +

      Defines the resource request CPU size when spawning new ACME HTTP01 challenge solver pods.

      +
      + solverResourceRequestMemory +
      + string +
      +

      Defines the resource request Memory size when spawning new ACME HTTP01 challenge solver pods.

      +
      + solverResourceLimitsCPU +
      + string +
      +

      Defines the resource limits CPU size when spawning new ACME HTTP01 challenge solver pods.

      +
      + solverResourceLimitsMemory +
      + string +
      +

      Defines the resource limits Memory size when spawning new ACME HTTP01 challenge solver pods.

      +
      + solverRunAsNonRoot +
      + bool +
      +

      Defines the ability to run the http01 solver as root for troubleshooting issues

      +
      + solverNameservers +
      + []string +
      +

      A list of comma separated dns server endpoints used for ACME HTTP01 check requests. This should be a list containing host and port, for example [“8.8.8.8:53”,“8.8.4.4:53”] Allows specifying a list of custom nameservers to perform HTTP01 checks on.

      +
      +

      ControllerConfiguration

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      + kubeConfig +
      + string +
      +

      kubeConfig is the kubeconfig file used to connect to the Kubernetes apiserver. If not specified, the controller will attempt to load the in-cluster-config.

      +
      + apiServerHost +
      + string +
      +

      apiServerHost is used to override the API server connection address. Deprecated: use kubeConfig instead.

      +
      + kubernetesAPIQPS +
      + float32 +
      +

      Indicates the maximum queries-per-second requests to the Kubernetes apiserver TODO: floats are not recommended. Maybe we should use resource.Quantity? https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity/

      +
      + kubernetesAPIBurst +
      + int32 +
      +

      The maximum burst queries-per-second of requests sent to the Kubernetes apiserver

      +
      + namespace +
      + string +
      +

      If set, this limits the scope of cert-manager to a single namespace and ClusterIssuers are disabled. If not specified, all namespaces will be watched”

      +
      + clusterResourceNamespace +
      + string +
      +

      Namespace to store resources owned by cluster scoped resources such as ClusterIssuer in.

      +
      + leaderElectionConfig +
      + + LeaderElectionConfig + +
      +

      LeaderElectionConfig configures the behaviour of the leader election

      +
      + controllers +
      + []string +
      +

      A list of controllers to enable. [’’] enables all controllers, [‘foo’] enables only the foo controller [’’, ‘-foo’] disables the controller named foo.

      +
      + issuerAmbientCredentials +
      + bool +
      +

      Whether an issuer may make use of ambient credentials. ‘Ambient Credentials’ are credentials drawn from the environment, metadata services, or local files which are not explicitly configured in the Issuer API object. When this flag is enabled, the following sources for credentials are also used: AWS - All sources the Go SDK defaults to, notably including any EC2 IAM roles available via instance metadata.

      +
      + clusterIssuerAmbientCredentials +
      + bool +
      +

      Whether a cluster-issuer may make use of ambient credentials for issuers. ‘Ambient Credentials’ are credentials drawn from the environment, metadata services, or local files which are not explicitly configured in the ClusterIssuer API object. When this flag is enabled, the following sources for credentials are also used: AWS - All sources the Go SDK defaults to, notably including any EC2 IAM roles available via instance metadata.

      +
      + enableCertificateOwnerRef +
      + bool +
      +

      Whether to set the certificate resource as an owner of secret where the tls certificate is stored. When this flag is enabled, the secret will be automatically removed when the certificate resource is deleted.

      +
      + enableGatewayAPI +
      + bool +
      +

      Whether gateway API integration is enabled within cert-manager. The ExperimentalGatewayAPISupport feature gate must also be enabled (default as of 1.15).

      +
      + copiedAnnotationPrefixes +
      + []string +
      +

      Specify which annotations should/shouldn’t be copied from Certificate to CertificateRequest and Order, as well as from CertificateSigningRequest to Order, by passing a list of annotation key prefixes. A prefix starting with a dash(-) specifies an annotation that shouldn’t be copied. Example: ‘*,-kubectl.kuberenetes.io/’- all annotations will be copied apart from the ones where the key is prefixed with ‘kubectl.kubernetes.io/’.

      +
      + numberOfConcurrentWorkers +
      + int32 +
      +

      The number of concurrent workers for each controller.

      +
      + maxConcurrentChallenges +
      + int32 +
      +

      The maximum number of challenges that can be scheduled as ‘processing’ at once.

      +
      + metricsListenAddress +
      + string +
      +

      The host and port that the metrics endpoint should listen on.

      +
      + metricsTLSConfig +
      + github.com/cert-manager/cert-manager/pkg/apis/config/shared/v1alpha1.TLSConfig +
      +

      TLS config for the metrics endpoint

      +
      + healthzListenAddress +
      + string +
      +

      The host and port address, separated by a ‘:’, that the healthz server should listen on.

      +
      + enablePprof +
      + bool +
      +

      Enable profiling for controller.

      +
      + pprofAddress +
      + string +
      +

      The host and port that Go profiler should listen on, i.e localhost:6060. Ensure that profiler is not exposed on a public address. Profiler will be served at /debug/pprof.

      +
      + logging +
      + k8s.io/component-base/logs/api/v1.LoggingConfiguration +
      +

      + logging configures the logging behaviour of the controller. + https://pkg.go.dev/k8s.io/component-base@v0.27.3/logs/api/v1#LoggingConfiguration +

      +
      + featureGates +
      + map[string]bool +
      + (Optional) +

      featureGates is a map of feature names to bools that enable or disable experimental features.

      +
      + ingressShimConfig +
      + + IngressShimConfig + +
      +

      ingressShimConfig configures the behaviour of the ingress-shim controller

      +
      + acmeHTTP01Config +
      + + ACMEHTTP01Config + +
      +

      acmeHTTP01Config configures the behaviour of the ACME HTTP01 challenge solver

      +
      + acmeDNS01Config +
      + + ACMEDNS01Config + +
      +

      acmeDNS01Config configures the behaviour of the ACME DNS01 challenge solver

      +
      +

      IngressShimConfig

      +

      (Appears on: ControllerConfiguration)

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      FieldDescription
      + defaultIssuerName +
      + string +
      +

      Default issuer/certificates details consumed by ingress-shim Name of the Issuer to use when the tls is requested but issuer name is not specified on the ingress resource.

      +
      + defaultIssuerKind +
      + string +
      +

      Kind of the Issuer to use when the TLS is requested but issuer kind is not specified on the ingress resource.

      +
      + defaultIssuerGroup +
      + string +
      +

      Group of the Issuer to use when the TLS is requested but issuer group is not specified on the ingress resource.

      +
      + defaultAutoCertificateAnnotations +
      + []string +
      +

      The annotation consumed by the ingress-shim controller to indicate a ingress is requesting a certificate

      +
      +

      LeaderElectionConfig

      +

      (Appears on: ControllerConfiguration)

      +
      + + + + + + + + + + + + + + + + + +
      FieldDescription
      + LeaderElectionConfig +
      + github.com/cert-manager/cert-manager/pkg/apis/config/shared/v1alpha1.LeaderElectionConfig +
      +

      (Members of LeaderElectionConfig are embedded into this type.)

      +
      + healthzTimeout +
      + github.com/cert-manager/cert-manager/pkg/apis/config/shared/v1alpha1.Duration +
      +

      Leader election healthz checks within this timeout period after the lease expires will still return healthy.

      +
      +
      +

      meta.cert-manager.io/v1

      +
      +

      Package v1 contains meta types for cert-manager APIs

      +
      +

      Resource Types:

      +
        +

        ConditionStatus (string alias)

        +

        (Appears on: CertificateCondition, CertificateRequestCondition, IssuerCondition)

        +
        +

        ConditionStatus represents a condition’s status.

        +
        + + + + + + + + + + + + + + + + + + + + + +
        ValueDescription
        +

        "False"

        +
        +

        ConditionFalse represents the fact that a given condition is false

        +
        +

        "True"

        +
        +

        ConditionTrue represents the fact that a given condition is true

        +
        +

        "Unknown"

        +
        +

        ConditionUnknown represents the fact that a given condition is unknown

        +
        +

        LocalObjectReference

        +

        (Appears on: VenafiTPP, SecretKeySelector)

        +
        +

        A reference to an object in the same namespace as the referent. If the referent is a cluster-scoped resource (e.g. a ClusterIssuer), the reference instead refers to the resource with the given name in the configured ‘cluster resource namespace’, which is set as a flag on the controller component (and defaults to the namespace that cert-manager runs in).

        +
        + + + + + + + + + + + + + +
        FieldDescription
        + name +
        + string +
        +

        Name of the resource being referred to. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

        +
        +

        ObjectReference

        +

        (Appears on: ChallengeSpec, OrderSpec, CertificateRequestSpec, CertificateSpec)

        +
        +

        ObjectReference is a reference to an object with a given name, kind and group.

        +
        + + + + + + + + + + + + + + + + + + + + + +
        FieldDescription
        + name +
        + string +
        +

        Name of the resource being referred to.

        +
        + kind +
        + string +
        + (Optional) +

        Kind of the resource being referred to.

        +
        + group +
        + string +
        + (Optional) +

        Group of the resource being referred to.

        +
        +

        SecretKeySelector

        +

        + (Appears on: ACMEExternalAccountBinding, ACMEIssuer, ACMEIssuerDNS01ProviderAcmeDNS, ACMEIssuerDNS01ProviderAkamai, ACMEIssuerDNS01ProviderAzureDNS, ACMEIssuerDNS01ProviderCloudDNS, ACMEIssuerDNS01ProviderCloudflare, ACMEIssuerDNS01ProviderDigitalOcean, ACMEIssuerDNS01ProviderRFC2136, + ACMEIssuerDNS01ProviderRoute53, JKSKeystore, PKCS12Keystore, VaultAppRole, VaultAuth, VaultIssuer, VaultKubernetesAuth, VenafiCloud) +

        +
        +

        A reference to a specific ‘key’ within a Secret resource. In some instances, key is a required field.

        +
        + + + + + + + + + + + + + + + + + +
        FieldDescription
        + LocalObjectReference +
        + + LocalObjectReference + +
        +

        (Members of LocalObjectReference are embedded into this type.)

        +

        The name of the Secret resource being referred to.

        +
        + key +
        + string +
        + (Optional) +

        The key of the entry in the Secret resource’s data field to be used. Some instances of this field may be defaulted, in others it may be required.

        +
        +
        +

        webhook.config.cert-manager.io/v1alpha1

        +
        +

        Package v1alpha1 is the v1alpha1 version of the webhook config API.

        +
        +

        Resource Types:

        +
          +

          WebhookConfiguration

          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          FieldDescription
          + securePort +
          + int32 +
          +

          securePort is the port number to listen on for secure TLS connections from the kube-apiserver. If 0, a random available port will be chosen. Defaults to 6443.

          +
          + healthzPort +
          + int32 +
          +

          healthzPort is the port number to listen on (using plaintext HTTP) for healthz connections. If 0, a random available port will be chosen. Defaults to 6080.

          +
          + tlsConfig +
          + github.com/cert-manager/cert-manager/pkg/apis/config/shared/v1alpha1.TLSConfig +
          +

          tlsConfig is used to configure the secure listener’s TLS settings.

          +
          + kubeConfig +
          + string +
          +

          kubeConfig is the kubeconfig file used to connect to the Kubernetes apiserver. If not specified, the webhook will attempt to load the in-cluster-config.

          +
          + apiServerHost +
          + string +
          +

          apiServerHost is used to override the API server connection address. Deprecated: use kubeConfig instead.

          +
          + enablePprof +
          + bool +
          +

          enablePprof configures whether pprof is enabled.

          +
          + pprofAddress +
          + string +
          +

          pprofAddress configures the address on which /debug/pprof endpoint will be served if enabled. Defaults to ‘localhost:6060’.

          +
          + logging +
          + k8s.io/component-base/logs/api/v1.LoggingConfiguration +
          +

          + logging configures the logging behaviour of the webhook. + https://pkg.go.dev/k8s.io/component-base@v0.27.3/logs/api/v1#LoggingConfiguration +

          +
          + featureGates +
          + map[string]bool +
          + (Optional) +

          featureGates is a map of feature names to bools that enable or disable experimental features.

          +
          +
          +

          + Generated with gen-crd-api-reference-docs on git commit 35e27b7. +

          diff --git a/content/v1.15-docs/reference/cmctl.md b/content/v1.15-docs/reference/cmctl.md new file mode 100644 index 0000000000..92ad87d542 --- /dev/null +++ b/content/v1.15-docs/reference/cmctl.md @@ -0,0 +1,379 @@ +--- +title: The cert-manager Command Line Tool (cmctl) +description: | + cmctl is a command line tool that can help you manage cert-manager and its resources inside your cluster +--- + +`cmctl` is a command line tool that can help you manage cert-manager and its resources inside your cluster. + +> 📢 The cert-manager CLI is moving to a new GitHub repository +> +> The cert-manager team have decided to move the `cmctl` code to a new GitHub repository. +> This will allow us to release new features and bug fixes for `cmctl` independently of cert-manager. +> It will simplify the Go package dependencies of cert-manager +> so there should be fewer security patch releases of cert-manager. +> It will make it easier for us to extend `cmctl` with features for managing `trust-manager` and `approver-policy`. +> And it will allow us to write more E2E tests for `cmctl` without further slowing down the test suite of cert-manager. +> +> ⚠️ cert-manager 1.14 is the last release that will still include a `cert-manager-ctl` container image, go package and GitHub release binary. +> +> Visit the new [cmctl repository on GitHub to find out more](https://github.com/cert-manager/cmctl). + +## Installation + +### Homebrew + +On Mac or Linux if you have [Homebrew](https://brew.sh) installed, you can +install `cmctl` with: + +```console +brew install cmctl +``` + +This will also install shell completion. + +### Manual Installation + +You need the `cmctl` file for the platform you're using, these can be +found on our +[cmctl GitHub releases page](https://github.com/cert-manager/cmctl/releases). +In order to use `cmctl` you need its binary to be accessible under +the name `cmctl` in your `$PATH`. +Run the following commands to set up the CLI. Replace OS and ARCH with your +systems equivalents: + +```console +OS=$(go env GOOS); ARCH=$(go env GOARCH); curl -fsSL -o cmctl https://github.com/cert-manager/cmctl/releases/latest/download/cmctl_${OS}_${ARCH} +chmod +x cmctl +sudo mv cmctl /usr/local/bin +``` + +Alternatively, you can install `cmctl` using `go`: + +```bash +go install github.com/cert-manager/cmctl/v2@latest +``` + +You can run `cmctl help` to test the CLI is set up properly: + +```console +$ cmctl help + +cmctl is a CLI tool manage and configure cert-manager resources for Kubernetes + +Usage: cmctl [command] + +Available Commands: + approve Approve a CertificateRequest + check Check cert-manager components + completion Generate completion scripts for the cert-manager CLI + convert Convert cert-manager config files between different API versions + create Create cert-manager resources + deny Deny a CertificateRequest + experimental Interact with experimental features + help Help about any command + inspect Get details on certificate related resources + renew Mark a Certificate for manual renewal + status Get details on current status of cert-manager resources + upgrade Tools that assist in upgrading cert-manager + version Print the cert-manager CLI version and the deployed cert-manager version + +Flags: + -h, --help help for cmctl + --log-flush-frequency duration Maximum number of seconds between log flushes (default 5s) + +Use "cmctl [command] --help" for more information about a command. +``` + +> There is also a [legacy kubectl plugin](#legacy-kubectl-plugin), but it is no longer recommended +> because the standalone `cmctl` binary provides better [auto-completion](#completion). + +## Commands + +### Approve and Deny CertificateRequests + +CertificateRequests can be +[approved or denied](../usage/certificaterequest.md#approval) using their +respective cmctl commands: + +> **Note**: The internal cert-manager approver may automatically approve all +> CertificateRequests unless disabled with the flag on the cert-manager-controller +> `--controllers=*,-certificaterequests-approver` + +```bash +$ cmctl approve -n istio-system mesh-ca --reason "pki-team" --message "this certificate is valid" +Approved CertificateRequest 'istio-system/mesh-ca' +``` + +```bash +$ cmctl deny -n my-app my-app --reason "example.com" --message "violates policy" +Denied CertificateRequest 'my-app/my-app' +``` + +### Convert + +`cmctl convert` can be used to convert cert-manager manifest files between +different API versions. Both YAML and JSON formats are accepted. The command +either takes a file name, directory path, or a URL as input. The contents is +converted into the format of the latest API version known to cert-manager, or +the one specified by `--output-version` flag. + +The default output will be printed to stdout in YAML format. One can use the +option `-o` to change the output destination. + +For example, this will output `cert.yaml` in the latest API version: + +```console +cmctl convert -f cert.yaml +``` + +### Create + +`cmctl create` can be used to create cert-manager resources manually. +Sub-commands are available to create different resources: + +#### CertificateRequest + +To create a cert-manager CertificateRequest, use `cmctl create +certificaterequest`. The command takes in the name of the CertificateRequest to +be created, and creates a new CertificateRequest resource based on the YAML +manifest of a Certificate resource as specified by `--from-certificate-file` +flag, by generating a private key locally and creating a 'certificate signing +request' to be submitted to a cert-manager Issuer. The private key will be +written to a local file, where the default is `.key`, or it can be +specified using the `--output-key-file` flag. + +If you wish to wait for the CertificateRequest to be signed and store the X.509 +certificate in a file, you can set the `--fetch-certificate` flag. The default +timeout when waiting for the issuance of the certificate is 5 minutes, but can +be specified with the `--timeout` flag. The default name of the file storing the +X.509 certificate is `.crt`, you can use the ` +--output-certificate-file` flag to specify otherwise. + +Note that the private key and the X.509 certificate are both written to file, +and are **not** stored inside Kubernetes. + +For example this will create a CertificateRequest resource with the name "my-cr" +based on the cert-manager Certificate described in `my-certificate.yaml` while +storing the private key and X.509 certificate in `my-cr.key` and `my-cr.crt` +respectively. + +```console +cmctl create certificaterequest my-cr --from-certificate-file my-certificate.yaml --fetch-certificate --timeout 20m +``` + +### Renew + +`cmctl` allows you to manually trigger a renewal of a specific certificate. +This can be done either one certificate at a time, using label selectors (`-l app=example`), or with the `--all` flag: + +For example, you can renew the certificate `example-com-tls`: +```console +$ kubectl get certificate +NAME READY SECRET AGE +example-com-tls True example-com-tls 1d + +$ cmctl renew example-com-tls +Manually triggered issuance of Certificate default/example-com-tls + +$ kubectl get certificaterequest +NAME READY AGE +example-com-tls-tls-8rbv2 False 10s +``` + +You can also renew all certificates in a given namespace: + +```console +$ cmctl renew --namespace=app --all +``` + +The renew command allows several options to be specified: +* `--all` renew all Certificates in the given Namespace, or all namespaces when combined with `--all-namespaces` +* `-A` or `--all-namespaces` mark Certificates across namespaces for renewal +* `-l` `--selector` allows set a label query to filter on +as well as `kubectl` like global flags like `--context` and `--namespace`. + +### Status Certificate + +`cmctl status certificate` outputs the details of the current status of a +Certificate resource and related resources like CertificateRequest, Secret, +Issuer, as well as Order and Challenges if it is a ACME Certificate. The +command outputs information about the resources, including Conditions, Events +and resource specific fields like Key Usages and Extended Key Usages of the +Secret or Authorizations of the Order. This will be helpful for troubleshooting +a Certificate. + +The command takes in one argument specifying the name of the Certificate +resource and the namespace can be specified as usual with the `-n` or +`--namespace` flag. + +This example queries the status of the Certificate named `my-certificate` in +namespace `my-namespace`. + +```console +cmctl status certificate my-certificate -n my-namespace +``` + +### Completion + +`cmctl` supports auto-completion for both subcommands as well as suggestions for +runtime objects. + +```console +$ cmctl approve -n +default kube-node-lease kube-public kube-system local-path-storage +``` + +Completion can be installed for your environment by following the instructions +for the shell you are using. It currently supports bash, fish, zsh, and +powershell. + +```console +$ cmctl completion help +``` + +--- + +### Experimental +`cmctl x` has experimental sub-commands for operations which are currently under +evaluation to be included into cert-manager proper. The behavior and interface +of these commands are subject to change or removal in future releases. + + +#### Create +`cmctl x create` can be used to create cert-manager resources manually. +Sub-commands are available to create different resources: + +##### CertificateSigningRequest +To create a [CertificateSigningRequest](../usage/kube-csr.md), use +```console +cmctl x create csr +``` +This command takes the name of the CertificateSigningRequest to be created, as +well as a file containing a Certificate manifest (`-f, +--from-certificate-file`). This command will generate a private key, based on +the options of the Certificate, and write it to the local file `.key`, or +specified by `-k, --output-key-file`. + +```bash +$ cmctl x create csr -f my-cert.yaml my-req +``` + + +
          + +cert-manager **will not** automatically approve CertificateSigningRequests. If +you are not running a custom approver in your cluster, you will likely need to +manually approve the CertificateSigningRequest: + +```bash +$ kubectl certificate approve +``` + +
          + +This command can also wait for the CertificateSigningRequest to be signed using +the flag `-w, --fetch-certificate`. Once signed it will write the resulting +signed certificate to the local file `.crt`, or specified by `-c, +--output-certificate-file`. + +```bash +$ cmctl x create csr -f my-cert.yaml my-req -w +``` + +#### Install + +```bash +cmctl x install +``` + +This command makes sure that the required `CustomResourceDefinitions` are installed together with the cert-manager, cainjector and webhook components. +Under the hood, a procedure similar to the [Helm install procedure](../installation/helm.md#steps) is used. + +You can also use `cmctl x install` to customize the installation of cert-manager. + +The example below shows how to tune the cert-manager installation by overriding the default Helm values: + +```bash +cmctl x install \ + --set prometheus.enabled=false \ # Example: disabling prometheus using a Helm parameter + --set webhook.timeoutSeconds=4s # Example: changing the wehbook timeout using a Helm parameter +``` + +You can find [a full list of the install parameters on cert-manager's ArtifactHub page](https://artifacthub.io/packages/helm/cert-manager/cert-manager#configuration). These are the same parameters that are available when using the Helm chart. +Once you have deployed cert-manager, you can [verify](../installation/kubectl.md#verify) the installation. + +The CLI also allows the user to output the templated manifest to `stdout`, instead of installing the manifest on the cluster. + +```bash +cmctl x install --dry-run > cert-manager.custom.yaml +``` + +#### Uninstall + +```bash +cmctl x uninstall +``` + +This command uninstalls any Helm-managed release of cert-manager. + +Starting from cmctl `v2.0.0`, the uninstall command is safe and will not delete the CRDs +by default, even if they were installed with a cert-manager Helm chart before v1.15.0 (using the option `--set installCRDs=true`). +Starting from cert-manager v1.15.0, the CRDs are not removed by default when uninstalling the Helm chart using Helm. + +> 🕐 Before `v2.0.0`, cmctl would remove the CRDs if they were installed with the Helm chart (similar to Helm's behavior). + +Most of the features supported by `helm uninstall` are also supported by this command. + +Some example uses: + +```bash +cmctl x uninstall + +cmctl x uninstall --namespace my-cert-manager + +cmctl x uninstall --dry-run +``` + +### Upgrade + +Tools that assist in upgrading cert-manager + +```bash +$ cmctl upgrade --help +``` +##### Migrate API version + +This command can be used to prepare a cert-manager installation that was created +before cert-manager `v1` for upgrading to a cert-manager version `v1.6` or later. +It ensures that any cert-manager custom resources that may have been stored in etcd at +a deprecated API version get migrated to `v1`. See [Migrating Deprecated API +Resources](https://cert-manager.io/docs/releases/upgrading/remove-deprecated-apis) for more context. + +```bash +$ cmctl upgrade migrate-api-version --qps 5 --burst 10 +``` + +## Kubectl plugin + +Since kubectl 1.26, kubectl plugins support auto-completion, which means you will have the same +experience with the standalone `cmctl` binary and with the kubectl plugin. + +To install the plugin you need the `kubectl_cert-manager` file for the platform you're using, +these can be found on our [cmctl GitHub releases page](https://github.com/cert-manager/cmctl/releases). +In order to use the kubectl plugin you need its binary to be accessible under the name `kubectl-cert_manager` in your `$PATH`. + +You can run `kubectl cert-manager help` to test that the plugin is set up properly. + +### Auto-completion with the kubectl plugin + +Since kubectl 1.26, it is possible to enable auto-completion for plugins. Assuming that you installed +`kubectl_cert-manager` in `/usr/local/bin`, you can set up auto-completion by running the following command: + +```bash +cat >kubectl_complete-cert_manager <<'EOF' +#!/usr/bin/env sh +kubectl cert-manager __complete "$@" +EOF +sudo install kubectl_complete-cert_manager /usr/local/bin +``` diff --git a/content/v1.15-docs/reference/tls-terminology.md b/content/v1.15-docs/reference/tls-terminology.md new file mode 100644 index 0000000000..23b6df3447 --- /dev/null +++ b/content/v1.15-docs/reference/tls-terminology.md @@ -0,0 +1,79 @@ +--- +title: TLS Terminology +description: | + Learn about the TLS terminology used in the cert-manager documentation such as publicly trusted, self-signed, root, intermediate and leaf certificate +--- + +Learn about the TLS terminology used in the cert-manager documentation such as `publicly trusted`, `self-signed`, `root`, `intermediate` and `leaf` _certificate_. + +## Overview + +With TLS being so widely deployed, terminology can sometimes get confused or be used to mean different things, and that reality +combined with the complexity of TLS can lead to serious misunderstandings and confusion. + +For further reference, you might want to check out some relevant RFCs: + +- [RFC 5246: TLS 1.2](https://datatracker.ietf.org/doc/html/rfc5246) +- [RFC 8446: TLS 1.3](https://datatracker.ietf.org/doc/html/rfc8446) +- [RFC 5280: X.509](https://datatracker.ietf.org/doc/html/rfc5280) + +## Definitions + +### `publicly trusted` + +What does "publicly trusted" mean? + +Broadly speaking, a "publicly trusted" certificate is one that you can use on the Internet and expect +that most reasonably up-to-date computers will be able to verify it using their system trust store. + +There isn't a single standard trust store containing certs which are "publicly trusted", but generally most +of the commonly seen trust stores are similar. An example would be [Mozilla's CA Certificate Program](https://wiki.mozilla.org/CA). + +### What does "self-signed" mean? Is my CA self-signed? + +Self-signed means exactly what it says; a certificate is self-signed if it is signed by its own private key. + +Self-signed is a commonly confused term, however, and is very frequently misused to mean "not publicly trusted". We tend to use terms +like "private PKI" to denote the situation where an organization might have their own internal CA certificates which wouldn't +be trusted outside of the organization. + +As an example, there are _many_ self-signed certificates in [Mozilla's CA Certificate Program](https://wiki.mozilla.org/CA), but +all of those certificates would usually be described as "publicly trusted". + +Your certificate is self-signed only if it's signed with its own key. + +### What's the difference between "root", "intermediate", and "leaf" certificates? + +cert-manager uses the following definitions: + +#### Root Certificates + +Roots are self-signed certificates and almost always marked as CA certificates. They're usually not sent over the wire +during a TLS handshake because they need to be explicitly trusted in order to be validated. + +Roots are sometimes defined as "CA certificates which are explicitly trusted"---which can include certificates which +aren't self-signed. cert-manager doesn't use this definition. + +Changing trust stores to include new roots or remove old ones is a non-trivial task which can take months or years for publicly +trusted roots. For this reason roots are usually issued with very long lifetimes, often on the order of decades. + +#### Intermediate Certificates + +Intermediates are CA certificates signed by another CA. Most intermediates will be signed by a root certificate, but it's +possible to construct longer chains where an intermediate can be signed by another intermediate. + +Intermediate certificates are usually issued with a much shorter lifetime than the CA which signed them. On the +Internet, intermediate certificates are used on network-connected machines for day-to-day issuance so that the +highly-valuable root certificates can remain entirely offline. + +While intermediate certificates can also be explicitly trusted via addition to a trust store, they're usually validated +by "walking up" the chain and validating signatures until an explicitly trusted self-signed root certificate is found. + +#### Leaf Certificates + +Leaf certificates are usually used to represent a particular identity, rather than being used to sign other certificates. +On the Internet leaf certificates usually identify a particular domain, such as `example.com`. + +Leaf certificates are sent first in a chain of certificates and represent the end of that chain. They must be sent +along with any intermediates required to create a chain which can be validated by verifying signatures up to a trusted +root certificate. diff --git a/content/v1.15-docs/releases/README.md b/content/v1.15-docs/releases/README.md new file mode 100644 index 0000000000..e8694fa0f7 --- /dev/null +++ b/content/v1.15-docs/releases/README.md @@ -0,0 +1,342 @@ +--- +title: Supported Releases +description: Supported releases, Kubernetes versions, OpenShift versions and upcoming release timeline +--- + +{/* +Inspired by https://istio.io/latest/about/supported-releases/ +*/} + +This page lists the status, timeline and policy for currently supported releases of cert-manager. + +All cert-manager releases are supported at least until the release of a second subsequent version. +That means there are always at least two supported versions of cert-manager at any given time, +and possibly more if there's also a current Long Term Support version. + +We aim to do regular releases roughly every 4 months but release dates can vary when accounting for holidays, +conferences (such as KubeCon), maintainer commitments and other world events. + +You don't have to wait until the next minor release to start using new features; we also aim to +create regular alpha releases which - while not as thoroughly tested or stable as other releases - +should be stable enough to run. + + +## Currently supported releases + +| Release | Release Date | End of Life | [Supported Kubernetes / OpenShift Versions][s] | [Tested Kubernetes Versions][test] | +|:------------:|:------------:|:----------------------:|:----------------------------------------------:|:----------------------------------:| +| [1.15][] | Jun 05, 2024 | Release of 1.17 | 1.25 → 1.31 / 4.12 → 4.16 | 1.25 → 1.31 | +| [1.14][] | Feb 03, 2024 | Release of 1.16 | 1.24 → 1.31 / 4.11 → 4.16 | 1.24 → 1.29 | +| [1.12 LTS][] | May 19, 2023 | May 19, 2025 | 1.22 → 1.31 / 4.9 → 4.16 | 1.22 → 1.29 | + +cert-manager 1.12 is a Long Term Support (LTS) release sponsored by [Venafi](https://www.venafi.com/). It will continue to be supported for at least 2 years from release. + +## Upcoming releases + +| Release | Release Date | End of Life | [Supported Kubernetes / OpenShift Versions][s] | +|:--------:|:------------:|:----------------:|:----------------------------------------------:| +| [1.16][] | Oct 03, 2024 | Release of 1.18 | 1.27 → 1.31 / 4.14 → 4.16 | + +Dates in the future are not firm commitments and are subject to change. + +We list cert-manager releases on [GitHub](https://github.com/cert-manager/cert-manager/releases), +and release notes on [cert-manager.io](https://cert-manager.io/docs/release-notes/). + +We also maintain detailed [upgrade instructions](https://cert-manager.io/docs/releases/upgrading/). + +## Support policy + + +### Supported vs Tested Versions of Kubernetes + +In general, we aim to run regular end-to-end tests of all Kubernetes versions which we list as supported. + +For various reasons, this isn't always possible; a big factor is which Kubernetes versions are supported +by [Kind](https://github.com/kubernetes-sigs/kind), which is used in our end-to-end tests. + +If a Kubernetes version is listed as "tested", you can be sure that we run end-to-end tests of cert-manager +on that version regularly and we'd fix any issues that we saw in those end-to-end tests. + +If a Kubernetes version is not listed as "tested" but is listed as "supported", we don't run tests regularly for that +Kubernetes release, but we _will_ still respond to and fix any bug reports for that version. + +For example, cert-manager 1.12 LTS might list supported versions of Kubernetes as 1.22 → 1.31 but only test 1.22 → 1.29. +That means that: + +- We will fix community-reported issues for cert-manager 1.12 on Kubernetes 1.30 or 1.31 +- We will not run automated tests for cert-manager 1.12 on Kubernetes 1.30 or 1.31 +- We will not generally test or fix issues for cert-manager 1.12 on Kubernetes 1.21 or earlier + +### What we mean by support + +Our support window is four months for each release branch. In the below +diagram, `release-1.2` is an example of a release branch. + +We offer two types of support: + +- [Technical support](#technical-support), +- [Security and bug fixes](#bug-fixes-support). + +For example, imagining that the latest release is `v1.2.0`, you can expect +support for both `v1.2.0` and `v1.1.0`. + +Only the last patch release of each branch is supported. + +```diagram + v1.0.0 ^ + Sep 2, 2020 | UNSUPPORTED +------+---------------------------------------------> release-1.0 | RELEASES + \ v + \ + \ v1.1.0 + \ Nov 24, 2020 ^ + ---------+-------------------------------> release-1.1 | + \ | SUPPORTED + \ | RELEASES + \ v1.2.0 | = the two + \ Feb 10, 2021 | last + ------------+--------------> release-1.2 | releases + \ v + \ + \ + \ + -----------> master branch + April 1, 2021 +``` + + +### Technical support + +Technical assistance is offered on a best-effort basis for supported +releases only. You can request support from the community on [Kubernetes +Slack](https://slack.k8s.io/) (in the `#cert-manager` channel), using +[GitHub Discussions][discussions] or using the [cert-manager-dev][group] +Google group. + +[discussions]: https://github.com/cert-manager/cert-manager/discussions +[group]: https://groups.google.com/g/cert-manager-dev + + +### Security and bug fixes + +We back-port important bug fixes — including security fixes — to all +currently supported releases. + +- [Security issues](#security-issues), +- [Critical bugs](#critical-bugs), +- [Long-standing bugs](#long-standing-bugs). + + +#### Security issues + +**Security issues** are fixed as soon as possible. They get back-ported to +the last two releases, and a new patch release is immediately created for them. + + +#### Critical bugs + +**Critical bugs** include both regression bugs as well as upgrade bugs. + +Regressions are functionalities that worked in a previous release but no longer +work. [#4142][], [#3393][] and [#2857][] are three examples of regressions. + +Upgrade bugs are issues (often Helm-related) preventing users from +upgrading to currently supported releases from earlier releases of +cert-manager. [#3882][] and [#3644][] are examples of upgrade bugs. + +Note that [intentional breaking changes](#breaking-changes) do not belong to +this category. + +Fixes for critical bugs are (usually) immediately back-ported by creating a new +patch release for the currently supported releases. + + +#### Long-standing bugs + +**Long-standing bug**: sometimes a bug exists for a long time, and may have +known workarounds. [#3444][] is an example of a long-standing bug. + +Where we feel that back-porting would be difficult or might be a stability +risk to clusters running cert-manager, we'll make the fix in a major +release but avoid back-porting the fix. + + +#### Breaking changes + +Breaking changes are changes that intentionally break the cert-manager +Kubernetes API or the command line flags. We avoid making breaking changes +where possible, and where they're required we'll give as much notice as +possible. + + +#### Other back-ports + +We aim to be conservative in what we back-port. That applies especially for anything which +could be a _runtime_ change - that is, a change which might alter behavior for someone +upgrading between patch releases. + +That means that if a candidate for back-porting has a chance of having a runtime impact we're +unlikely to accept the change unless it addresses a security issue or a critical bug. + +We reserve the right to back-port other changes which are unlikely to have a runtime impact, such as +documentation or tooling changes. An example would be [#5209][] which updated how we perform a release of +cert-manager but didn't have any realistic chance of having a runtime impact. + +Generally we'll seek to be pragmatic. A rule of thumb might be to ask: + +"Does this back-port improve cert-manager, bearing in mind that we really value stability for already-released versions?" + +[#3393]: https://github.com/cert-manager/cert-manager/issues/3393 "Broken CloudFlare DNS01 challenge" +[#2857]: https://github.com/cert-manager/cert-manager/issues/2857 "CloudDNS DNS01 challenge crashes cert-manager" +[#4142]: https://github.com/cert-manager/cert-manager/issues/4142 "Cannot issue a certificate that has the same subject and issuer" +[#3444]: https://github.com/cert-manager/cert-manager/issues/3444 "Certificates do not get immediately updated after updating them" +[#3882]: https://github.com/cert-manager/cert-manager/pull/3882 "Certificate's revision history limit validated by webhook" +[#3644]: https://github.com/cert-manager/cert-manager/issues/3644 "Helm upgrade from v1.2 to v1.2 impossible due to a Helm bug" +[#5209]: https://github.com/cert-manager/cert-manager/pull/5209 "release-1.8: rclone" + + + +## How we determine supported Kubernetes versions + +The list of supported Kubernetes versions displayed in the [Supported Releases](#supported-releases) section +depends on what the cert-manager maintainers think is reasonable to support and to test. + +In practice, this is largely determined based on what versions of [kind](https://github.com/kubernetes-sigs/kind) +are available for testing, and which versions of Kubernetes are provided by major upstream cloud Kubernetes vendors +including EKS, GKE, AKS and OpenShift. + +We treat OpenShift EUS as a different distribution since the support periods are so much longer. +We're likely to drop support for older OpenShift EUS before that release reaches EOL to increase the speed at which we can adopt +newer Kubernetes features. + +The table below lists the major Kubernetes distributions we check. In parentheses next to each release is the EOL +for that release. EOL dates often change throughout the lifecycle of a release. + +The "Oldest Kubernetes Release" is the oldest release we deemed relevant to the next cert-manager release, as of 2024-09-25 + +| Vendor | Oldest K8s Release | Other Kubernetes Releases | +|:---------------------:|:---------------------:|----------------------------------------------------------------------| +| [EKS][eks] | 1.28 (Nov 2024) | 1.29 (Mar 2025), 1.30 (Jul 2025) | +| [GKE][gke] | 1.28 (Feb 2025) | 1.29 (Mar 2025), 1.30 (Sep 2025) | +| [AKS][aks] | 1.28 (Jan 2025) | 1.29 (Mar 2025), 1.30 (Jul 2025), 1.31 (Nov 2025) | +| [OpenShift 4][os] | 1.26 (4.13, Nov 2024) | 1.27 (4.14, May 2025), 1.28 (4.15, Aug 2025), 1.29 (4.16, Dec 2025) | +| [OpenShift 4 EUS][os] | 1.25 (4.12, Jan 2025) | 1.27 (4.14, Oct 2025), 1.29 (4.16, Jun 2026) | + +[eks]: https://endoflife.date/amazon-eks +[gke]: https://endoflife.date/google-kubernetes-engine +[aks]: https://learn.microsoft.com/en-us/azure/aks/supported-kubernetes-versions?tabs=azure-cli#aks-kubernetes-release-calendar +[os]: https://endoflife.date/red-hat-openshift + +### OpenShift + +cert-manager supports OpenShift 4 based on the version of Kubernetes +that each release maps to. + +For convenience, the following table shows these version mappings: + +| OpenShift versions | Kubernetes version | +|:------------------:|--------------------| +| 4.16, 4.16 EUS | 1.29 | +| 4.15 | 1.28 | +| 4.14, 4.14 EUS | 1.27 | +| 4.13 | 1.26 | +| 4.12, 4.12 EUS | 1.25 | +| 4.11 | 1.24 | +| 4.10, 4.10 EUS | 1.23 | +| 4.9 | 1.22 | + +Note that some OpenShift versions listed above may be predicted, since an updated version of OpenShift may +not yet be available for the latest Kubernetes releases. + +The last version of cert-manager to support OpenShift 3 was cert-manager 1.2, which is +no longer maintained. + +## Terminology + +The term "release" (or "minor release") refers to one minor version of +cert-manager. For example, 1.2 and 1.3 are two releases. Note that we do +not use the prefix `v` for releases (just "1.2"). This is because releases +are not used as git tags. + +Patch releases use the `v` prefix (e.g., `v1.2.0`, `v1.3.1`...) since one +patch release = one git tag. The initial patch release is called "final +release": + +| Type of release | Example of git tag | Corresponding release | Corresponding release branch\* | +| --------------- | ------------------ | --------------------- | ------------------------------ | +| Final release | `v1.3.0` | 1.3 | `release-1.3` | +| Patch release | `v1.3.1` | 1.3 | `release-1.3` | +| Pre-release | `v1.4.0-alpha.0` | N/A\*\* | `release-1.4` | + +\*For maintainers: each release has an associated long-lived branch that we +call the “release branch”. For example, `release-1.2` is the release branch +for release 1.2. + +\*\*Pre-releases (e.g., `v1.3.0-alpha.0`) don't have a corresponding +release (e.g., 1.3) since a release only exists after a final release +(e.g., `v1.3.0`) has been created. + +Our naming scheme mostly follows [Semantic Versioning +2.0.0](https://semver.org/) with `v` prepended to git tags and docker +images: + +```plain +v.. +``` + +where `` is increased for each release, and `` counts the +number of patches for the current `` release. A patch is usually a +small change relative to the `` release. + +## Old cert-manager releases + +These cert-manager releases have reached their EOL date and +are no longer supported. + +| Release | Release Date | EOL | Compatible Kubernetes versions | Compatible OpenShift versions | +|----------|:------------:|:------------:|:------------------------------:|:-----------------------------:| +| [1.13][] | Sep 12, 2023 | Jun 05, 2024 | 1.21 → 1.27 | 4.8 → 4.14 | +| [1.11][] | Jan 11, 2023 | Sep 12, 2023 | 1.21 → 1.27 | 4.8 → 4.14 | +| [1.10][] | Oct 17, 2022 | May 19, 2023 | 1.20 → 1.26 | 4.7 → 4.13 | +| [1.9][] | Jul 22, 2022 | Jan 11, 2023 | 1.20 → 1.24 | 4.7 → 4.11 | +| [1.8][] | Apr 05, 2022 | Oct 17, 2022 | 1.19 → 1.24 | 4.6 → 4.11 | +| [1.7][] | Jan 26, 2021 | Jul 22, 2022 | 1.18 → 1.23 | 4.5 → 4.9 | +| [1.6][] | Oct 26, 2021 | Apr 05, 2022 | 1.17 → 1.22 | 4.4 → 4.9 | +| [1.5][] | Aug 11, 2021 | Jan 26, 2022 | 1.16 → 1.22 | 4.3 → 4.8 | +| [1.4][] | Jun 15, 2021 | Oct 26, 2021 | 1.16 → 1.21 | 4.3 → 4.7 | +| [1.3][] | Apr 08, 2021 | Aug 11, 2021 | 1.16 → 1.21 | 4.3 → 4.7 | +| [1.2][] | Feb 10, 2021 | Jun 15, 2021 | 1.16 → 1.21 | 4.3 → 4.7 | +| [1.1][] | Nov 24, 2020 | Apr 08, 2021 | 1.11 → 1.21 | 3.11 → 4.7 | +| [1.0][] | Sep 02, 2020 | Feb 10, 2021 | 1.11 → 1.21 | 3.11 → 4.7 | +| [0.16][] | Jul 23, 2020 | Nov 24, 2020 | 1.11 → 1.21 | 3.11 → 4.7 | +| [0.15][] | May 06, 2020 | Sep 02, 2020 | 1.11 → 1.21 | 3.11 → 4.7 | +| [0.14][] | Mar 11, 2020 | Jul 23, 2020 | 1.11 → 1.21 | 3.11 → 4.7 | +| [0.13][] | Jan 21, 2020 | May 06, 2020 | 1.11 → 1.21 | 3.11 → 4.7 | +| [0.12][] | Nov 27, 2019 | Mar 11, 2020 | 1.11 → 1.21 | 3.11 → 4.7 | +| [0.11][] | Oct 10, 2019 | Jan 21, 2020 | 1.9 → 1.21 | 3.09 → 4.7 | + +[s]: #kubernetes-supported-versions +[test]: #supported-vs-tested +[1.16]: https://github.com/cert-manager/cert-manager/milestone/38 +[1.15]: ./release-notes/release-notes-1.15.md +[1.14]: ./release-notes/release-notes-1.14.md +[1.13]: ./release-notes/release-notes-1.13.md +[1.12 LTS]: ./release-notes/release-notes-1.12.md +[1.11]: ./release-notes/release-notes-1.11.md +[1.10]: ./release-notes/release-notes-1.10.md +[1.9]: ./release-notes/release-notes-1.9.md +[1.8]: ./release-notes/release-notes-1.8.md +[1.7]: ./release-notes/release-notes-1.7.md +[1.6]: ./release-notes/release-notes-1.6.md +[1.5]: ./release-notes/release-notes-1.5.md +[1.4]: ./release-notes/release-notes-1.4.md +[1.3]: ./release-notes/release-notes-1.3.md +[1.2]: ./release-notes/release-notes-1.2.md +[1.1]: ./release-notes/release-notes-1.1.md +[1.0]: ./release-notes/release-notes-1.0.md +[0.16]: ./release-notes/release-notes-0.16.md +[0.15]: ./release-notes/release-notes-0.15.md +[0.14]: ./release-notes/release-notes-0.14.md +[0.13]: ./release-notes/release-notes-0.13.md +[0.12]: ./release-notes/release-notes-0.12.md +[0.11]: ./release-notes/release-notes-0.11.md diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.1.md b/content/v1.15-docs/releases/release-notes/release-notes-0.1.md new file mode 100644 index 0000000000..91c8a0d392 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.1.md @@ -0,0 +1,26 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.1' +--- + +This is the first release of cert-manager. It is currently still not in a production ready state, and features are subject to change. + +Notable features: + +- *Automated certificate renewal* +- *ACME DNS01 challenge mechanism* + - CloudDNS + - Route53 + - CloudFlare +- *ACME HTTP01 challenge mechanism* + - Should be compatible with all ingress controllers following ingress spec (GCE & NGINX tested) +- *Simple CA based issuance* + - Create an Issuer that references a Secret resource containing a signing key pair, and issue/renew certificates from that. +- *Cluster-wide issuers (aka `ClusterIssuer`)* +- *Backed by CRDs* + - Events logged to the Kubernetes API + - Status block utilized to store additional state about resources + +Please check the [README](https://github.com/cert-manager/cert-manager) for a quick-start guide. + +We really value any feedback and contributions to the project. If you'd like to get involved, please open some issues, comment or pick something up and get started! diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.10.md b/content/v1.15-docs/releases/release-notes/release-notes-0.10.md new file mode 100644 index 0000000000..10834c123c --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.10.md @@ -0,0 +1,143 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.10' +--- + +The `v0.10` release comes quick on the heels of `v0.9`. It continues the work on +the new `CertificateRequest` resource type, moving us towards a world where +out-of-tree Issuer types are first class citizens. + +As a project, we're pushing towards a 'stable' API release and eventually, a +`v1.0` release. This release, and the releases to follow over the coming months, +lay the foundation for these milestones. Keep an eye on the releases page over +the coming months for some exciting new developments! + +You can get started using the new `CertificateRequest` controllers by enabling +the `CertificateRequestControllers` feature gate - all Issuer types are now +supported, and your feedback is extremely valuable before we switch the new +implementation to be the default in `v0.11`! + +We've also simplified the way we bootstrap TLS certificates for the 'webhook' +component. Now, instead of creating an `Issuer` and `Certificate` resource for the +webhook (requiring you to disable validation on the cert-manager namespace), +we've implemented a dedicated `webhookbootstrap` controller which will manage +TLS assets for the webhook. + +--- + +This release includes changes from: + +* `Alejandro Garrido Mota` +* `Alpha` +* `Hans Kristian Flaatten` +* `James Munnelly` +* `Jonas-Taha El Sesiy` +* `JoshVanL` +* `Marcello Romani` +* `Moritz Johner` +* `Nicolas Kowenski` +* `Olaf Klischat` +* `Vasilis Remmas` +* `stuart.warren` +* `zeeZ` + +## Notable Items + +### All Issuer types now supported with `CertificateRequests` + +The `CertificateRequest` design proposal, first implemented in `v0.9`, changes the +way we request certificates from `Issuers` in order to allow out-of-tree Issuer +types. +This required us to refactor and adapt our existing in-tree `Issuer` types to +follow a similar pattern. + +The `v0.10` release finishes this refactoring so that all `Issuer` types now +support the new format. + +As the feature is currently still in an 'alpha' state, you must set the +`issuerRef.group` field on your Certificate resources to `certmanager.k8s.io`, +as well as enabling the `CertificateRequestControllers` feature gate on the +`controller` component of cert-manager. + +### Simplified webhook TLS bootstrapping + +In past releases, we've managed TLS for the webhook component by creating an +internal self signed and CA issuer that is used to mint serving certificates +for the apiserver to authenticate the webhook's identity. + +This introduced a number of complexities in our installation process and has +caused trouble for users in the past. + +In order to simplify this process and to support running a CRD conversion +webhook in future (to provide seamless migration between API versions), we've +introduced a dedicated `webhookbootstrap` controller that relies on flags and +Secret resources in order to configure TLS for the webhook. + +This will mean easier installation as well as future-proofing for our upcoming +plans in future releases. + +### `KeyUsages` on Certificate resources + +In order to support a more diverse set of applications, including apps that +require client-auth certificates, a new field `keyUsages` has been added which +accepts a list of usages that must be present on a Certificate. + +These will be automatically added when certificates are issued, just like any +other field on the Certificate. + +Thanks to Stuart Warren from Ocado for this change! + +### Preparation for `v1alpha2` and beyond + +Over the last few releases, we've been making a number of significant changes +to our API types (i.e. moving ACME configuration from Certificate resources +onto the Issuer resource). This has involved deprecating some old API fields. + +In a future release, we'll be removing these deprecated fields altogether, +requiring users to update their manifests to utilize the new way to specify +configuration. + +A number of steps have been taken in our own code base to support this change, +and in a future release, you'll be required to update **all** your manifests for +this new format. Future API revisions (e.g. `v1beta1` and `v1`) will be +automatically converted using a Kubernetes conversion webhook (available in +beta from Kubernetes 1.15 onward). + +## Action Required + +No special actions are required as part of this release. + +## Changelog + +### General + +- Add `DisableDeprecatedACMECertificates` feature gate to disable the old deprecated ACME configuration format ([#1923](https://github.com/cert-manager/cert-manager/pull/1923), [`@munnerz`](https://github.com/munnerz)) +- chart: fix formatting of values table in `README.md` ([#1936](https://github.com/cert-manager/cert-manager/pull/1936), [`@Starefossen`](https://github.com/Starefossen)) +- Add internal API version and implement machinery for defaulting & conversion ([#2002](https://github.com/cert-manager/cert-manager/pull/2002), [`@munnerz`](https://github.com/munnerz)) +- Fix concurrent map write panic in certificates controller ([#1980](https://github.com/cert-manager/cert-manager/pull/1980), [`@munnerz`](https://github.com/munnerz)) +- `cainjector`: allow injecting CAs directly from Secret resources ([#1990](https://github.com/cert-manager/cert-manager/pull/1990), [`@munnerz`](https://github.com/munnerz)) +- Mark `spec` and `status` as non-required fields in CRDs ([#1957](https://github.com/cert-manager/cert-manager/pull/1957), [`@munnerz`](https://github.com/munnerz)) +- Add ability to specify key usages and extended key usages in certificates ([#1996](https://github.com/cert-manager/cert-manager/pull/1996), [`@stuart-warren`](https://github.com/stuart-warren)) + +### ACME Issuer + +- Add option to assume role in Route53 DNS01 provider ([#1917](https://github.com/cert-manager/cert-manager/pull/1917), [`@moolen`](https://github.com/moolen)) +- Fix documentation for AzureDNS service principal creation ([#1960](https://github.com/cert-manager/cert-manager/pull/1960), [`@elsesiy`](https://github.com/elsesiy)) + +### Webhook + +- Use dedicated controller for webhook TLS bootstrapping ([#1993](https://github.com/cert-manager/cert-manager/pull/1993), [`@munnerz`](https://github.com/munnerz)) + +### `CertificateRequest` + +- Add ACME `CertificateRequest` controller implementation ([#1943](https://github.com/cert-manager/cert-manager/pull/1943), [`@JoshVanL`](https://github.com/JoshVanL)) +- Add Vault `CertificateRequest` controller implementation ([#1934](https://github.com/cert-manager/cert-manager/pull/1934), [`@JoshVanL`](https://github.com/JoshVanL)) +- Add `SelfSigned` `CertificateRequest` controller implementation ([#1906](https://github.com/cert-manager/cert-manager/pull/1906), [`@JoshVanL`](https://github.com/JoshVanL)) +- Add Venafi `CertificateRequest` controller implementation ([#1968](https://github.com/cert-manager/cert-manager/pull/1968), [`@JoshVanL`](https://github.com/JoshVanL)) +- Don't validate `issuerRef.kind` field if `issuerRef.group `is set in order to support out-of-tree Issuer types ([#1949](https://github.com/cert-manager/cert-manager/pull/1949), [`@munnerz`](https://github.com/munnerz)) +- Adds `CertificateRequest` `FailureTime`. The Certificate controller will re-try failed `CertificateRequests` at least one hour after this failed time. ([#1979](https://github.com/cert-manager/cert-manager/pull/1979), [`@JoshVanL`](https://github.com/JoshVanL)) + +### Monitoring + +- Added variable to specify custom namespace where to deploy `ServiceMonitor` resource ([#1970](https://github.com/cert-manager/cert-manager/pull/1970), [`@mogaal`](https://github.com/mogaal)) +- helm: fix labels and add Service for Prometheus `ServiceMonitor` ([#1942](https://github.com/cert-manager/cert-manager/pull/1942), [`@Starefossen`](https://github.com/Starefossen)) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.11.md b/content/v1.15-docs/releases/release-notes/release-notes-0.11.md new file mode 100644 index 0000000000..1ebfccce77 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.11.md @@ -0,0 +1,242 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.11' +--- + +The `v0.11` release is a significant milestone for the cert-manager project, and +is full of new features. +We are making a number of changes to our CRDs in a backwards incompatible way, +in preparation for moving into `v1beta1` and eventually `v1` in the coming +releases: + +* Renaming our API group from `certmanager.k8s.io` to `cert-manager.io` +* Bumping the API version from `v1alpha1` to `v1alpha2` +* Removing fields deprecated in `v0.8` (`certificate.spec.acme`, + `issuer.spec.http01` and `issuer.spec.dns01`) +* Renaming annotation prefixes on Ingress & cert-manager resources to use the + new `cert-manager.io` prefix, and in some cases `acme.cert-manager.io` +* Using the `status` subresource for submitting status updates to the API, + first introduced in Kubernetes 1.9. +* Tightening use of common name vs DNS name with ACME certificates + +We have also switched to using the new [`CertificateRequest`] based Certificate +issuance implementation, first introduced in alpha in cert-manager `v0.9`. + +These changes enable exciting new integrations points in cert-manager, enabling +new things like: + +* External issuer types, such as the [Smallstep Step Issuer] +* Deeper integrations into Kubernetes, with an experimental [CSI driver] that + can be used to automatically mount signed certificates into pods +* Experimental integration with Istio, allowing you to utilize any of + cert-manager's configured issuer types/CAs with the [node agent] +* Retrieving certificates without giving cert-manager access to your private + keys + +This is a really exciting time for cert-manager, as these changes have been +made possible by refining our past decisions around API types, and they will +enable us to push ahead with many new features in the project. + +## Important information + +With all of these great changes, there is also work to do. + +The changes to our CRD resources mean that upgrading requires more manual +intervention than in previous releases. + +It's recommended that you backup and completely [uninstall +cert-manager](https://cert-manager.io/docs/installation/uninstall/) +before re-installing the `v0.11` release. + +You will also need to manually update all your backed up cert-manager resource +types to use the new `apiVersion` setting. + +A table of resources and their old and new `apiVersion`s: + +| Kind | Old `apiVersion` | New `apiVersion` | +|------------------------|-------------------------------|---------------------------------| +| `Certificate` | `certmanager.k8s.io/v1alpha1` | `cert-manager.io/v1alpha2` | +| `Issuer` | `certmanager.k8s.io/v1alpha1` | `cert-manager.io/v1alpha2` | +| `ClusterIssuer` | `certmanager.k8s.io/v1alpha1` | `cert-manager.io/v1alpha2` | +| `CertificateRequest` | `certmanager.k8s.io/v1alpha1` | `cert-manager.io/v1alpha2` | +| `Order` | `certmanager.k8s.io/v1alpha1` | `acme.cert-manager.io/v1alpha2` | +| `Challenge` | `certmanager.k8s.io/v1alpha1` | `acme.cert-manager.io/v1alpha2` | + +You must also make sure to update all references to cert-manager in annotations to their +new prefix: + +| Annotation | Affected resources | New annotation | +|------------------------------------------------|------------------------------|-----------------------------------------------| +| `certmanager.k8s.io/acme-http01-edit-in-place` | `Ingress` | `acme.cert-manager.io/http01-edit-in-place` | +| `certmanager.k8s.io/acme-http01-ingress-class` | `Ingress` | `acme.cert-manager.io/http01-ingress-class` | +| `certmanager.k8s.io/issuer` | `Ingress` | `cert-manager.io/issuer` | +| `certmanager.k8s.io/cluster-issuer` | `Ingress` | `cert-manager.io/cluster-issuer` | +| `certmanager.k8s.io/acme-challenge-type` | `Ingress` | **REMOVED** | +| `certmanager.k8s.io/acme-dns01-provider` | `Ingress` | **REMOVED** | +| `certmanager.k8s.io/alt-names` | `Ingress, Secret` | `cert-manager.io/alt-names` | +| `certmanager.k8s.io/ip-sans` | `Ingress, Secret` | `cert-manager.io/ip-sans` | +| `certmanager.k8s.io/common-name` | `Ingress, Secret` | `cert-manager.io/common-name` | +| `certmanager.k8s.io/issuer-name` | `Ingress, Secret` | `cert-manager.io/issuer-name` | +| | `Ingress, Secret` | `cert-manager.io/issuer-kind` | +| | `Ingress, Secret` | `cert-manager.io/issuer-group` | +| | `Ingress, Secret` | `cert-manager.io/uri-sans` | +| | `Certificate` | `cert-manager.io/issue-temporary-certificate` | +| | `CertificateRequest` | `cert-manager.io/private-key-secret-name` | +| `certmanager.k8s.io/certificate-name` | `CertificateRequest, Secret` | `cert-manager.io/certificate-name` | + + +## Contributors + +This release has seen code contributions from a number of people in the +community: + +* `Adam Kunicki` +* `Alpha` +* `Brian Hong` +* `Dan Farrell` +* `Dig-Doug` +* `Galo Navarro` +* `Ingo Gottwald` +* `James Munnelly` +* `JoshVanL` +* `Kevin Lefevre` +* `Lachlan Cooper` +* `Michel Blankleder` +* `Toni Menzel` +* `Wellington F Silva` +* `Woz` +* `dulltz` + +As always, a big thank you to those opening issues, replying to issues and +helping out in the Slack channel. As well as working in other projects to help +users secure services running on Kubernetes. + +## Notable changes + +### Renamed API group + +Due to new policies in the upstream Kubernetes project, we have renamed the +API group from `certmanager.k8s.io` to `cert-manager.io`. + +This is a breaking change to our API surface as mentioned above, but it +is a long time coming. The original `k8s.io` suffix was used when the project +first started as there was not official guidance or information on how +`ThirdPartyResources` should be structured. Now that this area of the +Kubernetes project has evolved further, we're retrospectively changing this to +conform with the new requirements. + +### Moving to `v1alpha2` + +When cert-manager first started, we defined our APIs based on what we thought +made sense for end-users. + +Over time, through gathering feedback and monitoring the way users are actually +using cert-manager, we've identified some issues with our original API design. + +As part of the project moving towards `v1`, we've identified certain areas of our +APIs that are not fit for purpose. + +In order to begin the process of moving towards `v1`, we first deprecated a +number of fields in our `v1alpha1` API. We've now **dropped** these API fields +in `v1alpha2`, in preparation for declaring this new API as `v1beta1` in the +coming releases. + +### New `CertificateRequest` resource type + +The activation of `CertificateRequest` controllers are no longer behind a +feature and are now instead enabled by default. This means that when requesting +certificates using the `Certificate` resource the `CertificateRequest` resource +will be used as the default and only way to honor the request. The addition of +this resource introduces the ability for much greater extension points to +cert-manager, notably out-of-tree issuers, Istio integrations, and experimental +tooling such as a CSI driver. You can read more about the motivation and design +of this resource in the [enhancement +document](https://github.com/cert-manager/cert-manager/blob/master/design/20190708.certificate-request-crd.md). + +This change should cause no disruption to how end users interact with +cert-manager, with the exception of debugging now requiring this resource to be +inspected also. + +### Support for out-of-tree issuer types + +With the graduation of the `CertificateRequest` resource, cert-manager now +supports out-of-tree issuers by default and treats them the same as any other +core issuer. This process is facilitated by the addition of the `group` field on +issuer references inside your `Certificate` and `CertificateRequest` resources. + +If you're interested in implementing your own out-of-tree issuer, or if there +is a provider you would like see implemented, feel free to reach out either +through a [GitHub +issue](https://github.com/cert-manager/cert-manager/issues/new?template=feature-request.md) +or send us a message in the #cert-manager channel on [Kubernetes +Slack](http://slack.kubernetes.io/)! + +### New fields on Certificate resources + +This release includes a new field `URISANs` on the `Certificate` resource. With +this, you can specify unique resource identifier URLs as subject alternative +names on your certificates. This addition unblocks development for an Istio +integration where mTLS can be configured using cert-manager as the backend and +in turn opens up all cert-manager issuer types as valid certificate providers in +your Istio PKI. + +### Improved ACME Order controller design + +Some users may have noticed issues with the 'Order' resource not automatically +detecting changes to their configure 'solvers' on their Issuer resources. + +In `v0.11`, we've rewritten the ACME Order handling code to: + +1) better handle updates to Issuers during an Order +2) improve ACME API usage - we now cache more information about the ACME Order + process in the Kubernetes API, which allows us to act more reliably and + without causing excessive requests to the ACME server. + +### No longer generating 'temporary certificates' by default + +Previously, we have issued a temporary certificate when a `Certificate` resource +targeting an ACME issuer has been created. This would later be overridden once +the real signed certificate has been issued. The reason for this behavior was +to facilitate compatibility with `ingress-gce` however, many users have had trouble +with this in the past and has led to lots of confusion - namely where +applications would need restarting to take on the signed certificate rather than +the temporary. + +In this release, no temporary certificates will be created unless explicitly +requested. This can be done using the annotation +`"cert-manager.io/issue-temporary-certificate": "true` on `Certifcate` +resources. + +We've additionally changed the behavior of ingress-shim to now add this new +annotation to `Certificate` resources if +`"acme.cert-manager.io/http01-edit-in-place"` is present on the Ingress +resource. + +## Changelog + +## Action Required + +- Rename `certmanager.k8s.io` API group to `cert-manager.io` ([#2096](https://github.com/cert-manager/cert-manager/pull/2096), [`@munnerz`](https://github.com/munnerz)) +- Move Order and Challenge resources to the `acme.cert-manager.io` API group ([#2093](https://github.com/cert-manager/cert-manager/pull/2093), [`@munnerz`](https://github.com/munnerz)) +- Move `v1alpha1` API to `v1alpha2` ([#2087](https://github.com/cert-manager/cert-manager/pull/2087), [`@munnerz`](https://github.com/munnerz)) +- Allow controlling whether temporary certificates are issued using a new annotation `certmanager.k8s.io/issue-temporary-certificate` + on Certificate resources. Previously, when an ACME certificate was requested, a temporary certificate would be issued in order + to improve compatibility with `ingress-gce`. ingress-shim has been updated to automatically set this annotation on managed Certificate + resources when using the 'edit-in-place' annotation, but users that have manually created their Certificate resources will need to + manually add the new annotation to their Certificate resources. ([#2089](https://github.com/cert-manager/cert-manager/pull/2089), [`@munnerz`](https://github.com/munnerz)) + +## Other Notable Changes + +- Change the default leader election namespace to `kube-system` instead of the same namespace as the cert-manager pod, to avoid multiple copies of cert-manager accidentally being run at once ([#2155](https://github.com/cert-manager/cert-manager/pull/2155), [`@munnerz`](https://github.com/munnerz)) +- Adds `URISANs` field to `Certificate.Spec` resource. ([#2085](https://github.com/cert-manager/cert-manager/pull/2085), [`@JoshVanL`](https://github.com/JoshVanL)) +- Move status to a CRD Subresource ([#2097](https://github.com/cert-manager/cert-manager/pull/2097), [`@JoshVanL`](https://github.com/JoshVanL)) +- Enables supporting out of tree issuers with ingress annotations ([#2105](https://github.com/cert-manager/cert-manager/pull/2105), [`@JoshVanL`](https://github.com/JoshVanL)) +- Bump Kubernetes dependencies to 1.16.0 ([#2095](https://github.com/cert-manager/cert-manager/pull/2095), [`@munnerz`](https://github.com/munnerz)) +- Adds Certificate conformance suite ([#2034](https://github.com/cert-manager/cert-manager/pull/2034), [`@JoshVanL`](https://github.com/JoshVanL)) +- Build using Go 1.13.1 ([#2114](https://github.com/cert-manager/cert-manager/pull/2114), [`@munnerz`](https://github.com/munnerz)) +- Adds Kubernetes authentication type for Vault Issue ([#2040](https://github.com/cert-manager/cert-manager/pull/2040), [`@JoshVanL`](https://github.com/JoshVanL)) +- Service account annotation support in Helm chart ([#2086](https://github.com/cert-manager/cert-manager/pull/2086), [`@serialx`](https://github.com/serialx)) +- Update AWS Go SDK to 1.24.1 to support IAM Roles for Service Accounts ([#2083](https://github.com/cert-manager/cert-manager/pull/2083), [`@serialx`](https://github.com/serialx)) +- Remove deprecated API fields and functionality ([#2082](https://github.com/cert-manager/cert-manager/pull/2082), [`@munnerz`](https://github.com/munnerz)) +- Update `hack/ci/run-dev-kind.sh` script to use the right path of cert-manager charts. ([#2074](https://github.com/cert-manager/cert-manager/pull/2074), [`@srvaroa`](https://github.com/srvaroa)) +- Simplify, improve and rewrite the `acmeorders` controller ([#2041](https://github.com/cert-manager/cert-manager/pull/2041), [`@munnerz`](https://github.com/munnerz)) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.12.md b/content/v1.15-docs/releases/release-notes/release-notes-0.12.md new file mode 100644 index 0000000000..7180e8330d --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.12.md @@ -0,0 +1,183 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.12' +--- + +The `v0.12.0` release is finally ready! After a KubeCon-induced delay, this +version focuses on usability, user experience, bug-fixes and documentation. + +A big notable feature in this release is the new [`cert-manager.io`](https://cert-manager.io) +website - this has been a long time coming, but we hope that the information +on this site should more clearly walk new and experienced users alike through +the tool, and with it the rewrite into Markdown (with [Hugo](https://gohugo.io)) +should make external contributions easier! + +The rest of the notable features below are all focused on usability, and as +such, the upgrade process from `v0.11` should be nice and easy :holiday:. + +We'll be doing an in-depth walk-through of this release and what's planned for +for the next release during the next community call on Wednesday 4th December! +For more details on joining and getting involved, see the +[community section](https://github.com/cert-manager/cert-manager#community). + +## Contributors + +This release has seen code contributions from a number of people in the +community: + +* `Adrian Mouat` +* `Benjamin P. Jung` +* `Bouke van der Bijl` +* `Christian Groschupp` +* `Christophe Courtaut` +* `Eric Bailey` +* `Harold Drost` +* `Ingo Gottwald` +* `James Munnelly` +* `JayatiGoyal` +* `Joshua Van Leeuwen` +* `Krishna Durai` +* `Luca Berneking` +* `Matevz Mihalic` +* `Max Goltzsche` +* `Nick Parker` +* `Nils Cant` +* `Nolan Reisbeck` +* `Pierre Dorbais` +* `Sam Cogan` +* `Thomas` +* `chenjun.cj` +* `ismail BASKIN` +* `walter.goulet` + +As always, a big thank you to those opening issues, replying to issues and +helping out in the Slack channel. As well as working in other projects to help +users secure services running on Kubernetes. + +## Notable changes + +### New website + +We have launched a new website to better showcase cert-manager, which can be +found at [`cert-manager.io`](https://cert-manager.io). + +With this new site, we have also significantly restructured and rewritten the +documentation for the site in order to flow better, and hopefully inform users +more on the inner-workings of cert-manager whilst still making on-boarding to +the project easy. + +Whilst this is the first launch of the new website, there is still lots to do! +If you have any feedback, ideas or expertise to improve the site, please open +an issue or make a contribution over in the new +[cert-manager/website](https://github.com/cert-manager/website) repository. + +### Multi-architecture images + +If you run a non-homogeneous or alt-architecture cluster (i.e. `arm` or `arm64`) +then you may have run into issues when deploying cert-manager. + +For almost a year now, we have published Docker images built for these +architectures, but due to limitations in `quay.io`, using these images has +required changing deployment manifests and passing additional flags to +different cert-manager components. + +As of `v0.12`, we make use of [`Docker Image Manifests v2.2`](https://docs.docker.com/registry/spec/manifest-v2-2/), +which means that you will no longer have to make *any changes* to the +deployment manifests in order to deploy cert-manager into your cluster! + +This is a big usability win for users of non-`amd64` systems, and a big +1 +for usability! + +### Making it easier to debug failing ACME challenges + +During the ACME authorization flow, a number of issues can arise such as +misconfigured DNS records or ingress controllers. + +This release makes it simpler to identify these issues when they occur, +providing additional debugging information through the user of +`kubectl describe challenge `. + +Whilst this is a small addition, it vastly improves the user experience for +first time users who may have configuration issues with their DNS records or +cert-manager installation, another win for usability! + +### Simplifying the webhook component + +For those of you upgrading from older versions of cert-manager, you may already +be aware of some of the deployment issues with the 'webhook' component in +cert-manager. + +In previous releases, this component relied on the creation of an `APIService` +resource in order for the Kubernetes apiserver to utilize the webhook and +provide additional validation for our `CustomResourceDefinition` types. + +An `APIService` is a powerful resource, however, due to its nature, can cause +certain core operations (such as garbage collection) to not function if the +webhook becomes unavailable at any point, which can in turn cause cascading +failures in your Kubernetes cluster in the worst of cases. + +In `v0.12`, we have rewritten this component almost entirely, and we no longer +make use of the `APIService` resource in order to expose it. + +This should mean deploying the webhook is far easier, and far less likely to +cause cluster-wide issues. + +We have also extended the webhook to support 'API conversions' for our CRD +types. Whilst we don't currently make use of this functionality, when we +release the `v1beta1` we **will** make use of it, at which point the webhook +will be a required component in clusters running Kubernetes 1.15 or greater. + +## Changelog + +### Action Required + +- ACTION REQUIRED + Users who have previously set the Kubernetes Auth Mount Path will need to update their manifests to include the entire mount path. The `/login` endpoint is added for you. + + Changes the Vault Kubernetes Auth Path to require the entire mount path. `/login` is added to all mount paths when authenticating. + The default auth path has now changed from `kubernetes` to `/v1/auth/kubernetes` ([#2349](https://github.com/cert-manager/cert-manager/pull/2349), [`@JoshVanL`](https://github.com/JoshVanL)) + + +### Bug Fixes + +- Fixes issues with Pod Security Policies that prevented pods from running when Pod Security Policy is enabled in Kubernetes ([#2234](https://github.com/cert-manager/cert-manager/pull/2234), +[`@sam-cogan`](https://github.com/sam-cogan)) +- Fix issue causing certificates not to be issued when running with `OwnerReferencesPermissionEnforcement` admission controller enabled ([#2325](https://github.com/cert-manager/cert-manager/pull/2325), +[`@CoaxVex`](https://github.com/CoaxVex)) +- Fix bug causing SIGTERM and SIGINT signals to not be respected whilst the controller is performing leader election ([#2236](https://github.com/cert-manager/cert-manager/pull/2236), +[`@munnerz`](https://github.com/munnerz)) +- Fix setting `ownerReference` on Challenge resources created by Orders controller ([#2324](https://github.com/cert-manager/cert-manager/pull/2324), [`@CoaxVex`](https://github.com/CoaxVex)) +- Allow `CloudDNS` resolvers to be validated correctly without `serviceAccountSecretRef` to allow ambient permissions to be used. ([#2250](https://github.com/cert-manager/cert-manager/pull/2250), +[`@baelish`](https://github.com/baelish)) +- Add missing `apiVersion` to `Chart.yaml` ([#2270](https://github.com/cert-manager/cert-manager/pull/2270), [`@yurrriq`](https://github.com/yurrriq)) +- Perform API resource validation of the 'status' subresource on cert-manager resources ([#2283](https://github.com/cert-manager/cert-manager/pull/2283), [`@munnerz`](https://github.com/munnerz)) +- Fix outdated documentation for solver configuration in `Issuers` and `ClusterIssuers` ([#2210](https://github.com/cert-manager/cert-manager/pull/2210), [`@nickbp`](https://github.com/nickbp)) + + +### Other Notable Changes + +- Explicitly define `containerPort` protocol in helm chart ([#2405](https://github.com/cert-manager/cert-manager/pull/2405), [`@bouk`](https://github.com/bouk)) +- Allow permissive acceptance for matching Certificates with Secrets that are using legacy annotations to reduce non-required certificate reissue. +([#2400](https://github.com/cert-manager/cert-manager/pull/2400), [`@JoshVanL`](https://github.com/JoshVanL)) +- Add API token authentication option to CloudFlare issuer ([#2170](https://github.com/cert-manager/cert-manager/pull/2170), [`@matevzmihalic`](https://github.com/matevzmihalic)) +- Bump Kubernetes client library dependencies to 1.16.3 ([#2290](https://github.com/cert-manager/cert-manager/pull/2290), [`@munnerz`](https://github.com/munnerz)) +- Build using go 1.13.4 ([#2366](https://github.com/cert-manager/cert-manager/pull/2366), [`@munnerz`](https://github.com/munnerz)) +- Mark `certificaterequest.spec.csr` field as required in OpenAPI schema ([#2368](https://github.com/cert-manager/cert-manager/pull/2368), [`@munnerz`](https://github.com/munnerz)) +- Add `serverAuth` extended key usage to Certificates by default ([#2351](https://github.com/cert-manager/cert-manager/pull/2351), [`@JoshVanL`](https://github.com/JoshVanL)) +- Surface more information about ACME authorization failures on Challenge resources ([#2261](https://github.com/cert-manager/cert-manager/pull/2261), [`@munnerz`](https://github.com/munnerz)) +- Add documentation for the webhook ([#2252](https://github.com/cert-manager/cert-manager/pull/2252), [`@cgroschupp`](https://github.com/cgroschupp)) +- Add support for API resource conversion to the webhook. NOTE: this feature is **not** currently utilized by cert-manager ([#2001](https://github.com/cert-manager/cert-manager/pull/2001), +[`@munnerz`](https://github.com/munnerz)) +- Remove nested `cainjector` sub chart and include it in main chart ([#2285](https://github.com/cert-manager/cert-manager/pull/2285), [`@munnerz`](https://github.com/munnerz)) +- Change the default webhook listen address to 10250 for better compatibility with GKE private clusters ([#2278](https://github.com/cert-manager/cert-manager/pull/2278), +[`@munnerz`](https://github.com/munnerz)) +- Bump Helm & Tiller version used during end-to-end tests to 2.15.1 ([#2275](https://github.com/cert-manager/cert-manager/pull/2275), [`@munnerz`](https://github.com/munnerz)) +- Make `spec.csr`, `status.url`, `status.finalizeURL`, `status.certificate`, `status.authorizations`, `status.authorizations[].url`, `status.authorizations[].identifier`, +`status.authorizations[].wildcard`, `status.authorizations[].challenges`, `status.authorizations[].challenges[].url`, `status.authorizations[].challenges[].type`, +`status.authorizations[].challenges[].token` fields on Order resources immutable ([#2219](https://github.com/cert-manager/cert-manager/pull/2219), [`@munnerz`](https://github.com/munnerz)) +- No longer use architecture specific `acmesolver` images ([#2242](https://github.com/cert-manager/cert-manager/pull/2242), [`@munnerz`](https://github.com/munnerz)) +- enable cert-manager using `--kubeconfig` to connect API Server with `kubeconfig` file ([#2224](https://github.com/cert-manager/cert-manager/pull/2224), [`@answer1991`](https://github.com/answer1991)) +- Publish multi-architecture docker manifest lists ([#2230](https://github.com/cert-manager/cert-manager/pull/2230), [`@munnerz`](https://github.com/munnerz)) +- Make `order.status.authorizations[].wildcard` field a `*bool` ([#2225](https://github.com/cert-manager/cert-manager/pull/2225), [`@munnerz`](https://github.com/munnerz)) +- [Kubernetes APIServer dry-run](https://kubernetes.io/docs/reference/using-api/api-concepts/#dry-run) is supported. ([#2206](https://github.com/cert-manager/cert-manager/pull/2206), +[`@ismailbaskin`](https://github.com/ismailbaskin)) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.13.md b/content/v1.15-docs/releases/release-notes/release-notes-0.13.md new file mode 100644 index 0000000000..6eb7438a6e --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.13.md @@ -0,0 +1,62 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.13' +--- + +The `v0.13` contains a number of important bug-fixes and a few notable feature additions. It is a minor, incremental +update over `v0.12` and does not require any special upgrade steps. + +## ACME External Account Binding support + +Users that wish to use cert-manager with ACME servers other than Let's Encrypt may have found themselves unable to +register an account due to the lack of (EAB) 'External Account Binding' support. This allows an ACME server to validate +that a user is somehow associated with some other entity, like an account in the CAs customer management system. + +With EAB support, it's now possible to specify additional parameters (`spec.acme.externalAccountBinding`) on your ACME +Issuer resource and utilize cert-manager with your preferred ACME provider. + +## Support for full set of X.509 'subject' parameters + +In this release, support for the full range of 'subject' parameters as per the X.509 specification has been added. +This means you can set fields like `organizationalUnit`, `provinces`, `serialNumber`, `country`, and all other standard +X.509 subject fields. + +A big thanks to [`@mathianasj`](https://github.com/mathianasj) for this addition! + +## `InvalidRequest` status condition for `CertificateRequest` resources + +For the growing ecosystem of developers creating their own 'external issuer types' for cert-manager, we have added +support for a new 'status condition' type `InvalidRequest` - this can be used to signal from your signer/issuer to +cert-manager that the parameters that the user has requested on the X.509 CSR are 'invalid' and the CSR should **not** +be retried. + +This prevents users expending API quotas and making requests that will never succeed. + +### Bug Fixes + +- Fix invalid service account name used in RBAC resources when manually specifying a service account name ([#2509](https://github.com/cert-manager/cert-manager/pull/2509), [`@castlemilk`](https://github.com/castlemilk)) +- fixed a bug that in certain cases could cause HTTP01 ingress `serviceName` fields to be incorrectly set ([#2460](https://github.com/cert-manager/cert-manager/pull/2460), [`@greywolve`](https://github.com/greywolve)) +- Fix bug causing ever-increasing CPU usage in webhook component ([#2467](https://github.com/cert-manager/cert-manager/pull/2467), [`@munnerz`](https://github.com/munnerz)) +- Fix bug causing temporary certificates to overwrite previously issued certificates when adding a new `dnsName` to an existing Certificate resource ([#2469](https://github.com/cert-manager/cert-manager/pull/2469), [`@munnerz`](https://github.com/munnerz)) +- Fix `certmanager_certificate_expiration_timestamp_seconds` metric recording ([#2416](https://github.com/cert-manager/cert-manager/pull/2416), [`@munnerz`](https://github.com/munnerz)) +- Fixes `ClusterIssuers` not finding the secret when the secret is in a different namespace than the certificate request using the Venafi issuer type ([#2520](https://github.com/cert-manager/cert-manager/pull/2520), [`@mathianasj`](https://github.com/mathianasj)) +- Fixes generation if invalid certificate name the the 52nd character in a domain name is a symbol. ([#2516](https://github.com/cert-manager/cert-manager/pull/2516), [`@meyskens`](https://github.com/meyskens)) + + +### Other Notable Changes + +- Adds `InvalidRequest` condition type to `CertificateRequest`, signaling to not retry the request. ([#2508](https://github.com/cert-manager/cert-manager/pull/2508), [`@JoshVanL`](https://github.com/JoshVanL)) +- Add volume and volume mounts field to cert-manager helm chart ([#2504](https://github.com/cert-manager/cert-manager/pull/2504), [`@joshuastern`](https://github.com/joshuastern)) +- Add support for additional X.509 'subject' fields ([#2518](https://github.com/cert-manager/cert-manager/pull/2518), [`@mathianasj`](https://github.com/mathianasj)) +- Bump `k8s.io/*` dependencies to Kubernetes 1.17.0 ([#2452](https://github.com/cert-manager/cert-manager/pull/2452), [`@munnerz`](https://github.com/munnerz)) +- It is now possible to disable `AppArmor` when Pod Security Policies are used. ([#2489](https://github.com/cert-manager/cert-manager/pull/2489), [`@czunker`](https://github.com/czunker)) +- Support for arbitrary `securityContext` parameters ([#2455](https://github.com/cert-manager/cert-manager/pull/2455), [`@nefischer`](https://github.com/nefischer)) +- Remove misleading 'error decoding X.509 certificate' message ([#2470](https://github.com/cert-manager/cert-manager/pull/2470), [`@munnerz`](https://github.com/munnerz)) +- Remove IP address validation on `dns01-recursive-nameservers` to allow domain names ([#2428](https://github.com/cert-manager/cert-manager/pull/2428), [`@haines`](https://github.com/haines)) +- Optional `webhook.securityContext` and `cainjector.securityContext` chart parameters to specify pods security context. ([#2449](https://github.com/cert-manager/cert-manager/pull/2449), [`@nefischer`](https://github.com/nefischer)) +- webhook: register HTTP handlers for `pprof` debug endpoints ([#2450](https://github.com/cert-manager/cert-manager/pull/2450), [`@munnerz`](https://github.com/munnerz)) +- Adds support for chart configurable parameters `deploymentAnnotations`, `webhook.deploymentAnnotations` and `cainjector.deploymentAnnotations` ([#2447](https://github.com/cert-manager/cert-manager/pull/2447), [`@nefischer`](https://github.com/nefischer)) +- Adds ACME external account binding support ([#2392](https://github.com/cert-manager/cert-manager/pull/2392), [`@JoshVanL`](https://github.com/JoshVanL)) +- Fix false-y values in helm chart to mitigate [`kubernetes/kubernetes#66450`](https://github.com/kubernetes/kubernetes/issues/66450) ([#2383](https://github.com/cert-manager/cert-manager/pull/2383), [`@colek42`](https://github.com/colek42)) +- Explicitly define `containerPort` protocol in helm chart ([#2405](https://github.com/cert-manager/cert-manager/pull/2405), [`@bouk`](https://github.com/bouk)) +- Switch to using upstream `golang.org/x/crypto/acme` ACME client library ([#2422](https://github.com/cert-manager/cert-manager/pull/2422), [`@munnerz`](https://github.com/munnerz)) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.14.md b/content/v1.15-docs/releases/release-notes/release-notes-0.14.md new file mode 100644 index 0000000000..46f972d34b --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.14.md @@ -0,0 +1,128 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.14' +--- + +The `v0.14` release has a few focus areas: + +* Improving the deployment/installation process +* Improving the release process +* `CustomResourceDefinition` conversion +* Support for older Kubernetes and OpenShift versions +* Experimental 'bundle' output format for Certificates + +As usual, please read the [upgrade notes](../upgrading/upgrading-0.13-0.14.md) before upgrading. + +## Webhook changes + +**The webhook component is now required.** The webhook will be automatically enabled by the `v0.14` manifests, so no additional action is required. + +If you have issues running the webhook in your environment, we'd like to hear from you! We are aware of issues relating +to firewall rules from the Kubernetes API server to the webhook pod(s) - we would like to gather together a corpus of +configuration snippets that can be used to ensure the webhook is successfully deployed in these environments too. + +This change is required in order to support the upcoming changes to our API versions, as we introduce `v1alpha3`, +`v1beta1` and `v1` over the coming months! + +## Improving our deployment and release process + +After reports of various issues installing on older Kubernetes and OpenShift versions, we've taken some time to revise +our installation manifests. + +There are now two 'variants' to choose from, 'standard' and the 'legacy', with a simple way to know which to use: + +| Environment | Variant to use | +| -------------------- | -------------------------- | +| Kubernetes 1.15+ | `cert-manager.yaml` | +| OpenShift 4 | `cert-manager.yaml` | +| Kubernetes 1.11-1.14 | `cert-manager-legacy.yaml` | +| OpenShift 3.11 | `cert-manager-legacy.yaml` | + +Please be sure to read the upgrade guide for more information on how to upgrade from a previous release. + +## `CustomResourceDefinition` conversion webhook + `v1alpha3` API version + +As part of the effort to mature our API, we are releasing the `v1alpha3` API version. This contains a number of small +changes, notably moving some fields to the `subject` stanza on the Certificate resource to be more consistent with how +certain options are specified. + +With this we have enabled the 'conversion webhook', which enables API clients to utilize both the `v1alpha2` and +`v1alpha3` APIs simultaneously, similar to other core resources in Kubernetes. + +Thanks to this conversion webhook, this upgrade and future upgrades after it should be seamless. The ability to make +these kinds of changes to our API will enable the `v1beta1` API version to be released in a seamless manner in an +upcoming release too. + +More information on the webhook can be found in the [concepts section](../../concepts/webhook.md). + +## Support for Kubernetes 1.11 and OpenShift 3.11 + +We've had a number of users who are using OpenShift 3.11 & Kubernetes 1.11 reach out requesting support with +installation. In this release, we've expanded the range of Kubernetes versions we support to once again include 1.11, +as well as adding support for OpenShift 3.11. + +A big thanks to [`@meyskens`](https://github.com/meyskens) for putting this together! + +## Experimental 'bundle format' support (JKS and PKCS#12) + +One of our top feature requests has been for support for [JKS and PKCS#12](https://github.com/cert-manager/cert-manager/issues/586) +bundle files as an output from Certificate resources. + +In this release, we've added experimental support for both of these bundle formats. This can currently only be +configured globally with flags provided to the `cert-manager` pod (`--experimental-issue-jks` and +`--experimental-issue-pkcs12`). The password used for this bundle must _also_ be configured using the flags +`--experimental-jks-password` and `--experimental-pkcs12-keystore-password` respectively. + +In the next release, we are aiming to provide native support for these bundle format types as part of the Certificate +resource configuration. We have added these flags now in order to gather feedback on the way this feature works, and +help guide how this feature should work in future. + +## Extended support for Venafi features + +Users of the Venafi issuer often need to set custom metadata on their certificate requests in order to better associate +each request with different business areas, or in order to validate & authorize whether a request should be signed. + +In this release, we've added support for setting custom metadata by adding the `venafi.cert-manager.io/custom-fields` +annotation on `Certificate` and `CertificateRequest` resources. If using the Venafi TPP integration, version 19.2 or +greater is required. + +## Urgent Upgrade Notes + +### (No, really, you MUST read this before you upgrade) + +- Update Deployment selector to follow Helm chart best practices. This will require deleting the three cert-manager Deployment resources before upgrading. ([#2654](https://github.com/cert-manager/cert-manager/pull/2654), [`@munnerz`](https://github.com/munnerz)) + +## Changes by Kind + +### Feature + +- Add `--experimental-issue-jks` flag to enable JKS bundle generation in generated Secret resources. This flag will be replaced with native support for JKS bundles in future and is currently an experimental feature. If enabled, the `--experimental-jks-password` flag must also be set to the password used to encrypt JKS bundles. ([#2647](https://github.com/cert-manager/cert-manager/pull/2647), [`@munnerz`](https://github.com/munnerz)) +- Add `--experimental-issue-pkcs12` flag to enable PKCS12 bundle generation in generated Secret resources. This flag will be replaced with native support for PKCS12 bundles in future and is currently an experimental feature. If enabled, the `--experimental-pkcs12-keystore-password` flag must also be set to the password used to encrypt PKCS12 bundles. ([#2643](https://github.com/cert-manager/cert-manager/pull/2643), [`@munnerz`](https://github.com/munnerz)) +- Add `venafi.cert-manager.io/custom-fields` annotation for Venafi custom fields ([#2573](https://github.com/cert-manager/cert-manager/pull/2573), [`@meyskens`](https://github.com/meyskens)) +- Add `emailSANs` field to Certificate resource ([#2597](https://github.com/cert-manager/cert-manager/pull/2597), [`@meyskens`](https://github.com/meyskens)) +- Added `--tls-cipher-suites` command line flag to the webhook binary with sensible defaults ([#2562](https://github.com/cert-manager/cert-manager/pull/2562), [`@willthames`](https://github.com/willthames)) +- Build OpenShift 3.11 compatible CRDs ([#2609](https://github.com/cert-manager/cert-manager/pull/2609), [`@meyskens`](https://github.com/meyskens)) +- Enable CRD conversion webhook and begin serving `v1alpha3` ([#2563](https://github.com/cert-manager/cert-manager/pull/2563), [`@munnerz`](https://github.com/munnerz)) +- Improve startup time for webhook pod. ([#2574](https://github.com/cert-manager/cert-manager/pull/2574), [`@JoshVanL`](https://github.com/JoshVanL)) +- Replace `00-crds.yaml` file with a manifest file published as part of the release ([#2665](https://github.com/cert-manager/cert-manager/pull/2665), [`@munnerz`](https://github.com/munnerz)) + +### Other (Bug, Cleanup or Flake) + +- Bump `Venafi/vcert` dependency to support custom fields in Venafi TPP 19.2 ([#2663](https://github.com/cert-manager/cert-manager/pull/2663), [`@munnerz`](https://github.com/munnerz)) +- Fix `GroupVersionKind` set on `OwnerReference` of resources created by HTTP01 challenge solver, causing HTTP01 validations to fail on OpenShift 4 ([#2546](https://github.com/cert-manager/cert-manager/pull/2546), [`@munnerz`](https://github.com/munnerz)) +- Fix Venafi Cloud URL field being marked required ([#2568](https://github.com/cert-manager/cert-manager/pull/2568), [`@munnerz`](https://github.com/munnerz)) +- Fix bug in ingress-shim causing Certificate resources to be rapidly updated if multiple `spec.tls[].hosts` entries refer to the same Secret name but a different set of hosts ([#2611](https://github.com/cert-manager/cert-manager/pull/2611), [`@munnerz`](https://github.com/munnerz)) +- Fix bug that could cause certificates to be incorrectly issued with an invalid public key ([#2539](https://github.com/cert-manager/cert-manager/pull/2539), [`@munnerz`](https://github.com/munnerz)) +- Fix `cainjector.enabled=False` override being ignored by the Helm Chart ([#2544](https://github.com/cert-manager/cert-manager/pull/2544), [`@gtaylor`](https://github.com/gtaylor)) +- Include license header in manifests attached to GitHub releases ([#2684](https://github.com/cert-manager/cert-manager/pull/2684), [`@munnerz`](https://github.com/munnerz)) +- Make the webhook `RoleBinding` the leader election namespace instead of hard-coded `kube-system` ([#2621](https://github.com/cert-manager/cert-manager/pull/2621), [`@travisghansen`](https://github.com/travisghansen)) +- Replace `openshift` and `no-webhook` manifest variants with a "legacy" variant ([#2648](https://github.com/cert-manager/cert-manager/pull/2648), [`@meyskens`](https://github.com/meyskens)) +- Truncate message display if HTTP01 self check fails ([#2613](https://github.com/cert-manager/cert-manager/pull/2613), [`@munnerz`](https://github.com/munnerz)) +- Upgrade to Go 1.14 ([#2656](https://github.com/cert-manager/cert-manager/pull/2656), [`@munnerz`](https://github.com/munnerz)) + +## Other Changes + +- Add `//build/release-tars` targets for generating release artifacts ([#2556](https://github.com/cert-manager/cert-manager/pull/2556), [`@munnerz`](https://github.com/munnerz)) +- Improve local testing and development environment setup code ([#2534](https://github.com/cert-manager/cert-manager/pull/2534), [`@munnerz`](https://github.com/munnerz)) +- Remove `isOpenShift` from Helm chart ([#2642](https://github.com/cert-manager/cert-manager/pull/2642), [`@meyskens`](https://github.com/meyskens)) +- Remove `webhook.enabled` variable in Helm chart as the webhook now is a required component ([#2649](https://github.com/cert-manager/cert-manager/pull/2649), [`@meyskens`](https://github.com/meyskens)) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.15.md b/content/v1.15-docs/releases/release-notes/release-notes-0.15.md new file mode 100644 index 0000000000..47ca5264f9 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.15.md @@ -0,0 +1,133 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.15' +--- + +The `v0.15` release has a few focus areas: + +* Experimental new Certificate controller design +* New `installCRDs` option in the Helm chart +* Support for Red Hat's [Operator Lifecycle Manager](https://github.com/operator-framework/operator-lifecycle-manager) for easier deployment in OpenShift environments +* Improved deployment process for webhook component +* General Availability of JKS and PKCS#12 keystore support +* kubectl cert-manager CLI plugin allowing manual renewal and API version conversion + +As usual, please read the [upgrade notes](../upgrading/upgrading-0.14-0.15.md) before upgrading. + +## Experimental controllers + +The Certificate controller is one of the most commonly used controllers in the project. +It represents the 'full lifecycle' of an X.509 private key and certificate, including +private key management and renewal. + +As the project is maturing, more requirements around this controller are starting to become +apparent in order to implement feature requests such as private key rotation, JKS/PKCS#12 +keystores and manual certificate renewal triggering. + +This new controller aims to facilitate the above features, as well as make it easier to develop +individual areas of the controller over time and continue to make improvements. + +For more information on this we invite you to read our [design document](https://github.com/cert-manager/cert-manager/pull/2753). + +### Using the experimental controllers + +We are looking for feedback on the use of these new controllers in different environments. +If you are able to run these in your cluster and report any issues you're seeing that would +be very helpful to the further development of the project. + +The experimental controllers are currently feature gated and disabled by default. +You can enable these by the following steps, in the Helm values set: + +```yaml +featureGates: "ExperimentalCertificateControllers=true" +``` + +If you're using the static manifests you need to edit the cert-manager Deployment using `kubectl -n cert-manager edit deploy cert-manager` +and edit the `args` to include `--feature-gates=ExperimentalCertificateControllers=true`: + +```yaml + containers: + - args: + - --v=2 + - --cluster-resource-namespace=$(POD_NAMESPACE) + - --leader-election-namespace=kube-system + - --feature-gates=ExperimentalCertificateControllers=true +``` + +## Helm chart `installCRDs` option + +It's been a long-standing feature request to bundle our CRD resources as part +of our Helm chart, to make it easier for users installing with Helm to manage +the lifecycle of the CRDs we create. + +To facilitate this, and to help resolve common deployment issues, we have added +a new `installCRDs` option to the Helm chart which will mean the CRD resources +will be managed by your regular Helm installation. + +This feature is **disabled** by default, and can be enabled either in your +`values.yaml` file or as a flag with `helm install --set installCRDs=true`. + +## Support for OpenShift's Operator Lifecycle Manager + +cert-manager can now be deployed as a Red Hat Certified OpenShift Operator. +This is done using the [cert-manager operator](https://github.com/cert-manager/cert-manager-olm). +More information on this can be found on the [OpenShift Installation page](https://cert-manager.io/docs/installation/openshift/). + +## Improved deployment of the webhook + +In order to improve start up time of the webhook pod, as well as improved reliability and operability, +cert-manager `v0.15` includes a new `DynamicAuthority` structure in the webhook that is used to manage the +CA used to secure the webhook. + +Instances of the webhook will keep this CA up to date and use it to generate serving certificates which +are used to secure incoming connections. + +This means that the cert-manager-controller component is no longer required to be running in order for webhook startup to succeed. +This also means that users should no longer see long start up times for this pod unless there is a genuine issue/error that needs resolving. + +## General Availability of JKS and PKCS#12 keystores + +`v0.14` added experimental 'bundle format' support for JKS and PKCS#12. +In `v0.15` the `keystore` got added to the Certificate spec which makes cert-manager +add an additional keystore in your Certificate's Secret resource. +No additional feature gates need to be set anymore. + +```yaml +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + name: crt +spec: + secretName: crt-secret + dnsNames: + - foo.example.com + - bar.example.com + issuerRef: + name: letsencrypt-prod + keystores: + jks: + create: true + passwordSecretRef: # Password used to encrypt the keystore + key: password-key + name: jks-password-secret + pkcs12: + create: true + passwordSecretRef: # Password used to encrypt the keystore + key: password-key + name: pkcs12-password-secret +``` + +For JKS this adds the files: `keystore.jks` and `truststore.jks` to the target `spec.secretName`. +For PKCS#12, it adds the file `keystore.p12`. + +## kubectl cert-manager tool + +kubectl cert-manager is a kubectl plugin that assists with controlling cert-manager inside your +Kubernetes cluster. The kubectl cert-manager binary can be downloaded from the [GitHub release page](https://github.com/cert-manager/cert-manager/releases/tag/v0.15.0). +In `v0.15` the use is currently limited to the `convert` and `renew` commands. + +`kubectl cert-manager renew` can be used to manually trigger renewal of your certificates. This required the `ExperimentalCertificateControllers` feature gate to be set. + +`kubectl cert-manager convert` can be used to convert cert-manager config files between different API versions +if your cluster does not support the conversion webhook (i.e. running the 'legacy' release) +or if you want to upgrade all your local cert-manager configuration files. \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.16.md b/content/v1.15-docs/releases/release-notes/release-notes-0.16.md new file mode 100644 index 0000000000..2862c52f4b --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.16.md @@ -0,0 +1,91 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.16' +--- + +The `v0.16` release has a few focus areas: + +* Enable the new certificate controller for all users +* `kubectl cert-manager create certificaterequest` for signing local certificates +* `v1beta1` API + + +As usual, please read the [upgrade notes](../upgrading/upgrading-0.15-0.16.md) before upgrading. + +## New certificate controller + +The Certificate controller is one of the most commonly used controllers in the project. +It represents the 'full lifecycle' of an X.509 private key and certificate, including +private key management and renewal. + +In `v0.15` we added the new certificate controllers under a feature gate to allow users to test these and gather feedback. +Thanks to everyone testing these and reporting issues we were able to fix issues and improve the controller. +In `v0.16` this controller is now the default one in cert-manager. + +For more information on this, we invite you to read our [design document](https://github.com/cert-manager/cert-manager/pull/2753). + + +## kubectl cert-manager tool for signing certificates + +cert-manager `v0.15` included a kubectl plugin that allows users to interact with cert-manager. +In this release we have added a new sub-command to the cert-manager CLI which allows users to sign certificates on their computer +or inside a container. + +The `kubectl cert-manager create certificaterequest` command creates a new CertificateRequest +resource based on the YAML manifest of a Certificate resource as specified by `--from-certificate-file` flag. + +For example this will create a CertificateRequest resource with the name "my-cr" based on the Certificate described in `my-certificate.yaml` while storing the +private key and X.509 certificate in `my-cr.key` and `my-cr.crt` respectively. +```console +$ kubectl cert-manager create certificaterequest my-cr --from-certificate-file my-certificate.yaml --fetch-certificate --timeout 20m +``` + +More information can be found on our [kubectl plugin page](../../reference/cmctl.md#legacy-kubectl-plugin). + +## `v1beta1` API + +We are soon reaching cert-manager `v1.0` and the new `v1beta1` API is our first step towards a stable `v1` API. +The biggest change users may notice is the improved API documentation. We took the time to review and update all the user-facing APIs. You can view the [updated API documentation online](../../reference/api-docs.md), or use `kubectl explain` after installing this version of cert-manager. +`v1beta1` does not contain many big changes, this version is focused on streamlining field names and general clean up of the API in preparation for the release of the `v1` release. + +These are the changes made (for reference, our conversion will take care of everything for you): + +Certificate: + +* `keyAlgorithm` is now named `algorithm` under the `privateKey` property +* `keyEncoding` is now named `encoding` under the `privateKey` property +* `keySize` is now named `size` under the `privateKey` property +* Encoding values `PKCS1` and `PKCS8` are now uppercase + +CertificateRequest: + +* The field `csr` is now `request` + +Issuer: + +* DNS01 providers with DNS in their name now are uppercase `DNS`, these are: `cloudDNS` `azureDNS` and `acmeDNS` + +ACME Order: + +* The field `csr` is now `request` + +ACME Challenge: + +* The field `authzURL` is now `authorizationURL` +* Challenge types `HTTP-01` and `DNS-01` are now all uppercase +* Unsupported challenge types (`TLS-ALPN-01`, `TLS-SNI-01`, `TLS-SNI-02` and others) are not generated by cert-manager any longer + +If you're using Kubernetes 1.15 or higher, conversion webhooks will allow you seamlessly interact with `v1alpha2`, `v1alpha3` and `v1beta1` +API versions at the same time. This allows you to use the new API version without having to modify or redeploy your older resources. +Users of the `legacy` version of cert-manager will still only have the `v1alpha2` API. + +### `kubectl cert-manager convert` tool + +To assist you updating your manifest files on disk (for example in your infrastructure Git repo) we offer `v1beta1` support in `kubectl cert-manager`. +The `kubectl cert-manager convert` command will be able to convert your manifest files to `v1beta1` using: + +```console +$ kubectl cert-manager convert --output-version cert-manager.io/v1beta1 cert.yaml +``` + +More information can be found on our [kubectl plugin page](../../reference/cmctl.md#legacy-kubectl-plugin). diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.2.md b/content/v1.15-docs/releases/release-notes/release-notes-0.2.md new file mode 100644 index 0000000000..09bde47e93 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.2.md @@ -0,0 +1,19 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.2' +--- + +## Changelog since `v0.1.0` +### Action Required +- Move to `jetstack` organization. Action required: this will require updating your existing deployments to point to the new image repository, as new tags will not be pushed to the old `jetstackexperimental/cert-manager-controller` repository. A helm upgrade should take care of this. (#145, `@munnerz`) +- Set the Kubernetes secret type to TLS. Action required: this will cause renewals of existing certificates to fail. You must delete certificates that have been previously produced by cert-manager else cert-manager may enter a renewal loop when saving the new certificates. Alternatively, you may specify a new secret to store your certificate in and manually update your ingress resource/applications to reference the new secret. (#172, `@munnerz`) + +### Other notable changes +- No longer support `ClusterIssuer` resources when cert-manager is running with --namespace flag set (#179, `@munnerz`) +- Overcome 'registration already exists for provider key' errors in ACME provider by auto-detecting lost ACME registration URIs (#171, `@munnerz`) +- Fix checking for invalid data in issuer secrets (#170, `@munnerz`) +- Fix bug in ACME HTTP01 solver causing self-check to return true before paths have propagated (#166, `@munnerz`) +- Fix panic if the secret named in an ACME issuer exists but contains invalid data (or no data) (#165, `@munnerz`) +- Ensure 5 consecutive HTTP01 self-checks pass before issuing ACME certificate (#156, `@munnerz`) +- Fix race condition in ACME HTTP01 solver when validating multiple domains (#155, `@munnerz`) +- Consistently use `glog` throughout (#126, `@munnerz`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.3.md b/content/v1.15-docs/releases/release-notes/release-notes-0.3.md new file mode 100644 index 0000000000..e3445de81a --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.3.md @@ -0,0 +1,129 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.3' +--- + +# Highlights +This is a big feature filled release of cert-manager, and the first since moving to a +more frequent release model. + +There's been a huge uptick in community contributions to the project, and this release +comprises the combined effort of 38 code contributors and hundreds of users reporting +issues, feature requests and bug reports! + +There's quite a few big headline points, so we'll get straight in: + +## ACMEv2 and Let's Encrypt wildcard certificates +This release of cert-manager brings the long-awaited ACMEv2 support, and with it, Let's Encrypt +wildcard certificates! + +This allows you to request certificates for wildcard domains, e.g. `*.example.com`, which can be used +to secure many different subdomains of your domain! + +The introduction of ACMEv2 is a *breaking change*. Please read the notes below in the *Action Required* +section for details on how to handle your existing ACME Issuers whilst upgrading from `v0.2.x`. + +## Alpha support for HashiCorp Vault +This release introduces initial support for HashiCorp Vault as an `Issuer` backend! Initially, this includes support for authenticating via AppRole and static token. + +The support for this `Issuer` is classed as 'alpha' - feedback is invaluable at this stage of development, so we are getting it out there in a tagged release to gather usage info. + +More information on configuring a Vault Issuer can be found in the Vault Issuer docs. + +## `readthedocs.io` documentation site +Whilst this note applies to the `v0.2.x` release series also, it is worth noting. + +We have now moved to `readthedocs.io` and reStructuredText for our documentation. +This should hopefully make it easier for external collaborators to make quick edits +to our documentation, and should provide more structure. + +We'd like to take the time to thank all those that have opened issues or opened pull requests against +our documentation - it's a difficult thing to get right, but it's imperative our documentation is +clear for new users adopting the project. + +## New ACME DNS01 providers +When cert-manager was first released, only CloudDNS and CloudFlare DNS01 providers were +supported when solving ACME challenges. + +As new users, each using their own DNS providers, have adopted the project; there has been +a flurry of contributions adding support for the variety of providers out there. + +With this release, we support the following DNS providers when solving ACME DNS01 challenges: + +- Akamai FastDNS (#322, `@twz123`) +- Amazon Route53 +- Azure DNS (#246, `@mwieczorek`) +- CloudFlare +- Google CloudDNS +There are pull requests in flight to add support for: +- DNSPod (#486, `@hemslo`) +- DNSimple (#483, `@marc-sensenich`) +- DigitalOcean (#345, `@dl00`) +- INWX (#336, `@steigr`) +- RFC2136 (#245, `@simonfuhrer`) + +# Changelog +## Action Required +Please check the 'upgrading from 0.2 to 0.3' guide in the Administrative Tasks section of the docs here before upgrading. + +- Supporting resources for `ClusterIssuers` (e.g. signing CA certificates, or ACME account private keys) will now be stored in the same namespace as cert-manager, instead of `kube-system` in previous versions (#329, `@munnerz`): + *Action required*: you will need to ensure to properly manually migrate these referenced resources across into the deployment namespace of cert-manager, else cert-manager may not be able to find account private keys or signing CA certificates. + +- Use `ConfigMaps` for leader election (#327, `@mikebryant`): +- *Action required*: Before upgrading, scale the cert-manager Deployment to 0, to avoid two controllers attempting to operate on the same resources + +- Remove support for ACMEv1 in favor of ACMEv2 (#309, `@munnerz`): + *Action required*: As this release drops support for ACMEv1, all Issuer resources that use ACMEv1 endpoints (e.g. existing Let's Encrypt Issuers) will need updating to use equivalent ACMEv2 endpoints. (TODO: link to docs guide) + +- Remove `ingress-shim` and link it into cert-manager itself (#502, `@munnerz`) + *Action required*: You must change your 'helm install' command to use the new `--ingressShim.defaultIssuerName`, `--ingressShim.defaultIssuerKind` options when upgrading as `--ingressShim.extraArgs` has been removed. + +- Add `certmanager.k8s.io/acme-http01-edit-in-place` annotation and change ingress-shim to set `ingressClass` on ACME Certificate resources by default. (#493, `@munnerz`) + *Action required*: This is a potentially breaking change for users of ingress controllers that map a single IP address to a single Ingress resource, such as the GCE ingress controller. These users will need to add the following annotation to their ingress: `certmanager.k8s.io/acme-http01-edit-in-place: "true"`. + +## Other notable changes +### ACME Issuer +- Add ACME DNS01 provider for Akamai FastDNS (#322, `@twz123`) +- Add a meaningful user agent to the ACME client to help diagnosing abusive traffic patterns (#422, `@jsha`) +- Issuers using the AWS Route53 solver may attempt to find credentials using the environment, EC2 IAM Role, and other sources available to the cert-manager controller. This behavior is on by default for cluster issuers and off by default for issuers. This behavior may be enabled or disabled for all issuers or cluster issuers using the --issuer-ambient-credentials and `--cluster-issuer-ambient-credentials` flags on the cert-manager controller. (#363, `@euank`) +- Add limits to HTTP01 validation pod (#408, `@kragniz`) +- The ACME DNS01 solver now trims excess whitespace from AWS credentials (#391, `@euank`) +- ACME DNS01 challenge mechanism for Azure DNS (#246, `@mwieczorek`) +- Fix panic when ACME server returns an error other than HTTP Status Conflict during registration (#237, `@munnerz`) +### CA Issuer +- Add the Key Encipherment purpose to CA Issuer generated certificates (#488, `@bradleybluebean`) +- Bundle CA certificate with issued certificates (#317, `@radhus`) +### Vault Issuer +- Add experimental support for HashiCorp Vault issuers (#292, `@vdesjardins`) +- ingress-shim +- ingress-shim now reconfigures certificates (#386, `@kragniz`) +- ingress-shim will only sync Ingress resources with `kubernetes.io/tls-acme` annotation if the value of that annotation is true. (#325, `@wmedlar`) +### Docs +- Rewrite documentation and publish on `readthedocs` (#428, `@munnerz`) +- Document the minimum necessary permissions for using cert-manager with Route53 (#359, `@wmedlar`) +- Improve deployment documentation (#264, `@munnerz`) +### Helm +- Add `clusterResourceNamespace` option to Helm chart (#547, `@munnerz`) +- Enhance Helm chart in-line with best practices (#229, `@unguiculus`): +- Add support for node affinity and tolerations in Helm chart (#350, `@kiall`) +- Add `podAnnotations` to Helm chart (#387, `@etiennetremel`) +- Add Certificate CRD short names `cert` and `certs`. This is configurable in the Helm Chart with `certificateResourceShortNames`. (#312, `@Mikulas`) +- Remove default resource requests in Helm chart. Improve post-deployment informational messages. (#290, `@munnerz`) +- End-to-end testing now covers the helm chart for cert-manager on Kubernetes 1.7-1.9 (#216, `@munnerz`) +### Other +- Produce a single static manifest instead of a directory when generating deployment manifests (#574, `@munnerz`) +- Use cert-manager deployment namespace by default for leader election (#548, `@munnerz`) +- Removed --namespace flag (#433, `@kragniz`) +- Run cert-manager container as a non root user (#415, `@tettaji`) +- TLS secrets are now annotated with information about the certificate (#388, `@kragniz`) +- The static deployment manifests now automatically deploy into the 'cert-manager' namespace by default (#330, `@munnerz`) +- Rename Event types to be prefixed 'Err' instead of 'Error' for brevity (#332, `@munnerz`) +- Clearer event logging when issuing a certificate for the first time (#331, `@munnerz`) +- Provide static deployment manifests as an alternative to a Helm chart based deployment (#276, `@munnerz`) +- Update existing secrets instead of replacing in order to preserve annotations/labels (#221, `@munnerz`) +- Update to Go 1.9 (#200, `@euank`) +### Bug fixes +- Fix a race condition in the package responsible for scheduling renewals (#218, `@munnerz`) +- Fix a bug that caused ACME certificates to not be automatically renewed (#215, `@munnerz`) +- Fix a bug in checking certificate validity and improve validation of `dnsNames` and `commonName` (#183, `@munnerz`) +- Fix bugs when checking validity of certificate resources (#184, `@munnerz`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.4.md b/content/v1.15-docs/releases/release-notes/release-notes-0.4.md new file mode 100644 index 0000000000..1774927f80 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.4.md @@ -0,0 +1,100 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.4' +--- + +This is the next feature release of cert-manager, containing a number of additions +that have been in the works for a while now. + +As you will notice from the release notes below, we are seeing a lot more community +contributions to the project which is brilliant! smile + +A massive thank you to everyone involved in making this release a reality. + +We have moved to a more regular minor-release schedule, and aim to cut new feature +releases monthly. That means the next minor release (`v0.5`) is scheduled for +around the 11th August. + +# Highlights + +## Resource validation for `Issuers`, `ClusterIssuers` and `Certificates` +A common pain point for users has been around submitting invalid resources to the +API, which cannot be handled or processed. + +Other Kubernetes API types handle this well by applying 'validation' before the +resource is persisted or operated upon, and up until now we have not supported this. + +When submitting your resources to the Kubernetes apiserver, they will now be validated +and if invalid, cert-manager will inform you of why and how they are invalid and +suspend processing of that resource. + +In the next release, this validation will be turned into a `ValidatingWebhookConfiguration` +which will allow us to prevent these resources being persisted into the API in +the first place, similar to all other Kubernetes resource types. + +Due to some limitations with the current release of Helm, we have been unable to +support this webhook operation mode in the `v0.4` release of cert-manager. +However, releasing validation this way allows us to pilot the new validation rules +we have in place and it allows you to get started with it immediately! + +## Added reference documentation for API types +Regularly, users ask us "what can I specify on my resources". In the past, we have +had to recommend users check out our source code (namely `types.go`) in order to +find out what can and cannot be specified. + +Digging through source code is no longer required! As part of our documentation +publishing process, we now generate reference API documentation (similar to the +upstream Kubernetes project!). This is available under the +'Reference documentation -> API documentation' section of our docs site! + +## Better support for 'split horizon' DNS environments with ACME DNS01 challenges +A number of users have noticed that when running cert-manager with DNS01 challenges +in split-horizon DNS environments (using the ACME issuer), the self check stage +of the validation process failed as the 'internal' DNS resolvers were used to +check for challenge record propagation. + +We have added a new flag, `--dns01-self-check-nameservers`, that allows users to specify +custom recursive DNS servers to use for performing DNS01 self checks. + +In these environments, this flag can be set to some external nameserver list that +will be used for DNS01 resolution, e.g. 8.8.8.8:53,8.8.4.4:53. + +## Self-signed Issuers +We recently merged support for 'self signed' issuers. This allows users to create +the basis for a completely cert-manager managed PKI by 'self signing' certificates. + +This can be useful when debugging, or once cert-manager also supports setting the +`isCA` bit on a Certificate, for creating a self signed root CA! + +Read up on how to get started with this new issuer type in the documentation. + +# Changelog +## Action Required +- Check the acme issuer has the 'HTTP01' challenge type configured if in use. (#629, `@groner`) +ACME HTTP01 validation is no longer attempted using an +`Issuer`/`ClusterIssuer` with no ACME HTTP01 configuration. Note that the minimal +`http01: {}` configuration IS sufficient. + +If you rely on ACME HTTP01 validation, you should check your issuers to make +sure HTTP01 validation is explicitly enabled as in previous release, this was +not verified! + +## Other notable changes +### ACME Issuer +- Add `--dns01-nameservers` flag for setting nameservers for DNS01 check (#710, `@kragniz`) +- Fix bugs affecting eTLD and CNAMEs during DNS zone resolution (#582, `@ThatWasBrilliant`) +- Run `acmesolver` container as non-root user (#585, `@klausenbusk`) +- Support for ACME HTTP01 validations when using `istio-ingress` with a mTLS enabled mesh (#622, `@munnerz`) +### Vault Issuer +- Configurable Vault AppRole authentication path using the attribute is `spec.vault.auth.authPath` in the issuer. (#612, `@vdesjardins`) +### Self-signed Issuer +- Add 'self signed' Issuer type (#637, `@munnerz`) +### Docs +- Add reference documentation for API types (#644, `@munnerz`) +### Helm +- Added configuration variables to set `http_proxy`, `https_proxy` and `no_proxy` environment variables in Helm chart. (#680, `@fllaca`) +- added option to set additional environment variable values to the Helm chart (#556, `@nazarewk`) +### Other +- Add `certmanager.k8s.io/certificate-name` label to secrets. (#719, `@kragniz`) +- Add resource validation at start of sync loops, and mark resources as not Ready when invalid (#682, `@munnerz`) +- To disable `ingress-shim`, you can now set this flag: `--controllers=issuers,clusterissuers,certificates` (#717, `@kragniz`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.5.md b/content/v1.15-docs/releases/release-notes/release-notes-0.5.md new file mode 100644 index 0000000000..9b809c76ef --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.5.md @@ -0,0 +1,53 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.5' +--- + +# Highlights +## Resource validation webhook +Following the `v0.4.0` release, we have now added a 'validating webhook' for our API resources. This will help prevent invalid configurations being submitted to the API server. + +This feature is disabled by default. + +Information on enabling the new webhook component can be found in the Resource Validation Webhook document. + +## New Certificate options +A number of new fields have been added to the Certificate resource type: + +- `keyAlgorithm` - support alternative private key algorithms (e.g. RSA or ECDSA) for generated certificates. +- `keySize` - allow specifying an alternative key bit size +- `isCA` - allows generating certificates with the 'signing' usage set +- `organization` - allows specifying values for the 'O' field of Certificates (for supported providers) + +New fields like this make cert-manager more useful for applications beyond just securing Ingress, as well as allowing users to continue meeting their security requirements for X.509 certificates. + +## New ACME DNS providers +This release includes two new DNS provides for the ACME Issuer: + +- ACMEDNS +- RFC2136 +These additions should help more users begin using cert-manager with their chosen DNS provider, without having to delegate to an alternate provider that is supported + +# Changelog +## General +- Add `renew-before-expiry-duration` option to configure how long before expiration a certificate should be attempted to be renewed (#801, `@munnerz`) +- Add validation webhooks for API types (#478, `@munnerz`) +- Add extended issuer specific validation to certificates at runtime (#761, `@kragniz`) +## API changes +- Adds new fields: `keyAlgorithm`, `keySize` onto `CertificateSpec` to allow specifying algorithm (RSA, ECDSA) and key size to use when generating TLS keys (#722, `@badie`) +- Add `isCA` field to Certificates (#658, `@munnerz`) +- Add "organization" field to certificate objects (#838, `@Queuecumber`) +## CA Issuer +- Don't bundle the CA certificate when using the self signed issuer (#811, `@munnerz`) +## ACME +- Fix issue that could cause Certificates to fail renewal (#800, `@munnerz`) +- Add ACMEDNS as a DNS01 provider (#787, `@Queuecumber`) +- Fix panic from `acmedns.go` constructor failure (#858, `@jjo`) +- Fix CloudFlare provider failing on cleanup if no record is found (#849, `@frankh`) +- Fixed Route53 cleanup errors for already deleted records. (#746, `@euank`) +- Add support for delegating DNS01 challenges using CNAME records. (#670, `@gurvindersingh`) +- Fix a race that could cause ACME orders to fail despite them being in a 'valid' state (#764, `@munnerz`) +- Fix cleanup of Google Cloud DNS hosted zone for DNS01 challenge records (#754, `@kragniz`) +- Fix issue causing existing Ingresses to not be cleaned up properly after HTTP01 challenges in some cases (#831, `@munnerz`) +- Allow metadata server authentication for Google Cloud DNS (#664, `@rpahli`) +- Add RFC2136 DNS Provider (#661, `@splashx`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.6.md b/content/v1.15-docs/releases/release-notes/release-notes-0.6.md new file mode 100644 index 0000000000..575ebc78d6 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.6.md @@ -0,0 +1,104 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.6' +--- + +The long-awaited `v0.6` release is here! This release includes a huge number of improvements, bug fixes and new features. + +We've made a big focus on the ACME implementation, as well as improving the general user-experience when requesting certificates. + +We've exposed new X.509 certificate fields via the Certificate resource type, as well as improving support for these options across all Issuer types. + +As of the `v0.6` release being cut, we've also reached a huge 99 code contributors! This is incredible to see, and we're thankful to all those who have contributed in all forms over the last couple of years! + +Read on to get some of the highlights, as well as the full list of note-worthy changes below! + +# Highlights +## Introducing ACME 'Order' and 'Challenge' CRDs +This release of cert-manager refactors how ACME certificates are handled significantly. + +This should result in: + +Fewer API calls to ACME servers - information about orders and challenges is now stored within the Kubernetes API +Better behavior with regards to rate limits +A cleaner surface for debugging issues - we can now provide more context and information through the Events API as well as the 'status' field on our API types +This is largely an internal change, but with far reaching benefits. +For more details, check out the details in the pull request (#788). + +We are keen to hear feedback on this new design, so please create issues including the /area provider-acme text in order to report feedback/problems. + +## Improved handling of ACME rate limits +After extensive testing, we've found in the most extreme cases a 100 times reduction in ACME API client calls. + +This is a massive difference, and helps reduce the load that instances of cert-manager put on services like Let's Encrypt. + +As a result, we strongly recommend all users upgrade to the `v0.6` release as soon as possible! + +## Prometheus metrics for the ACME client +In order to support the API client testing above, we've also added support for Prometheus metrics into our ACME client. + +This means you can now start instrumenting cert-manager's own usage of ACME APIs, in order to detect issues and understand behavior before it becomes a problem. + +The metrics are broken down by path, status code and a number of other labels. + +## Validating resource webhook enabled by default +In order to provide a better experience out of the box, we've now enabled the validating webhook component by default. + +This means that when you submit resources to the API server, they will be checked for misconfiguration before they are persisted to the API, meaning configuration errors are surfaced immediately, and in some cases alongside steps that can be taken to remediate the errors. + +## ECDSA keys supported for ACME certificates +It's now possible to create ECDSA private keys when issuing certificates from ACME servers. You can configure the key type and key size using `certificate.spec.keyAlgorithm` and `certificate.spec.keySize` respectively. + +## Scalability improvements +As part of our validation for this release, we've been able to test cert-manager in larger deployment configurations. + +This includes running with an ACME issuer with 6,000+ domain names, showing that our client usage remains sensible and cert-manager itself does not begin to strain. + +Off the back of this scale testing, we've also got numerous scale-related improvements lined up for the next minor release, `v0.7`. + +# Action Required +There is only one PR that changes previous behavior in this release. + +Between `v0.4.0` and `v0.5.0`, we introduced support for following CNAME records when presenting DNS01 challenges. This inadvertently broke DNS01 challenge solving when a user used a CNAME record at the route of their DNS zone (i.e. on Route53 when using an Amazon ELB). + +This change reverts the default behavior to support this kind of setup without additional changes, and instead introduces a new `cnameStrategy` field on ACME Issuer resources. You can set this field to Follow to restore the behavior introduced in `v0.5.0`. + +This note only affects the ACME Issuer type. + +# Changelog +## General +- Bump Go version to 1.11 (#1050, `@munnerz`) +- Removed the Git commit hash from the version string in non canary builds (#997) (#1021, `@Nalum`) +- Include `ca.crt` in created secrets for Issuers that support it (Vault, CA and `SelfSigned`) (#848, `@Queuecumber`) +- Added RBAC permissions for user facing roles to access Certificates and Issuers. (#902, `@fuel-wlightning`) +- Add `global.priorityClassName` option to Helm chart (#1190, `@Art3mK`) +- Add `--namespace` option to limit scope to a single namespace (#1188, `@kragniz`) +- Print more useful information about Certificate, Order and Challenge resources when running `kubectl get` (#1194, `@munnerz`) +## ACME Issuer +- Introduce ACME 'Order' and 'Challenge' resource types & re-implement ACME Issuer to be completely driven by CRDs (#788, `@munnerz`) +- ACTION REQUIRED: Fix ACME issues relating to wildcard CNAME records and add a `cnameStrategy` field to the ACME Issuer DNS01 provider configuration (#1136, `@munnerz`) +- Added `certmanager.k8s.io/acme-http01-ingress-class` annotation to ingress-shim (#1006, `@kinolaev`) +- Make HTTP01 solver `serviceType` configurable, so one can use `ClusterIP` instead of the previously hard coded type `NodePort`. `NodePort` still remains as default. (#924, `@arnisoph`) +- Revised Cert Issuer Docs for DNS01 challenge and added a doc for AzureDNS (#915, `@damienwebdev`) +- Make HTTP01 solver pod resource request/limits configurable (#923, `@arnisoph`) +- Allow ECDSA keys for ACME certificates (#937, `@acoshift`) +- RFC2136 provider: fixes a minor bug where DNS01 nameserver key has value with no port (#908, `@splashx`) +- Add ACME HTTP client Prometheus metrics (#1226, `@munnerz`) +- Reduce usage of ACME `new-acct` endpoint (#1227, `@munnerz`) +- Disable TLS verification when self-checking (#1221, `@DanielMorsing`) +- Adds new flag `--dns01-recursive-nameservers-only=[true|false]` that defaults to false. When true, cert-manager will only ever query the configured DNS resolvers to perform the ACME DNS01 self check. This is useful in DNS constrained environments, where access to authoritative nameservers is restricted. Enabling this option could cause the DNS01 self check to take longer due to caching performed by the recursive nameservers. (#1184, `@tlmiller`) +- Retain Challenge resources when an Order has entered a failed state to make debugging easier (#1197, `@munnerz`) +- Increase back-off time between ACME order attempts on failure from 5 minutes to 1 hour (#1195, `@munnerz`) +- Add 'reason' field when an order/challenge gets marked invalid (#1192, `@DanielMorsing`) +- Add DigitalOcean DNS Provider (#972, `@aslafy-z`) +## CA Issuer +- Update CA Issuer status condition usage (#961, `@munnerz`) +- It is now possible to include a certificate chain in the secret for the CA Issuer. This will then be propagated to generated certificates. (#1077, `@mikebryant`) +## Vault Issuer +- A new field `caBundle` added to the Vault Issuer configures a CA certificate used to validate the connection to the Vault Server. (#911, `@vdesjardins`) +## Bug fixes +- Increase time between retries for failing `Issuers` and `ClusterIssuers` (#981, `@munnerz`) +- Fix concurrent map write race condition in ACME solver (#1033, `@munnerz`) +- Fix bug when updating ACME server URL on an existing Issuer resource (#1230, `@munnerz`) +- Fix issuing a certificate into a preexisting secret resource (#1217, `@munnerz`) +- Fix affinity and tolerations declaration (#1209, `@GuillaumeSmaha`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.7.md b/content/v1.15-docs/releases/release-notes/release-notes-0.7.md new file mode 100644 index 0000000000..87d0b89d07 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.7.md @@ -0,0 +1,86 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.7' +--- + +## Action Required +The Helm chart `rbac.create` option has moved to be `global.rbac.create`. +Users of the Helm chart will need to update their install overrides to use +the new format. + +The Helm chart has now moved to be hosted on `charts.jetstack.io`, and +exposed via the Helm Hub. This allows us to make +and test changes to the Helm chart more easily, and better manage versions. + +## Highlights +### Venafi Issuer type +This release introduces a new issuer type for Venafi Cloud and Venafi Trust +Protection Platform. + +The Venafi adapter will be built out over the coming months to improve the +integration and expose more of the Venafi platform's advanced functionality. + +### New `cainjector` controller +This release introduces support for injecting CA bundles into Kubernetes +`{Validating,Mutating}WebhookConfiguration` & APIService resources. + +You can utilize the new controller by adding the `certmanager.k8s.io/inject-ca-from` +annotation to your webhook and APIService resources. + +This was needed in order to improve our own deployment of the 'webhook' +component as part of this release. + +### Improved webhook deployment +The `v0.6` release utilized an additional ca-sync CronJob resource that allowed +us to secure the webhook component automatically using cert-manager itself. + +Thanks to the new `cainjector` controller described above, we have now removed +this CronJob altogether in favor of using the far more reliable controller. + +### Experimental ARM support +Support for ARM was adding as part of this release (#1212). We do not currently +have automated testing using ARM platforms, so this feature is still marked +experimental. + +To utilize the new ARM support, you'll need to update your manifests and append +the architecture to the image name (i.e. `quay.io/jetstack/cert-manager-controller-arm64:v0.7.0`). + +### Easier debugging of failing ACME challenges +The introduction of the Challenge resource in the last release has allowed us +to provide better means for debugging failures. + +In the `v0.7.0 release`, if a self check or ACME validation is failing for some +reason, this information will be displayed when running `kubectl get` and +`kubectl describe`. + +### Changelog since `v0.6.0` +- Add Venafi Cloud & TPP issuer type (#1250, `@munnerz`) +- `cainjector`: add support for injecting apiserver CA (#1420, `@munnerz`) +- Generate temporary self signed certificate whilst waiting for issuer to issue certificate (#1392, `@munnerz`) +- Added kubeprod as an alternative way to deploy cert-manager to the documentation (#1421, `@arapulido`) +- Use new `cainjector` controller for webhook APIService resource (#1415, `@munnerz`) +- Adds a controller for injecting CA data into webhooks and APIServices (#1398, `@DirectXMan12`) +- Bump Kubernetes dependencies to `v1.13` (#1268, `@munnerz`) +- Use `charts.jetstack.io` instead of the `helm/charts` repository to publish Helm chart (#1377, `@munnerz`) +- Recreate dead solver pods during self-check (#1388, `@DanielMorsing`) +- Improve RFC2136 DNS01 provider documentation (#944, `@briantopping`) +- Add more information to Google CloudDNS guide (#1295, `@wwwil`) +- Add validation schema to CRD resources (#1322, `@munnerz`) +- Fire additional events when syncing ACME certificates fails (#1327, `@munnerz`) +- Publish ARM32 and ARM64 images for all cert-manager components (#1212, `@munnerz`) +- Extend ACME self check to check CAA records (#1325, `@DanielMorsing`) +- Bump Kubernetes `apimachinery` dependencies to `v1.10.12` (#1344, `@munnerz`) +- Increase `acmesolver` default CPU resource limit to `100m` (#1335, `@munnerz`) +- Fix potential race when updating secret resource (#1318, `@munnerz`) +- Fix bug causing certificates to be re-issued endlessly in certain edge cases (#1280, `@munnerz`) +- Fix bug when specify certificate `keyAlgorithm` without an explicit `keySize` (#1309, `@munnerz`) +- Bump Go version to 1.11.5 (#1304, `@munnerz`) +- Fix typo in `SelfSigned` Issuer in webhook deployment manifests (#1294, `@munnerz`) +- Add IP Address in CSR (#1128, `@lrolaz`) +- Allow to use PKCS#8 encoded private keys in CA issuers. (#1191, `@chr-fritz`) +- Add webhook troubleshooting guide (#1288, `@munnerz`) +- Overhaul documentation and add additional content (#1279, `@munnerz`) +- Increase X.509 certificate duration from 90 days to 1 year for webhook component certificates (#1276, `@munnerz`) +- Fix bug where `--dns01-recursive-nameservers` flag was not respected when looking up the zone to update for a DNS01 challenge (#1266, `@munnerz`) +- Reuse acme clients to limit use of nonce/directory/accounts endpoints (#1265, `@DanielMorsing`) +- Surface self-check errors in challenge resource (#1244, `@DanielMorsing`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.8.md b/content/v1.15-docs/releases/release-notes/release-notes-0.8.md new file mode 100644 index 0000000000..9034c65fcd --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.8.md @@ -0,0 +1,102 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.8' +--- + +Following on from the `v0.7.x` releases and a series of prerelease candidates, +cert-manager `v0.8.0` is available at last! + +This release packs in a tonne of stability improvements, as well as a whole load +of new features grinning + +As part of this release, we're updating our API format in order to better +support the 1.0 release, which we hope to reach within the next few months. +This has been accomplished in a backwards-compatible for now, to make the +upgrade process easier, especially for users that manage large numbers of +certificate resources. + +As well as the new release, we've also finally created a project logo! +For those of you who are attending KubeCon EU, we'll be handing out stickers +at the Jetstack booth from tomorrow onward! + +## Action required +The deployment manifests have now moved from being a part of our GitHub +repository and are now published alongside each image tag. Please double +check the installation guide for more information on where the manifests +can now be found. This change does not affect the Helm chart! + +## New ACME configuration format +As part of stabilizing our API surface, we've made a change to the way +you configure your ACME based certificates. + +Instead of Certificate resources containing an extra `certificate.spec.acme` +field, which is only relevant for ACME certificates, the configuration has now +moved over to the Issuer resource instead. More details on this change can be +found in the upgrade notes. + +## OpenShift installation instructions +In order to make it easier for users to run cert-manager on platforms other +than Kubernetes, we've improved our OpenShift support, including an official +installation guide for users of OpenShift. + +If you use OpenShift in your organization, check out the getting started section +for more information on how to get up and running! + +## Webhook based ACME DNS01 solver +Over the last year and a half, we've had more than 15 pull requests to add new +ACME DNS01 providers to our codebase. It's been brilliant to see such vibrant +community involvement, however it's become infeasible for us to continue to +accept, test and maintain such a rapidly growing matrix of providers. + +As a result, we've put together a new 'webhook' DNS01 solver type. +This allows you to create and install your own DNS01 providers without having +to make changes in cert-manager itself. + +You can see an example repository to get started building your own over in the +cert-manager-webhook-example repo on GitHub. + +This is a new and experimental feature, however we're excited to see the community +move to this new model of extending cert-manager. + +## Switch to structured logging +As the project has grown, we've also increased the verbosity and frequency of our log messages. +Over time, this has become difficult to manage and work with, and so with the `v0.8` release +we have begun the process of switching over our code base to structured logging. + +This should make it far easier to index, search and grep through log messages that cert-manager +emits. + +Your feedback here is really valuable, so please open issues and comment on Slack if you +have any issues! + +## Changelog +- make email address an optional field in ACME issuers (#1483, `@DanielMorsing`) +- Fix bug when handling resources that have `lastTransitionTime` set to null (#1628, `@munnerz`) +- Allow OpenShift to install cert-manager chart (#1395, `@JGodin-C2C`) +- Update documentation for new 'solvers' field (#1623, `@munnerz`) +- Fix issue where ingress-shim would not clear old configuration when migrating to the new 'solvers' field (#1620, `@munnerz`) +- Add new `issuer.spec.acme.solvers` field that replaces `certificate.spec.acme` in order to make all certificate resources portable between issuer types. The previously syntax is still supported to allow easy migration to the new configuration format. (#1450, `@munnerz`) +- Fixes `additionalPrinterColumn` formatting for Certificate resources (#1616, `@munnerz`) +- Fix update loop in certificates controller and add additional debug logging (#1602, `@munnerz`) +- Automatically retry expired Challenge resources (#1603, `@munnerz`) +- Build under MacOS. (#1601, `@michaelfig`) +- Disable the CAA check by default, and introduce a new `--feature-gates=ValidateCAA=true` option to enable it (#1585, `@munnerz`) +- Improve error handling when ACME challenges fail to Present or CleanUp (#1597, `@munnerz`) +- Add static label for solver identification to allow usage of custom service (#1575, `@christianhuening`) +- Fix issues running the `cainjector` controller on Kubernetes 1.9 (#1579, `@munnerz`) +- Fix upgrade bug where `lastTransitionTime` may be set to nil, rendering cert-manager inoperable without manual intervention (#1576, `@munnerz`) +- Add webhook based DNS01 provider (#1563, `@munnerz`) +- Add DNS01 provider conformance test suite (#1562, `@munnerz`) +- fix typo in the deployment template (#1546, `@cpanato`) +- Automatically generate LICENSES file (#1549, `@munnerz`) +- Switch to go modules for dependency management (#1523, `@munnerz`) +- Bump to use Go 1.12 (#1429, `@munnerz`) +- use authoritative nameservers for CAA checks (#1521, `@DanielMorsing`) +- Update certificate if issuer changes (#1512, `@lentzi90`) +- also whitelist IPv6 (#1497, `@mdonoughe`) +- Set default `acmesolver` image based on arch (#1494, `@lentzi90`) +- Improve logging in ACME HTTP01 solver (#1474, `@munnerz`) +- Run metrics server on cert-manager instances that have not been elected as leader (#1482, `@kragniz`) +- Switch to structured logging using `logr` (#1409, `@munnerz`) +- fixing the quick-start documentation to use the new helm chart repo `charts.jetstack.io` (#1468, `@BradErz`) +- Removes need for `hostedZoneName` to be specified. Uses discovered DNS zone name instead. (#1466, `@logicfox`) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-0.9.md b/content/v1.15-docs/releases/release-notes/release-notes-0.9.md new file mode 100644 index 0000000000..564eb9c6e7 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-0.9.md @@ -0,0 +1,195 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v0.9' +--- + +The `v0.9` release is one of our biggest yet, packed with new features and bug +fixes! + +The introduction of the new `CertificateRequest` resource type is significant as +it is a step towards where we want to be for 1.0, defining an API specification +for Certificates and allowing anyone to implement their own issuers and CAs as +first class citizens. + +This release includes changes from: + +* `Aaron Gershman` +* `Aled James` +* `Artem Yarmoluk` +* `Carlos Panato` +* `Chris Abiad` +* `Christopher Abiad` +* `Crystal-Chun` +* `Dan` +* `Dobes Vandermeer` +* `Hans Kristian Flaatten` +* `Hays Clark` +* `Ivan Wallis` +* `James Munnelly` +* `Joshua Van Leeuwen` +* `Kevin Woo` +* `Lachlan Cooper` +* `Louis Taylor` +* `Michael Cristina` +* `Michael Tsang` +* `PirateBread` +* `Qiu Yu` +* `Sergej Nikolaev` +* `Solly Ross` +* `Stefan Kolb` +* `Steven Tobias` +* `Stuart Hu` +* `Till Wiese` +* `kfoozminus` + +## Notable Items + +### New `CertificateRequest` Resource + +A new resource has been introduced - `CertificateRequest` - that is used to +request certificates using a raw X.509 certificate signing request. This resource +is not typically used by humans but rather by other controllers or services. For +example, the `Certificate` controller will now create a `CertificateRequest` +resource to resolve its own Spec. + +Controllers to resolve `CertificateRequest`s are currently disabled by default +and enabled via the feature gate `CertificateRequestControllers`. This feature +is currently in Alpha and only the CA issuer has been implemented. + +This resource is going to enable out of tree, external issuer controllers to +resolve requests. Other issuer implementations and details on how to develop an +out of tree issuer will follow in later releases. You can read more on the +motivations and road map in the [enhancement +proposal](https://github.com/cert-manager/cert-manager/blob/master/design/20190708.certificate-request-crd.md) +or how this resource is used in the +[docs](https://cert-manager.io/docs/concepts/certificaterequest/). + + +### DNS Zones support for ACME challenge solver selector + +A list of DNS zones can now be added to the ACME challenge solver selector. The +most specific DNS zone match specified here will take precedence over other DNS +zone matches, so a solver specifying `sys.example.com` will be selected over one +specifying `example.com` for the domain `www.sys.example.com`. If multiple +solvers match with the same `dnsZones` value, the solver with the most matching +labels in `matchLabels` will be selected. If neither has more matches, the solver +defined earlier in the list will be selected. + +### Certificate Readiness Prometheus Metrics + +Cert-manager now exposes Prometheus metrics on Certificate ready statuses as +`certmanager_certificate_ready_status`. This is useful for monitoring +Certificate resources to ensure they have a `Ready=True` status. + +### Prometheus Operator `ServiceMonitor` + +Support has been added to include a Prometheus `ServiceMonitor` for cert-manager +in the helm chart. This enables monitoring of cert-manager when in conjunction +with the [Prometheus Operator](https://github.com/coreos/prometheus-operator). +This is disabled by default but can be enabled via the helm configuration. + +### ACMEv2 POST-as-GET + +We have now switched to use the new POST-as-GET feature that was introduced +into the latest version of the ACME spec a few months ago. + +If you are running your own ACME server, please ensure it supports POST-as-GET +as we no longer supported the old behavior. + +### ACME Issuer Solver Pod Template + +The ACME Solver Pod Spec now exposes a template that can be used to change +metadata about that pod. Currently, a template will expose labels, annotations, +node selector, tolerations, and affinity. This is useful when running +cert-manager in multi-arch clusters, or when you run workloads across different +types of nodes and need to restrict where the `acmesolver` pod runs. + +## Action Required + +### Length limit for Common Names + +Common names with a character length of over 63 will be rejected during +validation. This is due to the upper limit being detailed in RFC 5280. + +### Distroless Cert-Manager Base Images + +For each container, cert-manager ships with the base image +`gcr.io/distroless/static` which is a minimal image that includes no binaries. +Users who want to debug from within the cert-manager pod will need to attach an +additional container with their debug utilities to the pod's namespace. + +### CSRs in Order Resources now PEM Encoded + +CSRs in Order resources have previously been incorrectly DER encoded due to an +error in implementation. This has now been corrected to PEM encoding. Current +orders that were created with a previous version of cert-manager will fail to +validate and so will be recreated. This should resume the order normally. + +## Changelog + +### General + +- Reduce cert-manager's RBAC permissions ([#1658](https://github.com/cert-manager/cert-manager/pull/1658), [`@munnerz`](https://github.com/munnerz)) +- commented-out `extraArg` for `enable-certificate-owner-ref` ([#1828](https://github.com/cert-manager/cert-manager/pull/1828), [`@aegershman`](https://github.com/aegershman)) +- Validate that Certificates in a namespace have unique `secretName` ([#1689](https://github.com/cert-manager/cert-manager/pull/1689), [`@cheukwing`](https://github.com/cheukwing)) +- Feature addition: Support for PKCS#8 keys. ([#1308](https://github.com/cert-manager/cert-manager/pull/1308), [`@Crystal-Chun`](https://github.com/Crystal-Chun)) +- Add the removal of certificates when no longer required by the owner ingress ([#1705](https://github.com/cert-manager/cert-manager/pull/1705), [`@cheukwing`](https://github.com/cheukwing)) +- Fix bug causing ECDSA certificates to be issued using 2048 bit RSA private keys ([#1757](https://github.com/cert-manager/cert-manager/pull/1757), [`@munnerz`](https://github.com/munnerz)) +- Updated the labels in the helm charts to use the newer ones. ([#1769](https://github.com/cert-manager/cert-manager/pull/1769), [`@cpanato`](https://github.com/cpanato)) +- Allow disabling issuing temporary certificates with feature flag `--feature-gates=IssueTemporaryCertificate=false` ([#1764](https://github.com/cert-manager/cert-manager/pull/1764), [`@gordonbondon`](https://github.com/gordonbondon)) +- Switch to using Distroless for base images ([#1663](https://github.com/cert-manager/cert-manager/pull/1663), [`@munnerz`](https://github.com/munnerz)) +- Limit length for `CommonName` to 63 bytes ([#1818](https://github.com/cert-manager/cert-manager/pull/1818), [`@cheukwing`](https://github.com/cheukwing)) + +### ACME Issuer + +- Properly encode the CSR field on Order resources as PEM data instead of DER ([#1884](https://github.com/cert-manager/cert-manager/pull/1884), [`@munnerz`](https://github.com/munnerz)) +- Fire informational Event if an ACME solver cannot be chosen for a domain on an Order ([#1856](https://github.com/cert-manager/cert-manager/pull/1856), [`@munnerz`](https://github.com/munnerz)) +- Fix bug with auto-generated Order names being longer than 63 characters ([#1765](https://github.com/cert-manager/cert-manager/pull/1765), [`@cheukwing`](https://github.com/cheukwing)) +- Fix a panic when a misconfigured Issuer is used for HTTP01 challenge solving ([#1758](https://github.com/cert-manager/cert-manager/pull/1758), [`@munnerz`](https://github.com/munnerz)) +- Fix a bug where the logic to select a solver would always return the last solver and may return the wrong kind of solver for the challenge that it returned. ([#1717](https://github.com/cert-manager/cert-manager/pull/1717), [`@dobesv`](https://github.com/dobesv)) +- Fix indentation on ACME setup examples ([#1785](https://github.com/cert-manager/cert-manager/pull/1785), [`@lachlancooper`](https://github.com/lachlancooper)) +- Fix a the logic to select the most specific solver from an issuer if multiple matched ([#1715](https://github.com/cert-manager/cert-manager/pull/1715), [`@dobesv`](https://github.com/dobesv)) +- Adds support for `nodeSelector` and `tolerations` in `podTemplate.spec` ([#1803](https://github.com/cert-manager/cert-manager/pull/1803), [`@cheukwing`](https://github.com/cheukwing)) +- support azure non-public regions ([#1830](https://github.com/cert-manager/cert-manager/pull/1830), [`@stuarthu`](https://github.com/stuarthu)) +- Fix issue causing challenge controller to attempt to list Secrets across all namespaces even when --namespace is specified ([#1849](https://github.com/cert-manager/cert-manager/pull/1849), [`@munnerz`](https://github.com/munnerz)) +- Adds the handling of updates to the `spec.acme.email` field in Issuers ([#1763](https://github.com/cert-manager/cert-manager/pull/1763), [`@cheukwing`](https://github.com/cheukwing)) +- Fix issue with private managed-zone being picked in CloudDNS ([#1704](https://github.com/cert-manager/cert-manager/pull/1704), [`@cheukwing`](https://github.com/cheukwing)) +- Expose pod template for the ACME issuer solver pod ([#1749](https://github.com/cert-manager/cert-manager/pull/1749), [`@JoshVanL`](https://github.com/JoshVanL)) +- Ingress skips updating Certificate resource if already exists and not owned ([#1670](https://github.com/cert-manager/cert-manager/pull/1670), [`@cheukwing`](https://github.com/cheukwing)) +- Add support for ACMEv2 POST-as-GET ([#1648](https://github.com/cert-manager/cert-manager/pull/1648), [`@munnerz`](https://github.com/munnerz)) +- Fix incorrect handling of `issuewild` tag when verifying CAA ([#1777](https://github.com/cert-manager/cert-manager/pull/1777), [`@cheukwing`](https://github.com/cheukwing)) +- Add support for selecting ACME challenge solver to use by specifying `dnsZones` in the selector ([#1806](https://github.com/cert-manager/cert-manager/pull/1806), [`@munnerz`](https://github.com/munnerz)) +- Use proxy environment variables in self-check request ([#1850](https://github.com/cert-manager/cert-manager/pull/1850), [`@kinolaev`](https://github.com/kinolaev)) + +### Venafi Issuer + +- Venafi: use VCert `v4.1.0` ([#1827](https://github.com/cert-manager/cert-manager/pull/1827), [`@munnerz`](https://github.com/munnerz)) +- Bump Venafi VCert dependency to latest version ([#1754](https://github.com/cert-manager/cert-manager/pull/1754), [`@munnerz`](https://github.com/munnerz)) + +### Webhook + +- `cert-manager-webhook` secret exists in cert-manager namespace ([#1791](https://github.com/cert-manager/cert-manager/pull/1791), [`@jetstack-bot`](https://github.com/jetstack-bot)) +- Support CRD conversion webhooks in the CA injector controller. ([#1505](https://github.com/cert-manager/cert-manager/pull/1505), [`@DirectXMan12`](https://github.com/DirectXMan12)) + +### CA Issuer + +- Adds CSR signing to CA issuer ([#1835](https://github.com/cert-manager/cert-manager/pull/1835), [`@JoshVanL`](https://github.com/JoshVanL)) + +### `CertificateRequest` + +- Adds `CertificateRequest` resource ([#1789](https://github.com/cert-manager/cert-manager/pull/1789), [`@JoshVanL`](https://github.com/JoshVanL)) +- Adds CA issuer controller to resolve `CertificateRequests` where CA is the issuer reference ([#1836](https://github.com/cert-manager/cert-manager/pull/1836), [`@JoshVanL`](https://github.com/JoshVanL)) +- Adds Sign interface to Issuers ([#1807](https://github.com/cert-manager/cert-manager/pull/1807), [`@JoshVanL`](https://github.com/JoshVanL)) +- Adds `group` to `issuerRef` in `CertificateRequest` resources to distinguish resource ownership of incoming `CertificateRequests` so enabling full external issuer support. ([#1860](https://github.com/cert-manager/cert-manager/pull/1860), [`@JoshVanL`](https://github.com/JoshVanL)) + +### Documentation + +- Adds Design and Proposals page to website docs ([#1876](https://github.com/cert-manager/cert-manager/pull/1876), [`@JoshVanL`](https://github.com/JoshVanL)) +- Adds `CertificateRequest` proposal ([#1866](https://github.com/cert-manager/cert-manager/pull/1866), [`@JoshVanL`](https://github.com/JoshVanL)) + +### Monitoring + +- Prometheus metrics for deleted Certificates are cleaned up ([#1681](https://github.com/cert-manager/cert-manager/pull/1681), [`@cheukwing`](https://github.com/cheukwing)) +- Adds `ControllerSyncCallCount` Prometheus metric to count sync calls from each controller ([#1692](https://github.com/cert-manager/cert-manager/pull/1692), [`@cheukwing`](https://github.com/cheukwing)) +- Add support for Prometheus Operator `ServiceMonitor` object in Helm Chart ([#1761](https://github.com/cert-manager/cert-manager/pull/1761), [`@Starefossen`](https://github.com/Starefossen)) +- Add Prometheus metrics for tracking Certificate readiness ([#1811](https://github.com/cert-manager/cert-manager/pull/1811), [`@cheukwing`](https://github.com/cheukwing)) \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.0.md b/content/v1.15-docs/releases/release-notes/release-notes-1.0.md new file mode 100644 index 0000000000..5101c235af --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.0.md @@ -0,0 +1,216 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v1.0' +--- + +With cert-manager `v1.0` we're putting a seal of trust on 3 years of development on the cert-manager project. +In these 3 years cert-manager has grown in functionality and stability, but mostly in the community. +Today we see many people using cert-manager to secure their Kubernetes clusters, as well as cert-manager +being integrated into many other parts in the ecosystem. +In the past 16 releases many bugs got fixed, and things that needed to be broken were broken. +Several iterations on the API improved the user experience. +We solved 1500 GitHub Issues with even more PRs by 253 contributors. + +With releasing `v1.0` we're officially making a statement that cert-manager is a mature project now. +We will also be making a compatibility promise with our `v1` API. + +A big thank you to everyone who helped to build cert-manager in the past 3 years! +Let `v1.0` be the first of many big achievements! + + +The `v1.0` release is a stability release with a few focus areas: + +* `v1` API +* `kubectl cert-manager status` command to help with investigating issues +* Using new and stable Kubernetes APIs +* Improved logging +* ACME improvements + + +As usual, please read the [upgrade notes](../upgrading/upgrading-0.16-1.0.md) before upgrading. + + +## `v1` API + +In `v0.16` we introduced the `v1beta1` API. This brought some structural changes as well as better documentation of the API fields. +In `v1.0` we build on this with the `v1` API. This API is our first "stable" API version, while our others were well used we had to already provide some compatibility guarantees with the `v1` API we promise compatibility for the API for years to come. + +These are the changes made (for reference, our conversion will take care of everything for you): + +Certificate: + +* `emailSANs` is now named `emailAddresses` +* `uriSANs` is now named `uris` + +This change makes these 2 SANs consistent with the other SANs as well as the Go API. Dropping the term SAN from our API. + +### Upgrading +If you're using Kubernetes 1.16 or higher, conversion webhooks will allow you seamlessly interact with `v1alpha2`, `v1alpha3`, `v1beta1` and `v1` API versions at the same time. This allows you to use the new API version without having to modify or redeploy your older resources. +We highly recommend upgrading your manifests to the `v1` API as older versions will soon be deprecated. + +Users of the `legacy` version of cert-manager will still only have the `v1` API, migration steps can be found in the [upgrade notes](../upgrading/upgrading-0.16-1.0.md). + + +## `kubectl cert-manager status` command + +With the new improvements to our `kubectl` plugin it is easier to investigate issues with certificates not being issued. +`kubectl cert-manager status` now displays a lot more information about what has been going on with your certificate and in which +stage of issuance it currently is in. + +Once the plugin is installed, you can run `kubectl cert-manager status certificate `. That will then look for the Certificate with the name `` and any related resources like CertificateRequest, Secret, Issuer, as well as Order and Challenges if it is a ACME Certificate. +The command outputs information about the resources, including Conditions, Events and resource specific fields like Key Usages and Extended Key Usages of the Secret or Authorizations of the Order. + + +For example while debugging a not ready certificate: +``` +$ kubectl cert-manager status certificate acme-certificate + +Name: acme-certificate +Namespace: default +Created at: 2020-08-21T16:44:13+02:00 +Conditions: + Ready: False, Reason: DoesNotExist, Message: Issuing certificate as Secret does not exist + Issuing: True, Reason: DoesNotExist, Message: Issuing certificate as Secret does not exist +DNS Names: +- example.com +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Issuing 18m cert-manager Issuing certificate as Secret does not exist + Normal Generated 18m cert-manager Stored new private key in temporary Secret resource "acme-certificate-tr8b2" + Normal Requested 18m cert-manager Created new CertificateRequest resource "acme-certificate-qp5dm" +Issuer: + Name: acme-issuer + Kind: Issuer + Conditions: + Ready: True, Reason: ACMEAccountRegistered, Message: The ACME account was registered with the ACME server +error when finding Secret "acme-tls": secrets "acme-tls" not found +Not Before: +Not After: +Renewal Time: +CertificateRequest: + Name: acme-certificate-qp5dm + Namespace: default + Conditions: + Ready: False, Reason: Pending, Message: Waiting on certificate issuance from order default/acme-certificate-qp5dm-1319513028: "pending" + Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal OrderCreated 18m cert-manager Created Order resource default/acme-certificate-qp5dm-1319513028 +Order: + Name: acme-certificate-qp5dm-1319513028 + State: pending, Reason: + Authorizations: + URL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/97777571, Identifier: example.com, Initial State: pending, Wildcard: false +Challenges: +- Name: acme-certificate-qp5dm-1319513028-1825664779, Type: DNS-01, Token: J-lOZ39yNDQLZTtP_ZyrYojDqjutMAJOxCL1AkOEZWw, Key: U_W3gGV2KWgIUonlO2me3rvvEOTrfTb-L5s0V1TJMCw, State: pending, Reason: error getting clouddns service account: secret "clouddns-accoun" not found, Processing: true, Presented: false + +``` + +The command also can help looking into what is inside an issued certificate. This example looks at an issuer Let's Encrypt certificate in detail: +``` +$ kubectl cert-manager status certificate example +Name: example +[...] +Secret: + Name: example + Issuer Country: US + Issuer Organisation: Let's Encrypt + Issuer Common Name: Let's Encrypt Authority X3 + Key Usage: Digital Signature, Key Encipherment + Extended Key Usages: Server Authentication, Client Authentication + Public Key Algorithm: RSA + Signature Algorithm: SHA256-RSA + Subject Key ID: 65081d98a9870764590829b88c53240571997862 + Authority Key ID: a84a6a63047dddbae6d139b7a64565eff3a8eca1 + Serial Number: 0462ffaa887ea17797e0057ca81d7ba2a6fb + Events: +Not Before: 2020-06-02T04:29:56+02:00 +Not After: 2020-08-31T04:29:56+02:00 +Renewal Time: 2020-08-01T04:29:56+02:00 +[...] +``` + +## Using new and stable Kubernetes APIs + +cert-manager has been an early adopter of the Kubernetes CRDs. That and us supporting Kubernetes versions as for back as `v1.11` +made us use the now deprecated `apiextensions.k8s.io/v1beta1` for our CRDs and `admissionregistration.k8s.io/v1beta1` for our webhooks. +These are now deprecated and to be removed in Kubernetes `v1.22`. In `v1.0` we now offer full support for `apiextensions.k8s.io/v1` and +`admissionregistration.k8s.io/v1` for Kubernetes `v1.16` (where this got added) and above. +For users of Kubernetes `v1.15` we keep offering support for the `v1beta1` Kubernetes APIs in our legacy version. + + +## Improved logging + +For this release we upgraded our logging library to `klog/v2` analog to Kubernetes `v1.19`. +We also reviewed every log we write to assign it an appropriate log level. + +We followed the [Kubernetes logging guidelines](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md). To come up with 5 log levels ranging from `Error` (level 0) which only prints important errors to `Trace` (level 5) which can help you to know exactly what is gong on. +With this change we reduced the number of logs when you don't need to have a debugging trace while running cert-manager. + +Tip: My default cert-manager runs on level 2 (Info), you can set this using `global.logLevel` in the Helm chart. + +*Note*: Looking at the logs while troubleshooting cert-manager should be last resort behavior, for more info check out our [troubleshooting guide](../../troubleshooting/README.md) + +## ACME improvements + +The most used use case of cert-manager is probably to issue certificates from Let's Encrypt using ACME. In `v1.0` we took took feedback from the community to add two small but important improvements to our ACME issuer. + +### Disable Account Key Generation + +If you deploy ACME issuer certs on a large scale you probably want to re-use your ACME account across multiple clusters +so your rate limit exceptions get applied everywhere. +While this was already possible in cert-manager by copying over the secret referenced in `privateKeySecretRef`. +However this process was quite error prone as cert-manager was trying to be helpful and was happy to create a new account key +for you if one was not found. This is why we added `disableAccountKeyGeneration` to safe guard you against this behavior, +if set to true it will not create a key and warn you if no account key was given to it. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt +spec: + acme: + privateKeySecretRef: + name: example-issuer-account-key + disableAccountKeyGeneration: false +``` + +### Preferred Chain + +On September 29th Let's Encrypt will [change over](https://letsencrypt.org/2019/04/15/transitioning-to-isrg-root.html) to using its own `ISRG Root` CA. +This will replace the cross-signed certificates by `Identrust`. This change over needs no changes to your cert-manager configuration, any renewed or new certificates issued after this date will use the new CA root. + +Let's encrypt currently already signs certificates using this CA and offers them as "alternative certificate chain" via ACME. +In this release cert-manager adds support for accessing these alternative chains in the issuer config. +The new `preferredChain` option will allow you to specify a CA's common name for the certificate to be issued by. +If there is a certificate available matching that request it will present you that certificate. Note that this is a Preferred option, +if none is found matching the request it will give you the default certificate as before. This makes sure you still get your certificate +renewed once the alternative chain gets removed on the ACME issuer side. + +You can already today get certificates from the `ISRG Root` by using: +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + preferredChain: "ISRG Root X1" +``` + +If you prefer to keep the `IdenTrust` chain you can do that by setting the option to `DST Root CA X3`: +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + preferredChain: "DST Root CA X3" +``` + +Note that this Root CA is expiring soon, Let's Encrypt will keep this certificate chain active until September 29 2021. diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.1.md b/content/v1.15-docs/releases/release-notes/release-notes-1.1.md new file mode 100644 index 0000000000..d3ca28683b --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.1.md @@ -0,0 +1,52 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v1.1' +--- + +The `v1.1` release is our first release in the `v1` series with a few focus areas: + +* New features and fixes in the ACME Issuer +* Improved Venafi TPP Authentication + +We also want to thank several new contributors to the project for their PRs! + +* `alrs` +* `raphink` +* `renan` +* `sharmaansh21` +* `supriya-premkumar` + +All help is very appreciated and very welcome! + +Interested in knowing what will happen in the next releases of cert-manager? Go check out [our road map](https://github.com/cert-manager/cert-manager/blob/master/ROADMAP.md)! + +As usual, please read the [upgrade notes](../upgrading/upgrading-1.0-1.1.md) before upgrading. + +## ACME Improvements + +The ACME issuer is the most used cert-manager issuer. While most use it to talk to Let's Encrypt we are seeing a growing number of new ACME endpoints by certificate authorities, +PKI software exposing ACME endpoints and even ACME proxies to allow ACME being used to talk to other APIs. +In this release we focused on adding new features into the ACME issuer to make even more possible! + +### IP Addresses + +In [RFC8738](https://tools.ietf.org/html/rfc8738) the support for IP Address validation was added to the ACME spec. This allows cert-manager to use HTTP-01 validation to get certificates for the IP(s) of your ingress controller. +This can be done using the `ipAddresses` field of the Certificate resource. + +*Note:* Let's Encrypt has announced plans to support this soon! + +### Duration + +cert-manager now allows you to request certificates with a certain validity period from an ACME issuer. This allows you to get shorter or longer lived certificates from ACME solutions such as [Step-CA](https://smallstep.com/blog/private-acme-server/). You can enable this by setting `enableDurationFeature` to `true` in the ACME Issuer configuration. Be careful, if your ACME issuer does not support this feature it is allowed by the ACME spec to hard fail the Order causing your certificate renewal or creation to stop. + +*Note:* Let's Encrypt has announced intention to look into the possibilities of implementing this. + +### Error handling + +We improved the recognition and handling of errors given by the ACME server. We are now able to quickly retry transient errors and surface any fatal errors faster in the Kubernetes events and logs. +This allows you to get more insight into any rate limiting or other errors your ACME issuer provides us. + +## Improvements for Venafi TPP Authentication + +It is now possible to use a long lived access-token for authentication when configuring [Venafi TPP `Issuer` and `ClusterIssuer` types](../../configuration/venafi.md). +This authentication mechanism is supported by `Venafi TPP >= 19.2`. \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.10.md b/content/v1.15-docs/releases/release-notes/release-notes-1.10.md new file mode 100644 index 0000000000..d0d27f3cc4 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.10.md @@ -0,0 +1,163 @@ +--- +title: Release 1.10 +description: 'cert-manager release notes: cert-manager 1.10' +--- + +Release 1.10 adds a variety of quality-of-life fixes and features including improvements to the test suite. + +The latest version is `v1.10.2`. + +## Breaking Changes (You **MUST** read this before you upgrade!) + +### Container Name Changes + +This change is only relevant if you install cert-manager using Helm or the static manifest files. `v1.10.0` changes the names of containers in pods created by cert-manager. + +The names are changed to better reflect what they do; for example, the container in the controller pod had its name changed from `cert-manager` to `cert-manager-controller`, +and the webhook pod had its container name changed from `cert-manager` to `cert-manager-webhook`. + +This change could cause a break if you: + +1. Use Helm or the static manifests, and +2. Have scripts, tools or tasks which rely on the names of the cert-manager containers being static + +If both of these are true, you may need to update your automation before you upgrade. + +### On OpenShift the cert-manager Pods may fail until you modify Security Context Constraints + +In cert-manager 1.10 the [secure computing (seccomp) profile](https://kubernetes.io/docs/tutorials/security/seccomp/) for all the Pods +is set to `RuntimeDefault`. +(See [cert-manager pull request 5259](https://github.com/cert-manager/cert-manager/pull/5259/files).) +The `securityContext` fields of the Pod are set as follows: +```yaml +... +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + seccompProfile: + type: RuntimeDefault + ... +``` + +On some versions and configurations of OpenShift this can cause the Pod to be rejected by the +[Security Context Constraints admission webhook](https://docs.openshift.com/container-platform/4.10/authentication/managing-security-context-constraints.html#admission_configuring-internal-oauth). + +#### On OpenShift `v4.7`, `v4.8`, `v4.9` and `v4.10` you may need to modify Security Context Constraints to allow cert-manager Pods to be deployed + +In OpenShift `v4.7`, `v4.8`, `v4.9` and `v4.10`, the default SecurityContextConstraint is called "restricted", and it forbids Pods that have the `RuntimeDefault` seccomp profile. +If you deploy cert-manager on these versions of OpenShift you may see the following error condition on the cert-manager Deployments: + +```yaml +apiVersion: apps/v1 +kind: Deployment +# ... +status: + conditions: +# ... + - lastTransitionTime: "2022-11-01T09:41:41Z" + lastUpdateTime: "2022-11-01T09:41:41Z" + message: 'pods "cert-manager-84bc577876-qzbnf" is forbidden: unable to validate + against any security context constraint: [pod.metadata.annotations.seccomp.security.alpha.kubernetes.io/pod: + Forbidden: seccomp may not be set pod.metadata.annotations.container.seccomp.security.alpha.kubernetes.io/cert-manager-controller: + Forbidden: seccomp may not be set provider "anyuid": Forbidden: not usable by + user or serviceaccount provider "nonroot": Forbidden: not usable by user or + serviceaccount provider "hostmount-anyuid": Forbidden: not usable by user or + serviceaccount provider "machine-api-termination-handler": Forbidden: not usable + by user or serviceaccount provider "hostnetwork": Forbidden: not usable by user + or serviceaccount provider "hostaccess": Forbidden: not usable by user or serviceaccount + provider "privileged": Forbidden: not usable by user or serviceaccount]' + reason: FailedCreate + status: "True" + type: ReplicaFailure +# ... +``` + +The work around is to copy the "restricted" SecurityContextConstraint resource and then modify it to allow Pods with `RuntimeDefault` seccomp profile. +Then use `oc adm policy add-scc-to-user` to create a Role and a RoleBinding that allows all the cert-manager ServiceAccounts to use that SecurityContextConstraint. + +> 📖 Read [Enabling the default seccomp profile for all pods](https://docs.openshift.com/container-platform/4.10/security/seccomp-profiles.html#configuring-default-seccomp-profile_configuring-seccomp-profiles) to learn more about this process. + +#### On OpenShift `v4.11` you may need to modify Security Context Constraints to allow cert-manager Pods to be deployed + +In OpenShift `v4.11`, there is a new SecurityContextConstraint called `restricted-v2`, which permits Pods that have the `RuntimeDefault` seccomp profile and this will used for the cert-manager Pods by default, allowing the Pods to be created. + +But if you have upgraded OpenShift from a previous version, the old `restricted` SecurityContextConstraint may still be used and you will have to make changes to the RoleBindings in order to make it the default for all Pods. + +> 📖 Read [Pod security admission in the OpenShift `v4.11` release notes](https://docs.openshift.com/container-platform/4.11/release_notes/ocp-4-11-release-notes.html#ocp-4-11-auth-pod-security-admission) to learn more about the changes to the default security context constraints in `v4.11`. +> +> 📖 Read [Default security context constraints](https://docs.openshift.com/container-platform/4.11/authentication/managing-security-context-constraints.html#default-sccs_configuring-internal-oauth) in the OpenShift `v4.11` documentation to learn about the characteristics of the default Security Context Constraints in OpenShift. + +#### When using the OLM packages for OperatorHub on OpenShift `>= v4.7`, you may need to modify Security Context Constraints to allow the cert-manager ACME HTTP01 Pod to be deployed + +In the cert-manager OLM packages for RedHat OpenShift OperatorHub, the `seccompProfile` field in the Deployment resource has been removed, +and this should allow you to install it on OpenShift `v4.7`, `v4.8`, `v4.9`, `v4.10`, and `v4.11` without any extra configuration. + +But if you are using the ACME Issuer with the HTTP01 solver, cert-manager will deploy a short lived Pod that uses the `RuntimDefault` seccomp profile which may be denied because of the existing Security Context Constraints. + +> 📖 Read [Enabling the default seccomp profile for all pods](https://docs.openshift.com/container-platform/4.10/security/seccomp-profiles.html#configuring-default-seccomp-profile_configuring-seccomp-profiles) to learn how to configure your system to allow Pods that use the `RuntimeDefault` seccomp profile. + +## `v1.10.2`: Changes since `v1.10.1` + +cert-manager `v1.10.2` is primarily a performance enhancement release which might reduce memory consumption by up to 50% in some cases thanks to some brilliant work by [@irbekrm](https://github.com/irbekrm)! + +It also patches several vulnerabilities reported by scanners and updates the base images used for cert-manager containers. In addition, it removes a potentially confusing log line which had been introduced in `v1.10.0` which implied that an error had occurred when using external issuers even though there had been no error. + +### Feature + +- Enable support for Kubernetes 1.26 in tests ([#5647](https://github.com/cert-manager/cert-manager/pull/5647), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +### Bug or Regression + +- Fixes a bug where the cert-manager controller was caching all Secrets twice ([#5704](https://github.com/cert-manager/cert-manager/pull/5704), [@irbekrm](https://github.com/irbekrm)) +- Bump helm version to fix `CVE-2022-23525` ([#5676](https://github.com/cert-manager/cert-manager/pull/5676), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Don't log errors relating to `SelfSigned` issuer checks for external issuers ([#5687](https://github.com/cert-manager/cert-manager/pull/5687), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix `golang.org/x/text` vulnerability ([#5592](https://github.com/cert-manager/cert-manager/pull/5592), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Upgrade `golang/x/net` to fix `CVE-2022-41717` ([#5635](https://github.com/cert-manager/cert-manager/pull/5635), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Upgrade to go `1.19.4` to fix `CVE-2022-41717` ([#5620](https://github.com/cert-manager/cert-manager/pull/5620), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Use manually specified temporary directory template when verifying CRDs ([#5682](https://github.com/cert-manager/cert-manager/pull/5682), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +### Other (Cleanup or Flake) + +- Bump distroless base images to latest versions ([#5677](https://github.com/cert-manager/cert-manager/pull/5677), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## `v1.10.1`: Changes since `v1.10.0` + +### Bug or Regression + +- The Venafi Issuer now supports TLS 1.2 renegotiation, so that it can connect to TPP servers where the `vedauth` API endpoints are configured to *accept* client certificates. + (Note: This does not mean that the Venafi Issuer supports client certificate authentication). + ([#5576](https://github.com/cert-manager/cert-manager/pull/5371), [@wallrj](https://github.com/wallrj)) +- Upgrade to latest go patch release + ([#5560](https://github.com/cert-manager/cert-manager/pull/5560), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## `v1.10.0`: Changes since `v1.9.1` + +### Feature + +- Add `issuer_name`, `issuer_kind` and `issuer_group` labels to `certificate_expiration_timestamp_seconds`, `certmanager_certificate_renewal_timestamp_seconds` and `certmanager_certificate_ready_status` metrics (#5461, @dkulchinsky) +- Add make targets for running scans with trivy against locally built containers (#5358, @SgtCoDFish) +- CertificateRequests: requests that use the SelfSigned Issuer will be re-reconciled when the target private key Secret has been informed `cert-manager.io/private-key-secret-name`. This resolves an issue whereby a request would never be signed when the target Secret was not created or was misconfigured before the request. (#5336, @JoshVanL) +- CertificateSigningRequests: requests that use the SelfSigned Issuer will be re-reconciled when the target private key Secret has been informed `experimental.cert-manager.io/private-key-secret-name`. This resolves an issue whereby a request would never be signed when the target Secret was not created or was misconfigured before the request. + CertificateSigningRequests will also now no-longer be marked as failed when the target private key Secret is malformed- now only firing an event. When the Secret data is resolved, the request will attempt issuance. (#5379, @JoshVanL) +- Upgraded Gateway API to v0.5.0 (#5376, @inteon) +- Add caBundleSecretRef to the Vault Issuer to allow referencing the Vault CA Bundle with a Secret. Cannot be used in conjunction with the in-line caBundle field. (#5387, @Tolsto) +- The feature to create certificate requests with the name being a function of certificate name and revision has been introduced under the feature flag "StableCertificateRequestName" and it is disabled by default. This helps to prevent the error "multiple CertificateRequests were found for the 'next' revision...". (#5487, @sathyanarays) +- Helm: Added a new parameter `commonLabels` which gives you the capability to add the same label on all the resource deployed by the chart. (#5208, @thib-mary) + +### Bug or Regression + +- CertificateSigningRequest: no longer mark a request as failed when using the SelfSigned issuer, and the Secret referenced in `experimental.cert-manager.io/private-key-secret-name` doesn't exist. (#5323, @JoshVanL) +- DNS Route53: Remove incorrect validation which rejects solvers that don't define either a `accessKeyID` or `secretAccessKeyID`. (#5339, @JoshVanL) +- Enhanced securityContext for PSS/restricted compliance. (#5259, @joebowbeer) +- Fix issue where CertificateRequests marked as InvalidRequest did not properly trigger issuance failure handling leading to 'stuck' requests (#5366, @munnerz) +- `cmctl` and `kubectl cert-manager` now report their actual versions instead of "canary", fixing issue [#5020](https://github.com/cert-manager/cert-manager/issues/5020) (#5022, @maelvls) + +### Other + +- Avoid hard-coding release namespace in helm chart (#5163, @james-callahan) +- Bump cert-manager's version of Go to `1.19` (#5466, @lucacome) +- Remove `.bazel` and `.bzl` files from cert-manager now that bazel has been fully replaced (#5340, @SgtCoDFish) +- Updates Kubernetes libraries to `v0.25.2`. (#5456, @lucacome) +- Add annotations for ServiceMonitor in helm chart (#5401, @sathieu) +- Helm: Add NetworkPolicy support (#5417, @mjudeikis) +- To help troubleshooting, make the container names unique. + BREAKING: this change will break scripts/ CI that depend on `cert-manager` being the container name. (#5410, @rgl) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.11.md b/content/v1.15-docs/releases/release-notes/release-notes-1.11.md new file mode 100644 index 0000000000..316fc75b7e --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.11.md @@ -0,0 +1,160 @@ +--- +title: Release 1.11 +description: 'cert-manager release notes: cert-manager 1.11' +--- + +## v1.11.5 + +- Use Go 1.19.9 to fix a security issue in Go's `crypto/tls` library. ([#6317](https://github.com/cert-manager/cert-manager/pull/6317), [@maelvls](https://github.com/maelvls)) + +## v1.11.4 + +### Other + +- Resolved docker/docker trivy CVE alert ([#6164](https://github.com/cert-manager/cert-manager/pull/6164), [@inteon](https://github.com/inteon)) +- Upgraded base images ([#6128](https://github.com/cert-manager/cert-manager/pull/6128), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.11.3 + +cert-manager `v1.11.3` mostly contains ACME library changes. API Priority and Fairness feature is now disabled in the external webhook's extension apiserver. + +### Other + +- API Priority and Fairness controller is now disabled in extension apiserver for DNS webhook implementation. ([#6092](https://github.com/cert-manager/cert-manager/pull/6092), [@irbekrm](https://github.com/irbekrm)) +- Adds a warning for folks to not use controller feature gates helm value to configure webhook feature gates ([#6101](https://github.com/cert-manager/cert-manager/pull/6101), [@irbekrm](https://github.com/irbekrm)) + +## v1.11.2 + +### Bug or Regression + +- Build with go 1.19.9 ([#6014](https://github.com/cert-manager/cert-manager/pull/6014), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +### Other +- Bump the distroless base images ([#5930](https://github.com/cert-manager/cert-manager/pull/5930), [@maelvls](https://github.com/maelvls)) +- Bumps Docker libraries to fix vulnerability scan alert for `CVE-2023-28840`, `CVE-2023-28841`, `CVE-2023-28842` ([#6037](https://github.com/cert-manager/cert-manager/pull/6037), [@irbekrm](https://github.com/irbekrm)) - cert-manager was not actually affected by these CVEs which are all to do with Docker daemon's overlay network. +- Bumps Kubernetes libraries `v0.26.0` -> `v0.26.4` ([#6038](https://github.com/cert-manager/cert-manager/pull/6038), [@irbekrm](https://github.com/irbekrm)) - this might help with running cert-manager v1.11 on Kubernetes `v1.27` + + +## v1.11.1 + +### Bug or Regression + +- Bump helm and other dependencies to fix CVEs, along with upgrading go and base images ([#5815](https://github.com/cert-manager/cert-manager/pull/5815), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Bump the distroless base images ([#5930](https://github.com/cert-manager/cert-manager/pull/5930), [@maelvls](https://github.com/maelvls)) +- The auto-retry mechanism added in VCert 4.23.0 and part of cert-manager 1.11.0 ([#5674](https://github.com/cert-manager/cert-manager/pull/5674)) has been found to be faulty. Until this issue is fixed upstream, we now use a patched version of VCert. This patch will slowdown the issuance of certificates by 9% in case of heavy load on TPP. We aim to release at an ulterior date a patch release of cert-manager to fix this slowdown. ([#5819](https://github.com/cert-manager/cert-manager/pull/5819), [@maelvls](https://github.com/maelvls)) +- Use a fake kube-apiserver version when generating helm template in `cmctl x install`, to work around a hardcoded Kubernetes version in Helm. ([#5726](https://github.com/cert-manager/cert-manager/pull/5726), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +### Other + +- Bump keystore-go to v4.4.1 to work around an upstream rewrite of history ([#5730](https://github.com/cert-manager/cert-manager/pull/5730), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.11.0 + +cert-manager `v1.11.0` includes a drastic reduction in cert-manager's runtime memory usage, +a slew of improvements to AKS integrations and various other tweaks, fixes and improvements, +all towards cert-manager's goal of being the best way to handle certificates in modern +Cloud Native applications. + +### Support for Azure Workload Identity Federation with Azure DNS and ACME DNS-01 + +cert-manager can now authenticate using [Azure Workload Identity Federation](https://learn.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation) to manage ACME DNS-01 records in Azure DNS. +The advantage of this authentication mechanism is that you do not need to store and manage Azure credentials in Kubernetes Secret resources. +Instead cert-manager authenticates to Azure using a short lived Kubernetes ServiceAccount token. +This is now the recommended authentication method because it is more secure and easier to maintain than the other methods, +and it should be used instead of the [deprecated pod-managed identify mechanism](https://github.com/Azure/aad-pod-identity#-announcement). + +> 📖 Read about [configuring the ACME issuer with Azure DNS](../../configuration/acme/dns01/azuredns.md). +> +> 📖 Read the [AKS + LoadBalancer + Let's Encrypt tutorial](../../tutorials/getting-started-aks-letsencrypt/README.md) for an end-to-end example of this authentication method. +> +> 🔗 See [pull request #5570](https://github.com/cert-manager/cert-manager/pull/5570) for the implementation + +### Custom CA Bundles for ACME Servers + +Some users choose to run their own ACME servers rather than relying on services such as Let's Encrypt. cert-manager supports any server which +complies with the ACME spec for the ACME issuer, but some users had issues when using a private CA certificate for their ACME server, requiring +either that they ignore certificate validation (which is insecure) or that they hack their certificate into the cert-manager trust store. + +Now, users can set a caBundle flag on their ACME issuer, specifying the trust store that cert-manager should use when communicating with the +server. For more details, see [Private ACME Servers](../../configuration/acme/README.md#private-acme-servers) + +### `LiteralSubject` Improvements + +In cert-manager `1.9` we [added alpha support](./release-notes-1.9.md#literal-certificate-subjects) for the `LiteralSubject` field in the Certificate resource, which +allowed power-users to specify the exact subject they wanted for their certificate. This helps with forcing +an exact ordering of subject fields, for example. + +cert-manager `v1.11` improves on that support by [adding](https://github.com/cert-manager/cert-manager/pull/5587) the +ability to use several other fields which are used primarily in LDAP RDNs. + +### Potentially Breaking: Gateway API Upgrade + +It's exciting to see the [Gateway API](https://gateway-api.sigs.k8s.io) project progressing +nicely, and cert-manager still has experimental support for Gateway API. + +Unless you've _explicitly_ opted in to using the Gateway API support, you don't need to do +anything. If you've been using the support, however, you might need to take some actions +to ensure there aren't any breakages when you update. + +Check out the [upgrade guide](../upgrading/upgrading-1.10-1.11.md) for more +details on what you'll need to do. + +## Community + +Thanks again to all open-source contributors with commits in this release, including: + +- [@cmcga1125](https://github.com/cmcga1125) +- [@karlschriek](https://github.com/karlschriek) +- [@lvyanru8200](https://github.com/lvyanru8200) +- [@mmontes11](https://github.com/mmontes11) +- [@pinkfloydx33](https://github.com/pinkfloydx33) +- [@sathyanarays](https://github.com/sathyanarays) +- [@weisdd](https://github.com/weisdd) +- [@yann-soubeyrand](https://github.com/yann-soubeyrand) +- [@joycebrum](https://github.com/joycebrum) +- [@Git-Jiro](https://github.com/Git-Jiro) +- [@thib-mary](https://github.com/thib-mary) +- [@yk](https://github.com/yk) +- [@RomanenkoDenys](https://github.com/RomanenkoDenys) +- [@lucacome](https://github.com/lucacome) +- [@yanggangtony](https://github.com/yanggangtony) + +## Changes since cert-manager `v1.10` + +### Feature + +- Helm: allow configuring the image used by ACME HTTP-01 solver ([#5554](https://github.com/cert-manager/cert-manager/pull/5554), [@yann-soubeyrand](https://github.com/yann-soubeyrand)) +- Add the `--max-concurrent-challenges` controller flag to the helm chart ([#5638](https://github.com/cert-manager/cert-manager/pull/5638), [@lvyanru8200](https://github.com/lvyanru8200)) +- Adds the ability to specify a custom CA bundle in Issuers when connecting to an ACME server ([#5644](https://github.com/cert-manager/cert-manager/pull/5644), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Enable testing against Kubernetes 1.26 and test with Kubernetes 1.26 by default ([#5646](https://github.com/cert-manager/cert-manager/pull/5646), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Experimental make targets for pushing images to an OCI registry using `ko` and redeploying cert-manager to the cluster referenced by your current KUBECONFIG context. ([#5655](https://github.com/cert-manager/cert-manager/pull/5655), [@wallrj](https://github.com/wallrj)) +- Add ability to run acmesolver pods as root if desired. The default is still to run as non-root. ([#5546](https://github.com/cert-manager/cert-manager/pull/5546), [@cmcga1125](https://github.com/cmcga1125)) +- Add support for DC and UID in `LiteralSubject` field, all mandatory OIDs are now supported for LDAP certificates (rfc4514). ([#5587](https://github.com/cert-manager/cert-manager/pull/5587), [@SpectralHiss](https://github.com/SpectralHiss)) +- Add support for Workload Identity to AzureDNS resolver ([#5570](https://github.com/cert-manager/cert-manager/pull/5570), [@weisdd](https://github.com/weisdd)) +- Breaking: updates the gateway API integration to use the more stable v1beta1 API version. Any users of the cert-manager `ExperimentalGatewayAPISupport` alpha feature must ensure that `v1beta` of Gateway API is installed in cluster. ([#5583](https://github.com/cert-manager/cert-manager/pull/5583), [@lvyanru8200](https://github.com/lvyanru8200)) +- Certificate secrets get refreshed if the keystore format change ([#5597](https://github.com/cert-manager/cert-manager/pull/5597), [@sathyanarays](https://github.com/sathyanarays)) +- Introducing UseCertificateRequestBasicConstraints feature flag to enable Basic Constraints in the Certificate Signing Request ([#5552](https://github.com/cert-manager/cert-manager/pull/5552), [@sathyanarays](https://github.com/sathyanarays)) +- Return error when Gateway has a cross-namespace secret ref ([#5613](https://github.com/cert-manager/cert-manager/pull/5613), [@mmontes11](https://github.com/mmontes11)) +- Signers fire an event on CertificateRequests which have not been approved yet. Used for informational purposes so users understand why a request is not progressing. ([#5535](https://github.com/cert-manager/cert-manager/pull/5535), [@JoshVanL](https://github.com/JoshVanL)) + +### Bug or Regression + +- Don't log errors relating to self-signed issuer checks for external issuers ([#5681](https://github.com/cert-manager/cert-manager/pull/5681), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fixed a bug in AzureDNS resolver that led to early reconciliations in misconfigured Workload Identity-enabled setups (when Federated Identity Credential is not linked with a controller's k8s service account) ([#5663](https://github.com/cert-manager/cert-manager/pull/5663), [@weisdd](https://github.com/weisdd)) +- Use manually specified temporary directory template when verifying CRDs ([#5680](https://github.com/cert-manager/cert-manager/pull/5680), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- `vcert` was upgraded to `v4.23.0`, fixing two bugs in cert-manager. The first bug was preventing the Venafi issuer from renewing certificates when using TPP has been fixed. You should no longer see your certificates getting stuck with `WebSDK CertRequest Module Requested Certificate` or `This certificate cannot be processed while it is in an error state. Fix any errors, and then click Retry.`. The second bug that was fixed prevented the use of `algorithm: Ed25519` in Certificate resources with VaaS. ([#5674](https://github.com/cert-manager/cert-manager/pull/5674), [@maelvls](https://github.com/maelvls)) +- Upgrade `golang/x/net` to fix CVE-2022-41717 ([#5632](https://github.com/cert-manager/cert-manager/pull/5632), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Bug fix: When using feature gates with the helm chart, enable feature gate flags on webhook as well as controller ([#5584](https://github.com/cert-manager/cert-manager/pull/5584), [@lvyanru8200](https://github.com/lvyanru8200)) +- Fix `golang.org/x/text` vulnerability ([#5562](https://github.com/cert-manager/cert-manager/pull/5562), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fixes a bug that caused the Vault issuer to omit the Vault namespace in requests to the Vault API. ([#5591](https://github.com/cert-manager/cert-manager/pull/5591), [@wallrj](https://github.com/wallrj)) +- The Venafi Issuer now supports TLS 1.2 renegotiation, so that it can connect to TPP servers where the vedauth API endpoints are configured to *accept* client certificates. (Note: This does not mean that the Venafi Issuer supports client certificate authentication). ([#5568](https://github.com/cert-manager/cert-manager/pull/5568), [@wallrj](https://github.com/wallrj)) +- Upgrade to go 1.19.4 to fix CVE-2022-41717 ([#5619](https://github.com/cert-manager/cert-manager/pull/5619), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Upgrade to latest go minor release ([#5559](https://github.com/cert-manager/cert-manager/pull/5559), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Ensure `extraArgs` in Helm takes precedence over the new acmesolver image options ([#5702](https://github.com/cert-manager/cert-manager/pull/5702), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix cainjector's --namespace flag. Users who want to prevent cainjector from reading all Secrets and Certificates in all namespaces (i.e to prevent excessive memory consumption) can now scope it to a single namespace using the --namespace flag. A cainjector that is only used as part of cert-manager installation only needs access to the cert-manager installation namespace. ([#5694](https://github.com/cert-manager/cert-manager/pull/5694), [@irbekrm](https://github.com/irbekrm)) +- Fixes a bug where cert-manager controller was caching all Secrets twice ([#5691](https://github.com/cert-manager/cert-manager/pull/5691), [@irbekrm](https://github.com/irbekrm)) + +### Other + +- `certificate.spec.secretName` Secrets will now be labelled with the `controller.cert-manager.io/fao` label ([#5703](https://github.com/cert-manager/cert-manager/pull/5703), [@irbekrm](https://github.com/irbekrm)) +- Upgrade to go 1.19.5 ([#5714](https://github.com/cert-manager/cert-manager/pull/5714), [@yanggangtony](https://github.com/yanggangtony)) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.12.md b/content/v1.15-docs/releases/release-notes/release-notes-1.12.md new file mode 100644 index 0000000000..ff0a418078 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.12.md @@ -0,0 +1,644 @@ +--- +title: Release 1.12 +description: 'cert-manager release notes: cert-manager 1.12' +--- + +cert-manager 1.12 brings support for JSON logging, a lower memory footprint, +support for ephemeral service account tokens with Vault, and the support of the +`ingressClassName` field. We also improved on our ability to patch +vulnerabilities. + +## Known Issues + +These known issues apply to all releases of cert-manager `v1.12`. Some patch releases may have other specific issues, which are called out in the notes for the respective release below. + +- ACME Issuer (Let's Encrypt): wrong certificate chain may be used if `preferredChain` is configured: see [1.14 release notes](./release-notes-1.14.md#known-issues) for more information. + +- If two Certificate resources are incorrectly configured to have the same target Secret resource, cert-manager will generate a MANY CertificateRequests, possibly causing high CPU usage and/ or high costs due to the large number of certificates issued (see https://github.com/cert-manager/cert-manager/pull/6406). + This problem was resolved in v1.13.2 and other later versions, but the fix cannot be easily backported to `v1.12.x`. We recommend using `v1.12.x` with caution (avoid misconfigured Certificate resources) or upgrading to a newer version. + + +## Major Themes + +### Support for JSON logging + +JSON logs are now available in cert-manager! A massive thank you to +[@malovme](https://github.com/malovme) for going the extra mile to get +[#5828](https://github.com/cert-manager/cert-manager/pull/5828) merged! + +To enable JSON logs, add the flag `--logging-format=json` to the three +deployments (`cert-manager`, `cert-manager-webhook`, and +`cert-manager-cainjector`). + +For example, if you are using the Helm chart: + +```bash +helm repo add --force-update jetstack https://charts.jetstack.io +helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager \ + --set extraArgs='{--logging-format=json}' \ + --set webhook.extraArgs='{--logging-format=json}' \ + --set cainjector.extraArgs='{--logging-format=json}' +``` + +### Lower memory footprint + +In 1.12 we continued the work started in 1.11 to reduce cert-manager component's +memory consumption. + +#### Controller + +Caching of the full contents of all cluster `Secret`s can now be disabled by +setting a `SecretsFilteredCaching` alpha feature gate to true. This will ensure +that only `Secret` resources that are labelled with +`controller.cert-manager.io/fao` label [^1] are cached in full. Cert-manager +automatically adds this label to all `Certificate` `Secret`s. + +This change has been placed behind alpha feature gate as it could potentially +slow down large scale issuance because issuer credentials `Secret`s will now be +retrieved from kube-apiserver instead of local cache. To prevent the slow down, +users can manually label issuer `Secret`s with a +`controller.cert-manager.io/fao` label. +See the +[design](https://github.com/cert-manager/cert-manager/blob/master/design/20221205-memory-management.md) +and [implementation](https://github.com/cert-manager/cert-manager/pull/5824) for +additional details. +We would like to gather some feedback on this change before +it can graduate- please leave your comments on +(`cert-manager#6074`)[https://github.com/cert-manager/cert-manager/issues/6074]. + +Additionally, controller no longer watches and caches all `Pod` and `Service` +resources. +See [`cert-manager#5976`](https://github.com/cert-manager/cert-manager/pull/5976) for implementation. + +#### Cainjector + +[Cainjector's](../../concepts/ca-injector.md) control loops have been refactored, so by default it should +consume up to half as much memory as before, see +[`cert-manager#5746`](https://github.com/cert-manager/cert-manager/pull/5746). + +Additionally, a number of flags have been added to cainjector that can be used +to scope down what resources it watches and caches. + +If cainjector is only used as part of cert-manager installation, it only needs +to inject CA certs to cert-manager's `MutatingWebhookConfiguration` and +`ValidatingWebhookConfiguration` from a `Secret` in cert-manager's installation +namespace so all the other injectable/source types can be turned off and +cainjector can be scoped to a single namespace, see the relevant flags below: + +```go +// cainjector flags +--namespace= \ +--enable-customresourcedefinitions-injectable=false \ +--enable-certificates-data-source=false \ +--enable-apiservices-injectable=false +``` + +See [`cert-manager#5766`](https://github.com/cert-manager/cert-manager/pull/5766) for more detail. + +A big thanks to everyone who put in time reporting and writing up issues +describing performance problems in large scale installations. + +### Faster Response to CVEs By Reducing Transitive Dependencies + +In cert-manager 1.12, we have worked on reducing the impacts that unsupported +dependencies have on our ability to patch CVEs. + +Each binary now has its own `go.mod` file. When a CVE is declared in an +unsupported minor version of a dependency, and that the only solution is to bump +the minor version of the dependency, we can now choose to make an exception and +bump that minor version but limit the impact to a single binary. + +For example, in cert-manager 1.10, we chose not to fix a CVE reported in Helm +because it was forcing us to bump the minor versions of `k8s.io/api` and many +other dependencies. + +A side effect of the new `go.mod` layout is that it's now easier to import +cert-manager in Go, in terms of transitive dependencies that might show up in +your `go.mod` files or potential version conflicts between cert-manager and your +other dependencies. + +The caveat here is that we still only recommend importing cert-manager in [very +specific circumstances](../../contributing/importing.md), and the module changes +mean that if you imported some paths (specifically under `cmd` or some paths +under `test`) you might see broken imports when you try to upgrade. + +If you experience a break as part of this, we're sorry and we'd be interested to +chat about it. The vast majority of projects using cert-manager should notice no +impact, and there should be no runtime impact either. + +You can read more about this change in the design document +[`20230302.gomod.md`](https://github.com/cert-manager/cert-manager/blob/master/design/20230302.gomod.md). + +### Support for ephemeral service account tokens in Vault + +cert-manager can now authenticate to Vault using ephemeral service account +tokens (JWT). cert-manager already knew to authenticate to Vault using the +[Vault Kubernetes Auth +Method](https://developer.hashicorp.com/vault/docs/auth/kubernetes) but relied +on insecure service account tokens stored in Secrets. You can now configure +cert-manager in a secretless manner. With this new feature, cert-manager will +create an ephemeral service account token on your behalf and use that to +authenticate to Vault. + +> 📖 Read about [Secretless Authentication with a Service Account](../../configuration/vault.md#secretless-authentication-with-a-service-account). + +This change was implemented in the pull request +[`cert-manager#5502`](https://github.com/cert-manager/cert-manager/pull/5502). + +### Support for `ingressClassName` in the HTTP-01 solver + +cert-manager now supports the `ingressClassName` field in the HTTP-01 solver. We +recommend using `ingressClassName` instead of the field `class` in your Issuers +and ClusterIssuers. + +> 📖 Read more about `ingressClassName` in the documentation page [HTTP01](../../configuration/acme/http01/#ingressclassname). + +### Liveness probe and healthz endpoint in the controller + +A healthz HTTP server has been added to the controller component. +It serves a `/livez` endpoint, which reports the health status of the leader election system. +If the leader process has failed to renew its lease but has unexpectedly failed to exit, +the `/livez` endpoint will return an error code and an error message. +In conjunction with a new liveness probe in the controller Pod, +this will cause the controller to be restarted by the kubelet. + +> 📖 Read more about this new feature in [Best Practice: Use Liveness Probes](../../installation/best-practice.md#use-liveness-probes). + +## Community + +We extend our gratitude to all the open-source contributors who have made +commits in this release, including: + +- [@andrewsomething](https://github.com/andrewsomething) +- [@avi-08](https://github.com/avi-08) +- [@dsonck92](https://github.com/dsonck92) +- [@e96wic](https://github.com/e96wic) +- [@ExNG](https://github.com/ExNG) +- [@erikgb](https://github.com/erikgb) +- [@g-gaston](https://github.com/g-gaston) +- [@james-callahan](https://github.com/james-callahan) +- [@jkroepke](https://github.com/jkroepke) +- [@lucacome](https://github.com/lucacome) +- [@malovme](https://github.com/malovme) +- [@maumontesilva](https://github.com/maumontesilva) +- [@tobotg](https://github.com/tobotg) +- [@TrilokGeer](https://github.com/TrilokGeer) +- [@vidarno](https://github.com/vidarno) +- [@vinzent](https://github.com/vinzent) +- [@waterfoul](https://github.com/waterfoul) +- [@yanggangtony](https://github.com/yanggangtony) +- [@yulng](https://github.com/yulng) +- [@BobyMCbobs](https://github.com/BobyMCbobs) + +Thanks also to the following cert-manager maintainers for their contributions during this release: + +- [@inteon](https://github.com/inteon) +- [@wallrj](https://github.com/wallrj) +- [@maelvls](https://github.com/maelvls) +- [@SgtCoDFish](https://github.com/SgtCoDFish) +- [@irbekrm](https://github.com/irbekrm) +- [@jakexks](https://github.com/jakexks) +- [@JoshVanL](https://github.com/JoshVanL) +- [@munnerz](https://github.com/munnerz) + +Equally, thanks to everyone who provided feedback, helped users and raised issues +on GitHub and Slack, joined our meetings and talked to us at KubeCon! + +And special thanks to [@erikgb](https://github.com/erikgb) for continuously great +input and feedback and to [@lucacome](https://github.com/lucacome) for always +ensuring that our Kubernetes dependencies are up to date! + +Thanks also to the CNCF, which provides resources and support, and to the AWS +open source team for being good community members and for their maintenance of +the Private CA Issuer. + +In addition, massive thanks to Jetstack (by Venafi) for contributing developer +time and resources towards the continued maintenance of cert-manager projects. Venafi has sponsored +cert-manager 1.12 as a long term support release, meaning it will be maintained for much longer +than other releases to provide a stable platform for enterprises to build upon. + +## `v1.12.13` + +This patch release fixes the following vulnerabilities: +`CVE-2024-6104`, +`CVE-2024-24791`, +`CVE-2024-25620`, +`CVE-2024-26147`, and +`CVE-2024-41110`. + +> ℹ️ This version contains an unusually large number of Go dependency changes for a patch release. +> The cert-manager maintainers are confident that it is stable +> because it has passed the same extensive suite of tests as previous `1.12` releases. +> But if you are importing cert-manager `1.12` as a Go module you will notice that the minimum Go version is `1.21`, +> and the `k8s.io` modules are now updated to `0.29`. +> +> This reason for the large number of Go dependency changes is that the Helm SDK has been updated to fix security vulnerabilities in `cmctl`. +> This required the `k8s.io` modules to be updated from `0.27` to `0.29` in all components. +> Those newer minor versions of the Kubernetes modules pulled in new transitive dependencies, +> and incremented the minimum Go version from `1.20` to `1.21`. + +### Bugfixes + +- Bump the `go-retryablehttp` dependency to fix `CVE-2024-6104` ([#7128](https://github.com/cert-manager/cert-manager/pull/7128), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Updated Helm dependency to resolve `CVE-2024-25620` and `CVE-2024-26147` and Docker dependency to resolve `CVE-2024-41110` ([#7214](https://github.com/cert-manager/cert-manager/pull/7214), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Updates Go to `1.21.13` to resolve `CVE-2024-24791` ([#7216](https://github.com/cert-manager/cert-manager/pull/7216), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) + +### Dependencies + +#### Added +- `github.com/antlr/antlr4/runtime/Go/antlr/v4`: [`8188dc5`](https://github.com/antlr/antlr4/tree/runtime/Go/antlr/v4/8188dc5) +- `github.com/google/gnostic-models`: [`v0.6.8`](https://github.com/google/gnostic-models/tree/v0.6.8) +- `github.com/xhit/go-str2duration/v2`: [`v2.1.0`](https://github.com/xhit/go-str2duration/tree/v2.1.0) + +#### Changed +- `github.com/BurntSushi/toml`: [`v1.2.1 → v0.3.1`](https://github.com/BurntSushi/toml/compare/v1.2.1...v0.3.1) +- `github.com/alecthomas/kingpin/v2`: [`v2.3.1 → v2.3.2`](https://github.com/alecthomas/kingpin/compare/v2.3.1...v2.3.2) +- `github.com/asaskevich/govalidator`: [`f61b66f → 21a406d`](https://github.com/asaskevich/govalidator/compare/f61b66f...21a406d) +- `github.com/coreos/go-oidc`: [`v2.1.0+incompatible → v2.2.1+incompatible`](https://github.com/coreos/go-oidc/compare/v2.1.0...v2.2.1) +- `github.com/coreos/go-semver`: [`v0.3.0 → v0.3.1`](https://github.com/coreos/go-semver/compare/v0.3.0...v0.3.1) +- `github.com/coreos/go-systemd/v22`: [`v22.4.0 → v22.5.0`](https://github.com/coreos/go-systemd/compare/v22.4.0...v22.5.0) +- `github.com/cpuguy83/go-md2man/v2`: [`v2.0.2 → v2.0.3`](https://github.com/cpuguy83/go-md2man/compare/v2.0.2...v2.0.3) +- `github.com/davecgh/go-spew`: [`v1.1.1 → d8f796a`](https://github.com/davecgh/go-spew/compare/v1.1.1...d8f796a) +- `github.com/dustin/go-humanize`: [`v1.0.0 → v1.0.1`](https://github.com/dustin/go-humanize/compare/v1.0.0...v1.0.1) +- `github.com/emicklei/go-restful/v3`: [`v3.9.0 → v3.11.0`](https://github.com/emicklei/go-restful/compare/v3.9.0...v3.11.0) +- `github.com/evanphx/json-patch`: [`v5.6.0+incompatible → v5.7.0+incompatible`](https://github.com/evanphx/json-patch/compare/v5.6.0...v5.7.0) +- `github.com/fatih/color`: [`v1.15.0 → v1.16.0`](https://github.com/fatih/color/compare/v1.15.0...v1.16.0) +- `github.com/frankban/quicktest`: [`v1.10.0 → v1.14.3`](https://github.com/frankban/quicktest/compare/v1.10.0...v1.14.3) +- `github.com/fsnotify/fsnotify`: [`v1.6.0 → v1.7.0`](https://github.com/fsnotify/fsnotify/compare/v1.6.0...v1.7.0) +- `github.com/go-openapi/jsonreference`: [`v0.20.1 → v0.20.2`](https://github.com/go-openapi/jsonreference/compare/v0.20.1...v0.20.2) +- `github.com/golang-jwt/jwt/v4`: [`v4.4.2 → v4.5.0`](https://github.com/golang-jwt/jwt/compare/v4.4.2...v4.5.0) +- `github.com/golang/protobuf`: [`v1.5.3 → v1.5.4`](https://github.com/golang/protobuf/compare/v1.5.3...v1.5.4) +- `github.com/google/cel-go`: [`v0.12.6 → v0.17.7`](https://github.com/google/cel-go/compare/v0.12.6...v0.17.7) +- `github.com/google/gnostic`: [`v0.6.9 → v0.5.7-v3refs`](https://github.com/google/gnostic/compare/v0.6.9...v0.5.7-v3refs) +- `github.com/gorilla/websocket`: [`v1.4.2 → v1.5.0`](https://github.com/gorilla/websocket/compare/v1.4.2...v1.5.0) +- `github.com/hashicorp/go-hclog`: [`v1.2.0 → v1.6.3`](https://github.com/hashicorp/go-hclog/compare/v1.2.0...v1.6.3) +- `github.com/hashicorp/go-retryablehttp`: [`v0.7.2 → v0.7.7`](https://github.com/hashicorp/go-retryablehttp/compare/v0.7.2...v0.7.7) +- `github.com/imdario/mergo`: [`v0.3.12 → v0.3.13`](https://github.com/imdario/mergo/compare/v0.3.12...v0.3.13) +- `github.com/mattn/go-isatty`: [`v0.0.17 → v0.0.20`](https://github.com/mattn/go-isatty/compare/v0.0.17...v0.0.20) +- `github.com/onsi/ginkgo/v2`: [`v2.9.5 → v2.13.0`](https://github.com/onsi/ginkgo/compare/v2.9.5...v2.13.0) +- `github.com/onsi/gomega`: [`v1.27.7 → v1.29.0`](https://github.com/onsi/gomega/compare/v1.27.7...v1.29.0) +- `github.com/prometheus/client_golang`: [`v1.15.1 → v1.16.0`](https://github.com/prometheus/client_golang/compare/v1.15.1...v1.16.0) +- `github.com/prometheus/common`: [`v0.42.0 → v0.44.0`](https://github.com/prometheus/common/compare/v0.42.0...v0.44.0) +- `github.com/prometheus/procfs`: [`v0.9.0 → v0.10.1`](https://github.com/prometheus/procfs/compare/v0.9.0...v0.10.1) +- `github.com/sirupsen/logrus`: [`v1.9.0 → v1.9.3`](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.3) +- `github.com/spf13/cobra`: [`v1.7.0 → v1.8.0`](https://github.com/spf13/cobra/compare/v1.7.0...v1.8.0) +- `go.etcd.io/bbolt`: `v1.3.6 → v1.3.8` +- `go.etcd.io/etcd/api/v3`: `v3.5.7 → v3.5.10` +- `go.etcd.io/etcd/client/pkg/v3`: `v3.5.7 → v3.5.10` +- `go.etcd.io/etcd/client/v2`: `v2.305.7 → v2.305.10` +- `go.etcd.io/etcd/client/v3`: `v3.5.7 → v3.5.10` +- `go.etcd.io/etcd/pkg/v3`: `v3.5.7 → v3.5.10` +- `go.etcd.io/etcd/raft/v3`: `v3.5.7 → v3.5.10` +- `go.etcd.io/etcd/server/v3`: `v3.5.7 → v3.5.10` +- `go.uber.org/atomic`: `v1.9.0 → v1.10.0` +- `go.uber.org/multierr`: `v1.6.0 → v1.11.0` +- `golang.org/x/exp`: `a1ab85d → a9213ee` +- `gopkg.in/natefinch/lumberjack.v2`: `v2.0.0 → v2.2.1` +- `k8s.io/api`: `v0.27.2 → v0.29.7` +- `k8s.io/apiextensions-apiserver`: `v0.27.2 → v0.29.7` +- `k8s.io/apimachinery`: `v0.27.2 → v0.29.7` +- `k8s.io/apiserver`: `v0.27.2 → v0.29.7` +- `k8s.io/client-go`: `v0.27.2 → v0.29.7` +- `k8s.io/code-generator`: `v0.27.2 → v0.29.7` +- `k8s.io/component-base`: `v0.27.2 → v0.29.7` +- `k8s.io/gengo`: `c0856e2 → 9cce18d` +- `k8s.io/klog/v2`: `v2.100.1 → v2.110.1` +- `k8s.io/kms`: `v0.27.2 → v0.29.7` +- `k8s.io/kube-aggregator`: `v0.27.2 → v0.29.7` +- `k8s.io/kube-openapi`: `54b630e → 2dd684a` +- `k8s.io/utils`: `9f67429 → 3b25d92` +- `sigs.k8s.io/apiserver-network-proxy/konnectivity-client`: `v0.1.2 → v0.28.0` +- `sigs.k8s.io/structured-merge-diff/v4`: `v4.2.3 → v4.4.1` + +#### Removed +- `github.com/antlr/antlr4/runtime/Go/antlr`: [`v1.4.10`](https://github.com/antlr/antlr4/tree/runtime/Go/antlr/v1.4.10) +- `github.com/buger/jsonparser`: [`v1.1.1`](https://github.com/buger/jsonparser/tree/v1.1.1) +- `github.com/docopt/docopt-go`: [`ee0de3b`](https://github.com/docopt/docopt-go/tree/ee0de3b) +- `github.com/flowstack/go-jsonschema`: [`v0.1.1`](https://github.com/flowstack/go-jsonschema/tree/v0.1.1) +- `github.com/xhit/go-str2duration`: [`v1.2.0`](https://github.com/xhit/go-str2duration/tree/v1.2.0) +- `go.opentelemetry.io/otel/exporters/otlp/internal/retry`: `v1.10.0` + + +## `v1.12.12` + +### Bugfixes + +- BUGFIX: fix issue that caused Vault issuer to not retry signing when an error was encountered. ([#7113](https://github.com/cert-manager/cert-manager/pull/7113), [@cert-manager-bot](https://github.com/cert-manager-bot)) + +### Other (Cleanup or Flake) + +- Update `github.com/Azure/azure-sdk-for-go/sdk/azidentity` to address `CVE-2024-35255` ([#7093](https://github.com/cert-manager/cert-manager/pull/7093), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) + +## `v1.12.11` + +### Other (Cleanup or Flake) + +- Updated Go to `1.21.11` bringing in security fixes for `archive/zip` and `net/netip`. ([#7077](https://github.com/cert-manager/cert-manager/pull/7077), [@ThatsMrTalbot](https://github.com/thatsmrtalbot)) +- Upgrade Go to `1.21.10`, fixing `GO-2024-2824` (https://github.com/advisories/GHSA-2jwv-jmq4-4j3r). ([#7010](https://github.com/cert-manager/cert-manager/pull/7010), [@inteon](https://github.com/inteon)) + +## `v1.12.10` + +Special thanks to [@BobyMCbobs](https://github.com/BobyMCbobs) for reporting and testing the DigitalOcean issue! + +### Changes + +#### Bug or Regression + +- DigitalOcean: Ensure that only TXT records are considered for deletion when cleaning up after an ACME challenge ([#6894](https://github.com/cert-manager/cert-manager/pull/6894), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Bump `golang.org/x/net` to address [`CVE-2023-45288`](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) ([#6933](https://github.com/cert-manager/cert-manager/pull/6933), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## `v1.12.9` + +### Changes + +#### Bug or Regression + +- Allow `cert-manager.io/allow-direct-injection` in annotations ([#6811](https://github.com/cert-manager/cert-manager/pull/6811), [@jetstack-bot](https://github.com/jetstack-bot)) +- BUGFIX: JKS and PKCS12 stores now contain the full set of CAs specified by an issuer ([#6813](https://github.com/cert-manager/cert-manager/pull/6813), [@inteon](https://github.com/inteon)) +- BUGFIX: fix race condition due to registering and using global `runtime.Scheme` variables ([#6833](https://github.com/cert-manager/cert-manager/pull/6833), [@inteon](https://github.com/inteon)) + +#### Other (Cleanup or Flake) + +- Bump base images to the latest version. ([#6843](https://github.com/cert-manager/cert-manager/pull/6843), [@jetstack-bot](https://github.com/jetstack-bot)) +- Upgrade go to 1.21.8: fixes `CVE-2024-24783` ([#6826](https://github.com/cert-manager/cert-manager/pull/6826), [@jetstack-bot](https://github.com/jetstack-bot)) +- Upgrade `google.golang.org/protobuf`: fixing `GO-2024-2611` ([#6830](https://github.com/cert-manager/cert-manager/pull/6830), [@inteon](https://github.com/inteon)) + +## `v1.12.8` + +### Changes + +#### Bug or Regression + +- BUGFIX: `LiteralSubjects` with a #= value can result in memory issues due to faulty BER parser (`github.com/go-asn1-ber/asn1-ber`). ([#6773](https://github.com/cert-manager/cert-manager/pull/6773), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Bump go to 1.20.14 ([#6733](https://github.com/cert-manager/cert-manager/pull/6733), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Cert-manager is now built with Go 1.20.13 ([#6629](https://github.com/cert-manager/cert-manager/pull/6629), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix CVE 2023 48795 by upgrading to golang.org/x/crypto@v0.17.0 ([#6678](https://github.com/cert-manager/cert-manager/pull/6678), [@wallrj](https://github.com/wallrj)) +- Fix `GHSA-7ww5-4wqc-m92c` by upgrading to `github.com/containerd/containerd@v1.7.12` ([#6689](https://github.com/cert-manager/cert-manager/pull/6689), [@wallrj](https://github.com/wallrj)) + +## `v1.12.7` + +This patch release contains fixes for the following security vulnerabilities in the cert-manager-controller: +- [`GO-2023-2382`](https://pkg.go.dev/vuln/GO-2023-2382): Denial of service via chunk extensions in `net/http` + +If you use +[ArtifactHub Security report](https://artifacthub.io/packages/helm/cert-manager/cert-manager/1.12.6?modal=security-report) or +[trivy](https://trivy.dev/), +this patch will also silence the following warning +about a vulnerability in code which is imported but **not used** by the cert-manager-controller: +- [`CVE-2023-47108`](https://access.redhat.com/security/cve/CVE-2023-47108): DoS vulnerability in `otelgrpc` due to unbound cardinality metrics. + +An ongoing security audit of cert-manager suggested some changes to the webhook code to mitigate DoS attacks, +and these are included in this patch release. + +### Changes + +#### Feature + +- cert-manager is now built with Go `1.20.12` ([#6543](https://github.com/cert-manager/cert-manager/pull/6543), [@wallrj](https://github.com/wallrj)). + +#### Bug or Regression + +- The webhook server now returns HTTP error 413 (Content Too Large) for requests with body size `>= 3MiB`. This is to mitigate DoS attacks that attempt to crash the webhook process by sending large requests that exceed the available memory ([#6506](https://github.com/cert-manager/cert-manager/pull/6506), [@inteon](https://github.com/inteon)). +- The webhook server now returns HTTP error 400 (Bad Request) if the request contains an empty body ([#6506](https://github.com/cert-manager/cert-manager/pull/6506), [@inteon](https://github.com/inteon)). +- The webhook server now returns HTTP error 500 (Internal Server Error) rather than crashing, if the code panics while handling a request ([#6506](https://github.com/cert-manager/cert-manager/pull/6506), [@inteon](https://github.com/inteon)). +- Mitigate potential Slowloris attacks by setting `ReadHeaderTimeout` in all `http.Server` instances ([#6539](https://github.com/cert-manager/cert-manager/pull/6539), [@wallrj](https://github.com/wallrj)). +- Upgrade `otel` and `docker` to fix: `CVE-2023-47108` and `GHSA-jq35-85cj-fj4p` ([#6513](https://github.com/cert-manager/cert-manager/pull/6513), [@inteon](https://github.com/inteon)). + +#### Dependencies + +##### Added +- `cloud.google.com/go/dataproc/v2`: `v2.0.1` + +##### Changed +- `cloud.google.com/go/aiplatform`: `v1.45.0 → v1.48.0` +- `cloud.google.com/go/analytics`: `v0.21.2 → v0.21.3` +- `cloud.google.com/go/baremetalsolution`: `v0.5.0 → v1.1.1` +- `cloud.google.com/go/batch`: `v0.7.0 → v1.3.1` +- `cloud.google.com/go/beyondcorp`: `v0.6.1 → v1.0.0` +- `cloud.google.com/go/bigquery`: `v1.52.0 → v1.53.0` +- `cloud.google.com/go/cloudbuild`: `v1.10.1 → v1.13.0` +- `cloud.google.com/go/cloudtasks`: `v1.11.1 → v1.12.1` +- `cloud.google.com/go/compute`: `v1.21.0 → v1.23.0` +- `cloud.google.com/go/contactcenterinsights`: `v1.9.1 → v1.10.0` +- `cloud.google.com/go/container`: `v1.22.1 → v1.24.0` +- `cloud.google.com/go/datacatalog`: `v1.14.1 → v1.16.0` +- `cloud.google.com/go/dataplex`: `v1.8.1 → v1.9.0` +- `cloud.google.com/go/datastore`: `v1.12.1 → v1.13.0` +- `cloud.google.com/go/datastream`: `v1.9.1 → v1.10.0` +- `cloud.google.com/go/deploy`: `v1.11.0 → v1.13.0` +- `cloud.google.com/go/dialogflow`: `v1.38.0 → v1.40.0` +- `cloud.google.com/go/documentai`: `v1.20.0 → v1.22.0` +- `cloud.google.com/go/eventarc`: `v1.12.1 → v1.13.0` +- `cloud.google.com/go/firestore`: `v1.11.0 → v1.12.0` +- `cloud.google.com/go/gkebackup`: `v0.4.0 → v1.3.0` +- `cloud.google.com/go/gkemulticloud`: `v0.6.1 → v1.0.0` +- `cloud.google.com/go/kms`: `v1.12.1 → v1.15.0` +- `cloud.google.com/go/maps`: `v0.7.0 → v1.4.0` +- `cloud.google.com/go/metastore`: `v1.11.1 → v1.12.0` +- `cloud.google.com/go/policytroubleshooter`: `v1.7.1 → v1.8.0` +- `cloud.google.com/go/pubsub`: `v1.32.0 → v1.33.0` +- `cloud.google.com/go/run`: `v0.9.0 → v1.2.0` +- `cloud.google.com/go/servicedirectory`: `v1.10.1 → v1.11.0` +- `cloud.google.com/go/speech`: `v1.17.1 → v1.19.0` +- `cloud.google.com/go/translate`: `v1.8.1 → v1.8.2` +- `cloud.google.com/go/video`: `v1.17.1 → v1.19.0` +- `cloud.google.com/go/vmwareengine`: `v0.4.1 → v1.0.0` +- `cloud.google.com/go`: `v0.110.4 → v0.110.7` +- `github.com/felixge/httpsnoop`: [`v1.0.3 → v1.0.4`](https://github.com/felixge/httpsnoop/compare/v1.0.3...v1.0.4) +- `github.com/go-logr/logr`: [`v1.2.4 → v1.3.0`](https://github.com/go-logr/logr/compare/v1.2.4...v1.3.0) +- `github.com/golang/glog`: [`v1.1.0 → v1.1.2`](https://github.com/golang/glog/compare/v1.1.0...v1.1.2) +- `github.com/google/go-cmp`: [`v0.5.9 → v0.6.0`](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0) +- `github.com/google/uuid`: [`v1.3.0 → v1.3.1`](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) +- `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`: `v0.45.0 → v0.46.0` +- `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp`: `v0.44.0 → v0.46.0` +- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/exporters/otlp/otlptrace`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/metric`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/sdk`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/trace`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel`: `v1.19.0 → v1.20.0` +- `go.uber.org/goleak`: `v1.2.1 → v1.3.0` +- `golang.org/x/oauth2`: `v0.10.0 → v0.11.0` +- `golang.org/x/sys`: `v0.13.0 → v0.14.0` +- `google.golang.org/genproto/googleapis/api`: `782d3b1 → b8732ec` +- `google.golang.org/genproto/googleapis/rpc`: `782d3b1 → b8732ec` +- `google.golang.org/genproto`: `782d3b1 → b8732ec` +- `google.golang.org/grpc`: `v1.58.3 → v1.59.0` + +##### Removed +- `cloud.google.com/go/dataproc`: `v1.12.0` + + +## `v1.12.6` + +v1.12.6 fixes some CVE alerts and a Venafi issuer bug + +### Changes + +#### Bug or Regression + +- Bump `golang.org/x/net v0.15.0 => v0.17.0` as part of addressing `CVE-2023-44487` / `CVE-2023-39325` ([#6431](https://github.com/cert-manager/cert-manager/pull/6431), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- The Venafi issuer now properly resets the certificate and should no longer get stuck with `WebSDK CertRequest Module Requested Certificate` or `This certificate cannot be processed while it is in an error state. Fix any errors, and then click Retry.`. ([#6401](https://github.com/cert-manager/cert-manager/pull/6401), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Bump go to 1.20.10 to address `CVE-2023-39325`. Also bumps base images. ([#6412](https://github.com/cert-manager/cert-manager/pull/6412), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## `v1.12.5` + +v1.12.5 contains a backport for a name collision bug that was found in v1.13.0 + +### Changes + +#### Bug or Regression + +- BUGFIX: fix CertificateRequest name collision bug in StableCertificateRequestName feature. ([#6359](https://github.com/cert-manager/cert-manager/pull/6359), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Updated base images to the latest version. ([#6372](https://github.com/cert-manager/cert-manager/pull/6372), [@inteon](https://github.com/inteon)) +- Upgrade Go from 1.20.7 to 1.20.8. ([#6371](https://github.com/cert-manager/cert-manager/pull/6371), [@jetstack-bot](https://github.com/jetstack-bot)) + +## `v1.12.4` + +v1.12.4 contains an important security fix that +addresses [CVE-2023-29409](https://cve.report/CVE-2023-29409). + +### Changes + +- Fixes an issue where cert-manager would incorrectly reject two IP addresses as + being unequal when they should have compared equal. This would be most + noticeable when using an IPv6 address which doesn't match how Go's + `net.IP.String()` function would have printed that address. + ([#6297](https://github.com/cert-manager/cert-manager/pull/6297), + [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Use Go 1.20.7 to fix a security issue in Go's `crypto/tls` library. + ([#6318](https://github.com/cert-manager/cert-manager/pull/6318), + [@maelvls](https://github.com/maelvls)) + +## `v1.12.3` + +v1.12.3 contains a bug fix for the cainjector which addresses a memory leak! + +### Changes + +- BUGFIX\[cainjector\]: 1-character bug was causing invalid log messages and a memory leak ([#6235](https://github.com/cert-manager/cert-manager/pull/6235), [@jetstack-bot](https://github.com/jetstack-bot)) + +## `v1.12.2` + +v1.12.2 is a bugfix release, but includes a known issue. You should prefer +upgrading to the latest patch version available for 1.12. + +### Known issues + +- cainjector contains a memory leak due to re-assignment of a log variable (see https://github.com/cert-manager/cert-manager/issues/6217). The fix will be released in v1.12.3. See https://github.com/cert-manager/cert-manager/pull/6232 for context. + +### Changes + +- BUGFIX: `cmctl check api --wait 0` exited without output; we now make sure we perform the API check at least once ([#6116](https://github.com/cert-manager/cert-manager/pull/6116), [@jetstack-bot](https://github.com/jetstack-bot)) + +## `v1.12.1` + +The v1.12.1 release contains a couple dependency bumps and changes to ACME +external webhook library. Note that v1.12.1 contains a known issue, and you +should prefer upgrading to the latest patch version available for 1.12. + +### Known issues + +- [`cmctl` API check](https://cert-manager.io/docs/installation/verify/) is broken in v1.12.1. We suggest that you do not upgrade `cmctl` to this version. The fix will be released in v1.12.2. +See #6116 for context. +- cainjector contains a memory leak due to re-assignment of a log variable (see https://github.com/cert-manager/cert-manager/issues/6217). The fix will be released in v1.12.3. +See https://github.com/cert-manager/cert-manager/pull/6232 for context. + +### Other + +- Don't run API Priority and Fairness controller in webhook's extension apiserver ([#6085](https://github.com/cert-manager/cert-manager/pull/6085), [@irbekrm](https://github.com/irbekrm)) +- Adds a warning for folks to not use controller feature gates helm value to configure webhook feature gates ([#6100](https://github.com/cert-manager/cert-manager/pull/6100), [@irbekrm](https://github.com/irbekrm)) + +### Uncategorized + +- Updates Kubernetes libraries to `v0.27.2`. ([#6077](https://github.com/cert-manager/cert-manager/pull/6077), [@lucacome](https://github.com/lucacome)) +- Updates controller-runtime to `v0.15.0` ([#6098](https://github.com/cert-manager/cert-manager/pull/6098), [@lucacome](https://github.com/lucacome)) + +## `v1.12.0` + +### Changes + +#### Feature + +- Helm: Added PodDisruptionBudgets for cert-manager components to the Helm chart (disabled by default). ([#3931](https://github.com/cert-manager/cert-manager/pull/3931), [@e96wic](https://github.com/e96wic)) +- Added support for JSON logging (using `--logging-format=json`) ([#5828](https://github.com/cert-manager/cert-manager/pull/5828), [@malovme](https://github.com/malovme)) +- Added the --concurrent-workers flag that lets you control the number of concurrent workers for each of our controllers. ([#5936](https://github.com/cert-manager/cert-manager/pull/5936), [@inteon](https://github.com/inteon)) +- Adds `acme.solvers.http01.ingress.podTemplate.spec.imagePullSecrets` field to issuer spec to allow to specify image pull secrets for the ACME HTTP01 solver pod. ([#5801](https://github.com/cert-manager/cert-manager/pull/5801), [@malovme](https://github.com/malovme)) +- cainjector: + - New flags were added to the cainjector binary. They can be used to modify what injectable kinds are enabled. If cainjector is only used as a cert-manager's internal component it is sufficient to only enable validatingwebhookconfigurations and mutatingwebhookconfigurations injectable resources; disabling the rest can improve memory consumption. By default all are enabled. + - The `--watch-certs` flag was renamed to `--enable-certificates-data-source`. ([#5766](https://github.com/cert-manager/cert-manager/pull/5766), [@irbekrm](https://github.com/irbekrm)) +- Helm: you can now add volumes and volume mounts via Helm variables for the cainjector, webhook, and startupapicheck. ([#5668](https://github.com/cert-manager/cert-manager/pull/5668), [@waterfoul](https://github.com/waterfoul)) +- Helm: you can now enable the flags `--dns01-recursive-nameservers`, `--enable-certificate-owner-ref`, and `--dns01-recursive-nameservers-only` through Helm values. ([#5614](https://github.com/cert-manager/cert-manager/pull/5614), [@jkroepke](https://github.com/jkroepke)) +- **POTENTIALLY BREAKING**: the cert-manager binaries and some tests have been split into separate Go modules, allowing them to be easily patched independently. This should have no impact if you simply run cert-manager in your cluster. If you import cert-manager binaries, integration tests or end-to-end tests in Go, you may need to make code changes in response to this. See https://cert-manager.io/docs/contributing/importing/ for more details. ([#5880](https://github.com/cert-manager/cert-manager/pull/5880), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- The DigitalOcean issuer now sets a cert-manager user agent string. ([#5869](https://github.com/cert-manager/cert-manager/pull/5869), [@andrewsomething](https://github.com/andrewsomething)) +- The HTTP-01 solver can now be configured to create Ingresses with an `ingressClassName`. The credit goes to @dsonck92 for implementing the initial PR. ([#5849](https://github.com/cert-manager/cert-manager/pull/5849), [@maelvls](https://github.com/maelvls)) +- The Vault issuer can now be used with ephemeral Kubernetes tokens. With the new `serviceAccountRef` field, cert-manager generates a short-lived token associated to the service account to authenticate to Vault. Along with this new feature, we have added validation logic in the webhook in order to check the `vault.auth` field when creating an Issuer or ClusterIssuer. Previously, it was possible to create an Issuer or ClusterIssuer with an invalid value for `vault.auth`. ([#5502](https://github.com/cert-manager/cert-manager/pull/5502), [@maelvls](https://github.com/maelvls)) +- The cert-manager controller container of the controller Pod now has a `/livez` endpoint and a default liveness probe, which fails if leader election has been lost and for some reason the process has not exited. The liveness probe is disabled by default. ([#5962](https://github.com/cert-manager/cert-manager/pull/5962), [@wallrj](https://github.com/wallrj)) +- Upgraded Gateway API to v0.6.0. ([#5768](https://github.com/cert-manager/cert-manager/pull/5768), [@yulng](https://github.com/yulng)) +- Webhook now logs requests to mutating/validating webhook (with `--v=5` flag) ([#5975](https://github.com/cert-manager/cert-manager/pull/5975), [@tobotg](https://github.com/tobotg)) +- Certificate issuances are always failed (and retried with a backoff) for denied or invalid CertificateRequests. + This is not necessarily a breaking change as due to a race condition this may already have been the case. ([#5887](https://github.com/cert-manager/cert-manager/pull/5887), [@irbekrm](https://github.com/irbekrm)) +- The cainjector controller can now use server-side apply to patch mutatingwebhookconfigurations, validatingwebhookconfigurations, apiservices, and customresourcedefinitions. This feature is currently in alpha and is not enabled by default. To enable server-side apply for the cainjector, add the flag --feature-gates=ServerSideApply=true to the deployment. ([#5991](https://github.com/cert-manager/cert-manager/pull/5991), [@inteon](https://github.com/inteon)) +- Helm: Egress 6443/TCP is now allowed in the webhook. This is required for OpenShift and OKD clusters for which the Kubernetes API server listens on port 6443 instead of 443. ([#5788](https://github.com/cert-manager/cert-manager/pull/5788), [@ExNG](https://github.com/ExNG)) + +#### Documentation + +- Helm: the dead links in `values.yaml` are now working ([#5999](https://github.com/cert-manager/cert-manager/pull/5999), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +#### Bug or Regression + +- When using the `literalSubject` field on a Certificate resource, the IPs, URIs, DNS names, and email addresses segments are now properly compared. ([#5747](https://github.com/cert-manager/cert-manager/pull/5747), [@inteon](https://github.com/inteon)) +- When using the `jks` and `pkcs12` fields on a Certificate resource with a CA issuer that doesn't set the `ca.crt` in the Secret resource, cert-manager no longer loop trying to copy `ca.crt` into `truststore.jks` or `truststore.p12`. ([#5972](https://github.com/cert-manager/cert-manager/pull/5972), [@vinzent](https://github.com/vinzent)) +- Cmctl renew now prints an error message unless Certificate name(s) or --all are supplied ([#5896](https://github.com/cert-manager/cert-manager/pull/5896), [@maumontesilva](https://github.com/maumontesilva)) +- Fix development environment and go vendoring on Linux arm64. ([#5810](https://github.com/cert-manager/cert-manager/pull/5810), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix ordering of remote git tags when preparing integration tests ([#5910](https://github.com/cert-manager/cert-manager/pull/5910), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Helm: the flag `--acme-http01-solver-image` given to the variable `acmesolver.extraArgs` now has precedence over the variable `acmesolver.image`. ([#5693](https://github.com/cert-manager/cert-manager/pull/5693), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Ingress and Gateway resources will not be synced if deleted via [foreground cascading](https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion). ([#5878](https://github.com/cert-manager/cert-manager/pull/5878), [@avi-08](https://github.com/avi-08)) +- The auto-retry mechanism added in VCert 4.23.0 and part of cert-manager 1.11.0 (#5674) has been found to be faulty. Until this issue is fixed upstream, we now use a patched version of VCert. This patch will slowdown the issuance of certificates by 9% in case of heavy load on TPP. We aim to release at an ulterior date a patch release of cert-manager to fix this slowdown. ([#5805](https://github.com/cert-manager/cert-manager/pull/5805), [@inteon](https://github.com/inteon)) +- Upgrade to go 1.19.6 along with newer helm and containerd versions and updated base images ([#5813](https://github.com/cert-manager/cert-manager/pull/5813), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- cmctl: In order work around a hardcoded Kubernetes version in Helm, we now use a fake kube-apiserver version when generating the helm template when running `cmctl x install`. ([#5720](https://github.com/cert-manager/cert-manager/pull/5720), [@irbekrm](https://github.com/irbekrm)) + +#### Other (Cleanup or Flake) + +- ACME account registration is now re-verified if account key is manually changed. ([#5949](https://github.com/cert-manager/cert-manager/pull/5949), [@TrilokGeer](https://github.com/TrilokGeer)) +- Add `make go-workspace` target for generating a go.work file for local development ([#5935](https://github.com/cert-manager/cert-manager/pull/5935), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Added a Makefile target to build a standalone E2E test binary: make e2e-build ([#5804](https://github.com/cert-manager/cert-manager/pull/5804), [@wallrj](https://github.com/wallrj)) +- Bump keystore-go to v4.4.1 to work around an upstream rewrite of history ([#5724](https://github.com/cert-manager/cert-manager/pull/5724), [@g-gaston](https://github.com/g-gaston)) +- Bump the distroless base images ([#5929](https://github.com/cert-manager/cert-manager/pull/5929), [@maelvls](https://github.com/maelvls)) +- Bumps base images ([#5793](https://github.com/cert-manager/cert-manager/pull/5793), [@irbekrm](https://github.com/irbekrm)) +- The memory usage of the controller has been reduced by only caching the metadata of Pods and Services. ([#5976](https://github.com/cert-manager/cert-manager/pull/5976), [@irbekrm](https://github.com/irbekrm)) +- Cainjector memory improvements: removes second cache of secrets, CRDs, validating/mutatingwebhookconfigurations and APIServices that should reduce memory consumption by about half. + **BREAKING:** users who are relying on cainjector to work when `certificates.cert-manager.io` CRD is not installed in the cluster, now need to pass `--watch-certificates=false` flag to cainjector else it will not start. + Users who only use cainjector as cert-manager's internal component and have a large number of `Certificate` resources in cluster can pass `--watch-certificates=false` to avoid cainjector from caching `Certificate` resources and save some memory. ([#5746](https://github.com/cert-manager/cert-manager/pull/5746), [@irbekrm](https://github.com/irbekrm)) +- Cainjector now only reconciles annotated objects of injectable kind. ([#5764](https://github.com/cert-manager/cert-manager/pull/5764), [@irbekrm](https://github.com/irbekrm)) +- Container images are have an OCI source label ([#5722](https://github.com/cert-manager/cert-manager/pull/5722), [@james-callahan](https://github.com/james-callahan)) +- The acmesolver pods created by cert-manager now have `automountServiceAccountToken` turned off. ([#5754](https://github.com/cert-manager/cert-manager/pull/5754), [@wallrj](https://github.com/wallrj)) +- The controller memory usage has been further decreased by ignoring annotations, labels and managed fields when caching Secret resources. ([#5966](https://github.com/cert-manager/cert-manager/pull/5966), [@irbekrm](https://github.com/irbekrm)) +- The controller binary now uses much less memory on Kubernetes clusters with large or numerous Secret resources. The controller now ignores the contents of Secrets that aren't relevant to cert-manager. This functionality is currently placed behind `SecretsFilteredCaching` feature flag. The filtering mechanism might, in some cases, slightly slow down issuance or cause additional requests to kube-apiserver because unlabelled Secret resources that cert-manager controller needs will now be retrieved from kube-apiserver instead of being cached locally. To prevent this from happening, users can label all issuer Secret resources with the `controller.cert-manager.io/fao: true` label. ([#5824](https://github.com/cert-manager/cert-manager/pull/5824), [@irbekrm](https://github.com/irbekrm)) +- The controller now makes fewer calls to the ACME server. + **POTENTIALLY BREAKING**: this PR slightly changes how the name of the Challenge resources are calculated. To avoid duplicate issuances due to the Challenge resource being recreated, ensure that there is no in-progress ACME certificate issuance when you upgrade to this version of cert-manager. ([#5901](https://github.com/cert-manager/cert-manager/pull/5901), [@irbekrm](https://github.com/irbekrm)) +- The number of calls made to the ACME server during the controller startup has been reduced by storing the private key hash in the Issuer's status. ([#6006](https://github.com/cert-manager/cert-manager/pull/6006), [@vidarno](https://github.com/vidarno)) +- We are now testing with Kubernetes v1.27.1 by default. ([#5979](https://github.com/cert-manager/cert-manager/pull/5979), [@irbekrm](https://github.com/irbekrm)) +- Updates Kubernetes libraries to `v0.26.2`. ([#5820](https://github.com/cert-manager/cert-manager/pull/5820), [@lucacome](https://github.com/lucacome)) +- Updates Kubernetes libraries to `v0.26.3`. ([#5907](https://github.com/cert-manager/cert-manager/pull/5907), [@lucacome](https://github.com/lucacome)) +- Updates Kubernetes libraries to `v0.27.1`. ([#5961](https://github.com/cert-manager/cert-manager/pull/5961), [@lucacome](https://github.com/lucacome)) +- Updates base images ([#5832](https://github.com/cert-manager/cert-manager/pull/5832), [@irbekrm](https://github.com/irbekrm)) +- Upgrade to Go 1.20 ([#5969](https://github.com/cert-manager/cert-manager/pull/5969), [@wallrj](https://github.com/wallrj)) +- Upgrade to go 1.19.5 ([#5712](https://github.com/cert-manager/cert-manager/pull/5712), [@yanggangtony](https://github.com/yanggangtony)) +- Validates that `certificate.spec.secretName` is a valid `Secret` name ([#5967](https://github.com/cert-manager/cert-manager/pull/5967), [@avi-08](https://github.com/avi-08)) +- `certificate.spec.secretName` Secrets will now be labelled with `controller.cert-manager.io/fao` label ([#5660](https://github.com/cert-manager/cert-manager/pull/5660), [@irbekrm](https://github.com/irbekrm)) + +#### Uncategorized + +- We have replaced our python boilerplate checker with an installed Go version, removing the need to have Python installed when developing or building cert-manager. ([#6000](https://github.com/cert-manager/cert-manager/pull/6000), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +[^1]: fao = 'for attention of' diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.13.md b/content/v1.15-docs/releases/release-notes/release-notes-1.13.md new file mode 100644 index 0000000000..f2be0e347e --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.13.md @@ -0,0 +1,282 @@ +--- +title: Release 1.13 +description: 'cert-manager release notes: cert-manager 1.13' +--- + +## `v1.13.6` + +Special thanks to [@BobyMCbobs](https://github.com/BobyMCbobs) for reporting and testing the DigitalOcean issue! + +### Known Issues + +- ACME Issuer (Let's Encrypt): wrong certificate chain may be used if `preferredChain` is configured: see [1.14 release notes](./release-notes-1.14.md#known-issues) for more information. + +### Changes + +#### Bug or Regression + +- DigitalOcean: Ensure that only TXT records are considered for deletion when cleaning up after an ACME challenge ([#6892](https://github.com/cert-manager/cert-manager/pull/6892), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Bump `golang.org/x/net` to address [`CVE-2023-45288`](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) ([#6932](https://github.com/cert-manager/cert-manager/pull/6932), [@SgtCoDFish](https://github.com/SgtCoDFish)) + + +## `v1.13.5` + +### Known Issues +- ACME Issuer (Let's Encrypt): wrong certificate chain may be used if `preferredChain` is configured: see [1.14 release notes](./release-notes-1.14.md#known-issues) for more information. + +### Changes + +#### Bug or Regression + +- Allow `cert-manager.io/allow-direct-injection` in annotations ([#6810](https://github.com/cert-manager/cert-manager/pull/6810), [@jetstack-bot](https://github.com/jetstack-bot)) +- BUGFIX: JKS and PKCS12 stores now contain the full set of CAs specified by an issuer ([#6814](https://github.com/cert-manager/cert-manager/pull/6814), [@inteon](https://github.com/inteon)) +- BUGFIX: fix race condition due to registering and using global `runtime.Scheme` variables ([#6832](https://github.com/cert-manager/cert-manager/pull/6832), [@inteon](https://github.com/inteon)) + +#### Other (Cleanup or Flake) + +- Bump base images to the latest version. ([#6841](https://github.com/cert-manager/cert-manager/pull/6841), [@inteon](https://github.com/inteon)) +- Upgrade go to 1.21.8: fixes `CVE-2024-24783` ([#6824](https://github.com/cert-manager/cert-manager/pull/6824), [@inteon](https://github.com/inteon)) +- Upgrade `google.golang.org/protobuf`: fixing `GO-2024-2611` ([#6828](https://github.com/cert-manager/cert-manager/pull/6828), [@inteon](https://github.com/inteon)) + +## `v1.13.4` + +### Known Issues +- ACME Issuer (Let's Encrypt): wrong certificate chain may be used if `preferredChain` is configured: see [1.14 release notes](./release-notes-1.14.md#known-issues) for more information. + +### Changes + +#### Bug or Regression + +- BUGFIX: `LiteralSubjects` with a #= value can result in memory issues due to faulty BER parser (`github.com/go-asn1-ber/asn1-ber`). ([#6772](https://github.com/cert-manager/cert-manager/pull/6772), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Bump go to 1.20.14 ([#6736](https://github.com/cert-manager/cert-manager/pull/6736), [@jetstack-bot](https://github.com/jetstack-bot)) +- Cert-manager is now built with Go 1.20.12 ([#6544](https://github.com/cert-manager/cert-manager/pull/6544), [@wallrj](https://github.com/wallrj)) +- Cert-manager is now built with Go 1.20.13 ([#6630](https://github.com/cert-manager/cert-manager/pull/6630), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix CVE 2023 48795 by upgrading to golang.org/x/crypto@v0.17.0 ([#6675](https://github.com/cert-manager/cert-manager/pull/6675), [@wallrj](https://github.com/wallrj)) +- Fix `GHSA-7ww5-4wqc-m92c` by upgrading to `github.com/containerd/containerd@v1.7.12` ([#6684](https://github.com/cert-manager/cert-manager/pull/6684), [@wallrj](https://github.com/wallrj)) + +## `v1.13.3` + +This patch release contains fixes for the following security vulnerabilities in the cert-manager-controller: +- [`GO-2023-2334`](https://pkg.go.dev/vuln/GO-2023-2334): Decryption of malicious PBES2 JWE objects can consume unbounded system resources. + +If you use +[ArtifactHub Security report](https://artifacthub.io/packages/helm/cert-manager/cert-manager/1.13.2?modal=security-report) or +[trivy](https://trivy.dev/), +this patch will also silence the following warning +about a vulnerability in code which is imported but **not used** by the cert-manager-controller: +- [`CVE-2023-47108`](https://access.redhat.com/security/cve/CVE-2023-47108): DoS vulnerability in `otelgrpc` due to unbound cardinality metrics. + +An ongoing security audit of cert-manager suggested some changes to the webhook code to mitigate DoS attacks, +and these are included in this patch release. + +### Changes + +#### Bug or Regression + +- The webhook server now returns HTTP error 413 (Content Too Large) for requests with body size `>= 3MiB`. + This is to mitigate DoS attacks that attempt to crash the webhook process by sending large requests that exceed the available memory. + ([#6507](https://github.com/cert-manager/cert-manager/pull/6507), [@inteon](https://github.com/inteon)) +- The webhook server now returns HTTP error 400 (Bad Request) if the request contains an empty body. + ([#6507](https://github.com/cert-manager/cert-manager/pull/6507), [@inteon](https://github.com/inteon)) +- The webhook server now returns HTTP error 500 (Internal Server Error) rather than crashing, if the code panics while handling a request. + ([#6507](https://github.com/cert-manager/cert-manager/pull/6507), [@inteon](https://github.com/inteon)) +- Mitigate potential "Slowloris" attacks by setting `ReadHeaderTimeout` in all `http.Server` instances. + ([#6538](https://github.com/cert-manager/cert-manager/pull/6538), [@wallrj](https://github.com/wallrj)) +- Upgrade Go modules: `otel`, `docker`, and `jose` to fix CVE alerts. See + https://github.com/advisories/GHSA-8pgv-569h-w5rw, + https://github.com/advisories/GHSA-jq35-85cj-fj4p, and + https://github.com/advisories/GHSA-2c7c-3mj9-8fqh. + ([#6514](https://github.com/cert-manager/cert-manager/pull/6514), [@inteon](https://github.com/inteon)) + +### Dependencies + +#### Added +_Nothing has changed._ + +#### Changed +- `cloud.google.com/go/firestore`: `v1.11.0 → v1.12.0` +- `cloud.google.com/go`: `v0.110.6 → v0.110.7` +- `github.com/felixge/httpsnoop`: [`v1.0.3 → v1.0.4`](https://github.com/felixge/httpsnoop/compare/v1.0.3...v1.0.4) +- `github.com/go-jose/go-jose/v3`: [`v3.0.0 → v3.0.1`](https://github.com/go-jose/go-jose/v3/compare/v3.0.0...v3.0.1) +- `github.com/go-logr/logr`: [`v1.2.4 → v1.3.0`](https://github.com/go-logr/logr/compare/v1.2.4...v1.3.0) +- `github.com/golang/glog`: [`v1.1.0 → v1.1.2`](https://github.com/golang/glog/compare/v1.1.0...v1.1.2) +- `github.com/google/go-cmp`: [`v0.5.9 → v0.6.0`](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0) +- `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`: `v0.45.0 → v0.46.0` +- `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp`: `v0.44.0 → v0.46.0` +- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/exporters/otlp/otlptrace`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/metric`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/sdk`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel/trace`: `v1.19.0 → v1.20.0` +- `go.opentelemetry.io/otel`: `v1.19.0 → v1.20.0` +- `go.uber.org/goleak`: `v1.2.1 → v1.3.0` +- `golang.org/x/sys`: `v0.13.0 → v0.14.0` +- `google.golang.org/genproto/googleapis/api`: `f966b18 → b8732ec` +- `google.golang.org/genproto`: `f966b18 → b8732ec` +- `google.golang.org/grpc`: `v1.58.3 → v1.59.0` + +#### Removed +_Nothing has changed._ + +## `v1.13.2` + +v1.13.2 fixes some CVE alerts and contains fixes for: +1. a CertificateRequest runaway situation in case two Certificate resources point to the same Secret target resource +2. a small bug in the Helm chart (feature gate options) +3. a Venafi issuer bug + +### Changes + +#### Bug or Regression + +- Bump `golang.org/x/net v0.15.0 => v0.17.0` as part of addressing `CVE-2023-44487` / `CVE-2023-39325` ([#6432](https://github.com/cert-manager/cert-manager/pull/6432), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- BUGFIX[helm]: Fix issue where webhook feature gates were only set if controller feature gates are set. ([#6381](https://github.com/cert-manager/cert-manager/pull/6381), [@jetstack-bot](https://github.com/jetstack-bot)) +- Fix runaway bug caused by multiple Certificate resources that point to the same Secret resource. ([#6425](https://github.com/cert-manager/cert-manager/pull/6425), [@jetstack-bot](https://github.com/jetstack-bot)) +- The Venafi issuer now properly resets the certificate and should no longer get stuck with `WebSDK CertRequest Module Requested Certificate` or `This certificate cannot be processed while it is in an error state. Fix any errors, and then click Retry.`. ([#6402](https://github.com/cert-manager/cert-manager/pull/6402), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Bump go to 1.20.10 to address `CVE-2023-39325`. Also bumps base images. ([#6411](https://github.com/cert-manager/cert-manager/pull/6411), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## `v1.13.1` + +v1.13.1 contains a bugfix for a name collision bug in the StableCertificateRequestName feature that was enabled by default in v1.13.0. + +### Changes + +#### Bug or Regression + +- BUGFIX: fix CertificateRequest name collision bug in StableCertificateRequestName feature. ([#6358](https://github.com/cert-manager/cert-manager/pull/6358), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Upgrade `github.com/emicklei/go-restful/v3` to `v3.11.0` because `v3.10.2` is labeled as "DO NOT USE". ([#6368](https://github.com/cert-manager/cert-manager/pull/6368), [@inteon](https://github.com/inteon)) +- Upgrade Go from 1.20.7 to 1.20.8. ([#6370](https://github.com/cert-manager/cert-manager/pull/6370), [@jetstack-bot](https://github.com/jetstack-bot)) + +## `v1.13.0` + +cert-manager 1.13 brings support for DNS over HTTPS, support for loading options from a versioned +config file for the cert-manager controller, and more. This release also includes the promotion of +the `StableCertificateRequestName` and `SecretsFilteredCaching` feature gates to Beta. + +### Major Themes + +#### Load cert-manager controller options from a versioned config file + +It is now possible to load the cert-manager controller options from a versioned config file. +This was supported for the webhook already, but not for the controller. This is very useful +way to better manage these options and it allows us to change the options in the future without +breaking backwards compatibility by introducing a new config file version. + +#### DNS over HTTPS (DoH) support + +It is now possible to use DNS over HTTPS (DoH) for doing the self-checks during the ACME +DNS01 verification. The DNS self-check method to be used is controlled through the command line flag: +`--dns01-recursive-nameservers-only=true` in combination with +`--dns01-recursive-nameservers=https://` (e.g. `https://1.1.1.1/dns-query`) + +This is very useful in case all traffic must be HTTP(S) traffic, e.g. when using a `HTTPS_PROXY`. + +#### `StableCertificateRequestName` and `SecretsFilteredCaching` feature gates promoted to Beta + +The `StableCertificateRequestName` and `SecretsFilteredCaching` feature gates have been promoted to Beta. +This means that they are enabled by default and that we will not remove them in the future. In case you +are experiencing issues with these features, please let us know. The feature gates can still be disabled +by setting the feature gate to false (e.g. in case you are experiencing issues with these features). We +plan to promote these feature gates to GA in the future, which will mean that they can no longer be disabled. + +### Community + +Welcome to these new cert-manager members (more info - https://github.com/cert-manager/cert-manager/pull/6260): +@jsoref +@FlorianLiebhart +@hawksight +@erikgb + +Thanks again to all open-source contributors with commits in this release, including: +@AcidLeroy +@FlorianLiebhart +@lucacome +@cypres +@erikgb +@ubergesundheit +@jkroepke +@jsoref +@gdvalle +@rouke-broersma +@schrodit +@zhangzhiqiangcs +@arukiidou +@hawksight +@Richardds +@kahirokunn + +Thanks also to the following cert-manager maintainers for their contributions during this release: +@SgtCoDFish +@maelvls +@irbekrm +@inteon + +Equally thanks to everyone who provided feedback, helped users and raised issues on GitHub and Slack and joined our meetings! + +Special thanks to @AcidLeroy for adding "load options from a versioned config file" support for the cert-manager controller! This has been on our wishlist for a very long time. (see https://github.com/cert-manager/cert-manager/pull/5337) + +Also, thanks a lot to @FlorianLiebhart for adding support for DNS over HTTPS for the ACME DNS self-check. This is very useful in case all traffic must be HTTP(S) traffic, e.g. when using a `HTTPS_PROXY`. (see https://github.com/cert-manager/cert-manager/pull/5003) + +Thanks also to the [CNCF](https://www.cncf.io/), which provides resources and support, and to the AWS open source team for being good community members and for their maintenance of the [PrivateCA Issuer](https://github.com/cert-manager/aws-privateca-issuer). + +In addition, massive thanks to [Venafi](https://www.venafi.com/) for contributing developer time and resources towards the continued maintenance of cert-manager projects. + +### Changes + +#### Feature + +- Add support for logging options to webhook config file. (https://github.com/cert-manager/cert-manager/pull/6243, https://github.com/inteon) +- Add view permissions to the well-known (OpenShift) user-facing `cluster-reader` aggregated cluster role (https://github.com/cert-manager/cert-manager/pull/6241, https://github.com/erikgb) +- Certificate Shim: distinguish DNS names and IP address in certificate (https://github.com/cert-manager/cert-manager/pull/6267, https://github.com/zhangzhiqiangcs) +- Cmctl can now be imported by third parties. (https://github.com/cert-manager/cert-manager/pull/6049, https://github.com/SgtCoDFish) +- Make `enableServiceLinks` configurable for all Deployments and `startupapicheck` Job in Helm chart. (https://github.com/cert-manager/cert-manager/pull/6292, https://github.com/ubergesundheit) +- Promoted the `StableCertificateRequestName` and `SecretsFilteredCaching` feature gates to Beta (enabled by default). (https://github.com/cert-manager/cert-manager/pull/6298, https://github.com/inteon) +- The cert-manager controller options are now configurable using a configuration file. (https://github.com/cert-manager/cert-manager/pull/5337, https://github.com/AcidLeroy) +- The `pki.CertificateTemplate*` functions now perform validation of the CSR blob, making sure we sign a Certificate that matches the `IsCA` and `(Extended)KeyUsages` that are defined in the CertificateRequest resource. (https://github.com/cert-manager/cert-manager/pull/6199, https://github.com/inteon) +- [helm] Add `prometheus.servicemonitor.endpointAdditionalProperties` to define additional properties on a ServiceMonitor endpoint, e.g. relabelings (https://github.com/cert-manager/cert-manager/pull/6110, https://github.com/jkroepke) + +#### Design + +- DNS over HTTPS (DoH) is now possible for doing the self-checks during the ACME verification. + The DNS check method to be used is controlled through the command line flag: `--dns01-recursive-nameservers-only=true` in combination with `--dns01-recursive-nameservers=https://<` (e.g. `https://8.8.8.8/dns-query`). It keeps using DNS lookup as a default method. (https://github.com/cert-manager/cert-manager/pull/5003, https://github.com/FlorianLiebhart) + +#### Bug or Regression + +- Allow overriding default PDB `.minAvailable` with `.maxUnavailable` without setting `.minAvailable` to null (https://github.com/cert-manager/cert-manager/pull/6087, https://github.com/rouke-broersma) +- BUGFIX[ctl]: `cmctl check api --wait 0` exited without output and exit code 1; we now make sure we perform the API check at least once and return with the correct error code (https://github.com/cert-manager/cert-manager/pull/6109, https://github.com/inteon) +- BUGFIX[controller]: the issuer and certificate-name annotations on a Secret were incorrectly updated when other fields are changed. (https://github.com/cert-manager/cert-manager/pull/6147, https://github.com/inteon) +- BUGFIX[cainjector]: 1-character bug was causing invalid log messages and a memory leak (https://github.com/cert-manager/cert-manager/pull/6232, https://github.com/inteon) +- Fix CloudDNS issuers stuck in propagation check, when multiple instances are issuing for the same FQDN (https://github.com/cert-manager/cert-manager/pull/6088, https://github.com/cypres) +- Fix indentation of Webhook NetworkPolicy `matchLabels` in helm chart. (https://github.com/cert-manager/cert-manager/pull/6220, https://github.com/ubergesundheit) +- Fixed Cloudflare DNS01 challenge provider race condition when validating multiple domains (https://github.com/cert-manager/cert-manager/pull/6191, https://github.com/Richardds) +- Fixes a bug where webhook was pulling in controller's feature gates. + ⚠️ ⚠️ BREAKING ⚠️ ⚠️ : If you deploy cert-manager using helm and have `.featureGates` value set, the features defined there will no longer be passed to cert-manager webhook, only to cert-manager controller. Use `webhook.featureGates` field instead to define features to be enabled on webhook. + **Potentially breaking**: If you were, for some reason, passing cert-manager controller's features to webhook's `--feature-gates` flag, this will now break (unless the webhook actually has a feature by that name). (https://github.com/cert-manager/cert-manager/pull/6093, https://github.com/irbekrm) +- Fixes an issue where cert-manager would incorrectly reject two IP addresses as being unequal when they should have compared equal. This would be most noticeable when using an IPv6 address which doesn't match how Go's `net.IP.String()` function would have printed that address. (https://github.com/cert-manager/cert-manager/pull/6293, https://github.com/SgtCoDFish) +- We disabled the `enableServiceLinks` option for our ACME HTTP solver pods, because the option caused the pod to be in a crash loop in a cluster with lot of services. (https://github.com/cert-manager/cert-manager/pull/6143, https://github.com/schrodit) +- ⚠️ possibly breaking: Webhook validation of CertificateRequest resources is stricter now: all `KeyUsages` and `ExtendedKeyUsages` must be defined directly in the CertificateRequest resource, the encoded CSR can never contain more usages that defined there. (https://github.com/cert-manager/cert-manager/pull/6182, https://github.com/inteon) + +#### Other (Cleanup or Flake) + +- A subset of the klog flags have been deprecated and will be removed in the future. (https://github.com/cert-manager/cert-manager/pull/5879, https://github.com/maelvls) +- All service links in helm chart deployments have been disabled. (https://github.com/cert-manager/cert-manager/pull/6144, https://github.com/schrodit) +- Cert-manager will now re-issue a certificate if the public key in the latest CertificateRequest resource linked to a Certificate resource does not match the public key of the key encoded in the Secret linked to that Certificate resource (https://github.com/cert-manager/cert-manager/pull/6168, https://github.com/inteon) +- Chore: When `hostNetwork` is enabled, `dnsPolicy` is now set to `ClusterFirstWithHostNet`. (https://github.com/cert-manager/cert-manager/pull/6156, https://github.com/kahirokunn) +- Cleanup the controller config file structure by introducing nested structs. (https://github.com/cert-manager/cert-manager/pull/6242, https://github.com/inteon) +- Don't run API Priority and Fairness controller in webhook's extension apiserver (https://github.com/cert-manager/cert-manager/pull/6085, https://github.com/irbekrm) +- Helm: Add apache 2.0 license annotation (https://github.com/cert-manager/cert-manager/pull/6225, https://github.com/arukiidou) +- Make `apis/acme/v1/ACMEIssuer.PreferredChain` optional in JSON serialization. (https://github.com/cert-manager/cert-manager/pull/6034, https://github.com/gdvalle) +- The `SecretPostIssuancePolicyChain` now also makes sure that the `cert-manager.io/common-name`, `cert-manager.io/alt-names`, ... annotations on Secrets are kept at their correct value. (https://github.com/cert-manager/cert-manager/pull/6176, https://github.com/inteon) +- The cmctl logging has been improved and support for JSON logging has been added. (https://github.com/cert-manager/cert-manager/pull/6247, https://github.com/inteon) +- Updates Kubernetes libraries to `v0.27.2`. (https://github.com/cert-manager/cert-manager/pull/6077, https://github.com/lucacome) +- Updates Kubernetes libraries to `v0.27.4`. (https://github.com/cert-manager/cert-manager/pull/6227, https://github.com/lucacome) +- We now only check that the issuer name, kind and group annotations on a Secret match in case those annotations are set. (https://github.com/cert-manager/cert-manager/pull/6152, https://github.com/inteon) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.14.md b/content/v1.15-docs/releases/release-notes/release-notes-1.14.md new file mode 100644 index 0000000000..14b599d374 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.14.md @@ -0,0 +1,659 @@ +--- +title: Release 1.14 +description: 'cert-manager release notes: cert-manager 1.14' +--- + +cert-manager 1.14 brings a variety of [features](#feature), [security improvements](#security) and [bug fixes](#bug-or-regression-1), including: +support for creating [X.509 certificates with "Other Name" fields](#new-x509-features), and +support for creating [CA certificates with "Name Constraints" and "Authority Information Accessors" extensions](#new-ca-certificate-features). + +> 📢 The cert-manager CLI is moving to a new GitHub repository +> +> After this release, `cmctl` will no longer be released with `cert-manager` itself, +> and there will no further `quay.io/jetstack/cert-manager-ctl` OCI images. +> +> Read [The cert-manager Command Line Tool (cmctl) page](../../reference/cmctl.md) to learn more. + +### Known Issues + +#### ACME Issuer (Let's Encrypt): wrong certificate chain may be used if `preferredChain` is configured - [#6755](https://github.com/cert-manager/cert-manager/pull/6755), [#6757](https://github.com/cert-manager/cert-manager/issues/6757) + +On Thursday, Feb 8th, 2024, [Let's Encrypt stopped providing their cross-signed certificate chain by default](https://letsencrypt.org/2023/07/10/cross-sign-expiration), in requests made to their `/acme/certificate` API endpoint. +Instead the short-chain is returned by default and the long-chain (cross-signed) certificate chain is now included among the ["alternate" chains](https://www.rfc-editor.org/rfc/rfc8555#section-7.4.2). +The cert-manager ACME Issuer API has a `preferredChain` field since [`v1.0.0`](https://github.com/cert-manager/cert-manager/releases/tag/v1.0.0), which is [documented](../../reference/api-docs.md#acme.cert-manager.io/v1.ACMEIssuer) as follows: + +> `PreferredChain` is the chain to use if the ACME server outputs multiple. `PreferredChain` is no guarantee that this one gets delivered by the ACME endpoint. For example, for Let’s Encrypt’s DST cross sign you would use: “DST Root CA X3” or “ISRG Root X1” for the newer Let’s Encrypt root CA. This value picks the first certificate bundle in the ACME alternative chains that has a certificate with this value as its issuer’s CN. + +The problem is that the `preferredChain` feature matches the issuer CN of **any** certificate in the chain. +The result is that: +**Some** users who set `Isser.spec.acme.preferredChain: ISRG Root X1` in order to get early access to the Let's Encrypt short-chain certificates, will get long-chain (cross-signed) certificates when they renew after February 8th, 2024. +But **most** users will not be affected. Their new certificates will contain the short-chain (not cross-signed) which terminates at `ISRG Root X1`. + +The cert-manager maintainers are considering how to address this problem for the next release (1.15), +without breaking users who have come to rely on the existing, documented behavior. + +> 🔖 Read [cert-manager PR 6755 (bugfix: wrong certificate chain is used if `preferredChain` is configured)](https://github.com/cert-manager/cert-manager/pull/6755) to learn about the bug and to see the proposed fix. +> +> 🔖 Read [Let’s Encrypt: chain of trust](https://letsencrypt.org/certificates/) to learn about the hierarchy of root and intermediate certificates. + +##### Workarounds + +* **You can remove the `spec.acme.preferredChainChain: ISRG Root X1` field** from the `Issuer` or `ClusterIssuer`. + And then renew any certificates which use that issuer and which have been renewed since Feb 8th, 2024. + The new certificates will have a shorter chain which terminates at the self-signed root certificate for `ISRG Root X1`. + +* **You can do nothing**. + The affected certificates will have a longer chain which terminates at `DST Root CA X3` and + which contains the cross-signed intermediate certificate for `ISRG Root X1`, which expires on September 30th, 2024. + But that's OK as long as `DST Root CA X3` is trusted by your clients. + And your 90 day leaf certificate is certain to be be renewed before that date, + and certain to be renewed **after** June 6th, 2024, on which day Let's Encrypt will + stop providing the longer cross-signed chain entirely. + + > ⚠️ There may be [clients that are incompatible with `DST Root CA X3`](https://github.com/mono/mono/issues/21233). + +## `v1.14.7` + +### Bugfixes + +- BUGFIX: fix issue that caused Vault issuer to not retry signing when an error was encountered. ([#7114](https://github.com/cert-manager/cert-manager/pull/7114), [@cert-manager-bot](https://github.com/cert-manager-bot)) + +### Other (Cleanup or Flake) + +- Upgrade `go-jose` library to fix `CVE-2024-28180` trivy alert. ([#7109](https://github.com/cert-manager/cert-manager/pull/7109), [@inteon](https://github.com/inteon)) +- Update `github.com/Azure/azure-sdk-for-go/sdk/azidentity` to address `CVE-2024-35255` ([#7099](https://github.com/cert-manager/cert-manager/pull/7099), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) + +## `v1.14.6` + +## Changes by Kind + +### Other (Cleanup or Flake) + +- Upgrade Go to 1.21.10, fixing `GO-2024-2824` (https://github.com/advisories/GHSA-2jwv-jmq4-4j3r). ([#7008](https://github.com/cert-manager/cert-manager/pull/7008), [@inteon](https://github.com/inteon)) +- Helm BUGFIX: the cainjector ConfigMap was not mounted in the cainjector deployment. ([#7053](https://github.com/cert-manager/cert-manager/pull/7053), [@cert-manager-bot](https://github.com/cert-manager-bot)) +- Updated Go to 1.21.11 bringing in security fixes for `archive/zip` and `net/netip`. ([#7076](https://github.com/cert-manager/cert-manager/pull/7076), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) + +## `v1.14.5` + +Special thanks to [@BobyMCbobs](https://github.com/BobyMCbobs) for reporting and testing the DigitalOcean issue! + +### Known Issues + +- ACME Issuer (Let's Encrypt): wrong certificate chain may be used if `preferredChain` is configured: see [1.14 release notes](./release-notes-1.14.md#known-issues) for more information. + +### Changes + +#### Bug or Regression + +- DigitalOcean: Ensure that only TXT records are considered for deletion when cleaning up after an ACME challenge ([#6893](https://github.com/cert-manager/cert-manager/pull/6893), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Bump `golang.org/x/net` to address [`CVE-2023-45288`](https://nvd.nist.gov/vuln/detail/CVE-2023-45288) ([#6931](https://github.com/cert-manager/cert-manager/pull/6931), [@SgtCoDFish](https://github.com/SgtCoDFish)) + + +## `v1.14.4` + +> 📢 When upgrading to cert-manager release 1.14, please skip `v1.14.0`, `v1.14.1`, `v1.14.2` and `v1.14.3` and install this patch version instead. + +### Changes since `v1.14.3` + +#### Bug or Regression + +- Allow `cert-manager.io/allow-direct-injection` in annotations ([#6809](https://github.com/cert-manager/cert-manager/pull/6809), [@jetstack-bot](https://github.com/jetstack-bot)) +- BUGFIX: JKS and PKCS12 stores now contain the full set of CAs specified by an issuer ([#6812](https://github.com/cert-manager/cert-manager/pull/6812), [@jetstack-bot](https://github.com/jetstack-bot)) +- BUGFIX: cainjector leader election flag/ config option defaults are missing ([#6819](https://github.com/cert-manager/cert-manager/pull/6819), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Bump base images. ([#6842](https://github.com/cert-manager/cert-manager/pull/6842), [@inteon](https://github.com/inteon)) +- Upgrade Helm: fix `CVE-2024-26147` alert ([#6834](https://github.com/cert-manager/cert-manager/pull/6834), [@inteon](https://github.com/inteon)) +- Upgrade go to 1.21.8: fixes `CVE-2024-24783` ([#6825](https://github.com/cert-manager/cert-manager/pull/6825), [@jetstack-bot](https://github.com/jetstack-bot)) +- Upgrade `google.golang.org/protobuf`: fixing `GO-2024-2611` ([#6829](https://github.com/cert-manager/cert-manager/pull/6829), [@inteon](https://github.com/inteon)) + +## `v1.14.3` + +### Changes since `v1.14.2` + +#### Bug or Regression + +- BUGFIX: Fixes issue with JSON-logging, where only a subset of the log messages were output as JSON. ([#6781](https://github.com/cert-manager/cert-manager/pull/6781), [@jetstack-bot](https://github.com/jetstack-bot)) +- BUGFIX: `LiteralSubjects` with a #= value can result in memory issues due to faulty BER parser (`github.com/go-asn1-ber/asn1-ber`). ([#6774](https://github.com/cert-manager/cert-manager/pull/6774), [@jetstack-bot](https://github.com/jetstack-bot)) + +## `v1.14.2` + +### Changes since `v1.14.1` + +#### Bug or Regression + +- BUGFIX: cert-manager CA and SelfSigned issuers incorrectly copied the critical flag from the CSR instead of re-calculating that field themselves. ([#6727](https://github.com/cert-manager/cert-manager/pull/6727), [@jetstack-bot](https://github.com/jetstack-bot)) +- Helm: Fix a bug in the logic that differentiates between 0 and an empty value. ([#6729](https://github.com/cert-manager/cert-manager/pull/6729), [@jetstack-bot](https://github.com/jetstack-bot)) + +#### Other (Cleanup or Flake) + +- Bump Go to 1.21.7 ([#6735](https://github.com/cert-manager/cert-manager/pull/6735), [@jetstack-bot](https://github.com/jetstack-bot)) + +## `v1.14.1` + +cert-manager `v1.14.1` fixes bugs found *during* the release of `v1.14.0`. + +### Changes since `v1.14.0` + +#### Bug or Regression + +- Fix broken cainjector image value in Helm chart ([#6693](https://github.com/cert-manager/cert-manager/pull/6693), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix bug in cmctl namespace detection which prevented it being used as a startupapicheck image in namespaces other than cert-manager. ([#6706](https://github.com/cert-manager/cert-manager/pull/6706), [@inteon](https://github.com/inteon)) +- Fix bug in cmctl which caused `cmctl experimental install` to panic. ([#6706](https://github.com/cert-manager/cert-manager/pull/6706), [@inteon](https://github.com/inteon)) + +## `v1.14.0` + +> ⚠️ This version has known issues. +> +> During the release of `v1.14.0`, the Helm chart was found to use the wrong OCI image for the `cainjector` Deployment, +> which caused the Helm installation and the static manifest based installation to fail. +> Upon discovery of this bug, the release of `v1.14.0` was paused before the Helm chart or GitHub release were published; +> but the Git tag and the OCI images had already been published. +> +> The cert-manager team next fixed the Helm chart and two other bugs which are listed in the "Known Issues" section below, +> and then released `v1.14.1`, which is the version that users are strongly advised to install when they upgrade to 1.14. +> +> In order to complete the stalled `v1.14.0` release, +> the Helm chart and static YAML installation files were regenerated on a team member's laptop, +> using exactly the same build scripts as are used in the automated release process, +> and using the `v1.14.1` version of the code. +> The working `v1.14.0` Helm chart was published, +> and the working versions of the static manifest files attached to the draft `v1.14.0` GitHub release, +> and that was then published. +> +> For these reasons, users are strongly advised to skip this version and install the latest patch Helm chart instead. + +### Known Issues +- During the release of `v1.14.0`, the Helm chart for this version was found to use the wrong OCI image for the `cainjector` Deployment, + which caused the Helm installation to fail. + In order to complete the release, the cert-manager team have manually updated the Helm chart for this version, + which contains all the Helm chart fixes which are in `v1.14.1`. + But users are strongly advised to skip this version and install the `v1.14.1` Helm chart instead. +- A bug in cmctl namespace detection prevents it being used as a `startupapicheck` image in namespaces other than cert-manager. +- A bug in cmctl causes `cmctl experimental install` to panic. + +### Breaking Changes + +The startupapicheck job uses a new OCI image called "startupapicheck", instead of the ctl image. +If you run in an environment in which images cannot be pulled, be sure to include the new image. + +The KeyUsage and BasicConstraints extensions will now be encoded as critical in the CertificateRequest's CSR blob. + +### Major Themes + +#### New X.509 Features + +The cert-manager [Certificate resource](../../usage/certificate.md##creating-certificate-resources) now allows you to [configure a subset of "Other Name" SANs](../../reference/api-docs.md#cert-manager.io/v1.OtherName), +which are described in the [Subject Alternative Name section of RFC 5280](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6) (on page 37). + +We specifically support any `otherName` type with a `UTF-8` value, such as the [User Principal Name](https://docs.venafi.com/Docs/current/TopNav/Content/Certificates/r-UEP-support-SANs.php) or [`sAMAccountName`](https://learn.microsoft.com/en-us/windows/win32/ad/naming-properties). +These are useful when issuing unique certificates for authenticating with LDAP systems such as Microsoft Active Directory. +For example you can create certificates with this block in the spec: +``` + otherNames: + - oid: 1.3.6.1.4.1.311.20.2.3 # UPN OID + utf8Value: upn@domain.local +``` +The feature is still in alpha stage and requires you to [enable the `OtherNames` feature flag in the controller and webhook components](../../installation/configuring-components.md#feature-gates). + +#### New CA certificate Features + +You can now specify the [X.509 v3 Authority Information Accessors](https://www.rfc-editor.org/rfc/rfc5280#section-4.2.2.1) extension, +with URLs for certificates issued by the [CA Issuer](../../configuration/ca.md), +using the new [`issuingCertificateURLs` field](../../reference/api-docs.md#cert-manager.io/v1.CAIssuer). + +Users can now [use name constraints in CA certificates](../../usage/certificate.md#creating-certificate-with-name-constraints). +To know more details on name constraints check out [RFC5280 section 4.2.1.10](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10). + +#### Security + +An [ongoing CNCF security audit of the cert-manager code](https://github.com/cert-manager/cert-manager/issues/6132) revealed some weaknesses which we have addressed in this release, +such as using more secure default settings in the HTTP servers that serve metrics, healthz and pprof endpoints. +This will help mitigate denial-of-service attacks against those important services. + +All the cert-manager containers are now configured with [read only root file system](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) by default, +to prevent unexpected changes to the file system of the OCI image. + +And it is now possible to [configure the metrics server to use HTTPS](../../devops-tips/prometheus-metrics.md#tls) rather than HTTP, +so that clients can verify the identity of the metrics server. + +#### Other + +The liveness probe of the cert-manager controller Pod is now enabled by default. + +There is a new option `.spec.keystores.pkcs12.profile` to specify encryption and HMAC algorithms for PKCS keystores. +See the [API reference](../../../docs/reference/api-docs.md#cert-manager.io/v1.PKCS12Profile) for configuration options. + +### Community + +Thanks again to all open-source contributors with commits in this release, including: +- [@ABWassim](https://github.com/ABWassim) +- [@JoeNorth](https://github.com/JoeNorth) +- [@allenmunC1](https://github.com/allenmunC1) +- [@asapekia](https://github.com/asapekia) +- [@jeremycampbell](https://github.com/jeremycampbell) +- [@jkroepke](https://github.com/jkroepke) +- [@jsoref](https://github.com/jsoref) +- [@lauraseidler](https://github.com/lauraseidler) +- [@pevidex](https://github.com/pevidex) +- [@phillebaba](https://github.com/phillebaba) +- [@snorwin](https://github.com/snorwin) +- [@tanujd11](https://github.com/tanujd11) +- [@tberreis](https://github.com/tberreis) +- [@vinny](https://github.com/vinny) + +Thanks also to the following cert-manager maintainers for their contributions during this release: +- [@SgtCoDFish](https://github.com/SgtCoDFish) +- [@SpectralHiss](https://github.com/SpectralHiss) +- [@ThatsMrTalbot](https://github.com/ThatsMrTalbot) +- [@hawksight](https://github.com/hawksight) +- [@inteon](https://github.com/inteon) +- [@maelvls](https://github.com/maelvls) +- [@wallrj](https://github.com/wallrj) + +Equally thanks to everyone who provided feedback, helped users and raised issues on GitHub and Slack and joined our meetings! + +Thanks also to the [CNCF](https://www.cncf.io/), which provides resources and support, and to the AWS open source team for being good community members and for their maintenance of the [PrivateCA Issuer](https://github.com/cert-manager/aws-privateca-issuer). + +In addition, massive thanks to [Venafi](https://www.venafi.com/) for contributing developer time and resources towards the continued maintenance of cert-manager projects. + +### Changes + +#### Feature + +- ACME challenge solver Pod for HTTP01 will get a default annotation of `"cluster-autoscaler.kubernetes.io/safe-to-evict": "true"`. You can provide an annotation of `"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"` in your `podTemplate` if you don't like this. ([#6349](https://github.com/cert-manager/cert-manager/pull/6349), [@jsoref](https://github.com/jsoref)) +- Added a clock skew detector liveness probe that will force a restart in case we detect a skew between the internal monotonic clock and the system clock of more than 5 minutes. + Also, the controller's liveness probe is now enabled by default. ([#6328](https://github.com/cert-manager/cert-manager/pull/6328), [@inteon](https://github.com/inteon)) +- Added a new flag (--dynamic-serving-leaf-duration) that can adjust the lifetime of the dynamic leaf certificates ([#6552](https://github.com/cert-manager/cert-manager/pull/6552), [@allenmunC1](https://github.com/allenmunC1)) +- Added support for `otherName` SANS in Certificates ([#6404](https://github.com/cert-manager/cert-manager/pull/6404), [@SpectralHiss](https://github.com/SpectralHiss)) +- Added the option to specify the X.509 v3 Authority Information Accessors extension CA Issuers URLs for certificates issued by the CA issuer. ([#6486](https://github.com/cert-manager/cert-manager/pull/6486), [@jeremycampbell](https://github.com/jeremycampbell-okta)) +- Adds cert-manager's new core infrastructure initiative badge! See more details on https://www.bestpractices.dev/projects/8079 ([#6497](https://github.com/cert-manager/cert-manager/pull/6497), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- All Pods are now configured with `readOnlyRootFilesystem` by default. ([#6453](https://github.com/cert-manager/cert-manager/pull/6453), [@wallrj](https://github.com/wallrj)) +- MAYBE BREAKING: The startupapicheck job is now handled by an entirely new container called "startupapicheck". This replaces the previous ctl container. If you run in an environment in which images cannot be pulled, be sure to include the new container. ([#6549](https://github.com/cert-manager/cert-manager/pull/6549), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- New option `.spec.keystores.pkcs12.algorithms` to specify encryption and MAC algorithms for PKCS[#12](https://github.com/cert-manager/cert-manager/pull/12) keystores. Fixes issues [#5957](https://github.com/cert-manager/cert-manager/pull/5957) and [#6523](https://github.com/cert-manager/cert-manager/pull/6523). ([#6548](https://github.com/cert-manager/cert-manager/pull/6548), [@snorwin](https://github.com/snorwin)) +- The ACME HTTP01 solver Pod is now configured with `readOnlyRootFilesystem: true` ([#6462](https://github.com/cert-manager/cert-manager/pull/6462), [@wallrj](https://github.com/wallrj)) +- Updates the AWS SDK for Go to 1.48.7 to support Amazon EKS Pod Identity ([#6519](https://github.com/cert-manager/cert-manager/pull/6519), [@JoeNorth](https://github.com/JoeNorth)) +- Users can now use name constraints in CA certificates. To know more details on name constraints check out RFC section https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10 ([#6500](https://github.com/cert-manager/cert-manager/pull/6500), [@tanujd11](https://github.com/tanujd11)) +- ⚠️ potentially breaking ⚠️: The KeyUsage and BasicConstraints extensions will now be encoded as critical in the CertificateRequest's CSR blob. ([#6053](https://github.com/cert-manager/cert-manager/pull/6053), [@inteon](https://github.com/inteon)) +- Add TLS support to the metrics endpoint through either a certificate file or through dynamically issued certificates ([#6574](https://github.com/cert-manager/cert-manager/pull/6574), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Helm Chart: allow changing the default Deployment `revisionHistoryLimit` ([#6248](https://github.com/cert-manager/cert-manager/pull/6248), [@tberreis](https://github.com/tberreis)) +- Security: Limit the size of the response body read from HTTP requests by cert-manager. ([#6619](https://github.com/cert-manager/cert-manager/pull/6619), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Support custom `spec.namespaceSelector` for webhooks ([#6638](https://github.com/cert-manager/cert-manager/pull/6638), [@jkroepke](https://github.com/jkroepke)) + +#### Bug or Regression + +- BUGFIX[helm]: Fix issue where webhook feature gates were only set if controller feature gates are set. ([#6380](https://github.com/cert-manager/cert-manager/pull/6380), [@asapekia](https://github.com/asapekia)) +- Controller ConfigMap is now created only if `.Values.config` is set. ([#6357](https://github.com/cert-manager/cert-manager/pull/6357), [@ABWassim](https://github.com/ABWassim)) +- Fix runaway bug caused by multiple Certificate resources that point to the same Secret resource. ([#6406](https://github.com/cert-manager/cert-manager/pull/6406), [@inteon](https://github.com/inteon)) +- Fix(helm): templating of required value in controller and webhook ConfigMap resources ([#6435](https://github.com/cert-manager/cert-manager/pull/6435), [@ABWassim](https://github.com/ABWassim)) +- Fixed a webhook validation error message when the key algorithm was invalid. ([#6571](https://github.com/cert-manager/cert-manager/pull/6571), [@pevidex](https://github.com/pevidex)) +- Fixed error messaging when setting up vault issuer ([#6433](https://github.com/cert-manager/cert-manager/pull/6433), [@vinny](https://github.com/vinny-sabatini)) +- `GHSA-vgf6-pvf4-34rq`: The webhook server now returns HTTP error 413 (Content Too Large) for requests with body size `>= 3MiB`. This is to mitigate DoS attacks that attempt to crash the webhook process by sending large requests that exceed the available memory. + The webhook server now returns HTTP error 400 (Bad Request) if the request contains an empty body. + The webhook server now returns HTTP error 500 (Internal Server Error) rather than crashing, if the code panics while handling a request. ([#6498](https://github.com/cert-manager/cert-manager/pull/6498), [@inteon](https://github.com/inteon)) +- Increase the default webhook timeout to its maximum value of 30 seconds, so that the underlying timeout error message has more chance of being returned to the end user. ([#6488](https://github.com/cert-manager/cert-manager/pull/6488), [@wallrj](https://github.com/wallrj)) +- Listeners that do not support TLS on Gateway resources will now not raise `BadConfig` warnings anymore ([#6347](https://github.com/cert-manager/cert-manager/pull/6347), [@lauraseidler](https://github.com/lauraseidler)) +- Mitigate potential Slowloris attacks by setting `ReadHeaderTimeout` in all `http.Server` instances ([#6534](https://github.com/cert-manager/cert-manager/pull/6534), [@wallrj](https://github.com/wallrj)) +- The Venafi issuer now properly resets the certificate and should no longer get stuck with `WebSDK CertRequest Module Requested Certificate` or `This certificate cannot be processed while it is in an error state. Fix any errors, and then click Retry.`. ([#6398](https://github.com/cert-manager/cert-manager/pull/6398), [@maelvls](https://github.com/maelvls)) +- Update experimental install and uninstall commands to have flag parity with the rest of the CLI ([#6562](https://github.com/cert-manager/cert-manager/pull/6562), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Webhook ConfigMap if now created only if `.Values.webhook.config` is set. ([#6360](https://github.com/cert-manager/cert-manager/pull/6360), [@ABWassim](https://github.com/ABWassim)) +- BUGFIX: Ensure `otherName` SAN changes in Certificate resources trigger re-issuance. ([#6620](https://github.com/cert-manager/cert-manager/pull/6620), [@SpectralHiss](https://github.com/SpectralHiss)) +- Bugfix: Publish the `startupapicheck` image to `quay.io` ([#6609](https://github.com/cert-manager/cert-manager/pull/6609), [@wallrj](https://github.com/wallrj)) + +#### Other (Cleanup or Flake) + +- Cert-manager is now built with Go 1.21.5 ([#6545](https://github.com/cert-manager/cert-manager/pull/6545), [@wallrj](https://github.com/wallrj)) +- Bump Go to `1.21.3` to address `CVE-2023-39325`. Also bumps base images. ([#6410](https://github.com/cert-manager/cert-manager/pull/6410), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Bump `golang.org/x/net v0.15.0 => v0.17.0` as part of addressing `CVE-2023-44487` / `CVE-2023-39325` ([#6427](https://github.com/cert-manager/cert-manager/pull/6427), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Check code for unintended use of `crypto/md5`, a weak cryptographic primitive; using `golangci-lint` / `gosec` (G501). ([#6581](https://github.com/cert-manager/cert-manager/pull/6581), [@wallrj](https://github.com/wallrj)) +- Check code for unintended use of `crypto/sha1`, a weak cryptographic primitive; using `golangci-lint` / `gosec` (G505). ([#6579](https://github.com/cert-manager/cert-manager/pull/6579), [@wallrj](https://github.com/wallrj)) +- Check code for unintended use of weak random number generator (`math/rand` instead of `crypto/rand`); using `golangci-lint` / `gosec` (G404). ([#6582](https://github.com/cert-manager/cert-manager/pull/6582), [@wallrj](https://github.com/wallrj)) +- Cleanup: Restrict MutatingWebhookConfiguration to only CertificateRequest resources ([#6311](https://github.com/cert-manager/cert-manager/pull/6311), [@hawksight](https://github.com/hawksight)) +- Deprecated `pkg/util.RandStringRunes` and `pkg/controller/test.RandStringBytes`. Use `k8s.io/apimachinery/pkg/util/rand.String` instead. ([#6585](https://github.com/cert-manager/cert-manager/pull/6585), [@wallrj](https://github.com/wallrj)) +- Enabled verbose logging in startupapicheck by default, so that if it fails, users can know exactly what caused the failure. ([#6495](https://github.com/cert-manager/cert-manager/pull/6495), [@wallrj](https://github.com/wallrj)) +- Fix gosec G601: Implicit memory aliasing of items from a range statement ([#6551](https://github.com/cert-manager/cert-manager/pull/6551), [@wallrj](https://github.com/wallrj)) +- Fix handling of serial numbers in literal certificate subjects. Previously a serial number could be specified in `subject.serialNumber` while using a literal certificate subject. This was a mistake and has been fixed. ([#6533](https://github.com/cert-manager/cert-manager/pull/6533), [@inteon](https://github.com/inteon)) +- The end-to-end tests can now test the cert-manager Vault Issuer on an OpenShift cluster. ([#6391](https://github.com/cert-manager/cert-manager/pull/6391), [@wallrj](https://github.com/wallrj)) +- Update cert-manager's distroless base images from Debian 11 to Debian 12. This should have no practical effects on users. ([#6583](https://github.com/cert-manager/cert-manager/pull/6583), [@inteon](https://github.com/inteon)) +- Updated all code using GatewayAPI to use the now GA v1 APIs ([#6559](https://github.com/cert-manager/cert-manager/pull/6559), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Upgrade Go from 1.20.7 to 1.20.8. ([#6369](https://github.com/cert-manager/cert-manager/pull/6369), [@inteon](https://github.com/inteon)) +- Upgrade `github.com/emicklei/go-restful/v3` to `v3.11.0` because `v3.10.2` is labeled as "DO NOT USE". ([#6366](https://github.com/cert-manager/cert-manager/pull/6366), [@inteon](https://github.com/inteon)) +- Use the new generic `sets.Set` type in place of the deprecated `sets.String`. ([#6586](https://github.com/cert-manager/cert-manager/pull/6586), [@wallrj](https://github.com/wallrj)) +- cert-manager is now built with Go `v1.21.6` ([#6628](https://github.com/cert-manager/cert-manager/pull/6628), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Update the Azure SDK and remove deprecated `autorest` dependency ([#5452](https://github.com/cert-manager/cert-manager/pull/5452), [@phillebaba](https://github.com/phillebaba)) +- The cert-manager E2E tests can now be run on Kubernetes 1.29 ([#6641](https://github.com/cert-manager/cert-manager/pull/6641), [@wallrj](https://github.com/wallrj)) + +### Dependencies + +#### Added +- `cloud.google.com/go/cloudsqlconn`: `v1.4.3` +- `github.com/Azure/azure-sdk-for-go/sdk/azcore`: [`v1.9.1`](https://github.com/Azure/azure-sdk-for-go/sdk/azcore/tree/v1.9.1) +- `github.com/Azure/azure-sdk-for-go/sdk/azidentity`: [`v1.4.0`](https://github.com/Azure/azure-sdk-for-go/sdk/azidentity/tree/v1.4.0) +- `github.com/Azure/azure-sdk-for-go/sdk/internal`: [`v1.5.1`](https://github.com/Azure/azure-sdk-for-go/sdk/internal/tree/v1.5.1) +- `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns`: [`v1.2.0`](https://github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns/tree/v1.2.0) +- `github.com/AzureAD/microsoft-authentication-library-for-go`: [`v1.1.1`](https://github.com/AzureAD/microsoft-authentication-library-for-go/tree/v1.1.1) +- `github.com/Masterminds/goutils`: [`v1.1.1`](https://github.com/Masterminds/goutils/tree/v1.1.1) +- `github.com/Masterminds/semver/v3`: [`v3.1.1`](https://github.com/Masterminds/semver/v3/tree/v3.1.1) +- `github.com/Masterminds/sprig/v3`: [`v3.2.1`](https://github.com/Masterminds/sprig/v3/tree/v3.2.1) +- `github.com/Venafi/vcert/v5`: [`v5.3.0`](https://github.com/Venafi/vcert/v5/tree/v5.3.0) +- `github.com/dnaeon/go-vcr`: [`v1.2.0`](https://github.com/dnaeon/go-vcr/tree/v1.2.0) +- `github.com/golang-jwt/jwt/v5`: [`v5.0.0`](https://github.com/golang-jwt/jwt/v5/tree/v5.0.0) +- `github.com/hashicorp/go-secure-stdlib/plugincontainer`: [`v0.2.2`](https://github.com/hashicorp/go-secure-stdlib/plugincontainer/tree/v0.2.2) +- `github.com/huandu/xstrings`: [`v1.3.2`](https://github.com/huandu/xstrings/tree/v1.3.2) +- `github.com/jackc/chunkreader/v2`: [`v2.0.1`](https://github.com/jackc/chunkreader/v2/tree/v2.0.1) +- `github.com/jackc/pgconn`: [`v1.14.0`](https://github.com/jackc/pgconn/tree/v1.14.0) +- `github.com/jackc/pgio`: [`v1.0.0`](https://github.com/jackc/pgio/tree/v1.0.0) +- `github.com/jackc/pgpassfile`: [`v1.0.0`](https://github.com/jackc/pgpassfile/tree/v1.0.0) +- `github.com/jackc/pgproto3/v2`: [`v2.3.2`](https://github.com/jackc/pgproto3/v2/tree/v2.3.2) +- `github.com/jackc/pgservicefile`: [`091c0ba`](https://github.com/jackc/pgservicefile/tree/091c0ba) +- `github.com/jackc/pgtype`: [`v1.14.0`](https://github.com/jackc/pgtype/tree/v1.14.0) +- `github.com/jackc/pgx/v4`: [`v4.18.1`](https://github.com/jackc/pgx/v4/tree/v4.18.1) +- `github.com/kylelemons/godebug`: [`v1.1.0`](https://github.com/kylelemons/godebug/tree/v1.1.0) +- `github.com/matttproud/golang_protobuf_extensions/v2`: [`v2.0.0`](https://github.com/matttproud/golang_protobuf_extensions/v2/tree/v2.0.0) +- `github.com/montanaflynn/stats`: [`v0.7.0`](https://github.com/montanaflynn/stats/tree/v0.7.0) +- `github.com/pkg/browser`: [`681adbf`](https://github.com/pkg/browser/tree/681adbf) +- `github.com/shopspring/decimal`: [`v1.2.0`](https://github.com/shopspring/decimal/tree/v1.2.0) +- `github.com/sosodev/duration`: [`v1.2.0`](https://github.com/sosodev/duration/tree/v1.2.0) +- `github.com/xrash/smetrics`: [`039620a`](https://github.com/xrash/smetrics/tree/039620a) + +#### Changed +- `cloud.google.com/go/accessapproval`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/accesscontextmanager`: `v1.8.1 → v1.8.4` +- `cloud.google.com/go/aiplatform`: `v1.48.0 → v1.58.0` +- `cloud.google.com/go/analytics`: `v0.21.3 → v0.21.6` +- `cloud.google.com/go/apigateway`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/apigeeconnect`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/apigeeregistry`: `v0.7.1 → v0.8.2` +- `cloud.google.com/go/appengine`: `v1.8.1 → v1.8.4` +- `cloud.google.com/go/area120`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/artifactregistry`: `v1.14.1 → v1.14.6` +- `cloud.google.com/go/asset`: `v1.14.1 → v1.16.0` +- `cloud.google.com/go/assuredworkloads`: `v1.11.1 → v1.11.4` +- `cloud.google.com/go/automl`: `v1.13.1 → v1.13.4` +- `cloud.google.com/go/baremetalsolution`: `v1.1.1 → v1.2.3` +- `cloud.google.com/go/batch`: `v1.3.1 → v1.7.0` +- `cloud.google.com/go/beyondcorp`: `v1.0.0 → v1.0.3` +- `cloud.google.com/go/bigquery`: `v1.53.0 → v1.57.1` +- `cloud.google.com/go/billing`: `v1.16.0 → v1.18.0` +- `cloud.google.com/go/binaryauthorization`: `v1.6.1 → v1.8.0` +- `cloud.google.com/go/certificatemanager`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/channel`: `v1.16.0 → v1.17.3` +- `cloud.google.com/go/cloudbuild`: `v1.13.0 → v1.15.0` +- `cloud.google.com/go/clouddms`: `v1.6.1 → v1.7.3` +- `cloud.google.com/go/cloudtasks`: `v1.12.1 → v1.12.4` +- `cloud.google.com/go/compute`: `v1.23.0 → v1.23.3` +- `cloud.google.com/go/contactcenterinsights`: `v1.10.0 → v1.12.1` +- `cloud.google.com/go/container`: `v1.24.0 → v1.29.0` +- `cloud.google.com/go/containeranalysis`: `v0.10.1 → v0.11.3` +- `cloud.google.com/go/datacatalog`: `v1.16.0 → v1.19.0` +- `cloud.google.com/go/dataflow`: `v0.9.1 → v0.9.4` +- `cloud.google.com/go/dataform`: `v0.8.1 → v0.9.1` +- `cloud.google.com/go/datafusion`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/datalabeling`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/dataplex`: `v1.9.0 → v1.13.0` +- `cloud.google.com/go/dataproc/v2`: `v2.0.1 → v2.3.0` +- `cloud.google.com/go/dataqna`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/datastore`: `v1.13.0 → v1.15.0` +- `cloud.google.com/go/datastream`: `v1.10.0 → v1.10.3` +- `cloud.google.com/go/deploy`: `v1.13.0 → v1.16.0` +- `cloud.google.com/go/dialogflow`: `v1.40.0 → v1.47.0` +- `cloud.google.com/go/dlp`: `v1.10.1 → v1.11.1` +- `cloud.google.com/go/documentai`: `v1.22.0 → v1.23.7` +- `cloud.google.com/go/domains`: `v0.9.1 → v0.9.4` +- `cloud.google.com/go/edgecontainer`: `v1.1.1 → v1.1.4` +- `cloud.google.com/go/essentialcontacts`: `v1.6.2 → v1.6.5` +- `cloud.google.com/go/eventarc`: `v1.13.0 → v1.13.3` +- `cloud.google.com/go/filestore`: `v1.7.1 → v1.8.0` +- `cloud.google.com/go/firestore`: `v1.11.0 → v1.14.0` +- `cloud.google.com/go/functions`: `v1.15.1 → v1.15.4` +- `cloud.google.com/go/gkebackup`: `v1.3.0 → v1.3.4` +- `cloud.google.com/go/gkeconnect`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/gkehub`: `v0.14.1 → v0.14.4` +- `cloud.google.com/go/gkemulticloud`: `v1.0.0 → v1.0.3` +- `cloud.google.com/go/gsuiteaddons`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/iam`: `v1.1.1 → v1.1.5` +- `cloud.google.com/go/iap`: `v1.8.1 → v1.9.3` +- `cloud.google.com/go/ids`: `v1.4.1 → v1.4.4` +- `cloud.google.com/go/iot`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/kms`: `v1.15.0 → v1.15.5` +- `cloud.google.com/go/language`: `v1.10.1 → v1.12.2` +- `cloud.google.com/go/lifesciences`: `v0.9.1 → v0.9.4` +- `cloud.google.com/go/logging`: `v1.7.0 → v1.9.0` +- `cloud.google.com/go/longrunning`: `v0.5.1 → v0.5.4` +- `cloud.google.com/go/managedidentities`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/maps`: `v1.4.0 → v1.6.2` +- `cloud.google.com/go/mediatranslation`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/memcache`: `v1.10.1 → v1.10.4` +- `cloud.google.com/go/metastore`: `v1.12.0 → v1.13.3` +- `cloud.google.com/go/monitoring`: `v1.15.1 → v1.17.0` +- `cloud.google.com/go/networkconnectivity`: `v1.12.1 → v1.14.3` +- `cloud.google.com/go/networkmanagement`: `v1.8.0 → v1.9.3` +- `cloud.google.com/go/networksecurity`: `v0.9.1 → v0.9.4` +- `cloud.google.com/go/notebooks`: `v1.9.1 → v1.11.2` +- `cloud.google.com/go/optimization`: `v1.4.1 → v1.6.2` +- `cloud.google.com/go/orchestration`: `v1.8.1 → v1.8.4` +- `cloud.google.com/go/orgpolicy`: `v1.11.1 → v1.11.4` +- `cloud.google.com/go/osconfig`: `v1.12.1 → v1.12.4` +- `cloud.google.com/go/oslogin`: `v1.10.1 → v1.12.2` +- `cloud.google.com/go/phishingprotection`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/policytroubleshooter`: `v1.8.0 → v1.10.2` +- `cloud.google.com/go/privatecatalog`: `v0.9.1 → v0.9.4` +- `cloud.google.com/go/recaptchaenterprise/v2`: `v2.7.2 → v2.9.0` +- `cloud.google.com/go/recommendationengine`: `v0.8.1 → v0.8.4` +- `cloud.google.com/go/recommender`: `v1.10.1 → v1.12.0` +- `cloud.google.com/go/redis`: `v1.13.1 → v1.14.1` +- `cloud.google.com/go/resourcemanager`: `v1.9.1 → v1.9.4` +- `cloud.google.com/go/resourcesettings`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/retail`: `v1.14.1 → v1.14.4` +- `cloud.google.com/go/run`: `v1.2.0 → v1.3.3` +- `cloud.google.com/go/scheduler`: `v1.10.1 → v1.10.5` +- `cloud.google.com/go/secretmanager`: `v1.11.1 → v1.11.4` +- `cloud.google.com/go/security`: `v1.15.1 → v1.15.4` +- `cloud.google.com/go/securitycenter`: `v1.23.0 → v1.24.3` +- `cloud.google.com/go/servicedirectory`: `v1.11.0 → v1.11.3` +- `cloud.google.com/go/shell`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/spanner`: `v1.47.0 → v1.54.0` +- `cloud.google.com/go/speech`: `v1.19.0 → v1.21.0` +- `cloud.google.com/go/storagetransfer`: `v1.10.0 → v1.10.3` +- `cloud.google.com/go/talent`: `v1.6.2 → v1.6.5` +- `cloud.google.com/go/texttospeech`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/tpu`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/trace`: `v1.10.1 → v1.10.4` +- `cloud.google.com/go/translate`: `v1.8.2 → v1.9.3` +- `cloud.google.com/go/video`: `v1.19.0 → v1.20.3` +- `cloud.google.com/go/videointelligence`: `v1.11.1 → v1.11.4` +- `cloud.google.com/go/vision/v2`: `v2.7.2 → v2.7.5` +- `cloud.google.com/go/vmmigration`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/vmwareengine`: `v1.0.0 → v1.0.3` +- `cloud.google.com/go/vpcaccess`: `v1.7.1 → v1.7.4` +- `cloud.google.com/go/webrisk`: `v1.9.1 → v1.9.4` +- `cloud.google.com/go/websecurityscanner`: `v1.6.1 → v1.6.4` +- `cloud.google.com/go/workflows`: `v1.11.1 → v1.12.3` +- `cloud.google.com/go`: `v0.110.6 → v0.111.0` +- `github.com/asaskevich/govalidator`: [`f61b66f → a9d515a`](https://github.com/asaskevich/govalidator/compare/f61b66f...a9d515a) +- `github.com/aws/aws-sdk-go`: [`v1.44.331 → v1.49.13`](https://github.com/aws/aws-sdk-go/compare/v1.44.331...v1.49.13) +- `github.com/cpuguy83/go-md2man/v2`: [`v2.0.2 → v2.0.3`](https://github.com/cpuguy83/go-md2man/v2/compare/v2.0.2...v2.0.3) +- `github.com/digitalocean/godo`: [`v1.102.1 → v1.107.0`](https://github.com/digitalocean/godo/compare/v1.102.1...v1.107.0) +- `github.com/docker/distribution`: [`v2.8.1+incompatible → v2.8.2+incompatible`](https://github.com/docker/distribution/compare/v2.8.1...v2.8.2) +- `github.com/docker/docker`: [`v23.0.4+incompatible → v24.0.5+incompatible`](https://github.com/docker/docker/compare/v23.0.4...v24.0.5) +- `github.com/emicklei/go-restful/v3`: [`v3.9.0 → v3.11.0`](https://github.com/emicklei/go-restful/v3/compare/v3.9.0...v3.11.0) +- `github.com/envoyproxy/go-control-plane`: [`9239064 → v0.11.1`](https://github.com/envoyproxy/go-control-plane/compare/9239064...v0.11.1) +- `github.com/envoyproxy/protoc-gen-validate`: [`v0.10.1 → v1.0.2`](https://github.com/envoyproxy/protoc-gen-validate/compare/v0.10.1...v1.0.2) +- `github.com/evanphx/json-patch/v5`: [`v5.6.0 → v5.7.0`](https://github.com/evanphx/json-patch/v5/compare/v5.6.0...v5.7.0) +- `github.com/evanphx/json-patch`: [`v5.6.0+incompatible → v5.7.0+incompatible`](https://github.com/evanphx/json-patch/compare/v5.6.0...v5.7.0) +- `github.com/felixge/httpsnoop`: [`v1.0.3 → v1.0.4`](https://github.com/felixge/httpsnoop/compare/v1.0.3...v1.0.4) +- `github.com/frankban/quicktest`: [`v1.11.3 → v1.14.3`](https://github.com/frankban/quicktest/compare/v1.11.3...v1.14.3) +- `github.com/fsnotify/fsnotify`: [`v1.6.0 → v1.7.0`](https://github.com/fsnotify/fsnotify/compare/v1.6.0...v1.7.0) +- `github.com/go-asn1-ber/asn1-ber`: [`v1.5.4 → v1.5.5`](https://github.com/go-asn1-ber/asn1-ber/compare/v1.5.4...v1.5.5) +- `github.com/go-jose/go-jose/v3`: [`v3.0.0 → v3.0.1`](https://github.com/go-jose/go-jose/v3/compare/v3.0.0...v3.0.1) +- `github.com/go-ldap/ldap/v3`: [`v3.4.5 → v3.4.6`](https://github.com/go-ldap/ldap/v3/compare/v3.4.5...v3.4.6) +- `github.com/go-logr/logr`: [`v1.2.4 → v1.4.1`](https://github.com/go-logr/logr/compare/v1.2.4...v1.4.1) +- `github.com/go-logr/zapr`: [`v1.2.4 → v1.3.0`](https://github.com/go-logr/zapr/compare/v1.2.4...v1.3.0) +- `github.com/go-openapi/jsonpointer`: [`v0.19.6 → v0.20.2`](https://github.com/go-openapi/jsonpointer/compare/v0.19.6...v0.20.2) +- `github.com/go-openapi/jsonreference`: [`v0.20.2 → v0.20.4`](https://github.com/go-openapi/jsonreference/compare/v0.20.2...v0.20.4) +- `github.com/go-openapi/swag`: [`v0.22.3 → v0.22.7`](https://github.com/go-openapi/swag/compare/v0.22.3...v0.22.7) +- `github.com/golang/glog`: [`v1.1.0 → v1.1.2`](https://github.com/golang/glog/compare/v1.1.0...v1.1.2) +- `github.com/golang/mock`: [`v1.4.4 → v1.1.1`](https://github.com/golang/mock/compare/v1.4.4...v1.1.1) +- `github.com/google/cel-go`: [`v0.16.0 → v0.17.7`](https://github.com/google/cel-go/compare/v0.16.0...v0.17.7) +- `github.com/google/go-cmp`: [`v0.5.9 → v0.6.0`](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0) +- `github.com/google/go-pkcs11`: [`v0.2.0 → c6f7932`](https://github.com/google/go-pkcs11/compare/v0.2.0...c6f7932) +- `github.com/google/s2a-go`: [`v0.1.5 → v0.1.7`](https://github.com/google/s2a-go/compare/v0.1.5...v0.1.7) +- `github.com/google/uuid`: [`v1.3.0 → v1.5.0`](https://github.com/google/uuid/compare/v1.3.0...v1.5.0) +- `github.com/googleapis/enterprise-certificate-proxy`: [`v0.2.5 → v0.3.2`](https://github.com/googleapis/enterprise-certificate-proxy/compare/v0.2.5...v0.3.2) +- `github.com/gorilla/websocket`: [`v1.4.2 → v1.5.0`](https://github.com/gorilla/websocket/compare/v1.4.2...v1.5.0) +- `github.com/grpc-ecosystem/grpc-gateway/v2`: [`v2.7.0 → v2.18.1`](https://github.com/grpc-ecosystem/grpc-gateway/v2/compare/v2.7.0...v2.18.1) +- `github.com/hashicorp/go-hclog`: [`v1.4.0 → v1.5.0`](https://github.com/hashicorp/go-hclog/compare/v1.4.0...v1.5.0) +- `github.com/hashicorp/go-plugin`: [`v1.4.8 → v1.5.2`](https://github.com/hashicorp/go-plugin/compare/v1.4.8...v1.5.2) +- `github.com/hashicorp/go-retryablehttp`: [`v0.7.4 → v0.7.5`](https://github.com/hashicorp/go-retryablehttp/compare/v0.7.4...v0.7.5) +- `github.com/hashicorp/go-secure-stdlib/parseutil`: [`v0.1.7 → v0.1.8`](https://github.com/hashicorp/go-secure-stdlib/parseutil/compare/v0.1.7...v0.1.8) +- `github.com/hashicorp/go-sockaddr`: [`v1.0.2 → v1.0.6`](https://github.com/hashicorp/go-sockaddr/compare/v1.0.2...v1.0.6) +- `github.com/hashicorp/vault/api`: [`v1.9.2 → v1.10.0`](https://github.com/hashicorp/vault/api/compare/v1.9.2...v1.10.0) +- `github.com/hashicorp/vault/sdk`: [`v0.9.2 → v0.10.2`](https://github.com/hashicorp/vault/sdk/compare/v0.9.2...v0.10.2) +- `github.com/hashicorp/yamux`: [`0bc27b2 → v0.1.1`](https://github.com/hashicorp/yamux/compare/0bc27b2...v0.1.1) +- `github.com/imdario/mergo`: [`v0.3.12 → v0.3.16`](https://github.com/imdario/mergo/compare/v0.3.12...v0.3.16) +- `github.com/jmespath/go-jmespath`: [`v0.4.0 → b0104c8`](https://github.com/jmespath/go-jmespath/compare/v0.4.0...b0104c8) +- `github.com/miekg/dns`: [`v1.1.55 → v1.1.57`](https://github.com/miekg/dns/compare/v1.1.55...v1.1.57) +- `github.com/mitchellh/cli`: [`v1.0.0 → v1.1.5`](https://github.com/mitchellh/cli/compare/v1.0.0...v1.1.5) +- `github.com/mitchellh/go-wordwrap`: [`v1.0.0 → v1.0.1`](https://github.com/mitchellh/go-wordwrap/compare/v1.0.0...v1.0.1) +- `github.com/onsi/ginkgo/v2`: [`v2.12.0 → v2.13.0`](https://github.com/onsi/ginkgo/v2/compare/v2.12.0...v2.13.0) +- `github.com/onsi/gomega`: [`v1.27.10 → v1.29.0`](https://github.com/onsi/gomega/compare/v1.27.10...v1.29.0) +- `github.com/pavlo-v-chernykh/keystore-go/v4`: [`v4.4.1 → v4.5.0`](https://github.com/pavlo-v-chernykh/keystore-go/v4/compare/v4.4.1...v4.5.0) +- `github.com/prometheus/client_golang`: [`v1.16.0 → v1.18.0`](https://github.com/prometheus/client_golang/compare/v1.16.0...v1.18.0) +- `github.com/prometheus/client_model`: [`v0.4.0 → v0.5.0`](https://github.com/prometheus/client_model/compare/v0.4.0...v0.5.0) +- `github.com/prometheus/common`: [`v0.44.0 → v0.45.0`](https://github.com/prometheus/common/compare/v0.44.0...v0.45.0) +- `github.com/prometheus/procfs`: [`v0.10.1 → v0.12.0`](https://github.com/prometheus/procfs/compare/v0.10.1...v0.12.0) +- `github.com/rogpeppe/go-internal`: [`v1.11.0 → v1.12.0`](https://github.com/rogpeppe/go-internal/compare/v1.11.0...v1.12.0) +- `github.com/ryanuber/columnize`: [`v2.1.0+incompatible → v2.1.2+incompatible`](https://github.com/ryanuber/columnize/compare/v2.1.0...v2.1.2) +- `github.com/sirupsen/logrus`: [`v1.9.0 → v1.9.3`](https://github.com/sirupsen/logrus/compare/v1.9.0...v1.9.3) +- `github.com/spf13/cast`: [`v1.3.0 → v1.3.1`](https://github.com/spf13/cast/compare/v1.3.0...v1.3.1) +- `github.com/spf13/cobra`: [`v1.7.0 → v1.8.0`](https://github.com/spf13/cobra/compare/v1.7.0...v1.8.0) +- `github.com/stoewer/go-strcase`: [`v1.2.0 → v1.3.0`](https://github.com/stoewer/go-strcase/compare/v1.2.0...v1.3.0) +- `github.com/stretchr/objx`: [`v0.5.0 → v0.5.1`](https://github.com/stretchr/objx/compare/v0.5.0...v0.5.1) +- `github.com/urfave/cli/v2`: [`v2.1.1 → v2.25.7`](https://github.com/urfave/cli/v2/compare/v2.1.1...v2.25.7) +- `go.etcd.io/bbolt`: `v1.3.7 → v1.3.8` +- `go.etcd.io/etcd/api/v3`: `v3.5.9 → v3.5.11` +- `go.etcd.io/etcd/client/pkg/v3`: `v3.5.9 → v3.5.11` +- `go.etcd.io/etcd/client/v2`: `v2.305.9 → v2.305.10` +- `go.etcd.io/etcd/client/v3`: `v3.5.9 → v3.5.11` +- `go.etcd.io/etcd/pkg/v3`: `v3.5.9 → v3.5.10` +- `go.etcd.io/etcd/raft/v3`: `v3.5.9 → v3.5.10` +- `go.etcd.io/etcd/server/v3`: `v3.5.9 → v3.5.10` +- `go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc`: `v0.35.0 → v0.46.1` +- `go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp`: `v0.39.0 → v0.46.1` +- `go.opentelemetry.io/otel/exporters/otlp/internal/retry`: `v1.15.0 → v1.10.0` +- `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`: `v1.15.0 → v1.21.0` +- `go.opentelemetry.io/otel/exporters/otlp/otlptrace`: `v1.15.0 → v1.21.0` +- `go.opentelemetry.io/otel/metric`: `v0.36.0 → v1.21.0` +- `go.opentelemetry.io/otel/sdk`: `v1.15.0 → v1.21.0` +- `go.opentelemetry.io/otel/trace`: `v1.15.0 → v1.21.0` +- `go.opentelemetry.io/otel`: `v1.15.0 → v1.21.0` +- `go.opentelemetry.io/proto/otlp`: `v0.19.0 → v1.0.0` +- `go.uber.org/goleak`: `v1.2.1 → v1.3.0` +- `go.uber.org/zap`: `v1.25.0 → v1.26.0` +- `golang.org/x/crypto`: `v0.12.0 → v0.17.0` +- `golang.org/x/exp`: `d852ddb → 02704c9` +- `golang.org/x/lint`: `738671d → d0100b6` +- `golang.org/x/mod`: `v0.12.0 → v0.14.0` +- `golang.org/x/net`: `v0.14.0 → v0.19.0` +- `golang.org/x/oauth2`: `v0.11.0 → v0.15.0` +- `golang.org/x/sync`: `v0.3.0 → v0.5.0` +- `golang.org/x/sys`: `v0.11.0 → v0.15.0` +- `golang.org/x/term`: `v0.11.0 → v0.15.0` +- `golang.org/x/text`: `v0.12.0 → v0.14.0` +- `golang.org/x/time`: `v0.3.0 → v0.5.0` +- `golang.org/x/tools`: `74c255b → v0.16.1` +- `google.golang.org/api`: `v0.138.0 → v0.154.0` +- `google.golang.org/appengine`: `v1.6.7 → v1.6.8` +- `google.golang.org/genproto/googleapis/api`: `f966b18 → 50ed04b` +- `google.golang.org/genproto/googleapis/bytestream`: `1744710 → 3a041ad` +- `google.golang.org/genproto/googleapis/rpc`: `1744710 → 50ed04b` +- `google.golang.org/genproto`: `f966b18 → 50ed04b` +- `google.golang.org/grpc`: `v1.57.0 → v1.60.1` +- `google.golang.org/protobuf`: `v1.31.0 → v1.32.0` +- `gopkg.in/ini.v1`: `v1.62.0 → v1.67.0` +- `honnef.co/go/tools`: `v0.0.1-2020.1.4 → ea95bdf` +- `k8s.io/api`: `v0.28.1 → v0.29.0` +- `k8s.io/apiextensions-apiserver`: `v0.28.1 → v0.29.0` +- `k8s.io/apimachinery`: `v0.28.1 → v0.29.0` +- `k8s.io/apiserver`: `v0.28.1 → v0.29.0` +- `k8s.io/client-go`: `v0.28.1 → v0.29.0` +- `k8s.io/code-generator`: `v0.28.1 → v0.29.0` +- `k8s.io/component-base`: `v0.28.1 → v0.29.0` +- `k8s.io/gengo`: `c0856e2 → 9cce18d` +- `k8s.io/klog/v2`: `v2.100.1 → v2.110.1` +- `k8s.io/kms`: `v0.28.1 → v0.29.0` +- `k8s.io/kube-aggregator`: `v0.28.1 → v0.29.0` +- `k8s.io/kube-openapi`: `14e4089 → eec4567` +- `k8s.io/utils`: `3b25d92 → e7106e6` +- `sigs.k8s.io/apiserver-network-proxy/konnectivity-client`: `v0.1.2 → v0.29.0` +- `sigs.k8s.io/controller-runtime`: `v0.16.0 → v0.16.3` +- `sigs.k8s.io/gateway-api`: `v0.7.1 → v1.0.0` +- `sigs.k8s.io/structured-merge-diff/v4`: `v4.3.0 → v4.4.1` +- `sigs.k8s.io/yaml`: `v1.3.0 → v1.4.0` +- `software.sslmate.com/src/go-pkcs12`: `v0.2.1 → v0.4.0` + +#### Removed +- `cloud.google.com/go/storage`: `v1.10.0` +- `dmitri.shuralyov.com/gpu/mtl`: `666a987` +- `github.com/Azure/azure-sdk-for-go`: [`v68.0.0+incompatible`](https://github.com/Azure/azure-sdk-for-go/tree/v68.0.0) +- `github.com/Azure/go-autorest/autorest/adal`: [`v0.9.23`](https://github.com/Azure/go-autorest/autorest/adal/tree/v0.9.23) +- `github.com/Azure/go-autorest/autorest/date`: [`v0.3.0`](https://github.com/Azure/go-autorest/autorest/date/tree/v0.3.0) +- `github.com/Azure/go-autorest/autorest/mocks`: [`v0.4.2`](https://github.com/Azure/go-autorest/autorest/mocks/tree/v0.4.2) +- `github.com/Azure/go-autorest/autorest/to`: [`v0.4.0`](https://github.com/Azure/go-autorest/autorest/to/tree/v0.4.0) +- `github.com/Azure/go-autorest/autorest/validation`: [`v0.3.1`](https://github.com/Azure/go-autorest/autorest/validation/tree/v0.3.1) +- `github.com/Azure/go-autorest/autorest`: [`v0.11.29`](https://github.com/Azure/go-autorest/autorest/tree/v0.11.29) +- `github.com/Azure/go-autorest/logger`: [`v0.2.1`](https://github.com/Azure/go-autorest/logger/tree/v0.2.1) +- `github.com/Azure/go-autorest/tracing`: [`v0.6.0`](https://github.com/Azure/go-autorest/tracing/tree/v0.6.0) +- `github.com/Azure/go-autorest`: [`v14.2.0+incompatible`](https://github.com/Azure/go-autorest/tree/v14.2.0) +- `github.com/BurntSushi/xgb`: [`27f1227`](https://github.com/BurntSushi/xgb/tree/27f1227) +- `github.com/OneOfOne/xxhash`: [`v1.2.2`](https://github.com/OneOfOne/xxhash/tree/v1.2.2) +- `github.com/Venafi/vcert/v4`: [`69f417a`](https://github.com/Venafi/vcert/v4/tree/69f417a) +- `github.com/alecthomas/template`: [`a0175ee`](https://github.com/alecthomas/template/tree/a0175ee) +- `github.com/armon/circbuf`: [`bbbad09`](https://github.com/armon/circbuf/tree/bbbad09) +- `github.com/benbjohnson/clock`: [`v1.3.0`](https://github.com/benbjohnson/clock/tree/v1.3.0) +- `github.com/bketelsen/crypt`: [`5cbc8cc`](https://github.com/bketelsen/crypt/tree/5cbc8cc) +- `github.com/cespare/xxhash`: [`v1.1.0`](https://github.com/cespare/xxhash/tree/v1.1.0) +- `github.com/coreos/bbolt`: [`v1.3.2`](https://github.com/coreos/bbolt/tree/v1.3.2) +- `github.com/coreos/etcd`: [`v3.3.13+incompatible`](https://github.com/coreos/etcd/tree/v3.3.13) +- `github.com/coreos/go-systemd`: [`95778df`](https://github.com/coreos/go-systemd/tree/95778df) +- `github.com/coreos/pkg`: [`399ea9e`](https://github.com/coreos/pkg/tree/399ea9e) +- `github.com/dgrijalva/jwt-go`: [`v3.2.0+incompatible`](https://github.com/dgrijalva/jwt-go/tree/v3.2.0) +- `github.com/dgryski/go-sip13`: [`e10d5fe`](https://github.com/dgryski/go-sip13/tree/e10d5fe) +- `github.com/ghodss/yaml`: [`v1.0.0`](https://github.com/ghodss/yaml/tree/v1.0.0) +- `github.com/go-gl/glfw/v3.3/glfw`: [`6f7a984`](https://github.com/go-gl/glfw/v3.3/glfw/tree/6f7a984) +- `github.com/go-gl/glfw`: [`e6da0ac`](https://github.com/go-gl/glfw/tree/e6da0ac) +- `github.com/go-kit/kit`: [`v0.8.0`](https://github.com/go-kit/kit/tree/v0.8.0) +- `github.com/go-stack/stack`: [`v1.8.0`](https://github.com/go-stack/stack/tree/v1.8.0) +- `github.com/google/gnostic`: [`v0.5.7-v3refs`](https://github.com/google/gnostic/tree/v0.5.7-v3refs) +- `github.com/google/martian/v3`: [`v3.0.0`](https://github.com/google/martian/v3/tree/v3.0.0) +- `github.com/google/martian`: [`v2.1.0+incompatible`](https://github.com/google/martian/tree/v2.1.0) +- `github.com/google/renameio`: [`v0.1.0`](https://github.com/google/renameio/tree/v0.1.0) +- `github.com/hashicorp/consul/api`: [`v1.1.0`](https://github.com/hashicorp/consul/api/tree/v1.1.0) +- `github.com/hashicorp/consul/sdk`: [`v0.1.1`](https://github.com/hashicorp/consul/sdk/tree/v0.1.1) +- `github.com/hashicorp/go-msgpack`: [`v0.5.3`](https://github.com/hashicorp/go-msgpack/tree/v0.5.3) +- `github.com/hashicorp/go-syslog`: [`v1.0.0`](https://github.com/hashicorp/go-syslog/tree/v1.0.0) +- `github.com/hashicorp/go.net`: [`v0.0.1`](https://github.com/hashicorp/go.net/tree/v0.0.1) +- `github.com/hashicorp/logutils`: [`v1.0.0`](https://github.com/hashicorp/logutils/tree/v1.0.0) +- `github.com/hashicorp/mdns`: [`v1.0.0`](https://github.com/hashicorp/mdns/tree/v1.0.0) +- `github.com/hashicorp/memberlist`: [`v0.1.3`](https://github.com/hashicorp/memberlist/tree/v0.1.3) +- `github.com/hashicorp/serf`: [`v0.8.2`](https://github.com/hashicorp/serf/tree/v0.8.2) +- `github.com/jstemmer/go-junit-report`: [`v0.9.1`](https://github.com/jstemmer/go-junit-report/tree/v0.9.1) +- `github.com/kr/logfmt`: [`b84e30a`](https://github.com/kr/logfmt/tree/b84e30a) +- `github.com/mitchellh/gox`: [`v0.4.0`](https://github.com/mitchellh/gox/tree/v0.4.0) +- `github.com/mitchellh/iochan`: [`v1.0.0`](https://github.com/mitchellh/iochan/tree/v1.0.0) +- `github.com/morikuni/aec`: [`v1.0.0`](https://github.com/morikuni/aec/tree/v1.0.0) +- `github.com/oklog/ulid`: [`v1.3.1`](https://github.com/oklog/ulid/tree/v1.3.1) +- `github.com/pascaldekloe/goe`: [`57f6aae`](https://github.com/pascaldekloe/goe/tree/57f6aae) +- `github.com/prometheus/tsdb`: [`v0.7.1`](https://github.com/prometheus/tsdb/tree/v0.7.1) +- `github.com/sean-/seed`: [`e2103e2`](https://github.com/sean-/seed/tree/e2103e2) +- `github.com/shurcooL/sanitized_anchor_name`: [`v1.0.0`](https://github.com/shurcooL/sanitized_anchor_name/tree/v1.0.0) +- `github.com/spaolacci/murmur3`: [`f09979e`](https://github.com/spaolacci/murmur3/tree/f09979e) +- `golang.org/x/image`: `cff245a` +- `golang.org/x/mobile`: `d2bd2a2` +- `gopkg.in/alecthomas/kingpin.v2`: `v2.2.6` +- `gopkg.in/resty.v1`: `v1.12.0` +- `gotest.tools/v3`: `v3.4.0` +- `rsc.io/binaryregexp`: `v0.2.0` +- `rsc.io/quote/v3`: `v3.1.0` +- `rsc.io/sampler`: `v1.3.0` diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.15.md b/content/v1.15-docs/releases/release-notes/release-notes-1.15.md new file mode 100644 index 0000000000..a84c5f4711 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.15.md @@ -0,0 +1,124 @@ +--- +title: Release 1.15 +description: 'cert-manager release notes: cert-manager 1.14' +--- + +> 📢 The cert-manager CLI has moved to a new GitHub repository +> +> From this release, `cmctl` is no longer be released with `cert-manager` itself, +> and there will no further `quay.io/jetstack/cert-manager-ctl` OCI images. +> +> For the startupapicheck Job you should update references to point at +> `quay.io/jetstack/cert-manager-startupapicheck` +> +> Read [The cert-manager Command Line Tool (cmctl) page](../../reference/cmctl.md) to learn more. + +> 📢 Change in how the Helm chart manages CRDs +> +> From this release, the Helm chart will no longer uninstall the CRDs when the +> chart is uninstalled. If you want the CRDs to be removed on uninstall use +> `crds.keep=false` when installing the Helm chart. + +cert-manager 1.15 promotes several features to beta, including GatewayAPI support (`ExperimentalGatewayAPISupport`), the ability to provide a subject in the Certificate that will be used literally in the CertificateSigningRequest (`LiteralCertificateSubject`) and the outputting of additional certificate formats (`AdditionalCertificateOutputFormats`). + +## Community + +Thanks again to all open-source contributors with commits in this release, including: [@Pionerd](https://github.com/Pionerd), [@SgtCoDFish](https://github.com/SgtCoDFish), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot), [@andrey-dubnik](https://github.com/andrey-dubnik), [@bwaldrep](https://github.com/bwaldrep), [@eplightning](https://github.com/eplightning), [@erikgb](https://github.com/erikgb), [@findnature](https://github.com/findnature), [@gplessis](https://github.com/gplessis), [@import-shiburin](https://github.com/import-shiburin), [@inteon](https://github.com/inteon), [@jkroepke](https://github.com/jkroepke), [@lunarwhite](https://github.com/lunarwhite), [@mangeshhambarde](https://github.com/mangeshhambarde), [@pwhitehead-splunk](https://github.com/pwhitehead-splunk) & [@rodrigorfk](https://github.com/rodrigorfk), [@wallrj](https://github.com/wallrj). + +Thanks also to the following cert-manager maintainers for their contributions during this release: [@SgtCoDFish](https://github.com/SgtCoDFish), [@SpectralHiss](https://github.com/SpectralHiss), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot), [@hawksight](https://github.com/hawksight), [@inteon](https://github.com/inteon), [@maelvls](https://github.com/maelvls) & [@wallrj](https://github.com/wallrj). + +Equally thanks to everyone who provided feedback, helped users and raised issues on GitHub and Slack and joined our meetings! + +Thanks also to the CNCF, which provides resources and support, and to the AWS open source team for being good community members and for their maintenance of the PrivateCA Issuer. + +In addition, massive thanks to Venafi for contributing developer time and resources towards the continued maintenance of cert-manager projects. + +## `v1.15.3` + +### Bug or Regression + +- BUGFIX: the dynamic certificate source used by the webhook TLS server failed to detect a root CA approaching expiration, due to a calculation error. This will cause the webhook TLS server to fail renewing its CA certificate. Please upgrade before the expiration of this CA certificate is reached. ([#7232](https://github.com/cert-manager/cert-manager/pull/7232), [`@cert-manager-bot`](https://github.com/cert-manager-bot)) + +## `v1.15.2` + +### Bug or Regression + +- BUGFIX `route53`: explicitly set the `aws-global` STS region which is now required by the `github.com/aws/aws-sdk-go-v2` library. ([#7189](https://github.com/cert-manager/cert-manager/pull/7189), [`@cert-manager-bot`](https://github.com/cert-manager-bot)) +- Bump `grpc-go` to fix `GHSA-xr7q-jx4m-x55m` ([#7167](https://github.com/cert-manager/cert-manager/pull/7167), [`@SgtCoDFish`](https://github.com/SgtCoDFish)) +- Fix Azure DNS causing panics whenever authentication error happens ([#7188](https://github.com/cert-manager/cert-manager/pull/7188), [`@cert-manager-bot`](https://github.com/cert-manager-bot)) +- Fix incorrect value and indentation of `endpointAdditionalProperties` in the `PodMonitor` template of the Helm chart ([#7191](https://github.com/cert-manager/cert-manager/pull/7191), [`@inteon`](https://github.com/inteon)) +- Fixes ACME HTTP01 challenge behavior when using Gateway API to prevent unbounded creation of `HTTPRoute` resources ([#7186](https://github.com/cert-manager/cert-manager/pull/7186), [`@cert-manager-bot`](https://github.com/cert-manager-bot)) +- Upgrade `golang` from `1.22.3` to `1.22.5` ([#7165](https://github.com/cert-manager/cert-manager/pull/7165), [`@github-actions`](https://github.com/github-actions)) + +## `v1.15.1` + +### Bug or Regression + +- BUGFIX: fix issue that caused Vault issuer to not retry signing when an error was encountered. ([#7111](https://github.com/cert-manager/cert-manager/pull/7111), [@inteon](https://github.com/inteon)) + +### Other (Cleanup or Flake) + +- Update `github.com/Azure/azure-sdk-for-go/sdk/azidentity` to address `CVE-2024-35255` ([#7092](https://github.com/cert-manager/cert-manager/pull/7092), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Bump the `go-retryablehttp` dependency to fix `CVE-2024-6104` ([#7130](https://github.com/cert-manager/cert-manager/pull/7130), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## `v1.15.0` + +### Feature + +- GatewayAPI support has graduated to Beta. Add the `--enable-gateway-api` flag to enable the integration. ([#6961](https://github.com/cert-manager/cert-manager/pull/6961), [@ThatsMrTalbot](https://github.com/ThatsMrTalbot)) +- Add support to specify a custom key alias in a JKS Keystore ([#6807](https://github.com/cert-manager/cert-manager/pull/6807), [@bwaldrep](https://github.com/bwaldrep)) +- Add the ability to communicate with Vault via mTLS when strict client certificates is enabled at Vault server side ([#6614](https://github.com/cert-manager/cert-manager/pull/6614), [@rodrigorfk](https://github.com/rodrigorfk)) +- Added option to provide additional audiences in the service account auth section for vault ([#6718](https://github.com/cert-manager/cert-manager/pull/6718), [@andrey-dubnik](https://github.com/andrey-dubnik)) +- Venafi Issuer now sends a cert-manager HTTP User-Agent header in all Venafi Rest API requests. + For example: `cert-manager-certificaterequests-issuer-venafi/v1.15.0+(linux/amd64)+cert-manager/ef068a59008f6ed919b98a7177921ddc9e297200`. ([#6865](https://github.com/cert-manager/cert-manager/pull/6865), [@wallrj](https://github.com/wallrj)) +- Add hint to validation error message to help users of external issuers more easily fix the issue if they specify a Kind but forget the Group ([#6913](https://github.com/cert-manager/cert-manager/pull/6913), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Add support for numeric OID types in LiteralSubject. Eg. "1.2.3.4=String Value" ([#6775](https://github.com/cert-manager/cert-manager/pull/6775), [@inteon](https://github.com/inteon)) +- Promote the `LiteralCertificateSubject` feature to Beta. ([#7030](https://github.com/cert-manager/cert-manager/pull/7030), [@inteon](https://github.com/inteon)) +- Promoted the `AdditionalCertificateOutputFormats` feature gate to Beta (enabled by default). ([#6970](https://github.com/cert-manager/cert-manager/pull/6970), [@erikgb](https://github.com/erikgb)) +- The Helm chart now allows you to supply `extraObjects`; a list of YAML manifests which will helm will install and uninstall with the cert-manager manifests. ([#6424](https://github.com/cert-manager/cert-manager/pull/6424), [@gplessis](https://github.com/gplessis)) +- Update the Route53 provider to support fetching credentials using AssumeRoleWithWebIdentity ([#6878](https://github.com/cert-manager/cert-manager/pull/6878), [@pwhitehead-splunk](https://github.com/pwhitehead-splunk)) +- Helm can now add optional hostAliases to cert-manager Pod to allow the DNS self-check to pass in custom scenarios. ([#6456](https://github.com/cert-manager/cert-manager/pull/6456), [@Pionerd](https://github.com/Pionerd)) +- Added a new Ingress annotation for copying specific Ingress annotations to Certificate's secretTemplate ([#6839](https://github.com/cert-manager/cert-manager/pull/6839), [@mangeshhambarde](https://github.com/mangeshhambarde)) +- Added option to define additional token audiences for the Vault Kubernetes auth ([#6744](https://github.com/cert-manager/cert-manager/pull/6744), [@andrey-dubnik](https://github.com/andrey-dubnik)) +- Allow `cert-manager.io/allow-direct-injection` in annotations ([#6801](https://github.com/cert-manager/cert-manager/pull/6801), [@jkroepke](https://github.com/jkroepke)) + +### Design + +- Remove repetitive words ([#6949](https://github.com/cert-manager/cert-manager/pull/6949), [@findnature](https://github.com/findnature)) + +### Bug or Regression + +- BUGFIX: Fixes issue with JSON-logging, where only a subset of the log messages were output as JSON. ([#6779](https://github.com/cert-manager/cert-manager/pull/6779), [@inteon](https://github.com/inteon)) +- BUGFIX: JKS and PKCS12 stores now contain the full set of CAs specified by an issuer ([#6806](https://github.com/cert-manager/cert-manager/pull/6806), [@bwaldrep](https://github.com/bwaldrep)) +- BUGFIX: cainjector leader election flag/config option defaults are missing ([#6816](https://github.com/cert-manager/cert-manager/pull/6816), [@inteon](https://github.com/inteon)) +- BUGFIX: cert-manager issuers incorrectly copied the critical flag from the CSR instead of re-calculating that field themselves. ([#6724](https://github.com/cert-manager/cert-manager/pull/6724), [@inteon](https://github.com/inteon)) +- Breaking Change: Fixed unintended certificate chain is used if `preferredChain` is configured. ([#6755](https://github.com/cert-manager/cert-manager/pull/6755), [@import-shiburin](https://github.com/import-shiburin)) +- Bugfix: LiteralSubjects with a #= value can result in memory issues due to faulty BER parser (`github.com/go-asn1-ber/asn1-ber`). ([#6770](https://github.com/cert-manager/cert-manager/pull/6770), [@inteon](https://github.com/inteon)) +- DigitalOcean: Ensure that only TXT records are considered for deletion when cleaning up after an ACME challenge ([#6875](https://github.com/cert-manager/cert-manager/pull/6875), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix backwards incompatible removal of default Prometheus Service resource. ([#6699](https://github.com/cert-manager/cert-manager/pull/6699), [@inteon](https://github.com/inteon)) +- Fix broken cainjector image value in Helm chart ([#6692](https://github.com/cert-manager/cert-manager/pull/6692), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Helm: Fix a bug in the logic that differentiates between 0 and an empty value. ([#6713](https://github.com/cert-manager/cert-manager/pull/6713), [@inteon](https://github.com/inteon)) +- Make sure the Azure SDK error messages are stable. ([#6676](https://github.com/cert-manager/cert-manager/pull/6676), [@inteon](https://github.com/inteon)) +- When using the literalSubject on a Certificate, the webhook validation for the common name now also points to the literalSubject. ([#6767](https://github.com/cert-manager/cert-manager/pull/6767), [@lunarwhite](https://github.com/lunarwhite)) +- Bump `golang.org/x/net` to fix `CVE-2023-45288` ([#6929](https://github.com/cert-manager/cert-manager/pull/6929), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix ACME issuer being stuck waiting for DNS propagation when using Azure DNS with multiple instances issuing for the same FQDN ([#6351](https://github.com/cert-manager/cert-manager/pull/6351), [@eplightning](https://github.com/eplightning)) +- Fix cainjector ConfigMap not mounted in the cainjector deployment. ([#7055](https://github.com/cert-manager/cert-manager/pull/7055), [@inteon](https://github.com/inteon)) +- Added `disableAutoApproval` and `approveSignerNames` Helm chart options. ([#7054](https://github.com/cert-manager/cert-manager/pull/7054), [@inteon](https://github.com/inteon)) + +### Other (Cleanup or Flake) + +- Bump base images ([#6840](https://github.com/cert-manager/cert-manager/pull/6840), [@inteon](https://github.com/inteon)) +- Bump `github.com/go-jose/go-jose` to `v3.0.3` to fix `CVE-2024-28180` ([#6854](https://github.com/cert-manager/cert-manager/pull/6854), [@wallrj](https://github.com/wallrj)) +- Removed deprecated util functions that have been replaced by the `slices` and `k8s.io/apimachinery/pkg/util` packages. + Removed deprecated CSR functions which have been replaced with other functions in the `pkg/util/pki` package. ([#6730](https://github.com/cert-manager/cert-manager/pull/6730), [@inteon](https://github.com/inteon)) +- Upgrade go to 1.21.8: fixes `CVE-2024-24783` ([#6823](https://github.com/cert-manager/cert-manager/pull/6823), [@inteon](https://github.com/inteon)) +- Upgrade go to latest version 1.22.1 ([#6831](https://github.com/cert-manager/cert-manager/pull/6831), [@inteon](https://github.com/inteon)) +- Upgrade `google.golang.org/protobuf`: fixing `GO-2024-2611` ([#6827](https://github.com/cert-manager/cert-manager/pull/6827), [@inteon](https://github.com/inteon)) +- `cmctl` and `kubectl cert-manger` have been moved to the https://github.com/cert-manager/cmctl repo and will be versioned separately starting with `cmctl` `v2.0.0` ([#6663](https://github.com/cert-manager/cert-manager/pull/6663), [@inteon](https://github.com/inteon)) +- ⚠️ Possibly breaking: Helm will now keep the CRDs when you uninstall cert-manager by default to prevent accidental data loss + Add new `crds.keep` and `crds.enabled` Helm options which will replace the `installCRDs` option. ([#6760](https://github.com/cert-manager/cert-manager/pull/6760), [@inteon](https://github.com/inteon)) +- Graduate the `DisallowInsecureCSRUsageDefinition` feature gate to GA. (part 2) ([#6963](https://github.com/cert-manager/cert-manager/pull/6963), [@inteon](https://github.com/inteon)) +- Remove deprecated `pkg/util/pki/ParseSubjectStringToRawDERBytes` function. ([#6994](https://github.com/cert-manager/cert-manager/pull/6994), [@inteon](https://github.com/inteon)) +- Upgrade Kind to `v0.23.0` and update supported node image digests ([#7020](https://github.com/cert-manager/cert-manager/pull/7020), @github-actions[bot]) +- If the `--controllers` flag only specifies disabled controllers, the default controllers are now enabled implicitly. ([#7054](https://github.com/cert-manager/cert-manager/pull/7054), [@inteon](https://github.com/inteon)) +- Upgrade to Go 1.22.3, fixing `GO-2024-2824`. ([#6996](https://github.com/cert-manager/cert-manager/pull/6996), @github-actions[bot]) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.2.md b/content/v1.15-docs/releases/release-notes/release-notes-1.2.md new file mode 100644 index 0000000000..12cc382d93 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.2.md @@ -0,0 +1,86 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v1.2' +--- + +⚠️ cert-manager `v1.2` release drops support for Kubernetes versions below `v1.16`. This allows new features to be introduced whilst keeping the project maintainable. ⚠️ + +This release adds new features for several issuers and fixes several bugs. + +Please read the [upgrade notes](../upgrading/upgrading-1.1-1.2.md) before upgrading. + +Aside from that, there have been numerous bug fixes and features summarized below. + +# Deprecated Features and Breaking Changes + +1. The `--renew-before-expiration-duration` flag of the cert-manager controller-manager has been deprecated. Please set the `Certificate.Spec.RenewBefore` field instead. This flag will be removed in the next release. + +2. As Kubernetes `v1.16` is now the earliest supported version, The `legacy` manifests have now been removed. You can read more [here](../README.md). + +3. The `User-Agent` request header has been changed from `jetstack-cert-manager/` to `cert-manager/`. This may affect functionality if you rely on an a User-Agent allowlist in a corporate environment. + +# Copyright and Ownership + +* As this is the first release prepared after the [acceptance of cert-manager into the CNCF sandbox](https://blog.jetstack.io/blog/cert-manager-cncf/), the copyright strings have been changed to remove references to Jetstack. + +* The `User-Agent` request header has changed from `jetstack-cert-manager/` to `cert-manager/`. + +# New Features + +## Additional options for cert-manager controllers + +* The cert-manager controller can now be configured to expose profiling information using the new `--enable-profiling` flag. + +* cainjector leader election leases are now customizable using the new flags `--leader-election-lease-duration`, `--leader-election-renew-deadline` and `--leader-election-retry-period`. + +## Usability improvements + +* cert-manager can now create Java KeyStores that are compatible with Java 8 or greater. A file named `keystore.jks` will be added to the secret specified in the `Certificate.spec.secretName` encrypted with the password specified in the `Certificate.spec.jks.passwordSecretRef` secret. + + ```yaml + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: jks-example + spec: + secretName: jks-keystore + jks: + create: true + passwordSecretRef: + name: supersecret + key: password + ``` + +* ingress-shim now supports the new `cert-manager.io/usages` annotation for specifying custom key usages. If this isn't set, it defaults to `digital signature,key encipherment`, but a comma separated list of [any valid usages](https://pkg.go.dev/github.com/jetstack/cert-manager@v1.2.0/pkg/apis/certmanager/v1#KeyUsage) can be specified. + +* ingress-shim now also checks for `cert-manager.io/duration` and `cert-manager.io/renew-before` annotations and uses those values to set the `Certificate.Spec.Duration` and `Certificate.Spec.RenewBefore` fields. + +## Issuer Improvements + +* The Vault issuer now stores the root CA in `ca.crt` rather than the issuing CA, moving the chain into `tls.crt`. + +* The Venafi issuer now sets the `ca.crt` field of the secret. + +* A list of OCSP server URLs can now be set on certificates issued by the CA issuer using the `Issuer.spec.ca.ocspServers` field. + +## CLI User Experience + +* The cert-manager `kubectl` plugin can now show you information about certificates in your cluster: + ```shell + kubectl cert-manager inspect secret my-crt --namespace my-namespace + ``` + +* cert-manager CRDs have been given categories so now they appear in `kubectl get cert-manager` and `kubectl get cert-manager-acme`. + +## ACME + +* The ACME spec allows for a `NotAfter` date, which is supported by Step CA but not Let's Encrypt. This is gated behind a boolean on `Issuer.spec.acme.enableDurationFeature`. When enabled, cert-manager +will pass through the requested Duration to the ACME server. + +# Bug Fixes + +* The AWS Route53 DNS01 challenge now uses exponential backoff on failure. + +* Ingress validation rules have been relaxed to allow for Certificates to be created/updated for valid Ingress TLS entries even if the same Ingress contains some invalid TLS entries. + +* OpenAPI validation has relaxed in the helm chart to work around a type conversion bug that prevented users from upgrading cert-manager with `helm upgrade` \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.3.md b/content/v1.15-docs/releases/release-notes/release-notes-1.3.md new file mode 100644 index 0000000000..4f7a0a5f31 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.3.md @@ -0,0 +1,108 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v1.3' +--- + +# Patch Release `v1.3.1` + +## Bug and Security Fixes + +- A Helm upgrade bug was + [fixed](https://github.com/cert-manager/cert-manager/pull/3882), you should now + able to upgrade from cert-manager 1.2 to 1.3 when `--set installCRDs=true` is + used. This issue was due to [a Helm + bug](https://github.com/helm/helm/issues/5806#issuecomment-788116838) with the + `minimum` field on the CRDs. + +# Final Release `v1.3.0` + +The 1.3 release prepares for the implementation of certificate issuance policies and adoption of the upstream [Kubernetes CSR](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/) API. It also improves interoperability with HashiCorp [Vault Enterprise](https://www.vaultproject.io/docs/enterprise). +A slew of bugs have also been squashed. + +Special thanks to the external contributors who contributed to this release: + +* [@teejaded](https://github.com/teejaded) +* [@7opf](https://github.com/7opf) +* [@yann-soubeyrand](https://github.com/yann-soubeyrand) +* [@Kirill-Garbar](https://github.com/Kirill-Garbar) +* [@joshuastern](https://github.com/joshuastern) +* [@lalitadithya](https://github.com/lalitadithya) +* [@johejo](https://github.com/johejo) +* [@alrs](https://github.com/alrs) +* [@jsoref](https://github.com/jsoref) +* [@RinkiyaKeDad](https://github.com/RinkiyaKeDad) +* [@jonathansp](https://github.com/jonathansp) +* [@OmairK](https://github.com/OmairK) +* [@justinkillen](https://github.com/justinkillen) + +Please read the [upgrade notes](../upgrading/upgrading-1.2-1.3.md) before upgrading. + +As always, the full change log is available on the [GitHub release](https://github.com/cert-manager/cert-manager/releases/tag/v1.3.0). + +## Deprecated Features and Breaking Changes + +### Venafi Cloud Issuer + +This release updates the [Venafi Cloud Issuer][] to use `OutagePREDICT` instead of `DevOpsACCELERATE`. + +The only impact to Venafi Cloud users is the change in zone syntax. +The zone is now `\` +(e.g. `My Application\My CIT`). + +[Venafi Cloud Issuer]: https://cert-manager.io/docs/configuration/venafi/ + +### cert-manager controller + +The `--renew-before-expiration-duration` flag has been removed from the cert-manager controller, having been deprecated in the previous release. + +### cert-manager CRDs + +`CertificateRequests` are now immutable - the `spec` and `metadata.annotations` fields cannot be changed after creation. They were always designed to be immutable but this behavior is now *enforced* by the cert-manager webhook. + +## New Features + +### Policy Support Preparation + +* The [design documentation](https://github.com/cert-manager/cert-manager/blob/v1.3.0/design/20210203.certificate-request-identity.md) for Certificate Identity is now available. +* `CertificateRequests` now have identity fields mirroring the upstream [Kubernetes CSR](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/) object. +* `CertificateRequests` are now immutable. +* `CertificateRequests` now have an Approval condition type, with `Approved` and `Denied` reasons. +* The cert-manager controller currently always approves any `CertificateRequest`. +* Added `kubectl cert-manager [approve|deny]` commands to the kubectl plugin. + +### cert-manager CRDs + +* `CertificateRequests` now support the `revisionHistoryLimit` field to limit the amount of retained history. The default is unlimited (`nil`). + +### Vault Enterprise + +* cert-manager now sends the `X-VAULT-NAMESPACE` header for the `requestTokenWithAppRoleRef` API call. + +## Bug Fixes + +### cert-manager Controller + +* Fixed an issue which could cause multiple `CertificateRequests` to be created in a short time for a single `Certificate` resource. +* Certificate Readiness controller only updates a certificate's status if something has changed. + +### SelfSigned Issuer + +* The issuer now warns if you request a certificate with an empty subject DN - creating a certificate that is in violation of RFC 5280. Some applications will reject such certificates as invalid, such as Java's `keytool`. + +### Helm Chart + +* The `targetPort` used by the Prometheus service monitor is now correctly set from helm values. +* The correct permissions are added to the aggregate `edit` role. + +## Other Changes + +## Repository Hygiene + +* `SECURITY.md` now contains information on how to report security issues. +* The language of `CONTRIBUTING.md` has been updated to match existing copyright notices. + +### Tooling + +* cert-manager now can be built with go 1.16 on Apple Silicon. +* Docker images targets have been added to the Makefile. +* Bazel `v3.5.0` is required to build locally and to run tests. \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.4.md b/content/v1.15-docs/releases/release-notes/release-notes-1.4.md new file mode 100644 index 0000000000..a73c1310c4 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.4.md @@ -0,0 +1,379 @@ +--- +title: Release Notes +description: 'cert-manager release notes: cert-manager v1.4' +--- + +# Final Release `v1.4.0` + +Special thanks to the external contributors who contributed to this release: + +* [@andreas-p](https://github.com/andreas-p) +* [@erikgb](https://github.com/erikgb) +* [@eddiehoffman](https://github.com/eddiehoffman) +* [@inteon](https://github.com/inteon) +* [@anton-johansson](https://github.com/anton-johansson) +* [@edglynes](https://github.com/edglynes) +* [@jandersen-plaid](https://github.com/jandersen-plaid) +* [@foosinn](https://github.com/foosinn) +* [@jsoref](https://github.com/jsoref) +* [@clatour](https://github.com/clatour) +* [@tamalsaha](https://github.com/tamalsaha) + +## Deprecated Features and Breaking Changes + +### Removal of the cert-manager operator package on Red Hat Marketplace + +Since cert-manager `v0.15` there has been a package for cert-manager on [Red Hat Marketplace][], +but this has now been removed because it was not maintained and was found to be unreliable: +[#4055](https://github.com/cert-manager/cert-manager/issues/4055) +[#3732](https://github.com/cert-manager/cert-manager/issues/3732) +[#436](https://github.com/cert-manager/website/issues/436) + +[Red Hat Marketplace]: https://marketplace.redhat.com + +It is replaced by a new package which is generated via the [Community Operators Repository][], +and which is therefore available on +[OperatorHub.io](https://operatorhub.io), +[OpenShift Container Platform](https://openshift.com) and +[OKD](https://okd.io). + +[Community Operators Repository]: https://github.com/operator-framework/community-operators + +Please uninstall the existing cert-manager package and re-install +by following the [OLM Installation Documentation][]. + +[OLM Installation Documentation]: ../../installation/operator-lifecycle-manager.md + +### Upgrading cert-manager CRDs and stored versions of cert-manager custom resources + +We have deprecated the following cert-manager APIs: + +- `cert-manager.io/v1alpha2` +- `cert-manager.io/v1alpha3` +- `cert-manager.io/v1beta1` +- `acme.cert-manager.io/v1alpha2` +- `acme.cert-manager.io/v1alpha3` +- `acme.cert-manager.io/v1beta1` + +These APIs will be removed in cert-manager 1.6. + +
          + +⛔️ If you are upgrading cert-manager on a cluster which has previously had +cert-manager < `v1.0.0`, you will need to ensure that all cert-manager custom +resources are stored in `etcd` at `v1` version and that cert-manager CRDs do not +reference the deprecated APIs **by the time you upgrade to `v1.6`**. + +This is explained in more detail in the [Upgrading existing cert-manager +resources](../upgrading/remove-deprecated-apis.md#upgrading-existing-cert-manager-resources) +page. + +
          + +This change was made in the cert-manager PR [#4021][]. + +[#4021]: https://github.com/cert-manager/cert-manager/pull/4021 "Warn about removal of old v1alpha2, v1alpha3 and v1beta1 in 1.6" + +### Helm chart: `securityContext` defaults to non-root + +The Helm chart now follows the current Pod hardening best practices as defined +by the Kyverno [`pod-security +restricted`](https://kyverno.io/policies/pod-security/#restricted) policy. + +To pass the validation, the controller, webhook, and cainjector Pods are now +running as non-root: + +```yaml +apiVersion: v1 +kind: Pod +spec: + securityContext: + runAsNonRoot: true +``` + +
          + +⛔️ If you are using custom containers that run as root with the Helm chart, you +will need to set this back to `false`. + +
          + +Implemented in the cert-manager PR [#4036][]. + +[#4036]: https://github.com/cert-manager/cert-manager/pull/4036 "controller, cainject and webhook now run as non-root" + +### CA, Vault and Venafi issuer handling of `ca.crt` and `tls.crt` + +The CA, Vault, and Venafi issuer now produce a `tls.crt` that is de-duplicated, +in the correct order (leaf at the top, issuing certificate at the bottom) and +verified (i.e. each signature can be verified). + +The CA issuer now produces a `ca.crt` that contains the "most" root CA that +cert-manager is aware of. `ca.crt` may thus not be the actual self-signed root +CA, since cert-manager may not be aware of it. + +Fixed in the cert-manager PRs [#3982][], [#3983][], and [#3985][]. + +
          + +⛔️ You may need to adjust systems that consume the `ca.crt` from Secrets +managed by cert-manager with the CA issuer. + +
          + +[#3982]: https://github.com/cert-manager/cert-manager/pull/3982 "All issuers + Vault issuer" +[#3983]: https://github.com/cert-manager/cert-manager/pull/3983 "Venafi issuer" +[#3985]: https://github.com/cert-manager/cert-manager/pull/3985 "CA issuer" + + +### Vault renewal bug + +The renewal behavior has changed when a Certificate has a `duration` value of +more than 90 days and `renewBefore` has not been set. + +Previously, the Certificate was renewed 30 days before expiry; now, the renewal +happens 2/3 through the duration. + +This change was necessary to fix a bug where users of the Vault issuer would see +a clash between the default renewal duration of 30 days and the duration of +certificates issued by the Vault PKI. + +
          + +⛔️ If you were relying on the default renewal happening 30 days before expiry, +we would advise setting `renewBefore` to 30 days (`720h`) to keep the old +behavior. + +
          + +Fixed in the cert-manager PR [#4092][]. + +[#4092]: https://github.com/cert-manager/cert-manager/pull/4092 "Default renewal changed from 30 days before expiry to 1/3 of the duration before expiry" + +## New Features + +### Experimental Support for Kubernetes CertificateSigningRequests + +It is now possible to use the built-in Kubernetes [CertificateSigningRequest][] +resources with cert-manager. The CA Issuer is currently the only supported +issuer. The feature is experimental and can be enabled by adding a flag to the +cert-manager controller. For example, with Helm: + +```sh +helm install cert-manager jetstack/cert-manager \ + --set extraArgs="{--feature-gates=ExperimentalCertificateSigningRequestControllers=true}" +``` + +Note that you will still need to manually approve the CSR object before +cert-manager can sign the CSR. + +The documentation is available on the [the Kubernetes CSR usage +page](../../usage/kube-csr.md). + +Implemented in cert-manager PR [#4064][]. + +[#4064]: https://github.com/cert-manager/cert-manager/pull/4064 "CA issuer experimental support for CertificateSigningRequests" +[CertificateSigningRequest]: https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/ + +### Helm chart: webhook externally accessible for bare-metal + +In [some](https://github.com/kubernetes/kubernetes/issues/72936#issue-399522387) +Kubernetes setups, the apiserver is not able to talk to `kube-dns` (i.e., when +Kubernetes is running on bare-metal with no special `resolv.conf`). + +To work around that, the cert-manager webhook can now be configured to be +accessible from outside of the cluster. For example, in `values.yaml`: + +```yaml +# values.yaml +webhook: + serviceType: LoadBalancer + loadBalancerIP: 198.51.100.20 + url: + host: 198.51.100.20 +``` + +Implemented in cert-manager PRs [#3876][], [#3932][]. + +[#3932]: https://github.com/cert-manager/cert-manager/pull/3932 "Adds support for accessing coversion webhook from outside cluster network" +[#3876]: https://github.com/cert-manager/cert-manager/pull/3876 "Adds support for accessing mutating and validating webhooks from outside cluster network" + +### Helm chart: Service labels + +The cert-manager controller Service now supports custom labels using the +top-level field in `values.yaml`: + +```yaml +# values.yaml +serviceLabels: + app: armada-api +``` + +This may be useful in conjunction with Prometheus' `labelmap`. For example, with +the following sample Prometheus configuration: + +```yaml +# prometheus.yaml +- action: labelmap + regex: __meta_kubernetes_service_label_(.+) +``` + +With the above example, the source label +`__meta_kubernetes_service_label_app='armada-api'` becomes the new label +`app='armada-api'` when metrics related to this Service are scraped. + +Implemented in the cert-manager PR [#4009][]. + +[#4009]: https://github.com/cert-manager/cert-manager/pull/4009 "Helm chart: the Service labels can now be set on the controller" + +### Akamai DNS01 solver + +The Akamai DNS01 solver has been [updated][4007] to use the v2 of the `OPEN +EdgeGrid` Go package. + +[#4007]: https://github.com/cert-manager/cert-manager/pull/4007 "Update of the Akamai DNS01 solver" + +## Bug Fixes + +- The [RFC2136](https://cert-manager.io/docs/configuration/acme/dns01/rfc2136/) + issuer is now able to handle DNS01 challenges that map to multiple `TXT` + records. This lets you create Let's Encrypt certificates using RFC2136 with + multiple DNS names. Fixed in the cert-manager PR [#3622][]. +- The comparison function `PublicKeysEqual` is now correct for public keys. + Fixed in PR [#3914][]. +- The ACME issuer now works correctly with Certificates that have a long name + (52 characters or more). These Certificates would not get renewed due to + non-unique Order names being generated. Fixed in the cert-manager PR + [#3866][]. +- Orders that are used with a misbehaving ACME server should not get stuck + anymore. By misbehaving, we mean an ACME server that would validate the + authorizations before having set the status of the order to "ready". Fixed in + the cert-manager PR [#3805][]. +- The internal issuers now set the condition `Ready=False` with the reason + `RequestDenied` when a CertificateRequest has been `Denied`. This is to keep + the same behavior where a terminal state of a CertificateRequest should have a + `Ready` condition. Fixed in the cert-manager PR [#3878][]. + +[#3622]: https://github.com/cert-manager/cert-manager/pull/3622 "RFC2136 fixed when used with challenge domains that contain multiple TXT records" +[#3914]: https://github.com/cert-manager/cert-manager/pull/3914 "Comparison between public keys now works properly" +[#3866]: https://github.com/cert-manager/cert-manager/pull/3866 "Certificates with long names are not generated non-unique Orders anymore" +[#3805]: https://github.com/cert-manager/cert-manager/pull/3805 "Misbehaving ACME servers won't get Orders stuck anymore" +[#3878]: https://github.com/cert-manager/cert-manager/pull/3878 "When a CertificateRequest is Denied, the internal issuers set Ready=False" + +## Other Changes + +- The cert-manager controller now uses the `configmapsleases` resource instead + of the `configmaps` one for leader election. The only noticeable difference is + that a new `Lease` object is now being created in the leader election + namespace. Implemented in the cert-manager PR [#4016][]. + +[#4016]: https://github.com/cert-manager/cert-manager/pull/4016 "Use the configmapsleases resource instead of configmaps" + +- The `keyAlgorithm` for the ACME Issuer is now deprecated, and the EAB MAC + algorithm is now hard-coded to `HS256`. + + ```yaml + apiVersion: cert-manager.io/v1 + kind: Issuer + spec: + acme: + externalAccountBinding: + keyAlgorithm: HS256 # DEPRECATED. + ``` + Previously, we used to have a fork of `golang/crypto` which allowed us to set + the EAB MAC algorithm. We now use the upstream version of `golang/crypto` + where the EAB MAC algorithm is hard-coded to HS256. + + This change were implemented in the cert-manager PRs [#3877][] and [#3936][]. + +[#3877]: https://github.com/cert-manager/cert-manager/pull/3877 "Deprecation of the keyAlgorithm field" +[#3936]: https://github.com/cert-manager/cert-manager/pull/3936 "Webhook warns the user when keyAlgorithm is used" + +- If you happen to look at the cert-manager controller logs, you may see this + new message about optimistic locking: + + ``` + I0419 controller.go:158] msg="re-queuing item due to optimistic locking on resource" error="Operation cannot be fulfilled on certificates.cert-manager.io sauron-adverts-evo-app-tls: the object has been modified; please apply your changes to the latest version and try again" + ``` + + This message, shown at the `info` level, replaces the `error` level message + that showed previously: + + ``` + E0419 controller.go:158] msg="re-queuing item due to error processing" error="Operation cannot be fulfilled on certificates.cert-manager.io sauron-adverts-evo-app-tls: the object has been modified; please apply your changes to the latest version and try again" + ``` + + The goal is to prevent users from thinking that the optimistic locking + mechanism has to do with their issues, when in reality it mostly isn't and is + the normal operation mode for Kubernetes controllers. + + Fixed in the cert-manager PR [#3794][]. + +[#3794]: https://github.com/cert-manager/cert-manager/pull/3794 "Less alarming message on optimistic locking errors" + +- The `util.UsageContentCommittment` (which contained a spelling mistake) was + deprecated in favor of `util.UsageContentCommitment`. The only people impacted + by this deprecation are the the people importing the Go package + `github.com/jetstack/cert-manager/pkg/api/util`. + +[#3860]: https://github.com/cert-manager/cert-manager/pull/3860 "Fix a spelling mistake in a cert-manager Go package and deprecate the old name" + +- The webhook now panics when it is not able to register the API schemes. + Previously, the webhook would silently skip the error and start. + +[#4037]: https://github.com/cert-manager/cert-manager/pull/4037 "Webhook now panics instead of silently starting if the API scheme cannot be registered" + +- A couple of legacy functions in `test/e2e/util` package have been removed. + These functions can be found in the `test/unit/gen` package. + +[#3873]: https://github.com/cert-manager/cert-manager/pull/3873 "Legacy functions in the test/e2e/util have been removed" + +- The Kubernetes Go dependencies have been updated from `v0.19.0` to `v0.21.0`. + +[#3926]: https://github.com/cert-manager/cert-manager/pull/3926 "Update Kubernetes Go imports from v0.19.0 to v0.21.0" + +- When waiting for DNS propagating, the ACME DNS01 self-check now returns a + better message when an unexpected DNS response code is received, such as + `SERVFAIL`. + + Before: + ``` + Could not find the start of authority + ``` + + After: + ``` + Could not find the SOA record in the DNS tree + for the domain '_acme-challenge.foo.example.com' + using nameservers [8.8.8.8, 8.8.4.4] + ``` + + In addition to the above, you will get a new message when the DNS returns an + unexpected response code: + + ``` + When querying the SOA record for the domain + '_acme-challenge.foo.example.com' using nameservers + [8.8.8.8, 8.8.4.4], rcode was expected to be 'NOERROR' + or 'NXDOMAIN', but got 'SERVFAIL' + ``` + + Fixed in the cert-manager PR [#3906][]. + +[#3906]: https://github.com/cert-manager/cert-manager/pull/3906 "Better message when the ACME DNS01 self-check gets an unexpected DNS response code" + +- The `distroless/static` base image was updated to the latest version as of + 2021-05-20. + +## Honorable mentions + +Tim Ramlot ([@inteon](https://github.com/inteon)) has done a fantastic job at +adding the Istio `VirtualService` support for HTTP01 challenges in +[#3724](https://github.com/cert-manager/cert-manager/pull/3724). It took an immense +effort to have this PR ready and merged for the 1.4 release. + +After a lot of thinking, we have decided that trying to support every custom +resource for every proxy could not be done in-tree due to the Go dependency +weight that each integration adds. Jake Sanders proposed an [out-of-tree +approach](https://github.com/cert-manager/cert-manager/issues/3924) that will be +worked on as part of cert-manager 1.5. \ No newline at end of file diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.5.md b/content/v1.15-docs/releases/release-notes/release-notes-1.5.md new file mode 100644 index 0000000000..d3e03aa619 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.5.md @@ -0,0 +1,416 @@ +--- +title: Release 1.5 +description: 'cert-manager release notes: cert-manager v1.5' +--- + +## v1.5.5 + +### Changelog since v1.5.4 + +In 1.5.5, we have reverted a change that caused a regression in the ACME Issuer. +Before 1.5.4, the Ingress created by cert-manager while solving an HTTP-01 challenge contained the `kubernetes.io/ingress.class` annotation: + +```yaml +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: istio # The `class` present on the Issuer. +``` +In 1.5.4, the Ingress does not contain the annotation anymore. Instead, cert-manager uses the `ingressClassName` field: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +spec: + ingressClassName: istio # 🔥 Breaking change! +``` + +This broke many users that either don't use an Ingress controller that supports the field (such as ingress-gce and Azure AGIC), as well as people who did not need to create an IngressClass previously (such as with Istio and Traefik). + +The regression is present in cert-manager 1.5.4, 1.6.0, 1.6.1. It is only present on Kubernetes 1.19+ and only appears when using an Issuer or ClusterIssuer with an ACME HTTP-01 solver configured. + +In 1.5.5, we have restored the original behavior which is to use the annotation. We will also backport this fix to 1.5.5 and 1.6.2, allowing people to upgrade safely. + +Most people won't have any trouble upgrading from a version that contains the regression to 1.7.0, 1.6.2 or 1.5.5. If you are using Gloo, Contour, Skipper, or kube-ingress-aws-controller, you shouldn't have any issues. If you use the default "class" (e.g., `istio` for Istio) for Traefik, Istio, Ambassador, or ingress-nginx, then these should also continue to work without issue. + +If you are using Traefik, Istio, Ambassador, or ingress-nginx _and_ you are using a non-default value for the class (e.g., `istio-internal`), or if you experience any issues with your HTTP-01 challenges please read the [notes on Ingress v1 compatibility]. + +[notes on Ingress v1 compatibility]: https://cert-manager.io/docs/releases/upgrading/ingress-class-compatibility/ + +#### Bug or Regression + +- Fixed a regression where cert-manager was creating Ingresses using the field `ingressClassName` instead of the annotation `kubernetes.io/ingress.class`. More details about this regression are available [in the 1.7 release notes](https://cert-manager.io/docs/release-notes/release-notes-1.7/#ingress-class-semantics). ([#4783](https://github.com/cert-manager/cert-manager/pull/4783), [@maelvls](https://github.com/maelvls)) + +#### Other (Cleanup or Flake) + +- cert-manager now does one call to the ACME API instead of two when an Order fails. This belongs to the effort towards mitigating [the high load](https://github.com/cert-manager/cert-manager/issues/3298) that cert-manager deployments have on the Let's Encrypt API ([#4618](https://github.com/cert-manager/cert-manager/pull/4618), [@irbekrm](https://github.com/irbekrm)) + +## v1.5.4 + +### Changelog since v1.5.3 + +#### Bug or Regression + +- Fixed a bug that caused cert-manager to panic when the Vault Issuer failed to reach the health endpoint. ([#4476](https://github.com/cert-manager/cert-manager/pull/4476), [@JoshVanL](https://github.com/JoshVanL)) +- Helm chart: the post-install hook `startupapicheck` is now compatible with the PodSecurityPolicy resource. ([#4432](https://github.com/cert-manager/cert-manager/pull/4432), [@ndegory](https://github.com/ndegory)) +- Helm chart: the post-install hook `startupapicheck` now deletes any post-install hook resources left after a previous failed install allowing `helm install` to be re-run after a failed attempt. ([#4435](https://github.com/cert-manager/cert-manager/pull/4435), [@wallrj](https://github.com/wallrj)) + +#### Other (Cleanup or Flake) + +- Update cert-manager base image versions ([#4479](https://github.com/cert-manager/cert-manager/pull/4479), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.5.3 + +### Changelog since v1.5.2 + +#### Bug or Regression + +- Fix a bug where a Certificate may not get renewed when the issued Certificate has a one-second skew between `notBefore` and `notAfter` and `spec.duration` is not used. This one-second skew can be observed on certificates issued with Let's Encrypt and caused a mismatch in time precision between the time stored in `status.renewalTime` and the time internally computed by cert-manager. ([#4403](https://github.com/cert-manager/cert-manager/pull/4403), [@irbekrm](https://github.com/irbekrm)). Thanks to [@mfmbarros](https://github.com/mfmbarros) for help with debugging the issue! + +## v1.5.2 + +### Changelog since v1.5.1 + +#### Bug or Regression + +- Fix a regression introduced in v1.5.0 where the Ingress created for solving HTTP-01 challenges was created with `pathType: Exact` instead of `pathType: ImplementationSpecific`. ([#4385](https://github.com/cert-manager/cert-manager/pull/4385), [@jakexks](https://github.com/jakexks)) +- Fixed the HTTP-01 solver creating ClusterIP instead of NodePort services by default. ([#4394](https://github.com/cert-manager/cert-manager/pull/4394), [@jakexks](https://github.com/jakexks)) +- Helm chart and static manifest: the pointless `status` field is now stripped from the CRD manifests. ([#4387](https://github.com/cert-manager/cert-manager/pull/4387), [@irbekrm](https://github.com/irbekrm)) + +## v1.5.1 + +The CRDs for the cert-manager v1beta1 API were mistakenly changed in cert-manager v1.5.0. If you +installed the CRDs for v1.5.0, you should upgrade your CRDs to v1.5.1. + +The only affected API version is v1beta1, so if you're using the latest version - v1 - you won't +be affected by the CRD changes. It's worth upgrading to v1 in any case, since v1alpha2, v1alpha3 and +v1beta1 are all deprecated and will be removed in a future release. + +### Changelog since v1.5.0 + +#### Bug or Regression + +- Fix `v1beta1` CRDs which were accidentally changed in cert-manager v1.5.0 ([#4355](https://github.com/cert-manager/cert-manager/pull/4355), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.5.0 + +### Major Themes + +#### API Deprecation + +The recent Kubernetes 1.22 release has removed a number of deprecated APIs. You +can read the official blog post [Kubernetes API and Feature Removals In +1.22](https://kubernetes.io/blog/2021/07/14/upcoming-changes-in-kubernetes-1-22/) +to learn more about it. If you intend to upgrade to Kubernetes 1.22, you +**must** upgrade to cert-manager 1.5. + +To keep compatibility with older Kubernetes versions (down to 1.16), +cert-manager 1.5 is now compatible with both Ingress `v1` and `v1beta1`. +cert-manager will default to using `v1` Ingress, and fall back to `v1beta1` when +`v1` is not available. + +Please read the [Ingress class compatibility](../upgrading/ingress-class-compatibility.md) +notes to see if your Ingress controller has any known issues. + +Additionally, the cert-manager API versions `v1alpha2`, `v1alpha3` and `v1beta1` +are now deprecated, and will be removed in cert-manager 1.7. Please change all +your YAML manifests that use a deprecated API version to use +`cert-manager.io/v1` instead, and re-apply them. + +These deprecation changes have been implemented in the cert-manager PRs +[#4225](https://github.com/cert-manager/cert-manager/pull/4225) and +[#4172](https://github.com/cert-manager/cert-manager/pull/4172). + +### Experimental Features + +Features that we are currently working on are included in cert-manager releases +but disabled by default, as they are likely to change in future. If any of them +look interesting to you, please try them out and report bugs or quirks in a +GitHub Issue. + +#### Gateway API + +We have seen many requests from users to support different ways of routing HTTP +traffic into their clusters for solving ACME HTTP-01 challenges. As the +cloud-native ecosystem has so many different ingress implementations, we +searched for a solution that would avoid having to add individual support for +every kind of virtual service to the cert-manager API, and settled on the +[sig-network Gateway API](https://gateway-api.sigs.k8s.io/). + +The Gateway API project aims to provide a universal API for modeling service +networking in Kubernetes, and while it is still in its alpha stages is already +gaining [wide +adoption](https://gateway-api.sigs.k8s.io/references/implementations/). By +supporting the Gateway API HTTPRoute resource, we hope that anyone using +Ambassador, Contour, Gloo, HAProxy, Istio, Kong or Traefik will be able to solve +HTTP-01 challenges, with more implementations coming in future. + +To go along with the HTTPRoute resource support, we have also added a +gateway-shim controller that will allow users to annotate their Gateway +resources to get a cert-manager Certificate automatically created, similar to +the current ingress-shim functionality. + +Implemented in the cert-manager PRs +[#4276](https://github.com/cert-manager/cert-manager/pull/4276) and +[#4158](https://github.com/cert-manager/cert-manager/pull/4158). + +#### CertificateSigningRequests + +CertificateSigningRequest is a built-in Kubernetes resource that was originally +aimed at requesting X.509 client certificates and serving certificates for +Kubernetes components such as kubelet. + +We have seen a rising interest in using the CertificateSigningRequest (CSR) +resource as a way to provision workload certificates in service meshes such as +Istio and its [Istio Custom CA Integration using Kubernetes +CSR](https://istio.io/latest/docs/tasks/security/cert-management/custom-ca-k8s/). +For that purpose, the CSR resource needs to be integrated with existing signers +such as HashiCorp Vault or Venafi TPP. + +Back in cert-manager 1.4, the CA Issuer became the first built-in cert-manager +issuer to support signing CertificateSigningRequest resources. In 1.5, we +extended the support to all existing Issuers. + +The support for signing CSR resources is still experimental and requires to be +explicitly enabled. If you are interested, please take a look at the [Kubernetes +CertificateSigningRequest](https://cert-manager.io/docs/usage/kube-csr/) +documentation on the cert-manager website. + +To help you try the CSR support, you may want to try a new command that was +added to the kubectl plugin. It allows you to create a CSR resource out of a +cert-manager Certificate manifest: + +```shell +kubectl cert-manager x create certificatesigningrequest example-csr certificate.yaml +``` + +Finally, we decided to remove the annotation `experimental.cert-manager.io/ca` +that was added to the CertificateSigningRequest resource after being signed by +cert-manager. This annotation was introduced in cert-manager 1.4 and will no +longer be set on CertificateSigningRequest resources. We removed this annotation +due to a technical limitation related to the fact that Kubernetes resources have +a status subresource that is separate from the main resource. + +The above features were implemented in the cert-manager PRs +[#4112](https://github.com/cert-manager/cert-manager/pull/4112), +[#4100](https://github.com/cert-manager/cert-manager/pull/4100), +[#4103](https://github.com/cert-manager/cert-manager/pull/4103), +[#4108](https://github.com/cert-manager/cert-manager/pull/4108), +[#4106](https://github.com/cert-manager/cert-manager/pull/4106), and +[#4143](https://github.com/cert-manager/cert-manager/pull/4143) + +### User Experience + +#### kubectl plugin + +cert-manager comes with a kubectl plugin, `kubectl cert-manager`, that comes in +handy for checking the status of your cert-manager Certificate resources. + +In 1.5, a new experimental command for installing cert-manager has been added. +Under the hood, it uses the cert-manager Helm chart. This means that all helm +templating options are also supported by this install command: + +```bash +kubectl cert-manager x install \ + --set prometheus.enabled=false \ # Example: disabling prometheus using a Helm parameter + --set webhook.timeoutSeconds=4s # Example: changing the wehbook timeout using a Helm parameter +``` + +An interesting feature that comes when using with this new `install` command is +that it installs the CRDs in a way that prevents `helm uninstall` from deleting +the CRDs while uninstalling cert-manager. + +The plugin is now capable of determining when your cert-manager deployment is +ready to be used: + +```shell +kubectl cert-manager check api +``` + +The plugin also learned how to discover the version of cert-manager running on your +cluster, similar to `kubectl version`: + +```shell +kubectl cert-manager version +``` + +To install the plugin, check out the [Kubectl +plugin](https://cert-manager.io/docs/installation/kubectl-plugin/) page on +the cert-manager website. + +These features were implemented by Tim in the cert-manager PRs +[#4226](https://github.com/cert-manager/cert-manager/pull/4226), +[#4205](https://github.com/cert-manager/cert-manager/pull/4205), and +[#4138](https://github.com/cert-manager/cert-manager/pull/4138). + +#### Helm chart + +While installing cert-manager using Helm, you might have noticed that the +`--wait` flag does not wait until cert-manager is fully functional. + +With 1.5, the `--wait` flag now works as you would expect. The Helm chart now +comes with a small startup job that waits until the cert-manager API becomes +ready. + +Implemented in the cert-manager PR +[#4234](https://github.com/cert-manager/cert-manager/pull/4234) by Tim. + +#### Labels and annotations on generated Secret and CertificateRequest resources + +cert-manager now allows you to add custom annotations and labels to the Secret +containing the TLS key pair using the new Certificate field `secretTemplate`. +This is useful when using third-party solutions such as +[kubed](https://github.com/kubeops/kubed) to copy Secret resources to multiple +namespaces. The `secretTemplate` is synced to the Secret when the Certificate is +created or renewed. + +Here is an example of Certificate using the `secretTemplate` field: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +spec: + secretTemplate: + annotations: + my-secret-annotation: "foo" + labels: + my-secret-label: bar +``` + +Note that labels and annotations can only be added or replaced, but not removed. +Removing any labels or annotations from the template or removing the template +itself will have no effect. + +Along with the ability to set your own annotations and labels on Secret +resources created by cert-manager, you can also tell cert-manager which +annotations should be copied from Certificate resources to the generated +CertificateRequest resources. By default, cert-manager will skip copying the +annotations with the following prefixes: + +- `kubectl.kubernetes.io/`, +- `fluxcd.io`, +- `argocd.argoproj.io`. + +If you wish to keep the old behavior and allow all annotations to be copied, you +can pass the flag `--copied-annotations=*` to the cert-manager controller. + +Implemented in the cert-manager PRs +[#3828](https://github.com/cert-manager/cert-manager/pull/3828) and +[#4251](https://github.com/cert-manager/cert-manager/pull/4251). + +### Community + +This is the first time that cert-manager participated in Google Summer of Code. +Congratulations to [Arsh](https://github.com/RinkiyaKeDad) and +[Tim](https://github.com/inteon) for completing their GSoC projects! We hope you +both continue to contribute in future. + +Thanks again to all open-source contributors with commits in this release: + +- [alrs](https://github.com/alrs) +- [annerajb](https://github.com/annerajb) +- [Dean-Coakley](https://github.com/Dean-Coakley) +- [francescsanjuanmrf](https://github.com/francescsanjuanmrf) +- [inteon](https://github.com/inteon) +- [jonathansp](https://github.com/jonathansp) +- [kit837](https://github.com/kit837) +- [longkai](https://github.com/longkai) +- [mozz-lx](https://github.com/mozz-lx) +- [RinkiyaKeDad](https://github.com/RinkiyaKeDad) +- [tamalsaha](https://github.com/tamalsaha) +- [thiscantbeserious](https://github.com/thiscantbeserious) +- [ulrichgi](https://github.com/ulrichgi) +- [wpjunior](https://github.com/wpjunior) + +Also thanks to [coderanger](https://github.com/coderanger) for helping people +out on the Slack `#cert-manager` channel; it's a huge help and much appreciated. + + + +--- + +#### New Features + +- cert-manager now supports using Ed25519 private keys and signatures for + Certificates. Implemented in the cert-manager PR + [#4079](https://github.com/cert-manager/cert-manager/pull/4079). +- cert-manager now emits an event when a CertificateSigningRequest resource has + not yet been approved. Without this event, the user would never know that + cert-manager is waiting for the approval of the CertificateSigningRequest + resource. Implemented in the cert-manager PR + [#4229](https://github.com/cert-manager/cert-manager/pull/4229). +- cert-manager now only supports the version `v1` of the `AdmissionReviewVersion` + and `ConversionReviewVersion` resources, both available since Kubernetes 1.16. + The `v1beta1` version is no longer supported by cert-manager. This change was + implemented in the cert-manager PRs + [#4254](https://github.com/cert-manager/cert-manager/pull/4254) and + [#4253](https://github.com/cert-manager/cert-manager/pull/4253). +- cert-manager now restarts more quickly by clearing the leader election before + shutting down. Also, upon shutdown, the controller loops now cleanly stop, + which allows all in-flight reconciliation functions to finish before exiting. + Implemented in the cert-manager PR + [#4243](https://github.com/cert-manager/cert-manager/pull/4243). +- Metrics: a new metric, named `clock_time_seconds` was added; this metric + allows for monitoring systems that do not have a built-in time function (e.g. + DataDog) to calculate the number of seconds until a certificate expires by + subtracting this metric from the existing `certificate_expiration_timestamp` + metrics. Implemented in the cert-manager PR + [#4105](https://github.com/cert-manager/cert-manager/pull/4105). +- Helm chart: the Prometheus scraping service port now has a name. Implemented + in the cert-manager PR + [#4072](https://github.com/cert-manager/cert-manager/pull/4072). +- Helm chart: you can now configure the labels for the cert-manager-webhook + service using the Helm value `webhook.serviceLabels`. Implemented in the + cert-manager PR [#4260](https://github.com/cert-manager/cert-manager/pull/4260). + +#### Bug or Regression + +- Security: cert-manager now times out after 10 second when performing the + self-check while solving HTTP-01 challenges. Fixed in the cert-manager PR + [#4311](https://github.com/cert-manager/cert-manager/pull/4311). +- Cloudflare: Refactored DNS01 challenge to use API for finding the nearest Zone + (fixing potential DNS issues) + ([#4147](https://github.com/cert-manager/cert-manager/pull/4147), + [@thiscantbeserious](https://github.com/thiscantbeserious)) +- Fix a bug where failed CertificateRequest resources were not retried + ([#4130](https://github.com/cert-manager/cert-manager/pull/4130), + [@irbekrm](https://github.com/irbekrm)) +- Fix a regression that would lead to a Certificate becoming "Failed" when the + issued X.509 certificate's subject DN would be equal to the issuer's subject + DN. Fixed in the cert-manager PR + [#4237](https://github.com/cert-manager/cert-manager/pull/4237). +- Fix a regression where the `tls.crt` certificate chain would unexpectedly not + contain an intermediate CA certificate when no root CA is available in the CA + chain returned by the issuer. This bug affected the Vault Issuer, Venafi + Issuer and CA Issuer. This bug was fixed in the cert-manager PR + [#4261](https://github.com/cert-manager/cert-manager/pull/4261). +- Fix a goroutine leak that was causing the controller's memory usage to grow + with time. Fixed in the cert-manager PR + [#4233](https://github.com/cert-manager/cert-manager/pull/4233). +- Fix a race condition introduced in cert-manager 0.15 that would crash + cert-manager for clusters with a large number of certificates. Fixed in the + cert-manager PR [#4231](https://github.com/cert-manager/cert-manager/pull/4231). +- Fix a bug where the default renewal duration of certificate, set to 30 days, + would clash with the duration of certificates issued by the Vault Issuer. All + Certificate resources are now renewed 2/3 through the duration unless a custom + renew period is specified by setting `renewBefore` on the Certificate. Fixed + in the cert-manager PR + [#4092](https://github.com/cert-manager/cert-manager/pull/4092). +- The cert-manager binaries, including the kubectl plugin, now exit with the + correct exit code on SIGINT (Ctrl+C) and SIGTERM events. More specifically, + when one of these events is caught, cert-manager will exit with the code 128 + + signal number. Fixed in + [#4230](https://github.com/cert-manager/cert-manager/pull/4230). +- The static manifests available on the GitHub Releases page now contain a + version label `app.kubernetes.io/version: v1.5.0`. We also removed the + Helm-specific labels from the static manifests. Fixed in the cert-manager PR + [#4190](https://github.com/cert-manager/cert-manager/pull/4190). + +#### Other (Cleanup or Flake) + +- A conformance end-to-end testing suite was added for the + CertificateSigningRequest resources + ([#4101](https://github.com/cert-manager/cert-manager/pull/4101)). +- Reduce binary sizes from 74MB down to 49MB by adding the Go ldflag `-w` + ([#4181](https://github.com/cert-manager/cert-manager/pull/4181)). diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.6.md b/content/v1.15-docs/releases/release-notes/release-notes-1.6.md new file mode 100644 index 0000000000..74a9ce2809 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.6.md @@ -0,0 +1,162 @@ +--- +title: Release 1.6 +description: 'cert-manager release notes: cert-manager v1.6' +--- + +## v1.6.3 + +### Changes since 1.6.2 + +#### Bug or Regression + +- Bumps the version of Go used to build the cert-manager binaries to 1.17.8, to fix a slew of CVEs (none of which were likely to be exploited) ([#4975](https://github.com/cert-manager/cert-manager/pull/4975), [@vhosakot](https://github.com/vhosakot)) +- Fixes an expired hardcoded certificate which broke unit tests ([#4977](https://github.com/cert-manager/cert-manager/pull/4977), [@SgtCoDFish](https://github.com/SgtCoDFish), [@jakexks](https://github.com/jakexks)) + +## v1.6.2 + +In 1.6.2, we reverted a change that caused a regression in the ACME Issuer. In 1.6.0 and 1.6.1, the Ingress created by cert-manager while solving an HTTP-01 challenge contained the `kubernetes.io/ingress.class` annotation: + +```yaml +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: istio # The `class` present on the Issuer. +``` + +After 1.5, the Ingress does not contain the annotation anymore. Instead, cert-manager uses the `ingressClassName` field: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +spec: + ingressClassName: istio # 🔥 Breaking change! +``` + +This broke many users that either don't use an Ingress controller that supports the field (such as ingress-gce and Azure AGIC), as well as people who did not need to create an IngressClass previously (such as with Istio and Traefik). + +The regression is present in cert-manager 1.5.4, 1.6.0, and 1.6.1. It is only present on Kubernetes 1.19+ and only appears when using an Issuer or ClusterIssuer with an ACME HTTP-01 solver configured. + +In 1.6.2, we restored the original behavior which is to use the annotation. This patch is also available in 1.5.5 and in 1.7.0. + +Most people won't have any trouble upgrading from 1.6.0 or 1.6.1 to 1.6.2. If you are using Gloo, Contour, Skipper, or kube-ingress-aws-controller, you shouldn't have any issues. If you use the default "class" (e.g., `istio` for Istio) for Traefik, Istio, Ambassador, or ingress-nginx, then these should also continue to work without issue. + +If you are using Traefik, Istio, Ambassador, or ingress-nginx _and_ you are using a non-default value for the class (e.g., `istio-internal`), or if you experience any issues with your HTTP-01 challenges please read the [notes on Ingress v1 compatibility]. + +[notes on Ingress v1 compatibility]: https://cert-manager.io/docs/releases/upgrading/ingress-class-compatibility/ + +### Changelog since v1.6.1 + +#### Bug or Regression + +- The HTTP-01 ACME solver now uses the `kubernetes.io/ingress.class` annotation instead of the `spec.ingressClassName` in created Ingress resources. ([#4785](https://github.com/cert-manager/cert-manager/pull/4785), [@maelvls](https://github.com/maelvls)) + +#### Other (Cleanup or Flake) + +- cert-manager now does one call to the ACME API instead of two when an Order fails. This fix is part of the effort towards mitigating [the high load](https://github.com/cert-manager/cert-manager/issues/3298) that cert-manager deployments have on the Let's Encrypt API ([#4619](https://github.com/cert-manager/cert-manager/pull/4619), [@irbekrm](https://github.com/irbekrm)) +- Bump base images to latest versions ([#4707](https://github.com/cert-manager/cert-manager/pull/4707), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.6.1 + +### Changelog since v1.6.0 + +#### Bug or Regression + +- Fixes an issue in `cmctl` that prevented displaying the Order resource with cert-manager 1.6 when running `cmctl status certificate`. ([#4572](https://github.com/cert-manager/cert-manager/pull/4572), [@maelvls](https://github.com/maelvls)) +- Update to latest version of keystore-go to address a backwards incompatible change introduced in v1.6.0 ([#4564](https://github.com/cert-manager/cert-manager/pull/4564), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.6.0 + +### Breaking Changes (You **MUST** read this before you upgrade!) + +#### Legacy cert-manager API versions are no-longer served + +Following their deprecation in version 1.4, the cert-manager API versions `v1alpha2, v1alpha3, and v1beta1` are no longer served. + +This means if your deployment manifests contain any of these API versions, you will not be able to deploy them after upgrading. Our new `cmctl` utility or old `kubectl cert-manager` plugin can [convert](../../reference/cmctl.md#convert) old manifests to `v1` for you. + +
          + +⛔️ If you are upgrading cert-manager on a cluster which has previously had +cert-manager < `v1.0.0`, you will need to ensure that all cert-manager custom +resources are stored in `etcd` at `v1` version and that cert-manager CRDs do not +reference the deprecated APIs **before you upgrade to `v1.6`**. + +This is explained in more detail in the [Upgrading existing cert-manager resources](../upgrading/remove-deprecated-apis.md#upgrading-existing-cert-manager-resources) +page. + +
          + +#### JKS Keystore Minimum Password Length + +ℹ️ This no longer applies as it was fixed in `v1.6.1`, but will remain here for +informational purposes. If you haven't upgraded cert-manager to `v1.6.0` from any `v1.5` +release, we recommend upgrading straight to the latest version, skipping `v1.6.0`. + +In cert-manager `v1.6.0` [JKS Keystores][jks-keystore] had a minimum password length of 6 characters, +as an unintended side effect of [upgrading keystore-go from `v2` to `v4`][jks-keystore-upgrade-pr]. +If you are using a shorter password, certificates would have failed to renew, +and the only observable error was in the cert-manager logs. +This was fixed in cert-manager `v1.6.1`. + +[jks-keystore]: ../../reference/api-docs.md#cert-manager.io/v1.CertificateKeystores +[jks-keystore-upgrade-pr]: https://github.com/cert-manager/cert-manager/pull/4428 + +### Major Themes + +#### Command-line tool User Experience + +The cert-manager kubectl plugin has been redesigned as a [standalone utility: `cmctl`][cmctl] + +While the kubectl plugin functionality remains intact, using `cmctl` allows for full tab completion. + +[cmctl]: ../../reference/cmctl.md + +#### Supply Chain Security + +As part of the wider ecosystem's push for greater supply chain security we are aiming to achieve [SLSA 3](https://slsa.dev/levels#level-requirements) by the 1.7 release date. cert-manager 1.6 has achieved the requirements for SLSA 2 when installed via helm. Our helm chart's signature can be verified with the cert-manager maintainers' public key [published on our website](../../installation/code-signing.md). + +Our container images will be signed using sigstore's [cosign](https://github.com/sigstore/cosign) as soon as our OCI registry supports it. + +#### Tool Chain Updates + +cert-manager is now built with go 1.17 ([#4478](https://github.com/cert-manager/cert-manager/pull/4478), [@irbekrm](https://github.com/irbekrm)) +and can now be compiled on Apple Silicon ([#4485](https://github.com/cert-manager/cert-manager/pull/4485), [@munnerz](https://github.com/munnerz)). + +### Changelog since v1.5.0 + +#### Feature + +- Add Certificate `RenewBefore` Prometheus metrics ([#4419](https://github.com/cert-manager/cert-manager/pull/4419), [@artificial-aidan](https://github.com/artificial-aidan)) +- Add option to specify managed identity id when using Azure DNS DNS01 solver ([#4332](https://github.com/cert-manager/cert-manager/pull/4332), [@tomasfreund](https://github.com/tomasfreund)) +- Add support for building & developing on M1 macs ([#4485](https://github.com/cert-manager/cert-manager/pull/4485), [@munnerz](https://github.com/munnerz)) +- Adds release targets for both `cmctl` as well as `kubectl-cert_manager` ([#4523](https://github.com/cert-manager/cert-manager/pull/4523), [@JoshVanL](https://github.com/JoshVanL)) +- Allow setting Helm chart service annotations ([#3639](https://github.com/cert-manager/cert-manager/pull/3639), [@treydock](https://github.com/treydock)) +- CLI: Adds `cmctl completion` command for generating shell completion scripts for Bash, ZSH, Fish, and PowerShell ([#4408](https://github.com/cert-manager/cert-manager/pull/4408), [@JoshVanL](https://github.com/JoshVanL)) +- CLI: Adds support for auto-completion on runtime objects (Namespaces, CertificateRequests, Certificates etc.) ([#4409](https://github.com/cert-manager/cert-manager/pull/4409), [@JoshVanL](https://github.com/JoshVanL)) +- CLI: Only expose Kubernetes related flags on commands that use them ([#4407](https://github.com/cert-manager/cert-manager/pull/4407), [@JoshVanL](https://github.com/JoshVanL)) +- Enable configuring CLI command name and registering completion sub-command at build time. ([#4522](https://github.com/cert-manager/cert-manager/pull/4522), [@JoshVanL](https://github.com/JoshVanL)) + +#### Bug or Regression + +- Fix a bug in the Vault client that led to a panic after a request to Vault health endpoint failed. ([#4456](https://github.com/cert-manager/cert-manager/pull/4456), [@JoshVanL](https://github.com/JoshVanL)) +- Fix CRDs which were accidentally changed in cert-manager `v1.5.0` ([#4353](https://github.com/cert-manager/cert-manager/pull/4353), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Fix a regression in Ingress `PathType` introduced in `v1.5.0` ([#4373](https://github.com/cert-manager/cert-manager/pull/4373), [@jakexks](https://github.com/jakexks)) +- Fixed the HTTP-01 solver creating `ClusterIP` instead of `NodePort` services by default. ([#4393](https://github.com/cert-manager/cert-manager/pull/4393), [@jakexks](https://github.com/jakexks)) +- Fix a bug where a Certificate may not get renewed when the issued Certificate has a one-second skew between `notBefore` and `notAfter` and `spec.duration` is not used. This one-second skew can be observed on certificates issued with Let's Encrypt and caused a mismatch in time precision between the time stored in `status.renewalTime` and the time internally computed by cert-manager. ([#4399](https://github.com/cert-manager/cert-manager/pull/4399), [@irbekrm](https://github.com/irbekrm)) +- Helm chart: the post-install hook `startupapicheck` is now compatible with PodSecurityPolicy. ([#4364](https://github.com/cert-manager/cert-manager/pull/4364), [@ndegory](https://github.com/ndegory)) +- Helm chart: the post-install hook `startupapicheck` now deletes any post-install hook resources left after a previous failed install allowing `helm install` to be re-run after a failed attempt. ([#4433](https://github.com/cert-manager/cert-manager/pull/4433), [@wallrj](https://github.com/wallrj)) +- The defaults for leader election parameters are now consistent across cert-manager and cainjector. ([#4359](https://github.com/cert-manager/cert-manager/pull/4359), [@johanfleury](https://github.com/johanfleury)) +- Use `GetAuthorization` instead of `GetChallenge` when querying the current state of an ACME challenge. ([#4430](https://github.com/cert-manager/cert-manager/pull/4430), [@JoshVanL](https://github.com/JoshVanL)) + +#### Other (Cleanup or Flake) + +- Adds middleware logging back to ACME client for debugging ([#4429](https://github.com/cert-manager/cert-manager/pull/4429), [@JoshVanL](https://github.com/JoshVanL)) +- Deprecation: The API versions: `v1alpha2`, `v1alpha3`, and `v1beta1`, are no longer served in cert-manager 1.6 and will be removed in cert-manager 1.7. ([#4482](https://github.com/cert-manager/cert-manager/pull/4482), [@wallrj](https://github.com/wallrj)) +- Expose error messages (e.g., invalid access token) from the Cloudflare API to users; allow live testing using Cloudflare API token (not just key). ([#4465](https://github.com/cert-manager/cert-manager/pull/4465), [@andrewmwhite](https://github.com/andrewmwhite)) +- Fix manually specified `PKCS#10` CSR and X.509 Certificate version numbers (although these were ignored in practice) ([#4392](https://github.com/cert-manager/cert-manager/pull/4392), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Improves logging for 'owner not found' errors for `CertificateRequest`s owning `Order`s. ([#4369](https://github.com/cert-manager/cert-manager/pull/4369), [@irbekrm](https://github.com/irbekrm)) +- Refactor: move from `io/ioutil` to `io` and `os` package ([#4402](https://github.com/cert-manager/cert-manager/pull/4402), [@Juneezee](https://github.com/Juneezee)) +- Helm chart and static manifest: the pointless `status` field is now stripped from the CRD manifests. ([#4379](https://github.com/cert-manager/cert-manager/pull/4379), [@irbekrm](https://github.com/irbekrm)) +- Update cert-manager base image versions ([#4474](https://github.com/cert-manager/cert-manager/pull/4474), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- cert-manager now uses Go 1.17. ([#4478](https://github.com/cert-manager/cert-manager/pull/4478), [@irbekrm](https://github.com/irbekrm)) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.7.md b/content/v1.15-docs/releases/release-notes/release-notes-1.7.md new file mode 100644 index 0000000000..8727e00d09 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.7.md @@ -0,0 +1,222 @@ +--- +title: Release 1.7 +description: 'cert-manager release notes: cert-manager v1.7' +--- + +## v1.7.3 + +v1.7.3 is in effect a bug fix release which increases some hard-coded timeouts which were preventing the use of certain ACME issuers +which sometimes had slower response times. This is known to include ZeroSSL and Sectigo. + +These issues were reported by many users, who we listed and thanked on the [GitHub release](https://github.com/cert-manager/cert-manager/releases/tag/v1.7.3). + +### Changes since v1.7.2 + +#### Bug + +- Increase timeouts for `Issuer` and `ClusterIssuer` controllers to 2 minutes and increase ACME client HTTP timeouts to 90 seconds, in order to enable the use of slower ACME issuers which take a long time to process certain requests. ([#5232](https://github.com/cert-manager/cert-manager/pull/5232), [@JoooostB](https://github.com/JoooostB) [@SgtCoDFish](https://github.com/SgtCoDFish)) + +#### Other (Cleanup) + +- Bumps go to 1.17.11 and bumps base images to latest distroless images ([#5234](https://github.com/cert-manager/cert-manager/pull/5234), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.7.2 + +### Changes since 1.7.1 + +#### Bug or Regression + +- Bumps the version of Go used to build the cert-manager binaries to 1.17.8, to fix a slew of CVEs (none of which were likely to be exploited) ([#4976](https://github.com/cert-manager/cert-manager/pull/4976), [@vhosakot](https://github.com/vhosakot)) +- Fixes an expired hardcoded certificate which broke unit tests ([#4978](https://github.com/cert-manager/cert-manager/pull/4978), [@SgtCoDFish](https://github.com/SgtCoDFish), [@jakexks](https://github.com/jakexks)) + +## v1.7.1 + +### Changes since v1.7.0 + +#### Bug or Regression + +- Fix: The alpha feature Certificate's `additionalOutputFormats` is now correctly validated at admission time, and no longer _only_ validated if the `privateKey` field of the Certificate is set. The Webhook component now contains a separate feature set. + `AdditionalCertificateOutputFormats` feature gate (disabled by default) has been added to the webhook. This gate is required to be enabled on both the controller and webhook components in order to make use of the Certificate's `additionalOutputFormat` feature. ([#4816](https://github.com/cert-manager/cert-manager/pull/4816), [@JoshVanL](https://github.com/JoshVanL)) + +## v1.7.0 + +### Breaking Changes (You **MUST** read this before you upgrade!) + +#### Removal of Deprecated APIs + +⚠ Following their deprecation in version 1.4, the cert-manager API versions v1alpha2, v1alpha3, and v1beta1 have been removed. +You must ensure that all cert-manager custom resources are stored in etcd at version v1 +and that all cert-manager `CustomResourceDefinition`s have only v1 as the stored version +**before** upgrading. + +Since release 1.7, `cmctl` can automatically migrate any deprecated API resources. +Please [download `cmctl-v1.7.1`] and read [Migrating Deprecated API Resources] +for full instructions. + +[download `cmctl-v1.7.1`]: https://github.com/cert-manager/cert-manager/releases/tag/v1.7.1 +[Migrating Deprecated API Resources]: https://cert-manager.io/docs/releases/upgrading/remove-deprecated-apis/ + +#### Ingress Class Semantics + +In 1.7, we have reverted a change that caused a regression in the ACME Issuer. +Before v1.5.4, the Ingress created by cert-manager while solving an HTTP-01 challenge contained the `kubernetes.io/ingress.class` annotation: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: istio # The `class` present on the Issuer. +``` +Since v1.5.4, the Ingress does not contain the annotation anymore. Instead, cert-manager uses the `ingressClassName` field: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +spec: + ingressClassName: istio # 🔥 Breaking change! +``` + +This broke many users that either don't use an Ingress controller that supports the field (such as ingress-gce and Azure AGIC), as well as people who did not need to create an IngressClass previously (such as with Istio and Traefik). + +The regression is present in cert-manager v1.5.4, 1.6.0, and 1.6.1. It is only present on Kubernetes 1.19+ and only appears when using an Issuer or ClusterIssuer with an ACME HTTP-01 solver configured. + +In 1.7, we have restored the original behavior which is to use the annotation. We also backported this fix to 1.5.5 and 1.6.2, allowing people to upgrade safely. + +Most people won't have any trouble upgrading from a version that contains the regression to 1.7.0, 1.6.2 or 1.5.5. If you are using Gloo, Contour, Skipper, or kube-ingress-aws-controller, you shouldn't have any issues. If you use the default "class" (e.g., `istio` for Istio) for Traefik, Istio, Ambassador, or ingress-nginx, then these should also continue to work without issue. + +If you are using Traefik, Istio, Ambassador, or ingress-nginx _and_ you are using a non-default value for the class (e.g., `istio-internal`), or if you experience any issues with your HTTP-01 challenges please read the [notes on Ingress v1 compatibility]. + +[notes on Ingress v1 compatibility]: https://cert-manager.io/docs/releases/upgrading/ingress-class-compatibility/ + +#### Upgrading with Server Side Apply + +As part of the work to [remove deprecated APIs](#removal-of-deprecated-apis) cert-manager `CustomResourceDefinition`s no longer require a conversion webhook. The related change in cert-manager `CustomResourceDefinition` specs results in invalid `CustomResourceDefinition` configurations for users who are upgrading to cert-manager 1.7 using `kubectl apply --server-side=true -f `. This can be solved either by performing the upgrade with client side apply or by manually patching the [managed fields](https://kubernetes.io/docs/reference/using-api/server-side-apply/#field-management) of cert-manager `CustomResourceDefinitions`: + +```bash +crds=("certificaterequests.cert-manager.io" "certificates.cert-manager.io" "challenges.acme.cert-manager.io" "clusterissuers.cert-manager.io" "issuers.cert-manager.io" "orders.acme.cert-manager.io") + +for crd in "${crds[@]}"; do + manager_index="$(kubectl get crd "${crd}" --show-managed-fields --output json | jq -r '.metadata.managedFields | map(.manager == "cainjector") | index(true)')" + kubectl patch crd "${crd}" --type=json -p="[{\"op\": \"remove\", \"path\": \"/metadata/managedFields/${manager_index}\"}]" +done +``` +Thanks to [@stevehipwell](https://github.com/stevehipwell) for the above patch commands. + +See the original GitHub issue [`cert-manager#4831`](https://github.com/cert-manager/cert-manager/issues/4831) + +### Major Themes + +#### Removal of Deprecated APIs + +In 1.7 the cert-manager API versions v1alpha2, v1alpha3, and v1beta1, that were deprecated in 1.4, +have been removed from the custom resource definitions (CRDs). +As a result, you will notice that the YAML manifest files are much smaller. + +In this release we have added a new sub-command to the cert-manager CLI (`cmctl upgrade migrate-api-version`), +which you SHOULD run BEFORE upgrading cert-manager to 1.7. +Please read [Removing Deprecated API Resources] for full instructions. + +#### Additional Certificate Output Formats + +`additionalOutputFormats` is a field on the Certificate `spec` that allows +specifying additional supplementary formats of issued certificates and their +private key. There are currently two supported additional output formats: +`CombinedPEM` (the PEM-encoded private key followed by the certificate chain) +and `DER` (the DER-encoded private key only). Any combination of output formats +can be requested for the same certificate. +Read [Additional Certificate Output Formats] for more details and +thanks to [@seuf](https://github.com/seuf) for getting this across the line! + +[Additional Certificate Output Formats]: ../../usage/certificate.md#additional-certificate-output-formats + +#### Server-Side Apply + +This is the first version of cert-manager which relies on [Server-Side Apply]. +We use it to properly manage the annotations and labels on TLS secrets. +For this reason cert-manager 1.7 requires at least Kubernetes 1.18 (see +[Supported Releases](https://cert-manager.io/docs/installation/supported-releases/) for further compatibility details). + +[Server-Side Apply]: https://kubernetes.io/docs/reference/using-api/server-side-apply/ + +#### Configuration Files + +In this release we introduce a new configuration file for the cert-manager-webhook. +Instead of configuring the webhook using command line flags, +you can now modify the webhook Deployment to mount a ConfigMap +containing a configuration file. +Read the [WebhookConfiguration Schema] for more information. + +In future releases we will introduce configuration files for the other cert-manager components: +the controller and the cainjector. + +[WebhookConfiguration Schema]: https://cert-manager.io/v1.7-docs/reference/api-docs/#webhook.config.cert-manager.io/v1alpha1.WebhookConfiguration + +#### Developing cert-manager Without Bazel + +In a future release, we'll remove the use of `bazel` for building and testing cert-manager, +with the aim of making it as easy as possible for anyone to contribute and to get involved +with the cert-manager project. + +The [work is ongoing][Bazel -> Make Migration Tracker], but for now we've ensured that cert-manager 1.7 can be built with `go build`, +and that all unit tests can be run with `go test ./cmd/... ./internal/... ./pkg/...`. + +[Bazel -> Make Migration Tracker]: https://github.com/cert-manager/cert-manager/issues/4712 + +### Community + +Thanks again to all open-source contributors with commits in this release, including: + +- [@Adphi](https://github.com/Adphi) +- [@devholic](https://github.com/devholic) +- [@johnwchadwick](https://github.com/johnwchadwick) +- [@jsoref](https://github.com/jsoref) +- [@jwenz723](https://github.com/jwenz723) +- [@seuf](https://github.com/seuf) +- [@thirdeyenick](https://github.com/thirdeyenick) + +And thanks as usual to [coderanger](https://github.com/coderanger) for helping people +out on the [`#cert-manager` Slack channel]; it's a huge help and much appreciated. + +[`#cert-manager` Slack channel]: ../../contributing/README.md#slack + +### Changelog since v1.6.0 + +#### Feature + +- Add `--acme-http01-solver-nameservers` flag to enable custom nameservers usage for ACME HTT01 challenges propagation checks. ([#4287](https://github.com/cert-manager/cert-manager/pull/4287), [@Adphi](https://github.com/Adphi)) +- Add `cmctl upgrade migrate-api-version` to ensure all CRD resources are stored at 'v1' prior to upgrading to v1.7 onwards ([#4711](https://github.com/cert-manager/cert-manager/pull/4711), [@munnerz](https://github.com/munnerz)) +- Add goimports verification step for CI ([#4710](https://github.com/cert-manager/cert-manager/pull/4710), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Add support for loading webhook flags/options from a WebhookConfiguration file on disk ([#4546](https://github.com/cert-manager/cert-manager/pull/4546), [@munnerz](https://github.com/munnerz)) +- Added `additionalOutputFormats` parameter to allow `DER` (binary) and `CombinedPEM` (key + cert bundle) formats. ([#4598](https://github.com/cert-manager/cert-manager/pull/4598), [@seuf](https://github.com/seuf)) +- Added a makefile based build workflow which doesn't depend on bazel ([#4554](https://github.com/cert-manager/cert-manager/pull/4554), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Added a new Helm chart parameter `prometheus.servicemonitor.honorLabels`, which sets the `honor_labels` field of the Prometheus scrape config. ([#4608](https://github.com/cert-manager/cert-manager/pull/4608), [@thirdeyenick](https://github.com/thirdeyenick)) +- Breaking change: pprof now runs by default on `localhost:6060` on the webhook and the controller, but only if explicitly enabled. Pprof can now be enabled also for cainjector. All three components have `--enable-profiling`, `--profiler-address` CLI flags to configure profiling. Thanks to [@bitscuit](https://github.com/bitscuit) for help with this! ([#4550](https://github.com/cert-manager/cert-manager/pull/4550), [@irbekrm](https://github.com/irbekrm)) +- Certificate Secrets are now managed by the APPLY API call, rather than UPDATE/CREATE. The issuing controller actively reconciles Certificate SecretTemplate's against corresponding Secrets, garbage collecting and correcting key/value changes. ([#4638](https://github.com/cert-manager/cert-manager/pull/4638), [@JoshVanL](https://github.com/JoshVanL)) + +#### Bug or Regression + +- Ensures 1 hour backoff between errored calls for new ACME Orders. ([#4616](https://github.com/cert-manager/cert-manager/pull/4616), [@irbekrm](https://github.com/irbekrm)) +- Fix unexpected exit when multiple DNS providers are passed to `RunWebhookServer` ([#4702](https://github.com/cert-manager/cert-manager/pull/4702), [@devholic](https://github.com/devholic)) +- Fixed a bug that can cause `cmctl version` to erroneously display the wrong webhook pod versions when older failed pods are present. ([#4615](https://github.com/cert-manager/cert-manager/pull/4615), [@johnwchadwick](https://github.com/johnwchadwick)) +- Fixes a bug where a previous failed CertificateRequest was picked up during the next issuance. Thanks to @MattiasGees for raising the issue and help with debugging! ([#4688](https://github.com/cert-manager/cert-manager/pull/4688), [@irbekrm](https://github.com/irbekrm)) +- Fixes an issue in `cmctl` that prevented displaying the Order resource with cert-manager 1.6 when running `cmctl status certificate`. ([#4569](https://github.com/cert-manager/cert-manager/pull/4569), [@maelvls](https://github.com/maelvls)) +- Improve checksum validation in makefile based tool installation ([#4680](https://github.com/cert-manager/cert-manager/pull/4680), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- The HTTP-01 ACME solver now uses the `kubernetes.io/ingress.class` annotation instead of the `spec.ingressClassName` in created Ingress resources. ([#4762](https://github.com/cert-manager/cert-manager/pull/4762), [@jakexks](https://github.com/jakexks)) +- The `cmctl experimental install` command now uses the cert-manager namespace. This fixes a bug which was introduced in release 1.6 that caused cert-manager to be installed in the default namespace. ([#4763](https://github.com/cert-manager/cert-manager/pull/4763), [@wallrj](https://github.com/wallrj)) +- Fixed a bug in the way the Helm chart handles service annotations on the controller and webhook services. ([#4329](https://github.com/cert-manager/cert-manager/pull/4329), [@jwenz723](https://github.com/jwenz723)) +- Update to latest version of keystore-go to address a backwards incompatible change introduced in v1.6.0 ([#4563](https://github.com/cert-manager/cert-manager/pull/4563), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +#### Other (Cleanup or Flake) + +- Adds `clock_time_seconds_gauge` metric which returns the current clock time, based on seconds since 1970/01/01 UTC ([#4640](https://github.com/cert-manager/cert-manager/pull/4640), [@JoshVanL](https://github.com/JoshVanL)) +- Adds an automated script for cert-manager developers to update versions of kind used for development and testing. ([#4574](https://github.com/cert-manager/cert-manager/pull/4574), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Breaking change: removes the deprecated `dns01-self-check-nameservers` flag. Use `--dns01-recursive-nameservers` instead. ([#4551](https://github.com/cert-manager/cert-manager/pull/4551), [@irbekrm](https://github.com/irbekrm)) +- Bump kind image versions ([#4593](https://github.com/cert-manager/cert-manager/pull/4593), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Clean up: Remove `v1beta1` form the webhook's `admissionReviewVersions` as cert-manager no longer supports v1.16 ([#4639](https://github.com/cert-manager/cert-manager/pull/4639), [@JoshVanL](https://github.com/JoshVanL)) +- Cleanup: Pipe feature gate flag to the e2e binary. Test against shared Feature Gate map for feature enabled and whether they should be tested against. ([#4703](https://github.com/cert-manager/cert-manager/pull/4703), [@JoshVanL](https://github.com/JoshVanL)) +- Ensures that in cases where an attempt to finalize an already finalized order is made, the originally issued certificate is used (instead of erroring and creating a new ACME order) ([#4697](https://github.com/cert-manager/cert-manager/pull/4697), [@irbekrm](https://github.com/irbekrm)) +- No longer log an error when a Certificate is deleted during normal operation. ([#4637](https://github.com/cert-manager/cert-manager/pull/4637), [@JoshVanL](https://github.com/JoshVanL)) +- Removed deprecated API versions from the cert-manager CRDs ([#4635](https://github.com/cert-manager/cert-manager/pull/4635), [@wallrj](https://github.com/wallrj)) +- Update distroless base images for cert-manager ([#4706](https://github.com/cert-manager/cert-manager/pull/4706), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Upgrade Kubernetes dependencies to v0.23.1 ([#4675](https://github.com/cert-manager/cert-manager/pull/4675), [@munnerz](https://github.com/munnerz)) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.8.md b/content/v1.15-docs/releases/release-notes/release-notes-1.8.md new file mode 100644 index 0000000000..e5cc204636 --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.8.md @@ -0,0 +1,201 @@ +--- +title: Release 1.8 +description: 'cert-manager release notes: cert-manager v1.8' +--- + +## v1.8.2 + +v1.8.2 is in effect a bug fix release which increases some hard-coded timeouts which were preventing the use of certain ACME issuers +which sometimes had slower response times. This is known to include ZeroSSL and Sectigo. + +These issues were reported by many users, who we listed and thanked on the [GitHub release](https://github.com/cert-manager/cert-manager/releases/tag/v1.8.2). + +### Changes since v1.8.1 + +#### Bug + +- Increase timeouts for `Issuer` and `ClusterIssuer` controllers to 2 minutes and increase ACME client HTTP timeouts to 90 seconds, in order to enable the use of slower ACME issuers which take a long time to process certain requests. ([#5231](https://github.com/cert-manager/cert-manager/pull/5231), [@JoooostB](https://github.com/JoooostB) [@SgtCoDFish](https://github.com/SgtCoDFish)) + +#### Other (Cleanup or Flake) + +- Bump distroless base images to latest versions ([#5235](https://github.com/cert-manager/cert-manager/pull/5235), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +## v1.8.1 + +v1.8.1 is a patch release rebuilding cert-manager 1.8 using the latest version of Go, and reverting a previous commit which had negatively affected some GitOps workflows. + +### Changes since v1.8.0 + +#### Bug + +- Reverts a check for Prometheus APIs before creating cert-manager `ServiceMonitor`s which broke users' GitOps flows ([#5204](https://github.com/cert-manager/cert-manager/pull/5204)) + +#### Cleanup + +- Bumps the version of Go used to build the cert-manager binaries to 1.17.11 which fixes a few CVEs (although we don't think that any of those CVEs were likely to be exploited in cert-manager) ([#5203](https://github.com/cert-manager/cert-manager/pull/5203), [@irbekrm](https://github.com/irbekrm)) + +## v1.8.0 + +cert-manager 1.8 includes wider support for Kubernetes server-side-apply, a new build and development experience based around +`Makefile`s rather than Bazel, and a range of other improvements, tweaks and bug fixes. + +Version 1.8 also marks our first release in which the Go import path for cert-manager is that of the repo's new home: + +`github.com/cert-manager/cert-manager` + +### Breaking Changes (You MUST read this before you upgrade!) + +#### Validation of the `rotationPolicy` field + +The field `spec.privateKey.rotationPolicy` on Certificate resources is now validated. Valid options are Never and Always. If you are using a GitOps flow and one of your YAML manifests contains a Certificate with an invalid value, you will need to update it with a valid value to prevent your GitOps tool from failing on the new validation. Please follow the instructions listed on the page [Upgrading from v1.7 to v1.8](https://cert-manager.io/docs/releases/upgrading/upgrading-1.7-1.8/). ([#4913](https://github.com/cert-manager/cert-manager/pull/4913), [@jahrlin](https://github.com/jahrlin)) + +##### What happens if I upgrade to 1.8.0 without doing the above steps? + +After upgrading to 1.8.0, when updating existing Certificate objects that have an incorrect value for `rotationPolicy`, Kubernetes clients such as kubectl, Helm, or ArgoCD will start showing the following message: + +```text +Certificate.cert-manager.io "my-cert" is invalid: spec.privateKey.rotationPolicy: Unsupported value: "Foo": supported values: "Never", "Always". +``` + +##### Why was this change necessary? + +Previously, when the value of the `rotationPolicy` field was set to an incorrect value, you would not know since no event or condition would be visible on the Certificate itself. The only way to know that something was wrong was to dig into the cert-manager-controller logs and see the message "Certificate with unknown `certificate.spec.privateKey.rotationPolicy` value": + +```text +I0329 12:43:13.325771 1 keymanager_controller.go:176] cert-manager/certificates-key-manager "msg"="Certificate with unknown certificate.spec.privateKey.rotationPolicy value" "key"="default/my-cert" "rotation_policy"="Foo" +``` + +This change was implemented in [#4913](https://github.com/cert-manager/cert-manager/pull/4913). + +#### Changed Container Layouts + +This only affects you if you're modifying cert-manager containers in some way, such as adding init scripts or otherwise +changing how the binaries inside the containers are called. + +Bazel has a unique way of creating containers, which places the actual binary at a long unusual path. For the v1.7.0 cert-manager-webhook +container for example, the binary is placed at `/app/cmd/webhook/webhook.runfiles/com_github_jetstack_cert_manager/cmd/webhook/webhook_/webhook` +and `/app/cmd/webhook/webhook` is provided as a symlink to the binary. + +This is simplified in our new build system; we only place a single binary at `/app/cmd/webhook/webhook` and the old path disappears. +This applies to all cert-manager containers. + +We also removed the "LICENSES" file from the containers and replaced it with a link to the cert-manager repo. + +#### `.exe` Extension on Windows + +We package `cmctl` and `kubectl_cert-manager` for Windows on `amd64` platforms, but previously the binaries had the +same names as the binaries on other platforms, e.g. `cmctl` with no file extension. + +In 1.8.0 and later, the binaries now have a `.exe` extension since this is standard practice on Windows. This could affect you +if you're calling the binary in a Powershell script, for example. + +We've also now added zip-compressed versions of the `cmctl` and `kubectl_cert-manager` binaries on Windows, since `.tar.gz` is less +common on Windows. + +#### Changed Import Path + +This will only affect you if you're writing code in Go which imports cert-manager as a module, which we generally recommend against +doing in most cases. + +All versions of cert-manager prior to v1.8.0 used a Go import path corresponding to the old cert-manager repository, `github.com/jetstack/cert-manager`. + +v1.8.0 marks the first release in which the import path changes to the new location, `github.com/cert-manager/cert-manager`. + +We have a guide for [Importing cert-manager in Go](https://cert-manager.io/docs/contributing/importing/) on cert-manager.io with all the details, including +details on why we don't recommend importing cert-manager as a module if that's avoidable. + +### Major Themes + +#### Server-Side Apply + +cert-manager v1.8.0 adds initial support for Kubernetes [Server-Side Apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/), which became stable +in Kubernetes 1.22. This support is behind a feature gate for now, and is only supported by cert-manager on Kubernetes 1.22 and later. + +Server-Side Apply helps to ensure that changes to resources are made in a managed way, and aims to prevent certain classes of bugs. Notably, it should +eliminate conflicts when multiple controllers try to apply status changes to a single resource. You'll likely have seen messages relating to this kind of +conflict in logs before, e.g.: + +```text +I0119 12:34:56.000000 1 controller.go:161] cert-manager/controller/certificaterequests-issuer-acme "msg"="re-queuing item due to optimistic locking on resource" "key"="my-namespace/my-cr" "error"="Operation cannot be fulfilled on certificaterequests.cert-manager.io \"my-cr\": the object has been modified; please apply your changes to the latest version and try again" +``` + +These conflicts aren't usually actually a problem which will block the issuance of a certificate, but they can delay things as they cause extra +reconcile loops. Server-side apply cleans things up, which should mean less noise in logs and fewer pointless reconcile loops. + +If you want to test it out, you can enable alpha-level cert-manager Server-Side Apply support through the +`--feature-gates` [controller flag](../../cli/controller.md). + +#### From Bazel to Make + +A common theme when someone tries to make a change to cert-manager for the first time is that they ask for help with navigating Bazel, which cert-manager +used as its build tool. Helping people with Bazel isn't easy; it's an _incredibly_ powerful tool, but that power also brings a lot of complications +which can seriously get in the way of being able to make even simple changes to the code base. Even developers who are familiar with contributing +to open source projects in Go can find it daunting to make changes thanks to Bazel. + +The problem isn't limited to open-source contributors; many of cert-manager's maintainers also struggle with configuring and changing Bazel, too. + +cert-manager 1.8 is the first release which is built and tested using a newly written `make`-based build system. We believe that this new build system should +make it _much_ simpler to understand and change the commands which are being run behind the scenes to build and test cert-manager. In time, we'll fully +document the new build system, ensure it's at full feature-parity with Bazel and then remove all references to Bazel across the codebase. + +A neat side effect of this change is that our build times have significantly improved. Bazel took around 14 minutes to build every cert-manager +artifact for every platform during a release, while the new `make` build system can do the same (and more) in under 5 minutes. + +#### Exponential backoff after a failed issuance + +cert-manager v1.8.0 introduces [exponential backoff after failed certificate issuance](https://github.com/cert-manager/cert-manager/blob/f8900ad1d8cc9b7c3697d7554911e2959fa56480/design/20220118.certificate-issuance-exponential-backoff.md). + +Previously, a failed issuance was retried every hour which — especially in larger cert-manager installations — could cause rate limits to be hit as well as overwhelm external services. Failed attempts +are now retried with a binary exponential backoff starting with `1h` then `2h`, `4h` up to a maximum of `32h`. As part of the new backoff behavior, a new `failedIssuanceAttempts` field was added to the +`Certificate` spec to track the number of currently failed issuances. + +The `cmctl renew` [command](../../cli/cmctl.md) command can still be used to force `Certificate` renewal immediately. + +We're also considering reducing the initial backoff from 1 hour. If you have a use case where this would be useful please do comment on [our tracking issue](https://github.com/cert-manager/cert-manager/issues/4786). + +## Changelog since v1.7.0 + +### Feature + +- ACTION REQUIRED: The field `spec.privateKey.rotationPolicy` on Certificate resources is now validated. Valid options are Never and Always. If you are using a GitOps flow and one of your YAML manifests contains a Certificate with an invalid value, you will need to update it with a valid value to prevent your GitOps tool from failing on the new validation. ([#4913](https://github.com/cert-manager/cert-manager/pull/4913), [@jahrlin](https://github.com/jahrlin)) +- Build: add make targets for running unit and integration tests, as part of the Bazel replacement. ([#4865](https://github.com/cert-manager/cert-manager/pull/4865), [@SgtCoDFish](https://github.com/SgtCoDFish)) +- Build: add make targets for running the end-to-end tests, as part of the Bazel replacement. ([#4914](https://github.com/cert-manager/cert-manager/pull/4914), [@maelvls](https://github.com/maelvls)) +- cert-manager now supports the field `spec.expirationSeconds` on Kubernetes CertificateSigningRequest resources. Using this field requires Kubernetes 1.22. You can still use the annotation `experimental.cert-manager.io/request-duration` to request a duration. ([#4957](https://github.com/cert-manager/cert-manager/pull/4957), [@enj](https://github.com/enj)) +- cert-manager now properly updates the content of the data keys `tls-combined.pem` and `key.der` on Secret resources that are associated to Certificate resources that use the field `additionalOutputFormats`. The field `additionalOutputFormat` is an alpha feature and can be enabled by passing the flag `--feature-gates=AdditionalCertificateOutputFormats=true` to the cert-manager controller. ([#4813](https://github.com/cert-manager/cert-manager/pull/4813), [@JoshVanL](https://github.com/JoshVanL)) +- ClusterRoles aggregation to user-facing admin/edit/view ClusterRoles can be optionally turned off ([#4937](https://github.com/cert-manager/cert-manager/pull/4937), [@illrill](https://github.com/illrill)) +- ACTION REQUIRED: Server-Side Apply: the feature gate `ServerSideApply=true` now configures the `ingress-shim` and `gateway-shim` controllers to use Kubernetes Server-Side Apply on Certificate resources. When upgrading to cert-manager 1.8 with `ServerSideApply=true`, do make sure there are no Challenge resources currently in the cluster. If there are some, you will need to manually delete them once they are in 'valid' state as cert-manager post-1.8 with the Server-Side Apply feature is not able to clean up Challenge resources created pre-1.8. ([#4811](https://github.com/cert-manager/cert-manager/pull/4811), [@JoshVanL](https://github.com/JoshVanL)) +- Server-Side Apply: the feature gate `ServerSideApply=true` configures the `certificaterequests-*` controllers to use Kubernetes Server-Side Apply on CertificateRequest resources. ([#4792](https://github.com/cert-manager/cert-manager/pull/4792), [@JoshVanL](https://github.com/JoshVanL)) +- Server-Side Apply: the feature gate `ServerSideApply=true` configures the `certificates-*` controllers to use Kubernetes Server-Side Apply on Certificate resources. ([#4777](https://github.com/cert-manager/cert-manager/pull/4777), [@JoshVanL](https://github.com/JoshVanL)) +- Server-Side Apply: the feature gate `ServerSideApply=true` configures the CertificateSigningRequest controllers to use Kubernetes Server-Side Apply on CertificateSigningRequest resources. ([#4798](https://github.com/cert-manager/cert-manager/pull/4798), [@JoshVanL](https://github.com/JoshVanL)) +- Server-Side Apply: the feature gate `ServerSideApply=true` configures the `issuers` and `clusterissuers` controllers to use Kubernetes Server-Side Apply on Issuer and ClusterIssuer resources. ([#4794](https://github.com/cert-manager/cert-manager/pull/4794), [@JoshVanL](https://github.com/JoshVanL)) +- Server-Side Apply: the feature gate `ServerSideApply=true` configures the `orders` controller to use Kubernetes Server-Side Apply on Order resources. ([#4799](https://github.com/cert-manager/cert-manager/pull/4799), [@JoshVanL](https://github.com/JoshVanL)) +- The annotation `experimental.cert-manager.io/request-duration` now has a minimum value of 600 seconds. This annotation This change ensures compatibility with the Kubernetes resource CertificateSigningRequest, which requires a minimum of 600 seconds on the field `spec.expirationSeconds`. ([#4973](https://github.com/cert-manager/cert-manager/pull/4973), [@irbekrm](https://github.com/irbekrm)) +- The annotation `ingress.kubernetes.io/whitelist-source-range` used by the Ingress shim when creating Ingress resources can now be overridden by setting the field `ingressTemplate` on the Issuer and ClusterIssuer. ([#4789](https://github.com/cert-manager/cert-manager/pull/4789), [@tasharnvb](https://github.com/tasharnvb)) +- The experimental Gateway API support now uses the v1alpha2 CRDs. ([#4791](https://github.com/cert-manager/cert-manager/pull/4791), [@jakexks](https://github.com/jakexks)) +- The user-agent used by cert-manager in its Kubernetes API clients and ACME clients now takes the form `cert-manager-/ (/) cert-manager/`. Another change is the addition of specific field managers strings; previously, all the controllers had the same field manager `cert-manager`. Now, each controller has its own field manager string of the form `cert-manager-`. ([#4773](https://github.com/cert-manager/cert-manager/pull/4773), [@JoshVanL](https://github.com/JoshVanL)) +- You can now uninstall cert-manager using the command `cmctl experimental uninstall`. ([#4897](https://github.com/cert-manager/cert-manager/pull/4897), [@jahrlin](https://github.com/jahrlin)) +- You can now use an external issuer resource as the default issuer when using the Ingress shim feature. The default issuer can be set using the flags `--default-issuer-group`, `--default-issuer-kind`, and `--default-issuer-name`. ([#4833](https://github.com/cert-manager/cert-manager/pull/4833), [@jakexks](https://github.com/jakexks)) + +### Design + +- ACTION REQUIRED: The import path for cert-manager has been updated to `github.com/cert-manager/cert-manager`. If you import cert-manager as a go module (which isn't currently recommended), you'll need to update the module import path in your code to import cert-manager 1.8 or later. ([#4587](https://github.com/cert-manager/cert-manager/pull/4587), [@SgtCoDFish](https://github.com/SgtCoDFish)) + +### Bug or Regression + +- ACTION REQUIRED: The field `additionalOutputFormats`, which is available as an alpha feature on Certificate resources, is now correctly validated. Previously, it would only get validated when the `privateKey` field was set on the Certificate. If you are using the `additionalOutputFormats` field, you will want to add the feature gate `AdditionalCertificateOutputFormats` to both the webhook and the controller. Previously, you only needed to set `AdditionalCertificateOutputFormats` on the controller. If the feature gate is missing on either the controller or the webhook, you won't be able to use the `additionalOutputFormat` field. ([#4814](https://github.com/cert-manager/cert-manager/pull/4814), [@JoshVanL](https://github.com/JoshVanL)) +- The Go version used to build the cert-manager binaries has been bumped to 1.17.8 to fix a slew of CVEs (none of which were likely to be exploited). ([#4970](https://github.com/cert-manager/cert-manager/pull/4970), [@vhosakot](https://github.com/vhosakot)) +- Helm: the default nodeSelector is now `kubernetes.io/os: linux`. If this label isn't present on any nodes in the cluster, the `nodeSelector` will need to be overwritten, or that label added to some nodes. ([#3605](https://github.com/cert-manager/cert-manager/pull/3605), [@mikebryant](https://github.com/mikebryant)) +- Use multivalue records instead of simple records for the AWS Route53 ACME DNS challenge solver, to allow for multiple challenges for the same domain at the same time ([#4793](https://github.com/cert-manager/cert-manager/pull/4793), [@fvlaicu](https://github.com/fvlaicu)) + +### Other (Cleanup or Flake) + +- Aggregated admin and edit roles will now include permissions to update certificates' status, which will allow namespace admins and editors to run the `cmctl renew` command in their namespaces. ([#4955](https://github.com/cert-manager/cert-manager/pull/4955), [@andreadecorte](https://github.com/andreadecorte)) +- Cleanup: No longer log an error when cert-manager encounters a conflict in the secrets manager, in favor of always force applying. ([#4815](https://github.com/cert-manager/cert-manager/pull/4815), [@JoshVanL](https://github.com/JoshVanL)) +- Failed certificate issuances are now retried with an exponential backoff where the backoff periods are `1h`, `2h`, `4h`, `8h`, `16h`, `32h`. A new field `failedIssuanceAttempts` is now set by cert-manager on the Certificate status. This field keeps track of consecutive failed issuances. The backoff period gets reset after a successful issuance. Like before, updating a field on a failed Certificate (such as `spec.dnsNames`) or running the command `cmctl renew` continues to trigger a re-issuance. ([#4772](https://github.com/cert-manager/cert-manager/pull/4772), [@irbekrm](https://github.com/irbekrm)) +- When starting up, cert-manager now solely relies on Lease objects to perform the leader election. Previously, cert-manager supported both ConfigMap and Lease objects for leader election. Existing ConfigMap resources used for leader election will remain and will need deleting manually. A side effect of this is that you cannot upgrade to v1.8.0 from cert-manager 1.3 (although upgrading multiple versions at a time was never supported). ([#4935](https://github.com/cert-manager/cert-manager/pull/4935), [@davidsbond](https://github.com/davidsbond)) +- Helm: you can now set custom labels on the ServiceAccount resources using the values `serviceAccount.labels`, `cainjector.serviceAccount.labels`, `webhook.serviceAccount.labels`, and `startupapicheck.serviceAccount.labels`. ([#4932](https://github.com/cert-manager/cert-manager/pull/4932), [@4molybdenum2](https://github.com/4molybdenum2)) + +### Uncategorized + +- Introducing a new metric `controller_sync_error_count` counting the number of errors during sync() of a controller. ([#4987](https://github.com/cert-manager/cert-manager/pull/4987), [@jayme-github](https://github.com/jayme-github)) +- When creating an acmesolver pod, cert-manager now sets `allowPrivilegeEscalation` to `false` by default. The Helm chart now also sets `securityContext.allowPrivilegeEscalation` to `false` by default for the controller, cainjector, and webhook pods as well as for the startupapicheck job. ([#4953](https://github.com/cert-manager/cert-manager/pull/4953), [@ajvn](https://github.com/ajvn)) diff --git a/content/v1.15-docs/releases/release-notes/release-notes-1.9.md b/content/v1.15-docs/releases/release-notes/release-notes-1.9.md new file mode 100644 index 0000000000..7aafcf3a0e --- /dev/null +++ b/content/v1.15-docs/releases/release-notes/release-notes-1.9.md @@ -0,0 +1,130 @@ +--- +title: Release 1.9 +description: 'cert-manager release notes: cert-manager v1.9' +--- + +## `v1.9.2` + +cert-manager `v1.9.2` is a bug fix release which fixes +an issue where CertificateRequests marked as InvalidRequest did not properly trigger issuance failure handling leading to 'stuck' requests, and +a problem which prevented the Venafi Issuer from connecting to TPP servers where the `vedauth` API endpoints were configured to *accept* client certificates. +It is also compiled with a newer version of Go 1.18 (`v1.18.8`) which fixes some vulnerabilities in the Go standard library. + +## Changes since `v1.9.1` + +### Bug or Regression + +- Fix issue where CertificateRequests marked as InvalidRequest did not properly trigger issuance failure handling leading to 'stuck' requests. + ([#5371](https://github.com/cert-manager/cert-manager/pull/5371), [@munnerz](https://github.com/munnerz) ) +- The Venafi Issuer now supports TLS 1.2 renegotiation, so that it can connect to TPP servers where the `vedauth` API endpoints are configured to *accept* client certificates. (Note: This does not mean that the Venafi Issuer supports client certificate authentication). + ([#5577](https://github.com/cert-manager/cert-manager/pull/5577), [@wallrj](https://github.com/wallrj)) +- Upgrade to latest go patch release. + ([#5561](https://github.com/cert-manager/cert-manager/pull/5561), [@SgtCoDFish](https://github.com/SgtCoDFish)) + + +## v1.9.1 + +cert-manager v1.9.1 is a bug fix release which removes an incorrect check in the Route53 DNS solver. This accidental change prevented the use of credentials derived from +instance metadata or AWS pod metadata. + +## Changes since v1.9.0 + +### Bug or Regression + +- DNS Route53: Remove incorrect validation which rejects solvers that don't define either a `accessKeyID` or `secretAccessKeyID`. ([#5341](https://github.com/cert-manager/cert-manager/pull/5341), [@jetstack-bot](https://github.com/jetstack-bot)) + +## v1.9.0 + +cert-manager v1.9.0 adds alpha support for using cert-manager `Certificate`s in scenarios where the ordering of the Relative Distinguished Names (RDN) sequence that constitutes an X.509 certificate's subject needs to be preserved; improves the ability to configure the `Certificate` created via ingress-shim using annotations on the `Ingress` resource; introduces various changes/improvements in contributor flow; and finishes the new make-based contributor workflow. + +### Major Themes + +#### Literal Certificate Subjects + +cert-manager's `Certificate` allows users to configure the subject fields of the X.509 certificate via `spec.subject` and `spec.commonName` fields. The [X.509 spec](https://datatracker.ietf.org/doc/html/rfc5280#section-4.1.2.6) states that the subject is an (ordered) sequence of Relative Distinguished Names (RDN). + +cert-manager does not strictly abide by this spec when encoding the subject fields from the `Certificate` spec. For example, the order of the RDN sequence may not be preserved. This is because cert-manager uses Go's libraries for X.509 certificates, and the Go libraries don't preserve ordering. + +For the vast majority of users this does not matter, but there are specific cases that require defining the exact ordered RDN sequence. For example, if the certificate is used for LDAP authentication and the RDN sequence represents a [location in LDAP directory tree](https://ldapwiki.com/wiki/Directory%20Information%20Tree). See [`cert-manager#3203`](https://github.com/cert-manager/cert-manager/issues/3203). + +For these use cases, a new alpha `LiteralSubject` field has been added to the `Certificate` spec where users can pass a literal RDN sequence: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: test +spec: + secretName: test + literalSubject: "C=US,O=myOrg,CN=someName" +``` + +To use this field, the alpha feature gate `LiteralCertificateSubject` needs to be enabled on both the cert-manager controller and webhook. Bear in mind that `spec.literalSubject` is mutually exclusive with `spec.commonName` and `spec.subject`. + +This feature is aimed at the specific scenario where an exact RDN sequence needs to be defined. We do not intend to deprecate the existing `spec.subject` and `spec.commonName` fields and we recommend that folks keep using those fields in all other cases; they're simpler, have better validation and are more obvious to read and change. + +#### ingress-shim `Certificate` Configuration + +cert-manager 1.9 adds the ability to configure an ingress-shim `Certificate`'s `spec.revisionHistoryLimit` and `spec.privateKey` via [annotations on the `Ingress` resource](https://cert-manager.io/docs/usage/ingress/#supported-annotations). + +This should allow folks to configure ingress-shim `Certificate`s according to best practices (i.e by setting `Certificate`'s `spec.privateKey.rotationPolicy` to `Always`). + +In the future we would like to design a better mechanism to configure these `Certificate`s. We advise caution when using `Ingress` annotations as there is no validation of the annotations at `Ingress` creation time. + +#### Contribution Workflow + +Over the past couple of months there have been a number of discussions in regards to contributor experience and project health, partially triggered by the awesome community discussions in cert-manager's KubeCon booth and also by the work done to move cert-manager to CNCF's incubating stage. + +For example, we've [clarified our feature policy](https://cert-manager.io/docs/contributing/policy/) and discussed the process of building cert-manager's [roadmap](https://github.com/cert-manager/cert-manager/blob/master/ROADMAP.md). If you're interested in these topics, we're happy to chat about them! + +#### `make` Workflow + +cert-manager 1.8 introduced a new `make` based workflow alongside the existing Bazel workflow. The work to improve the `make` workflow was continued in 1.9 and our [contributor documentation](https://cert-manager.io/docs/contributing/building/) has been redefined to use `make` commands. This should make building and testing cert-manager easier with faster build and test times, easier debugging and less complexity. + +As part of this, Bazel has now been fully deprecated for building and testing cert-manager. + +As usual, we welcome any feedback in regards to further improving contributor experience. + +## Changes since v1.8.0 + +### Feature + +- Added support for pulling both AWS access key IDs and secret keys from Kubernetes secrets (#5194, @Compy) +- Adds `make clean-all` for starting a fresh development environment and `make which-go` for getting go version information when developing cert-manager (#5118, @SgtCoDFish) +- Adds `make upload-release` target for publishing cert-manager releases to GCS, simplifying the cert-manager release process simpler and making it easier to change (#5205, @SgtCoDFish) +- Adds a new alpha Prometheus summary vector metric `certmanager_http_venafi_client_request_duration_seconds` which allows tracking the latency of Venafi API calls. The metric is labelled by the type of API call. Example PromQL query: `certmanager_http_venafi_client_request_duration_seconds{api_call="request_certificate"}` will show the average latency of calls to the Venafi certificate request endpoint (#5053, @irbekrm) +- Adds more verbose logging info for certificate renewal in the DynamicSource webhook to include `DNSNames` (#5142, @AcidLeroy) +- Adds new LICENSES format and ability to verify and update licenses through make (#5243, @SgtCoDFish) +- Adds private key Ingress annotations to set private key properties for Certificate (#5239, @oGi4i) +- Adds the `cert-manager.io/revision-history-limit` annotation for Ingress resources, to limit the number of CertificateRequests which are kept for a Certificate (#5221, @oGi4i) +- Adds the `literalSubject` field for Certificate resources. This is an alpha feature, enabled by passing the flag `--feature-gates=LiteralCertificateSubject=true` to the cert-manager controller and webhook. `literalSubject` allows fine-grained control of the subject a certificate should have when issued and is intended for power-users with specific use cases in mind (#5002, @spockz) +- Change default build dir from `bin` to `_bin`, which plays better with certain tools which might treat `bin` as just another source directory (#5130, @SgtCoDFish) +- Helm: Adds a new `namespace` parameter which allows users to override the namespace in which resources will be created. This also allows users to set the namespace of the chart when using cert-manager as a sub chart. (#5141, @andrewgkew) +- Helm: Allow for users to not auto-mount service account tokens [see also `k/k#57601`](https://github.com/kubernetes/kubernetes/issues/57601) (#5016, @sveba) +- Use multiple retries when provisioning tools using `curl`, to reduce flakes in tests and development environments (#5272, @SgtCoDFish) + +### Bug or Regression + +- CertificateRequests controllers must wait for the core secrets informer to be synced (#5224, @rodrigorfk) +- Ensure that `make release-artifacts` only builds unsigned artifacts as intended (#5181, @SgtCoDFish) +- Ensure the startupapicheck is only scheduled on Linux nodes in the helm chart (#5136, @craigminihan) +- Fixed a bug where the Venafi Issuer would not verify its access token (TPP) or API key (Cloud) before becoming ready. Venafi Issuers now remotely verify the access token or API key (#5212, @jahrlin) +- Fixed release artifact archives generated by Make so that a leading `./` is stripped from paths. This ensures that behavior is the same as v1.7 and earlier (#5050, @jahrlin) +- Increase timeouts for `Issuer` and `ClusterIssuer` controllers to 2 minutes and increase ACME client HTTP timeouts to 90 seconds, in order to enable the use of slower ACME issuers which take a long time to process certain requests. (#5226, @SgtCoDFish) +- Increases Venafi Issuer timeout for retrieving a certificate increased to 60 seconds, up from 10. This gives TPP instances longer to complete their workflows and make the certificate available before cert-manager times out and re-queues the request. (#5247, @hawksight) +- Remove `pkg/util/coverage` which broke compatibility with go 1.18; thanks @davidsbond for finding the issue! (#5032, @SgtCoDFish) +- `cmctl` and `kubectl cert-manager` now report their actual versions instead of "canary", fixing issue [#5020](https://github.com/cert-manager/cert-manager/issues/5020) (#5286, @jetstack-bot) + +### Other (Cleanup or Flake) + +- Adds `make update-all` as a convenience target to run before raising a PR (#5251, @SgtCoDFish) +- Adds make targets for updating and verifying CRDs and codegen (#5242, @SgtCoDFish) +- Bump cert-manager's version of Go to 1.18 (#5152, @lucacome) +- Bumps distroless base images to their latest versions (#5222, @irbekrm) +- CertificateSigningRequest: no longer mark a request as failed when using the SelfSigned issuer, and the Secret referenced in `experimental.cert-manager.io/private-key-secret-name` doesn't exist. (#5332, @jetstack-bot) +- Only require python for the one test we have which needs it, rather than requiring it globally (#5245, @SgtCoDFish) +- Remove deprecated field `securityContext.enabled` from helm chart (#4721, @Dean-Coakley) +- Removes support for `networking/v1beta` Ingresses in ingress-shim. (#5250, @irbekrm) +- Reverts additional check for `ServiceMonitor` (#5202, @irbekrm) +- Updates Kubernetes libraries to `v0.24.2`. (#5097, @lucacome) +- Updates warning message that is thrown if issuance fails because private key does not match spec, but private key regeneration is disabled. See https://github.com/cert-manager/cert-manager/pull/5199. (#5199, @irbekrm) diff --git a/content/v1.15-docs/releases/upgrading/ingress-class-compatibility.md b/content/v1.15-docs/releases/upgrading/ingress-class-compatibility.md new file mode 100644 index 0000000000..2f9d360d61 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/ingress-class-compatibility.md @@ -0,0 +1,102 @@ +--- +title: Notes on the breaking change with the `class` field that happened in cert-manager v1.5.4 +description: 'cert-manager installation: Notes on ingress classes and safe upgrades' +--- + + +> ⚠️ This document focuses on the `class` field of the Issuer and ClusterIssuer +> resources and the annotation `kubernetes.io/ingress.class`. If you are +> interested in using `ingressClassName` on your Ingress resources when using +> cert-manager's HTTP-01 solver, see the page [Securing Ingress +> Resources](../../configuration/acme/http01#ingressclassname). + +In cert-manager v1.5.4 we made a change to the HTTP-01 code which was not +backwards compatible. Before v1.5.4, cert-manager was using the `class` field on +the Issuer and ClusterIssuer to add the annotation +`kubernetes.io/ingress.class`. In cert-manager v1.5.4, cert-manager stopped +setting the annotation. See [Regression: HTTP-01 challenges fail with Istio, +Traefik, ingress-gce and Azure AGIC]. + +In v1.5.5, v1.6.2 and 1.7.1 we fixed this problem. + +If you have cert-manager v1.5.3 (or below) you should skip v1.5.4 and instead: + +- upgrade to v1.5.5 +- then the newest version of cert-manager 1.6 +- and then the newest version of cert-manager 1.7 + +and you can ignore the rest of this document. + +[Regression: HTTP-01 challenges fail with Istio, Traefik, ingress-gce and Azure AGIC]: https://github.com/cert-manager/cert-manager/issues/4537 + +The following notes apply to anyone upgrading from cert-manager v1.5.4, v1.6.0, v1.6.1 on Kubernetes v1.19 or later. + +# Background + +cert-manager 1.5 was released to coincide with Kubernetes 1.22, which +[removed](https://kubernetes.io/blog/2021/07/14/upcoming-changes-in-kubernetes-1-22/) the `v1beta1` +Ingress API. As cert-manager creates Ingress resources to solve HTTP-01 challenges, this code path +needed to be updated. + +In the `v1beta1` spec, Ingress Class was a string annotation that was adopted by all popular +Ingress controllers by convention. In the `v1` spec, `IngressClass` is now its own resource type, +and the `.spec.ingressClassName` field on `v1` Ingresses is now a reference to that object. +As the Kubernetes documentation points out, the old and new specs are not directly equivalent. + +During the 1.5 and 1.6 cert-manager release cycles, we discovered that ingress controllers have +handled the graduation of Ingress to `v1` differently. Some treat the class as an opaque string, +similarly to the annotation. Some were unintentionally broken, as their default ingress class name +contains characters that are disallowed in object references, e.g. (`/`). Some now require you to +create an `IngressClass` object matching the field to work. + +cert-manager aims to be compatible with as many ingress controllers as possible. According to the +Ingress v1 [Kubernetes enhancement proposal], the deprecated annotation, if present, takes +precedence over the new field. From our perspective, the option that maintains the highest +compatibility is to only use the annotation, even when creating `v1` Ingresses. + +[Kubernetes enhancement proposal]: https://github.com/kubernetes/enhancements/tree/44dd2975dc6cdad96ca73e7b0ba1794f1196f604/keps/sig-network/1453-ingress-api#interoperability-with-previous-annotation + +# Notes For Specific Ingress Controllers + +## ingress-nginx + +If you chose not to use the IngressClass `nginx` that is created by default by +the Helm chart (e.g., you named the IngressClass `nginx-outside`), you will need +to add the flags `--ingress-class` to your ingress-nginx deployment: + +``` +--ingress-class=nginx-outside --ingress-class-by-name=true +``` + +In case you are using the Helm chart, you will need to use at least these values: + +```yaml +ingressClassResource: + name: nginx-outside + controllerValue: k8s.io/ingress-nginx-outside +ingressClassByName: true +ingressClass: nginx-outside +``` + +## Istio + +If you are using Istio and you had to create an IngressClass while migrating to cert-manager 1.5 or 1.6 +and you chose to create an IngressClass that isn't named `istio` (e.g., you named it `istio-internal`), +you will need to change the `class` field on those Issuers back to `istio`. + +## Traefik + +If you are using Traefik and you had to create an IngressClass while migrating to cert-manager 1.5 +or 1.6 and the IngressClass you created isn't named `traefik` (for example, you called +the IngressClass `traefik-external`), you will need to add a command-line argument to your +Traefik deployment: + +``` +--providers.kubernetesingress.ingressclass=traefik-external +``` + +## Ambassador + +If you are using Ambassador and you had to create an IngressClass while migrating to +cert-manager 1.5 or 1.6, and the IngressClass you created isn't named `ambassador` +(e.g., `ambassador-internal`), you will need to change the `class` field on the affected Issuers back to `ambassador`. diff --git a/content/v1.15-docs/releases/upgrading/remove-deprecated-apis.md b/content/v1.15-docs/releases/upgrading/remove-deprecated-apis.md new file mode 100644 index 0000000000..e1d8226159 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/remove-deprecated-apis.md @@ -0,0 +1,29 @@ +--- +title: Migrating Deprecated API Resources +description: 'cert-manager installation: Removal of deprecated APIs' +--- + +The following cert-manager APIs were deprecated in cert-manager `v1.4`: + +- `cert-manager.io/v1alpha2` +- `cert-manager.io/v1alpha3` +- `cert-manager.io/v1beta1` +- `acme.cert-manager.io/v1alpha2` +- `acme.cert-manager.io/v1alpha3` +- `acme.cert-manager.io/v1beta1` + +These APIs are no longer served in cert-manager 1.6 and are fully removed in cert-manager 1.7. If you have a cert-manager installation that is using or has previously used these deprecated APIs you might need to upgrade your cert-manager custom resources and CRDs. This should be done before upgrading to cert-manager 1.6 or later. + +
          +An earlier version of this document listed a number of kubectl commands to run to migrate resources. These steps have now been encoded in [`cmctl upgrade migrate-api-version` command](../../reference/cmctl.md#migrate-api-version). If you have already run the kubectl commands, your resources should have been migrated and there should be no need to also run the `cmctl` command. However, if you are not sure, you can still run the `cmctl` command as well- it will be a no-op if no actions are needed. +
          + +# Upgrading existing cert-manager resources + +1. Familiarize yourself with the [official Kubernetes documentation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#writing-reading-and-updating-versioned-customresourcedefinition-objects) on CRD versioning. + +2. Make sure your cert-manager deployment is currently at version `v1.0` or later. + +3. Make sure that any cert-manager custom resource manifests that refer to the deprecated APIs are updated to use the `cert-manager.io/v1` API and re-applied. You can use the [cmctl convert command](../../reference/cmctl.md#convert)to convert manifests. + +4. Run the command [`cmctl upgrade migrate-api-version`](../../reference/cmctl.md#migrate-api-version). It automates the steps described in [Upgrade existing objects to a new stored version](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#upgrade-existing-objects-to-a-new-stored-version). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.10-0.11.md b/content/v1.15-docs/releases/upgrading/upgrading-0.10-0.11.md new file mode 100644 index 0000000000..183d9fc643 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.10-0.11.md @@ -0,0 +1,119 @@ +--- +title: Upgrading from v0.10 to v0.11 +description: 'cert-manager installation: Upgrading v0.10 to v0.11' +--- + +The `v0.11` release marks the removal of the `v1alpha1` API that was used in +previous versions of cert-manager, as well as our API group changing to be +`cert-manager.io` instead of `certmanager.k8s.io`. + +We have also removed support for the **old configuration format** that was +deprecated in the `v0.8` release. This means you **must** transition to using the +new `solvers` style configuration format for your ACME issuers **before** +upgrading to `v0.11`. For more information, see the +[upgrading to `v0.8`](./upgrading-0.7-0.8.md) guide. + +This makes for a fairly significant breaking change for users, as **all** +cert-manager resources, or even Ingresses that reference cert-manager +resources, will need to be updated to reflect these changes. + +This upgrade should be performed in a few steps: + +1. Back up existing cert-manager resources, as per the + [backup and restore guide](../../devops-tips/backup.md). + +2. [Uninstall cert-manager](../../installation/uninstall.md). + +3. Ensure the old cert-manager CRD resources have also been deleted: `kubectl get crd | grep certmanager.k8s.io` + +4. Update the `apiVersion` on all your backed up resources from + `certmanager.k8s.io/v1alpha1` to `cert-manager.io/v1alpha2`. + +5. Re-install cert-manager from scratch according to the + [installation guide](../../installation/upgrade.md). + +You must be sure to properly **backup**, **uninstall**, **re-install** and +**restore** your installation in order to ensure the upgrade is successful. + +## Additional annotation changes + +As well as changing the API group used by our CRDs, we have also changed the +annotation-based configuration key to **also** reflect the new API group. + +This means that if you use any cert-manager annotations on any of your other +resources (such as Ingresses, `{Validating,Mutating}WebhookConfiguration`, etc) +you will need to update them to reflect the new API group. + +A full table of annotations, including the old and new equivalents: + +| Old Annotation | New Annotation | +|:-----------------------------------------------|:--------------------------------------------| +| `certmanager.k8s.io/acme-http01-edit-in-place` | `acme.cert-manager.io/http01-edit-in-place` | +| `certmanager.k8s.io/acme-http01-ingress-class` | `acme.cert-manager.io/http01-ingress-class` | +| `certmanager.k8s.io/issuer` | `cert-manager.io/issuer` | +| `certmanager.k8s.io/cluster-issuer` | `cert-manager.io/cluster-issuer` | +| `certmanager.k8s.io/acme-challenge-type` | `DEPRECATED` | +| `certmanager.k8s.io/acme-dns01-provider` | `DEPRECATED` | +| `certmanager.k8s.io/alt-names` | `cert-manager.io/alt-names` | +| `certmanager.k8s.io/ip-sans` | `cert-manager.io/ip-sans` | +| `certmanager.k8s.io/common-name` | `cert-manager.io/common-name` | +| `certmanager.k8s.io/issuer-name` | `cert-manager.io/issuer-name` | +| `certmanager.k8s.io/issuer-kind` | `cert-manager.io/issuer-kind` | + + +You can use the following bash magic to print a list of Ingress resources that +still contain an old annotation: + +```bash +$ kubectl get ingress \ + --all-namespaces \ + -o json | \ + jq '.items[] | select(.metadata.annotations| to_entries | map(.key)[] | test("certmanager")) | "Ingress resource \(.metadata.namespace)/\(.metadata.name) contains old annotations: (\( .metadata.annotations | to_entries | map(.key)[] | select( . | test("certmanager") ) ))"' +Ingress resource "demo/testcrt contains old annotations: (certmanager.k8s.io/cluster-issuer)" +Ingress resource "example/ingress-resource contains old annotations: (certmanager.k8s.io/cluster-issuer)" +``` + +In order to help with this migration, the following CLI tool will automatically +migrate these annotations for you. Note that it *will not* make any changes to +your cluster for you. + +Firstly, download the binary for your given platform +```bash + $ wget -O api-migration https://github.com/cert-manager/cert-manager/releases/download/v0.11.0/api-migration-linux +``` + +Or for Darwin +```bash + $ wget -O api-migration https://github.com/cert-manager/cert-manager/releases/download/v0.11.0/api-migration-darwin +``` + +Mark the binary as executable and run the binary against your cluster +```bash +$ chmod +x api-migration && ./api-migration --kubeconfig /path/to/my/kubeconfig.yaml +``` + +Follow the CLI output and check for the difference that has been made in files +```bash +$ diff ingress.yaml ingress-migrated.yaml +``` + +Finally, once the new ingress resources have been reviewed, apply the manifests +```bash +$ kubectl apply -f ingress-migrated.yaml --kubeconfig /path/to/my/kubeconfig.yaml +``` + +You should make sure to update _all_ Ingress resources to ensure that your +certificates continue to be kept up to date. + +## `Issuer/ClusterIssuer` solvers + +Support for the deprecated `spec.http01` or `spec.dns01` fields in `Issuer` and +`ClusterIssuer` have been removed. Any `Issuer` or `ClusterIssuer` objects must +be converted to use the equivalent `spec.solvers[].http01` or +`spec.solvers[].dns01` syntax. You can read more about the Issuer resource in +the [configuration documentation](../../configuration/README.md). + +Any issuers that haven't been converted will result the `cert-manager` pod being +unable to find any solvers at the expected location. This will result in errors +like the following: `no configured challenge solvers can be used for this +challenge` diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.11-0.12.md b/content/v1.15-docs/releases/upgrading/upgrading-0.11-0.12.md new file mode 100644 index 0000000000..a2a8c1da07 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.11-0.12.md @@ -0,0 +1,29 @@ +--- +title: Upgrading from v0.11 to v0.12 +description: 'cert-manager installation: Upgrading v0.11 to v0.12' +--- + +The focus of this release has been on stability and bug fixes, as well as +overhauling and improving the documentation website. As such, there has been +minimal changes that effect end users bar two changes which require action when +upgrading. + +After addressing the following points, you should then follow the standard +upgrade process [here](../../installation/upgrade.md). + +## Changes to the Vault Kubernetes Auth Mount Path +If you are using Kubernetes authentication for Vault `Issuers` then there has +been a change to the required mount path. This value now requires the entire +mount path. For example, if the previous path had been set to `kubernetes`, the +new path will now require `/v1/auth/kubernetes`. You can read why this change +was made [here](https://github.com/cert-manager/cert-manager/issues/2205). + +## Removal of the Webhook API service +The Webhook component now no longer makes use of a Kubernetes `APIService`, and +as such, should be removed. This action is only required if you have installed +cert-manager using static manifests. The following command will delete the +service and can be done before or after applying the upgrade. + +```bash +$ kubectl delete apiservice v1beta1.webhook.cert-manager.io +``` \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.12-0.13.md b/content/v1.15-docs/releases/upgrading/upgrading-0.12-0.13.md new file mode 100644 index 0000000000..7f8ce01e48 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.12-0.13.md @@ -0,0 +1,7 @@ +--- +title: Upgrading from v0.12 to v0.13 +description: 'cert-manager installation: Upgrading v0.12 to v0.13' +--- + +When upgrading from `v0.12` to `v0.13`, no special upgrade steps are required. +Follow the regular upgrade process [here](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.13-0.14.md b/content/v1.15-docs/releases/upgrading/upgrading-0.13-0.14.md new file mode 100644 index 0000000000..22921cae0c --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.13-0.14.md @@ -0,0 +1,30 @@ +--- +title: Upgrading from v0.13 to v0.14 +description: 'cert-manager installation: Upgrading v0.13 to v0.14' +--- + +Due to changes in the Deployment selector you will need to remove the deployments first before being able to upgrade. + + +You should run the following before upgrading: +```bash +$ kubectl delete -n cert-manager deployment cert-manager cert-manager-cainjector cert-manager-webhook +``` + +If you're using Helm to install cert-manager with a deployment name different than `cert-manager` you might need to change the deployment names in the command above. + +This will delete the deployment so they can be replaced when you apply the upgrade. +This step will not affect any existing certificates but will stop renewal or new issuance while upgrading. + +Version `v0.14` now comes in 2 versions of static manifests, you will need to use the correct new one: + +* Kubernetes 1.15 or higher: you can use the normal `cert-manager.yaml` +* Kubernetes 1.14 or lower: you have to now use the `cert-manager-legacy.yaml` version +* OpenShift 4: you can now use the normal `cert-manager.yaml` +* OpenShift 3: you have to now use the `cert-manager-legacy.yaml` version instead of the OpenShift version + +> **Note**: If you're using the `cert-manager-legacy.yaml` version you will not have API version conversion and thus only support `cert-manager.io/v1alpha2` API resources. + +The webhook is now a required component, meaning that `no-webhook` variant of the manifests are no longer available in this release. Please use the appropriate manifests as mentioned above according to your Kubernetes version. + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.14-0.15.md b/content/v1.15-docs/releases/upgrading/upgrading-0.14-0.15.md new file mode 100644 index 0000000000..629e556079 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.14-0.15.md @@ -0,0 +1,26 @@ +--- +title: Upgrading from v0.14 to v0.15 +description: 'cert-manager installation: Upgrading v0.14 to v0.15' +--- + +## New `installCRDs` addition + +If you're using Helm to install cert-manager you now have the option `installCRDs`. +This will let Helm install CRDs like other cluster resources. +If you deployed cert-manager before do **NOT** use this option as it does not support +upgrading from manually installed CRDs. + +> **Note**: If enabled, when uninstalling, CRD resources will be deleted causing all +> installed custom resources to be DELETED. + +## Removal of `00-crds.yaml` file + +As part of changes to the way we publish release artifacts, the `00-crds.yaml` +file is no longer made available as part of our repository. + +You can now find the appropriate version of the CRD resources to install +attached to the GitHub release. You will need to select the appropriate +'legacy' or full manifest variant depending on the Kubernetes or +OpenShift version you are running. + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.15-0.16.md b/content/v1.15-docs/releases/upgrading/upgrading-0.15-0.16.md new file mode 100644 index 0000000000..beb13e4459 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.15-0.16.md @@ -0,0 +1,16 @@ +--- +title: Upgrading from v0.15 to v0.16 +description: 'cert-manager installation: Upgrading v0.15 to v0.16' +--- + +## Issue with older versions of `kubectl` +`kubectl` versions with patch versions lower than `v1.18.8` `v1.17.11` or `v1.16.14` have issues updating the `v0.16` CRD files, due to [a bug when handling deeply nested CRDs](https://github.com/kubernetes/kubernetes/issues/91615). +This bug will make `kubectl apply -f [...]` hang. + +This bug only happens during a re-apply of the v0.16 CRDs. Initial upgrade does not cause issues. If you have this issue please upgrade your `kubectl` to the latest patch release. +Versions of `kubectl` of `v1.15.x` or below are not being supported anymore as these are unsupported by the Kubernetes community. + +### Helm +Helm users who use `installCRDs=true` MUST upgrade to Helm `v3.3.1` before upgrading. + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.16-1.0.md b/content/v1.15-docs/releases/upgrading/upgrading-0.16-1.0.md new file mode 100644 index 0000000000..54fd19eb24 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.16-1.0.md @@ -0,0 +1,127 @@ +--- +title: Upgrading from v0.16 to v1.0 +description: 'cert-manager installation: Upgrading v0.16 to v1.0' +--- + +> The upgrade process for upgrading to `v1.0` is very Kubernetes version specific. Please check the version of your cluster using `kubectl version` and follow the steps required for your version of Kubernetes. + +## Issue with older versions of `kubectl` +`kubectl` versions with patch versions lower than `v1.18.8` `v1.17.11` or `v1.16.14` have issues updating from the `v0.16` CRD files, due to [a bug when handling deeply nested CRDs](https://github.com/kubernetes/kubernetes/issues/91615). +This bug will make `kubectl apply -f [...]` hang. + +This bug only happens during a re-apply of the v0.16 CRDs or upgrading from it. Upgrades from lower versions do not cause issues. If you have this issue please upgrade your `kubectl` to the latest patch release. +Versions of `kubectl` of `v1.15.x` or below are not being supported anymore as these are unsupported by the Kubernetes community. + +### Helm +Helm users who use `installCRDs=true` MUST upgrade to Helm `v3.3.1` or later before upgrading. + +## Upgrade instructions per Kubernetes version + +### Kubernetes `1.16` and above +These are the upgrade instructions to upgrade from cert-manager `v0.14.0` or higher, please consult other upgrade guides first before upgrading to `v1.0` if you run an older version of cert-manager. + +No special requirements, you can follow the [regular upgrade process](../../installation/upgrade.md). + +### Kubernetes `1.15.x` + +cert-manager now uses `apiextensions.k8s.io/v1` to install CRDs inside Kubernetes. This got added in Kubernetes `1.16`. +Our legacy installation will still be using `apiextensions.k8s.io/v1beta1`. For this reason Kubernetes 1.15 users now need to install the legacy version of the cert-manager manifests. +You can follow the instructions of "Kubernetes 1.14" below on how to upgrade to the legacy version of `v1.0`. + +> **Note**: The legacy version only supports a single CRD version. We advise you to consider upgrading to Kubernetes 1.16 or above for an easier migration. + +### Kubernetes `1.14` and below + +These are the upgrade instructions to upgrade from cert-manager `v0.11.0` or higher, please consult other upgrade guides first before upgrading to `v1.0` if you run an older version of cert-manager. + +> **Note**: Due to the lack of support for conversion webhooks in your Kubernetes version this will not be an easy migration. We advise you to consider upgrading to Kubernetes 1.16 or higher before upgrading. Upgrading your Kubernetes cluster might be easier than upgrading cert-manager. + +We have released our `cert-manager.io/v1` API that replaces `cert-manager.io/v1alpha2`. +Since the legacy version for Kubernetes 1.15 and below only supports one CRD version +you have to transition all resources to `cert-manager.io/v1`. + +This makes for a fairly significant breaking change for users, as **all** +cert-manager resources will need to be updated to reflect these changes. +Ingress annotations will stay the same, this means if you only use ingress-shim +you do not have to convert these resources over but it is recommended. +However you should convert the (Cluster)Issuers and delete the old CRD versions. + +This upgrade MUST be performed in the following sequence of steps: + +1. [Back up](../../devops-tips/backup.md) existing cert-manager resources. See the backup section. + +2. [Uninstall cert-manager](../../installation/uninstall.md). + +3. Update the `apiVersion` on all your backed up resources from + `cert-manager.io/v1alpha2` to `cert-manager.io/v1`. See the converting section for that. + +4. Ensure the old cert-manager CRD resources have also been deleted: `kubectl get crd | grep cert-manager.io` + + +5. Re-install cert-manager `v1.0` from scratch according to the + [installation guide](../../installation/upgrade.md). + +6. Apply the backed up resources again. + +You must be sure to properly **backup**, **uninstall**, **re-install** and +**restore** your installation in order to ensure the upgrade is successful. + +#### Backing up resources +You can backup the custom resources you or cert-manager created using the following `kubectl` command: +```bash +kubectl get -o yaml \ + --all-namespaces \ + issuer,clusterissuer,certificates,certificaterequests > cert-manager-backup.yaml +``` + +*Note that this will not export private keys or secrets.* + +#### Converting resources + +You can use [cmctl convert](../../reference/cmctl.md#convert) to automatically convert your backup from `v1alpha2` to `v1` using the following command: + +```bash +cmctl convert --output-version cert-manager.io/v1 -f cert-manager-backup.yaml > cert-manager-v1.yaml +``` + +*Tip:* you can use `kubectl apply --dry-run` on a local/test cluster with cert-manager `v1.0` installed to validate your conversion + + +#### Uninstall cert-manager +Next step is to uninstall cert-manager. +This will cause a temporary halt to renewal of certificates but will not affect any TLS traffic. + +How you do this depends on how you installed cert-manager. + +Using Helm: +```bash +$ helm --namespace cert-manager delete cert-manager +``` + +Using `kubectl`: +```bash +kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/vX.Y.Z/cert-manager.yaml +``` + +Make sure you also delete the CRDs. This will delete all cert-manager resources, so make sure your backup is complete. +You can do this manually by executing the following commands: +```bash +kubectl delete crd certificaterequests.cert-manager.io +kubectl delete crd certificates.cert-manager.io +kubectl delete crd challenges.acme.cert-manager.io +kubectl delete crd clusterissuers.cert-manager.io +kubectl delete crd issuers.cert-manager.io +kubectl delete crd orders.acme.cert-manager.io +``` + +For more info see the [uninstall cert-manager guide](../../installation/uninstall.md). + +#### Reinstall and restore +To install cert-manager again you can follow the normal [installation guide](../../installation/upgrade.md). + +Once it has been fully installed you can re-apply the converted resources: +```bash +kubectl apply -f cert-manager-v1.yaml +``` + +Congratulations you're now fully upgraded to cert-manager `v1.0` diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.2-0.3.md b/content/v1.15-docs/releases/upgrading/upgrading-0.2-0.3.md new file mode 100644 index 0000000000..d41d548f5d --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.2-0.3.md @@ -0,0 +1,129 @@ +--- +title: Upgrading from v0.2 to v0.3 +description: 'cert-manager installation: Upgrading v0.2 to v0.3' +--- + +During the `v0.3` release, a number of breaking changes were made that require +you to update either deployment configuration and runtime configuration (e.g. +`Certificate`, `Issuer` and `ClusterIssuer` resources). + +After reading these instructions, you should then proceed to upgrade cert-manager +according to your deployment configuration (e.g. using `helm upgrade` if installing +via Helm chart, or `kubectl apply` if installing with raw manifests). + +A brief summary: + +- Supporting resources for `ClusterIssuers` (e.g. signing CA certificates, or + ACME account private keys) will now be stored in the same namespace as + cert-manager, instead of `kube-system` in previous versions (#329, `@munnerz`) + +- Switch to `ConfigMaps` instead of Endpoints for leader election (#327, `@mikebryant`) + +- Removing support for ACMEv1 in favor of ACMEv2 (#309, `@munnerz`) + +* Removing ingress-shim and compiling it into cert-manager itself (#502, `@munnerz`) + +- Change to the default behavior of ingress-shim. It now generates Certificates + with the `ingressClass` field set instead of the `ingress` field. This will + mean users of ingress controllers that assign a single IP to a single Ingress (e.g. + the GCE ingress controller) will no longer work without adding a new annotation + to your ingress resource. + +## Supporting resources for `ClusterIssuers` moving into the cert-manager namespace + +In the past, the cert-manager controller was hard coded to look for supplemental +resources, such as Secrets containing DNS provider credentials, in the `kube-system` +namespace. + +We now store these resources in the same namespace as the cert-manager pod itself +runs within. + +When upgrading, you should make sure to move any of these supplemental resources into +the cert-manager deployment namespace, or otherwise deploy cert-manager into `kube-system` +itself. + +You can also change the 'cluster resource namespace' when deploying cert-manager: + +With the helm chart: `--set clusterResourceNamespace=kube-system`. + +Or if using the static deployment manifests, by adding the `--cluster-resource-namespace` +flag to the `args` field of the cert-manager container. + +## Switch to `ConfigMaps` instead of Endpoints for leader election + +cert-manager-controller performs leader election to allow you to run 'hot standby' +replicas of cert-manager. + +In the past, we used Endpoint resources to perform this election. +The new best practice is to use `ConfigMap` resources in order to reduce API overhead +in large clusters. + +As such, `v0.3` switches us to use `ConfigMap` resources for leader election. + +During the upgrade, you should first scale your cert-manager-controller deployment +to 0 to ensure no other replicas of cert-manager are running when the new `v0.3` +deployment starts: + +```bash +$ kubectl scale --namespace --replicas=0 deployment +``` + +## Removing support for ACMEv1 in favor of ACMEv2 + +The ACME `v2` specification is now in production with Let's Encrypt. +In order to support this new spec, which includes support for wildcard certificates, +we have removed support for the `v1` protocol altogether. + +If you have any ACME Issuer or `ClusterIssuer` resources, you should update the +server fields of these to the new ACMEv2 endpoints. + +For example, if you have a Let's Encrypt production issuer, you should update the +server URL: + +```yaml +apiVersion: certmanager.k8s.io/v1alpha2 +kind: Issuer +... +spec: + acme: + # server: https://acme-v01.api.letsencrypt.org/directory + server: https://acme-v02.api.letsencrypt.org/directory # we switch 'v01' to 'v02' +``` + +## Removing ingress-shim and compiling it into cert-manager itself + +In `v0.3` we removed the ingress-shim component and instead now compile in its +functionality into the main cert-manager binary. + +This change also introduces a change to the way you configure default Issuers +and `ClusterIssuers` at deployment time. + +The deployment documentation has been updated accordingly, but instead of setting +`ingressShim.extraArgs={--default-issuer-name=letsencrypt-pod}` there are +now dedicated Helm chart fields: + +```bash + --set ingressShim.defaultIssuerName=letsencrypt-prod \ + --set ingressShim.defaultIssuerKind=ClusterIssuer +``` + +## Change to the default behavior of ingress-shim + +In the past, when using ingress-shim, we set the `ingress` field on the Certificate +resource to trigger cert-manager to edit the specified Ingress resource to solve +the challenge. + +The alternate option is to set the `ingressClass` field, which causes +cert-manager to create temporary Ingress resources to solve the challenge. This +behavior provides better compatibility with ingress controllers like +[`nginx-ingress`](https://github.com/kubernetes/ingress-nginx). + +In `v0.3` we have changed the default behavior of ingress-shim to set the `ingressClass` +field instead of `ingress`. + +This will cause validations for ingress controllers like +[`ingress-gce`](https://github.com/kubernetes/ingress-gce) to fail without +additional configuration in your Ingress resources annotations. + +Add the follow annotation to your Ingress resources if you are using the GCE ingress +controller, in addition to the usual ingress-shim annotation(s): \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.3-0.4.md b/content/v1.15-docs/releases/upgrading/upgrading-0.3-0.4.md new file mode 100644 index 0000000000..29c572672b --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.3-0.4.md @@ -0,0 +1,6 @@ +--- +title: Upgrading from v0.3 to v0.4 +description: 'cert-manager installation: Upgrading v0.3 to v0.4' +--- + +There are no special notes or considerations when upgrading from `v0.3` to `v0.4`. \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.4-0.5.md b/content/v1.15-docs/releases/upgrading/upgrading-0.4-0.5.md new file mode 100644 index 0000000000..ee2ade3830 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.4-0.5.md @@ -0,0 +1,21 @@ +--- +title: Upgrading from v0.4 to v0.5 +description: 'cert-manager installation: Upgrading v0.4 to v0.5' +--- + +Version 0.5 of cert-manager introduces a new 'webhook' component, which is used +by the Kubernetes apiserver to validate our CRD resource types. + +This should help in future to reduce errors caused by misconfigured Certificate +and Issuer resources. + +When upgrading from a previous release using Helm, it is **essential** that +you perform one extra step before upgrading. + +## Disabling resource validation on the cert-manager namespace + +Before upgrading, you should add the `certmanager.k8s.io/disable-validation: "true"` +label to the `cert-manager` namespace. + +This will allow the system resources that cert-manager requires to bootstrap +TLS to be created in its own namespace. \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.5-0.6.md b/content/v1.15-docs/releases/upgrading/upgrading-0.5-0.6.md new file mode 100644 index 0000000000..9fbc721e4a --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.5-0.6.md @@ -0,0 +1,105 @@ +--- +title: Upgrading from v0.5 to v0.6 +description: 'cert-manager installation: Upgrading v0.5 to v0.6' +--- + +> **Warning**: If you are upgrading from a release older than `v0.5`, please read +> the [Upgrading from older versions using +> Helm](#upgrading-from-older-versions-using-helm) note at the bottom of this +> document! + +The upgrade process from `v0.5` to `v0.6` should be fairly seamless for most users. +As part of the new release, we have changed how we ship the +`CustomResourceDefinition` resources that cert-manager needs in order to operate +(as well as introducing two **new** CRD types). + +Depending on the way you have installed cert-manager in the past, your upgrade +process will slightly vary: + +## Upgrading with the Helm chart + +If you have previously deployed cert-manager `v0.5` using the Helm installation +method, you will now need to perform one extra step before upgrading. + +Due to issues with the way Helm handles CRD resources in Helm charts, we have +now moved the installation of these resources into a separate YAML manifest +that must be installed with `kubectl apply` before upgrading the chart. + +You can follow the [regular upgrade guide](../../installation/upgrade.md) as usual in order to upgrade +from `v0.5` to `v0.6`. + +## Upgrading with static manifests + +The static manifests have moved into the `deploy/manifests` directory for +this release. + +We now also no longer ship different manifests for different configurations, in +favor of a single `cert-manager.yaml` file which should work for all Kubernetes +clusters from Kubernetes `v1.9` onward. + +You can follow the [regular upgrade guide](../../installation/upgrade.md) as usual in order to upgrade from +`v0.5` to `v0.6`. + +## Upgrading from older versions using Helm + +If you are upgrading from a version **older than `v0.5`** and +**have installed with Helm**, you will need to perform a fresh installation of +cert-manager due to issues with the Helm upgrade process. +This will involve the **removal of all cert-manager custom resources**. +This **will not** delete the Secret resources being used by your apps. + +Before upgrading you will need to: + +1. Read and follow the [backup guide](../../devops-tips/backup.md) to create a + backup of your configuration. + +2. Delete the existing cert-manager Helm release (replacing 'cert-manager' with + the name of your Helm release): + +Uninstall the Helm chart. +```bash +$ helm delete --purge cert-manager +``` + +Ensure the cert-manager `CustomResourceDefinition` resources do not exist: +```bash +$ kubectl delete crd \ + certificates.certmanager.k8s.io \ + issuers.certmanager.k8s.io \ + clusterissuers.certmanager.k8s.io +``` + +3. Perform a fresh install (as per the [installation guide](../../installation/upgrade.md) + +Install the cert-manager CRDs +```bash + $ kubectl apply \ + -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.6/deploy/manifests/00-crds.yaml +``` + +Update helm repository cache +```bash +$ helm repo update +``` + +Install cert-manager +```bash +$ helm install \ + --name cert-manager \ + --namespace cert-manager \ + --version v0.6.6 \ + stable/cert-manager +``` + +4. Follow the steps in the [restore guide](../../devops-tips/backup.md) to + restore your configuration. + +5. Verify that your Issuers and Certificate resources are 'Ready': + +```bash +$ kubectl get clusterissuer,issuer,certificates --all-namespaces +NAMESPACE NAME READY SECRET AGE +cert-manager cert-manager-webhook-ca True cert-manager-webhook-ca 1m +cert-manager cert-manager-webhook-webhook-tls True cert-manager-webhook-webhook-tls 1m +example-com example-com-tls True example-com-tls 11s +``` \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.6-0.7.md b/content/v1.15-docs/releases/upgrading/upgrading-0.6-0.7.md new file mode 100644 index 0000000000..419bb410c2 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.6-0.7.md @@ -0,0 +1,6 @@ +--- +title: Upgrading from v0.6 to v0.7 +description: 'cert-manager installation: Upgrading v0.6 to v0.7' +--- + +There are no special notes or considerations when upgrading from `v0.6` to `v0.7`. \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.7-0.8.md b/content/v1.15-docs/releases/upgrading/upgrading-0.7-0.8.md new file mode 100644 index 0000000000..084e1487a0 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.7-0.8.md @@ -0,0 +1,270 @@ +--- +title: Upgrading from v0.7 to v0.8 +description: 'cert-manager installation: Upgrading v0.7 to v0.8' +--- + +Upgrading from `v0.7` to `v0.8` is possible using the regular +[upgrade guide](../../installation/upgrade.md). + +All resources should continue to operate as before. + +As part of `v0.8`, a new format **for configure ACME Certificate resources** has +been introduced. Notably, challenge solver configuration has moved **from** +the Certificate resource (under `certificate.spec.acme`) and now resides on +your configure **Issuer** resource, under `issuer.spec.acme.solvers`. + +This allows Certificate resources to be portable between different Issuer types. + +Both the old and the new format of configuration are supported in the `v0.8` +release, so it is possible to **incrementally upgrade your resources** if you +have a large, multi-team deployment of cert-manager that makes it complex to +upgrade all manifests at once in place. + +After upgrading, it is **strongly recommended** that you update your ACME Issuer +and Certificate resources to the [new format](../../configuration/acme/README.md). + +We will be removing support for the old format ahead of the 1.0 release. + +The documentation has been updated to reflect configuring using the new format, +and as such, exhaustive information can be found in the +[document](../../configuration/acme/README.md). + +## Performing an incremental switch to the new format + +The following guide assumes you have 2 'solver types' currently in use across +your cert-manager deployment - one for DNS01 and another for HTTP01 using an +ingress class of `nginx`. The `nginx` based HTTP01 solver will be configured as +the default solver type for Certificate resources that reference our issuer. + +You can adjust the instructions below to fit your own configuration, either +with more or less solvers as appropriate. + +First, we will modify our ACME Issuer to add the new HTTP01 and DNS01 solvers. +This operation **will not** effect any existing Certificates that already +explicitly set a `certificate.spec.acme` field: + +```yaml +apiVersion: certmanager.k8s.io/v1alpha2 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + email: user@example.com + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: example-issuer-account-key + + # The HTTP01 and DNS01 fields are now **deprecated**. + # We leave them in place here so that any Certificates that still + # specify a `certificate.spec.acme` stanza will continue to operate + # correctly. + # cert-manager will decide which configuration to use based on whether + # the Certificate contains a `certificate.spec.acme` stanza. + http01: {} + dns01: + providers: + - name: cloudflare + cloudflare: + email: my-cloudflare-acc@example.com + apiKeySecretRef: + name: cloudflare-api-key-secret + key: api-key + + # Configure the challenge solvers. + solvers: + # An empty selector will 'match' all Certificate resources that + # reference this Issuer. + - selector: {} + http01: + ingress: + ingressClassName: nginx + - selector: + # Any Certificate resources, or Ingress resources that use + # ingress-shim and match the below label selector will use this + # configured solver type instead of the default nginx based HTTP01 + # solver above. + # You can continue to add new solver types if needed. + # The most specific 'match' will be used. + matchLabels: + use-cloudflare-solver: "true" + dns01: + # Adjust the configuration below according to your environment. + # You can view more example configurations for different DNS01 + # providers in the documentation: https://cert-manager.io/docs/tutorials/acme/dns-validation/ + cloudflare: + email: my-cloudflare-acc@example.com + apiKeySecretRef: + name: cloudflare-api-key-secret + key: api-key +``` + + +By retaining both the old and the new configuration format on the Issuer +resource, we can begin the process of incrementally upgrading our Certificate +resources. + +Any Certificate resources that you have manually created (i.e. not managed by +ingress-shim) must then be updated to remove the `certificate.spec.acme` +stanza. + +Given the above configuration, certificates will use the HTTP01 solver with the +`nginx` ingress class in order to solve ACME challenges. + +If a particular certificate requires a wildcard, or you simply want to use +DNS01 for that certificate instead of HTTP01, you can add the `use-cloudflare-solver: "true"` +label to your Certificate resources and the appropriate ACME challenge solver +will be used. + +## Upgrading ingress-shim managed certificates to the new format + +When using ingress-shim, cert-manager itself will create and manage your +Certificate resource for you. + +In order to support both the old and the new format simultaneously, +ingress-shim will continue to set the `certificate.spec.acme` field on +Certificate resources it manages. + +In order to force ingress-shim to also use the new format, you must **remove** +the old format configuration from your Issuer resources (i.e. `issuer.spec.acme.http01` +and `issuer.spec.acme.dns01`). + +When ingress-shim detects that these fields are not specified, it will +clear/not set the `certificate.spec.acme` field. + +If you are managing a certificate using ingress-shim that requires an +alternative solver type (other than the default solver configured on the issuer +which in this instance is the HTTP01 `nginx` solver), you can add labels to the +Ingress resource which will be automatically copied across to the Certificate +resource: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: my-test-ingress + labels: + use-cloudflare-solver: "true" +``` + +## Confirming all Certificate resources are upgraded + +In order to check if any of your Certificate resources still have the old +configuration format, you can run the following command: + +```bash +$ kubectl get certificate --all-namespaces \ + -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,OWNER:.metadata.ownerReferences[0].kind,OLD FORMAT:.spec.acme" +NAMESPACE NAME OWNER OLD FORMAT +default test +default test2 Ingress map[config:[map[domains:[abc.com] http01:map[ingressClass:nginx]]]] +``` + +In the above example, we can see there are two Certificate resources. + +The `test` resource has been updated to no longer include the +`certificate.spec.acme` field. + +The `test2` resource still specifies the old configuration format, however it +**also** has an `OwnerReference` linking it to an **Ingress** resource. +This is because the `test2` Certificate resource is managed by ingress-shim. + +As mentioned in the previous section, ingress-shim managed certificates will +only switch to the new format once the **old format** configuration on the +**Issuer** resource has been removed. This means we need to continue to the +next section in order to remove the old format configuration altogether from +**Issuer** resource in order for ingress-shim to automatically migrate the +`test2` Certificate resource. + +## Removing old configuration altogether + +Once we've verified that all non-ingress-shim managed Certificate resources +have been updated to not specify the `certificate.spec.acme` stanza using the +command above, we can proceed to remove the `issuer.spec.acme.http01` and +`issuer.spec.acme.dns01` stanzas from our Issuer resources. +Once completed, the Issuer resource from the previous section should look like +the following: + +```yaml +apiVersion: certmanager.k8s.io/v1alpha2 +kind: ClusterIssuer +metadata: + name: letsencrypt-staging +spec: + acme: + email: user@example.com + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + name: example-issuer-account-key + + # Configure the challenge solvers. + solvers: + # An empty selector will 'match' all Certificate resources that + # reference this Issuer. + - selector: {} + http01: + ingress: + ingressClassName: nginx + - selector: + # Any Certificate resources, or Ingress resources that use + # ingress-shim and match the below label selector will use this + # configured solver type instead of the default nginx based HTTP01 + # solver above. + # You can continue to add new solver types if needed. + # The most specific 'match' will be used. + matchLabels: + use-cloudflare-solver: "true" + dns01: + # Adjust the configuration below according to your environment. + # You can view more example configurations for different DNS01 + # providers in the documentation: https://cert-manager.io/docs/tutorials/acme/dns-validation/ + cloudflare: + email: my-cloudflare-acc@example.com + apiKeySecretRef: + name: cloudflare-api-key-secret + key: api-key +``` + +After applying the above Issuer resource, you should re-run the command from +the last section to verify that the remaining ingress-shim managed Certificate +resources have also been updated to the new format: + +```bash +$ kubectl get certificate --all-namespaces \ + -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,OWNER:.metadata.ownerReferences[0].kind,OLD FORMAT:.spec.acme" +NAMESPACE NAME OWNER OLD FORMAT +default test +default test2 Ingress +``` + +## Manually triggering a Certificate to be issued to validate the full configuration + +To be certain that you've correctly configured your new Issuer/Certificate +resources, it is advised you attempt to issue a new Certificate after removing +the old configuration format. + +To do so, you can either: + +- update the `secretName` field of an existing Certificate resource +- add an additional `dnsName` to one of your existing Certificate resources +- create a new Certificate resource + +You should ensure that your Certificates are still be issued correctly to avoid +any potential issues at renewal time. + +## Special notes for `ingress-gce` users + +Users of the `ingress-gce` ingress controller may find that their experience +configuring cert-manager to solve challenges using HTTP01 validation is +slightly more painful using the new format, as it requires the `ingressName` +field to be specified as a distinct `solver` on the Issuer resource (as +opposed to in the past where the `ingressName` could be specified as a field on +the `Certificate` resource). + +This is a [known issue](https://github.com/cert-manager/cert-manager/issues/1666), +and a workaround is scheduled to be completed for `v0.9`. + +In the meantime, `ingress-gce` users can either choose to manually create a +new solver entry per Ingress resource they want to use to solve challenges, or +otherwise continue to use the **old format** until a suitable alternative +appears in `v0.9`. \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.8-0.9.md b/content/v1.15-docs/releases/upgrading/upgrading-0.8-0.9.md new file mode 100644 index 0000000000..4adef854be --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.8-0.9.md @@ -0,0 +1,21 @@ +--- +title: Upgrading from v0.8 to v0.9 +description: 'cert-manager installation: Upgrading v0.8 to v0.9' +--- + +Due to a change in the API group that cert-manager deployments use +(`apps/v1beta1` to `apps/v1`), cert-manager deployments must first be deleted +before applying the new version. This will cause downtime until the new version +has been applied. No data loss will occur during this operation however it is +always advised to backup your data during an upgrade, which you can follow +[here](../../devops-tips/backup.md). To perform this action run: + +```bash +$ kubectl delete deployments --namespace cert-manager \ + cert-manager \ + cert-manager-cainjector \ + cert-manager-webhook +``` + +After this operation, follow the standard upgrade process as defined in the +[upgrade guide](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-0.9-0.10.md b/content/v1.15-docs/releases/upgrading/upgrading-0.9-0.10.md new file mode 100644 index 0000000000..d5bdd3d523 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-0.9-0.10.md @@ -0,0 +1,24 @@ +--- +title: Upgrading from v0.9 to v0.10 +description: 'cert-manager installation: Upgrading v0.9 to v0.10' +--- + +Due to changes in the way the webhook component's TLS is bootstrapped in +`v0.10`, you will need to delete your webhook's Certificate and Issuer +resources. + +If you are using a deployment tool that automatically handles this (i.e. Helm), +there should be no additional action to take. + +If you are using the 'static manifests' to install, you should run the following +after upgrading: + +```bash +$ kubectl delete -n cert-manager issuer cert-manager-webhook-ca cert-manager-webhook-selfsign +$ kubectl delete -n cert-manager certificate cert-manager-webhook-ca cert-manager-webhook-webhook-tls +$ kubectl delete apiservice v1beta1.admission.certmanager.k8s.io +``` + +The Secret resources used to contain TLS assets for the webhook are now +automatically handled internally by cert-manager, so these resources are no +longer required. \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.0-1.1.md b/content/v1.15-docs/releases/upgrading/upgrading-1.0-1.1.md new file mode 100644 index 0000000000..86de90149e --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.0-1.1.md @@ -0,0 +1,7 @@ +--- +title: Upgrading from v1.0 to v1.1 +description: 'cert-manager installation: Upgrading v1.0 to v1.1' +--- + +When upgrading from `v1.0` to `v1.1`, no special upgrade steps are required 🎉. +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.1-1.2.md b/content/v1.15-docs/releases/upgrading/upgrading-1.1-1.2.md new file mode 100644 index 0000000000..18877b54ca --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.1-1.2.md @@ -0,0 +1,21 @@ +--- +title: Upgrading from v1.1 to v1.2 +description: 'cert-manager installation: Upgrading v1.1 to v1.2' +--- + +In an effort to introduce new features whilst keeping the project maintainable, +cert-manager now only supports Kubernetes down to version `v1.16`. This means +the `legacy` manifests have now been removed. Some users experience issues when +upgrading the legacy `CRD`s to `v1.2`. To solve this, you could replace the `CRD`s: +1. Backup `cert-manager` resources as described in [the docs](../../devops-tips/backup.md) +2. Run `kubectl replace -f https://github.com/cert-manager/cert-manager/releases/download/v1.2.0/cert-manager.crds.yaml` to replace the CRDs. +3. Follow the standard upgrade process. +You can read more about supported Kubernetes versions + [here](../README.md). + +In this release some features have been deprecated. Please read the [version +1.2 release notes](../../releases/release-notes/release-notes-1.2.md) for more details +and consider whether you are using any of these deprecated features before you +proceed with the upgrade. + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.10-1.11.md b/content/v1.15-docs/releases/upgrading/upgrading-1.10-1.11.md new file mode 100644 index 0000000000..caaf203f1e --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.10-1.11.md @@ -0,0 +1,25 @@ +--- +title: Upgrading from v1.10 to v1.11 +description: 'cert-manager installation: Upgrading v1.10 to v1.11' +--- + +There are no breaking changes between cert-manager `v1.10` and `v1.11` unless you're using +the experimental Gateway API support in cert-manager. + +## Gateway API + +Unless you've explicitly opted into using cert-manager's Gateway API experimental feature, +you don't need to worry about this change. + +cert-manager `v1.11` updates cert-manager's supported version of the Gateway API CRDs to +`v1beta1`. Since Gateway API isn't yet entirely stable, you should expect some breakage as +the project evolves and when upgrading to new versions, currently. + +You shouldn't need to change any config on your actual Gateway API resources because of this +upgrade, but you **must** ensure that you've installed the `v1beta1` Gateway API version. + +There are additional details in the [Gateway API usage](../../usage/gateway.md) document. + +## Next Steps + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.11-1.12.md b/content/v1.15-docs/releases/upgrading/upgrading-1.11-1.12.md new file mode 100644 index 0000000000..78348421c1 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.11-1.12.md @@ -0,0 +1,10 @@ +--- +title: Upgrading from v1.11 to v1.12 +description: 'cert-manager installation: Upgrading v1.11 to v1.12' +--- + +There are no breaking changes between cert-manager 1.11 and 1.12. + +## Next Steps + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.12-1.13.md b/content/v1.15-docs/releases/upgrading/upgrading-1.12-1.13.md new file mode 100644 index 0000000000..6cd4d4e503 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.12-1.13.md @@ -0,0 +1,21 @@ +--- +title: Upgrading from v1.12 to v1.13 +description: 'cert-manager installation: Upgrading v1.12 to v1.13' +--- + +When upgrading cert-manager from 1.12 to 1.13, in few cases you might need to take additional steps to ensure a smooth upgrade: + +1. **IMPORTANT NOTE**: If upgrading from a version below v1.12, upgrade to the latest v1.12 release before upgrading to v1.13. Otherwise, some certificates may be unexpectedly re-issued (see https://github.com/cert-manager/cert-manager/issues/6494#issuecomment-1816112309) + +2. BREAKING: If you deploy cert-manager using helm and have `.featureGates` value set, the features defined +there will no longer be passed to cert-manager webhook, only to cert-manager controller. Use `webhook.featureGates` field +instead to define features to be enabled on webhook. (https://github.com/cert-manager/cert-manager/pull/6093, https://github.com/irbekrm) + +3. Potentially breaking: If you were, for some reason, passing cert-manager controller's features to webhook's --feature-gates flag, +this will now break (unless the webhook actually has a feature by that name). (https://github.com/cert-manager/cert-manager/pull/6093, https://github.com/irbekrm) + +4. Potentially breaking: Webhook validation of CertificateRequest resources is stricter now: all `KeyUsages` and `ExtendedKeyUsages` must be defined directly in the CertificateRequest resource, the encoded CSR can never contain more usages that defined there. (https://github.com/cert-manager/cert-manager/pull/6182, https://github.com/inteon) + +## Next Steps + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.13-1.14.md b/content/v1.15-docs/releases/upgrading/upgrading-1.13-1.14.md new file mode 100644 index 0000000000..8a1b69a802 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.13-1.14.md @@ -0,0 +1,30 @@ +--- +title: Upgrading from v1.13 to v1.14 +description: 'cert-manager installation: Upgrading v1.13 to v1.14' +--- + +Before upgrading cert-manager from 1.13 to 1.14 please read the following important notes about breaking changes in 1.14: + +## Please install the latest patch release: `v1.14.2` + +The following bugs were found in `v1.14.1` and have been fixed in `v1.14.2`: + +- cert-manager CA and SelfSigned issuers incorrectly copied the critical flag from the CSR instead of re-calculating that field themselves + +The following bugs were found during the release of `v1.14.0` and have been fixed in `v1.14.1`: + +- During the release of `v1.14.0`, the Helm chart was found to use the wrong OCI image for the `cainjector` Deployment, + which caused the Helm installation to fail. +- A bug in cmctl namespace detection prevents it being used as a startupapicheck image in namespaces other than cert-manager. +- A bug in cmctl causes `cmctl experimental install` to panic. + +Read the [`v1.14.2` release notes](../release-notes/release-notes-1.14.md#v1.14.2) and [`v1.14.1` release notes](../release-notes/release-notes-1.14.md#v1.14.1) for more information. + +## New startupapicheck image + +The startupapicheck job uses a new OCI image called [startupapicheck](../../cli/startupapicheck.md), instead of the [ctl](../../cli/cmctl.md) image. +If you run in an environment in which images cannot be pulled, be sure to include the new image. + +## Next Steps + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.14-1.15.md b/content/v1.15-docs/releases/upgrading/upgrading-1.14-1.15.md new file mode 100644 index 0000000000..e08a0aeb04 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.14-1.15.md @@ -0,0 +1,20 @@ +--- +title: Upgrading from v1.14 to v1.15 +description: 'cert-manager installation: Upgrading v1.14 to v1.15' +--- + +Before upgrading cert-manager from 1.14 to 1.15 please read the following important notes about breaking changes in 1.15: + +## GatewayAPI promotion to beta + +GatewayAPI support has been promoted to beta, and thus the feature flag `ExperimentalGatewayAPISupport` is now enabled by default. + +If you had previously enabled this feature flag you will now need to pass the flag `--enable-gateway-api` instead. This is because while the feature is now enabled by default, we still need to gate it behind a flag so cert-manager will not crash if the GatewayAPI CRDs are not installed. + +## Startupapicheck image change + +As of this release the cert-manager ctl is no longer part of the main repo, it has been broken out into its own project. As such the startupapicheck job uses a new OCI image called [startupapicheck](../../cli/startupapicheck.md). If you run in an environment in which images cannot be pulled, be sure to include the new image. + +## Next Steps + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.2-1.3.md b/content/v1.15-docs/releases/upgrading/upgrading-1.2-1.3.md new file mode 100644 index 0000000000..a7a56e390b --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.2-1.3.md @@ -0,0 +1,32 @@ +--- +title: Upgrading from v1.2 to v1.3 +description: 'cert-manager installation: Upgrading v1.2 to v1.3' +--- + +## Upgrade notes for users of the Venafi Cloud Issuer + +This release updates the [Venafi Cloud Issuer][] to use `OutagePREDICT` instead of `DevOpsACCELERATE`. + +The only impact to Venafi Cloud users is the change in zone syntax. +The zone is now `\` +(e.g. `My Application\My CIT`). + +### Background + +Venafi are currently transitioning Venafi Cloud users to the `OutagePREDICT` ("OP") product, +from `DevOpsACCELERATE` ("DA"), which will be sunset later in 2021. + +The [Venafi Cloud Issuer][] in cert-manager relies upon the `VCert` library, +and the [`VCert` `v4.13.0`][] release marks this "DA2OP" transition. +The `VCert` module dependencies in cert-manager have been updated in order for cert-manager to complete the transition as well. + +With this update, cert-manager users with Venafi Cloud issuers will need to be aware that the zone format changes from a UUID (DA Zone ID) to a string of the form `\`. +This means users will need to create an Application in `OutagePREDICT` and associate an _Issuing Template_ with it +(the same _Issuing Templates_ assigned to DA Projects Zones can be used since _Issuing Templates_ are shared between Venafi Cloud products). + +[Venafi Cloud Issuer]: https://cert-manager.io/docs/configuration/venafi/ +[`VCert` `v4.13.0`]: https://github.com/Venafi/vcert/releases/tag/v4.13.0 + +## Next Steps + +You should now follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.3-1.4.md b/content/v1.15-docs/releases/upgrading/upgrading-1.3-1.4.md new file mode 100644 index 0000000000..d7befe89e1 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.3-1.4.md @@ -0,0 +1,31 @@ +--- +title: Upgrading from v1.3 to v1.4 +description: 'cert-manager installation: Upgrading v1.3 to v1.4' +--- + +## Removal of the cert-manager operator package on Red Hat Marketplace + +Since cert-manager `v0.15` there has been a package for cert-manager on [Red Hat Marketplace][], +but this has now been removed because it was not maintained and was found to be unreliable: +[#4055](https://github.com/cert-manager/cert-manager/issues/4055) +[#3732](https://github.com/cert-manager/cert-manager/issues/3732) +[#436](https://github.com/cert-manager/website/issues/436) + +[Red Hat Marketplace]: https://marketplace.redhat.com + +It is replaced by a new package which is generated via the [Community Operators Repository][], +and which is therefore available on +[OperatorHub.io](https://operatorhub.io), +[OpenShift Container Platform](https://openshift.com) and +[OKD](https://okd.io). + +[Community Operators Repository]: https://github.com/operator-framework/community-operators + +Please uninstall the existing cert-manager package and re-install +by following the [OLM Installation Documentation][]. + +[OLM Installation Documentation]: ../../installation/operator-lifecycle-manager.md + +## Now Follow the Regular Upgrade Process + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.4-1.5.md b/content/v1.15-docs/releases/upgrading/upgrading-1.4-1.5.md new file mode 100644 index 0000000000..46385192ce --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.4-1.5.md @@ -0,0 +1,11 @@ +--- +title: Upgrading from v1.4 to v1.5 +description: 'cert-manager installation: Upgrading v1.4 to v1.5' +--- + +If you are currently using HTTP-01 challenges or the Ingress shim annotations, please read the [Ingress class compatibility](./ingress-class-compatibility.md) +notes to see if your Ingress controller has any known issues with the migration to Ingress v1. + +## Now Follow the Regular Upgrade Process + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.5-1.6.md b/content/v1.15-docs/releases/upgrading/upgrading-1.5-1.6.md new file mode 100644 index 0000000000..e819e77947 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.5-1.6.md @@ -0,0 +1,30 @@ +--- +title: Upgrading from v1.5 to v1.6 +description: 'cert-manager installation: Upgrading v1.5 to v1.6' +--- + +### Upgrading cert-manager CRDs and stored versions of cert-manager custom resources + +Following their deprecation in version 1.4, the cert-manager API versions `v1alpha2, v1alpha3, and v1beta1` are no longer served. + +This means if your deployment manifests contain any of these API versions, you will not be able to deploy them after upgrading. +Our new `cmctl` utility or old `kubectl cert-manager` plugin can [convert](../../reference/cmctl.md#convert) old manifests to `v1` for you. + +
          + +⛔️ If you are upgrading cert-manager on a cluster which has previously had +cert-manager < `v1.0.0`, you will need to ensure that all cert-manager custom +resources are stored in `etcd` at `v1` version and that cert-manager CRDs do not +reference the deprecated APIs **before you upgrade to `v1.6`**. + +This is explained in more detail in the [Upgrading existing cert-manager resources](./remove-deprecated-apis.md#upgrading-existing-cert-manager-resources) +page. + +
          + +If you are currently using HTTP-01 challenges or the Ingress shim annotations, please read the [Ingress class compatibility](./ingress-class-compatibility.md) +notes to see if your Ingress controller has any known issues with the migration to Ingress v1. + +## Now Follow the Regular Upgrade Process + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.6-1.7.md b/content/v1.15-docs/releases/upgrading/upgrading-1.6-1.7.md new file mode 100644 index 0000000000..4b5e012dd4 --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.6-1.7.md @@ -0,0 +1,24 @@ +--- +title: Upgrading from v1.6 to v1.7 +description: 'cert-manager installation: Upgrading v1.6 to v1.7' +--- + +⚠ Following their deprecation in version 1.5, the cert-manager API versions v1alpha2, v1alpha3, and v1beta1 have been removed. +You must ensure that all cert-manager custom resources are stored in etcd at version v1 +and that all cert-manager `CustomResourceDefinition`s have only v1 as the stored version +**before** upgrading. +Please read [Migrating Deprecated API Resources] for full instructions. + +[Migrating Deprecated API Resources]: ./remove-deprecated-apis.md + +If you are currently using HTTP-01 challenges or the Ingress shim annotations, please read the [Ingress class compatibility](./ingress-class-compatibility.md) +notes to see if your Ingress controller has any known issues with the migration to Ingress v1. + +If running Kubernetes versions before `v1.22`, the +[`ServerSideApply`](https://kubernetes.io/docs/reference/using-api/server-side-apply/) +feature gate _must_ be enabled in the cluster. This beta feature is enabled by default +on supported versions before `v1.22`. + +## Now Follow the Regular Upgrade Process + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). \ No newline at end of file diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.7-1.8.md b/content/v1.15-docs/releases/upgrading/upgrading-1.7-1.8.md new file mode 100644 index 0000000000..b65538b5ba --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.7-1.8.md @@ -0,0 +1,91 @@ +--- +title: Upgrading from v1.7 to v1.8 +description: 'cert-manager installation: Upgrading v1.6 to v1.7' +--- + +#### Validation of the `rotationPolicy` field + +The field `spec.privateKey.rotationPolicy` on Certificate resources is now validated. Valid options are Never and Always. + +Before upgrading to 1.8.0, you will need to check that all the Certificate YAML manifests you have stored in Git if you are using a GitOps flow (or any other "source of truth") have a correct `rotationPolicy` value. To help you find out which Certificate YAML manifests need updating, you can run the following command: + +```sh +kubectl get cert -A -ojson | jq -r \ + '.items[] | select(.spec.privateKey.rotationPolicy | strings | . != "Always" and . != "Never") | "\(.metadata.name) in namespace \(.metadata.namespace) has rotationPolicy=\(.spec.privateKey.rotationPolicy)"' +``` + +This command will show you, the name and namespace of each Certificate resource that needs to be updated in Git. For example: + +```text +smoketest-cert in namespace default has rotationPolicy=Foo +``` + +#### Server-Side Apply + +Server-Side Apply is an alpha feature of cert-manager introduced in 1.8. By +default, the feature is disabled, in which case you can skip this section. + +If you are using Server-Side Apply, i.e., you are running the cert-manager +controller with the flag + +```text +--feature-gates=ServerSideApply=true +``` + +Then you need to take action before upgrading to cert-manager 1.8. You will have +to make sure that there are no Challenge resources currently in the cluster. If +there are some, you will need to manually delete them once they are in a 'valid' +state. + +The reason the Challenge resources need to be removed before upgrading to 1.8 +when using the new Server-Side Apply feature is that cert-manager post-1.8 is +not able to clean up Challenge resources that were created pre-1.8. + +If running Kubernetes versions before `v1.22`, the +[`ServerSideApply`](https://kubernetes.io/docs/reference/using-api/server-side-apply/) +feature gate _must_ be enabled in the cluster. This beta feature is enabled by +default on supported versions before `v1.22`. + +#### Migrating from the Gateway API v1alpha1 to v1alpha2 + +This section only applies to you if you are using the feature gate +`ExperimentalGatewayAPISupport`. + +cert-manager 1.8 drops support for the Gateway API v1alpha1, and now only +supports v1alpha2. + +Before upgrading cert-manager, you will need to: + +1. remove all existing Gateway API v1alpha1 resources, +2. upgrade the Gateway API CRDs to v1alpha2, +3. re-create the Gateway API resources with the v1alpha2. + +This manual intervention is needed because the Gateway API project does not +come with a conversion webhook that would allow an easier migration from +v1alpha1 to v1alpha2. + +After upgrading cert-manager to 1.8, you will need to remove the `labels` field, +and add the `parentRefs`: + +```diff + apiVersion: cert-manager.io/v1 + kind: Issuer + metadata: + name: letsencrypt + namespace: default + spec: + acme: + solvers: + - http01: + gatewayHTTPRoute: +- labels: +- gateway: traefik ++ parentRefs: ++ - name: traefik ++ namespace: traefik ++ kind: Gateway +``` + +## Now, Follow the Regular Upgrade Process + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.8-1.9.md b/content/v1.15-docs/releases/upgrading/upgrading-1.8-1.9.md new file mode 100644 index 0000000000..5c61e8293a --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.8-1.9.md @@ -0,0 +1,11 @@ +--- +title: Upgrading from v1.8 to v1.9 +description: 'cert-manager installation: Upgrading v1.8 to v1.9' +--- + +If running Kubernetes versions before `v1.22`, the +[`ServerSideApply`](https://kubernetes.io/docs/reference/using-api/server-side-apply/) +feature gate _must_ be enabled in the cluster. This beta feature is enabled by default +on supported versions before `v1.22`. + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/releases/upgrading/upgrading-1.9-1.10.md b/content/v1.15-docs/releases/upgrading/upgrading-1.9-1.10.md new file mode 100644 index 0000000000..76695893ba --- /dev/null +++ b/content/v1.15-docs/releases/upgrading/upgrading-1.9-1.10.md @@ -0,0 +1,17 @@ +--- +title: Upgrading from v1.9 to v1.10 +description: 'cert-manager installation: Upgrading v1.9 to v1.10' +--- + +## On OpenShift the cert-manager Pods may fail until you modify Security Context Constraints + +In cert-manager 1.10 the [secure computing (seccomp) profile](https://kubernetes.io/docs/tutorials/security/seccomp/) for all the Pods +is set to `RuntimeDefault`. +On some versions and configurations of OpenShift this can cause the Pod to be rejected by the +[Security Context Constraints admission webhook](https://docs.openshift.com/container-platform/4.10/authentication/managing-security-context-constraints.html#admission_configuring-internal-oauth). + +> 📖 Read the [Breaking Changes section in the 1.10 release notes](../../releases/release-notes/release-notes-1.10.md) before upgrading. + +## Next Steps + +From here on you can follow the [regular upgrade process](../../installation/upgrade.md). diff --git a/content/v1.15-docs/troubleshooting/README.md b/content/v1.15-docs/troubleshooting/README.md new file mode 100644 index 0000000000..fff96f1672 --- /dev/null +++ b/content/v1.15-docs/troubleshooting/README.md @@ -0,0 +1,116 @@ +--- +title: Troubleshooting +description: | + Learn how to debug common problems with cert-manager +--- + +In this section, you will learn troubleshooting techniques that will help you find the root cause if your Certificate fails to be issued or renewed. + +This section also includes the following guides: + +* [Troubleshooting Problems with ACME / Let's Encrypt Certificates](./acme.md): + Learn more about how the ACME issuer works and how to diagnose problems with it. +* [Troubleshooting Problems with the Webhook](./webhook.md): + Learn how to diagnose problems with the cert-manager webhook. + +## Overview + +When troubleshooting cert-manager your best friend is `kubectl describe`, this will give you information on the resources as well as recent events. It is not advised to use the logs as these are quite verbose and only should be looked at if the following steps do not provide help. + +cert-manager consists of multiple custom resources that live inside your Kubernetes cluster, these resources are linked together and are often created by one another. When such an event happens it will be reflected in a Kubernetes event, you can see these per-namespace using `kubectl get event`, or in the output of `kubectl describe` when looking at a single resource. + +## Troubleshooting a failed certificate request + +There are several resources that are involved in requesting a certificate. + +``` + + ( +---------+ ) + ( | Ingress | ) Optional ACME Only! + ( +---------+ ) + | | + | +-------------+ +--------------------+ | +-------+ +-----------+ + |-> | Certificate |----> | CertificateRequest | ----> | | Order | ----> | Challenge | + +-------------+ +--------------------+ | +-------+ +-----------+ + | +``` + +The cert-manager flow all starts at a `Certificate` resource, you can create this yourself or your Ingress resource will do this for you if you have the [correct annotations](../usage/ingress.md) set. + +### 1. Checking the Certificate resource +First we have to check if we have a `Certificate` resource created in our namespace. We can get these using `kubectl get certificate`. +```console +$ kubectl get certificate +NAME READY AGE +example-com-tls False 1h +``` + +If none is present and you plan to use the [ingress-shim](../usage/ingress.md): check the ingress annotations more about that is in the [ingress troubleshooting guide](../usage/ingress.md#troubleshooting). +If you are not using the ingress-shim: check the output of the command you used to create the certificate. + +If you see one with ready status `False` you can get more info using `kubectl describe certificate`, if the status is `True` that means that cert-manager has successfully issued a certificate. +```console +$ kubectl describe certificate +[...] +Status: + Conditions: + Last Transition Time: 2020-05-15T21:45:22Z + Message: Issuing certificate as Secret does not exist + Reason: DoesNotExist + Status: False + Type: Ready + Next Private Key Secret Name: example-tls-wtlww +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Issuing 105s cert-manager Issuing certificate as Secret does not exist + Normal Generated 105s cert-manager Stored new private key in temporary Secret resource "example-tls-wtlww" + Normal Requested 104s cert-manager Created new CertificateRequest resource "example-tls-bw5t9" +``` + +Here you will find more info about the current certificate status under `Status` as well as detailed information about what happened to it under `Events`. Both will help you determine the current state of the certificate. +The last status is `Created new CertificateRequest resource`, it is worth taking a look at in which state `CertificateRequest` is to get more info on why our `Certificate` isn't getting issued. + +### 2. Checking the `CertificateRequest` +The `CertificateRequest` resource represents a CSR in cert-manager and passes this CSR on onto the issuer. +You can find the name of the `CertificateRequest` in the `Certificate` event log or using `kubectl get certificaterequest` + +To get more info we again run `kubectl describe`: +```console +$ kubectl describe certificaterequest +API Version: cert-manager.io/v1 +Kind: CertificateRequest +Spec: + Request: [...] + Issuer Ref: + Group: cert-manager.io + Kind: ClusterIssuer + Name: letencrypt-production +Status: + Conditions: + Last Transition Time: 2020-05-15T21:45:36Z + Message: Waiting on certificate issuance from order example-tls-fqtfg-1165244518: "pending" + Reason: Pending + Status: False + Type: Ready +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal OrderCreated 8m20s cert-manager Created Order resource example-tls-fqtfg-1165244518 +``` + +Here we will see any issue regarding the Issuer configuration as well as Issuer responses. + +### 3. Check the issuer state +If in the above steps you saw an issuer not ready error you can do the same steps again for (cluster)issuer resources: +```console +$ kubectl describe issuer +$ kubectl describe clusterissuer +``` + +These will allow you to get any error messages regarding accounts or network issues with your issuer. +Troubleshooting ACME issuers is described in more detail in [Troubleshooting Issuing ACME Certificates](./acme.md). + +### 4. ACME Troubleshooting +ACME (e.g. Let's Encrypt) issuers have 2 additional resources inside cert-manager: `Orders` and `Challenges`. +Troubleshooting these is described in [Troubleshooting Issuing ACME Certificates](./acme.md). diff --git a/content/v1.15-docs/troubleshooting/acme.md b/content/v1.15-docs/troubleshooting/acme.md new file mode 100644 index 0000000000..c8b527b1cf --- /dev/null +++ b/content/v1.15-docs/troubleshooting/acme.md @@ -0,0 +1,226 @@ +--- +title: Troubleshooting Problems with ACME / Let's Encrypt Certificates +description: | + Learn how to diagnose problems if cert-manager fails to renew ACME / Let's Encrypt Certificates. +--- + +Learn how to diagnose problems if cert-manager fails to renew ACME / Let's Encrypt Certificates. + +## Overview + +When requesting ACME certificates, cert-manager will create `Order` and +`Challenges` to complete the request. As such, there are more resources to +investigate and debug if there is a problem during the process. You can read +more about these resources in the [concepts +pages](../concepts/acme-orders-challenges.md). + +Before you start here you should probably take a look at our [general troubleshooting guide](./README.md) + +## 1. Troubleshooting (Cluster)Issuers + +First of all check if the (Cluster)Issuer you're using is in a ready state: +```bash +$ kubectl get issuer +$ kubectl get clusterissuer +NAME READY AGE +letsencrypt True 38m +letsencrypt-http False 32m +``` + +If you see `False` check the status using `kubectl describe`. For example: +```bash +$ kubectl describe issuer letsencrypt-http +$ kubectl describe clusterissuer letsencrypt-http +Name: letsencrypt +API Version: cert-manager.io/v1 +Kind: Issuer +Spec: + Acme: + Email: cert-manager@example.com + Private Key Secret Ref: + Name: letsencrypt + Server: https://acme-staging-v02.api.letsencrypt.org/directory +Status: + Acme: + Conditions: + Message: Failed to update ACME account:400 urn:ietf:params:acme:error:invalidEmail: Unable to update account :: invalid contact domain. Contact emails @example.com are forbidden + Reason: ErrUpdateACMEAccount + Status: False + Type: Ready +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Warning ErrUpdateACMEAccount 101s (x3 over 106s) cert-manager Failed to update ACME account:400 urn:ietf:params:acme:error:invalidEmail: Unable to update account :: invalid contact domain. Contact emails @example.com are forbidden +``` + +### Common errors + +* `Failed to update ACME account:400 urn:ietf:params:acme:error:invalidEmail`: the email you specified in the Issuer configuration isn't valid. +* `Error initializing issuer: Failed to register ACME account: secrets "acme-key" already exists`: there might be a leftover account from a previous issuer that is no longer valid, you should remove the secret so it can be recreated. +* `Error accepting challenge: 400 urn:ietf:params:acme:error:malformed: Unable to update challenge :: authorization must be pending`: this suggests that the authorization was not in 'pending' state at a time when cert-manager sent a request to the ACME server to accept the challenge. This may be because the domain validation has already failed and the authorization has been marked as 'invalid'. Check the authorization URL on the status of the `Order` or `Challenge` to see the status of the authorization and any additional information. + +## 2. Troubleshooting Orders + +When we run a describe on the `CertificateRequest` resource we see that an `Order` that has +been created: + +```bash +$ kubectl describe certificaterequest example-com-2745722290 +... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal OrderCreated 5s cert-manager Created Order resource default/example-com-2745722290-439160286 +``` + +Orders are a request to an ACME instance to issue a certificate. +By running `kubectl describe order` on a particular order, +information can be gleaned about failures in the process: + +```console +$ kubectl describe order example-com-2745722290-439160286 +... +Reason: +State: pending +URL: https://acme-v02.api.letsencrypt.org/acme/order/41123272/265506123 +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Created 1m cert-manager Created Challenge resource "example-com-2745722290-439160286-0" for domain "test1.example.com" + Normal Created 1m cert-manager Created Challenge resource "example-com-2745722290-439160286-1" for domain "test2.example.com" +``` + +Here we can see that cert-manager has created two Challenge resources to verify we control specific domains, +a requirements of the ACME order to obtain a signed certificate. + +You can then go on to run +`kubectl describe challenge example-com-2745722290-439160286-0` to further debug the +progress of the Order. + +Once an Order is successful, you should see an event like the following: + +```bash +$ kubectl describe order example-com-2745722290-439160286 +... +Reason: +State: valid +URL: https://acme-v02.api.letsencrypt.org/acme/order/41123272/265506123 +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Created 72s cert-manager Created Challenge resource "example-com-2745722290-439160286-0" for domain "test1.example.com" + Normal Created 72s cert-manager Created Challenge resource "example-com-2745722290-439160286-1" for domain "test2.example.com" + Normal OrderValid 4s cert-manager Order completed successfully +``` + +You can see some additional information about the state of the [ACME authorization](https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.4) that needs to be validated as part of this order using the authorization URL from the status of the `Order`: + +```bash +$ kubectl get order -ojsonpath='{.status.authorizations[x].url}' +``` + +If the Order is not completing successfully, you can debug the challenges +for the Order by running `kubectl describe` on the `Challenge` resource which is described in the following steps. + +## 3. Troubleshooting Challenges + +In order to determine why an ACME Order is not being finished, we can debug +using the `Challenge` resources that cert-manager has created. + +In order to determine which `Challenge` is failing, you can run +`kubectl get challenges`: + + +```console +$ kubectl get challenges +... +NAME STATE DOMAIN REASON AGE +example-com-2745722290-4391602865-0 pending example.com Waiting for dns-01 challenge propagation 22s +``` + +This shows that the challenge has been presented using the DNS01 solver +successfully and now cert-manager is waiting for the 'self check' to pass. + +You can get more information about the challenge and it's lifecycle by using `kubectl describe`: + +```bash +$ kubectl describe challenge example-com-2745722290-4391602865-0 +... +Status: + Presented: true + Processing: true + Reason: Waiting for dns-01 challenge propagation + State: pending +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Started 19s cert-manager Challenge scheduled for processing + Normal Presented 16s cert-manager Presented challenge using dns-01 challenge mechanism +``` + +Progress about the state of each challenge will be recorded either as Events +or on the Challenge's `status` block (as shown above). + +In case of DNS01 you will find any errors from your DNS provider here. + +Both HTTP01 and DNS01 go through a "self-check" first before cert-manager presents the challenge to the ACME provider. +This is done not to overload the ACME provider with failed challenges due to DNS or loadbalancer propagations. +The status of this can be found in the Status block of the describe: +```console +$ kubectl describe challenge +[...] +Status: + Presented: true + Processing: true + Reason: Waiting for http-01 challenge propagation: failed to perform self check GET request 'http://example.com/.well-known/acme-challenge/_fgdLz0i3TFiZW4LBjuhjgd5nTOkaMBhxYmTY': Get "http://example.com/.well-known/acme-challenge/_fgdLz0i3TFiZW4LBjuhjgd5nTOkaMBhxYmTY: remote error: tls: handshake failure + State: pending +[...] +``` + +In this example our HTTP01 check fails due a network issue. +You will also see any errors coming from your DNS provider here. + +You can also see some additional information about the state of the [ACME authorization](https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.4) that the challenge should validate using the authorization URL on from the status of the `Challenge`: + +```bash +$ kubectl get challenge -ojsonpath='{.spec.authorizationURL}' +``` + +### HTTP01 troubleshooting +First of all check if you can see the challenge URL from the public internet, if this does not work check your Ingress and firewall configuration as well as the service and pod cert-manager created to solve the ACME challenge. +If this does work check if your cluster can see it too. It is important to test this from inside a Pod. If you get a connection error it is suggested to check the cluster's network configuration. +If you receive a `tls: handshake failure`, try setting the annotation `cert-manager.io/issue-temporary-certificate: "true"` on the Ingress or Certificate resource. This will issue a temporary self signed certificate for the ingress controller to use before the actual certificate is issued. +If you still are having issues, there may be an issue with your ingress controller handling multiple resources for the same hostname, in this case, the annotation `acme.cert-manager.io/http01-edit-in-place: "true"` is likely required. + +For example when using GKE with the Google Cloud Loadbalancer it is recommended to set: +``` +cert-manager.io/issue-temporary-certificate: "true" +acme.cert-manager.io/http01-edit-in-place: "true" +``` +This will allow the Google Cloud Loadbalancer to propagate a HTTPS endpoint correctly with a temporary certificate, the `http01-edit-in-place` part will prevent GKE from assigning a 2nd IP address for the challenge endpoint. + +#### Got 404 status code +If your challenge self-check fails with a 404 not found error. Make sure to check the following: + +* you can access the URL from the public internet +* the ACME solver pod is up and running +* use `kubectl describe ingress` to check the status of the HTTP01 solver ingress. (unless you use `acme.cert-manager.io/http01-edit-in-place`, then check the same ingress as your domain) + +### DNS01 troubleshooting +If you see no error events about your DNS provider you can check the following +Check if you can see the `_acme_challenge.domain` TXT DNS record from the public internet, or in your DNS provider's interface. +cert-manager will check if a DNS record has been propagated by querying the cluster's DNS solver. If you are able to see it from the public internet but not from inside the cluster you might want to change [the DNS server for self-check](../configuration/acme/dns01/README.md#setting-nameservers-for-dns01-self-check) as some cloud providers overwrite DNS internally. + +#### cert-manager identifies the wrong zone for your domain name +cert-manager by default uses SOA (Start of Authority) records to determine which zone name to use at your DNS provider. +Some DNS resolvers will filter this information, if this is the case cert-manager cannot determine the zone and it is advised to [change the DNS server for DNS01 self-checks](../configuration/acme/dns01/README.md#setting-nameservers-for-dns01-self-check). + +If you use `dnsmasq` as your DNS server, this may occur if you use the [`--filterwin2k` flag](http://www.thekelleys.org.uk/dnsmasq/docs/setup.html). +In [OpenWRT there is a `filterwin2k` configuration option](https://openwrt.org/docs/guide-user/base-system/dhcp#all_options). +And in [LuCI there is a "Filter useless" option](https://github.com/openwrt/luci/blob/15757dd5b18f9e00ba3c9b38af4d46702a31fe33/modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js#L217-L219). +By enabling this flag, `dnsmasq` drops all `SOA` records. + +## March 2020 Let's Encrypt CAA Rechecking Bug +Following the [announcement on March 4](https://community.letsencrypt.org/t/revoking-certain-certificates-on-march-4/114864) Let's Encrypt will be revoking a number of certificates due to a bug in the way they validate CAA records, we have created a tool to analyse your existing cert-manager managed certificates and compare their serial numbers to the publicised list of revoked certificates. +It's advised that all users of Let's Encrypt & cert-manager run a check using this tool to ensure they do not experience any invalid certificate errors in clusters. +You can find a copy of the checker tool here: https://github.com/jetstack/letsencrypt-caa-bug-checker. diff --git a/content/v1.15-docs/troubleshooting/webhook.md b/content/v1.15-docs/troubleshooting/webhook.md new file mode 100644 index 0000000000..2d5b33f8b2 --- /dev/null +++ b/content/v1.15-docs/troubleshooting/webhook.md @@ -0,0 +1,1086 @@ +--- +title: The Definitive Debugging Guide for the cert-manager Webhook Pod +description: 'This guide helps you debug communication issues between the Kubernetes API server and the cert-manager webhook Pod.' +--- + +> Last verified: 8 Sept 2022 + +The cert-manager webhook is a pod that runs as part of your cert-manager +installation. When applying a manifest with `kubectl`, the Kubernetes API server +calls the cert-manager webhook over TLS to validate your manifests. This guide +helps you debug communication issues between the Kubernetes API server and the +cert-manager webhook pod. + +The error messages listed in this page are encountered while installing or +upgrading cert-manager, or shortly after installing or upgrading cert-manager +when trying to create a Certificate, Issuer, or any other cert-manager custom +resource. + +In the below diagram, we show the common pattern when debugging an issue with +the cert-manager webhook: when creating a cert-manager custom resource, the API +server connects over TLS to the cert-manager webhook pod. The red cross +indicates that the API server fails talking to the webhook. + +Diagram that shows a kubectl command that aims to create an issuer resource, and an arrow towards the Kubernetes API server, and an arrow between the API server and the webhook that indicates that the API server tries to connect to the webhook. This last arrow is crossed in red. + +The rest of this document presents error messages you may encounter. + +## Error: `connect: connection refused` + +> This issue was reported in 4 GitHub issues ([#2736](https://github.com/jetstack/cert-manager/issues/2736 "Getting WebHook Connection Refused error when using Azure DevOps Pipelines"), [#3133](https://github.com/jetstack/cert-manager/issues/3133 "Failed calling webhook webhook.cert-manager.io: connect: connection refused"), [#3445](https://github.com/jetstack/cert-manager/issues/3445 "Connection refused for cert-manager-webhook service"), [#4425](https://github.com/cert-manager/cert-manager/issues/4425 "Webhook error")), was reported in 1 GitHub issue in an external project ([`aws-load-balancer-controller#1563`](https://github.com/kubernetes-sigs/aws-load-balancer-controller/issues/1563 "Internal error occurred: failed calling webhook webhook.cert-manager.io, no endpoints available")), on Stack Overflow ([`serverfault#1076563`](https://web.archive.org/web/20210903183221/https://serverfault.com/questions/1076563/creating-issuer-for-kubernetes-cert-manager-is-causing-404-and-500-error "Creating issuer for kubernetes cert-manager is causing 404 and 500 error")), and was mentioned in 13 Slack messages that can be listed with the search `in:#cert-manager in:#cert-manager-dev ":443: connect: connection refused"`. This error message can also be found in other projects that are building webhooks ([`kubewarden-controller#110`](https://github.com/kubewarden/kubewarden-controller/issues/110 "Investigate failure on webhooks not ready when installing cert-manager from helm chart: connection refused")). + +Shortly after installing or upgrading cert-manager, you may hit this error when +creating a Certificate, Issuer, or any other cert-manager custom resource. For +example, creating an Issuer resource with the following command: + +```sh +kubectl apply -f- < 10.96.20.99 (webhook pod) TCP 59466 → 443 [SYN] +10.96.20.99 (webhook pod) -> 192.168.1.43 (apiserver) TCP 443 → 59466 [RST, ACK] +``` + +The `RST` packet is sent by the Linux kernel when nothing is listening to the +requested port. The `RST` packet can also be returned by one of the TCP hops, +e.g., a firewall, as detailed in the Stack Overflow page [What can be the +reasons of connection refused errors?](https://stackoverflow.com/a/2333446/3808537) + +Note that firewalls usually don't return an `RST` packet; they usually drop the +`SYN` packet entirely, and you end up with the error message `i/o timeout` or +`context deadline exceeded`. If that is the case, continue your investigation +with the section [Error: `i/o timeout` (connectivity issue)](#io-timeout) and [Error: `context +deadline exceeded`](#context-deadline-exceeded) respectively. + +Let's eliminate the possible causes from the closest to the source of the TCP +connection (the API server) to its destination (the pod `cert-manager-webhook`). + +Let's imagine that the name `cert-manager-webhook.cert-manager.svc` was resolved +to 10.43.183.232. This is a cluster IP. The control plane node, in which the API +server process runs, uses its iptables to rewrite the IP destination using the +pod IP. That might be the first problem: sometimes, no pod IP is associated with +a given cluster IP because the kubelet doesn't fill in the Endpoint resource +with pod IPs as long as the readiness probe doesn't work. + +Let us first check whether it is a problem with the Endpoint resource: + +```sh +kubectl get endpoints -n cert-manager cert-manager-webhook +``` + +A valid output would look like this: + +```text +NAME ENDPOINTS AGE +cert-manager-webhook 10.244.0.2:10250 27d ✅ +``` + +If you have this valid output and have the `connect: connection refused`, then +the issue is deeper in the networking stack. We won't dig into this case, but +you might want to use `tcpdump` and Wireshark to see whether traffic properly +flows from the API server to the node's host namespace. The traffic from the +host namespace to the pod's namespace already works fine since the kubelet was +already able to reach the readiness endpoint. + +Common issues include firewall dropping traffic from the control plane to +workers; for example, the API server on GKE is only allowed to talk to worker +nodes (which is where the cert-manager webhook is running) over port +`10250`. In EKS, your security groups might deny traffic from your control +plane VPC towards your workers VPC over TCP `10250`. + +If you see ``, it indicates that the cert-manager webhook is properly +running but its readiness endpoint can't be reached: + +```text +NAME ENDPOINTS AGE +cert-manager-webhook 236d ❌ +``` + +To fix ``, you will have to check whether the cert-manager-webhook +deployment is healthy. The endpoints stays at `` while the +cert-manager-webhook isn't marked as `healthy`. + +```sh +kubectl get pod -n cert-manager -l app.kubernetes.io/name=webhook +``` + +You should see that the pod is `Running`, and that the number of containers that +are ready is `0/1`: + +```text +NAME READY STATUS RESTARTS AGE +cert-manager-76578c9687-24kmr 0/1 Running 7 (8h ago) 28d ❌ +``` + +We won't be detailing the case where you get `1/1` and `Running`, since it would +indicate an inconsistent state in Kubernetes. + +Continuing with `0/1`, that means the readiness endpoint isn't answering. When +that happens, no endpoint is created. The next step is to figure out why the +readiness endpoint isn't answering. Let us see which port the kubelet is using +when hitting the readiness endpoint: + +```sh +kubectl -n cert-manager get deploy cert-manager-webhook -oyaml | grep -A5 readiness +``` + +In our example, the port that the kubelet will try to hit is 6080: + +```yaml +readinessProbe: + failureThreshold: 3 + httpGet: + path: /healthz + port: 6080 # ✨ + scheme: HTTP +``` + +Now, let us port-forward to that port and see if `/healthz` works. In a shell +session, run: + +```sh +kubectl -n cert-manager port-forward deploy/cert-manager-webhook 6080 +``` + +In another shell session, run: + +```sh +curl -sS --dump-header - 127.0.0.1:6080/healthz +``` + +The happy output is: + +```http +HTTP/1.1 200 OK ✅ +Date: Tue, 07 Jun 2022 17:16:56 GMT +Content-Length: 0 +``` + +If the readiness endpoint doesn't work, you will see: + +```text +curl: (7) Failed to connect to 127.0.0.1 port 6080 after 0 ms: Connection refused ❌ +``` + +At this point, verify that the readiness endpoint is configured on that same +port. Let us see the logs to check that our webhook is listening on 6080 for its +readiness endpoint: + +```console +$ kubectl logs -n cert-manager -l app.kubernetes.io/name=webhook | head -10 +I0607 webhook.go:129] "msg"="using dynamic certificate generating using CA stored in Secret resource" +I0607 server.go:133] "msg"="listening for insecure healthz connections" "address"=":6081" ❌ +I0607 server.go:197] "msg"="listening for secure connections" "address"=":10250" +I0607 dynamic_source.go:267] "msg"="Updated serving TLS certificate" +... +``` + +In the above example, the issue was a misconfiguration of the readiness port. In +the webhook deployment, the argument `--healthz-port=6081` was mismatched with +the readiness configuration. + + +## Error: `i/o timeout` (connectivity issue) + +> This error message was reported 26 times on Slack. To list these messages, do a search with `in:#cert-manager in:#cert-manager-dev "443: i/o timeout"`. The error message was reported in 2 GitHub issues ([#2811](https://github.com/cert-manager/cert-manager/issues/2811 "i/o timeout from apiserver when connecting to webhook on k3s"), [#4073](https://github.com/cert-manager/cert-manager/issues/4073 "Internal error occurred: failed calling webhook")) + +```text +Error from server (InternalError): error when creating "STDIN": Internal error occurred: + failed calling webhook "webhook.cert-manager.io": failed to call webhook: + Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": + dial tcp 10.0.0.69:443: i/o timeout +``` + +When the API server tries to talk to the cert-manager webhook, the `SYN` packet +is never answered, and the connection times out. If we were to run tcpdump +inside the webhook's net namespace, we would see: + +```text +192.168.1.43 (apiserver) -> 10.0.0.69 (webhook pod) TCP 44772 → 443 [SYN] +192.168.1.43 (apiserver) -> 10.0.0.69 (webhook pod) TCP [TCP Retransmission] 44772 → 443 [SYN] +192.168.1.43 (apiserver) -> 10.0.0.69 (webhook pod) TCP [TCP Retransmission] 44772 → 443 [SYN] +192.168.1.43 (apiserver) -> 10.0.0.69 (webhook pod) TCP [TCP Retransmission] 44772 → 443 [SYN] +``` + +This issue is caused by the `SYN` packet being dropped somewhere. + + +### Cause 1: GKE Private Cluster + +The default Helm configuration should work with GKE private clusters, but +changing `securePort` might break it. + +For context, unlike public GKE clusters where the control plane can freely talk +to pods over any TCP port, the control plane in private GKE clusters can only +talk to the pods in worker nodes over TCP port `10250` and `443`. These two open +ports refer to the `containerPort` inside the pod, not the port called `port` in +the Service resource. + +For it to work, the `containerPort` inside the Deployment must match either +`10250` or `443`; `containerPort` is configured by the Helm value +`webhook.securePort`. By default, `webhook.securePort` is set to `10250`. + +To see if something is off with the `containerPort`, let us start looking at the +Service resource: + +```sh +kubectl get svc -n cert-manager cert-manager-webhook -oyaml +``` + +Looking at the output, we see that the `targetPort` is set to `"https"`: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: cert-manager-webhook +spec: + ports: + - name: https + port: 443 # ❌ This port is not the cause. + protocol: TCP + targetPort: "https" # 🌟 This port might be the cause. +``` + +The reason the above `port: 443` can't be the cause is because kube-proxy, which +also runs on the control plane node, translates the webhook's cluster IP to a +pod IP, and also translates the above `port: 443` to the value in +`containerPort`. + +To see how what is behind the target port `"https"`, we look at the +Deployment resource: + +```sh +kubectl get deploy -n cert-manager cert-manager-webhook -oyaml | grep -A3 ports: +``` + +The output shows that the `containerPort` is not set to `10250`, meaning that +a new firewall rule will have to be added in Google Cloud. + +```yaml + ports: + - containerPort: 12345 # 🌟 This port matches neither 10250 nor 443. + name: https + protocol: TCP +``` + +To recap, if the above `containerPort` is something other than `443` or `10250` and +you prefer not changing `containerPort` to `10250`, you will have to add a +new firewall rule. You can read the section [Adding a firewall rule in a +GKE private +cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/private-clusters#add_firewall_rules) +in the Google documentation. + +For context, the reason we did not default `securePort` to `443` is because +binding to `443` requires one additional Linux capability +(`NET_BIND_SERVICE`); on the other side, `10250` doesn't require any +additional capability. + +### Cause 2: EKS on a custom CNI + +If you are on EKS and you are using a custom CNI such as Weave or Calico, +the Kubernetes API server (which is in its own node) might not be able to +reach the webhook pod. This happens because the control plane cannot be +configured to run on a custom CNI on EKS, meaning that the CNIs cannot +enable connectivity between the API server and the pods running in the +worker nodes. + +Supposing that you are using Helm, the workaround is to add the following +value in your `values.yaml` file: + +```yaml +webhook: + hostNetwork: true + securePort: 10260 +``` + +Or if you are using Helm from the command-line, use the following flag: + +```sh +--set webhook.hostNetwork=true --set webhook.securePort=10260 +``` + +By setting `hostNetwork` to `true`, the webhook pod will be run in the +host's network namespace. By running in the host's network namespace, the +webhook pod becomes accessible over the node's IP, which means you will +work around the fact that kube-apiserver can't reach any pod IPs nor +cluster IPs. + +By setting `securePort` to `10260` instead of relying on the default value +(which is `10250`), you will prevent a conflict between the webhook and the +kubelet. The kubelet, which is an agent that runs on every Kubernetes +worker node and runs directly on the host, uses the port `10250` to +expose its internal API to kube-apiserver. + +To understand how `hostnetwork` and `securePort` interact, we have to look +at how the TCP connection is established. When the kube-apiserver process +tries to connect to the webhook pod, kube-proxy (which also runs on control +plane nodes, even without a CNI) kicks in and translates the webhook's +cluster IP to the webhook's host IP: + +```diagram + https://cert-manager-webhook.cert-manager.svc:443/validate + | + |Step 1: resolve to the cluster IP + v + https://10.43.103.211:443/validate + | + |Step 2: send TCP packet + v + src: 172.28.0.1:43021 + dst: 10.43.103.211:443 + | + |Step 3: kube-proxy rewrite (cluster IP to host IP) + v + src: 172.28.0.1:43021 + dst: 172.28.0.2:10260 + | + | control-plane node + | (host IP: 172.28.0.1) +------------|-------------------------------------------------- + | (host IP: 172.28.0.2) + v worker node + +-------------------+ + | webhook pod | + | listens on | + | 172.28.0.2:10260 | + +-------------------+ +``` + +The reason `10250` is used as the default `securePort` is because it works +around another limitation with GKE Private Clusters, as detailed in the +above section [GKE Private Cluster](#gke-private-cluster). + +### Cause 3: Network Policies, Calico + +Assuming that you are using the Helm chart and that you are using the +default value of `webhook.securePort` (which is `10250`), and that you are +using a network policy controller such as Calico, check that there exists a +policy allowing traffic from the API server to the webhook pod over TCP +port `10250`. + +### Cause 4: EKS and Security Groups + +Assuming that you are using the Helm chart and that you are using the +default value of `webhook.securePort` (which is `10250`), you might want to +check that your AWS Security Groups allow TCP traffic over `10250` from the +control plane's VPC to the workers VPC. + +### Other causes + +If none of the above causes apply, you will need to figure out why the +webhook is unreachable. + +To debug reachability issues (i.e., packets being dropped), we advise to +use `tcpdump` along with Wireshark at every TCP hop. You can follow the +article [Debugging Kubernetes Networking: my `kube-dns` is not +working!](https://maelvls.dev/debugging-kubernetes-networking/) to learn +how to use `tcpdump` with Wireshark to debug networking issues. + +## Error: `x509: certificate is valid for xxx.internal, not cert-manager-webhook.cert-manager.svc` (EKS with Fargate pods) + +```text +Internal error occurred: failed calling webhook "webhook.cert-manager.io": + Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: + x509: certificate is valid for ip-192-168-xxx-xxx.xxx.compute.internal, + not cert-manager-webhook.cert-manager.svc +``` + +> This issue was first reported in +> [#3237](https://github.com/cert-manager/cert-manager/issues/3237 "Can't +> create an issuer when cert-manager runs on EKS in Fargate pods (AWS)"). + +This is probably because you are running on EKS with Fargate enabled. +Fargate creates a microVM per pod, and the VM's kernel is used to run the +container in its own namespace. The problem is that each microVM gets its +own kubelet. As for any Kubernetes node, the VM's port `10250` is listened to +by a kubelet process. And `10250` is also the port that the cert-manager +webhook listens on. + +But that's not a problem: the kubelet process and the cert-manager webhook +process are running in two separate network namespaces, and ports don't +clash. That's the case both in traditional Kubernetes nodes, as well as +inside a Fargate microVM. + +The problem arises when the API server tries hitting the Fargate pod: the +microVM's host net namespace is configured to port-forward every possible port +for maximum compatibility with traditional pods, as demonstrated in the Stack +Overflow page [EKS Fargate connect to local kubelet][66445207]. But the port +`10250` is already used by the microVM's kubelet, so anything hitting this port +won't be port-forwarded and will hit the kubelet instead. + +[66445207]: https://stackoverflow.com/questions/66445207 "EKS Fargate connect to local kubelet" + +To sum up, the cert-manager webhook looks healthy and is able to listen to port +`10250` as per its logs, but the microVM's host does not port-forward `10250` to the +webhook's net namespace. That's the reason you see a message about an unexpected +domain showing up when doing the TLS handshake: although the cert-manager +webhook is properly running, the kubelet is the one responding to the API +server. + +This is a limitation of Fargate's microVMs: the IP of the pod and the IP of the +node are the same. It gives you the same experience as traditional pods, but it +poses networking challenges. + +To fix the issue, the trick is to change the port the cert-manager webhook is +listening on. Using Helm, we can use the parameter `webhook.securePort`: + +```sh +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version [[VAR::cert_manager_latest_version]] \ + --set webhook.securePort=10260 +``` + +## Error: `service "cert-managercert-manager-webhook" not found` + +```text +Error from server (InternalError): error when creating "test-resources.yaml": Internal error occurred: + failed calling webhook "webhook.cert-manager.io": failed to call webhook: + Post "https://cert-managercert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": + service "cert-managercert-manager-webhook" not found +``` + +> This error was reported in 2 GitHub issues ([#3195](https://github.com/jetstack/cert-manager/issues/3195 "service cert-manager-webhook not found"), +> [#4999](https://github.com/cert-manager/cert-manager/issues/4999 "Verification on 1.7.2 fails (Kubectl apply), service cert-manager-webhook not found")). + +We do not know the cause of this error, please comment on one of the GitHub +issues above if you happen to come across it. + +## Error: `no endpoints available for service "cert-manager-webhook"` (OVHCloud) + +```text +Error: INSTALLATION FAILED: Internal error occurred: + failed calling webhook "webhook.cert-manager.io": + Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: + no endpoints available for service "cert-manager-webhook" +``` + +> This issue was first reported once in Slack +> ([1](https://kubernetes.slack.com/archives/C4NV3DWUC/p1634118489064400?thread_ts=1592676867.472700&cid=C4NV3DWUC)). + +This error is rare and was only seen in OVHcloud managed Kubernetes clusters, +where the etcd resource quota is quite low. etcd is the database where your +Kubernetes resources (such as pods and deployments) are stored. OVHCloud limits +the disk space used by your resources in etcd. When the limit is reached, the +whole cluster starts behaving erratically and one symptom is that Endpoint +resources aren't created by the kubelet. + +To verify that it is in fact a problem of quota, you should be able to see the +following messages in your kube-apiserver logs: + +```sh +rpc error: code = Unknown desc = ETCD storage quota exceeded +rpc error: code = Unknown desc = quota computation: etcdserver: not capable +rpc error: code = Unknown desc = The OVHcloud storage quota has been reached +``` + +The workaround is to remove some resources such as CertificateRequest resources +to get under the limit, as explained in OVHCloud's [ETCD Quotas error, +troubleshooting](https://docs.ovh.com/gb/en/kubernetes/etcd-quota-error/) page. + +## Error: `x509: certificate has expired or is not yet valid` + +> This error message was reported once in Slack +> ([1](https://kubernetes.slack.com/archives/C4NV3DWUC/p1618579222346800)). + +When using `kubectl apply`: + +```text +Internal error occurred: failed calling webhook "webhook.cert-manager.io": + Post https://kubernetes.default.svc:443/apis/webhook.cert-manager.io/v1beta1/mutations?timeout=30s: + x509: certificate has expired or is not yet valid +``` + +> This error message was reported once in Slack +([1](https://kubernetes.slack.com/archives/C4NV3DWUC/p1618579222346800)). + +Please answer to the above Slack message since we are still unsure as to what +may cause this issue; to get access to the Kubernetes Slack, visit +[https://slack.k8s.io/](https://slack.k8s.io/). + +## Error: `net/http: request canceled while waiting for connection` + +```text +Error from server (InternalError): error when creating "STDIN": + Internal error occurred: failed calling webhook "webhook.cert-manager.io": + Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: + net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) +``` + +> This error message was reported once in Slack +([1](https://kubernetes.slack.com/archives/C4NV3DWUC/p1632849763397100)). + + +## Error: `context deadline exceeded` + +> This error message was reported in GitHub issues ([2319](https://github.com/cert-manager/cert-manager/issues/2319 "Documenting context deadline exceeded errors relating to the webhook, on bare metal"), [2706](https://github.com/cert-manager/cert-manager/issues/2706 "") [5189](https://github.com/cert-manager/cert-manager/issues/5189 "Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s: context deadline exceeded"), [5004](https://github.com/cert-manager/cert-manager/issues/5004 "After installing cert-manager using kubectl, cmctl check api fails with https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s: context deadline exceeded")), and once [on Stack Overflow](https://stackoverflow.com/questions/72059332/how-can-i-fix-failed-calling-webhook-webhook-cert-manager-io). + +This error appears with cert-manager 0.12 and above when trying to apply an +Issuer or any other cert-manager custom resource after having installed or +upgraded cert-manager: + +```text +Error from server (InternalError): error when creating "STDIN": + Internal error occurred: failed calling webhook "webhook.cert-manager.io": + Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: + context deadline exceeded +``` + +> ℹ️ In older releases of cert-manager (0.11 and below), the webhook relied on +> the [APIService +> mechanism](https://kubernetes.io/docs/tasks/extend-kubernetes/setup-extension-api-server/), +> and the message looked a bit different but the cause was the same: +> +> ```text +> Error from server (InternalError): error when creating "STDIN": +> Internal error occurred: failed calling webhook "webhook.certmanager.k8s.io": +> Post https://kubernetes.default.svc:443/apis/webhook.certmanager.k8s.io/v1beta1/mutations?timeout=30s: +> context deadline exceeded +> ``` + +> ℹ️ The message `context deadline exceeded` also appears when using `cmctl +> check api`. The cause is identical, you can continue reading this section to +> debug it. +> +> ```text +> Not ready: Internal error occurred: failed calling webhook "webhook.cert-manager.io": failed to call webhook: +> Post "https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=10s": +> context deadline exceeded +> ``` + +The trouble with the message `context deadline exceeded` is that it obfuscates +the part of the HTTP connection that timed out. When this message appears, we +can't tell which part of the HTTP interaction timed out. It might be the DNS +resolution, the TCP handshake, the TLS handshake, sending the HTTP request or +receiving the HTTP response. + +> ℹ️ For context, the query parameter `?timeout=30s` that you can see in the +> above error messages is a timeout that the API server decides when calling the +> webhook. It is often set to 10 or 30 seconds. + + +The first step to debug this issue is to make sure the `timeoutSeconds` field on +the cert-manager mutating and validating webhook configurations are +configured to 30 seconds (the maximum value). By default, it is set to 10 +seconds, meaning that `context deadline exceeded` will potentially hide the +other timeout messages. To check the value of the `timeoutSeconds` field, run: + +```console +$ kubectl get mutatingwebhookconfigurations,validatingwebhookconfigurations cert-manager-webhook \ + -ojsonpath='{.items[*].webhooks[*].timeoutSeconds}' +10 10 +``` + +This means that both webhooks are configured with a context timeout of 10 +seconds. To configure them to 30 seconds, run: + +```bash +kubectl patch mutatingwebhookconfigurations,validatingwebhookconfigurations cert-manager-webhook \ + --type=json -p '[{"op": "replace", "path": "/webhooks/0/timeoutSeconds", "value": 30}]' +``` + +The following diagram shows what are the three errors that may be hidden behind +the all-catching `context deadline exceeded` error message, represented by the +outer box, that is thrown after 30 seconds: + + + +```diagram + context deadline exceeded + | + 30 seconds | + timeout v ++-------------------------------------------------------------------------+ +| | +| i/o timeout | +| | net/http: TLS handshake timeout | +| 10 seconds | | | +| timeout v | | +|------------+ 30 seconds | net/http: request canceled | +|TCP | timeout v while awaiting headers | +|handshake +---------------------+ | | +|------------| TLS | | | +| | handshake +------------+ 10 seconds | | +| +---------------------| sending | timeout v | +| | request +------------+ | +| +------------|receiving |------+ | +| |resp. header| recv.| | +| +------------+ resp.| | +| | body +-----+ +| +------|other| +| |logic| +| +-----+ ++-------------------------------------------------------------------------+ +``` + +In the rest of the section, we will be trying to trigger one of the three "more +specific" errors: + +- `i/o timeout` is the TCP handshake timeout and comes from + [`DialTimeout`](https://pkg.go.dev/net#DialTimeout) in the Kubernetes + apiserver. The name resolution may be the cause, but usually, this message + appears after the API server sent the `SYN` packet and waited for 10 seconds + for the `SYN-ACK` packet to be received from the cert-manager webhook. +- `net/http: request canceled while waiting for connection (Client.Timeout + exceeded while awaiting headers)` is the HTTP response timeout and comes from + [here](https://github.com/kubernetes/kubernetes/blob/abba1492f/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go#L96-L101) + and is configured to [30 + seconds](https://github.com/kubernetes/kubernetes/blob/abba1492f/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go#L36-L38). + The Kubernetes API server already sent the HTTP request is is waiting for the + HTTP response headers (e.g., `HTTP/1.1 200 OK`). +- `net/http: TLS handshake timeout` is when the TCP handshake is done, and the + Kubernetes API server sent the initial TLS handshake packet (`ClientHello`) + and waited for 10 seconds for the cert-manager webhook to answer with the + `ServerHello` packet. + +We can sort these three messages in two categories: either it is a connectivity +issue (`SYN` is dropped), or it is a webhook issue (i.e., the TLS certificate is +wrong, or the webhook is not returning any HTTP response): + +| Timeout message | Category | +|-----------------------------------------------------|--------------------| +| `i/o timeout` | connectivity issue | +| `net/http: TLS handshake timeout` | webhook-side issue | +| `net/http: request canceled while awaiting headers` | webhook-side issue | + +The first step is to rule out a webhook-side issue. In your shell session, run +the following: + +```sh +kubectl -n cert-manager port-forward deploy/cert-manager-webhook 10250 +``` + +In another shell session, check that you can reach the webhook: + +```sh +curl -vsS --resolve cert-manager-webhook.cert-manager.svc:10250:127.0.0.1 \ + --service-name cert-manager-webhook-ca \ + --cacert <(kubectl -n cert-manager get secret cert-manager-webhook-ca -ojsonpath='{.data.ca\.crt}' | base64 -d) \ + https://cert-manager-webhook.cert-manager.svc:10250/validate 2>&1 -d@- <<'EOF' | sed '/^* /d; /bytes data]$/d; s/> //; s/< //' +{"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1","request":{"requestKind":{"group":"cert-manager.io","version":"v1","kind":"Certificate"},"requestResource":{"group":"cert-manager.io","version":"v1","resource":"certificates"},"name":"foo","namespace":"default","operation":"CREATE","object":{"apiVersion":"cert-manager.io/v1","kind":"Certificate","spec":{"dnsNames":["foo"],"issuerRef":{"group":"cert-manager.io","kind":"Issuer","name":"letsencrypt"},"secretName":"foo","usages":["digital signature"]}}}} +EOF +``` + +The happy output looks like this: + +```http +POST /validate HTTP/1.1 +Host: cert-manager-webhook.cert-manager.svc:10250 +User-Agent: curl/7.83.0 +Accept: */* +Content-Length: 1299 +Content-Type: application/x-www-form-urlencoded + +HTTP/1.1 200 OK +Date: Wed, 08 Jun 2022 14:52:21 GMT +Content-Length: 2029 +Content-Type: text/plain; charset=utf-8 + +... +"response": { + "uid": "", + "allowed": true +} +``` + +If the response shows `200 OK`, we can rule out a webhook-side issue. Since the +initial error message was `context deadline exceeded` and not an apiserver-side +issue such as `x509: certificate signed by unknown authority` or `x509: +certificate has expired or is not yet valid`, we can conclude that the problem +is a connectivity issue: the Kubernetes API server isn't able to establish a TCP +connection to the cert-manager webhook. Please follow the instructions in the +section [Error: `i/o timeout` (connectivity issue)](#io-timeout) above to +continue debugging. + +## Error: `net/http: TLS handshake timeout` + +> This error message was reported in 1 GitHub issue ([#2602](https://github.com/cert-manager/cert-manager/issues/2602 "Internal error occurred: failed calling webhook webhook.cert-manager.io: Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: net/http: TLS handshake timeout")). + +```text +Error from server (InternalError): error when creating "STDIN": + Internal error occurred: failed calling webhook "webhook.cert-manager.io": + Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: + net/http: TLS handshake timeout +``` + +Looking at the [above diagram](#diagram), this error message indicates that the +Kubernetes API server successfully established a TCP connection to the pod IP +associated with the cert-manager webhook. The TLS handshake timeout means that +the cert-manager webhook process isn't the one ending the TCP connection: there +is some HTTP proxy in between that is probably waiting for a plain HTTP request +instead a `ClientHello` packet. + +We do not know the cause of this error. Please comment on the above GitHub +issue if you notice this error. + +## Error: `HTTP probe failed with statuscode: 500` + +> This error message was reported in 2 GitHub issue ([#3185](https://github.com/cert-manager/cert-manager/issues/3185 "kubectl install cert-manager: Readiness probe failed: HTTP probe failed with statuscode: 500"), [#4557](https://github.com/cert-manager/cert-manager/issues/4557 "kubectl install cert-manager: Readiness probe failed: HTTP probe failed with statuscode: 500")). + +The error message is visible as an event on the cert-manager webhook: + +```text +Warning Unhealthy (x13 over 15s) kubelet, node83 + Readiness probe failed: HTTP probe failed with statuscode: 500 +``` + +We do not know the cause of this error. Please comment on the above GitHub +issue if you notice this error. + +## Error: `Service Unavailable` + +> This error was reported in 1 GitHub issue ([#4281](https://github.com/cert-manager/cert-manager/issues/4281 "Can't deploy Issuer, Service Unavailable")) + +```text +Error from server (InternalError): error when creating "STDIN": Internal error occurred: + failed calling webhook "webhook.cert-manager.io": + Post "https://my-cert-manager-webhook.default.svc:443/mutate?timeout=10s": + Service Unavailable +``` + +The above message appears in Kubernetes clusters using the Weave CNI. + +We do not know the cause of this error. Please comment on the above GitHub +issue if you notice this error. + +## Error: `failed calling admission webhook: the server is currently unable to handle the request` + +> This issue was reported in 4 GitHub issues ([1369](https://github.com/cert-manager/cert-manager/issues/1369 "the server is currently unable to handle the request"), [1425](https://github.com/cert-manager/cert-manager/issues/1425 "Verifying Install: failed calling admission webhook (Azure, GKE private cluster)") [3542](https://github.com/cert-manager/cert-manager/issues/3542 "SSL Certificate Manager has got expired, we need to renew SSL certificate in existing ClusterIssuer Kubernetes Service (AKS)"), [4852](https://github.com/cert-manager/cert-manager/issues/4852 "error: unable to retrieve the complete list of server APIs: webhook.cert-manager.io/v1beta1: the server is currently unable to handle the request (AKS)")) + +```text +Error from server (InternalError): error when creating "test-resources.yaml": Internal error occurred: + failed calling admission webhook "issuers.admission.certmanager.k8s.io": + the server is currently unable to handle the request +``` + +We do not know the cause of this error. Please comment in one of the above +GitHub issues if you are able to reproduce this error. + +## Error: `x509: certificate signed by unknown authority` + +> Reported in GitHub issues +> ([2602](https://github.com/cert-manager/cert-manager/issues/2602#issuecomment-606474055 "x509: certificate signed by unknown authority")) + +When installing or upgrading cert-manager and using a namespace that is not +`cert-manager`: + +```text +Error: UPGRADE FAILED: release core-l7 failed, and has been rolled back due to atomic being set: + failed to create resource: conversion webhook for cert-manager.io/v1alpha3, Kind=ClusterIssuer failed: + Post https://cert-manager-webhook.core-l7.svc:443/convert?timeout=30s: + x509: certificate signed by unknown authority +``` + +A very similar error message may show when creating an Issuer or any other +cert-manager custom resource: + +```text +Internal error occurred: failed calling webhook "webhook.cert-manager.io": + Post https://cert-manager-webhook.cert-manager.svc:443/mutate?timeout=30s: + x509: certificate signed by unknown authority` +``` + +With `cmctl install` and `cmctl check api`, you might see the following error +message: + +```text +2022/06/06 15:36:30 Not ready: the cert-manager webhook CA bundle is not injected yet + (Internal error occurred: conversion webhook for cert-manager.io/v1alpha2, Kind=Certificate failed: + Post "https://-cert-manager-webhook.cert-manager.svc:443/convert?timeout=30s": + x509: certificate signed by unknown authority) +``` + +If you are using cert-manager 0.14 and below with Helm, and that you are +installing in a namespace different from `cert-manager`, the CRD manifest had +the namespace name `cert-manager` hardcoded. You can see the hardcoded namespace +in the following annotation: + +```sh +kubectl get crd issuers.cert-manager.io -oyaml | grep inject +``` + +You will see the following: + +```yaml +cert-manager.io/inject-ca-from-secret: cert-manager/cert-manager-webhook-ca +# ^^^^^^^^^^^^ +# hardcoded +``` + +> **Note 1:** this bug in the cert-manager Helm chart was [was +fixed](https://github.com/cert-manager/cert-manager/commit/f33beefc) in +cert-manager 0.15. +> +> **Note 2:** since cert-manager 1.6, this annotation is [no longer +> used](https://github.com/cert-manager/cert-manager/pull/4841) on the +> cert-manager CRDs since conversion is no longer needed. + +The solution, if you are still using cert-manager 0.14 or below, is to render +the manifest using `helm template`, then edit the annotation to use the correct +namespace, and then use `kubectl apply` to install cert-manager. + +If you are using cert-manager 1.6 and below, the issue might be due to the +cainjector being stuck trying to inject the self-signed certificate that the +cert-manager webhook created and stored in the Secret resource +`cert-manager-webhook-ca` into the `spec.caBundle` field of the cert-manager +CRDs. The first step is to check whether the cainjector is running with no +problem: + +```console +$ kubectl -n cert-manager get pods -l app.kubernetes.io/name=cainjector +NAME READY STATUS RESTARTS AGE +cert-manager-cainjector-5c55bb7cb4-6z4cf 1/1 Running 11 (31h ago) 28d +``` + +Looking at the logs, you will be able to tell if the leader election worked. It +can take up to one minute for the leader election work to complete. + +```console +I0608 start.go:126] "starting" version="v1.8.0" revision="e466a521bc5455def8c224599c6edcd37e86410c" +I0608 leaderelection.go:248] attempting to acquire leader lease kube-system/cert-manager-cainjector-leader-election... +I0608 leaderelection.go:258] successfully acquired lease kube-system/cert-manager-cainjector-leader-election +I0608 controller.go:186] cert-manager/secret/customresourcedefinition/controller/controller-for-secret-customresourcedefinition "msg"="Starting Controller" +I0608 controller.go:186] cert-manager/certificate/customresourcedefinition/controller/controller-for-certificate-customresourcedefinition "msg"="Starting Controller" +I0608 controller.go:220] cert-manager/secret/customresourcedefinition/controller/controller-for-secret-customresourcedefinition "msg"="Starting workers" "worker count"=1 +I0608 controller.go:220] cert-manager/certificate/customresourcedefinition/controller/controller-for-certificate-customresourcedefinition "msg"="Starting workers" "worker count"=1 +``` + +The happy output contains lines like this: + +```console +I0608 sources.go:184] cert-manager/secret/customresourcedefinition/generic-inject-reconciler + "msg"="Extracting CA from Secret resource" "resource_name"="issuers.cert-manager.io" "secret"="cert-manager/cert-manager-webhook-ca" +I0608 controller.go:178] cert-manager/secret/customresourcedefinition/generic-inject-reconciler + "msg"="updated object" "resource_name"="issuers.cert-manager.io" +``` + +Now, look for any message that indicates that the Secret resource that the +cert-manager webhook created can't be loaded. The two error messages that might +show up are: + +```text +E0608 sources.go:201] cert-manager/secret/customresourcedefinition/generic-inject-reconciler + "msg"="unable to fetch associated secret" "error"="Secret \"cert-manager-webhook-caq\" not found" +``` + +The following message indicates that the given CRD has been skipped because the +annotation is missing. You can ignore these messages: + +```text +I0608 controller.go:156] cert-manager/secret/customresourcedefinition/generic-inject-reconciler + "msg"="failed to determine ca data source for injectable" "resource_name"="challenges.acme.cert-manager.io" +``` + +If nothing seems wrong with the cainjector logs, you will want to check that the +`spec.caBundle` field in the validation, mutation, and conversion configurations +are correct. The Kubernetes API server uses the contents of that field to trust +the cert-manager webhook. The `caBundle` contains the self-signed CA created by +the cert-manager webhook when it started. + +```console +$ kubectl get validatingwebhookconfigurations cert-manager-webhook -ojson | jq '.webhooks[].clientConfig' +{ + "caBundle": "LS0tLS1...LS0tLS0K", + "service": { + "name": "cert-manager-webhook", + "namespace": "cert-manager", + "path": "/validate", + "port": 443 + } +} +``` + +```console +$ kubectl get mutatingwebhookconfigurations cert-manager-webhook -ojson | jq '.webhooks[].clientConfig' +{ + "caBundle": "LS0tLS1...RFLS0tLS0K", + "service": { + "name": "cert-manager-webhook", + "namespace": "cert-manager", + "path": "/validate", + "port": 443 + } +} +``` + +Let us see the contents of the `caBundle`: + +```console +$ kubectl get mutatingwebhookconfigurations cert-manager-webhook -ojson \ + | jq '.webhooks[].clientConfig.caBundle' -r | base64 -d \ + | openssl x509 -noout -text -in - + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + ee:8f:4f:c8:55:7b:16:76:d8:6a:a2:e5:94:bc:7c:6b + Signature Algorithm: ecdsa-with-SHA384 + Issuer: CN = cert-manager-webhook-ca + Validity + Not Before: May 10 16:13:37 2022 GMT + Not After : May 10 16:13:37 2023 GMT + Subject: CN = cert-manager-webhook-ca +``` + +Let us check that the contents of `caBundle` works for connecting to the +webhook: + +```console +$ kubectl -n cert-manager get secret cert-manager-webhook-ca -ojsonpath='{.data.ca\.crt}' \ + | base64 -d | openssl x509 -noout -text -in - + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + ee:8f:4f:c8:55:7b:16:76:d8:6a:a2:e5:94:bc:7c:6b + Signature Algorithm: ecdsa-with-SHA384 + Issuer: CN = cert-manager-webhook-ca + Validity + Not Before: May 10 16:13:37 2022 GMT + Not After : May 10 16:13:37 2023 GMT + Subject: CN = cert-manager-webhook-ca +``` + +Our final test is to try to connect to the webhook using this trust bundle. Let +us port-forward to the webhook pod: + +```sh +kubectl -n cert-manager port-forward deploy/cert-manager-webhook 10250 +``` + +In another shell session, send a `/validate` HTTP request with the following +command: + +```sh +curl -vsS --resolve cert-manager-webhook.cert-manager.svc:10250:127.0.0.1 \ + --service-name cert-manager-webhook-ca \ + --cacert <(kubectl get validatingwebhookconfigurations cert-manager-webhook -ojson | jq '.webhooks[].clientConfig.caBundle' -r | base64 -d) \ + https://cert-manager-webhook.cert-manager.svc:10250/validate 2>&1 -d@- <<'EOF' | sed '/^* /d; /bytes data]$/d; s/> //; s/< //' +{"kind":"AdmissionReview","apiVersion":"admission.k8s.io/v1","request":{"requestKind":{"group":"cert-manager.io","version":"v1","kind":"Certificate"},"requestResource":{"group":"cert-manager.io","version":"v1","resource":"certificates"},"name":"foo","namespace":"default","operation":"CREATE","object":{"apiVersion":"cert-manager.io/v1","kind":"Certificate","spec":{"dnsNames":["foo"],"issuerRef":{"group":"cert-manager.io","kind":"Issuer","name":"letsencrypt"},"secretName":"foo","usages":["digital signature"]}}}} +EOF +``` + +You should see a successful HTTP request and response: + +```http +POST /validate HTTP/1.1 +Host: cert-manager-webhook.cert-manager.svc:10250 +User-Agent: curl/7.83.0 +Accept: */* +Content-Length: 1299 +Content-Type: application/x-www-form-urlencoded + +HTTP/1.1 200 OK +Date: Wed, 08 Jun 2022 16:20:45 GMT +Content-Length: 2029 +Content-Type: text/plain; charset=utf-8 + +... +``` + +## Error: `cluster scoped resource "mutatingwebhookconfigurations/" is managed and access is denied` + +> This message was reported in GitHub issue +> [3717](https://github.com/cert-manager/cert-manager/issues/3717 "Cannot +> install on GKE autopilot cluster due to mutatingwebhookconfigurations access +> denied"). + +While installing cert-manager on GKE Autopilot, you will see the following +message: + +```text +Error: rendered manifests contain a resource that already exists. Unable to continue with install: + could not get information about the resource: + mutatingwebhookconfigurations.admissionregistration.k8s.io "cert-manager-webhook" is forbidden: + User "XXXX" cannot get resource "mutatingwebhookconfigurations" in API group "admissionregistration.k8s.io" at the cluster scope: + GKEAutopilot authz: cluster scoped resource "mutatingwebhookconfigurations/" is managed and access is denied +``` + +This error message will appear when using Kubernetes 1.20 and below with GKE +Autopilot. It is due to a [restriction on mutating admission webhooks in GKE +Autopilot](https://github.com/cert-manager/cert-manager/issues/3717). + +As of October 2021, the "rapid" Autopilot release channel has rolled out version +1.21 for Kubernetes masters. Installation via the Helm chart may end in an error +message but cert-manager is reported to be working by some users. Feedback and +PRs are welcome. + +## Error: `the namespace "kube-system" is managed and the request's verb "create" is denied` + +When installing cert-manager on GKE Autopilot with Helm, you will see the +following error message: + +```text +Not ready: the cert-manager webhook CA bundle is not injected yet +``` + +After this failure, you should still see the three pods happily running: + +```console +$ kubectl get pods -n cert-manager +NAME READY STATUS RESTARTS AGE +cert-manager-76578c9687-24kmr 1/1 Running 0 47m +cert-manager-cainjector-b7d47f746-4799n 1/1 Running 0 47m +cert-manager-webhook-7f788c5b6-mspnt 1/1 Running 0 47m +``` + +But looking at either of the logs, you will see the following error message: + +```text +E0425 leaderelection.go:334] error initially creating leader election record: + leases.coordination.k8s.io is forbidden: User "system:serviceaccount:cert-manager:cert-manager-webhook" + cannot create resource "leases" in API group "coordination.k8s.io" in the namespace "kube-system": + GKEAutopilot authz: the namespace "kube-system" is managed and the request's verb "create" is denied +``` + +That is due to a limitation of GKE Autopilot. It is not possible to create +resources in the `kube-system` namespace, and cert-manager uses the well-known +`kube-system` to manage the leader election. To get around the limitation, you +can tell Helm to use a different namespace for the leader election: + +```sh +helm install cert-manager jetstack/cert-manager --version 1.8.0 \ + --namespace cert-manager --create-namespace \ + --set global.leaderElection.namespace=cert-manager +``` diff --git a/content/v1.15-docs/trust/README.md b/content/v1.15-docs/trust/README.md new file mode 100644 index 0000000000..13a6678307 --- /dev/null +++ b/content/v1.15-docs/trust/README.md @@ -0,0 +1,29 @@ +--- +title: Trusting certificates +description: "Managing client trust stores" +--- + +
          + +When configuring a client to connect to a TLS server with a serving certificate that is signed by a private CA, +you will need to provide the client with the CA certificate in order for it to verify the server. +`ca.crt` will likely contain the certificate you need to trust, +but __do not mount the same `Secret` as the server__ to access `ca.crt`. +This is because: + +1. That `Secret` also contains the private key of the server, which should only be accessible to the server. + You should use RBAC to ensure that the `Secret` containing the serving certificate and private key are only accessible to Pods that need it. +2. Rotating CA certificates safely relies on being able to have both the old and new CA certificates trusted at the same time. See [the FAQ](../faq/README.md#chain-cacrt) for more details. + +
          + +When configuring the client you should independently choose and fetch the CA certificates that you want to trust. +Download the CA out of band and store it in a `Secret` or `ConfigMap` separate from the `Secret` containing the server's private key and certificate. + +[trust-manager](trust-manager) can be used to manage these certificates and automatically distribute them to multiple namespaces. + +This ensures that if the material in the `Secret` containing the server key and certificate is tampered with, +the client will fail to connect to the compromised server. + +The same concept also applies when configuring a server for mutually-authenticated TLS; +don't give the server access to Secret containing the client certificate and private key. diff --git a/content/v1.15-docs/trust/trust-manager/README.md b/content/v1.15-docs/trust/trust-manager/README.md new file mode 100644 index 0000000000..68d1ebea58 --- /dev/null +++ b/content/v1.15-docs/trust/trust-manager/README.md @@ -0,0 +1,404 @@ +--- +title: trust-manager +description: 'Distributing Trust Bundles in Kubernetes' +--- + +trust-manager is the easiest way to manage trust bundles in Kubernetes and OpenShift clusters. + +It orchestrates bundles of trusted X.509 certificates which are primarily used for validating +certificates during a TLS handshake but can be used in other situations, too. + +## Overview + +trust-manager is a small Kubernetes operator which aims to help reduce the overhead of managing +TLS trust bundles in your clusters. + +It adds the `Bundle` custom Kubernetes resource (CRD) which can read input from various sources +and combine the resultant certificates into a bundle ready to be used by your applications. + +trust-manager ensures that it's both quick and easy to keep your trusted certificates up-to-date +and enables cluster administrators to easily automate providing a secure bundle without having +to worry about rebuilding containers to update trust stores. + +It's designed to complement cert-manager and works well when consuming CA certificates from a +cert-manager `Issuer` or `ClusterIssuer` but can be used entirely independently of cert-manager +if needed. + +## Installation + +See the [installation guide](./installation.md) for instructions on how to +install trust-manager. + +## Usage + +trust-manager is intentionally simple, adding just one new Kubernetes `CustomResourceDefintion`: `Bundle`. + +A `Bundle` represents a set of X.509 certificates that should be distributed across a cluster. + +All `Bundle`s are cluster scoped. + +`Bundle`s comprise a list of `sources` from which trust-manager will assemble the final bundle, along with +a `target` describing how and where the resulting bundle will be written. + +An example `Bundle` might look like this: + +```yaml +apiVersion: trust.cert-manager.io/v1alpha1 +kind: Bundle +metadata: + name: my-org.com # The bundle name will also be used for the target +spec: + sources: + # Include a bundle of publicly trusted certificates which can be + # used to validate most TLS certificates on the internet, such as + # those issued by Let's Encrypt, Google, Amazon and others. + - useDefaultCAs: true + + # A Secret in the "trust" namespace; see "Trust Namespace" below for further details + - secret: + name: "my-db-tls" + key: "ca.crt" + + # Here is another Secret source, but this time using a label selector instead of a Secret's name. + - secret: + selector: + matchLabels: + fruit: apple + key: "ca.crt" + + # A ConfigMap in the "trust" namespace; see "Trust Namespace" below for further details + - configMap: + name: "my-org.net" + key: "root-certs.pem" + + # Here is another ConfigMap source, but this time using a label selector instead of a ConfigMap's name. + - configMap: + selector: + matchLabels: + fruit: apple + key: "ca.crt" + + # A manually specified string + - inLine: | + -----BEGIN CERTIFICATE----- + MIIC5zCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwprdWJl + .... + 0V3NCaQrXoh+3xrXgX/vMdijYLUSo/YPEWmo + -----END CERTIFICATE----- + target: + # Sync the bundle to a ConfigMap called `my-org.com` in every namespace which + # has the label "linkerd.io/inject=enabled" + # All ConfigMaps will include a PEM-formatted bundle, here named "root-certs.pem" + # and in this case we also request binary formatted bundles in JKS and PKCS#12 formats, + # here named "bundle.jks" and "bundle.p12". + configMap: + key: "root-certs.pem" + additionalFormats: + jks: + key: "bundle.jks" + pkcs12: + key: "bundle.p12" + namespaceSelector: + matchLabels: + linkerd.io/inject: "enabled" +``` + +`Bundle` resources currently support several source types: + +- `configMap` - a `ConfigMap` resource in the trust-manager namespace +- `secret` - a `Secret` resource in the trust-manager namespace +- `inLine` - a manually specified string containing at least one certificate +- `useDefaultCAs` - usually, a bundle of publicly trusted certificates + +`ConfigMap` is the default target type, but as of v0.7.0 trust-manager also supports `Secret` resources as targets. + +Support for `Secret` targets must be explicitly enabled in the trust-manager controller; see details below under "Enable Secret targets". + +Both `ConfigMap` and `Secret` also support specifying label selectors to select multiple resources at once, which is useful in dynamic +environments where the name of the `ConfigMap` or `Secret` is known only at runtime. When adding a source, either of type `ConfigMap` or `Secret`, +the fields `name` and `selector` are mutually exclusive: one **must** be set, but not both. + + +All sources and target options are documented in the trust-manager [API reference documentation](./api-reference.md). + +#### Targets + +All `Bundle` targets are written to `ConfigMap`s (and/or `Secret`s) whose name matches that of the +`Bundle`, and every target has a PEM-formatted bundle included. + +Users can also optionally choose to write JKS/PKCS#12 formatted binary trust store(s) to targets. +JKS has been supported since v0.5.0, and PKCS#12 since v0.7.0. + +Applications consuming JKS and PKCS#12 trust stores often require a password to be set for legacy reasons. These passwords are often security theater - either they use very weak encryption or the passwords are provided in plaintext next to the files they encrypt which defeats the purpose of having them. + +Trust bundles do not contain private keys, and so for most use cases there wouldn't be any security benefit to encrypting them. As such, passwords for trust stores are set by default to `changeit` for JKS and `""` (the empty string or "password-less") for PKCS#12. + +Recent releases allow you to change that password by setting the bundle YAML file `spec.target.additionalFormats.jks.password` and `spec.target.additionalFormats.pkcs12.password`. + +Older releases have the current default values hard-coded and they can not be changed. For more information read [why password are not helpful](../../faq/README.md#keystore-passwords). + + + +#### Namespace Selector + +A target's `namespaceSelector` is used to restrict which Namespaces your `Bundle`'s target +should be synced to. + +`namespaceSelector` supports the field `matchLabels`. + +Please see [Kubernetes documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) +for more information about how label selectors can be configured. + +If `namespaceSelector` is empty, a `Bundle`'s target will be synced to all Namespaces. + +> ⚠️ A future update to trust-manager **will** change this behavior so that an empty namespace selector will sync only +to the trust-manager namespace by default. + +## Quick Start Example + +Let's get started with an example of creating our own `Bundle`! + +First we'll create a demo cluster: + +```bash +git clone https://github.com/cert-manager/trust-manager trust-manager +cd trust-manager +make demo +``` + +Once we have a running cluster, we can create a `Bundle` using the default CAs which were configured +when trust-manager started up. Since we've installed trust-manager using Helm, our default CA package +contains publicly trusted certificates derived from a Debian container. + +```bash +kubectl --kubeconfig ./bin/kubeconfig.yaml apply -f - < 🤔 Wondering why we used `tls.crt` and not `ca.crt`? More details [below](./README.md#preparing-for-production). + +Finally, we'll update our `Bundle` to include our new private CA: + +```bash +kubectl --kubeconfig ./bin/kubeconfig.yaml apply -f - < ⚠️ This upgrade process assumes that it's the only thing running. If another user or process changes Helm values +> while you're doing this process, you might overwrite their work. + +First, we'll dump our current Helm values, so we don't lose them: + +```bash +helm get values -n cert-manager trust-manager -oyaml > values.yaml +``` + +Next, if `defaultPackageImage.tag` is already set in `values.yaml`, update it. Otherwise, add it. +You can find the available tags [on `quay.io`](https://quay.io/repository/jetstack/cert-manager-package-debian?tab=tags&tag=latest). + +```yaml +# values.yaml +... +defaultPackageImage: + tag: XYZ +``` + +These versions of the default package image tags are derived directly from the version of the `ca-certificates` package in Debian. + +Finally, apply back the changes, being sure to manually specify the version of trust-manager which is installed, to avoid +also updating the trust-manager controller at the same as the default CA package: + +```bash +# Get the currently installed version. You could do this manually if you find that easier. +TRUST_MANAGER_VER=$(helm list --filter "^trust-manager$" -n cert-manager -ojson | jq -r ".[0].app_version") + +# Check the version makes sense +echo $TRUST_MANAGER_VER + +# Run the upgrade +helm upgrade -f values.yaml -n cert-manager trust-manager jetstack/trust-manager --version $TRUST_MANAGER_VER +``` + +If an incorrect tag is used, your deployment will fail and you'll likely need to use `helm rollback` to get back +to a working state. + +## Preparing for Production + +TLS can be complicated and there are many ways to misuse TLS certificates. + +Here are some potential gotchas to be aware of before running trust-manager in production. + +If you're planning on running trust-manager in production and you're using more than just the default CA package, +we **strongly** advise you to read and understand this section. It could save you from causing an outage later. + +> ℹ️ These gotchas aren't specific to trust-manager and you could run into any of them with any method of managing TLS trust! + +### Bundling Intermediates + +If you've ever used a Let's Encrypt client such as [Certbot](https://certbot.eff.org/) you'll probably have +seen that it generates several certificate files, such as `cert.pem`, `chain.pem`, and `fullchain.pem`. + +These various files are provided to support various different applications, which might require the certificate +and the chain to be given separately. For most users and applications `fullchain.pem` is the only correct choice. + +Unfortunately the existence of these files has the unfortunate side effect of people sometimes assuming that `cert.pem` +is the correct choice even when `fullchain.pem` would be correct. This means that the rest of the chain will not +be sent when the certificate is used. + +Often, a quick fix that _seems_ to work for this is that clients add the chain to their trust store, which will seem +to fix certificate errors in the short term. It's easy for this kind of "fix" to end up being embedded somewhere as a +solution which others can follow. + +This "fix" is dangerous; it means that the intermediate cannot be safely rotated without all trust stores +which contain it being updated first. + +Intermediates in this case become _de facto_ root certificates, which completely defeats the point of having +intermediate certificates in the first place. + +Avoid using intermediates in any trust store wherever possible unless you're absolutely certain they should be included. +An example of where it might be OK would be cross signing, which is not likely to be required in the general case. + +It would be better to copy just the root certificate to a new `ConfigMap` and use that as a source rather than trusting +an intermediate. + +### cert-manager Integration: `ca.crt` vs `tls.crt` + +If you're pointing trust-manager at a `Secret` containing a cert-manager-issued certificate, you'll see two relevant +fields: `ca.crt` and `tls.crt`. (We're ignoring `tls.key` - trust-manager definitely doesn't need to access that) + +That leads to an obvious question: between `ca.crt` and `tls.crt`, which should I use for trust-manager? + +Unfortunately, it's impossible to say in the general case which field is correct to use, but we can provide guidelines. + +`tls.crt` will generally contain multiple certificates which may not all be issuers and some of which are likely to be +intermediate certificates. If that's the case, you shouldn't use `tls.crt` as a source. (See "Bundling Intermediates" above for details.) + +`ca.crt` might then seem like the more generally correct choice but it's important to bear in mind that it can only ever +be populated on a best-effort basis. The contents of `ca.crt` depend on the `Issuer` being configured correctly, and some +issuer types may not ever be able to provide a useful or correct entry for this field. + +As a rule, you should prefer to create `Bundles` exclusively using root certificates (again, see above), and so you should +only use whichever field has a single root certificate in it. Consider reading below about why you might not want to +actually rely directly on cert-manager-issued certificates. + +### cert-manager Integration: Intentionally Copying CA Certificates + +It's very strange in the Kubernetes world to suggest intentionally adding a step which seems to make automating infrastructure +harder, but in the case of TLS trust stores it can be a wise choice. + +Say you have a cert-manager `Issuer` which has the root certificate you want to trust in `ca.crt`. It's tempting to +use the `Secret` directly and point at `ca.crt`, but a best practice would be to copy that root into a separate `ConfigMap` +(or `Secret`). + +The reason is - as with many TLS gotchas - certificate rotation. If you rotate your issuer such that it's issued from a new root +certificate, trust-manager will see the `Secret` be updated and automatically update your trust bundle to include the new root - +immediately distrusting the old root. + +That means that if any services were still using a certificate issued by the old root, they'll be distrusted and will break. + +Rotation requires that both root certificates are trusted simultaneously for a period, or else that all issued certificates +are rotated either before or at the same time as the old root. + +## Known Issues + +### `kubectl describe` + +The `useDefaultCAs` option hits a corner case inside `kubectl describe` and is rendered as `Use Default C As: true`. This is +purely cosmetic. diff --git a/content/v1.15-docs/trust/trust-manager/api-reference.md b/content/v1.15-docs/trust/trust-manager/api-reference.md new file mode 100644 index 0000000000..8134a417a1 --- /dev/null +++ b/content/v1.15-docs/trust/trust-manager/api-reference.md @@ -0,0 +1,734 @@ +--- +title: trust-manager API Reference +description: "trust-manager API documentation for custom resources" +--- + +Packages: + +- [`trust.cert-manager.io/v1alpha1`](#trustcert-manageriov1alpha1) + +# `trust.cert-manager.io/v1alpha1` + +Resource Types: + + +- [Bundle](#bundle) + + + + +## `Bundle` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          apiVersionstringtrust.cert-manager.io/v1alpha1true
          kindstringBundletrue
          metadataobjectRefer to the Kubernetes API documentation for the fields of the `metadata` field.true
          specobject + Desired state of the Bundle resource.
          +
          true
          statusobject + Status of the Bundle. This is set and managed automatically.
          +
          false
          + + +### `Bundle.spec` + + +Desired state of the Bundle resource. + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          sources[]object + Sources is a set of references to data whose data will sync to the target.
          +
          true
          targetobject + Target is the target location in all namespaces to sync source data to.
          +
          true
          + + +### `Bundle.spec.sources[index]` + + +BundleSource is the set of sources whose data will be appended and synced to the BundleTarget in all Namespaces. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          configMapobject + ConfigMap is a reference to a ConfigMap's `data` key, in the trust Namespace.
          +
          false
          inLinestring + InLine is a simple string to append as the source data.
          +
          false
          secretobject + Secret is a reference to a Secrets's `data` key, in the trust Namespace.
          +
          false
          useDefaultCAsboolean + UseDefaultCAs, when true, requests the default CA bundle to be used as a source. Default CAs are available if trust-manager was installed via Helm or was otherwise set up to include a package-injecting init container by using the "--default-package-location" flag when starting the trust-manager controller. If default CAs were not configured at start-up, any request to use the default CAs will fail. The version of the default CA package which is used for a Bundle is stored in the defaultCAPackageVersion field of the Bundle's status field.
          +
          false
          + + +### `Bundle.spec.sources[index].configMap` + + +ConfigMap is a reference to a ConfigMap's `data` key, in the trust Namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          namestring + Name is the name of the source object in the trust Namespace. If not set, `selector` must be set.
          +
          false
          selectorLabelSelector + A LabelSelector object to reference, by labels, a list of source objects in the trust Namespace. If not set, `name` must be set.
          +
          false
          + + +### `Bundle.spec.sources[index].secret` + + +Secret is a reference to a Secrets's `data` key, in the trust Namespace. + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          namestring + Name is the name of the source object in the trust Namespace. If not set, `selector` must be set.
          +
          false
          selectorLabelSelector + A LabelSelector object to reference, by labels, a list of source objects in the trust Namespace. If not set, `name` must be set.
          +
          false
          + + +### `Bundle.spec.target` + + +Target is the target location in all namespaces to sync source data to. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          additionalFormatsobject + AdditionalFormats specifies any additional formats to write to the target
          +
          false
          configMapobject + ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to.
          +
          false
          namespaceSelectorobject + NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector.
          +
          false
          secretobject + Secret is the target Secret that all Bundle source data will be synced to. Using Secrets as targets is only supported if enabled at trust-manager startup. By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace.
          +
          false
          + + +### `Bundle.spec.target.additionalFormats` + + +AdditionalFormats specifies any additional formats to write to the target + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          jksobject + JKS requests a JKS-formatted binary trust bundle to be written to the target. The bundle is created with the hardcoded password "changeit".
          +
          false
          pkcs12object + PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. The bundle is created without a password.
          +
          false
          + + +### `Bundle.spec.target.additionalFormats.jks` + + +JKS requests a JKS-formatted binary trust bundle to be written to the target. The bundle is created with the hardcoded password "changeit". + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.spec.target.additionalFormats.pkcs12` + + +PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. The bundle is created without a password. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.spec.target.configMap` + + +ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.spec.target.namespaceSelector` + + +NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          matchLabelsmap[string]string + MatchLabels matches on the set of labels that must be present on a Namespace for the Bundle target to be synced there.
          +
          false
          + + +### `Bundle.spec.target.secret` + + +Secret is the target Secret that all Bundle source data will be synced to. Using Secrets as targets is only supported if enabled at trust-manager startup. By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.status` + + +Status of the Bundle. This is set and managed automatically. + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          conditions[]object + List of status conditions to indicate the status of the Bundle. Known condition types are `Bundle`.
          +
          false
          defaultCAVersionstring + DefaultCAPackageVersion, if set and non-empty, indicates the version information which was retrieved when the set of default CAs was requested in the bundle source. This should only be set if useDefaultCAs was set to "true" on a source, and will be the same for the same version of a bundle with identical certificates.
          +
          false
          targetobject + Target is the current Target that the Bundle is attempting or has completed syncing the source data to.
          +
          false
          + + +### `Bundle.status.conditions[index]` + + +BundleCondition contains condition information for a Bundle. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          statusstring + Status of the condition, one of ('True', 'False', 'Unknown').
          +
          true
          typestring + Type of the condition, known values are (`Synced`).
          +
          true
          lastTransitionTimestring + LastTransitionTime is the timestamp corresponding to the last status change of this condition.
          +
          + Format: date-time
          +
          false
          messagestring + Message is a human readable description of the details of the last transition, complementing reason.
          +
          false
          observedGenerationinteger + If set, this represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.condition[x].observedGeneration is 9, the condition is out of date with respect to the current state of the Bundle.
          +
          + Format: int64
          +
          false
          reasonstring + Reason is a brief machine readable explanation for the condition's last transition.
          +
          false
          + + +### `Bundle.status.target` + + +Target is the current Target that the Bundle is attempting or has completed syncing the source data to. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          additionalFormatsobject + AdditionalFormats specifies any additional formats to write to the target
          +
          false
          configMapobject + ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to.
          +
          false
          namespaceSelectorobject + NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector.
          +
          false
          secretobject + Secret is the target Secret that all Bundle source data will be synced to. Using Secrets as targets is only supported if enabled at trust-manager startup. By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace.
          +
          false
          + + +### `Bundle.status.target.additionalFormats` + + +AdditionalFormats specifies any additional formats to write to the target + + + + + + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          jksobject + JKS requests a JKS-formatted binary trust bundle to be written to the target. The bundle is created with the hardcoded password "changeit".
          +
          false
          pkcs12object + PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. The bundle is created without a password.
          +
          false
          + + +### `Bundle.status.target.additionalFormats.jks` + + +JKS requests a JKS-formatted binary trust bundle to be written to the target. The bundle is created with the hardcoded password "changeit". + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.status.target.additionalFormats.pkcs12` + + +PKCS12 requests a PKCS12-formatted binary trust bundle to be written to the target. The bundle is created without a password. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.status.target.configMap` + + +ConfigMap is the target ConfigMap in Namespaces that all Bundle source data will be synced to. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          + + +### `Bundle.status.target.namespaceSelector` + + +NamespaceSelector will, if set, only sync the target resource in Namespaces which match the selector. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          matchLabelsmap[string]string + MatchLabels matches on the set of labels that must be present on a Namespace for the Bundle target to be synced there.
          +
          false
          + + +### `Bundle.status.target.secret` + + +Secret is the target Secret that all Bundle source data will be synced to. Using Secrets as targets is only supported if enabled at trust-manager startup. By default, trust-manager has no permissions for writing to secrets and can only read secrets in the trust namespace. + + + + + + + + + + + + + + + + +
          NameTypeDescriptionRequired
          keystring + Key is the key of the entry in the object's `data` field to be used.
          +
          true
          diff --git a/content/v1.15-docs/trust/trust-manager/installation.md b/content/v1.15-docs/trust/trust-manager/installation.md new file mode 100644 index 0000000000..1657dd0bf5 --- /dev/null +++ b/content/v1.15-docs/trust/trust-manager/installation.md @@ -0,0 +1,150 @@ +--- +title: Installing trust-manager +description: 'Installation guide for trust-manager' +--- + +## Installation Steps + +### 1. Update Helm Repository + +Helm is the easiest way to install trust-manager and comes with a publicly trusted certificate bundle package +(for the`useDefaultCAs` source) derived from Debian containers. + +```bash +helm repo add jetstack https://charts.jetstack.io --force-update +``` + +### 2. Install cert-manager (optional) + +When installed via Helm, trust-manager has a dependency on cert-manager for provisioning an application certificate +unless you explicitly opt to use a Helm-generated certificate instead. + +In production, we recommend installing cert-manager first and having trust-manager depend on it. + +If you haven't already installed cert-manager, you can install it using the following command: + +```bash +# Run this command only if you haven't installed cert-manager already +helm install cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version [[VAR::cert_manager_latest_version]] \ + --set crds.enabled=true +``` + +If you're running cert-manager without the default approver, see [approver-policy Integration](#approver-policy-integration) +for details on how to avoid a stuck installation. + +If you don't want to rely on cert-manager, you can install using a Helm-generated cert; see [Installing trust-manager without cert-manager](./installation.md#install-without-cert-manager). + +### 3. Install trust-manager + +trust-manager is simple to install and is contained in a single Helm chart: + +```bash +helm upgrade trust-manager jetstack/trust-manager \ + --install \ + --namespace cert-manager \ + --wait +``` + +Various options are available, and some are documented below. + +## Installation Options + +#### Enable Secret targets + +`Secret` targets are supported as of trust-manager v0.7.0, but need to be explicitly enabled on the controller. +The feature can be enabled with a Helm value `--set secretTargets.enabled=true`, but since the controller needs +RBAC to read and update secrets, you also need to set `secretTargets.authorizedSecretsAll` or `secretTargets.authorizedSecrets`. +Please consult the +[trust-manager Helm chart docs](https://github.com/cert-manager/trust-manager/blob/main/deploy/charts/trust-manager/README.md#values) +for details and trade-offs. + +#### approver-policy Integration + + + +If you're running [approver-policy](../../policy/approval/approver-policy/README.md) then cert-manager's default approver will be disabled which will mean that +trust-manager's webhook certificate will - by default - block when you install the Helm chart until it's manually approved. + +As of trust-manager v0.6.0 you can choose to automatically add an approver-policy `CertificateRequestPolicy` which +will approve the trust-manager webhook certificate: + +```bash +helm upgrade trust-manager jetstack/trust-manager \ + --install \ + --namespace cert-manager \ + --wait \ + --set app.webhook.tls.approverPolicy.enabled=true \ + --set app.webhook.tls.approverPolicy.certManagerNamespace=cert-manager +``` + +Note that if you've installed cert-manager to a different namespace, you'll need to pass that namespace in `app.webhook.tls.approverPolicy.certManagerNamespace`! + +#### Trust Namespace + +One of the more important configuration options you might need to consider at install time is which "trust namespace" to use, +which can be set via the Helm value `app.trust.namespace`. + +By default, the trust namespace is the only namespace where`Secret`s will be read. This restriction is in place +for security reasons - we don't want to give trust-manager the permission to read all `Secret`s in all namespaces. With additional configuration, secrets may be read from or written to other namespaces. + +The trust namespace defaults to `cert-manager`, but there's no need for it to be set to the namespace that cert-manager +is installed in - trust-manager has no runtime dependency on cert-manager at all! - so we'd recommend setting the trust +namespace to whichever is most appropriate for your environment. + +An ideal deployment would be a fresh namespace dedicated entirely to trust-manager, to minimize the number of actors in your +cluster that can modify your trust sources. + +#### Installing trust-manager without cert-manager + + + +As an alternative to generating a webhook certificate using cert-manager, it's possible to opt to use Helm to generate the webhook certificate instead. + +This isn't recommended for production, since Helm-generated certificates might be complicated to monitor or to reason about. The certificate is also rotated +every time trust-manager is upgraded, which necessitates pod restarts and may complicate the upgrade process. + +Installing without cert-manager can be great for smaller, more resource-constrained deployments such as experiments, demos or home labs. + +Using a Helm-generated cert requires a single flag: + +```bash +helm upgrade trust-manager jetstack/trust-manager \ + --install \ + --namespace cert-manager \ + --wait \ + --set app.webhook.tls.helmCert.enabled=true +``` + +## Uninstalling + +To uninstall trust-manager installed via Helm, run: + +```terminal +$ helm uninstall trust-manager -n cert-manager + +These resources were kept due to the resource policy: +[CustomResourceDefinition] bundles.trust.cert-manager.io + +release "trust-manager" uninstalled +``` + +As shown in the output, the `CustomResourceDefinition` for `Bundle` is not removed by the Helm uninstall command. +This is to prevent data loss, as removing the `CustomResourceDefinition` would also remove all `Bundle` resources. + +> ☢️ This will remove all `Bundle` resources from the cluster: +> +> ```terminal +> kubectl delete crd bundles.trust.cert-manager.io +> ``` + +> ⚠️ trust-manager versions prior to `v0.9.0` do not keep the `CustomResourceDefinition` on uninstall +> and will remove all `Bundle` resources from the cluster. Make sure to back up your `Bundle` resources +> before uninstalling trust-manager if you are using a version prior to `v0.9.0`. Or upgrade to `v0.9.0` +> before uninstalling. + +## Usage + +> 📖 Read the [trust-manager docs](./README.md). diff --git a/content/v1.15-docs/tutorials/README.md b/content/v1.15-docs/tutorials/README.md new file mode 100644 index 0000000000..fe697e2f0b --- /dev/null +++ b/content/v1.15-docs/tutorials/README.md @@ -0,0 +1,36 @@ +--- +title: Tutorials +description: 'cert-manager tutorials: Overview' +--- + +Step-by-step tutorials are a great way to get started with cert-manager, and we provide a few +for you to learn from. Take a look! + +- [Securing Ingresses with NGINX-Ingress and cert-manager](./acme/nginx-ingress.md): Tutorial for deploying NGINX into your + cluster and securing incoming connections with a certificate from Let's Encrypt. +- [GKE + Ingress + Let's Encrypt](./getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md): + Learn how to deploy cert-manager on Google Kubernetes Engine and how to configure it to get certificates for Ingress, from Let's Encrypt. +- [AKS + LoadBalancer + Let's Encrypt](getting-started-aks-letsencrypt/README.md): + Learn how to deploy cert-manager on Azure Kubernetes Service (AKS) and how to configure it to get certificates for an HTTPS web server, from Let's Encrypt. +- [EKS + LoadBalancer + Let's Encrypt](getting-started-aws-letsencrypt/README.md): + Learn how to deploy cert-manager on Amazon Elastic Kubernetes Service (EKS) and how to configure it to get certificates for an HTTPS web server, from Let's Encrypt. +- [Pomerium Ingress](./acme/pomerium-ingress.md): Tutorial on using the Pomerium Ingress Controller with cert-manager. +- [Issuing an ACME Certificate using DNS Validation](./acme/dns-validation.md): + Tutorial on how to resolve DNS ownership validation using DNS01 challenges. +- [Issuing an ACME Certificate using HTTP Validation](./acme/http-validation.md): + Tutorial on how to resolve DNS ownership validation using HTTP01 challenges. +- [Migrating from kube-lego](./acme/migrating-from-kube-lego.md): Tutorial on + how to migrate from the now deprecated kube-lego project. +- [Securing an EKS Cluster with Venafi](./venafi/venafi.md): Tutorial for + creating an EKS cluster and securing an NGINX deployment with a Venafi issued + certificate. +- [Obtaining SSL certificates with the ZeroSSL](./zerossl/zerossl.md): Tutorial describing usage of the ZeroSSL as external ACME server. +- [Managing public trust in Kubernetes with trust-manager](./getting-started-with-trust-manager/README.md): Learn how to deploy and configure trust-manager to automatically distribute your approved Public CA configuration to your Kubernetes cluster. +- [Learn how to set Certificate defaults automatically](./certificate-defaults/README.md): Learn how to use Kyverno `ClusterPolicy` to set default values for cert-manager `Certificates`. + +### External Tutorials + +- A great AWS blog post on using cert-manager for end-to-end encryption in EKS. See [Setting up end-to-end TLS encryption on Amazon EKS](https://aws.amazon.com/blogs/containers/setting-up-end-to-end-tls-encryption-on-amazon-eks-with-the-new-aws-load-balancer-controller/) +- A full cert-manager installation demo on a GKE Cluster. See [How-To: Automatic SSL Certificate Management for your Kubernetes Application Deployment](https://medium.com/contino-engineering/how-to-automatic-ssl-certificate-management-for-your-kubernetes-application-deployment-94b64dfc9114) +- cert-manager installation on GKE Cluster using Workload Identity. See [Kubernetes, ingress-nginx, cert-manager & external-dns](https://blog.atomist.com/kubernetes-ingress-nginx-cert-manager-external-dns/) +- A video tutorial for beginners showing cert-manager in action. See [Free SSL for Kubernetes with cert-manager](https://www.youtube.com/watch?v=hoLUigg4V18) diff --git a/content/v1.15-docs/tutorials/acme/dns-validation.md b/content/v1.15-docs/tutorials/acme/dns-validation.md new file mode 100644 index 0000000000..bddf11097b --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/dns-validation.md @@ -0,0 +1,169 @@ +--- +title: DNS Validation +description: 'cert-manager turorials: Issuing an ACME certificate using DNS validation' +--- + +## Issuing an ACME certificate using DNS validation + +cert-manager can be used to obtain certificates from a CA using the +[ACME](https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment) +protocol. The ACME protocol supports various challenge mechanisms which are +used to prove ownership of a domain so that a valid certificate can be issued +for that domain. + +One such challenge mechanism is DNS01. With a DNS01 challenge, you prove +ownership of a domain by proving you control its DNS records. +This is done by creating a TXT record with specific content that proves you +have control of the domains DNS records. + +The following Issuer defines the necessary information to enable DNS validation. +You can read more about the Issuer resource in the [Issuer +docs](../../configuration/README.md). + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-staging + namespace: default +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + email: user@example.com + + # Name of a secret used to store the ACME account private key + privateKeySecretRef: + name: letsencrypt-staging + + # ACME DNS-01 provider configurations + solvers: + # An empty 'selector' means that this solver matches all domains + - selector: {} + dns01: + cloudDNS: + # The ID of the GCP project + # reference: https://cert-manager.io/docs/tutorials/acme/dns-validation/ + project: $PROJECT_ID + # This is the secret used to access the service account + serviceAccountSecretRef: + name: clouddns-dns01-solver-svc-acct + key: key.json + + # We only use cloudflare to solve challenges for example.org. + # Alternative options such as 'matchLabels' and 'dnsZones' can be specified + # as part of a solver's selector too. + - selector: + dnsNames: + - example.org + dns01: + cloudflare: + email: my-cloudflare-acc@example.com + # !! Remember to create a k8s secret before + # kubectl create secret generic cloudflare-api-key-secret + apiKeySecretRef: + name: cloudflare-api-key-secret + key: api-key +``` + + +We have specified the ACME server URL for Let's Encrypt's [staging +environment](https://letsencrypt.org/docs/staging-environment/). The staging +environment will not issue trusted certificates but is used to ensure that the +verification process is working properly before moving to production. Let's +Encrypt's production environment imposes much stricter [rate +limits](https://letsencrypt.org/docs/rate-limits/), so to reduce the chance of +you hitting those limits it is highly recommended to start by using the staging +environment. To move to production, simply create a new Issuer with the URL set +to `https://acme-v02.api.letsencrypt.org/directory`. + +The first stage of the ACME protocol is for the client to register with the +ACME server. This phase includes generating an asymmetric key pair which is +then associated with the email address specified in the Issuer. Make sure to +change this email address to a valid one that you own. It is commonly used to +send expiry notices when your certificates are coming up for renewal. The +generated private key is stored in a Secret named `letsencrypt-staging`. + +The `dns01` stanza contains a list of DNS01 providers that can be used to +solve DNS challenges. Our Issuer defines two providers. This gives us a choice +of which one to use when obtaining certificates. + +More information about the DNS provider configuration, including a list of +supported providers, can be found [in the DNS01 reference docs](../../configuration/acme/dns01/README.md). + +Once we have created the above Issuer we can use it to obtain a certificate. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com + namespace: default +spec: + secretName: example-com-tls + issuerRef: + name: letsencrypt-staging + dnsNames: + - '*.example.com' + - example.com + - example.org +``` + +The Certificate resource describes our desired certificate and the possible +methods that can be used to obtain it. You can obtain certificates for wildcard +domains just like any other. Make sure to wrap wildcard domains with asterisks +in your YAML resources, to avoid formatting issues. If you specify both +`example.com` and `*.example.com` on the same Certificate, it will take slightly +longer to perform validation as each domain will have to be validated one after +the other. You can learn more about the Certificate resource in the +[docs](../../usage/README.md). If the certificate is obtained successfully, the +resulting key pair will be stored in a secret called `example-com-tls` in the +same namespace as the Certificate. + +The certificate will have a common name of `*.example.com` and the [Subject +Alternative Names +(SANs)](https://en.wikipedia.org/wiki/Subject_Alternative_Name) will be +`*.example.com`, `example.com` and `example.org`. + +In our Certificate we have referenced the `letsencrypt-staging` Issuer above. +The Issuer must be in the same namespace as the Certificate. If you want to +reference a `ClusterIssuer`, which is a cluster-scoped version of an Issuer, you +must add `kind: ClusterIssuer` to the `issuerRef` stanza. + +For more information on `ClusterIssuers`, read the +[issuer concepts](../../concepts/issuer.md). + +The `acme` stanza defines the configuration for our ACME challenges. Here we +have defined the configuration for our DNS challenges which will be used to +verify domain ownership. For each domain mentioned in a `dns01` stanza, +cert-manager will use the provider's credentials from the referenced Issuer to +create a TXT record called `_acme-challenge`. This record will then be verified +by the ACME server in order to issue the certificate. Once domain ownership has +been verified, any cert-manager affected records will be cleaned up. + +> Note: It is your responsibility to ensure the selected provider is +> authoritative for your domain. + +After creating the above Certificate, we can check whether it has been obtained +successfully using `kubectl describe`: + +```bash +$ kubectl describe certificate example-com +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal CreateOrder 57m cert-manager Created new ACME order, attempting validation... + Normal DomainVerified 55m cert-manager Domain "*.example.com" verified with "dns-01" validation + Normal DomainVerified 55m cert-manager Domain "example.com" verified with "dns-01" validation + Normal DomainVerified 55m cert-manager Domain "example.org" verified with "dns-01" validation + Normal IssueCert 55m cert-manager Issuing certificate... + Normal CertObtained 55m cert-manager Obtained certificate from ACME server + Normal CertIssued 55m cert-manager Certificate issued successfully +``` + +You can also check whether issuance was successful with `kubectl get secret +example-com-tls -o yaml`. You should see a base64 encoded signed TLS key pair. + +Once our certificate has been obtained, cert-manager will periodically check its +validity and attempt to renew it if it gets close to expiry. cert-manager +considers certificates to be close to expiry when the 'Not After' field on the +certificate is less than the current time plus 30 days. \ No newline at end of file diff --git a/content/v1.15-docs/tutorials/acme/example/deployment.yaml b/content/v1.15-docs/tutorials/acme/example/deployment.yaml new file mode 100644 index 0000000000..d876c66cf9 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/deployment.yaml @@ -0,0 +1,20 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kuard +spec: + selector: + matchLabels: + app: kuard + replicas: 1 + template: + metadata: + labels: + app: kuard + spec: + containers: + - image: gcr.io/kuar-demo/kuard-amd64:1 + imagePullPolicy: Always + name: kuard + ports: + - containerPort: 8080 diff --git a/content/v1.15-docs/tutorials/acme/example/ingress-tls-final.yaml b/content/v1.15-docs/tutorials/acme/example/ingress-tls-final.yaml new file mode 100644 index 0000000000..48f8094a85 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/ingress-tls-final.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: kuard + annotations: + cert-manager.io/issuer: "letsencrypt-prod" + +spec: + ingressClassName: nginx + tls: + - hosts: + - example.example.com + secretName: quickstart-example-tls + rules: + - host: example.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: kuard + port: + number: 80 diff --git a/content/v1.15-docs/tutorials/acme/example/ingress-tls.yaml b/content/v1.15-docs/tutorials/acme/example/ingress-tls.yaml new file mode 100644 index 0000000000..60fef7448b --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/ingress-tls.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: kuard + annotations: + cert-manager.io/issuer: "letsencrypt-staging" + +spec: + ingressClassName: nginx + tls: + - hosts: + - example.example.com + secretName: quickstart-example-tls + rules: + - host: example.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: kuard + port: + number: 80 diff --git a/content/v1.15-docs/tutorials/acme/example/ingress.yaml b/content/v1.15-docs/tutorials/acme/example/ingress.yaml new file mode 100644 index 0000000000..0651471ca0 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/ingress.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: kuard + annotations: {} + #cert-manager.io/issuer: "letsencrypt-staging" +spec: + ingressClassName: nginx + tls: + - hosts: + - example.example.com + secretName: quickstart-example-tls + rules: + - host: example.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: kuard + port: + number: 80 diff --git a/content/v1.15-docs/tutorials/acme/example/pomerium-certificates.yaml b/content/v1.15-docs/tutorials/acme/example/pomerium-certificates.yaml new file mode 100644 index 0000000000..7e07111417 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/pomerium-certificates.yaml @@ -0,0 +1,36 @@ +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: pomerium-cert + namespace: pomerium +spec: + secretName: pomerium-tls + issuerRef: + name: pomerium-issuer + kind: Issuer + usages: + - server auth + - client auth + dnsNames: + - pomerium-proxy.pomerium.svc.cluster.local + - pomerium-authorize.pomerium.svc.cluster.local + - pomerium-databroker.pomerium.svc.cluster.local + - pomerium-authenticate.pomerium.svc.cluster.local +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: pomerium-redis-cert + namespace: pomerium +spec: + secretName: pomerium-redis-tls + issuerRef: + name: pomerium-issuer + kind: Issuer + usages: + - server auth + - client auth + dnsNames: + - pomerium-redis-master.pomerium.svc.cluster.local + - pomerium-redis-headless.pomerium.svc.cluster.local + - pomerium-redis-replicas.pomerium.svc.cluster.local diff --git a/content/v1.15-docs/tutorials/acme/example/pomerium-production-issuer.yaml b/content/v1.15-docs/tutorials/acme/example/pomerium-production-issuer.yaml new file mode 100644 index 0000000000..f15a289904 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/pomerium-production-issuer.yaml @@ -0,0 +1,19 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-prod + namespace: pomerium +spec: + acme: + # The ACME server URL + server: https://acme-v02.api.letsencrypt.org/directory + # Email address used for ACME registration + email: user@example.com + # Name of a secret used to store the ACME account private key + privateKeySecretRef: + name: letsencrypt-prod + # Enable the HTTP-01 challenge provider + solvers: + - http01: + ingress: + ingressClassName: pomerium diff --git a/content/v1.15-docs/tutorials/acme/example/pomerium-staging-issuer.yaml b/content/v1.15-docs/tutorials/acme/example/pomerium-staging-issuer.yaml new file mode 100644 index 0000000000..8f8b91992a --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/pomerium-staging-issuer.yaml @@ -0,0 +1,19 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-staging + namespace: pomerium +spec: + acme: + # The ACME server URL + server: https://acme-staging-v02.api.letsencrypt.org/directory + # Email address used for ACME registration + email: user@example.com + # Name of a secret used to store the ACME account private key + privateKeySecretRef: + name: letsencrypt-staging + # Enable the HTTP-01 challenge provider + solvers: + - http01: + ingress: + ingressClassName: pomerium diff --git a/content/v1.15-docs/tutorials/acme/example/pomerium-values.yaml b/content/v1.15-docs/tutorials/acme/example/pomerium-values.yaml new file mode 100644 index 0000000000..2460377547 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/pomerium-values.yaml @@ -0,0 +1,39 @@ +authenticate: + existingTLSSecret: pomerium-tls + idp: + provider: "google" + clientID: YOUR_CLIENT_ID + clientSecret: YOUR_SECRET + serviceAccount: YOUR_SERVICE_ACCOUNT + ingress: + annotations: + cert-manager.io/issuer: letsencrypt-staging + tls: + secretName: authenticate.localhost.pomerium.io-tls + +proxy: + existingTLSSecret: pomerium-tls + +databroker: + existingTLSSecret: pomerium-tls + storage: + clientTLS: + existingSecretName: pomerium-redis-tls + existingCASecretKey: ca.crt + +authorize: + existingTLSSecret: pomerium-tls + +redis: + enabled: true + generateTLS: false + tls: + certificateSecret: pomerium-redis-tls + +ingressController: + enabled: true + +config: + rootDomain: localhost.pomerium.io #Change this to your reserved domain space. + existingCASecret: pomerium-tls + generateTLS: false # On by default, disabled when cert-manager or another solution is in place. diff --git a/content/v1.15-docs/tutorials/acme/example/production-issuer.yaml b/content/v1.15-docs/tutorials/acme/example/production-issuer.yaml new file mode 100644 index 0000000000..16ed60e210 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/production-issuer.yaml @@ -0,0 +1,18 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-prod +spec: + acme: + # The ACME server URL + server: https://acme-v02.api.letsencrypt.org/directory + # Email address used for ACME registration + email: user@example.com + # Name of a secret used to store the ACME account private key + privateKeySecretRef: + name: letsencrypt-prod + # Enable the HTTP-01 challenge provider + solvers: + - http01: + ingress: + ingressClassName: nginx diff --git a/content/v1.15-docs/tutorials/acme/example/service.yaml b/content/v1.15-docs/tutorials/acme/example/service.yaml new file mode 100644 index 0000000000..864b481ccb --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: kuard +spec: + ports: + - port: 80 + targetPort: 8080 + protocol: TCP + selector: + app: kuard diff --git a/content/v1.15-docs/tutorials/acme/example/staging-issuer.yaml b/content/v1.15-docs/tutorials/acme/example/staging-issuer.yaml new file mode 100644 index 0000000000..9b0f337256 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/example/staging-issuer.yaml @@ -0,0 +1,18 @@ +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-staging +spec: + acme: + # The ACME server URL + server: https://acme-staging-v02.api.letsencrypt.org/directory + # Email address used for ACME registration + email: user@example.com + # Name of a secret used to store the ACME account private key + privateKeySecretRef: + name: letsencrypt-staging + # Enable the HTTP-01 challenge provider + solvers: + - http01: + ingress: + ingressClassName: nginx diff --git a/content/v1.15-docs/tutorials/acme/http-validation.md b/content/v1.15-docs/tutorials/acme/http-validation.md new file mode 100644 index 0000000000..5abc937c04 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/http-validation.md @@ -0,0 +1,166 @@ +--- +title: HTTP Validation +description: 'cert-manager tutorials: Issuing an ACME certificate using HTTP validation' +--- + +## Issuing an ACME certificate using HTTP validation + +cert-manager can be used to obtain certificates from a CA using the +[ACME](https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment) +protocol. The ACME protocol supports various challenge mechanisms which are +used to prove ownership of a domain so that a valid certificate can be issued +for that domain. + +One such challenge mechanism is the HTTP01 challenge. With a HTTP01 challenge, +you prove ownership of a domain by ensuring that a particular file is present at +the domain. It is assumed that you control the domain if you are able to +publish the given file under a given path. + +The following Issuer defines the necessary information to enable HTTP +validation. You can read more about the Issuer resource in the [Issuer +docs](../../concepts/issuer.md). + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-staging + namespace: default +spec: + acme: + # The ACME server URL + server: https://acme-staging-v02.api.letsencrypt.org/directory + # Email address used for ACME registration + email: user@example.com + # Name of a secret used to store the ACME account private key + privateKeySecretRef: + name: letsencrypt-staging + # Enable the HTTP-01 challenge provider + solvers: + # An empty 'selector' means that this solver matches all domains + - selector: {} + http01: + ingress: + ingressClassName: nginx +``` + +We have specified the ACME server URL for Let's Encrypt's [staging +environment](https://letsencrypt.org/docs/staging-environment/). The staging +environment will not issue trusted certificates but is used to ensure that the +verification process is working properly before moving to production. Let's +Encrypt's production environment imposes much stricter [rate +limits](https://letsencrypt.org/docs/rate-limits/), so to reduce the chance of +you hitting those limits it is highly recommended to start by using the staging +environment. To move to production, simply create a new Issuer with the URL set +to `https://acme-v02.api.letsencrypt.org/directory`. + +The first stage of the ACME protocol is for the client to register with the +ACME server. This phase includes generating an asymmetric key pair which is +then associated with the email address specified in the Issuer. Make sure to +change this email address to a valid one that you own. It is commonly used to +send expiry notices when your certificates are coming up for renewal. The +generated private key is stored in a Secret named `letsencrypt-staging`. + +We must provide one or more Solvers for handling the ACME challenge. In this +case we want to use HTTP validation so we specify an `http01` Solver. We could +optionally map different domains to use different Solver configurations. + +Once we have created the above Issuer we can use it to obtain a certificate. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com + namespace: default +spec: + secretName: example-com-tls + issuerRef: + name: letsencrypt-staging + commonName: example.com + dnsNames: + - www.example.com +``` + +The Certificate resource describes our desired certificate and the possible +methods that can be used to obtain it. You can learn more about the Certificate +resource in the [docs](../../usage/certificate.md). If the certificate is +obtained successfully, the resulting key pair will be stored in a secret called +`example-com-tls` in the same namespace as the Certificate. + +The certificate will have a common name of `example.com` and the [Subject +Alternative Names +(SANs)](https://en.wikipedia.org/wiki/Subject_Alternative_Name) will be +`example.com` and `www.example.com`. Note that only these SANs will be respected +by TLS clients. + +In our Certificate we have referenced the `letsencrypt-staging` Issuer above. +The Issuer must be in the same namespace as the Certificate. If you want to +reference a `ClusterIssuer`, which is a cluster-scoped version of an Issuer, you +must add `kind: ClusterIssuer` to the `issuerRef` stanza. + +For more information on `ClusterIssuers`, read the [`ClusterIssuer` +docs](../../concepts/issuer.md). + +The `acme` stanza defines the configuration for our ACME challenges. Here we +have defined the configuration for our HTTP01 challenges which will be used to +verify domain ownership. To verify ownership of each domain mentioned in an +`http01` stanza, cert-manager will create a Pod, Service and Ingress that +exposes an HTTP endpoint that satisfies the HTTP01 challenge. + +The fields `ingressClassName`, `class`, and `name` in the `http01` stanza can be +used to control how cert-manager interacts with Ingress resources: + +- If the `ingressClassName` field is specified, a new ingress resource with a + randomly generated name will be created in order to solve the challenge. This + new resource will have the field `ingressClassName` with the value of the + `ingressClassName` field. This is the recommended way of configuring which + Ingress controller should be used. This works for the likes of the NGINX + ingress controller. +- If the `class` field is specified, a new ingress resource with a randomly + generated name will be created in order to solve the challenge. This new + resource will have an annotation with key `kubernetes.io/ingress.class` and + value set to the value of the `class` field. This field is only recommended + with ingress-gce which [does not support the `ingressClassName` + field](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress). +- If the `name` field is specified, then an Ingress resource with the same name + in the same namespace as the Certificate must already exist and it will be + modified only to add the appropriate rules to solve the challenge. This field + is useful for the Google Cloud Loadbalancer ingress controller, as well as a + number of others, that assign a single public IP address for each ingress + resource. Without manual intervention, creating a new ingress resource would + cause any challenges to fail. + +- If neither are specified, new ingress resources will be created with a randomly + generated name, but they will not have the ingress class annotation set. +- If both are specified, then the `ingress` field will take precedence. + +Once domain ownership has been verified, any cert-manager affected resources will +be cleaned up or deleted. + +> Note: It is your responsibility to point each domain name at the correct IP +> address for your ingress controller. + +After creating the above Certificate, we can check whether it has been obtained +successfully using `kubectl describe`: + +```bash +$ kubectl describe certificate example-com +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal CreateOrder 57m cert-manager Created new ACME order, attempting validation... + Normal DomainVerified 55m cert-manager Domain "example.com" verified with "http-01" validation + Normal DomainVerified 55m cert-manager Domain "www.example.com" verified with "http-01" validation + Normal IssueCert 55m cert-manager Issuing certificate... + Normal CertObtained 55m cert-manager Obtained certificate from ACME server + Normal CertIssued 55m cert-manager Certificate issued successfully +``` + +You can also check whether issuance was successful with `kubectl get secret +example-com-tls -o yaml`. You should see a base64 encoded signed TLS key pair. + +Once our certificate has been obtained, cert-manager will periodically check its +validity and attempt to renew it if it gets close to expiry. cert-manager +considers certificates to be close to expiry when the 'Not After' field on the +certificate is less than the current time plus 30 days. \ No newline at end of file diff --git a/content/v1.15-docs/tutorials/acme/migrating-from-kube-lego.md b/content/v1.15-docs/tutorials/acme/migrating-from-kube-lego.md new file mode 100644 index 0000000000..84992cb0fb --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/migrating-from-kube-lego.md @@ -0,0 +1,232 @@ +--- +title: Migrating from Kube-LEGO +description: 'cert-manager tutorials: Migrating from kube-lego' +--- + +[kube-lego](https://github.com/jetstack/kube-lego) is an older Jetstack project +for obtaining TLS certificates from Let's Encrypt (or another ACME server). + +Since cert-managers release, kube-lego has been gradually deprecated in favor +of this project. There are a number of key differences between the two: + +| Feature | kube-lego | cert-manager | +|-------------------------------------------|----------------------------------|------------------------| +| Configuration | Annotations on Ingress resources | CRDs | +| CAs | ACME | ACME, signing key pair | +| Kubernetes | `v1.2` - `v1.8` | `v1.7+` | +| Debugging | Look at logs | Kubernetes Events API | +| Multi-tenancy | Not supported | Supported | +| Distinct issuance sources per Certificate | Not supported | Supported | +| Ingress controller support (ACME) | GCE, NGINX | All | + +This guide will walk through how you can safely migrate your kube-lego +installation to cert-manager, without service interruption. + +By the end of the guide, we should have: + +1. Scaled down and removed kube-lego + +2. Installed cert-manager + +3. Migrated ACME private key to cert-manager + +4. Created an ACME `ClusterIssuer` using this private key, to issue certificates + throughout your cluster + +5. Configured cert-manager's [`ingress-shim`](../../usage/ingress.md) to + automatically provision Certificate resources for all Ingress resources with + the `kubernetes.io/tls-acme: "true"` annotation, using the `ClusterIssuer` we + have created + +6. Verified that the cert-manager installation is working + + +## 1. Scale down kube-lego + +Before we begin deploying cert-manager, it is best we scale our kube-lego +deployment down to 0 replicas. This will prevent the two controllers +potentially 'fighting' each other. If you deployed kube-lego using the official +deployment YAMLs, a command like so should do: + +```bash +$ kubectl scale deployment kube-lego \ + --namespace kube-lego \ + --replicas=0 +``` + +You can then verify your kube-lego pod is no longer running with: + +```bash +$ kubectl get pods --namespace kube-lego +``` + +## 2. Deploy cert-manager + +cert-manager should be deployed using Helm, according to our official +[installation guide](../../installation/README.md). No special steps are +required here. We will return to this deployment at the end of this guide and +perform an upgrade of some of the CLI flags we deploy cert-manager with however. + +Please take extra care to ensure you have configured RBAC correctly when +deploying Helm and cert-manager - there are some nuances described in our +deploying document! + +## 3. Obtaining your ACME account private key + +In order to continue issuing and renewing certificates on your behalf, we need +to migrate the user account private key that kube-lego has created for you over +to cert-manager. + +Your ACME user account identity is a private key, stored in a secret resource. +By default, kube-lego will store this key in a secret named `kube-lego-account` +in the same namespace as your kube-lego Deployment. You may have overridden this +value when you deploy kube-lego, in which case the secret name to use will be +the value of the `LEGO_SECRET_NAME` environment variable. + +You should download a copy of this secret resource and save it in your local +directory: + +```bash +$ kubectl get secret kube-lego-account -o yaml \ + --namespace kube-lego \ + --export > kube-lego-account.yaml +``` + +Once saved, open up this file and change the `metadata.name` field to something +more relevant to cert-manager. For the rest of this guide, we'll assume you +chose `letsencrypt-private-key`. + +Once done, we need to create this new resource in the `cert-manager` namespace. +By default, cert-manager stores supporting resources for `ClusterIssuers` in the +namespace that it is running in, and we used `cert-manager` when deploying +cert-manager above. You should change this if you have deployed cert-manager +into a different namespace. + +```bash +$ kubectl create -f kube-lego-account.yaml \ + --namespace cert-manager +``` + +## 4. Creating an ACME `ClusterIssuer` using your old ACME account + +We need to create a `ClusterIssuer` which will hold information about the ACME +account previously registered via kube-lego. In order to do so, we need two more +pieces of information from our old kube-lego deployment: the server URL of the +ACME server, and the email address used to register the account. + +Both of these bits of information are stored within the kube-lego `ConfigMap`. + +To retrieve them, you should be able to `get` the `ConfigMap` using `kubectl`: + +```bash +$ kubectl get configmap kube-lego -o yaml \ + --namespace kube-lego \ + --export +``` + +Your email address should be shown under the `.data.lego.email` field, and the +ACME server URL under `.data.lego.url`. + +For the purposes of this guide, we will assume the email is +`user@example.com` and the URL +`https://acme-staging-v02.api.letsencrypt.org/directory`. + +Now that we have migrated our private key to the new Secret resource, as well as +obtaining our ACME email address and URL, we can create a `ClusterIssuer` +resource! + +Create a file named `cluster-issuer.yaml`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + # Adjust the name here accordingly + name: letsencrypt-staging +spec: + acme: + # The ACME server URL + server: https://acme-staging-v02.api.letsencrypt.org/directory + # Email address used for ACME registration + email: user@example.com + # Name of a secret used to store the ACME account private key from step 3 + privateKeySecretRef: + name: letsencrypt-private-key + # Enable the HTTP-01 challenge provider + solvers: + - http01: + ingress: + ingressClassName: nginx +``` + +We then submit this file to our Kubernetes cluster: + +```bash +$ kubectl create -f cluster-issuer.yaml +``` + +You should be able to verify the ACME account has been verified successfully: + +```bash +$ kubectl describe clusterissuer letsencrypt-staging +... +Status: + Acme: + Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/7571319 + Conditions: + Last Transition Time: 2019-01-30T14:52:03Z + Message: The ACME account was registered with the ACME server + Reason: ACMEAccountRegistered + Status: True + Type: Ready +``` + +## 5. Configuring ingress-shim to use our new `ClusterIssuer` by default + +Now that our `ClusterIssuer` is ready to issue certificates, we have one last +thing to do: we must reconfigure `ingress-shim` (deployed as part of cert-manager) +to automatically create Certificate resources for all Ingress resources it finds +with appropriate annotations. + +More information on the role of ingress-shim can be found [in the +docs](../../usage/ingress.md), but for now we can just run a `helm +upgrade` in order to add a few additional flags. Assuming you've named your +`ClusterIssuer` `letsencrypt-staging` (as above), run: + +```bash +$ helm upgrade cert-manager \ + jetstack/cert-manager \ + --namespace cert-manager \ + --set ingressShim.defaultIssuerName=letsencrypt-staging \ + --set ingressShim.defaultIssuerKind=ClusterIssuer +``` + +You should see the cert-manager pod be re-created, and once started it should +automatically create Certificate resources for all of your ingresses that +previously had kube-lego enabled. + +## 6. Verify each ingress now has a corresponding Certificate + +Before we finish, we should make sure there is now a Certificate resource for +each ingress resource you previously enabled kube-lego on. + +You should be able to check this by running: + +```bash +$ kubectl get certificates --all-namespaces +``` + +There should be an entry for each ingress in your cluster with the kube-lego +annotation. + +We can also verify that cert-manager has 'adopted' the old TLS certificates by +viewing the logs for cert-manager: + +```bash +$ kubectl logs -n cert-manager -l app=cert-manager -c cert-manager +... +I1025 21:54:02.869269 1 sync.go:206] Certificate my-example-certificate scheduled for renewal in 292 hours +``` + +Here we can see cert-manager has verified the existing TLS certificate and +scheduled it to be renewed in 292 hours time. \ No newline at end of file diff --git a/content/v1.15-docs/tutorials/acme/nginx-ingress.md b/content/v1.15-docs/tutorials/acme/nginx-ingress.md new file mode 100644 index 0000000000..c7cf9f1568 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/nginx-ingress.md @@ -0,0 +1,602 @@ +--- +title: Securing NGINX-ingress +description: 'cert-manager tutorials: Using ingress-nginx to solve an ACME HTTP-01 challenge' +--- + +This tutorial will detail how to install and secure ingress to your cluster +using NGINX. + +## Step 1 - Install Helm + +> *Skip this section if you have helm installed.* + +The easiest way to install `cert-manager` is to use [`Helm`](https://helm.sh), a +templating and deployment tool for Kubernetes resources. + +First, ensure the Helm client is installed following the [Helm installation +instructions](https://helm.sh/docs/intro/install/). + +For example, on MacOS: + +```bash +brew install kubernetes-helm +``` + +## Step 2 - Deploy the NGINX Ingress Controller + +A [`kubernetes ingress controller`](https://kubernetes.io/docs/concepts/services-networking/ingress) is +designed to be the access point for HTTP and HTTPS traffic to the software +running within your cluster. The `ingress-nginx-controller` does this by providing +an HTTP proxy service supported by your cloud provider's load balancer. + +You can get more details about `ingress-nginx` and how it works from the +[documentation for `ingress-nginx`](https://kubernetes.github.io/ingress-nginx/). + +Add the latest helm repository for the ingress-nginx + +```bash +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +``` + +Update the helm repository with the latest charts: + +```bash +$ helm repo update +Hang tight while we grab the latest from your chart repositories... +...Skip local chart repository +...Successfully got an update from the "stable" chart repository +...Successfully got an update from the "ingress-nginx" chart repository +...Successfully got an update from the "coreos" chart repository +Update Complete. ⎈ Happy Helming!⎈ +``` + +Use `helm` to install an NGINX Ingress controller: + +```bash +$ helm install quickstart ingress-nginx/ingress-nginx + +NAME: quickstart +... lots of output ... +``` + +It can take a minute or two for the cloud provider to provide and link a public +IP address. When it is complete, you can see the external IP address using the +`kubectl` command: + +```bash +$ kubectl get svc +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +kubernetes ClusterIP 10.0.0.1 443/TCP 13m +quickstart-ingress-nginx-controller LoadBalancer 10.0.114.241 80:31635/TCP,443:30062/TCP 8m16s +quickstart-ingress-nginx-controller-admission ClusterIP 10.0.188.24 443/TCP 8m16s +``` + +This command shows you all the services in your cluster (in the `default` +namespace), and any external IP addresses they have. When you first create the +controller, your cloud provider won't have assigned and allocated an IP address +through the `LoadBalancer` yet. Until it does, the external IP address for the +service will be listed as ``. + +Your cloud provider may have options for reserving an IP address prior to +creating the ingress controller and using that IP address rather than assigning +an IP address from a pool. Read through the documentation from your cloud +provider on how to arrange that. + +## Step 3 - Assign a DNS name + +The external IP that is allocated to the ingress-controller is the IP to which +all incoming traffic should be routed. To enable this, add it to a DNS zone you +control, for example as `www.example.com`. + +This quick-start assumes you know how to assign a DNS entry to an IP address and +will do so. + +## Step 4 - Deploy an Example Service + +Your service may have its own chart, or you may be deploying it directly with +manifests. This quick-start uses manifests to create and expose a sample service. +The example service uses [`kuard`](https://github.com/kubernetes-up-and-running/kuard), +a demo application. + +The quick-start example uses three manifests for the sample. The first two are a +sample deployment and an associated service: + +```yaml file=./example/deployment.yaml +``` + +```yaml file=./example/service.yaml +``` + +You can create download and reference these files locally, or you can +reference them from the GitHub source repository for this documentation. +To install the example service from the tutorial files straight from GitHub, do +the following: + +```bash +kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/deployment.yaml +# expected output: deployment.extensions "kuard" created + +kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/service.yaml +# expected output: service "kuard" created +``` + +An [Ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) is +what Kubernetes uses to expose this example service outside the cluster. You +will need to download and modify the example manifest to reflect the domain that +you own or control to complete this example. + +A sample ingress you can start with is: + +```yaml file=./example/ingress.yaml +``` + +You can download the sample manifest from GitHub , edit it, and submit the +manifest to Kubernetes with the command below. Edit the file in your editor, and once +it is saved: + +```bash +kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/ingress.yaml +# expected output: ingress.networking.k8s.io/kuard created +``` + +> Note: The ingress example we show above has a `host` definition within it. The +> `ingress-nginx-controller` will route traffic when the hostname requested +> matches the definition in the ingress. You *can* deploy an ingress without a +> `host` definition in the rule, but that pattern isn't usable with a TLS +> certificate, which expects a fully qualified domain name. + +Once it is deployed, you can use the command `kubectl get ingress` to see the status + of the ingress: + +```text +NAME HOSTS ADDRESS PORTS AGE +kuard * 80, 443 17s +``` + +It may take a few minutes, depending on your service provider, for the ingress +to be fully created. When it has been created and linked into place, the +ingress will show an address as well: + +```text +NAME HOSTS ADDRESS PORTS AGE +kuard * 203.0.113.2 80 9m +``` + +> Note: The IP address on the ingress *may not* match the IP address that the +> `ingress-nginx-controller` has. This is fine, and is a quirk/implementation detail +> of the service provider hosting your Kubernetes cluster. Since we are using +> the `ingress-nginx-controller` instead of any cloud-provider specific ingress +> backend, use the IP address that was defined and allocated for the +> `quickstart-ingress-nginx-controller ` `LoadBalancer` resource as the primary access point for +> your service. + +Make sure the service is reachable at the domain name you added above, for +example `http://www.example.com`. The simplest way is to open a browser +and enter the name that you set up in DNS, and for which we just added the +ingress. + +You may also use a command line tool like `curl` to check the ingress. + +```bash +$ curl -kivL -H 'Host: www.example.com' 'http://203.0.113.2' +``` + +The options on this curl command will provide verbose output, following any +redirects, show the TLS headers in the output, and not error on insecure +certificates. With `ingress-nginx-controller`, the service will be available +with a TLS certificate, but it will be using a self-signed certificate +provided as a default from the `ingress-nginx-controller`. Browsers will show +a warning that this is an invalid certificate. This is expected and normal, +as we have not yet used cert-manager to get a fully trusted certificate +for our site. + +> *Warning*: It is critical to make sure that your ingress is available and +> responding correctly on the internet. This quick-start example uses Let's +> Encrypt to provide the certificates, which expects and validates both that the +> service is available and that during the process of issuing a certificate uses +> that validation as proof that the request for the domain belongs to someone +> with sufficient control over the domain. + +## Step 5 - Deploy cert-manager + +We need to install cert-manager to do the work with Kubernetes to request a +certificate and respond to the challenge to validate it. We can use Helm or +plain Kubernetes manifests to install cert-manager. + +Since we installed Helm earlier, we'll assume you want to use Helm; follow the +[Helm guide](../../installation/helm.md). For other methods, read the +[installation documentation](../../installation/README.md) for cert-manager. + +cert-manager mainly uses two different custom Kubernetes resources - known as +[`CRDs`](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) - +to configure and control how it operates, as well as to store state. These +resources are Issuers and Certificates. + +### Issuers + +An Issuer defines _how_ cert-manager will request TLS certificates. Issuers are +specific to a single namespace in Kubernetes, but there's also a `ClusterIssuer` +which is meant to be a cluster-wide version. + +Take care to ensure that your Issuers are created in the same namespace as the +certificates you want to create. You might need to add `-n my-namespace` to your +`kubectl create` commands. + +Your other option is to replace your `Issuers` with `ClusterIssuers`; +`ClusterIssuer` resources apply across all Ingress resources in your cluster. +If using a `ClusterIssuer`, remember to update the Ingress annotation `cert-manager.io/issuer` to +`cert-manager.io/cluster-issuer`. + +If you see issues with issuers, follow the [Troubleshooting Issuing ACME Certificates](../../troubleshooting/acme.md) guide. + +More information on the differences between `Issuers` and `ClusterIssuers` - including +when you might choose to use each can be found on [Issuer concepts](../../concepts/issuer.md#namespaces). + +### Certificates + +Certificates resources allow you to specify the details of the certificate you +want to request. They reference an issuer to define _how_ they'll be issued. + +For more information, see [Certificate concepts](../../usage/certificate.md). + +## Step 6 - Configure a Let's Encrypt Issuer + +We'll set up two issuers for Let's Encrypt in this example: staging and production. + +The Let's Encrypt production issuer has [very strict rate limits](https://letsencrypt.org/docs/rate-limits/). +When you're experimenting and learning, it can be very easy to hit those limits. Because of that risk, +we'll start with the Let's Encrypt staging issuer, and once we're happy that it's working +we'll switch to the production issuer. + +Note that you'll see a warning about untrusted certificates from the staging issuer, but that's totally expected. + +Create this definition locally and update the email address to your own. This +email is required by Let's Encrypt and used to notify you of certificate +expiration and updates. + +```yaml file=./example/staging-issuer.yaml +``` + +Once edited, apply the custom resource: + +```bash +kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/staging-issuer.yaml +# expected output: issuer.cert-manager.io "letsencrypt-staging" created +``` + +Also create a production issuer and deploy it. As with the staging issuer, you +will need to update this example and add in your own email address. + +```yaml file=./example/production-issuer.yaml +``` + +```bash +kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/production-issuer.yaml +# expected output: issuer.cert-manager.io "letsencrypt-prod" created +``` + +Both of these issuers are configured to use the [`HTTP01`](../../configuration/acme/http01/README.md) challenge provider. + +Check on the status of the issuer after you create it: + +```bash +$ kubectl describe issuer letsencrypt-staging +Name: letsencrypt-staging +Namespace: default +Labels: +Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"cert-manager.io/v1","kind":"Issuer","metadata":{"annotations":{},"name":"letsencrypt-staging","namespace":"default"},(...)} +API Version: cert-manager.io/v1 +Kind: Issuer +Metadata: + Cluster Name: + Creation Timestamp: 2018-11-17T18:03:54Z + Generation: 0 + Resource Version: 9092 + Self Link: /apis/cert-manager.io/v1/namespaces/default/issuers/letsencrypt-staging + UID: 25b7ae77-ea93-11e8-82f8-42010a8a00b5 +Spec: + Acme: + Email: email@example.com + Private Key Secret Ref: + Key: + Name: letsencrypt-staging + Server: https://acme-staging-v02.api.letsencrypt.org/directory + Solvers: + Http 01: + Ingress: + Class: nginx +Status: + Acme: + Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/7374163 + Conditions: + Last Transition Time: 2018-11-17T18:04:00Z + Message: The ACME account was registered with the ACME server + Reason: ACMEAccountRegistered + Status: True + Type: Ready +Events: +``` + +You should see the issuer listed with a registered account. + +## Step 7 - Deploy a TLS Ingress Resource + +With all the prerequisite configuration in place, we can now do the pieces to +request the TLS certificate. There are two primary ways to do this: using +annotations on the ingress with [`ingress-shim`](../../usage/ingress.md) or +directly creating a certificate resource. + +In this example, we will add annotations to the ingress, and take advantage +of ingress-shim to have it create the certificate resource on our behalf. +After creating a certificate, the cert-manager will update or create a ingress +resource and use that to validate the domain. Once verified and issued, +cert-manager will create or update the secret defined in the certificate. + +> Note: The secret that is used in the ingress should match the secret defined +> in the certificate. There isn't any explicit checking, so a typo will result +> in the `ingress-nginx-controller` falling back to its self-signed certificate. +> In our example, we are using annotations on the ingress (and ingress-shim) +> which will create the correct secrets on your behalf. + +Edit the ingress add the annotations that were commented out in our earlier +example: + +```yaml file=./example/ingress-tls.yaml +``` + +and apply it: + +```bash +kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/ingress-tls.yaml +# expected output: ingress.networking.k8s.io/kuard configured +``` + +Cert-manager will read these annotations and use them to create a certificate, +which you can request and see: + +```bash +$ kubectl get certificate +NAME READY SECRET AGE +quickstart-example-tls True quickstart-example-tls 16m +``` + +cert-manager reflects the state of the process for every request in the +certificate object. You can view this information using the +`kubectl describe` command: + +```bash +$ kubectl describe certificate quickstart-example-tls +Name: quickstart-example-tls +Namespace: default +Labels: +Annotations: +API Version: cert-manager.io/v1 +Kind: Certificate +Metadata: + Cluster Name: + Creation Timestamp: 2018-11-17T17:58:37Z + Generation: 0 + Owner References: + API Version: networking.k8s.io/v1 + Block Owner Deletion: true + Controller: true + Kind: Ingress + Name: kuard + UID: a3e9f935-ea87-11e8-82f8-42010a8a00b5 + Resource Version: 9295 + Self Link: /apis/cert-manager.io/v1/namespaces/default/certificates/quickstart-example-tls + UID: 68d43400-ea92-11e8-82f8-42010a8a00b5 +Spec: + Dns Names: + www.example.com + Issuer Ref: + Kind: Issuer + Name: letsencrypt-staging + Secret Name: quickstart-example-tls +Status: + Acme: + Order: + URL: https://acme-staging-v02.api.letsencrypt.org/acme/order/7374163/13665676 + Conditions: + Last Transition Time: 2018-11-17T18:05:57Z + Message: Certificate issued successfully + Reason: CertIssued + Status: True + Type: Ready +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal CreateOrder 9m cert-manager Created new ACME order, attempting validation... + Normal DomainVerified 8m cert-manager Domain "www.example.com" verified with "http-01" validation + Normal IssueCert 8m cert-manager Issuing certificate... + Normal CertObtained 7m cert-manager Obtained certificate from ACME server + Normal CertIssued 7m cert-manager Certificate issued Successfully +``` + +The events associated with this resource and listed at the bottom +of the `describe` results show the state of the request. In the above +example the certificate was validated and issued within a couple of minutes. + +Once complete, cert-manager will have created a secret with the details of +the certificate based on the secret used in the ingress resource. You can +use the describe command as well to see some details: + +```bash +$ kubectl describe secret quickstart-example-tls +Name: quickstart-example-tls +Namespace: default +Labels: cert-manager.io/certificate-name=quickstart-example-tls +Annotations: cert-manager.io/alt-names=www.example.com + cert-manager.io/common-name=www.example.com + cert-manager.io/issuer-kind=Issuer + cert-manager.io/issuer-name=letsencrypt-staging + +Type: kubernetes.io/tls + +Data +==== +tls.crt: 3566 bytes +tls.key: 1675 bytes +``` + +Now that we have confidence that everything is configured correctly, you +can update the annotations in the ingress to specify the production issuer: + +```yaml file=./example/ingress-tls-final.yaml +``` + +```bash +$ kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/ingress-tls-final.yaml +ingress.networking.k8s.io/kuard configured +``` + +You will also need to delete the existing secret, which cert-manager is watching +and will cause it to reprocess the request with the updated issuer. + +```bash +$ kubectl delete secret quickstart-example-tls +secret "quickstart-example-tls" deleted +``` + +This will start the process to get a new certificate, and using describe +you can see the status. Once the production certificate has been updated, +you should see the example KUARD running at your domain with a signed TLS +certificate. + +```bash +$ kubectl describe certificate quickstart-example-tls +Name: quickstart-example-tls +Namespace: default +Labels: +Annotations: +API Version: cert-manager.io/v1 +Kind: Certificate +Metadata: + Cluster Name: + Creation Timestamp: 2018-11-17T18:36:48Z + Generation: 0 + Owner References: + API Version: networking.k8s.io/v1 + Block Owner Deletion: true + Controller: true + Kind: Ingress + Name: kuard + UID: a3e9f935-ea87-11e8-82f8-42010a8a00b5 + Resource Version: 283686 + Self Link: /apis/cert-manager.io/v1/namespaces/default/certificates/quickstart-example-tls + UID: bdd93b32-ea97-11e8-82f8-42010a8a00b5 +Spec: + Dns Names: + www.example.com + Issuer Ref: + Kind: Issuer + Name: letsencrypt-prod + Secret Name: quickstart-example-tls +Status: + Conditions: + Last Transition Time: 2019-01-09T13:52:05Z + Message: Certificate does not exist + Reason: NotFound + Status: False + Type: Ready +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Generated 18s cert-manager Generated new private key + Normal OrderCreated 18s cert-manager Created Order resource "quickstart-example-tls-889745041" +``` + +You can see the current state of the ACME Order by running `kubectl describe` +on the Order resource that cert-manager has created for your Certificate: + +```bash +$ kubectl describe order quickstart-example-tls-889745041 +... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Created 90s cert-manager Created Challenge resource "quickstart-example-tls-889745041-0" for domain "www.example.com" +``` + +Here, we can see that cert-manager has created 1 'Challenge' resource to fulfill +the Order. You can dig into the state of the current ACME challenge by running +`kubectl describe` on the automatically created Challenge resource: + +```bash +$ kubectl describe challenge quickstart-example-tls-889745041-0 +... +Status: + Presented: true + Processing: true + Reason: Waiting for http-01 challenge propagation + State: pending +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Started 15s cert-manager Challenge scheduled for processing + Normal Presented 14s cert-manager Presented challenge using http-01 challenge mechanism +``` + +From above, we can see that the challenge has been 'presented' and cert-manager +is waiting for the challenge record to propagate to the ingress controller. +You should keep an eye out for new events on the challenge resource, as a +'success' event should be printed after a minute or so (depending on how fast +your ingress controller is at updating rules): + +```bash +$ kubectl describe challenge quickstart-example-tls-889745041-0 +... +Status: + Presented: false + Processing: false + Reason: Successfully authorized domain + State: valid +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Started 71s cert-manager Challenge scheduled for processing + Normal Presented 70s cert-manager Presented challenge using http-01 challenge mechanism + Normal DomainVerified 2s cert-manager Domain "www.example.com" verified with "http-01" validation +``` + +> Note: If your challenges are not becoming 'valid' and remain in the 'pending' +> state (or enter into a 'failed' state), it is likely there is some kind of +> configuration error. Read the [Challenge resource reference +> docs](../../reference/api-docs.md#acme.cert-manager.io/v1.Challenge) for more +> information on debugging failing challenges. + +Once the challenge(s) have been completed, their corresponding challenge +resources will be *deleted*, and the 'Order' will be updated to reflect the +new state of the Order: + +```bash +$ kubectl describe order quickstart-example-tls-889745041 +... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Created 90s cert-manager Created Challenge resource "quickstart-example-tls-889745041-0" for domain "www.example.com" + Normal OrderValid 16s cert-manager Order completed successfully +``` + +Finally, the 'Certificate' resource will be updated to reflect the state of the +issuance process. If all is well, you should be able to 'describe' the Certificate +and see something like the below: + +```bash +$ kubectl describe certificate quickstart-example-tls +Status: + Conditions: + Last Transition Time: 2019-01-09T13:57:52Z + Message: Certificate is up to date and has not expired + Reason: Ready + Status: True + Type: Ready + Not After: 2019-04-09T12:57:50Z +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Generated 11m cert-manager Generated new private key + Normal OrderCreated 11m cert-manager Created Order resource "quickstart-example-tls-889745041" + Normal OrderComplete 10m cert-manager Order "quickstart-example-tls-889745041" completed successfully +``` diff --git a/content/v1.15-docs/tutorials/acme/pomerium-ingress.md b/content/v1.15-docs/tutorials/acme/pomerium-ingress.md new file mode 100644 index 0000000000..326dd0f5a4 --- /dev/null +++ b/content/v1.15-docs/tutorials/acme/pomerium-ingress.md @@ -0,0 +1,191 @@ +--- +title: Pomerium Ingress +description: 'cert-manager tutorials: Solving ACME HTTP-01 challenges using Pomerium ingress' +--- + +This tutorial covers installing the [Pomerium Ingress Controller](https://pomerium.com/docs/k8s/ingress.html) and securing it with cert-manager. [Pomerium](https://pomerium.com) is an identity-aware proxy that can also provide a custom ingress controller for your Kubernetes services. + +## Prerequisites + +1. Install [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) and set the context to the cluster you'll be working with. + +1. Pomerium connects to an identity provider (**IdP**) to authenticate users. See one of their [guides](https://www.pomerium.com/docs/identity-providers/) to learn how to set up your IdP of choice to provide oauth2 validation. + +1. This tutorial assumes you have a domain space reserved for this cluster (such as `*.example.com`). You will need access to DNS for this domain to assign A and CNAME records as needed. + +## Install The Pomerium Ingress Controller + +1. Install Pomerium to your cluster: + + ```sh + kubectl apply -f https://raw.githubusercontent.com/pomerium/ingress-controller/main/deployment.yaml + ``` + + Define a Secret with your IdP configuration. See Pomerium's [Identity Providers](https://www.pomerium.com/docs/identity-providers) pages for more information specific to your IdP: + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: idp + namespace: pomerium + type: Opaque + stringData: + client_id: ${IDP_PROVIDED_CLIENT_ID} + client_secret: ${IDP_PROVIDED_CLIENT_SECRET} + ``` + + Add the secret to the cluster with `kubectl apply -f`. + +1. Define the global settings for Pomerium: + + ```yaml + apiVersion: ingress.pomerium.io/v1 + kind: Pomerium + metadata: + name: global + namespace: pomerium + spec: + secrets: pomerium/bootstrap + authenticate: + url: https://authenticate.example.com + identityProvider: + provider: ${YOUR_IdP} + secret: pomerium/idp + # certificates: + # - pomerium/pomerium-proxy-tls + ``` + + Replace `${YOUR_IdP}` with your identity provider. Apply with `kubectl -f`. + + Note that the last two lines are commented out. They reference a TLS certificate we will create further in the process. + +## Install cert-manager + +Install cert-manager using any of the methods documented in the [Installation](https://cert-manager.io/docs/installation/) section of the cert-manager docs. The simplest method is to download and apply the provided manifest: + +```sh +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/[[VAR::cert_manager_latest_version]]/cert-manager.yaml +``` + +## Configure Let's Encrypt Issuer + +For communication between the Ingresses and the internet, we'll want to use certificates signed by a trusted certificate authority like Let's Encrypt. This example creates two Let's Encrypt issuers, one for staging and one for production. + +The Let's Encrypt production issuer has [strict rate limits](https://letsencrypt.org/docs/rate-limits/). Before your configuration is finalized you may have to recreate services several times, hitting those limits. It's easy to confuse rate limiting with errors in configuration or operation while building your stack. + +Because of this, we will start with the Let's Encrypt staging issuer. Once your configuration is all but finalized, we will switch to a production issuer. Both of these issuers are configured to use the [`HTTP01`](../../configuration/acme/http01/README.md) challenge provider. + +1. The following YAML defines a staging certificate issuer. You must update the email address to your own. The `email` field is required by Let's Encrypt and used to notify you of certificate expiration and updates. + + ```yaml file=./example/pomerium-staging-issuer.yaml + ``` + + You can download and edit the example and apply it with `kubectl apply -f`, or edit, and apply the custom resource in one command: + + ```bash + kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/pomerium-staging-issuer.yaml + ``` + +1. Create a production issuer and deploy it. As with the staging issuer, update this example with your own email address: + + ```yaml file=./example/pomerium-production-issuer.yaml + ``` + + ```bash + kubectl create --edit -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/pomerium-production-issuer.yaml + ``` + +1. You can confirm on the status of the issuers after you create them: + + ```bash + kubectl describe issuer -n pomerium letsencrypt-staging + kubectl describe issuer -n pomerium letsencrypt-prod + ``` + + You should see the issuer listed with a registered account. + +1. Define a certificate for the Pomerium Proxy service. This should be the only certificate you need to manually define: + + ```yaml + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: pomerium-proxy-tls + namespace: pomerium + spec: + dnsNames: + - 'authenticate.example.com' + issuerRef: + kind: Issuer + name: letsencrypt-staging + secretName: pomerium-proxy-tls + ``` + + Adjust the `dnsNames` value to match your domain space. The subdomain (`authenticate` in our example) must match the domain used for the callback URL in your IdP configuration. Add the certificate with `kubectl -f`. + +1. Uncomment the last two lines of the Pomerium global configuration that reference your newly created certificate, and re-apply to the cluster. + +Pomerium should now be installed and running in your cluster. You can verify by going to `https://authenticate.example.com` in your browser. Use `kubectl describe pomerium` to review the status of the Pomerium deployment and see recent events. + +## Define a Test Service + +To test our new Ingress Controller, we will add the [kuard](https://github.com/kubernetes-up-and-running/kuard) app to our cluster and define an Ingress for it. + +1. Define the kuard deployment and associated service: + + ```yaml file=./example/deployment.yaml + ``` + + ```yaml file=./example/service.yaml + ``` + + You can download and reference these files locally, or you can reference them from the GitHub source repository for this documentation. + + To install the example service from the tutorial files straight from GitHub: + + ```bash + kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/deployment.yaml + kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/master/content/docs/tutorials/acme/example/service.yaml + ``` + +1. Create a new Ingress manifest (`example-ingress.yaml`) for our test service: + + ```yaml + apiVersion: networking.k8s.io/v1 + kind: Ingress + metadata: + name: kuard + annotations: + cert-manager.io/issuer: letsencrypt-staging + ingress.pomerium.io/policy: '[{"allow":{"and":[{"domain":{"is":"example.com"}}]}}]' + spec: + ingressClassName: pomerium + rules: + - host: kuard.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: kuard + port: + number: 80 + tls: + - hosts: + - kuard.example.com + secretName: kuard.example.com-tls + ``` + + Again, change the references to `example.com` to match your domain space. + +1. Apply the Ingress manifest to the cluster: + + ```bash + kubectl apply -f example-ingress.yaml + ``` + +The Pomerium Ingress Controller will use cert-manager to automatically provision a certificate from the `letsencrypt-staging` issuer for the route to `kuard.example.com`. + +Once you've configured all your application services correctly in the cluster, adjust the issuer for your Ingresses (including the Authenticate service) to use `letsencrypt-prod`. diff --git a/content/v1.15-docs/tutorials/certificate-defaults/README.md b/content/v1.15-docs/tutorials/certificate-defaults/README.md new file mode 100644 index 0000000000..e14febf9c8 --- /dev/null +++ b/content/v1.15-docs/tutorials/certificate-defaults/README.md @@ -0,0 +1,571 @@ +--- +title: Learn how to set Certificate defaults automatically +description: | + Learn how to use Kyverno ClusterPolicy to set default values for cert-manager Certificates cluster wide. +--- + +*Last Verified: 19 January 2024* + +# Objective + +We will set up a cluster where a user specifies as little YAML as possible in `Certificate` resources. +This will be achieved by utilizing Kyverno to apply custom "default" values to the `Certificate` fields, that are not specified by a user. + +There are some benefits to having defaults: + +- `Certificate` consumers minimize their YAML resources. +- `Certificate` consumers retain flexibility to override fields when needed. +- Cluster operators can decide what the default should be, rather than having to rely on built-in defaults from cert-manager. + +## Use cases + +By setting custom defaults across our cluster, we enable platform teams to tackle use cases such as: + +- **To ensure that `CertificateRequest` resources get cleaned up.** + + Use a `ClusterPolicy` to set a custom default value for the `Certificate.Spec.RevisionHistoryLimit` field. + +- **To help your users choose secure default key settings for their `Certificate` resources.** + + Use a `ClusterPolicy` to set custom default values for the `Certificate.Spec.PrivateKey` fields. + +- **To default the `Issuer` for users within the cluster.** + + Use a `ClusterPolicy` to set a custom default for the `Certificate.spec.issuerRef` fields. + +- **To set a default pattern for the naming of the `Secret` where the certificate will be populated.** + + Use a `ClusterPolicy` to set a custom default value for the `spec.secretName` required field. + +- **Make application developers' lives easier by allowing them to create secure X.509 TLS certificates with the minimum of configuration.** + + Use a `ClusterPolicy` to set all other required `Certificate.spec` fields. + Only a single identity specification field will be required, one of: + - `commonName` or `literalSubject` + - `dnsNames` + - `uris` + - `emailAddresses` + - `ipAddresses` + - `otherNames` + +## Process + +We will set up defaults for three different scenarios, getting slightly more advanced each time: + +1. Setting defaults for optional `Certificate` resource fields. +2. Setting defaults for required `Certificate` resource fields. +3. Setting defaults for `Certificate` resource fields, when using `Ingress` annotations to request certificates. + +# Setup + +## Prerequisites + +**💻 Software** + +1. [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl): The Kubernetes + command-line tool which allows you to configure Kubernetes clusters. +1. [helm](https://helm.sh/): A package manager for Kubernetes. +1. [kind](https://kind.sigs.k8s.io/) (**OPTIONAL**): For creating a local + Kubernetes environment that runs in Docker or other container runtimes. + +## Local Kubernetes Environment + +> ⚠️ This step can be skipped if you have another Kubernetes environment. + +1. Create a cluster environment using `kind` for this tutorial. + + ```shell + kind create cluster --name defaults + ``` + + > ⏲ It should take less than one minute to create the cluster, depending on your machine. + > + > ⚠️ This cluster is only suitable for learning purposes. It is not suitable for production use. + +## Software Installation + +Once you have your cluster environment, install the required Kubernetes packages using `helm`. + +1. Set some environment variables for the helm chart versions: + + ```shell + export CERT_MANAGER_CHART_VERSION="[[VAR::cert_manager_latest_version]]" \ + KYVERNO_CHART_VERSION="3.1.4" \ + INGRESS_NGINX_CHART_VERSION="4.9.0" + ``` + +1. Install cert-manager + + ```shell + helm upgrade --install cert-manager cert-manager \ + --namespace cert-manager \ + --version $CERT_MANAGER_CHART_VERSION \ + --set crds.enabled=true \ + --set startupapicheck.enabled=false \ + --create-namespace \ + --repo https://charts.jetstack.io/ + ``` + +1. Install Kyverno + + ```shell + helm upgrade --install kyverno kyverno \ + --namespace kyverno-system \ + --version $KYVERNO_CHART_VERSION \ + --create-namespace \ + --repo https://kyverno.github.io/kyverno/ + ``` + +1. Install ingress-nginx + + ```shell + helm upgrade --install ingress-nginx ingress-nginx \ + --namespace ingress-nginx \ + --version $INGRESS_NGINX_CHART_VERSION \ + --create-namespace \ + --repo https://kubernetes.github.io/ingress-nginx + ``` + +> For complete installation instructions, please refer to the following links: +> - [cert-manager installation instructions](./../../../docs/installation/helm.md) +> - [Kyverno installation instructions](https://kyverno.io/docs/installation/methods/#install-kyverno-using-helm) +> - [ingress-nginx installation instructions](https://kubernetes.github.io/ingress-nginx/deploy/) + +# Setting Defaults + +The main tutorial starts here with some background, before tackling each of the three scenarios. + +## Required vs Non-required + +The `Certificate` resource has a `spec` section with a number of "required" fields. +This means these fields must be present when you create a `Certificate` resource. +There are also a number of other fields that are not required to be explicitly defined on each `Certificate` resource. +This essentially means the value of one of these fields is either not required, or has defaults defined somewhere else. +That somewhere else could be in the cert-manager code base, or indeed by the issuer that creates and returns the X.509 certificate. +Let's explore how we can manipulate these values to be something custom and make the `Certificate` user's life easier. + +We will set up some `ClusterPolicy` resources and `Certificate` resources in this tutorial. +We will make reference to a `ClusterIssuer` in the `Certificate` spec that doesn't exist, but for this tutorial the `ClusterIssuer` is not required as we will not actually be requesting certificates. +That means anyone can follow this tutorial even without their own domain. + +> ⚠️ To make it easy to get started we are using cluster scoped `ClusterPolicy` resources. +> You can scope your defaults to the namespace level through the use of `Policy` resources in the future, but that will not be covered in this tutorial. + +## 1 - Defaulting optional fields + +In this section we will create rules which set three fields for all `Certificate` resources automatically. +None of the three fields here are required fields, but they might need to be set depending on platform and issuer preferences. +These rules will: + +- Set a default value of: `revisionHistoryLimit: 2`. +- Set a [default value of `Always` under `spec.privateKey.rotationPolicy`](../../usage/certificate.md#the-rotationpolicy-setting). +- Set defaults for all `spec.privateKey` fields. + +> ℹ️ Note how these rules tackle the first two of our [uses cases](#use-cases). + +1. First take a look at the `ClusterPolicy`: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/cpol-mutate-certificates-0.yaml + ``` + 🔗 `cpol-mutate-certificates-0.yaml` + +1. Apply the policy to the cluster and check that it is ready: + + ```shell + kubectl apply -f cpol-mutate-certificates-0.yaml + kubectl get cpol + ``` + + When the `ClusterPolicy` is ready the output should look like this: + + ```log + NAME ADMISSION BACKGROUND VALIDATE ACTION READY AGE MESSAGE + mutate-certificates true true Audit True 0s Ready + ``` + +1. Now inspect the "test-revision" `Certificate`: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/cert-test-revision.yaml + ``` + 🔗 `cert-test-revision.yaml` + + You can see that we have set the most minimal configuration currently possible, specifying only a DNS name for the certificate, where to save it (`secretName`) and the issuer to use to request the certificate (`issuerRef`). + +1. Use the following command to *dry-run apply* the certificate and then `diff` it against the original resource, to see how the defaults from our `ClusterPolicy` are applied: + + ```shell + kubectl apply -f cert-test-revision.yaml --dry-run=server -o yaml | diff -uZ cert-test-revision.yaml - + ``` + + This command should return some output similar to this example: + + ```yaml + --- cert-test-revision.yaml 2024-01-08 12:14:59.225074232 +0000 + +++ - 2024-01-12 17:37:51.076593214 +0000 + @@ -1,8 +1,14 @@ + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + + annotations: + + kubectl.kubernetes.io/last-applied-configuration: | + + {"apiVersion":"cert-manager.io/v1","kind":"Certificate","metadata":{"annotations":{},"name":"test-revision","namespace":"default"},"spec":{"dnsNames":["example.com"],"issuerRef":{"group":"cert-manager.io","kind":"ClusterIssuer","name":"not-my-corp-issuer"},"secretName":"test-revision-cert"}} + + creationTimestamp: "2024-01-12T17:37:51Z" + + generation: 1 + name: test-revision + namespace: default + + uid: 9f9a4f0a-4aa7-427d-ae4b-c1716fed8246 + spec: + dnsNames: + - example.com + @@ -10,4 +16,10 @@ + group: cert-manager.io + kind: ClusterIssuer + name: not-my-corp-issuer + + privateKey: + + algorithm: ECDSA + + encoding: PKCS1 + + rotationPolicy: Always + + size: 521 + + revisionHistoryLimit: 2 + secretName: test-revision-cert + ``` + + We have successfully defaulted the `privateKey` and `revisionHistoryLimit` fields! + +1. Let's override all of these defaulted fields, to validate that we can still set what we want as an end user. To test this, let's use the "test-revision-override" `Certificate`: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/cert-test-revision-override.yaml + ``` + 🔗 `cert-test-revision-override.yaml` + + As before, *dry-run apply* and `diff` the output with the input file: + + ```shell + kubectl apply -f cert-test-revision-override.yaml --dry-run=server -o yaml | diff -uZ cert-test-revision-override.yaml - + ``` + + Here you can see in the output there are no specification changes for the `Certificate` itself. + The `Certificate` already had all the fields defined that our `ClusterPolicy` rules would have affected. + + ```yaml + --- cert-test-revision-override.yaml 2024-01-05 14:45:14.972562067 +0000 + +++ - 2024-01-12 17:39:57.217028745 +0000 + @@ -1,8 +1,14 @@ + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + + annotations: + + kubectl.kubernetes.io/last-applied-configuration: | + + {"apiVersion":"cert-manager.io/v1","kind":"Certificate","metadata":{"annotations":{},"name":"test-revision-override","namespace":"default"},"spec":{"dnsNames":["example.com"],"issuerRef":{"group":"cert-manager.io","kind":"ClusterIssuer","name":"not-my-corp-issuer"},"privateKey":{"algorithm":"RSA","encoding":"PKCS8","rotationPolicy":"Never","size":4096},"revisionHistoryLimit":44,"secretName":"test-revision-override-cert"}} + + creationTimestamp: "2024-01-12T17:39:57Z" + + generation: 1 + name: test-revision-override + namespace: default + + uid: 83a6ddbc-6903-479e-802d-e11149985338 + spec: + dnsNames: + - example.com + ``` + +## 2 - Defaulting required fields + +> ⚠️ This section requires cert-manager v1.14.x or newer to work properly out of the box. +> See the [Appendix](#cert-manager-version-requirement) section for details. + +Now we can set a Kyverno `ClusterPolicy` to apply default values to any of the `Certificate` fields. +This includes the *required* fields. +In our example `ClusterPolicy` we will do two things: + +- Set the relevant `issuerRef` fields to default to use the "our-corp-issuer" `ClusterIssuer`. +- Apply a default `secretName` that is the name of the `Certificate` object suffixed with "-cert". + +> ℹ️ Note how these rules are tackling the third and fourth [uses cases](#use-cases). + +1. Here is the `ClusterPolicy` resource to set both fields with defaults: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/cpol-mutate-certificates-1.yaml + ``` + 🔗 `cpol-mutate-certificates-1.yaml` + + This `ClusterPolicy` is an extension of the policy we applied previously. + +1. Apply this policy: + + ```shell + kubectl apply -f cpol-mutate-certificates-1.yaml + ``` + + You should see that our existing `ClusterPolicy` has been changed: + + ```shell + clusterpolicy.kyverno.io/mutate-certificates configured + ``` + + Get the `ClusterPolicy` to validate it is "Ready": + + ```shell + kubectl get cpol + ``` + + This command should return some output similar to this example: + + ```shell + NAME ADMISSION BACKGROUND VALIDATE ACTION READY AGE MESSAGE + mutate-certificates true true Audit True 6m21s Ready + ``` + +1. Look at the "test-minimal" `Certificate` designed to validate that all our rules within the policy are operative: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/cert-test-minimal.yaml + ``` + 🔗 `cert-test-minimal.yaml` + +1. *Dry-run apply* and `diff` to validate all our defaults have applied to this minimal `Certificate`: + + ```shell + kubectl apply -f cert-test-minimal.yaml --dry-run=server -o yaml | diff -uZ cert-test-minimal.yaml - + ``` + + This command should return some output similar to this example: + + ```yaml + --- cert-test-minimal.yaml 2024-01-05 14:45:07.140668401 +0000 + +++ - 2024-01-12 17:44:08.110290752 +0000 + @@ -1,8 +1,25 @@ + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + + annotations: + + kubectl.kubernetes.io/last-applied-configuration: | + + {"apiVersion":"cert-manager.io/v1","kind":"Certificate","metadata":{"annotations":{},"name":"test-minimal","namespace":"default"},"spec":{"dnsNames":["example.com"]}} + + creationTimestamp: "2024-01-12T17:44:08Z" + + generation: 1 + name: test-minimal + namespace: default + + uid: 792d29c7-8cf3-4f3a-9f12-4fba396e0d6e + spec: + dnsNames: + - example.com + + issuerRef: + + group: cert-manager.io + + kind: ClusterIssuer + + name: our-corp-issuer + + privateKey: + + algorithm: ECDSA + + encoding: PKCS1 + + rotationPolicy: Always + + size: 521 + + revisionHistoryLimit: 2 + + secretName: test-minimal-cert + ``` + + See how we have automatically populated the `spec.issuerRef` and `spec.secretName` field values. + This indicates the Kyverno `ClusterPolicy` has been applied to the supplied `Certificate` resource. + +1. To be absolutely sure we have not enforced any settings, let us explicitly set each property of the `Certificate` for which we have a default rule. We will use the "test-revision-override" `Certificate`: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/cert-test-revision-override.yaml + ``` + 🔗 `cert-test-revision-override.yaml` + +1. *Dry-run apply* and `diff` this file: + + ```shell + kubectl apply -f cert-test-revision-override.yaml --dry-run=server -o yaml | diff -uZ cert-test-revision-override.yaml - + ``` + + This command should return some output similar to this example: + + ```yaml + --- cert-test-revision-override.yaml 2024-01-05 14:45:14.972562067 +0000 + +++ - 2024-01-12 17:45:48.261997150 +0000 + @@ -1,8 +1,14 @@ + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + + annotations: + + kubectl.kubernetes.io/last-applied-configuration: | + + {"apiVersion":"cert-manager.io/v1","kind":"Certificate","metadata":{"annotations":{},"name":"test-revision-override","namespace":"default"},"spec":{"dnsNames":["example.com"],"issuerRef":{"group":"cert-manager.io","kind":"ClusterIssuer","name":"not-my-corp-issuer"},"privateKey":{"algorithm":"RSA","encoding":"PKCS8","rotationPolicy":"Never","size":4096},"revisionHistoryLimit":44,"secretName":"test-revision-override-cert"}} + + creationTimestamp: "2024-01-12T17:45:48Z" + + generation: 1 + name: test-revision-override + namespace: default + + uid: d0ad7abe-c703-45f7-acf9-634b3a263cfa + spec: + dnsNames: + - example.com + ``` + + From this command you can see that none of the `Certificate` specification fields have been changed. + Only the metadata section has changed which tells us the policies have applied but not set any defaults because values were already provided. + This shows that you retain the flexibility to override the cluster defaults when needed. + +## 3 - Defaulting through Ingress Annotations + +Many cert-manager users don't create `Certificate` resources directly and instead use the [ingress-shim](https://cert-manager.io/docs/usage/ingress/) functionality. +cert-manager creates `Certificate` resources based on the [supported annotations](https://cert-manager.io/docs/usage/ingress/#supported-annotations) and the `Ingress` specification. +Let's see how we can still use `ClusterPolicy` to apply our defaults in this use case. + +1. This example `Ingress` resource has a `cert-manager.io/cluster-issuer` annotation which instructs cert-manager to create a `Certificate` with an `issuerRef` field pointing at a `ClusterIssuer` called `our-corp-issuer`: + + ```yaml file=../../../../public/docs/tutorials/certificate-defaults/ingress.yaml + ``` + 🔗 `ingress.yaml` + +1. This annotation and the relevant `ingress.spec.tls` configuration are all we need so apply the resource: + + ```shell + kubectl apply -f ingress.yaml + ``` + +1. Now validate that the `Certificate` resource was automatically generated: + + ```shell + kubectl get cert defaults-example-certificate-tls -o yaml + ``` + + This command should return some output similar to this example: + + ```yaml + apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + creationTimestamp: "2024-01-12T17:47:04Z" + generation: 1 + name: defaults-example-certificate-tls + namespace: default + ownerReferences: + - apiVersion: networking.k8s.io/v1 + blockOwnerDeletion: true + controller: true + kind: Ingress + name: defaults-example + uid: bea33a55-a9ed-4664-a56a-a679eb8272c3 + resourceVersion: "584260" + uid: 43ced989-723b-4eac-bad0-f8bead6976df + spec: + dnsNames: + - app.example.com + issuerRef: + group: cert-manager.io + kind: ClusterIssuer + name: our-corp-issuer + privateKey: + algorithm: ECDSA + encoding: PKCS1 + rotationPolicy: Always + size: 521 + revisionHistoryLimit: 2 + secretName: defaults-example-certificate-tls + usages: + - digital signature + - key encipherment + status: + conditions: + - lastTransitionTime: "2024-01-12T17:47:04Z" + message: Issuing certificate as Secret does not exist + observedGeneration: 1 + reason: DoesNotExist + status: "True" + type: Issuing + - lastTransitionTime: "2024-01-12T17:47:04Z" + message: Issuing certificate as Secret does not exist + observedGeneration: 1 + reason: DoesNotExist + status: "False" + type: Ready + nextPrivateKeySecretName: defaults-example-certificate-tls-nbjws + ``` + +1. You can optionally validate that the "mutate-certificates" `ClusterPolicy` has been applied by viewing the logs of the Kyverno admission controller container. + + ```shell + kubectl logs -n kyverno-system $(kubectl get pod -n kyverno-system -l app.kubernetes.io/component=admission-controller -o jsonpath='{.items[0].metadata.name}') -c kyverno --tail 3 + ``` + + This command should return some output similar to this example: + + ```log + I0112 17:47:04.425863 1 mutation.go:113] webhooks/resource/mutate "msg"="mutation rules from policy applied successfully" "clusterroles"=["cert-manager-controller-approve:cert-manager-io","cert-manager-controller-certificates","cert-manager-controller-certificatesigningrequests","cert-manager-controller-challenges","cert-manager-controller-clusterissuers","cert-manager-controller-ingress-shim","cert-manager-controller-issuers","cert-manager-controller-orders","system:basic-user","system:discovery","system:public-info-viewer","system:service-account-issuer-discovery"] "gvk"={"group":"cert-manager.io","version":"v1","kind":"Certificate"} "gvr"={"group":"cert-manager.io","version":"v1","resource":"certificates"} "kind"="Certificate" "name"="defaults-example-certificate-tls" "namespace"="default" "operation"="UPDATE" "policy"="mutate-certificates" "resource.gvk"={"Group":"cert-manager.io","Version":"v1","Kind":"Certificate"} "roles"=["kube-system:cert-manager:leaderelection"] "rules"=["set-revisionHistoryLimit","set-privateKey-rotationPolicy","set-privateKey-details"] "uid"="6f93bd8d-29ca-4eab-8e96-065ea82a1bf2" "user"={"username":"system:serviceaccount:cert-manager:cert-manager","uid":"21cbad67-9d2e-44ee-bb02-7fef9aa2e502","groups":["system:serviceaccounts","system:serviceaccounts:cert-manager","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["cert-manager-648cd49b44-z6g8s"],"authentication.kubernetes.io/pod-uid":["4bd741fa-a8ec-48a1-82d5-26c5b7acce5e"]}} + I0112 17:47:04.458402 1 mutation.go:113] webhooks/resource/mutate "msg"="mutation rules from policy applied successfully" "clusterroles"=["cert-manager-controller-approve:cert-manager-io","cert-manager-controller-certificates","cert-manager-controller-certificatesigningrequests","cert-manager-controller-challenges","cert-manager-controller-clusterissuers","cert-manager-controller-ingress-shim","cert-manager-controller-issuers","cert-manager-controller-orders","system:basic-user","system:discovery","system:public-info-viewer","system:service-account-issuer-discovery"] "gvk"={"group":"cert-manager.io","version":"v1","kind":"Certificate"} "gvr"={"group":"cert-manager.io","version":"v1","resource":"certificates"} "kind"="Certificate" "name"="defaults-example-certificate-tls" "namespace"="default" "operation"="UPDATE" "policy"="mutate-certificates" "resource.gvk"={"Group":"cert-manager.io","Version":"v1","Kind":"Certificate"} "roles"=["kube-system:cert-manager:leaderelection"] "rules"=["set-revisionHistoryLimit","set-privateKey-rotationPolicy","set-privateKey-details"] "uid"="ec61a3c9-df0a-4daf-8bc3-227dc80348a9" "user"={"username":"system:serviceaccount:cert-manager:cert-manager","uid":"21cbad67-9d2e-44ee-bb02-7fef9aa2e502","groups":["system:serviceaccounts","system:serviceaccounts:cert-manager","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["cert-manager-648cd49b44-z6g8s"],"authentication.kubernetes.io/pod-uid":["4bd741fa-a8ec-48a1-82d5-26c5b7acce5e"]}} + I0112 17:47:09.477776 1 mutation.go:113] webhooks/resource/mutate "msg"="mutation rules from policy applied successfully" "clusterroles"=["cert-manager-controller-approve:cert-manager-io","cert-manager-controller-certificates","cert-manager-controller-certificatesigningrequests","cert-manager-controller-challenges","cert-manager-controller-clusterissuers","cert-manager-controller-ingress-shim","cert-manager-controller-issuers","cert-manager-controller-orders","system:basic-user","system:discovery","system:public-info-viewer","system:service-account-issuer-discovery"] "gvk"={"group":"cert-manager.io","version":"v1","kind":"Certificate"} "gvr"={"group":"cert-manager.io","version":"v1","resource":"certificates"} "kind"="Certificate" "name"="defaults-example-certificate-tls" "namespace"="default" "operation"="UPDATE" "policy"="mutate-certificates" "resource.gvk"={"Group":"cert-manager.io","Version":"v1","Kind":"Certificate"} "roles"=["kube-system:cert-manager:leaderelection"] "rules"=["set-revisionHistoryLimit","set-privateKey-rotationPolicy","set-privateKey-details"] "uid"="c4384662-cb2a-49a0-8e83-e590942ec48d" "user"={"username":"system:serviceaccount:cert-manager:cert-manager","uid":"21cbad67-9d2e-44ee-bb02-7fef9aa2e502","groups":["system:serviceaccounts","system:serviceaccounts:cert-manager","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["cert-manager-648cd49b44-z6g8s"],"authentication.kubernetes.io/pod-uid":["4bd741fa-a8ec-48a1-82d5-26c5b7acce5e"]}} + ``` + + Taking the last line as an example you can pull out: + + ```log + "kind"="Certificate" "name"="defaults-example-certificate-tls" "namespace"="default" "operation"="UPDATE" "policy"="mutate-certificates" "resource.gvk"={"Group":"cert-manager.io","Version":"v1","Kind":"Certificate"} "roles"=["kube-system:cert-manager:leaderelection"] "rules"=["set-revisionHistoryLimit","set-privateKey-rotationPolicy","set-privateKey-details"] + ``` + + See the `policy` key indicates that our policy has been applied. + In the `rules` section you can identify that three of our five rules have been applied to the generated "defaults-example-certificate-tls" `Certificate` resource. + +When using an `Ingress` resource, you always need to specify the `secretName` from which to load the certificate. +No defaulting is required in this use case because this is a required part of the `Ingress` specification. + +The only additional YAML that a user is required to specify on the `Ingress` resource is the annotation: + +```yaml +cert-manager.io/cluster-issuer: "our-corp-issuer" +``` + +This annotation serves as both the trigger for cert-manager to act upon this `Ingress` and also as the configuration value for the `Certificate.spec.issuerRef` fields. +This single line replaces the need for the user to create a `Certificate` resource entirely. +This results in a reduction of the total YAML required to secure the application behind this `Ingress`. + +# Summary + +This is a fairly simple example of how easy it can be to setup *defaults* for your cluster `Certificate` resources. +We've shown how a `ClusterPolicy` doesn't have to "enforce" settings, rather it can be used to set and extend the default options. +`Certificate` users can reduce their YAML, whilst maintaining the flexibility to override any value when needed. + +We have shown how a simple `ClusterPolicy` with only 5 rules can change the user experience creating `Certificate` resources from: + +```yaml file=../../../../public/docs/tutorials/certificate-defaults/cert-test-revision-override.yaml +``` +🔗 `cert-test-revision-override.yaml` + +To instead only need to specify the configuration important to them, for example: + +```yaml file=../../../../public/docs/tutorials/certificate-defaults/cert-test-minimal.yaml +``` +🔗 `cert-test-minimal.yaml` + +With this policy we achieved our objective and have enabled users to submit minimal `Certifiate` resources. +This completes our fifth [use case](#use-cases), with only a single field contained within the specification, the `dnsNames` entry. +Every other specified field was automatically defaulted using Kyverno with `ClusterPolicy` which would typically be setup by a platform administrator. + +# Cleanup + +If you created the kind cluster for this tutorial you can simply run: + +```shell +kind delete cluster --name defaults +``` + +Otherwise to remove all resources deployed in this tutorial: + +```shell +# Assuming you are running from this directly or saved all the files to yamls/ +kubectl delete -f ingress.yaml +kubectl delete -f cpol-mutate-certificates-1.yaml +helm uninstall kyverno -n kyverno-system +helm uninstall cert-manager -n cert-manager +helm uninstall ingress-nginx -n ingress-nginx +``` + +# Appendix + +## cert-manager version requirement + +The behavior of cert-manager's mutating webhook has been changed from v1.14.x onward. +For a more complete explanation and details of the change please refer to [PR #6311](https://github.com/cert-manager/cert-manager/pull/6311). +Instructions for a manual fix can be found [in this comment on PR #6311](https://github.com/cert-manager/cert-manager/pull/6311#issuecomment-1889517418). + +## Presets Feature Request + +For further background reading around setting "defaults" or "presets", you can refer to [issue 2239](https://github.com/cert-manager/cert-manager/issues/2239). +This tutorial came out of an investigation of that issue. + +The cert-manager team reasoned that the requested solution could be achieved with the use of other, more generic open-source policy tools. +Kyverno is just one example and similar can be achieved with [Gatekeeper](https://github.com/open-policy-agent/gatekeeper) as an alternative tool. diff --git a/content/v1.15-docs/tutorials/getting-started-aks-letsencrypt/README.md b/content/v1.15-docs/tutorials/getting-started-aks-letsencrypt/README.md new file mode 100644 index 0000000000..bfe5229148 --- /dev/null +++ b/content/v1.15-docs/tutorials/getting-started-aks-letsencrypt/README.md @@ -0,0 +1,688 @@ +--- +title: Deploy cert-manager on Azure Kubernetes Service (AKS) and use Let's Encrypt to sign a certificate for an HTTPS website +description: | + Learn how to deploy cert-manager on Azure Kubernetes Service (AKS) + and configure it to get a signed certificate from Let's Encrypt for an HTTPS web server, + using the DNS-01 protocol and Azure DNS with workload identity federation. +--- + +*Last Verified: 11 January 2024* + +In this tutorial you will learn how to deploy and configure cert-manager on Azure Kubernetes Service (AKS) +and how to deploy an HTTPS web server and make it available on the Internet. +You will learn how to configure cert-manager to get a signed certificate from Let's Encrypt, +which will allow clients to connect to your HTTPS website securely. +You will configure cert-manager to use the [Let's Encrypt DNS-01 challenge protocol](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) with Azure DNS, +using workload identity federation to authenticate to Azure. + +> **Microsoft Azure**: A suite of cloud computing services by Microsoft.
          +> **Kubernetes**: Runs on your servers. Automates the deployment, scaling, and management of containerized applications.
          +> **cert-manager**: Runs in Kubernetes. Obtains TLS / SSL certificates and ensures the certificates are valid and up-to-date.
          +> **Let’s Encrypt**: An Internet service. Allows you to generate free short-lived SSL certificates. + +# Part 1 + +In the first part of this tutorial you will learn the basics required to deploy an HTTPS website on an Azure Kubernetes cluster using cert-manager to create the SSL certificate for the web server. +You will create a DNS domain for your website, create an Azure Kubernetes cluster, install cert-manager, create an SSL certificate and then deploy a web server which responds to HTTPS requests from clients on the Internet. +But the SSL certificate in part 1 is only for testing purposes. + +In part 2 you will learn how to configure cert-manager to use Let's Encrypt and Azure DNS to create a trusted SSL certificate which you can use in production. + +## Configure the Azure CLI (`az`) + +If your have not already done so, [download and install the Azure CLI (`az`)](https://learn.microsoft.com/en-us/cli/azure/). + +Set up the `az` command for interactive use: + +```bash +az init +``` + +Log in, if you have not already done so: + +```bash +az login +``` + +Set the default resource group and location: + +```bash +export AZURE_DEFAULTS_GROUP=your-resource-group # ❗ Your Azure resource group +export AZURE_DEFAULTS_LOCATION=eastus2 # ❗ Your Azure location. +``` + +> ℹ️ You will need an `az` version `>=2.40.0`. Run `az version` to print the current version. +> +> ℹ️ When you run `az init`, choose "Optimize for interaction" when prompted. +> +> ℹ️ When you run `az login`, a web browser will be opened at https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize. +> Continue the login in the web browser and then return to your terminal. +>> +> 📖 Read the [Azure Command-Line Interface (CLI) documentation](https://learn.microsoft.com/en-us/cli/azure/). +> +> 📖 Read [CLI configuration values and environment variables](https://learn.microsoft.com/en-us/cli/azure/azure-cli-configuration?source=recommendations#cli-configuration-values-and-environment-variables) for more ways to configure the `az` defaults. + +## Create a public domain name + +In this tutorial you will deploy an HTTPS website with a publicly accessible domain name, so you will need to register a domain unless you already have one. +You could use any [domain name registrar](https://www.cloudflare.com/en-gb/learning/dns/glossary/what-is-a-domain-name-registrar/) to register a domain name for your site. +Here we will use a registrar called `Gandi` and register a cheap domain name for the purposes of this tutorial. +We will use the domain name: `cert-manager-tutorial-22.site` but you should choose your own. + +Now that you know your domain name, save it in an environment variable: + +```bash +export DOMAIN_NAME=cert-manager-tutorial-22.site # ❗ Replace this with your own DNS domain name +``` + +And add it to Azure DNS as a zone: + +```bash +az network dns zone create --name $DOMAIN_NAME +``` + +Log in to the control panel for your domain registrar and set the NS records for your domain to match the DNS names of the Azure [authoritative DNS servers](https://www.cloudflare.com/en-gb/learning/dns/dns-server-types/). +You can find these by looking for the NS records of your Azure hosted DNS zone: + +```bash +az network dns zone show --name $DOMAIN_NAME --output yaml +``` + +You can check that the NS records have been updated using `dig` to "trace" the hierarchy of NS records, +rather than using your local DNS resolver: + +```bash +dig $DOMAIN_NAME ns +trace +nodnssec +``` + +> ⏲ It **may** take more than 1 hour for the NS records to be updated in the parent zone, +> and it may take some time for the old NS records to be replaced in the caches of DNS resolver servers, +> if you looked up the DNS name before updating the NS records. +> +> 📖 Read [How do I Update My DNS Records?](https://docs.gandi.net/en/domain_names/common_operations/dns_records.html) in the `Gandi.net` docs, +> or seek the equivalent documentation for your own domain name registrar. + +## Create a Kubernetes cluster + +To get started, let's create a Kubernetes cluster in Microsoft Azure. +You will need to pick a name for your cluster. +Here, we will go with "test-cluster-1". +Save it in an environment variable: + +```bash +export CLUSTER=test-cluster-1 +``` + +Now, create the cluster using the following command: + +```bash +az aks create \ + --name ${CLUSTER} \ + --node-count 1 \ + --node-vm-size "Standard_B2s" \ + --load-balancer-sku basic +``` + +Update your `kubectl` config file with the credentials for your new cluster: + +```bash +az aks get-credentials --admin --name "$CLUSTER" +``` + +Now check that you can connect to the cluster: + +```bash +kubectl get nodes -o wide +``` + +> ⏲ It will take 4-5 minutes to create the cluster. +> +> 💵 To minimize your cloud bill, this command creates a 1-node cluster using a +> low cost virtual machine and load balancer. +> +> ⚠️ This cluster is only suitable for learning purposes it is not suitable for production use. +> +> 📖 Read [Run Kubernetes in Azure the Cheap Way](https://trstringer.com/cheap-kubernetes-in-azure/) for more cost saving tips. +> + +## Install cert-manager + +Now you can install and configure cert-manager. + +Install cert-manager using `helm` as follows: + +```bash +helm repo add jetstack https://charts.jetstack.io --force-update +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version [[VAR::cert_manager_latest_version]] \ + --set crds.enabled=true +``` + +This will create three Deployments and some Services and Pods in a new namespace called `cert-manager`. +It also installs various cluster scoped supporting resources such as RBAC roles and Custom Resource Definitions. + +You can view some of the resources that have been installed as follows: + +```bash +kubectl -n cert-manager get all +``` + +And you can explore the Custom Resource Definitions (cert-manager's API) using `kubectl explain`, as follows: + +```bash +kubectl explain Certificate +kubectl explain CertificateRequest +kubectl explain Issuer +``` + +> 📖 Read about [other ways to install cert-manager](../../installation/README.md). +> +> 📖 Read more about [Certificates and Issuers](../../concepts/README.md). + +## Create a test ClusterIssuer and a Certificate + +Now everything is ready for you to create your first certificate. +This will be a self-signed certificate but later we'll replace it with a Let's Encrypt signed certificate. + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/clusterissuer-selfsigned.yaml +``` +🔗 `clusterissuer-selfsigned.yaml` + +```bash +kubectl apply -f clusterissuer-selfsigned.yaml +``` + +Then use `envsubst` to substitute your chosen domain name into the following Certificate template: + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/certificate.yaml +``` +🔗 `certificate.yaml` + +```bash +envsubst < certificate.yaml | kubectl apply -f - +``` + +> 🔗 If you don't already have `envsubst` installed you can [download and install a Go implementation of `envsubst`](https://github.com/a8m/envsubst). + +Use `cmctl status certificate` to check the status of the Certificate: + +```bash +cmctl status certificate www +``` + +If successful, the private key and the signed certificate will be stored in a Secret called `www-tls`. +You can use `cmctl inspect secret www-tls` to decode the base64 encoded X.509 content of the Secret: + +```terminal +$ cmctl inspect secret www-tls +... +Valid for: + DNS Names: + - www.cert-manager-tutorial-22.site + URIs: + IP Addresses: + Email Addresses: + Usages: + - digital signature + - key encipherment + - server auth +... +``` + +## Deploy a sample web server + +Now deploy a simple web server which responds to HTTPS requests with "hello world!". +The SSL / TLS key and certificate are supplied to the web server by using the `www-tls` Secret as a volume +and by mounting its contents into the file system of the `hello-app` container in the Pod: + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/deployment.yaml +``` +🔗 `deployment.yaml` + +```bash +kubectl apply -f deployment.yaml +``` + +You also need to create a Kubernetes LoadBalancer Service, so that connections from the Internet can be routed to the web server Pod. +When you create the following Kubernetes Service, an Azure load balancer with an ephemeral public IP address will also be created: + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/service.yaml +``` +🔗 `service.yaml` + +Create a unique DNS name for the LoadBalancer Service and then apply it: +```bash +export AZURE_LOADBALANCER_DNS_LABEL_NAME=lb-$(uuidgen) # ❗ The label must start with a lowercase ASCII letter +envsubst < service.yaml | kubectl apply -f - +``` + +Within 2-3 minutes, a load balancer should have been provisioned with a public IP. + +```bash +kubectl get service helloweb +``` + +Sample output + +```terminal +$ kubectl get service helloweb +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +helloweb LoadBalancer 10.0.141.1 20.114.151.62 443:30394/TCP 7m15s +``` + +The `EXTERNAL-IP` will be different for you and it may be different each time you re-create the LoadBalancer service, +but it will have a stable DNS host name associated with it +because you annotated the Service with `azure-dns-label-name`. +This stable DNS hostname can be used as an alias for your chosen `$DOMAIN_NAME` by creating a [DNS CNAME record](https://www.cloudflare.com/en-gb/learning/dns/dns-records/dns-cname-record/): + +```bash +az network dns record-set cname set-record \ + --zone-name $DOMAIN_NAME \ + --cname $AZURE_LOADBALANCER_DNS_LABEL_NAME.$AZURE_DEFAULTS_LOCATION.cloudapp.azure.com \ + --record-set-name www +``` + +Check that `www.$DOMAIN_NAME` now resolves to the ephemeral public IP address of the load balancer: + +```terminal +$ dig www.$DOMAIN_NAME A +... +;; QUESTION SECTION: +;www.cert-manager-tutorial-22.site. IN A +... +;; ANSWER SECTION: +www.cert-manager-tutorial-22.site. 3600 IN CNAME lb-ec8776e1-d067-4d4c-8cce-fdf07ce48260.eastus2.cloudapp.azure.com. +lb-ec8776e1-d067-4d4c-8cce-fdf07ce48260.eastus2.cloudapp.azure.com. 10 IN A 20.122.27.189 +... +``` + +If the DNS is correct and the load balancer is working and the hello world web server is running, +you should now be able to connect to it using curl or using your web browser: + +```bash +curl --insecure -v https://www.$DOMAIN_NAME +``` + +> ⚠️ We used curl's `--insecure` option because it rejects self-signed certificates by default. +> Later you will learn how to create a trusted certificate signed by Let's Encrypt. + +You should see that the certificate has the expected DNS names and that it is self-signed: + +```terminal +... +* Server certificate: +* subject: CN=www.cert-manager-tutorial-22.site +* start date: Jan 4 15:28:30 2023 GMT +* expire date: Apr 4 15:28:30 2023 GMT +* issuer: CN=www.cert-manager-tutorial-22.site +* SSL certificate verify result: self-signed certificate (18), continuing anyway. +... +Hello, world! +Protocol: HTTP/2.0! +Hostname: helloweb-55cb4cd887-tjlvh +``` + +> 📖 Read more about [Using a Service to Expose Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/). +> +> 📖 Read more about [Using a public IP address and DNS label with the Azure Kubernetes Service (AKS) load balancer](https://learn.microsoft.com/en-us/azure/aks/static-ip). + +# Part 2 + +In part 1 you created a test certificate. +Now you will learn how to configure cert-manager to use Let's Encrypt and Azure DNS to create a trusted certificate which you can use in production. +You need to prove to Let's Encrypt that you own the domain name of the certificate and one way to do this is to create a special DNS record in that domain. +This is known as the [DNS-01 challenge type](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge). + +cert-manager can create that DNS record for you in by using the Azure DNS API but it needs to authenticate to Azure first, +and currently the most secure method of authentication is to use [workload identity federation](https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview). +The advantages of this method are that cert-manager will use an ephemeral Kubernetes ServiceAccount Token to authenticate to Azure and the token need not be stored in a Kubernetes Secret. + +> ℹ️ cert-manager `>= v1.11.0` supports workload identity federation for ACME (Let's Encrypt) DNS-01 with Azure DNS. +> Older versions of cert-manager support other authentication mechanisms which are not covered in this tutorial. +> +> 📖 Read about [other ways to configure the ACME issuer with Azure DNS](../../configuration/acme/dns01/azuredns.md). + +## Install the Azure workload identity features + +The workload identity features in Azure AKS are relatively new (at time of writing) and they require some non-default features to be enabled. + +Install the [Azure CLI AKS Preview Extension](https://github.com/Azure/azure-cli-extensions/tree/main/src/aks-preview), +which you will need to configure some advanced workload identity federation features on your AKS cluster. + +```bash +az extension add --name aks-preview +``` + +Register the `EnableWorkloadIdentityPreview` feature flag which is required for the AKS cluster in this demo. + +```bash +az feature register --namespace "Microsoft.ContainerService" --name "EnableWorkloadIdentityPreview" + +# It takes a few minutes for the status to show Registered. Verify the registration status by using the az feature list command: +az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/EnableWorkloadIdentityPreview')].{Name:name,State:properties.state}" + +# When ready, refresh the registration of the Microsoft.ContainerService resource provider by using the az provider register command: +az provider register --namespace Microsoft.ContainerService +``` + +> 📖 Read more about [Registering the `EnableWorkloadIdentityPreview` feature flag](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster). + +## Reconfigure the cluster + +Next enable the workload identity federation features on the cluster that you created earlier: + +```bash +az aks update \ + --name ${CLUSTER} \ + --enable-oidc-issuer \ + --enable-workload-identity # ℹ️ This option is currently only available when using the aks-preview extension. +``` + +> 📖 Read [Deploy and configure workload identity on an Azure Kubernetes Service (AKS) cluster](https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster) for more information about the `--enable-workload-identity` feature. + +## Reconfigure cert-manager + +We will label the cert-manager controller Pod and ServiceAccount for the attention of the Azure Workload Identity webhook, +which will result in the cert-manager controller Pod having an extra volume containing a Kubernetes ServiceAccount token which it will use to authenticate with Azure. + +The labels can be configured using the Helm values file below: + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/values.yaml +``` +🔗 `values.yaml` + +```bash +existing_cert_manager_version=$(helm get metadata -n cert-manager cert-manager | grep '^VERSION' | awk '{ print $2 }') +helm upgrade cert-manager jetstack/cert-manager \ + --reuse-values \ + --namespace cert-manager \ + --version $existing_cert_manager_version \ + --values values.yaml +``` + +The newly rolled out cert-manager Pod will have some new environment variables set, +and the Azure workload-identity ServiceAccount token as a projected volume: + +```bash +kubectl describe pod -n cert-manager -l app.kubernetes.io/component=controller +``` + +```terminal +Containers: + ... + cert-manager-controller: + ... + Environment: + ... + AZURE_CLIENT_ID: + AZURE_TENANT_ID: f99bd6a4-665c-41cf-aff1-87a89d5c62d4 + AZURE_FEDERATED_TOKEN_FILE: /var/run/secrets/azure/tokens/azure-identity-token + AZURE_AUTHORITY_HOST: https://login.microsoftonline.com/ + Mounts: + /var/run/secrets/azure/tokens from azure-identity-token (ro) +Volumes: + ... + azure-identity-token: + Type: Projected (a volume that contains injected data from multiple sources) + TokenExpirationSeconds: 3600 +``` + +> 📖 Read about [the role of the Mutating Admission Webhook](https://azure.github.io/azure-workload-identity/docs/installation/mutating-admission-webhook.html) in Azure AD Workload Identity for Kubernetes. +> +> 📖 Read about [other values that can be customized in the cert-manager Helm chart](https://artifacthub.io/packages/helm/cert-manager/cert-manager?modal=values). + +## Create an Azure Managed Identity + +When cert-manager creates a certificate using Let's Encrypt +it can use DNS records to prove that it controls the DNS domain names in the certificate. +In order for cert-manager to use the Azure API and manipulate the records in the Azure DNS zone, +it needs an Azure account and the best type of account to use is called a "Managed Identity". +This account does not come with a password or an API key and it is designed for use by machines rather than humans. + +Choose a managed identity name: + +```bash +export USER_ASSIGNED_IDENTITY_NAME=cert-manager-tutorials-1 # ❗ Replace with your preferred managed identity name +``` + +Create the Managed Identity: + +```bash +az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" +``` + +Grant it permission to modify the DNS zone records: + +```bash +export USER_ASSIGNED_IDENTITY_CLIENT_ID=$(az identity show --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -o tsv) +az role assignment create \ + --role "DNS Zone Contributor" \ + --assignee $USER_ASSIGNED_IDENTITY_CLIENT_ID \ + --scope $(az network dns zone show --name $DOMAIN_NAME -o tsv --query id) +``` + +> 📖 Read [What are managed identities for Azure resources?](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview) +> for an overview of managed identities and their uses. +> +> 📖 Read [Azure built-in roles](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles) to learn about the "DNS Zone Contributor" role. + +## Add a federated identity + +Now we will configure Azure to trust certain Kubernetes ServiceAccount tokens, +in particular, the service account tokens from our specific Kubernetes cluster, +and only tokens which are associated with the cert-manager ServiceAccount. +cert-manager will authenticate to Azure using an short lived Kubernetes ServiceAccount token, +and it will be able to impersonate the managed identity that you created in the previous step. + +First export the following environment variables containing the name and namespace of the Kubernetes ServiceAccount used by the cert-manager controller: + +```bash +export SERVICE_ACCOUNT_NAME=cert-manager # ℹ️ This is the default Kubernetes ServiceAccount used by the cert-manager controller. +export SERVICE_ACCOUNT_NAMESPACE=cert-manager # ℹ️ This is the default namespace for cert-manager. +``` + +Then configure the managed identity to trust the cert-manager Kubernetes ServiceAccount, +by supplying its "subject" (the distinguishing name of the Kubernetes ServiceAccount) +and its "issuer" (a URL at which the JWT signing certificate and other metadata can be downloaded): + +```bash +export SERVICE_ACCOUNT_ISSUER=$(az aks show --resource-group $AZURE_DEFAULTS_GROUP --name $CLUSTER --query "oidcIssuerProfile.issuerUrl" -o tsv) +az identity federated-credential create \ + --name "cert-manager" \ + --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \ + --issuer "${SERVICE_ACCOUNT_ISSUER}" \ + --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}" +``` + +> 📖 Read about [Workload identity federation](https://learn.microsoft.com/en-us/azure/active-directory/develop/workload-identity-federation) in the Microsoft identity platform documentation. + + +## Create a ClusterIssuer for Let's Encrypt Staging + +A ClusterIssuer is a custom resource which tells cert-manager how to sign a Certificate. +In this case the ClusterIssuer will be configured to connect to the Let's Encrypt staging server, +which allows us to test everything without using up our Let's Encrypt certificate quota for the domain name. + +Save the following content to a file called `clusterissuer-lets-encrypt-staging.yaml`, change the `email` field to use your email address and apply it: + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/clusterissuer-lets-encrypt-staging.yaml +``` +🔗 `clusterissuer-lets-encrypt-staging.yaml` + + +As you can see there are some variables in the `clusterissuer-lets-encrypt-staging.yaml` which need to be filled in before we apply it; +most have been defined earlier in this tutorial but you need to set the following: + +```bash +export EMAIL_ADDRESS= # ❗ Replace this with your email address +export AZURE_SUBSCRIPTION= # ❗ Replace this with your Azure account name +``` + +Now use `envsubst` to fill in the variables and pipe it into `kubectl apply`, as follows: + +```bash +export AZURE_SUBSCRIPTION_ID=$(az account show --name $AZURE_SUBSCRIPTION --query 'id' -o tsv) +envsubst < clusterissuer-lets-encrypt-staging.yaml | kubectl apply -f - +``` + +You can check the status of the ClusterIssuer: + +```bash +kubectl describe clusterissuer letsencrypt-staging +``` + +Example output + +```console +Status: + Acme: + Last Registered Email: firstname.lastname@example.com + Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/77882854 + Conditions: + Last Transition Time: 2022-11-29T13:05:33Z + Message: The ACME account was registered with the ACME server + Observed Generation: 1 + Reason: ACMEAccountRegistered + Status: True + Type: Ready +``` + +> ℹ️ Let's Encrypt uses the Automatic Certificate Management Environment (ACME) protocol +> which is why the configuration above is under a key called `acme`. +> +> ℹ️ The email address is only used by Let's Encrypt to remind you to renew the certificate after 30 days before expiry. You will only receive this email if something goes wrong when renewing the certificate with cert-manager. +> +> ℹ️ The Let's Encrypt production issuer has [very strict rate limits](https://letsencrypt.org/docs/rate-limits/). +> When you're experimenting and learning, it can be very easy to hit those limits. Because of that risk, +> we'll start with the Let's Encrypt staging issuer, and once we're happy that it's working +> we'll switch to the production issuer. +> +> 📖 Read more about [configuring the ACME Issuer](../../configuration/acme/README.md). +> + + +## Re-issue the Certificate using Let's Encrypt + +Patch the Certificate to use the staging ClusterIssuer: + +```bash +kubectl patch certificate www --type merge -p '{"spec":{"issuerRef":{"name":"letsencrypt-staging"}}}' +``` + +That should trigger cert-manager to renew the certificate: +Use `cmctl` to check: + +```bash +cmctl status certificate www +cmctl inspect secret www-tls +``` + +And finally, when the new certificate has been issued, you must restart the web server to use it: + +```bash +kubectl rollout restart deployment helloweb +``` + +You should once again be able to connect to the website, but this time you will see the Let's Encrypt staging certificate: + +```terminal +$ curl -v --insecure https://www.$DOMAIN_NAME +... +* Server certificate: +* subject: CN=www.cert-manager-tutorial-22.site +* start date: Jan 5 12:41:14 2023 GMT +* expire date: Apr 5 12:41:13 2023 GMT +* issuer: C=US; O=(STAGING) Let's Encrypt; CN=(STAGING) Artificial Apricot R3 +* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. +... +Hello, world! +Protocol: HTTP/2.0! +Hostname: helloweb-9b8bcdd56-6rxm8 +``` + +> ⚠️ We used curl's `--insecure` option again here because the Let's Encrypt staging issuer creates untrusted certificates. +> Next you will learn how to create a trusted certificate signed by the Let's Encrypt production issuer. + +## Create a production ready certificate + +Now that everything is working with the Let's Encrypt staging server, we can switch to the production server and get a trusted certificate. + +Create a Let's Encrypt production Issuer by copying the staging ClusterIssuer YAML and modifying the server URL and the names, +then apply it: + +```yaml file=../../../../public/docs/tutorials/getting-started-aks-letsencrypt/clusterissuer-lets-encrypt-production.yaml +``` +🔗 `clusterissuer-lets-encrypt-production.yaml` + + +```bash +envsubst < clusterissuer-lets-encrypt-production.yaml | kubectl apply -f - +``` + +Check the status of the ClusterIssuer: + +```bash +kubectl describe clusterissuer letsencrypt-production +``` + +Patch the Certificate to use the production ClusterIssuer: + +```bash +kubectl patch certificate www --type merge -p '{"spec":{"issuerRef":{"name":"letsencrypt-production"}}}' +``` + +That should trigger cert-manager to renew the certificate: +Use `cmctl` to check: + +```bash +cmctl status certificate www +cmctl inspect secret www-tls +``` + +And finally, when the new certificate has been issued, you must restart the web server to use it: + +```bash +kubectl rollout restart deployment helloweb +``` + +Now you should be able to connect to the web server securely, without the `--insecure` flag, +and if you visit the site in your web browser, it should show a padlock (🔒) symbol next to the URL. + +```bash +curl -v https://www.$DOMAIN_NAME +``` + +```terminal +... +* Server certificate: +* subject: CN=cert-manager-tutorial-22.site +* start date: Nov 30 15:41:40 2022 GMT +* expire date: Feb 28 15:41:39 2023 GMT +* subjectAltName: host "www.cert-manager-tutorial-22.site" matched cert's "www.cert-manager-tutorial-22.site" +* issuer: C=US; O=Let's Encrypt; CN=R3 +* SSL certificate verify ok. +... +``` + +That concludes this tutorial. +You have learned how to deploy cert-manager on Azure AKS and how to configure it to issue Let's Encrypt signed certificates using the DNS-01 protocol with Azure DNS. +You have learned about workload identity federation in Azure and learned how to configure cert-manager to authenticate to Azure using a Kubernetes ServiceAccount Token. + +## Cleanup + +After completing the tutorial you can clean up by deleting the cluster, the domain name and the managed identity, as follows: + +``` +az aks delete --name $CLUSTER +az network dns zone delete --name $DOMAIN_NAME +az identity delete --name $USER_ASSIGNED_IDENTITY_NAME +``` + +## Next Steps + +> 📖 Read other [cert-manager tutorials](../README.md) and [getting started guides](../../getting-started/README.md). +> +> 📖 Read more about [configuring the cert-manager ACME issuer with Azure DNS](../../configuration/acme/dns01/azuredns.md). diff --git a/content/v1.15-docs/tutorials/getting-started-aws-letsencrypt/README.md b/content/v1.15-docs/tutorials/getting-started-aws-letsencrypt/README.md new file mode 100644 index 0000000000..87110e8d49 --- /dev/null +++ b/content/v1.15-docs/tutorials/getting-started-aws-letsencrypt/README.md @@ -0,0 +1,652 @@ +--- +title: Deploy cert-manager on AWS Elastic Kubernetes Service (EKS) and use Let's Encrypt to sign a TLS certificate for an HTTPS website +description: | + Learn how to deploy cert-manager on AWS Elastic Kubernetes Service (EKS) + and configure it to get a signed TLS (SSL) certificate from Let's Encrypt for an HTTPS web server, + using the DNS-01 protocol and AWS Route53 DNS. +--- + +*Last Verified: 9 September 2024* + +In this tutorial you will learn how to deploy and configure cert-manager on AWS Elastic Kubernetes Service (EKS) +and how to deploy an HTTPS web server and make it available on the Internet. +You will learn how to configure cert-manager to get a signed certificate from Let's Encrypt, +which will allow clients to connect to your HTTPS website securely. +You will configure cert-manager to use the [Let's Encrypt DNS-01 challenge protocol](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) with AWS Route53 DNS, +using IAM Roles for Service Accounts (IRSA) to authenticate to AWS. + +# Part 1 + +In the first part of this tutorial you will learn the basics required to deploy an HTTPS website on an AWS Elastic Kubernetes Service (EKS) cluster, using cert-manager to create the SSL certificate for the web server. +You will create a DNS domain for your website, create an EKS cluster, install cert-manager, create a TLS certificate and then deploy a web server which responds to HTTPS requests from clients on the Internet. +The TLS certificate in part 1 is only for testing purposes; in part 2 you will learn how to configure cert-manager to use Let's Encrypt and Route53 DNS to create a trusted certificate which you can use in production. + +## Configure the AWS CLI (`aws`) + +If your have not already done so, [download and install the AWS CLI (`aws`)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). + +Set up the `aws` command for interactive use: + +```bash +aws configure +``` + +Set the default [output format](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-output-format.html) and region: + +```bash +export AWS_DEFAULT_OUTPUT=json # ❗ Use JSON output for this tutorial +export AWS_DEFAULT_REGION=us-west-2 # ❗ Your AWS region. +``` + +> 📖 Read +> [Set up the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html), and +> [Configure the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html), +> to learn more about configuring `aws`. + +## Create a public domain name + +In this tutorial you will deploy an HTTPS website with a publicly accessible domain name, so you will need to register a domain unless you already have one. +You could use any [domain name registrar](https://www.cloudflare.com/en-gb/learning/dns/glossary/what-is-a-domain-name-registrar/) to register a domain name for your site. +For example you could use `Gandi` and register a cheap domain name for the purposes of this tutorial. + +Now that you know your domain name, save it in an environment variable: + +```bash +export DOMAIN_NAME=example.com # ❗ Replace this with your own DNS domain name +``` + +And add it to AWS Route53 as a zone: + +```bash +aws route53 create-hosted-zone --caller-reference $(uuidgen) --name $DOMAIN_NAME +``` + +The details of the created zone will be printed to the console: + +```json +{ + "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z0984294TRL0R8AT3SQA", + "HostedZone": { + "Id": "/hostedzone/Z0984294TRL0R8AT3SQA", + "Name": "cert-manager-aws-tutorial.richard-gcp.jetstacker.net.", + "CallerReference": "77274711-b648-4da5-81b7-74512897d0db", + "Config": { + "PrivateZone": false + }, + "ResourceRecordSetCount": 2 + }, + "ChangeInfo": { + "Id": "/change/C04685872DX6N6587E1TL", + "Status": "PENDING", + "SubmittedAt": "2024-09-03T16:29:11.960000+00:00" + }, + "DelegationSet": { + "NameServers": [ + "ns-1504.awsdns-60.org", + "ns-538.awsdns-03.net", + "ns-278.awsdns-34.com", + "ns-1765.awsdns-28.co.uk" + ] + } +} +``` + +Log in to the control panel for your domain registrar and set the NS records for your domain to match the DNS names of the [authoritative DNS servers](https://www.cloudflare.com/en-gb/learning/dns/dns-server-types/) for your Route53 hosted zone. +See `NameServers` in the output of `aws route53 create-hosted-zone` (above) or you can find the name servers later: + +```bash +HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name $DOMAIN_NAME --query "HostedZones[0].Id" --output text) +aws route53 get-hosted-zone --id ${HOSTED_ZONE_ID} +``` + +You can check that the NS records have been updated by using `dig` to "trace" the hierarchy of NS records: + +```bash +dig $DOMAIN_NAME ns +trace +nodnssec +``` + +> ⏲ It **may** take more than 1 hour for the NS records to be updated in the parent zone, +> and it may take some time for the old NS records to be replaced in the caches of DNS resolver servers, +> if you looked up the DNS name before updating the NS records. +> +> 📖 Read [How do I Update My DNS Records?](https://docs.gandi.net/en/domain_names/common_operations/dns_records.html) in the `Gandi.net` docs, +> or seek the equivalent documentation for your own domain name registrar. + +## Create an EKS Kubernetes cluster + +To get started, let's create a Kubernetes cluster using EKS. +The easiest way to create an EKS cluster is with `eksctl`. +[Download and install `eksctl`](https://eksctl.io/installation/). + +Pick a name for your cluster and save it in an environment variable: + +```bash +export CLUSTER=test-cluster-1 +``` + +Now, create the cluster using the following command: + +```bash +eksctl create cluster \ + --name $CLUSTER \ + --nodegroup-name node-group-1 \ + --node-type t3.small \ + --nodes 3 \ + --nodes-min 1 \ + --nodes-max 3 \ + --managed \ + --spot +``` + +This will update your `kubectl` config file with the credentials for your new cluster. + +Check that you can connect to the cluster: + +```bash +kubectl get nodes -o wide +``` + +> ⏲ It will take 15-20 minutes to create the cluster. Why? +> See [Reduction in EKS cluster creation time](https://github.com/aws/containers-roadmap/issues/1227). +> +> 💵 To minimize your cloud bill, this command creates a 3-node cluster using +> [low cost virtual machines](https://aws.amazon.com/ec2/instance-types/t3) and +> [spot instances](https://eksctl.io/usage/spot-instances/). +> +> ⚠️ This cluster is only suitable for learning purposes it is not suitable for production use. + +## Install cert-manager + +Now you can install and configure cert-manager. + +Install cert-manager using `helm` as follows: + +```bash +helm install cert-manager cert-manager \ + --repo https://charts.jetstack.io \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true +``` + +This will create three Deployments and some Services and Pods in a new namespace called `cert-manager`. +It also installs various cluster scoped supporting resources such as RBAC roles and Custom Resource Definitions. + +You can view some of the resources that have been installed as follows: + +```bash +kubectl -n cert-manager get all +``` + +And you can explore the Custom Resource Definitions (cert-manager's API) using `kubectl explain`, as follows: + +```bash +kubectl explain Certificate +kubectl explain CertificateRequest +kubectl explain Issuer +``` + +> 📖 Read about [other ways to install cert-manager](../../installation/README.md). +> +> 📖 Read more about [Certificates and Issuers](../../concepts/README.md). + +## Create a test ClusterIssuer and a Certificate + +Now everything is ready for you to create your first certificate. +This will be a self-signed certificate but later we'll replace it with a Let's Encrypt signed certificate. + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/clusterissuer-selfsigned.yaml +``` +🔗 `clusterissuer-selfsigned.yaml` + +```bash +kubectl apply -f clusterissuer-selfsigned.yaml +``` + +Then use `envsubst` to substitute your chosen domain name into the following Certificate template: + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/certificate.yaml +``` +🔗 `certificate.yaml` + +```bash +envsubst < certificate.yaml | kubectl apply -f - +``` + +> 🔗 If you don't already have `envsubst` installed you can [download and install a Go implementation of `envsubst`](https://github.com/a8m/envsubst). + +Use `cmctl status certificate` to check the status of the Certificate: + +```bash +cmctl status certificate www +``` + +If successful, the private key and the signed certificate will be stored in a Secret called `www-tls`. +You can use `cmctl inspect secret www-tls` to decode the base64 encoded X.509 content of the Secret: + +```terminal +$ cmctl inspect secret www-tls +... +Valid for: + DNS Names: + - www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net + URIs: + IP Addresses: + Email Addresses: + Usages: + - digital signature + - key encipherment + - server auth +... +``` + +## Deploy a sample web server + +Now deploy a simple web server which responds to HTTPS requests with "hello world!". +The TLS key and certificate are supplied to the web server by using the `www-tls` Secret as a volume +and by mounting its contents into the file system of the `hello-app` container in the Pod: + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/deployment.yaml +``` +🔗 `deployment.yaml` + +```bash +kubectl apply -f deployment.yaml +``` + +You also need to create a Kubernetes LoadBalancer Service, so that connections from the Internet can be routed to the web server Pod. +When you create the following Kubernetes Service, an AWS classic load balancer with an ephemeral public IP address will also be created: + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/service.yaml +``` +🔗 `service.yaml` + +```bash +kubectl apply -f service.yaml +``` + +Within 2-3 minutes, a load balancer should have been provisioned with a public IP. + +```bash +kubectl get service helloweb +``` + +Sample output + +```terminal +$ kubectl get service helloweb +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +helloweb LoadBalancer 10.100.175.247 ae25d292150aa4e3e90e6c25376f9a7d-496307726.us-west-2.elb.amazonaws.com 443:32184/TCP 6m +``` + +The `EXTERNAL-IP` will be different for you and it may be different each time you re-create the LoadBalancer service, +but it will have a stable DNS host name associated with it. + +> ℹ️ By default, EKS creates [classic](https://aws.amazon.com/elasticloadbalancing/features/#Product_comparisons) +> load balancers for LoadBalancer Services in the cluster, +> using the [Legacy Cloud Provider Load balancer Controller](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html#lbc-legacy). +> This is convenient for this tutorial because it does not require any additional software or configuration, but +> [AWS Cloud Provider Load balancer Controller is legacy and is currently only receiving critical bug fixes](https://aws.github.io/aws-eks-best-practices/networking/loadbalancing/loadbalancing/#choosing-load-balancer-type) +> according to the [EKS Best Practices Guide](https://aws.github.io/aws-eks-best-practices/). +> Consider using the [AWS Load Balancer Controller](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html) instead. + +The stable DNS host name of the load balancer can be used as an alias for the `www` record in your chosen `$DOMAIN_NAME` +by creating a Route53 [Alias Record](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html): + +```bash +HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name $DOMAIN_NAME --query "HostedZones[0].Id" --output text) +ELB_CANONICAL_HOSTED_ZONE_NAME=$(kubectl get svc helloweb --output=jsonpath='{ .status.loadBalancer.ingress[0].hostname }') +aws elb describe-load-balancers --query "LoadBalancerDescriptions[?CanonicalHostedZoneName == '$ELB_CANONICAL_HOSTED_ZONE_NAME'] | [0]" \ +| jq '{ + "Comment": "Creating an alias record", + "Changes": [ + { + "Action": "CREATE", + "ResourceRecordSet": { + "Name": "www.\($DOMAIN_NAME)", + "Type": "A", + "AliasTarget": { + "HostedZoneId": .CanonicalHostedZoneNameID, + "DNSName": .CanonicalHostedZoneName, + "EvaluateTargetHealth": false + } + } + } + ] +}' \ + --arg DOMAIN_NAME "${DOMAIN_NAME}" \ +| aws route53 change-resource-record-sets --hosted-zone-id $HOSTED_ZONE_ID --change-batch file:///dev/stdin +``` + +> ℹ️ Read [Routing traffic to an ELB load balancer](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html) +> to learn more about this task. +> +> ℹ️ The script uses a [`JMESPath` query](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-filter.html) +> to get the ELB for the Kubernetes Service by matching against the DNS name. +> +> 📖 There is an alternative way to manage the DNS record for the load balancer, using [ExternalDNS](https://kubernetes-sigs.github.io/external-dns/latest/). +> ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers. +> Read [ExternalDNS for usage within a Kubernetes cluster on AWS](https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/aws.md) to learn more. + + +Check that `www.$DOMAIN_NAME` now resolves to the ephemeral public IP address of the load balancer: + +```terminal +$ dig www.$DOMAIN_NAME A +... +;; QUESTION SECTION: +;www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net. IN A + +;; ANSWER SECTION: +www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net. 60 IN A 34.212.236.229 +www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net. 60 IN A 44.232.234.71 +www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net. 60 IN A 35.164.69.198 +``` + +If the DNS is correct and the load balancer is working and the hello world web server is running, +you should now be able to connect to it using curl or using your web browser: + +```bash +curl --insecure -v https://www.$DOMAIN_NAME +``` + +> ⚠️ We used curl's `--insecure` option because curl will reject the untrusted certificate we generated otherwise. +> Later you will learn how to create a trusted certificate signed by Let's Encrypt. + +You should see that the certificate has the expected DNS names and that it is self-signed: + +```terminal +... +* Server certificate: +* subject: CN=www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net +* start date: Sep 4 08:43:56 2024 GMT +* expire date: Dec 3 08:43:56 2024 GMT +* issuer: CN=www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net +* SSL certificate verify result: self-signed certificate (18), continuing anyway. +... +Hello, world! +Protocol: HTTP/2.0! +Hostname: helloweb-55cb4cd887-tjlvh +``` + +> 📖 Read more about [Using a Service to Expose Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/). + +# Part 2 + +In part 1 you created a test certificate. +Now you will learn how to configure cert-manager to use Let's Encrypt and AWS Route53 DNS to create a trusted certificate which you can use in production. +You need to prove to Let's Encrypt that you own the domain name of the certificate and one way to do this is to create a special DNS record in that domain. +This is known as the [DNS-01 challenge type](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge). + +cert-manager can create that DNS record for you in by using the AWS Route53 API but it needs to authenticate first, +and currently the most secure method of authentication is to use [IAM roles for service accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html). +The advantages of this method are that cert-manager will use an ephemeral Kubernetes ServiceAccount Token to authenticate to AWS and the token need not be stored in a Kubernetes Secret. + +> 📖 Read about [other ways to configure the ACME issuer with AWS Route53 DNS](../../configuration/acme/dns01/route53.md). + +## Create an IAM OIDC provider for your cluster + +```sh +eksctl utils associate-iam-oidc-provider --cluster $CLUSTER --approve +``` + +> ℹ️ Read [Create an IAM OIDC provider for your cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) for more details. + +## Create an IAM policy + +```bash +aws iam create-policy \ + --policy-name cert-manager-acme-dns01-route53 \ + --description "This policy allows cert-manager to manage ACME DNS01 records in Route53 hosted zones. See https://cert-manager.io/docs/configuration/acme/dns01/route53" \ + --policy-document file:///dev/stdin < ℹ️ Read the [cert-manager ACME DNS01 Route53 configuration documentation](https://cert-manager.io/docs/configuration/acme/dns01/route53), +> for more details of this IAM policy. + +## Create an IAM role and associate it with a Kubernetes service account + +The following command performs three tasks: +1. creates a new dedicated Kubernetes ServiceAccount in the cert-manager namespace, and +1. configures a new AWS Role with the permissions defined in the policy from the previous step. +1. configures the Role so that it can be only be assumed by clients with tokens for new dedicated Kubernetes ServiceAccount in this EKS cluster. + +```sh +AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) +eksctl create iamserviceaccount \ + --name cert-manager-acme-dns01-route53 \ + --namespace cert-manager \ + --cluster ${CLUSTER} \ + --role-name cert-manager-acme-dns01-route53 \ + --attach-policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/cert-manager-acme-dns01-route53 \ + --approve +``` + +> ℹ️ Read [Assign IAM roles to Kubernetes service accounts](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html), +> for more details. + +## Grant permission for cert-manager to create ServiceAccount tokens + +cert-manager needs permission to generate a JWT token for the Kubernetes ServiceAccount that you created in the previous step. +Apply the following RBAC Role and RoleBinding in the cert-manager namespace: + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/rbac.yaml +``` +🔗 `rbac.yaml` + +```sh +kubectl apply -f rbac.yaml +``` + +## Create a ClusterIssuer for Let's Encrypt Staging + +A ClusterIssuer is a custom resource which tells cert-manager how to sign a Certificate. +In this case the ClusterIssuer will be configured to connect to the Let's Encrypt staging server, +which allows us to test everything without using up our Let's Encrypt certificate quota for the domain name. + +Save the following content to a file called `clusterissuer-lets-encrypt-staging.yaml`, change the `email` field to use your email address and apply it: + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/clusterissuer-lets-encrypt-staging.yaml +``` +🔗 `clusterissuer-lets-encrypt-staging.yaml` + + +As you can see there are some variables in the `clusterissuer-lets-encrypt-staging.yaml` which need to be filled in before we apply it; +most have been defined earlier in this tutorial but you need to set the following: + +```bash +export EMAIL_ADDRESS= # ❗ Replace this with your email address +``` + +Now use `envsubst` to fill in the variables and pipe it into `kubectl apply`, as follows: + +```bash +export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) +envsubst < clusterissuer-lets-encrypt-staging.yaml | kubectl apply -f - +``` + +You can check the status of the ClusterIssuer: + +```bash +kubectl describe clusterissuer letsencrypt-staging +``` + +Example output + +```console +Status: + Acme: + Last Registered Email: firstname.lastname@example.com + Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/77882854 + Conditions: + Last Transition Time: 2024-09-04T15:41:18Z + Message: The ACME account was registered with the ACME server + Observed Generation: 1 + Reason: ACMEAccountRegistered + Status: True + Type: Ready +``` + +> ℹ️ Let's Encrypt uses the Automatic Certificate Management Environment (ACME) protocol +> which is why the configuration above is under a key called `acme`. +> +> ℹ️ The email address is only used by Let's Encrypt to remind you to renew the certificate after 30 days before expiry. You will only receive this email if something goes wrong when renewing the certificate with cert-manager. +> +> ℹ️ The Let's Encrypt production issuer has [very strict rate limits](https://letsencrypt.org/docs/rate-limits/). +> When you're experimenting and learning, it can be very easy to hit those limits. Because of that risk, +> we'll start with the Let's Encrypt staging issuer, and once we're happy that it's working +> we'll switch to the production issuer. +> +> 📖 Read more about [configuring the ACME Issuer](../../configuration/acme/README.md). +> + +## Re-issue the Certificate using Let's Encrypt + +Patch the Certificate to use the staging ClusterIssuer: + +```bash +kubectl patch certificate www --type merge -p '{"spec":{"issuerRef":{"name":"letsencrypt-staging"}}}' +``` + +That should trigger cert-manager to renew the certificate: +Use `cmctl` to check: + +```bash +cmctl status certificate www +cmctl inspect secret www-tls +``` + +And finally, when the new certificate has been issued, you must restart the web server to use it: + +```bash +kubectl rollout restart deployment helloweb +``` + +You should once again be able to connect to the website, but this time you will see the Let's Encrypt staging certificate: + +```terminal +$ curl -v --insecure https://www.$DOMAIN_NAME +... +* Server certificate: +* subject: CN=www.cert-manager-tutorial-22.site +* start date: Jan 5 12:41:14 2023 GMT +* expire date: Apr 5 12:41:13 2023 GMT +* issuer: C=US; O=(STAGING) Let's Encrypt; CN=(STAGING) Artificial Apricot R3 +* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. +... +Hello, world! +Protocol: HTTP/2.0! +Hostname: helloweb-9b8bcdd56-6rxm8 +``` + +> ⚠️ We used curl's `--insecure` option again here because the Let's Encrypt staging issuer creates untrusted certificates. +> Next you will learn how to create a trusted certificate signed by the Let's Encrypt production issuer. + +## Create a production ready certificate + +Now that everything is working with the Let's Encrypt staging server, we can switch to the production server and get a trusted certificate. + +Create a Let's Encrypt production Issuer by copying the staging ClusterIssuer YAML and modifying the server URL and the names, +then apply it: + +```yaml file=../../../../public/docs/tutorials/getting-started-aws-letsencrypt/clusterissuer-lets-encrypt-production.yaml +``` +🔗 `clusterissuer-lets-encrypt-production.yaml` + + +```bash +export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query "Account" --output text) +envsubst < clusterissuer-lets-encrypt-production.yaml | kubectl apply -f - +``` + +Check the status of the ClusterIssuer: + +```bash +kubectl describe clusterissuer letsencrypt-production +``` + +Patch the Certificate to use the production ClusterIssuer: + +```bash +kubectl patch certificate www --type merge -p '{"spec":{"issuerRef":{"name":"letsencrypt-production"}}}' +``` + +That should trigger cert-manager to renew the certificate: +Use `cmctl` to check: + +```bash +cmctl status certificate www +cmctl inspect secret www-tls +``` + +And finally, when the new certificate has been issued, you must restart the web server to use it: + +```bash +kubectl rollout restart deployment helloweb +``` + +Now you should be able to connect to the web server securely, without the `--insecure` flag, +and if you visit the site in your web browser, it should show a padlock (🔒) symbol next to the URL. + +```bash +curl -v https://www.$DOMAIN_NAME +``` + +```terminal +... + +* Server certificate: +* subject: CN=www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net +* start date: Sep 4 19:32:24 2024 GMT +* expire date: Dec 3 19:32:23 2024 GMT +* subjectAltName: host "www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net" matched cert's "www.cert-manager-aws-tutorial.richard-gcp.jetstacker.net" +* issuer: C=US; O=Let's Encrypt; CN=R11 +* SSL certificate verify ok. +... +``` + +That concludes this tutorial. +You have learned how to deploy cert-manager on AWS EKS and how to configure it to issue Let's Encrypt signed certificates using the DNS-01 protocol with Route53 DNS. +You have learned about IAM Roles for service accounts (IRSA) and learned how to configure cert-manager to authenticate to AWS Route53 using a Kubernetes ServiceAccount token. + +# Cleanup + +After completing the tutorial you can clean up by deleting the EKS cluster and the Route53 hosted zone, as follows: + +``` +eksctl delete cluster --name $CLUSTER +HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name $DOMAIN_NAME --query "HostedZones[0].Id" --output text) +aws route53 delete-hosted-zone --id ${HOSTED_ZONE_ID} +``` + +The IAM policy, role, and identity provider can be deleted manually from the AWS web UI. + +# Next Steps + +> 📖 Read other [cert-manager tutorials](../README.md) and [getting started guides](../../getting-started/README.md). +> +> 📖 Read more about [configuring the cert-manager ACME issuer with Route53 DNS](../../configuration/acme/dns01/route53.md). diff --git a/content/v1.15-docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md b/content/v1.15-docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md new file mode 100644 index 0000000000..6ba62a3d52 --- /dev/null +++ b/content/v1.15-docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md @@ -0,0 +1,779 @@ +--- +title: Deploy cert-manager on Google Kubernetes Engine (GKE) and create SSL certificates for Ingress using Let's Encrypt +description: Learn how to deploy cert-manager on Google Kubernetes (GKE) Engine and then configure it to sign SSL certificates using Let's Encrypt +--- + +*Last Verified: 15 July 2022* + +In this tutorial you will learn how to deploy and configure cert-manager on Google Kubernetes Engine (GKE). +You will learn how to configure cert-manager to get a signed SSL certificate from Let's Encrypt, +using an [HTTP-01 challenge](https://letsencrypt.org/docs/challenge-types/#http-01-challenge). +Finally you will learn how the certificate can be used to serve an HTTPS website with a public domain name. + +> **Google Cloud**: A suite of cloud computing services by Google.
          +> **Kubernetes**: Runs on your servers. Automates the deployment, scaling, and management of containerized applications.
          +> **cert-manager**: Runs in Kubernetes. Obtains TLS / SSL certificates and ensures the certificates are valid and up-to-date.
          +> **Let’s Encrypt**: An Internet service. Allows you to generate free short-lived SSL certificates. + +First you will create a Kubernetes (GKE) cluster and deploy a sample web server. +You will then create a public IP address and a public domain name for your website. +You'll set up Ingress and Google Cloud load balancers so that Internet clients can connect to the web server using HTTP. +Finally you will use cert-manager to get an SSL certificate from Let's Encrypt +and configure the load balancer to use that certificate. +By the end of this tutorial you will be able to connect to your website from the Internet using an `https://` URL. + +## Prerequisites + +**💻 Google Cloud account** + +You will need a Google Cloud account. +Registration requires a credit card or bank account details. +Visit the [Get started with Google Cloud](https://cloud.google.com/docs/get-started) page and follow the instructions. + +> 💵 If you have never used Google Cloud before, you may be eligible for the +> [Google Cloud Free +> Program](https://cloud.google.com/free/docs/gcp-free-tier/#free-trial), which +> gives you a 90 day trial period that includes $300 in free Cloud Billing +> credits to explore and evaluate Google Cloud. + +**💻 Domain Name** + +You will need a domain name and the ability to create DNS records in that domain. We will be getting a $12 domain name from Google Domains. Google Domains is one of the many possible "domain name registrars". NameCheap and GoDaddy are two other well-known registrars. + +> 💵 If you prefer not purchasing a domain name, it is also possible to adapt this tutorial to use the IP address to serve your website and for the SSL certificate. + +**💻 Software** + + +You will also need to install the following software on your laptop: + +1. [gcloud](https://cloud.google.com/sdk/docs/install): A set of tools to create and manage Google Cloud resources. +2. [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl): The Kubernetes command-line tool which allows you to configure Kubernetes clusters. +3. [curl](https://everything.curl.dev/get): A command-line tool for connecting to a web server using HTTP and HTTPS. + +> ℹ️ Try running `gcloud components install kubectl` to quickly install `kubectl`. + +## 0. Configure `gcloud` with a Google Cloud project + +If you don't have a Google Cloud account, the command below will create one for you: + +```bash +gcloud init +``` + +You will need to answer "yes" to the following question: + +```text +Do you want to configure a default Compute Region and Zone? (Y/n)? Y +``` + +After running the command, you will shown the project name, default region, and default zone. + +Example output: + +```text +* Commands that require authentication will use firstname.lastname@example.com by default +* Commands will reference project `your-project` by default +* Compute Engine commands will use region `europe-west1` by default +* Compute Engine commands will use zone `europe-west1-b` by default +``` + +In this tutorial, we will refer to the name of the project that was selected while running `gcloud init` with the variable `PROJECT`. Where ever you see `$PROJECT` in a command, you need to either (1) replace the variable manually before you execute the command, +or (2) export the variable in your shell session. This applies to all environment variables that you will encounter in the commands listed in this tutorial. + +We will go with option (2), so we need to export the environment variables before continuing using the information that was printed by `gcloud init`: + +```bash +export PROJECT=your-project # Your Google Cloud project ID. +export REGION=europe-west1 # Your Google Cloud region. +``` + +## 1. Create a Kubernetes Cluster + +To get started, let's create a Kubernetes cluster in Google Cloud. You will need to pick a name for your cluster. Here, we will go with "test-cluster-1". Let us save it in an environment variable: + +```bash +export CLUSTER=test-cluster-1 +``` + +Now, create the cluster using the following command: + +```bash +gcloud container clusters create $CLUSTER --preemptible --num-nodes=1 +``` + +Set up the [Google Kubernetes Engine auth plugin for kubectl](https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke): + +```bash +gcloud components install gke-gcloud-auth-plugin +export USE_GKE_GCLOUD_AUTH_PLUGIN=True +gcloud container clusters get-credentials $CLUSTER +``` + +Now check that you can connect to the cluster: + +```bash +kubectl get nodes -o wide +``` + +> ⏲ It will take 4-5 minutes to create the cluster. +> +> 💵 To minimize your cloud bill, this command creates a 1-node cluster using a +> [preemptible virtual +> machine](https://cloud.google.com/kubernetes-engine/docs/how-to/preemptible-vms) +> which is cheaper than a normal virtual machine. + +## 2. Deploy a sample web server + +We will deploy a very simple web server which responds to HTTP requests with "hello world!". + +```bash +kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0 +``` + +We also need to create a Kubernetes Service, so that connections can be routed to the web server Pods: + +```bash +kubectl expose deployment web --port=8080 +``` + +> ℹ️ These [kubectl imperative commands](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/imperative-command/) are used for readability and brevity. +> Feel free to use YAML manifests and `kubectl apply -f` instead. +> +> ℹ️ The Service created by `kubectl expose` will be of type `ClusterIP` (the default) and this is only reachable by components within the cluster. Later we will create an Ingress which is how we make the service available to clients outside the cluster. +> +> 🔰 Read more about [Using a Service to Expose Your App](https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/). + +## 3. Create a static external IP address + +This tutorial is about creating a public facing HTTPS website with a Let's Encrypt SSL certificate using the HTTP01 challenge mechanism, +so we need a public IP address so that both Let's Encrypt and other Internet clients can connect to your website. + +It is easy to create a public IP address in Google Cloud and later we will associate it with your website domain name and with a Google Cloud load balancer, which will accept HTTP(S) connections from Internet clients and proxy the requests to the web servers running in your cluster. + +Create a global static IP address as follows: + +```bash +gcloud compute addresses create web-ip --global +``` + +You should see the new IP address listed: + +```bash +gcloud compute addresses list +``` + +> ⚠️ You MUST create a `global` IP address because that is a prerequisite of the [External HTTP(S) Load Balancer](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress-xlb) which we will be using in this tutorial. +> +> 💵 Global static IP addresses are only available in the Premium network service tier and are more expensive than ephemeral and standard public IP addresses. +> +> 🔰 Read more about [Network service tiers in Google Cloud](https://cloud.google.com/network-tiers). +> +> 🔰 Read more about [Reserving a static external IP address in Google Cloud](https://cloud.google.com/compute/docs/ip-addresses/reserve-static-external-ip-address). + +Finally, we will save the IP address into an environment variable for later use. Display the IP address with the following command: + +```bash +gcloud compute addresses describe web-ip --format='value(address)' --global +``` + +Then, copy the output and save it into an environment variable: + +```bash +export IP_ADDRESS=198.51.100.1 # Replace with your IP address +``` + +## 4. Create a domain name for your website + +You will need a domain name for your website and Let's Encrypt checks your domain before it signs your SSL certificate, +so the domain name needs to be reachable from the Internet. + +We will purchase a cheap domain name using a credit card. Go to https://domains.google.com, and type something in the search box. For the example, we searched for `hello-app.com` because the example container that we will be deploying is called `hello-app`. Most importantly, we make sure to sort the domain names by price: + +![](/images/getting-started/screenshot_google-domains_get-a-new-domain.png) + +We don't pick `hello-app.com` because it costs $2,800; instead, we go with the one at the top: `heyapp.net`. It looks good! We then click the cart button. On the next screen, you will want to disable the auto-renewal, since we don't want to pay for this domain every year: + +![](/images/getting-started/screenshot_google-domains_your-cart.png) + +Now that you know your domain name, save it in an environment variable: + +```bash +export DOMAIN_NAME=heyapp.net +``` + +Next, you will need to create a new `A` record pointing at the IP address that we created above. Head back to https://domains.google.com/registrar, open your domain (here, `heyapp.net`) and click "DNS" on the left menu. You will see "Custom records". You want to add a new record of type `A` and put the IP address from the previous step into "data". You must leave "Host name" empty because we are configuring the top-level domain name: + +![](/images/getting-started/screenshot_google-domains_resource-records.png) + +> 🔰 Learn more about [What is a DNS A record? from the Cloudflare DNS tutorial](https://www.cloudflare.com/learning/dns/dns-records/dns-a-record/). + +> ℹ️ It is not strictly necessary to create a domain name for your website. You can connect to it using the IP address and later you can create an SSL certificate for the IP address instead of a domain name. If for some reason you can't create a domain name, then feel free to skip this section and adapt the instructions below to use an IP address instead. +> +> ℹ️ Every Google Cloud address has an automatically generated reverse DNS name like `51.159.120.34.bc.googleusercontent.com`, +> but the parent domain `googleusercontent.com` has a CAA record which prevents +> Let's Encrypt from signing certificates for the sub-domains. +> See [Certificate Authority Authorization (CAA)](https://letsencrypt.org/docs/caa/) in the Let's Encrypt documentation. + +## 5. Create an Ingress + +You won't be able to reach your website yet. +Your web server is running inside your Kubernetes cluster but there is no route or proxy through which Internet clients can connect to it, yet! +Now we will create a Kubernetes Ingress object and in Google Cloud this will trigger the creation of a various services which together allow Internet clients to reach your web server running inside your Kubernetes cluster. + +Initially we are going to create an HTTP (not an HTTPS) Ingress so that we can test the basic connectivity before adding the SSL layer. + +Copy the following YAML into a file called `ingress.yaml` and apply it: + +```yaml +# ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: web-ingress + annotations: + # This tells Google Cloud to create an External Load Balancer to realize this Ingress + kubernetes.io/ingress.class: gce + # This enables HTTP connections from Internet clients + kubernetes.io/ingress.allow-http: "true" + # This tells Google Cloud to associate the External Load Balancer with the static IP which we created earlier + kubernetes.io/ingress.global-static-ip-name: web-ip +spec: + defaultBackend: + service: + name: web + port: + number: 8080 +``` + +```bash +kubectl apply -f ingress.yaml +``` + +This will trigger the creation of a Google HTTP(S) loadbalancer associated with the IP address that you created earlier. +You can watch the progress and the resources that are being created: + +```bash +kubectl describe ingress web-ingress +``` + +Within 4-5 minutes all the load balancer components should be ready and you should be able to connect to the DNS name and see the response from the hello-world web server that we deployed earlier: + +``` +curl http://$DOMAIN_NAME +``` + +Example output: + +```console +Hello, world! +Version: 1.0.0 +Hostname: web-79d88c97d6-t8hj2 +``` + +At this point we have a Google load balancer which is forwarding HTTP traffic to the hello-world web server running in a Pod in our cluster. + +> ⏲ It may take 4-5 minutes for the load balancer components to be created and +> configured and for Internet clients to be routed to your web server. +> Refer to the [Troubleshooting](#troubleshooting) section if it takes longer. +> +> 🔰 Read about how to [Use a static IP addresses for HTTP(S) load balancers via Ingress annotation](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress-xlb#static_ip_addresses_for_https_load_balancers). +> +> 🔰 Read a [Summary of external Ingress annotations for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress#summary_of_external_ingress_annotations). +> +> 🔰 Read about [Troubleshooting Ingress with External HTTP(S) Load Balancing on GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/load-balance-ingress#testing_the). +> +> ℹ️ There are two Ingress classes available for GKE Ingress. The `gce` class deploys an external load balancer and the `gce-internal` class deploys an internal load balancer. Ingress resources without a class specified default to `gce`. +> +> ⚠️ Contrary to the Kubernetes Ingress documentation, you MUST use the `kubernetes.io/ingress.class` annotation rather than the `Ingress.Spec.IngressClassName` field. +> See [ingress-gce #1301](https://github.com/kubernetes/ingress-gce/issues/1301#issuecomment-1133356812) and [ingress-gce #1337](https://github.com/kubernetes/ingress-gce/pull/1337). + + +## 6. Install cert-manager + +So finally we are ready to start creating an SSL certificate for our website. +The first thing you need to do is install cert-manager, and we'll install it the easy using `kubectl` as follows: + +``` +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/[[VAR::cert_manager_latest_version]]/cert-manager.yaml +``` + +This will create three Deployments, and a bunch of Services and Pods in a new namespace called `cert-manager`. +It also installs various cluster scoped supporting resources such as RBAC roles and Custom Resource Definitions. + +You can view some of the resources that have been installed as follows: + +```bash +kubectl -n cert-manager get all +``` + +And you can explore the Custom Resource Definitions (cert-manager's API) using `kubectl explain`, as follows: + +```bash +kubectl explain Certificate +kubectl explain CertificateRequest +kubectl explain Issuer +``` + +> 🔰 Read about [other ways to install cert-manager](../../installation). +> +> 🔰 Read more about [Certificates and Issuers](../../concepts). + +## 7. Create an Issuer for Let's Encrypt Staging + +An Issuer is a custom resource which tells cert-manager how to sign a Certificate. +In this case the Issuer will be configured to connect to the Let's Encrypt staging server, +which allows us to test everything without using up our Let's Encrypt certificate quota for the domain name. + +> ℹ️ Let's Encrypt uses the Automatic Certificate Management Environment (ACME) protocol +> which is why the configuration below is under a key called `acme`. + +Save the following content to a file called `issuer-lets-encrypt-staging.yaml`, change the `email` field to use your email address and apply it: + +```yaml +# issuer-lets-encrypt-staging.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-staging +spec: + acme: + server: https://acme-staging-v02.api.letsencrypt.org/directory + email: # ❗ Replace this with your email address + privateKeySecretRef: + name: letsencrypt-staging + solvers: + - http01: + ingress: + name: web-ingress +``` + +```bash +kubectl apply -f issuer-lets-encrypt-staging.yaml +``` + +> ℹ️ The email address is only used by Let's Encrypt to remind you to renew the certificate after 30 days before expiry. You will only receive this email if something goes wrong when renewing the certificate with cert-manager. + +You can check the status of the Issuer: + +```bash +kubectl describe issuers.cert-manager.io letsencrypt-staging +``` + +Example output + +```console +Status: + Acme: + Last Registered Email: firstname.lastname@example.com + Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/60706744 + Conditions: + Last Transition Time: 2022-07-13T16:13:25Z + Message: The ACME account was registered with the ACME server + Observed Generation: 1 + Reason: ACMEAccountRegistered + Status: True + Type: Ready +``` + +> ℹ️ The Let's Encrypt production issuer has [very strict rate limits](https://letsencrypt.org/docs/rate-limits/). +> When you're experimenting and learning, it can be very easy to hit those limits. Because of that risk, +> we'll start with the Let's Encrypt staging issuer, and once we're happy that it's working +> we'll switch to the production issuer. +> +> ⚠️ In the next step you will see a warning about untrusted certificates because +> we start with the staging issuer, but that's totally expected. +> +> 🔰 Read more about [configuring the ACME Issuer](../../configuration/acme). + +## 8. Re-configure the Ingress for SSL + +Earlier we created an Ingress and saw that we could connect to our web server using HTTP. +Now we will reconfigure that Ingress for HTTPS. + +First a quick hack, to work around a problem with the Google Cloud ingress controller. +Create an empty Secret for your SSL certificate **before reconfiguring the Ingress** and apply it: + +```yaml +# secret.yaml +apiVersion: v1 +kind: Secret +metadata: + name: web-ssl +type: kubernetes.io/tls +stringData: + tls.key: "" + tls.crt: "" +``` + +```bash +kubectl apply -f secret.yaml +``` + +> ℹ️ This is a work around for a chicken-and-egg problem, where the ingress-gce +> controller won't update its forwarding rules unless it can first find the +> Secret that will eventually contain the SSL certificate. But Let's Encrypt +> won't sign the SSL certificate until it can get the special +> `.../.well-known/acme-challenge/...` URL which cert-manager adds to the +> Ingress and which must then be translated into Google Cloud forwarding rules, +> by the ingress-gce controller. +> +> 🔰 Read more about [Kubernetes Secrets and how to use them](https://kubernetes.io/docs/concepts/configuration/secret/). + +Now make the following changes to the Ingress and apply them: + +```diff +--- a/ingress.yaml ++++ b/ingress.yaml +@@ -7,7 +7,12 @@ metadata: + kubernetes.io/ingress.class: gce + kubernetes.io/ingress.allow-http: "true" + kubernetes.io/ingress.global-static-ip-name: web-ip ++ cert-manager.io/issuer: letsencrypt-staging + spec: ++ tls: ++ - secretName: web-ssl ++ hosts: ++ - $DOMAIN_NAME + defaultBackend: + service: + name: web +``` + +``` +kubectl apply -f ingress.yaml +``` + +This triggers a complex set of operations which may take many minutes to eventually complete. +Some of these steps take 2-3 minutes and some will initially fail. +They should all eventually succeed because cert-manager and ingress-gce (the Google Cloud ingress controller) will periodically re-reconcile. + +Eventually, When all the pieces are in place, you should be able to +use curl to check the HTTPS connection to your website: + +```bash +curl -v --insecure https://$DOMAIN_NAME +``` + +You should see that the HTTPS connection is established but that the SSL certificate is not trusted; +that's why you use the `--insecure` flag at this stage + +Example output: +```console +* Server certificate: +* subject: CN=www.example.com +* start date: Jul 14 08:52:29 2022 GMT +* expire date: Oct 12 08:52:28 2022 GMT +* issuer: C=US; O=(STAGING) Let's Encrypt; CN=(STAGING) Artificial Apricot R3 +* SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. +``` + +> ⏲ You will have to wait 5-10 minutes for the SSL certificate to be signed and then loaded by the Google Cloud load balancer. +> Refer to the [Troubleshooting](#troubleshooting) section if it takes longer. +> +> ℹ️ Adding the annotation `cert-manager.io/issuer: letsencrypt-staging` marks the Ingress for the attention of the cert-manager `ingress-shim` +> and causes it to create a new Certificate with a reference to the Issuer that we created earlier. +> +> 🔰 Read [Securing Ingress Resources](../../usage/ingress.md) to learn more. +> +> 🔰 Read about how to [Specify certificates for your Ingress in GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-multi-ssl#specifying_certificates_for_your_ingress). + +## 9. Create a production ready SSL certificate + +Now that everything is working with the Let's Encrypt staging server, we can switch to the production server and get a trusted SSL certificate. + +Create a Let's Encrypt production Issuer and apply it: + +```yaml +# issuer-lets-encrypt-production.yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: letsencrypt-production +spec: + acme: + server: https://acme-v02.api.letsencrypt.org/directory + email: # ❗ Replace this with your email address + privateKeySecretRef: + name: letsencrypt-production + solvers: + - http01: + ingress: + name: web-ingress +``` + +```bash +kubectl apply -f issuer-lets-encrypt-production.yaml +``` + +Then update the Ingress annotation to use the production Issuer: + +```bash +kubectl annotate ingress web-ingress cert-manager.io/issuer=letsencrypt-production --overwrite +``` + +This will trigger cert-manager to get a new SSL certificate signed by the Let's Encrypt production CA and store it to the `web-ssl` Secret. +Within about 10 minutes, this new certificate will be synced to the Google Cloud load balancer and you will be able to connect to the website using secure HTTPS: + +```bash +curl -v https://$DOMAIN_NAME +``` + +Example output: +```console +... +* Server certificate: +* subject: CN=www.example.com +* start date: Jul 14 09:44:29 2022 GMT +* expire date: Oct 12 09:44:28 2022 GMT +* subjectAltName: host "www.example.com" matched cert's "www.example.com" +* issuer: C=US; O=Let's Encrypt; CN=R3 +* SSL certificate verify ok. +... +Hello, world! +Version: 1.0.0 +Hostname: web-79d88c97d6-t8hj2 +``` + +It should also be possible to visit `https://$DOMAIN_NAME` in your web browser, without any errors or warnings. + +That concludes the tutorial. +You now understand how cert-manager integrates with Kubernetes Ingress and cloud Ingress controllers. +You have learned how to use cert-manager to get free Let's Encrypt SSL certificates. +And you have seen how the certificates can be used by a cloud based load balancer to terminate SSL connections from Internet clients +and forward HTTPS requests to a web server running in your Kubernetes cluster. + +> 💵 Read the [Clean up](#clean-up) section to learn how to delete all the resources that you created in this tutorial and reduce your cloud bill. +> +> 🔰 Read the [Troubleshooting](#troubleshooting) section if you encounter difficulties with the steps described in this tutorial. + +## Clean up + +After completing the tutorial you can clean up by deleting the cluster and the domain name and the static IP as follows: + +```bash +# Delete the cluster and all the Google Cloud resources related to the Ingress that it contains +gcloud container clusters delete $CLUSTER + +# Delete the domain name +gcloud dns record-sets delete $DOMAIN_NAME --zone $ZONE --type A + +# Delete the static IP address +gcloud compute addresses delete web-ip --global +``` + +## Troubleshooting + +When you create or update the Ingress object in this tutorial it triggers a complex set of operations which may take many minutes to eventually complete. +Some of these steps take 2-3 minutes and some will initially fail but then subsequently succeed when either cert-manager or the Google ingress controller re-reconciles. +In short, you should allow 5-10 minutes after you create or change the Ingress and you should expect to see some errors and warnings when you run `kubectl describe ingress web-ingress`. + +Here's a brief summary of the operations performed by cert-manager and ingress-gce (the Google Cloud Ingress controller): + +* cert-manager connects to Let's Encrypt and sends an SSL certificate signing request. +* Let's Encrypt responds with a "challenge", which is a unique token that cert-manager must make available at a well-known location on the target web site. This proves that you are an administrator of that web site and domain name. +* cert-manager deploys a Pod containing a temporary web server that serves the Let's Encrypt challenge token. +* cert-manager reconfigures the Ingress, adding a `rule` to route requests for from Let's Encrypt to that temporary web server. +* Google Cloud ingress controller reconfigures the external HTTP load balancer with that new rule. +* Let's Encrypt now connects and receives the expected challenge token and the signs the SSL certificate and returns it to cert-manager. +* cert-manager stores the signed SSL certificate in the Kubernetes Secret called `web-ssl`. +* Google Cloud ingress controller uploads the signed certificate and associated private key to a Google Cloud certificate. +* Google Cloud ingress controller reconfigures the external load balancer to serve the uploaded SSL certificate. + +### Check Ingress and associated events + +Use `kubectl describe` to view the Ingress configuration and all the associated Events. +Check that the IP address is correct and that the TLS and Host entries match the domain name that you chose for your website. +Notice that `ingress-gce` creates an Event for each of the Google Cloud components that it manages. +And notice that it adds annotations with references to the ID of each of those components. +cert-manager also creates Events when it reconciles the Ingress object, including details of the Certificate object that it creates for the Ingress. + +```console +$ kubectl describe ingress web-ingress +Name: web-ingress +Labels: +Namespace: default +Address: 34.120.159.51 +Ingress Class: +Default backend: web:8080 (10.52.0.13:8080) +TLS: + web-ssl terminates www.example.com +Rules: + Host Path Backends + ---- ---- -------- + * * web:8080 (10.52.0.13:8080) +Annotations: cert-manager.io/issuer: letsencrypt-staging + ingress.kubernetes.io/backends: {"k8s1-01784147-default-web-8080-1647ccd2":"HEALTHY"} + ingress.kubernetes.io/forwarding-rule: k8s2-fr-1lt9dzcy-default-web-ingress-yteotwe4 + ingress.kubernetes.io/https-forwarding-rule: k8s2-fs-1lt9dzcy-default-web-ingress-yteotwe4 + ingress.kubernetes.io/https-target-proxy: k8s2-ts-1lt9dzcy-default-web-ingress-yteotwe4 + ingress.kubernetes.io/ssl-cert: k8s2-cr-1lt9dzcy-4gjeakdb9n7k6ls7-a257650b5fefd174 + ingress.kubernetes.io/target-proxy: k8s2-tp-1lt9dzcy-default-web-ingress-yteotwe4 + ingress.kubernetes.io/url-map: k8s2-um-1lt9dzcy-default-web-ingress-yteotwe4 + kubernetes.io/ingress.allow-http: true + kubernetes.io/ingress.class: gce + kubernetes.io/ingress.global-static-ip-name: web-ip +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal CreateCertificate 28m cert-manager-ingress-shim Successfully created Certificate "web-ssl" + Normal Sync 28m loadbalancer-controller UrlMap "k8s2-um-1lt9dzcy-default-web-ingress-yteotwe4" updated + Warning Sync 24m (x16 over 28m) loadbalancer-controller Error syncing to GCP: error running load balancer syncing routine: loadbalancer 1lt9dzcy-default-web-ingress-yteotwe4 does not exist: googleapi: Error 404: The resource 'projects/your-project/global/sslCertificates/k8s2-cr-1lt9dzcy-4gjeakdb9n7k6ls7-e3b0c44298fc1c14' was not found, notFound + Normal Sync 34s (x16 over 65m) loadbalancer-controller Scheduled for sync +``` + +### Use cmctl to show the state of a Certificate and its associated resources + +> ℹ️ [Install `cmctl`](../../reference/cmctl.md) if you have not already done so. + +When you create a Certificate, cert-manager will create a collection of temporary resources +which each contain information about the status of certificate signing process. +You can read more about these in the [Certificate Lifecycle](../../usage/certificate.md#certificate-lifecycle) section. +Use the `cmctl status` command to view details of all these resources and all the associated Events and error messages. + +You may see some temporary errors, like: + +```console +$ cmctl status certificate web-ssl +Name: web-ssl +Namespace: default +Created at: 2022-07-14T17:30:06+01:00 +Conditions: + Ready: False, Reason: MissingData, Message: Issuing certificate as Secret does not contain a private key + Issuing: True, Reason: MissingData, Message: Issuing certificate as Secret does not contain a private key +DNS Names: +- www.example.com +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Issuing 4m37s cert-manager-certificates-trigger Issuing certificate as Secret does not contain a private key + Normal Generated 4m37s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "web-ssl-8gsqc" + Normal Requested 4m37s cert-manager-certificates-request-manager Created new CertificateRequest resource "web-ssl-dblrj" +Issuer: + Name: letsencrypt-staging + Kind: Issuer + Conditions: + Ready: True, Reason: ACMEAccountRegistered, Message: The ACME account was registered with the ACME server + Events: +error: 'tls.crt' of Secret "web-ssl" is not set +Not Before: +Not After: +Renewal Time: +CertificateRequest: + Name: web-ssl-dblrj + Namespace: default + Conditions: + Approved: True, Reason: cert-manager.io, Message: Certificate request has been approved by cert-manager.io + Ready: False, Reason: Pending, Message: Waiting on certificate issuance from order default/web-ssl-dblrj-327645514: "pending" + Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal cert-manager.io 4m37s cert-manager-certificaterequests-approver Certificate request has been approved by cert-manager.io + Normal OrderCreated 4m37s cert-manager-certificaterequests-issuer-acme Created Order resource default/web-ssl-dblrj-327645514 + Normal OrderPending 4m37s cert-manager-certificaterequests-issuer-acme Waiting on certificate issuance from order default/web-ssl-dblrj-327645514: "" +Order: + Name: web-ssl-dblrj-327645514 + State: pending, Reason: + Authorizations: + URL: https://acme-staging-v02.api.letsencrypt.org/acme/authz-v3/3008789144, Identifier: www.example.com, Initial State: pending, Wildcard: false +Challenges: +- Name: web-ssl-dblrj-327645514-2671694319, Type: HTTP-01, Token: TKspp86xMjQzTvMVXWkezEA2sE2GSWjnld5Lt4X13ro, Key: TKspp86xMjQzTvMVXWkezEA2sE2GSWjnld5Lt4X13ro.f4bppCOm-jXasFGMKjpBE5aQlhiQBeTPIs0Lx822xao, State: pending, Reason: Waiting for HTTP-01 challenge propagation: did not get expected response when querying endpoint, expected "TKspp86xMjQzTvMVXWkezEA2sE2GSWjnld5Lt4X13ro.f4bppCOm-jXasFGMKjpBE5aQlhiQBeTPIs0Lx822xao" but got: Hello, world! +Version: 1... (truncated), Processing: true, Presented: true +``` + +This is because cert-manager is performing a preflight check to see if the temporary challenge web server is reachable at the expected URL. +Initially it will not be reachable, because cert-manager takes some time to deploy the temporary web server and the Ingress controller takes time to set up the new HTTP routing rules. +Eventually you will see that the Certificate is Ready and signed: + +```console +$ cmctl status certificate web-ssl +Name: web-ssl +Namespace: default +Created at: 2022-07-14T17:30:06+01:00 +Conditions: + Ready: True, Reason: Ready, Message: Certificate is up to date and has not expired +DNS Names: +- www.example.com +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Issuing 31m cert-manager-certificates-trigger Issuing certificate as Secret does not contain a private key + Normal Generated 31m cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "web-ssl-8gsqc" + Normal Requested 31m cert-manager-certificates-request-manager Created new CertificateRequest resource "web-ssl-dblrj" + Normal Issuing 26m cert-manager-certificates-issuing The certificate has been successfully issued +Issuer: + Name: letsencrypt-staging + Kind: Issuer + Conditions: + Ready: True, Reason: ACMEAccountRegistered, Message: The ACME account was registered with the ACME server + Events: +Secret: + Name: web-ssl + Issuer Country: US + Issuer Organisation: (STAGING) Let's Encrypt + Issuer Common Name: (STAGING) Artificial Apricot R3 + Key Usage: Digital Signature, Key Encipherment + Extended Key Usages: Server Authentication, Client Authentication + Public Key Algorithm: RSA + Signature Algorithm: SHA256-RSA + Subject Key ID: a51e3621f5c1138947810f27dce425b33c88cb16 + Authority Key ID: de727a48df31c3a650df9f8523df57374b5d2e65 + Serial Number: fa8bb0b603ca2cdbfdfb2872d05ee52cda10 + Events: +Not Before: 2022-07-14T16:34:52+01:00 +Not After: 2022-10-12T16:34:51+01:00 +Renewal Time: 2022-09-12T16:34:51+01:00 +``` + +### Check that the SSL certificate has been copied to Google Cloud + +After cert-manager receives the signed Certificate it stores in the `web-ssl` Secret, +and this in turn triggers the Google Cloud ingress controller to copy that SSL certificate to Google Cloud. +You can see the certificate using the `gcloud` command, as follows: + +```console +$ gcloud compute ssl-certificates list +NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME MANAGED_STATUS +k8s2-cr-1lt9dzcy-4gjeakdb9n7k6ls7-a257650b5fefd174 SELF_MANAGED 2022-07-14T09:37:06.920-07:00 2022-10-12T08:34:51.000-07:00 +``` + +And you can view its contents and check its attributes as follows: + +```console +$ gcloud compute ssl-certificates describe k8s2-cr-1lt9dzcy-4gjeakdb9n7k6ls7-a257650b5fefd174 --format='value(certificate)' \ + | openssl x509 -in - -noout -text +... +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:9f:47:f1:cb:25:37:9b:86:a3:ef:bf:2e:77:3b:45:fc:1a + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, O = Let's Encrypt, CN = R3 + Validity + Not Before: Jul 14 17:11:15 2022 GMT + Not After : Oct 12 17:11:14 2022 GMT + Subject: CN = www.example.com +``` + +### Check the Google Cloud forwarding-rules + +After you add the TLS stanza to the Ingress object, you should eventually see a forwarding-rule for the SSL connection: + +```console +$ gcloud compute forwarding-rules describe k8s2-fs-1lt9dzcy-default-web-ingress-yteotwe4 --global +IPAddress: 34.120.159.51 +IPProtocol: TCP +creationTimestamp: '2022-07-14T09:37:12.362-07:00' +description: '{"kubernetes.io/ingress-name": "default/web-ingress"}' +fingerprint: oBTg7dRaIqI= +id: '2303318464959215831' +kind: compute#forwardingRule +labelFingerprint: 42WmSpB8rSM= +loadBalancingScheme: EXTERNAL +name: k8s2-fs-1lt9dzcy-default-web-ingress-yteotwe4 +networkTier: PREMIUM +portRange: 443-443 +selfLink: https://www.googleapis.com/compute/v1/projects/your-project/global/forwardingRules/k8s2-fs-1lt9dzcy-default-web-ingress-yteotwe4 +target: https://www.googleapis.com/compute/v1/projects/your-project/global/targetHttpsProxies/k8s2-ts-1lt9dzcy-default-web-ingress-yteotwe4 +``` diff --git a/content/v1.15-docs/tutorials/getting-started-with-trust-manager/README.md b/content/v1.15-docs/tutorials/getting-started-with-trust-manager/README.md new file mode 100644 index 0000000000..afeec714f1 --- /dev/null +++ b/content/v1.15-docs/tutorials/getting-started-with-trust-manager/README.md @@ -0,0 +1,603 @@ +--- +title: Managing public trust in kubernetes with trust-manager +description: Learn how to deploy and configure trust-manager to automatically distribute your approved Public CA configuration to your Kubernetes cluster. +--- + +*Last Verified: 19 June 2023* + +In this tutorial we will walk through how we can use +[trust-manager](https://cert-manager.io/docs/trust/trust-manager/) to +distribute publicly trusted Certificate Authority (CA) certificates inside +a Kubernetes cluster. Once distributed we will also show: + +- How you can automatically reload applications when your trust bundle changes +- How you can enforce applications to use your distributed CA bundle + +From there we will use a simple `curl` pod to show how to automatically mount +the trusted CA `Bundle`, so it can be used without having to configure curl +manually. This mimics how an application would not need any additional +configuration to make use of your trusted CA certificates bundle. + +In this tutorial we will be limiting the scope of our changes to only impact +the `team-a` namespace. To get the most out of these features you will want +to remove this limitation. + +> **Note:** All resources provided are demonstrative and should be reviewed + properly before using in production environments. + +## Prerequisites + +**💻 Software** + +1. [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl): The Kubernetes +command-line tool which allows you to configure Kubernetes clusters. +1. [helm](https://helm.sh/): A package manager for Kubernetes. +1. [yq](https://github.com/mikefarah/yq#install): A command line tool for +parsing YAML with helpful coloring. + +## Distribute Public CA Trust + +Let us first setup trust-manager and have our public CAs distributed to our +demo namespace: `team-a`. + +### Setup Application & Bundle + +1) Install trust-manager following the + [instructions here](../../trust/trust-manager/README.md#installation). + +1) Create your first `Bundle` resource including only Public CA certificates + + ```yaml file=./trust/bundle-public.yaml + ``` + + ```shell + kubectl apply -f - < **Note**: this is to limit the scope of our trust bundle to only the + `team-a` namespace as mentioned previously. + +1) Verify that the trust-manager controller has correctly propagated the + CA bundle to the namespace: + + ```shell + kubectl get configmap -n team-a public-bundle -o yaml + ``` + + Note that this output should be quite long. This is because the default + public bundle that we use has a lot of public CAs in it. + +### Mount Trust Bundle to Application with Automatic Use + +To use our trusted CAs we will mount them to the application in a default +location that most applications expect to find a `ca-certificates.crt` file. +The benefit to this approach is that most application code inside the container +will use this file by default and not require any additional configuration. There is the added benefit that you will be mounting over the top of +`/etc/ssl/certs` which will remove existing CA certificates, usually +present from a container base image or pulled in during CI builds. + +> **WARNING:** We have chosen one well known location in this example which + is used by alpine and `curl` for sourcing trusted CAs. This is not the only + location that can be used, so a container may have other default locations. + If you want to see where default CAs are located you can use + [paranoia](https://github.com/jetstack/paranoia) to inspect a built container + image. + +1) Apply the application deployment: + + ```yaml file=./trust/deploy-auto.yaml + ``` + + ```shell + kubectl apply -f - < ..data/ca-certificates.crt + ``` + + Note that normally this container image the output would look something + like the following, when there is no volume overriding this directory: + + ``` + ~ $ ls -ltr /etc/ssl/certs/ + total 608 + -rw-r--r-- 1 root root 214222 Apr 14 01:11 ca-certificates.crt + lrwxrwxrwx 1 root root 52 Apr 14 01:11 ca-cert-vTrus_Root_CA.pem -> /usr/share/ca-certificates/mozilla/vTrus_Root_CA.crt + lrwxrwxrwx 1 root root 56 Apr 14 01:11 ca-cert-vTrus_ECC_Root_CA.pem -> /usr/share/ca-certificates/mozilla/vTrus_ECC_Root_CA.crt + ... + lrwxrwxrwx 1 root root 53 Apr 14 01:11 02265526.0 -> ca-cert-Entrust_Root_Certification_Authority_-_G2.pem + lrwxrwxrwx 1 root root 31 Apr 14 01:11 002c0b4f.0 -> ca-cert-GlobalSign_Root_R46.pem + ``` + +1) Make a HTTPS call out to a well known site to validate `curl` works without +having to pass the additional `--cacert` flag: + + ```shell + curl -v https://bbc.co.uk/news + ``` + + Success will result in a valid TLS connection such as: + + ``` + * Trying 151.101.0.81:443... + * Connected to bbc.co.uk (151.101.0.81) port 443 (#0) + * ALPN: offers h2,http/1.1 + * TLSv1.3 (OUT), TLS handshake, Client hello (1): + * CAfile: /etc/ssl/certs/ca-certificates.crt + * CApath: none + * TLSv1.3 (IN), TLS handshake, Server hello (2): + * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): + * TLSv1.3 (IN), TLS handshake, Certificate (11): + * TLSv1.3 (IN), TLS handshake, CERT verify (15): + * TLSv1.3 (IN), TLS handshake, Finished (20): + * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): + * TLSv1.3 (OUT), TLS handshake, Finished (20): + * SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 + * ALPN: server accepted h2 + * Server certificate: + * subject: C=GB; ST=London; L=London; O=BRITISH BROADCASTING CORPORATION; CN=www.bbc.com + * start date: Mar 14 06:16:13 2023 GMT + * expire date: Apr 14 06:16:12 2024 GMT + * subjectAltName: host "bbc.co.uk" matched cert's "bbc.co.uk" + * issuer: C=BE; O=GlobalSign nv-sa; CN=GlobalSign RSA OV SSL CA 2018 + * SSL certificate verify ok. + ``` + +1. Exit the container: `exit` + +## Configure Real Applications + +Based on the example above, Kubernetes is able to mount over the top of the +default CA certificate bundle. You can use this with applications assuming you +know where the default locations they retrieve CA certificates from. + +For example with `Go` your application is configurable with either +`SSL_CERT_FILE` or `SSL_CERT_DIR` to point to the default CA certificate +file location. + +See more details [here](https://go.dev/src/crypto/x509/root_unix.go) and +for the default locations on various OS bases, check +[here](https://go.dev/src/crypto/x509/root_linux.go) + +```go +// Possible certificate files; stop after finding one. +var certFiles = []string{ + "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo etc. + "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6 + "/etc/ssl/ca-bundle.pem", // OpenSUSE + "/etc/pki/tls/cacert.pem", // OpenELEC + "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7 + "/etc/ssl/cert.pem", // Alpine Linux +} + +// Possible directories with certificate files; all will be read. +var certDirectories = []string{ + "/etc/ssl/certs", // SLES10/SLES11, https://golang.org/issue/12139 + "/etc/pki/tls/certs", // Fedora/RHEL + "/ +``` + +Having checked Python the `ssl` library uses the same two environment variables +for finding the trusted CAs: `SSL_CERT_DIR` and / or `SSL_CERT_FILE`. You can +verify this [in documentation](https://docs.python.org/3/library/ssl.html#ssl.get_default_verify_paths) +and from a `python3` runtime: + +```python3 +>>> import ssl +>>> ssl.get_default_verify_paths() +DefaultVerifyPaths(cafile=None, capath='/usr/lib/ssl/certs', openssl_cafile_env='SSL_CERT_FILE', openssl_cafile='/usr/lib/ssl/cert.pem', openssl_capath_env='SSL_CERT_DIR', openssl_capath='/usr/lib/ssl/certs') +``` + +This should mean that any CAs mounted in a file and any of the following files +will be trusted by any python application runtime, similar to `Go`: + +- '/usr/lib/ssl/cert.pem' +- '/usr/lib/ssl/certs/*' + +Similar could be achieved with other languages. + +## Automate and Enforce + +So now we have mounted trust-manager's bundle manually, you might be thinking: + +- What happens if the CA Bundle is changed, how do I get that change to my + application? +- How do I ensure that my CA Bundle is mounted to all applications in my + cluster without having to request changes from my tenants? + +Let's tackle both of these scenarios using additional Open Source tools. + +### Rollout CA Bundle Changes + +If your CA bundle changes, those changes will be synced to the namespaces +pretty quickly. This change will be reflected in the volume attached to the +container, but most applications will not pickup on the file system change. +The common approach is restarting the client application deployment, through +the use of `kubectl rollout restart deployment `. There is an +option to automate this process through a third party piece of open-source +software. + +Using [Stakater Reloader](https://github.com/stakater/Reloader) it is +possible to reload or rollout a deployment whenever a `ConfigMap` or `Secret` +changes. So whenever the `Bundle`'s target is synced, the Reloader component +can pick up this change and rollout applications mounting those resource +as volumes or environment variables. + +**Please note** that there are many alternative pieces of software that you +could bundle or write into your application container. They would simply watch +the file system for changes and trigger a reload of the application process. +Such an approach requires container image or code changes and this could be +difficult to implement with many tenants. The advantage to using reloader here +is that it's a generic solution, applicable to all applications running in a +cluster. + +1. Continuing with the reloader, it can be installed with helm: + + ```shell + helm repo add stakater https://stakater.github.io/stakater-charts + helm repo update + helm install reloader stakater/reloader -n stakater-reloader --create-namespace --set fullnameOverride=reloader + ``` + +1. We can reuse the deployment `sleep-auto` from the previous section and + configured it to enabled the reload functionality: + + ```shell + kubectl annotate deployment -n team-a sleep-auto reloader.stakater.com/auto="true" + ``` + + **Please note** there are several configuration options to configure + the reloader tooling and this is only the most basic example. Refer to + [the documentation](https://github.com/stakater/Reloader#how-to-use-reloader) + for more detailed examples. + +1. In another terminal watch the application rollout: + + ```shell + kubectl get po -n team-a -w + ``` + +1. To test this change we can edit our `Bundle` resource to remove all the + default Public CA certificates and only provide one CA certificate instead: + + ```yaml file=./trust/bundle-one-ca.yaml + ``` + + ```shell + kubectl apply -f - < istio-install-config.yaml +``` diff --git a/content/v1.15-docs/tutorials/istio-csr/example/example-issuer.yaml b/content/v1.15-docs/tutorials/istio-csr/example/example-issuer.yaml new file mode 100644 index 0000000000..4dd383dbcb --- /dev/null +++ b/content/v1.15-docs/tutorials/istio-csr/example/example-issuer.yaml @@ -0,0 +1,45 @@ +# SelfSigned issuers are useful for creating root certificates +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned + namespace: istio-system +spec: + selfSigned: {} +--- +# Request a self-signed certificate from our Issuer; this will function as our +# issuing root certificate when we pass it into a CA Issuer. + +# It's generally fine to issue root certificates like this one with long lifespans; +# the certificates which istio-csr issues will be much shorter lived. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: istio-ca + namespace: istio-system +spec: + isCA: true + duration: 87600h # 10 years + secretName: istio-ca + commonName: istio-ca + privateKey: + algorithm: ECDSA + size: 256 + subject: + organizations: + - cluster.local + - cert-manager + issuerRef: + name: selfsigned + kind: Issuer + group: cert-manager.io +--- +# Create a CA issuer using our root. This will be the Issuer which istio-csr will use. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: istio-ca + namespace: istio-system +spec: + ca: + secretName: istio-ca diff --git a/content/v1.15-docs/tutorials/istio-csr/example/istio-config-getting-started.yaml b/content/v1.15-docs/tutorials/istio-csr/example/istio-config-getting-started.yaml new file mode 100644 index 0000000000..83b6eeee7b --- /dev/null +++ b/content/v1.15-docs/tutorials/istio-csr/example/istio-config-getting-started.yaml @@ -0,0 +1,21 @@ +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +metadata: + namespace: istio-system +spec: + profile: "demo" + hub: gcr.io/istio-release + meshConfig: + # Change the following line to configure the trust domain of the Istio cluster. + trustDomain: cluster.local + values: + global: + # Change certificate provider to cert-manager istio agent for istio agent + caAddress: cert-manager-istio-csr.cert-manager.svc:443 + components: + pilot: + k8s: + env: + # Disable istiod CA Sever functionality + - name: ENABLE_CA_SERVER + value: "false" diff --git a/content/v1.15-docs/tutorials/venafi/venafi.md b/content/v1.15-docs/tutorials/venafi/venafi.md new file mode 100644 index 0000000000..d1a83964b9 --- /dev/null +++ b/content/v1.15-docs/tutorials/venafi/venafi.md @@ -0,0 +1,585 @@ +--- +title: Securing Ingresses with Venafi +description: 'cert-manager tutorials: Securing Ingress using Venafi Issuers' +--- + +This guide walks you through how to secure a Kubernetes +[`Ingress`](https://kubernetes.io/docs/concepts/services-networking/ingress/) +resource using the Venafi Issuer type. + +Whilst stepping through, you will learn how to: + +- Create an EKS cluster using [`eksctl`](https://github.com/weaveworks/eksctl) +- Install cert-manager into the EKS cluster +- Deploy [`nginx-ingress`](https://github.com/kubernetes/ingress-nginx) to + expose applications running in the cluster +- Configure a Venafi Cloud issuer +- Configure cert-manager to secure your application traffic + +While this guide focuses on EKS as a Kubernetes provisioner and Venafi +as a Certificate issuer, the steps here should be generally re-usable for other +Issuer types. + +## Prerequisites + +- An AWS account +- `kubectl` installed +- Access to a publicly registered DNS zone +- A Venafi Cloud account and API credentials + +## Create an EKS cluster + +If you already have a running EKS cluster you can skip this step and move onto +deploying cert-manager. + +[`eksctl`](https://eksctl.io/introduction/installation/) is a tool that makes it +easier to deploy and manage an EKS cluster. + +Installation instructions for various platforms can be found in the +[`eksctl` installation +instructions](https://eksctl.io/introduction/installation/). + +Once installed, you can create a basic cluster by running: + +``` +$ eksctl create cluster +``` + +This process may take up to 20 minutes to complete. Complete instructions on +using `eksctl` can be found in the [`eksctl` usage +section](https://eksctl.io/usage/creating-and-managing-clusters/). + +Once your cluster has been created, you should verify that your cluster is +running correctly by running the following command: + +``` +$ kubectl get pods --all-namespaces +NAME READY STATUS RESTARTS AGE +aws-node-8xpkp 1/1 Running 0 115s +aws-node-tflxs 1/1 Running 0 118s +coredns-694d9447b-66vlp 1/1 Running 0 23s +coredns-694d9447b-w5bg8 1/1 Running 0 23s +kube-proxy-4dvpj 1/1 Running 0 115s +kube-proxy-tpvht 1/1 Running 0 118s +``` + +You should see output similar to the above, with all pods in a Running state. + +## Installing cert-manager + +There are no special requirements to note when installing cert-manager on EKS, +so the regular [running on +Kubernetes](../../installation/README.md) guides +can be used to install cert-manager. + +Please walk through the installation guide and return to this step once you +have validated cert-manager is deployed correctly. + +## Installing `ingress-nginx` + +A [Kubernetes ingress +controller](https://eksctl.io/usage/creating-and-managing-clusters/) is designed +to be the access point for HTTP and HTTPS traffic to the software running within +your cluster. The [`ingress-nginx`](https://github.com/kubernetes/ingress-nginx) +controller does this by providing an HTTP proxy service supported by your cloud +provider's load balancer (in this case, a [Network Load Balancer +(NLB)](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html). + +You can get more details about `ingress-nginx` and how it works from the +[documentation for `ingress-nginx`](https://kubernetes.github.io/ingress-nginx/). + +To deploy `ingress-nginx` using an ELB to expose the service, run the following: + +Deploy the AWS specific prerequisite manifest +```bash +$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.4.0/deploy/static/provider/aws/deploy.yaml +``` + +Deploy the 'generic' `ingress-nginx` manifest +```bash +$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/aws/deploy.yaml +``` + +You may have to wait up to 5 minutes for all the required components in your +cluster and AWS account to become ready. + +You can run the following command to determine the address that Amazon has +assigned to your NLB: + +```bash +$ kubectl get service -n ingress-nginx +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +ingress-nginx LoadBalancer 10.100.52.175 a8c2870a5a8a311e9a9a10a2e7af57d7-6c2ec8ede48726ab.elb.eu-west-1.amazonaws.com 80:31649/TCP,443:30567/TCP 4m10s +``` + +The *EXTERNAL-IP* field may say `` for a while. This indicates the NLB +is still being created. Retry the command until an *EXTERNAL-IP* has been +provisioned. + +Once the *EXTERNAL-IP* is available, you should run the following command to +verify that traffic is being correctly routed to `ingress-nginx`: + +``` +$ curl http://a8c2870a5a8a311e9a9a10a2e7af57d7-6c2ec8ede48726ab.elb.eu-west-1.amazonaws.com/ + +404 Not Found + +

          404 Not Found

          +
          openresty/1.15.8.1
          + + +``` + +Whilst the above message would normally indicate an error (the page not being +found), in this instance it indicates that traffic is being correctly routed to +the `ingress-nginx` service. + +> Note: Although the AWS Application Load Balancer (ALB) is a modern load +> balancer offered by AWS that can can be provisioned from within EKS, at the +> time of writing, the +> [`alb-ingress-controller`](https://github.com/kubernetes-sigs/aws-alb-ingress-controller>) +> is only capable of serving sites using certificates stored in AWS Certificate +> Manager (ACM). Version 1.15 of Kubernetes should address multiple bug fixes +> for this controller and allow for TLS termination support. + +## Configure your DNS records + +Now that our NLB has been provisioned, we should point our application's DNS +records at the NLBs address. + +Go into your DNS provider's console and set a CNAME record pointing to your +NLB. + +For the purposes of demonstration, we will assume in this guide you have created +the following DNS entry: + +``` +example.com CNAME a8c2870a5a8a311e9a9a10a2e7af57d7-6c2ec8ede48726ab.elb.eu-west-1.amazonaws.com +``` + +As you progress through the rest of this tutorial, please replace `example.com` +with your own registered domain. + +## Deploying a demo application + +For the purposes of this demo, we provide an example deployment which is a +simple "hello world" website. + +First, create a new namespace that will contain your application: + +```bash +$ kubectl create namespace demo +namespace/demo created +``` + +Save the following YAML into a file named `demo-deployment.yaml`: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: hello-kubernetes + namespace: demo +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 8080 + selector: + app: hello-kubernetes +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hello-kubernetes + namespace: demo +spec: + replicas: 2 + selector: + matchLabels: + app: hello-kubernetes + template: + metadata: + labels: + app: hello-kubernetes + spec: + containers: + - name: hello-kubernetes + image: paulbouwer/hello-kubernetes:1.5 + resources: + requests: + cpu: 100m + memory: 100Mi + ports: + - containerPort: 8080 +``` + +Then run: + +```bash +kubectl apply -n demo -f demo-deployment.yaml +``` + +Note that the Service resource we deploy is of type `ClusterIP` and not +`LoadBalancer`, as we will expose and secure traffic for this service using +`ingress-nginx` that we deployed earlier. + +You should be able to see two Pods and one Service in the `demo` namespace: + +```bash +kubectl get po,svc -n demo +NAME READY STATUS RESTARTS AGE +hello-kubernetes-66d45d6dff-m2lnr 1/1 Running 0 7s +hello-kubernetes-66d45d6dff-qt2kb 1/1 Running 0 7s + +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +service/hello-kubernetes ClusterIP 10.100.164.58 80/TCP 7s +``` + +Note that we have not yet exposed this application to be accessible over the +internet. We will expose the demo application to the internet in later steps. + +## Creating a Venafi Issuer resource + +cert-manager supports both Venafi TPP and Venafi Cloud. + +Please only follow one of the below sections according to where you want to +retrieve your Certificates from. + +### Venafi TPP + +Assuming you already have a Venafi TPP server set up properly, you can create +a Venafi Issuer resource that can be used to issue certificates. + +To do this, you need to make sure you have your TPP *username* and *password*. + +In order for cert-manager to be able to authenticate with your Venafi TPP +server and set up an Issuer resource, you'll need to create a Kubernetes +Secret containing your username and password: + +```bash +$ kubectl create secret generic \ + venafi-tpp-secret \ + --namespace=demo \ + --from-literal=username='YOUR_TPP_USERNAME_HERE' \ + --from-literal=password='YOUR_TPP_PASSWORD_HERE' +``` + +We must then create a Venafi Issuer resource, which represents a certificate +authority within Kubernetes. + +Save the following YAML into a file named `venafi-issuer.yaml`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: venafi-issuer + namespace: demo +spec: + venafi: + zone: "Default" # Set this to the Venafi policy zone you want to use + tpp: + url: https://venafi-tpp.example.com/vedsdk # Change this to the URL of your TPP instance + caBundle: + credentialsRef: + name: venafi-tpp-secret +``` + +Then run: + +```bash +$ kubectl apply -n demo -f venafi-issuer.yaml +``` + +When you run the following command, you should see that the Status stanza of +the output shows that the Issuer is Ready (i.e. has successfully validated +itself with the Venafi TPP server). + +```bash +$ kubectl describe issuer -n demo venafi-issuer + + Status: + Conditions: + Last Transition Time: 2019-07-17T15:46:00Z + Message: Venafi issuer started + Reason: Venafi issuer started + Status: True + Type: Ready + Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Ready 14s cert-manager Verified issuer with Venafi server +``` + +### Venafi Cloud + +You can sign up for a Venafi Cloud account by visiting the [enrollment +page](https://www.venafi.com/cloud). + +Once registered, you should fetch your API key by clicking your name in the top +right of the control panel interface. + +In order for cert-manager to be able to authenticate with your Venafi Cloud +account and set up an Issuer resource, you'll need to create a Kubernetes +Secret containing your API key: + +```bash +$ kubectl create secret generic \ + venafi-cloud-secret \ + --namespace=demo \ + --from-literal=apikey= +``` + +We must then create a Venafi Issuer resource, which represents a certificate +authority within Kubernetes. + +Save the following YAML into a file named `venafi-issuer.yaml`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: venafi-issuer + namespace: demo +spec: + venafi: + zone: "Default" # Set this to the Venafi policy zone you want to use + cloud: + apiTokenSecretRef: + name: venafi-cloud-secret + key: apikey +``` + +Then run: + +```bash +$ kubectl apply -n demo -f venafi-issuer.yaml +``` + +When you run the following command, you should see that the Status stanza of +the output shows that the Issuer is Ready (i.e. has successfully validated +itself with the Venafi Cloud service). + +```bash +$ kubectl describe issuer -n demo venafi-issuer +... +Status: + Conditions: + Last Transition Time: 2019-07-17T15:46:00Z + Message: Venafi issuer started + Reason: Venafi issuer started + Status: True + Type: Ready +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Ready 14s cert-manager Verified issuer with Venafi server +``` + +## Request a Certificate + +Now that the Issuer is configured and we have confirmed it has been set up +correctly, we can begin requesting certificates which can be used by Kubernetes +applications. + +Full information on how to specify and request Certificate resources can be +found in the [Requesting Certificates](../../usage/certificate.md) guide. + +For now, we will create a basic X.509 Certificate that is valid for our domain, +`example.com`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com-tls + namespace: demo +spec: + secretName: example-com-tls + dnsNames: + - example.com + commonName: example.com + issuerRef: + name: venafi-issuer +``` + +Save this YAML into a file named `example-com-tls.yaml` and run: + +```bash +$ kubectl apply -n demo -f example-com-tls.yaml +``` + +As long as you've ensured that the zone of your Venafi Cloud account (in our +example, we use the "Default" zone) has been configured with a CA or contains a +custom certificate, cert-manager can now take steps to populate the +`example-com-tls` Secret with a certificate. It does this by identifying itself +with Venafi Cloud using the API key, then requesting a certificate to match the +specifications of the Certificate resource that we've created. + +You can run `kubectl describe` to check the progress of your Certificate: + +```bash +$ kubectl describe certificate -n demo example-com-tls +... +Status: + Conditions: + Last Transition Time: 2019-07-17T17:43:01Z + Message: Certificate is up to date and has not expired + Reason: Ready + Status: True + Type: Ready + Not After: 2019-10-15T12:00:00Z +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Issuing 33s cert-manager Requesting new certificate... + Normal GenerateKey 33s cert-manager Generated new private key + Normal Validate 33s cert-manager Validated certificate request against Venafi zone policy + Normal Requesting 33s cert-manager Requesting certificate from Venafi server... + Normal Retrieve 15s cert-manager Retrieved certificate from Venafi server + Normal CertIssued 15s cert-manager Certificate issued successfully +``` + +Once the Certificate has been issued, you should see events similar to above. + +You should then be able to see the certificate has been successfully stored in +the Secret resource: + +```bash +$ kubectl get secret -n demo example-com-tls +NAME TYPE DATA AGE +example-com-tls kubernetes.io/tls 3 2m47s + +$ kubectl get secret example-com-tls -o 'go-template={{index .data "tls.crt"}}' | \ + base64 --decode | \ + openssl x509 -noout -text +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0d:ce:bf:89:04:d4:41:83:f4:4c:32:66:64:fb:60:14 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, CN=DigiCert Test SHA2 Intermediate CA-1 + Validity + Not Before: Jul 17 00:00:00 2019 GMT + Not After : Oct 15 12:00:00 2019 GMT + Subject: C=US, ST=California, L=Palo Alto, O=Venafi Cloud, OU=SerialNumber, CN=example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ad:2e:66:02:20:c9:b1:6a:00:63:70:4e:22:3c: + 45:63:6e:e7:fd:4c:94:7d:75:50:22:a2:01:72:99: + 9c:23:04:90:51:85:4d:47:32:e4:8b:ee:b1:ea:09: + 1a:de:97:5d:31:05:a2:73:73:4f:06:a3:b2:59:ee: + bc:30:f7:26:85:3d:b3:56:e4:c2:97:34:b6:ac:6d: + 65:7e:a2:4e:b4:ce:f2:0a:0a:4c:d7:32:d7:5a:18: + e8:69:c6:34:28:26:36:ef:c5:bc:ae:ba:ca:d2:46: + 3f:d4:61:39:66:8f:19:cc:d6:d6:10:77:af:51:93: + 1b:4d:f8:d1:10:19:ab:ac:b3:7b:0b:98:58:29:e6: + a9:ac:9f:7a:dc:63:0d:51:f5:bd:9f:f3:03:2e:b3: + 2d:2f:00:87:f4:e1:cd:5a:32:c6:d8:fb:49:c4:e7: + da:3f:0f:8f:bb:66:94:28:5d:99:fe:7c:f0:17:1b: + fd:3e:ed:dd:36:bf:8e:62:60:0c:85:7f:76:74:4b: + 37:d9:c2:e8:74:49:04:bf:f1:83:81:cc:4f:9b:f3: + 40:97:d4:dc:b6:d3:2d:dc:73:18:93:48:a5:8f:6c: + 57:7f:ec:62:c0:bc:c2:b0:e9:0a:51:2d:c4:b6:87: + 68:96:87:f8:9a:86:3c:6a:f1:01:ca:57:c4:07:e7: + b0:51 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:D6:4D:F9:39:60:6C:73:C3:22:F5:AD:30:0C:2F:A0:D5:CA:75:4A:2A + + X509v3 Subject Key Identifier: + A3:B3:47:2C:41:5E:9C:B2:27:97:57:14:A4:2E:BA:8C:93:E7:01:65 + X509v3 Subject Alternative Name: + DNS:example.com + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl3.digicert.com/DigiCertTestSHA2IntermediateCA1.crl + + Full Name: + URI:http://crl4.digicert.com/DigiCertTestSHA2IntermediateCA1.crl + + X509v3 Certificate Policies: + Policy: 2.16.840.1.114412.1.1 + CPS: https://www.digicert.com/CPS + + Authority Information Access: + OCSP - URI:http://ocsp.digicert.com + CA Issuers - URI:http://cacerts.test.digicert.com/DigiCertTestSHA2IntermediateCA1.crt + + X509v3 Basic Constraints: critical + CA:FALSE + Signature Algorithm: sha256WithRSAEncryption + ae:d4:9c:8a:66:19:9e:7d:12:b7:05:c2:b6:33:b3:9c:a5:40: + 47:ab:34:8d:1b:0f:51:96:de:e9:46:5a:e4:16:10:43:56:bf: + fa:f8:64:f4:cb:53:39:5b:45:ca:7f:15:d9:59:25:21:23:c4: + 4d:dc:a7:f7:83:21:d2:3f:a8:0a:26:f4:ef:fa:1b:2b:7d:97: + 7e:28:f3:ca:cd:b2:c4:92:f3:92:27:7f:e0:f1:ac:d6:db:4c: + 10:8a:f8:6f:09:bb:b3:4f:19:06:aa:bb:74:1c:e0:51:42:f6: + 8c:7d:77:f7:80:a4:03:ab:a9:ae:ae:2b:89:17:af:2f:eb:f7: + 3d:61:7c:dd:e1:5d:d2:5a:c5:6a:f6:c8:92:4c:0a:b5:75:d1: + dd:39:f2:a7:a2:10:8c:6d:bf:ca:08:ad:b9:a9:df:e3:59:8f: + 64:16:3c:7e:8a:6e:27:fc:49:d7:06:f0:bd:94:15:f2:fd:0f: + 94:8a:b8:73:67:73:53:22:df:9d:36:e9:34:f9:2a:68:00:59: + 78:6d:2d:8f:a0:0f:13:af:bd:b3:aa:8c:37:c4:22:cf:23:fb: + 56:bc:4e:55:ae:3a:0a:e6:3e:b1:1a:22:71:7b:08:b8:00:41: + 14:26:f6:9b:9b:72:3f:eb:dc:dd:1b:db:a8:20:fd:54:75:ae: + 25:7f:80:e6 +``` + +In the next step, we'll configure your application to actually use this new +Certificate resource. + +## Exposing and securing your application + +Now that we have issued a Certificate, we can expose our application using a +Kubernetes Ingress resource. + +Create a file named `application-ingress.yaml` and save the following in it, +replacing `example.com` with your own domain name: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: frontend-ingress + namespace: demo +spec: + ingressClassName: nginx + tls: + - hosts: + - example.com + secretName: example-com-tls + rules: + - host: example.com + http: + paths: + - path: / + pathType: Exact + backend: + service: + name: kuard + port: + number: 80 +``` + +You can then apply this resource with: + +```bash +$ kubectl apply -n demo -f application-ingress.yaml +``` + +Once this has been created, you should be able to visit your application at the +configured URL, here `example.com`! + +Navigate to the address in your web browser and you should see the certificate +obtained via Venafi being used to secure application traffic. diff --git a/content/v1.15-docs/tutorials/zerossl/zerossl.md b/content/v1.15-docs/tutorials/zerossl/zerossl.md new file mode 100644 index 0000000000..e25ee3c784 --- /dev/null +++ b/content/v1.15-docs/tutorials/zerossl/zerossl.md @@ -0,0 +1,181 @@ +--- +title: "Securing Ingresses with ZeroSSL" +linkTitle: "Securing Ingresses with ZeroSSL" +--- + +# The ZeroSSL + +This guide walks you through how to secure a Kubernetes [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) resource using the ZeroSSL Issuer type. + +The ZeroSSL just like Let's Encrypt and its competitors allows to create free 90 days certificates. All is need is to create account at https://zerossl.com/. After that go to developer section and generate `EAB Credentials for ACME Clients`. You will need it later. + + +`Please note!` \ +EAB credentials are not stored in your account, please make sure to note them somewhere. Each click on "Generate" will create a new set of credentials. Even if you create multiple credentials, all of them will remain functional. + + + +# Prerequisites + +- An AWS account +- kubectl installed +- Access to a publicly registered DNS zone +- Kubernetes cluster, you can use AWS EKS +- [ingress-nginx](https://kubernetes.github.io/ingress-nginx/) deployed and working inside cluster + + +# Tutorial scenario: + +## Installing cert-manager + +Make sure you use cert-manager `1.8.2+`/`1.7.3+`. See [link](https://github.com/cert-manager/cert-manager/pull/5226) for more details. + +Please walk through the installation guide and return to this step once you +have validated cert-manager is deployed correctly. Follow steps under [running on +Kubernetes](../../installation/helm.md) to install in k8s. + +In order to automatically switch to the ZeroSSL we recommend setting default shim by adding the following configuration to values file. + +```yaml +ingressShim: + defaultIssuerName: "zerossl-production" + defaultIssuerKind: "ClusterIssuer" + +crds: + enabled: true +``` + +Install it using helm: +``` +helm upgrade --install --namespace cert-manager --version [[VAR::cert_manager_latest_version]] cert-manager jetstack/cert-manager -f values.yaml +``` + +## Configure your DNS records + +The best way to manage DNS using AWS is by using Route53. Create AWS account with permissions to modify Route53 rules. + +## EAB secret +Once you will get your credentials first step is to create seed with secrets. They are responsible for authenticating with your ZeroSSL account. + +```bash +$ kubectl create secret generic \ + zero-ssl-eabsecret \ + --namespace=cert-manager \ + --from-literal=secret='YOUR_ZEROSSL_EAB_HMAC_KEY' +``` + +### Another way of creating secret. + +Encode it in base64 first. +```bash +echo -n "YOUR_ZEROSSL_EAB_HMAC_KEY" | base64 -w 0 +``` + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: zero-ssl-eabsecret +data: + secret: YOUR_ENCODED_ZEROSSL_EAB_HMAC_KEY +``` +```bash +kubectl apply -f zero-ssl-eabsecret.yaml -n cert-manager +``` + +## Cluster issuer +Then we must create the `ZeroSSL` `ClusterIssuer`, let's call it `zerossl-production`. In our case we are using AWS. See pre-conditions to provision all required elements. + +```yaml +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: zerossl-production +spec: + acme: + # ZeroSSL ACME server + server: https://acme.zerossl.com/v2/DV90 + email: dummy-email@yopmail.com + + # name of a secret used to store the ACME account private key + privateKeySecretRef: + name: zerossl-prod + + # for each cert-manager new EAB credencials are required + externalAccountBinding: + keyID: YOUR_ZEROSSL_EAB_KEY_ID + keySecretRef: + name: zero-ssl-eabsecret + key: secret + keyAlgorithm: HS256 + + # ACME DNS-01 provider configurations to verify domain + solvers: + - selector: {} + dns01: + route53: + region: us-west-2 + # optional if ambient credentials are available; see ambient credentials documentation + # see Route53 for >0 issue "letsencrypt.org" and change to >0 issue "sectigo.com" + accessKeyID: ACCESS_KEY_ID + secretAccessKeySecretRef: + name: route53-credentials-secret + key: secret-access-key + +``` + +### Then run: + +```bash +$ kubectl apply -n cert-manager -f zerossl-production.yaml +``` + +```bash +$ kubectl describe Clusterissuer zerossl-prod + +Status: + Acme: + Last Registered Email: dummy-email@yopmail.com + Uri: https://acme.zerossl.com/v2/DV90/account/tXXX_NwSv15rlS_XXXX + Conditions: + Last Transition Time: 2021-09-09T17:03:26Z + Message: The ACME account was registered with the ACME server + Reason: ACMEAccountRegistered + Status: True + Type: Ready +``` + +### Please note! +If this step failed and the ACME account is not registered please check if secrets in `zero-ssl-eabsecret` are correct. + +## Request a ingress certificate + + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: test-ingress + namespace: default +spec: + rules: + - host: test.example.com + tls: + - secretName: secret-tls + +``` + +Apply test-ingress: + +```bash +kubectl apply -f ingress.yaml +``` + +You are set! Check your ingress. +```bash +kubectl describe ingress test-ingress -n default +# check if tls is terminated using secret-tls + +openssl s_client -showcerts -connect test.example.com:443 +# verify server certificate and its chain +``` diff --git a/content/v1.15-docs/usage/README.md b/content/v1.15-docs/usage/README.md new file mode 100644 index 0000000000..def51ce1fd --- /dev/null +++ b/content/v1.15-docs/usage/README.md @@ -0,0 +1,30 @@ +--- +title: Requesting Certificates +description: 'cert-manager usage: Overview' +--- + +
          + +
          + +Once an [`Issuer`](../configuration/README.md) has been configured, you're ready to issue your first certificate! + +There are several use cases and methods for requesting certificates through cert-manager: + +- [Securing Ingress Resources](./ingress.md): A method to secure ingress resources + in your cluster. +- [Securing OpenFaaS functions](https://docs.openfaas.com/reference/ssl/kubernetes-with-cert-manager/): + Secure your OpenFaaS services using cert-manager. +- [Integration with Garden](https://docs.garden.io/guides/cert-manager-integration): Garden is a + developer tool for developing Kubernetes applications which has first class + support for integrating cert-manager. +- [Securing Knative](https://knative.dev/docs/serving/encryption/enabling-automatic-tls-certificate-provisioning/): Secure + your Knative services with trusted HTTPS certificates. +- [Enable mTLS on Pods with CSI](./csi.md): Using the cert-manager CSI + driver to provide unique keys and certificates that share the lifecycle of + pods. +- [Securing Istio Gateway](https://istio.io/docs/tasks/traffic-management/ingress/ingress-certmgr/): + Secure your Istio Gateway in Kubernetes using cert-manager. +- [Securing Istio Service Mesh](./istio-csr/README.md): Using the cert-manager + [Istio](https://istio.io) integration, secure the mTLS PKI for each pod + through cert-manager managed certificates. diff --git a/content/v1.15-docs/usage/certificate.md b/content/v1.15-docs/usage/certificate.md new file mode 100644 index 0000000000..34bf98d0b4 --- /dev/null +++ b/content/v1.15-docs/usage/certificate.md @@ -0,0 +1,479 @@ +--- +title: Certificate resource +description: 'cert-manager usage: Certificates' +--- + +> **apiVersion:** cert-manager.io/v1
          +> **kind:** Certificate + +
          + +
          + +In cert-manager, the `Certificate` resource represents a human readable definition +of a certificate request. cert-manager uses this input to generate a private key +and [`CertificateRequest`](./certificaterequest.md) resource in order to obtain +a signed certificate from an [`Issuer`](../configuration/README.md) or +[`ClusterIssuer`](../configuration/README.md). The signed certificate and private +key are then stored in the specified `Secret` resource. cert-manager will ensure +that the certificate is [auto-renewed before it expires](#renewal-reissuance) and +[re-issued if requested](#non-renewal-reissuance). + +In order to issue any certificates, you'll need to configure an +[`Issuer`](../configuration/README.md) or [`ClusterIssuer`](../configuration/README.md) +resource first. + +## Creating Certificate Resources + +A `Certificate` resource specifies fields that are used to generate certificate +signing requests which are then fulfilled by the issuer type you have +referenced. `Certificates` specify which issuer they want to obtain the +certificate from by specifying the `certificate.spec.issuerRef` field. + +A `Certificate` resource, for the `example.com` and `www.example.com` DNS names, +`spiffe://cluster.local/ns/sandbox/sa/example` URI Subject Alternative Name, +that is valid for 90 days and renews 15 days before expiry is below. It contains +an exhaustive list of all options a `Certificate` resource may have however only +a subset of fields are required as labelled. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com + namespace: sandbox +spec: + # Secret names are always required. + secretName: example-com-tls + + # secretTemplate is optional. If set, these annotations and labels will be + # copied to the Secret named example-com-tls. These labels and annotations will + # be re-reconciled if the Certificate's secretTemplate changes. secretTemplate + # is also enforced, so relevant label and annotation changes on the Secret by a + # third party will be overwriten by cert-manager to match the secretTemplate. + secretTemplate: + annotations: + my-secret-annotation-1: "foo" + my-secret-annotation-2: "bar" + labels: + my-secret-label: foo + + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + + # keystores allows adding additional output formats. This is an example for reference only. + keystores: + pkcs12: + create: true + passwordSecretRef: + name: example-com-tls-keystore + key: password + profile: Modern2023 + + duration: 2160h # 90d + renewBefore: 360h # 15d + + isCA: false + usages: + - server auth + - client auth + + subject: + organizations: + - cert-manager + + # Avoid using commonName for DNS names in end-entity (leaf) certificates. Unless you have a specific + # need for it in your environment, use dnsNames exclusively to avoid issues with commonName. + # Usually, commonName is used to give human-readable names to CA certificates and can be avoided for + # other certificates. + commonName: example.com + + # The literalSubject field is exclusive with subject and commonName. It allows + # specifying the subject directly as a string. This is useful for when the order + # of the subject fields is important or when the subject contains special types + # which can be specified by their OID. + # + # literalSubject: "O=jetstack, CN=example.com, 2.5.4.42=John, 2.5.4.4=Doe" + + # At least one of commonName (possibly through literalSubject), dnsNames, uris, emailAddresses, ipAddresses or otherNames is required. + dnsNames: + - example.com + - www.example.com + uris: + - spiffe://cluster.local/ns/sandbox/sa/example + emailAddresses: + - john.doe@cert-manager.io + ipAddresses: + - 192.168.0.5 + # Needs cert-manager 1.14+ and "OtherNames" feature flag + otherNames: + # Should only supply oid of ut8 valued types + - oid: 1.3.6.1.4.1.311.20.2.3 # User Principal Name "OID" + utf8Value: upn@example.local + + # Issuer references are always required. + issuerRef: + name: ca-issuer + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + # This is optional since cert-manager will default to this value however + # if you are using an external issuer, change this to that issuer group. + group: cert-manager.io +``` + +The signed certificate will be stored in a `Secret` resource named +`example-com-tls` in the same namespace as the `Certificate` once the issuer has +successfully issued the requested certificate. + +If `secretTemplate` is present, annotations and labels set in this property +will be copied over to `example-com-tls` secret. Both properties are optional. + +The `Certificate` will be issued using the issuer named `ca-issuer` in the +`sandbox` namespace (the same namespace as the `Certificate` resource). + +> Note: If you want to create an `Issuer` that can be referenced by +> `Certificate` resources in _all_ namespaces, you should create a +> [`ClusterIssuer`](../concepts/issuer.md#namespaces) resource and set the +> `certificate.spec.issuerRef.kind` field to `ClusterIssuer`. + +> Note: The `renewBefore` and `duration` fields must be specified using a [Go +> `time.Duration`](https://golang.org/pkg/time/#ParseDuration) string format, +> which does not allow the `d` (days) suffix. You must specify these values +> using `s`, `m`, and `h` suffixes instead. Failing to do so without installing +> the [`webhook component`](../concepts/webhook.md) can prevent cert-manager +> from functioning correctly +> [`#1269`](https://github.com/cert-manager/cert-manager/issues/1269). + +> Note: Take care when setting the `renewBefore` field to be very close to the +> `duration` as this can lead to a renewal loop, where the `Certificate` is always +> in the renewal period. Some `Issuers` set the `notBefore` field on their +> issued X.509 certificates before the issue time to fix clock-skew issues, +> leading to the working duration of a certificate to be less than the full +> duration of the certificate. For example, Let's Encrypt sets it to be one hour +> before issue time, so the actual _working duration_ of the certificate is 89 +> days, 23 hours (the _full duration_ remains 90 days). + +A full list of the fields supported on the Certificate resource can be found in +the [API reference documentation](../reference/api-docs.md#cert-manager.io/v1.CertificateSpec). + +### Target Secret + +When a certificate is issued by an intermediate CA and the `Issuer` can provide +the issued certificate's chain, the contents of `tls.crt` will be the requested +certificate followed by the certificate chain. + +Additionally, if the Certificate Authority is known, the corresponding CA +certificate will be stored in the secret with key `ca.crt`. For example, with +the ACME issuer, the CA is not known and `ca.crt` will not exist in the Secret. +The `ca.crt` value at the time of issuance can be copied to the trust store of +the application that is using the certificate. However, DO NOT directly mount +the `ca.crt` value into the application's trust store, as it will be updated +when the certificate is renewed (see [Trusting certificates](../trust/README.md) for more details). + +cert-manager intentionally avoids adding root certificates to `tls.crt`, because they +are useless in a situation where TLS is being done securely. For more information, +see [RFC 5246 section 7.4.2](https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.2) +which contains the following explanation: + +> Because certificate validation requires that root keys be distributed +> independently, the self-signed certificate that specifies the root +> certificate authority MAY be omitted from the chain, under the +> assumption that the remote end must already possess it in order to +> validate it in any case. + + +### X.509 key usages and extended key usages + +cert-manager supports requesting certificates that have a number of [custom key +usages](https://tools.ietf.org/html/rfc5280#section-4.2.1.3) and [extended key +usages](https://tools.ietf.org/html/rfc5280#section-4.2.1.12). Although +cert-manager will attempt to honor this request, some issuers will remove, add +defaults, or otherwise completely ignore the request. +The `CA` and `SelfSigned` `Issuer` will always return certificates matching the usages you have requested. + +Unless any number of usages has been set, cert-manager will set the default +requested usages of `digital signature`, `key encipherment`, and `server auth`. +cert-manager will not attempt to request a new certificate if the current +certificate does not match the current key usage set. + +An exhaustive list of supported key usages can be found in the [API reference +documentation](../reference/api-docs.md#cert-manager.io/v1.KeyUsage). + + +### Additional Certificate Output Formats + +`additionalOutputFormats` is a field on the Certificate `spec` that allows +specifying additional supplementary formats of issued certificates and their +private key. There are currently two supported additional output formats: +`CombinedPEM` and `DER`. Both output formats can be specified on the same +Certificate. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +spec: + ... + secretName: my-cert-tls + additionalOutputFormats: + - type: CombinedPEM + - type: DER + +# Results in: + +apiVersion: v1 +kind: Secret +metadata: + name: my-cert-tls +type: kubernetes.io/tls +data: + ca.crt: + tls.key: + tls.crt: + tls-combined.pem: + key.der: +``` + +#### `CombinedPEM` + +The `CombinedPEM` type will create a new key entry in the resulting +Certificate's Secret `tls-combined.pem`. This entry will contain the PEM encoded +private key, followed by at least one new line character, followed by the PEM +encoded signed certificate chain- + +```text + + "\n" + +``` + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: my-cert-tls +type: kubernetes.io/tls +data: + tls-combined.pem: + ... +``` + +#### `DER` + +The `DER` type will create a new key entry in the resulting Certificate's Secret +`key.der`. This entry will contain the DER binary format of the private key. + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: my-cert-tls +type: kubernetes.io/tls +data: + key.der: + ... +``` + +### Creating Certificate With Name Constraints + +Root or Intermediate CA certificates can have name constraints. Name constraints indicates a name space within which all subject names in subsequent certificates in a certification path MUST be located. +Checkout https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10 for more details on this. + +
          + +⛔️ This feature is only enabled by adding it to the +`--feature-gates` flag on the cert-manager controller and webhook components: + +```bash +--feature-gates=NameConstraints=true +``` + +
          + +To create a CA Certificate with name constraints use the following configuration: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: ca-cert-example +spec: + secretName: example-ca-key-pair + isCA: true + issuerRef: + name: selfsigned + kind: ClusterIssuer + commonName: "example1.com" + dnsNames: + - example1.com + nameConstraints: + critical: true + permitted: + dnsDomains: ["example1.com", "example2.com"] + ipRanges: ["10.10.0.0/16"] + emailAddress: ["example@example.org"] + excluded: + ipRanges: ["10.10.0.0/24"] +``` + +Note that when used with cert-manager's built-in CA and SelfSigned Issuer, the SANs (DNS name, IP address, URI, and email address) are not checked with the certificate's own name constraints, and are not checked with any of name constraints contained in the chain of certificates the certificate belongs to. + +The certificate may get issued successfully, but be rejected by clients during TLS handshakes. + +## Issuance triggers + + +### Reissuance triggered by expiry (renewal) + +cert-manager will automatically renew `Certificate`s. It will calculate _when_ to renew a `Certificate` based on the issued X.509 certificate's duration and a 'renewBefore' value which specifies _how long_ before expiry a certificate should be renewed. + +`spec.duration` and `spec.renewBefore` fields on a `Certificate` can be used to specify an X.509 certificate's duration and a 'renewBefore' value. Default value for `spec.duration` is 90 days. Some issuers might be configured to only issue certificates with a set duration, so the actual duration may be different. +Minimum value for `spec.duration` is 1 hour and minimum value for `spec.renewBefore` is 5 minutes. +It is also required that `spec.duration` > `spec.renewBefore`. + +Once an X.509 certificate has been issued, cert-manager will calculate the renewal time for the `Certificate`. By default this will be 2/3 through the X.509 certificate's duration. If `spec.renewBefore` has been set, it will be `spec.renewBefore` amount of time before expiry. cert-manager will set `Certificate`'s `status.RenewalTime` to the time when the renewal will be attempted. + + + +### Reissuance triggered by user actions + +A certificate object is reissued under the following circumstances: + +- when a change is made to one of the following fields on the Certificate's + spec: `commonName`, `dnsNames`, `ipAddresses`, `uris`, `emailAddresses`, + `subject`, `isCA`, `usages`, `duration` or `issuerRef`; + A more detailed explanation can be found on the [FAQ page](../faq/README.md#when-do-certs-get-re-issued). +- when a reissuance is manually triggered with the following: + ```sh + cmctl renew cert-1 + ``` + Note that the above command requires [cmctl](../reference/cmctl.md#renew). + +
          + +**❌** Deleting the Secret resource associated with a Certificate resource is +**not a recommended solution** for manually rotating the private key. The +recommended way to manually rotate the private key is to trigger the reissuance +of the Certificate resource with the following command (requires +[`cmctl`](../reference/cmctl.md#renew)): + +```sh +cmctl renew cert-1 +``` + +
          + + +## Issuance behavior: Temporary Certificates while Issuing + +When requesting certificates [using the ingress-shim](./ingress.md), the +component `ingress-gce`, if used, requires that a temporary certificate is +present while waiting for the issuance of a signed certificate when serving. To +facilitate this, if the following annotation: + + ```yaml + cert-manager.io/issue-temporary-certificate: "true" + ``` + +is present on the certificate, a self-signed temporary certificate will be +present on the `Secret` until it is overwritten once the signed certificate has +been issued. + +Adding the following annotation on an ingress will automatically set "issue-temporary-certificate" on the certificate: + + ```yaml + acme.cert-manager.io/http01-edit-in-place: "true" + ``` + + +## Issuance behavior: Rotation of the private key + +By default, the private key won't be rotated automatically. Using the setting +`rotationPolicy: Always`, the private key Secret associated with a Certificate +object can be configured to be rotated as soon as an the Certificate is reissued (see +[Issuance triggers](#issuance-triggers)). + +With `rotationPolicy: Always`, cert-manager waits until the Certificate +object is correctly signed before overwriting the `tls.key` file in the +Secret. + +With this setting, you can expect **no downtime** if your application can detect +changes to the mounted `tls.crt` and `tls.key` and reload them gracefully or +automatically restart. + +If your application only loads the private key and signed certificate once +at start up, the new certificate won't immediately be served by your +application, and you will want to either manually restart your pod with +`kubectl rollout restart`, or automate the action by running +[wave](https://github.com/wave-k8s/wave). Wave is a Secret controller that +makes sure deployments get restarted whenever a mounted Secret changes. + +
          + +Re-use of private keys + +Some issuers, like the built-in [Venafi +issuer](../configuration/venafi.md), may disallow re-using private keys. +If this is the case, you must explicitly configure the `rotationPolicy: +Always` setting for each of your Certificate objects accordingly. + +
          + +In the following example, the certificate has been set with +`rotationPolicy: Always`: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +spec: + secretName: my-cert-tls + privateKey: + rotationPolicy: Always # 🔰 Here. +``` + +#### The `rotationPolicy` setting + +The possible values for `rotationPolicy` are: + +| Value | Description | +| ---------------------- | ------------------------------------------------------------- | +| `Never` (default) | cert-manager reuses the existing private key on each issuance | +| `Always` (recommended) | cert-manager regenerates a new private key on each issuance | + +With `rotationPolicy: Never`, a private key is only generated if one does not +already exist in the target Secret resource (using the `tls.key` key). All +further issuances will re-use this private key. This is the default in order to +maintain compatibility with previous releases. + +With `rotationPolicy: Always`, a new private key will be generated each time an +action triggers the reissuance of the certificate object (see [Actions that will +trigger a rotation of the private key](#actions-triggering-private-key-rotation) +above). Note that if the private key secret already exists when creating the +certificate object, the existing private key will not be used, since the +rotation mechanism also includes the initial issuance. + +
          + +👉 We recommend that you configure `rotationPolicy: Always` on your Certificate +resources. Rotating both the certificate and the private key simultaneously +prevents the risk of issuing a certificate with an exposed private key. Another +benefit to renewing the private key regularly is to let you be confident that +the private key rotation can be done in case of emergency. More generally, it is +a good practice to be rotating the keys as often as possible, reducing the risk +associated with compromised keys. + +
          + +## Cleaning up Secrets when Certificates are deleted + +By default, cert-manager does not delete the `Secret` resource containing the signed certificate when the corresponding `Certificate` resource is deleted. +This means that deleting a `Certificate` won't take down any services that are currently relying on that certificate, but the certificate will no longer be renewed. +The `Secret` needs to be manually deleted if it is no longer needed. + +If you would prefer the `Secret` to be deleted automatically when the `Certificate` is deleted, you need to configure your installation to pass the `--enable-certificate-owner-ref` flag to the controller. + +## Inner workings diagram for developers + + + +[1] https://cert-manager.io/docs/usage/certificaterequest diff --git a/content/v1.15-docs/usage/certificaterequest.md b/content/v1.15-docs/usage/certificaterequest.md new file mode 100644 index 0000000000..7afa1087e9 --- /dev/null +++ b/content/v1.15-docs/usage/certificaterequest.md @@ -0,0 +1,254 @@ +--- +title: CertificateRequest resource +description: 'cert-manager core concepts: CertificateRequests' +--- + +> **apiVersion:** cert-manager.io/v1 +> **kind:** CertificateRequest + +
          + +
          + +The `CertificateRequest` is a namespaced resource in cert-manager that is used +to request X.509 certificates from an [`Issuer`](../concepts/issuer.md). The resource +contains a base64 encoded string of a PEM encoded certificate request which is +sent to the referenced issuer. A successful issuance will return a signed +certificate, based on the certificate signing request. `CertificateRequests` are +typically consumed and managed by controllers or other systems and should not be +used by humans - unless specifically needed. + +A simple `CertificateRequest` looks like the following: + +```yaml +apiVersion: cert-manager.io/v1 +kind: CertificateRequest +metadata: + name: my-ca-cr +spec: + request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQzNqQ0NBY1lDQVFBd2daZ3hDekFKQmdOVkJBWVRBbHBhTVE4d0RRWURWUVFJREFaQmNHOXNiRzh4RFRBTApCZ05WQkFjTUJFMXZiMjR4RVRBUEJnTlZCQW9NQ0VwbGRITjBZV05yTVJVd0V3WURWUVFMREF4alpYSjBMVzFoCmJtRm5aWEl4RVRBUEJnTlZCQU1NQ0dwdmMyaDJZVzVzTVN3d0tnWUpLb1pJaHZjTkFRa0JGaDFxYjNOb2RXRXUKZG1GdWJHVmxkWGRsYmtCcVpYUnpkR0ZqYXk1cGJ6Q0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQwpBUW9DZ2dFQkFLd01tTFhuQkNiRStZdTIvMlFtRGsxalRWQ3BvbHU3TlZmQlVFUWl1bDhFMHI2NFBLcDRZQ0c5Cmx2N2kwOHdFMEdJQUgydnJRQmxVd3p6ZW1SUWZ4YmQvYVNybzRHNUFBYTJsY2NMaFpqUlh2NEVMaER0aVg4N3IKaTQ0MWJ2Y01OM0ZPTlRuczJhRkJYcllLWGxpNG4rc0RzTEVuZmpWdXRiV01Zeis3M3ptaGZzclRJUjRzTXo3cQpmSzM2WFM4UkRjNW5oVVcyYU9BZ3lnbFZSOVVXRkxXNjNXYXVhcHg2QUpBR1RoZnJYdVVHZXlZUUVBSENxZmZmCjhyOEt3YTFYK1NwYm9YK1ppSVE0Nk5jQ043OFZnL2dQVHNLZmphZURoNWcyNlk1dEVidHd3MWdRbWlhK0MyRHIKWHpYNU13RzJGNHN0cG5kUnRQckZrU1VnMW1zd0xuc0NBd0VBQWFBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQgpBUUFXR0JuRnhaZ0gzd0N3TG5IQ0xjb0l5RHJrMUVvYkRjN3BJK1VVWEJIS2JBWk9IWEFhaGJ5RFFLL2RuTHN3CjJkZ0J3bmlJR3kxNElwQlNxaDBJUE03eHk5WjI4VW9oR3piN0FVakRJWHlNdmkvYTJyTVhjWjI1d1NVQmxGc28Kd005dE1QU2JwcEVvRERsa3NsOUIwT1BPdkFyQ0NKNnZGaU1UbS9wMUJIUWJSOExNQW53U0lUYVVNSFByRzJVMgpjTjEvRGNMWjZ2enEyeENjYVoxemh2bzBpY1VIUm9UWmV1ZEp6MkxmR0VHM1VOb2ppbXpBNUZHd0RhS3BySWp3ClVkd1JmZWZ1T29MT1dNVnFNbGRBcTlyT24wNHJaT3Jnak1HSE9tTWxleVdPS1AySllhaDNrVDdKU01zTHhYcFYKV0ExQjRsLzFFQkhWeGlKQi9Zby9JQWVsCi0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo= + isCA: false + usages: + - signing + - digital signature + - server auth + # 90 days + duration: 2160h + issuerRef: + name: ca-issuer + # We can reference ClusterIssuers by changing the kind here. + # The default value is Issuer (i.e. a locally namespaced Issuer) + kind: Issuer + group: cert-manager.io +``` + +This `CertificateRequest` will make cert-manager attempt to request the `Issuer` +`ca-issuer` in the default issuer group `cert-manager.io`, return a +certificate based upon the certificate signing request. Other groups can be +specified inside the `issuerRef` which will change the targeted issuer to other +external, third party issuers you may have installed. + +The resource also exposes the option for stating the certificate as CA, Key +Usages, and requested validity duration. + +All fields within the `spec` of the `CertificateRequest`, as well as any managed +cert-manager annotations, are immutable and cannot be modified after creation. + +A successful issuance of the certificate signing request will cause an update to +the resource, setting the status with the signed certificate, the CA of the +certificate (if available), and setting the `Ready` condition to `True`. + +Whether issuance of the certificate signing request was successful or not, a retry of the +issuance will _not_ happen. It is the responsibility of some other controller to +manage the logic and life cycle of `CertificateRequests`. + +## Conditions +`CertificateRequests` have a set of strongly defined conditions that should be +used and relied upon by controllers or services to make decisions on what +actions to take next on the resource. + +### Ready +Each ready condition consists of the pair `Ready` - a boolean value, and +`Reason` - a string. The set of values and meanings are as follows: + +| Ready | Reason | Condition Meaning | +| ----- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| False | Pending | The `CertificateRequest` is currently pending, waiting for some other operation to take place. This could be that the `Issuer` does not exist yet or the `Issuer` is in the process of issuing a certificate. | +| False | Failed | The certificate has failed to be issued - either the returned certificate failed to be decoded or an instance of the referenced issuer used for signing failed. No further action will be taken on the `CertificateRequest` by its controller and it can be considered terminally failed. | +| True | Issued | A signed certificate has been successfully issued by the referenced `Issuer`. | + +This condition should be set by the issuer. + +### Denied +| Denied | Reason | Condition Meaning | +| ----- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| True | \ | The `CertificateRequest` was Denied by an approver. This `CertificateRequest` can be considered terminally failed. + +This condition should only be set by an approver. + +### Approved +| Approved | Reason | Condition Meaning | +| ----- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| True | \ | The `CertificateRequest` was approved by the approver. This `CertificateRequest` is approved and can be issued by the issuer. + +This condition should only be set by an approver. + +### InvalidRequest +| InvalidRequest | Reason | Condition Meaning | +| ----- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| True | \ | The `CertificateRequest` is invalid. This `CertificateRequest` can be considered terminally failed. + + +## UserInfo + +`CertificateRequests` include a set of `UserInfo` fields as part of the spec, +namely: `username`, `groups`, `uid`, and `extra`. These values contain the user +who created the `CertificateRequest`. This user will be cert-manager itself in +the case that the `CertificateRequest` was created by a +[`Certificate`](../usage/certificate.md) resource, or instead the user who created the +`CertificateRequest` directly. + +> **Warning**: These fields are managed by cert-manager and should _never_ be +> set or modified by anything else. When the `CertificateRequest` is created, +> these fields will be overridden, and any request attempting to modify them +> will be rejected. + + +### Approval +CertificateRequests can be `Approved` or `Denied`. These mutually exclusive +conditions gate a CertificateRequest from being signed by its managed signer. + +- A signer should _not_ sign a managed CertificateRequest without an Approved condition +- A signer _will_ sign a managed CertificateRequest with an Approved condition +- A signer will _never_ sign a managed CertificateRequest with a Denied condition + +These conditions are _permanent_, and cannot be modified or changed once set. + +```bash +NAMESPACE NAME APPROVED DENIED READY ISSUER REQUESTOR AGE +istio-system service-mesh-ca-whh5b True True mesh-ca system:serviceaccount:istio-system:istiod 16s +istio-system my-app-fj9sa True mesh-ca system:serviceaccount:my-app:my-app 4s +``` + + +#### Behavior + +The Approved and Denied conditions are two distinct condition types on the +CertificateRequest. These conditions must only have the status of True, and +are mutually exclusive (i.e. a CertificateRequest cannot have an Approved and +Denied condition simultaneously). This behavior is enforced in the cert-manager +validating admission webhook. + +An "approver" is an entity that is responsible for setting the Approved/Denied +conditions. It is up to the approver's implementation as to what +CertificateRequests are managed by that approver. + +The Reason field of the Approved/Denied condition should be set to *who* set the +condition. Who can be interpreted however makes sense to the approver +implementation. For example, it may include the API group of an approving policy +controller, or the client agent of a manual request. + +The Message field of the Approved/Denied condition should be set to *why* the +condition is set. Again, why can be interpreted however makes sense to the +implementation of the approver. For example, the name of the resource that +approves this request, the violations which caused the request to be denied, or +the team to who manually approved the request. + + +#### Approver Controller + +By default, cert-manager will run an internal approval controller which will +automatically approve _all_ CertificateRequests that reference any internal +issuer type in any namespace: `cert-manager.io/Issuer`, +`cert-manager.io/ClusterIssuer`. + +**Disabling the internal auto approver:** + +To disable this controller, in the Helm chart set the `disableAutoApproval` value to `true`: + +```bash +# ⚠️ This Helm option is only available in cert-manager v1.15.0 and later. +--set disableAutoApproval=true +``` + +**Approving additional issuers using the internal auto approver:** + +Alternatively, in order for the internal approver controller to approve +CertificateRequests that reference an external issuer, in the Helm chart add the +issuers to the `approveSignerNames` list, or set the `approveSignerNames` value +to an empty list to approve all issuers (internal and external). + +```bash +# ⚠️ This Helm option is only available in cert-manager v1.15.0 and later. +--set approveSignerNames[0]="issuers.cert-manager.io/*" \ +--set approveSignerNames[1]="clusterissuers.cert-manager.io/*" \ +\ +--set approveSignerNames[2]="issuers.my-issuer.example.com/*" \ +--set approveSignerNames[3]="clusterissuers.my-issuer.example.com/*" +``` + +#### RBAC Syntax + +When a user or controller attempts to approve or deny a CertificateRequest, the +cert-manager webhook will evaluate whether it has sufficient permissions to do +so. These permissions are based upon the request +itself- specifically the request's IssuerRef: + +```yaml +apiGroups: ["cert-manager.io"] +resources: ["signers"] +verbs: ["approve"] +resourceNames: + # namesapced signers + - "./." + # cluster scoped signers + - "./" + # all signers of this resource name + - "./*" +``` + +An example ClusterRole that would grant the permissions to set the Approve and +Denied conditions of CertificateRequests that reference the cluster scoped +`myissuers` external issuer, in the group `my-example.io`, with the name `myapp`: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: my-example-io-my-issuer-myapp-approver +rules: + - apiGroups: ["cert-manager.io"] + resources: ["signers"] + verbs: ["approve"] + resourceNames: ["myissuers.my-example.io/myapp"] +``` + +If the approver does not have sufficient permissions defined above to set the +Approved or Denied conditions, the request will be rejected by the cert-manager +validating admission webhook. + +- The RBAC permissions *must* be granted at the cluster scope +- Namespaced signers are represented by a namespaced resource using the syntax of `./.` +- Cluster scoped signers are represented using the syntax of `./` +- An approver can be granted approval for all namespaces via `./*` +- The apiGroup must *always* be `cert-manager.io` +- The resource must *always* be `signers` +- The verb must *always* be `approve`, which grants the approver the permissions to set *both* Approved and Denied conditions + +An example of signing all `myissuer` signers in all namespaces, and +`clustermyissuers` with the name `myapp`, in the `my-example.io` group: + +```yaml + resourceNames: ["myissuers.my-example.io/*", "clustermyissuers.my-example.io/myapp"] +``` + +An example of signing `myissuer` with the name `myapp` in the namespaces `foo` +and `bar`: + +```yaml + resourceNames: ["myissuers.my-example.io/foo.myapp", "myissuers.my-example.io/bar.myapp"] +``` + +## Inner workings diagram for developers + + diff --git a/content/v1.15-docs/usage/csi-driver-spiffe/README.md b/content/v1.15-docs/usage/csi-driver-spiffe/README.md new file mode 100644 index 0000000000..9acfa65a5b --- /dev/null +++ b/content/v1.15-docs/usage/csi-driver-spiffe/README.md @@ -0,0 +1,236 @@ +--- +title: csi-driver-spiffe +description: 'Container Storage Interface (CSI) driver plugin for Kubernetes, providing SPIFFE SVIDs using cert-manager' +--- + +csi-driver-spiffe is a Container Storage Interface (CSI) driver plugin for +Kubernetes, designed to work alongside [cert-manager](https://cert-manager.io/). + +It transparently delivers [SPIFFE](https://spiffe.io/) [SVIDs](https://spiffe.io/docs/latest/spiffe-about/spiffe-concepts/#spiffe-verifiable-identity-document-svid) +(in the form of X.509 certificate key pairs) to mounting Kubernetes Pods. + +The end result is that any and all Pods running in Kubernetes can securely request +a SPIFFE identity document from a Trust Domain with minimal configuration. + +These documents in turn have the following properties: + +- automatically renewed ✔️ +- private key never leaves the node's virtual memory ✔️ +- each Pod's document is unique ✔️ +- the document shares the same life cycle as the Pod and is destroyed on Pod termination ✔️ +- enable mTLS within a trust domain ✔️ + +```yaml +... + volumeMounts: + - mountPath: "/var/run/secrets/spiffe.io" + name: spiffe + volumes: + - name: spiffe + csi: + driver: spiffe.csi.cert-manager.io + readOnly: true +``` + +### Components + +The project is split into two components: the driver and the approver. + +#### CSI Driver + +The CSI driver runs as DaemonSet on the cluster and is responsible for +generating, requesting, and mounting a certificate and private key to Pods on the +node it manages. The CSI driver creates and manages a +[tmpfs](https://www.kernel.org/doc/html/latest/filesystems/tmpfs.html) directory. + +When a Pod is created with the CSI volume configured, the +driver will locally generate a private key, and create a cert-manager +[CertificateRequest](../../usage/certificaterequest.md) +in the same Namespace as the Pod. + +The driver uses [CSI Token Requests](https://kubernetes-csi.github.io/docs/token-requests.html). +This means that the token of the pod being created is passed to the driver. + +This token's details are used for creating the SPIFFE ID which represents the pod's identity, +and the token is used for creating the actual CertificateRequest for the SVID. + +Once the certificate is signed by the configured cert-manager issuer, the driver +mounts the private key and certificate into the Pod's Volume, and watches the +certificate to renew it and the private key based on the certificate's +expiry date. + +#### Approver + +A distinct [cert-manager approver](../../usage/certificaterequest.md#approval) +Deployment is responsible for managing approval and denial of csi-driver-spiffe +CertificateRequests. + +The approver ensures that requests have: + +1. acceptable key usages (Key Encipherment, Digital Signature, Client Auth, Server Auth); +2. a requested duration which matches the enforced duration (default 1 hour); +3. no [SANs](https://en.wikipedia.org/wiki/Subject_Alternative_Name) or other + identifiable attributes except a single [URI SAN](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier); +4. a URI SAN which is the SPIFFE identity of the ServiceAccount which created + the CertificateRequest; +5. a SPIFFE ID Trust Domain matching the one that was configured at startup. + +The approver only considers CertificateRequests which have the +`spiffe.csi.cert-manager.io/identity` annotation, which is added by csi-driver-spiffe + to all requests it creates. + +## Installation + +See the [installation guide](./installation.md) for instructions on how to +install csi-driver-spiffe. + +## Security Considerations + +csi-driver-spiffe deals with highly valuable credentials which should be kept secret. The design +of using a Kubernetes CSI volume makes it simple to restrict access to only the pod which mounts +the CSI volume, but care should still be taken not to expose the private key created by csi-driver-spiffe. + +csi-driver-spiffe _always_ uses the token of the pod it's issuing for to create the CertificateRequest +resource for the SVID it creates. That means that: + +1. During issuance, csi-driver-spiffe has the ability to do whatever the Pod can do; bear in mind that a + compromised csi-driver-spiffe pod could abuse these permissions, although in normal operation only the + CertificateRequest permission is used. +2. Importantly: all pods using csi-driver-spiffe must have permission to create CertificateRequest resources. + +The requirement for a pod to have permission to create CertificateRequests has important security +implications. If a Pod with these permissions is compromised it can create arbitrary CertificateRequest +resources, which could reference arbitrary issuers in the cluster. + +Since csi-driver-spiffe requires that approval is used in-cluster, this risk is mitigated by approval. + +It's important, though, that any other forms of approval in the cluster (such as approver-policy) are +carefully configured not to overlap with the csi-driver-spiffe approver and to restrict access to other +issuers. + +For example, an approver-policy `CertificateRequestPolicy` resource which allowed any pod to issue +using an ACME (Let's Encrypt) issuer might allow a compromised Pod to issue a publicly trusted +certificate, if that Pod used csi-driver-spiffe and thus had permissions to create CertificateRequest +resources. + +Using csi-driver-spiffe safely means considering which approval methods are available in your cluster +and carefully configuring those approvers to ensure that pods cannot target issuers they're not meant +to be able to use. + +## Usage + +Once the driver is successfully installed, Pods can begin to request and mount +their key and SPIFFE certificate. Since the Pod's ServiceAccount is impersonated +when creating CertificateRequests, every ServiceAccount must be given that +permission which intends to use the volume. + +Example manifest with a dummy Deployment: + +```bash +kubectl apply -f https://raw.githubusercontent.com/cert-manager/csi-driver-spiffe/ed646ccf28b1ecdf63f628bf16f1d350a9b850c1/deploy/example/example-app.yaml + +kubectl exec -n sandbox \ + $(kubectl get pod -n sandbox -l app=my-csi-app -o jsonpath='{.items[0].metadata.name}') \ + -- \ + cat /var/run/secrets/spiffe.io/tls.crt | \ + openssl x509 --noout --text | \ + grep "Issuer:" +# expected output: Issuer: CN = csi-driver-spiffe-ca + +kubectl exec -n sandbox \ + $(kubectl get pod -n sandbox -l app=my-csi-app -o jsonpath='{.items[0].metadata.name}') \ + -- \ + cat /var/run/secrets/spiffe.io/tls.crt | \ + openssl x509 --noout --text | \ + grep "URI:" +# expected output: URI:spiffe://foo.bar/ns/sandbox/sa/example-app +``` + +### Runtime Configuration + +If csi-driver-spiffe was installed with runtime configuration enabled, it will watch +a named ConfigMap for issuer configuration. If that ConfigMap exists and contains a valid issuer +reference, that issuer will be used for all created CertificateRequest resources. + +If the ConfigMap is deleted or does not contain a valid issuer reference, it will be +ignored. If a default issuer was specified at install time, that default will be used +as a fallback. If no valid runtime configuration is provided and no default issuer was +specified, issuance (and therefore pod creation) will fail until a valid issuer is configured. + +The name of the runtime configuration ConfigMap is set with the `app.runtimeIssuanceConfigMap` +Helm value at install time. A valid ConfigMap must contain the `issuer-name`, `issuer-kind` +and `issuer-group` keys. + +An example of creating a ConfigMap for a ClusterIssuer named `my-issuer-name` is below: + +```console +kubectl create configmap spiffe-issuer -n cert-manager \ + --from-literal=issuer-name=my-issuer-name \ + --from-literal=issuer-kind=ClusterIssuer \ + --from-literal=issuer-group=cert-manager.io +``` + +### FS-Group + +When running Pods with a specified user or group, the volume will not be +readable by default due to Unix based file system permissions. The mounting +volumes file group can be specified using the following volume attribute: + +```yaml +... + securityContext: + runAsUser: 123 + runAsGroup: 456 + volumes: + - name: spiffe + csi: + driver: spiffe.csi.cert-manager.io + readOnly: true + volumeAttributes: + spiffe.csi.cert-manager.io/fs-group: "456" +``` + +```bash +kubectl apply -f https://raw.githubusercontent.com/cert-manager/csi-driver-spiffe/ed646ccf28b1ecdf63f628bf16f1d350a9b850c1/deploy/example/fs-group-app.yaml + +kubectl exec -n sandbox $(kubectl get pod -n sandbox -l app=my-csi-app-fs-group -o jsonpath='{.items[0].metadata.name}') -- cat /var/run/secrets/spiffe.io/tls.crt | openssl x509 --noout --text | grep URI: +# expected output: URI:spiffe://foo.bar/ns/sandbox/sa/fs-group-app +``` + +### Root CA Bundle + +> ⚠️ This feature is significantly less powerful than [trust-manager](../../trust/trust-manager/README.md), +> and is much harder to use and update. It's recommended to use trust-manager instead. + +By default, the CSI driver will only mount the Pod's private key and signed +certificate. csi-driver-spiffe can be optionally configured to also mount a +statically defined CA bundle from a volume that will be written to all Pod +volumes. + +If the CSI driver detects this bundle has changed (through overwrite, renewal, +etc), the new bundle will be written to all existing volumes. + +The following example mounts the CA certificate used by the Trust Domain +ClusterIssuer. + +```terminal +helm upgrade -i -n cert-manager cert-manager-csi-driver-spiffe jetstack/cert-manager-csi-driver-spiffe --wait \ + --set "app.logLevel=1" \ + --set "app.trustDomain=my.trust.domain" \ + \ + --set "app.runtimeIssuanceConfigMap=spiffe-issuer" + --set "app.issuer.name=csi-driver-spiffe-ca" \ + --set "app.issuer.kind=ClusterIssuer" \ + --set "app.issuer.group=cert-manager.io" \ + \ + --set "app.driver.volumes[0].name=root-cas" \ + --set "app.driver.volumes[0].secret.secretName=csi-driver-spiffe-ca" \ + --set "app.driver.volumeMounts[0].name=root-cas" \ + --set "app.driver.volumeMounts[0].mountPath=/var/run/secrets/cert-manager-csi-driver-spiffe" \ + --set "app.driver.sourceCABundle=/var/run/secrets/cert-manager-csi-driver-spiffe/ca.crt" + +kubectl rollout restart deployment -n sandbox my-csi-app + +kubectl exec -it -n sandbox $(kubectl get pod -n sandbox -l app=my-csi-app -o jsonpath='{.items[0].metadata.name}') -- ls /var/run/secrets/spiffe.io/ +# expected output: ca.crt tls.crt tls.key +``` diff --git a/content/v1.15-docs/usage/csi-driver-spiffe/installation.md b/content/v1.15-docs/usage/csi-driver-spiffe/installation.md new file mode 100644 index 0000000000..c2244c8d30 --- /dev/null +++ b/content/v1.15-docs/usage/csi-driver-spiffe/installation.md @@ -0,0 +1,128 @@ +--- +title: Installing cert-manager csi-driver-spiffe +description: 'Installation guide for cert-manager csi-driver-spiffe' +--- + +## Installation Steps + +### 1. Install cert-manager + +csi-driver-spiffe requires cert-manager to be [installed](../../installation/README.md) but +a default installation of cert-manager **will not work**. + +> ⚠️ It is **vital** that the [default approver is disabled in cert-manager](../../usage/certificaterequest.md#approver-controller) ⚠️ + +If the default approver is not disabled, the csi-driver-spiffe approver will +race with cert-manager and policy enforcement will become useless. + +Policy enforcement is absolutely critical for using csi-driver-spiffe safely. See +the [security considerations](./README.md#security-considerations) section for more details. + +Here's a example which reconfigure an installed cert-manager (v1.15.0+) to run without auto-approver: + +```terminal +# ⚠️ This Helm option is only available in cert-manager v1.15.0 and later. + +existing_cert_manager_version=$(helm get metadata -n cert-manager cert-manager | grep '^VERSION' | awk '{ print $2 }') +helm upgrade cert-manager jetstack/cert-manager \ + --reuse-values \ + --namespace cert-manager \ + --version $existing_cert_manager_version \ + --set disableAutoApproval=true +``` + +### 2. Configure an Issuer / ClusterIssuer + +> This step can be deferred if you use [runtime configuration](./README.md#runtime-configuration), +> but a valid issuer must be configured before a pod can successfully use +> csi-driver-spiffe to obtain an SVID. + +Install or configure some kind of issuer which will be used for signing +CertificateRequest resources in your Trust Domain. + +If you wish to use a namespace-scoped issuer it must be created in every namespace +that Pods will mount volumes from. + +You must use an Issuer type which is compatible with signing certificates with a custom +URI SAN. ACME issuers won't generally work, and the SelfSigned issuer is not appropriate. + +An example demo [ClusterIssuer](../../concepts/issuer.md#namespaces) can +be found [in the csi-driver-spiffe repo](https://github.com/cert-manager/csi-driver-spiffe/blob/ed646ccf28b1ecdf63f628bf16f1d350a9b850c1/deploy/example/clusterissuer.yaml). + +> ⚠️ This Trust Domain's root CA is generated by cert-manager and **the private key is stored in the cluster**! +> +> This might not be appropriate for production deployments, depending on your threat model. + +We'll also use [cmctl](../../reference/cmctl.md) to approve the CertificateRequest, +since the default approver was disabled above. + +```terminal +kubectl apply -f https://raw.githubusercontent.com/cert-manager/csi-driver-spiffe/ed646ccf28b1ecdf63f628bf16f1d350a9b850c1/deploy/example/clusterissuer.yaml + +# We must also approve the CertificateRequest since we +# disabled the default approver +cmctl approve -n cert-manager \ + $(kubectl get cr -n cert-manager -ojsonpath='{.items[0].metadata.name}') +``` + +### 3. Install csi-driver-spiffe + +Install csi-driver-spiffe into the cluster using the issuer we configured. We +must also configure the issuer resource type and name of the issuer we +configured so that the approver has [permissions to approve referencing CertificateRequests](../../usage/certificaterequest.md#rbac-syntax). + +Installation varies slightly depending on whether you want to use runtime configuration, which is recommended. + +#### With Runtime Configuration + +First, create a ConfigMap in the installation namespace with details of the issuer to want to use. + +The issuer doesn't have to exist until a pod tries to mount csi-driver-spiffe. + +The name of the ConfigMap is passed into csi-driver-spiffe at install time. + +```bash +kubectl create configmap -n cert-manager spiffe-issuer \ + --from-literal=issuer-name=csi-driver-spiffe-ca \ + --from-literal=issuer-kind=ClusterIssuer \ + --from-literal=issuer-group=cert-manager.io +``` + +```bash +helm upgrade -i -n cert-manager cert-manager-csi-driver-spiffe jetstack/cert-manager-csi-driver-spiffe --wait \ + --set "app.logLevel=1" \ + --set "app.trustDomain=my.trust.domain" \ + --set "app.issuer.name=" \ + --set "app.issuer.kind=" \ + --set "app.issuer.group=" \ + --set "app.runtimeIssuanceConfigMap=spiffe-issuer" +``` + +In the example above the default issuer values (i.e. `app.issuer.name`, `app.issuer.kind` and `app.issuer.group`) +are explicitly set to be empty, meaning that only runtime configuration will be used. + +You can set the default issuer values if you want to fall back to that issuer in the event that the runtime +configuration ConfigMap is invalid or deleted. + +#### Without Runtime Configuration + +Note that the `issuer.name`, `issuer.kind` and `issuer.group` will need to be changed to match +the issuer you're actually using! + +```bash +helm repo add jetstack https://charts.jetstack.io --force-update + +helm upgrade cert-manager-csi-driver-spiffe jetstack/cert-manager-csi-driver-spiffe \ + --install \ + --namespace cert-manager \ + --wait \ + --set "app.logLevel=1" \ + --set "app.trustDomain=my.trust.domain" \ + --set "app.issuer.name=csi-driver-spiffe-ca" \ + --set "app.issuer.kind=ClusterIssuer" \ + --set "app.issuer.group=cert-manager.io" +``` + +## Usage + +> 📖 Read the [csi-driver-spiffe docs](./README.md). diff --git a/content/v1.15-docs/usage/csi-driver/README.md b/content/v1.15-docs/usage/csi-driver/README.md new file mode 100644 index 0000000000..51136fdfb9 --- /dev/null +++ b/content/v1.15-docs/usage/csi-driver/README.md @@ -0,0 +1,174 @@ +--- +title: csi-driver +description: 'Mounting cert-manager certificates without secrets' +--- + +csi-driver is a [Container Storage Interface (CSI)](https://kubernetes-csi.github.io/docs/) 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](./installation.md) 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`. + +```yaml +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](../../configuration/README.md). + +**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: + +| Attribute | Description | Default | Example | +|-----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|--------------------------------------|----------------------------------| +| `csi.cert-manager.io/issuer-name` | The Issuer name to sign the certificate request. | | `ca-issuer` | +| `csi.cert-manager.io/issuer-kind` | The Issuer kind to sign the certificate request. | `Issuer` | `ClusterIssuer` | +| `csi.cert-manager.io/issuer-group` | The group name the Issuer belongs to. | `cert-manager.io` | `out.of.tree.foo` | +| `csi.cert-manager.io/common-name` | Certificate common name (supports variables). | | `my-cert.foo` | +| `csi.cert-manager.io/dns-names` | DNS 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-sans` | IP addresses the certificate will be requested for. | | `192.0.0.1,192.0.0.2` | +| `csi.cert-manager.io/uri-sans` | URI names the certificate will be requested for (supports variables). | | `spiffe://foo.bar.cluster.local` | +| `csi.cert-manager.io/duration` | Requested duration the signed certificate will be valid for. | `720h` | `1880h` | +| `csi.cert-manager.io/is-ca` | Mark the certificate as a certificate authority. | `false` | `true` | +| `csi.cert-manager.io/key-usages` | Set the key usages on the certificate request. | `digital signature,key encipherment` | `server auth,client auth` | +| `csi.cert-manager.io/key-encoding` | Set the key encoding format (PKCS1 or PKCS8). | `PKCS1` | `PKCS8` | +| `csi.cert-manager.io/certificate-file` | File name to store the certificate file at. | `tls.crt` | `foo.crt` | +| `csi.cert-manager.io/ca-file` | File name to store the ca certificate file at. | `ca.crt` | `foo.ca` | +| `csi.cert-manager.io/privatekey-file` | File name to store the key file at. | `tls.key` | `foo.key` | +| `csi.cert-manager.io/fs-group` | Set 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-before` | The time to renew the certificate before expiry. Defaults to a third of the requested duration. | `$CERT_DURATION/3` | `72h` | +| `csi.cert-manager.io/reuse-private-key` | Re-use the same private when when renewing certificates. | `false` | `true` | +| `csi.cert-manager.io/pkcs12-enable` | Enable writing the signed certificate chain and private key as a PKCS12 file. | | `true` | +| `csi.cert-manager.io/pkcs12-filename` | File location to write the PKCS12 file. Requires `csi.cert-manager.io/keystore-pkcs12-enable` be set to `true`. | `keystore.p12` | `tls.p12` | +| `csi.cert-manager.io/pkcs12-password` | Password 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. + +```text +csi.cert-manager.io/common-name +csi.cert-manager.io/dns-names +csi.cert-manager.io/uri-sans +``` + +Variables follow the [go `os.Expand`](https://pkg.go.dev/os#Expand) structure, +which is generally what you would expect on a UNIX shell. The CSI driver has +access to the following variables: + +```text +${POD_NAME} +${POD_NAMESPACE} +${POD_UID} +${SERVICE_ACCOUNT_NAME} +``` + +#### Example Usage + +```yaml +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](../../usage/certificaterequest.md) resource will be created +by the mounting Pod's ServiceAccount. This can be paired with +[approver-policy](../../policy/approval/approver-policy/README.md) 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: + +```yaml +# 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 +``` diff --git a/content/v1.15-docs/usage/csi-driver/installation.md b/content/v1.15-docs/usage/csi-driver/installation.md new file mode 100644 index 0000000000..4b325dafe9 --- /dev/null +++ b/content/v1.15-docs/usage/csi-driver/installation.md @@ -0,0 +1,54 @@ +--- +title: Installing cert-manager csi-driver +description: 'Installation guide for cert-manager csi-driver' +--- + +## Installation Steps + +You must have a working installation of cert-manager present on your cluster and be running at least Kubernetes `v1.19`. + +Instructions on how to install cert-manager can be found [on this website](../../installation/README.md). + +To install csi-driver, use helm: + +```terminal +helm repo add jetstack https://charts.jetstack.io --force-update + +helm upgrade cert-manager-csi-driver jetstack/cert-manager-csi-driver \ + --install \ + --namespace cert-manager \ + --wait +``` + +You can verify the installation has completed correctly by checking the presence +of the CSIDriver resource as well as a CSINode resource present for each node, +referencing `csi.cert-manager.io`. + +```terminal +$ kubectl get csidrivers +NAME CREATED AT +csi.cert-manager.io 2019-09-06T16:55:19Z + +$ kubectl get csinodes -o yaml +apiVersion: v1 +items: +- apiVersion: storage.k8s.io/v1beta1 + kind: CSINode + metadata: + name: kind-control-plane + ownerReferences: + - apiVersion: v1 + kind: Node + name: kind-control-plane +... + spec: + drivers: + - name: csi.cert-manager.io + nodeID: kind-control-plane + topologyKeys: null +... +``` + +## Usage + +> 📖 Read the [csi-driver docs](./README.md). diff --git a/content/v1.15-docs/usage/csi.md b/content/v1.15-docs/usage/csi.md new file mode 100644 index 0000000000..a05b6017ee --- /dev/null +++ b/content/v1.15-docs/usage/csi.md @@ -0,0 +1,92 @@ +--- +title: CSI Driver +description: 'cert-manager usage: CSI driver' +--- + +
          + +
          + +## Enabling mTLS of Pods using cert-manager csi-driver + +[csi-driver](./csi-driver/README.md) facilitates secretless provisioning of certificates +for pods in a Kubernetes cluster. + +Using this driver will ensure that the private key and corresponding signed +certificate will be unique to each Pod and will be stored on disk to the node +that the Pod is scheduled to. + +The life cycle of the certificate key pair matches that of the Pod; the certificate is issued +when the Pod is creation, and destroyed during termination. + +This driver also handles renewal of live certificates on the fly. + +## What's a CSI driver? + +A [Kubernetes CSI driver](https://kubernetes-csi.github.io/docs/introduction.html) +is a storage plugin which is deployed into your Kubernetes cluster. + +It can honor volume requests in Pod specifications, just like those enabled by default such as +the `Secret`, `ConfigMap`, or `hostPath` volume drivers. + +In the case of cert-manager's csi-driver an [ephemeral volume](https://kubernetes.io/docs/concepts/storage/volumes/#csi-ephemeral-volumes) +is used, meaning that the volume is created and destroyed as the Pod is created and +terminated. + +This means that not only are volumes created with unique certificates and keys per Pod, +but also that the private key never leaves the host's node, and that the desired certificate for +that Pod template can be defined in line with the spec or template for the pod. + +> **Warning**: Use of the CSI driver is mostly intended for supporting a PKI in +> your cluster and facilitating TLS. As such, a private Certificate Authority +> should generally be used for issuance. +> It is *not* recommended to use public Certificate Authorities such as Let's Encrypt, +> which maintain strict rate limits on the number of certificates that can be issued +> for a single domain. +> Like Pods, these certificate key pairs are designed to be thrown away and can be +> created and destroyed at any time during normal operation. + +## How Does it Work? + +The CSI specification is a protocol and standard for building storage drivers +for container orchestration platforms with the intention that a single driver +may be ported across multiple platforms and outlines a consistent specification +to how drivers should behave from an infrastructure perspective. Since +cert-manager is designed to only be run with a Kubernetes cluster, so too does +the cert-manager CSI driver. + +The driver should be deployed as a +[DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) +which means a single instance of the driver may be run on each node. The driver +will not work when running multiple instances on a single node. The set of nodes +that the driver runs on can be restricted using the +[`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) +in its Pod template. + +When a Pod is scheduled to a node with a cert-manager CSI volume specified, the +[`Kubelet`](https://kubernetes.io/docs/concepts/overview/components/#kubelet) +running on that node will send a `NodePublishVolume` call to the driver on that +node, containing that Pods information as well as the attributes detailed from +the in-line volume attributes. From this, the driver will generate a private key +as well as a certificate request based upon that key using information built +from the volume attributes. The driver will create a `CertificateRequest` +resource in the same namespace in the Pod that, if valid, cert-manager will +return a signed certificate. + +The resulting signed certificate and generated key will be written to that +node's file system to be mounted to the Pods file system. Since the driver needs +access to the nodes file system it must be made privileged. Once mounted, the +Pod will begin execution with the unique private key and certificate available in +its file system, as defined by its mount path. + +By default, the driver will keep track of certificates created in order to +monitor when they should be marked for renewal. When this happens, the driver +will request for a new signed certificate, and when successful, will simply +overwrite the existing certificate in path. + +When the Pod is marked for termination, the `NodeUnpublishVolume` call is made +to the node's driver which in turn destroys the certificate and key from the +nodes file system. + +The CSI driver is able to recover its full state in the event the its Pod being +terminated. diff --git a/content/v1.15-docs/usage/gateway.md b/content/v1.15-docs/usage/gateway.md new file mode 100644 index 0000000000..87e51c471e --- /dev/null +++ b/content/v1.15-docs/usage/gateway.md @@ -0,0 +1,445 @@ +--- +title: Annotated Gateway resource +description: 'cert-manager usage: Kubernetes Gateways' +--- + +> **apiVersion:** gateway.networking.k8s.io/v1 +> **kind:** Gateway + +
          + +
          + +**FEATURE STATE**: cert-manager 1.15 [beta] + +
          + +📌 This page focuses on automatically creating Certificate resources by +annotating Kubernetes Gateway resource. If you are looking for using an ACME Issuer along +with HTTP-01 challenges using the Kubernetes Gateway API, see [ACME +HTTP-01](../configuration/acme/http01/README.md). + +
          + +
          + +🚧 cert-manager 1.14+ is tested with v1 Kubernetes Gateway API. It should also work +with v1beta1 and v1alpha2 because of resource conversion, but has not been tested with it. + +
          + +cert-manager can generate TLS certificates for Gateway resources. This is +configured by adding annotations to a Gateway and is similar to the process for +[Securing Ingress Resources](../usage/ingress.md). + +The Gateway resource is part of the [Gateway API][gwapi], a set of CRDs that you +install on your Kubernetes cluster and which provide various improvements over +the Ingress API. + +[gwapi]: https://gateway-api.sigs.k8s.io + +The Gateway resource holds the TLS configuration, as illustrated in the +following diagram (source: https://gateway-api.sigs.k8s.io): + +![Gateway vs. HTTPRoute](/images/gateway-roles.png) + +
          + +📌 This feature requires the installation of the [Gateway API bundle](https://gateway-api.sigs.k8s.io/guides/#installing-a-gateway-controller) and passing an +additional flag to the cert-manager controller. + +To install v1.5.1 Gateway API bundle (Gateway CRDs and webhook), run the following command: + +```sh +kubectl apply -f "https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml" +``` + +Since cert-manager 1.15, the Gateway API support is no longer gated behind a +feature flag, but you still need to enable the Gateway API support. + +To enable the Gateway API support, use the [file-based +configuration](../installation/configuring-components.md#configuration-file) using the +following `config` Helm value: + +```yaml +config: + apiVersion: controller.config.cert-manager.io/v1alpha1 + kind: ControllerConfiguration + enableGatewayAPI: true +``` + +The corresponding Helm command is: + +```sh +helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager \ + --set config.apiVersion="controller.config.cert-manager.io/v1alpha1" \ + --set config.kind="ControllerConfiguration" \ + --set config.enableGatewayAPI=true +``` + +The Gateway API CRDs should either be installed before cert-manager starts or +the cert-manager Deployment should be restarted after installing the Gateway API +CRDs. This is important because some of the cert-manager components only perform +the Gateway API check on startup. You can restart cert-manager with the +following command: + +```sh +kubectl rollout restart deployment cert-manager -n cert-manager +``` + +
          + +The annotations `cert-manager.io/issuer` or `cert-manager.io/cluster-issuer` +tell cert-manager to create a Certificate for a Gateway. For example, the +following Gateway will trigger the creation of a Certificate with the name +`example-com-tls`: + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: example + annotations: + cert-manager.io/issuer: foo +spec: + gatewayClassName: foo + listeners: + - name: http + hostname: example.com + port: 443 + protocol: HTTPS + allowedRoutes: + namespaces: + from: All + tls: + mode: Terminate + certificateRefs: + - name: example-com-tls +``` + +A few moments later, cert-manager will create a Certificate. The Certificate is +named after the Secret name `example-com-tls`. The `dnsNames` field is set with +the `hostname` field from the Gateway spec. + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com-tls +spec: + issuerRef: + name: my-issuer + kind: Issuer + group: cert-manager.io + dnsNames: + - example.com # ✅ Copied from the `hostname` field. + secretName: example-com-tls +``` + +
          + +🚧 this mechanism can only be used to create Secrets in the same namespace as the `Gateway`, see [`cert-manager#5610`](https://github.com/cert-manager/cert-manager/issues/5610) + +
          + +## Use cases + +### Generate TLS certs for selected TLS blocks + +cert-manager skips any listener block that cannot be used for generating a +Certificate. For a listener block to be used for creating a Certificate, it must +meet the following requirements: + +| Field | Requirement | +|--------------------------------|-------------------------------------------------------------| +| `tls.hostname` | Must not be empty. | +| `tls.mode` | Must be set to `Terminate`. `Passthrough` is not supported. | +| `tls.certificateRef.name` | Cannot be left empty. | +| `tls.certificateRef.kind` | If specified, must be set to `Secret`. | +| `tls.certificateRef.group` | If specified, must be set to `core`. | +| `tls.certificateRef.namespace` | If specified, must be the same as the `Gateway`. | + +In the following example, the first four listener blocks will not be used to +generate Certificate resources: + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: my-gateway + namespace: default + annotations: + cert-manager.io/issuer: my-issuer +spec: + gatewayClassName: foo + listeners: + # ❌ Missing "tls" block, the following listener is skipped. + - name: example-1 + port: 80 + protocol: HTTP + hostname: example.com + + # ❌ Missing "hostname", the following listener is skipped. + - name: example-2 + port: 443 + protocol: HTTPS + tls: + certificateRefs: + - name: example-com-tls + kind: Secret + group: "" + + # ❌ "mode: Passthrough" is not supported, the following listener is skipped. + - name: example-3 + hostname: example.com + port: 8443 + protocol: HTTPS + tls: + mode: Passthrough + certificateRefs: + - name: example-com-tls + kind: Secret + group: "" + + # ❌ Cross-namespace secret references are not supported, the following listener is skipped. + - name: example-4 + hostname: foo.example.com + port: 8443 + protocol: HTTPS + allowedRoutes: + namespaces: + from: All + tls: + mode: Terminate + certificateRefs: + - name: example-com-tls + kind: Secret + group: "" + namespace: other-namespace + + # ✅ The following listener is valid. + - name: example-5 + hostname: bar.example.com # ✅ Required. + port: 8443 + protocol: HTTPS + allowedRoutes: + namespaces: + from: All + tls: + mode: Terminate # ✅ Required. "Terminate" is the only supported mode. + certificateRefs: + - name: example-com-tls # ✅ Required. + kind: Secret # ✅ Optional. "Secret" is the only valid value. + group: "" # ✅ Optional. "" is the only valid value. +``` + +cert-manager has skipped over the first four listener blocks and has created a +single Certificate named `example-com-tls` for the last listener block: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com-tls +spec: + issuerRef: + name: my-issuer + kind: Issuer + group: cert-manager.io + dnsNames: + - foo.example.com + secretName: example-com-tls +``` + +### Two listeners with the same Secret name + +The same Secret name can be re-used in multiple TLS blocks, regardless of the +hostname. Let us imagine that you have these two listeners: + +```yaml +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: example + annotations: + cert-manager.io/issuer: my-issuer +spec: + gatewayClassName: foo + listeners: + # Listener 1. + - name: example-1 + hostname: example.com + port: 443 + protocol: HTTPS + tls: + mode: Terminate + certificateRefs: + - name: example-com-tls + + # Listener 2: Same Secret name as Listener 1, with a different hostname. + - name: example-2 + hostname: "*.example.com" + port: 443 + protocol: HTTPS + tls: + mode: Terminate + certificateRefs: + - name: example-com-tls + + # Listener 3: also same Secret name, except the hostname is also the same. + - name: example-3 + hostname: "*.example.com" + port: 8443 + protocol: HTTPS + tls: + mode: Terminate + certificateRefs: + - name: example-com-tls + + # Listener 4: different Secret name. + - name: example-4 + hostname: site.org + port: 443 + protocol: HTTPS + tls: + mode: Terminate + certificateRefs: + - name: site-org-tls +``` + +cert-manager will create two Certificates since two Secret names are used: +`example-com-tls` and `site-org-tls`. Note the Certificate's `dnsNames` contains +a single occurrence of `*.example.com ` for both listener 2 and 3 (the +`hostname` values are de-duplicated). + +The two Certificates look like this: + +```yaml +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: example-com-tls +spec: + issuerRef: + name: my-issuer + kind: Issuer + group: cert-manager.io + dnsNames: + - example.com # From listener 1. + - *.example.com # From listener 2 and 3. + secretName: example-com-tls +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: site-org-tls +spec: + issuerRef: + name: my-issuer + kind: Issuer + group: cert-manager.io + dnsNames: + - site.org # From listener 4. + secretName: site-org-tls +``` + +## Supported Annotations + +If you are migrating to Gateway resources from Ingress resources, be aware that +there are some differences between [the annotations for Ingress resources](./ingress.md#supported-annotations) +versus the annotations for Gateway resources. + +The Gateway resource supports the following annotations for generating +Certificate resources: + +- `cert-manager.io/issuer`: the name of an Issuer to acquire the certificate + required for this Gateway. The Issuer _must_ be in the same namespace as the + Gateway resource. + +- `cert-manager.io/cluster-issuer`: the name of a ClusterIssuer to acquire the + Certificate required for this Gateway. It does not matter which namespace your + Gateway resides, as `ClusterIssuers` are non-namespaced resources. + +- `cert-manager.io/issuer-kind`: the kind of the external issuer resource, for + example `AWSPCACIssuer`. This is only necessary for out-of-tree issuers. + +- `cert-manager.io/issuer-group`: the API group of the external issuer + controller, for example `awspca.cert-manager.io`. This is only necessary for + out-of-tree issuers. + +- `cert-manager.io/common-name`: (optional) this annotation allows you to + configure `spec.commonName` for the Certificate to be generated. + +- `cert-manager.io/email-sans`: (optional) this annotation allows you to + configure `spec.emailAddresses` field for the Certificate to be generated. + Supports comma-separated values e.g. "me@example.com,you@example.com" + +- `cert-manager.io/subject-organizations`: (optional) this annotation allows you to + configure `spec.subject.organizations` field for the Certificate to be generated. + Supports comma-separated values e.g. "Company 1,Company 2" + +- `cert-manager.io/subject-organizationalunits`: (optional) this annotation allows you to + configure `spec.subject.organizationalUnits` field for the Certificate to be generated. + Supports comma-separated values e.g. "IT Services,Cloud Services" + +- `cert-manager.io/subject-countries`: (optional) this annotation allows you to + configure `spec.subject.countries` field for the Certificate to be generated. + Supports comma-separated values e.g. "Country 1,Country 2" + +- `cert-manager.io/subject-provinces`: (optional) this annotation allows you to + configure `spec.subject.provinces` field for the Certificate to be generated. + Supports comma-separated values e.g. "Province 1,Province 2" + +- `cert-manager.io/subject-localities`: (optional) this annotation allows you to + configure `spec.subject.localities` field for the Certificate to be generated. + Supports comma-separated values e.g. "City 1,City 2" + +- `cert-manager.io/subject-postalcodes`: (optional) this annotation allows you to + configure `spec.subject.postalCodes` field for the Certificate to be generated. + Supports comma-separated values e.g. "123ABC,456DEF" + +- `cert-manager.io/subject-streetaddresses`: (optional) this annotation allows you to + configure `spec.subject.streetAddresses` field for the Certificate to be generated. + Supports comma-separated values e.g. "123 Example St,456 Other Blvd" + +- `cert-manager.io/subject-serialnumber`: (optional) this annotation allows you to + configure `spec.subject.serialNumber` field for the Certificate to be generated. + Supports comma-separated values e.g. "10978342379280287615,1111144445555522228888" + +- ` cert-manager.io/duration`: (optional) this annotation allows you to + configure `spec.duration` field for the Certificate to be generated. + +- `cert-manager.io/renew-before`: (optional) this annotation allows you to + configure `spec.renewBefore` field for the Certificate to be generated. + +- `cert-manager.io/usages`: (optional) this annotation allows you to configure + `spec.usages` field for the Certificate to be generated. Pass a string with + comma-separated values i.e "key agreement,digital signature, server auth" + +- `cert-manager.io/revision-history-limit`: (optional) this annotation allows you to + configure `spec.revisionHistoryLimit` field to limit the number of CertificateRequests to be kept for a Certificate. + Minimum value is 1. If unset all CertificateRequests will be kept. + +- `cert-manager.io/private-key-algorithm`: (optional) this annotation allows you to + configure `spec.privateKey.algorithm` field to set the algorithm for private key generation for a Certificate. + Valid values are `RSA`, `ECDSA` and `Ed25519`. If unset an algorithm `RSA` will be used. + +- `cert-manager.io/private-key-encoding`: (optional) this annotation allows you to + configure `spec.privateKey.encoding` field to set the encoding for private key generation for a Certificate. + Valid values are `PKCS1` and `PKCS8`. If unset an algorithm `PKCS1` will be used. + +- `cert-manager.io/private-key-size`: (optional) this annotation allows you to + configure `spec.privateKey.size` field to set the size of the private key for a Certificate. + If algorithm is set to `RSA`, valid values are `2048`, `4096` or `8192`, and will default to `2048` if not specified. + If algorithm is set to `ECDSA`, valid values are `256`, `384` or `521`, and will default to `256` if not specified. + If algorithm is set to `Ed25519`, size is ignored. + +- `cert-manager.io/private-key-rotation-policy`: (optional) this annotation allows you to + configure `spec.privateKey.rotationPolicy` field to set the rotation policy of the private key for a Certificate. + Valid values are `Never` and `Always`. If unset a rotation policy `Never` will be used. + +## Inner workings diagram for developers + + + +[1] https://cert-manager.io/docs/usage/certificate diff --git a/content/v1.15-docs/usage/ingress.md b/content/v1.15-docs/usage/ingress.md new file mode 100644 index 0000000000..cc1b9fc04a --- /dev/null +++ b/content/v1.15-docs/usage/ingress.md @@ -0,0 +1,228 @@ +--- +title: Annotated Ingress resource +description: 'cert-manager usage: Kubernetes Ingress' +--- + +> **apiVersion:** networking.k8s.io/v1 +> **kind:** Ingress + +
          + +
          + +A common use-case for cert-manager is requesting TLS signed certificates to +secure your ingress resources. This can be done by simply adding annotations to +your `Ingress` resources and cert-manager will facilitate creating the +`Certificate` resource for you. A small sub-component of cert-manager, +ingress-shim, is responsible for this. + +## How It Works + +The sub-component ingress-shim watches `Ingress` resources across your cluster. +If it observes an `Ingress` with annotations described in the [Supported +Annotations](#supported-annotations) section, it will ensure a `Certificate` +resource with the name provided in the `tls.secretName` field and configured as +described on the `Ingress` exists in the `Ingress`'s namespace. For example: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + # add an annotation indicating the issuer to use. + cert-manager.io/cluster-issuer: nameOfClusterIssuer + name: myIngress + namespace: myIngress +spec: + rules: + - host: example.com + http: + paths: + - pathType: Prefix + path: / + backend: + service: + name: myservice + port: + number: 80 + tls: # < placing a host in the TLS config will determine what ends up in the cert's subjectAltNames + - hosts: + - example.com + secretName: myingress-cert # < cert-manager will store the created certificate in this secret. +``` + +## Supported Annotations + +You can specify the following annotations on Ingress resources in order to +trigger Certificate resources to be automatically created: + +- `cert-manager.io/issuer`: the name of the issuer that should issue the certificate + required for this Ingress. + + > ⚠️ This annotation does _not_ assume a namespace scoped issuer. It will + default to cert-manager.io Issuer, however in case of external issuer types, + this should be used for both namespaced and cluster scoped issuer types. + + > ⚠️ If a namespace scoped issuer is used then the issuer *must* be in + the same namespace as the Ingress resource. + +- `cert-manager.io/cluster-issuer`: the name of a cert-manager.io ClusterIssuer + to acquire the certificate required for this Ingress. It does not matter which + namespace your Ingress resides, as ClusterIssuers are non-namespaced + resources. + + > ⚠️ This annotation is a shortcut to refer to to + cert-manager.io ClusterIssuer without having to specify group and kind. It is + _not_ intended to be used to specify an external cluster-scoped issuer- please + use `cert-manager.io/issuer` annotation for those. + +- `cert-manager.io/issuer-kind`: the kind of the external issuer resource, for + example `AWSPCAIssuer`. This is only necessary for out-of-tree issuers. + +- `cert-manager.io/issuer-group`: the API group of the external issuer + controller, for example `awspca.cert-manager.io`. This is only necessary for + out-of-tree issuers. + +- `kubernetes.io/tls-acme: "true"`: this annotation requires additional + configuration of the ingress-shim [see below](#optional-configuration). + Namely, a default Issuer must be specified as arguments to the ingress-shim + container. + +- `acme.cert-manager.io/http01-ingress-class`: this annotation allows you to + configure the ingress class that will be used to solve challenges for this + ingress. Customizing this is useful when you are trying to secure internal + services, and need to solve challenges using a different ingress class to that + of the ingress. If not specified and the `acme-http01-edit-in-place` annotation + is not set, this defaults to the ingress class defined in the Issuer resource. + +- `acme.cert-manager.io/http01-edit-in-place: "true"`: this controls whether the + ingress is modified 'in-place', or a new one is created specifically for the + HTTP01 challenge. If present, and set to "true", the existing ingress will be + modified. Any other value, or the absence of the annotation assumes "false". + This annotation will also add the annotation + `"cert-manager.io/issue-temporary-certificate": "true"` onto created + certificates which will cause a [temporary + certificate](../usage/certificate.md#temporary-certificates-whilst-issuing) to be set + on the resulting Secret until the final signed certificate has been returned. + This is useful for keeping compatibility with the `ingress-gce` component. + +- `cert-manager.io/common-name`: (optional) this annotation allows you to + configure `spec.commonName` for the Certificate to be generated. + +- `cert-manager.io/email-sans`: (optional) this annotation allows you to + configure `spec.emailAddresses` field for the Certificate to be generated. + Supports comma-separated values e.g. "me@example.com,you@example.com" + +- `cert-manager.io/subject-organizations`: (optional) this annotation allows you to + configure `spec.subject.organizations` field for the Certificate to be generated. + Supports comma-separated values e.g. "Company 1,Company 2" + +- `cert-manager.io/subject-organizationalunits`: (optional) this annotation allows you to + configure `spec.subject.organizationalUnits` field for the Certificate to be generated. + Supports comma-separated values e.g. "IT Services,Cloud Services" + +- `cert-manager.io/subject-countries`: (optional) this annotation allows you to + configure `spec.subject.countries` field for the Certificate to be generated. + Supports comma-separated values e.g. "Country 1,Country 2" + +- `cert-manager.io/subject-provinces`: (optional) this annotation allows you to + configure `spec.subject.provinces` field for the Certificate to be generated. + Supports comma-separated values e.g. "Province 1,Province 2" + +- `cert-manager.io/subject-localities`: (optional) this annotation allows you to + configure `spec.subject.localities` field for the Certificate to be generated. + Supports comma-separated values e.g. "City 1,City 2" + +- `cert-manager.io/subject-postalcodes`: (optional) this annotation allows you to + configure `spec.subject.postalCodes` field for the Certificate to be generated. + Supports comma-separated values e.g. "123ABC,456DEF" + +- `cert-manager.io/subject-streetaddresses`: (optional) this annotation allows you to + configure `spec.subject.streetAddresses` field for the Certificate to be generated. + Supports comma-separated values e.g. "123 Example St,456 Other Blvd" + +- `cert-manager.io/subject-serialnumber`: (optional) this annotation allows you to + configure `spec.subject.serialNumber` field for the Certificate to be generated. + Supports comma-separated values e.g. "10978342379280287615,1111144445555522228888" + +- ` cert-manager.io/duration`: (optional) this annotation allows you to + configure `spec.duration` field for the Certificate to be generated. + +- `cert-manager.io/renew-before`: (optional) this annotation allows you to + configure `spec.renewBefore` field for the Certificate to be generated. + +- `cert-manager.io/usages`: (optional) this annotation allows you to configure + `spec.usages` field for the Certificate to be generated. Pass a string with + comma-separated values i.e "key agreement,digital signature, server auth" + +- `cert-manager.io/revision-history-limit`: (optional) this annotation allows you to + configure `spec.revisionHistoryLimit` field to limit the number of CertificateRequests to be kept for a Certificate. + Minimum value is 1. If unset all CertificateRequests will be kept. + +- `cert-manager.io/private-key-algorithm`: (optional) this annotation allows you to + configure `spec.privateKey.algorithm` field to set the algorithm for private key generation for a Certificate. + Valid values are `RSA`, `ECDSA` and `Ed25519`. If unset an algorithm `RSA` will be used. + +- `cert-manager.io/private-key-encoding`: (optional) this annotation allows you to + configure `spec.privateKey.encoding` field to set the encoding for private key generation for a Certificate. + Valid values are `PKCS1` and `PKCS8`. If unset an algorithm `PKCS1` will be used. + +- `cert-manager.io/private-key-size`: (optional) this annotation allows you to + configure `spec.privateKey.size` field to set the size of the private key for a Certificate. + If algorithm is set to `RSA`, valid values are `2048`, `4096` or `8192`, and will default to `2048` if not specified. + If algorithm is set to `ECDSA`, valid values are `256`, `384` or `521`, and will default to `256` if not specified. + If algorithm is set to `Ed25519`, size is ignored. + +- `cert-manager.io/private-key-rotation-policy`: (optional) this annotation allows you to + configure `spec.privateKey.rotationPolicy` field to set the rotation policy of the private key for a Certificate. + Valid values are `Never` and `Always`. If unset a rotation policy `Never` will be used. + +## Generate multiple certificates with multiple ingresses + +If you need to generate certificates from multiple ingresses make sure it has the issuer annotation. +Besides the annotation, it is necessary that each ingress possess a unique `tls.secretName` + +## Optional Configuration + +The ingress-shim sub-component is deployed automatically as part of +installation. + +If you would like to use the old +[kube-lego](https://github.com/jetstack/kube-lego) `kubernetes.io/tls-acme: +"true"` annotation for fully automated TLS, you will need to configure a default +`Issuer` when deploying cert-manager. This can be done by adding the following +`--set` when deploying using Helm: + +```bash + --set ingressShim.defaultIssuerName=letsencrypt-prod \ + --set ingressShim.defaultIssuerKind=ClusterIssuer \ + --set ingressShim.defaultIssuerGroup=cert-manager.io +``` + +Or by adding the following arguments to the cert-manager deployment +`podTemplate` container arguments. + +``` + - --default-issuer-name=letsencrypt-prod + - --default-issuer-kind=ClusterIssuer + - --default-issuer-group=cert-manager.io +``` + +In the above example, cert-manager will create `Certificate` resources that +reference the `ClusterIssuer` `letsencrypt-prod` for all Ingresses that have a +`kubernetes.io/tls-acme: "true"` annotation. + +Issuers configured via annotations have a preference over the default issuer. If a default issuer is configured via CLI flags and a `cert-manager.io/cluster-issuer` or `cert-manager.io/issuer` annotation also has been added to an Ingress, the created `Certificate` will refer to the issuer configured via annotation. + +For more information on deploying cert-manager, read the [installation +guide](../installation/README.md). + +## Troubleshooting + +If you do not see a `Certificate` resource being created after applying the ingress-shim annotations check that at least `cert-manager.io/issuer` or `cert-manager.io/cluster-issuer` is set. If you want to use `kubernetes.io/tls-acme: "true"` make sure to have checked all steps above and you might want to look for errors in the cert-manager pod logs if not resolved. + +## Inner workings diagram for developers + + + +[1] https://cert-manager.io/docs/usage/certificate diff --git a/content/v1.15-docs/usage/istio-csr/README.md b/content/v1.15-docs/usage/istio-csr/README.md new file mode 100644 index 0000000000..3e614f5b4b --- /dev/null +++ b/content/v1.15-docs/usage/istio-csr/README.md @@ -0,0 +1,98 @@ +--- +title: Securing Istio Service Mesh +description: 'cert-manager usage: Istio and istio-csr' +--- + +
          + +
          + +cert-manager can be integrated with [Istio](https://istio.io) using the project +[istio-csr](https://github.com/cert-manager/istio-csr). istio-csr will deploy an +agent that is responsible for receiving certificate signing requests for all +members of the Istio mesh, and signing them through cert-manager. + +istio-csr is an agent that allows for [Istio](https://istio.io) workload and +control plane components to be secured using +[cert-manager](https://cert-manager.io). + +Certificates facilitating mTLS — both inter +and intra-cluster — will be signed, delivered and renewed using [cert-manager +issuers](https://cert-manager.io/docs/concepts/issuer). + +## Installation + +See the [installation guide](./installation.md) for setting up istio-csr in a fresh +[kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) cluster. + +Following the guide is the best way to see istio-csr in action. + +## Lower-Level Details (For Experienced Istio Users) + +⚠️ The [installation guide](./installation.md) guide is a better place if you just want to try istio-csr out! + +Running istio-csr requires a few steps and preconditions in order: + +1. A cluster _without_ Istio already installed +2. cert-manager [installed](https://cert-manager.io/docs/installation/) in the cluster +3. An `Issuer` or `ClusterIssuer` which will be used to issue Istio certificates +4. istio-csr installed (likely via helm) +5. Istio [installed](https://istio.io/latest/docs/setup/install/istioctl/) with + some custom config required, e.g. using the example config from the [repository](https://github.com/cert-manager/istio-csr/tree/5d2e629f9f9aec7f476337d6ae69482cea9a7a71/make/config/istio). + +### Why Custom Istio Install Manifests? + +If you take a look at the contents of [the example Istio install +manifests](https://github.com/cert-manager/istio-csr/tree/5d2e629f9f9aec7f476337d6ae69482cea9a7a71/make/config/istio) +there are a few custom configuration options which are important. + +Required changes include setting `ENABLE_CA_SERVER` to `false` and setting the `caAddress` from which Istio will +request certificates; replacing the CA server is the whole point of istio-csr! + +Mounting and statically specifying the root CA is also an important recommended step. Without a manually specified +root CA istio-csr defaults to trying to discover root CAs automatically, which could theoretically lead to a +[signer hijacking attack](https://github.com/cert-manager/istio-csr/issues/103#issuecomment-923882792) if for example +a signer's token was stolen (such as the cert-manager controller's token). + +### Issuer or ClusterIssuer? + +Unless you know you need a `ClusterIssuer` we'd recommend starting with an `Issuer`, since it should be easier to reason about +the access controls for an Issuer; they're namespaced and so naturally a little more limited in scope. + +That said, if you view your entire Kubernetes cluster as being a trust domain itself, then a ClusterIssuer is the more natural +fit. The best choice will depend on your specific situation. + +Our [installation guide](./installation.md) uses an `Issuer`. + +### Which Issuer Type? + +Whether you choose to use an `Issuer` or a `ClusterIssuer`, you'll also need to choose the type of issuer you want such as: + +- [CA](https://cert-manager.io/docs/configuration/ca/) +- [Vault](https://cert-manager.io/docs/configuration/vault/) +- or an [external issuer](https://cert-manager.io/docs/configuration/external/) + +The key requirement is that arbitrary values can be placed into the `subjectAltName` (SAN) X.509 extension, since +Istio places SPIFFE IDs there. + +That means that the ACME issuer **will not work** — publicly trusted certificates such as those issued by Let's Encrypt +don't allow arbitrary entries in the SAN, for very good reasons. + +If you're already using [HashiCorp Vault](https://www.vaultproject.io/) then the Vault issuer is an obvious choice. If +you want to control your own PKI entirely, we'd recommend the CA issuer. The choice is ultimately yours. + +### Installing istio-csr After Istio + +This is unsupported because it's exceptionally difficult to do safely. It's likely that installing istio-csr _after_ Istio isn't +possible to do without downtime, since installing istio-csr second would require a time period where all Istio sidecars trust +both the old Istio-managed CA and the new cert-manager controlled CA. + +## How Does istio-csr Work? + +istio-csr implements the gRPC Istio certificate service which authenticates, +authorizes, and signs incoming certificate signing requests from Istio +workloads, routing all certificate handling through cert-manager installed in +the cluster. + +This seamlessly matches the behavior of istiod in a typical installation, while +allowing certificate management through cert-manager. diff --git a/content/v1.15-docs/usage/istio-csr/example/example-cluster-issuer.yaml b/content/v1.15-docs/usage/istio-csr/example/example-cluster-issuer.yaml new file mode 100644 index 0000000000..cb387c29d7 --- /dev/null +++ b/content/v1.15-docs/usage/istio-csr/example/example-cluster-issuer.yaml @@ -0,0 +1,46 @@ +# NB: We generally recommend using Issuers rather than ClusterIssuers with istio-csr. +# Issuers are easier to scope, and therefore easier to reason about in terms of security. + +# SelfSigned issuers are useful for creating root certificates +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned +spec: + selfSigned: {} +--- +# Request a self-signed certificate from our ClusterIssuer; this will function as our +# issuing root certificate when we pass it into a CA ClusterIssuer. + +# It's generally fine to issue root certificates like this one with long lifespans; +# the certificates which istio-csr issues will be much shorter lived. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: istio-ca + namespace: cert-manager +spec: + isCA: true + duration: 87600h # 10 years + secretName: istio-ca + commonName: istio-ca + privateKey: + algorithm: ECDSA + size: 256 + subject: + organizations: + - cluster.local + - cert-manager + issuerRef: + name: selfsigned + kind: ClusterIssuer + group: cert-manager.io +--- +# Create a CA issuer using our root. This will be the ClusterIssuer which istio-csr will use. +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: istio-ca +spec: + ca: + secretName: istio-ca diff --git a/content/v1.15-docs/usage/istio-csr/example/example-issuer.yaml b/content/v1.15-docs/usage/istio-csr/example/example-issuer.yaml new file mode 100644 index 0000000000..4dd383dbcb --- /dev/null +++ b/content/v1.15-docs/usage/istio-csr/example/example-issuer.yaml @@ -0,0 +1,45 @@ +# SelfSigned issuers are useful for creating root certificates +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned + namespace: istio-system +spec: + selfSigned: {} +--- +# Request a self-signed certificate from our Issuer; this will function as our +# issuing root certificate when we pass it into a CA Issuer. + +# It's generally fine to issue root certificates like this one with long lifespans; +# the certificates which istio-csr issues will be much shorter lived. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: istio-ca + namespace: istio-system +spec: + isCA: true + duration: 87600h # 10 years + secretName: istio-ca + commonName: istio-ca + privateKey: + algorithm: ECDSA + size: 256 + subject: + organizations: + - cluster.local + - cert-manager + issuerRef: + name: selfsigned + kind: Issuer + group: cert-manager.io +--- +# Create a CA issuer using our root. This will be the Issuer which istio-csr will use. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: istio-ca + namespace: istio-system +spec: + ca: + secretName: istio-ca diff --git a/content/v1.15-docs/usage/istio-csr/example/istio-config-getting-started.yaml b/content/v1.15-docs/usage/istio-csr/example/istio-config-getting-started.yaml new file mode 100644 index 0000000000..83b6eeee7b --- /dev/null +++ b/content/v1.15-docs/usage/istio-csr/example/istio-config-getting-started.yaml @@ -0,0 +1,21 @@ +apiVersion: install.istio.io/v1alpha1 +kind: IstioOperator +metadata: + namespace: istio-system +spec: + profile: "demo" + hub: gcr.io/istio-release + meshConfig: + # Change the following line to configure the trust domain of the Istio cluster. + trustDomain: cluster.local + values: + global: + # Change certificate provider to cert-manager istio agent for istio agent + caAddress: cert-manager-istio-csr.cert-manager.svc:443 + components: + pilot: + k8s: + env: + # Disable istiod CA Sever functionality + - name: ENABLE_CA_SERVER + value: "false" diff --git a/content/v1.15-docs/usage/istio-csr/installation.md b/content/v1.15-docs/usage/istio-csr/installation.md new file mode 100644 index 0000000000..be04ea83c9 --- /dev/null +++ b/content/v1.15-docs/usage/istio-csr/installation.md @@ -0,0 +1,407 @@ +--- +title: Installing istio-csr +description: "Installation guide for cert-manager's Istio integration: istio-csr" +--- + +## Installation steps + +This guide will run through installing and using istio-csr from scratch. We'll use [kind](https://kind.sigs.k8s.io/) to create a new cluster locally in Docker, but this guide should work on any cluster as long as the relevant Istio [Platform Setup](https://istio.io/latest/docs/setup/platform-setup/) has been performed. + +Note that if you're following the Platform Setup guide for OpenShift, do not run the `istioctl install` command listed in that guide; we'll run our own command later. + +### 0. Background + +#### Issuer Configuration + +istio-csr uses cert-manager to issue Istio certificates, and needs to be able to reference an issuer resource to do this. + +You can choose to configure an issuer when installing with the Helm chart and / or to configure a ConfigMap to watch which can then be used to configure an issuer at runtime. + +Configuring a ConfigMap for the issuer details is called "runtime configuration", and it's required if no issuer is specified in the Helm chart. + +If you configure an issuer in the chart, you'll be able to start issuing as soon as the istio-csr pods come online but you'll need to have already installed cert-manager and created the issuer. + +If you don't set an issuer in the chart, istio-csr will not become ready until an issuer is specified via runtime configuration, but you'll be able to install cert-manager and istio-csr concurrently. + +Note that the chart contains a default issuer name and so using runtime configuration requires an explicit opt-in. The guide below assumes you'll install istio-csr after an issuer is configured without runtime configuration; there are notes for runtime configuration at the bottom. + +#### Istio Ambient + +As of `v0.12.0` istio-csr supports Istio Ambient mode, which allows for pods to be included in the Istio mesh without a side-car container. + +To enable Istio Ambient mode support, pass the `app.server.caTrustedNodeAccounts` Helm value, which is a comma-separated list of `namespace/service-accounts` values indicating which service accounts are permitted to use node authentication. + +An example would be `--set app.server.caTrustedNodeAccounts=istio-system/ztunnel` + +### 1. Initial Setup + +You'll need the following tools installed on your machine: + +- [istioctl](https://github.com/istio/istio/releases/latest) +- [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation) and [docker](https://docs.docker.com/get-docker/) (if you're using kind) +- [helm](https://helm.sh/docs/intro/install/) +- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) +- [jq](https://stedolan.github.io/jq/download/) + +In addition, Istio must not already be installed in your cluster. Installing istio-csr _after_ Istio is not supported. + +### 2. Creating the Cluster and Installing cert-manager + +Kind will automatically set up kubectl to point to the newly created cluster. + +We install cert-manager [using helm](https://cert-manager.io/docs/installation/helm/) here, but if you've got a preferred method you can install in any way. + +```console +kind create cluster + +# Helm setup +helm repo add jetstack https://charts.jetstack.io --force-update + +# install cert-manager; this might take a little time +helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --version [[VAR::cert_manager_latest_version]] \ + --set crds.enabled=true + +# We need this namespace to exist since our cert will be placed there +kubectl create namespace istio-system +``` + +### 3. Create a cert-manager Issuer and Issuing Certificate + +An Issuer tells cert-manager how to issue certificates; we'll create a self-signed root CA in our cluster because it's really simple to configure. + +The approach of using a locally generated root certificate would work in a production deployment too, but there are also several [other issuers](https://cert-manager.io/docs/configuration/) in cert-manager which could be used. Note that the ACME issuer **will not work**, since it can't add the required fields to issued certificates. + +There are also some comments on the [example-issuer](https://github.com/cert-manager/website/blob/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/example-issuer.yaml) providing a little more detail. Note also that this guide only uses `Issuer`s and not `ClusterIssuer`s - using a `ClusterIssuer` isn't a drop-in replacement, and in any case we recommend that production deployments use Issuers for easier access controls and scoping. + +```console +kubectl apply -f https://raw.githubusercontent.com/cert-manager/website/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/example-issuer.yaml +``` + +### 4. Export the Root CA to a Local File + +While it's possible to configure Istio such that it can automatically "discover" the root CA, this can be dangerous in +some specific scenarios involving other security holes, enabling [signer hijacking attacks](https://github.com/cert-manager/istio-csr/issues/103#issuecomment-923882792). + +As such, we'll export our Root CA and configure Istio later using that static cert. + +```console +# Export our cert from the secret it's stored in, and base64 decode to get the PEM data. +kubectl get -n istio-system secret istio-ca -ogo-template='{{index .data "tls.crt"}}' | base64 -d > ca.pem + +# Out of interest, we can check out what our CA looks like +openssl x509 -in ca.pem -noout -text + +# Add our CA to a secret +kubectl create secret generic -n cert-manager istio-root-ca --from-file=ca.pem=ca.pem +``` + +### 5. Installing istio-csr + +istio-csr is best installed via Helm, and it should be simple and quick to install. There +are a bunch of other configuration options for the helm chart, which you can check out [here](../../usage/istio-csr/README.md). + +```console +helm repo add jetstack https://charts.jetstack.io --force-update + +# We set a few helm template values so we can point at our static root CA +helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \ + --install \ + --namespace cert-manager \ + --wait \ + --set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \ + --set "volumeMounts[0].name=root-ca" \ + --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \ + --set "volumes[0].name=root-ca" \ + --set "volumes[0].secret.secretName=istio-root-ca" + +# Check to see that the istio-csr pod is running and ready +kubectl get pods -n cert-manager +NAME READY STATUS RESTARTS AGE +cert-manager-aaaaaaaaaa-11111 1/1 Running 0 9m46s +cert-manager-cainjector-aaaaaaaaaa-22222 1/1 Running 0 9m46s +cert-manager-istio-csr-bbbbbbbbbb-00000 1/1 Running 0 63s +cert-manager-webhook-aaaaaaaaa-33333 1/1 Running 0 9m46s +``` + +### 6. Installing Istio + +If you're not running on kind, you may need to do some additional [setup tasks](https://istio.io/latest/docs/setup/platform-setup/) before installing Istio. + +We use the `istioctl` CLI to install Istio, configured using a custom IstioOperator manifest. + +The custom manifest does the following: + +- Disables the CA server in istiod, +- Ensures that Istio workloads request certificates from istio-csr, +- Ensures that the istiod certificates and keys are mounted from the Certificate created when installing istio-csr. + +First we download our demo manifest and then we apply it. + +```console +curl -sSL https://raw.githubusercontent.com/cert-manager/website/7f5b2be9dd67831574b9bde2407bed4a920b691c/content/docs/tutorials/istio-csr/example/istio-config-getting-started.yaml > istio-install-config.yaml +``` + +You may wish to inspect and tweak `istio-install-config.yaml` if you know what you're doing, +but this manifest should work for example purposes as-is. + +If you set a custom `app.tls.trustDomain` when installing istio-csr via helm earlier, you'll need to ensure that +value is repeated in `istio-install-config.yaml`. + +This final command will install Istio; the exact command you need might vary on different platforms, +and will certainly vary on OpenShift. + +```console +# This takes a little time to complete +istioctl install -f istio-install-config.yaml + +# If you're on OpenShift, you need a different profile: +# istioctl install --set profile=openshift -f istio-install-config.yaml +``` + +You will be prompted for input to confirm your choice of Istio profile: + +```console +This will install the Istio 1.14.1 demo profile with ["Istio core" "Istiod" "Ingress gateways" "Egress gateways"] components into the cluster. Proceed? (y/N) +``` + +Confirm your selection by entering `y` into the console to proceed with installation. + +## Validating Install + +The following steps are option but can be followed to validate everything is hooked correctly: + +1. Deploy a sample application & watch for `certificaterequests.cert-manager.io` resources +2. Verify `cert-manager` logs for new `certificaterequests` and responses +3. Verify the CA Endpoint being used in a `istio-proxy` sidecar container +4. Using `istioctl` to fetch the certificate info for the `istio-proxy` container + +To see this all in action, lets deploy a very simple sample application from the +[Istio samples](https://github.com/istio/istio/tree/master/samples/httpbin). + +First set some environment variables whose values could be changed if needed: + +```shell +# Set namespace for sample application +export NAMESPACE=default +# Set env var for the value of the app label in manifests +export APP=httpbin +# Grab the installed version of istio +export ISTIO_VERSION=$(istioctl version -o json | jq -r '.meshVersion[0].Info.version') +``` + +We use the `default` namespace for simplicity, so let's label the namespace for Istio injection: + +```shell +kubectl label namespace $NAMESPACE istio-injection=enabled --overwrite +``` + +In a separate terminal you should now follow the logs for `cert-manager`: + +```shell +kubectl logs -n cert-manager $(kubectl get pods -n cert-manager -o jsonpath='{.items..metadata.name}' --selector app=cert-manager) --since 2m -f +``` + +In another separate terminal, lets watch the `istio-system` namespace for `certificaterequests`: + +```shell +kubectl get certificaterequests.cert-manager.io -n istio-system -w +``` + +Now deploy the sample application `httpbin` in the labeled namespace. Note the use of a +variable to match the manifest version to your installed Istio version: + +```shell +kubectl apply -n $NAMESPACE -f https://raw.githubusercontent.com/istio/istio/$ISTIO_VERSION/samples/httpbin/httpbin.yaml +``` + +You should see something similar to the output here for `certificaterequests`: + +``` +NAME APPROVED DENIED READY ISSUER REQUESTOR AGE +istio-ca-74bnl True True selfsigned system:serviceaccount:cert-manager:cert-manager 2d2h +istiod-w9zh6 True True istio-ca system:serviceaccount:cert-manager:cert-manager 27m +istio-csr-8ddcs istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s +istio-csr-8ddcs True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s +istio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s +istio-csr-8ddcs True True istio-ca system:serviceaccount:cert-manager:cert-manager-istio-csr 0s +``` + +The key request being `istio-csr-8ddcs` in our example output. You should then check your +`cert-manager` log output for two log lines with this request being "Approved" and "Ready": + +``` +I0113 16:51:59.186482 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "istio-csr-8ddcs" condition "Approved" to 2022-01-13 16:51:59.186455713 +0000 UTC m=+3507.098466775 +I0113 16:51:59.258876 1 conditions.go:261] Setting lastTransitionTime for CertificateRequest "istio-csr-8ddcs" condition "Ready" to 2022-01-13 16:51:59.258837897 +0000 UTC m=+3507.170859959 +``` + +You should now see the application is running with both the application container and the sidecar: + +```shell +~ kubectl get pods -n $NAMESPACE +NAME READY STATUS RESTARTS AGE +httpbin-74fb669cc6-559cg 2/2 Running 0 4m +``` + +To validate that the `istio-proxy` sidecar container has requested the certificate from the correct +service, check the container logs: + +```shell +kubectl logs $(kubectl get pod -n $NAMESPACE -o jsonpath="{.items...metadata.name}" --selector app=$APP) -c istio-proxy +``` + +You should see some early logs similar to this example: + +Istio v1.12 and earlier versions: + +``` +2022-01-13T16:51:58.495493Z info CA Endpoint cert-manager-istio-csr.cert-manager.svc:443, provider Citadel +2022-01-13T16:51:58.495817Z info Using CA cert-manager-istio-csr.cert-manager.svc:443 cert with certs: var/run/secrets/istio/root-cert.pem +2022-01-13T16:51:58.495941Z info citadelclient Citadel client using custom root cert: cert-manager-istio-csr.cert-manager.svc:443 +``` + +Istio v1.13+ + +``` +2022-01-13T16:51:58.495493Z info CA Endpoint cert-manager-istio-csr.cert-manager.svc:443, provider Citadel +2022-01-13T16:51:58.495817Z info Using CA cert-manager-istio-csr.cert-manager.svc:443 cert with certs: var/run/secrets/istio/root-cert.pem +2022-01-13T16:51:58.495941Z info citadelclient Citadel client using custom root cert: var/run/secrets/istio/root-cert.pem +``` + +Finally we can inspect the certificate being used in memory by Envoy. This one liner should return you the certificate being used: + +```shell +istioctl proxy-config secret $(kubectl get pods -n $NAMESPACE -o jsonpath='{.items..metadata.name}' --selector app=$APP) -o json | jq -r '.dynamicActiveSecrets[0].secret.tlsCertificate.certificateChain.inlineBytes' | base64 --decode | openssl x509 -text -noout +``` + +In particular look for the following sections: + +``` + Signature Algorithm: ecdsa-with-SHA256 + Issuer: O=cert-manager, O=cluster.local, CN=istio-ca + Validity + Not Before: Jan 13 16:51:59 2022 GMT + Not After : Jan 13 17:51:59 2022 GMT +... + X509v3 Subject Alternative Name: + URI:spiffe://cluster.local/ns/default/sa/httpbin +``` + +You should see the relevant Trust Domain inside the Issuer. In the default case, it should be: +`cluster.local` as above. Note that the SPIFFE URI may be different if you used a different +namespace or application. + +## Clean up + +Assuming your running inside kind, you can simply remove the cluster: + +```shell +kind delete cluster +``` + +## Installation with Runtime Configuration + +There are two options for installing with runtime configuration: + +1. Install after cert-manager, still providing an explicit `issuerRef` in the Helm chart +2. Blank out the `issuerRef` in the Helm chart and use pure runtime configuration + +Both options will require a ConfigMap to be created to point at an issuer. This ConfigMap can be created +before or after installation, and must be created in the same namespace as the istio-csr pods. + +### Creating the ConfigMap + +Three keys are required, specifying the issuer name, kind and group. Any method of creating a ConfigMap will work. For example: + +```bash +kubectl create configmap -n cert-manager istio-issuer \ + --from-literal=issuer-name=my-issuer-name \ + --from-literal=issuer-kind=ClusterIssuer \ + --from-literal=issuer-group=cert-manager.io +``` + +The Helm chart includes the ability to create the runtime configuration ConfigMap at install time if desired, through the `app.runtimeConfiguration.issuer` values: + +```yaml +app: + runtimeConfiguration: + issuer: + name: my-issuer-name + kind: Issuer + group: cert-manager.io +``` + +### Option 1: Installation after cert-manager + +If cert-manager is already installed, you can use the same `helm upgrade` command as above but also specifying the name of the runtime configuration ConfigMap: + +```bash +helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \ + --install \ + --namespace cert-manager \ + --wait \ + ... + --set "app.runtimeConfiguration.name=istio-issuer" +``` + +In this scenario, the issuer defined in `app.certmanager.issuer` will be used at startup and to create the `istiod` certificate. + +When istio-csr detects the runtime ConfigMap, it'll use the issuer configured there. If the ConfigMap is updated, istio-csr will respect the update dynamically. + +If the runtime ConfigMap is deleted, istio-csr will revert to using the value from `app.certmanager.issuer`. + +### Option 2: Pure Runtime Configuration + +Pure runtime configuration is only practical with istio-csr `v0.11.0` or newer. + +Pure runtime configuration requires more values to be set: + +1. The `app.certmanager.issuer` values must be blanked out (as they're set to a default value in the chart) +2. The `istiod` certificate must not be provisioned alongside the istio-csr resources. By passing `app.tls.istiodCertificateEnable=dynamic`, the istiod will be dynamically generated when runtime configuration is available. +3. `app.runtimeConfiguration.name` must be set. + +An example `values.yaml` file for pure runtime configuration is as follows: + +```yaml +app: + runtimeIssuanceConfigMap: istio-issuer + certmanager: + issuer: + enabled: false # Important: the default issuer is enabled by default + tls: + rootCAFile: "/var/run/secrets/istio-csr/ca.pem" + istiodCertificateEnable: dynamic +volumeMounts: +- name: root-ca + mountPath: /var/run/secrets/istio-csr +volumes: +- name: root-ca + secret: + secretName: istio-root-ca +``` + +This file could then be used with the following command: + +```bash +helm upgrade cert-manager-istio-csr jetstack/cert-manager-istio-csr \ + --install \ + --namespace cert-manager \ + --wait \ + --values values.yaml +``` + +#### Completing a Pure Runtime Installation + +To make istio-csr easier to install alongside cert-manager, pure runtime configuration slightly modifies the behavior of +istio-csr's health checks. This is because Helm will not complete an install until the health checks are passing. + +If and only if using pure runtime configuration, istio-csr's health checks will report as healthy until runtime configuration is available for the first time. + +After runtime configuration becomes available for the first time, the health checks will revert to their normal operation. + +## Usage + +> 📖 Read the [istio-csr docs](./README.md). diff --git a/content/v1.15-docs/usage/kube-csr.md b/content/v1.15-docs/usage/kube-csr.md new file mode 100644 index 0000000000..99a2081d00 --- /dev/null +++ b/content/v1.15-docs/usage/kube-csr.md @@ -0,0 +1,177 @@ +--- +title: CertificateSigningRequest resource +description: 'cert-manager usage: Kubernetes CertificateSigningRequest resources' +--- + +> **apiVersion:** certificates.k8s.io/v1 +> **kind:** CertificateSigningRequest + +
          + +
          + +Kubernetes has an in-built +[CertificateSigningRequest](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/) +resource. This resource is similar to the cert-manager +[CertificateRequest](../usage/certificaterequest.md) in that it is used to +request an X.509 signed certificate from a referenced Certificate Authority +(CA). + +Using this resource may be useful for users who are using an application that +supports this resource, but not the cert-manager CertificateRequest resource, +and they still wish for certificates to be signed through cert-manager. + +CertificateSigningRequests reference a `SignerName` or signer as the entity it +wishes to sign its request from. For cert-manager, a signer can be mapped to +either an [Issuer or ClusterIssuer](../configuration/README.md). + +#### Feature State + +This feature is currently in an _experimental_ state, and its behavior is +subject to change in further releases. + +
          + +⛔️ This feature is only enabled by adding it to the `--feature-gates` flag on +the cert-manager controller: + +```bash +--feature-gates=ExperimentalCertificateSigningRequestControllers=true +``` + +Which can be added using Helm: + +```bash +$ helm install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set featureGates="ExperimentalCertificateSigningRequestControllers=true" \ + --set crds.enabled=true +``` + +> Note: cert-manager supports signing CertificateSigningRequests +> using all [internal Issuers](../configuration/README.md). + +> Note: cert-manager _does not_ automatically approve CertificateSigningRequests +> that reference a cert-manager [Issuer](../configuration/README.md). Please refer to +> the [Kubernetes documentation](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#request-signing-process) +> for the request process of CertificateSigningRequests. + + +
          + + +## Signer Name + +CertificateSigningRequests contain a +[`spec.signerName`](https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#request-signing-process) +field to reference a CA to sign the request. cert-manager Issuers or +ClusterIssuers are referenced in the following form: + +``` +.cert-manager.io/. +``` + +For example, a namespaced Issuer in the namespace `sandbox` with the name +`my-issuer` would be referenced via: + +```yaml + signerName: issuers.cert-manager.io/sandbox.my-issuer +``` + +A ClusterIssuer with the name `my-cluster-issuer` would be referenced via: + +```yaml + signerName: clusterissuers.cert-manager.io/my-cluster-issuer +``` + +### Referencing Namespaced Issuers + +Unlike CertificateRequests, CertificateSigningRequests are cluster scoped +resources. To prevent users from requesting certificates from a namespaced +Issuer in a namespace that they otherwise would not have access to, cert-manager +performs a +[SubjectAccessReview](https://kubernetes.io/docs/reference/access-authn-authz/authorization/#checking-api-access). +This review ensures that the requesting user has the permission to `reference` +the `signers` resource in the given namespace. The name should be either the +name of the Issuer, or `"*"` to reference all Issuers in that namespace. + +An example Role to give permissions to reference Issuers in the `sandbox` +namespace would look like the following: + +```yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: cert-manager-referencer:my-issuer + namespace: sandbox +rules: +- apiGroups: ["cert-manager.io"] + resources: ["signers"] + verbs: ["reference"] + resourceNames: + - "my-issuer" # To give permission to _only_ reference Issuers with the name 'my-issuer' + - "*" # To give permission to reference Issuers with any name in this namespace +``` + +## Annotations + +To keep feature parity with CertificateRequests, annotations are used to store +values that do not exist as `spec` or `status` fields on the +CertificateSigningRequest resource. These fields are either set by the +_requester_ or by the _signer_ as labelled below. + +Requester annotations: + +- `experimental.cert-manager.io/request-duration`: **Set by the requester**. Accepts + a [Go time duration](https://golang.org/pkg/time/#ParseDuration) string + specifying the requested certificate duration. Defaults to 90 days. Some + signers such as Venafi or ACME typically _do not_ allow requesting a + duration. + +- `experimental.cert-manager.io/request-is-ca`: **Set by the requester**. If set to + `"true"`, will request for a CA certificate. + +- `experimental.cert-manager.io/private-key-secret-name`: **Set by the + requester**. Required only for the SelfSigned signer. Used to reference a + Secret which contains the PEM encoded private key of the requester's X.509 + certificate signing request at key `tls.key`. Used to sign the requester's + request. + +- `venafi.experimental.cert-manager.io/custom-fields`: **Set by the + requester**. Optional for only the Venafi signer. Used for adding custom + fields to the Venafi request. This will only work with Venafi TPP `v19.3` + and higher. The value is a JSON array with objects containing the name and + value keys, for example: + ``` + venafi.experimental.cert-manager.io/custom-fields: |- + [ + {"name": "field-name", "value": "field value"}, + {"name": "field-name-2", "value": "field value 2"} + ] + ``` + +Signer annotations: + +- `venafi.experimental.cert-manager.io/pickup-id`: **Set by the signer**. Only + used for the Venafi signer. Used to record the Venafi Pickup ID of a + certificate signing request that has been submitted to the Venafi API for + collection during issuance. + +## Usage + +CertificateSigningRequests can be manually created using +[cmctl](../reference/cmctl.md#experimental). +This command takes a manifest file containing a +[Certificate](../usage/certificate.md) resource as input. This generates a +private key and creates a CertificateSigningRequest. CertificateSigningRequests +are not approved by default, so you will likely need to approve it manually: + +```bash +$ kubectl certificate approve +``` + +## Inner workings diagram for developers + + diff --git a/content/v1.15-docs/variables.json b/content/v1.15-docs/variables.json new file mode 100644 index 0000000000..d62331f269 --- /dev/null +++ b/content/v1.15-docs/variables.json @@ -0,0 +1,3 @@ +{ + "cert_manager_latest_version": "v1.15.3" +}