了解如何自动设置证书默认值
上次验证:2024 年 1 月 19 日
目标
我们将设置一个集群,用户在 Certificate
资源中需要指定的 YAML 代码尽可能少。这将通过利用 Kyverno 来实现,Kyverno 会将自定义的“默认”值应用于用户未指定的 Certificate
字段。
拥有默认值有一些好处
Certificate
的使用者可以最大程度地减少其 YAML 资源。Certificate
的使用者保留了在需要时覆盖字段的灵活性。- 集群操作员可以决定默认值是什么,而不是依赖 cert-manager 的内置默认值。
用例
通过在我们的集群中设置自定义默认值,我们使平台团队能够解决诸如以下用例:
-
确保
CertificateRequest
资源得到清理。使用
ClusterPolicy
为Certificate.Spec.RevisionHistoryLimit
字段设置自定义默认值。 -
帮助用户为其
Certificate
资源选择安全的默认密钥设置。使用
ClusterPolicy
为Certificate.Spec.PrivateKey
字段设置自定义默认值。 -
为集群内的用户默认
Issuer
。使用
ClusterPolicy
为Certificate.spec.issuerRef
字段设置自定义默认值。 -
为存放证书的
Secret
的命名设置默认模式。使用
ClusterPolicy
为spec.secretName
必填字段设置自定义默认值。 -
通过允许应用程序开发人员以最少的配置创建安全的 X.509 TLS 证书,使他们的生活更轻松。
使用
ClusterPolicy
设置所有其他必需的Certificate.spec
字段。只需一个身份规范字段,即以下之一:commonName
或literalSubject
dnsNames
uris
emailAddresses
ipAddresses
otherNames
流程
我们将为三种不同的场景设置默认值,每次都更高级一点
- 为可选的
Certificate
资源字段设置默认值。 - 为必需的
Certificate
资源字段设置默认值。 - 使用
Ingress
注释请求证书时,为Certificate
资源字段设置默认值。
设置
先决条件
💻 软件
- kubectl:Kubernetes 命令行工具,允许您配置 Kubernetes 集群。
- helm:Kubernetes 的包管理器。
- kind(**可选**):用于创建在 Docker 或其他容器运行时中运行的本地 Kubernetes 环境。
本地 Kubernetes 环境
⚠️ 如果您有其他 Kubernetes 环境,则可以跳过此步骤。
-
使用
kind
为本教程创建集群环境。kind create cluster --name defaults⏲ 创建集群可能需要不到一分钟,具体取决于您的机器。
⚠️ 此集群仅适合学习目的。它不适合生产使用。
软件安装
在您拥有集群环境后,使用 helm
安装所需的 Kubernetes 包。
-
为 helm 图表版本设置一些环境变量
export CERT_MANAGER_CHART_VERSION="v1.16.1" \KYVERNO_CHART_VERSION="3.1.4" \INGRESS_NGINX_CHART_VERSION="4.9.0" -
安装 cert-manager
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/ -
安装 Kyverno
helm upgrade --install kyverno kyverno \--namespace kyverno-system \--version $KYVERNO_CHART_VERSION \--create-namespace \--repo https://kyverno.github.io/kyverno/ -
安装 ingress-nginx
helm upgrade --install ingress-nginx ingress-nginx \--namespace ingress-nginx \--version $INGRESS_NGINX_CHART_VERSION \--create-namespace \--repo https://kubernetes.github.io/ingress-nginx
有关完整安装说明,请参阅以下链接
设置默认值
本教程从这里开始,先介绍一些背景知识,然后再分别介绍这三种场景。
必需与非必需
Certificate
资源有一个 spec
部分,其中包含许多“必需”字段。这意味着创建 Certificate
资源时必须存在这些字段。还有一些其他字段不需要在每个 Certificate
资源上明确定义。这实际上意味着这些字段之一的值不是必需的,或者在其他地方定义了默认值。该其他地方可能在 cert-manager 代码库中,也可能是在创建和返回 X.509 证书的发行者中。让我们探讨如何操作这些值以使其成为自定义值,并使 Certificate
用户的生活更轻松。
在本教程中,我们将设置一些 ClusterPolicy
资源和 Certificate
资源。我们将引用 Certificate
spec 中不存在的 ClusterIssuer
,但对于本教程而言,ClusterIssuer
不是必需的,因为我们实际上不会请求证书。这意味着即使没有自己的域名,任何人都可以学习本教程。
⚠️ 为了便于入门,我们使用集群范围的
ClusterPolicy
资源。将来,您可以通过使用命名空间级别的Policy
资源将默认值范围限定到命名空间级别,但这在本教程中不会介绍。
1 - 默认可选字段
在本节中,我们将创建一些规则,这些规则会自动为所有 Certificate
资源设置三个字段。这里没有三个字段是必需字段,但根据平台和发行者的偏好,可能需要设置这些字段。这些规则将
- 设置默认值为:
revisionHistoryLimit: 2
。 - 设置 默认值为
Always
在spec.privateKey.rotationPolicy
下。 - 为所有
spec.privateKey
字段设置默认值。
ℹ️ 请注意,这些规则如何解决我们的 用例 中的前两个。
-
首先看一下
ClusterPolicy
apiVersion: kyverno.io/v1kind: ClusterPolicymetadata:name: mutate-certificatesspec:failurePolicy: Failrules:# Set a sane default for the history field if not already present- name: set-revisionHistoryLimitmatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:# +(...) This is the clever syntax for if not already set+(revisionHistoryLimit): 2# Set rotation to always if not already set- name: set-privateKey-rotationPolicymatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:privateKey:+(rotationPolicy): Always# Set private key details for algorithm and size- name: set-privateKey-detailsmatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:privateKey:+(algorithm): ECDSA+(size): 521+(encoding): PKCS1 -
将策略应用于集群并检查其是否已准备就绪
kubectl apply -f cpol-mutate-certificates-0.yamlkubectl get cpol当
ClusterPolicy
准备就绪时,输出应如下所示NAME ADMISSION BACKGROUND VALIDATE ACTION READY AGE MESSAGEmutate-certificates true true Audit True 0s Ready -
现在检查“test-revision”
Certificate
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: test-revisionnamespace: defaultspec:dnsNames:- example.comissuerRef:group: cert-manager.iokind: ClusterIssuername: not-my-corp-issuersecretName: test-revision-cert您可以看到,我们设置了目前最小的配置,仅指定了证书的 DNS 名称、证书保存位置 (
secretName
) 和用于请求证书的发行者 (issuerRef
)。 -
使用以下命令对证书执行dry-run apply,然后与原始资源进行
diff
,查看来自我们ClusterPolicy
的默认值是如何应用的。kubectl apply -f cert-test-revision.yaml --dry-run=server -o yaml | diff -uZ cert-test-revision.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/v1kind: Certificatemetadata:+ 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: 1name: test-revisionnamespace: default+ uid: 9f9a4f0a-4aa7-427d-ae4b-c1716fed8246spec:dnsNames:- example.com@@ -10,4 +16,10 @@group: cert-manager.iokind: ClusterIssuername: not-my-corp-issuer+ privateKey:+ algorithm: ECDSA+ encoding: PKCS1+ rotationPolicy: Always+ size: 521+ revisionHistoryLimit: 2secretName: test-revision-cert我们已成功将
privateKey
和revisionHistoryLimit
字段设为默认值! -
让我们覆盖所有这些默认字段,以验证我们作为最终用户仍然可以设置我们想要的。为了测试这一点,让我们使用“test-revision-override”
Certificate
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: test-revision-overridenamespace: defaultspec:dnsNames:- example.comissuerRef:group: cert-manager.iokind: ClusterIssuername: not-my-corp-issuerprivateKey:algorithm: RSAencoding: PKCS8rotationPolicy: Neversize: 4096revisionHistoryLimit: 44secretName: test-revision-override-cert🔗
cert-test-revision-override.yaml
与之前一样,对输出执行dry-run apply并与输入文件进行
diff
。kubectl apply -f cert-test-revision-override.yaml --dry-run=server -o yaml | diff -uZ cert-test-revision-override.yaml -在这里,您可以在输出中看到对
Certificate
本身没有规范更改。该Certificate
已经定义了我们ClusterPolicy
规则会影响的所有字段。--- 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/v1kind: Certificatemetadata:+ 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: 1name: test-revision-overridenamespace: default+ uid: 83a6ddbc-6903-479e-802d-e11149985338spec:dnsNames:- example.com
2 - 设置必需字段的默认值
⚠️ 此部分需要 cert-manager v1.14.x 或更高版本才能正常运行。有关详细信息,请参见附录部分。
现在,我们可以设置一个 Kyverno ClusterPolicy
,以将默认值应用于任何Certificate
字段。这包括必需字段。在我们的示例ClusterPolicy
中,我们将执行两件事。
- 将相关
issuerRef
字段设为默认值,以使用“our-corp-issuer”ClusterIssuer
。 - 应用一个默认
secretName
,该名称为Certificate
对象的名称后缀为“-cert”。
ℹ️ 注意这些规则如何解决第三和第四个用例。
-
以下是用于设置这两个字段默认值的
ClusterPolicy
资源。apiVersion: kyverno.io/v1kind: ClusterPolicymetadata:name: mutate-certificatesspec:failurePolicy: Failrules:# Set a sane default for the history field if not already present- name: set-revisionHistoryLimitmatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:# +(...) This is the clever syntax for if not already set+(revisionHistoryLimit): 2# Set rotation to always if not already set- name: set-privateKey-rotationPolicymatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:privateKey:+(rotationPolicy): Always# Set private key details for algorithm and size- name: set-privateKey-detailsmatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:privateKey:+(algorithm): ECDSA+(size): 521+(encoding): PKCS1# Set a secretName when one is not provided- name: set-default-secret-namematch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:# You can read more about this syntax in the Kyverno documentation:# https://kyverno.io/docs/writing-policies/variables/#variables-from-admission-review-requests+(secretName): "{{request.object.metadata.name}}-cert"# Set a default for issuerRef fields- name: set-default-issuer-refmatch:any:- resources:kinds:- Certificatemutate:patchStrategicMerge:spec:+(issuerRef):name: our-corp-issuerkind: ClusterIssuergroup: cert-manager.io🔗
cpol-mutate-certificates-1.yaml
此
ClusterPolicy
是我们之前应用的策略的扩展。 -
应用此策略。
kubectl apply -f cpol-mutate-certificates-1.yaml您应该会看到我们现有的
ClusterPolicy
已更改。clusterpolicy.kyverno.io/mutate-certificates configured获取
ClusterPolicy
,以验证其是否处于“就绪”状态。kubectl get cpol此命令应返回类似于以下示例的输出。
NAME ADMISSION BACKGROUND VALIDATE ACTION READY AGE MESSAGEmutate-certificates true true Audit True 6m21s Ready -
查看“test-minimal”
Certificate
,该证书旨在验证策略中的所有规则是否都处于运行状态。apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: test-minimalnamespace: defaultspec:dnsNames:- example.com -
对该最小
Certificate
执行dry-run apply并进行diff
,以验证所有默认值是否都已应用。kubectl apply -f cert-test-minimal.yaml --dry-run=server -o yaml | diff -uZ cert-test-minimal.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/v1kind: Certificatemetadata:+ 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: 1name: test-minimalnamespace: default+ uid: 792d29c7-8cf3-4f3a-9f12-4fba396e0d6espec: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请查看我们如何自动填充了
spec.issuerRef
和spec.secretName
字段值。这表明 KyvernoClusterPolicy
已应用于提供的Certificate
资源。 -
为了确保我们没有强制执行任何设置,让我们显式设置具有默认规则的
Certificate
的每个属性。我们将使用“test-revision-override”Certificate
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: test-revision-overridenamespace: defaultspec:dnsNames:- example.comissuerRef:group: cert-manager.iokind: ClusterIssuername: not-my-corp-issuerprivateKey:algorithm: RSAencoding: PKCS8rotationPolicy: Neversize: 4096revisionHistoryLimit: 44secretName: test-revision-override-cert -
对该文件执行dry-run apply并进行
diff
。kubectl apply -f cert-test-revision-override.yaml --dry-run=server -o yaml | diff -uZ cert-test-revision-override.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/v1kind: Certificatemetadata:+ 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: 1name: test-revision-overridenamespace: default+ uid: d0ad7abe-c703-45f7-acf9-634b3a263cfaspec:dnsNames:- example.com从此命令中,您可以看到没有一个
Certificate
规范字段被更改。只有元数据部分发生了更改,这告诉我们策略已应用,但没有设置任何默认值,因为已经提供了值。这表明,您可以在需要时保留覆盖群集默认值的灵活性。
3 - 通过 Ingress 注释设置默认值
许多 cert-manager 用户不会直接创建Certificate
资源,而是使用ingress-shim功能。cert-manager 根据支持的注释和Ingress
规范创建Certificate
资源。让我们看看如何在这种情况中仍然使用ClusterPolicy
应用默认值。
-
此示例
Ingress
资源具有cert-manager.io/cluster-issuer
注释,该注释指示 cert-manager 创建一个Certificate
,该证书具有一个指向名为our-corp-issuer
的ClusterIssuer
的issuerRef
字段。apiVersion: networking.k8s.io/v1kind: Ingressmetadata:annotations:cert-manager.io/cluster-issuer: "our-corp-issuer"name: defaults-examplenamespace: defaultspec:ingressClassName: nginxrules:- host: app.example.comhttp:paths:- backend:service:name: appport:number: 80path: /pathType: ImplementationSpecifictls:- hosts:- app.example.comsecretName: defaults-example-certificate-tls -
此注释和相关的
ingress.spec.tls
配置是我们应用该资源所需的全部内容。kubectl apply -f ingress.yaml -
现在验证是否已自动生成
Certificate
资源。kubectl get cert defaults-example-certificate-tls -o yaml此命令应返回类似于以下示例的输出。
apiVersion: cert-manager.io/v1kind: Certificatemetadata:creationTimestamp: "2024-01-12T17:47:04Z"generation: 1name: defaults-example-certificate-tlsnamespace: defaultownerReferences:- apiVersion: networking.k8s.io/v1blockOwnerDeletion: truecontroller: truekind: Ingressname: defaults-exampleuid: bea33a55-a9ed-4664-a56a-a679eb8272c3resourceVersion: "584260"uid: 43ced989-723b-4eac-bad0-f8bead6976dfspec:dnsNames:- app.example.comissuerRef:group: cert-manager.iokind: ClusterIssuername: our-corp-issuerprivateKey:algorithm: ECDSAencoding: PKCS1rotationPolicy: Alwayssize: 521revisionHistoryLimit: 2secretName: defaults-example-certificate-tlsusages:- digital signature- key enciphermentstatus:conditions:- lastTransitionTime: "2024-01-12T17:47:04Z"message: Issuing certificate as Secret does not existobservedGeneration: 1reason: DoesNotExiststatus: "True"type: Issuing- lastTransitionTime: "2024-01-12T17:47:04Z"message: Issuing certificate as Secret does not existobservedGeneration: 1reason: DoesNotExiststatus: "False"type: ReadynextPrivateKeySecretName: defaults-example-certificate-tls-nbjws -
您可以通过查看 Kyverno 准入控制器容器的日志,选择性地验证“mutate-certificates”
ClusterPolicy
是否已应用。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此命令应返回类似于以下示例的输出。
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"]}}以最后一行为例,您可以提取以下内容。
"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"]请参见
policy
键,该键表明我们的策略已应用。在rules
部分,您可以识别出我们的五个规则中有三个已应用于生成的“defaults-example-certificate-tls”Certificate
资源。
当使用Ingress
资源时,您始终需要指定要从中加载证书的secretName
。在这种情况下不需要设置默认值,因为这是Ingress
规范的必需部分。
用户在Ingress
资源上需要指定的唯一其他 YAML 是注释。
cert-manager.io/cluster-issuer: "our-corp-issuer"
此注释既是 cert-manager 对此Ingress
采取行动的触发器,也是Certificate.spec.issuerRef
字段的配置值。这一行代码取代了用户创建Certificate
资源的必要性。这减少了为在此Ingress
后面保护应用程序所需的总 YAML 量。
摘要
这是一个关于为群集Certificate
资源设置默认值的简单示例。我们已经展示了ClusterPolicy
不必“强制”设置,而可以用于设置和扩展默认选项。Certificate
用户可以减少 YAML,同时保留在需要时覆盖任何值的灵活性。
我们已经展示了如何使用一个只有 5 个规则的简单ClusterPolicy
,将创建Certificate
资源的用户体验从
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: test-revision-overridenamespace: defaultspec:dnsNames:- example.comissuerRef:group: cert-manager.iokind: ClusterIssuername: not-my-corp-issuerprivateKey:algorithm: RSAencoding: PKCS8rotationPolicy: Neversize: 4096revisionHistoryLimit: 44secretName: test-revision-override-cert
🔗 cert-test-revision-override.yaml
更改为仅需要指定对他们重要的配置,例如
apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: test-minimalnamespace: defaultspec:dnsNames:- example.com
通过这项策略,我们实现了目标,并让用户能够提交最小化的证书
资源。 这完成了我们的第五个用例, 规范中只包含一个字段,即dnsNames
条目。 每个其他指定的字段都使用 Kyverno 和ClusterPolicy
自动设置为默认值, 这些通常由平台管理员设置。
清理
如果您为本教程创建了集群,则可以简单地运行
kind delete cluster --name defaults
否则,要删除在本教程中部署的所有资源
# Assuming you are running from this directly or saved all the files to yamls/kubectl delete -f ingress.yamlkubectl delete -f cpol-mutate-certificates-1.yamlhelm uninstall kyverno -n kyverno-systemhelm uninstall cert-manager -n cert-managerhelm uninstall ingress-nginx -n ingress-nginx
附录
cert-manager 版本要求
cert-manager 的变异 Webhook 的行为从 v1.14.x 开始发生了改变。 要了解有关更改的更完整解释和详细信息,请参阅PR #6311。 关于手动修复的说明可以在PR #6311 上的此评论中找到。
预设功能请求
要了解更多关于设置“默认值”或“预设”的背景信息,您可以参考问题 2239。 本教程是在对该问题的调查中产生的。
cert-manager 团队认为,可以通过使用其他更通用的开源策略工具来实现所请求的解决方案。 Kyverno 只是一个示例,类似的效果也可以使用Gatekeeper作为替代工具来实现。