本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
OPA Gatekeeper:Kubernetes 的策略和治理
Open Policy Agent Gatekeeper 项目可用于帮助在您的 Kubernetes 环境中强制执行策略并加强治理。在这篇文章中,我们将详细介绍该项目的目标、历史和当前状态。
以下来自 Kubecon EU 2019 会议的录音是使用 Gatekeeper 的绝佳起点
动机
如果您的组织一直在运营 Kubernetes,您可能一直在寻找控制最终用户在集群上可以做什么的方法,以及确保集群符合公司策略的方法。这些策略可能旨在满足治理和法律要求,或强制执行最佳实践和组织约定。在 Kubernetes 中,如何在不牺牲开发敏捷性和操作独立性的情况下确保合规性?
例如,您可以强制执行以下策略:
- 所有镜像必须来自已批准的仓库
- 所有 Ingress 主机名必须全局唯一
- 所有 Pod 必须具有资源限制
- 所有命名空间必须有一个列出联系点的标签
Kubernetes 允许通过准入控制器 Webhook 将策略决策与 API 服务器分离,以在将准入请求持久化为 Kubernetes 中的对象之前对其进行拦截。Gatekeeper 的创建是为了让用户能够通过配置而不是代码自定义准入控制,并了解集群的状态,而不仅仅是准入时正在评估的单个对象。Gatekeeper 是一个可自定义的 Kubernetes 准入 Webhook,它强制执行由 Open Policy Agent (OPA) 执行的策略,OPA 是一个由 CNCF 托管的云原生环境策略引擎。
演进
在我们深入了解 Gatekeeper 的当前状态之前,让我们先了解一下 Gatekeeper 项目是如何演进的。
- Gatekeeper v1.0 - 使用 OPA 作为准入控制器,kube-mgmt sidecar 强制执行基于 configmap 的策略。它提供验证和修改准入控制。由 Styra 捐赠。
- Gatekeeper v2.0 - 使用 Kubernetes 策略控制器作为准入控制器,OPA 和 kube-mgmt sidecars 强制执行基于 configmap 的策略。它提供验证和修改准入控制以及审计功能。由 Microsoft 捐赠。
- Gatekeeper v3.0 - 准入控制器与 OPA Constraint Framework 集成,以强制执行基于 CRD 的策略并允许以声明方式配置的策略可靠地共享。它使用 kubebuilder 构建,提供验证和(最终将实现)修改准入控制以及审计功能。这使得可以为 Rego 策略创建策略模板,将策略创建为 CRD,并在策略 CRD 上存储审计结果。该项目是 Google、Microsoft、Red Hat 和 Styra 之间的合作成果。
Gatekeeper v3.0 功能
现在让我们仔细看看 Gatekeeper 的当前状态以及如何利用所有最新功能。考虑一个组织希望确保集群中的所有对象都具有作为对象标签一部分提供的部门信息。您如何使用 Gatekeeper 来实现这一点?
验证准入控制
一旦所有 Gatekeeper 组件都已在您的集群中安装,每当集群中创建、更新或删除资源时,API 服务器将触发 Gatekeeper 准入 webhook 来处理准入请求。
在验证过程中,Gatekeeper 充当 API 服务器和 OPA 之间的桥梁。API 服务器将强制执行 OPA 执行的所有策略。
策略和约束
通过集成 OPA Constraint Framework,约束是其作者希望系统满足给定一组要求的声明。每个约束都使用 Rego 编写,Rego 是一种声明性查询语言,OPA 用它来枚举违反系统预期状态的数据实例。所有约束都作为逻辑 AND 进行评估。如果一个约束不满足,则整个请求将被拒绝。
在定义约束之前,您需要创建一个约束模板,该模板允许人们声明新的约束。每个模板都描述了强制执行约束的 Rego 逻辑和约束的 schema,其中包括 CRD 的 schema 和可以传递给约束的参数,很像函数的参数。
例如,这是一个约束模板 CRD,它要求在任意对象上存在某些标签。
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
listKind: K8sRequiredLabelsList
plural: k8srequiredlabels
singular: k8srequiredlabels
validation:
# Schema for the `parameters` field
openAPIV3Schema:
properties:
labels:
type: array
items: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
deny[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("you must provide labels: %v", [missing])
}
一旦约束模板部署到集群中,管理员就可以根据约束模板创建单个约束 CRD。例如,这是一个约束 CRD,它要求所有命名空间都存在标签 hr
。
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-hr
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["hr"]
同样,可以很容易地从同一个约束模板创建另一个约束 CRD,它要求所有命名空间都存在标签 finance
。
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-finance
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["finance"]
如您所见,通过约束框架,我们可以通过约束模板可靠地共享 Rego,使用匹配字段定义强制范围,并向约束提供用户定义的参数,为每个约束创建自定义行为。
审计
审计功能允许定期评估复制的资源与集群中强制执行的约束,以检测预先存在的错误配置。Gatekeeper 将审计结果存储为相关约束的 status
字段中列出的 violations
。
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-hr
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["hr"]
status:
auditTimestamp: "2019-08-06T01:46:13Z"
byPod:
- enforced: true
id: gatekeeper-controller-manager-0
violations:
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: default
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: gatekeeper-system
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: kube-public
- enforcementAction: deny
kind: Namespace
message: 'you must provide labels: {"hr"}'
name: kube-system
数据复制
审计需要将 Kubernetes 资源复制到 OPA 中,然后才能针对强制执行的约束进行评估。需要访问集群中除正在评估的对象之外的其他对象的约束也需要数据复制。例如,强制 Ingress 主机名唯一性的约束必须能够访问集群中的所有其他 Ingress。
要配置要复制的 Kubernetes 数据,请创建一个 sync config 资源,其中包含要复制到 OPA 的资源。例如,以下配置将所有命名空间和 Pod 资源复制到 OPA。
apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
name: config
namespace: "gatekeeper-system"
spec:
sync:
syncOnly:
- group: ""
version: "v1"
kind: "Namespace"
- group: ""
version: "v1"
kind: "Pod"
未来计划
Gatekeeper 项目的社区将专注于提供修改准入控制以支持修改场景(例如:在创建新资源时自动为对象添加部门信息)、支持外部数据以将集群外部的上下文注入到准入决策中、支持试运行以在强制执行策略之前查看策略对集群中现有资源的影响,以及更多审计功能。
如果您有兴趣了解更多关于该项目的信息,请查看 Gatekeeper 仓库。如果您有兴趣帮助定义 Gatekeeper 的方向,请加入 OPA Slack 上的 #kubernetes-policy 频道,并参加我们的每周会议,讨论开发、问题、用例等。