V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
newmiao
V2EX  ›  Go 编程语言

OPA 进阶-分布式利器 Bundle

  •  
  •   newmiao · 2020-04-16 20:45:24 +08:00 · 1725 次点击
    这是一个创建于 1471 天前的主题,其中的信息可能已经有所发展或是发生改变。

    BundleOPA管理policydata的一种方式。

    OPA实现的轻量级策略引擎,一开始就是为了云原生环境的service提供解耦的策略服务,分布式是必然要考虑的问题。

    Bundle api的设计中,其实就全面考虑并体现了在分布式应用中如何更好的解耦策略引擎的管理。

    比如:

    • 如何做集中配置管理
    • 如何动态更新策略
    • 如何监控策略引擎节点的状态以及决策日志收集

    有了这些功能,再加上其高效的策略描述语言RegoOPA才真正称得上是云原生时代的通用策略引擎

    本文将带大家简单梳理一遍Bundle的组织方式、管理 api 、及监控方式。

    考虑到一次性过完不易消化,文末会提供一个直接可实操的docker-compose版本的demo,将全面覆盖本文细节

    建议大家看完本文,本机运行去体验一下,会有更直观的理解。

    文章目录

    • Bundle 文件组织方式
    • opa server api
    • Bundle 管理 api
    • Bundle 集成方式
      • opa server 方式
      • go lib 方式
    • Bundle 的监控
    • Bundle in action

    Bundle 文件组织方式

    下面我们先来看下Bundle的文件组织方式

    Bundle下的data,只能被识别data.jsondata.yaml的文件, 而其上边的目录会作为其数据前缀

    如下边roles/data.json (bundle/example作为一个bundle),会将data.json的数据挂在data.roles节点下

    cd bundle/example
    tree -a
    .
    ├── .manifest
    ├── bindings
    │   └── data.json
    ├── main.rego
    ├── rbac.rego
    └── roles
        └── data.json
    

    其中.manifest文件是Bundle的一个可选的元数据(metadata)配置文件

    cat .manifest
    {
      "revision" : "9f160bcd446bf50b1b17b570c322198a68d8e106",
      "roots": ["roles", "bindings","rbac","system"]
    }
    

    它的作用是声明Bundle的版本revision及其下的路径前缀(roots: path prefix

    roots不仅规定了Bundle应该有的路径前缀;在用Bundle api(后边会提到)更新文件时,也会按其规定的路径前缀来更新文件

    然后bundle也支持tarball格式加载到server

    例如opa run -b的方式指定Bundle

    cd bundle/example
    tar -czf bundle.tar.gz .
    opa run -b bundle.tar.gz
    

    Tips: 关于如何在交互式命令行里传递input。 之前非 bundle 使用 opa run quick-start repl.input:quick-start/input.json 到 bundle 格式时,就需要构建 repl/input/data.json 文件格式作为输入

    具体可以用时参考文档bundle-file-format

    opa server api

    在了解Bundle支持的管理 api 前,我们先看下opa server api

    主要 api 如下:

    | type | 用途 | | ---- | ---- | | Data api| 查询文档(能被输出的规则、虚拟文档等)| | Policy api| 查询策略| | Query api| 执行命令| | Compile api| 执行部分查询计算(partial evaluate query)| | Health api| 健康检查| | Metric api| 指标统计(prometheus格式)|

    下面我们以文档查询(Data) api 为例尝试下:

    我们先用之前quick-start的代码起一个opa sever

    opa run --server quick-start
    

    (注意:opa server api的路径前缀为/v1/, 对应的,查询 api 路径前缀为/v1/data/,)

    # 构造 input 输出请求
    cat <<EOF > v1-data-input.json
    {
        "input": $(cat quick-start/input.json)
    }
    EOF
    # 查询 example_rbac
    curl -s  http://0.0.0.0:8181/v1/data/example_rbac?pretty=true -d @v1-data-input.json
    
    {
      "result": {
        "allow": true,
        "role_has_permission": [
          "widget-reader"
        ],
        "user_has_role": [
          "widget-reader"
        ]
      }
    }
    

    Tips:不指定路径时,默认路径为data.system.main,这时输入不需要包裹在input key 内。 也可以使用--set--set-file 可以覆盖配置文件中的配置 opa run --server --set=default_decision=example_rbac/allow/ quick-start curl -s http://0.0.0.0:8181/ -d @quick-start/input.json

    而且 Data 查询也支持组合参数如explain,metrics,provenance等,详细查看文档,这里就不展开了。

    Bundle 管理 api

    Bundle为了在分布式系统中更好的展现 OPA 的威力,提供了四种 Api:

    • Bundles 用于策略分发,可以定时轮训更新Bundle
    • Decision Logs 定期上传日志包,支持按大小分片,开启后会有日志 id,决策日志可追溯
    • Status 定期上传服务状态,包含metrics等信息
    • Discovery 服务发现,可以用于集中管理OPABundle配置,各个节点下载定期同步配置后,按配置去更新Bundle

    如下图:

    management api

    这里举个带注释Bundle的四种接口配置例子

    (先扫一遍留个印象,具体使用时查看文档,后边会提供可实操的代码)

    # opa/config-bundle.yaml
    services:
      # 定义服务,支持多个
      - name: example_bundle
        url: http://demo-server:8888/
    
    labels:
      app: myapp
    
    bundles:
      # 定义 bundle, 支持多个
      authz:
        # bundle 所处的服务
        service: example_bundle
        # 这里指从 resource 处更新 bundle 文件包,即:
        # http://demo-server:8888/bundle/rbac.tar.gz
        resource: bundle/rbac.tar.gz
        polling:
          # 300~600s 间更新一次
          min_delay_seconds: 300
          max_delay_seconds: 600
    
    decision_logs:
      service: example_bundle
      # partition_name 为区分上传地址,会跟到 /logs 后, 即:
      # http://demo-server:8888/logs/bundle
      # 注意上传的是 gzip 日志文件
      partition_name: bundle
      reporting:
        min_delay_seconds: 30
        max_delay_seconds: 60
    
    status:
      service: example_bundle
      # 即 http://demo-server:8888/status/bundle
      partition_name: bundle
    
    # 默认查询路径
    default_decision: rbac/allow
    

    Bundle 集成方式

    这里我们简单过下集成方式

    opa server 方式

    运行方式很简单如下:

    opa run -s -a 0.0.0.0:8181 -c opa/config-bundle.yaml
    

    运行后,opa server 会根据配置自动拉取Bundle包:rbac.tar.gz

    下载成功后启动策略服务。同时定期上传决策日志和状态给服务端(即:demo-server:8888

    go lib 方式

    使用 lib github.com/open-policy-agent/opa/rego集成

    关键代码举例如下:

    // 构建查询,PrepareForEval 可重用
    var err error
    query, err := rego.New(
        rego.LoadBundle("./rbac.tar.gz"),
        rego.Query("x = data.rbac.allow"),
    ).PrepareForEval(context.Background())
    
    // 执行查询
    results, err := query.Eval(context.Background(), rego.EvalInput(input))
    if err != nil {
        fmt.Fatalln("Opa eval error:", err)
        return
    } else if len(results) == 0 {
        fmt.Fatalln("Opa eval error: no result")
        return
    }
    
    fmt.Println("Opa result:", results[0].Expressions[0].Value)
    

    具体组织方式官方推荐的有下边集中式分布式这两种:

    host-local

    distributed-enforcement

    推荐感兴趣的同学再去看下官方 go 集成的 demo: example-api-authz-go

    Bundle 的监控

    opa server 支持metrics, 而且是prometheus格式的

    所以配合prometheus可以直接进行对其数据指标的监控,如下图:

    prometheus

    再配合grafanadashbord可以更好的展示metrics数据,如下图:

    grafana

    Bundle in action

    上边说这么多,不实际试一下怎么知道Bundle究竟如何呢?

    这里提供一个docker-compose版的 demo 给大家去本地验证尝试

    里边提供了三种Bundle版本:

    • opa-bundle
    • opa-discovery
    • demo-sever (go lib 集成)

    也提供了两种版本的monitor

    • slim version
    • advance version

    代码见:NewbMiao/opa-koans/bundle

    里边有详细的操作文档,有问题可以在 Repo 里提 issue

    这个 Repo 包含了这一系列的OPA教程,欢迎感兴趣的同学 star 关注!

    同时我在知乎也建了一个OPA 技术圈,也欢迎大家参与讨论。

    好了,到此,OPA的基本教程就结束了。后边再抽空结合官方的例子写些实战教程吧。


    最后附上一个 Repo 中验证 Bundle 的过程,大家也可以从这里开始尝试哦

    scripts/bundleVerify.sh


    文章首发公众号:newbmiao

    推荐阅读:OPA 系列

    欢迎关注,获取及时更新内容

    2 条回复    2020-04-18 10:31:01 +08:00
    guonaihong
        1
    guonaihong  
       2020-04-16 20:52:52 +08:00
    Bundle 是 k8s 生态里的?
    newmiao
        2
    newmiao  
    OP
       2020-04-18 10:31:01 +08:00
    @guonaihong 进入了 CNCF 孵化项目,是 CNCF 生态下,可以看看这个声明: https://www.cncf.io/blog/2019/04/02/toc-votes-to-move-opa-into-cncf-incubator/
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   970 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:00 · PVG 04:00 · LAX 13:00 · JFK 16:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.