服務賬號
此頁面介紹了 Kubernetes 中的 ServiceAccount 物件,提供有關服務賬戶如何工作、用例、限制、替代方案以及額外指導資源連結的資訊。
什麼是服務賬戶?
服務賬戶是一種非人類賬戶,在 Kubernetes 中,它在 Kubernetes 叢集中提供一個獨特的身份。應用程式 Pod、系統元件以及叢集內部和外部的實體可以使用特定 ServiceAccount 的憑據來標識為該 ServiceAccount。此身份在各種情況下都很有用,包括向 API 伺服器進行身份驗證或實施基於身份的安全策略。
服務賬戶作為 ServiceAccount 物件存在於 API 伺服器中。服務賬戶具有以下屬性:
名稱空間化: 每個服務賬戶都繫結到一個 Kubernetes 名稱空間。每個名稱空間在建立時都會獲得一個
default
ServiceAccount。輕量: 服務賬戶存在於叢集中,並在 Kubernetes API 中定義。你可以快速建立服務賬戶以啟用特定任務。
可移植: 複雜容器化工作負載的配置包可能包含系統元件的服務賬戶定義。服務賬戶的輕量級特性和名稱空間化的身份使配置具有可移植性。
服務賬戶與使用者賬戶不同,使用者賬戶是叢集中經過身份驗證的人類使用者。預設情況下,使用者賬戶不存在於 Kubernetes API 伺服器中;相反,API 伺服器將使用者身份視為不透明資料。你可以使用多種方法作為使用者賬戶進行身份驗證。一些 Kubernetes 發行版可能會新增自定義擴充套件 API 以在 API 伺服器中表示使用者賬戶。
描述 | ServiceAccount | 使用者或組 |
---|---|---|
位置 | Kubernetes API (ServiceAccount 物件) | 外部 |
訪問控制 | Kubernetes RBAC 或其他授權機制 | Kubernetes RBAC 或其他身份和訪問管理機制 |
預期用途 | 工作負載、自動化 | 人員 |
預設服務賬戶
當你建立一個叢集時,Kubernetes 會自動為叢集中的每個名稱空間建立一個名為 default
的 ServiceAccount 物件。在每個名稱空間中的 default
服務賬戶預設沒有許可權,除了在啟用基於角色的訪問控制 (RBAC) 時 Kubernetes 授予所有已認證主體的預設 API 發現許可權。如果你刪除了名稱空間中的 default
ServiceAccount 物件,控制平面 會用一個新的物件替換它。
如果你在名稱空間中部署一個 Pod,並且沒有手動為該 Pod 分配 ServiceAccount,Kubernetes 會將該名稱空間的 default
ServiceAccount 分配給該 Pod。
Kubernetes 服務賬戶的用例
作為一般準則,你可以在以下場景中使用服務賬戶來提供身份:
- 你的 Pod 需要與 Kubernetes API 伺服器通訊,例如在以下情況下:
- 提供對儲存在 Secrets 中的敏感資訊的只讀訪問。
- 授予跨名稱空間訪問許可權,例如允許
example
名稱空間中的 Pod 讀取、列出和監視kube-node-lease
名稱空間中的 Lease 物件。
- 你的 Pod 需要與外部服務通訊。例如,一個工作負載 Pod 需要一個商業雲 API 的身份,並且商業提供商允許配置適當的信任關係。
- 使用
imagePullSecret
向私有映象倉庫進行身份驗證. - 外部服務需要與 Kubernetes API 伺服器通訊。例如,作為 CI/CD 管道的一部分向叢集進行身份驗證。
- 你在叢集中使用第三方安全軟體,該軟體依賴不同 Pod 的 ServiceAccount 身份將這些 Pod 分組到不同的上下文中。
如何使用服務賬戶
要使用 Kubernetes 服務賬戶,你需要執行以下操作:
使用 Kubernetes 客戶端(如
kubectl
)或定義物件的清單建立 ServiceAccount 物件。使用授權機制(如 RBAC)向 ServiceAccount 物件授予許可權。
在 Pod 建立期間將 ServiceAccount 物件分配給 Pod。
如果你正在使用來自外部服務的身份,請檢索 ServiceAccount 令牌並從該服務中使用它。
有關說明,請參閱為 Pod 配置服務賬戶。
授予 ServiceAccount 許可權
你可以使用內建的 Kubernetes 基於角色的訪問控制 (RBAC) 機制,為每個服務賬戶授予所需的最小許可權。你建立一個授予訪問許可權的“角色”,然後將該角色“繫結”到你的 ServiceAccount。RBAC 允許你定義一組最小許可權,以便服務賬戶許可權遵循最小特權原則。使用該服務賬戶的 Pod 不會獲得超出正常執行所需的更多許可權。
有關說明,請參閱ServiceAccount 許可權。
使用 ServiceAccount 進行跨名稱空間訪問
你可以使用 RBAC 允許一個名稱空間中的服務賬戶對叢集中不同名稱空間中的資源執行操作。例如,假設你在 `dev` 名稱空間中有一個服務賬戶和一個 Pod,並且你希望你的 Pod 能夠檢視 `maintenance` 名稱空間中執行的 Job。你可以建立一個授予列出 Job 物件許可權的 Role 物件。然後,你將在 `maintenance` 名稱空間中建立一個 RoleBinding 物件,將該 Role 繫結到 ServiceAccount 物件。現在,`dev` 名稱空間中的 Pod 可以使用該服務賬戶列出 `maintenance` 名稱空間中的 Job 物件。
為 Pod 分配 ServiceAccount
要為 Pod 分配 ServiceAccount,你可以在 Pod 規約中設定 spec.serviceAccountName
欄位。然後 Kubernetes 會自動將該 ServiceAccount 的憑據提供給 Pod。在 v1.22 及更高版本中,Kubernetes 使用 TokenRequest
API 獲取一個短生命週期的、自動輪換的令牌,並將其作為投影卷掛載。
預設情況下,Kubernetes 會為 Pod 提供已分配 ServiceAccount 的憑據,無論是 default
ServiceAccount 還是你指定的自定義 ServiceAccount。
要阻止 Kubernetes 自動注入指定 ServiceAccount 或 default
ServiceAccount 的憑據,請將 Pod 規約中的 automountServiceAccountToken
欄位設定為 false
。
在 v1.22 之前的版本中,Kubernetes 將一個長期有效的靜態令牌作為 Secret 提供給 Pod。
手動檢索 ServiceAccount 憑據
如果你需要 ServiceAccount 憑據以掛載到非標準位置,或者用於非 API 伺服器的受眾,請使用以下方法之一:
- TokenRequest API(推薦):在你的“應用程式程式碼”中請求一個短生命週期的服務賬戶令牌。令牌會自動過期,並可在過期時輪換。如果你有一個不瞭解 Kubernetes 的傳統應用程式,你可以在同一個 Pod 中使用一個 sidecar 容器來獲取這些令牌並使其可用於應用程式工作負載。
- 令牌卷投影(也推薦):在 Kubernetes v1.20 及更高版本中,使用 Pod 規約指示 kubelet 將服務賬戶令牌作為“投影卷”新增到 Pod 中。投影令牌會自動過期,並且 kubelet 會在令牌過期之前輪換它。
- 服務賬戶令牌 Secret(不推薦):你可以將服務賬戶令牌作為 Kubernetes Secret 掛載到 Pod 中。這些令牌不會過期,也不會輪換。在 v1.24 之前的版本中,每個服務賬戶都會自動建立一個永久令牌。由於與靜態、長期憑據相關的風險,此方法不再推薦,尤其是在大規模使用時。LegacyServiceAccountTokenNoAutoGeneration 特性門(在 Kubernetes v1.24 到 v1.26 中預設啟用)阻止 Kubernetes 自動為 ServiceAccounts 建立這些令牌。該特性門在 v1.27 中被移除,因為它已升級為 GA 狀態;你仍然可以手動建立無限期的服務賬戶令牌,但應考慮其安全影響。
注意
對於在 Kubernetes 叢集外部執行的應用程式,你可能會考慮建立一個儲存在 Secret 中的長期 ServiceAccount 令牌。這允許身份驗證,但 Kubernetes 專案建議你避免這種方法。長期有效的持有者令牌存在安全風險,一旦洩露,令牌可能會被濫用。相反,請考慮使用替代方案。例如,你的外部應用程式可以使用受良好保護的私鑰“和”證書進行身份驗證,或者使用自定義機制,例如你自行實現的身份驗證 Webhook。
你還可以使用 TokenRequest 為外部應用程式獲取短期令牌。
限制對 Secret 的訪問(已棄用)
Kubernetes v1.32 [已棄用]
注意
自 Kubernetes v1.32 起,kubernetes.io/enforce-mountable-secrets
已棄用。請使用單獨的名稱空間來隔離對已掛載 Secret 的訪問。Kubernetes 提供了一個名為 kubernetes.io/enforce-mountable-secrets
的註解,你可以將其新增到 ServiceAccounts。當應用此註解時,ServiceAccount 的 Secret 只能掛載到指定型別的資源上,從而增強了叢集的安全態勢。
你可以使用清單向 ServiceAccount 添加註解:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubernetes.io/enforce-mountable-secrets: "true"
name: my-serviceaccount
namespace: my-namespace
當此註解設定為 "true" 時,Kubernetes 控制平面會確保此 ServiceAccount 的 Secret 受到某些掛載限制。
- 作為卷掛載到 Pod 中的每個 Secret 的名稱必須出現在 Pod 的 ServiceAccount 的
secrets
欄位中。 - 在 Pod 中使用
envFrom
引用的每個 Secret 的名稱也必須出現在 Pod 的 ServiceAccount 的secrets
欄位中。 - 在 Pod 中使用
imagePullSecrets
引用的每個 Secret 的名稱也必須出現在 Pod 的 ServiceAccount 的secrets
欄位中。
透過理解和執行這些限制,叢集管理員可以保持更嚴格的安全配置,並確保只有適當的資源才能訪問 Secret。
驗證服務賬戶憑據
ServiceAccount 使用簽名的 JSON Web Token (JWT) 向 Kubernetes API 伺服器以及存在信任關係的其他系統進行身份驗證。根據令牌的頒發方式(使用 TokenRequest
頒發的時間受限令牌,或使用 Secret 的傳統機制頒發),ServiceAccount 令牌可能還具有過期時間、受眾以及令牌“開始”有效的時間。當作為 ServiceAccount 執行的客戶端嘗試與 Kubernetes API 伺服器通訊時,客戶端會在 HTTP 請求中包含 Authorization: Bearer
頭部。API 伺服器按以下方式檢查該持有者令牌的有效性:
- 檢查令牌簽名。
- 檢查令牌是否已過期。
- 檢查令牌宣告中的物件引用當前是否有效。
- 檢查令牌當前是否有效。
- 檢查受眾宣告。
TokenRequest API 為 ServiceAccount 生成“繫結令牌”。此繫結與作為該 ServiceAccount 的客戶端(例如 Pod)的生命週期相關聯。有關繫結 Pod 服務賬戶令牌的 JWT 架構和負載示例,請參見令牌卷投影。
對於使用 TokenRequest
API 頒發的令牌,API 伺服器還會檢查正在使用 ServiceAccount 的特定物件引用是否存在,並透過該物件的唯一 ID 進行匹配。對於作為 Secret 掛載在 Pod 中的傳統令牌,API 伺服器會根據 Secret 檢查令牌。
有關身份驗證過程的更多資訊,請參閱身份驗證。
在你的程式碼中驗證服務賬戶憑據
如果你自己的服務需要驗證 Kubernetes 服務賬戶憑據,你可以使用以下方法:
- TokenReview API(推薦)
- OIDC 發現
Kubernetes 專案建議你使用 TokenReview API,因為此方法會在刪除繫結到 API 物件(如 Secrets、ServiceAccounts、Pods 或 Nodes)的令牌時立即使其失效。例如,如果你刪除了包含投影 ServiceAccount 令牌的 Pod,叢集會立即使該令牌失效,並且 TokenReview 會立即失敗。如果你改為使用 OIDC 驗證,你的客戶端會繼續將令牌視為有效,直到令牌達到其過期時間戳。
你的應用程式應始終定義其接受的受眾,並應檢查令牌的受眾是否與應用程式預期的受眾匹配。這有助於最大限度地縮小令牌的範圍,使其只能在你的應用程式中使用,而不能在其他地方使用。
替代方案
- 使用其他機制頒發自己的令牌,然後使用Webhook 令牌身份驗證來使用你自己的驗證服務驗證持有者令牌。
- 為 Pod 提供你自己的身份。
使用 SPIFFE CSI 驅動外掛以 X.509 證書對的形式向 Pod 提供 SPIFFE SVID.
🛇 此項鍊接到不屬於 Kubernetes 本身第三方專案或產品。更多資訊
- 無需使用服務賬戶令牌即可從叢集外部向 API 伺服器進行身份驗證
- 配置 API 伺服器以接受來自你的身份提供商的 OpenID Connect (OIDC) 令牌.
- 使用外部身份和訪問管理 (IAM) 服務(例如來自雲提供商)建立的服務賬戶或使用者賬戶,向你的叢集進行身份驗證。
- 將 CertificateSigningRequest API 與客戶端證書一起使用.
- 配置 kubelet 以從映象倉庫檢索憑據.
- 使用裝置外掛訪問虛擬可信平臺模組(TPM),然後允許使用私鑰進行身份驗證。
下一步
本頁面上的專案引用了提供 Kubernetes 所需功能的第三方產品或專案。Kubernetes 專案作者不對這些第三方產品或專案負責。有關詳細資訊,請參閱 CNCF 網站指南。
在提議新增額外第三方連結的更改之前,你應該閱讀內容指南。