通过 OPA 运行 Kubernetes Pod Security Policy
Kubernetes是当今云原生生态系统中最流行的容器编排平台。因此,Kubernetes的安全性也是一个越来越令人感兴趣和关注的领域。
在这篇博文中,首先我将讨论Pod安全策略准入控制器。然后我们将看到Open Policy Agent如何实现Pod安全策略。事实上,在Kubecon + CloudNaticeCon North America 2019的Kubernetes SIG Auth期间,Open Policy Agent / Gatekeeper被提及为Pod安全策略的潜在替代品。
首先,简要了解一下容器、安全和准入控制器。
容器和安全概述
Kubernetes
中的容器是什么?
容器是轻量级的,可移植的,易于管理。在同一主机上运行的容器没有单独的物理/虚拟机。换句话说,容器共享资源、硬件和它们所运行的主机的操作系统内核。因此,使用者围绕哪些进程可以在容器内运行、这些进程有哪些权限、容器是否允许权限升级、使用哪些镜像等问题拥有适当的安全性变得非常重要。
kubernetes
中的 Pod
是什么?
Pod是Kubernetes应用程序的基本执行单元,是Kubernetes对象模型中最小、最简单的单元,由你创建或部署。它是一组由一个或多个容器组成的共享存储/网络,以及如何运行这些容器的规范。
因此,在容器上执行安全策略时,我们检查并应用Pod规范的安全策略。那么,这些政策是如何执行的呢?使用准入控制器。
什么是 Admission Controller
?
准入控制器是kube-apiserver的一部分。在配置被存储在集群设置(etcd)之前,它们拦截对Kubernetes API服务器的请求。一个准入控制器可以是验证性的(验证传入的请求),也可以是突变性的(修改传入的请求),或者两者都是。请参考Kubernetes文档,快速了解各种准入控制器的情况。
使用 Open Policy Agent
作为 Admission Controller
开放政策代理(OPA)是一个开源的、通用的政策引擎,它使把政策写成代码成为可能。OPA提供了一种高水平的声明性语言–Rego–来实现政策即代码。使用OPA,我们可以在微服务、CI/CD管道、API网关等方面执行策略。OPA最重要的用例之一是Kubernetes的策略执行,作为一个准入控制器。
这些策略是在Rego中编写的,并加载到OPA中,作为Kubernetes集群的准入控制器运行。OPA将根据Rego策略评估对Kubernetes API服务器的任何资源创建/更新/删除请求。如果该请求满足所有的策略,该请求就被允许。但即使有一个策略失败,请求也会被拒绝。
关于OPA
及 Rego
的更多详情,请阅读Rego Docs
现在,让我们来看看Pod安全策略的细节。
Pod Security Policy
是什么?
Pod安全策略(PSP)是一个集群级的资源,作为一个准入控制器来实现。PSP允许用户将安全要求转化为管理Pod规格的具体政策。起初,当一个PodSecurityPolicy资源被创建时,它什么都不做。而为了使用它,请求用户或目标pod的服务账户必须通过允许 “使用 “动词来授权使用该策略。你可以参考Kubernetes文档中的启用Pod安全策略。
请注意,PSP接纳控制器既是验证接纳控制器,又是变异接纳控制器。对于一些参数,PSP录取控制器使用默认值来改变传入的请求。此外,顺序始终是先变异,然后再验证。
我们可以使用 PSP
控制哪些参数?
下表简要介绍了PSP中使用的各种参数和字段。详细解释见Kubernetes文档。
Field | Kubernetes API Reference (Kind – Version – Group ) | Control Aspect |
---|---|---|
privileged | SecurityContext v1 core | Running containers in privileged mode |
hostPID, hostIPC | PodSpec v1 core (https://v1-18.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#podspec-v1-core) | Usage of host namespaces |
… | … | … |
如何使用 OPA
来 实现 PSP
?
我在前面提到,Rego语言允许我们把任何自定义策略写成代码。这意味着,我们可以使用Rego编写上述的Pod安全策略,并将OPA作为一个准入控制器来执行。
让我们快速看下 Rego
实现 privileged pod policy
。
1 | package kubernetes.admission |
那么,这个策略是做什么的呢?如果输入请求中的任何容器是作为特权容器运行的,它将返回一条信息。
PSP
实践
让我们通过一个基于minikube的基本教程来看看这个策略的运作情况。首先,按照OPA文档中的教程,将OPA设置为准入控制器。这个教程加载一个入口验证策略。取而代之的是,我们将加载上面显示的特权策略。
一旦OPA被设置为minikube上的接纳控制器,使用上面的策略创建一个文件priorleged.rego。然后,在 “OPA “命名空间中,将该策略创建一个configmap
。
kubectl create configmap privileged-policy --from-file=privileged.rego -n opa
现在,让我们使用以下清单创建一个具有特权的容器的部署。
1 | apiVersion: v1 |
当你尝试创建这个pod
的时候,你将注意到因为OPA
的存在而动作被拒绝。
1 | Error from server (Container nginx runs in privileged mode.): error when creating "privileged-deploy.yaml": admission webhook "validating-webhook.openpolicyagent.org" denied the request: Container nginx runs in privileged mode. |
同样,我们可以为其他Pod编写安全策略,并使用OPA
进行强制执行。
在此篇教程中,为了简单起见我们使用configmap
来加载策略,但这不是生产部署的最佳策略。在生产环境中,你可以从外部的 bundle
服务器中定期的下载 OPA
策略。你所有的策略可以在 bundle
服务中进行维护,另外 OPA
也会定期的下载来保持其最新状态。请查看Bundle API
了解更多信息。
简而言之,使用 OPA
,我们可以强制执行 Pod
安全策略。不仅如此,我们还可以使用相同的设置来执行任何其他自定义的安全/基于标准的政策。
在PSP
中应用OPA
的几点关键益处
- 可以在同一个准入控制器中管理所有的策略避免了分散的管理
- 完善了
Policy-as-code
在CICD
中的实现 - 使得通过版本控制工具例如
Git
来维护OPA
策略成为了可能,OPA
也提供了APIs
来动态的管理策略并进行加载 - 根据自己的实施进行定制化的拒绝信息
另外,我们也可以部署 OPA
作为 mutating admission controller
。这样的话,你也可以完善 PSP Admission Controller
的 mutating
行为。