翻譯:小君君

技術校對:星空下的文仔、bot

在專案中, Kubernetes 叢集會對 Kubernetes APIServer 的每個請求都進行身份驗證和授權管理。在此過程中,授權管理通常由 RBAC 授權模組來實現,但開發者也可以選擇其他元件,如 Open Policy Agent(OPA)。

本文從使用目的、設計方式以及示例演示闡述瞭如何利用 Webhook 授權模組使 OPA 實現高階授權策略。

使用動機

在一些專案中,我們希望為使用者提供類似叢集管理員的訪問許可權。

但為了確保基線的安全性和穩定性,我們不希望授予使用者完整的叢集管理員許可權。

例如:

我們允許使用者完全訪問除

kube-system

之外的所有 namespace,因為我們的基礎設施(例如監視和日誌記錄)部署在

kube-system

中;

我們希望強制執行 PodSecurityPolicy,不允許使用者以

root

的身份執行容器,也不允許使用者直接掛載

hostPath

卷。

面對這些要求,一種解決方案是透過 Kubernetes RBAC 和一個自定義運算子實現授權。

其基本思想是讓所有必要的許可權透過 RBAC RoleBindings 進行授予繫結。並且,除了

kube-system

(透過 operator)之外,我們為每個 namespace 的客戶提供了 ClusterRole

admin

。每當我們發現某些東西不能像預期那樣工作時,我們就會透過每個 namespace 角色或 ClusterRole 新增其他許可權。

但是,這種方式會出現很多針對特定用例的單獨規則。從長遠發展角度來看,這些規則無法得到很好的維護。

特別是在使用者群不斷增長的情況下,只要有人檢測到與配置不匹配的邊緣情況,調整角色不太可行。

綜上所述,我們不能選擇基於白名單的配置授權,而是需要切換到基於黑名單的模型。因為,我們真正想要的是為客戶提供叢集管理員訪問許可權,並限制某些特定許可權。

基於白名單與黑名單的授權

關於授權,絕大多數要求可以透過 Roles 和 RoleBindings 簡單地使用 RBAC 授權模組來實現 [1]。但 RBAC 在設計上僅限於白名單。即對於每個請求,它會選擇檢查其中的一個 Roles 和 RoleBindings 是否適用,然後批准請求。

請求只有在沒有匹配項時才會被拒絕,雖然聽起來限制不大,但一些特定用例需要更大的靈活性。例如:

當用戶想在除

kube-system

之外的所有 namespace 中建立/更新/刪除 Pod 時,透過 RBAC 實現此目的的唯一方法是在每個 namespace 的基礎上分配許可權。例如,我們可以部署 ClusterRole 和每個 namespace 的 RoleBinding。如果 namespace 隨時間而變化,則必須手動部署此 RoleBindings 或為它執行 operator;

當 Kubernetes 叢集提供預安裝的 StorageClass 時,使用者可能會想要擁有建立/更新/刪除自定義 StorageClass 的許可權。但他不應該有修改預安裝 StorageClass 的許可權。如果你想利用 RBAC 來實現,則使用者必須有權建立 StorageClass,並且一旦建立 StorageClass,就必須分配其他許可權以更新和刪除此 StorageClass。

如果你有很多這樣的用例,你就要透過運營商來實現很多自定義的邏輯,但是你需要知道這些用例可能不會被擴充套件。因為這樣做就會有很多的運營商和隨附的 RBAC 角色,我們將很難控制使用者實際擁有的權利。

下面,我們將展示如何透過 OPA 輕鬆實現上述兩種情況。

Webhook 授權模組與 ValidatingWebhook & MutatingWebhook

除了本文探討的情況,一些高階用例也可以透過 Dynamic Admission Control 實現,如 ValidatingWebhook 或 MutatingWebhook。這裡為大家推薦兩篇關於如何使用 OPA 的部落格:

Policy Enabled Kubernetes with Open Policy Agent

[2]以及

Kubernetes Compliance with Open Policy Agent

[3]。

動態准入控制具有以下限制:僅在 Kubernetes 資源上呼叫 Webhook 來建立、更新和刪除事件。

因此,它們不可能拒絕獲取的請求。但與 Webhook 授權模組相比,它們也具有優勢,因為它們可以根據 Kubernetes 資源的內容拒絕請求。這些是 Webhook 授權模組無法訪問的資訊。

作為參考,Webhook 授權模組由 SubjectAccessReviews 決定,而 ValidatingWebhook 和 MutatingWebhook 則由 AdmissionReviews 決定。在實踐中,我們透過授權模組和 MutatingWebhook 來整合 OPA。

設計

本節概述了 Kubernetes 如何與 OPA 整合。

由於 OPA 本身不能實現 Kubernetes 所需的 REST 介面,所以 Kubernetes Policy Controller 將 Kubernetes SubjectAccessReviews 和 AdmissionReviews 轉換為 OPA 查詢。

利用 Open Policy Agent 實現 K8S 授權

對於 Kubernetes API 伺服器收到的每個請求,執行以下序列:

請求已透過身份驗證;

基於透過認證提取的使用者資訊,授權請求:

呼叫 Webhook。在我們的例子中,Webhook 可以拒絕請求或將其轉為發給 RBAC。Kubernetes Webhook 也可以允許請求,但這在 Kubernetes Policy Controller 中無法實現;

執行 RBAC 模組。如果 RBAC 不允許該請求,則拒絕該請求;

如果請求導致持久性發生變化,例如建立/更新/刪除資源,則執行 Admission Controllers(MutatingWebhook 只是其中之一)。

因此,根據我們想要拒絕的具體內容,我們可以實施授權或許可 OPA 策略。有關如何配置此方案的更多資訊,請參見 open-policy-agent / kubernetes-policy-controller(授權方案[4])。

實現

本節將說明如何使用 OPA 實現上述用例。除 kube-system 之外,為每個 namespace 建立/更新/刪除 Pod。

它的基本思想是透過 RBAC 在叢集範圍內授予 Pod 的建立/更新/刪除許可權,然後使用 OPA 策略拒絕訪問 kube-system 中的 Pod。首先,我們授予

user

組建立/更新/刪除 Pod 的許可權:

kind

ClusterRole

apiVersion

rbac

authorization

k8s

io

/

v1

metadata

name

pods

rules

-

apiGroups

“”

resources

“pods”

verbs

“create”

“update”

“delete”

——-

kind

ClusterRoleBinding

apiVersion

rbac

authorization

k8s

io

/

v1

metadata

name

user

-

pods

subjects

-

kind

Group

name

user

apiGroup

rbac

authorization

k8s

io

roleRef

kind

ClusterRole

name

pods

apiGroup

rbac

authorization

k8s

io

現在,允許

user

組中每個使用者在叢集範圍內建立/更新/刪除 Pod。如有需要透過 OPA 限制這些許可權,請部署以下策略:

package

authorization

import

data

k8s

matches

deny

[{

“id”

“pods-kube-system”

“resource”

{

“kind”

kind

“namespace”

namespace

“name”

name

},

“resolution”

{

“message”

“Your‘re not allowed to create/update/delete pods in kube-system”

},

}]

{

matches

[[

kind

namespace

name

resource

]]

not

re_match

“^(system:kube-controller-manager|system:kube-scheduler)$”

resource

spec

user

resource

spec

resourceAttributes

namespace

=

“kube-system”

resource

spec

resourceAttributes

resource

=

“pods”

re_match

“^(create|update|delete|deletecollections)$”

resource

spec

resourceAttributes

verb

}

注意

排除

system:kube-controller-manager

system:kube-scheduler

,因為 Kubernetes 控制管理器和排程程式都必須能夠訪問 Pod。

resource。spec。resourceAttributes。resource =“pods” 如果刪除,我們就可以限制對

kube-system

中所有 namespace 資源的訪問。

OPA 使我們為所有策略編寫單元測試變得非常容易。有關更多資訊,請參閱如何測試策略[5]。

在特定 StorageClass 上執行建立/更新/刪除

在此示例中,我們要授予使用者對除

ceph

之外的所有 StorageClass 建立/更新/刪除許可權。與第一個示例一樣,我們必須透過 RBAC 授予使用者訪問許可權:

kind

ClusterRole

apiVersion

rbac

authorization

k8s

io

/

v1

metadata

name

storageclasses

rules

-

apiGroups

“storage。k8s。io”

resources

“storageclasses”

verbs

“create”

“update”

“delete”

——-

kind

ClusterRoleBinding

apiVersion

rbac

authorization

k8s

io

/

v1

metadata

name

user

-

storageclasses

subjects

-

kind

Group

name

user

apiGroup

rbac

authorization

k8s

io

roleRef

kind

ClusterRole

name

storageclasses

apiGroup

rbac

authorization

k8s

io

現在我們需要拒絕透過 OPA 訪問 StorageClass 的

ceph

,部署以下策略:

package

authorization

import

data

k8s

matches

deny

[{

“id”

“storageclasses”

“resource”

{

“kind”

kind

“namespace”

namespace

“name”

name

},

“resolution”

{

“message”

“Your’re not allowed to create/update/delete the StorageClass‘ceph’”

},

}]

{

matches

[[

kind

namespace

name

resource

]]

resource

spec

resourceAttributes

resource

=

“storageclasses”

resource

spec

resourceAttributes

name

=

“ceph”

re_match

“^(create|update|delete|deletecollections)$”

resource

spec

resourceAttributes

verb

}

你可以透過以下的方式進行策略的單元測試:

package

authorization

test_deny_update_storageclass_ceph

{

deny

[{

“id”

id

“resource”

{

“kind”

“storageclasses”

“namespace”

“”

“name”

“ceph”

},

“resolution”

resolution

}]

with

data

kubernetes

storageclasses

“”

]。

ceph

as

{

“kind”

“SubjectAccessReview”

“apiVersion”

“authorization。k8s。io/v1beta1”

“spec”

{

“resourceAttributes”

{

“verb”

“update”

“version”

“v1”

“resource”

“storageclasses”

“name”

“ceph”

},

“user”

“alice”

“group”

“user”

],

},

}

}

總結

總之,與內建 RBAC 授權相比,OPA 允許更靈活的策略,尤其是在不使用其他 operator 的情況下。在我看來,將 OPA 直接整合為授權模組和准入控制器會很好,但與此同時,Kubernetes Policy Controller 彌補了 Kubernetes 和 OPA 之間的差距。以下是我透過實踐得到的一些啟示:

拒絕訪問特定的 CustomResourceDefinitions,如

calico

拒絕訪問特定的 ClusterRoles,如

cluster-admin

admin

只允許埠轉發到

kube-system

中的某些特定 Pod;

建立一個對映,哪些 PodSecurityPolicies 可用於哪些 namespace ;

除了一些預安裝的配置,允許使用者訪問 ValidatingWebhookConfigurations。

以上就是本文的全部內容,你是如何看待 OPA 作為 Kubernetes 的策略引擎?如果感興趣,不妨在讀完本文後,親自動手進行嘗試!

參考文獻

1。

https://

kubernetes。io/docs/refe

rence/access-authn-authz/rbac/

2。

https://

medium。com/capital-one-

tech/policy-enabled-kubernetes-with-open-policy-agent-3b612b3f0203

3。

https://

itnext。io/kubernetes-co

mpliance-with-open-policy-agent-3d282179b1e9

4。

https://

github。com/open-policy-

agent/gatekeeper

5。

https://www。

openpolicyagent。org/doc

s/how-do-i-test-policies。html