【翻译】在Kubernetes中用Gatekeeper执行策略

在管理Kubernetes集群时,集群管理员需要确保系统的整体稳定性。为了实现这一目标,有必要避免控制平面的中断,也要避免用户能够升级他们的权限从而导致进一步的问题的任何风险。考虑到这一点,保护kube-system命名空间和执行pod安全策略以运行具有必要权限的有效载荷是必须的。

为了实现我们的目标,我们看了一下Kubernetes的原生方式,但发现RBAC不足以覆盖一些用例。最终我们决定使用Gatekeeper,因为它允许我们为授权添加 "拒绝 "规则,也允许我们为集群中的有效载荷执行Pod安全策略。Gatekeeper在执行最佳实践方面确实很出色,使其自然适合我们想要实现的目标。

这篇文章解释了使Gatekeeper成为与RBAC一起使用验证Webhooks改善Kubernetes授权过程的良好选择的论点。我们还展示了几个例子,说明如何保护kube-system命名空间以及如何执行一些pod安全策略。

问题所在

在提供Kubernetes集群时,确保稳定性是很重要的。通常情况下,你想授予用户足够的权限以获得自由,但你也想保护集群免受意外的变化和中断。为了达到这个目的,应该阻止与kube-system命名空间的不必要的交互,以保护该命名空间不受用户错误和恶意行为的影响。

也有必要为集群中的有效载荷执行Pod安全策略。

Kubernetes提供了RBAC等工具,通过Roles和ClusterRoles处理对集群的访问。这种方法的问题是,RBAC是纯粹的加法,所以集群管理员需要定义一个最终用户可以访问的详细权限列表。在这种情况下,我们想提供对整个集群的访问,除了kube-system--这在RBAC中是不可能的,因为它没有 "拒绝 "选项。

Kubernetes曾经提供过Pod安全策略,帮助集群中的Pod执行最佳安全实践,但这些策略在V1.21版本中已经被废弃。幸运的是,我们有开放政策代理(OPA),这是一个开源的通用政策引擎,有一个名为Gatekeeper的Kubernetes具体实现。这可以作为Pod安全策略的完美替代。

Gatekeeper提供了一个带有通用策略的。该库帮助我们避免不断地重新发明轮子,但如果你有非常具体的要求,也可以创建自定义策略。

为了解决RBAC中固有的访问限制,OPA/Gatekeeper是一个不错的选择。它能以一种更可配置的方式执行不同类型的访问,并允许执行多种类型的pod安全策略以防止权限升级问题。

认证和授权

虽然它是集群管理的一个重要部分,但认证不在本文的讨论范围之内。我们假设从现在开始,每个请求都是经过认证的。

为用户提供对集群中不同资源的访问是集群管理员的主要关切之一。在这种情况下,用户应该有对集群的完全访问权,只是被排除在使用kube-system命名空间之外。这在实践中通常是一个复杂的任务,因为集群管理员需要跟踪每个用户或用户组的权限。

使用RBAC,可以为用户提供集群管理员的权限,使他们有足够的灵活性来使用集群。问题是,这提供了对kube-system命名空间的访问,意味着他们可能会破坏集群。

保护控制平面

为了避免控制面出现不必要的混乱,应该阻止对kube-system命名空间的访问。只有属于system:*组的用户或任何被云提供商用来管理控制平面资源的用户,才能访问kube-system命名空间及其资源。

限制对kube-system命名空间的访问是一项微妙的任务,因为无意中阻止管理控制平面的用户可能会导致集群中出现意外的故障。如果由于某种原因,任何一个控制平面控制器停止了对该命名空间的访问,那么最终将破坏集群,而不是保护它。

集群用户应该被允许在Kubernetes集群上部署任何东西,但集群管理员需要通过执行政策确保他们遵循良好的做法。

解决方案--验证准入Webhooks

入场控制器似乎是解决前面提到的所有问题的自然方式,因为当请求到达入场Webhook时,认证和授权已经被处理。当寻找一个兼容的实现时,脱颖而出的工具又是Gatekeeper。

验证接纳Webhooks是Kubernetes中实现的接纳控制器的一部分。这些负责拦截对kube-api的请求,并可以根据其内容允许或拒绝对请求的访问。

要有一个有效的验证准入网络钩子,就必须要有一个准入网络钩子服务器。在这种情况下,服务器是Gatekeeper,Kubernetes通过使用ValidatingWebhookConfiguration对象来通知它,该对象在安装Gatekeeper时创建。

ValidatingWebhookConfiguration对象有一个叫做rules的字段,用来定义哪些请求应该用webhook进行验证。这些规则可以匹配apiGroups、apiVersions、资源或操作。阅读更多关于ValidatingWebhookConfiguration的内容,了解如何定制其行为。

为了理解Validating Webhooks如何与OPA互动,看看这篇博文中介绍的架构。

需要注意的一点是,只有当请求经过认证,并且请求之前被RBAC授权时,才会通过Validating Webhook。

Enforcing policies with Gatekeeper diagram 1-100

开放策略代理

开放策略代理(OPA)是一个开源的、与平台无关的策略引擎,使用户能够使用OPA的策略语言Rego以代码形式创建策略。与Kubernetes中的接纳控制器相结合,OPA为集群管理员提供了多种配置选项,以创建自定义策略。

Gatekeeper I是与Kubernetes集成的OPA实现。它允许用户通过引入一个名为ConstraintTemplate的自定义资源来创建和执行策略,该资源允许集群管理员通过创建自定义资源来扩展Kubernetes的API,以执行自定义策略。

约束模板和约束条件

为了执行一个新策略,首先需要使用包含验证约束的rego代码的ConstraintTemplate来定义它。

为了执行该政策,根据先前创建的ConstraintTemplate创建一个自定义资源--这也被称为 "约束"。约束的创建通知 Gatekeeper,它需要被强制执行。

在约束中,定义一个匹配字段,该字段由Kubernetes选择器组成,有助于定义应用特定约束的元素,包括种类命名空间labelSelector和其他。

考虑的问题

虽然所描述的场景需要在kube-system命名空间上执行多个策略,但通常Gatekeeper被用于其他目的,一般的建议是避免向kube-system命名空间添加限制,因为这些限制会导致控制面的中断。

作为一条经验法则,始终确保所执行的策略不会阻碍集群中关键工作负载或依赖关系的部署。同样,如果有第三方控制器与群集互动,请确保访问它们所需的资源,以便按预期工作。

如何使用网守

让我们来看看Kubernetes中政策执行的例子。对于这一点,唯一的要求是一个健康的Kubernetes集群。

安装Gatekeeper

要部署gatekeeper 3.4

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.4/deploy/gatekeeper.yaml

用Rego创建一个约束模板

cat <<EOF | kubectl create -f - apiVersion: templates.gatekeeper.sh/v1beta1 kind:ConstraintTemplate元数据: name: denyrestrictednamespaceaccess spec: crd: spec: names: kind:DenyRestrictedNamespaceAccess 目标: - 目标: admission.k8s.gatekeeper.sh rego。| package DenyNamespace violation[{"msg": msg}] { not startswith(input.review.userInfo.username, "system:") msg := sprintf("you can not use namespace: %v", [input.review.object.metadata.namespace]) } EOF

这创建了一个名为DenyRestrictedNamespaceAccess的自定义资源定义(CRD),允许我们强制执行该策略。该策略说,只有在提出请求的用户没有系统:前缀的情况下才是违规。

策略得到审查AdmissionReview对象,并返回一个类似的对象,其中包含一个可以被设置为真或假的字段 "允许"。阅读更多关于接纳控制器的信息。

创建一个约束条件

cat <<EOF | kubectl create -f - apiVersion: constraints.gatekeeper.sh/v1beta1 kind:DenyRestrictedNamespaceAccess 元数据: name: denyrestrictednamespaceaccess spec: match: namespaces: - kube-system rules: - operations:["*"] EOF

匹配字段指定kube-system命名空间是执行该策略的空间。

操作字段表示对命名空间的每个操作都执行该策略,即CREATE、UPDATE、DELETE。记住,这种webhook不允许对GET请求进行过滤。

要检查策略是否被执行,请运行以下命令。

kubectl create serviceaccount testsa -n kube-system

该命令应返回。

[denyrestrictednamespaceaccess] 你不能使用命名空间:kube-system

用Rego创建一个Pod安全策略约束模板

这是一个来自Gatekeeper常用策略的例子。

cat <<EOF | kubectl create -f - apiVersion: templates.gatekeeper.sh/v1beta1 kind:ConstraintTemplate 元数据: name: k8spspallowprivilegeescalationcontainer annotations: description:控制限制升级到root权限。 规格: crd: 规格: 名称: kind:K8sPSPAllowPrivilegeEscalationContainer 目标: - 目标: admission.k8s.gatekeeper.sh rego:| package k8spspallowprivilegeescalationcontainer violation[{"msg": msg, "details": {}}] { c := input_containers[_] input_allow_privilege_escalation(c) msg := sprintf("Privilege escalation container is not allowed: %v", [c. name]] } input_allow_privilege_escalation(c)name]) } input_allow_privilege_escalation(c) { not has_field(c, "securityContext") } input_allow_privilege_escalation(c) { not c. securityContext.allowPriviation.securityContext.allowPrivilegeEscalation == false } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } # has_field 返回一个对象是否有一个字段 has_field(object, field) = true { object[field] } EOF

该策略审查容器,看这些容器是否没有安全上下文,或者安全上下文是否被设置为真。

创建一个违规的pod

cat <<EOF | kubectl create -f - apiVersion: v1 kind:Pod元数据: name: static-web-without-security-context-0 spec: containers: - name: web image: nginx ports: - name: web containerPort: 80 protocol:TCP EOF

在实际执行策略之前,让我们创建一个没有安全上下文的Pod,以说明策略是如何应用的以及审计功能是如何工作的。

创建Pod安全策略(PSP)约束

cat <<EOF | kubectl create -f - apiVersion: constraints.gatekeeper.sh/v1beta1 kind:K8sPSPAllowPrivilegeEscalation-container 元数据: name: psp-allow-privilege-escalation-container 规格: match: kinds: - apiGroups: [""] kinds:["Pod"] excludedNamespaces:["kube-system"] EOF

该约束条件强制要求该策略应用于所有pod。它还排除了任何运行在kube-system命名空间的pod。

验证该策略

cat <<EOF | kubectl create -f - apiVersion: v1 kind:Pod 元数据: name: static-web-without-security-context-1 spec: containers: - name: web image: nginx ports: - name: web containerPort: 80 protocol:TCP EOF

试图创建上述pod应该返回以下结果。这个pod和已经创建的pod是一样的,但这次它被webhook屏蔽了。

[psp-allow-privilege-escalation-container] 特权升级容器不允许:web

为了成功创建pod,请更新清单,为容器添加一个安全上下文。

    securityContext: allowPrivilegeEscalation: false

审计

守门员允许用户查看违反任何现有策略的预先存在的资源。在这个案例中,这个集群之前运行的是一个没有securityContext的pod,这意味着任何用户都可以看到之前触发的策略违反,使用以下命令。

kubectl get constraint -o json | jq '.items[].status.violations' [ { "enforceAction":"deny", "kind":"Pod", "message":"不允许特权升级的容器:web","名称"。"static-web-without-security-context-0", "namespace":"default" }, ]

结论

提供一个灵活、安全、高可用的Kubernetes集群是一项艰巨的任务,涉及许多挑战。我们已经研究了如何保护控制面资源,以及如何防止pod上的权限升级问题。

在这个过程中,我们发现了RBAC对Kubernetes的一些限制,并通过使用Gatekeeper根据自定义需求添加 "拒绝 "规则来解决这些问题。请记住,集群管理员应详细审查哪些用户应该或不应该访问kube-system

限制对kube-system的访问是一个非常特殊的要求,一般建议避免向kube-system命名空间添加约束。该帖子展示了如何做到这一点作为参考,但请记住,这可能导致控制平面的中断。确保任何控制平面的用户都能按预期工作。

所提供的两个例子允许集群管理员拒绝对命名空间的访问,并防止容器的特权升级。这些例子足以说明这个想法,应该给集群管理员一个创建自定义策略的起点。

重要的是要记住,当AdmissionReview到达Gatekeeper时,请求已经被验证和授权了,所以这些话题不在这篇文章的范围内。

OPA/Gatekeeper是在Kubernetes集群中处理多种策略的一个伟大选择。使用约束模板和约束集群管理员可以定义约束应用于哪些资源。关于RegoGatekeeper的官方文档肯定有助于更好地理解和创建自定义策略。

hiring.png

猜你喜欢

转载自blog.csdn.net/community_717/article/details/128432939