Kubernetes 是当今云原生生态系统中最受欢迎的容器编排平台。因此,Kubernetes 的安全性也引起了越来越多的关注。
在此博客文章中,首先我将讨论 Pod 安全策略准入控制器。然后,我们将看到 Open Policy Agent 如何实现 Pod 安全策略。实际上,Open Policy Agent 被视为 Pod 安全策略的潜在替代方案。
首先,简要介绍一下容器,安全性和准入控制器。
容器和安全简介
容器轻巧,轻便且易于管理。在同一主机上运行的容器没有单独的物理 / 虚拟机。换句话说,容器共享运行它们的主机的资源,硬件和 OS 内核。因此,具有适当的安全性变得非常重要,这些安全性涉及容器中可以运行哪些进程,这些进程具有哪些特权,容器是否将允许特权升级,使用了什么镜像等等。
Pod 是 Kubernetes 应用程序的基本执行单元,是您创建或部署的 Kubernetes 对象模型中最小和最简单的单元。它是一个或多个具有共享存储 / 网络的容器的组,以及有关如何运行容器的规范。因此,在容器上实施安全策略时,我们将检查安全策略并将其应用于 Pod 规范。那么,这些策略如何执行?使用准入控制器。
什么是 Admission Controllers?
准入控制器是 kube-apiserver 的一部分。在配置存储在集群设置(etcd)中之前,它们拦截对 Kubernetes API 服务器的请求。准入控制器可以是正在验证(用于验证传入请求的一个)或正在变异(用于修改传入请求的一个)或两者都在进行。请参阅 Kubernetes 文档以快速浏览各种准入控制器。
Open Policy Agent 作为 admission controller
Open Policy Agent(OPA)是一种开放源代码的通用策略引擎,可以将策略编写为代码。OPA 提供了一种高级声明性语言 -Rego- 以策略作为代码。使用 OPA,我们可以跨微服务,CI / CD 管道,API 网关等执行策略。OPA 最重要的用例之一是 Kubernetes 作为准入控制者的策略实施。
OPA 作为准入控制器,您可以强制执行非 root 用户之类的策略,要求使用特定的资源标签,确保所有 pod 都指定了资源请求和限制等。基本上,OPA 允许您使用 Rego 语言将任何自定义策略编写为代码。
这些策略以 Rego 编写并加载到 OPA 中,作为 Kubernetes 集群上的准入控制器运行。OPA 将根据 Rego 策略评估对 Kubernetes API 服务器的任何资源创建 / 更新 / 删除请求。如果请求满足所有策略,则允许该请求。但是,即使单个策略失败,请求也会被拒绝。
在此处阅读有关 OPA,Rego 的更多信息,并用作 OPA 文档中的准入控制器。
Pod Security Policy
Pod 安全策略(PSP)是实现为准入控制器的集群级别资源。PSP 允许用户将安全要求转换为管理 Pod 规范的特定策略。首先,创建 PodSecurityPolicy 资源时,它什么也不做。为了使用它,必须通过允许“使用”动词来授权请求用户或目标 pod 的服务帐户使用该策略。您可以参考 Kubernetes 文档上的启用 Pod 安全策略。
注意,PSP 准入控制器既充当验证角色,又充当变异准入控制器。对于某些参数,PSP 准入控制器使用默认值来更改传入的请求。此外,顺序始终是先突变然后验证。
使用 PSP 我们可以控制哪些所有参数?
下表简要概述了 PSP 中使用的各种参数和字段。在此处的 Kubernetes 文档中提供了详细说明。
那么,我们可以在 OPA 中实现 PSP 吗?
前面提到,Rego 语言允许我们将任何自定义策略编写为代码。这意味着,我们可以使用 Rego 编写上述的 Pod 安全策略,并以 OPA 作为准入控制器来执行。
让我们快速了解一下实施“特权”Pod 安全策略的 Rego 策略。可以在 Rego playground 试用此策略。
package kubernetes.admission
deny[message] {
#applies for Pod resources
input.request.kind.kind == "Pod"
#loops through all containers in the request
container := input.request.object.spec.containers[_]
#for each container, check privileged field
container.securityContext.privileged
#if all above statements are true, return message
message := sprintf("Container %v runs in privileged mode.", [container.name])
}
那么,该策略有何作用?如果输入请求中的任何容器正在作为特权容器运行,它将返回一条消息。
PSP 实战
让我们通过基于 minikube 的教程来了解这项策略的实际效果。首先,按照此处 OPA 文档中的教程,将 OPA 设置为准入控制器。本教程将加载入口验证策略。取而代之的是,我们将加载上面显示的特权策略。
将 OPA 设置为 minikube 上的准入控制器后,请使用上述策略创建文件 privileged.rego。然后,在“opa”名称空间中将策略创建为 configmap。
kubectl create configmap privileged-policy --from-file=privileged.rego -n opa
等待策略加载到 OPA。当 configmap 的注释增加了 openpolicyagent.org/policy-status:'{"status":"ok"}'
项时表明已经加载了该策略。
现在,让我们使用以下清单创建具有特权容器的部署:
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
securityContext:
privileged: true
当您尝试创建此 Pod 时,您会注意到 Open Policy Agent 拒绝了 Pod。
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 加载了策略,但这并不是生产部署的最佳策略。对于生产部署,可以将 OPA 配置为定期从外部捆绑服务器中下载策略捆绑。您的所有策略都可以在此捆绑服务器中维护。OPA 将通过定期下载策略来保持最新状态。有关更多详细信息,请参考 Bundle API。
简而言之,使用 OPA,我们可以实施 Pod 安全策略。不仅如此,我们还可以使用相同的设置来实施任何其他基于自定义。
将 OPA 用于 PSP 的主要好处是什么?
我们从这种方法中获得的一些主要好处是:
- 在一个准入控制器中集中管理所有策略(PSP 和其他自定义策略),而不必分别进行管理
- 在 CI / CD 管道中也执行相同的策略,从而在整个堆栈中实施“按代码编码”。
- 能够在源控制存储库(如 Git)中维护 OPA 策略。OPA 提供了 HTTP API 以动态管理加载的策略。
- 将策略决策流式传输到您选择的外部日志记录 / 监视工具。
- 根据您的设置 / 实现自定义拒绝消息。
另外,我们可以将 OPA 部署为变异许可控制器。这样,您还可以实现 PSP Admission Controller 的变异行为。
结论
我们可以通过 OPA 有效实施 Pod 安全策略。此外,这使我们能够将安全策略建模为代码。而且,所有这些都在一个 OPA 准入控制器中。
PS: 本文属于翻译,原文