Open Policy Agent(OPA) 入门实践

2023-10-30 03:30
文章标签 实践 入门 open agent policy opa

本文主要是介绍Open Policy Agent(OPA) 入门实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是张晋涛。

本篇我来为你介绍一个我个人很喜欢的,通用策略引擎,名叫 OPA,全称是 Open Policy Agent。

在具体聊 OPA 之前,我们先来聊一下为什么需要一个通用策略引擎,以及 OPA 解决了什么问题。

OPA 解决了什么问题

在实际的生产环境中很多场景中都需要策略控制,比如:

  • 需要策略控制用户是否可登陆服务器或者做一些操作;

  • 需要策略控制哪些项目/哪些组件可进行部署;

  • 需要策略控制如何访问数据库;

  • 需要策略控制哪些资源可部署到 Kubernetes 中;

ca518dcdc9c9480e467157ad57aba8f1.png
img

但是对于这些场景或者软件来说,配置它们的策略是需要与该软件进行耦合的,彼此是不统一,不通用的。管理起来也会比较混乱,带来了不小的维护成本。

OPA 的出现可以将各处配置的策略进行统一,极大的降低了维护成本。以及将策略与对应的软件/服务进行解耦,方便进行移植/复用。

f63613d95f97f0260fc8ce8a8726e65d.png
img

OPA 的发展过程

OPA 最初是由 Styra 公司在 2016 年创建并开源的项目,目前该公司的主要产品就是提供可视化策略控制及策略执行的可视化 Dashboard 服务的。

OPA 首次进入 CNCF 并成为 sandbox 级别的项目是在 2018 年, 在 2021 年的 2 月份便已经从 CNCF 毕业,这个过程相对来说还是比较快的,由此也可以看出 OPA 是一个比较活跃且应用广泛的项目。

OPA 是什么

前面我们已经介绍过 Open Policy Agent (OPA) 是一种开源的通用策略引擎,可在整个堆栈中实现统一、上下文感知的策略控制。

OPA 可将策略决策与应用程序的业务逻辑分离(解耦),透过现象看本质,策略就是一组规则,请求发送到引擎,引擎根据规则来进行决策。

7c50072c1a8d105729985348de3b4c7a.png
img

图 3 ,OPA 的策略解耦示例

OPA 并不负责具体任务的执行,它仅负责决策,需要决策的请求通过 JSON 的方式传递给 OPA ,在 OPA 决策后,也会将结果以 JSON 的形式返回。

Rego

OPA 中的策略是以 Rego 这种 DSL(Domain Specific Language) 来表示的。

Rego 受 Datalog(https://en.wikipedia.org/wiki/Datalog) 的启发,并且扩展了 Datalog 对于结构化文档模型的支持,方便以 JSON 的方式对数据进行处理。

Rego 允许策略制定者可以专注于返回内容的查询而不是如何执行查询。同时 OPA 中也内置了执行规则时的优化,用户可以默认使用。

Rego 允许我们使用规则(if-then)封装和重用逻辑,规则可以是完整的或者是部分的。

每个规则都是由头部和主体组成。在 Rego 中,如果规则主体对于某些变量赋值为真,那么我们说规则头为真。可以通过绝对路径引用任何加载到 OPA 中的规则来查询它的值。规则的路径总是:data..(规则生成的所有值都可以通过全局 data 变量进行查询。例如,下方示例中的 data.example.rules.any_public_networks

  • 完整规则是将单个值分配给变量的 if-then 语句。

ba2afa518447f1c4e7e4c71dcf03b6b9.png
img

图 4 ,Rego 完整规则示例

  • 部分规则是生成一组值并将该组分配给变量的 if-then 语句。

89dddd4c6445fe744362136bbaca2f13.png
img

图 5 ,Rego 部分规则示例

  • 逻辑或是要在 Rego 中定义多个具有相同名称的规则。(查询中将多个表达式连接在一起时,表示的是逻辑 AND)

b77af52e4f574da39eb82fe017437557.png
img

图 6 ,Rego 规则或的完全规则和部分规则示例图

OPA 的使用

OPA 的使用还是比较简单的,我们来看一下。

安装 OPA

二进制方式

我们可以直接从 OPA 的 release 页面下载其二进制进行使用

➜  ~ wget -q -O ~/bin/opa https://github.com/open-policy-agent/opa/releases/download/v0.35.0/opa_linux_amd64_static 
➜  ~ chmod +x ~/bin/opa
➜  ~ opa version
Version: 0.35.0
Build Commit: a54537a
Build Timestamp: 2021-12-01T02:11:47Z
Build Hostname: 9e4cf671a460
Go Version: go1.17.3
WebAssembly: unavailable

容器

我们可以使用其官方镜像

➜  ~ docker run --rm  openpolicyagent/opa:0.35.0 version    
Version: 0.35.0
Build Commit: a54537a
Build Timestamp: 2021-12-01T02:10:31Z
Build Hostname: 4ee9b086e5de
Go Version: go1.17.3
WebAssembly: available

OPA 交互

opa eval

最简单的命令是  opa eval ,当然我们除了能使用它进行策略的执行外,还可以用来做表达式计算。

6a4d808eca3975c2d62a3859bd82c758.png
img

图 7 , opa eval 的使用帮助

➜  ~ opa eval "6+6"
{"result": [{"expressions": [{"value": 12,"text": "6+6","location": {"row": 1,"col": 1}}]}]
}

opa run

opa run 会启动一个交互式 shell ( REPL) 。我们可以使用 REPL 来试验策略并构建新的原型。

➜  ~ opa run
OPA 0.35.0 (commit a54537a, built at 2021-12-01T02:11:47Z)Run 'help' to see a list of commands and check for updates.> true
true
> ["Hello", "OPA"]
["Hello","OPA"
]
> pi := 3.14
Rule 'pi' defined in package repl. Type 'show' to see rules.
> show
package replpi := 3.14
> pi > 1
true

我们也可以将策略直接加载进去,或者 将 OPA 作为一个服务运行并通过 HTTP 执行查询。默认情况下,OPA 会监听在 8181 端口。

➜  ~ opa run --server
{"addrs":[":8181"],"diagnostic-addrs":[],"level":"info","msg":"Initializing server.","time":"2021-12-07T01:12:47+08:00"}

打开浏览器也可以看到一个简单的查询窗口

12e367aaddb57ea74d153e819f639a0c.png
img

opa 作为 go 的库使用

OPA 可以作为库嵌入到 Go 程序中。将 OPA 嵌入为库的最简单方法是导入 github.com/open-policy-agent/opa/rego 包。通过 rego.New 函数用来创建一个可以准备或评估的对象, PrepareForEval() 以获取可执行查询。

以下是一个简单的示例:

  • 目录结构

➜  opa tree 
.
├── data
├── go.mod
├── go.sum
├── input.json
├── k8s-label.rego
└── main.go1 directory, 5 files
  • 策略文件

这里的策略文件是来校验 INPUT 中是否包含名为 domain 的 label , 以及该 label 是否以 moelove-开头。

package kubernetes.validating.existencedeny[msg] {not input.request.object.metadata.labels.domainmsg := "Every resource must have a domain label"
}deny[msg] {value := input.request.object.metadata.labels.domainnot startswith(value, "moelove-")msg := sprintf("domain label must start with `moelove-`; found `%v`", [value])
}
  • INPUT 文件, 以 Kubernetes 的 AdmissionReview 为例

{"kind": "AdmissionReview","request": {"kind": {"kind": "Pod","version": "v1"},"object": {"metadata": {"name": "myapp","labels": {"domain": "opa"}},"spec": {"containers": [{"image": "alpine","name": "alpine"}]}}}
}
  • main.go 文件

package mainimport ("context""encoding/json""fmt""log""os""github.com/open-policy-agent/opa/rego"
)func main() {ctx := context.Background()// Construct a Rego object that can be prepared or evaluated.r := rego.New(rego.Query(os.Args[2]),rego.Load([]string{os.Args[1]}, nil))// Create a prepared query that can be evaluated.query, err := r.PrepareForEval(ctx)if err != nil {log.Fatal(err)}// Load the input document from stdin.var input interface{}dec := json.NewDecoder(os.Stdin)dec.UseNumber()if err := dec.Decode(&input); err != nil {log.Fatal(err)}rs, err := query.Eval(ctx, rego.EvalInput(input))if err != nil {log.Fatal(err)}fmt.Println(rs)
}

执行结果如下:

➜  opa go run main.go k8s-label.rego "data" < input.json
[{[map[kubernetes:map[validating:map[existence:map[deny:[domain label must start with `moelove-`; found `opa`]]]]]] map[]}]

总结

以上便是对于 OPA 的一个大致介绍,OPA 的应用场景有很多,后续文章中将为大家分享 OPA 在 Kubernetes 中的应用,和将 OPA 应用与 CI/CD pipeline 的场景。敬请期待。

这篇关于Open Policy Agent(OPA) 入门实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/305309

相关文章

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

Ollama整合open-webui的步骤及访问

《Ollama整合open-webui的步骤及访问》:本文主要介绍如何通过源码方式安装OpenWebUI,并详细说明了安装步骤、环境要求以及第一次使用时的账号注册和模型选择过程,需要的朋友可以参考... 目录安装环境要求步骤访问选择PjrIUE模型开始对话总结 安装官方安装地址:https://docs.

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

Spring Boot统一异常拦截实践指南(最新推荐)

《SpringBoot统一异常拦截实践指南(最新推荐)》本文介绍了SpringBoot中统一异常处理的重要性及实现方案,包括使用`@ControllerAdvice`和`@ExceptionHand... 目录Spring Boot统一异常拦截实践指南一、为什么需要统一异常处理二、核心实现方案1. 基础组件

SpringBoot项目中Maven剔除无用Jar引用的最佳实践

《SpringBoot项目中Maven剔除无用Jar引用的最佳实践》在SpringBoot项目开发中,Maven是最常用的构建工具之一,通过Maven,我们可以轻松地管理项目所需的依赖,而,... 目录1、引言2、Maven 依赖管理的基础概念2.1 什么是 Maven 依赖2.2 Maven 的依赖传递机

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬