头盔安全

关于 Kubernetes 最受欢迎的包管理器的故事的本质可以用表情符号来描述:

  • 盒子是 Helm(这是最接近最新 Emoji 版本的东西);
  • 锁——安全;
  • 小人物就是问题的解决方案。

头盔安全

事实上,一切都会有点复杂,而且故事充满了关于的技术细节 如何确保 Helm 安全.

  • 简要介绍一下 Helm 是什么,以防您不知道或忘记。 它解决什么问题以及它在生态系统中的位置。
  • 我们来看看 Helm 架构。 如果不了解组件的架构,关于安全性以及如何使工具或解决方案更安全的讨论是不完整的。
  • 让我们讨论 Helm 组件。
  • 最紧迫的问题是未来——Helm 3 的新版本。 

本文中的所有内容均适用于 Helm 2。该版本目前正在生产中,很可能是您当前使用的版本,并且它是包含安全风险的版本。


关于演讲者: 亚历山大·卡约罗夫(阿莱克斯)已开发10年,帮助完善内容 莫斯科 Python 大会++ 并加入委员会 掌舵峰会。 现在,他在 Chainstack 担任开发主管 - 这是开发经理和负责交付最终版本的人员之间的混合体。 也就是说,它位于战场上,从产品的创造到操作的一切都发生在战场上。

Chainstack 是一家小型、积极发展的初创公司,其使命是让客户忘记运行去中心化应用程序的基础设施和复杂性;开发团队位于新加坡。 不要要求 Chainstack 出售或购买加密货币,而是提出谈论企业区块链框架,他们会很乐意回答你。

头盔

这是 Kubernetes 的包(图表)管理器。 将应用程序引入 Kubernetes 集群的最直观、最通用的方式。

头盔安全

当然,我们谈论的是一种比创建自己的 YAML 清单和编写小型实用程序更具结构性和工业性的方法。

Helm 是目前可用且流行的最好的。

为什么是头盔? 主要是因为它得到 CNCF 的支持。 Cloud Native 是一个大型组织,是 Kubernetes、etcd、Fluentd 等项目的母公司。

另一个重要的事实是 Helm 是一个非常受欢迎的项目。 当我在 2019 年 12 月开始谈论如何确保 Helm 安全时,该项目在 GitHub 上有一千颗星。 到 XNUMX 月,人数已达 XNUMX 人。

许多人对 Helm 感兴趣,因此即使您尚未使用它,了解它的安全性也会让您受益匪浅。 安全很重要。

Helm 核心团队由 Microsoft Azure 支持,因此是一个相当稳定的项目,与许多其他项目不同。 3 月中旬 Helm 2 Alpha XNUMX 的发布表明,有相当多的人在从事该项目,他们有开发和改进 Helm 的愿望和精力。

头盔安全

Helm 解决了 Kubernetes 中应用程序管理的几个根本问题。

  • 应用程序包装。 即使像 WordPress 上的“Hello, World”这样的应用程序也已经包含多个服务,并且您希望将它们打包在一起。
  • 管理管理这些应用程序带来的复杂性。
  • 应用程序安装或部署后不会结束的生命周期。 它继续存在,需要更新,Helm 会为此提供帮助,并尝试为此采取正确的措施和政策。

套袋 它的组织方式清晰:元数据完全按照 Linux、Windows 或 MacOS 的常规包管理器的工作方式进行。 即存储库、各种包的依赖关系、应用程序的元信息、设置、配置功能、信息索引等。Helm 允许您为应用程序获取和使用所有这些。

复杂性管理。 如果您有许多相同类型的应用程序,则需要参数化。 模板由此而来,但为了避免必须想出自己的创建模板的方式,您可以使用 Helm 提供的开箱即用的功能。

应用程序生命周期管理 - 在我看来,这是最有趣且尚未解决的问题。 这就是我当时来到 Helm 的原因。 我们需要关注应用程序生命周期,并希望将我们的 CI/CD 和应用程序周期转移到这种范例。

Helm 允许您:

  • 管理部署,引入配置和修订的概念;
  • 成功执行回滚;
  • 对不同的事件使用钩子;
  • 添加额外的应用程序检查并对其结果做出响应。

而且 头盔有“电池” - 大量美味的东西可以以插件的形式包含在内,简化您的生活。 插件可以独立编写,它们相当孤立,不需要和谐的架构。 如果您想实现某些功能,我建议将其作为插件进行,然后可能将其包含在上游中。

Helm 基于三个主要概念:

  • 图表回购 — 您的清单可能的描述和参数化数组。 
  • 配置 ——即将应用的值(文本、数值等)。
  • 发布 收集上面的两个组件,一起变成Release。 可以对版本进行版本控制,从而实现有组织的生命周期:安装时较小,升级、降级或回滚时较大。

舵架构

该图概念性地描述了 Helm 的高级架构。

头盔安全

让我提醒您一下,Helm 是与 Kubernetes 有关的东西。 因此,我们离不开 Kubernetes 集群(矩形)。 kube-apiserver 组件驻留在 master 上。 没有 Helm,我们就有 Kubeconfig。 Helm 带来了一个小型二进制文件(如果您可以称之为 Helm CLI 实用程序),它可以安装在计算机、笔记本电脑、大型机等任何设备上。

但这还不够。 Helm 有一个名为 Tiller 的服务器组件。 它代表 Helm 在集群内的利益;它是 Kubernetes 集群内的一个应用程序,就像任何其他应用程序一样。

Chart Repo 的下一个组件是包含图表的存储库。 有官方的仓库,也可能有公司或项目的私人仓库。

相互作用

让我们看看当我们想要使用 Helm 安装应用程序时,架构组件如何交互。

  • 我们说话 Helm install,访问存储库(Chart Repo)并获取 Helm Chart。

  • Helm 实用程序 (Helm CLI) 与 Kubeconfig 交互,以确定要联系哪个集群。 
  • 收到此信息后,该实用程序将位于我们集群中的 Tiller 作为应用程序引用。 
  • Tiller 调用 Kube-apiserver 在 Kubernetes 中执行操作,创建一些对象(服务、pod、副本、秘密等)。

接下来,我们将使图表变得复杂,以查看整个 Helm 架构作为一个整体可能面临的攻击向量。 然后我们会尽力保护她。

攻击矢量

第一个潜在的弱点是 特权API - 用户。 作为该计划的一部分,这名黑客获得了 Helm CLI 的管理员访问权限。

非特权 API 用户 如果它在附近的某个地方,也可能造成危险。 这样的用户将有不同的上下文,例如,他可以在 Kubeconfig 设置中固定在一个集群命名空间中。

最有趣的攻击向量可能是驻留在 Tiller 附近的集群中并且可以访问它的进程。 这可以是查看集群网络环境的 Web 服务器或微服务。

Chart Repo 是一种奇特但越来越流行的攻击变体。 无良作者创建的图表可能包含不安全的资源,您只要相信它就会完成它。 或者它可以替换您从官方存储库下载的图表,例如以策略的形式创建资源并升级其访问权限。

头盔安全

让我们尝试抵御来自这四个方面的攻击,并找出 Helm 架构中哪些地方存在问题,哪些地方可能没有问题。

让我们放大图表,添加更多元素,但保留所有基本组件。

头盔安全

Helm CLI 与 Chart Repo 通信,与 Kubeconfig 交互,并将工作转移到集群的 Tiller 组件上。

Tiller 由两个对象表示:

  • Tiller-deploy svc,暴露某个服务;
  • Tiller-deploy pod(图中为一个副本中的单个副本),整个负载在其上运行,访问集群。

使用不同的协议和方案进行交互。 从安全角度来看,我们最感兴趣的是:

  • Helm CLI 访问图表存储库的机制:什么协议、是否有身份验证以及可以用它做什么。
  • 使用 kubectl 的 Helm CLI 与 Tiller 通信所采用的协议。 这是安装在集群内的 RPC 服务器。
  • Tiller 本身可供驻留在集群中的微服务访问并与 Kube-apiserver 交互。

头盔安全

让我们按顺序讨论所有这些领域。

RBAC

除非启用 RBAC,否则讨论 Helm 或集群内任何其他服务的任何安全性都是没有意义的。

看起来这不是最新的推荐,但我确信很多人即使在生产中仍然没有启用 RBAC,因为它很麻烦,需要配置很多东西。 不过,我鼓励您这样做。

头盔安全

https://rbac.dev/ — RBAC 网站律师。 它包含大量有趣的材料,可帮助您设置 RBAC、展示其优点以及如何在生产中基本使用它。

我将尝试解释 Tiller 和 RBAC 的工作原理。 Tiller 在集群内的某个服务帐户下工作。 通常,如果未配置 RBAC,则这将是超级用户。 在基本配置中,Tiller 将是管理员。 这就是为什么人们常说 Tiller 是通往集群的 SSH 隧道。 事实上,确实如此,因此您可以使用单独的专用服务帐户来代替上图中的默认服务帐户。

当您初始化 Helm 并将其首次安装在服务器上时,您可以使用以下命令设置服务帐户 --service-account。 这将允许您使用具有所需的最低权限集的用户。 确实,您必须创建这样一个“花环”:Role 和 RoleBinding。

头盔安全

不幸的是,Helm 不会为你做这件事。 您或您的 Kubernetes 集群管理员需要提前为 service-account 准备一组 Roles 和 RoleBindings,以便通过 Helm。

问题出现了——Role 和 ClusterRole 之间有什么区别? 不同之处在于 ClusterRole 适用于所有命名空间,这与常规 Role 和 RoleBindings 不同,后者仅适用于专门的命名空间。 您可以为整个集群和所有命名空间配置策略,也可以为每个命名空间单独配置策略。

值得一提的是,RBAC解决了另一个大问题。 许多人抱怨 Helm 不幸的是不是多租户(不支持多租户)。 如果多个团队使用一个集群并使用Helm,基本上不可能在这个集群内设置策略并限制他们的访问,因为Helm运行在某个服务帐户下,并且它从该服务帐户下创建集群中的所有资源,这有时非常不方便。 这是真的——就像二进制文件本身一样,进程也一样, Helm Tiller 没有多租户概念.

然而,有一个很好的方法可以让您在集群中多次运行 Tiller。 这没有问题,Tiller 可以在每个命名空间中启动。 因此,您可以使用 RBAC、Kubeconfig 作为上下文,并限制对特殊 Helm 的访问。

它看起来像这样。

头盔安全

例如,有两个具有不同团队(两个命名空间)上下文的 Kubeconfig:X Team 用于开发团队和管理集群。 管理员集群有自己的宽 Tiller,它位于 Kube-system 命名空间中,是一个相应的高级服务帐户。 并为开发团队提供单独的命名空间,他们将能够将他们的服务部署到特殊的命名空间。

这是一个可行的方法,Tiller 不太耗电,不会极大地影响您的预算。 这是快速解决方案之一。

您可以随意单独配置 Tiller,并为 Kubeconfig 提供团队、特定开发人员或环境的上下文:开发、暂存、生产(令人怀疑的是,所有内容都将位于同一个集群上,但是,这是可以完成的)。

继续我们的故事,让我们从 RBAC 转向 ConfigMap。

配置映射

Helm 使用 ConfigMaps 作为其数据存储。 当我们谈论架构时,没有任何数据库可以存储有关发布、配置、回滚等信息。ConfigMaps 用于此目的。

ConfigMap 的主要问题是众所周知的——原则上它们是不安全的; 不可能存储敏感数据。 我们谈论的是不应该超出服务范围的一切,例如密码。 目前 Helm 最原生的方式是从使用 ConfigMap 切换到使用 Secret。

这样做非常简单。 覆盖 Tiller 设置并指定存储为机密。 然后,对于每个部署,您将收到的不是 ConfigMap,而是一个秘密。

头盔安全

你可能会说秘密本身是一个奇怪的概念,而且不太安全。 然而,值得理解的是,Kubernetes 开发人员自己正在这样做。 从1.10版本开始,即在相当长的一段时间里,至少在公共云中,连接正确的存储来存储秘密是可能的。 该团队目前正在研究如何更好地分配对机密、单个 Pod 或其他实体的访问权限。

最好将存储头盔转移到秘密中,而它们反过来又受到集中保护。

当然会保留 数据存储限制为 1 MB。 Helm 这里使用 etcd 作为 ConfigMap 的分布式存储。 他们认为这是一个适合复制等的数据块。 Reddit 上有一个关于此问题的有趣讨论,我建议在周末找到这篇有趣的读物或阅读摘录 这里.

图表回购

图表是社会上最脆弱的,可能成为“中间人”的来源,特别是如果您使用库存解决方案。 首先,我们讨论的是通过 HTTP 公开的存储库。

您肯定需要通过 HTTPS 公开 Helm Repo - 这是最好的选择,而且价格便宜。

注意 图表签名机制。 这项技术非常简单。 这与您在 GitHub 上使用的东西相同,这是一个带有公钥和私钥的常规 PGP 机器。 设置并确保拥有必要的密钥并签署所有内容,这确实是您的图表。

另外, Helm 客户端支持 TLS (不是服务器端 HTTP 意义上的,而是双向 TLS 的)。 您可以使用服务器和客户端密钥进行通信。 老实说,我不使用这样的机制,因为我不喜欢相互证书。 基本上, 图表博物馆 - 用于为 Helm 2 设置 Helm Repo 的主要工具 - 还支持基本身份验证。 如果更方便、更安静,您可以使用基本身份验证。

还有一个插件 helm-gcs,它允许您在 Google Cloud Storage 上托管 Chart Repos。 这非常方便,效果很好并且非常安全,因为所有描述的机制都是回收的。

头盔安全

如果您启用 HTTPS 或 TLS、使用 mTLS 并启用基本身份验证以进一步降低风险,您将获得与 Helm CLI 和 Chart Repo 的安全通信通道。

gRPC API

下一步非常重要 - 确保 Tiller 的安全,它位于集群中,一方面是服务器,另一方面,它本身访问其他组件并试图冒充某人。

正如我已经说过的,Tiller 是一个公开 gRPC 的服务,Helm 客户端通过 gRPC 访问它。 当然,默认情况下 TLS 是禁用的。 为什么这样做是一个有争议的问题,在我看来,一开始就简化了设置。

对于生产甚至登台,我建议在 gRPC 上启用 TLS。

在我看来,与图表的 mTLS 不同,这在这里很合适,而且完成起来非常简单 - 生成 PQI 基础设施、创建证书、启动 Tiller、在初始化期间传输证书。 之后,您可以执行所有 Helm 命令,向自己展示生成的证书和私钥。

头盔安全

这样您就可以保护自己免受集群外部向 Tiller 发出的所有请求的影响。

因此,我们已经保护了 Tiller 的连接通道,我们已经讨论了 RBAC 并调整了 Kubernetes apiserver 的权限,减少了它可以交互的域。

防护头盔

让我们看一下最终的图表。 这是具有相同箭头的相同架构。

头盔安全

现在可以安全地将所有连接绘制为绿色:

  • 对于 Chart Repo,我们使用 TLS 或 mTLS 和基本身份验证;
  • Tiller 的 mTLS,它作为带有 TLS 的 gRPC 服务公开,我们使用证书;
  • 集群使用具有 Role 和 RoleBinding 的特殊服务帐户。 

我们已经显着保护了集群的安全,但有人聪明地说:

“只有一种绝对安全的解决方案——一台关闭的计算机,位于一个混凝土盒子里,并由士兵看守。”

有多种方法可以操纵数据并寻找新的攻击向量。 然而,我相信这些建议将达到基本的行业安全标准。

奖金

这部分与安全性没有直接关系,但也很有用。 我将向您展示一些很少有人知道的有趣的事情。 例如,如何搜索图表 - 官方和非官方。

在存储库中 github.com/helm/charts 现在大约有 300 个图表和两个流:稳定版和孵化器。 任何做出贡献的人都非常清楚从孵化器到马厩是多么困难,以及飞出马厩是多么容易。 然而,这并不是搜索 Prometheus 图表以及您喜欢的任何其他内容的最佳工具,原因很简单 - 它不是一个可以方便地搜索软件包的门户。

但有一个服务 hub.helm.sh,这使得查找图表更加方便。 最重要的是,还有更多的外部存储库和近 800 个可用的超级按钮。 另外,如果由于某种原因您不想将图表发送到稳定版,您可以连接您的存储库。

尝试 hub.helm.sh,让我们一起开发它。 该服务位于Helm项目下,如果你是前端开发人员并且只想改善外观,你甚至可以为其UI做出贡献。

我还想提请您注意 开放 Service Broker API 集成。 听起来很麻烦、不清楚,但却解决了每个人都面临的问题。 让我用一个简单的例子来解释一下。

头盔安全

有一个 Kubernetes 集群,我们要在其中运行一个经典应用程序 - WordPress。 一般来说,完整的功能需要数据库。 有许多不同的解决方案,例如,您可以启动自己的有状态服务。 这不是很方便,但很多人都这么做。

其他人,比如我们 Chainstack,使用 MySQL 或 PostgreSQL 等托管数据库作为他们的服务器。 这就是为什么我们的数据库位于云中的某个位置。

但是出现了一个问题:我们需要将我们的服务与数据库连接,创建数据库风格,传输凭据并以某种方式管理它。 所有这些通常由系统管理员或开发人员手动完成。 而且应用少的时候也没有问题。 当它们很多时,您需要联合收割机。 有这样一个收割机——它就是Service Broker。 它允许您使用公共云集群的特殊插件,并通过 Broker 从提供商处订购资源,就像 API 一样。 为此,您可以使用本机 Kubernetes 工具。

这很简单。 例如,您可以使用基础层(可以配置)查询 Azure 中的托管 MySQL。 使用 Azure API,将创建数据库并准备使用。 您无需干预此操作,插件负责此操作。 例如,OSBA(Azure 插件)将向服务返回凭据并将其传递给 Helm。 您将能够将 WordPress 与云 MySQL 结合使用,完全不处理托管数据库,也不用担心内部的有状态服务。

可以说,Helm 充当了粘合剂的角色,一方面允许您部署服务,另一方面消耗云提供商的资源。

您可以编写自己的插件并在本地使用整个故事。 然后,您将拥有自己的企业云提供商插件。 我建议尝试这种方法,特别是如果您规模较大并且想要快速部署某个功能的开发、登台或整个基础设施。 这将使您的运营或 DevOps 变得更加轻松。

我已经提到的另一个发现是 helm-gcs 插件,它允许您使用 Google-buckets(对象存储)来存储 Helm 图表。

头盔安全

您只需要四个命令即可开始使用它:

  1. 安装插件;
  2. 发起它;
  3. 设置存储桶的路径,该路径位于gcp中;
  4. 以标准方式发布图表。

美妙之处在于将使用本机 gcp 方法进行授权。 您可以使用服务帐户、开发人员帐户,无论您想要什么。 非常方便,而且无需任何操作费用。 如果你像我一样提倡 opsless 哲学,那么这将非常方便,尤其是对于小型团队。

替代品

Helm 并不是唯一的服务管理解决方案。 关于它有很多疑问,这可能就是第三个版本出现得如此之快的原因。 当然还有其他选择。

这些可以是专门的解决方案,例如 Ksonnet 或 Metaarticle。 您可以使用经典的基础设施管理工具(Ansible、Terraform、Chef 等)来实现我谈到的相同目的。

终于有解决办法了 算子框架,其受欢迎程度正在不断增长。

Operator Framework 是最值得考虑的 Helm 替代方案。

它更原生于 CNCF 和 Kubernetes, 但进入门槛要高得多,您需要更多地编程并更少地描述清单。

有各种插件,例如 Draft、Scaffold。 它们让生活变得更加轻松,例如,它们简化了开发人员部署测试环境的发送和启动 Helm 的周期。 我称他们为赋能者。

这是所有东西所在位置的可视化图表。

头盔安全

x 轴是您对正在发生的事情的个人控制级别,y 轴是 Kubernetes 的原生级别。 Helm 版本 2 处于中间位置。 在版本 3 中,虽然不是很大,但控制和原生水平都得到了提高。 Ksonnet 级别的解决方案甚至仍然不如 Helm 2。但是,它们值得一看,以了解这个世界上还有什么。 当然,您的配置管理器将在您的控制之下,但它绝对不是 Kubernetes 原生的。

Operator Framework 绝对是 Kubernetes 原生的,允许您更优雅、更谨慎地管理它(但请记住入门级别)。 相反,这适用于专门的应用程序并为其创建管理,而不是使用 Helm 打包大量应用程序的大规模收割机。

扩展器只是稍微改进控制、补充工作流程或在 CI/CD 管道上走捷径。

头盔的未来

好消息是Helm 3来了,Helm 3.0.0-alpha.2的alpha版本已经发布了,大家可以尝试一下。 它相当稳定,但功能仍然有限。

为什么需要 Helm 3? 首先,这是一个关于 蒂勒失踪,作为一个组件。 正如您已经了解的那样,这是向前迈出的一大步,因为从架构安全性的角度来看,一切都被简化了。

当 Helm 2 创建时,也就是 Kubernetes 1.8 左右甚至更早的时候,许多概念还不成熟。 比如CRD理念现在正在积极落地,Helm将 使用CRD来存储结构。 可以只使用客户端而不维护服务器部分。 因此,请使用本机 Kubernetes 命令来处理结构和资源。 这是向前迈出的一大步。

会出现 支持本机 OCI 存储库 (开放容器倡议)。 这是一项巨大的举措,Helm 感兴趣主要是为了发布其图表。 例如,Docker Hub 支持许多 OCI 标准。 我不是在猜测,但也许经典的 Docker 存储库提供商将开始为您提供托管 Helm 图表的机会。

对我来说有争议的故事是 卢阿支持,作为编写脚本的模板引擎。 我不是 Lua 的忠实粉丝,但这将是一个完全可选的功能。 我检查了 3 次 - 不需要使用 Lua。 因此,那些想要使用 Lua 的人,那些喜欢 Go 的人,加入我们庞大的阵营并为此使用 go-tmpl 。

最后,我绝对缺少的是 模式出现和数据类型验证。 int 或 string 不会再有问题,不需要用双引号将零括起来。 将出现一个 JSONS 架构,允许您显式地描述值。

将被大量返工 事件驱动模型。 已经在概念上描述了它。 查看 Helm 3 分支,您将看到添加了多少事件和钩子以及其他东西,这将大大简化,另一方面,增加对部署过程及其反应的控制。

Helm 3 会更简单、更安全、更有趣,不是因为我们不喜欢 Helm 2,而是因为 Kubernetes 正在变得更加先进。 相应地,Helm可以利用Kubernetes的发展,并在其上为Kubernetes创建优秀的管理器。

另一个好消息是 开发运营大会 亚历山大·卡约罗夫会告诉你, 容器安全吗? 让我们提醒您,开发、测试和运营流程整合会议将在莫斯科举行 30月1日和XNUMX月XNUMX日。 20 月 XNUMX 日之前您仍然可以这样做 提交一份报告 并告诉我们您对该解决方案的体验 其中之一 DevOps 方法的任务。

关注会议检查点和新闻 邮件列表 и 电报频道.

来源: habr.com

添加评论