憑證與憑證簽署請求
Kubernetes 憑證與信任組合 API 透過為 Kubernetes API 的用戶端提供程式化介面來請求與取得來自憑證授權單位 (CA) 的 X.509 憑證,進而實現 X.509 憑證佈建的自動化。
也提供散發信任組合的實驗性 (alpha) 支援。
憑證簽署請求
Kubernetes v1.19 [stable]
CertificateSigningRequest (CSR) 資源用於請求憑證由指定的簽署者簽署,之後請求可能會在最終簽署前被核准或拒絕。
請求簽署程序
CertificateSigningRequest 資源類型允許用戶端根據簽署請求來要求簽發 X.509 憑證。CertificateSigningRequest 物件包含 spec.request
欄位中 PEM 編碼的 PKCS#10 簽署請求。CertificateSigningRequest 使用 spec.signerName
欄位來表示簽署者(請求的接收者)。請注意,在 API 版本 certificates.k8s.io/v1
之後,spec.signerName
是必要的鍵值。在 Kubernetes v1.22 及更高版本中,用戶端可以選擇性地設定 spec.expirationSeconds
欄位,以請求已簽發憑證的特定生命週期。此欄位的最小有效值為 600
,即十分鐘。
一旦建立,CertificateSigningRequest 必須先獲得核准才能簽署。根據所選的簽署者,CertificateSigningRequest 可能會由控制器自動核准。否則,CertificateSigningRequest 必須透過 REST API(或 client-go)或執行 kubectl certificate approve
手動核准。同樣地,CertificateSigningRequest 也可能被拒絕,這會告知已設定的簽署者不得簽署該請求。
對於已核准的憑證,下一步是簽署。相關的簽署控制器首先驗證是否滿足簽署條件,然後建立憑證。接著,簽署控制器會更新 CertificateSigningRequest,將新的憑證儲存在現有 CertificateSigningRequest 物件的 status.certificate
欄位中。status.certificate
欄位可能是空的,或者包含 PEM 格式編碼的 X.509 憑證。在簽署者執行此操作之前,CertificateSigningRequest 的 status.certificate
欄位會是空的。
一旦 status.certificate
欄位被填入,請求就已完成,用戶端現在可以從 CertificateSigningRequest 資源中取得已簽署的憑證 PEM 資料。如果未滿足核准條件,簽署者可以拒絕憑證簽署。
為了減少叢集中舊 CertificateSigningRequest 資源的數量,垃圾收集控制器會定期執行。垃圾收集會移除一段時間內狀態未變更的 CertificateSigningRequest。
- 已核准的請求:在 1 小時後自動刪除
- 已拒絕的請求:在 1 小時後自動刪除
- 失敗的請求:在 1 小時後自動刪除
- 待處理的請求:在 24 小時後自動刪除
- 所有請求:在已簽發的憑證過期後自動刪除
憑證簽署授權
允許建立 CertificateSigningRequest 和檢索任何 CertificateSigningRequest
- 動詞:
create
、get
、list
、watch
,群組:certificates.k8s.io
,資源:certificatesigningrequests
例如
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-creator
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- create
- get
- list
- watch
允許核准 CertificateSigningRequest
- 動詞:
get
、list
、watch
,群組:certificates.k8s.io
,資源:certificatesigningrequests
- 動詞:
update
,群組:certificates.k8s.io
,資源:certificatesigningrequests/approval
- 動詞:
approve
,群組:certificates.k8s.io
,資源:signers
,resourceName:<signerNameDomain>/<signerNamePath>
或<signerNameDomain>/*
例如
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-approver
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- get
- list
- watch
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/approval
verbs:
- update
- apiGroups:
- certificates.k8s.io
resources:
- signers
resourceNames:
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs:
- approve
允許簽署 CertificateSigningRequest
- 動詞:
get
、list
、watch
,群組:certificates.k8s.io
,資源:certificatesigningrequests
- 動詞:
update
,群組:certificates.k8s.io
,資源:certificatesigningrequests/status
- 動詞:
sign
,群組:certificates.k8s.io
,資源:signers
,resourceName:<signerNameDomain>/<signerNamePath>
或<signerNameDomain>/*
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: csr-signer
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- get
- list
- watch
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/status
verbs:
- update
- apiGroups:
- certificates.k8s.io
resources:
- signers
resourceNames:
- example.com/my-signer-name # example.com/* can be used to authorize for all signers in the 'example.com' domain
verbs:
- sign
簽署者
簽署者抽象地表示可能簽署或已簽署安全憑證的實體或多個實體。
任何可供特定叢集外部使用的簽署者都應提供有關簽署者如何運作的資訊,以便消費者可以理解這對 CertifcateSigningRequests 和(如果已啟用)ClusterTrustBundles 的意義。這包括
- 信任分發:信任錨點(CA 憑證或憑證同捆包)如何分發。
- 允許的主體:不允許的主體被請求時的任何限制和行為。
- 允許的 x509 擴充:包括 IP subjectAltNames、DNS subjectAltNames、Email subjectAltNames、URI subjectAltNames 等,以及不允許的擴充被請求時的行為。
- 允許的金鑰用途 / 延伸金鑰用途:當 CSR 中指定的用途與簽署者決定的用途不同時的任何限制和行為。
- 到期/憑證生命週期:是否由簽署者固定、由管理員設定、由 CSR
spec.expirationSeconds
欄位決定等等,以及當簽署者決定的到期時間與 CSRspec.expirationSeconds
欄位不同時的行為。 - 允許/不允許 CA 位元:以及當 CSR 包含對 CA 憑證的請求,但簽署者不允許時的行為。
通常,一旦 CSR 獲得核准且憑證已簽發,CertificateSigningRequest 的 status.certificate
欄位會包含單一 PEM 編碼的 X.509 憑證。有些簽署者會在 status.certificate
欄位中儲存多個憑證。在這種情況下,簽署者的文件應指定額外憑證的含義;例如,這可能是憑證加上在 TLS 交握期間要呈現的中繼憑證。
如果您想提供信任錨點(根憑證),則應與 CertificateSigningRequest 及其 status.certificate
欄位分開進行。例如,您可以使用 ClusterTrustBundle。
PKCS#10 簽署請求格式沒有標準機制來指定憑證到期時間或生命週期。因此,到期時間或生命週期必須透過 CSR 物件的 spec.expirationSeconds
欄位設定。內建簽署者使用 ClusterSigningDuration
設定選項,預設為 1 年(kube-controller-manager 的 --cluster-signing-duration
命令列標記),作為未指定 spec.expirationSeconds
時的預設值。當指定 spec.expirationSeconds
時,會使用 spec.expirationSeconds
和 ClusterSigningDuration
的最小值。
注意
spec.expirationSeconds
欄位是在 Kubernetes v1.22 中新增的。較早版本的 Kubernetes 不會採用此欄位。v1.22 之前的 Kubernetes API 伺服器會在建立物件時靜默地捨棄此欄位。Kubernetes 簽署者
Kubernetes 提供內建簽署者,每個簽署者都有一個眾所周知的 signerName
kubernetes.io/kube-apiserver-client
:簽署將被 API 伺服器視為用戶端憑證的憑證。永遠不會被 kube-controller-manager 自動核准。- 信任分發:簽署的憑證必須被 API 伺服器視為用戶端憑證。CA 同捆包不會透過任何其他方式分發。
- 允許的主體 - 沒有主體限制,但核准者和簽署者可以選擇不核准或簽署。某些主體,例如叢集管理員層級的使用者或群組,在不同發行版本和安裝之間有所不同,但在核准和簽署之前值得額外審查。預設啟用
CertificateSubjectRestriction
准入外掛程式來限制system:masters
,但它通常不是叢集中唯一的叢集管理員主體。 - 允許的 x509 擴充 - 採用 subjectAltName 和金鑰用途擴充,並捨棄其他擴充。
- 允許的金鑰用途 - 必須包含
["client auth"]
。不得包含超出["digital signature", "key encipherment", "client auth"]
的金鑰用途。 - 到期/憑證生命週期 - 對於此簽署者的 kube-controller-manager 實作,設定為
--cluster-signing-duration
選項的最小值,或者,如果指定,則為 CSR 物件的spec.expirationSeconds
欄位。 - 允許/不允許 CA 位元 - 不允許。
kubernetes.io/kube-apiserver-client-kubelet
:簽署將被 API 伺服器視為用戶端憑證的用戶端憑證。可能會被 kube-controller-manager 自動核准。- 信任分發:簽署的憑證必須被 API 伺服器視為用戶端憑證。CA 同捆包不會透過任何其他方式分發。
- 允許的主體 - 組織完全是
["system:nodes"]
,通用名稱是 "system:node:${NODE_NAME}
"。 - 允許的 x509 擴充 - 採用金鑰用途擴充,禁止 subjectAltName 擴充,並捨棄其他擴充。
- 允許的金鑰用途 -
["key encipherment", "digital signature", "client auth"]
或["digital signature", "client auth"]
。 - 到期/憑證生命週期 - 對於此簽署者的 kube-controller-manager 實作,設定為
--cluster-signing-duration
選項的最小值,或者,如果指定,則為 CSR 物件的spec.expirationSeconds
欄位。 - 允許/不允許 CA 位元 - 不允許。
kubernetes.io/kubelet-serving
:簽署伺服器憑證,API 伺服器會將其視為有效的 kubelet 伺服器憑證,但不保證其他任何內容。永遠不會被 kube-controller-manager 自動核准。- 信任分發:簽署的憑證必須被 API 伺服器視為有效,以終止與 kubelet 的連線。CA 同捆包不會透過任何其他方式分發。
- 允許的主體 - 組織完全是
["system:nodes"]
,通用名稱是 "system:node:${NODE_NAME}
"。 - 允許的 x509 擴充 - 採用金鑰用途和 DNSName/IPAddress subjectAltName 擴充,禁止 EmailAddress 和 URI subjectAltName 擴充,並捨棄其他擴充。必須至少存在一個 DNS 或 IP subjectAltName。
- 允許的金鑰用途 -
["key encipherment", "digital signature", "server auth"]
或["digital signature", "server auth"]
。 - 到期/憑證生命週期 - 對於此簽署者的 kube-controller-manager 實作,設定為
--cluster-signing-duration
選項的最小值,或者,如果指定,則為 CSR 物件的spec.expirationSeconds
欄位。 - 允許/不允許 CA 位元 - 不允許。
kubernetes.io/legacy-unknown
:完全不保證信任。Kubernetes 的某些第三方發行版本可能會採用由其簽署的用戶端憑證。穩定的 CertificateSigningRequest API(版本certificates.k8s.io/v1
及更高版本)不允許將signerName
設定為kubernetes.io/legacy-unknown
。永遠不會被 kube-controller-manager 自動核准。- 信任分發:無。在 Kubernetes 叢集中,此簽署者沒有標準的信任或分發。
- 允許的主體 - 任何
- 允許的 x509 擴充 - 採用 subjectAltName 和金鑰用途擴充,並捨棄其他擴充。
- 允許的金鑰用途 - 任何
- 到期/憑證生命週期 - 對於此簽署者的 kube-controller-manager 實作,設定為
--cluster-signing-duration
選項的最小值,或者,如果指定,則為 CSR 物件的spec.expirationSeconds
欄位。 - 允許/不允許 CA 位元 - 不允許。
kube-controller-manager 為每個內建簽署者實作了 控制平面簽署。所有這些簽署者的失敗僅在 kube-controller-manager 日誌中報告。
注意
spec.expirationSeconds
欄位是在 Kubernetes v1.22 中新增的。較早版本的 Kubernetes 不會採用此欄位。v1.22 之前的 Kubernetes API 伺服器會在建立物件時靜默地捨棄此欄位。這些簽署者的信任分發是在頻外進行的。上述描述之外的任何信任都純粹是巧合。例如,某些發行版本可能會採用 kubernetes.io/legacy-unknown
作為 kube-apiserver 的用戶端憑證,但這不是標準做法。這些用途都與 ServiceAccount 權杖密碼 .data[ca.crt]
無關。該 CA 同捆包僅保證驗證使用預設服務 (kubernetes.default.svc
) 連線到 API 伺服器。
自訂簽署者
您也可以引入自己的自訂簽署者,它應該具有類似的前綴名稱,但使用您自己的網域名稱。例如,如果您代表一個使用網域 open-fictional.example
的開放原始碼專案,那麼您可以使用 issuer.open-fictional.example/service-mesh
作為簽署者名稱。
自訂簽署者使用 Kubernetes API 來簽發憑證。請參閱 基於 API 的簽署者。
簽署
控制平面簽署者
Kubernetes 控制平面實作了每個 Kubernetes 簽署者,作為 kube-controller-manager 的一部分。
注意
在 Kubernetes v1.18 之前,kube-controller-manager 會簽署任何標記為已核准的 CSR。注意
spec.expirationSeconds
欄位是在 Kubernetes v1.22 中新增的。較早版本的 Kubernetes 不會採用此欄位。v1.22 之前的 Kubernetes API 伺服器會在建立物件時靜默地捨棄此欄位。基於 API 的簽署者
REST API 的使用者可以透過提交 UPDATE 請求到要簽署的 CSR 的 status
子資源來簽署 CSR。
作為此請求的一部分,應設定 status.certificate
欄位以包含已簽署的憑證。此欄位包含一個或多個 PEM 編碼的憑證。
所有 PEM 區塊都必須具有 "CERTIFICATE" 標籤,不包含標頭,並且編碼的資料必須是 RFC5280 第 4.1 節中描述的 BER 編碼 ASN.1 憑證結構。
憑證內容範例
-----BEGIN CERTIFICATE-----
MIIDgjCCAmqgAwIBAgIUC1N1EJ4Qnsd322BhDPRwmg3b/oAwDQYJKoZIhvcNAQEL
BQAwXDELMAkGA1UEBhMCeHgxCjAIBgNVBAgMAXgxCjAIBgNVBAcMAXgxCjAIBgNV
BAoMAXgxCjAIBgNVBAsMAXgxCzAJBgNVBAMMAmNhMRAwDgYJKoZIhvcNAQkBFgF4
MB4XDTIwMDcwNjIyMDcwMFoXDTI1MDcwNTIyMDcwMFowNzEVMBMGA1UEChMMc3lz
dGVtOm5vZGVzMR4wHAYDVQQDExVzeXN0ZW06bm9kZToxMjcuMC4wLjEwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDne5X2eQ1JcLZkKvhzCR4Hxl9+ZmU3
+e1zfOywLdoQxrPi+o4hVsUH3q0y52BMa7u1yehHDRSaq9u62cmi5ekgXhXHzGmm
kmW5n0itRECv3SFsSm2DSghRKf0mm6iTYHWDHzUXKdm9lPPWoSOxoR5oqOsm3JEh
Q7Et13wrvTJqBMJo1GTwQuF+HYOku0NF/DLqbZIcpI08yQKyrBgYz2uO51/oNp8a
sTCsV4OUfyHhx2BBLUo4g4SptHFySTBwlpRWBnSjZPOhmN74JcpTLB4J5f4iEeA7
2QytZfADckG4wVkhH3C2EJUmRtFIBVirwDn39GXkSGlnvnMgF3uLZ6zNAgMBAAGj
YTBfMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMB
Af8EAjAAMB0GA1UdDgQWBBTREl2hW54lkQBDeVCcd2f2VSlB1DALBgNVHREEBDAC
ggAwDQYJKoZIhvcNAQELBQADggEBABpZjuIKTq8pCaX8dMEGPWtAykgLsTcD2jYr
L0/TCrqmuaaliUa42jQTt2OVsVP/L8ofFunj/KjpQU0bvKJPLMRKtmxbhXuQCQi1
qCRkp8o93mHvEz3mTUN+D1cfQ2fpsBENLnpS0F4G/JyY2Vrh19/X8+mImMEK5eOy
o0BMby7byUj98WmcUvNCiXbC6F45QTmkwEhMqWns0JZQY+/XeDhEcg+lJvz9Eyo2
aGgPsye1o3DpyXnyfJWAWMhOz7cikS5X2adesbgI86PhEHBXPIJ1v13ZdfCExmdd
M1fLPhLyR54fGaY+7/X8P9AZzPefAkwizeXwe9ii6/a08vWoiE4=
-----END CERTIFICATE-----
非 PEM 內容可能會出現在 CERTIFICATE PEM 區塊之前或之後,並且未經過驗證,以允許 RFC7468 第 5.2 節中描述的說明文字。
當以 JSON 或 YAML 編碼時,此欄位會進行 base-64 編碼。包含上述範例憑證的 CertificateSigningRequest 看起來會像這樣
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JS..."
核准或拒絕
在簽署者根據 CertificateSigningRequest 簽發憑證之前,簽署者通常會檢查該 CSR 的簽發是否已核准。
控制平面自動核准
kube-controller-manager 隨附一個內建核准者,用於 signerName 為 kubernetes.io/kube-apiserver-client-kubelet
的憑證,該核准者將節點憑證的 CSR 上的各種權限委派給授權。kube-controller-manager 會將 SubjectAccessReview 資源 POST 到 API 伺服器,以便檢查憑證核准的授權。
使用 kubectl
核准或拒絕
Kubernetes 管理員(具有適當的權限)可以使用 kubectl certificate approve
和 kubectl certificate deny
命令手動核准(或拒絕)CertificateSigningRequests。
使用 kubectl 核准 CSR
kubectl certificate approve <certificate-signing-request-name>
同樣地,拒絕 CSR
kubectl certificate deny <certificate-signing-request-name>
使用 Kubernetes API 核准或拒絕
REST API 的使用者可以透過提交 UPDATE 請求到要核准的 CSR 的 approval
子資源來核准 CSR。例如,您可以編寫一個運算子,監看特定種類的 CSR,然後傳送 UPDATE 來核准它們。
當您發出核准或拒絕請求時,請根據您決定的狀態設定 Approved
或 Denied
狀態條件。
對於 Approved
CSR
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
conditions:
- lastUpdateTime: "2020-02-08T11:37:35Z"
lastTransitionTime: "2020-02-08T11:37:35Z"
message: Approved by my custom approver controller
reason: ApprovedByMyPolicy # You can set this to any string
type: Approved
對於 Denied
CSR
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
...
status:
conditions:
- lastUpdateTime: "2020-02-08T11:37:35Z"
lastTransitionTime: "2020-02-08T11:37:35Z"
message: Denied by my custom approver controller
reason: DeniedByMyPolicy # You can set this to any string
type: Denied
通常會使用 TitleCase 將 status.conditions.reason
設定為機器友善的原因代碼;這是一個慣例,但您可以將其設定為您喜歡的任何內容。如果您想為人類消費新增註解,請使用 status.conditions.message
欄位。
叢集信任同捆包
Kubernetes v1.27 [alpha]
ClusterTrustBundles 是一個叢集範圍的物件,用於將 X.509 信任錨點(根憑證)分發到叢集內的工作負載。它們旨在與 CertificateSigningRequests 的 簽署者概念良好協作。
ClusterTrustBundles 可以以兩種模式使用:簽署者連結和簽署者未連結。
通用屬性和驗證
所有 ClusterTrustBundle 物件對其 trustBundle
欄位的內容都有強驗證。該欄位必須包含一個或多個 X.509 憑證,DER 序列化,每個憑證都包裝在 PEM CERTIFICATE
區塊中。憑證必須解析為有效的 X.509 憑證。
深奧的 PEM 功能,例如區塊間資料和區塊內標頭,在物件驗證期間會被拒絕,或者可能會被物件的消費者忽略。此外,允許消費者使用他們自己任意但穩定的排序來重新排序同捆包中的憑證。
ClusterTrustBundle 物件應被視為在叢集內世界可讀。如果您的叢集使用 RBAC 授權,則所有 ServiceAccounts 都具有預設授權,允許他們取得、列出和 監看所有 ClusterTrustBundle 物件。如果您使用自己的授權機制,並且已在叢集中啟用 ClusterTrustBundles,則應設定等效規則,使這些物件在叢集中公開,以便它們按預期運作。
如果您預設沒有權限列出叢集信任同捆包,您可以模擬您有權存取的服務帳戶,以查看可用的 ClusterTrustBundles
kubectl get clustertrustbundles --as='system:serviceaccount:mynamespace:default'
簽署者連結的 ClusterTrustBundles
簽署者連結的 ClusterTrustBundles 與簽署者名稱相關聯,如下所示
apiVersion: certificates.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
name: example.com:mysigner:foo
spec:
signerName: example.com/mysigner
trustBundle: "<... PEM data ...>"
這些 ClusterTrustBundles 旨在由叢集中特定於簽署者的控制器維護,因此它們具有多個安全功能
- 若要建立或更新簽署者連結的 ClusterTrustBundle,您必須被允許對簽署者進行證明(自訂授權動詞
attest
,API 群組certificates.k8s.io
;資源路徑signers
)。您可以為特定資源名稱<signerNameDomain>/<signerNamePath>
設定授權,或比對模式(例如<signerNameDomain>/*
)。 - 簽署者連結的 ClusterTrustBundles 必須以從其
spec.signerName
欄位衍生的前綴命名。斜線 (/
) 會替換為冒號 (:
),並附加最終冒號。後面接著任意名稱。例如,簽署者example.com/mysigner
可以連結到 ClusterTrustBundleexample.com:mysigner:<arbitrary-name>
。
簽署者連結的 ClusterTrustBundles 通常會在工作負載中透過簽署者名稱上的欄位選取器和單獨的標籤選取器的組合來使用。
簽署者未連結的 ClusterTrustBundles
簽署者未連結的 ClusterTrustBundles 具有空的 spec.signerName
欄位,如下所示
apiVersion: certificates.k8s.io/v1alpha1
kind: ClusterTrustBundle
metadata:
name: foo
spec:
# no signerName specified, so the field is blank
trustBundle: "<... PEM data ...>"
它們主要用於叢集組態用例。每個簽署者未連結的 ClusterTrustBundle 都是一個獨立的物件,這與簽署者連結的 ClusterTrustBundles 的慣用分組行為相反。
簽署者未連結的 ClusterTrustBundles 沒有 attest
動詞要求。相反地,您可以使用常用的機制(例如基於角色的存取控制)直接控制對它們的存取。
為了將它們與簽署者連結的 ClusterTrustBundles 區分開來,簽署者未連結的 ClusterTrustBundles 的名稱不得包含冒號 (:
)。
從 Pod 存取 ClusterTrustBundles
Kubernetes v1.29 [alpha]
ClusterTrustBundles 的內容可以注入到容器檔案系統中,類似於 ConfigMaps 和 Secrets。請參閱clusterTrustBundle 投射卷宗來源以取得更多詳細資訊。
如何為使用者簽發憑證
需要幾個步驟才能讓一般使用者能夠驗證身分並調用 API。首先,此使用者必須擁有 Kubernetes 叢集簽發的憑證,然後將該憑證呈現給 Kubernetes API。
建立私密金鑰
以下腳本示範如何產生 PKI 私密金鑰和 CSR。設定 CSR 的 CN 和 O 屬性非常重要。CN 是使用者名稱,O 是此使用者將歸屬的群組。您可以參考 RBAC 以取得標準群組。
openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
建立 CertificateSigningRequest
建立 CertificateSigningRequest 並透過 kubectl 將其提交到 Kubernetes 叢集。以下是用於產生 CertificateSigningRequest 的腳本。
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser
spec:
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
EOF
需要注意的一些要點
usages
必須是 'client auth
'expirationSeconds
可以設定更長的時間(即864000
代表十天)或更短的時間(即3600
代表一小時)request
是 CSR 檔案內容的 base64 編碼值。您可以使用此命令取得內容cat myuser.csr | base64 | tr -d "\n"
核准 CertificateSigningRequest
使用 kubectl 建立 CSR 並核准它。
取得 CSR 清單
kubectl get csr
核准 CSR
kubectl certificate approve myuser
取得憑證
從 CSR 檢索憑證
kubectl get csr/myuser -o yaml
憑證值採用 Base64 編碼格式,位於 status.certificate
下。
從 CertificateSigningRequest 匯出已簽發的憑證。
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
建立角色和角色綁定
憑證建立完成後,就可以為此使用者定義角色和角色綁定,以存取 Kubernetes 叢集資源。
這是為此新使用者建立角色的範例命令
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
這是為此新使用者建立角色綁定的範例命令
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
新增至 kubeconfig
最後一步是將此使用者新增到 kubeconfig 檔案中。
首先,您需要新增新的憑證
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
然後,您需要新增內容
kubectl config set-context myuser --cluster=kubernetes --user=myuser
若要測試它,請將內容變更為 myuser
kubectl config use-context myuser
下一步
- 閱讀 在叢集中管理 TLS 憑證
- 檢視 kube-controller-manager 內建 簽署者的原始碼
- 檢視 kube-controller-manager 內建 核准者的原始碼
- 有關 X.509 本身的詳細資訊,請參閱 RFC 5280 第 3.1 節
- 有關 PKCS#10 憑證簽署請求語法的資訊,請參閱 RFC 2986
- 閱讀有關 ClusterTrustBundle API 的資訊