策略即代码:为了 OpenPolicyAgent 学 Rego?试试 Javascript
距离上个版本 用 Pipy 实现 OPA,已经过去快半年了。当初使用Pipy 实现了可信镜像仓库的检查,那时的版本实现起来会稍微复杂,从策略仓库到证书创建到Admission Webhook 的创建都需要大量的人工操作,配置和逻辑也还是耦合在一起。
这个版本安装和使用起来会更加简单。
当初我用“不务正业”来形容 Pipy 实现准入控制,等看完这篇文章,欢迎留言说说你的看法。
架构
还是继续上次的场景,在 Pod 创建时对 Pod 使用的镜像所在仓库进行检查,以及检查镜像的 tag 是否合法。
这里借助 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 两个按钮
再次测试
#清理
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 管理,可以轻松实现策略即代码。同时,资源消耗更少,性能更高(代理场景的特点)。