实验目的

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 创建用户

  1. 创建私钥
  1. openssl genrsa -out deploy.key 2048
  1. 创建csr(证书签名请求)文件
  1. openssl req -new -key deploy.key -out deploy.csr -subj "/CN=deploy/O=MGM"
  1. 通过集群的CA证书和deploy的csr文件,来为deploy颁发证书

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

  1. openssl x509 -req -in deploy.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out deploy.crt -days 3650
  1. 为用户配置credentials认证环境和context上下文环境
  1. kubectl config set-credentials deploy --client-certificate=deploy.crt --client-key=deploy.key
  2. kubectl config get-users
  3. kubectl config set-context deploy --cluster=kubernetes --namespace=test --user=deploy
  4. kubectl config get-contexts
  1. 测试切换用户环境
  1. kubectl config use-context deploy
  2. kubectl config use-context kubernetes-admin@kubernetes

2 创建角色

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

  • Role属于某个命名空间,而ClusterRole属于整个集群,其中包括所有的命名空间
  • ClusterRole能够授予集群范围的权限,比如node资源的管理,比如非资源类型的接口请求(如"/health"),比如可以请求全命名空间的资源(通过指定 --all-namespaces)

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

  1. kind: Role
  2. metadata:
  3. namespace: test
  4. name: manager
  5. rules:
  6. - apiGroups: ["apps"]
  7. resources: ["*"]
  8. verbs: ["*"]
  9. - apiGroups: [""]
  10. resources: ["pods"]
  11. verbs: ["*"]
  1. kubectl apply -f role.yaml
  2. kubectl get role -n test

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

  1. kubectl api-resources|grep "apps/v1"
  2. kubectl api-resources|grep " v1"

3 将前面的角色和用户绑定

  1. kind: RoleBinding
  2. apiVersion: rbac.authorization.k8s.io/v1
  3. metadata:
  4. name: manager-binding
  5. namespace: test
  6. subjects:
  7. - kind: User
  8. name: deploy
  9. roleRef:
  10. kind: Role
  11. name: manager
  12. apiGroup: "rbac.authorization.k8s.io"
  1. kubectl apply -f Rolebinding.yaml
  2. kubectl get rolebinding -n test

测试deploy用户创建pod

  1. kubectl get pods -n test --context=deploy
  2. kubectl run nginx --image=nginx:latest -n default --context=deploy
  3. kubectl run nginx --image=nginx:latest -n test --context=deploy

5 安装gatekeeper

  1. wget https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml
  2. kubectl apply -f gatekeeper.yaml

检查

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

ConstraintTemplate 约束模板

在定义约束之前,必须先定义一个 ConstraintTemplate (相当于创造了自定义的api-resources类型)

它主要内容描述的是 执行约束的Rego语句 和 约束的模式。

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

spec由两部分组成:

- crd:CustomResourceDefinition 自定义资源

- targets:一组target,是以 rego 代码块为主体

实验

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

  1. apiVersion: templates.gatekeeper.sh/v1beta1
  2. kind: ConstraintTemplate
  3. metadata:
  4. name: updatelimits
  5. spec:
  6. crd:
  7. spec:
  8. names:
  9. kind: UpdateLimits
  10. targets:
  11. - target: admission.k8s.gatekeeper.sh
  12. rego: |
  13. package updatelimit
  14. ###TIME check
  15. nanosec := time.now_ns()
  16. wday := time.weekday(nanosec)
  17. dhour :=time.clock(nanosec)[0]
  18. dmin :=time.clock(nanosec)[1]
  19. ###userAuth Check
  20. #ns := input.review.object.metadata.namespace
  21. uname := input.review.userInfo.username
  22. # 23:30至次日06:00,要考虑 k8s 的8h时差
  23. timeOK {
  24. dhour==15
  25. dmin>=30
  26. }
  27. timeOK {
  28. dhour>15
  29. dhour<22
  30. }
  31. weekdayOK{
  32. wday == "Wednesday"
  33. }
  34. weekdayOK{
  35. wday == "Monday"
  36. }
  37. #三种不同情况下的限制提示
  38. violation[{"msg": msgX}] {
  39. uname != "deploy"
  40. msgX = "\n>>>>>>>>>>>>>>>>>>>>>>>>>> Changes are only allowed for USER [deploy].\n"
  41. }
  42. violation[{"msg": msgX}] {
  43. uname == "deploy"
  44. not weekdayOK
  45. msgX = "\n%%%%%%%%%%%%%%%%%%%%%%%%%% Changes are only allowed on [Monday] or [Wednesday].\n"
  46. }
  47. violation[{"msg": msgX}] {
  48. uname == "deploy"
  49. weekdayOK
  50. not timeOK
  51. msgX = "\n************************** Changes are only allowed in [23:30-06:00].\n"
  52. }
  1. # kubectl apply -f constrainttemplateV1Beta1.yaml
  2. # kubectl get ConstraintTemplate
  3. # kubectl api-resources |grep gatekeeper
  4. NAME SHORTNAMES APIVERSION NAMESPACED KIND
  5. updatelimits constraints.gatekeeper.sh/v1beta1 false UpdateLimits

注意项

  1. spec.crd.spec.names.kind 小写后必须和 metadata.name 一致
  2. violation返回值是一个结构体切片:[{"msg": STRING}]
  1. violation[{"msg": message}] {
  2. message := ""
  3. }

Constraint 约束条件

知识介绍(可以略过)

Constraint负责通知Gatekeeper,admin想要一个什么样的template

Constraint使用 K8sRequiredLabels 来约束上文中的模版,以便于确保 gatekeeper 标签被定义到所有namespace上

可认为是对某一个 ConstraintTemplate 的实例化,其中对 ConstraintTemplate 的未指定参数进行了具体的配置。

注意spec.match字段,它定义了 一个指定的约束 将要被应用到的 目标的范围

Note the match field, which defines the scope of objects to which a given constraint will be applied.

支持的匹配项目:

  • kinds:接受一个对象列表,包含 apiGroups和 kinds,用来指定 约束将应用到的 对象组/种类的字段。如果指定了多个对象,只要满足其中一个就会被匹配

    only one match is needed for the resource to be in scope.
  • 目标范围:允许 * ,Cluster 或者 Namespaced

此外还有:

  • namespaces:指定ns列表
  • excludedNamespaces:指定ns排除列表
  • labelSelector
  • namespaceSelector

注意:

如果定义了多个matcher,则匹配资源必须满足所有顶级matcher

空matcher匹配所有

namespaces, excludedNamespaces, 和 namespaceSelector 将会匹配上没有ns所属的资源,为了避免这种情况,注意指定Namespace范围。

实验

  1. apiVersion: constraints.gatekeeper.sh/v1beta1
  2. kind: UpdateLimits
  3. metadata:
  4. name: updatelimit-for-test
  5. spec:
  6. match:
  7. namespaces: ["test"]
  8. kinds:
  9. - apiGroups: ["apps"]
  10. kinds:
  11. - "Deployment"
  12. - "DaemonSet"
  13. - "StatefulSet"

部署

  1. kubectl apply -f ConstraintV1Beta1.yaml
  2. kubectl get constraint

测试deployment

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. creationTimestamp: null
  5. name: nginx
  6. namespace: depl
  7. spec:
  8. replicas: 0
  9. selector:
  10. matchLabels:
  11. io/os: linux
  12. template:
  13. metadata:
  14. labels:
  15. io/os: linux
  16. spec:
  17. containers:
  18. - image: nginx:latest
  19. name: nginx

shell脚本:

  1. #!/bin/sh
  2. deployFile=nginx-deployment.yaml
  3. echo
  4. echo
  5. echo
  6. kubectl config use-context deploy
  7. kubectl apply -f ${deployFile} -n depl && kubectl delete -f ${deployFile} -n depl
  8. echo -e "\n\n\n"
  9. kubectl config use-context kubernetes-admin@kubernetes

实验结果:

  1. root@master:~/OPAtest/MyTest# ./test.sh
  2. Switched to context "deploy".
  3. Error from server ([updatelimit-for-depl]
  4. %%%%%%%%%%%%%%%%%%%%%%%%%% Changes are only allowed on [Monday] or [Wednesday].
  5. ): error when creating "nginx-deployment.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [updatelimit-for-depl]
  6. %%%%%%%%%%%%%%%%%%%%%%%%%% Changes are only allowed on [Monday] or [Wednesday].

参考资料:

  1. 用户与角色绑定:https://zhuanlan.zhihu.com/p/43237959
  2. Input对象:https://www.openpolicyagent.org/docs/latest/kubernetes-primer/#input-document
  3. 时间函数:https://www.openpolicyagent.org/docs/latest/policy-reference/#time
  4. rego实验室:https://play.openpolicyagent.org/

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

  1. 关于iOS特定设别推送(特定用户推送)【原】

    在这里,我就不哆嗦如何制作推送证书之类的了,网上一搜一大堆. 我们现在很多开发者的推送,就是集成第三方的推送SDK,然后通过第三方的推送平台帮我们进行推送.其实,这种推送(如JPush),一般只能广播 ...

  2. PHP处理大数据量老用户头像更新的操作--解决数据量大超时的问题

    /** * @title 老用户头像更新--每3秒调用一次接口,每次更新10条数据 * @example user/createHeadPicForOldUser? * @method GET * @ ...

  3. day108:MoFang:首页检测用户是否登录&在项目中使用MongoDB&用户页面更新用户信息&交易密码界面实现

    目录 1.首页页面也要检测用户是否登录 2.在flask中使用MongoDB 3.用户页面更新用户信息 4.交易密码界面/密码修改界面/昵称修改界面初始化 5.交易密码实现 1.首页页面也要检测用户是 ...

  4. 【】二次通告--Apache log4j-2.15.0-rc1版本存在绕过风险,请广大用户尽快更新版本

    [转载自360众测] Apache Log4j2是一个基于Java的日志记录工具.该工具重写了Log4j框架,并且引入了大量丰富的特性.我们可以控制日志信息输送的目的地为控制台.文件.GUI组件等,通 ...

  5. 通过自定义特性,使用EF6拦截器完成创建人、创建时间、更新人、更新时间的统一赋值(使用数据库服务器时间赋值,接上一篇)

    目录: 前言 设计(完成扩展) 实现效果 扩展设计方案 扩展后代码结构 集思广益(问题) 前言: 在上一篇文章我写了如何重建IDbCommandTreeInterceptor来实现创建人.创建时间.更 ...

  6. 自动化部署与统一安装升级 - 类ansible工具 udeploy0.3版本发布 (更新时间2014-12-24)

    下载地址:  unifyDeploy0.1版本  unifyDeploy0.2版本     unifyDeploy0.3版本 (更新时间2014-07-25)   自动化部署与统一安装升级,适用于多资 ...

  7. MYSQL 更新时间自动同步与创建时间默认值共存问题

    本文作者:苏生米沿 本文地址:http://blog.csdn.net/sushengmiyan/article/details/50326259 在使用SQL的时候,希望在更新数据的时候自动填充更新 ...

  8. Dynamics CRM 插件Plugin中获取和更新时间字段值的准确转换

    前面两篇介绍了后台代码通过组织服务获取更新时间字段.窗体javascript通过Odata获取更新时间字段,最后篇来实验下在插件中的获取和更新时间字段是否需要时制的转化,为何说是最后篇呢,因为在CRM ...

  9. mysql自动更新时间

    ALTER TABLE sys_user MODIFY COLUMN update_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDAT ...

随机推荐

  1. NOIP 模拟八 考试总结

    T1星际旅行 给出n个点,m条边,求满足一条路径使得m-2条边经过2次,2条边经过1次的方案数.并且题目中给出有自环. 看到题面我以为是个计数DP,可能是计数题做多了吧哈哈.其实仔细朝图的方向想一想就 ...

  2. Win32窗口框架

    Win32窗口框架 WindowClass 单例,负责窗口初始化注册和取消注册: 负责提供静态方法: 放在Window类内部,方便初始化时,wndProc(HandleMsgSetup)的赋值: cl ...

  3. SPA测试

    1.生产端:环境准备为了进行SPA测试,在生产数据库中创建了SPA测试专用用户,避免与其他用户相互混淆与可能产生的误操作. CREATE USER SPA IDENTIFIED BY SPA DEFA ...

  4. 从零入门 Serverless | SAE 场景下,应用流量的负载均衡及路由策略配置实践

    作者 | 落语 阿里云云原生技术团队 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 S ...

  5. gin 集成 consul

    "github.com/hashicorp/consul/api" package initialize import ( "fmt" "github ...

  6. LinkedList-常用方法以及双向链表的理解

    链表 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括两 ...

  7. 【转】简述C和C++的学习历程

    简述C和C++的学习历程(转) --by:肖舸老师总是被同学们问到,如何学习C和C++才不茫然,才不是乱学,想了一下,这里给出一个总的回复. 一家之言,欢迎拍砖哈. 1.可以考虑先学习C. 大多数时候 ...

  8. 3.3 Execution Flow of a DDD Based Application 基于DDD的应用程序执行流程

    3.3 Execution Flow of a DDD Based Application 基于DDD的应用程序执行流程 The figure below shows a typical reques ...

  9. Object.create 和 Object.assign

    Object.assign(target, ...source) 1.Object.assign方法只会拷贝源对象自身(不包括原型)的并且可枚举的属性到目标对象,使用源对象的get和目标对象的set, ...

  10. SpringCloud-SpringBoot-SpringCloudAlibaba对应版本选择

    一.SpringCloud-SpringBoot 对应的版本选择 SpringCloud官网常规方式只能查看最新的几个版本信息 https://spring.io/projects/spring-cl ...