學習如何自動設定憑證預設值
上次驗證時間:2024 年 1 月 19 日
目標
我們將設定一個叢集,讓使用者在 Certificate
資源中盡可能少指定 YAML。這將透過使用 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
規格中不存在的 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
)。 -
使用以下命令試執行套用憑證,然後將其與原始資源進行
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
和之前一樣,試執行套用並使用輸入檔案
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 -
試執行套用並使用
diff
來驗證我們所有的預設值是否已套用至這個最精簡的Certificate
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 -
試執行套用並使用
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
規格欄位都沒有變更。只有 metadata 區段已變更,這告訴我們已套用原則,但由於已提供值,因此未設定任何預設值。這表示您在需要時可以保留覆寫叢集預設值的彈性。
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
透過此策略,我們達成了目標,並使使用者能夠提交最小化的 Certifiate
資源。這完成了我們的第五個使用案例,規範中只包含一個欄位,即 dnsNames
項目。其他所有指定的欄位都使用 Kyverno 和 ClusterPolicy
自動預設,這通常由平台管理員設定。
清理
如果您為本教學建立了一個 kind 叢集,您可以簡單地執行:
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 版本要求
從 v1.14.x 開始,cert-manager 的變更 webhook 行為已變更。如需更完整的說明和變更詳細資訊,請參閱PR #6311。手動修復的說明可以在 PR #6311 上的此評論中找到。
預設值功能請求
如需更多關於設定「預設值」或「預設設定」的背景閱讀,您可以參考issue 2239。本教學來自對該問題的調查。
cert-manager 團隊認為,可以使用其他更通用的開放原始碼策略工具來實現所請求的解決方案。Kyverno 只是其中一個範例,也可以使用 Gatekeeper 作為替代工具來實現類似的功能。