关注分享主机优惠活动
国内外VPS云服务器

Kubernetes 准入控制器指南

摘要:我们对安全功能的最新介绍是一组名为准入控制器的插件。 通过将标志传递到服务器来配置有效的准入控制器集。 本讨论将仅关注基于 的准入控制器。 总结 准入控制器提供了显着的安全优势。

作者:Malte Isberner (StackRox)

Kubernetes 极大地提高了当今生产环境中后端集群的速度和可管理性。 Kubernetes 的灵活性、可扩展性和易用性使其成为容器编排事实上的标准。 Kubernetes 还提供各种功能来保护您的生产工作负载。 安全功能的最新介绍是一组称为准入控制器的插件。 要使用 Kubernetes 的一些更高级的安全功能,例如在命名空间中强制执行安全配置基线的 pod 安全策略,您必须启用准入控制器。 以下基本提示和技巧将帮助您利用准入控制器充分利用 Kubernetes 的安全功能。

什么是 Kubernetes 准入控制器?

简而言之,Kubernetes 准入控制器是一个插件,用于管理和强制执行集群的使用方式。 将它们视为可以拦截(经过身份验证的)API 请求并修改请求对象或完全拒绝请求的看门人。 准入控制过程有两个阶段。 首先是变更阶段,然后是验证阶段。 因此,准入控制器可以充当修改控制器、验证控制器或两者的组合。 例如,LimitRanger 准入控制器使用默认资源请求和限制(修改阶段)来扩展 pod,以确保 pod 不会超过 LimitRange 对象中指定的值。您可以确认您已设置资源要求。 每个命名空间限制(验证阶段)。

准入控制器阶段

许多用户认为内置的 Kubernetes 操作的某些方面实际上是由准入控制器管理的。 例如,如果您删除命名空间,然后进入终止状态。,NamespaceLifecycle 准入控制器会阻止在此命名空间中创建新对象。

在 Kubernetes 附带的 30 多个准入控制器中,有两个用于特殊用途,具有几乎无限的灵活性。 - ValidatingAdmissionWebhook 和 MutatingAdmissionWebhook 在 Kubernetes 1.13 中均处于测试阶段。 让我们仔细看看这两个准入控制器,因为它们本身不实现任何策略决策逻辑。 相反,相应的操作是从集群内运行的服务的 REST 端点(Webhook)检索的。 这种方法将准入控制器逻辑与 Kubernetes API 服务器分离,并允许用户在 Kubernetes 集群中创建、更新或删除资源时实现自定义逻辑。

两种类型的准入控制器 Webhooks 之间的差异大多是不言自明的。 修改的准入 Webhook 可能会修改对象,但验证的准入 Webhook 不会修改对象。 但是,即使您修改准入 Webhook,请求仍可能被拒绝并以经过身份验证的方式运行。 与修改 Webhooks 相比,验证准入 Webhooks 有两个主要优点。 首先,出于安全原因,您可以禁用 MutatingAdmissionWebhook 准入控制器(或对谁可以创建 MutatingWebhookConfiguration 对象实施更严格的 RBAC 限制)。 这是因为它可能会导致混乱甚至危险的副作用。 。 其次,如上所示,验证准入控制器(以及 Webhook)在控制器更改后执行。 因此,请确保 webhook 看到的请求对象是将持久化到 etcd 的最终版本。

将标志传递给 Kubernetes API 服务器以配置一组有效的准入控制器。 请注意,旧的 -admission-control 标志在 1.10 中已弃用,并由 -enable-admission 取代。- 插件。

--enable-admission-plugins=ValidatingAdmissionWebhook,MutingAdmissionWebhook

Kubernetes 建议默认启用以下准入控制器。

--enable-admission-plugins=NamespaceLifecycle、LimitRanger、ServiceAccount、DefaultStorageClass、DefaultTolerationSeconds、MutatingAdmissionWebhook、ValidatingAdmissionWebhook、优先级、ResourceQuota、PodSecurityPolicy

是有关准入控制器及其描述的完整列表,请参阅官方 Kubernetes 参考。 本讨论仅关注基于 Webhook 的准入控制器。

为什么我们需要准入控制器?

安全性:准入控制器提供了一个可以通过应用安全基线来提高安全性的方法。 内置的 PodSecurityPolicy 准入控制器可能是最明显的例子。 例如,它可用于防止容器以 root 身份运行,或确保容器的根文件系统始终以只读方式挂载。 可以使用基于 Webhook 的自定义准入控制器实现的其他用例包括:

允许仅从企业已知的特定存储库拉取镜像,拒绝未知的镜像存储库。

拒绝不符合安全标准的部署。 例如,使用特权标志的容器可以绕过许多安全检查。 这种风险可以通过基于 Webhook 的准入控制器来缓解,该控制器要么拒绝此类部署(验证),要么覆盖特权标志并将其设置为 fa。这是正确的。

治理:准入控制器允许您强制遵守某些实践,例如适当的标签、注释、资源限制和其他设置。被迫的。 常见场景包括:

在不同的对象上强制或部署标签验证,以确保为不同的对象使用正确的标签,例如分配给团队或项目的每个对象为每个对象指定一个应用程序标签。

自动向对象添加注释,例如将正确的成本中心分配给“开发”部署资源。

配置管理:准入控制器允许您验证集群中运行的对象的配置,这有助于防止配置错误。 准入控制器允许您检测和修复没有语义标签的部署映像。 例如,

自动添加资源限制或检查资源限制。

确保将适当的标签添加到 Pod。 或

确保生产部署中使用的映像引用不使用最新标签或带有 -dev 后缀的标签。

因此,准入控制器和策略管理可帮助应用程序在不断变化的控制环境中保持合规性。

示例:创建和部署准入控制器 Webhook

为了演示如何利用准入控制器 Webhook 建立自定义安全策略,我们将讨论 Kubernetes 的缺点之一。有一个解决方案来解决这个问题。 例如:许多默认设置都针对易用性和减少混乱进行了优化,但有时会牺牲安全性。 其中一项设置是允许容器默认以 root 身份运行(这种情况不需要任何额外的配置,并且 Dockerfile 中不存在 USER 指令)。 尽管容器与底层主机有一定程度的隔离,但以 root 身份运行容器会增加部署的风险级别 -,因为应避免使用许多安全最佳实践之一。 例如,最近披露的 runC 漏洞 (CVE-2019-5736) 仅当容器以 root 身份运行时才能被利用。

您可以使用自定义修改准入控制器 Webhooks 来强制执行更安全的默认值。默认值:除非明确请求,否则 Webhook 将导致 pod 以非 root 用户身份运行(在这种情况下它将分配用户 ID 1234)。 请注意,此设置不会阻止您在集群中部署工作负载,包括合法需要以 root 身份运行的工作负载。 您需要做的就是在部署配置中显式启用此危险程序的操作模式,并为所有其他工作负载默认为非 root 模式。

完整的代码和部署说明可在随附的 GitHub 存储库中找到。 在这里,我们将重点关注 Webhook 工作原理的一些更微妙的方面。

变异(变异)Webhook 配置

通过在 Kubernetes 中创建 MutatingWebhookConfiguration 对象来定义变异准入控制器 Webhook。 本示例使用以下设置:

apiVersion:admissionregistration.k8s.io/v1beta1kind:MutatingWebhookConfigurationmetadata:name:demo-webhookwebhooks:- name:webhook-server.webhook -demo.svc clientConfig:服务:名称: webhook-server 命名空间: webhook-demo 路径: "/mutate" caBundle: ${CA_PEM_B64} 规则: - 操作: [ "CREATE" ] apiGroups: [ ""] apiVersions: ["v1" ]资源:[“豆荚”]

此配置定义了一个 webhook webhook-server.webhook-demo.svc,用于在 Kubernetes API 服务器上查询命名空间 webhook[k4 中的服务 webhook-server。 ] 演示。 必须满足几个先决条件才能启用此配置。

Webhook REST API

Kubernetes API 服务器使用请求中的 JSON 编码的AdmissionReview(已设置 Request 字段)来访问指定的服务和 URL 发出 HTTPS POST 请求。到路径。 身体。 响应必须是 JSON 编码的AdmissionReview。 这次设置了响应字段。

演示存储库包含处理序列化/反序列化样板代码的函数,使您可以专注于实现在 Kubernetes API 对象上运行的逻辑。 在此示例中,实现准入控制器逻辑的函数称为 applySecurityDefaults。 在 /mutate URL 中提供此功能的 HTTPS 服务器可以这样配置:

mux := http.NewServeMux()mux。    Handle("/mutate",acceptFuncHandler(applySecurityDefaults))server := &http.Server{ Addr: ":8443", Handler: mux,}log.Fatal(server.ListenAndServeTLS(certPath, keyPath))

请注意,要在没有提升权限的情况下运行服务器,请让 HTTP 服务器侦听端口 8443。 Kubernetes 不允许您在 webhook 配置中指定端口。 始终假设 HTTPS 端口 443。由于一切都需要服务对象,因此您可以轻松地将服务上的端口 443 映射到容器上的端口 8443。

apiVersion: v1kind: Servicemetadata: name: webhook-server namespace: webhook-demospec : 选择器: app: webhook-server # 在deployment/pod中指定的端口: - port : 443 targetPort: webhook-api # 容器端口8443的名称

对象修改逻辑

更改准入控制器webhook以通过JSON补丁Masu执行更改。 JSON 修补标准包含许多复杂性,远远超出了本讨论的范围,但此示例 Go 数据结构及其用法是 JSON 修补工作原理的一个很好的示例,它应该为用户提供有关 JSON 修补工作原理的初步概述。

type patchOperation struct { Op string `json:"op"` 路径字符串 `json:"path"` 值接口 {} `json:"value,omitempty"`}

如果 pod .spec.securityContext.runAsNonRoot 设置为 true,则构造以下 patchOperation 对象:

patches = append(patches, patchOperation{ Op: "add", Path: "/spec/securityContext/runAsNonRoot" ,值:true,})

TLS 证书

Webhook 必须通过 HTTPS 提供服务,因此需要合适的服务器证书。 这些证书可以是自签名的(由自签名 CA 签名),但 Kubernetes 在与 webhook 服务器通信时必须指向相应的 CA 证书。 此外,证书的公用名 (CN) 必须与 Kubernetes API 服务器使用的服务器名称匹配(对于内部服务,..svc)。 在本例中,这是 webhook-server.webhook-demo.svc。 生成自签名 TLS 证书在互联网上已有详细记录,因此示例仅引用相应的 shell 脚本。

前面显示的 Webhook 配置包含占位符 ${CA_PEM_B64}。 在创建此配置之前,您必须将此部分替换为 CA 的 Base64 编码的 PEM 证书。 opensslbase64- 命令可用于此目的。

测试 webhook

部署并配置 webhook 服务器后(这可以通过从存储库调用 ./deploy.sh 脚本来完成),您可以测试我将要的内容。 检查 webhook 是否真正执行其功能。 该存储库包含三个示例:

未指定安全上下文的 Pod (pod-with-defaults)。 此 pod 必须以用户 ID 1234 的非 root 身份运行。

指定明确允许以 root 身份运行的安全上下文的 pod(pod-with-override)。

指定对于配置冲突的 pod,应使用用户 ID 0(pod-with-conflict)以非 root 用户身份运行它们。 为了指示拒绝对象创建请求,我们添加了准入控制器逻辑来拒绝这些明显的错误配置。

运行 kubectl create -f 示例les/.yaml 创建其中一个 pod。 在前两个示例中,您可以通过检查日志来确定 Pod 运行时的用户 ID。 示例:

$ kubectl create -f Examples/pod-with-defaults .yaml$ kubectl logs pod-with-defaults我以用户 1234 身份运行

在第三个示例中,对象的创建被拒绝并显示相应的错误消息。

$ kubectl create -f Examples/pod-with-conflict.yaml 来自服务器的错误(InternalError):创建时“examples/pod-with-conflict.yaml”错误:发生内部错误:接收 webhook 'webhook-server.webhook-demo.svc' 拒绝了请求:指定了 runAsNonRoot,但 runAsUser 已设置为 0(root 用户)已设置。  

您还可以使用自己的工作负载进行测试。 当然,您可以通过更改 webhook 的逻辑并查看这些更改如何影响对象创建来进一步进行实验。 有关如何尝试此类更改的详细信息,请参阅存储库的自述文件。

概述

Kubernetes 准入控制器提供了显着的安全优势。 让我们仔细看看两个带有工作代码的强大示例,以帮助您开始利用这些强大的功能。

参考文档:

https://kubernetes.io/docs/re...

https://docs.okd.io/latest/ar...

https://kubernetes.io/blog/20...

https://medium. com/ibm-cloud/...

https://github.com/kubernetes...

https://github.com/istio/istio

p>

https://www.stackrox.com/post...


KubeCon + CloudNativeCon + 开源峰会会议日期:

会议日程公布日期:2019年4月10日

会议活动日期:2019年6月24-26日

KubeCon + CloudNativeCon +开源峰会赞助计划
KubeCon + CloudNativeCon + 开源峰会多元化奖学金现已接受申请
KubeCon + CloudNativeCon 与开源峰会在国内首次合并
KubeCon + CloudNativeCon + 开源峰会购票窗口,立即购买门票!
CNCF 已结束,邀请您加入我们的用户社区

未经允许不得转载:主机频道 » Kubernetes 准入控制器指南

评论 抢沙发

评论前必须登录!