博客 | NGINX

NGINX 现代应用参考架构 1.0.0 版发布

NGINX-F5-horiz-black-type-RGB 的一部分
Jason Schmidt 缩略图
杰森·施密特
2022 年 4 月 28 日发布

当我们在 2021 年 8 月的 Sprint 2.0 上发布 NGINX现代应用s参考架构(MARA) 时,我们就预先说明了我们的设计目标。 我们希望创建一个在 Kubernetes 中运行的现代应用架构的示例,旨在支持安全性、可扩展性、可靠性、监控和自省。 该项目需要能够在不同的基础设施上部署,采用“即插即用”的方式组合功能组件,而无需耗时的集成工作。

自 Sprint 以来的几个月里,我们一直在推进我们的路线图。 与任何项目一样,我们有成功也有失败,我们将成功的经验融入到 MARA 中,同时也不断积累经验教训。 我们希望通过记录这些问题并在设计时牢记这些教训,可以防止其他人遇到同样的问题。

我们最近通过MARA 版本 1.0.0达到了一个里程碑,它重新组织了项目目录并改变了实例化和销毁环境的过程。 我们消除了重复的代码,创建了易于容纳未来添加的目录结构,并标准化了管理脚本。 由于此版本标志着 MARA 历史上的一个重要点,我们希望停下来向社区报告我们的进展,记录我们认为的一些更重要的经验教训,并提供一些有关我们未来路线图的信息。

NGINX 现代应用参考架构 1.0.0 版拓扑图

遥测 – 指标、日志记录和跟踪

MARA 的核心贡献者具有大规模运行软件的经验,并且了解从运营、工程和管理角度提供服务所需的条件。 他们知道,当应用出现故障而你又无法轻松地确定问题到底是什么时,你会感到多么沮丧。 DevOps 界流传的一句话简明扼要地概括了这个问题: “调试微服务就像解决一系列谋杀谜案一样”。

考虑到这一点,我们将增加可观察性作为短期路线图的首要任务。 此上下文中的可观察性包括日志管理、指标和跟踪数据。 然而,仅仅收集数据是不够的——您必须能够深入挖掘数据并对环境中发生的事情做出有意义的决策。

我们对跟踪选项的探索使我们找到了OpenTelemetry (OTEL),因为它支持整个遥测数据、日志、指标和跟踪。 我们设想了一种实现方式,其中 OTEL 代理收集、处理和重复数据删除所有跟踪数据,然后将其传递给 OTEL 收集器进行聚合和导出,并在工作流的末尾使用可视化系统使数据可用。 这种方法为用户提供了最广泛的显示和分析数据的选择,同时利用 OTEL 标准简化了早期阶段(收集、聚合等)。

我们分两个阶段实施:

  1. 为 Kubernetes 部署 OpenTelemetry Operator,以管理环境中的 OTEL 收集器

  2. Bank of Sirius应用程序进行检测以发出跟踪和指标

MARA 的原始版本使用ElasticsearchFilebeat进行日志记录,虽然我们考虑过用Grafana Loki替换它们,但我们决定暂时保留原来的选择。 在指标方面,我们意识到我们需要修改基于PrometheusGrafana 的原始部署,用社区维护的kube-prometheus-stack Helm 图表替换我们最初使用的定制 Prometheus 配置,该图表构成了一个完整的 Prometheus 环境,包括 Grafana、节点导出器,以及一系列适合管理 Kubernetes 环境的预配置仪表板和抓取目标。 为此,我们为F5 NGINX Ingress Controller和 Bank of Sirius应用添加了一些额外的仪表板。

这只是实施 OTEL 所需的大量工作的一个简短摘要。 为了节省其他人攀登同样陡峭的学习曲线的努力,我们在博客上记录了将 OpenTelemetry 集成到现代应用程序参考架构中 - 进度报告中的整个过程。

部署选项 – Kubeconfig

在 MARA 的初始版本中,我们选择了Amazon Elastic Kubernetes Service (EKS) 作为部署环境。 许多用户告诉我们,出于成本原因,他们希望在需要较少资源的“本地”环境中运行 MARA,例如实验室或工作站。 可移植性是原始项目的一个关键目标(现在仍然是),所以这是我们证明我们能够实现它的机会。 为了使任务更容易,我们决定设计一个可以在任何满足一些最低要求的 Kubernetes 集群上运行的部署程序。

第一步,我们向 MARA 添加了一个新的 Pulumi 项目,该项目读取kubeconfig文件来与 Kubernetes 集群进行通信。 该项目位于 Pulumi Kubernetes 项目和基础设施项目(后者的例子有 AWS 和 Digital Ocean 的项目)之间。 从实际角度来看,创建 kubeconfig 项目降低了集成新基础设施项目的门槛。 如果基础设施项目可以将 kubeconfig 文件、集群名称和集群上下文传递给 kubeconfig 项目,则 MARA 部署过程的其余部分就可以无缝进行。

在我们的测试中,我们使用了几个易于安装、对 CPU 和内存要求较小的 Kubernetes 发行版,包括K3sCanonical MicroK8sminikube 。 这些发行版都部署在运行 Ubuntu 21.10 的虚拟机(VM) 上,该虚拟机具有 2 个 CPU和 16 GB RAM 。 此外,所有发行版都配置为提供持久卷和 Kubernetes LoadBalancer 支持。

该过程中最困难的部分是使用作为项目一部分的定制 NGINX Ingress Controller 的私有注册表。 (请注意,部署 MARA 时,您可以使用基于 NGINX 开源或 NGINX Plus 的标准 NGINX Ingress Controller 以及此定制的 NGINX Ingress Controller。) 我们发现,我们需要将我们的注册逻辑与Amazon Elastic Container Registry (ECR) 分离,以采用更加与平台无关的方法,这项任务目前正在进行中。 我们还意识到,提取出口地址主机名的逻辑特定于AWS Elastic Load Balancing (ELB),需要重写才能应用于其他用例。

MARA 管理脚本和 Pulumi 项目目前使用一些特定逻辑来解决上述问题。 目前,基于 Kubernetes 配置的部署必须使用来自官方 NGINX 注册表的 NGINX Ingress Controller(基于 NGINX Open Source 或 NGINX Plus)。

我们在 MARA 配置文件中添加了几个调整参数,以适应不提供基于云的部署所需资源的本地部署。 大多数参数与Elastic Stack各个组件请求的副本数量有关。 随着测试的推进,将根据部署环境的资源限制来增加用于微调 MARA 的参数。

通过这些更改,我们可以成功部署到 K3s、MicroK8s 和 Minikube,并且我们已经在Azure Kubernetes 服务(AKS)、 Digital OceanGoogle Kubernetes EngineLinode和 Rancher's Harvester上成功测试了逻辑。 有关更多信息,请参阅MARA 提供商状态页面MARA: 现在在我们博客上的您附近的工作站上运行

与合作伙伴的合作

我们的合作伙伴非常乐意接受并支持我们与 MARA 的合作,其中许多人都来联系我们以了解有关该项目的更多信息,询问如何在他们的产品中利用它,甚至添加功能。

我们选择Pulumi作为 MARA 的核心部分,因为它易于使用且支持 Python,后者是一种非常流行的语言,它使得 MARA 代码能够被大型社区轻松理解。 此外,Pulumi 充满活力的社区和对项目的参与是我们希望通过 MARA 实现的社区参与的典范。

2021 年末,我们与Sumo Logic合作,将 MARA 与 NGINX Ingress Controller 一起作为其云监控解决方案的一部分。 这是一个检验我们关于 MARA 可插入性的主张的机会。 挑战在于用 Sumo Logic 解决方案替代 MARA 中的 Grafana、Prometheus 和 Elastic。 我们很高兴,我们成功地使用了与其他部署相同的逻辑来构建解决方案,并且将其配置为不仅可以连接到 Sumo Logic SaaS,还可以从我们的环境中提取指标。

作为我们与 OpenTelemetry 合作的一部分,我们与Lightstep合作,轻松地重新配置了我们的 OTEL 收集器以将跟踪和指标导出到 Lightstep 的 SaaS 产品。 这是我们热衷于进一步研究的领域,因为我们坚信 OTEL 代表可观察性的未来。

迄今为止的经验教训

我们迄今学到的最大教训是模块化方法的智慧。 与 Sumo Logic 的合作表明我们可以成功地混合和搭配 MARA 组件。 随着我们将 OTEL 更全面地融入环境,我们期待得到进一步的确认。 我们之前提到过,我们正在考虑用 Grafana Loki 取代 Elasticsearch 作为日志管理环境,因为它减少了堆栈的资源占用。 话虽如此,我们提倡“实用的模块化”,而不是走极端,把所有东西都变成微服务。 例如,虽然拥有一个可以处理许多应用日志的专门服务是有意义的,但不太明显的是,您需要单独的微服务来进行日志收集、存储和可视化。

我们还了解到,通过在配置中明确包含默认值而不是仅仅省略相关参数来设置默认值会很有帮助。 这对管理员来说有两种便利:他们不必记住默认设置,并且只需修改配置中正确位置处已经以正确语法出现的参数即可轻松更改默认设置。

我们学到的另一个惨痛的教训是,一些解决方案之所以受欢迎,并不是因为它们是最好的,而是因为它们最容易安装或有最好的教程。 这就是为什么在设计过程中质疑你的假设并咨询同事如此重要——开放的沟通文化对于帮助尽早发现和补救问题大有帮助。

尽管如此,我们多次实施了可行的逻辑,但却让我们陷入困境或引发其他问题。 例如,当我们开始通过 Pulumi 部署应用时,我们使用ConfigMaps的 YAML 清单,依靠Pulumi 转换来更新变量。 这是可行的,但由于多种原因并不理想,其中最重要的原因是可维护性。 在下一次迭代中,我们使用kube2pulumi将清单转换为 Pulumi 代码,然后可以使用该代码构建 ConfigMaps,从而提高了代码的可读性和可维护性。

当合并将无效设置在部署 YAML 中插入时,另一个教训就开始了。 我们被迫重写并仔细检查 YAML 的大部分内容,以确保代码在语法上正确并且符合我们的要求,这是一个令人沮丧且耗时的过程。 为了避免将来出现问题,我们现在已经在 GitHub 推送过程中实现了通用 YAML 和 Kubernetes 特定的linting和验证的自动化。

最后,从一开始我们的目标就是确保我们的主线分支始终可运行。 当你检查一个新项目并必须解决维护人员在主线中引入的问题时,这是令人沮丧的。 不幸的是,我们失败了几次,包括天狼星银行子模块的这些例子:

  • 我们错误地忘记将 URL 方案从ssh://更改为https:// 。 这对我们来说不是问题,因为我们都使用ssh连接到 GitHub。 但是,当用户尝试初始化子模块时,没有 GitHub 的 SSH 密钥的用户会收到大量错误消息。
  • 管理脚本的一个版本依赖于一个通用包,我们错误地认为这个包会安装在每个人的机器上,就像安装在我们的机器上一样。
  • 我们忘记在重写启动逻辑时检查子模块源。 该子模块包含部署 Bank of Sirius 所需的清单,不幸的是,当这些清单不可用时抛出的错误和警告非常模糊,以至于我们花了好几天的时间调试奇怪的行为,才发现根本原因。

下一步

我们对未来几个月的开发有宏伟的计划,包括重构 NGINX Ingress Controller 构建、注册表推送和入口主机名/IP 地址逻辑。

在每次 MARA 会议上,我们注意到的一件事是,我们很快就开始看到针对 NGINX Ingress Controller 的扫描和攻击。 这促使我们开始将 NGINX Ingress Controller 与 NGINX App Protect WAF 集成到 MARA 中。 这带来了确定如何最好地管理 App Protect 生成的日志的挑战和机遇。

我们计划在未来几个月内做出的另一项改变是让所有模块从 Kubernetes 而不是 Pulumi 和 Kubernetes 中提取机密。 这意味着所有模块都使用一个通用的秘密存储库,并让管理员控制秘密的填充方式。 我们正在编写一个新模块,从用户选择的存储库中读取机密并创建相应的 Kubernetes 机密。

MARA 目前包含一个用于生成负载的工具,该工具是基于Locust的工具的升级和略微修改版本,该工具随原始 Bank of Anthos 应用程序一起提供,我们从该应用程序中分叉了 Bank of Sirius。 我们正在编写的新测试工具 Cicada Swarm 不仅可以生成负载,还可以跟踪和报告指标何时超过您设置的阈值,使其成为在云中快速测试软件产品性能的框架。 它使用并行化技术来提供具有您所需的置信度、更高的精度和可定制的回归分析的测试结果,以确定 CI/CD 管道中的构建成功或失败。

最后,我们不能提及负载测试而不谈论如何衡量负载测试的影响,这让我们回到遥测。 我们对 OpenTelemetry 的潜力感到非常兴奋,并希望很快能够实现更全面的实施。 即使没有完全实施,我们的目标也是能够运行测试,衡量其影响,并根据数据告诉我们的情况做出运营决策。

与往常一样,我们欢迎您的请求问题评论。 我们对 MARA 的目标是激励社区共同讨论、尝试、测试和迭代不同的潜在解决方案,以加深我们对如何最好地部署和管理现代应用的理解。

相关文章

这篇文章是系列文章的一部分。 随着我们不断增加 MARA 的功能,我们会在博客上发布详细信息:


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”