OPA-Gatekeeper实验:对特定用户的更新时间窗口做限制

OPA-Gatekeeper可以在Kubernetes 中,通过策略来实现一些额外的管理、安全方面的限制,例如:限制特定用户在 Namespace 中的行为权限

本次实验将在test命名空间内对开发人员的更新操作提供时间窗口限制

说明:
在自建的k8s集群实验成功。
在rancher2.4.4中创建失败,原因是rego语法解析错误,已经提交到官方论坛,尚未解决。

实现思路

为了方便管理,开发人员将使用统一用户deploy,
然后在k8s中添加基于角色的访问控制(RBAC),即使用role和rolebinding,限制deploy在test命名空间内的资源权限。
最后使用gatekeeper做时间窗口限制。

Namespace role user
test   manager   deploy  
实现步骤 1 创建用户

创建私钥

openssl genrsa -out deploy.key 2048

创建csr(证书签名请求)文件

openssl req -new -key deploy.key -out deploy.csr -subj "/CN=deploy/O=MGM"

通过集群的CA证书和deploy的csr文件,来为deploy颁发证书

我的CA证书是在/etc/kubernetes/pki/目录下

openssl x509 -req -in deploy.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out deploy.crt -days 3650

为用户配置credentials认证环境和context上下文环境

kubectl config set-credentials deploy --client-certificate=deploy.crt --client-key=deploy.key kubectl config get-users kubectl config set-context deploy --cluster=kubernetes --namespace=test --user=deploy kubectl config get-contexts

测试切换用户环境

kubectl config use-context deploy kubectl config use-context kubernetes-admin@kubernetes 2 创建角色

在RBAC中,角色有两种——普通角色(Role)和集群角色(ClusterRole),ClusterRole是特殊的Role:

Role属于某个命名空间,而ClusterRole属于整个集群,其中包括所有的命名空间

ClusterRole能够授予集群范围的权限,比如node资源的管理,比如非资源类型的接口请求(如"/health"),比如可以请求全命名空间的资源(通过指定 --all-namespaces)

这里要在test命名空间内创建一个权限小的普通角色

kind: Role metadata: namespace: test name: manager rules: - apiGroups: ["apps"] resources: ["*"] verbs: ["*"] - apiGroups: [""] resources: ["pods"] verbs: ["*"] kubectl apply -f role.yaml kubectl get role -n test

以上涉及的api资源查看方式:

kubectl api-resources|grep "apps/v1" kubectl api-resources|grep " v1" 3 将前面的角色和用户绑定 kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: manager-binding namespace: test subjects: - kind: User name: deploy roleRef: kind: Role name: manager apiGroup: "rbac.authorization.k8s.io" kubectl apply -f Rolebinding.yaml kubectl get rolebinding -n test

测试deploy用户创建pod

kubectl get pods -n test --context=deploy kubectl run nginx --image=nginx:latest -n default --context=deploy kubectl run nginx --image=nginx:latest -n test --context=deploy 5 安装gatekeeper wget https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml kubectl apply -f gatekeeper.yaml

检查

kubectl get ConstraintTemplate #等待出现 No resources found 才表示成功 kubectl get crd #CustomResourceDefinitions #只有当AGE不为<Invalid>而是一个时间时,才表示这个资源对象可用 ConstraintTemplate 约束模板

在定义约束之前,必须先定义一个 ConstraintTemplate (相当于创造了自定义的api-resources类型)
它主要内容描述的是 执行约束的Rego语句 和 约束的模式。

约束的模式允许admin对约束行为进行微调,就像对一个函数传参。

spec由两部分组成:
- crd:CustomResourceDefinition 自定义资源
- targets:一组target,是以 rego 代码块为主体

实验

以下模板提供了时间窗口限制(每周一、三,晚23:30至次日06:00)

apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: updatelimits spec: crd: spec: names: kind: UpdateLimits targets: - target: admission.k8s.gatekeeper.sh rego: | package updatelimit ###TIME check nanosec := time.now_ns() wday := time.weekday(nanosec) dhour :=time.clock(nanosec)[0] dmin :=time.clock(nanosec)[1] ###userAuth Check #ns := input.review.object.metadata.namespace uname := input.review.userInfo.username # 23:30至次日06:00,要考虑 k8s 的8h时差 timeOK { dhour==15 dmin>=30 } timeOK { dhour>15 dhour<22 } weekdayOK{ wday == "Wednesday" } weekdayOK{ wday == "Monday" } #三种不同情况下的限制提示 violation[{"msg": msgX}] { uname != "deploy" msgX = "\n>>>>>>>>>>>>>>>>>>>>>>>>>> Changes are only allowed for USER [deploy].\n" } violation[{"msg": msgX}] { uname == "deploy" not weekdayOK msgX = "\n%%%%%%%%%%%%%%%%%%%%%%%%%% Changes are only allowed on [Monday] or [Wednesday].\n" } violation[{"msg": msgX}] { uname == "deploy" weekdayOK not timeOK msgX = "\n************************** Changes are only allowed in [23:30-06:00].\n" } # kubectl apply -f constrainttemplateV1Beta1.yaml # kubectl get ConstraintTemplate # kubectl api-resources |grep gatekeeper NAME SHORTNAMES APIVERSION NAMESPACED KIND updatelimits constraints.gatekeeper.sh/v1beta1 false UpdateLimits 注意项

spec.crd.spec.names.kind 小写后必须和 metadata.name 一致

violation返回值是一个结构体切片:[{"msg": STRING}]

violation[{"msg": message}] { message := "" } Constraint 约束条件 知识介绍(可以略过)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxxxz.html