使用 ABAC 授權
基於屬性的存取控制 (ABAC) 定義了一種存取控制範例,其中存取權限是透過使用結合屬性的原則授予使用者的。
原則檔案格式
若要啟用 ABAC
模式,請在啟動時指定 --authorization-policy-file=SOME_FILENAME
和 --authorization-mode=ABAC
。
檔案格式為每行一個 JSON 物件。不應有封閉的清單或地圖,每行只能有一個地圖。
每一行都是一個「原則物件」,其中每個物件都是一個具有以下屬性的地圖
- 版本控制屬性
apiVersion
,字串類型;有效值為 "abac.authorization.kubernetes.io/v1beta1"。允許原則格式的版本控制和轉換。kind
,字串類型:有效值為 "Policy"。允許原則格式的版本控制和轉換。
spec
屬性設定為具有以下屬性的地圖- 主體比對屬性
user
,字串類型;來自--token-auth-file
的使用者字串。如果您指定user
,則它必須與已驗證使用者的使用者名稱相符。group
,字串類型;如果您指定group
,則它必須與已驗證使用者的其中一個群組相符。system:authenticated
符合所有已驗證的請求。system:unauthenticated
符合所有未驗證的請求。
- 資源比對屬性
apiGroup
,字串類型;一個 API 群組。- 範例:
apps
、networking.k8s.io
- 萬用字元:
*
符合所有 API 群組。
- 範例:
namespace
,字串類型;一個命名空間。- 範例:
kube-system
- 萬用字元:
*
符合所有資源請求。
- 範例:
resource
,字串類型;資源類型- 範例:
pods
、deployments
- 萬用字元:
*
符合所有資源請求。
- 範例:
- 非資源比對屬性
nonResourcePath
,字串類型;非資源請求路徑。- 範例:
/version
或/apis
- 萬用字元
*
符合所有非資源請求。/foo/*
符合/foo/
的所有子路徑。
- 範例:
readonly
,布林值類型,當為 true 時,表示資源比對原則僅適用於 get、list 和 watch 操作,非資源比對原則僅適用於 get 操作。
- 主體比對屬性
注意
未設定的屬性與設定為其類型零值(例如,空字串、0、false)的屬性相同。但是,為了可讀性,應優先選擇未設定。
在未來,原則可能會以 JSON 格式表示,並透過 REST 介面進行管理。
授權演算法
請求具有與原則物件屬性對應的屬性。
當收到請求時,會判斷屬性。未知的屬性會設定為其類型的零值(例如,空字串、0、false)。
設定為 "*"
的屬性將符合對應屬性的任何值。
針對原則檔案中的每個原則檢查屬性元組是否符合。如果至少有一行符合請求屬性,則請求已授權(但稍後可能會驗證失敗)。
若要允許任何已驗證的使用者執行某些操作,請編寫一個原則,將群組屬性設定為 "system:authenticated"
。
若要允許任何未驗證的使用者執行某些操作,請編寫一個原則,將群組屬性設定為 "system:unauthenticated"
。
若要允許使用者執行任何操作,請編寫一個 policy,並將 apiGroup、namespace、resource 和 nonResourcePath 屬性設定為 "*"
。
Kubectl
Kubectl 使用 apiserver 的 /api
和 /apis
端點來探索提供的資源類型,並使用位於 /openapi/v2
的 schema 資訊來驗證透過 create/update 操作傳送至 API 的物件。
當使用 ABAC 授權時,這些特殊資源必須透過 policy 中的 nonResourcePath
屬性明確公開(請參閱下方的 範例)。
/api
、/api/*
、/apis
和/apis/*
用於 API 版本協商。/version
用於透過kubectl version
檢索伺服器版本。/swaggerapi/*
用於 create/update 操作。
若要檢查特定 kubectl 操作中涉及的 HTTP 呼叫,您可以提高詳細程度。
kubectl --v=8 version
範例
Alice 可以對所有資源執行任何操作
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
kubelet 可以讀取任何 pod
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}
kubelet 可以讀取和寫入事件
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
Bob 只能讀取 "projectCaribou" 命名空間中的 pod
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}
任何人都可以對所有非資源路徑發出唯讀請求
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}} {"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:unauthenticated", "readonly": true, "nonResourcePath": "*"}}
關於服務帳戶的快速注意事項
每個服務帳戶都有一個對應的 ABAC 使用者名稱,並且該服務帳戶的使用者名稱是根據命名慣例產生的。
system:serviceaccount:<namespace>:<serviceaccountname>
建立新的命名空間會導致以以下格式建立新的服務帳戶
system:serviceaccount:<namespace>:default
例如,如果您想使用 ABAC 授予預設服務帳戶(在 kube-system
命名空間中)對 API 的完整權限,您需要將此行新增至您的 policy 檔案中。
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
apiserver 需要重新啟動才能載入新的 policy 行。