前言
在实际生产环境中,许多场景需要进行策略控制,例如,不同团队的API需要限制访问权限,以避免未经授权的网络访问。为实现这种控制,可以采用策略控制的方法。然而,实施策略控制需要修改代码,而且策略通常很分散。为了解决这个问题,可以使用OPA(Open Policy Agent)进行策略控制。
OPA 可以通过定义的策略查询输入数据,并生成决策。例如:
OPA简介及原理
OPA 是什么
OPA(Open Policy Agent)是一个开源的通用策略引擎,由 Styra 公司于2016年创建并开源,目前已是 CNCF 的毕业项目。其主要功能是将策略决策与应用程序的业务逻辑分离,将策略看作一组规则。请求被发送到引擎后,引擎会根据规则来进行决策。OPA 并不负责具体任务的执行,它仅负责决策。请求通过 JSON 方式传递给 OPA,决策结果也以 JSON 的形式返回。OPA将策略配置统一到一处,极大地降低维护成本,并将策略与对应的软件/服务解耦,方便进行移植和复用。
OPA 策略
OPA 中的策略是以 Rego 这种DSL(Domain Specific Language)来表示的。每个规则都是由头部和主体组成。在 Rego 中,如果规则主体对于某些变量赋值为真,那么我们说规则头为真。可以通过绝对路径引用任何加载到 OPA 中的规则来查询它的值。规则的路径总是:data.PACKAGE.RULE (规则生成的所有值都可以通过全局 data 变量进行查询) 。如果有多个规则相同,则一旦匹配到一个为true的规则,就为true。下面的案例中有具体代码,可在后面的章节详细了解rego编写。
OPA 原理
OPA 将策略执行与决策解耦。当软件需要做出决策时,它向OPA 查询并提供结构化数据(例如JSON)作为输入。其工作原理如下图所示:
如何使用OPA
案例一:OPA 实现API权限控制
如果要实现放行角色为admin的用户请求,并且所有人都能够访问路径为/public的GET类型的API,我们可以探究一下OPA 如何实现这个需求:
文件名: policy.rego
文件名: input.json
文件名: policy_test.rego
如下命令使用input.json
文件来验证是否能满足policy.rego
文件中的data.policy.allow
规则。
附:如只想查看最终结果,可加上--format raw
参数,输出如下
opa run
会启动一个交互式 shell ( REPL) 。我们可以使用 REPL 来试验策略和构建策略。
“读取-求值-输出” 循环(Read-Eval-Print Loop,简称REPL)
我们也可以将策略直接加载进去,或者将 OPA 作为一个服务运行并通过 HTTP 执行查询。默认情况下,OPA 监会监听在 8181 端口。
打开postman访问 OPA server, postman信息如下
下图中的请求何满足策略规则呢?
上图请求表示,使用OPA Server中policy包中的allow规则校验该请求。
该策略中仅允许roles是admin的用户执行操作,查看我们postman中body数据,得知roles是developer,顾这条策略不满足,OPA会继续查看其他策略。
该策略中仅允许request path是/public
开头且请求方法是GET
的请求, 满足我们postman中的request内容,顾该请求满足策略要求。
案例二:OPA在Kubernetes中的使用案例
由于OPA应用到Kubernetes中时,需要较多的Kubernetes基础,这里想淡化对Kubernetes基础的要求,所以使用Gatekeeper来集成Kubernetes。
Gatekeeper是一个开源的使用OPA来定义和执行策略的系统
下文将实现不允许在default namespace中部署deployment资源的案例。
文件名:template.yaml
文件名:constraint.yaml
文件名nginx-app.yaml
尝试创建资源的时候,会出现如下报错,因为OPA策略中已经指定,不允许在default namespace中创建deployment资源。
创建demo namespace,并尝试在该namespace中创建deployment资源,可成功创建。
总结
本文分享自 ThoughtWorks洞见 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!