在項目中, Kubernetes 集羣會對 Kubernetes APIServer 的每個請求都進行身份驗證和授權管理。在此過程中,授權管理通常由 RBAC 授權模塊來實現,但開發者也可以選擇其他組件,如 Open Policy Agent(OPA)。
關於授權,絕大多數要求可以通過 Roles 和 RoleBindings 簡單地使用 RBAC 授權模塊來實現 [1]。但 RBAC 在設計上僅限於白名單。即對於每個請求,它會選擇檢查其中的一個 Roles 和 RoleBindings 是否適用,然後批准請求。
如果你有很多這樣的用例,你就要通過運營商來實現很多自定義的邏輯,但是你需要知道這些用例可能不會被擴展。因為這樣做就會有很多的運營商和隨附的 RBAC 角色,我們將很難控制用戶實際擁有的權利。下面,我們將展示如何通過 OPA 輕鬆實現上述兩種情況。
除了本文探討的情況,一些高級用例也可以通過 Dynamic Admission Control 實現,如 ValidatingWebhook 或 MutatingWebhook。這裡為大家推薦兩篇關於如何使用 OPA 的博客:Policy Enabled Kubernetes with Open Policy Agent [2]以及 Kubernetes Compliance with Open Policy Agent [3]。
作為參考,Webhook 授權模塊由 SubjectAccessReviews 決定,而 ValidatingWebhook 和 MutatingWebhook 則由 AdmissionReviews 決定。在實踐中,我們通過授權模塊和 MutatingWebhook 來集成 OPA。
對於 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" : "Yourre 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" : "Yourre not allowed to create/update/delete the StorageClassceph" },
}] {
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
推薦閱讀: