策略即代码:为了 OpenPolicyAgent 学 Rego?试试 Javascript

策略即代码:为了 OpenPolicyAgent 学 Rego?试试 Javascript

距离上个版本 用 Pipy 实现 OPA,已经过去快半年了。当初使用Pipy 实现了可信镜像仓库的检查,那时的版本实现起来会稍微复杂,从策略仓库到证书创建到Admission Webhook 的创建都需要大量的人工操作,配置和逻辑也还是耦合在一起。

这个版本安装和使用起来会更加简单。

当初我用“不务正业”来形容 Pipy 实现准入控制,等看完这篇文章,欢迎留言说说你的看法。

架构

还是继续上次的场景,在 Pod 创建时对 Pod 使用的镜像所在仓库进行检查,以及检查镜像的 tag 是否合法

Untitled

这里借助 Pipy Repo 的能力,将代表策略的脚本和配置交由 Repo 进行管理;Pipy 实例实时从 Pipy Repo 同步策略,并进行动态加载

同时 Pipy Repo 对外提供 REST API 来管理策略,对策略的修改更容易。也方便与企业现有管理后台进行对接。

下面就开始部署验证,这里所使用的所有代码都已提交到 GitHub 仓库:https://github.com/flomesh-io/demo-policy-as-code。

运行

git clone https://github.com/flomesh-io/demo-policy-as-code.git
cd demo-policy-as-code

准备

环境

使用 Kubernetes 发行版 K3s 作为集群环境,集群的搭建不做过多说明。我用 k3d

k3d cluster create policy-as-code -p "6060:30060@server:0"

注:K3d 是在容器中运行 K3s,这里做了将容器的 30060 端口映射到本地的 6060 端口,后面会详细解释。

部署策略服务器

执行下面的命令部署策略服务器 Repo:

kubectl apply -f repo/pipy-repo.yaml

确保 Pod 正常运行:

kubectl get po -n pipy
NAME                              READY   STATUS        RESTARTS   AGE
pipy-repo-697bbd9f4b-94pld        1/1     Running       0          10s

发布策略

要使用的策略(脚本和配置)位于 ./repo/scripts 目录中。前面提到 Repo 提供了 REST API 来管理 codebase(策略)。

这里提供了脚本 init-codebase.sh,通过 curl 命令将策略发布到策略服务器。

./init-codebase.sh

部署策略引擎

这个版本中,使用 helm chart 完成证书的创建、服务的部署以及 Admission WebHook 的注册。

helm install policy-as-code ./policy-as-code -n default

确保 Pod 正常运行:

kubectl get po -n pipy
NAME                              READY   STATUS    RESTARTS   AGE
pipy-repo-697bbd9f4b-94pld        1/1     Running   0          2m
policy-as-code-5867f9cdb9-9vwks   1/1     Running   0          8s

测试

./test 目录中有三个 yaml 文件用于测试。

非法的镜像仓库:

kubectl apply -f test/bad.yaml

Error from server (192.168.64.1:5000/hello-world:linux repo not start with any repo [docker.io, k8s.gcr.io]): error when creating "test/bad.yaml": admission webhook "validating-webhook.pipy.flomesh-io.cn" denied the request: 192.168.64.1:5000/hello-world:linux repo not start with any repo [docker.io, k8s.gcr.io]

非法的镜像 tag:

kubectl apply -f test/bad2.yaml

Error from server (docker.io/library/hello-world:latest tag end with :latest): error when creating "test/bad2.yaml": admission webhook "validating-webhook.pipy.flomesh-io.cn" denied the request: docker.io/library/hello-world:latest tag end with :latest

合法的镜像

kubectl apply -f test/ok.yaml

pod/hello-world-success created

就这么结束了?当然没有,我们还要对策略进行动态的调整。

继续下面的测试之前,执行 kubectl delete -f test/ok.yaml 清理刚才创建的 Pod。

修改策略

修改 ./repo/scripts/config.json文件,清空 invalidTagSuffixes 数组中的内容。

{
  "validRepoPrefixes": [
    "docker.io",
    "k8s.gcr.io"
  ],
  "invalidTagSuffixes": []
}

**注意:**这里需要执行脚本 ./init-codebase.sh 更新策略。

此时,再次尝试 apply test/bad2.yaml。你会发现,这次 Pod 创建成功了。

kubectl apply -f test/bad2.yaml
pod/hello-world-bad-tag created

我们没有修改任何逻辑代码,仅仅修改了配置就完成了对 Pod 镜像检查逻辑的调整。可能有人会问,命令行太麻烦调试不方便,有没有更直观的方式?

答案是:有!

图形用户界面

Pipy Repo 提供了图形用户界面,方便脚本的开发和调试。详细信息可以参考快速入门 Pipy Repo,了解图形用户界面的使用。

还记得开头的地方我们为 K3d 容器做了端口映射:6060=>30060,细心的你也可能发现我们为 Pipy Repo 创建了 NodePort Servce,node port 端口为 30060

此时,本地启动一个 Pipy:

#k3d
pipy http://localhost:6060 --admin-port=6061
#主机直接部署 k3s 请使用这条命令
pipy http://localhost:30060 --admin-port=6061

在浏览器中打开 http://localhost:6060,你会看到:

点击下面我们创建的 codebase /image-verify,在左侧文件目录中可以找到我们修改后的 config.json:

在编辑器中编辑,改回原来的配置,然后点击 2 和 3 两个按钮

2021-12-08 at 00.36.59

再次测试

#清理
kubectl delete -f test/bad2.yaml

kubectl apply -f test/bad2.yaml
Error from server (docker.io/library/hello-world:latest tag end with :latest): error when creating "test/bad2.yaml": admission webhook "validating-webhook.pipy.flomesh-io.cn" denied the request: docker.io/library/hello-world:latest tag end with :latest

可以看到,修改的结果体现在错误信息里了。

总结

Open Policy Agent (OPA) 为策略引擎带来了新的天地,但是使用 Rego 语言编写策略为使用带来了门槛。Pipy 以其流量编程、易扩展的特性结合 Repo 的 codebase 管理,可以轻松实现策略即代码。同时,资源消耗更少,性能更高(代理场景的特点)。

comments powered by Disqus