使用 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)。
設定為 "*" 的屬性將匹配相應屬性的任何值。
檢查屬性元組是否與策略檔案中的每個策略匹配。如果至少有一行匹配請求屬性,則請求被授權(但可能稍後驗證失敗)。
要允許任何已認證使用者執行操作,請編寫一個將 group 屬性設定為 "system:authenticated" 的策略。
要允許任何未認證使用者執行操作,請編寫一個將 group 屬性設定為 "system:unauthenticated" 的策略。
要允許使用者執行任何操作,請編寫一個將 apiGroup、namespace、resource 和 nonResourcePath 屬性設定為 "*" 的策略。
Kubectl
Kubectl 使用 apiserver 的 /api 和 /apis 端點來發現已服務的資源型別,並使用位於 /openapi/v2 的 schema 資訊驗證透過建立/更新操作傳送到 API 的物件。
使用 ABAC 授權時,這些特殊資源必須透過策略中的 nonResourcePath 屬性顯式暴露(請參閱下面的示例)
/api、/api/*、/apis和/apis/*用於 API 版本協商。/version用於透過kubectl version檢索伺服器版本。/swaggerapi/*用於建立/更新操作。
要檢查特定 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 的完全許可權,您將在策略檔案中新增此行
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
apiserver 將需要重啟才能載入新的策略行。