容器运行时安全是什么?

2023-10-28 16:14:57 浏览数 (1)

作者:Rob Newsome[1],stack.io[2]产品管理主管

Kubernetes API 服务器是 Kubernetes 控制平面的核心组件之一。该组件暴露 Kubernetes API,并充当控制平面的前端。当用户或进程与 Kubernetes 交互时,API 服务器处理这些请求,并验证和配置 Kubernetes API 对象,如部署或命名空间。当然,这是在 Kubernetes Admission Controllers 的帮助下进行的。那么,什么是 Admission Controller?

根据官方的 Kubernetes 文档,Admissions Controller 是一段代码,它在对象持久化之前拦截 Kubernetes API 服务器的请求,但在请求经过身份验证和授权之后。有两种类型的 Admission Controllers,即 Mutating 和 Validating。某些控制器可以同时具备这两种功能,但一般来说,控制器要么对请求进行改变并修改对象,要么如其名称所示,对请求进行验证。

为了更清楚地理解,让我通俗地解释一下它的工作原理。假设你有一个带有一些 Kubernetes 对象定义(如部署或 Pod)的 YAML 文件,并且你想将其应用到你的集群中。当你将该请求发送到 API 服务器时,它首先检查你是否具有创建该对象的必要权限。然后,该请求将被转发给 Mutating Admission Controllers。这些控制器可以根据集群中的配置更改该对象的定义。之后,如果定义模式有效,则将请求转发给 Validating Admission Controllers。如果一切都正确,资源将被创建,并将对象的详细信息发送到 etcd。

Admission Controllers 的工作原理

Kyverno[3]OPA Gatekeeper[4]Datree[5]这样的第三方策略引擎工具使用 Mutating 和 Validating Admission Webhooks 来管理策略。例如,Kyverno 作为集群内的 Dynamic Admission Controller 运行。它接收来自 Kubernetes API 服务器的 Mutating 和 Validating webhook 请求,并应用匹配的策略以返回强制执行的准入策略或拒绝请求的结果。OPA Gatekeeper 也是类似的。它是一个 Validating 和 Mutating webhook,用于强制执行由Open Policy Agent[6]执行的策略。但是这些工具有自己定义这些策略的格式,并且它们之间当然存在差异。例如,OPA 使用一种称为 Rego 的语言,对于一些人来说编写或理解策略可能会很困难,因为它是一种不同的语言,需要学习曲线。

但是在 Kubernetes 1.26 版本中,Kubernetes Validating Admission Policies[7]的首个 Alpha 版本已经可用。在 Kubernetes 1.28 中,它现在处于 Beta 阶段。该功能将声明性策略管理的标准化引入到 Kubernetes API 中。这意味着我们能够以 Kubernetes 原生方式管理和定义策略。Validating Admission Policies 使用Common Expression Language[8](CEL)来定义策略规则,并允许我们拥有参数化和作用域化的策略。构建、安装和管理第三方 Webhooks 可能会非常复杂,但是这个新功能将消除所有对调用远程 Webhook 的要求,并允许我们使用 CEL 表达式在 API 内部作为内置过程管理策略。

这是否意味着第三方工具的终结?我个人认为不是,并且我相信 OPA Gatekeeper 和 Kyverno 等工具将调整其方法以适应这种新方法。但是如果他们不这样做,我认为这些工具可能会面临问题,因为大多数 Kubernetes 用户不希望选择使用不同的工具来管理策略,如果 Kubernetes 的 API 已经原生提供了这个功能。这当然是我个人的观点。

让我们看看 Kubernetes Validating Admission Policies 的实际应用!

在进行演示之前,我应该提醒你,这个功能在 Kubernetes API 中默认是未启用的,你需要启用必要的 ValidatingAdmissionPolicy 功能门。根据你的 Kubernetes 版本,你还需要在 API 中启用 admissionregistration.k8s.io/v1alpha1 或 admissionregistration.k8s.io/v1beta1。在这个演示中,我将使用一个 Kubernetes 集群的 1.27 版本,并使用'v1alpha1' API 版本来创建 Validating Admission Policy 资源。

对于策略,我们需要两个资源。首先,是定义资源的实际规则和验证操作的策略,其次是将实际策略绑定到例如命名空间的绑定资源。

我将使用一个简单的示例策略,该策略将为具有标签定义的命名空间中的部署对象定义一个副本数的限制规则。首先,让我创建一个简单的命名空间资源。

代码语言:javascript复制
apiVersion: v1
kind: Namespace
metadata:
  labels:
    environment: demo
  name: demo

当然,这没有什么特别的,我将使用 kubectl apply 来创建这个命名空间。让我们定义我们的策略:

代码语言:javascript复制
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicy
metadata:
  name: "demo-policy"
spec:
  matchConstraints:
    resourceRules:
    - apiGroups:   ["apps"]
      apiVersions: ["v1"]
      operations:  ["CREATE", "UPDATE"]
      resources:   ["deployments"]
  validations:
    - expression: "object.spec.replicas <= 5"
      message: "You can not have more than 5 replicas in the demo namespace for deployments"

该策略将检查部署资源,并跟踪创建和更新操作。这些部署对象需要定义 5 个或更少的副本。但是我还需要一个 Policy Binding 资源:

代码语言:javascript复制
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
  name: "demo-binding"
spec:
  policyName: "demo-policy"
  validationActions: [Deny]
  matchResources:
    namespaceSelector:
      matchLabels:
        environment: demo

从绑定资源中可以看出,该策略将强制执行到具有标签“environment = demo”的命名空间中的部署资源。让我们使用 kubectl apply 创建这些资源。

现在是时候测试我们的新策略了。我将使用一个简单的部署定义:

代码语言:javascript复制
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
  labels:
    app: nginx
spec:
  replicas: 6
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx

我不会为这个部署对象定义服务或其他特定内容。让我们应用这个部署:

代码语言:javascript复制
kubectl apply -f deployment.yaml -n demo

如预期的那样,我无法创建部署对象。策略生效,以下是错误消息:

代码语言:javascript复制
The deployments "demo-app" is invalid: : ValidatingAdmissionPolicy
'demo-policy' with binding 'demo-binding' denied request:
You can not create more than 5 replicas in the demo namespace for deployments

当然,对于此演示的目的来说,这是一个成功。如果我将 spec.replicas 更改为 5,部署将成功创建。

从我在这篇博客文章中展示的示例演示中可以看出,Validating Admission Policies 使得在 Kubernetes 中编写、强制执行和使用策略变得非常容易,而无需第三方工具。这也非常灵活。通过使用 CEL 表达式,你可以为多个操作和多个验证规则创建定义明确的自定义策略。当然,你可以添加更多的验证规则来扩展这些策略,或者你可以使用不同的验证操作。我真诚地相信这将成为 Kubernetes 中策略管理的事实标准。

这个功能在 Kubernetes 1.28 中现处于 Beta 阶段,所以你可以通过启用功能门来自行尝试。但我相信当它默认启用或进入稳定阶段时,这个功能将变得非常有用。

参考资料

[1]

Emin Alemdar: https://www.linkedin.com/in/emin-alemdar/

[2]

Medium: https://eminalemdar.medium.com/policy-management-in-kubernetes-is-changing-9d4808f548a0

[3]

Kyverno: https://kyverno.io/

[4]

OPA Gatekeeper: https://open-policy-agent.github.io/gatekeeper/website/

[5]

Datree: https://www.datree.io/

[6]

Open Policy Agent: https://www.openpolicyagent.org/

[7]

Validating Admission Policies: https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/

[8]

Common Expression Language: https://github.com/google/cel-spec本文转载自CNCF

0 人点赞