使用 CertificateSigningRequest 為 Kubernetes API 客戶端頒發證書

Kubernetes 允許你使用公鑰基礎設施 (PKI) 作為客戶端來對叢集進行身份驗證。

為了使普通使用者能夠進行身份驗證並呼叫 API,需要幾個步驟。首先,該使用者必須擁有由你的 Kubernetes 叢集信任的機構頒發的 X.509 證書。然後,客戶端必須將該證書呈現給 Kubernetes API。

你將使用 CertificateSigningRequest 作為此過程的一部分,並且你或一些其他主體必須批准該請求。

你將建立一個私鑰,然後獲得頒發的證書,最後為客戶端配置該私鑰。

準備工作

  • 你需要一個 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。建議在至少有兩個不是控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者你可以使用這些 Kubernetes 演練場中的一個。

  • 你需要 kubectlopensslbase64 實用程式。

本頁面假設你正在使用 Kubernetes 基於角色的訪問控制 (RBAC)。如果你有替代或額外的授權安全機制,也需要考慮到這些。

建立私鑰

在此步驟中,你將建立一個私鑰。你需要將此文件保密;任何擁有它的人都可以冒充該使用者。

# Create a private key
openssl genrsa -out myuser.key 3072

建立 X.509 證書籤名請求

重要的是要設定 CSR 的 CN 和 O 屬性。CN 是使用者的名稱,O 是該使用者所屬的組。你可以參考 RBAC 以瞭解標準組。

# Change the common name "myuser" to the actual username that you want to use
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"

建立 Kubernetes CertificateSigningRequest

使用此命令對 CSR 文件進行編碼

cat myuser.csr | base64 | tr -d "\n"

建立 CertificateSigningRequest 並透過 kubectl 提交到 Kubernetes 叢集。以下是可用於生成 CertificateSigningRequest 的 shell 片段。

cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser # example
spec:
  # This is an encoded CSR. Change this to the base64-encoded contents of myuser.csr
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
EOF

一些注意事項

  • usages 必須是 client auth
  • expirationSeconds 可以設定得更長(例如 864000 代表十天)或更短(例如 3600 代表一小時)。你不能請求短於 10 分鐘的持續時間。
  • request 是 CSR 檔案內容的 Base64 編碼值。

批准 CertificateSigningRequest

使用 kubectl 查詢你建立的 CSR,並手動批准它。

獲取 CSR 列表

kubectl get csr

批准 CSR

kubectl certificate approve myuser

獲取證書

從 CSR 中檢索證書,以檢查它是否正常。

kubectl get csr/myuser -o yaml

證書值在 .status.certificate 下是 Base64 編碼格式。

從 CertificateSigningRequest 中匯出頒發的證書。

kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt

將證書配置到 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

測試它

kubectl --context myuser auth whoami

你應該會看到確認你為“myuser”的輸出。

建立 Role 和 RoleBinding

建立證書後,是時候為該使用者定義 Role 和 RoleBinding 以訪問 Kubernetes 叢集資源了。

這是為這個新使用者建立 Role 的示例命令

kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods

這是為這個新使用者建立 RoleBinding 的示例命令

kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser

下一步

最後修改於 2025 年 3 月 4 日晚上 8:22 PST: 將客戶端證書的 CSR 移至任務部分 (2a3a72e16c)