Kubernetes 身份驗證確保只有授權使用者和服務才能存取叢集資源。文章詳細介紹 OIDC 和 Webhook 兩種驗證方法,並解析其運作流程與組態引數。OIDC 透過第三方身份提供者驗證使用者,Webhook 則透過外部服務驗證 Token。理解這兩種機制有助於提升 Kubernetes 叢集的安全性。
Kubernetes 身份驗證機制詳解:OIDC 與 Webhook 認證流程
Kubernetes 提供了多種身份驗證機制,其中 OpenID Connect(OIDC)與 Webhook 認證是兩種常見且重要的驗證方式。本文將探討這兩種機制的運作原理、組態方法及其在實際應用中的考量。
OIDC 身份驗證流程
OIDC 是一種根據 OAuth 2.0 的身份驗證協定,它允許使用者透過第三方身份提供者進行身份驗證。以下是 OIDC 認證流程的詳細步驟:
- 使用者身份驗證:使用者向 Kubernetes API 伺服器發起身份驗證請求,並被重定向到身份提供者進行驗證。
- 取得授權碼:使用者在身份提供者處完成驗證後,獲得一個授權碼。
- 交換令牌:使用者使用授權碼向身份提供者請求身份令牌(ID Token)和重新整理令牌(Refresh Token)。
- 組態 kubeconfig:使用者將獲得的身份令牌新增到
kubeconfig組態檔案中。 - API 請求認證:當使用者使用
kubectl發起 Kubernetes API 請求時,kubectl會自動將身份令牌作為 Bearer Token 新增到請求中。 - 令牌驗證:Kubernetes API 伺服器接收到請求後,會向身份提供者驗證令牌的有效性。
- 請求處理:如果令牌驗證成功,API 伺服器會允許請求繼續執行。
OIDC 組態引數
要啟用 OIDC 身份驗證,需要在 Kubernetes API 伺服器上組態以下引數:
--oidc-issuer-url:身份提供者的 URL。--oidc-client-id:客戶端 ID。--oidc-username-claim(可選):用於指定使用者名稱的 Claim,預設為sub。--oidc-group-claim(可選):用於指定使用者群組的 Claim,預設為groups。
# 示例命令列引數
--oidc-issuer-url=https://auth.example.com
--oidc-client-id=dTBlg7xO7dks1uG6Op976jC7TjUZDCDz
--oidc-username-claim=username
--oidc-group-claim=groups
JWT 令牌結構解析
OIDC 使用 JSON Web Token(JWT)作為身份令牌。JWT 包含多個 Claim,用於描述使用者的屬性。以下是一個 JWT 令牌的示例:
{
"iss": "https://auth.example.com",
"sub": "Ch5hdXRoMHwMTYzOTgzZTdjN2EyNWQxMDViNjESBWF1N2Q2",
"aud": "dTBlg7xO7dks1uG6Op976jC7TjUZDCDz",
"exp": 1517266346,
"iat": 1517179946,
"at_hash": "OjgZQ0vauibNVcXP52CtoQ",
"username": "user",
"email": "user@example.com",
"email_verified": true,
"groups": [
"qa",
"infrastructure"
]
}
內容解密:
此 JWT 令牌包含了多個重要的 Claim,如 iss(發行者)、sub(主體)、exp(過期時間)、username 和 groups。這些 Claim 用於描述使用者的身份和屬性,並在 Kubernetes API 伺服器進行身份驗證時使用。
Webhook 認證流程
Webhook 認證是一種允許 Kubernetes API 伺服器與外部認證服務進行互動的機制。以下是 Webhook 認證的詳細步驟:
- 提取 Bearer Token:API 伺服器從收到的請求中提取 Bearer Token。
- 傳送 TokenReview 請求:API 伺服器向認證服務傳送一個包含 Bearer Token 的
TokenReview請求。 - 驗證 Token:認證服務驗證 Bearer Token 的有效性。
- 傳回驗證結果:認證服務傳回一個
TokenReview回應,指示 Token 是否有效。
TokenReview 請求與回應
以下是 TokenReview 請求和回應的示例:
# 請求
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"spec": {
"token": "some-bearer-token-string"
}
}
# 成功回應
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": {
"authenticated": true,
"user": {
"username": "janedoe@example.com",
"uid": "42",
"groups": [
"developers",
"qa"
]
}
}
}
# 失敗回應
{
"apiVersion": "authentication.k8s.io/v1beta1",
"kind": "TokenReview",
"status": {
"authenticated": false
}
}
內容解密:
Webhook 認證允許 Kubernetes 與外部認證服務進行整合,提供更大的靈活性。在 TokenReview 請求中,API 伺服器將 Bearer Token 傳送給認證服務。認證服務驗證 Token 後,傳回一個指示 Token 是否有效的回應。如果 Token 有效,回應中還會包含使用者的詳細資訊,如使用者名稱、UID 和所屬群組。
Kubernetes 驗證與使用者管理深度解析
Kubernetes 的驗證機制是確保叢集安全性的關鍵組成部分。API 伺服器負責處理所有請求,而驗證服務則提供指導,決定是否允許或拒絕 Kubernetes API 請求。
Token-Based 驗證機制的效能瓶頸
大多數根據 token 的驗證機制都需要額外的請求和回應來驗證 token。例如,OIDC 和 webhook 驗證都需要額外的往返時間來驗證 token。如果身份提供者回應不及時,這可能會成為 API 請求的效能瓶頸。因此,選擇低延遲和高效能的提供者至關重要。
Dex:Kubernetes 的 OIDC 代理
當現有的驗證服務無法滿足需求時,Dex 是一個值得考慮的解決方案。Dex 是 CoreOS 的一個專案,提供了一個標準的 OIDC 前端,支援多種常見的後端,包括 LDAP、Active Directory、SQL、SAML 和 SaaS 提供者,如 GitHub、GitLab 和 LinkedIn。Dex 使得將 Kubernetes 與現有的身份管理系統整合變得更加容易。
多重驗證機制的組態
Kubernetes 叢集可以同時啟用多個驗證機制。這種組態在除錯失敗的次要 API 驗證機制時非常有用。例如,可以同時組態 TLS 使用者端憑證和 OIDC 驗證。當多個驗證外掛程式同時啟用時,第一個成功驗證使用者的外掛程式將會短路驗證程式。
kubeconfig:Kubernetes 的組態檔案
kubeconfig 檔案記錄瞭如何驗證 Kubernetes API 請求的詳細資訊。kubectl 使用這個組態檔案來決定傳送請求到 API 伺服器的位置和方法。這個檔案通常位於 ~/.kube/config,但也可以透過 --kubeconfig 引數或 KUBECONFIG 環境變數來指定。
kubeconfig 的結構
kubeconfig 檔案有三個頂層結構:users、clusters 和 contexts。
users定義了使用者名稱和驗證機制。clusters提供了連線到叢集所需的資訊,包括 API 伺服器的 IP 或完整網域名稱。contexts將使用者與叢集關聯起來,形成一個單一的命名實體。
管理 kubeconfig
可以使用 kubectl 命令來管理 kubeconfig 檔案。以下是一些範例命令:
$ export KUBECONFIG=mykubeconfig
$ kubectl config set-credentials cluster-admin --username=admin --password=somepassword
$ kubectl config set-credentials regular-user --username=user --password=someotherpassword
$ kubectl config set-cluster cluster1 --server=https://10.1.1.3
$ kubectl config set-cluster cluster2 --server=https://192.168.1.50
$ kubectl config set-context cluster1-admin --cluster=cluster1 --user=cluster-admin
$ kubectl config set-context cluster1-regular --cluster=cluster1 --user=regular-user
$ kubectl config set-context cluster2-regular --cluster=cluster2 --user=regular-user
$ kubectl config view
kubeconfig 的內容
apiVersion: v1
clusters:
- cluster:
server: https://10.1.1.3
name: cluster1
- cluster:
server: https://192.168.1.50
name: cluster2
contexts:
- context:
cluster: cluster1
user: cluster-admin
name: cluster1-admin
- context:
cluster: cluster1
user: regular-user
name: cluster1-regular
- context:
cluster: cluster2
user: regular-user
name: cluster2-regular
current-context: ""
kind: Config
preferences: {}
users:
- name: cluster-admin
user:
password: somepassword
username: admin
- name: regular-user
user:
password: someotherpassword
username: user
重點解析
- Kubernetes 的驗證機制對於確保叢集安全性至關重要。
- Token-Based 驗證機制需要額外的請求和回應來驗證 token,可能會成為效能瓶頸。
- Dex 提供了一個標準的 OIDC 前端,支援多種常見的後端,是整合 Kubernetes 與現有身份管理系統的一個好選擇。
- 可以同時啟用多個驗證機制,以提高除錯的便利性。
kubeconfig檔案記錄了驗證 Kubernetes API 請求的詳細資訊,是kubectl的重要組態檔案。
Kubernetes 身份驗證與服務帳戶管理
Kubernetes 提供了靈活的身份驗證機制,讓使用者能夠安全地與叢集互動。在本章中,我們將探討 Kubernetes 的身份驗證機制,包括使用者身份驗證和服務帳戶的管理。
使用者身份驗證與 Context 設定
Kubernetes 允許使用者透過多種方式進行身份驗證,例如 X.509 使用者端憑證、靜態權杖檔案和認證代理等。為了簡化叢集管理,Kubernetes 引入了 context 的概念,將叢集、使用者和名稱空間的組態進行組合,從而實作快速切換。
$ kubectl config use-context cluster2-regular
Switched to context "cluster2-regular".
這使得在不同叢集之間切換,或者在同一個叢集中模擬不同使用者變得非常簡單。使用者可以根據自己的需求建立多個 context,並透過簡單的命令進行切換。
服務帳戶(Service Accounts)
除了使用者身份驗證外,Kubernetes 還提供了服務帳戶(Service Accounts)來管理 Pod 內部程式對 API 的存取。服務帳戶是一種名稱空間級別的使用者帳戶,用於為 Pod 提供身份驗證。
建立服務帳戶
$ kubectl create sa testsa
$ kubectl get sa testsa -oyaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: testsa
namespace: default
secrets:
- name: testsa-token-nr6md
當建立服務帳戶時,Kubernetes 會自動建立一個 Secret,其中包含用於身份驗證的權杖。這個權杖會被掛載到 Pod 中的一個已知位置,供 Kubernetes 使用者端使用。
服務帳戶的應用
每個 Pod 都會關聯一個服務帳戶,如果在 Pod 清單中沒有指定,則會使用預設的服務帳戶。預設服務帳戶在名稱空間建立時自動建立。
apiVersion: v1
kind: Pod
metadata:
name: testpod
spec:
serviceAccountName: testpod-sa
JWT 權杖解析
服務帳戶使用的 JWT 權杖包含了多個 Claims,用於識別服務帳戶的相關資訊。
{
"iss": "kubernetes/serviceaccount",
"kubernetes.io/serviceaccount/namespace": "default",
"kubernetes.io/serviceaccount/secret.name": "testsa-token-nr6md",
"kubernetes.io/serviceaccount/service-account.name": "testsa",
"kubernetes.io/serviceaccount/service-account.uid": "23fe204f-0f66-11e8-85d0-080027da173d",
"sub": "system:serviceaccount:default:testsa"
}
安全考量
雖然服務帳戶為 Pod 提供了存取 Kubernetes API 的能力,但在某些場景下,從安全的角度來看,為 Pod 提供 API 存取許可權可能並不合適。我們將在後續章節中探討如何對這些使用案例進行安全強化。
Kubernetes 授權機制
在 Kubernetes 中,API 請求的安全驗證包含三個主要步驟:驗證(Authentication)、授權(Authorization)和准入控制(Admission Control)。本章將重點介紹授權機制的運作原理及其在 Kubernetes 中的重要性。
RESTful API 與資源操作
Kubernetes API 是一個 RESTful API,其設計簡單且具擴充套件性。RESTful API 的核心概念是透過動詞(Verbs)來操作資源(Resources)。例如,當我們請求取得一個 Pod 的資訊時,實際上是發送了一個 GET 請求到特定的資源路徑。
kubectl 請求分析
透過增加 -v 選項來提高日誌級別,我們可以觀察到 kubectl 在背後傳送的 API 請求細節:
$ kubectl -v=6 get po testpod
I0202 00:28:31.933993 17487 loader.go:357] Config loaded from file /home/ubuntu/.kube/config
I0202 00:28:31.994930 17487 round_trippers.go:436] GET https://10.0.0.1:6443/api/v1/namespaces/default/pods/testpod 200 OK
在這個例子中,kubectl 發送了一個 GET 請求來取得 testpod 的資訊。這裡的 GET 是動詞,而 pods/testpod 是資源。
RESTful 動詞與 Kubernetes 資源操作
RESTful API 中常見的四個基本動詞是:Create、Read、Update 和 Delete(CRUD),分別對應到 HTTP 的 POST、GET、PUT 和 DELETE 方法。在 Kubernetes 中,除了這四個基本動詞外,還支援 list、watch、proxy、redirect 和 deletecollection 等動詞來操作資源。
授權機制
驗證使用者身份後,下一步是授權,即判斷使用者是否有許可權執行特定的操作。Kubernetes 的授權機制由 API 伺服器負責,並透過 --authorization-mode 引數來組態不同的授權模組。
授權模組
目前 Kubernetes 支援多個授權模組,包括:
- AlwaysAllow 和 AlwaysDeny:這兩個模組分別無條件允許或拒絕所有請求,主要用於測試環境。
- Node:該模組負責限制工作節點(kubelet)對 API 伺服器的存取許可權,確保 kubelet 只能執行必要的操作。
- RBAC(Role-Based Access Control):根據角色的存取控制,是目前最為靈活和強大的授權機制,能夠在執行時動態定義存取控制策略。
RBAC 詳解
RBAC 允許管理員透過定義角色(Roles)和角色繫結(RoleBindings)來精細控制使用者對 Kubernetes 資源的存取許可權。這種機制避免了粗粒度許可權控制的問題,使得安全性和靈活性得到了提升。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Kubernetes 身份驗證與授權機制詳解
package "Kubernetes Cluster" {
package "Control Plane" {
component [API Server] as api
component [Controller Manager] as cm
component [Scheduler] as sched
database [etcd] as etcd
}
package "Worker Nodes" {
component [Kubelet] as kubelet
component [Kube-proxy] as proxy
package "Pods" {
component [Container 1] as c1
component [Container 2] as c2
}
}
}
api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2
note right of api
核心 API 入口
所有操作經由此處
end note
@enduml此圖示展示了 Kubernetes 中一個請求的處理流程,從驗證到授權再到准入控制的完整過程。
內容解密:
此圖表闡述了 Kubernetes 處理 API 請求的流程。首先,使用者發出請求到 Kubernetes API。接著,系統進行驗證,確認使用者的身份。如果驗證透過,則進入授權階段。在授權階段,RBAC 模組檢查使用者的角色和許可權。如果允許,則進入准入控制階段;如果拒絕,則傳回 HTTP 403 Forbidden 錯誤。