Kubernetes-GitOps-实现指南-全-

Kubernetes GitOps 实现指南(全)

原文:annas-archive.org/md5/f6f117c1e7c6b5c4adc43265af5cd587

译者:飞龙

协议:CC BY-NC-SA 4.0

序言

你好!

在快速发展的软件开发领域,保持部署的一致性、可扩展性和可靠性是一个重大挑战。GitOps 作为一种革命性的方式,弥合了开发与运维之间的鸿沟,尤其是在 Kubernetes 环境中。通过将 Git 作为系统和应用配置的唯一可信来源,GitOps 自动化并标准化了部署,确保部署过程一致、可审计且高效。

GitOps 利用版本控制、基础设施即代码和持续部署的原则,创建无缝透明的工作流。这种方法不仅简化了运维工作,还增强了团队协作并加快了交付速度,使团队可以将更多精力集中在创新上,而不是处理突发问题。

本书《使用 GitOps 实现 Kubernetes:在 AWS 和 Azure 上自动化、管理、扩展和保护基础设施与云原生应用》旨在提供一份全面的 GitOps 掌握指南。通过实际案例、逐步教程和行业专家的见解,我们将探讨如何在 Kubernetes 部署中有效实施 GitOps 实践。

我们的旅程从介绍 GitOps 的核心概念和原则开始。我们将深入探讨 Argo CD、Flux CD、Helm 和 Kustomize 等工具的技术细节,以及它们如何与 Kubernetes 集成。接下来,我们将讨论一些高级主题,如多集群管理、安全性和可扩展性,确保你对 GitOps 有全面的理解。

基于我们在云架构和 DevOps 实践方面的丰富经验,我们将分享已在多个行业中验证过的真实场景和最佳实践。通过本书的学习,你将掌握实施 GitOps 策略所需的知识和技能,无论是当前还是未来的 Kubernetes 部署,都能确保降低复杂性并提高可扩展性。

无论你是 DevOps 工程师、站点可靠性工程师、平台工程师,还是云架构师,本书将为你提供成功应对当今云原生环境所需的工具和见解。让我们一起踏上这段旅程,解锁 GitOps 在 Kubernetes 部署中的全部潜力。

本书适合的读者

使用 GitOps 实现 Kubernetes:在 AWS 和 Azure 上自动化、管理、扩展和保护基础设施与云原生应用 旨在为那些希望提升使用 GitOps 原则部署和管理 Kubernetes 环境的专业人士提供指导。

本书的主要读者包括以下群体:

  • DevOps 工程师:负责管理和自动化应用程序及基础设施部署的专业人士。本书将为他们提供先进的 GitOps 技术,以简化工作流,减少部署错误,并确保环境间的一致性。

  • 站点可靠性工程师(SRE):专注于维护应用程序可靠性和性能的工程师。本书将提供如何将 GitOps 集成以提高可观察性、自动恢复和高效扩展 Kubernetes 集群的洞见。

  • 平台工程师:构建和维护支持应用开发与部署的底层平台的人员。他们将学习如何实施 GitOps 以管理基础设施作为代码,确保平台的健壮性、可扩展性和安全性。

  • 云工程师:与云平台打交道、需要管理复杂 Kubernetes 环境的工程师。本书将教他们如何利用 GitOps 自动化部署、管理多云环境并优化云资源利用。

  • 软件工程师:希望更好理解部署过程并参与基础设施管理的开发人员。本书将为他们提供全面的 GitOps 实践知识,使他们能与运维团队更高效地协作。

  • 解决方案架构师:负责设计和实施技术解决方案的专业人员。他们将更深入地理解如何将 GitOps 融入其架构设计,确保解决方案的可扩展性和可维护性。

  • IT 领导者和经理:负责在组织中实施 DevOps 和云原生策略的领导者。本书将帮助他们理解 GitOps 的好处,指导他们在团队中做出关于采纳和扩展 GitOps 实践的明智决策。

本书的目标读者理应具备以下背景:

  • 云计算知识:读者应具备基础的云计算概念和环境理解,因为 GitOps 实践通常涉及将应用程序部署到云平台上。

  • 持续集成和持续部署(CI/CD)原则的熟悉度:对 CI/CD 原则的基本理解至关重要,因为 GitOps 建立在这些方法论基础上,自动化并简化了部署过程。

  • 基本的 Kubernetes 理解:具备 Kubernetes 的相关经验会非常有帮助,因为本书深入探讨了如何将 GitOps 与 Kubernetes 环境集成。读者应熟悉 Kubernetes 的基本概念,如 Pod、服务和部署。

  • 版本控制系统的经验:由于 GitOps 依赖于 Git 进行版本控制,读者应具备 Git 或类似版本控制系统的经验。这包括理解分支、合并和管理代码库。

  • DevOps 工具和实践:熟悉如 Docker、Helm 等 DevOps 工具将帮助读者更高效地掌握本书中讨论的高级主题。

到本书结束时,读者将掌握实施 GitOps 策略所需的知识和实际技能,确保在 Kubernetes 部署中减少复杂性、提高可扩展性和改善操作效率。

本书涵盖的内容

第一章GitOps 简介,提供了 GitOps 的基础理解,探讨了其原则以及它如何转变现代软件开发中的文化、工作流和思维方式。

第二章使用 GitOps 导航云原生操作,深入探讨了如何使用 GitOps 实践构建和管理容器化应用,涵盖 Kubernetes 基础、容器镜像优化和云原生管道等主题。

第三章与 Git 和 GitHub 的版本控制和集成,阐述了 Git 和 GitHub 在 GitOps 中的关键作用,提供了有关有效版本控制和协作开发实践的见解。

第四章使用 GitOps 工具的 Kubernetes,探讨了各种 GitOps 工具,如 Helm、Kustomize、Argo CD 和 Flux CD,详细介绍了它们与 Kubernetes 的集成,并提供了比较分析,帮助选择适合特定需求的工具。

第五章GitOps 的规模化和多租户,讨论了针对规模化部署和管理多集群环境的高级 GitOps 实践,包括有效的 Git 仓库管理策略和为 Kubernetes 构建服务目录。

第六章GitOps 架构设计与操作控制,重点介绍了 GitOps 的架构框架和操作方法,强调在云原生部署中的可扩展性、弹性和效率。

第七章IT 文化转型以拥抱 GitOps,重点讨论了采用 GitOps 所需的文化转变,涉及基础设施即代码、不可变基础设施、DORA 指标以及克服组织抗拒的原则。

第八章在 OpenShift 中使用 GitOps,深入探讨了在 Red Hat OpenShift 环境中应用 GitOps 原则,包括设置 GitOps 工作流、利用 OpenShift 的 CI/CD 工具以及保护 GitOps 管道。

第九章Azure 和 AWS 部署中的 GitOps,介绍了在 Azure 和 AWS 生态系统中实施 GitOps 实践,详细阐述了集成云原生工具和服务,以简化应用和基础设施管理。

第十章基础设施自动化的 GitOps —— Terraform 和 Flux CD,深入探讨了如何通过 Terraform 和 Flux CD 集成自动化基础设施管理,涵盖了版本控制、多环境管理和高级自动化技术。

第十一章在 Kubernetes 上使用 GitOps 部署实际项目,提供了一个动手实践指南,介绍了如何使用 GitOps 和 Kubernetes 执行实际项目,从设置开发环境到设计、开发和部署可扩展的应用程序。

第十二章GitOps 可观察性,探讨了将可观察性实践集成到 GitOps 工作流中的方法,涵盖了 SRE 原则、内部与外部可观察性、SLO 驱动的性能和高级监控技术。

第十三章GitOps 安全性,讨论了 GitOps 的安全方面,包括加固声明式 CD、实现政策即代码、管理密钥、维护平台目录和自动化安全扫描。

第十四章GitOps 的 FinOps、可持续性、AI 和未来趋势,突出了将 FinOps 与 GitOps 融合,实现可持续和成本效益的运营,涉及成本预测、优化、碳足迹评估、AI 驱动的自动化以及 GitOps 未来的趋势。为了充分发挥本书的价值

为了充分发挥本书的价值,读者应具备云计算和 DevOps 原则的基础知识。熟悉 Kubernetes 和容器化技术(如 Docker)是必需的。具备版本控制系统的经验,特别是 Git,将对 GitOps 有很大帮助,因为 GitOps 严重依赖这些工具。基本了解 CI/CD 流水线和基础设施即代码的概念也将帮助读者理解本书中涉及的高级主题。

本书提到的软件/硬件 操作系统要求
Kubernetes Windows、macOS 或 Linux
Git Windows、macOS 或 Linux
Docker Windows、macOS 或 Linux
Argo CD Windows、macOS 或 Linux
Flux CD Windows、macOS 或 Linux
Helm Windows、macOS 或 Linux
Kustomize Windows、macOS 或 Linux
Terraform Windows、macOS 或 Linux
Azure Kubernetes Service (AKS) Windows、macOS 或 Linux
AWS Elastic Kubernetes Service (EKS) Windows、macOS 或 Linux
OpenShift Windows、macOS 或 Linux

本书提供了完成每一章所需的所有必要指令。提供了逐步的指南,确保顺利的设置和实现过程。本书中讨论的示例和项目的源代码已上传到公开的代码库。请参阅下一页获取代码库链接和更多详细信息。

如果你正在使用本书的数字版,我们建议你自己输入代码,或从本书的 GitHub 仓库获取代码(下节中会提供链接)。这样做可以帮助你避免因复制粘贴代码而可能导致的错误。

下载示例代码文件

你可以从 GitHub 上下载本书的示例代码文件,网址是 github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes。如果代码有更新,它将会在 GitHub 仓库中更新。

我们还有来自丰富书籍和视频目录中的其他代码包可供下载,访问 github.com/PacktPublishing/。快去看看吧!

使用的约定

本书中使用了许多文本约定。

文本中的代码:表示文本中的代码词汇、数据库表名、文件夹名称、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名。举个例子:“在 optimization/opencost 下有全球定义的值,然后为每个特定国家有一个自定义定价模型。”

代码块的格式如下:

helm repo add sealed-secrets https://bitnami-	labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets
#Install e.g. CLI on MacOS
brew install kubeseal

当我们希望引起你对某个代码块中特定部分的注意时,相关的行或项目会以粗体显示:

clusterName: "aks-excelsior-development-2"globalConfig:  chat_gpt_token: sk-dw******  signing_key: ea657a******  account_id: 7935371f******sinksConfig:- slack_sink:    name: main_slack_sink     slack_channel: pocs     api_key: xoxb******- robusta_sink:    name: robusta_ui_sink     token: eyJhY2NvdW******enablePrometheusStack: true # This part is added to the default generated_values.yaml enablePlatformPlaybooks: true runner:  sendAdditionalTelemetry: true rsa:  private: ******  public: ******# This part is added to the default generated_values.yaml playbookRepos:  chatgpt_robusta_actions:    url: "https://github.com/robusta-dev/kubernetes-chatgpt-bot.git"# This part is added to the default generated_values.yaml customPlaybooks:# Add the 'Ask ChatGPT' button to all Prometheus alerts - triggers:  - on_prometheus_alert: {}  actions:  - chat_gpt_enricher: {}

任何命令行输入或输出格式如下:

$ aws eks --region eu-central-1 update-kubeconfig --name eksgitopscluster

粗体:表示新术语、重要词汇或你在屏幕上看到的词汇。例如,菜单或对话框中的词汇会以粗体显示。举个例子:“当常见漏洞和暴露CVE)被揭示时,如果你选择驾驶舱和舰队方法,采用 GitOps 大规模管理也有助于实施大规模的漏洞管理策略。”

提示或重要注意事项

看起来像这样。

联系我们

我们非常欢迎读者的反馈。

一般反馈:如果你对本书的任何方面有疑问,请通过 customercare@packtpub.com 给我们发送电子邮件,并在邮件主题中提到书名。

勘误:尽管我们已尽力确保内容的准确性,但错误总是难以避免。如果你在本书中发现任何错误,我们将非常感谢你向我们报告。请访问 www.packtpub.com/support/errata 并填写表单。

盗版:如果你在互联网上发现我们作品的任何非法副本,无论何种形式,我们将非常感激你提供其位置地址或网站名称。请通过 copyright@packt.com 与我们联系,并附上相关链接。

如果你有兴趣成为作者:如果你在某个领域有专长,并且有兴趣写书或为书籍做贡献,请访问 authors.packtpub.com

分享你的想法

一旦你阅读了 实施 Kubernetes 中的 GitOps,我们很想听听你的想法!请 点击此处直接访问 Amazon 书评页面并分享你的反馈。

你的评论对我们和技术社区非常重要,它将帮助我们确保提供卓越的高质量内容。

下载本书的免费 PDF 版

感谢购买本书!

你喜欢在旅途中阅读,但又无法随身携带纸质书籍吗?

你的电子书购买是否与你选择的设备不兼容?

不用担心,现在购买每本 Packt 图书,你都可以免费获得该书的无 DRM PDF 版本。

在任何地方、任何设备上阅读。直接在应用程序中搜索、复制并粘贴你喜欢的技术书籍中的代码。

福利不止于此,你还可以获得独家折扣、新闻通讯和每日送达的优质免费内容。

按照以下简单步骤获取福利:

  1. 扫描二维码或访问以下链接

packt.link/free-ebook/9781835884225

  1. 提交你的购买凭证

  2. 就这些!我们会将你的免费 PDF 和其他福利直接发送到你的电子邮箱

第一部分:通过简化的编排/Kubernetes 理解 GitOps

在本部分,你将探讨 GitOps 的基础知识。从广泛的概述开始,你将了解 GitOps 如何成为现代软件开发和平台工程中的关键实践。我们将深入探讨如何进行云原生操作,强调 Git 和 GitHub 的集成,以实现有效的版本控制。此外,你将使用 Kubernetes 和各种 GitOps 工具来简化部署过程,全面理解这些技术如何互联互通,以简化和增强软件的部署与管理。

本部分包括以下章节:

  • 第一章,GitOps 简介

  • 第二章,通过 GitOps 导航云原生操作

  • 第二章,版本控制与 Git 和 GitHub 的集成

  • 第四章,使用 GitOps 工具的 Kubernetes

第一章:GitOps 简介

在本章的开篇,我们将深入探讨 GitOps,这种革新的方法正在改变软件开发和运营的方式。本章的开头讲述了 GitOps 的来龙去脉,重点关注它对组织文化和工作流程的转变影响。GitOps 基础 部分概述了其核心原则,如 Git 的集中管理、声明式方法和自动同步。传统 CI/CD 与 DevOps 对比 GitOps 追溯了软件部署的演变过程,将 GitOps 置于该领域更广泛的历史背景中。本章还对比了传统的 CI/CD 和 DevOps 方法论与 GitOps,突出 GitOps 作为管理复杂系统的一种进化。我们将总结讨论在平台工程中采用 GitOps 的优势,同时说明它的效率、一致性和适应性。

本章节将涵盖以下主题:

  • 揭示 GitOps - 重塑开发文化和实践

  • GitOps 的基本原理以及在平台工程中采用它的优势

  • 为什么选择 GitOps?

  • GitOps、IaC 和 Kubernetes 的集成

技术要求

若要跟进本章内容,您需要对 版本控制基础设施即代码IaC)、持续集成CI)、持续交付CD)和 Kubernetes 有基本的了解。熟悉主要云服务提供商如 Google Cloud PlatformGCP)、AWS 和 Azure 也会有所裨益。

揭示 GitOps - 重塑开发文化和实践

在现代软件开发和运营领域,GitOps 出现为各种思想和实践的交汇点,重新定义了管理复杂系统的方法。

GitOps 这个术语最早由 Alexis Richardson 提出,他是 Weaveworks 的联合创始人,通过一系列博客文章于 2017 年 8 月首次引入。Richardson 将 GitOps 描述为一种方法论,其中开发者工具在推动运维流程中至关重要。这种方法强调使用声明性工具的重要性,并倡导将配置视为代码的最佳实践。因此,这些配置应该受到版本控制的管理,与 GitOps 的核心原则保持一致。

这一创新理念标志着软件开发和 IT 运营团队在管理基础设施和应用程序的方式上发生了变革,推动了更高效、透明和可靠的流程。

GitOps 是一个突破性的范式,改变了软件开发和运维团队管理和部署应用程序及基础设施的方式。其核心思想是将广泛使用的版本控制系统 Git 作为声明性基础设施和应用程序的唯一真理源。

版本控制,也称为源代码管理,是一种记录文件或文件集随时间变化的系统,使您能够稍后调用特定的版本。它允许多人同时在同一文档上工作,版本控制系统提供了一种管理多人之间变更的方式。

传统 CI/CD 与 DevOps 对比 GitOps

在传统的 IT 运维中,如图 1.1所示,开发团队定期将新版本的软件交给质量保证QA)团队。该团队对软件进行测试,然后交给运维团队进行部署。

随着软件发布周期的缩短,传统的运维模型难以跟上步伐。运维团队负责为新版本的软件配置基础设施,同时专注于系统的可靠性、弹性和安全性:

图 1.1 – 传统 IT 运维工作流示例

图 1.1 – 传统 IT 运维工作流示例

在没有先进框架的情况下管理基础设施可能会变得复杂,需要专业的知识。IT 运维涵盖了 IT 员工为满足企业技术需求提供的所有过程和服务。这包括处理维护工作和应对客户问题。在传统模型中,开发、QA 和运维团队往往在不同的管理结构下工作,因此详细的交接过程和完善的文档至关重要:

图 1.2 – 分离团队的传统组织模型

图 1.2 – 分离团队的传统组织模型

传统的组织模型,特点是团队之间明确分离,往往会使交付过程复杂化。这种分离通常导致部署速度变慢和部署频率降低。此外,团队之间任务的交接增加了沟通不畅的风险,这可能导致测试疏漏和部署错误。

大多数开发团队使用自动化构建系统和 CI 来编译、测试和生成可部署的工件。

CI 是现代软件开发中的基础过程,它自动化了构建、测试和打包应用程序的过程,如图 1.3所示:

图 1.3 – CI 工作流示例

图 1.3 – CI 工作流示例

在这一系统中,软件工程师经常将代码更改提交到中央代码库(例如Git 仓库),这些更改会自动构建、测试并准备好与主代码分支进行集成。这种方法确保软件始终处于可以部署到生产环境的状态,强调了持续集成(CI)在保持软件开发持续流动中的重要性。

CI 的自动化流程对于确保代码在与主分支合并之前的质量和完整性至关重要。通过自动化这些阶段,CI 最小化了与人为错误相关的风险,并加快了开发周期。然而,过程通常在部署阶段停止,许多组织的这一环节仍然是人工的。人工部署可能涉及复杂的程序或半自动化脚本,且通常需要运维工程师在服务器上物理地转移和重启应用程序。这种人工干预容易出错,缺乏强有力的控制机制,使得其效率低下且具有风险。

在 CI 的基础上,CD 将自动化推进了一步:

图 1.4 – CD 工作流示例

图 1.4 – CD 工作流示例

CD 是一种实践,在这种实践中,代码更改在通过 CI 的构建和测试阶段后,自动准备并可以发布到生产环境。它始终保持软件处于发布就绪状态,极大简化了更新和新特性发布的流程。

CD 与持续部署

CD 和持续部署是软件开发中的密切相关实践,旨在简化发布流程。CD 确保每次代码更改都被自动构建、测试并准备好发布,从而允许手动部署到生产环境。持续部署更进一步,自动将每个通过测试的更改直接部署到生产环境中,消除了手动步骤。这加速了发布流程,但要求对自动化和测试协议有高度的信任。

CD 不仅通过启用较小且频繁的更新来减少与发布相关的风险,这些更新比大型且不频繁的更新更易于管理,而且它还显著缩短了通常需要的长时间测试周期,特别是在大规模代码更改的情况下。这种方法增强了开发、运维和其他团队之间的协作,使各方朝着快速且高效交付高质量软件的共同目标迈进。CD 有效地管理并缓解了与大规模代码修改相关的潜在风险,推动了更加灵活和响应迅速的软件开发生命周期。

CD 使企业能够快速适应市场变化和客户反馈,在创新和客户满意度上保持竞争优势。

DevOps 标志着组织框架和思维方式的重大转变,着重强调自动化。从本质上讲,DevOps 作为一种粘合剂,将 CI/CD 的技术高效性与组织的战略目标结合在一起。它强调在整个开发过程中持续的反馈、监控和优化,确保部署后的持续改进。这种方法确保软件开发不仅仅是一个以部署为终点的线性过程,而是一个循环过程,其中反馈和性能数据会反哺开发过程。

GitOps 是一种影响力巨大的运营模型,它在 DevOps 的核心实践基础上发展,将其应用于基础设施自动化。它整合了版本控制、协作工作、遵守合规标准以及使用 CI/CD 工具等基本原则。这一策略有助于有效且可靠地管理 IaC 过程。

通过将 DevOps 集成到 CI/CD 管道中,组织可以创造一个更加整体、高效和协作的环境。这不仅加速了创新和交付的步伐,而且显著提升了产品质量和客户满意度,使组织在日益发展的数字化环境中保持竞争力。

在这种模型中,部署和运营的传统角色从运营团队转移到应用程序的开发团队。DevOps 将软件开发Dev)与 IT 运营Ops)集成,旨在缩短整体系统开发生命周期。这种整合促进了功能、修复和更新的频繁交付,确保它们与业务目标紧密对接。

以下是采纳 DevOps 的一些关键优势:

  • 加强开发和运营团队之间的协作

  • 提高开发产品的质量

  • 发布频率的提高

  • 缩短将新功能推向市场的时间

  • 降低设计、开发和运营过程中的成本

  • 降低平均恢复时间MTTR),增强系统的韧性并最小化中断的影响

从 DevOps 到 GitOps 的演变代表了追求更高效、更可靠的软件开发和运营实践的自然进展。DevOps 旨在打破软件开发与运营之间的障碍,培养合作和持续改进的文化,而 GitOps 通过围绕 Git 版本控制系统构建整个运营工作流,将这一点进一步深化。GitOps 将 Git 作为声明式基础设施和应用程序的唯一真理来源。

降低 MTTR

减少 MTTR 指的是改善 DevOps 研究与评估 (DORA) 指标中的一个关键指标,即恢复系统或服务故障或中断的平均时间。这个指标对于理解和增强 IT 运维的弹性和可靠性至关重要。通过减少 MTTR,组织可以确保在出现中断后,系统能够更快恢复,最大限度地减少对用户和业务运营的影响。这一改进通常通过更有效的事件管理流程、自动化和更好的故障处理准备来实现。

这种方法不仅简化了部署和管理过程,还提高了透明度、问责制和可重现性。

从 DevOps 到 GitOps 的过渡是由在管理复杂和动态的云原生环境中对更高自动化、一致性和安全性的需求所驱动的。

GitOps 通过利用 Git 强大的版本控制功能来自动化部署过程,这意味着系统中的每一个更改都可以被跟踪、回滚,并经过同行评审过程,就像软件开发中的代码更改一样。这一转变将软件开发的严谨性和精确性带入了运维领域,大大减少了人为错误的可能性,并提高了生产环境的稳定性和安全性。

此外,GitOps 与当今云环境中流行的容器化和微服务架构完美契合,使得企业能够实现更快速、更高效的部署管道,这对于在快速变化的数字环境中保持敏捷和响应能力至关重要。

在本章接下来的部分,我们将深入探讨采用 GitOps 的好处。我们将探讨为什么应该使用它、它与 Kubernetes 的集成以及与 Argo CD 和 Flux CD 等工具的结合。

GitOps 的基本原理及其在平台工程中采用的优势

DevOps 是对这些孤岛现象的回应,融合了开发和运维的角色。它将 CI/CD 原则扩展到包括文化转变,促进协作,旨在打破开发人员和 IT 运维之间的隔阂。重点是对软件生命周期的整体性方法,确保开发和运维的考虑从一开始就得到集成。DevOps 采用了如 IaC 和监控等实践,营造了一个更具响应性和敏捷性的环境。

GitOps 是一种较新的创新,建立在这些基础上,但引入了一个重要转变:它将 DevOps 和 CI/CD 的原则集中在 Git 仓库周围。

在 GitOps 的故事中,如图 1.5所示,一切从一个 Git 仓库开始,其中存储并版本控制着系统的完整状态——代码、配置、环境设置,甚至文档。这种方法允许高水平的透明度、可追溯性和审计性,因为每次更改都会被记录,并可以追溯到某个提交:

图 1.5 – 一个包含 DevOps 的 GitOps 管道示例

图 1.5 – 一个包含 DevOps 的 GitOps 管道示例

在 GitOps 中,Git 不仅仅是一个版本控制系统;它是应用代码和基础设施配置的唯一真实来源。这种方法利用了 Git 的优势——如版本控制、协作功能和拉取请求工作流——来管理整个部署和运营过程。GitOps 强调声明式方法,即系统的期望状态在 Git 中定义,自动化过程确保实际状态与期望状态一致。

从应用代码到基础设施配置,所有内容都存储在 Git 仓库中。这样的集中化不仅简化了管理和追踪变更的过程,还确保了开发和部署各个阶段的一致性和透明度。

在 GitOps 场景中的工作流优雅地实现了自动化且高效。开发人员通过拉取请求提交更改,随后这些更改将经过自动化测试和审查。一旦获得批准,这些更改会自动部署到生产环境,符合前面提到的 CI/CD 原则。

拉取请求

拉取请求是版本控制系统中的一项功能,特别是在 Git 中,它促进了软件开发中的协作。作为一个检查点,拉取请求允许开发人员通知其他人他们已经推送到托管服务(如 GitHub 或 GitLab)上仓库中的更改。在推送包含更新的分支后,开发人员可以发起拉取请求,将这些更改合并到主分支中。这个过程邀请其他人对提议的更改进行审查和讨论,确保代码在合并之前经过协作审查和优化,从而提高了代码质量并促进了团队成员之间的共享理解。

这种自动化不仅简化了部署过程,还显著减少了人为错误的可能性。此外,由于整个系统的状态都受到版本控制,因此在出现问题时,回滚到先前的状态变得非常简单。

这个过程通常被称为以 Git 为中心,它使团队能够使用与代码开发相同的工具和流程来管理基础设施和应用程序,从而为软件交付带来统一的方法。

GitOps 代表了从传统实践到现代方法的重大进化,它利用了 Git、自动化和声明式模型的优势。这一方法为实现 DevOps 文化提供了框架,提供了一种与各种工具(如 Kubernetes 和 CI/CD 解决方案)兼容的通用方法。

GitOps 工作组通过其定义的 GitOps 原则支撑了这一方法,强调声明式配置、版本化和不可变状态、自动拉取和持续协调的重要性。

随着我们进一步探讨,这些基础原则将通过实际示例加以说明,展示采用 GitOps 思维方式在平台工程中的现实影响和优势。

为什么选择 GitOps?

采用 GitOps 进行平台工程带来了众多优势,重新塑造了团队与基础设施和应用程序的互动方式。这一方法利用了 Git、自动化和声明式配置的优势,为管理复杂系统提供了强有力的框架。以下是一些关键的好处:

  • 声明式与不可变特性:GitOps 关注于声明系统的期望状态,而不是详细说明命令式脚本。它采用不可变基础设施的方法,通过替换资源而不是修改现有资源来进行变更,从而增强一致性和稳定性。

  • 自动化同步:GitOps 的核心在于自动同步系统状态与 Git 中描述的配置,涵盖了基础设施和应用程序的整个生命周期,包括部署、更新、扩展和恢复。

  • 拉取请求工作流集成:GitOps 中的操作流程与拉取请求工作流深度集成,体现了将一切视为代码的理念。这种集成有助于代码审查、协作讨论、共享知识和责任。

  • 持续反馈与监控:GitOps 强调持续监控,以检测并修正任何与期望状态的偏差,促进持续的系统维护和改进。

  • 提高效率与生产力:通过自动化平台工程的各个方面,GitOps 减少了人工操作和人为错误,使团队能够更多地专注于创新。

  • 提高一致性与可靠性:将 Git 作为唯一的真实数据源,并采用声明式配置,确保了在不同环境中的基础设施一致性和可靠性。

  • 更快的恢复与回滚:GitOps 使得快速回滚到先前状态成为可能,增强了系统的弹性并加速了从故障中的恢复。

  • 协作与透明性:该方法鼓励协作平台工程,通过同行评审和讨论促进知识共享和透明性。

  • 简化的审计与合规性:所有更改都在 Git 中追踪,简化了审计过程,并便于遵循监管要求和内部政策的合规性。

  • 可扩展性和灵活性:GitOps 能够高效地随组织需求进行扩展,并适应各种类型的基础设施,包括云、内部部署和混合环境。

  • 增强的安全性:使用拉取请求和代码审查增加了额外的安全层,确保对基础设施和应用程序的更改进行彻底审查。

  • 简化的入职和知识共享:Git 仓库提供了系统当前状态的清晰概览,有助于新团队成员的入职,并促进知识共享的环境。

  • 持续改进与适应:GitOps 固有的反馈循环和监控使团队能够迭代地改进系统,并适应变化的需求。

采用 GitOps 对公司来说会带来一些挑战,这些挑战可能会影响公司向这种方法论的过渡。首先,存在学习曲线,需要针对 Kubernetes、Helm 或 Argo CD 等特定工具进行培训,这可能会暂时降低生产力。实施 GitOps 还需要在文化上发生转变,要求严格的代码管理和 CI/CD 实践。初期的设置和集成过程可能复杂且耗时,需要在时间和资源上进行大量投入。

此外,有效组织 Git 仓库结构至关重要,因为它直接影响部署的可管理性和可扩展性。如果管理不善,可能会导致运营效率低下和错误增加。另一个关键方面是秘密管理;GitOps 工作流要求小心处理敏感数据,以防止安全漏洞。必须实施适当的策略来安全存储、访问和管理 GitOps 过程中的秘密,以确保自动化部署保持安全高效。

在本节中,我们重点介绍了采用 GitOps 进行平台工程的显著优势和挑战。这种方法论利用 Git、自动化和声明式配置的优势,提供了一个强大的框架来管理复杂的系统。下一节将介绍 GitOps、IaC 与 Kubernetes 的集成。

GitOps、IaC 与 Kubernetes 的集成

在本节中,我们将深入探讨 GitOps、IaC 和 Kubernetes 的复杂集成,以及诸如 Argo CD 和 Flux CD 等关键工具。我们将探索这种紧密结合如何增强云原生操作,简化部署流程并加强安全性,从而彻底改变基础设施管理和应用程序部署的方式,特别是在现代软件开发环境中。

GitOps 与 IaC

IaC 通过代码而非手动程序来管理和提供基础设施。该方法包括创建配置文件,详细说明您的基础设施需求,从而简化修改和传播这些配置的过程。IaC 保证每次都能一致地提供相同的环境,同时将配置规范转化为编码文档,从而改进配置管理。

这种方法有助于避免没有文档记录的、临时的配置更改。

GitOps 将熟悉的 Git 版本控制系统扩展到基础设施和部署管理,并与 IaC 原则紧密对接。这个集成允许开发人员像管理软件开发过程一样管理基础设施配置和代码部署,带来诸多优势:

  • 加速生产时间:更快速的基础设施提供,减少人为错误,导致更加可预测的结果。

  • 基于模板的可重用性:将 IaC 配置文件作为模板,提供进一步相关配置的基准。

  • 统一部署:实现一致的基础设施部署,避免那些可能导致未来重大问题的小差异。

  • 可追溯性和可审计性:将 IaC 与代码库集成以进行源代码追踪,提供详细的变更历史记录,包括版本控制和审计轨迹,识别是谁在何时进行了更改。

  • 增强的组织知识:版本控制记录了更改背后的理由,成为新员工和现有员工的重要资源。

  • 改进的灾难恢复:IaC 确保在发生故障时能够快速重建环境,最小化停机时间和业务中断。

GitOps 和 Kubernetes

GitOps 和 Kubernetes (kubernetes.io/docs/concepts/overview/) 在现代软件开发和基础设施管理领域形成了强大的组合。Kubernetes 是一个开源平台,用于自动化跨主机集群部署、扩展和操作应用容器的过程,为管理大规模容器化应用提供了坚实的基础。而 GitOps 则是一个操作框架,将 Git 的原则——版本控制、协作和合规性——应用于基础设施自动化。两者结合时,GitOps 和 Kubernetes 提供了一个高效、可扩展和可靠的系统,用于管理复杂的应用和基础设施。

Kubernetes 已成为编排容器化应用程序的关键工具,提供了自动化发布和回滚、服务发现与负载均衡(它能够为 Pods 和服务分配 IP 地址以实现负载均衡)、存储编排、以及在不暴露密钥或不需要重建 Docker 镜像的情况下进行机密和配置管理等功能,并具备自愈机制,如重新启动失败的容器和在节点出现问题时重新调度 Pods。

此外,Kubernetes 支持基于 CPU 使用情况的横向扩展,并且以声明式方式操作。这些功能随着每次 Kubernetes 发布而不断发展。

GitOps 与 Kubernetes 的融合显著加快并提高了部署过程的效率。这个组合通过启用 CD 自动化并集成必要的反馈和控制系统,促进了更频繁的部署。通过使用 Git 的声明式定义,开发人员可以采用知名的工作流,这简化了创建新开发或测试环境以及将新功能部署到集群的能力。因此,这导致了每日变化的频率增加,加速了新功能和功能交付给最终用户。

GitOps 还使团队能够变得更加自给自足。传统上,开发团队依赖运维团队将变更部署到生产环境中。GitOps 改变了这种动态,允许开发团队在部署和管理生产环境中的代码和配置变更时,减少对平台和运维团队的依赖。只需将更改提交到 Git 仓库并合并拉取请求,就可以通过 GitOps 工具触发其余的过程。这种自服务特性提高了效率和战略能力。

GitOps 通过将 Git 作为声明式配置的真实来源,提升了部署和基础设施管理的能力。在声明式系统中,重点是定义期望的结果,而不是实现它的步骤。这种方法与命令式方法不同,后者涉及指定一系列步骤,通常会增加操作人员的额外工作负担。在 GitOps 中,环境的每个组件都可以在 Git 仓库中进行编码和声明。一旦进行更改并提交到 Git,系统会自动处理这些声明,以创建或更新必要的对象。

与 Kubernetes 的声明式特性无缝集成,是 GitOps 真正发挥作用的地方。Kubernetes 在协调循环中操作,持续调整集群的实际状态,以匹配其配置定义的期望状态。当检测到当前状态与期望状态之间的差异时,Kubernetes 会采取自动措施以协调这些差异。这可能涉及创建、更新或删除资源,以确保集群的配置与 Git 仓库中定义的内容一致。

GitOps 与 Kubernetes 协调循环的结合提供了一个强大的自动化系统管理框架。这确保了所有系统组件根据 Git 中定义的精确配置一致地部署,遵循完全声明式的方法,简化操作,提高可靠性,并保持开发、预发布和生产环境之间的一致性。

可观察性是 GitOps 在 Kubernetes 环境中的另一个关键方面。它涉及持续监控集群中实际的状态,并与期望的状态进行比较。GitOps 帮助衡量和监控集群中运行的内容,并提醒团队任何不一致之处。现代 GitOps 工具有监控和通知功能,以支持这一功能。

合规性与审计 的角度来看,GitOps 提供了显著的优势。以 Git 作为唯一的事实来源,审计变得简单:审计员可以通过检查源代码库来评估期望的状态,并通过查看底层基础设施提供商和 Kubernetes 集群状态来验证当前状态。这简化了跨各种领域的合规性和审计流程。

对于那些为不同业务和团队需求使用 多个 Kubernetes 集群 的组织来说,管理这些集群并保持一致的配置和安全策略是一项重大挑战。GitOps 通过允许跨这些集群运行的 GitOps 代理代替运维团队管理一切,从而解决了这一问题,使其成为多集群配置管理的理想解决方案。

灾难恢复DR)对于组织从中断业务运营的事件中迅速恢复至关重要,主要目标是快速恢复关键系统和 IT 基础设施。从 GitOps 的角度来看,DR 主要处理配置管理,而非数据恢复。这个区别非常重要,因为虽然配置保存在 Git 中,但实际数据并不在其中。像 Git 这样的工具对于配置的版本控制非常有用,但不支持数据恢复。例如,如果数据库被删除,Git 无法帮助恢复它;因此,需要单独的数据恢复策略,专门用于恢复丢失的数据。

在 Kubernetes 生态系统中,使用 GitOps 自动化基础设施配置的趋势正在上升。这包括部署、服务和各种 Kubernetes 实体的创建。DevOps 和 站点可靠性工程SRE)团队越来越多地转向 GitOps 来管理所有基础设施配置文件作为代码。这种方法利用了 GitOps 固有的基础设施即代码(IaC)特性。

此外,GitOps 还增强了 安全 协议。它在 Git 中使用复杂的加密方法来监视和管理变更,还可以验证变更以确认作者和来源。这种实践确保了集群的安全定义状态。在安全漏洞发生时,Git 的不可变性和审计性质使得可以重建一个与受损系统分离的系统,从而最大程度地减少停机时间并提高事件响应的效率。

软件打包和发布到生产环境中的责任分离实践进一步遵循最小特权原则,降低了安全漏洞发生的可能性和严重性,并提供了更小的攻击面。

GitOps 通过确保整个基础设施环境和组件在 Git 仓库中以声明方式定义,促进了这一过程。在灾难事件发生时,只需从 Git 中重新应用配置文件,快速恢复生态系统。

Kubernetes 和 Argo CD

Argo CD 是针对 Kubernetes 的 GitOps CD 工具 (argo-cd.readthedocs.io),是一个声明性工具,专为 Kubernetes 的持续交付而设计。它可以作为独立解决方案运行,也可以集成到现有的 CI/CD 流水线中,以高效地在 Kubernetes 集群中部署必要的资源。

使用 Argo CD 将 GitOps 与 Kubernetes 集成,为在 Kubernetes 上管理云原生应用程序和作业提供了一种简化的方法。Argo CD 是 Argo 项目系列的一部分,提供了一套工具,包括 Workflows、Events 和 Rollouts,这些工具增强了 Kubernetes 原生应用程序的交付能力。对于转向容器化环境和 Kubernetes 部署的组织来说尤为重要,此时 Argo CD 可作为一个全面的解决方案。

在大型企业典型的大规模部署中,拥有众多开发人员和大量微服务的情况下,GitOps 方法论显得尤为突出。然而,为了有效实施,通常需要额外的工具和服务。在这样的组织中,每个团队独立运行和管理其 Kubernetes 集群并不现实。更有效的策略是在一个集中平台上操作和维护多租户集群。这种设置为团队在这些集群中管理其工作负载提供了自主权,同时仍提供集中的监视和维护。

Argo CD 在促进这种集中式集群管理方法方面发挥了关键作用,推动了 GitOps 的采用。以下是在 Kubernetes 中使用 Argo CD 创建有效 GitOps 策略时需要考虑的一些关键因素:

  • 用户入职:简化入职流程至关重要。集中部署操作员的安装、设置和维护工作,可以减轻将多个微服务迁移到 Kubernetes 的过程,而不是将这一负担交给各个团队。在用户数量庞大的系统中,采用单点登录SSO)尤为有利,能够简化新用户的引入。

  • 多租户和管理:在多租户环境中,用户需要对资源进行安全且灵活的访问。Kubernetes 的基于角色的访问控制RBAC)系统是一个强大的功能,但可能不足以管理大量集群。Argo CD 通过额外的访问控制功能增强了这一点,与 SSO 提供商无缝集成,便于访问多个集群。

  • 可观察性:有效 CD 工具的一个关键特性是使开发人员能够监控和跟踪应用程序的状态。Argo CD 的用户友好界面提供了详细的应用程序配置洞察,例如与 Git 的同步状态、特定的不同步元素和任何操作问题。

在接下来的章节中,我们将探讨 Flux CD,这是一款与 Kubernetes 集成后,能够实现可扩展性并确保各种部署类型之间环境一致性的工具。

Kubernetes 与 Flux CD

Flux(fluxcd.io)是一个开放且可扩展的 Kubernetes CD 解决方案,是现代 DevOps 生态系统中的一个关键组成部分。

在撰写本文时,Weaveworks 的首席执行官 Alexis Richardson 在 LinkedIn 上宣布,公司正面临经济挑战,将关闭并停止商业运营。Weaveworks 将与一位财务受托人合作,受托人将很快公布,以管理关闭过程。尽管公司创造了可观的收入并扩大了客户基础,这一决定仍然做出,突显了在维持运营过程中面临的财务波动和战略挑战。原始公告可在此查阅:www.linkedin.com/posts/richardsonalexis_hi-everyone-i-am-very-sad-to-announce-activity-7160295096825860096-ZS67/

作为一款 GitOps 工具,Flux 确保 Git 仓库中清单的状态与 Kubernetes 集群中的运行状态始终保持同步。GitOps 不仅仅是另一个工具,它为开发人员提供了一种使用 Git 来管理 Kubernetes 中操作工作流的方法。这种方法强调使用如 Git 这样的版本控制系统来部署 Kubernetes 中的应用程序,使开发人员能够直接将代码推送到生产环境中。更改可以轻松追踪并在必要时回滚,从而增强部署的可靠性。

以下是 Flux CD 的主要特性:

  • 版本控制仓库与集群之间的自动同步

  • 仓库变更在集群中的即时反映

  • 从仓库直接部署代码到生产环境

  • 版本控制的配置,确保所有配置都是最新的

  • 灾难恢复能力,能够以相同的配置设置新集群

在 Kubernetes 的背景下,作为强大的容器编排平台,Flux CD 起着至关重要的作用。Kubernetes 在自动化和简化应用程序部署与管理方面表现出色,尤其是在跨多种部署场景中扩展和保持一致的环境方面。Flux CD 遵循 GitOps 原则,通过不断同步应用程序和基础设施的状态与存储在 Git 仓库中的配置,加入了一层自动化和安全性。这确保了实际状态与期望状态在安全和受控的方式下保持一致。Kubernetes 和 Flux CD 之间的协同作用提供了以下几个关键优势:

  • 自动化部署:Flux CD 的自动更新和配置会被提交到 Git 仓库

  • 可扩展性和可靠性:Kubernetes 在处理容器化应用程序方面的强大能力与 Flux CD 在配置上的一致性相得益彰

  • 增强的安全性:Flux CD 将 Git 作为唯一的事实来源,增加了额外的安全层

  • 运营效率:集成优化了操作,减少了人工干预,提高了效率

总结来说,Kubernetes 与 Flux CD 的结合为现代软件部署和管理提供了全面的解决方案。它们的集成增强了自动化、可扩展性、安全性和效率,使其成为云原生技术和 DevOps 实践中不可或缺的工具。

总结

本章深入介绍了 GitOps,探讨了其对软件开发和运维的变革性影响。我们首先将 GitOps 与传统的 CI/CD 和 DevOps 方法进行了对比,突出了其独特的方法和优势。

接着,我们介绍了推动 GitOps 产生的部署策略的历史和演变。讨论了 Git 集中化、声明式方法、自动化同步和持续反馈等关键原则,强调了 GitOps 在提升平台工程效率、一致性和协作方面的作用。

此外,我们还深入探讨了 GitOps 与 Kubernetes 等工具的集成,展示了其在现代云环境中的可扩展性和安全性优势。最后,我们强调了采用 GitOps 的重要性,因为它提供了强大的框架并能适应不断变化的技术环境。

第二章中,我们将深入探讨 GitOps 在云原生环境中的实际应用,分析它与 Kubernetes 的无缝集成、轻量级 Kubernetes 发行版的架构以及云原生 CI/CD 管道的设计。

进一步阅读

要了解本章中讨论的更多主题,请查看以下资源:

第二章:使用 GitOps 导航云原生操作

第一章中,我们深入探讨了 GitOps 的基础概念,并将其方法与传统的 CI/CD 和 DevOps 方法进行了对比。我们探讨了 GitOps 的历史发展、关键原则(如 Git 集中化和自动化同步)以及其与 Kubernetes 的融合。本章将强调 GitOps 在提升现代云环境中的可扩展性和安全性方面的作用。到本章结束时,你将对 GitOps 在软件部署和操作中的变革性影响有全面的理解,为其在云原生操作中的应用打下基础。

在本章中,我们将重点讨论以下几个关键领域:

  • GitOps 与云原生技术

  • Kubernetes 简介

  • 探索 K3s 作为一种轻量级的 Kubernetes 发行版

  • 容器

  • 示例工作流——使用 Docker 和 K3s 轻松实现持续交付(CD)

技术要求

为了操作本章中的示例,你需要一个 Kubernetes 集群。虽然我们将引导你如何安装 K3s 以适应这些示例,但任何 Kubernetes 设置都可以满足需求。

K3s 已针对 Linux 系统进行了优化,因此请确保你可以访问 Linux 环境。如果你使用的是非 Linux 系统,可以考虑使用Windows 子系统 LinuxWSL)或Virtual Box(参见本章末尾的进一步阅读部分中的[1]和[2])。

本章的代码可以在本书 GitHub 仓库中的Chapter02文件夹中找到:github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

GitOps 与云原生技术融合的概述

第一章中,我们探讨了 GitOps,这是 DevOps 和 Git 的融合,强调其通过将软件开发技术应用于基础设施管理,从而提升操作效率和系统稳定性的能力。接下来,第二章基于这一基础,进一步探讨了 GitOps 如何与云原生技术融合。这项技术标志着应用开发的重大转变,具有容器化、微服务和动态编排的特点,提升了可扩展性和弹性。

GitOps 通过启用系统化、版本控制管理复杂系统,进一步补充了这一点。GitOps 与云原生技术,特别是 Kubernetes 之间的协同作用,带来了更加动态、灵活和可靠的系统管理方式。本章旨在展示 GitOps 如何简化并提升云原生环境的能力。

此外,GitOps 是从 DevOps 和版本控制的交汇处衍生出来的一种方法,它利用 Git 的强大功能来管理和自动化软件系统的部署与操作。通过将基础设施视为代码,GitOps 使得使用 Git 的常见拉取请求和合并操作来审查、版本控制和部署更改变得容易。这种方法确保了一致性、可追溯性,并且易于回滚,特别在云原生环境中具有强大的作用。

云原生技术则代表了一种关于应用程序构建和部署的范式转变。它涉及使用容器、微服务和动态编排来创建强大、可扩展且可独立部署的应用程序。这项技术最大化了云的灵活性,使得快速扩展和弹性变得可能。当与 GitOps 集成时,云原生技术变得更加强大,使团队能够更有效地管理复杂系统,并且信心倍增。

在深入了解 GitOps 的实际应用之前,首先有必要介绍 Kubernetes,这是云原生技术的核心编排平台。此外,我们还将讨论 K3s,这是一个 Kubernetes 的轻量级变体。K3s 特别适用于个人开发环境,因为它允许在单个笔记本电脑上部署 Kubernetes 集群。这种设置使得进行动手实验和学习成为可能,为理解和应用 Kubernetes 环境中的 GitOps 技巧提供了一个实用的基础。随着我们进入更高级的话题和 GitOps 实践演示,这些知识将至关重要。

Kubernetes 简介

在接下来的章节中,我们将介绍 Kubernetes,包括该项目的简要历史概述以及 Kubernetes 架构的核心概念。在第二部分,我们将深入探讨 K3s,并探索如何使用它在笔记本电脑上运行本地的 Kubernetes 集群。

什么是 Kubernetes?

Kubernetes 是一个强大且开源的平台,旨在简化应用容器的部署、扩展和管理的自动化过程。它在容器编排的领域中扮演着核心角色,提供了一个可靠的框架,能够有效地管理跨多个环境(包括物理数据中心、公有云和私有云)的容器化应用程序。

最初,Google 的 Kubernetes 项目代号为Project 7,向《星际迷航》中的“七人组”致敬,象征着一种更易接近的版本,改良自 Google 的 Borg 系统。由于许可限制,采用了“Kubernetes”这一希腊语单词,意为舵手,并体现在其七辐车轮的标志中,巧妙地向其《星际迷航》的灵感来源致敬。2014 年发布后,Joe Beda、Brendan Burns 和 Craig McLuckie 以及其他 Google 工程师共同推动了其开发。与 Borg 的 C++ 编码不同,Kubernetes 使用了Go。其第一个版本 Kubernetes 1.0 于 2015 年发布。通过与 Linux 基金会的合作,Kubernetes 成为了云原生计算基金会(CNCF)的基石,并迅速获得了红帽、VMware、Mesosphere、Docker、Microsoft Azure 和 AWS 等主要技术公司提供的服务的整合。

Kubernetes 在云计算中扮演着至关重要的角色,促进了声明式配置和自动化。它支持多种容器工具,包括 Docker,并且能够跨多个主机管理复杂的容器架构,这使得它极具价值。

Kubernetes 简化了应用程序的部署和扩展,其针对容器化应用的自动化发布和回滚功能增强了可靠性和效率。它允许在多个主机上编排容器,处理应用程序的部署和扩展,并覆盖它们的网络和存储需求。

该平台的自愈功能会在容器失败时自动重启、替换和重新调度容器。它还会根据负载变化扩展容器,并通过多种部署模式在不发生停机的情况下更新容器。

Kubernetes 支持多种工作负载,包括无状态有状态数据处理工作负载。它足够灵活,可以交付复杂的应用程序,同时提供可扩展性和可靠性,并有效管理工作负载。

总体来说,Kubernetes 革新了容器化应用程序的部署和管理方式,成为现代软件开发和运维领域的关键工具。

Kubernetes 架构

Kubernetes 架构旨在管理和编排容器化应用程序。它由多个组件组成,这些组件共同协作。

在 Kubernetes 架构中,集群被分为两个主要组件:控制平面工作节点(或数据平面)。控制平面负责全球决策和管理集群的状态。它包括如API 服务器etcd调度器控制器管理器云控制器管理器等核心元素。

相反,节点组件负责运行实际的工作负载。每个节点包含至关重要的服务,如 Kubelet容器运行时kube-proxy,它们确保容器按预期运行,并处理集群内部和外部的网络通信。

这种架构使得系统具有健壮性和可扩展性,控制平面保持控制,节点高效地管理工作负载。

控制平面包括以下组件:

  • API 服务器(kube-apiserver):该中央管理实体处理 REST 请求,验证请求,并更新对应的 etcd 中的对象。它是 Kubernetes 控制平面的主要接口。

  • etcd:这是一个一致且高可用的 键值存储,作为所有集群数据的主要存储。它对集群状态管理至关重要。

  • 调度器(kube-scheduler):调度器负责根据资源可用性、用户定义的约束、污点和选择器将 Pods 分配到节点上。这确保每个 Pod 被放置在满足资源需求且遵循调度策略(如污点和亲和性/反亲和性选择器)的最佳节点上。

  • 控制器管理器(kube-controller-manager):该组件在后台运行各种控制器过程。它监控集群的状态,管理工作负载的生命周期,并处理节点上的操作,以确保 Kubernetes 集群的期望状态得到维持。

  • 云控制器管理器:一个架构组件,嵌入了特定云平台的控制逻辑,允许云服务提供商将其平台与 Kubernetes 连接。它将与云平台相关的代码从 Kubernetes 核心逻辑中抽象出来,使得每个云服务可以独立开发其插件。每个托管 Pods 的节点组件,包含了维护和管理容器及网络通信的基本组件:

    • Kubelet:该代理确保容器按照 Pod 配置中定义的规范在 Pod 中运行。它管理每个节点上 Pod 的状态,并与主节点的控制平面(或在高可用 Kubernetes 集群中与多个主节点)进行通信。

    • 容器运行时:这是负责运行容器的底层软件。Kubernetes 支持多种容器运行时,如 Docker、containerd 和 CRI-O,使其能够运行容器化应用。

    • kube-proxy:该组件负责管理 Pods 的网络交互。它路由 TCP 和 UDP 包,并促进连接转发,添加一个作为代理的 Kubernetes 服务抽象。

图 2.1 展示了此处描述的 Kubernetes 架构,包含了控制平面和每个组件节点:

图 2.1 – Kubernetes 集群架构

图 2.1 – Kubernetes 集群架构

若要深入了解 Kubernetes 架构中的每个组件,请参考官方 Kubernetes 文档(kubernetes.io/)。该资源提供了关于 Kubernetes 系统各个方面的全面信息和详细说明,包括其主节点和节点组件。

现在我们已经基本了解了 Kubernetes 及其在 Kubernetes 集群中运行的主要组件,是时候学习如何使用 K3s(一种轻量级的 Kubernetes 发行版)在笔记本电脑上设置本地集群了。

探索 K3s 作为轻量级 Kubernetes 发行版

如前所述,在本书中,特别是在本章中,我们将使用 K3s 这个轻量级的 Kubernetes 发行版(k3s.io/)来运行我们的示例。

K3s 特别适合于那些全规模 Kubernetes 实施可能过于消耗资源或复杂的场景。

其轻量特性使其非常适合边缘计算和物联网(IoT)场景,这些环境中资源通常有限,而效率至关重要。在这些环境中,K3s 提供了必要的 Kubernetes 特性,同时消除了额外的开销。此外,Loft 的 vCluster 等解决方案已经利用 K3s 在 Kubernetes 内部运行 Kubernetes,促进了宿主集群中的多租户管理。这种方式允许在单一集群内创建独立的 Kubernetes 环境,优化了资源使用,并在多租户架构中提供了可扩展性。这些使用案例展示了 K3s 在多种计算环境中的多功能性和高效性。更多关于 K3s 的信息,请参阅官方文档:docs.k3s.io/

K3s 名称的由来

如官方文档中所解释的(https://docs.k3s.io/),K3s 的名称源于创建一个内存占用显著更小的 Kubernetes 安装版本的意图。命名规则沿用了 Kubernetes 的命名惯例,Kubernetes 常被缩写为 K8s,由 10 个字母组成。将其字母数减半得出了 K3s,并且这个命名风格代表了 Kubernetes 更紧凑的版本。与 Kubernetes 不同,K3s 并没有扩展形式,其发音也未被官方定义。这个命名反映了创建一个更轻量、更高效的 Kubernetes 版本的目标。

K3s 简化了 Kubernetes 集群的部署过程,使其即便对于小规模操作或开发用途也变得可行。通过去除非必要的组件并使用更轻量的替代方案,K3s 大幅减少了 Kubernetes 的体积和复杂度,同时保持了其核心功能。

K3s 保持与更大 Kubernetes 生态系统的兼容性,确保为 Kubernetes 设计的工具和应用程序通常也能与 K3s 一起使用。

K3s 的一个关键特点是其单一二进制文件安装,包含了 Kubernetes 服务器和代理,简化了设置过程。这使得它成为开发人员的理想选择,尤其是那些希望快速设置一个用于测试或开发的 Kubernetes 环境,而无需完整的 Kubernetes 安装。

K3s 还提供灵活的网络和存储选项,满足从小型本地集群到更大、更复杂环境的各种用例需求。它的多功能性和易用性使其成为那些希望探索 Kubernetes 而不需要庞大基础设施的人的热门选择。

最后,K3s 的轻量化和高效性使其成为持续集成/持续部署CI/CD)管道的理想选择,在资源有限的环境中能够加快构建和测试周期。在第五章中,我们将学习如何使用 K3s 在 Kubernetes 上运行 Kubernetes。

本地集群设置

在开始我们的第一个部署示例之前,首先需要设置环境,并了解 Kubernetes,特别是 K3s,如何帮助我们完成部署。K3s 主要设计用于 Linux 环境,因此请确保你有一个现代的 Linux 系统,如 Red Hat Enterprise Linux、CentOS、Fedora、Ubuntu/Debian,甚至是 Raspberry Pi。如果你是 Windows 用户,仍然可以通过设置WSL或通过VirtualBox运行 Linux虚拟机VM)来使用 K3s。这些设置将帮助你准备好利用 Kubernetes 的强大功能进行部署。

选择你的本地 Kubernetes 环境——K3s、Minikube 和替代方案

本章中,我们选择使用 K3s 是因为它轻量化且易于设置,特别适合开发和测试 Kubernetes 环境。然而,还有许多其他替代方案可以用来设置本地 Kubernetes 集群,满足不同的需求和平台。例如,Colima(github.com/abiosoft/colima)是 macOS 用户的一个优秀选择,提供了一个直接在 macOS 上运行的 Docker 和 Kubernetes 环境,几乎无需配置。Minikubeminikube.sigs.k8s.io)是另一个流行的选择,它支持 Windows、macOS 和 Linux,适合那些希望在单个节点上模拟 Kubernetes 集群的人,在这个节点上可以进行 Kubernetes 应用程序的实验和测试。

尽管在本章中我们选择使用 K3s,但我们鼓励你根据自己的平台或偏好使用最适合的本地集群设置。在后续章节中,我们将主要集中讨论如何使用 K3s 或 Minikube。这些平台为学习和部署 Kubernetes 应用程序提供了一个便捷且一致的环境,确保无论使用何种本地集群技术,我们所探讨的概念和过程都能轻松掌握。

设置 WSL

关于 WSL 的性质以及在 Windows 上安装它的过程超出了本书的范围。然而,关于安装步骤的全面指南和 WSL 的深入信息可以通过官方的 Microsoft 文档获取(请参见本章末尾的进一步阅读部分中的 [1]):

图 2.2 – 一张表示 Windows 操作系统上运行 WSL 的概念图

图 2.2 – 一张表示 Windows 操作系统上运行 WSL 的概念图

请记住,通过官方站点保持更新最新的 WSL 版本和功能,将增强您的体验,并确保与最新的 Windows 更新兼容。

设置 VirtualBox

VirtualBox 是由 Oracle 开发的开源 虚拟化软件。它允许用户在一台物理计算机上运行多个操作系统,创建能够独立运行的虚拟机。这使得它成为软件测试、开发和教育目的的重要工具,因为它为运行和实验不同操作系统提供了一个灵活且隔离的环境,且不会影响宿主系统:

图 2.3 – VirtualBox 首页,网址:https://www.virtualbox.org/.

图 2.3 – VirtualBox 首页,网址:https://www.virtualbox.org/。

安装 VirtualBox 的详细步骤超出了本书的范围。然而,您可以在官方文档中找到全面的安装说明和其他信息 [2]。

为了获取最新的信息和技巧,强烈建议访问官方 VirtualBox 文档。

除非另有说明,本章及后续章节将假设在 WSL 中使用 Ubuntu-22.04 LTS 版本进行安装。此设置为我们的示例和演示提供了一个一致且可控的环境。

通过聚焦于特定版本的 Ubuntu,我们确保所提供的指导和场景尽可能相关和适用,紧密契合在 WSL 中使用的最常见且稳定的 Linux 发行版。

K3s 设置和安装验证

本节将介绍使用默认配置的 K3s 建立 Kubernetes 集群所需的基本步骤,假设 WSL 已经安装并正常运行。

下载并安装 K3s

按照以下步骤下载并安装 K3s:

  1. 让我们从打开一个新的终端窗口并输入以下命令开始:

    pietro), which does not need to match your Windows username. The next step involves setting the password that will be used to run a command as an administrator (sudo). If the operations are completed correctly, the Terminal window should look like this:
    

图 2.4 – 在 WSL 上成功安装 Ubuntu 22.04.3 LTS 实例

图 2.4 – 在 WSL 上成功安装 Ubuntu 22.04.3 LTS 实例

  1. 在继续进行 K3s 设置之前,最好执行命令以更新操作系统并安装最新的补丁:

    $ sudo apt update
    $ sudo apt upgrade
    

    这确保您使用的是最新且安全的软件版本。

apt update 和 apt upgrade 命令

apt updateapt upgrade 命令在使用 APT 包管理器的系统中,尤其是在基于 Debian 的 Linux 发行版(如 Ubuntu)中,起着至关重要的作用。apt update 命令通过从配置的源获取可用软件包及其版本的最新信息来刷新本地包索引。这不会安装或升级任何软件包,而是更新包列表,以通知系统有关新软件、已删除软件或已更新软件的信息。包索引更新后,apt upgrade 命令用于将已安装的软件包升级到最新版本。它会下载并安装所有有新版本的软件包更新,确保系统是最新的,并可能更加安全。

如果需要,输入在安装 Ubuntu 时设置的密码。执行这些命令后,终端窗口应如下所示:

图 2.5 – 执行  和  命令后的终端窗口

图 2.5 – 执行 apt updateapt upgrade 命令后的终端窗口

  1. 下一步是使用以下命令安装 K3s:

    $ curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644
    

    上述命令将下载并设置必要的工具,随后启动 K3s 服务器。K3s 实例的成功设置如图 2.6所示:

    图 2.6 – 成功设置 K3s

图 2.6 – 成功设置 K3s

验证 K3s 安装

必须使用两个命令来检查 K3s 设置和配置的正确性。第一个命令如下:

$ k3s --version

上述命令用于检查我们正在运行的 K3s 版本。如果 K3s 服务器运行正常,我们应该能看到类似以下内容的信息:

图 2.7 – 执行  命令的结果

图 2.7 – 执行 k3s –version 命令的结果

检查 K3s 设置正确性的第二个命令如下:

$ k3s check-config

k3s check-config 命令对系统配置进行诊断检查,以确保其适合运行 K3s 集群。它验证关键方面,例如内核兼容性、所需的系统依赖项,以及必要功能和模块的存在。此命令有助于在进行 K3s 安装之前识别潜在问题或缺失的配置,从而确保更顺利的安装过程:

图 2.8 – 成功配置 k3s check-config 命令

图 2.8 – 成功配置 k3s check-config 命令

恭喜!你已确认 K3s 服务器已经在本地开发环境中安装成功。现在是时候验证 Kubernetes 集群并部署一个测试应用程序了。

检查 Kubernetes 集群

为了确认我们的 K3s 节点正在运行,我们可以输入以下命令:

$ kubectl get nodes

如果 Kubernetes 集群正常工作,前述命令将产生以下输出:

图 2.9 – 运行 kubectl get nodes 命令后的示例输出

图 2.9 – 运行 kubectl get nodes 命令后的示例输出

确认节点正常运行后,我们可以运行以下命令以获取更多关于运行中的集群的信息:

$ kubectl cluster-info

kubectl cluster-info 命令是 Kubernetes 中一个非常有用的工具,用于获取关于集群的重要信息。执行此命令后,它会显示一些关键细节,如 Kubernetes 主节点和服务端点地址。这个命令帮助用户快速了解集群的控制平面及核心服务(如 KubeDNS 和适用时的仪表板)的状态和连通性。它对于故障排除和确保 Kubernetes 集群配置正确并正常运行特别有价值。使用简单,kubectl cluster-info 通常是验证 Kubernetes 环境健康状态和状态的第一个命令,如下所示:

图 2.10 – 执行 kubectl cluster-info 命令后提供的信息

图 2.10 – 执行 kubectl cluster-info 命令后提供的信息

kubectl

kubectl 是一个命令行工具,是与 Kubernetes 进行交互的主要接口。它允许用户部署应用程序、检查和管理集群资源以及查看日志。基本上,kubectl 提供了有效控制 Kubernetes 集群所需的命令。用户可以使用这个多功能工具创建、删除和更新 Kubernetes 应用程序和基础设施的各个部分。它旨在用户友好,提供全面的帮助命令和输出格式选项,使用户更容易理解和管理复杂的 Kubernetes 环境。kubectl 是开发人员和系统管理员处理 Kubernetes 的不可或缺的工具,为在各种环境中处理容器化应用程序和服务提供了一种强大且灵活的方式。

Kubernetes 清单

Kubernetes 清单是一个配置文件,通常使用 YAML 或 JSON 编写,定义了应该部署到 Kubernetes 集群的资源。它指定了对象(如 Pods、Services 或 Deployments)所需的状态,Kubernetes 需要根据这些清单创建和管理这些对象。这个清单使得用户能够以结构化且可版本化的格式声明应用程序的要求、网络和存储配置等设置。

例如,部署一个简单应用程序的基本 Kubernetes 清单可能如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: hw-gitops-folks
spec:
  containers:
  - name: hw-gitops-folks-container
    image: k8s.gcr.io/echoserver:1.4
    ports:
    - containerPort: 8080

在这个清单中,定义了一个名为 hw-gitops-folks 的 Pod。它包含一个名为 hw-gitops-container 的容器,该容器使用 Kubernetes 容器注册表中的 echoserver:1.4 镜像。该容器暴露了 8080 端口。当这个清单应用到 Kubernetes 集群时,它将创建一个运行简单回显服务器的 Pod,可用于基本的测试。

我们的第一次 K3s 部署

现在我们已经成功地设置、配置并验证了我们的 K3s 集群,我们准备开始一个激动人心的阶段:为我们的首次部署做准备。此步骤标志着我们旅程中的一个重要里程碑,标志着我们从 K3s 的基础配置转向实际使用集群来进行实际应用。即将进行的部署过程不仅会加强我们对 Kubernetes 概念的理解,还将展示我们 K3s 环境的实际应用价值。这是一个理论与实践相结合的时刻,让我们亲眼看到我们配置的集群如何托管和管理应用程序。让我们带着探索 Kubernetes 配置的能力的热情前进,同时牢记我们所学的实践和已建立的强大基础设施:

  1. 让我们首先输入以下命令,这将列出所有正在运行的 Pods:

    $ kubectl get pods
    

    执行该命令的结果应该如下所示:

    No resources found in default namespace
    
  2. 上面的输出是正常的,因为到目前为止还没有执行任何部署。让我们试试另一个命令:

    kube-system namespace. These Pods are essential for the operation of the Kubernetes system. The specific Pods and their statuses are detailed in *Figure 2**.11*, offering a comprehensive view of the active system components within this crucial namespace:
    

图 2.11 – 在 kube-system 命名空间中运行 Pods 的示例

图 2.11 – 在 kube-system 命名空间中运行 Pods 的示例

什么是 Kubernetes 中的命名空间?

在 Kubernetes 中,命名空间是一个基本概念,用于将集群组织成逻辑上隔离的子组。它提供了一种在多个用户和应用程序之间划分集群资源的方法。本质上,命名空间就像是物理 Kubernetes 集群中的虚拟集群。它们允许进行资源管理、访问控制和配额管理,从而实现高效、安全的多租户环境。例如,不同的开发团队或项目可以在各自的命名空间中操作,而不相互干扰。命名空间还便于资源命名,确保具有相同名称的资源可以在不同的命名空间中共存。命名空间在 Kubernetes 中发挥着至关重要的作用,特别是在具有大量应用程序和团队的大型系统中,它们有助于实现可扩展性和维持秩序。

在 Kubernetes 中创建不同的命名空间被广泛认为是一种最佳实践,原因有很多。命名空间提供了集群的逻辑分区,使资源管理更加有序和高效。特别是在多个团队或项目的环境中,这种分隔尤为重要,它可以确保资源之间的清晰区分,减少命名冲突,并通过隔离工作负载来提高安全性。此外,命名空间还便于精细化访问控制,管理员可以为不同的命名空间分配特定的权限和资源限制,从而防止不同部分的集群之间发生意外或未经授权的互动。通过使用命名空间,团队还可以简化部署过程,更有效地监控资源使用情况,从而使 Kubernetes 环境更加健壮和可扩展。本质上,命名空间在维护复杂 Kubernetes 集群的秩序、安全性和效率方面至关重要。那么,让我们开始创建一个命名空间吧:

  1. 让我们继续,在继续进行首次部署之前,先创建一个新的命名空间:

    $ kubectl create namespace gitops-kubernetes
    

    执行此命令后的响应应该类似于以下内容:

    namespace/gitops-kubernetes created
    
  2. 删除命名空间的命令如下:

    hello-world image and a service to make the deployment accessible (the complete version of the manifest mentioned here can be found in this book’s GitHub repository):
    
    

    apiVersion: apps/v1

    kind: Deployment

    metadata:

    name: hello-world-deployment

    namespace: gitops-kubernetes

    ...

    spec:

    ...

    spec:

    containers:

    • name: hello-world

    image: nginxdemos/hello

    ports:

    • containerPort: 80

    apiVersion: v1

    kind: Service

    metadata:

    name: hello-world-service

    namespace: gitops-kubernetes

    spec:

    type: NodePort

    ...

    ports:

    • protocol: TCP

    port: 80

    nodePort: 30007

    
    To apply the manifest, we need to save it in a `.yaml` (or .`yml`) file, such as `hello-world-deployment.yaml` (its name isn’t important).
    
  3. 要编辑文件,我们可以使用像 nano 这样的编辑器,运行以下命令:

    hello-world-deployment that runs a container using the nginxdemos/hello image, which serves a simple HTML page. The container is configured to expose port 80. In the metadata section, we have specified to run the Pod in the namespace we created previously – that is, namespace: gitops-kubernetes.
    
  4. hello-world-serviceNodePort 类型,用于暴露部署。这项服务使得 hello-world 应用程序可以通过集群节点上的端口访问(在这个例子中是 port 30007)。在元数据部分,我们已指定在之前创建的命名空间中运行该服务——即 namespace: gitops-kubernetes

NodePort

在这个 hello-world 服务示例中,选择了 NodePort 服务类型,以展示在 Kubernetes 中暴露服务给外部流量的一种简单方式。NodePort 会在所有节点上打开一个特定的端口,任何发送到该端口的流量都会被转发到该服务。虽然这对开发和测试很有用,但在实际的云环境中可能并不理想,特别是在云中的虚拟机(VM)上运行时。这是因为 NodePort 会暴露主机虚拟机/节点的端口,可能会通过让服务对外部可访问,造成安全风险。在生产环境中,通常更倾向于使用更安全和可控的服务暴露方法。

  1. 要应用此清单,请使用 kubectl apply -f <``filename>.yaml 命令:

    $ kubectl apply -f hello-world-deployment.yaml
    

    执行此命令后的响应应该类似于以下内容:

    deployment.apps/hello-world-deployment created
    service/hello-world-service unchanged
    
  2. 现在,我们可以使用以下命令列出在 gitpos-kubernetes 命名空间中运行的 Pods 和服务:

    $ kubectl get pods --namespace gitops-kubernetes & kubectl get services --namespace gitops-kubernetes
    

    此命令的结果显示在 图 2.12 中:

图 2.12 – 应用部署文件的结果,我们可以看到有用的信息,如集群 IP 和分配的端口

图 2.12 – 应用部署文件的结果,我们可以看到有用的信息,如集群 IP 和分配的端口

现在,我们已经在 Kubernetes 集群中部署了应用程序,下一步是测试其功能。这就是 端口转发 起到关键作用的地方。

端口转发

使用 kubectl 进行端口转发可以临时将流量从本地计算机路由到 Kubernetes 集群中的 Pod。此方法对于测试特别有用,因为它使我们能够像在本地运行应用程序一样与之交互,而无需公开暴露它。通过将本地端口转发到 Pod 的端口,我们可以验证部署的运行情况,确保应用程序在受控环境中按预期运行,然后再将其暴露给外部流量。以下步骤概述了在运行中的 Pod 上执行端口转发并使用 curl 测试其功能的过程:

  1. kubectl 命令将本地端口转发到 Pod 的端口:

    [POD_NAME] with the name of your Pod. For instance, in *Figure 2**.12*, the name of the pod is hello-world-deployment-6b7f766747-nxj44. Here, [LOCAL_PORT] should be replaced with the local port on your machine – for example, 9000 (ensure that the local port is not already used by another running service!) – while [REMOTE_PORT] should be replaced with the port on the Pod that you want to forward traffic to. In our case, as reported in *Figure 2**.10*, the Pod port is 80.
    
  2. 此时,我们正在使用 Pod 的名称 hello-world-deployment-6b7f766747-nxj44。因此,如果我们想将本地端口 9000 转发到 Pod 的端口 80,命令如下:

    $ kubectl port-forward hello-world-deployment-6b7f766747-nxj44 --namespace gitops-kubernetes 9000:80
    

    这将产生以下输出:

    Forwarding from 127.0.0.1:9000 -> 80
    Forwarding from [::1]:9000 -> 80
    

    上述输出表明,端口转发已经在你的机器上设置好,将流量从本地端口重定向到 Kubernetes Pod 或其他网络服务的端口。保持此命令运行,因为它会维持端口转发会话。

  3. 打开一个新的终端或命令提示符,并键入以下命令以打开新的 WSL shell:

    curl to send a request to the local port that is being forwarded:
    
    

    9000,kubectl 然后将其转发到 Pod 的端口(80)。你应该在终端中看到请求的输出。通常,这是由你的应用程序在 Kubernetes Pod 中提供的内容,如 图 2.13 所示:

    
    

图 2.13 – 我们的应用程序在 Kubernetes Pod 中运行时提供的内容示例

图 2.13 – 我们的应用程序在 Kubernetes Pod 中运行时提供的内容示例

恭喜你取得了这一了不起的成果!你已经成功在 Kubernetes 中部署了第一个应用程序,并且内容已经正确提供,正如通过成功的 curl 调用所证明的那样。这是你在 Kubernetes 旅程中的一个重要里程碑,展示了你不仅能部署应用程序,还能确保它在集群中的正常运行。

在接下来的章节中,我们将深入探讨 Docker,详细研究其基本组件、功能和实际应用。我们将构建我们的第一个 Docker 镜像,并展示如何将其作为容器在本地运行。

开始使用容器

由于其能够将应用程序及其所有依赖项打包和隔离,容器已成为云原生应用程序开发的基石。这种隔离确保了在各种环境中的一致性,使其在开发和部署中极为高效。容器镜像是包含可执行代码和依赖项的静态文件,采用分层结构以实现高效的修改和存储,每一层代表变更或添加。

尽管容器具有很强的多用途性,但 Kubernetes 并未提供用于构建这些镜像的原生机制,因此需要像Docker这样的外部工具。

Docker,作为一个开放源代码平台,通过简化应用程序在容器中的创建、部署和执行,改变了容器化的世界。它使开发人员能够以统一的格式封装带有其依赖项的应用程序,从而促进软件开发。Docker 的容器提供了半隔离的环境,平衡了隔离性与效率,允许多个容器在单个主机上并发运行。这些容器既轻量又便携,确保在从本地笔记本到云基础设施等各种平台上的统一功能性。

Docker 文件在创建这些镜像方面起着关键作用,指定包括的步骤和组件。

开放容器倡议OCI)标准化容器镜像格式和运行时,进一步增强了在不同容器技术之间的互操作性和可移植性。

Docker 设置

到目前为止,我们一直专注于在 WSL 中使用 Ubuntu 22.04 作为实例。虽然本书不涵盖 Docker 的逐步设置过程,但您可以在官方 Docker 文档中找到全面的安装指南和故障排除提示:docs.docker.com/engine/install/ubuntu/。成功安装 Docker 后,您可以在终端中输入以下命令验证其安装并检查 Docker 是否在系统上正常运行:

$ sudo docker run hello-world

sudo docker run hello-world 命令通过运行一个非常简单的容器快速验证了 Docker 的安装和设置。执行时,它执行以下操作:

  • sudo:确保命令以超级用户权限运行,这通常是 Docker 命令所需的。

  • docker run:告诉 Docker 运行一个容器。

  • hello-world:指定要使用的镜像。在这种情况下,它是 hello-world 镜像,这是由 Docker, Inc 创建的一个最小的 Docker 镜像,通常用作验证 Docker 是否安装和运行正常的测试镜像。

如果 Docker 已正确安装和配置,该命令将从 Docker Hub 拉取 hello-world 镜像(如果尚未下载),并基于该镜像创建一个新容器并运行。该容器仅显示一条消息,确认 Docker 安装正确,然后退出,如 图 2.14 所示:

图 2.14 – 执行  命令的结果

图 2.14 – 执行 docker run hello-world 命令的结果

Docker 替代方案

尽管 Docker 是构建容器镜像的最流行工具之一,但也有多个可用的替代工具:

  • Podman:一个开源的、无守护进程的容器引擎,可在 Linux 系统上运行。它与 Docker 兼容,但不需要运行守护进程。Podman 以简化容器和 Pod 管理而闻名。

  • Rancherdesktop:一款开源应用程序,提供在桌面上与容器和 Kubernetes 配合使用的所有必需工具。

  • containerd:一个核心容器运行时,遵循行业标准,作为服务可用于 Linux 和 Windows。它能够管理主机系统上容器的整个生命周期。

  • CRI-O:这是 Kubernetes 容器运行时接口的实现,便于使用与 OCI 兼容的运行时。它充当桥梁,将 OCI 兼容的运行时与 kubelet 连接起来。

  • rkt(发音为“rocket”):由 CoreOS 开发,是一个适用于 Linux 的 Pod 原生容器引擎。它在现代集群环境中旨在提供安全性、简洁性和可组合性。

  • LXD:一个先进的系统容器和虚拟机管理器,通过使用 Linux 容器提供类似虚拟机的用户体验。

  • OpenVZ:这是一个基于容器技术的虚拟化解决方案,适用于 Linux 系统,能够在单一物理服务器上生成多个安全和隔离的 Linux 容器。

为了帮助选择最适合您特定需求的容器化工具,以下表格提供了多个 Docker 替代方案的比较。它突出了它们的主要特点和理想使用场景,为您提供有关哪个工具最符合您项目需求或偏好的见解:

替代方案 描述
Podman 最适合优先考虑安全性并且用户希望使用无守护进程的解决方案的环境。它与 Docker 的 CLI 完全兼容,使其成为无缝替代方案。
Rancherdesktop 一款用户友好的基于 GUI 的工具,专为希望更轻松地管理容器和 Kubernetes 的开发人员设计,特别适用于开发和测试环境中的桌面环境。
Containerd 由于其在生产环境中作为容器运行时的性能和可靠性而被选中。缺乏 Docker 的镜像构建功能,但在高效运行容器方面表现出色。
Rkt 以前是一个可行的替代方案,但其开发已停止,可能会限制其在长期项目中的适用性。
OpenVZ 适合托管解决方案或需要在单个主机上创建多个隔离的 Linux 环境的场景,专注于资源效率和可扩展性。

表 2.1 – 容器化工具的比较概览 – 评估不同开发需求下 Docker 的替代方案

Dockerfile

创建容器镜像的第一步是定义一个 Dockerfile,它本质上是镜像的 蓝图。这个文件包含了一组指令和命令,告诉 Docker 如何构建镜像。它首先指定一个基础镜像,通常是一个操作系统的精简版本,比如 Ubuntu 或 Alpine Linux。接着,通过指定依赖项、复制应用程序文件和设置环境变量,逐步添加额外的层。Dockerfile 中的每一条命令都会创建镜像中的新层,逐步构建运行应用程序所需的环境。以下是一个 Dockerfile 的示例:

# Use an official Python runtime as a parent image
FROM python:3.8-slim
# Set the working directory in the container
WORKDIR /usr/src/app
# Copy the current directory contents into the container at /usr/src/app
COPY . .
# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]

让我们更仔细地查看这个文件:

  • FROM python:3.8-slim:这一行指定了构建时使用的基础镜像。该 Dockerfile 以 Python 3.8 镜像开始,特别是 slim 版本,它是一个较小、更紧凑的版本。

  • WORKDIR /usr/src/app:这一行设置容器内的工作目录为 /usr/src/app。以后所有的命令都将在该目录中运行。

  • COPY . .:这一行将 Dockerfile 当前目录中的文件复制到容器中的工作目录(/usr/src/app)。

  • RUN pip install --no-cache-dir -r requirements.txt:这一行在容器内执行一个命令,即安装 requirements.txt 中列出的 Python 依赖项。

  • EXPOSE 80:这一行通知 Docker 容器在运行时监听 80 端口。注意,这并不会发布端口。

  • ENV NAME World:这一行将 NAME 环境变量设置为 World。容器中运行的应用程序可以使用这个变量。

  • CMD ["python", "app.py"]:容器启动时执行的默认命令。该行启动 Python 应用程序。

这个 Dockerfile 提供了一个简单的示例,说明如何从一个简单的 requirements.txt 文件构建 Docker 镜像。你可以使用以下命令构建该镜像:

$ sudo docker build -t hello-world-py-app:1.0 .

此时,正如 图 2.15 所示,你的容器镜像正在构建过程中。在此过程中,Docker 会从 公共容器注册表(如 DockerHub、Quay 或 Red Hat Registry)中获取任何现有的层。容器注册表的相关内容将在接下来的页面介绍。然后,它会根据 Dockerfile 中的指令添加新的层。如果某些层已经存在于本地,Docker 会从容器缓存或 Docker 缓存中使用这些层,从而通过避免冗余下载来加速构建过程:

图 2.15 – docker build 命令的结果

图 2.15 – docker build 命令的结果

容器镜像现在已在本地 Docker 缓存中可用,准备使用。可以使用以下命令验证其存在:

$ docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
hello-world-py-app   1.0       765f270eef8c   7 minutes ago   139MB
hello-world          latest    d2c94e258dcb   8 months ago    13.3kB

一旦镜像创建完成,就可以在本地使用或上传到公共容器注册表以供外部使用,例如在 CI/CD 流水线中。为了我们的目的,我们将在本地运行容器镜像。为此,请使用以下命令:

$ sudo docker run -p 8080:8080 -ti hello-world-py-app:1.0

上述命令包含几个选项:

  • -p选项将主机上的端口绑定到容器上的端口,从而允许外部访问容器的服务

  • -t选项分配一个伪 TTY,为容器提供一个终端

  • -i选项启用交互模式,允许与容器进行交互

  • -d选项将在后台运行容器并输出一个哈希值,可用于与容器进行异步交互

公共容器注册表

公共容器注册表是一个在线服务,用户可以在其中存储和共享容器镜像。它作为一个集中式存储库,促进容器化应用程序的分发。为了上传和管理镜像,用户通常需要在注册表提供商处创建一个账户。该账户允许用户发布、更新和维护镜像,使其对他人可访问。Docker Hub、Google Container Registry 和 Amazon Elastic Container Registry 等公共注册表是流行的选择,提供便捷的互联网访问。这些平台不仅为容器镜像提供存储,还通常提供版本控制、目录管理和安全扫描等附加功能。拥有这些服务的账户使得开发人员能够在不同环境中一致地部署应用程序,简化软件开发,并更有效地与社区中的其他人进行协作。

请注意,创建公共容器注册表账户的过程虽然是管理和分发容器镜像的关键步骤,但超出了本章和本书的范围。每个注册表(如 Docker Hub 或 Google Container Registry)都有自己的一套账户创建和管理指南和程序。建议您参考这些服务提供的具体文档,了解设置账户的详细说明。

上述命令将在 Docker 网络内启动应用程序,并将其绑定到我们本地机器的端口8080。然后,它将等待传入的请求,如图 2.16所示:

图 2.16 – docker run 命令的结果

图 2.16 – docker run 命令的结果

在新的终端中,我们可以尝试使用curl访问正在运行的容器:

$ curl http://localhost:8080

或者,我们可以运行以下命令:

$ curl localhost:8080/[YOUR_NAME_HERE]

你将收到一个类似于图 2.17中的响应,我使用了我的名字来获取输出:

图 2.17 – 从我们作为容器化镜像运行的 Python Flask 应用程序接收到的响应示例

图 2.17 – 从我们作为容器化镜像运行的 Python Flask 应用程序接收到的响应示例

现在我们已经具备了必要的工具和对 Docker 及容器的理解,在接下来的章节中,我们将整合这些元素,构建第一个使用 Docker 和 K3s 的 CD 管道。

示例工作流——使用 Docker 和 K3s 实现轻松的 CD

到此为止,我们已经准备好使用迄今为止探索的工具创建一个非常简单的 CD 管道。基本思路是模拟开发人员执行的操作,更新我们到目前为止使用的 Flask 应用程序,添加一个新功能,允许获取当前的日期和时间。

我们的示例将包括执行以下步骤:

  1. 本地开发:我们将编辑之前的 Python Flask 应用程序,暴露一个新的服务,返回当前的日期和时间。

  2. 将应用程序 Docker 化并在本地运行:我们将像之前一样使用 docker build 命令在本地构建新版本的 Docker 镜像。使用 Dockerfile 部分作为参考。

    在构建镜像后,我们将使用 Docker 在本地运行它,以确保容器化应用程序按预期工作。使用 Dockerfile 部分作为参考。

  3. 将镜像发布到公共容器注册表:我们将把构建的镜像发布到公共注册表仓库。

  4. 部署到 K3s:我们将编写 Kubernetes 清单文件,指定应用程序如何在 K3s 上部署,包括使用哪个 Docker 镜像以及所需的副本数。

你将使用在本章 探索 K3s 作为轻量级 Kubernetes 发行版 部分中学到的命令,将此配置应用到你的 K3s 集群中。

让我们开始吧!

本地开发

编辑此书 GitHub 仓库中的 app.py 文件,添加以下 Python 代码:

…
@app.route('/datetime')
def datetime():
    import datetime
    now = datetime.datetime.now()
    return now.strftime("%Y-%m-%d %H:%M:%S")
…

你可以自由选择任何你喜欢的代码编辑器来编辑这个文件——这无关紧要。

将应用程序 Docker 化并在本地运行

按照以下步骤将应用程序 Docker 化并在本地运行:

  1. Dockerfile 部分,我们创建了第一个版本的 Docker 镜像,标签为 hello-world-py-app:1.0。现在我们添加了一个新功能,是时候创建这个镜像的新版本了。我们将使用标签 2.0,通过以下 docker build 命令进行构建:

    $ sudo docker build -t hello-world-py-app:2.0 .
    
  2. 输入以下命令后,你应该能看到列出两个镜像:

    $ sudo docker images
    

    该命令的结果应如下所示:

    hello-world-py-app   2.0       a7d7ab4514fa   19 seconds ago      145MB
    hello-world-py-app   1.0       3f8f095a7b37   About an hour ago   145MB
    
  3. 我们可以使用以下 docker 命令在本地运行 Docker 镜像:

    $ sudo docker run -p 8080:8080 -ti hello-world-py-app:2.0
    

    这将产生类似以下的结果:

    * Serving Flask app 'app'
    * Debug mode: on
    WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
     * Running on all addresses (0.0.0.0)
     * Running on http://127.0.0.1:8080
     * Running on http://172.17.0.2:8080
    Press CTRL+C to quit
    …
    
  4. 在一个新的终端中,我们可以尝试使用 curl 访问正在运行的容器:

    $ curl http://localhost:8080/datetime
    

    我们将获得当前的响应:

    2024-01-13 12:39:50
    

做得好——作为开发人员,你已经测试了新功能是否按预期工作!现在,我们可以将我们的镜像发布到公共仓库。

将镜像发布到容器注册表

将我们的 hello-world-py-app:2.0 Docker 镜像发布到公共仓库涉及几个步骤:

  1. 假设你已经在公共容器注册表(例如 Docker Hub)上有一个账户,第一步是打开一个新的终端,并使用 Docker CLI 登录到注册表:

    username/repository:tag format. Run the following command to tag the previously built image:
    
    

    $ sudo docker tag hello-world-py-app:2.0 [yourusername]/hello-world-py-app:2.0

    
    
  2. 然后,我们需要推送标记的镜像:

    hello-world-py-app:2.0 image is listed there.
    

部署到 K3s

现在终于到了将镜像部署到本地 Kubernetes 集群的时刻!我们可以重用在 我们的第一次 K3s 部署 部分中使用的 Kubernetes 清单文件,但我们将做几个修改,最重要的是更新清单文件,指明 Kubernetes 集群需要从哪里下载镜像,使用我们的容器仓库。现在,让我们开始吧:

  1. 在清单文件的 deployment 部分,我们需要将镜像值从 nginxdemos/hello 更改为 [yourusername]/hello-world-py-app:2.0。然后,我们需要将文件中指定的位置的名称从 hello-world 更改为 first-cd-pipeline

        spec:
          sectioners:
          - name: first-cd-pipeline
            image: [yourusername]/hello-world-py-app:2.0
    

    在这里,我们还将部署的名称更改为 first-cd-pipeline-deployment。部署文件可以在本书的 GitHub 仓库中的 Chapter02 文件夹找到。

  2. 保存新文件,命名为 first-cd-pipeline-deployment.yaml,并使用以下命令应用该部署:

    $ kubectl apply -f first-cd-pipeline-deployment.yaml
    

    响应应该像这样:

    deployment.apps/first-cd-pipeline-deployment created
    service/first-cd-pipeline-service created
    
  3. 在建立端口转发之前,如 我们的第一次 K3s 部署 部分末尾所述,我们需要通过运行以下命令获取一些有用的信息:

    $ kubectl get pods --namespace gitops-kubernetes & kubectl get services --namespace gitops-kubernetes
    

    这将产生类似以下的输出:

    NAME                        TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
    first-cd-pipeline-service   NodePort   10.43.172.10   <none>        80:30007/TCP   29s
    NAME                         READY   STATUS    RESTARTS   AGE
    first-cd-pipeline-deployment-5b85cfd665-5626b   1/1     Running   0          29s
    
  4. 到此为止,我们已经拥有执行端口转发所需的所有信息:

    curl to test that the new feature has been deployed and hosted by the K3s cluster:
    
    

    $ curl http://localhost:8080/datetime

    
    You should see an output similar to the following:
    
    

    2024-01-13 17:59:39

    
    
  5. 要删除部署,输入以下命令:

    $ kubectl delete -f first-cd-pipeline-deployment.yaml
    

恭喜你通过手动 CD 部署达到了这个里程碑!

这里概述的将 Docker 镜像发布到公共容器注册表的步骤,应该视为一个手动示例,展示了 CD 的基本原理。然而,在实际操作中,这个过程通常使用 Git Actions 等工具进行自动化,从而简化和优化部署周期。尽管这些手动步骤提供了基础理解,现实应用中通常依赖更复杂的自动化工具来提高效率和一致性。在下一章中,我们将深入探讨如何将这些工具集成到工作流程中,从而增强 CD 过程并减少手动干预。

总结

在本章中,我们探讨了使用 Kubernetes 和 K3s 部署云原生应用的实践方面,重点介绍了高效的容器管理和编排的关键技术。本章侧重于构建管理云原生环境所需的基础技能,包括理解 Kubernetes 资源和部署方法。

随着我们进入下一章,重点将转向介绍 Git 工具。我们将探讨如何利用这些工具创建一个自动化的 CI/CD 流水线,这是无缝部署和管理云原生应用的核心组件,同时提升开发和运营工作流程。

进一步阅读

要了解更多关于本章所涉及的主题,请查看以下资源:

第三章:版本控制与 Git 和 GitHub 的集成

到目前为止,我们的探索已经揭示了 GitOps 的基础概念及其在管理云原生操作中的关键作用。这一过程涉及了解 GitOps 在基础设施管理中的原理、优势及其变革性特征,以及它如何提升和简化云原生流程。

本章将进一步扩展这些概念。它将深入探讨 Git 在版本控制中的重要性,这一内容是现代软件开发的关键组成部分。本章还将探讨 GitHub 在协作开发中的贡献,以及如何最大化其在团队效率中的作用。此外,它还将讨论将 GitOps 实践与 Git 和 GitHub 集成的方式,强调自动化集成流程。

本章概述了在 GitOps 框架内使用 Git 和 GitHub 的最佳实践,旨在提升工作流效率,并促进强大的 DevOps 文化。

本章将重点讨论以下几个关键领域:

  • 版本控制系统

  • 为什么选择 Git?

  • 探索 GitHub

  • 集成 GitOps 和 GitHub

技术要求

为了充分理解本章中提出的概念和实践,需要满足一些技术要求。你应该具备基本的软件开发流程知识,并且熟悉命令行工具。为了跟随涉及 Git 和 GitHub 的示例,你需要一台能连接互联网的计算机。通过这种实践方法,你将能够将 GitOps 的理论和实践应用到现实世界的场景中。

本章的代码可以在我们的 GitHub 仓库的Chapter03文件夹中找到,网址:github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

探索版本控制系统——本地、集中式和分布式

版本控制系统VCSs)是现代软件开发中不可或缺的工具,它们负责高效管理文件变化,特别是代码。Git 作为一种广泛使用的版本控制系统,通过跟踪修改记录,允许用户根据需要查看和恢复特定版本的文件,展现了这一功能的优势。对于协作项目而言,这种功能尤为重要,它提供了一个完整的记录,能够明确谁在什么时候、出于什么原因做了更改,从而增强了责任感和透明度。

本质上,版本控制是关于记录随时间变化的更改。这使得恢复项目的先前状态变得更加容易,无论是修复 bug、测试还是撤销更改。它不仅限于软件代码;版本控制可以应用于任何类型的文件,因此它成为了像图形设计师或网页设计师这样的专业人士的宝贵工具,他们可能需要管理工作版本。使用 VCS 可以最小化与文件丢失或错误相关的风险,因为它提供了一个安全网,能够轻松回退到早期状态并理解项目的演变。这提高了效率并且使工作流程更加结构化,同时减少了额外负担。

通过将版本控制集成到工作流程中,团队和个人获得了一个强大的工具,帮助他们应对项目开发中的复杂性,确保更顺畅、更可控的持续改进和协作过程。

版本控制系统(VCS)可以分为三种主要类型:本地、集中式和分布式:

  • 本地 VCSLVCS):这是最简单的形式。它通过使用一个数据库来跟踪本地计算机中文件的更改,通常会将所有更改存储在版本控制下。这个系统直观易用,但有一些局限性,尤其是在协作和数据备份的环境中。图 3.1展示了左侧是 LVCS 的示例。

  • 集中式 VCSCVCS):这些系统,如SubversionSVN),有一个包含所有版本文件的单一服务器。各种客户端从这个中心位置检出文件。这种设置比 LVCS 大大增强了协作性,因为每个人都知道别人正在做什么。然而,中央服务器也是单点故障;如果它出现故障,就没有人可以继续协作或保存版本更改。

图 3.1 – LCVS 和 CVCS 的示例

图 3.1 – LCVS 和 CVCS 的示例

并行版本控制系统与 SVN

并行版本控制系统CVS)是早期的版本控制系统,它通过允许团队在集中式代码库中同时进行协作开发来促进软件开发。然而,它存在一些局限性,尤其是在处理二进制文件时。它还缺乏一些高级功能。SVN 作为 CVS 的现代替代方案应运而生,解决了这些问题。SVN 也是一个集中式系统,它通过允许多个用户高效地协作工作,提供了集中式的文件变更源,改善了协作,提高了不同团队成员所做变更的跟踪与管理。

  • 分布式版本控制系统DVCSs):像 Git 这样的系统属于这一类别。与单一的中央仓库不同,每个用户都拥有整个仓库的完整副本。这种方式支持更复杂的工作流程,增加了冗余性和备份选项,还能实现离线工作。同时,它支持各种形式的合并分支,为版本控制提供了更灵活的方式,尤其适用于有众多贡献者的大型项目。

图 3.2 – 分布式版本控制系统示例

图 3.2 – 分布式版本控制系统示例

在探索过包括 LVCS、CVCS 和 DVCS 在内的多种版本控制系统(VCS)后,我们可以清楚地看到 Git 在 DVCS 中为何如此突出。接下来,我们将深入探讨 Git 的独特优势和功能,了解它为何成为现代软件开发中的必备工具。

为什么选择 Git?

Git 的故事始于 2000 年代初期 Linux 内核项目的开发挑战。这一时期,Linux 的创始人 Linus Torvalds 遇到了现有版本控制工具的困境。当时 Linux 社区使用的专有分布式版本控制系统(DVCS)BitKeeper 存在诸多限制和约束,迫切需要一个新系统。这促使了 2005 年 Git 的诞生,标志着版本控制系统领域的重大转变。

Git 的设计目标明确,汲取了使用 BitKeeper 时的经验教训。其中最关键的目标包括速度、简洁的设计以及对非线性开发的强大支持。该系统特别针对 Linux 内核等大型项目进行优化,既提高了速度,也有效处理了数据量。这种对效率和灵活性的关注在面对如此规模和复杂性的项目时至关重要。

Git 的结构独特且高效。它是一个分布式版本控制系统,意味着每个用户都在本地存储项目的完整历史。这样的设计不仅提升了速度,还为版本控制提供了更加灵活和安全的方式。在 Git 中,仓库包含提交,这些提交本质上是项目在不同阶段的快照,以及对这些提交的引用(称为)。多年来,Git 逐渐发展和成熟,在保留最初特点的同时,也变得更加用户友好。它与 GitHub 等平台的集成(我们将在本章的 探索 GitHub 部分深入探讨 GitHub)以及 BitbucketGitLab 的结合进一步增强了其功能,提供了集中式的协作、代码共享和项目管理平台。

为了说明 Git 的广泛应用,值得一提的是,GitHub 社区宣布其平台上的开发者数量已超过 1 亿人:

github.blog/2023-01-25-100-million-developers-and-counting/

在 GitOps 实践中使用 Git 强调了其可靠性和高效性,使其成为现代软件开发和版本控制的基石。

在从多个角度理解了 Git 的重要性之后,我们现在将转向更实际的方式。在接下来的部分中,我们将从 Git 命令的基础和示例开始,提供一个实践经验。

Git 设置

本章不深入介绍 Git 安装的细节,但你可以在官方 Git 文档中找到一份详细的逐步指南(请参见本章末的进一步阅读部分中的[1])。在我们讨论的过程中,我们假设 Git 已经安装在Windows Subsystem for LinuxWSL)Ubuntu 22.04 发行版上。需要强调的是,Git 可以在 Windows(无需 WSL)、macOS 和 Linux 上本地安装。

有关设置 WSL 的更多信息,请参阅第二章,特别是其中的WSL 设置部分,其中提供了相关的指导和见解。

要验证您的 Git 安装,您可以在命令提示符中输入一个特定的命令。此命令将帮助您确认 Git 是否已正确安装并正常运行:

$ git version

预期的响应应类似于以下内容:

git version 2.45.1

做得好!在接下来的部分中,我们将深入探讨 Git 的基础,学习其命令,并研究 GitOps 中必不可少的最有趣的功能。

创建和克隆 Git 仓库

Git 仓库是 Git 版本控制系统的基石,包含所有项目文件及其修订历史。它通过包含必要变更跟踪数据的 .git 目录进行标识。仓库可以是用户计算机上的本地实体,也可以是 GitHub 等服务器上的远程版本,支持个人工作和协作工作。它们在项目版本管理和演化中扮演着至关重要的角色,以提交的结构化链表格式存储文件和历史记录。该设置支持多种交互,如克隆(从远程服务器创建仓库的本地副本)、分支(从主代码库分支出独立版本进行开发或测试,且不影响原始代码)以及代码版本比较(检查不同版本代码文件之间的差异,以跟踪变更或合并更新)。

可以通过两条命令来启动一个 Git 仓库:

  • git init:此命令用于在尚未受版本控制的目录中初始化一个新的 Git 仓库。执行此命令会在目录中创建一个名为 .git 的隐藏子文件夹,设置仓库管理和版本控制所需的结构。

  • git clone:此命令用于创建现有 Git 仓库的本地副本,通常是托管在远程服务器上的仓库,例如 GitHub。当你克隆一个仓库时,它不仅下载项目文件,还将完整的历史记录和所有分支下载到你的本地仓库中。这个过程确保你可以访问项目的完整开发历史。

打开命令提示符并激活一个 WSL 实例,具体步骤详见第二章中,设置 WSL部分,然后按照随后的编号步骤创建并克隆一个 Git 仓库:

  1. 创建一个名为Chapter_3的新目录:

    Chapter_3 as the current working directory, type cd Chapter_3 into the command prompt.
    
  2. 一旦进入Chapter_3目录,你就可以使用git init命令初始化一个新的 Git 仓库。此步骤对于在新项目目录中启动版本控制至关重要:

    $ git init
    

    命令的输出应该如下所示:

    hint: Using 'master' as the name for the initial branch. This default branch name
    hint: is subject to change. To configure the initial branch name to use in all
    …
    hint:   git branch -m <name>
    Initialized empty Git repository in /home/pietro/Chapter_3/.git/
    
  3. 使用ls -a命令列出工作目录的内容后,你应该能够看到新创建的.git隐藏目录。这个目录表明 Git 仓库已成功初始化:

    .git directory, you can use the ls -a ./.git command. This will display all the files and subdirectories within the .git directory, providing insight into the structure of the initialized Git repository:
    
    

    $ ls -a ./git

    
    The output should look like the following:
    
    

    . .. HEAD branches config description hooks info objects refs

    
    
  4. 要通过克隆初始化一个仓库,首先需要导航到另一个目录。然后,在该目录中执行克隆命令,并使用适当的 URL 在新位置创建一个现有 Git 仓库的副本。这个过程将复制仓库,包括其历史记录和分支,进入你指定的目录:

    $ git clone https://github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes
    

    命令的输出应该如下所示:

    Cloning into 'Implementing-GitOps-with-Kubernetes'...
    remote: Enumerating objects: 151, done.
    remote: Compressing objects: 100% (94/94), done.
    ...
    Resolving deltas: 100% (32/32), done.
    

我们现在已经学会了如何从头开始创建一个新仓库,或通过克隆一个现有的仓库来创建一个新仓库。接下来,我们将重点了解和使用基本的 Git 命令来开始记录我们仓库中的更改。此步骤对于管理和跟踪项目文件的演变至关重要。

Git 基础知识

理解 Git 的基础知识包括熟悉一系列基本命令,这些命令有助于软件开发中的版本控制。通过这些命令,你可以跟踪并管理项目文件的更改,控制项目演变的每个方面。从暂存和提交更改到管理分支和更新项目以获取最新开发,掌握这些命令对于有效使用 Git 至关重要。本介绍将带你了解git statusgit addgit commitgit branchgit mergegit pullgit push等关键命令,每个命令在 Git 工作流中都发挥着至关重要的作用:

  • git status:此命令显示更改的状态,指示这些更改是未跟踪、已修改还是已暂存。

  • git add:此命令将更改暂存到你的项目历史中。它为下一步做准备,允许你控制哪些内容成为项目历史的一部分。

  • git commit:此命令将暂存的更改保存到项目的历史记录中,类似于捕捉快照。它完成了使用 git add 暂存的内容。

  • git branch:使用此命令查看本地正在工作的分支,从而了解不同的开发线路。

  • git merge:此命令将不同的开发线路合并,通常用于将一个分支的更改整合到另一个分支(例如,将 feature 分支合并到 master 分支)。

  • git fetch:此命令更新你本地的远程仓库变更数据库,在将这些变更整合到本地分支之前,用于查看更新内容。

  • git pull:此命令将远程仓库的更改更新到你的本地开发分支。当你需要在本地环境中同步他人做出的更改时,这非常有用。

  • git push:此命令将本地提交更新到远程仓库,确保远程仓库反映出你的最近更改。

基本的 Git 提交状态推送循环示例

让我们从一个实际的例子开始,展示如何在本地使用 Git,使用Git 基础部分列出的命令。你可以自由使用本章创建和克隆 Git 仓库部分初始化的仓库,也可以从一个新的仓库开始:

  1. 设置 GIT 身份:

    $ git config --global user.email "you@example.com"
    git status command to see the current state of your files, whether they are untracked, modified, or ready to be committed:
    
    

    $ git status

    
    The response to this command should look something like this:
    
    

    在主分支上

    尚未提交

    无需提交(创建/复制文件并使用“git add”进行跟踪)

    
    This indicates that your working directory is clean, meaning that no tracked files have been modified and no untracked files are present. Additionally, it confirms that you’re on a specific branch (`master`) that hasn’t diverged from its remote counterpart.
    
  2. 在工作目录中创建一个新的非空文件:

    README file in the current working directory.
    
  3. 再次执行 git status 命令:

    On branch master
    No commits yet
    Untracked files:
       (use "git add <file>..." to include in what will be committed)
           README
    README file appears with the untracked status because Git recognizes it as a file that is not present in the last commit and that hasn’t been prepared for inclusion in future commits. The untracked status prevents Git from automatically adding files that might not be intended for version control, such as binary files. To include the README file in your project’s version history, you need to explicitly track it with Git, ensuring it’s considered for subsequent commit snapshots.
    
  4. 要跟踪修改,添加新文件,请使用 git add 命令:

    git status command again:
    
    

    在主分支上

    尚未提交

    待提交更改:

    (使用 "git rm --cached ..." 来取消暂存)

    README 文件现在已被标记为暂存,因为它出现在“待提交更改”部分,表示它已准备好进行下一次提交。

    
    
  5. 通过将暂存区准备好,如所需的,现在是时候使用 git commit -m "添加 README 文件" 将更改记录到仓库历史中了,这样我们就能指定我们已实现的修改:

    git commit command should be like the following:
    
    

    [master (root-commit) f933b54] 添加 README 文件。

    1 个文件已更改,1 个插入(+)

    创建模式 100644 README

    
    Whenever you add, modify, or delete one or more files (or non-empty folders), you’ll need to repeat *steps 5* and *7* to ensure that those changes are properly staged and committed.
    

Git 工作流

基本的 Git 工作流涉及一种战略性分支方法,有助于高效的开发和发布过程。此策略包括不同类型的分支:

  • Main (或 Master):项目生命周期中维护生产就绪代码的基础分支

  • Develop:与主分支一起启动,包含预生产代码和正在测试的功能

  • Feature:用于开发新功能,这些分支在完成后会合并回 develop 分支

  • Release:专门用于准备代码发布到生产环境

  • Hotfix:直接在主分支上修复紧急问题

在此工作流中,变更通过提交进行跟踪。提交记录了文件修改的历史,包括修改内容、修改者以及修改时间。这种结构不仅有效地组织了工作,还通过明确定义每个分支的目的并简化新特性、修复和发布的整合,加速了发布周期。图 3.3 展示了一个 Git 工作流示例。

图 3.3 – Git 工作流示例

图 3.3 – Git 工作流示例

最初,仓库的内容位于默认分支中。为了进行修改或添加,建议创建并在自己的分支上进行工作。这种做法可以确保主代码库保持稳定,同时开发特性或修复。深入探讨 Git 的复杂性,如分支、合并和远程策略,超出了本书的范围。然而,对于那些希望深入了解的人,可以参考 PACKT 出版的《Mastering Git》,第[3]章进一步阅读部分中提供了关于高级 Git 概念的全面见解。这是扩展 Git 知识的极好资源,帮助你超越基础知识。

本节结束了我们对 Git 的简要探讨,标志着我们进入 GitHub 之旅的开始。接下来的章节将介绍并深入探讨 GitHub,展示其在 GitOps 世界中的重要性和实用性。

探索 GitHub

GitHub 是软件开发领域的一个重要平台,作为使用 Git 的协作项目的中心。它通过提供基于 Web 的图形界面,扩展了 Git 的功能。GitHub 使得托管公共和私有仓库变得更加便捷,便于个人和团队无论地理位置如何都能共同协作。它的重要性不仅仅体现在代码存储上,还在于促进了一个社区,在这个社区中,开发者可以分享、贡献并在彼此的工作基础上进行建设,推动开源开发文化的发展。

注意

创建 GitHub 账户对于在这个广泛使用的平台上存储源代码至关重要。本书将引导你通过使用 GitHub 来管理公共和私有仓库中的代码。有关账户创建的详细说明可以在 GitHub 网站上找到,你可以在其中找到所有开始使用所需的信息(github.com/)。

SSH 访问提供了一种安全的方式与 Git 仓库进行交互,免去了每次命令输入用户名和密码的需求。它对于无需账户即可克隆公共项目特别有用。然而,对于分叉或推送更改,仍然需要一个账户。有关详细的设置说明,请参阅 GitHub 官方的 SSH 访问指南(docs.github.com/en/authentication/connecting-to-github-with-ssh)。

GitHub 显著提升了协作软件开发,通过支持远程团队合作并简化诸如错误跟踪和持续集成等流程。其拉取请求系统促进了协作,便于代码审查和合并。此外,GitHub 作为一个综合的代码托管平台,支持公共和私人仓库,从而增强了开源和私人项目的支持。这种可访问性和与开发工具的集成使得 GitHub 对全球开发者来说是不可或缺的。

GitHub 的生态系统

GitHub 的生态系统是一个全面而动态的环境,超越了简单的代码托管。它涵盖了一系列支持整个软件开发生命周期的工具、集成、社区功能和服务。这些包括项目管理工具、问题跟踪、持续集成和部署服务以及代码审查设施。此外,GitHub 还提供了一个庞大的社区和开发者网络,贡献开源项目、分享见解,并在各种项目上进行合作。这个生态系统已经成为软件开发世界的一个重要组成部分,促进了全球开发者之间的创新与合作:

  • 版本控制:GitHub 的核心功能是提供基于 Git 的版本控制,用于管理和跟踪代码更改

  • 问题跟踪:包括报告和跟踪项目中的错误、功能请求和任务的工具

  • 协作功能:诸如拉取请求和代码审查等功能促进了协同编程和团队互动

  • GitHub Actions:用于自动化工作流,例如持续集成持续部署CI/CD

  • 项目管理:用于组织和优先排序工作的工具,例如项目和看板

  • 社区与网络:为开发者提供一个平台,贡献开源项目、建立网络并进行合作

  • Marketplace:提供第三方应用和集成,以扩展 GitHub 功能

  • GitHub Pages:提供直接从 GitHub 仓库托管静态网站和文档的服务

  • 安全功能:包括漏洞扫描和管理访问控制的功能

在了解了 GitHub 是什么以及如何访问之后,现在是时候将我们的注意力转向实际应用了。

GitHub 通过集成更好的代码质量工具来增强软件开发流程,例如命令行操作、问题讨论、拉取请求和代码审查,以及 GitHub Marketplace 中可用的大量应用。

它通过 GitHub flow 促进了协作,使开发者能够高效地管理仓库中的工作,概述项目方向,并在彻底讨论和达成一致后无缝合并更新。它从而改变了传统的软件构建方法。

GitHub flow

GitHub 流程是一种基于分支的工作流程,集成了 Git 命令,适用于全球团队。它包括为并行开发创建分支,为可逆的项目点添加提交,并使用拉取请求促进透明度(见本章中的Git 工作流部分)。代码审查是核心,促进了开放文化。合并操作无缝地整合了变更,而部署确保了代码的稳健性。这种工作流程适应了各种协作规模,从小团队到全球贡献,强调拉取请求的讨论和整合。GitHub 的工具取代了传统的邮件审查,简化了开发过程。我们可以将 GitHub 流程总结为以下步骤:

  1. 创建仓库。首先需要在我们的 GitHub 空间中创建一个仓库。在 GitHub 空间的每个页面的右上角,点击+,然后点击新建仓库,如图 3.4所示。

图 3.4 – 创建一个新的 GitHub 仓库

图 3.4 – 创建一个新的 GitHub 仓库

对于仓库名称,你可以选择像gitops-for-k8s-gitops-integration这样的名称。描述是可选的。根据你对开放访问或限制可见性的偏好,决定是选择私有仓库还是公共仓库。确保勾选添加 README 文件复选框,然后点击创建仓库按钮,如图 3.5所示。

图 3.5 – 创建一个新 GitHub 仓库的表单

图 3.5 – 创建一个新 GitHub 仓库的表单

  1. 创建分支。默认情况下,创建的仓库有一个名为main的分支,认为它包含生产就绪的代码。最佳实践建议为我们要实现的每个功能使用不同的feature分支。要在 GitHub 中创建新分支,点击main项目,如图 3.6所示。要创建新分支,点击创建分支 features/docker-file-and-ci,如图 3.6所强调的那样。

图 3.6 – 创建一个新的 features/docker-file-and-ci 功能分支

图 3.6 – 创建一个新的 features/docker-file-and-ci 功能分支

  1. 添加提交。现在是时候向我们的仓库中添加一些有用的文件了。在本练习中,我们将使用本书中第二章Dockerfile部分中看到的相同 Docker 文件。要添加 Docker 文件,请点击添加文件按钮(见图 3.7)。如果选择创建新文件,将会打开一个编辑器,在其中粘贴 Docker 文件内容并提交。另一种选择是选择上传文件,直接从你的计算机上传 Docker 文件。

图 3.7 – 添加新文件或上传现有文件的菜单

图 3.7 – 添加新文件或上传现有文件的菜单

  1. 复制 Docker 文件的内容并将文件命名为dockerfile,如图 3.8所示。点击在第二章Dockerfile部分中使用的requirements.txt文件。

图 3.8 – GitHub 编辑器界面用于编辑仓库文件

图 3.8 – GitHub 编辑器界面用于编辑仓库文件

  1. 通过指定所采取的操作来采用最佳的提交信息实践,例如Create dockerfile作为建议的描述,并提交你的更改。在主页中,选择README文件并在文件开头添加以下行,然后使用默认描述提交更改:

    ## This repository will be used to show GitOps and GitHub capabilities
    

    请参见* [2]中的进一步阅读*部分,了解有关提交最佳实践的有用列表。

  2. 打开一个拉取请求。在main分支派生的分支中进行更改后,你可以启动一个拉取请求,这是 GitHub 协作的核心元素。此功能允许你建议更改,寻求审查以将你的贡献合并到另一个分支,并通过颜色突出显示差异。即使代码尚未最终确定,你也可以在提交后立即使用拉取请求开始讨论。在自己的仓库中练习这一操作,通过自己合并来熟悉 GitHub 的协作流程,是在进行更大项目之前的一个极好的方法。

  3. 在仓库的标签页中,点击仓库的Pull requests标签,然后点击New Pull request。在Example Comparison框中,选择features/dockerfile-and-ci分支与main分支进行比较,如图 3.9所示,然后点击Create pull request按钮。

图 3.9 – 创建拉取请求并选择比较的分支

图 3.9 – 创建拉取请求并选择比较的分支

  1. 在页面底部的比较视图中查看更改。如果它们准确反映了你想要的修改,继续创建拉取请求。为你的拉取请求指定一个标题,并简要描述你的更改,比如详细说明添加了一个 Docker 文件以及使用 GitHub Actions 自动化 Docker 镜像构建。你可以在描述中添加表情符号、图片或 GIF,并通过创建拉取请求来完成。

  2. 讨论和审查代码。开始协作时,需要从同事那里寻求对拉取请求的审查。此步骤允许协作者在最终合并到main分支之前提供反馈或建议修改,从而确保代码集成是以达成共识为基础的。

  3. 在最后一步,将你的features/dockerfile-and-ci分支合并到main分支以添加更新。如果你的拉取请求与main分支之间出现任何冲突,GitHub 会提示你在合并之前解决这些冲突。如果没有冲突,合并应该是顺利的。完成此过程后,选择main分支。

我们已经介绍了 GitHub 和 GitFlow 的基本概念,并提供了一个动手示例。我们鼓励你按照本章中 Git 仓库 部分的指导,使用 Git 命令行工具来克隆仓库。掌握了这些基础知识后,我们准备深入了解将 GitOps 与 GitHub 集成,特别是通过提交自动化 Docker 部署。

集成 GitOps 和 GitHub

GitHub Actions 提供了一个强大的自动化工具,能够在 GitHub 生态系统内帮助开发人员简化软件开发工作流。具体而言,GitHub Action 可以显著增强 GitOps 工作流,通过自动构建和推送 Docker 镜像到服务,并随后将新版本部署到 Kubernetes 集群。这一功能简化了 CI/CD 过程,使团队能够更轻松地在云原生环境中高效维护和更新他们的应用程序。

最佳实践建议,当你想使用这个 GitHub Action 时,你的 GitHub 仓库应该有一个 dev 分支和一个 mastermain 分支,并且应该使用标签进行发布。在以下示例中,为了简便起见,我们将直接在 main 分支上工作。最佳实践建议在不同的分支中进行操作。

以下是使用 GitHub Actions 自动化 Docker 镜像创建的步骤:

  1. 点击仓库选项卡中的 Actions,如 图 3.10 所示:

图 3.10 – 以圆圈标出的 Actions 按钮所在的选项卡菜单

图 3.10 – 以圆圈标出的 Actions 按钮所在的选项卡菜单

  1. 在新页面上,点击 set up a workflow yourself,如 图 3.11 所示:

图 3.11 – 在 GitHub 中手动定义工作流

图 3.11 – 在 GitHub 中手动定义工作流

  1. 在编辑器中,添加以下内容:

    name: Create Docker Image CI
    on:
      push:
        branches: [ main ]
      pull_request:
        branches: [ main ]
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v4.1.1
        - name: Build the Docker image
          run: docker build . --file dockerfile --tag my-image-name:$(date +%s)
    

    name 字段作为我们操作的标识符。在 on 部分,我们指定触发该操作的事件,主要关注特定分支。通常设置为 main。如果你创建了一个新分支并想触发该操作,你需要相应地修改此部分。

    jobs | build 部分,你会找到 runs-on 字段,它指定了我们的任务将在哪种类型的 GitHub 服务器上运行。这与我们的 Docker 镜像版本不同,后者由 Dockerfile 确定。在这个例子中,我们的 Docker 镜像将基于 Ubuntu 20.04。Docker 镜像的构建将在运行 uses 字段指令的 GitHub 服务器上进行,该字段指示工作流执行仓库的检出操作。name 字段为该步骤提供一个标签。最后,run 字段指定要执行的命令。通过这种配置,我们准备好在基于 Ubuntu 20.04 的 Docker 镜像上进行第一次构建。

  2. 为了启动新的构建,我们需要对 main 分支进行修改。你可以通过在 GitHub 的集成编辑器中对 Docker 文件进行简单的注释更改,或者编辑 README 文件来轻松完成这一操作。在图 3.12中,构建是通过更新 README 文件触发的。

图 3.12 – 提交触发的工作流列表,位于 Actions 页面

图 3.12 – 提交触发的工作流列表,位于 Actions 页面

一旦你在仓库中进行了更改,GitHub 将自动检测到这一变化并启动新的构建。你会看到一个指示符,表示构建已被触发。

  1. 要访问构建日志,只需点击 构建,如图 3.13所示。这将引导你到该构建的专用页面。一旦进入该页面,你可以深入了解构建过程的各个步骤,并查看与每个步骤相关的日志,如图 3.14所示。GitHub 还会在构建失败时提供电子邮件通知,你可以方便地在 GitHub 平台中配置你的警报偏好设置。

图 3.13 – 成功构建的总结

图 3.13 – 成功构建的总结

图 3.14 – 构建过程的详细步骤,包含每个步骤的日志

图 3.14 – 构建过程的详细步骤,包含每个步骤的日志

在此阶段,你应该对 Git、GitFlow、GitHub 以及如何开发 CI 流程以便为每次提交构建 Docker 镜像有一个全面的理解。

摘要

本章深入探讨了 Git 在版本控制中的关键作用,以及 GitHub 在 GitOps 框架中对协作软件开发的支持。本文概述了这些工具在提升团队效率、自动化部署流程和促进稳健 DevOps 文化中的重要性。涉及的关键内容包括使用 Git 和 GitHub 的技术要求、VCS 的好处、Git 和 GitHub 的功能以及 GitOps 实践的整合。最后,本章总结了一些利用 Git 和 GitHub 精简工作流程效率的最佳实践。

在接下来的章节中,我们将探讨额外的工具,如 Argo CD 和 Flux CD,并将它们与 GitOps 集成,从而使我们能够通过部署环节完善我们的流水线。

深入阅读

第四章:GitOps 的规模化与多租户

本章深入探讨了GitOps的高级应用,重点是 Kubernetes 环境中的扩展性和多租户问题。内容针对那些已具备如Argo CD等工具基础知识的人,并希望在更复杂的场景中扩展知识。

我们将从讨论如何使用 GitOps 构建可扩展的集群基础设施开始。这包括设计能够适应日益增长的需求的 Kubernetes 集群,所有这些都通过 GitOps 方法进行管理。讨论的一个重要部分是如何高效地在多个集群间部署应用,重点关注可扩展性和定制化。

我们将重点讨论在共享的 Kubernetes 环境中强制实施多租户。我们将探讨如何使用 GitOps 工具(如 Argo CD)实现这一目标,并遵循其操作哲学。与此同时,我们还将介绍如vCluster等工具,这些工具简化了多租户的强制执行,同时保持 GitOps 原则。

本章的重点是概念而非工具。尽管工具可能会发展变化,但其背后的基本原则保持不变,为理解这些技术提供了稳定的基础。

我们还将讨论如何实现轻量级的内部开发平台(IDP),以便通过Kubernetes 服务目录(KSC)促进第三方工具的部署。这种方法简化了 Kubernetes 中的应用管理。

现实世界的见解是本章的重要组成部分,借鉴了在不同项目环境中积累的经验和教训。这个实践视角对于理解这些策略在实际应用中的效果至关重要。

本章面向中级学习者,不会深入探讨 Argo CD 的安装或基本操作。相反,它将重点介绍这些工具在复杂的现实场景中的应用,展示为每种情况选择最合适工具的实际使用。目标是通过关注方法而非工具,帮助你全面理解如何使用 GitOps 在 Kubernetes 中扩展和管理多租户环境,并结合现实世界的应用和见解。

本章内容较为艰难,但我希望你在完成后能够学到很多。我尽量以简洁的方式将项目中的所有见解与您分享。本章可以逻辑上分为两个部分。第一部分涵盖了使用 GitOps 进行规模化应用的策略及通过 KSC 进行的必要设置。第二部分,从第 45 页开始,侧重于使用 GitOps 进行多租户管理,以便最大化地利用设置。

本章将涵盖以下主要内容:

  • 理解“应用之应用”方法

  • 理解多集群管理

  • 理解有效的 Git 仓库策略

  • 构建 Kubernetes 的服务目录

  • 探索使用 Argo CD 实现本地多租户功能

  • 使用 vCluster 和 Argo CD 探索多租户

技术要求

由于空间有限,许多示例已被简化或不完整。因此,我们提供了一个包含完整示例的代码库。它遵循 chapter05/section 的模式 —— 即 chapter05/chapter-5-building-a-service-catalog-for-kubernetes。所有讨论过的代码示例以及其他资源,请参考书籍 GitHub 仓库中的 Chapter05 文件夹,网址为 github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

传统 CI/CD 与 GitOps CD 的对比

传统 CI/CD 和 Argo CD 之间的主要区别在于部署处理方式

图 5.1 – 传统 CI/CD 与 GitOps CD 的对比

图 5.1 – 传统 CI/CD 与 GitOps CD 的对比

传统 CI/CD 遵循一种工作流,在该工作流中,变更会自动集成、测试并部署,而 Argo CD 使用同步机制确保实际状态与 Git 仓库中的期望状态匹配。Argo CD 依赖 CI 步骤,这意味着任何更改必须经过 CI 流程,Argo CD 才能检测到并采取行动。这确保了只有经过验证的更改会被部署。与 CI/CD 不同,CI/CD 可能需要手动干预,这可能导致不一致,而 Argo CD 持续监控并同步系统状态与 Git 仓库,减少漂移的风险并保持一致性。

在接下来的部分,我们将探讨平台工程与 IDP 之间的区别

平台工程与 IDP 的对比

在我看来,内部开发平台IDP)和内部开发门户IDPO)之间的区别变得越来越重要,已经成为许多讨论的话题。为了澄清这些不同的概念,以下是我对这些术语的区分:

  • 平台工程:这是传统的方法,专门的团队负责拥有、运营和持续改进 Kubernetes 平台本身。团队的关注点是底层基础设施,确保其稳定性、可扩展性和安全性。开发人员通常使用这个平台,专注于他们的软件或平台团队未提供的第三方工具。这是许多项目中常见的方法。

  • 内部开发平台 (IDP):该方法引入了一种 IDP 解决方案,如 Spotify 的 backstage.io。IDP 团队负责提供和维护 IDP 本身,其中包括广泛的文档、构建块和开发人员模板,并充当开发人员的门户(IDPO)。开发人员可以利用这些资源,在定义的 Kubernetes 环境中自我部署应用。这样,开发人员就可以通过贡献或请求对 IDP 的内容和功能产生一定的影响。平台团队的工程重点从核心 Kubernetes 操作转向管理和发展 IDP。然而,开发人员仍然负责其部署的 Kubernetes 环境的日常操作,包括更新和故障排除。

现在,让我们探索“应用之应用”方法。

理解“应用之应用”方法

在管理多个应用时,主要有两种成熟的策略:应用之应用方法和应用集。本节将解决几个关键问题:

  • “应用之应用”方法克服了哪些挑战?

  • 在哪些情况下“应用之应用”方法最为有利?

  • “应用之应用”方法如何提升 GitOps 实践?

在此上下文中,应用 指的是存储清单的 Git 仓库和文件夹,这些清单是运行应用在 Kubernetes 中所需的基本定义。Argo CD 很灵活,它支持原始 YAML 清单、自定义配置管理以及流行的工具,如 KustomizeHelmJsonnet

那么,对于必须部署多个应用的场景怎么办?我们应该如何管理这些清单?每个部署的应用都需要一个应用定义。然而,当这些应用是相关实体的集合时,如果 Argo CD 能识别这种关系,将会更有利。为了解决这一需求,Argo 社区开发了“应用之应用”方法。实际上,这种方法允许定义一个根 Argo CD 应用,进而定义和同步多个子应用。这种方法通过利用分层的文件夹结构,简化了管理流程,特别是在复杂部署中。

图 5**.2 说明了“应用之应用”方法的一个示例。在此示例中,单个 Argo CD 应用 仅对应一个特定的 Web 应用:

图 5.2 – 应用之应用方法

图 5.2 – 应用之应用方法

检查应用清单可揭示关键细节:

project: default
source:
  repoURL: 'git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git'
  path: ./chapter05/chapter-5-the-app-of-apps-approach/app-of-app/simple-webapp
  targetRevision: main
destination:
  server: 'https://kubernetes.default.svc'
  namespace: app-of-app
syncPolicy:
  automated:
    prune: true
    selfHeal: true

在这里,path 被设置为直接指向特定应用。接下来,让我们探索 图 5**.3 中展示的“应用之应用”方法,以便更全面地理解:

图 5.3 – 应用之应用

图 5.3 – 应用之应用

与之前指向单个应用程序清单不同,根应用现在引用 Git 仓库中的特定文件夹。该文件夹包含所有单独的应用程序清单,这些清单定义并促进每个应用程序的创建和部署。通过采用这种方法,您可以在统一的 YAML 清单中声明所有应用程序。以下示例展示了这一模式,以便更好地理解:

project: default
source:
  repoURL: 'git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git'
  path: ./chapter05/chapter-5-the-app-of-apps-approach app-of-apps/simple-webapps
  targetRevision: main
  directory:
    recurse: true
 destination:
  server: 'https://kubernetes.default.svc'
  namespace: app-of-apps
syncPolicy:
  automated:
    prune: true
    selfHeal: true

在提供的定义中,path 属性指示 Argo CD 定位到仓库中的特定目录——在此例中为 simple-webapps。该目录包含定义应用程序的 Kubernetes 清单,并支持诸如 Helm、Kustomize 或普通 YAML 文件等多种格式。在所提供的配置中,有两个值得注意的属性:selfHeal: truedirectory.recurse: trueselfHeal 功能确保在检测到任何变化时自动更新子应用程序,保持一致的部署状态。此外,recurse 设置允许迭代 webapps 文件夹,从而促进所有包含应用程序的部署。

因此,App of Apps 方法使您能够通过简单地更新 Git 仓库中的清单来管理您的应用程序资源——根据需要添加或删除应用程序资源。这种方法减少了对通过 Web UI 或 CLI 与 Argo CD 应用程序直接交互的依赖。

App of Apps 的用例及示例

Argo CD 中的 App of Apps 方法对于将多个应用程序作为单个实体进行管理,同时确保它们在部署过程中的隔离性非常有利。这在诸如集群引导和管理 Argo CD 应用程序而不依赖 CLI 或 UI 等场景中特别有用。让我们通过相关示例来探讨这些用例:

  • 集群引导:假设您有一组标准的应用程序,需要在每个新的 Kubernetes 集群中安装。与其单独部署每个应用程序,不如将它们分组为一个“根”应用程序。这样可以简化过程,允许您同时部署整个应用程序集,从而提高不同部署之间的效率和一致性。

    开发者和服务提供者示例:假设您正在开发或提供涉及为每个部署部署一个自定义但相似的技术栈的服务,如下所示:

    • 前端

    • 后端与前端

    • 数据库

    App of Apps 方法允许您将这些组件封装为一个单一的部署实体,从而简化过程。

  • 无需 CLI 或 GUI 管理 Argo CD 应用程序:你可以使用 Git 操作修改现有的根应用程序,例如添加新的文件夹到其监视的路径中。这个功能让 Argo CD 能够自动部署新的应用程序或更新现有应用程序,而无需通过 CLI 或 Web UI 进行交互,这与 GitOps 的版本控制和可审计性原则保持一致。

    平台工程师示例:作为平台工程师,假设你为每个客户在 Kubernetes 上提供类似的技术栈,例如如下所示:

    • Ingress-Controller

    • Cert-Manager

    • External-DNS

    “应用的应用”方法在这里非常有用,因为它使你能够有效地管理这些组件,确保每个客户的环境都能始终如一地配置所需的工具。

在这两种使用场景中,“应用的应用”方法使得部署过程更加简洁、高效和一致,无论你是在作为服务提供商处理不同的客户需求,还是作为平台工程师确保多个 Kubernetes 集群的一致性。

ApplicationSets 方法

在本节中,你将了解通过使用ApplicationSet [1] 控制器来创建、更新、管理和删除多个 Argo CD 应用程序的过程。

我们将深入探讨ApplicationSet的概念,并解答以下关键问题:

  • ApplicationSet究竟由什么组成?

  • ApplicationSet的功能和优势是什么?

  • 为什么需要生成器,且有哪些不同种类?

在 Argo CD 框架中,ApplicationSet [2] 显著提升了 Kubernetes 中持续部署CD)的 GitOps 策略。该工具巧妙地处理了管理各种 Kubernetes 清单的复杂性,例如部署、服务、密钥和配置文件,所有这些都保存在 Git 仓库中。与 Argo CD 应用程序资源不同,后者仅限于从单一 Git 仓库部署资源到一个集群或命名空间,而 ApplicationSet 扩展了这一功能。它利用模板化自动化来同时创建、修改和管理多个 Argo CD 应用程序,从而扩大了其操作范围,涵盖多个集群和命名空间。

安装在与 Argo CD 相同命名空间中的 ApplicationSet 控制器发挥着至关重要的作用。它通过 ApplicationSet 的自定义资源CR)生成多个 Argo CD 应用程序。这种安排确保你的 Argo CD 应用程序与指定的资源保持同步,实质上将 ApplicationSet 转化为一个或多个 Argo CD 应用程序,从而提升整体部署效率和可扩展性。

生成 指的是控制器使用各种 生成器 的过程,那么这些生成器到底是什么呢?在 ApplicationSet 资源中,生成器通过创建将被纳入模板字段的参数,从而发挥重要作用,最终生成 Argo CD 应用程序。关于这一过程的实际示例,请参阅本章引言。生成器的功能由其数据源决定。例如,List 生成器从预定义的列表中获取参数,Cluster 生成器使用 Argo CD 集群列表,Git 生成器从 Git 仓库中的文件或目录中获取源。

ApplicationSets 中有许多不同的生成器,适用于不同的使用场景和角色。例如,Cluster 生成器非常适合 平台工程师 用于扩展他们的平台,而 Pull Request 生成器则允许开发人员通过 GitOps 部署功能给 QA。此外,Matrix 生成器 允许将最多两个生成器组合在一起,以满足更具体的需求。

我们将利用 Cluster 生成器来大规模实现 GitOps。超越理论,让我们深入探讨它的实际应用。我们将从一个单一集群开始,给它添加一个标签,如 env=prod。可以在 Argo CD 用户界面中通过导航到 设置 | 集群 | 选择集群内 | 编辑 | 添加标签 来完成:

图 5.4 – 添加标签

图 5.4 – 添加标签

现在,创建一个 ApplicationSet 清单,如下所示:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: simple-webapp
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: prod
        values:
          branch: main
  template:
    metadata:
      name: "{{name}}-simple-webapp"
      annotations:
        argocd.argoproj.io/manifest-generate-paths: ".;.."
    spec:
      project: default
      sources:
        - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
          targetRevision: "{{values.branch}}"
          path: ./chapter05/chapter-5-the-app-of-apps-approach/applicationsets/simple-webapp
      destination:
        name: "{{name}}"
        namespace: "argocd"
        syncOptions:
          - CreateNamespace=true

在这里,我们使用了 Cluster 生成器,它旨在将我们的 simple-webapp 部署到多个 Kubernetes 集群中。通过使用 env=prod 选择器,ApplicationController 会根据集群的数量创建多个应用程序。每个应用程序的名称将被修改为包含集群名称,例如 in-cluster-simple-webapp

要应用 ApplicationSet,请使用以下命令:

kubectl apply -f simple-webapp-applicationset.yaml

要查看 ApplicationSet,请运行以下命令:

kubectl get applicationsets -n argocd

你也可以通过以下方式查看模板化的应用程序:

kubectl get application -n argocd

当你检查 Argo CD 用户界面时,你不会直接找到 ApplicationSet,但你会看到名为 in-cluster-simple-webapp 的模板化应用程序。该应用程序由应用程序控制器以如下方式管理:

图 5.5 – 通过 ApplicationSet 模板化的应用程序,由应用程序控制器管理,并通过 Cluster 生成器提供信息

图 5.5 – 通过 ApplicationSet 模板化的应用程序,由应用程序控制器管理,并通过 Cluster 生成器提供信息

通过 ApplicationSet 清单可以查看模板化的应用程序,其中应用程序控制器使用 Cluster 生成器来设置必要的参数。

应该使用哪种方法?

在我参与的多数项目中,团队倾向于使用单独的应用程序和 ApplicationSets,而不是应用程序的应用程序方法。从平台工程师的[3]角度来看,为了通过 GitOps 创建可扩展的基础设施,ApplicationSets 方法似乎是最合逻辑的选择。

Argo CD 中的“应用程序的应用程序”模式适用于以下方面:

  • 引导多个应用程序:高效地同时部署多个应用程序。

  • 将应用程序作为单一单元进行管理:简化多个应用程序的管理。

  • 优化部署工作流:简化应用程序的部署和更新过程。

ApplicationSets 在以下场景中特别有用:

  • 为多样化的环境创建灵活的部署策略:可以部署到多个 Kubernetes 集群,部署到不同集群中的不同命名空间,或部署到单一集群中的不同命名空间(开发人员、DevOps 和平台工程师)。

  • 在 Monorepos 中管理应用程序:从不同的 Git 仓库、SCM 提供商或文件夹中部署(开发人员、DevOps、平台工程师)。

  • 为多租户集群启用自服务:ApplicationSets 可以促进自服务模型,特别是通过 Pull Request 生成器。这允许开发人员在多租户集群中更自主地部署应用程序,无需集群级别的权限(开发人员与平台工程师的协作)。

  • 跨多个集群部署集群附加组件:通过集群生成器,你可以将附加组件部署到 Argo CD 管理的特定集群,这对于大规模的多集群环境非常有用(平台工程师、站点可靠性工程师SREs)和 DevSecOps 工程师)。

与“应用程序的应用程序”方法相比,后者更适合在单一仓库或集群内管理一组相关的应用程序,ApplicationSets 提供了更多的灵活性和可扩展性,特别是在具有多样化部署需求的环境中。它们允许更细粒度和分布式的控制,与复杂的基础设施需求和多集群策略保持一致。

稍后,我们将采用 ApplicationSet 来开发一个 IDP 的可扩展模型,称为 KSC。该平台旨在高效管理大量 Kubernetes 集群,同时确保持续更新的安全措施得到维护。

接下来,我们将深入了解在 Argo CD 的 GitOps 环境中,多集群管理意味着什么以及它为我们打开了哪些可能性。

理解多集群管理

在本节中,我们将深入探讨两种不同的方法,来管理 GitOps 框架中的多集群环境。我们的重点不在于工具本身,而是在于如何将这些集群作为一个统一的平台来协调和管理的总体战略。通过这次探索,我们希望能够传达一种更深入的理解,强调有效的协调才是关键,而不是具体工具的对比。我们将讨论两个不同的概念:

  • 一个控制台,统领一切:该概念强调以集中管理和协调多个集群,作为一个统一的平台。

  • 一个控制台 – 多样化舰队管理:该概念侧重于从单一控制点管理多个 Argo CD 集群,同时考虑集群间通信的安全性问题。

在工具选择方面,我们的经验表明,Argo CD 由于其支持集群、ApplicationSets 和生成器,比 Flux 更适合在多集群环境中通过 GitOps 进行扩展,后者缺乏专门的多集群管理概念。当管理扩展到超出专用集群的场景,如主机集群中的vCluster方法时,这种差异更为明显。

这里有一些关于在 GitOps 框架中进行多集群管理的额外考虑因素:

  • 高可用性和灾难恢复:包括在多个区域部署,甚至使用多个提供商,以确保系统的稳健性和恢复力。

  • 现有专业知识:组织内 Kubernetes、云计算或 GitOps 的知识水平起着至关重要的作用。

  • 预算限制:多集群管理的成本不应超过预定的金额。

  • 合规性和法规要求:确保在不同区域或行业遵守行业标准和法律法规。

  • 网络基础设施和延迟:优化网络性能和减少延迟,这在地理分布较广的集群中尤其重要。

  • 云或服务提供商实现:例如,AKS 与 Flux CD 一起使用进行 GitOps 实现,而 OpenShift 使用 Argo CD 进行 GitOps 部署。

总体而言,选择 Argo CD 或 Flux CD 的关键在于它们在协调和管理多集群环境方面的能力,以及具体的使用案例需求。

一个控制台,统领一切

在这种方法中,开发人员和平台工程师共享一个 Argo CD 实例(图 5.6)。这个共享实例使平台工程师能够提供集中式管理功能,并对各个 Kubernetes 集群进行全面控制。他们管理和监控所有的部署,确保开发人员能够访问所需的资源,同时遵循公司政策和安全标准。这种方法促进了协作,并提供了所有集群的统一视图,有效地减少了大型分布式组织中的复杂性:

图 5.6 – 一机掌控 – 使用共享 Argo CD 实例

图 5.6 – 一机掌控 – 使用共享 Argo CD 实例

在 GitOps 使用 Argo CD 的 一机掌控 方法中,以下是一些关键的考虑事项:

  • 开发人员访问:确定开发人员访问 Argo CD UI 需要建立与组、项目和角色相关的 基于角色的访问控制 (RBAC),可能还包括 Dex 和 OIDC 提供者的集成。

  • 项目访问控制:限制团队对特定项目的访问,以防止在集群间未经授权的部署。

  • 资源分配:节省是否在正确的领域进行?这个问题促使对资源分配进行关键评估,质疑成本节省是否有效地集中在最大化效率和整体价值的领域。

  • 版本更新:协调多个团队共享实例中 Argo CD 的更新至关重要。这种协调确保版本兼容性,防止与 API 废弃相关的问题,保持一个稳定和功能齐全的 GitOps 环境供所有团队使用。

与多个团队合作时,这种方法带来了众多问题和考虑因素,需要解决,强调了有效实施所需的复杂性和规划。

以下是我们在使用这种方法时的几点经验:

  • 共享 Argo CD 的使用常常导致系统负载增加,偶尔引发故障

  • Argo CD 的 PR-生成器等功能的集成增加了复杂性

  • 这需要强大的多租户框架和工具

  • Argo CD 作为唯一的控制点,引入了系统故障的更高风险

  • 团队数量的增加显著提高了沟通和系统维护的要求

  • 虽然在硬件资源上有节省,但这些节省被对人力资源的更大需求所抵消,这些人力资源用于管理和协调。

我们采用这种方法来共享集群,以便促进冷启动、节省资金和资源、提供学习平台,并提供共享服务,如文档和执行器。共享集群更适合孵化项目,当一个项目成熟或需要进入生产阶段时,应该转移到自己的集群上。

一机掌控 – 多舰队指挥官概念

在这一概念中,平台团队将使用一个 Argo CD 实例来部署和管理开发团队所需的整个基础设施。平台团队还会为每个团队部署专用的 Argo CD 实例,并为每个团队提供专用 UI。重点依然相同,但更侧重于编排过程以及将这些集群管理为一个统一平台的方式。开发者将获得自己的专用 Argo CD 实例:

图 5.7:一个驾驶舱 – 多样化舰队管理,每个集群都有专用的 Argo CD 实例

图 5.7:一个驾驶舱 – 多样化舰队管理,每个集群都有专用的 Argo CD 实例

一个驾驶舱掌控一切的方法相比,这种方法涉及以下几个方面:

  • 专用的 Argo CD 实例:每个集群由其自身的 Argo CD 实例管理,从而增强了每个集群的自主性并减少了单点故障的风险。

  • 自主项目管理:每个团队在其指定的集群内管理项目,从而实现更大的控制和定制化。

  • 资源分配:与其依赖共享的 Argo CD 实例,不如每个集群运行自己的堆栈。虽然这种方式可以在每个集群的独立 Argo CD 实例内提供集中的资源管理,但可能会导致整体资源消耗增加。

  • 版本控制自主性:每个团队控制其 Argo CD 实例的版本更新,确保在其集群环境内的平稳运行和兼容性。

下面是我们在使用一个驾驶舱 – 多样化舰队 管理方法中的一些经验:

  • 更高的自主性:专用资源和 UI 访问权限赋予更多的自由灵活性责任。这种设置允许开发者进行自助服务并扩展控制,让他们专注于开发。

  • 轻松上手:这种模式简化了 GitOps 的采用,使其适合新手和有经验的团队。采用这种方法,新的同事上手所需的时间更少。

  • 资源消耗:尽管提供了明确的团队隔离,但这种方法可能导致更高的资源使用。

  • 增强的安全性:一个 Argo CD 实例的被攻破不会影响其他实例,从而提高了整体安全性。

  • 平台团队专注:平台团队专注于为可扩展的自助式方法扩展和工程化服务。与开发团队的互动时间减少,同时创建和加固与共享 Argo CD 实例相关的多租户功能所需的时间也更少。

  • 韧性和隔离:这种方法增强了每个项目或开发团队的韧性和隔离性。它消除了邻居噪声问题,其他团队或项目对 Kubernetes 或基础设施的升级不会影响单个团队,确保更平稳的操作并减少干扰。

这种方法用于处理关键工作负载,确保严格的租户隔离,增强开发人员的自服务能力,并在符合安全、治理和合规性严格要求的情况下增强安全性。在 GitOps 领域,尤其是在从安全角度进行 DevOps 实践时,随着规模的扩大,这种方法变得尤为重要。

在大规模管理多集群环境时,GitOps 的重点不仅仅是监督专用 Kubernetes 集群。它还涉及利用 Argo CD 来满足不同的需求并部署多种工作负载,包括客户应用程序和基础设施组件,同时在不同集群之间维持安全合规性。这种方法旨在弥合开发人员和平台工程师之间的差距,促进可扩展性,并提高两个领域的生产力。

然而,GitOps 还有另一个缺口,涉及如何设定最佳的暂存概念。这将在下一节中进行更详细的解释。

理解有效的 Git 仓库策略

在 GitOps 框架中有效地推动应用程序在各个阶段之间的推广,尤其是在大规模操作时,是开发人员和平台工程师面临的一个关键挑战。将应用程序部署到不同的环境涉及超越单一部署场景的复杂性。使用 Argo CD 后,整个过程变得更加可管理,能够在多个集群间部署,而无需多个 CD 管道。

本节深入探讨了管理环境的各种方法:环境分支、每个 Git 的环境以及环境文件夹。每种方法都有其优缺点,选择通常取决于项目的具体需求和团队的专业知识。像Codefresh [4]这样的公司已经开发了解决方案,以便通过 Argo CD 促进阶段传播。然而,本书更侧重于理解这些方法,而非具体工具,引导你选择最适合你环境的策略。

环境分支

GitOps 中的每分支一个环境[4]方法,涉及使用分支来表示不同的环境,如暂存环境或生产环境,通常被认为是一种反模式。这种方法可能会使拉取请求和分支之间的合并变得复杂,产生配置漂移,并在管理大量环境时增加维护难度。它也与 Kubernetes 生态系统相矛盾,通常更适合传统应用程序。在 GitOps 中,建议将应用程序源代码和环境配置分开存储在不同的仓库中,避免使用每分支一个环境的模式。对于部署推广,Git 合并可能会因为冲突和无意更改而变得复杂,这使得推广管理比看起来更为复杂。

每个分支环境方法的优点包括对许多开发人员的熟悉性,以及通过 git 合并推广版本的理论简单性。

然而,如果你正在使用 GitOps 和 Kubernetes,缺点是显而易见的:

  • 复杂合并:通过 Git 合并的推广可能会导致冲突和意外的更改

  • 配置漂移:不同的分支可能导致环境特定的代码,造成配置漂移

  • 维护挑战:管理大量分支可能变得难以控制

  • 依赖变更:管理有依赖的变更会遇到困难,因为并非所有提交都能干净地挑选出来

现在,让我们探索一个简单的部署清单作为示例。

图 5.8:如何在各阶段之间传播

图 5.8:如何在各阶段之间传播

这个基本示例说明了在部署清单中结合传播逻辑的必要性,确保特定的值,例如副本数量,能够根据每个阶段的独特需求进行适当扩展。使用 Helm 或 Kustomize 与 GitOps 一起时可能会遇到挑战,因为 Helm 为各个阶段使用不同的values.yaml文件,而 Kustomize 依赖于覆盖。此外,基于 Kubernetes 生态系统的 GitOps 也带来了自身的复杂性,必须加以管理。

虽然这种方法可能适用于传统应用程序,但对于现代的 Kubernetes 环境来说并不理想。分支仍然可以用于功能开发和 PR 用于测试变更。然而,你仍然需要管道或工作流将变更提交到 Git 中。也有一种在 Argo CD 外部将变更写回 Git 的选项。像 Argo CD 及其 PR 生成器这样的工具可以帮助管理这些过程,但请注意,PR 生成器是将 Git 内容传递到集群中,而不是反向操作。

每个环境一个 Git

main分支通过拉取请求和审查工作流。对于需要更高安全性的需求,组织可以使用两个 git 仓库:一个用于所有与生产相关的配置和环境,另一个用于非生产元素,在确保安全的同时平衡可管理的仓库数量。

在我的职业生涯中,我只遇到过一个团队采用这种方法,专门为了防止初级开发人员无意中访问和暴露敏感数据。

环境文件夹

在 GitOps 和 Kubernetes 中采用 按环境分文件夹 的方法,涉及将不同环境的配置组织在单个 Git 仓库的独立文件夹中。每个文件夹代表一个特定的环境,如 developmentstagingproduction。这种结构使得每个环境的配置能够清晰地分离和管理,简化了更新和维护。它使得 Kubernetes 的部署过程更加简洁,与 GitOps 原则保持一致,通过将所有环境配置保存在统一的仓库中,确保更改的一致性和可追溯性。

要有效地为 Kubernetes 创建文件夹结构,首先需要了解你的业务需求,例如为不同国家开发高度可用的门户以及各自的版本要求。然后,将与业务相关的值(如公司徽标)整合到所有环境中。此外,还要考虑动态的客户相关值,例如客户状态等级,如 silvergoldplatinum。这种方法确保你的 Kubernetes 设置(如最小副本数)与通用和特定的业务需求保持一致。

我们将使用之前在按文件夹分环境方法中所做的相同示例:

图 5.9:如何通过环境文件夹在阶段之间传播

图 5.9:如何通过环境文件夹在阶段之间传播

我们将展示如何使用 Kustomize 轻松实现跨环境的变更传播。第一步是设置特定的文件夹结构来促进这一过程:

图 5.10:带有环境文件夹的示例阶段

图 5.10:带有环境文件夹的示例阶段

探索文件结构时,base 目录包含跨所有环境共享的配置,通常进行的更改较少。对于多个环境同时修改的情况,base 文件夹是管理这些更改的理想位置,因为它为影响不同部署设置的更新提供了一个集中的更新点:

./base/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: simple-webapp
  template:
    metadata:
      labels:
        app: simple-webapp
    spec:
      containers:
        - image: "ghcr.io/la-cc/simple-webapp:1.0.1-stable" #specific version
          name: simple-webapp
          env:
            - name: UI_X_COLOR #business-related values
              value: darkblue
            - name: SUBSCRIPTION_TIER
              value: silver

在这个简单的示例中,你可以看到我们涵盖了之前描述中所有的要点,比如具体版本、与业务相关的值等:

./base/kustomization.yaml:

resources:
  - deployment.yaml

base 文件夹,也称为 mixins 或组件,包含不同环境共享的配置。其内容根据你认为在各个环境中共享的特性来定义,这一决策由你的应用程序的具体需求来指导。在我们的示例中,这个文件夹包括 QA、staging 和生产环境的配置。

在本节中,我们将通过应用 QA 特定的配置,使用 patch.yaml 文件修改基础部署。这种方法允许我们为 QA 环境自定义基础设置,而无需更改通用的部署设置:

./overlays/qa/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patches:
  - path: patch.yaml
namePrefix: qa-
commonLabels:
  variant: qa

以下代码展示了如何使用补丁覆盖基础版本中的颜色,从而允许针对 qa 配置的特定阶段:

./overlays/qa/patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-webapp
spec:
  replicas: 1
  template:
    spec:
      containers:
        - image: "ghcr.io/la-cc/simple-webapp:1.1.5-new-ui"
          name: simple-webapp
          env:
            - name: UI_X_COLOR
              value: aqua

重要提示

Kubernetes 中的 kustomize 工具允许你自定义 YAML 配置,而无需修改原始文件。它通过使用补丁、覆盖层和其他技术,以更结构化和可扩展的方式管理配置变化,从而生成最终的配置清单。

你可以通过在 ..chapter05/chapter-5-effective-git-repository-strategies/folders-for-environments 文件夹内执行以下命令,轻松查看补丁更改,这将显示基础覆盖层已被打补丁:

kustomize build overlays/qa

在这一阶段,我们将对一个包含业务相关值的特定版本进行测试。这个版本将最终成为我们未来“黄金”客户的新版本。

以下代码块展示了如何引用基础版本,链接到正确的补丁,并为所有生成的资源设置相应的名称前缀:

./overlays/stage/kustomization.yaml:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
patches:
  - path: patch.yaml
namePrefix: stage-
commonLabels:
  variant: stage

该过程遵循与 QA 环境类似的补丁方法。

以下代码块展示了如何使用补丁覆盖基础版本中的颜色,从而允许针对 Staging 配置的特定阶段:

./overlays/stage/patch.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: simple-webapp
spec:
  replicas: 2
  template:
    spec:
      containers:
        - image: "ghcr.io/la-cc/simple-webapp:1.1.4-feature-login"
          name: simple-webapp

GitOps 中基于文件夹的方法提供了一个简化的所有阶段概览,消除了在不同分支间切换和比较的需要。然而,这个简单的示例只是表面上的一点。实际上,你将管理各种文件和环境特定的配置。该结构的适应性还允许扩展到区域特定的环境,如 qa-europeqa-asia,并根据独特的区域需求和业务目标进行定制。

以下场景展示了这个方法的强大之处:

重要提示

这个过程是一个外部工作流,独立于 Argo CD,极大地简化了部署管理,通过便于在各个阶段之间进行比较和传播。

  • Linux 中的 diff 命令用于比较两个文件或目录,以行对行的格式显示它们内容的差异。

    你可以通过运行 diff qa/patch.yaml stage/patch.yaml 来查看 QA 和 Staging 环境之间的差异。

  • 用例 2:将应用版本从 QA 环境推广到 Staging 环境:

重要提示

Linux 中的 cp 命令用于将文件和目录从一个位置复制到另一个位置。

  1. 首先,使用 cp 命令将新版本文件复制到 qa/version.yamlstaging-us/version.yaml

  2. 然后,提交并推送更改到 Git。

  • base

  • 现在,再次提交并推送更改到 Git。

  • 此时,你可以从 QA、Staging 和生产环境中移除多余的配置,因为配置已经存在于 base 中。

  • 最后一次,提交并推送更改到 Git。

这种方法通过允许你轻松比较不同的阶段,大大简化了部署的管理。你可以通过选择文件或文件夹快速比较差异,避免了像 挑选提交 这样复杂的 Git 操作。不同阶段之间的变化,例如从 QA 到 staging,能够通过复制和粘贴文件高效处理。此方法的灵活性扩展到不同地区、国家、Kubernetes 发行版和工具,只受限于你的需求。它为多种部署场景提供了可定制和适应性强的解决方案,并且可以通过任何工作流机制实现自动化。

那么,是什么使得这种方法在 Kubernetes 和尤其是在扩展 GitOps 操作时如此有效呢?

这种方法在大规模 Kubernetes 和 GitOps 中的适用性固有于 Kubernetes 本身。Kubernetes 设计为声明式和以配置为中心,能够与结构化的、基于文件夹的方法无缝集成。这种方法支持 GitOps 强调版本控制和可追溯性的核心特性,这对于在大规模 Kubernetes 环境中有效管理配置至关重要。该方法的简洁性和组织性使其成为 Kubernetes 和 GitOps 框架在可扩展性和系统化部署需求中的理想选择。

使用 ApplicationSet 生成器进行扩展

我们已经深入探讨了在 Kubernetes 上以大规模 GitOps 操作中,App of Apps [5] 方法与 ApplicationSets 之间的区别。现在,我们将探讨如何使用带生成器的 ApplicationSets 来开发一个简化的开发者平台,在本书中被称为 KSC。具体来说,我们将展示如何通过 ApplicationSet 在不同的集群中部署 ingress 控制器,每个控制器根据集群特定的值进行定制。我们的重点是使用 kube-prometheus-stack,它采用了带有 子图伞形图,例如 Grafana。

以下是使用伞形 ingress-nginx Chart.yaml 文件的简要概述:

apiVersion: v2
name: ingress-nginx #umbrella chart
version: 1.0.0
description: This Chart deploys ingress-nginx.
dependencies:
  - name: ingress-nginx #subchart
    version: 4.8.0
    repository: https://kubernetes.github.io/ingress-nginx

对于 ingress-nginx 伞形图,使用相同的名称来处理 ingress-nginx.controller.resources —— 用于特定的覆盖设置。这个区别对于不熟悉伞形图的人来说至关重要,因为许多团队因命名重叠而难以将值按预期应用。

现在,让我们了解一下,哪些部分使得我们能够通过 Argo CD 构建可扩展的部署,下面是 nginx-ingress-applicationset.yaml 的相关摘录:

spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: prod
        values:
          branch: main
  template:
    metadata:
      name: "{{name}}-ingress-nginx "
    spec:
      sources:
        - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
          targetRevision: main
          ref: valuesRepo
        - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
          targetRevision: "{{values.branch}}"
          path: "./chapter05/chapter-5-building-a-service-catalog-for-kubernetes/networking/ingress-nginx"
          helm:
            releaseName: "ingress-nginx"
            valueFiles:
              - "values.yaml"
              - "$valuesRepo/chapter05/chapter-5-building-a-service-catalog-for-kubernetes/cluster/{{name}}/networking/ingress-nginx/values.yaml"

你可以通过提供的名称,在本书的 GitHub 仓库中找到完整的示例。

如前所述,生成器的概念保持不变。变化在于应用控制器如何获取主图(见 1图 5.11),为特定目标集群获取自定义值(见 2图 5.11),然后使用 Helm 对这些值进行模板化,并将其部署到目标集群(见 3图 5.11)。以下图示将进一步澄清潜在的过程,增强对后台操作的理解:

图 5.11:带有环境文件夹的示例阶段

图 5.11:带有环境文件夹的示例阶段

这个由应用控制器使用的 ApplicationSet,利用生成器集群修改 Helm 图表,包括主图和子图。该方法有助于在大规模实施 GitOps。市场上广泛使用的工具 Argo CD 在支持这一方法的实施中起着至关重要的作用,支持应用部署的动态和可扩展管理。

在下一节中,我们将展示如何构建 KSG,允许您从该目录中部署跨集群分布的不同服务,并采用扩展方式。

构建 Kubernetes 的服务目录

在本节中,我们将为 Kubernetes 作为轻量级 IDP 开发一个服务目录。该平台将通过 Kubernetes 部署简化必要基础设施的提供。轻量级 IDP 旨在通过 GitOps 灵活地扩展 Kubernetes 集群,随着项目的增长,确保快速的市场交付时间。此外,它还将根据需要促进安全性(security)、财务运营(FinOps)和服务网格(service-mesh)等服务的扩展,同时确保集群保持最新,并简化集群管理,无论涉及多少个集群。这种方法强调了 Kubernetes、GitOps 和可扩展基础设施管理之间的协同作用。

在继续之前,建立您的标签或标记策略非常重要,特别是如果您不希望将整个堆栈部署到每个集群。此时,提供创建和扩展服务目录的机会可能是有益的。在这种情况下,建议部署一个针对不同特定目的的基础 Kubernetes 集群。一个潜在的方式可能如下:

标签 堆栈将 被部署 备注
env: devstagingprod noneplain cluster 不会部署任何堆栈。Dev 应仅用于测试目的,不稳定。
core-basic: enabled argocdexternal-dnsingress-nginx 如果您希望通过 cert-manager 颁发证书,应与 security-basic 一起部署。
security-basic: enabled cert-manageracme-issuerfalcokyvernosealed-secretsexternal-secretsrbac 应该在每个集群上部署以保持集群安全。
monitoring-basic: enabled grafanavictoria metricsmsteams-proxymailhogstunnelprometheus-node-exporterprometheus-alertmanagerfalco-exporter,和 cluster-alerting 将部署没有日志技术栈的监控技术栈。
monitoring-medium: enabled lokipromtailminio-loki-tenant 这个技术栈需要存储,并且应该与 storage-basic: enabled 一起部署。
storage-basic: enabled minio-operatornfs-subdir-provisioner 这个技术栈是 monitoring-medium 技术栈所需的。你也可以在没有 monitoring-medium 技术栈的情况下部署这个技术栈,用于对象存储或 NFS 的其他用途。

表 5.1:使用标签管理不同技术栈的潜在方法

例如,基于你的工作流,使用一个操作员或 CI/CD 流水线,你可以高效地将标签从你的 Kubernetes 集群映射并传输到 Argo CD 集群。

构建服务目录

为了避免超出范围,我们将集中关注构建服务目录时的一些服务,并将使用以下文件夹结构:

图 5.12:目录中可能的服务示例

图 5.12:目录中可能的服务示例

这里,applicationsets 是一个专门用于通过标签在多个 Kubernetes 集群中部署各种服务的目录。在内部,cluster 目录包含多个集群,每个集群都在 ApplicationSet 中进行迭代,并通过集群生成器的参数进行增强。其他目录,如 dnsnetworking 等,将服务按逻辑分组。它们包括 Helm 伞形图表以及针对特定服务的子图表,如 external-dnsingress-nginx

我们现在将回顾著名的 nginx-ingress-applicationset.yaml 文件,该文件已更新以包含标签方法:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: ingress-nginx
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: dev
            core-basic: enabled
        values:
          branch: main
    - clusters:
        selector:
          matchLabels:
            env: prod
            core-basic: enabled
        values:
          branch: main
....

现在,ApplicationController 仅将应用程序部署到匹配 env = dev | prodcore-basic = enabled 标签的集群。结构上类似于 图 5.11 中显示的其他服务的 ApplicationSets,但在来自安全文件夹的 cert-manager 中有一个独特的方面,加入了一个额外的标签,security-basic: enabled,在其 ApplicationSet 中。

以下代码块展示了如何实现它:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: cert-manager
  namespace: argocd
spec:
  generators:
    - clusters:
        selector:
          matchLabels:
            env: dev
            core-basic: enabled
            security-basic: enabled
        values:
          branch: main
    - clusters:
        selector:
          matchLabels:
            env: prod
            core-basic: enabled
            security-basic: enabled
        values:
          branch: main
...

现在,Argo CD 的应用程序控制器仅将 cert-manager 部署到带有特定附加标签的集群。

标签是强大的工具,通过单一的中央 Argo CD 单元,允许你管理本地和公共云环境中的不同技术栈。这种灵活性使得跨多个环境的无缝管理成为可能。结合不同角色的多样化视角,标签促进了以下内容:

  • 平台工程师可以采用这种方法,结合 SRE 原则,提供可扩展的 Cluster-as-a-Service。

  • DevSecOps 工程师可以在所有集群中实施政策,确保治理和合规性。

  • 开发人员可以利用这种方法,在各种客户集群中部署具有自定义值的可扩展应用程序

这种统一的方法简化了操作,并确保在不同环境和角色之间保持一致性。

如果您有额外的清单,专门为您的特定需求量身定制,其中服务需要扩展——例如,如果 Argo CD 在部署到目标集群时需要一个可选的入口,以便通过入口进行外部访问,而不是通过 Kubernetes API 进行直接访问——您可以在system.argocd下引入一个额外的templates文件夹。在此文件夹中,您可以包括一个类似于templates.ingress.yaml的清单,例如以下摘录:

{{- if .Values.ingress -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  annotations:
    kubernetes.io/ingress.class: {{ .Values.ingress.className }}
    ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-passthrough: {{ .Values.ingress.sslPassthrough | default "false" | quote }}
    cert-manager.io/cluster-issuer: {{ .Values.ingress.issuer }}
    cert-manager.io/renew-before: 360h #15 days
    cert-manager.io/common-name: {{ .Values.ingress.host }}
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  rules:
    - host: {{ .Values.ingress.host }}
…

这种方法使您能够覆盖伞形图表中的值,并在必要时部署额外的入口,如下所示:

#overwrite helm umbrella chart values:
ingress:
  host: argocd.your-domain.com
  issuer: "letsencrypt"
  className: "nginx"

如果您的组织使用来自根 CA 的通用证书,所有外部 DNS 都需要这些证书,您可以利用kustomize来建立一个文件夹结构。例如,您可以创建kustomize.dns.external-dns-secrets,并将您的root-ca.yaml文件放入其中。然后,您可以通过几行代码将其集成到external-dns的 ApplicationSet 中,如下所示:

...
      sources:
        - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
          targetRevision: "{{values.branch}}"
          path: "./kustomize/dns/external-dns-secrets"
        - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
...

有了这一点,我们成功创建了一个目录,将扩展我们的服务、政策和应用程序组合的范围。

一个关键点是关注实现大规模 GitOps 的整体方法,而不是专注于诸如 Argo CD 等特定工具。工具可能会更替,例如 Flux 或 Argo CD 的继任者,但保持灵活的战略始终是至关重要的。这类似于不同框架和语言中开发实践的演变,同时保持其基础方法。通过仔细组织各种环境的文件夹,并将此结构与ApplicationSet结合,便形成了一个高效且可扩展的 GitOps 解决方案。这样的策略不仅简化了管理,还显著减少了对任何给定环境的维护需求。KSC 描述了将 CNCF/OSS 项目结合在一起,为开发人员、平台工程师和 SRE 创建一个安全、自管理的服务平台的力量。

奖励——大规模维护与 GitOps 和 KSC

假设您正在管理数百个 Kubernetes 集群,每个集群都有不同的技术栈,并且在每个集群中都有部署核心服务。这导致大约 2000 个应用程序分布在这些集群中。关键需求是保持所有内容的最新和安全。您已经出色地扩展并保持了应用程序的一致性。突然间,在同一天,您使用的 Ingress-NGINX 镜像暴露了两个关键的常见漏洞和暴露(CVEs),同时还有 Cert-Manager 的 bug 修复和增强 External-DNS 弹性的额外配置。所有集群都受到影响。考虑到一切都通过 Helm 图表进行管理,您如何一次性维护所有集群?解决方案如下:

  • 您可以手动检查所有 Helm chart 版本,查看差异,然后升级版本并通过 Argo CD 在所有集群中部署。然而,CVE 和更改并不会在特定时间发布;它们是在发现漏洞后发布的。

  • 您的 Kubernetes 集群中有一个管道或作业,它定期检查服务目录中的 Helm chart 新版本。如果发现新版本,它会创建一个拉取请求,显示所有更改的值,并在满足所有条件或经过审核后自动合并。

第二个选项听起来更好,并且您可以在管道中运行一个脚本,完成这项工作。或者,您也可以使用 GitHub Action 来实现这一目的。

这就是拉取请求的样子:

Name: External DNS
Version in Chart.yaml: 6.23.6
Latest Version in Repository: 6.26.4
between     /tmp/tmp.aJBFfh/diff_value.yaml
and /tmp/tmp.aJBFfh/diff_latest_value.yaml
     _        __  __
   _| |_   _ / _|/ _|
 / _' | | | | |_| |_ 
| (_| | |_| |  _|  _|
 \__,_|\__, |_| |_|           
|___/
returned three differences
image.tag
  ± value change
    - 0.13.5-debian-11-r79
    + 0.13.6-debian-11-r28

之后,GitOps 方法接管,跨所有集群推出更改。通过这种方式,您可以通过 GitOps 中央管理更改并进行部署,从而最小化维护工作,而无需考虑涉及的集群数量。

以下部分将介绍如何仅使用 Argo CD 提供的资源来实现多租户概念。

探索使用 Argo CD 的原生多租户

本章不是关于使用 Argo CD 设置最安全、最优化的多租户环境。这是因为最佳设置取决于您的具体 SRE 动机、安全团队的限制、治理、公司合规政策、行业要求以及团队的技能水平。此外,工具经常发生变化,通常每年有多次小版本更新,引入新功能。因此,我们在这里的重点是创建多租户的实现方法,同时考虑到您应该注意的方面、当前可以解决的问题以及未来的考虑因素。

那么,为什么选择使用 Argo CD 设置多租户环境,而不是为每个项目使用独立的集群呢?

有几个原因:

  • 减少集群数量使得维护诸如 Kubernetes 版本升级等方面变得更加容易。

  • 为了最大化资源利用率和效率,多租户是至关重要的。

  • 在非动态、基于票务的冷启动环境中,尤其是在不是每个 Kubernetes 集群都运行在云中的情况下,多租户成为一种必需。

  • 通过实施 FinOps 实践,每台机器的成本都能得到密切监控和优化。多租户帮助通过最大化多个团队或项目之间资源的利用率来降低整体成本,从而确保高效支出并减少浪费。

在本节中,您将学习如何使用 Argo CD 作为中央管理工具来实施多租户设置,以管理来自不同团队的工作负载。

此设置的环境是一个位于公司自有数据中心的 Kubernetes 平台,受到存储等资源的约束。由平台团队提供的核心 Argo CD 实例用于 GitOps 方法。此核心实例以声明性方式提供平台上下文(如ExternalDNSCert Manager等)。开发团队维护自己的 Git 仓库,访问 Kubernetes 集群则通过Active DirectoryAD)组进行管理。

挑战在于如何在相同的核心 Argo CD 实例上进行部署,同时防止团队滥用该实例并突破各自的隔离环境。

以下是启用安全多客户操作的要求:

  • 团队应当独立工作

  • 每个团队只能访问其指定的命名空间

  • 团队必须避免对其他团队造成负面影响,例如,通过不当的资源配置。

  • 维持声明性 GitOps 方法

  • 扩展的 GitOps 以声明性方式为新项目和新团队进行管理

此外,平台团队的责任起始和结束边界需要清晰明确。为此,您可以考虑以下方法:

  • 平台团队提供平台和上下文,但仅限于初始仓库的设置:

    • 优点:无需管理如个人访问令牌PATs)或SSH 密钥等凭证。

    • 缺点灾难恢复更加具有挑战性;例如,在旋转集群后,开发人员必须重新初始化对仓库的访问。

  • 平台团队提供平台、上下文和初始仓库:

    • 优点:灾难恢复变得更加简化。可以丢弃或迁移无状态集群,GitOps 方法会正确恢复一切。

    • 缺点:必须管理不同团队仓库的凭证。

通过理解并实施这些策略,您可以在资源受限的基于 Kubernetes 的基础设施中有效地管理多租户环境,使用 Argo CD。策略的实施基于开发团队和平台团队的 GitOps 经验。

从平台团队的角度,我们将采用第二种方法,在我们的 Git 仓库中创建一个文件夹,由 Argo CD 聚合,并采用特定的文件夹结构。但首先,让我们看看图 5.13。在这里,您可以看到不同的团队可以访问特定的命名空间,这些命名空间由RBAC配额网络策略进行管理,并通过一个共同的 Argo CD 实例进行管理,包含项目和应用。平台团队还使用 Argo CD 实例为开发团队的新项目提供新的命名空间作为服务:

图 5.13:使用 GitOps 和 Argo CD 的多租户管理

图 5.13:使用 GitOps 和 Argo CD 的多租户管理

每个团队将创建的文件夹结构如下所示:

图 5.14:使用 GitOps 和 Argo CD 的多租户管理

图 5.14:使用 GitOps 和 Argo CD 的多租户管理

在 Argo CD 中,项目代表团队的规章制度。你可以为每个开发团队设置一个项目,从而定义相关的规则集。这样,平台团队可以为开发人员提供足够的“游乐场”。

让我们看一下 argocd-project-devteam-a.yaml

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: devteam-a
  namespace: argocd  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:  description: Enable DevTeam-A Project to deploy new applications  sourceRepos:
    - "*"
  destinations:
    - namespace: "devteam-a"
      server: https://kubernetes.default.svc
  # Restrict Namespace cluster-scoped resources from being created
  clusterResourceBlacklist:
    - group: ""
      kind: "Namespace"
  # Restrict namespaced-scoped resources from being created
  namespaceResourceBlacklist:
    - group: "argoproj.io"
      kind: "AppProject"
    - group: "argoproj.io"
      kind: "Application"
    - group: ""
      kind: "ResourceQuota"
    - group: "networking.k8s.io"
      kind: "NetworkPolicy"

在这个上下文中,AppProject 的结构很简单,包括 sourceReposdestinationsrolesclusterResourcesBlackListWhiteList,以及 namespaceResourceBlacklistWhiteList 等元素。

操作流程涉及确定资源的来源、它们可以部署到的集群以及项目中允许部署的命名空间。它定义了项目可以在集群中创建的资源和命名空间资源,并可选择允许或明确禁止(!)某些操作。

可以设置全局项目,以将配置分发到其他项目。这意味着你可以实施集群范围的限制,这些限制会被其他AppProjects继承,从而不必为每个项目复制整个配置块。

项目角色可以用于授予或拒绝对项目中特定资源的访问权限。这里也使用了全局角色(argo-rbac-cm)和团队或项目角色。然而,如果用户的 Kubernetes RBAC 权限比项目中定义的权限更广泛,项目设置将无法限制他们访问或修改资源的能力。因此,在 RBAC 集群层级约束用户权限是至关重要的。

参考以下示例:

destinations:
    - namespace: "!kube-system"
      server: https://kubernetes.default.svc
    - namespace: "devteam-a-*"
      server: https://kubernetes.default.svc
    - namespace: "*"
      server: https://kubernetes.default.svc

重要说明

在这里,你显式禁止了部署到 kube-system,同时允许部署到 devteam-a 命名空间。然而,这也无意间允许了部署到其他命名空间,如 devteam-b,因为它们与拒绝模式不匹配。这种情况凸显了对 Kubernetes 及相关工具的深入理解在实施大规模 GitOps 多租户方法中的重要性。

现在,让我们看看如何在这个环境中设置应用程序:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: application-initializer-devteam-a
  namespace: argocd
spec:
  project: devteam-a
  source:
    repoURL: https://dev.azure.com/ORGA-X/devteam-a/_git/application
    targetRevision: main
    path: ./applicationset
  destination:
    server: https://kubernetes.default.svc
    namespace: devteam-a
…

资源由 Argo CD 核心实例收集,并通过 GitOps 方法进行部署。此时,平台团队负责管理应用程序,并不允许开发人员自行部署应用程序(参见限制)。你应该小心,因为限制创建资源与操作资源不同。因此,根据你的环境、公司治理和安全指南,你可能需要配置额外的策略和WebHook验证。

devteam-a 在他们的代码库中有一个名为 applicationset 的文件夹。该文件夹表示 Argo CD 的起点。开发人员可以确定应用程序的顺序,并通过 kustomize、Helm 或直接的 Kubernetes 清单文件来部署应用程序。在此配置中,开发人员无法创建诸如应用程序、ApplicationSets 和 AppProjects 等自定义资源。

这种基于 GitOps 的多租户方法存在一些限制:

  • 限制团队访问 Argo CD UI/CLI:团队通常无法通过 Argo CD 的 UI 或 CLI 创建和管理应用程序。如果你希望提供此类访问权限,则需要使用 Dex 服务器,在 RBAC ConfigMap 中创建策略,映射组到角色,或使用项目角色。

  • 限制对监控堆栈的访问:团队可能无法访问监控堆栈。在这个层次上实现多租户也是必要的。

  • CRD 版本冲突的潜在问题:如果两个团队选择为同一服务部署不同版本的 CRD,就必须解决这些冲突。一个解决方法是通过拉取请求阻止此类操作并进行处理。

  • 声明式管理的挑战:声明式管理的概念可能与多租户原则冲突。这是因为 Argo CD 要求自定义资源,如应用程序,必须与 Argo CD 本身位于同一命名空间。一个目前正在开发的 beta 功能可能允许将应用程序部署到不同的命名空间。

选择使用 GitOps 实现多租户时,你可以节省硬件资源。然而,需要考虑的是,维护和执行多租户配置所需的工程资源可能会增加。GitOps 可以简化管理和执行,但它也有自己的约束,取决于使用的工具以及底层 Kubernetes 版本和核心方法。

这就是为什么 AppProject 对于多租户来说不够的原因。为了让开发团队获得完整的 GitOps 体验,单独使用 Argo CD 需要一些执行措施。由于这里描述的限制,可以使用一些工具来减少这些限制。我们将在下一节中讨论这个问题。

探索 vCluster 与 Argo CD 的多租户实现

在上一节中,我们探讨了如何使用 Argo CD 原生实现多租户,并介绍了编写时的当前限制。虽然这些限制未来可能会得到解决,但目前无法确定。

在本节中,我们将通过引入一个名为 vCluster 的工具来扩展多租户方法。该工具通过 Argo CD 以声明性方式启用 GitOps 扩展,解决了之前讨论的大部分限制。这种方法从 Namespaces-as-a-Service 模式转变为更全面的 虚拟 Kubernetes 服务(VKaaS)Kubernetes 服务(KaaS) 方法。

vCluster 是一个开源解决方案,用于创建和管理虚拟 Kubernetes 集群,提出了一种新的 Kubernetes 集群管理方法。它通过建立一个宿主集群,在其上运行类似种子集群的 vCluster,这些 vCluster 在命名空间内操作。此设置允许部署多个集群。必要的 Kubernetes 组件和一个额外的 syncer 作为 Pod 在命名空间内运行,提供一个具有专用 API 的独特虚拟集群。这些虚拟集群尽管运行在宿主集群的单一命名空间内,但提供了独立且完全成熟的集群的假象。特别是在命名空间限制是问题,并且需要与宿主集群的多租户设置不兼容的特定配置时,这种方式尤其有用。

这里的重点不仅仅是工具本身,而是它如何帮助我们满足前面部分中列出的需求。我们将保持相同的需求,并探索 vCluster 如何克服之前讨论的限制。

在我们的上下文中,租户 (图 5.15) 是指由 vCluster 管理的项目,这些项目运行在专用节点上,每个节点都有自己的 Argo CD 实例。因此,在我们的框架中,每个项目都是一个租户,每个租户对应一个命名空间,符合 vCluster 在共享集群中基于命名空间的方法:

图 5.15:如何根据服务将租户分组的示例

图 5.15:如何根据服务将租户分组的示例

完成此设置过程后,如 图 5.16 所示,您的系统将呈现一个配置,其中共享工作负载和隔离工作负载在宿主集群上同时存在。这种并存的程度取决于您如何应用污点和容忍度,以及如何采用其他策略来指导 Kubernetes 的部署决策。这一能力对于有效地将共享工作负载分布到集群中至关重要。

我们即将探讨的方法展示了如何区分客户种子集群的工作负载,这些集群运行在专用节点池上,以及默认节点池和宿主集群的工作负载。需要注意的是,这些宿主集群工作负载对于 Kubernetes 或平台团队的操作至关重要,例如部署种子集群:

图 5.16:vCluster 多租户设置

图 5.16:vCluster 多租户设置

我们将把工作流分为四个步骤。然而,只有前两个步骤是构建 vCluster 多租户设置所必需的:

  1. 步骤 1 – 部署 vCluster

重要提示

对于这一部分,KSC 通过优化/vCluster 进行扩展。

以下代码摘自应用程序,可以在 GitHub 上找到 vcluster-application.yaml 文件,该文件重点关注核心内容。需要理解的是,多个仓库作为源被引用,并且创建了一个 Helm 发布,并使用特定的值覆盖它:

  sources:
    - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
      targetRevision: main
      ref: valuesRepo
  # - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
  #   path: "./chapter05chapter-5-building-a-service-catalog-for-kubernetes/cluster/vcluster-team-a/" #this part allows to deploy additional manifest like rbac.yaml
  #   targetRevision: main
    - repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
      targetRevision: main
      path: "./chapter05/chapter-5-building-a-service-catalog-for-kubernetes/optimization/vcluster"
      helm:
        releaseName: "vcluster-team-a"
        valueFiles:
          - "values.yaml"
          - "$valuesRepo/chapter05/chapter-5-building-a-service-catalog-for-kubernetes/cluster/vcluster-team-a/optimization/vcluster/values.yaml"

此外,我们将部署特定的 Kubernetes 资源,如networkpolicy-deny-ingress.yamlrbac.yaml,以在命名空间级别有效地管理访问控制。这些资源对于确保多租户环境中的安全性和访问协议至关重要。

  1. 第 2 步 – 将运行在主集群上的 Argo CD 连接到 vCluster

    1. 这一步涉及使用 vCluster 和 Argo CD 设置多租户环境。重点是建立 Argo CD(在主集群上运行)与运行在主集群上的 vCluster 之间的连接。此过程从连接 vCluster 开始。你可以通过一条命令来实现这一连接。如果是端口转发连接,可以使用以下命令:
    vcluster connect vcluster-team-a -n vcluster-team-a
    
    1. 当使用 ingress 进行 SSL 透传时,可以通过以下命令建立连接:
    vcluster connect vcluster-team-a \
    -n vcluster-team-a \
    --server=https://vcluster-team-a.example.com
    

    记得配置一些特定于 vCluster 和 ingress-controller 的参数,以启用 SSL 透传。

    1. 一旦设置完成,将主系统上的 Argo CD 连接到 vCluster 的过程就非常简单,可以通过一行命令来完成:
    argocd cluster add vcluster_vcluster-team-a \
    --label env=vdev \
    --upsert \
    --name vcuster-team-a
    

重要提示

在这个阶段,我们已经有效地解决了多租户的挑战。团队现在可以使用熟悉的vcluster connect命令连接到虚拟集群。这一功能对于促进团队的自给自足至关重要。

  1. 第 3 步 – 指向 KSC

    在这里,重点是将虚拟 Kubernetes 环境与服务目录集成。此步骤涉及创建一个应用程序,该应用程序指向一个包含为虚拟集群专门设计的一套应用程序的仓库。这就像之前提供的应用程序示例。通过建立虚拟 KSCvKSC),你可以区分不同的环境,并通过标签来部署,就像管理专用 Kubernetes 集群一样。

    为了实现这一目标,你可以参考我博客中提供的逐步指南[7]。该指南提供了详细的说明和见解,帮助你构建 vKSC。这个资源对于理解如何在多租户环境中使用 vCluster 有效地管理和部署应用程序非常有帮助,确保你的 Kubernetes 环境能够平稳且可扩展地运行。

  2. 第 4 步 – 在 vCluster 中部署 Argo CD,同时在 主集群上运行 Argo CD

    在设置 vCluster 的多租户环境时,我们已经建立了一个代表 vKSC 的文件夹结构。该结构对于组织 vCluster 中的各种服务和应用至关重要。在将 Argo CD 集成到这个服务目录后,与 KSC 中的其他服务类似,我们现在必须使用在主集群上运行的 Argo CD,通过 GitOps 在所有集群中部署 Argo CD。这种方法使得部署过程自动化且一致,有助于避免代码冗余,并能够为每个集群单独修补清单文件。此设置确保了在多租户 Kubernetes 环境中,通过在所有集群中统一部署 Argo CD,能够高效地进行管理和部署。

奖励—简化连接多个 vCluster—一个实用的 bash 脚本

管理多个 vCluster 通常会变得繁琐且混乱,特别是当涉及到单独连接每个集群时。为了解决这个挑战并简化工作流,我开发了一个简单的 bash 脚本。这个脚本大大简化了过程。它基于主集群的上下文运行,并采用一致的命名模式,例如命名空间为vcluster-demo,入口格式为vcluster-team-a.example.com。使用这个脚本,你可以高效地遍历并连接所有 vCluster,从而节省大量时间和精力,轻松管理多集群环境。

使用 GitOps 解决的多租户限制—回顾

使用 vCluster 和 Argo CD 实现多租户,如前面步骤所述,解决了几个关键限制:

  • 团队对 Argo CD UI/CLI 的访问受限:可以通过实施步骤 3步骤 4来解决。每个团队都会获得一个 Argo CD 实例,提供 UI 和 CLI 访问权限,从而增强了自治性和操作效率。

  • 访问监控栈的权限受限:可以通过在 vCluster 中部署额外的监控栈来解决。此步骤确保团队可以使用必要的监控工具,以便有效地管理集群。

  • 与 CRD 版本的潜在冲突:这个问题不再存在,因为每个虚拟 Kubernetes 集群都维护着一个独立的键值存储,具有不同的 CRD 版本。这种分离有效地消除了由于 CRD 版本不一致引发的冲突。

  • 声明式管理的挑战:这一问题通过平台团队在 Argo CD 上提供虚拟集群的能力得以解决,从而使各个团队能够有效地管理他们的专属 vCluster。从开发者的角度来看,按照步骤 3步骤 4的实施(参见《探索 vCluster 和 Argo CD 的多租户功能》部分)可以确保顺利的声明式管理过程。

然而,重要的是要注意这种方法固有的权衡。虽然与每个项目/团队单独使用一个集群的专用方法相比,这一概念看起来更为高效,特别是在资源利用方面,但 vCluster 确实比原生方法消耗更多资源。虚拟集群中的大多数资源可以同步到主集群,而loft.sh(vCluster 的创造者)正在致力于扩展这种双向同步。此外,还有 vCluster Pro 企业版本,提供进一步的增强功能,例如主集群和 vCluster 之间的自定义同步、休眠 vCluster、创建模板等。然而,这里关注的重点不仅仅是工具,而是方法——如何在大规模下使用 GitOps 有效地实施多租户策略。

随着本章的结束,以下部分总结了关键要点。

总结——来自多租户经验的见解和教训。

随着本章的结束,回顾一下我们所学到的关键主题和经验教训是非常有启发性的。从App of Apps 方法开始,我们为理解在 Kubernetes 环境中管理应用程序的复杂性奠定了基础。这个方法强调了采用结构化、可扩展的方式来处理应用程序部署和编排的重要性。

接着是多集群管理,我们探讨了管理多个 Kubernetes 集群的复杂性,这对大规模运营的组织至关重要。这个探索与关于有效 Git 仓库策略的部分相辅相成,重点优化了仓库管理,以提升 GitOps 中心环境中的运营效率。

这一过程进一步展开,涉及了ApplicationSet 生成器构建 Kubernetes 服务目录。这些部分深入探讨了在多个 Kubernetes 集群中有效地扩展应用和服务所需的技术和工具,强调了 Kubernetes 固有的可扩展性和灵活性。

Argo CD 的本地多租户使用 vCluster 和 Argo CD 的多租户部分提供了对不同方法和工具的透彻理解,帮助实现高效的多租户管理。它们强调了如何使用 Argo CD 和 vCluster 实现和管理多租户环境,提供了创建隔离、高效的多租户环境的见解。

在整个探索过程中,出现了几个关键的经验教训和见解:

  • 策略往往比工具的选择更为重要,这加强了方法相对于具体技术的重要性。

  • 本地实现多租户可以节省硬件资源,但可能会增加对工程资源的需求。

  • 使用如 App of Apps 和 ApplicationSets 等模式,可以大大帮助构建适用于不同角色和用例的可扩展部署策略。

  • 使用 Argo CD 管理多个集群变得更简便,特别是结合有效使用标签和 GitOps 方法时。

  • 标签在与 ApplicationSets 和 Cluster 生成器结合使用时,可以促进跨集群的选择性和灵活的部署策略。

  • 尽管本地多租户方法看似资源高效,但它们可能带来复杂性,并且需要更多的工程资源。

  • 像 vCluster 这样的工具提供了一种更为隔离的多租户方法,同时保持声明式管理并利用 GitOps。

  • 需要谨慎管理节省硬件资源与增加工程师和开发者入职培训工作之间的平衡。

  • 大规模的 GitOps 赋能平台工程团队和开发者,使他们能够专注于应用开发,而不是运营负担。

本章结尾时,显而易见的是,理解底层方法为创造多样化且具有深远影响的现实世界解决方案和产品打开了无数可能性。

其中包括以下产品:

  • 平台即服务(PaaS)产品:作为一个平台工程团队,理解这些概念能够帮助创建一个 PaaS 产品。该平台提供一套必不可少的工具和服务,简化了应用开发和部署过程。

  • 面向多样化客户的软件即服务(SaaS)解决方案开发:通过利用 GitOps 和 Argo CD,开发者可以创建可定制的 SaaS 解决方案,这些解决方案易于在不同地区和版本的 Kubernetes 集群中部署。该方法确保了自动化、一致的部署,使开发者能够高效地满足不同客户群体的独特需求。

  • 面向 SRE 团队的部署解决方案:SRE 团队可以利用这些知识来改善他们的部署策略,确保运营中的高可用性和高效率。

  • 面向安全团队的治理与合规工具:安全团队可以利用这些策略在所有集群中实施强有力的治理和合规措施。通过有效使用标签,他们可以建立全面的服务包,以确保遵守安全标准和监管要求。

这些应用展示了本章讨论的策略的多样性和现实世界影响,突显了深入理解 GitOps 和多租户架构如何促成多样化、可扩展且安全的技术解决方案的创造。

总结

总结来说,本章不仅阐明了实现 Kubernetes 中多租户和扩展的各种策略和工具,还强调了深入理解这些概念的重要性。通过 GitOps 和多租户架构的深入探讨,可以发现尽管有多种方法可以提高 Kubernetes 的效率,但每种方法都有其权衡。最终的选择应与组织的特定需求及开发团队的目标相一致。

在下一章中,我们将介绍本章中已部分应用的不同架构,以说明诸如一个驾驶舱控制所有的多集群管理方法,并讨论它们的优缺点、使用案例以及从多个项目中获得的见解。

参考文献

第五章:GitOps 架构设计与操作控制

在快速发展的云原生技术领域,理解并有效实施多种架构框架,对于那些希望充分利用 Kubernetes 潜力的组织来说至关重要。随着我们在本章深入探讨这一主题,我们将探索多种架构,这些架构不仅支持多集群管理——这是上一章部分介绍的主题——还促进了 GitOps 在服务和产品部署中的有效实施,这些部署被许多公司所使用。

我们的旅程将带领我们通过实际场景和从采用不同架构方法的项目中获得的实践见解。通过分析不同公司如何成功地将 GitOps 方法论整合到服务和产品的部署与管理中,我们能够获得在不同背景下有效的方法的宝贵视角。本章特别适合 平台工程师SRE内部开发平台 构建者,因为它专注于部署团队使用的各种运营模型,来提供他们的工作负载或平台环境。

我们将深入研究使用 Argo CDFlux CDCluster API 等工具来管理 Kubernetes 集群和工作负载的细微差别。这些工具在实现 Kubernetes 环境高效和可扩展管理方面处于前沿。

到本章结束时,你将全面理解不同架构选择如何影响 Kubernetes 部署的效果和效率,特别是在 GitOps 背景下。无论你是构建基础设施的平台工程师,确保可靠性的 SRE,还是构建内部平台的开发者,这里分享的见解都将在你追求云原生环境中卓越运营的过程中发挥重要作用。

因此,本章将涉及以下主题:

  • 探索适用于 Kubernetes 环境的多种 GitOps 架构框架

  • 探讨架构选择对 GitOps 效率的影响

  • 为云原生部署量身定制可扩展性、弹性和效率的设计

  • 集中控制 – 使用单个 Argo 实例管理集群

  • 专用实例 – 每个集群一个实例,使用 Argo CD

  • 专用实例 – 每个集群一个实例,使用 Flux CD

  • 中间路径 – 每个逻辑组一个实例,使用 Argo CD

  • 使用 Argo CD 的驾驶舱和舰队方法

  • 集中式 Kubernetes 集群创建 – 利用 Cluster API 和 Argo CD 简化集群部署

  • 深入探讨 Cluster API 和 GitOps – 实践操作

探索适用于 Kubernetes 环境的多种 GitOps 架构框架

探索适用于 Kubernetes 环境的多种 GitOps 架构框架,对于希望简化部署管道和操作工作流的组织至关重要。GitOps 由 Weaveworks 提出,强调将 Git 作为声明性基础设施和应用程序的唯一可信来源。在 Kubernetes 环境中,这转化为一系列最佳实践和模式,指导容器编排的管理与自动化。

GitOps 中的多个架构框架针对不同的组织需求和技术环境。框架的选择通常取决于环境的复杂性、操作的规模和治理需求。

GitOps 的采用在 Kubernetes 架构决策中有多方面的影响:

  • 基础设施即代码(IaC):通过 GitOps,整个 Kubernetes 架构都定义为代码——通常是 YAML 文件,描述系统的期望状态。这种方法使开发人员和运维团队能够协作处理基础设施变更,且这些变更可以像应用程序代码一样进行版本控制、审查和审计。

  • 不可变基础设施:采用 GitOps 的架构框架通常优先考虑不可变性。一旦资源被部署,就不应该在运行环境中手动更改。相反,任何修改都会在 Git 仓库中进行,这会触发部署流程以更新基础设施。

  • 模块化设计:GitOps 鼓励对基础设施采取模块化方法。每个模块,或一组 Kubernetes 资源,都可以作为 Git 中的一个独立项目进行管理。这种模块化与 Kubernetes 的微服务架构哲学相契合,其中每个服务都可以独立部署、扩展和管理。

  • 自动化部署策略:GitOps 下的架构框架通常包含先进的部署策略,如金丝雀发布、蓝绿部署和 A/B 测试。GitOps 工具自动化了这些策略的发布和监控,使得它们能够以受控的方式更容易地实施。

  • 环境一致性:GitOps 确保每个环境——从开发到预生产到生产——都能以高度一致性进行复制。这是通过在不同环境中使用相同的声明性配置来实现的,从而减少了“在我机器上能工作”的现象。

  • 安全性和合规性:通过将架构元素作为代码定义在 Git 仓库中,GitOps 使得安全策略和合规检查能够成为 持续集成/持续部署 (CI/CD) 流水线的一部分。这意味着安全性作为架构的一部分被设计,而不是事后的考虑。

  • 单一仓库与多个仓库:一些组织选择使用一个包含所有配置和应用的仓库,这简化了管理,但在大团队或复杂应用中可能难以扩展。另一些组织则偏好多个仓库,将配置和应用分开,以提供更精细的访问控制和更清晰的关注点分离。

  • 推送与拉取部署模型:在基于推送的模型中,变更从仓库推送到 Kubernetes 集群,通常通过 CI/CD 流水线进行。相反,基于拉取的模型涉及 Kubernetes 集群内的一个操作员监视仓库,并在检测到变更时拉取更新。虽然推送模型提供即时性,但拉取模型因其与 Kubernetes 声明式哲学的契合及增强的安全性而受到赞扬。

  • 单体架构与微服务架构:在 Kubernetes 中的应用架构方面,GitOps 可以应用于单体架构和微服务架构。由于单体架构的单一特性,GitOps 可能更易于管理,但微服务架构通过 GitOps 能够独立部署和扩展服务,从中受益。

GitOps 赋能的 Kubernetes 架构框架正在不断发展,以促进更强大、可扩展和安全的应用部署。拥抱 GitOps 不仅简化了操作工作流程,还加强了软件架构的最佳实践。随着组织采用这些框架,它们必须保持灵活,并愿意适应云原生技术快速变化的格局。

在下一部分,我们将探讨架构选择对使用 GitOps 的影响。

检查架构选择对 GitOps 效果的影响

GitOps 本质上与 Kubernetes 的声明式基础设施管理方法一致,其中系统的期望状态通过代码描述。此状态被提交到 Git 仓库,并作为唯一的“真相来源”。GitOps 的有效性取决于架构选择如何支持声明式模型,从而实现以下几个方面:

  • 版本控制:跟踪变化历史,提供历史背景,并支持回滚到先前状态

  • 变更管理:促进基础设施代码变更的同行评审和批准,提高部署的质量和安全性

  • 自动化同步:确保系统的实际状态自动 converges 到在仓库中定义的期望状态

影响 GitOps 的架构选择

在考虑架构选择对 GitOps 影响时,有几个关键因素需要考虑:

  • 仓库结构:在单一仓库(单体仓库)和多仓库(每个服务或团队一个仓库)之间的选择,可能会显著影响应用程序的可管理性和可扩展性。单体仓库可能简化依赖追踪和版本管理,但随着规模扩大可能变得难以处理。多仓库策略提高了模块化和关注点分离,但需要更复杂的同步机制。

  • 部署策略:架构必须支持多种部署策略,例如金丝雀发布、蓝绿部署或滚动更新。GitOps 工具自动化这些策略的执行,策略选择会影响资源利用、部署期间的停机时间以及在类似生产环境中测试变更的能力。

  • 环境隔离:关于如何隔离和管理环境(开发、预发布和生产)的架构决策将影响 GitOps 工作流。可以通过独立的分支、目录甚至独立的仓库来处理环境特定的配置,每种方法都会影响访问控制、可追溯性和复杂性。

  • 可扩展性:随着组织的规模扩大,架构应能够支持处理更大的工作负载、更复杂的部署以及更多服务的 GitOps 方法。这可能涉及到集群分区、采用多集群策略或利用专门针对可扩展性设计的云原生工具。

  • 安全考虑:架构决策必须确保安全性融入 GitOps 工作流中。这包括从保护 Git 仓库访问权限到加密敏感数据,以及在整个 CI/CD 流水线中自动执行策略。

做出有根据的架构决策

为确保 GitOps 的有效性,组织必须做出有根据的架构决策:

  • 评估组织需求:了解组织在规模、复杂性、合规性和团队工作流程方面的需求。

  • 评估工具兼容性:选择与所选架构兼容并能支持所需部署策略的 GitOps 工具。

  • 促进协作:架构应鼓励开发、运维和安全团队之间的协作,以便利用集体的专业知识支持 GitOps 工作流。

  • 持续优化:架构决策应根据持续运营中的反馈进行重新评估和优化,以适应新的挑战和机会。

总之,在设置 Kubernetes 环境时所做的架构选择对 GitOps 方法的成功具有深远的影响。通过构建一个拥抱版本控制、变更管理和自动同步的架构,组织可以利用 GitOps 提升基础设施的灵活性和稳定性。对仓库结构、部署策略、环境隔离、可扩展性和安全性做出明智决策,将使团队能够充分利用 GitOps 的潜力,从而打造一个更加弹性和响应迅速的基础设施。

为云原生部署量身定制可扩展性、韧性和效率的设计

为实现可扩展性、韧性和效率而量身定制架构设计是云原生部署的基础,因为云环境的动态特性可能带来机遇与挑战。云原生架构使系统能够对故障具有韧性,适应不断变化的负载,并高效利用资源。在融入 GitOps 实践时,这些设计可以系统地实施并持续改进。

云原生架构中的可扩展性

云原生部署预计能够优雅地处理不同的负载。这种灵活性对在需求高峰期间维持性能并在较为平静的时期优化成本至关重要。以下是实现高可扩展性的一些方法:

  • 水平扩展:架构应设计为支持水平扩展,这意味着通过增加应用程序实例来处理增加的负载。

  • 微服务:将应用程序拆分成微服务可以使各个组件独立扩展,从而对资源分配进行精细控制。

  • 无状态应用:无状态应用本质上具有更好的可扩展性,因为任何实例都可以处理任何请求,从而实现简便的水平扩展。

GitOps 可以通过根据 Git 仓库中定义的负载自动调整实例数量来管理这些服务的部署和扩展。

通过冗余和隔离增强韧性

一个具有韧性的系统能够在不产生重大停机或数据丢失的情况下承受并从故障中恢复。以下是实现更强韧性的一些方法:

  • 高可用性:架构必须设计为具有高可用性,并具备冗余组件,在发生故障时可以接管。

  • 故障隔离:微服务架构天然支持故障隔离。一个服务中的问题不应蔓延并导致系统级的故障。

  • 灾难恢复:一个强大的备份与恢复策略以及多区域部署可以确保应用程序在发生灾难性事件时仍然能够存活。

在 GitOps 工作流中,仓库中的期望状态反映了这些高可用性配置,允许系统通过自动重新部署失败的组件来实现自我修复。

主动优化以提高效率。

云原生部署的效率是指用更少的时间、更少的资源和更少的人工干预实现更多的目标。如果事先优化以下方面,你可以在早期就实现高效:

  • 自动扩展:实施自动扩展策略,根据实时指标调整资源,确保高效使用基础设施。

  • 负载均衡:有效的负载均衡将流量分配到各个实例,以优化资源利用并确保一致的性能。

  • 资源限制:在 Kubernetes 中设置适当的资源限制和请求有助于防止任何单一服务消耗过多资源,从而实现更高效的系统。

GitOps 通过基于 Git 仓库中定义的配置触发操作,自动化执行这些策略的过程。

利用 GitOps 量身定制设计。

设计具有可扩展性、韧性和高效性的架构需要精心规划,并使用合适的工具来管理云原生应用的部署和运行。在定制设计时,考虑以下方面:

  • 基础设施即代码(IaC):将你的基础设施和策略定义为代码,以保持清晰且可审计的资源分配和管理过程。

  • 可观测性:实施全面的日志记录、监控和告警,以深入了解系统的性能和健康状态,指导设计调整的决策。

  • 持续改进:利用 GitOps 持续部署更新和改进架构,确保其不断发展以应对不断变化的需求和挑战。

为了让云原生部署在弹性且常常不可预测的云环境中茁壮成长,量身定制具备可扩展性、韧性和高效性的设计至关重要。通过利用 GitOps,团队可以确保这些设计原则在所有环境中得到一致应用,从而快速响应变化并维持强大高效的系统。随着云技术的不断演进,支持这些技术的架构和实践也必须与时俱进,GitOps 为这一持续演化提供了框架。

第十一章 中,我们将探讨不同 GitOps 方法在实际应用中部署真实世界应用程序的实际用法。下一部分深入探讨应用程序设计在 GitOps 中的重要性,强调操作设置的重要性。团队的关注点不仅仅应该是部署应用程序,还应该是选择合适的 GitOps 实例策略以实现有效部署。在使用 Argo CD 等工具实施 GitOps 之前,必须仔细考虑所需的集群数量。我们在前一章简要介绍了单实例方法,同时重点讨论了可扩展性。下一部分将考察各种方法、组织在实际应用中的经验,以及在这些场景中经历的优缺点,特别强调 GitOps 实例的操作控制。

集中控制 - 使用单一 Argo 实例管理集群

随着组织的发展和演变,对可扩展、安全和高效部署策略的需求变得越来越重要。Argo CD 作为 GitOps 领域的关键角色之一 [1, 2],凭借其在多个方面的全面能力脱颖而出,例如性能、安全性、可用性和故障转移过程。在这一部分,我们将深入探讨不同架构模型的细微差别以及操作管理的复杂性。然而,在我们深入讨论这些话题之前,必须首先解决一些在这一领域显著影响决策的前提问题:

  • 安全性考虑:在使用 Argo CD 扩展时,安全性涉及 基于角色的访问控制 (RBAC) 和 单点登录 (SSO) 机制的强大组合。一个关键的安全特性是清单的客户端渲染,这可以减少威胁面。然而,像 HelmKustomizeJsonnet 等工具在生成清单时的强大功能带来了潜在风险,因为它们允许执行任意代码。这就需要谨慎考虑,特别是在较大的实例中,以防止在清单生成中被滥用。

  • 可扩展性的可用性:即使在 Argo CD 扩展时,它的易用性和可扩展性的声誉依然保持不变。然而,在多个 Kubernetes 实例中管理应用程序可能会导致复杂性,例如需要独特的应用程序命名约定,以及在单个 UI 实例中管理大量应用程序的挑战。尽管该工具的 UI 过滤器功能强大,但无法保存,迫使团队寻找创造性的解决方案,比如使用书签保存过滤器。

  • 故障转移策略:GitOps 方法,由 Argo CD 体现,通过简单的 git 提交促进快速变更和恢复。然而,这种设置和拆卸的简便性也暴露了由于配置错误可能带来的重大影响。例如,更新配置管理插件时出现的一个小错误,可能导致大规模的应用程序故障。这引发了“爆炸半径”(blast radius)的疑问——一个配置错误可能带来的影响范围。

  • 性能扩展:Argo CD 有两个版本:标准版和 高可用性 (HA) 版。后者专为可扩展性设计,部署多个关键组件的副本,例如 repo-server。Argo CD 的可扩展性体现在它支持最多 1,500 个应用程序、14,000 个对象、50 个集群和 200 个开发人员,而无需进行重大调整。这个基准虽然保守,但考虑到了应用程序的差异,例如它们的对象数量、清单复杂性和更新频率。这些数据来自 Joseph Sandoval 在 KubeCon 上的演讲以及 Adobe 和 Dan Garfield from Codefresh [3] 的分享,提供了规划扩展需求的基础指导。

总结来说,虽然 Argo CD 是一个强大的工具,能够处理现代软件环境中的复杂扩展问题,但它在性能能力、安全风险、可用性挑战和故障转移策略方面需要仔细考虑。根据组织的具体需求做出正确的架构选择,可以充分发挥 Argo CD 的优势,同时降低与扩展相关的潜在风险。

这种方法——集中控制

这种方法对你来说可能很熟悉。在托管集群方法中,多个团队使用单个 Argo CD 实例来完成不同的任务。平台团队使用这个共享实例来为其他团队部署必要的平台上下文。

重要提示

平台上下文,根据各个公司的需求量身定制,包括有效的 Kubernetes 平台操作所需的关键工具,如 Ingress Controllers 和 Cert-Managers。

开发人员使用相同的 Argo CD 实例来部署他们的应用程序。类似地,SRE 团队利用它部署帮助识别瓶颈、分析性能问题等的工具。安全团队也利用这个共享的 Argo CD 实例来部署其策略,并通过策略引擎强制执行。此外,他们还部署像 kubeclarity [4] 或 trivy operator [5] 这样的安全工具,以监控集群中运行的镜像中的漏洞,跟踪使用的包并检查许可证。然而,现在的重大变化是,取而代之的是一个 Argo CD 实例管理多个集群(图 6**.1):

图 6.1 – 集中控制与单一驾驶舱控制所有集群的区别

图 6.1 – 集中控制与单一驾驶舱控制所有集群的区别

下表概述了优缺点:

优点 缺点
集中视图和控制:跨所有集群的统一视图,用于部署活动 扩展性和性能:扩展需要对单个组件进行调优
简化管理:管理单个 Argo CD 实例以管理多个 Kubernetes 集群简化了行政任务 单点故障:部署可能存在单点故障的风险
API/CLI 集成:只需一个服务器 URL,API 和 CLI 集成变得更加简单 安全影响:所有集群的管理员凭据集中化
网络流量和成本影响:负责 Kubernetes 监控的应用控制器可能会产生显著的网络成本,特别是当集群位于不同区域时

表格 6.1 – 集中控制方法的优缺点

单一控制平面方法涉及一个 Argo CD 实例管理所有集群,这是一种常见的做法,旨在提供统一的应用视图并提升开发者体验。

对于那些根据环境分配访问权限并担心在一个实例下管理所有应用程序的组织,RBAC 策略和 AppProjects 可以建立必要的边界,定义部署位置和访问控制。

该架构还要求建立和维护一个专门的管理集群,用于托管 Argo CD 控制平面,并直接访问所有其他集群。该管理集群的位置可能引发安全问题,特别是如果它涉及到公共暴露。

这里的关键问题是如何在保持协作的同时确保租户分离。在使用 Argo CD 的 GitOps 方法中,内置的 自定义资源项目角色 被用来实现多租户框架。然而,确定谁负责实施、维护和扩展这种方法,以优化共享的 Argo CD 实例,是至关重要的。

如果平台团队负责管理,他们还必须处理安全性、治理和合规性等方面,特别是如果他们拥有集群的管理员权限。这一可行性取决于团队的资源和专业知识。例如,一个资源充足、对平台有核心知识并在安全性和FinOps等领域具有专业技能的平台团队,能够有效地管理这一任务。然而,较小的团队可能会发现维护安全性是一个挑战。

一些公司采纳的解决方案是不同团队之间的协作:

  • 平台团队 ↔ 安全团队

  • 平台团队 ↔ 开发者

  • 平台团队 ↔ FinOps 团队

  • 平台团队 ↔ SRE 团队

平台团队负责与这些团队沟通并实施承诺。他们还必须为安全团队强制执行的必要更改提供合理解释。这个模型适用于员工不超过 30-50 名的较小公司。超过 50 名员工后,平台团队与开发者/SRE 团队之间增加的互动可能会拖慢开发进度。

何时使用集中控制方法

集中控制方法通常是团队在多个集群中实现 Argo CD 时的初步选择。它特别适用于在小型团队框架内管理开发、暂存和生产环境。该模型支持高可用性、可扩展组件、RBAC 和 SSO,适合小规模操作和简洁的网络配置。

何时避免集中控制方法

拥有多个独立团队、广泛网络或需要高灵活性的较大组织应谨慎采用此方法。该模型在关键故障时可能导致较大的“爆炸半径”,且对于大量用户的灵活性有限,可能会带来负面影响。对于托管在虚拟专用云或防火墙后面的 Kubernetes 网络,尽管可以实现,但网络隧道的增加会增加复杂性。

总结来说,集中控制方法的单一控制平面方法,尽管在简化和管理方便性方面提供了诸多优势,但在安全性、可扩展性和性能方面存在风险。组织在采纳这种模型之前,必须仔细权衡这些因素,同时考虑其具体需求、团队规模和网络架构。

下一节讨论每个 Kubernetes 集群的独立 Argo CD 实例及其相关挑战。

独立实例 - 每个集群一个 Argo CD 实例

一个 Argo CD 实例被安装并与其管理的集群共存,这意味着每个集群都有自己的独立 Argo CD 实例。这种方法有多个优点和挑战。本节旨在帮助你理解并实现 Kubernetes 环境中的独立 Argo CD 实例。每个 Argo CD 实例都将安装并与其管理的集群共存,如图 6.2所示。

每个集群和每个团队都从拥有独立的 Argo CD 实例中受益。这意味着每个集群可以独立配置、管理和监控,从而允许根据每个集群的具体需求制定量身定制的管理策略。但这种方法也意味着每个 Argo CD 实例都需要其自己的资源。确保每个集群拥有足够的资源来支持其 Argo CD 实例至关重要。这一要求需要详细的规划和评估,以高效分配资源并避免潜在的资源短缺或不平衡:

图 6.2 – 每个集群独立的 Argo CD 实例示例

图 6.2 – 每个集群的专用 Argo CD 实例示例

让我们来看看一些优缺点,以更好地理解这种方法:

优点 缺点
可靠性提升:每个集群独立运行,提高了整体的可靠性 管理复杂性:每个实例都需要单独管理和更新,增加了整体复杂性
关注点隔离:这种设置提供更好的安全性,因为每个集群是自包含的 访问复杂性:为跨多个实例的用户提供访问权限可能会带来挑战
无需外部网络访问:独立的 Argo CD 实例不依赖于外部网络访问,这对边缘部署甚至是通过 USB 驱动器进行更新的隔离环境至关重要 灾难恢复考虑:由于设置的去中心化特性,灾难恢复需要特别的规划
适用于边缘部署:其独立性质非常适合边缘的集群,确保每个集群完全独立地运行

表 6.2 – 专用实例方法的优缺点

一开始看,这种方式似乎优点大于缺点。经过多年的实践,两个显著的好处已经得到证明。

提高的安全性可能是最突出的好处。通过使用独立的 Argo CD 实例,安全措施可以精确地根据每个集群的独特需求和脆弱性进行定制。这种定制化确保安全协议不仅坚固,而且精心设计,以应对特定威胁,为每个独特的环境提供坚固的防御。

另一个关键优势是 隔离风险管理。在传统设置中,单一的故障或漏洞可能会导致系统范围的危机。然而,通过使用专用的 Argo CD 实例,这类风险被限制在受影响的集群内,显著减少了发生广泛问题的可能性。风险隔离在一个单一漏洞可能导致重大操作中断的环境中至关重要。

然而,根据实际经验,有一个缺点超过了许多优点,特别是当集群和 Argo CD 实例数量增加,维护工作量大幅上升时。

维护负担是另一个重要因素。管理多个 Argo CD 实例意味着每个实例都需要单独的关注——从更新和配置调整到常规监控。增加的工作量可能会给 IT 团队带来压力,要求采用更强大和高效的管理策略,以应对额外的管理任务。

何时使用专用的 Argo CD 实例

独立 Argo CD 实例在需要最大可靠性和可访问性的场景中最为有利,尤其是在外部网络受限或不存在的情况下。这些实例是部署到边缘集群的默认选择,因为它们具有完全的操作独立性。为了扩展这些部署,通常会与基础设施管理工具,如 Crossplane 或 Terraform 进行集成,以简化设置和拆卸。另一种变体是使用中心辐射模型来管理跨多个集群的多个独立 Argo CD 实例。

何时避免使用专用的 Argo CD 实例

然而,独立实例带来了显著的管理开销。在单个团队管理简单的从预发布到生产的工作流的场景下,为每个集群分开使用 Argo CD 可能效率不高。在多个实例之间进行测试和实施变更也会带来挑战。采用金丝雀发布策略来更新一批实例虽然有效,但也为过程增添了另一个复杂层次。

总之,是否使用独立的 Argo CD 实例应该根据组织的具体需求和能力来决定。虽然它们提供了更高的可靠性和安全性,但在管理、更新和灾难恢复规划方面的复杂性必须谨慎考虑。对于某些环境,特别是边缘环境,独立的方式是理想选择,但对于较简单的设置或较小的团队来说,这种方式可能会引入不必要的复杂性。

是否决定为每个集群使用一个 Argo CD 实例,取决于你们组织的具体需求和能力。虽然这种方法能提供更高的可靠性和安全性,但在管理、更新和灾难恢复的复杂性方面需要仔细考虑。这一策略对于边缘部署和外部网络受限的环境非常有效,但对于简单的设置或较小的团队来说,可能过于复杂。

下一节将讨论每个 Kubernetes 集群使用专用 Flux CD 实例及其相关挑战。

专用实例 – 每个集群使用 Flux CD 实例

在 GitOps 工具领域,Argo CD 和 Flux CD 之间的区别至关重要,特别是在考虑它们在每个集群使用专用实例时。虽然 Argo CD 在 GitOps 领域是一个知名工具,但 Flux CD 也占据了重要地位,拥有强大的社区和大量的用户基础。理解这些工具的多样性对掌握 Kubernetes 集群管理的多种选择至关重要。

我的 GitOps 之旅始于 Flux CD,这是一款在长期使用中表现出色的工具,特别是在不需要扩展和管理多个集群的项目中。Flux CD 的这一特定适用性源于其与 Argo CD 不同的方式和功能。

乍一看,Flux CD 的使用可能看起来与 Argo CD 类似,几乎就像是一个简单的图标替换,如 图 6.3 所示,每个集群都有一个专用的 Flux CD 实例。然而,实际使用 Flux CD 的经验揭示了更深层次的复杂性。与 Argo CD 不同,Flux CD 需要在 Kubernetes 和 Helm 上具有更高水平的专业知识,要求团队精通如 HelmKustomizeKubernetes 等工具:

图 6.3: 每个集群的专用 Flux CD 实例示例

图 6.3: 每个集群的专用 Flux CD 实例示例

Flux CD 管理部署的方法围绕 Helm 发布和 Helm 控制器。这些元素对于处理 Kubernetes 中的包部署和生命周期管理至关重要。Flux CD 中的 Helm 控制器提供了一种声明式的方法来安装、升级和管理 Kubernetes 环境中的 Helm 图表,符合 GitOps 原则。这要求团队对 Helm 图表及其管理有扎实的理解。

此外,Flux CD 使用 Kustomizations 来应用 Kubernetes 清单。此功能允许在将资源应用到集群之前进行定制,为管理复杂部署提供了强大的工具。理解并有效使用 Flux Kustomization 需要对 Kubernetes 清单的工作原理以及如何根据特定部署需求进行定制有深刻的了解。

在组织结构方面,有效采用 Flux CD 通常涉及小型、自治的团队,通常由 5-7 名成员组成。这些团队作为更大组织中的独立单元,处理项目并交付特定的产品或服务。这种结构虽然有利于聚焦和高效交付,但由于 Flux CD 的复杂性和所需的高级技能,带来了入职培训的挑战。

使用 Flux CD 进行团队每个集群管理的主要优势在于其灵活性和适应性,使其成为复杂部署场景的理想选择。Flux CD 支持高级定制选项,尤其对具有全面 Kubernetes 和 Helm 知识的团队特别有利。

然而,这种复杂性伴随着陡峭的学习曲线。Flux CD 的高级功能和定制选项增加了其设置和操作的复杂性。因此,将团队融入 Flux CD 工作流可能是耗时的,并且需要更高水平的技术能力。

这次讨论并不集中在比较 Flux CD 和 Argo CD,而是关注“每个集群实例化”方法在两者上的有效性。前面提到的优缺点同样适用于 Flux CD,因为这两个工具都在 Kubernetes 上运行,并采用原生 Kubernetes 方法来促进部署到集群中。然而,需要注意的是,虽然 Flux CD 需要更高的技能水平和对 Helm 图表或自定义化的先验经验,但 Argo CD 也可以直接与普通的 Kubernetes 清单一起使用。

此区分突显了尽管 Argo CD 和 Flux CD 在复杂性和要求上有所不同,但它们都可以有效地集成到每个集群实例化模型中。虽然 Argo CD 提供了更适合较简单场景的用户友好方法,但 Flux CD 的适应性和技术要求使其非常适合更复杂的部署,特别是对于精通 Kubernetes 和 Helm 的团队而言。

理解每个工具的操作细节、优势和需求对于希望优化其 Kubernetes 管理策略的组织至关重要。在集群实例化方法中,选择 Argo CD 和 Flux CD 应基于部署场景的特定需求以及管理团队的技能水平。通过将工具的能力与团队的专业知识和项目需求对齐,组织可以实现其 Kubernetes 集群的高效管理和有效管理。

下一节将会很有趣,因为将结合已经提出的各种概念来帮助您找到一种中间路径。

The middle way – instance per logical group with Argo CD

The middle way – instance per logical group with Argo CD 是一种以使用带有 Argo CD 的控制集群来管理一组集群为中心的方法。这种方法提出了一个精炼的架构,旨在在 Kubernetes 集群管理中平衡可扩展性、可管理性和效率。它涉及每个逻辑集群组(如团队、地区或环境)运行一个 Argo CD 实例,具体取决于组织结构和需求。

在这种模型中,Argo CD 部署在属于特定组的控制集群上。从这个中心点出发,Argo CD 管理该组内的所有集群。这种安排旨在通过整合控制来简化管理流程,但仍保持了不同集群组之间的分离(图 6**.4):

图 6.4 – 基于 Argo CD 项目中逻辑组实例的示例

图 6.4 – 基于 Argo CD 项目中逻辑组实例的示例

这种架构通过将多个集群有效地划分为逻辑组来平衡管理的需求。它提供了一种解决方案,缓解了维护过多独立实例的挑战,同时提供了一种更易于管理和可扩展的方法。此分组不仅提高了操作效率,还增强了系统的安全性和可靠性。与每个集群一个实例的架构相比,开发人员的体验得到了改善,因为按照明确和易懂的分组约定减少了认知负担,简化了集成过程。

让我们来看一下可能的和最合理的分组方式。例如,组可以根据部门进行逻辑排序:

  • 基于部门:不同的部门,如开发、运营或 QA,每个部门都有自己的 Argo CD 实例来管理他们的特定集群。

    • 开发:为开发人员提供一个实例,用于开发新产品特性

    • 运营:为运营团队提供一个独立的实例来管理部署和基础设施

    • QA:为 QA 团队提供一个实例,用于测试和验证产品

此时,开发人员已经拥有一个具有不同工作负载集群的开发环境,可以自主使用。运营部门也有集群组,可以操作对组织至关重要的基础设施组件,例如 LDAP 服务器、DNS 服务器、ACME 服务器、数据库等。QA 部门可以在不同的集群上测试交付的软件特性,进行不同版本的测试,并使用他们的工具进行负载测试。

现在,让我们来看一下项目和地理位置:

  • 基于项目:对于处理多个项目的公司,可以为每个项目分配一个独立的实例,从而促进集中管理和自主性:

    • 电子商务平台:为电子商务项目团队提供一个专用实例

    • 移动应用开发:为从事移动应用的团队提供一个独立的实例

    • 内部工具:用于开发和维护公司内部工具的团队

    在这种情况下,每个项目都会分配到一个独立的 Argo CD 实例。例如,负责电子商务平台的团队可以完全控制他们的部署管道和功能发布,将工作流程定制为项目的具体需求。同样,专注于移动应用开发的团队可以集中管理他们的部署,重点关注移动特定的需求和测试环境。对于内部工具,专用的实例允许团队快速迭代并部署更新,确保内部操作的顺利和高效运行。

  • 地理位置:拥有全球运营的公司可以根据地理区域对集群进行分组,以便更好的本地化和合规性管理:

    • 北美运营:用于北美地区集群的实例

    • 欧洲:为管理欧洲国家集群提供一个专用实例

    • 亚太地区APAC):一个专注于亚太地区特定需求和合规性的实例

    例如,专门为北美运营设立的 Argo CD 实例使团队能够根据当地的合规性和运营标准管理集群。在欧洲,团队可以通过专注于欧洲的实例解决特定地区的要求,如GDPR 合规性。同样,对于亚太地区,可以通过实例满足独特的运营和监管环境,确保部署优化以符合当地的偏好和法律要求。这样的地域性分组不仅提高了效率,还确保了遵守地区性法规和文化细微差别,成为全球运营中的重要策略。

这些分组是有效的,我个人在多个公司中见过这种设置。然而,这与组织结构和项目管理方式更为相关。我还没有看到 Argo CD 在生产环境中的实际使用;我只了解它的概念或概念验证。

尽管集中式控制器减少了某些缺点,例如部署中的潜在单点故障、所有集群的管理员凭证集中化、以及需要为扩展调优单个组件等问题,但这些问题被转移到群组层面。

通过这种设置,出现以下优缺点:

优点 缺点
负载分配:通过将集群分组,这种方法使得工作负载在各组间分配更加均衡,减轻了应用控制器、仓库服务器和 API 服务器的负担。 多个实例维护:这种方法需要维护多个 Argo CD 实例,每个群组一个,这可能会增加管理工作量。
群组特定凭证:凭证是按群组范围划定的,这简化了访问管理,同时保持了安全性。 减少单点故障:虽然每个群组拥有一个控制集群作为中央管理点能减少单点故障,但它也引入了一种新的脆弱性。如果控制集群出现问题,可能会中断所有群组部署的管理。
统一部署活动视图:每个群组都有一个统一的视图来展示所有部署活动,从而简化了监控和管理流程。 集中的管理员凭证:所有群组集群的管理员凭证都存储在控制集群中,简化了访问管理。这种集中方式可以增强安全措施,因为它减少了需要保护的访问点数量。
减少配置重复:由于一个组中的集群可能具有相似的 RBAC、AppProject 和其他配置,这种模型大大减少了重复配置的需求。 管理集群要求:需要一个单独的管理集群来托管 Argo CD 实例,这为基础设施增加了一层,需要设置和维护,可能使整体系统架构更加复杂。

表 6.3 – 中庸方法的优缺点

何时使用中庸方法

中庸方法特别适用于管理每个逻辑组中不同类型集群的组织。它在以下场景中表现尤为出色:不同部门(如开发、运维或质量保证)需要独立控制各自的集群。此方法非常适合处理多个项目的企业,每个项目都有独特的需求,从而实现专注和自主管理。此外,对于跨国公司来说,这种方法有助于根据地理位置有效管理集群,确保符合地区标准并提高运营效率。

何时不使用中庸方法

尽管中庸方法有其优点,但并不适用于每个场景。对于资源有限的小型组织来说,维护多个 Argo CD 实例可能是一个艰巨且资源密集的任务。需要在规模上调整每个实例,再加上需要一个单独的管理集群,这增加了复杂性,而小型或较简单的环境可能并不需要这种复杂性。在集中式控制更为实用和高效,尤其是对于小型设置时,这种方法可能会带来不必要的复杂性。

这种方法在个人管理和集中管理模型之间提供了一个折衷方案,将工作负载分配到各个组,并减少了配置的重复性。它通过限制潜在故障对特定组的影响,增强了系统的安全性和可靠性。然而,它需要仔细规划和考虑组织结构、资源可用性以及运营规模,以确保其与组织的具体需求相匹配。尽管这种方法并不适用于所有情况,但它为中型到大型 Kubernetes 环境提供了灵活高效的解决方案。

下一节将介绍如何使用中央 Argo CD 实例为集群提供所需的工具,并确保开发人员通过集群上的专用 Argo CD 实例保持自主性。

与 Argo CD 配合使用的驾驶舱和舰队方法

在 Kubernetes 和 GitOps 的动态世界中,驾驶舱与舰队方法提供了一种创新的解决方案,结合了集中管理和个体自主性。这种方法涉及平台团队使用一个中央 Argo CD 实例进行总体控制,同时为每个开发者的集群提供各自的 Argo CD 实例(图 6.5)。这种方法专为那些旨在简化 Kubernetes 操作的组织设计,同时也赋予各个团队或部门在集群管理中的自主权。自 2023 年 7 月以来,Flux 已经实现了一个类似的方法,称为 Hub 和 Spoke [6]:

图 6.5 – 驾驶舱与舰队方法的示例

图 6.5 – 驾驶舱与舰队方法的示例

该方法的核心原则依托于两个关键组件——驾驶舱和舰队:

  • 驾驶舱:由平台团队管理,驾驶舱涉及操作一个集中式的 Argo CD 实例。这个中央实例作为指挥与控制中心,负责在组织的所有 Kubernetes 集群中部署和管理关键基础设施组件。驾驶舱的主要角色是确保所有集群之间的关键基础设施元素应用一致。这包括强制执行组织的标准和政策,从而建立一个一致且安全的基础设施框架。

  • 舰队:与驾驶舱的集中式特性不同,舰队为每个开发者或特定团队提供各自的 Argo CD 实例,专门管理其集群。通过这种去中心化,团队能够独立管理应用程序的生命周期,从配置到部署和更新。这样的自主性在促进创新和敏捷性方面至关重要,尤其是在快速发展的开发环境中,快速部署和迭代更新已成为常态。

深入探讨该方法

驾驶舱与舰队方法的双层结构旨在解决大型组织中多个集群的多样化需求:

  • 集中的驾驶舱提供了一个简洁、全面的视图,展示组织的 Kubernetes 基础设施。这种集中化对于大规模操作至关重要,因为在基础设施管理和政策执行中一致性是必要的。通过拥有统一的控制点,平台团队可以高效地管理共享资源、应用全球安全政策,并确保各集群之间的合规性。

  • 而去中心化的舰队则满足了各个开发团队或部门的具体需求。每个团队都可以根据项目需求灵活地调整其集群配置。这种设置在不同团队从事各种项目,每个项目有自己独特的要求和部署策略的环境中尤其有益。

操作动态

实施控制台与舰队方法需要一个精心协调的操作模型,平衡集中治理与去中心化自主性:

  • 一方面,平台团队必须确保集中式控制台有效地管理共享组件,并维护所有集群中所需的标准。这涉及到定期更新、安全补丁和对集中式基础设施的监控。

  • 另一方面,通过舰队模型管理集群的各个团队需要将他们的开发和部署策略与更广泛的组织目标对齐。他们还必须确保自己的实践符合平台团队设定的安全性和政策指南。

以下表格比较了这种方法的一些优缺点:

优点 缺点
集中式视图和控制:为所有集群提供平台上下文部署活动的统一视图。 安全性隐患:集中管理所有舰队集群的管理员凭证可能带来安全风险。
简化的管理:为多个 Kubernetes 集群管理单个 Argo CD 实例简化了管理任务,简化了为舰队集群提供和维护平台上下文的过程。 资源消耗:管理集群和舰队集群都需要消耗额外资源,包括硬件和工程资源。
可靠性提升:每个舰队集群独立运行,这增强了整体的可靠性,并且允许团队之间严格分离。 单点故障:对于舰队集群部署提供平台上下文来说,存在单点故障的潜在风险。
舰队集群的维护和扩展:对于平台团队来说,更容易同时在所有集群中推出新的工具或政策。这也影响着在平台上下文中维护或升级工具的过程。 扩展性和性能:扩展要求对平台上下文中的各个组件进行调优。

表 6.4 – 控制台与舰队方法的优缺点

何时使用控制台与舰队方法

座舱和舰队方法特别适用于管理跨多个集群的多种项目的大型组织。这种策略非常适合那些既需要集中控制共享资源,又需要分散自治权供个别团队或部门使用的环境。它在复杂的多集群环境中尤其有益,在这些环境中需要简化的操作来高效地管理公共基础设施元素和策略。此外,拥有多个团队或部门的组织,每个团队或部门都有独特的操作需求,可以利用这种方法为每个单位提供所需的工具和自主权,以适应其特定项目。跨多个地区运营的全球公司也发现这种方法很有优势,因为它允许集中管理全球标准,同时使地方团队能够根据地区需求管理集群。

何时不使用座舱和舰队方法

相反,座舱和舰队方法可能不适合小型到中型企业,这些企业的集群数量有限且复杂性较低。在这种情况下,创建并维护集中式和分散式系统的设置所带来的开销可能会超过其带来的好处。那些集群需求一致的组织可能会发现更简化、更加集中的方法更高效且实用。此外,资源有限的公司(无论是人力还是基础设施方面)可能会在有效维护双重管理系统方面面临挑战。对于工作流程简化的环境来说,其中开发和部署过程简单且在整个组织中一致,可能无法从混合方法带来的额外复杂性中获得显著的价值。

座舱和舰队方法见证了 Kubernetes 管理不断发展的趋势,提供了一个既全面又灵活的解决方案。它巧妙地解决了大规模组织管理庞大 Kubernetes 基础设施的挑战,在集中控制和分散管理的灵活性之间找到了平衡。这种方法促进了一个协作高效的环境,在这个环境中,平台团队和各个开发团队和谐合作,各自有着独特但相互关联的角色。随着组织在 Kubernetes 之旅中的不断成长和发展,像座舱和舰队这样的方案变得越来越重要,帮助在大规模集群管理的复杂性中找到方向。

为您的 GitOps 需求选择合适的方法

决定采用哪种 GitOps 方法可能具有挑战性,因为没有一种方法适用于所有情况。在我在各行业和公司中的经验中,主要出现了两种方法:大型组织中的驾驶舱和集群方法,随着项目需求进行扩展;以及小型独立团队的每个集群实例方法。然而,每种方法都有其缺点,尤其是在安全性方面,特别是在公共云操作中。为了应对这些挑战并缓解不足之处,请参阅第十三章使用 GitOps 的安全性。像Akuity这样的公司已经开始提供 SaaS 和自托管解决方案,这些方案建立在 Argo CD 的 GitOps 基础上,但颠覆了这一原则。

这一点在下图中得到了说明:

图 6.6 – Akuity 平台的 Argo CD SaaS 和自托管服务示例 [6]

图 6.6 – Akuity 平台的 Argo CD SaaS 和自托管服务示例 [6]

Akuity 平台巧妙地整合了 Argo CD 管理的驾驶舱和集群方法,其中在集群上的 Argo CD 实例会向 Akuity 平台中的中央 Argo CD“驾驶舱”注册。该模型融合了每个集群实例和单一实例架构的优点,有效解决了它们大多数的局限性。

在这个混合代理架构中,代理运行在每个集群内,并建立与控制平面的出站通信,回到驾驶舱中。这种设置显著减少了控制平面和集群之间的网络流量,并且因为不需要直接访问集群或管理员凭证,从而解决了常见的安全问题。这种架构尤其适用于将外部 Argo CD 实例连接到受限环境中的集群,比如本地开发集群。

Akuity 平台简化了 Argo CD 的操作方面。与传统模型不同,传统模型需要一个专用的管理集群来托管 Argo CD,而 Akuity 平台则托管 Argo CD 实例和自定义资源。这一创新不仅简化了管理流程,还引入了自动快照和灾难恢复功能,有效消除了关于单点故障的担忧。

从可见性的角度来看,Akuity 平台提供了所有组织中 Argo CD 实例的集中视图,类似于单一实例架构。该平台通过为每个实例提供仪表盘,展示应用程序健康指标和同步历史,增强了开源功能。它还简化了设置管理,允许通过用户友好的向导轻松编写通常复杂的 YAML 配置文件。此外,所有 Argo CD 实例的活动审核日志功能的加入,极大地简化了合规报告和监控。

如果你查看驾驶舱和舰队方法的缺点,你就能明白为什么 Akuity 提供了创新的解决方案。

下表展示了 Akuity 平台如何最小化或消除表 6.4中提到的大多数缺点:

缺点 解释
安全性隐患:集中管理所有舰队集群的管理员凭证可能会带来安全风险。 舰队集群中的代理消除了驾驶舱中的中央凭证。它通过回到驾驶舱的出站访问操作,消除了对集群的直接访问或管理员凭证的需求,从而降低了安全隐患。
资源消耗:管理集群和舰队集群都需要消耗额外的资源,包括硬件和工程资源。 控制平面与舰队集群之间的网络流量得到了减少。Argo CD 不再需要在特定时间间隔内建立与舰队集群的连接。应用程序同步被减少,因为它们现在驻留在舰队集群中,从而减轻了负担。
单点故障:舰队集群部署存在单点故障的潜在风险,以提供平台上下文。 舰队集群通过自定义资源在集群内部自主获取和存储平台上下文,确保即使在连接丢失的情况下也能保持持续性。
扩展性和性能:扩展需要在平台上下文中调优各个组件。 无消除。调优要求转移到不同的方面,如为每个舰队集群设置特定的 External-DNS 域过滤器,这是扩展的关键。这需要调节值,以便适应每个集群的需求。

表 6.5 - Akuity 平台如何最小化或消除表 6.4中提到的大多数缺点

本质上,Akuity 平台采用并增强了驾驶舱和舰队方法,允许舰队集群中的 Argo CD 实例连接回中央的“驾驶舱”,从而提供了一种无缝、安全且高效的方式来管理大规模 Kubernetes 环境。Akuity 的方法作为一种创新解决方案,尤其适用于那些应对 Kubernetes 集群管理中的复杂性和安全问题的组织。

到目前为止,我们已经讨论了 Kubernetes 集群已经存在的情况。接下来,我们将退后一步,使用 GitOps 方法自己创建 Kubernetes 集群。

集中式 Kubernetes 集群创建——利用 Cluster API 和 Argo CD 简化集群部署

在现代软件部署的世界里,集群 API 与 Argo CD 的协同作用展示了 GitOps 实践的强大和高效。这种方法不仅使 Argo CD 在集群内的操作变得更加容易,还利用 GitOps 方法学来部署集群本身。这些集群构成了 Argo CD 和它所管理的工作负载(包括通过 Argo CD 部署的各种应用程序)的基础设施。

本节深入探讨了如何利用 Argo CD,或者如何为团队提供自服务门户,以简化 Kubernetes 集群的部署。这一方法的有效性得到了 KubermaticCLASTIXGiant Swarm 等公司验证,它们利用这一方法为客户提供了多样化的托管 Kubernetes 解决方案。这些解决方案从独立产品到全面的托管服务不等,旨在简化 Kubernetes 部署。

这一策略使得组织能够集中化并自动化 Kubernetes 集群的创建和管理,确保使用 Argo CD 部署和管理应用程序时,基础设施的一致性和可靠性。在此背景下使用 GitOps,不仅提升了这些流程的效率,还提供了管理复杂多集群环境所需的可扩展性和灵活性。通过将集群 API 与 Argo CD 集成,组织可以创建一个强大的管道,用于部署和管理 Kubernetes 集群,进而用于部署各种工作负载,包括 Argo CD 工具集本身以及为开发人员提供的应用栈。

这种方法标志着 Kubernetes 集群配置和管理方式的重大转变,向着更加自动化、可扩展且开发人员友好的环境迈进。它展示了 GitOps 的潜力,不仅可以简化应用部署,还能优化底层基础设施管理,从而使组织能够专注于创新和开发。

集群 API 介绍

集群 API [7] 项目是 Kubernetes 生态系统中的一项关键计划,旨在简化 Kubernetes 集群的设置、更新和管理。该项目由 Kubernetes 特殊兴趣小组SIG)集群生命周期组发起,利用符合 Kubernetes 标准的 API 和设计原则,自动化管理平台运维人员所负责的集群生命周期的过程。它有助于定义和管理底层基础设施组件——如虚拟机、网络资源、负载均衡器以及 虚拟私有云VPC)——类似于应用开发人员处理应用部署的方式。这种方法确保了在不同基础设施环境中,集群的部署具有一致性和可靠性。

Cluster API 的一个关键特点是它能够为 AWS 提供 Kubernetes 本地的声明式基础设施。这吸收了之前集群管理工具(如 kopskubicorn)的经验和原则。它的功能包括能够管理 VPC、网关、安全组和实例,支持 弹性 Kubernetes 服务EKS),并能够在私有子网中部署 Kubernetes 控制平面,同时使用单独的堡垒服务器。SSH 不用于节点引导,且只安装最小组件来引导控制平面和工作节点。

Cluster API 采用 Apache-2.0 许可证,并为开发者和希望贡献进一步开发的爱好者提供了一个活跃的社区。开发者可以在与维护者的定期办公时间内参与讨论并获得支持。

Cluster API 在 Kubernetes 集群管理领域提供了多种应用场景,满足云原生生态系统中不同需求。以下是一些 Cluster API 特别有用的常见场景:

  • 多集群管理:Cluster API 简化了跨各种环境的多个 Kubernetes 集群的管理。它允许对多个集群进行一致的自动化配置、升级和操作任务,使其成为管理大量 Kubernetes 集群的组织的理想选择。

  • 自动化集群生命周期管理:它自动化了 Kubernetes 集群的整个生命周期,包括创建、扩展、升级和删除。在集群需要根据需求频繁扩展或缩减,或者需要更新到最新的 Kubernetes 版本时,这种自动化尤其有用。

  • 混合云和多云部署:对于在混合云或多云环境中运营的组织,Cluster API 使得 Kubernetes 集群能够在不同的云提供商之间进行一致的部署和管理。这种一致性对于那些希望避免厂商锁定并保持云策略灵活性的企业至关重要。

  • 基础设施即代码(IaC):Cluster API 与 IaC 模式兼容,允许团队通过声明性方式定义和管理集群。这种方法对于 DevOps 团队通过代码保持基础设施和配置的一致性非常有益。

  • 自助服务集群:在大型组织中,不同的团队可能需要自己的 Kubernetes 集群。Cluster API 提供了一个自助服务模型,使团队可以在遵守集中式政策和标准的同时,自主地配置和管理自己的集群。

  • CI/CD 管道:将 Cluster API 与 CI/CD 管道集成,可以简化测试和推出新应用或更新的过程。它允许在 CI/CD 流程中动态创建和销毁集群,从而实现更高效的测试和部署工作流。

  • 灾难恢复:Cluster API 在灾难恢复策略中可以发挥重要作用。自动创建备份集群并快速复制集群状态有助于减少停机时间,确保高可用性。

  • 边缘计算:对于需要在多个边缘位置部署 Kubernetes 集群的边缘计算场景,Cluster API 提供了一种统一的方式,从一个中心点管理这些集群。

  • 学习与实验:对于教育目的或实验,Cluster API 允许用户快速创建和销毁 Kubernetes 集群。这对于学习 Kubernetes、测试新功能或尝试不同配置非常有用。

每一个使用案例都展示了 Cluster API 在高效管理 Kubernetes 集群和大规模应用中的多样性和实用性,满足现代云原生应用和基础设施的不同需求。

Cluster API 如何被不同公司利用

在探索 Kubernetes 管理的多样化领域时,可以明显看到不同组织有各自独特的需求和策略。这些需求根据其具体的运营需求、基础设施偏好和长期技术目标而有所不同。因此,出现了各种不同的 Cluster API 实现,每种实现都经过量身定制,以满足这些不同的需求。有些组织选择完全托管的 Kubernetes 服务,而其他组织则倾向于自管理解决方案,以避免供应商锁定并保持对基础设施的更大控制。

以下仅是部分使用 Cluster API 的公司:

  • VMware Kubernetes 解决方案 (vSphere with Tanzu):VMware 将 Kubernetes 直接集成到 vSphere 平台中,充分利用了 Cluster API,特别是在 vSphere 提供者方面。这使得开发者可以直接从 vSphere 部署和管理 Kubernetes 集群。

  • Cluster API 提供者 Azure (CAPZ):这是微软为 Azure 实现的 Cluster API,并取代了 AKS Engine 用于自管理 Kubernetes 集群。CAPZ 利用 Azure 强大的可扩展基础设施,提供了一种无缝且高效的方式来操作 Kubernetes,简化集群管理任务,并增强 Azure 云服务固有的自动化功能。这一实现确保用户可以完全控制自己的 Kubernetes 环境,同时享受 Azure 提供的本地集成和服务。

  • Giant Swarm (Kubernetes 平台):Giant Swarm 使用 Cluster API 创建一个统一的应用入口,支持跨多个云服务提供商端点的自管理 Kubernetes 集群。它提供一个托管的 Kubernetes 解决方案,具备灵活性,可以部署到多个目标云服务提供商,强调低供应商锁定和基于订阅的定价模式。

  • CLASTIX(Kamaji):Kamaji 是 Cluster API 的一个完全开源实现,以其在管理集群上高效扩展控制平面而著称,从而降低了成本。该方法涉及创建工作节点,并使它们能够加入相应的租户。

  • Kubermatic Kubernetes Platform (KKP):该平台自 Cluster API 的第一个版本起就开始了,专注于创建和管理工作节点实例,并将它们加入集群。架构包括一个主集群和种子集群,并配备了一个特殊的机器控制器进行精确管理。

这些实现反映了不同的策略和优先事项,例如供应商锁定考虑、定制能力、资源节约和与现有基础设施的集成。选择特定的实现取决于组织的需求,包括治理、合规性和操作需求。

在这种背景下,考察不同公司如何使用 Cluster API 提供了有价值的洞察,帮助理解这个工具的实际应用和好处。例如,Cluster API 的 Azure 提供者(CAPZ)架起了微软 Azure 管理的 Kubernetes 服务 AKS 和 Kubernetes 本地管理之间的桥梁,与 Cluster API 的标准化声明式方法相契合。同时,像 CLASTIX 的 Kamaji 等开源解决方案强调灵活性和控制,适用于那些希望避免供应商锁定的组织。相比之下,VMware 的 vSphere with Tanzu 将 Kubernetes 集成到其平台中,简化了工作流,提供无缝的 Kubernetes 本地环境。同样,Giant SwarmKubermatic Kubernetes Platform 针对特定的操作需求,如与 Cluster API 版本的兼容性和资源节约进行优化。这些实现展示了 Cluster API 的适应性,突出了它在提供灵活的、与云无关的 Kubernetes 解决方案方面的重要性。

Cluster API 和任何技术一样,既有优点也有缺点。了解这些优缺点有助于判断它是否适用于特定的 Kubernetes 管理场景。

以下是 Cluster API 的一些优点:

  • 一致性和标准化:Cluster API 提供了一种标准化的方式来管理 Kubernetes 集群。这种一致性对于大规模和多云环境至关重要。

  • 自动化和可扩展性:它自动化了 Kubernetes 集群的创建、配置和管理过程,对那些需要高效扩展运营的组织来说非常有利。

  • 声明式 API:与 Kubernetes 的声明式配置原则相一致,Cluster API 允许用户定义其期望的集群状态,系统随后会努力实现这一状态。

  • 与云原生生态系统的集成:它与 Kubernetes 生态系统中的其他工具集成良好,提供了无缝的体验,将集群管理作为更广泛的云原生基础设施的一部分。

  • 多云与混合云支持:Cluster API 支持多个云服务提供商,使得在混合云或多云环境中管理集群变得更加容易。

  • 社区支持:作为 Kubernetes 项目的一部分,它受益于强大的社区支持和持续的开发工作。

以下是 Cluster API 的一些缺点:

  • 复杂性:Cluster API 可能较难理解和实现,特别是对于那些刚接触 Kubernetes 或云原生技术的用户。

  • 某些领域的定制化有限:尽管它提供了标准化的方案,但有时这会限制特定使用场景或环境的定制化选项。

  • 依赖于 Kubernetes 专业知识:有效使用 Cluster API 需要对 Kubernetes 概念和架构有很好的理解。

  • 资源开销:运行额外的控制器和资源来管理集群可能会导致 Kubernetes 环境中资源消耗增加。

  • 学习曲线:对于不熟悉 Kubernetes 声明式模型和基于 API 的管理的团队来说,可能会面临显著的学习曲线。

总结来说,Cluster API 是一个强大的工具,适用于那些希望自动化和标准化 Kubernetes 集群管理的组织,尤其是在大规模和多云环境下。然而,它的复杂性和对 Kubernetes 专业知识的需求可能会给某些团队带来挑战。和任何技术决策一样,重要的是在特定组织需求和能力的背景下评估这些因素。

在下一部分中,我们将进行实践操作,使用 Cluster API 和 GitOps 在 Azure 上部署 Kubernetes 集群。

深入探讨 Cluster API 和 GitOps – 实践操作

在这一部分中,我们将使用 Cluster API,通过在虚拟机上使用 Argo CD 的声明式方法,在 Azure 中预置 Kubernetes 集群。

首先,让我们看看我们的环境长什么样:

  • Azure:

    • Azure 租户 ID

    • Azure 订阅

    • Azure 应用注册,具有对订阅的贡献者访问权限

    • Azure Kubernetes 服务AKS

    • 所需的 Azure 基础设施,包括 虚拟机规模集VMSS)、虚拟网络等

  • 托管集群 – AKS:

    • Argo CD 运行在托管集群上
  • 工作负载集群 – VMSS:

    • 控制平面

    • 节点

  • 工具:

    • kubectl

    • clusterctl

    • az cli

    • helm

初始化管理集群

clusterctl 命令接收一个提供商列表作为输入。当首次执行时,clusterctl init 会自动将 cluster-api 核心提供商包括在列表中。如果未指定,它还会添加 kubeadm 启动引导和 kubeadm 控制平面提供商:

#export AZURE_SUBSCRIPTION_ID="<SubscriptionId>"
# Initialize Azure Service Principal credentials and Azure related config below
export AZURE_TENANT_ID="<Tenant>"
export AZURE_CLIENT_ID="<AppId>"
export AZURE_CLIENT_SECRET="<Password>"
export AZURE_SUBSCRIPTION_ID="<SubscriptionId>"
# Define the names and namespace for AzureClusterIdentity resources
export AZURE_CLUSTER_IDENTITY_SECRET_NAME="cluster-identity-secret"
export CLUSTER_IDENTITY_NAME="cluster-identity"
export AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE="default"
# Convert credentials to Base64 for secure storage
export AZURE_SUBSCRIPTION_ID_B64="$(echo -n "$AZURE_SUBSCRIPTION_ID" | base64 | tr -d '\n')"
export AZURE_TENANT_ID_B64="$(echo -n "$AZURE_TENANT_ID" | base64 | tr -d '\n')"
export AZURE_CLIENT_ID_B64="$(echo -n "$AZURE_CLIENT_ID" | base64 | tr -d '\n')"
export AZURE_CLIENT_SECRET_B64="$(echo -n "$AZURE_CLIENT_SECRET" | base64 | tr -d '\n')"
# Construct a Kubernetes secret for Azure Service Principal, to be used by AzureCluster
# This step secures the Service Principal's password within the Kubernetes environment
kubectl create secret generic "${AZURE_CLUSTER_IDENTITY_SECRET_NAME}" –from-literal=clientSecret="${AZURE_CLIENT_SECRET}" –namespace "${AZURE_CLUSTER_IDENTITY_SECRET_NAMESPACE}"
# Begin the setup of the management cluster with Cluster API for Azure
clusterctl init --infrastructure azure

你应该看到类似以下的输出:

Fetching providers
Skipping installing cert-manager as it is already installed.
Installing Provider="cluster-api" Version="v1.6.0" TargetNamespace="capi-system"
Installing Provider="bootstrap-kubeadm" Version="v1.6.0" TargetNamespace="capi-kubeadm-bootstrap-system"
Installing Provider="control-plane-kubeadm" Version="v1.6.0" TargetNamespace="capi-kubeadm-control-plane-system"
Installing Provider="infrastructure-azure" Version="v1.12.1" TargetNamespace="capz-system"
Your management cluster has been initialized successfully!
You can now create your first workload cluster by running the following:
  clusterctl generate cluster [name] --kubernetes-version [version] | kubectl apply -f -

输出还提到,由于cert-manager已经安装,所以跳过了安装该组件。此步骤很重要,因为cert-manager在 Kubernetes 环境中管理证书,确保集群组件之间的安全通信,通过自动化颁发和续订 TLS 证书来发挥关键作用。

此外,输出显示成功设置了一个管理集群,并为 Kubernetes 集群管理安装了必要的提供商,包括 Cluster API、Kubeadm 和 Azure 基础设施,这些都安装在特定的命名空间中。此步骤对于简化 Kubernetes 操作至关重要,因为工作负载集群可以通过一个简单的命令创建,从而促进集群的高效部署和管理。

创建你的第一个工作负载集群

一旦管理集群准备好,你就可以创建你的第一个工作负载集群。

重要提示

确保选择一个在你所选区域内可用的虚拟机规格。要查看可用的 SKUs,请使用命令az vm list-skus -l <your_location> -r virtualMachines -o table

请将以下变量替换为你的具体值:

# Specify the Virtual Machine sizes for the control plane and nodes.
export AZURE_CONTROL_PLANE_MACHINE_TYPE="Standard_D2s_v3"
export AZURE_NODE_MACHINE_TYPE="Standard_D2s_v3"
# Define the Azure region for resource deployment. Modify to match your preferred region
export AZURE_LOCATION="centralus"

以下命令为部署名为capi-quickstart的 Kubernetes 集群准备了一个 YAML 清单,并指定了 Kubernetes 版本1.29.0、一个控制平面节点和三个工作节点。通过将此配置保存为capi-quickstart.yaml,它可以实现自动化和一致的集群部署,将集群的期望状态和结构封装在一个文件中。

现在,你已经准备好生成集群 YAML 清单:

clusterctl generate cluster capi-quickstart \
    --kubernetes-version v1.29.0 \
    --control-plane-machine-count=1 \
    --worker-machine-count=3 \
    > capi-quickstart.yaml

此时,你应该在capi-quickstart.yaml文件中拥有包含以下自定义资源的内容:

  • KubeadmConfigTemplate:这是kubeadmconfigtemplates API 的架构。

  • AzureClusterIdentity:这是azureclustersidentities API 的架构。

  • AzureMachineTemplate:这些模板定义了在集群中创建 Azure 虚拟机的规格。它是azuremachinetemplates API 的架构。

  • MachineDeployment:这个自定义资源指定了所需的工作节点数量及其属性。它有助于通过自动管理工作节点的创建和扩展来扩展集群。

  • KubeadmControlPlane:这定义了 Kubernetes 集群的控制平面,包括控制平面节点的数量及其配置等设置。

  • AzureCluster:这个自定义资源表示集群的 Azure 特定详细信息,例如网络配置和虚拟网络的详细信息。

  • Cluster:这定义了高层次的集群配置,包括控制平面设置、工作节点引用和特定于提供商的详细信息。它是表示整个 Kubernetes 集群的顶级资源。

现在,你可以使用 kubectl 应用文件。但是,我们将利用 Argo CD 和 GitOps 最大化声明式方法的好处。所以,创建一个 应用程序,如下所示:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: capi-capz-quickstart
spec:
  destination:
    name: ''
    namespace: capi-capz-quickstart
    server: 'https://kubernetes.default.svc'
  source:
    path: >-
      ./chapter-6-gitops-architectural-designs-and-operational-control/chapter-6-centralized-kubernetes-cluster-creation/
    repoURL: git@github.com:PacktPublishing/Implementing-GitOps-with-Kubernetes.git
    targetRevision: HEAD
  sources: []
  project: default
  syncPolicy:
    automated:
      prune: false
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - Validate=false

在此时,你可以查看集群的配置状态:

kubectl get cluster
#Output like:
NAME              CLUSTERCLASS   PHASE          AGE   VERSION
capi-quickstart                  Provisioning   2m

现在,查看集群的配置状态:

clusterctl describe cluster capi-quickstart
#Output like:
NAME                                                                READY
Cluster/capi-quickstart                                             True
├─ClusterInfrastructure - AzureCluster/capi-quickstart               True
├─ControlPlane - KubeadmControlPlane/capi-quickstart-control-plane  True
│ └─Machine/capi-quickstart-control-plane-dct9z                     True
└─Workers
  └─MachineDeployment/capi-quickstart-md-0
    └─3 Machines...

从前面的输出可以看出,集群部分投入使用。输出中各个组件显示 READY True 表明集群的操作状态。具体来说,集群 (Cluster/capi-quickstart)、其 Azure 基础设施 (AzureCluster/capi-quickstart) 和 KubeadmControlPlane/capi-quickstart-control-plane 被标记为 True,这表明这些集群的关键部分已完全投入使用。控制平面节点正在运行,但工作节点尚未启动。

重要提示

控制平面在我们安装 容器网络 接口 (CNI) 之前无法就绪。

工作节点尚未投入使用,因为我们需要部署 CNI 组件。需要注意的是,Azure 目前不支持 Calico 网络。使用默认 Calico 配置的 CAPZ 集群将会遇到 DNS 功能的问题。为了解决这个问题,我们将部署一个使用 VXLAN 封装的 Calico 配置来处理 Pod 流量。你可以使用此处提供的模板来部署 Azure Calico CNI

若要获取 kubeconfig,以便与集群交互,请按照以下步骤操作:

  1. 以下命令会获取 capi-quickstart Kubernetes 集群的 kubeconfig 详情,并保存到文件中:

    clusterctl get kubeconfig capi-quickstart > capi-quickstart.kubeconfig
    
  2. 现在,我们需要使用以下命令在工作负载集群中安装 CNI 插件:

    helm repo add projectcalico https://docs.tigera.io/calico/charts --kubeconfig=./capi-quickstart.kubeconfig && \
    provisioned, and you gain access to the nodes:
    
    

    kubectl --kubeconfig=./capi-quickstart.kubeconfig get nodes

    输出类似于:

    名称                                  状态   角色           年龄

    capi-quickstart-control-plane-kcqmm   Ready    control-plane   8m26s

    capi-quickstart-md-0-2kj9c            Ready              6m58s

    capi-quickstart-md-0-7krx6            Ready              6m56s

    capi-quickstart-md-0-b8m7r            Ready              7m2s

    
    
  3. 现在你可以将集群添加到你的 Argo CD 操控台中,作为一个舰队船只并继续工作。

在 Azure 中,由于 CNI 的特殊性,执行此操作需要一些额外的工作,例如设置一个 webhook,在 status control-plane=true 达成时立即部署 CNI 插件。这稍微限制了自服务的能力,并且需要通过 CI/CD 和 webhooks 等方式进行扩展。然而,Cluster API 提供了其他多个提供程序,在这些情况下可能不需要这样做:

图 6.7 – 流程可视化

图 6.7 – 流程可视化

在这个例子中,我们演示了如何利用 Cluster API 创建一个声明式设置,该设置可以通过 Argo CD 部署,以提供基础设施或工作负载集群。图 6.7 说明了这一过程。随后,Argo CD 可以通过 argocd cluster add 层叠到其上。这使得你能够使用 Kubernetes 服务目录 (KSC) 等工具,根据标签部署服务。

总结

本章中,我们全面探索了 Kubernetes 环境中的 GitOps,揭示了现代云原生部署中至关重要的见解和策略。我们首先探讨了根据可扩展性、韧性和高效性量身定制架构设计的关键性,这些都是当今动态云环境中的基础原则。这一架构框架的探索强调了基础设施即代码(IaC)的不可或缺性,它不仅为协作和版本控制提供了益处,还通过建立不可更改的基础设施,防止了在生产环境中的手动修改。强调模块化设计,我们突出了高效的微服务管理如何转变操作工作流。

然后,我们的探索深入了架构选择及其对 GitOps 效能的重大影响。我们学习了采用声明性模型的重要性,这种方法无缝集成了版本控制、变更管理和自动同步。本节阐明了在选择仓库结构时所需的考虑因素,权衡了单体仓库与多仓库策略的优缺点。它还讨论了部署策略、环境隔离、可扩展性和安全性在实现强大 GitOps 实施过程中的重要作用。

随后,我们转向理解 GitOps 在推动云原生架构系统化改进中的作用。我们详细分析了横向扩展、微服务、无状态应用程序、高可用性、故障隔离和灾难恢复等关键方面。我们探讨了 GitOps 如何通过自动扩展、负载均衡和设置资源限制等策略管理部署,确保系统的韧性和高效性。

本章的第二部分将我们的重点转向了适用于 Kubernetes 环境中 GitOps 的各种架构方法。随着组织的发展,规模化、安全性和高效部署策略的需求变得至关重要。我们深入探讨了 Argo CD,分析了它在性能扩展、安全性、可用性和故障转移过程中的能力。我们对比了使用集中式 Argo CD 实例与为每个集群设置专用实例之间的细微差别。同时,我们也突出了 Argo CD 与 Flux CD 之间的差异,提供了对它们各自优缺点的平衡视角。

此外,我们还探索了 Argo CD 的创新驾驶舱和舰队方法,这一策略不仅仅局限于 Kubernetes 集群管理,还包括使用 Cluster API 声明式地配置集群。

随着我们为下一个章节铺路,我们将深入探讨成功实施和操作 GitOps 所需的文化转变。我们将探讨将基础设施视为应用程序的转型,以及不可变基础设施的原则,然后再深入探讨各种 DevOps 研究与评估 (DORA) 指标。我们还将讨论 GitOps 持续改进的关键需求,以及克服可能妨碍其采用的文化障碍。这为我们对成功 GitOps 的深刻理解奠定了基础——成功的 GitOps 不仅仅依赖于正确的工具和技术,还依赖于 IT 领域内的文化适应和演变。

参考文献

第六章:IT 部门文化转型,迎接 GitOps 的到来

在信息技术快速发展的环境中,采用GitOps标志着一个重大的范式转变,它不仅带来技术变革,同时也在 IT 部门内部引发了一场深刻的文化变革。本章将深入探讨这一变化的多层面,重点阐述 GitOps 如何从根本上重新定义运维流程和方法论。

从本质上讲,GitOps 代表了软件开发与 IT 运维的融合,基于版本控制和协作的原则,这些原则是 Git 所固有的。它是一种将基础设施和应用部署视为代码的方法,能够实现高度的自动化和精确的 IT 运维。该方法确保了应用开发过程中所应用的严格标准同样被扩展到基础设施的管理,尤其是在 Kubernetes 环境中。

GitOps 最具变革性的一面是建立不可变基础设施。通过对比和同步循环,GitOps 自动化地将基础设施的实际状态与在 Git 仓库中定义的目标状态对齐。这种对齐减少了人工干预的需求,降低了人为错误的潜力,并提高了 IT 系统的整体可靠性和安全性。

本章的重要部分是理解 GitOps 对 IT 性能的影响。我们将通过DevOps 研究与评估DORA)指标的视角来探讨这一点,DORA 指标是一组广泛认可的指标,用于衡量 DevOps 实践的有效性。通过将这些指标应用于 GitOps,组织可以定量评估在部署频率、变更交付时间、变更失败率和平均恢复时间等领域的改进。

然而,采用 GitOps 的过程不仅仅是实现像 Argo CD 这样的工具。它需要不断参与到 GitOps 趋势和实践的演变中。像任何新兴技术一样,GitOps 也面临着一系列挑战。这些挑战包括需要提升团队技能、调整现有工作流程,以及持续优化流程,以符合 GitOps 的最佳实践。

本章的最后部分讨论了实施 GitOps 对组织的更广泛影响。采纳 GitOps 不仅仅是一个技术升级,它是推动组织内部文化转型的催化剂。我们将分享来自不同公司多个项目的见解和经验,展示 GitOps 如何推动一个更加协作、透明和高效的 IT 文化。这些真实的案例提供了关于将 GitOps 融入组织结构中的挑战、策略和成功的宝贵经验。

这篇关于 GitOps 的全面探讨,从其技术基础到文化影响,旨在让你清晰地理解这一方法论的变革力量。这是一场超越技术采纳的旅程,描绘了通向更加敏捷、响应迅速和创新的 IT 文化之路。

我们将在本章讨论以下主要主题:

  • 将基础设施视为应用程序

  • 不可变基础设施的原则

  • DORA 指标简介

  • 理解在 GitOps 中持续改进的必要性

  • 克服文化障碍以采用 GitOps

将基础设施视为应用程序

在不断发展的 DevOps 景观中,将基础设施视为应用程序的概念 —— 通常称为 infra-as-apps —— 在 GitOps 的背景下尤为流行。为了理解这一点,我们需要快速了解 基础设施即代码 (IaC)。IaC 将在 第十章 中详细讨论。这是一个关键组成部分,例如 Terraform 采用其声明式方法,使基础设施可以像应用程序一样处理。

理解 IaC

IaC 是一种现代方法,用于通过代码而非传统手动流程管理和配置 IT 基础设施。这种方法允许你自动化设置、管理和配置服务器、存储、网络和应用程序等计算资源。将基础设施视为软件,IaC 应用软件开发实践,如版本控制和测试,来管理基础设施。

IaC 的主要目标是增强基础设施部署和管理的效率、可靠性和一致性。通过使用代码定义基础设施,减少了人为错误,加快了部署速度。IaC 实现了更为一致和可重复的资源配置和部署过程,简化了基础设施随时间的扩展和管理。

重要提示

命令式:直接使用 kubectl 命令创建、更新或删除 Kubernetes 资源,适合开发和实验中的快速调整。

声明式:在 YAML 文件中定义所需状态并应用它们,让 Kubernetes 确保实际状态与声明状态一致。这在生产环境中非常理想,带来诸如版本控制和可重复性等好处。

IaC 通常采用声明式命令式方法定义基础设施的期望状态。这种规范使得 IaC 工具可以自动进行必要的更改,从而实现更加敏捷、高效和可靠的 IT 环境,更好地支持现代业务需求。

IaC 的重要性

云计算的兴起是推动 IaC 日益普及的重要因素。组织面临着在多个环境中(如公共云、私有云和混合云)管理和部署资源的挑战。IaC 自动化了这些资源的部署和管理,简化了复杂环境的管理。

此外,企业快速高效地交付应用程序和服务的需求,使得 IaC 变得越来越重要。在当今快速变化的数字世界中,组织必须迅速适应市场和客户的需求。IaC 简化了 IT 操作,实现了更快速、更灵活的扩展。

此外,IaC 支持DevOps 原则,弥合了软件开发和 IT 运维之间的差距。将基础设施视为代码使得组织能够将软件开发方法应用于基础设施,增强了开发和运维团队之间的协作与沟通。

IaC 如何工作

IaC 的基本概念是将基础设施视为软件。这包括采用严格的软件开发实践,如版本控制、基础设施代码测试以及持续集成和部署。这种方法确保了基础设施的一致性,减少了停机时间和维护时间。

IaC 过程从编写脚本开始,这些脚本使用声明性语言描述基础设施的期望状态。这些脚本像任何软件一样存储在版本控制系统中,允许进行版本管理、审计和回滚。然后,IaC 工具将这些脚本应用于实际的基础设施,确保其与期望状态一致。这个可重复性确保了一致性,减少了人为错误。

在 Argo CD 的 GitOps 框架中理解基础设施即应用

在 Argo CD 的领域中,应用程序的概念超越了传统的定义 [1]。在这里,应用程序不仅仅包括软件,还涵盖了其期望的状态配置、目标部署环境以及管理这些资源如何同步和管理的策略。这种方法标志着与传统应用程序理解方式的显著转变。

通常,工程团队将应用程序视为在独立基础设施上运行的软件层。标准流程首先涉及手动或使用像TerraformCloud Formation模板这样的工具来设置基础设施。一旦这项基础工作完成,另一个团队会将他们的应用程序部署到已准备好的基础设施上。然而,Argo CD 提供了一种更为集成的视角。在这个以 GitOps 驱动的环境中,应用程序的部署会被持续监控。Argo CD 会不断地将应用程序的实时状态与其预定义的期望状态进行比较。这种持续的比较对于保持一致性和可靠性至关重要。实际状态与期望状态之间的偏差可能由两个主要原因造成。首先,实际状态可能会发生漂移,这指的是环境中未预见的变化或修改。其次,期望状态本身可能会更新,从而需要对部署进行更改。

每当这种偏差发生时,Argo CD 就会介入来调和这些差异。调和这一差异的行为是 GitOps 部署方式的核心,Argo CD 正是这种方式的践行者。这一方法与OpenGitOps 标准所设立的原则相符,确保了系统化和标准化的部署及基础设施管理方法。

这一范式的转变,把基础设施视为类似应用程序的存在,带来了更加无缝和集成的工作流。它强调了以与应用程序开发同等的细致和关怀来对待基础设施管理,突出了一种系统性的方法来进行系统部署和管理。

拥抱基础设施即应用——连接 GitOps 与基础设施管理

传统上,通过声明性配置创建和管理基础设施一直是一个挑战,尽管像TerraformCloud Formation模板、PulumiCloud Development Kit for TerraformCDKTF)等工具的流行使得这一过程变得更加便捷。这些工具通常通过CI/CD 管道一次性或通过触发更改来应用期望状态。然而,这种方法在 GitOps 的一个关键方面存在不足:持续的状态监控。

问题在于,虽然 CI/CD 管道在部署新计划或更新时效率很高,但它们并不会持续监控状态漂移。例如,如果执行了一个 Terraform 计划,而实际状态后来被外部改变,CI/CD 系统对此变化毫无察觉。这就是像 Argo CD 这样的 GitOps 操作员不可或缺的地方。Argo CD 的作用是不断监控基础设施的实际状态,并确保它与期望状态一致,从而防止漂移。

采用这种不允许漂移的方法已被证明对团队有益,不仅能够更高效地管理应用程序,还能提升他们快速恢复故障的能力。在这种模型中,回滚到之前的状态就像执行git revert一样简单。

团队在管理应用程序时所获得的好处,现在已经可以扩展到基础设施管理中,这得益于这一范式的转变。然而,我们的重点将放在 Crossplane 上。作为一个开源的 CNCF 项目,Crossplane 使用户能够通过 Kubernetes API 配置和管理各种云资源。当与像 Argo CD 这样的 GitOps 操作符结合时,Crossplane 允许部署表示各种云资源的应用程序,如 Azure Key Vault数据库Kubernetes 集群和负载均衡器,跨 AzureAWS 及其他云平台进行管理。这一集成标志着基础设施管理的新时代,结合了 GitOps 的强大功能和现代云资源的多样性。

如何使用 IaC 部署基础设施

现在我们已经掌握了所有必要的背景信息,并希望对 GitOps 方法和使用 Terraform 将基础设施视为应用程序之间的差异有了充分的理解,让我们通过检查三个用例来实际阐明这一点。

在开始之前,我们简要介绍一下用于此设置的工具及其选择原因。从 Azure 开始:

  • Azure Kubernetes Service (AKS):该服务提供一个托管的 Kubernetes 环境,简化了容器化应用程序的部署、管理和扩展,同时具备 Azure 基础设施的强大可靠性。

  • 容器注册表:该服务提供一个安全、可扩展的私有 Docker 容器镜像注册表,提升了容器化应用程序的管理和部署能力。

  • Azure 上的 PostgreSQL 服务器:该服务提供可靠且可扩展的云数据库服务,确保高效管理和存储应用数据。

  • Azure Key Vault:这是一个用于安全存储和访问密钥、证书及机密信息的工具。它对于管理敏感信息和增强整体安全性至关重要。

对于 Kubernetes,我们有以下内容:

  • Argo CD:一个声明式的 GitOps 持续交付工具,用于 Kubernetes,支持自动化部署和管理应用程序。

  • External-DNS:该工具自动化管理 DNS 记录,简化了将 Kubernetes 服务与外部 DNS 名称连接的过程。

  • Cert-Manager:该工具管理 Kubernetes 的 SSL/TLS 证书,自动化证书的签发和更新过程。

  • External-Secrets Operator:该工具与 Azure Key Vault 等系统集成,安全地将机密信息注入 Kubernetes,提升对敏感数据的安全访问。

对于 IaC 部分的部署,我们有以下内容:

  • Terraform 模块:这些是 Terraform 中的组件,Terraform 是一个 IaC 工具,旨在实现模块化和可重用的基础设施定义。它们通过允许用户以代码方式定义所需的基础设施状态,从而促进声明式方法,Terraform 会执行这些定义,创建并管理实际的基础设施,确保它与指定的状态匹配。

  • Crossplane:这是一个与 Kubernetes 生态系统集成的 IaC 工具,允许通过 Kubernetes 自定义资源定义CRDs)管理外部资源,如云服务。它采用声明式模型,用户以 Kubernetes 本地方式定义基础设施需求,实现对 Kubernetes 内部资源和外部云基础设施的一致性和统一管理。

这些工具的结合形成了一个完整的生态系统。Azure 的服务提供了一个安全且可扩展的云平台,而 Kubernetes 工具如 Argo CD 和 Cert-Manager 确保了高效且安全的应用部署和管理。Azure Key Vault 与 Kubernetes 中的 External-Secrets Operator 的集成,展示了云基础设施与 Kubernetes 如何无缝协作,以提高安全性和运营效率。现在,让我们来看一下用例。

用例 1 – 通过 Terraform 部署所有内容

在第一个用例中,如图 7.1所示,所有内容都是通过 Terraform 部署的。这意味着最初,所需的云基础设施是通过 Terraform 部署的:

图 7.1 – 用例 1 – 通过 Terraform 部署所有内容

图 7.1 – 用例 1 – 通过 Terraform 部署所有内容

为了简化这个示例,我们移除了任何不必要的复杂性,比如 CI/CD 流水线。在生产环境中,你应该避免手动执行此操作,除非是用于初步启动或解决鸡与蛋的问题。一旦基础设施部署完成,后续的 Terraform 模块将用于在 Kubernetes 环境中部署更多的基础设施。

重要说明

值得注意的是,已有原生的方法可将 Terraform 与 GitOps 集成,例如 Terraform 控制器。该工具支持多种针对 Terraform 资源的 GitOps 模型,包括全自动、部分基础设施管理的混合自动化、状态强制和漂移检测,所有这些都在一个原生框架中进行。然而,本章更多聚焦于工具的原生使用。

这种方法是合理的,几年前甚至是标准做法。在这里,基础设施通过声明式模块方法作为一个应用进行处理和部署。

然而,这种方法也有一些缺点:

  • 缺乏持续监控:这种方法无法持续监控基础设施状态的漂移,而这是 GitOps 中的关键组成部分。

  • 可扩展性的复杂性:随着基础设施的增长,仅通过 Terraform 进行管理可能会变得越来越复杂,尤其是在状态管理、多阶段和模块依赖关系方面。

  • 有限的动态响应:这种方法缺乏 GitOps 工作流所提供的动态响应能力,在 GitOps 工作流中,基础设施可以更无缝地进行实时调整。

  • 管理模块的开销:在每个部署环节中都依赖 Terraform 模块可能会导致模块管理和版本控制的开销。

  • 配置漂移的潜在风险:如果没有持续的协调,随着时间的推移,配置漂移的风险会更高,因为手动更新可能无法持续跟踪或记录。

用例 2 – 将 Terraform 和 Argo CD 集成用于部署流程

下一种方法,如图 7.2所示,结合了第一种方法,然后将任务委托给 Argo CD。这种方法在实践中非常常见,并且经常出现在不同客户的各种项目中。在这种方法中,首先使用 Terraform 模块进行 Azure 基础设施的部署。随后,Argo CD 被作为初始实例通过 Terraform 模块进行部署。然后,Argo CD 接管 GitOps 部分并部署与 Kubernetes 上下文相关的基础设施。在这种方法中,声明性方法最为合适。Terraform 模块以声明方式呈现,基础设施,如 Cert-Manager,也作为应用程序应用程序集以声明性方式呈现,如前几章所述:

图 7.2 – 用例 2 – 将 Terraform 和 Argo CD 集成用于部署流程

图 7.2 – 用例 2 – 将 Terraform 和 Argo CD 集成用于部署流程

尽管这种方法有其优势,但也有需要考虑的潜在缺点:

  • 集成的复杂性:将 Terraform 与 Argo CD 结合使用可能会增加复杂性,要求对这两种工具都有扎实的理解。

  • 初期学习曲线:对于那些对 Terraform 或 Argo CD 不熟悉的团队,由于这两种不同范式的结合,学习曲线可能较为陡峭。

  • 维护的开销:这种组合方法可能需要更多的维护工作,因为它涉及管理两个系统而不是一个。

  • 配置错误的风险:随着两种强大工具的并行使用,配置错误的风险增加,这可能导致部署问题或安全漏洞。

  • 更新协调:在 Terraform 管理的基础设施和 Argo CD 管理的应用程序之间协调更新,需要仔细规划以避免冲突并确保顺利运行。

用例 3 – 在 Kubernetes 上的统一管理 – 使用 CR 和 Crossplane 进行全面编排

接下来的方法,如 图 7.3 所示,充分利用 Kubernetes API,同时聚焦于 CRD自定义资源CR),允许用户定义自己的资源类型,并实例化这些类型以进行自定义配置和功能扩展。该方法使用 Crossplane 来配置云基础设施,并部署 Kubernetes 基础设施所需的第三方工具,如 Cert-Manager。通过 CR 的声明性特性,它将基础设施视为应用程序,提供一个完全可追踪的解决方案,利用 Kubernetes 生态系统作为编排平台以保持资源同步。这个概念可以扩展,使几乎所有的云基础设施都通过 Argo CD 与 Crossplane 结合进行配置。所有内容都在集群内进行维护,只需了解 Kubernetes 清单——在这种情况下,是 CRD 和 CR:

图 7.3 – 用例 3 – 在 Kubernetes 上的统一管理 – 使用 CR 和 Crossplane 的全规模编排

图 7.3 – 用例 3 – 在 Kubernetes 上的统一管理 – 使用 CR 和 Crossplane 的全规模编排

为了更好地理解如何使用 Crossplane、CR 和 Argo CD 在 Azure 上创建资源,下面是一个使用 CR VirtualNetwork 类型的小示例。此操作的要求是安装 Kubernetes,并且安装和配置了 Azure 提供者 [3]。

一旦准备工作完成,并且网络提供者已安装,我们可以创建一个 VirtualNetwork 类型的已管理资源,举例来说,这可以用于 AKS。

首先,创建一个 CR,像这样:

apiVersion: network.azure.upbound.io/v1beta1
kind: VirtualNetwork
metadata:
  name: crossplane-quickstart-network
spec:
  forProvider:
    addressSpace:
      - 10.0.0.0/16
    location: "West Europe"
    resourceGroupName: docs

然后,将 CR 推送到由 Argo CD 管理的 Git 仓库中。现在,CD 部分应通过 GitOps 与 Argo CD 完成,您应该能够在门户中看到已创建的 Azure 网络资源。

然而,这种设置假设存在一个已管理的集群,其中部署和配置了必要的工具。它有以下潜在的弱点:

  • Kubernetes 生态系统的复杂性:它需要对 Kubernetes 有深入的理解,包括 CRD 和 CR,这对于不太熟悉这些概念的团队可能具有挑战性

  • 依赖于已管理的集群:这种方法依赖于已管理的 Kubernetes 集群,因此在没有这种设置的环境中,其适用性受到限制

  • 资源密集型:这种方法可能资源密集,要求集群内有更多的计算能力和内存

  • 配置和维护:管理和维护 CRD 和 CR 的配置可能会繁琐且容易出错,特别是在大规模部署和版本升级时

正如你所看到的,没有一种“通用”方法能够满足所有需求。团队的正确方法在很大程度上取决于公司的具体需求、团队规模、团队在各个领域的技能等因素。然而,我们仍然应该花些时间重新思考为什么将 infra-as-apps 视为颠覆性创新。

为什么 infra-as-apps 是一个颠覆性创新?

总结一下,以下是 infra-as-apps 作为一个颠覆性创新的优势列表:

  • 安全性:通过集中密钥管理并将直接的云访问转变为通过 Git 进行的变更管理,infra-as-apps 增强了安全性。这种方法减少了直接云访问带来的风险,并通过版本控制追踪变更,改进了审计日志。

  • 高效的资源管理:该模型简化了新资源的配置和现有资源的升级。它允许更灵活和响应更快的基础设施管理,减少了资源分配和更新所需的时间和精力。

  • 改进的 CI/CD 拉取请求:infra-as-apps 专注于提升 CI/CD 管道中的拉取请求,提供自动回滚和更彻底的测试。这使得部署过程更为稳健和可靠,确保生产环境中的更高质量和稳定性。

  • 更简便的多云资源配置:借助 Crossplane 等工具,infra-as-apps 使得在多个云环境中配置资源变得更加简便。此功能简化了多云战略的实施,使得跨不同云平台管理和部署资源变得更加高效。

  • 简化的基础设施管理:这种方法显著简化了管理基础设施的过程,使其更加高效,减少人为错误的发生。

  • 开发者的入门和资源配置简易性:它简化了开发者入门和管理资源的过程,减少了设置和部署应用时所需的时间和复杂性。

  • 更快的平均恢复时间(MTTR):它提高了从故障中恢复的速度。

  • 稳固的可审计性:它提供了全面的审计日志和清晰的责任追踪,使得跟踪变更和保持合规性变得更加容易。

许多公司,如 CERN、Splash、Grafana Labs、IBM 和 SAP,已经采用了 Crossplane 用于各种用例。CERN 在 GitOpsCon US 2021 上由 Ricardo Rocha 展示的《A Multi-Cluster, Multi-Cloud Infrastructure with GitOps at CERN》[2]是一个实践中应用 infra-as-apps 的典范。CERN 以运营大型强子对撞机而闻名,利用 infra-as-apps 管理广泛的基础设施,包括超过 600 个集群、3000 个节点、13000 个核心、30 TB 的内存和 160 TB 的原始存储,以处理来自实验的大量数据。他们使用 Kubernetes 管理大规模的集群和计算资源。CERN 的实施涉及使用带有 Crossplane 配置的 Helm 图表进行集群和资源管理,支持快速扩展和多云资源分配。

作为第二个例子,IBM 使用 Crossplane 和 GitOps 管理基础设施生命周期和应用程序部署的做法也值得注意。在GitOpsify Everything: When Crossplane Meets Argo CD [4]中,IBM 的 CI/CD 工程师 Ken Murray 和软件工程师 Ying Mo 探讨了 Crossplane 与 Argo CD 在不同 IT 环境中的集成。IBM 的方法是将 Crossplane 作为基础设施提供和集群管理的抽象层,使他们能够高效地维护 Kubernetes 集群池。该方法利用 Helm 模板来定义资源配置,并通过允许用户与简单的资源类型进行交互,从而简化了集群管理,而 Crossplane 则处理与云服务提供商的通信。

Infra-as-apps 与传统的infra-as-code不同,它在各个层面上完全拥抱 GitOps。这种方法将基础设施的手动更改视为偏离 Git 定义的期望状态,从而增强了基础设施管理的安全性和可预测性。它代表了基础设施管理方式的重大转变,使其与应用程序开发和部署的动态和自动化特性更加契合。

GitOps 发生了很大的变化,创建了不可变基础设施,同时也影响了公司的文化。在接下来的部分,我们将探讨不可变基础设施。

理解不可变基础设施的原理

不可变基础设施的原理结合 GitOps 方法,为现代软件开发环境中的基础设施和部署管理提供了一种变革性的方式。不可变基础设施指的是一种模型,其中服务器一旦部署,就永远不再直接修改。相反,更改需要通过用新实例替换服务器来实现。这种模型大大减少了由配置漂移引发的问题,并通过将服务器视为可快速替换的可丢弃单元,提高了系统的可靠性,从而在部署过程中提供了更大的可扩展性和效率。

将 GitOps 融入这一模型能够放大这些好处。GitOps 利用 Git 作为管理软件应用程序和基础设施的中央真实来源。它将云原生模式应用于部署,这种模式通常与 Kubernetes 相关,但也适用于各种平台。GitOps 的核心原则包括将基础设施视为代码,确保版本化和不可变的部署,自动拉取所需状态,并持续协调期望状态与实际状态之间的差异。

不可变基础设施的本质

不可变基础设施是一种概念,一旦服务器部署完成,便不再修改;如果需要更改,则会创建新的实例并替换旧的实例。这种方法与传统的可变基础设施截然不同,后者的服务器会不断更新和修改。不可变模型带来了几个关键优势。

不可变基础设施的优势如下:

  • 一致性和可靠性:不可变服务器保持在已知的稳定状态,显著减少了由于环境漂移或不一致性引发的意外问题的风险。

  • 增强的安全性:由于服务器在部署后不再修改,攻击面保持不变,简化了安全管理和异常检测。

  • 简化的管理和调试:故障排除变得更加简单,因为基础设施保持在可预测的状态。

  • 可扩展性与性能:可以高效地启动和关闭新的实例以满足需求,保持一致的性能水平。

然而,这种方法并非没有挑战:

  • 增加的存储和资源需求:不可变基础设施可能需要更多的存储,因为每次更改都涉及创建一个新实例。

  • 潜在的部署开销:每次更改都需要设置一个全新的实例,这可能比更新现有实例更耗费资源。

  • 配置管理的复杂性:管理大量的服务器实例可能变得非常复杂,尤其是在大规模环境中。

将不可变基础设施与 GitOps 集成

将 GitOps 融入不可变基础设施利用了 Git 的核心原则——版本控制、协作和自动化——来进行运营管理,使得基础设施被视为代码,所有配置和状态都被精心维护在 Git 仓库中,从而增强了一致性和可追溯性。

GitOps 的优势如下:

  • 唯一真实来源:为应用程序和基础设施代码提供单一的代码库,确保一致性和可追溯性。

  • 自动化、可靠的部署:通过 GitOps 操作员进行持续部署,自动化并简化了部署过程。

  • 增强的协作与透明度:拉取请求工作流增强了协作,提供清晰的审计跟踪,确保变更的可追责性。

  • 增强的安全性和合规性:Git 固有的特性有助于强大的访问控制、加密和合规性遵循。

尽管有这些优势,GitOps 也有其缺点:

  • 扩展性复杂性:管理多个仓库并处理大规模部署的复杂性可能具有挑战性。

  • Git 在操作任务中的局限性:Git 主要设计用于代码版本控制,可能并不适合用于操作性更新,可能导致潜在冲突。

  • 学习曲线和采纳阻力:团队可能面临陡峭的学习曲线,或者对采用新工作流、工具和思维方式的抵触情绪。我将在后面讨论这一部分。

协同效应与挑战

当不可变基础设施与 GitOps 结合时,它们创造了强大的协同效应:

  • 将基础设施视为动态的、版本控制的实体:基础设施被视为类似于应用程序代码的对象,所有变更都通过 GitOps 方法进行追踪、审查和部署。

  • 快速恢复和回滚能力:这种组合能够快速从故障中恢复,并轻松回滚到之前的稳定状态。

  • 简化的操作:这种方法减少了手动干预的需求,最小化了人为错误并简化了操作流程。

然而,这种集成也带来了独特的挑战:

  • 复杂的工作流管理:平衡基础设施的不可变性与 GitOps 工作流的动态特性需要仔细的规划和执行。

  • 依赖于工具和流程:这一方法的有效性在很大程度上依赖于正确的工具和明确定义的流程。

  • 平衡安全性和敏捷性:在快速变化的环境中确保安全性需要在严格控制与操作灵活性之间找到微妙的平衡。

使用不可变基础设施实现有效的生产环境

最佳的生产环境不可变基础设施可以通过整合若干关键实践来构建,这些实践通过经验不断优化。以下是有效的生产环境可能呈现的样子及其原因:

  • Kubernetes 生产集群的只读访问:在生产环境中,Kubernetes 集群应从开发人员的角度看待为一个受管服务或黑箱。这意味着对集群的访问应主要为只读,开发人员不应被允许手动更改集群,从而确保环境的可控性和稳定性。

  • 仅通过 GitOps 创建和删除资源:这一原则规定,所有进入集群的资源应仅通过 GitOps 进行管理。这包括整个创建过程,涵盖命名空间、部署、服务、入口、服务帐户等元素。此方法确保所有变更可追溯可逆,并与 Git 仓库中的真相源保持一致

  • 不要创建命名空间覆盖应用程序:在 Argo CD 及其应用程序概念的背景下,一个应用程序不应该能够创建命名空间。这是因为 Argo CD 不支持删除由应用程序创建的命名空间[5]。此限制是为了防止命名空间的 uncontrolled 创建,避免在共享环境中引发冲突和管理问题。接下来的示例将通过具体实例来阐明在使用 Argo CD 的共享环境中管理命名空间的实际影响和潜在风险。

    假设五个团队共享一个 Kubernetes 命名空间。每个团队创建自己的 Argo CD 应用程序来部署其服务组件,贡献于整体微服务架构。假设 A 团队决定停用其服务。它们会删除自己的应用程序和相关的已部署服务,并尝试通过应用程序删除共享的命名空间。然而,Argo CD 应用程序本身并不了解或连接到同一命名空间内的其他应用程序或未链接的资源。因此,如果允许这种删除操作,它将无意中导致命名空间及其中其他团队部署的所有服务被删除。幸运的是,这种情况在实践中是不可行的,因为 Argo 项目团队并未实现此类功能,以避免这些破坏性和意外的后果。

  • 使用合适的工具,如 PR-Generator:将 PR-Generator 等工具集成到与 Argo CD 的 GitOps 工作流中,可以极大地提升测试和部署过程。PR-Generator 可以在 PR 启动时立即创建带有特定前缀的资源,确保资源正确创建并被清理,同时遵守不要创建命名空间覆盖 应用程序原则。

遵循这些实践可以实现以下几个好处:

  • 每次更改都通过 Git 进行,确保了集中化和版本控制的变更管理过程。

  • 所有更改都记录在 Git 历史中,提供了透明且可追溯的所有修改记录。

  • 资源得到清晰的管理,集群中不会留下任何残余的“孤立”资源。

  • 使用 PR 和 Git 进行干净高效的工作流管理,借助如 PR-Generator 等工具。

  • 它在组织内建立了标准和承诺,使这些实践可以在不同项目之间复制。

在生产环境中实施这些原则,创建了一个强大、安全、可管理的基础设施,充分利用了不可变基础设施和 GitOps 方法的优点。

一个同时使用Kustomize和 Argo CD 的应用程序的潜在文件夹结构可能如下所示:

.
├── base
│   ├── kustomization.yaml
│   ├── namespace.yaml
│   ├── role.yaml
│   ├── rolebinding.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   ├── statefulset.yaml
│   ├── templates
│   │   └── statefulset_template.yaml
│   └── values.yaml
└── overlays
    ├── production
    │   ├── kustomization.yaml
    │   ├── namespace.yaml
    │   └── statefulset.yaml
    └── staging
        ├── kustomization.yaml
        ├── namespace.yaml
        └── statefulset.yaml

这种结构确保所有资源都可以通过 Argo CD 和 GitOps 方法进行部署和清理,从而消除了在应用同步选项中设置 自动创建命名空间 选项以创建命名空间的需求。

不可变基础设施的应用配置

接下来,我们将检查一个可能有助于不可变基础设施设置的应用配置:

图 7.4 – 应用同步策略配置示例

图 7.4 – 应用同步策略配置示例

如果您希望获得最具不可变性的基础设施设置,请设置以下标志:

  • 修剪资源:启用此选项,允许 Argo CD 自动删除集群中存在但在 Git 仓库中不再定义的资源。这样可以确保集群中的所有资源都通过 GitOps 方法进行管理。

  • 自我修复:启用此选项。它确保直接在集群中进行的任何偏离 Git 仓库的更改都会被 Argo CD 自动修正,从而保持 Git 中定义的期望状态。

  • 设置删除最终器:启用此选项,以确保资源仅在从 Git 仓库中移除后才会从集群中删除。这可以防止过早删除,并确保只有在资源从 Git 中移除后才进行清理。

  • 忽略差异:启用此选项以指示 Argo CD 忽略其无法识别的特定差异。您可以在 Argo CD 配置中定义要忽略的具体差异。

  • 自动创建命名空间:确保禁用此选项,以防止 Argo CD 自动创建命名空间。命名空间应在您的 Git 仓库中作为资源显式定义。

通过设置这些策略,您可以确保资源的创建、删除和同步都通过 Git 仓库中的更改进行管理,同时遵循 GitOps 原则。这种方法确保了 Git 中声明的状态与集群中的实际状态之间的紧密耦合。

不可变基础设施与 GitOps 的结合代表了 IT 运维和开发的现代方法。它将稳定性、安全性和动态自动化工作流的最佳特性结合在一起。虽然在可靠性、安全性和效率方面提供了显著的优势,但也在复杂性、资源需求以及对特定工具和实践的依赖方面带来了挑战。与任何 IT 方法论一样,成功实施这些概念依赖于对其优缺点的清晰理解、精心的规划以及应对不断变化的 IT 环境的适应性。

到目前为止,我们已经探讨了与 GitOps 相关的各种转型方面。但是,如果无法从中获得或衡量任何附加值,那这一切又有什么意义呢?因此,在下一节中,我们将探讨使产品质量可衡量的具体指标。

引入 DORA 指标

在本节中,我们将向您介绍 DORA 指标,并深入探讨 DORA 团队开发的一组关键绩效指标。这些指标对于评估和提升 IT 团队的软件交付和运营绩效至关重要。四个主要的 DORA 指标是部署频率变更领先时间变更失败率MTTR

  • 部署频率:这是评估团队成功将代码部署到生产环境的频率。频繁的部署表明开发过程高效且响应迅速,能够更快地获得反馈并实现持续改进。为了提高部署频率,可以采用 CI/CD 实践。使用如JenkinsGitHub ActionsGitLab CI等工具自动化构建和部署流水线。定期的小规模部署可以降低风险并加速反馈。此外,特性标志可以用于管理部署并逐步推出新特性。

  • 变更领先时间:这是指从代码提交到生产环境部署的时间长度。这个指标反映了开发过程的速度和敏捷性。较短的领先时间通常意味着能更快速地获得用户反馈,并且能够迅速适应和改进软件。通过优化开发过程可以缩短领先时间。这包括采用敏捷方法论、增强团队之间的协作,并将代码审查和测试整合到开发流程中。利用自动化测试和持续集成工具,确保代码更改能够快速进行测试和集成。可以使用跟踪工具来监控从代码提交到部署的时间,帮助识别瓶颈。

  • 变更失败率:这个指标关注导致生产环境失败的部署比例。该指标对于理解软件开发过程的可靠性和稳定性至关重要。较低的变更失败率意味着软件部署的质量和可靠性较高。为了降低变更失败率,可以专注于提升代码质量和部署的可靠性。实施自动化测试,包括单元测试、集成测试和端到端测试,及早发现问题。使用静态代码分析工具并进行全面的代码审查。实践持续部署并进行自动回滚,采用金丝雀发布蓝绿部署等方式以最小化失败部署的影响。

  • MTTR:这是从生产环境故障中恢复所需的平均时间。这个指标非常关键,因为它反映了团队快速修复问题的能力,从而最小化停机时间并保持服务质量。减少 MTTR 需要改善事件响应和恢复流程。实施监控和警报工具,如 Prometheus、Grafana 或 New Relic,以便快速检测问题。建立清晰的事件管理协议和值班轮换。使用基础设施即代码(IaC)工具如 Terraform,实现快速且一致的环境恢复。定期进行事件响应演练,确保团队能够快速恢复。

这些指标与 GitOps 方法非常契合,该方法强调自动化、监控和快速反馈。GitOps 通过自动化管道可以提高部署频率和变更交付时间。它还通过启用更快速的回滚和通过持续集成与交付等实践促进更可靠的部署,从而有助于减少变更失败率和平均恢复时间(MTTR)。

然而,尽管 DORA 指标提供了宝贵的见解,但它们也带来了一些挑战。实施这些指标需要一个成熟的 DevOps 团队和完善的 CI/CD 流程。数据收集和标记需要精确且具有可操作性。指标必须根据不同团队和产品的独特节奏和流程进行调整。

在独立于特定的 Git 源版本控制SVCs)如 DevOps、GitHub 或 GitLab 测量这些指标时,组织可以通过集成提供必要数据可视化和仪表盘的各种工具来进行。团队可以利用不同工具的 API 收集相关数据点,以计算这些指标。例如,可以使用跟踪代码部署的工具来监控部署频率,而变更交付时间则可以通过从版本控制系统中提取代码提交和部署的时间戳来计算。

组织可以选择通过开发适合其环境的逻辑来实施 DORA 指标,或者使用像 GitLab 的价值流分析仪表盘 等成熟工具。GitLab 的仪表盘 [6] 能有效可视化软件开发生命周期并计算 DORA 指标。它提供了一个互动界面,用于追踪软件交付过程中的关键阶段,并使团队能够自定义仪表盘,以适应其特定的工作流程,从而提高对交付时间、周期时间和其他重要指标的理解。这个功能有助于识别瓶颈和需要改进的领域,从而提高部署频率和整体 DevOps 性能。

同样,SquaredUp 专注于 Azure DevOps 集成 [7] 并提供专为 DevOps 团队设计的 DORA 指标仪表盘。该仪表盘提供了关键性能指标的全面视图,包括部署频率、变更的交付时间、变更失败率和 MTTR。它帮助团队监控和分析他们的软件交付过程,便于识别需要改进的领域。SquaredUp 的解决方案强调了数据驱动的决策在软件开发中的重要性,展示了指标在优化 DevOps 工作流中的关键作用。

成功利用 DORA 指标的关键在于理解这些测量的背景,将它们作为一个整体而非单独分析,并根据不同团队和项目的独特需求进行调整。

总结来说,DORA 指标提供了一种结构化和可量化的评估与改进 DevOps 性能的方法。它们为软件交付过程提供了全面的视角,突出需要改进的领域,并促进了持续开发和运营效率的文化。

理解 GitOps 中持续改进的必要性

在快速发展的软件开发领域,GitOps 的采用标志着协作方法和运营效率的显著转变。GitOps 是一种将 Git 与 Kubernetes 操作流程相结合的方法论,它不仅仅是一套实践,它代表了一个持续改进和适应的过程。本节探讨了 GitOps 如何促使和促进在安全性、开发、平台工程和财务运营等多个领域的持续改进

  • 与 GitOps 一起演变的安全实践:GitOps 领域的安全性是动态的,且在持续演变。团队使用诸如 Kyverno 等工具部署策略,以适应快速变化的安全威胁环境。新漏洞和攻击途径的出现要求采取主动和适应性的策略。GitOps 通过支持快速迭代和部署安全策略来应对这一需求。然而,管理机密的方式发生了变化——从使用 Sealed Secrets 等工具,到采用 External-Secrets Operators。这一转变强调了团队需要不断发展其工具和实践,在一个停滞就意味着脆弱的领域中保持领先。

  • 开发者通过 GitOps 的持续创新:对于开发者而言,GitOps 不仅仅是一种部署方法,更是持续创新的催化剂。像蓝绿部署金丝雀部署等技术变得更加流畅,同时像 PR-Generators 这样的新工具提升了部署流程。这些创新在一个部署策略和工具不断变化的环境中至关重要。GitOps 赋能开发者快速部署、实验和迭代,从而促进了持续改进的文化,并能够灵活应对市场和技术的变化。

  • 平台工程和可扩展基础设施:平台工程团队认为 GitOps 是管理基础设施的高效和可扩展的得力助手。像 Argo CD 中的App of AppsApplicationSets with Cluster Generator等模式展示了基础设施管理的发展趋势。像 Crossplane 和 Cluster API 这样的工具,扩展了 GitOps 的能力,从仅仅应用部署,拓展到管理和配置多样化的云资源。这一发展凸显了团队必须不断适应并提升技能和工具,以有效管理日益复杂和分布式的系统。

  • FinOps – GitOps 时代的财务优化:在 FinOps 领域,GitOps 引入了如OpenCost等工具,使得能够在命名空间级别进行详细的成本跟踪和分配。如此细化的成本分配以及根据使用模式调整资源可用性的能力,标志着云成本管理方式的重大转变。这也表明,财务运营团队需要不断整合新工具和策略,以持续优化成本。像Kubegreen这样的工具,通过根据需求调整资源,证明了云环境中财务运营的不断发展。

GitOps 的旅程是持续且多面的。来自不同领域的团队——从安全、开发到平台工程,再到 FinOps——不仅要采纳 GitOps,还要拥抱其持续改进的理念。这包括定期评估、愿意采纳新工具和实践,以及对学习和适应的承诺。

在本章的最后部分,我们将探讨如何克服文化障碍,采纳 GitOps,并了解不同团队如何采用不同的方式进行工作。

克服文化障碍以采纳 GitOps

采用 GitOps 不仅仅是工具实施;它还意味着组织内部的文化转变。这一转变涉及到打破传统的部门壁垒,培养协作,并将团队统一到共同目标上。GitOps 作为一个统一的力量,简化了操作和开发,朝着更高效的 IT 环境迈进。在软件开发的动态世界中,GitOps 的持续改进至关重要。这段旅程注重学习、适应和不断发展实践。

在检视不同定义或将 GitOps 与 DevOps 对比时,技术方面可以通过 Weaveworks 博客上关于 GitOps 文化的内容进行总结,博客详细阐述了 GitOps 如何不仅仅是工具或实践的集合,而是代表着组织内部更广泛的文化转变。这一方法将 Git 集成到运营和开发过程的核心,强调透明性、问责制和协作。GitOps 文化的特点是将 Git 集中用于管理基础设施、应用程序和 CI/CD 流程,从而增强自动化、稳定性和一致性。它培养了一个团队成员不断改进的环境,这一切得益于 Git 基础的工作流所提供的可见性和控制力。

关于 GitOps 方法及其相关的技术挑战、责任、协作等内容可能是正确的。我并不是说它错了,因为它并没有错。然而,我想将焦点转移到一个视角,考虑到不同行业的日常工作。并不是每个公司都像 Weaveworks 那样是软件公司。

一个项目的故事——交流、经验与学习

根据我与DevOps 专业人员CTO平台工程师的经验和讨论,显然工具和方法的变化比改变团队或公司心态更为直接,因为后者需要时间进行转变。

一些公司是这样处理的:

  • 在我们使用 Argo CD 进行 GitOps 管理基础设施和应用服务的过程中,我们注意到显著的改进。例如,我们可以轻松识别我们在预生产和生产环境中的偏差,这些环境会被密切监控。对于开发和临时环境,我们使用 Helm 和 CD 流水线,不跟踪变更。

  • Weaveworks 在 GitOps 文化中的强调表明,GitOps,特别是通过 Weave GitOps,促进了一个强大的团队文化,特点是优秀的沟通协调合作。GitOps 提供的角色职责的清晰度使团队能够保持自治,同时借助 Kubernetes 命名空间来组织和隔离工作负载。此外,Weave 收购 Magalix 进一步强调了 GitOps 中的安全策略,使管理员能够在整个 GitOps 过程中设定并执行策略。这种方法突显了 GitOps 文化的运营性质,有别于 DevOps 的理想文化,专注于精准和责任。

我相信当你超越技术层面并仔细阅读时,Weaveworks 确实抓住了问题的关键。对话暗示,GitOps 方法促进了不同团队之间的文化变革,这些团队应掌握相同的工具,但使用场景各不相同。各团队可以独立工作,但这需要出色的沟通、协调和合作。此外,还需要定义角色和职责。每一次变更或倡议都应清晰且透明地传达给其他团队。这一切听起来都很棒,但在涉及不同团队的实际项目中,情况如何呢?我将尝试通过一个我项目中的例子来说明。

在该项目中,存在一个平台团队、若干开发团队和一个安全团队。安全团队的职责不仅是确保组织内遵守安全指南,还包括 IT 治理和合规性。因此,它感到有责任通过一切可行的手段保护公司,并在 GitOps 过程中执行政策。

平台团队为开发人员提供了必要的 Kubernetes 集群和上下文环境,因此他们只需要专注于自己的应用程序,最多关注第三方工具。他们将自己的角色视为开发者的支持者,开发者作为客户购买并使用平台,平台的核心价值最大程度地强调自助服务可用性性能。开发团队将 Kubernetes 视为产品并进行应用程序开发。让我们看看一个团队的合理决策如何无意中对另一个团队造成伤害:

  • 安全团队执行了一项策略,禁止任何应用程序以提升的权限运行,结果,一些平台上下文中的应用程序以及自研应用停止工作。这导致了应用程序的停机和软件故障。

    采取这一行动的理由是确保公司受到保护。

  • 平台团队进行了从 Kubernetes 1.24 到 1.25 的升级,因为前一版本已结束支持。结果,安全团队使用的第三方工具不再工作,一些开发者的应用程序也停止了运行。此次变更未考虑到升级过程中将PodSecurityPolicies替换为PodSecurityStandards

    该行动的理由是确保提供支持的版本,并确保平台按照安全团队的要求保持最新。这项责任包括确保性能得到优化和可靠,同时遵守与 Kubernetes 生态系统相关的最新安全协议和合规标准。

  • 开发者使用他们的自主权,在具有外部 IP 地址的节点上打开一个NodePort进行测试。应用程序变得可以外部访问。调试功能正常,但测试所需时间更长。幸运的是,应用程序使用Log4j版本 2.10 进行日志记录,简化了调试过程。

    该行动的理由是提高测试和调试的性能。开发者面临着完成任务的压力,选择了一种快速解决方案来测试他们的应用程序,将即时功能优先于长期的安全性和合规性考虑。

不同措施所导致的可能后果包括:客户感到沮丧,公司每分钟都在亏损,公司的声誉下降。这些是修改后的使用案例,幸运的是,我的项目没有受到 Log4J 事件的影响。但这里的重点不是发生了什么,而是这些情况的出现是可以理解的,从团队的角度来看是有道理的。

反思最近挑战的原因,似乎不同团队提供的各种解释都是合理的。例如,当检查安全团队和平台团队所做的变更时,他们从自己的角度承担了责任,确保公司得到了充分的保护和代表。然而,他们并未认为自己对应用程序的停机或客户的损失负有责任,认为他们的行动是正当的。如果团队之间能够提前进行简单的沟通和透明化,关于即将发生的变更,这种情况本可以避免。

从开发者的角度来看,他们面临着完成任务的压力,以防止已有进度延误的功能进一步拖延,这已经导致客户感到沮丧。调试仅在开发环境中启用,并且他们认为没有必要通知安全团队或平台团队,认为这些团队无法理解变更,并且没有理由阻碍变更。开发者认为他们是在为公司的最大利益行事,旨在满足客户需求。

从开发者的角度来看,他们感受到强烈的责任感,需要按时完成任务。然而,他们忽视了与安全团队或平台团队之间简单沟通和透明度的重要性,认为这些团队可能无法理解变更,并可能不必要地阻碍这一变更。在追求为公司争取最大利益和满足客户需求的过程中,他们错失了与这些团队合作的机会,这本可以使他们的工作与更广泛的组织目标相协调。

这些经验

从这些事件中汲取的教训促成了一个公会的成立,各团队的代表定期参加会议。这使得变更及其影响能够被讨论和公开,促进了团队间的清晰沟通和合作。此外,它帮助不同团队理解彼此的观点、需求和原因,从而提高了透明度。虽然并非所有决策都经过讨论,而且有时由于时间限制或紧迫性(例如关键的安全漏洞问题),决策是迅速做出的,但总体情况已有所改善。提高的透明度有助于更好地理解变更的影响,减少了这些变更的爆炸半径。团队成员间的同理心增加了,指责文化大大减少了。

整体情况有所改善吗?是的

所有决策都是在讨论后作出的吗?不是,因为时间压力和紧迫性通常会导致决策迅速做出。

来自另一个近期项目的关键问答

本节将聚焦于某个公司和多个项目中的具体问题和答案,这些项目仍在转型过程中,从 DevOps 方法开始,现已转向平台工程,同时也会分享他们进行这种转型的真实原因:

  • Q1:GitOps 是如何重构你们的团队组织结构的?

    A1:最初,我们每个项目都有单独的 DevOps 团队。GitOps 促成了一个中央平台团队的创建,以高效管理 Kubernetes 集群。

  • Q2:转型到 GitOps 时遇到了哪些挑战?

    A2:我们的主要挑战是适应 GitOps 提供的不可变基础设施,特别是理解所有的变更都需要通过 Git 提交来流转。

  • Q3:你们从 GitOps 中获得了哪些好处?

    A3:GitOps 为我们带来了一个清晰且可追溯的工作流程。每一个变更,无论大小,现在都通过 Git 进行精确跟踪。

  • Q4:GitOps 如何影响了团队沟通?

    A4:沟通有了显著改善。我们的平台团队对开发者的需求有了更深入的理解,这促进了更有同理心的合作

  • Q5:你能分享一些成功的文化转型案例吗?

    A5:绝对如此。我们发展了主动错误文化,专注于自动化和持续学习,这从根本上改变了我们的解决问题的方法。

  • Q6:GitOps 如何改变了你们团队的日常工作?

    A6:团队成员的动力责任感显著提升,他们在自己的角色中有了更大的自主性

  • Q7:你的团队是如何适应 GitOps 的?

    A7:出乎意料的是,团队的抵触情绪很小。团队理解这次转型的必要性,并且对此非常接受。

  • Q8:你们如何衡量这次转型的成功?

    A8:虽然我们还没有精确的衡量指标,但手动干预的减少和Git 活动的增加是成功的重要指标。

  • Q9: 你的团队规模是多少?

    A9: 我们的团队由大约 20 名开发人员和三名平台工程师组成。

这种对话格式使得人们能够清晰理解 GitOps 如何改变团队动态、面临的挑战以及工作流效率。

采用 GitOps 不仅仅是实施一套工具;它涉及组织内的文化变革。克服传统部门之间的壁垒,培养协作和持续学习的文化,并将不同的团队对齐到共同的运维目标上,是这条旅程中的重要步骤。因此,GitOps 的采用成为了一个统一的力量,将各类运维和开发工作对齐,推动形成一个更高效、透明和响应迅速的 IT 环境。

总结来说,GitOps 的持续改进不仅仅是一个建议;它是快速变化、节奏快速的软件开发和 IT 运维世界中的必需品。在团队进行这项旅程时,重点应始终放在学习、适应和发展实践上,以保持在变化是唯一常态的环境中的领先地位。因此,GitOps 更像是一条通向卓越运维和持续改进的道路,而非一个最终目标。

总结

本章提供了 GitOps 推动的 IT 文化革命的有力视角。它首先确立了 GitOps 不仅仅是技术上的转变,而是 IT 部门内部深刻的文化变革。这种方法通过 Git 将软件开发与 IT 运维结合,改变了运维流程和方法论,将基础设施视为应用程序。它实现了自动化和精准,并将严格的软件开发实践延伸到基础设施管理中。

GitOps 带来的一个关键变化是建立了不可变的基础设施,自动化地将基础设施的实际状态与期望状态对齐,减少了人工干预和错误。本章还通过 DORA 指标探讨了 GitOps 对 IT 性能的影响,提供了部署频率、变更前置时间、失败率和恢复时间的定量评估。本章还讨论了 GitOps 采用对整个组织的影响。这不仅仅是工具的实现;它是推动深远文化转变的催化剂,促进了一个协作、透明和高效的 IT 文化。来自不同组织的实际案例展示了 GitOps 如何推动这些变化。

总的来说,本章揭示了 GitOps 的变革力量,它超越了技术层面,为走向更敏捷、更具创新力的 IT 文化指引了方向。

在下一章中,我们将探讨 GitOps 与 OpenShift 的结合应用,OpenShift 是来自 Red Hat 的 Kubernetes 下游发行版,并分析它的管理方式有何不同。

参考文献

第三部分:动手实践 GitOps 自动化基础设施和 CI/CD

在这一部分,你将亲身体验使用 GitOps 自动化基础设施和 CI/CD 流程。你将探索在 OpenShift、Azure 和 AWS 等平台上的具体实施,并集成 Terraform 和 Flux CD 等工具以增强自动化。本实操部分旨在为你提供在不同环境中应用 GitOps 所需的技能,确保你能够高效且有效地管理基础设施和 CI/CD 流水线。

本部分包括以下章节:

  • 第八章,OpenShift 上的 GitOps

  • 第九章,GitOps 在 Azure 和 AWS 部署中的应用

  • 第十章,GitOps 在基础设施自动化中的应用——Terraform 和 Flux CD

  • 第十一章,在 Kubernetes 上使用 GitOps 部署实际项目

第七章:使用 OpenShift 进行 GitOps

本章将深入探讨GitOpsRed Hat OpenShift中的应用,这是一种彻底改变我们部署、管理和运营容器化应用程序的方式。

在本章中,我们将探索 GitOps 的基本原则,重点介绍它们如何与 Red Hat OpenShift 的强大功能无缝集成。这种结合不仅提升了部署的效率和可靠性,还与现代 DevOps 实践保持一致,促进了开发与运维团队之间的协作。

我们将从使用CodeReady ContainersCRC)设置本地 OpenShift 环境开始,通过实践的方法来理解 OpenShift 如何运作以及如何使用 GitOps 原则进行管理。接下来,我们将深入实际示例和最佳实践,包括配置自动化部署、管理应用程序配置,并确保 OpenShift 集群中的高可用性和安全性。

无论你是 OpenShift 的新手,还是希望增强现有工作流,本章对 GitOps 的探索将为优化你的云原生开发过程提供有价值的见解和技巧。

在本章中,我们将重点关注以下几个关键领域:

  • Red Hat OpenShift 简介

  • 在 Red Hat OpenShift 中设置 GitOps

  • 利用 Red Hat OpenShift 的 CI/CD 实现 GitOps

  • 自动化和配置最佳实践

  • Kubernetes 与 Red Hat OpenShift 的比较

技术要求

对于本章,确保你有 Red Hat OpenShift 集群的访问权限,或者通过 Red Hat OpenShift Local 进行本地设置。熟悉 GitOps 实践和工具,如 Argo CD,以及基本的开发工具如 Git 和代码编辑器,是必要的。对于容器技术、Kubernetes 架构和 YAML 语法的基础理解将有助于跟随实践练习。确保有稳定的互联网连接以便下载工具和访问集群。如果在本地运行 OpenShift,您的机器最好至少有 16GB 的 RAM 和足够的存储空间。

本章相关的代码和资源文件可以在我们的专用 GitHub 仓库中的Chapter08文件夹找到:github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

Red Hat OpenShift 简介

OpenShift(www.redhat.com/en/technologies/cloud-computing/openshift),由 Red Hat 开发,是一个领先的企业级 Kubernetes 平台,提供了一整套功能,旨在简化容器化应用的部署、扩展和操作。它通过简化许多与部署和管理容器化基础设施相关的复杂任务,扩展了 Kubernetes,使其成为希望实施现代 DevOps 和 GitOps 实践的企业的理想选择。

OpenShift 的核心优势之一是它对开发者生产力操作效率的关注。它提供了一整套丰富的开发者工具和一个用户友好的控制台,使开发者可以更轻松地构建、部署和管理他们的应用。OpenShift 的集成开发环境IDE)和内建的 CI/CD 功能使开发者能够自动化软件交付过程的许多环节,从代码构建到测试、部署和监控。

安全性是 OpenShift 的另一个亮点。它在应用栈的每个层级都集成了内建的安全特性,从操作系统OS)到网络,再到应用服务。这种集成方法确保了安全性不是事后的补充,而是深深融入应用生命周期的每一个环节。诸如增强型安全 LinuxSELinux)强制隔离、自动化漏洞扫描和默认安全配置等功能有助于保护应用和数据免受外部威胁和内部配置错误的影响。

SELinux

SELinux 是一项内核集成的安全功能,强制执行强制访问控制MAC)策略,以增强系统安全性。它遵循最小权限原则,将系统进程和用户的权限限制在完成其功能所需的最低权限内。SELinux 有助于防止未经授权的访问,并可以在强制模式下运行,阻止并记录未经授权的操作,或者在宽松模式下运行,只记录违规操作而不加以阻止。这为基于 Linux 的系统,包括 OpenShift,增加了一个重要的安全层,通过比传统访问控制更精细的方式来控制访问。

此外,OpenShift 旨在支持各种工作负载,从传统的单体应用到微服务和无服务器功能。它的灵活架构支持多种编程语言、框架和数据库,允许团队使用最适合其需求的工具和技术。此外,OpenShift 的容器原生存储和网络解决方案提供了高需求应用所需的可扩展性和性能。

在 GitOps 的背景下,OpenShift 提供了一个强大的平台,用于实现声明式的、版本控制的基础设施和应用部署工作流。通过利用 OpenShift 的能力,团队可以实现更高水平的自动化可重复性一致性,这些都是 GitOps 哲学的核心。凭借其强大的生态系统,OpenShift 使组织能够简化部署管道,增强安全性并提高操作效率,是采用 GitOps 方法论的理想选择。

Red Hat OpenShift 环境设置

在设置 OpenShift 集群用于学习、测试或开发时,您有多个选项可供考虑,每个选项都有其独特的优点。了解这些替代方案将帮助您根据目标、可用资源和技术舒适度选择最合适的方案。

  • OpenShift 开发者沙箱:这是一个很好的起点,适合初学者或希望在没有任何设置的情况下测试 OpenShift 功能的人。开发者沙箱(developers.redhat.com/developer-sandbox)提供了一个免费的预配置 OpenShift 环境。您只需要注册,即可获得 30 天的免费访问权限,使用共享的 OpenShift 和 Kubernetes 集群。这个选项非常适合那些希望避免手动设置复杂性并寻找快速开始实验 OpenShift 功能的用户。

  • 云端 OpenShift 集群:在云端(如 Azure、AWS 或 GCP)设置 OpenShift 集群是一种强大的解决方案,提供了可扩展性和现实世界的适用性。这种方法适合那些希望模拟生产环境或从事更大、更复杂项目的用户。然而,需要注意的是,在云端运行集群可能会产生费用,具体费用取决于云服务提供商和所消耗的资源。

  • 裸金属设置:在裸金属上设置 OpenShift Local 是一项具有挑战性且资源密集的任务。与云环境不同,您必须手动管理网络、存储和硬件兼容性,这需要较高的技术水平。系统要求大量的内存、多个 CPU 核心以及可观的存储,这对于最初没有为这种负载设计的环境来说可能会显得令人生畏。尽管裸金属安装提供了更大的控制权和潜在的性能优势,但它也带来了复杂性和潜在的障碍,需要仔细规划和理解。

  • Red Hat OpenShift Local:对于那些偏好本地解决方案的用户,通过使用 Red Hat CRC 在本地机器上设置 OpenShift 集群是一种有效的方法。这种方法允许更深入的操作体验,适合个人学习和开发场景。

Red Hat OpenShift Local 提供了一种快速简便的方式来启动 OpenShift 集群的构建。它针对本地机器操作进行了优化,简化了设置和测试过程,提供了一个类似云环境的开发环境,直接在桌面上运行。此工具支持多种编程语言,通过提供一个最小化的预配置 OpenShift 集群,简化了基于容器应用的开发,无需依赖服务器基础设施。

OpenShift Local 使得可以直接将微服务创建、构建并部署到 Kubernetes 托管的容器中,支持包括 Linux、macOS 和 Windows 10 等多种操作系统。这使得它成为本地开发和测试的理想平台,模拟了真实 OpenShift 集群的环境。

在本章剩余部分,我们选择使用 OpenShift Local,因其便捷性和与本地开发场景的相关性。需要特别注意的是,要有效运行示例,最低硬件配置要求是为本地集群分配 6 个虚拟 CPU 和 12GB 内存。这个要求确保用户能够在 GitOps 上下文中充分体验 OpenShift Local 的全部功能,而不会出现显著的性能问题。

首先,导航到developers.redhat.com/products/openshift-local/overview,然后点击在您的笔记本电脑上安装 OpenShift,如图 8.1所示。

图 8.1 – Red Hat OpenShift Local (CRC)首页

图 8.1 – Red Hat OpenShift Local (CRC)首页

要继续设置集群,必须通过创建一个 Red Hat 账户来下载安装程序(如果您还没有账户的话)。在显示的页面(图 8.2)中,选择与您的操作系统(Linux、Windows 或 macOS)对应的安装程序,并确保选择下载拉取密钥复制拉取密钥选项,因为安装过程中需要拉取密钥。记住,如果需要,您可以随时返回此页面。

图 8.2 – 根据目标操作系统下载 CRC 安装程序的起始网页

图 8.2 – 根据目标操作系统下载 CRC 安装程序的起始网页

在这一点上,需要注意的是,详细的安装步骤超出了本文的范围。然而,您可以在 Red Hat 提供的官方文档中找到全面的指南。

要查看完整的操作流程,请访问以下链接:access.redhat.com/documentation/en-us/red_hat_codeready_containers/1.0/html/getting_started_guide/getting-started-with-codeready-containers_gsg#doc-wrapper

该资源概述了建立本地 OpenShift 集群所需的所有步骤。作为验证安装正确性的标准步骤,请执行以下命令:

$ crc version

这应生成如下所示的输出:

CodeReady Containers version: 1.25.0+0e5748c8
OpenShift version: 4.7.13

OpenShift CRC 设置问题排查

设置环境可能是一个复杂的过程,且可能会遇到一些困难。它需要对系统配置和依赖项的细致了解和谨慎处理。虽然遵循提供的指南和文档可以简化过程,但您仍然可能遇到意想不到的挑战。重要的是以耐心的态度进行设置,并准备好进行一些故障排除,以解决出现的问题。请记住,使用以下命令正确启动集群:

$ crc start --cpus 6 --memory 12288

此命令确保您的 CRC 实例以指定的计算资源启动:6 个 CPU 和 12288 MB(大约 12 GB)内存。这些设置对您的 OpenShift 集群的最佳性能至关重要。

如果在设置过程中遇到任何问题,请尝试执行以下命令序列来进行故障排除并重置您的环境:

  • crc delete -f:强制删除现有的 CRC 实例,清除任何当前的配置。

  • crc cleanup:此命令有助于清理之前实例留下的任何残留文件或配置,确保一个干净的环境。

  • crc setup:重新运行设置命令,以再次为 CRC 配置您的系统。

  • crc config unset proxy-ca-file:这将移除可能导致问题的任何代理配置设置。

  • crc start --log-level debug:再次启动 CRC 实例,这次启用调试日志记录。这将提供更详细的输出,有助于识别设置过程中的问题所在。

为了完成集群的设置,还需要一个关键步骤:安装 OpenShift oc。该工具对于与 OpenShift 集群交互至关重要,允许用户通过命令行执行各种任务,例如部署应用程序、检查集群资源和管理管理活动。oc CLI 专为开发人员和系统管理员设计,提供了超越 Kubernetes 基本功能的高级功能。因此,oc CLI 是希望通过脚本自动化流程或更直接地管理集群的用户必不可少的组件,确保在 OpenShift 生态系统内高效运作。

安装oc CLI 的详细步骤可以在官方文档中找到。请访问oc CLI 以管理您的 OpenShift 集群。

输入以下命令检查oc是否已正确安装:

$ oc version

前述命令的预期输出应如下所示:

Client Version: 4.15.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: 4.14.12
Kubernetes Version: v1.27.10+28ed2d7

现在集群设置完成,我们准备进入下一部分,重点将是设置 GitOps 在我们的 Red Hat OpenShift 集群中。

通过应用 GitOps,我们可以充分发挥新配置的 OpenShift 环境的潜力,确保更高效和自动化的操作框架。让我们继续前进,探索 GitOps 在 OpenShift 中的令人兴奋的功能。

在 Red Hat OpenShift 中设置 GitOps

首先安装必要的 GitOps 工具。Argo CD(请参见 第四章 中的 Argo CD 部分)是 OpenShift 的流行选择,因为它可以无缝集成到 Kubernetes 环境中。您可以通过 OperatorHub 将 Argo CD 直接安装到 OpenShift 集群中,OperatorHub 提供了一个简单的安装过程并自动管理应用程序生命周期:

  1. 要获取在 CRC 上运行的本地 OpenShift 集群的地址,请在终端中使用以下命令:

    crc start command will typically include several important pieces of information relevant to your local OpenShift cluster setup. Here’s an example of what you might see:
    
    

    INFO 正在加载捆绑包:crc_vfkit_4.14.12_arm64...

    INFO 已经启动了 OpenShift 4.14.12 的 CRC 虚拟机

    启动了 OpenShift 集群。

    该服务器可以通过 Web 控制台访问:

    https://console-openshift-console.apps-crc.testing

    以管理员身份登录:

    用户名:kubeadmin

    密码:C57Yw-465gL-NXcpv-nri5w

    以用户身份登录:

    用户名:developer

    密码:developer

    使用 'oc' 命令行接口:

    $ eval $(crc oc-env)

    $ oc login -u developer https://api.crc.testing:6443

    
    This output provides you with the URL for the OpenShift web console, along with login credentials for both the administrator and regular (developer) user accounts. It also includes instructions for logging in to your cluster using the `oc` CLI. Ensure you save these details, as you will need them to access your local OpenShift cluster.
    
  2. 导航至 console-openshift-console.apps-crc.testing,并根据 图 8.3 中的说明使用 crc start 命令登录。这将使您可以完全访问 OpenShift 集群的管理功能。

图 8.3 – 管理员模式下的集群页面

图 8.3 – 管理员模式下的集群页面

  1. 在 OpenShift Web 控制台中,导航至左侧面板并展开 Operators 部分。

  2. 点击 OpenShift GitOps 定位并安装相关的 Operator。此操作将显示 OpenShift GitOps operator,您可以继续将其安装到您的集群中(有关指导,请参见 图 8.4)。

OpenShift Operators

OpenShift Operator 是一种打包、部署和管理 Kubernetes 应用程序的方法。OpenShift Operators 扩展了 Kubernetes API,用于代表 Kubernetes 用户创建、配置和管理复杂的有状态应用实例。它们自动化管理的软件生命周期,包括从初始部署到升级,再到日常操作,遵循最佳实践。这种方法简化了复杂应用程序和服务的管理,使开发人员和运维人员可以专注于应用程序的细节,同时利用 Kubernetes 系统的可扩展性和可靠性。从本质上讲,Operators 封装了运行服务所需的人工操作知识,提供了一种更高效、更可靠的方式来管理云原生环境中的应用程序。

图 8.4 – 导航到 OperatorHub 并搜索 OpenShift GitOps Operator

图 8.4 – 导航至 OperatorHub 并搜索 OpenShift GitOps 操作员

  1. 找到 Red Hat OpenShift GitOps 操作员后,点击它以查看更多详细信息。然后,继续点击安装按钮。当系统提示时,保留默认值并继续安装过程(参见图 8.5)。这将启动在集群中设置 OpenShift GitOps 操作员,为您的环境提供 GitOps 工作流所需的工具。

图 8.5 – 安装操作员前显示详细信息的面板

图 8.5 – 安装操作员前显示详细信息的面板

  1. 对于安装模式,选择集群中的所有命名空间(默认),以允许操作员跨所有命名空间进行操作。

  2. 对于安装命名空间,选择操作员推荐的命名空间 openshift-gitops-operator,这是专门为 GitOps 操作员推荐的。

  3. 点击安装并等待安装操作完成。这可能需要几分钟时间。安装完成后,点击查看操作员以验证安装是否成功,并确保一切设置正确。

  4. 在 Web 控制台中保持在管理员模式,导航到创建项目以启动一个新项目。填写项目创建表单,按照项目要求或具体指南进行填写(参见图 8.6)。这将为您的 GitOps 部署和相关资源创建一个专用命名空间。

图 8.6 – Red Hat OpenShift – 创建项目

图 8.6 – Red Hat OpenShift – 创建项目

注意!

您项目的显示名称可以根据您的偏好进行调整,但重要的是要记住这个名称,因为您将在后续步骤中始终使用它。确保您选择的名称易于记忆且与项目相关,以避免日后混淆。

  1. 一旦项目创建完成,您新建立的项目的仪表板应该会在 OpenShift Web 控制台中出现,如图 8.7所示。它将提供有关项目资源、活动和状态的概览。确保详细信息与您的期望和配置一致,因为这个仪表板将是您在接下来的步骤中管理和监控项目组件的核心。

图 8.7 – 新创建项目的仪表板

图 8.7 – 新创建项目的仪表板

  1. 在 OpenShift Web 控制台中,转到操作员 | 已安装的操作员。找到并点击Red Hat OpenShift GitOps,然后选择所有实例以查看并管理您的 GitOps 操作员实例(参见图 8.8获取指导)。

图 8.8 – 操作员已安装的实例列表及其状态

图 8.8 – 操作员已安装的实例列表及其状态

  1. 在继续之前,请确保左上角选择的项目是 gitopsk8sdeployments。然后,点击 创建新项 并选择 Argo CD 来设置一个新的实例。

  2. 在出现的表单中,输入 argocd-for-gitops-deployments 作为名称。

  3. 要为 Argo CD 服务器创建外部路由,点击 服务器 | 路由 并确保勾选 已启用。这将允许您从 OpenShift 集群外部访问 Argo CD 界面。

  4. 等待 状态 值变为 可用,如 图 8.9 所示。这表明您的 Argo CD 实例已经完全部署,并可以在 OpenShift 集群中使用。状态更改可能需要几分钟时间,因为系统正在完成设置和部署过程。

图 8.9 – 显示为特定命名空间创建的 Argo CD 实例的新项

图 8.9 – 显示为特定命名空间创建的 Argo CD 实例的新项

切换到 OpenShift Web 控制台中的 开发者 模式,点击 拓扑。此视图将为您提供一个已部署资源的图形表示,帮助您直观地理解所选项目中应用程序和服务的结构及其关系。

图 8.10 – 部署资源的图形表示

图 8.10 – 部署资源的图形表示

  1. 为了进一步测试 Argo CD 是否正确设置,您可以使用 oc 并运行以下命令:

    gitopsk8sdeployments namespace, allowing you to verify that the Argo CD pods have been successfully deployed and are running as expected. If the Argo CD setup was successful, you should see the related pods listed without issues (all of them in the Running status):
    
    

    名称 就绪 状态 重启次数 存在时间

    argocd-for-gitops-deployments-application-controller-0 1/1 运行中 0 6m1s

    argocd-for-gitops-deployments-redis-6c9476c7dc-76c6n 1/1 运行中 0 6m1s

    argocd-for-gitops-deployments-repo-server-65cdc966d4-qzpvt 1/1 运行中 0 6m1s

    
    

现在我们已经成功设置了 Argo CD 并验证了其正确安装,我们可以继续进行部署。接下来,让我们进入下一步,在 OpenShift 环境中利用我们的 GitOps 工作流高效地管理和部署应用程序。

利用 Red Hat OpenShift 的 CI/CD 进行 GitOps

在本节中,我们将深入探讨如何利用 Red Hat OpenShift 的 CI/CD 能力进行 GitOps。具体来说,我们将应用这些原则来部署天气应用程序,该应用程序在 第四章我的城市天气应用程序 部分中已经介绍过。通过使用部署 YAML 文件,我们将在 OpenShift 集群中通过我们的 Argo CD 实例来编排应用程序的发布,目标命名空间为 gitopsk8sdeployments。这个实际示例将展示 OpenShift 的 CI/CD 工具与 GitOps 方法相结合,如何简化和自动化部署过程,确保一致、可追踪且高效的应用程序交付流水线。

让我们探讨如何整合这些强大的技术,以无缝部署我们的天气应用:

  1. 在 OpenShift web 控制台中,确保你处于管理员模式。

  2. 然后,在列表中导航到argocd-for-gitops-deployments-server

图 8.11 – 管理员模式下的路由部分

图 8.11 – 管理员模式下的路由部分

  1. 点击gitopsk8sdeployments命名空间中提供的 URL。

图 8.12 – 我们演示项目创建的 Argo CD 实例的登录页面

图 8.12 – 我们演示项目创建的 Argo CD 实例的登录页面

  1. 要获取管理员凭证,请切换到 OpenShift web 控制台中的开发者模式。

  2. 然后,点击argocd-for-gitops-deployments-cluster。在该秘密的详细信息中,找到并复制admin.password条目的值。

图 8.13 – gitopsk8sdeployments 项目的 Secrets 部分

图 8.13 – gitopsk8sdeployments 项目的 Secrets 部分

  1. 一旦你访问 Argo CD 界面,应用列表最初应该是空的,正如图 8.14所示,因为还没有使用 Argo CD 部署任何应用。在这一点上,你已经准备好创建一个新的应用。这一步将涉及定义源代码库、代码库中存放 Kubernetes 清单的路径以及应用应部署的目标位置,在此案例中是 OpenShift 本地集群。

图 8.14 – Argo CD 实例的初始空应用列表

图 8.14 – Argo CD 实例的初始空应用列表

要创建新的 Argo CD 应用,你可以选择使用 Argo CD 的 Web UI 或oc CLI。如果选择 CLI,正如前面章节所示,你可以应用一个部署文件(例如argocd-deployment.yaml),该文件指定了应用的配置。

  1. 利用本章附带的代码仓库中的代码,你可以通过执行以下命令创建新的应用:

    argocd-deployment.yaml file is as follows:
    
    

    apiVersion: argoproj.io/v1alpha1

    kind: Application

    metadata:

    name: my-weather-app

    spec:

    目标:

    name: ''

    namespace: gitopsk8sdeployments

    server: 'https://kubernetes.default.svc'

    来源:

    path: deployment/base

    repoURL: 'https://github.com/pietrolibro/gitops-k8s-deployments-book-weather-app.git'

    targetRevision: main

    sources: []

    project: default

    syncPolicy:

    automated: null

    CreateNamespace: true

    
    At this point, a new application titled `my-weather-app` will be visible in the Argo CD dashboard that was previously opened.
    

图 8.15 – 已填充新创建应用的 Argo CD 实例

图 8.15 – 已填充新创建应用的 Argo CD 实例

  1. 应用程序最初会显示为OutofSync状态,表示集群的实际状态与 Git 仓库中定义的期望状态不匹配。为了解决此问题,点击Sync以将应用同步到仓库中定义的期望状态。此操作将根据 Git 仓库中定义的配置开始部署过程。

  2. 一旦应用程序完成同步,如图 8.16-17所示,它将与清单中定义的配置保持一致。这包括根据清单设置部署的两个副本。应用程序的状态应反映它现在与期望状态同步,且两个副本在 OpenShift 集群中按预期运行。

图 8.16 – 同步成功后的应用面板

图 8.16 – 同步成功后的应用面板

图 8.17 – 同步后已部署资源的详细状态

图 8.17 – 同步后已部署资源的详细状态

为了测试 GitOps CI/CD 部署方法,你可以使用 Git 将仓库拉取到本地,然后修改部署文件中指定的副本数。

仅对应用代码的更改不会导致同步状态被标记为不同步。同步状态只会受到与部署相关的更改的影响(例如,YAML 配置文件)。GitOps 工具(如 Argo CD)会监控仓库中配置文件的状态。如果配置文件中定义的期望状态与 Kubernetes 集群中的实际状态之间存在差异,它将被标记为不同步。因此,只有对部署文件(如 YAML 文件)的修改才会影响同步状态,而不会影响应用代码本身的更改。

此操作体现了 GitOps 工作流中典型的迭代和受控更改。如果你不喜欢直接使用 Git,你可以选择直接在 GitHub 上编辑文件,这样可以简化过程,同时实现相同的结果。

  1. 一旦你进行了更改并提交,这时 Argo CD 中的应用状态将转为Out of Sync(不同步)。这表示实际部署的状态与 Git 仓库中定义的期望状态不匹配。在我们的演示中,我们采用手动同步方法,这意味着在任何更改后,你需要手动触发 Argo CD 中的同步操作。这一步是应用新配置的关键,突显了 GitOps 原则,即通过版本控制的文件进行更新,最小化人工干预,以确保更改是有意为之并且有记录的。

图 8.18 – 在更改清单文件后,应用处于 OutOfSync 状态

图 8.18 – 在更改清单文件后,应用处于 OutOfSync 状态

  1. 要重新同步应用程序并应用更新的配置,只需在 Argo CD 仪表盘中点击 同步 按钮。启动同步后,监控过程以确保其成功完成。一旦同步成功,应用程序的状态将更新,以反映它现在与 Git 仓库中定义的目标状态同步,包括您所做的更改,如更新后的副本数。

随着我们从理解 Red Hat OpenShift 和 Kubernetes 的基础概念过渡,现在我们将焦点转向在这些环境中应用自动化和配置最佳实践。

自动化和配置最佳实践

OpenShift 被广泛用于全球托管关键应用程序。因此,应用程序必须满足高可用性标准,通常目标是五个 9(99.999%),以确保持续的服务交付。OpenShift 有助于以高可用的方式部署应用程序,减少故障,即使实例或基础设施出现问题也能保证服务不中断。

本总结概述了在 OpenShift 上部署高可用应用程序的一些关键实践:

  • 多个副本:部署多个 Pod 实例可以确保单个 Pod 的删除或故障不会导致停机。推荐的做法是为每个应用至少配置两个副本,以确保持续性。

  • 推荐使用 RollingUpdate

  • 根据需要设置 terminationGracePeriodSeconds,以便为应用程序提供足够的时间完成任务。

  • 探针:使用 存活探针就绪探针启动探针 来监控应用程序的健康状态。存活探针帮助在应用失败时重启应用,就绪探针管理应用的流量,启动探针在其他探针开始监控之前为应用启动提供时间。

  • 使用 initContainersstartupProbes 来确保在启动主应用程序之前,依赖项已经准备好,并使用就绪探针来维持健康检查。

  • Pod 中断预算(PDB):实施 PDBs 限制在维护过程中可以同时不可用的 Pod 数量,从而保护应用程序的可用性。

  • 自动扩展:利用 水平 Pod 自动扩展器HPA)和 垂直 Pod 自动扩展器VPA)根据当前负载动态调整 Pod 副本数或每个 Pod 的资源,以确保应用程序能够应对不同水平的流量。

  • Pod 拓扑扩展约束:将 Pod 副本分布在不同的故障域(例如节点、机架或区域)中,以避免同时停机并确保更好的可用性和弹性。

  • 部署策略:使用蓝绿部署或金丝雀部署策略,以最小化应用程序更新过程中的中断。这些策略能够实现更安全的发布,并且在出现问题时可以轻松回滚。

对于托管在 OpenShift 上的关键应用,采用这些最佳实践将显著提高可用性、韧性和持续的服务交付,满足甚至超越企业级的期望和服务级别 协议SLA)。

此外,节点大小、资源分配和调度策略等因素在提升 OpenShift 框架的性能和可靠性方面起着至关重要的作用。关于应用安全,我们强烈建议遵循以下最佳实践,以增强应用的安全防护:

  • 使用可信的基础容器镜像:优先使用官方或供应商提供的容器镜像,因为这些镜像经过严格的测试、加固和维护。如果选择社区支持的镜像,确保它们来自可靠的来源。避免使用来自未知来源的镜像,尤其是在公共注册表(如 Docker Hub)中找到的镜像,因为这些镜像可能存在安全风险。

  • 定期更新基础容器镜像:保持容器镜像的最新版本非常重要,因为它们包含了最新的安全补丁和修复。在你的 CI 管道中实现自动化流程,以便在构建过程中拉取最新的基础镜像,并在新的基础镜像更新发布时触发应用镜像的重建。

  • 区分构建镜像和运行时镜像:通过使用不同的镜像来分离构建环境和运行时环境。构建镜像应仅包含编译和构建应用所需的内容,而运行时镜像则应精简,仅包括运行应用所需的基本组件。这种方法通过减少不必要的依赖和漏洞来最小化攻击面。

  • 遵循限制性的安全上下文约束(SCC):在可能的情况下,配置容器镜像以遵守 OpenShift 的限制性 SCC。此约束执行严格的安全策略,限制潜在的安全漏洞。将应用程序调整为在限制性 SCC 下运行,可以最大化安全级别,在应用程序遭到入侵时保护集群。有关更多指导,请参考 OpenShift 关于支持任意用户 ID 的文档。

  • 确保组件间通信安全:确保应用组件间的通信是安全的,特别是当传输敏感数据时。虽然 OpenShift 的网络设计本身就是安全的,但使用传输层安全性TLS)可以增加额外的保护层。为了更简化的方案,可以考虑利用OpenShift 服务网格,它可以管理 TLS,从而减轻单个应用的负担,并提供对安全策略的集中控制。

探讨了在 OpenShift 中提升应用可用性、韧性和安全性的关键实践后,我们结束了本节内容。这些指南为保持符合企业标准的强大、安全的应用程序提供了基础。接下来的部分将深入对比分析 Kubernetes 和 Red Hat OpenShift。这一比较将揭示每个平台的独特功能和优势,帮助你理解它们在各种操作环境中的独特优势。让我们继续揭示 Kubernetes 和 Red Hat OpenShift 的异同,为容器编排策略中的明智决策奠定基础。

Kubernetes 和 Red Hat OpenShift 的比较

表 8.1 提供了 Kubernetes 和 OpenShift 之间的高级对比。Kubernetes 提供了一个灵活且广泛采用的容器编排平台,而 OpenShift 提供了一个更集成、更注重安全性的企业解决方案,具有广泛的支持和内建的功能,以提高开发者生产力和操作效率。

功能/方面 Kubernetes OpenShift
来源 Google 的开源项目 Red Hat 的企业版 Kubernetes 发行版
安装 手动,需要设置网络、存储等 通过自动化设置和配置简化
Web UI 提供基础的仪表板 提供功能全面且用户友好的控制台,具有高级功能
安全性 基本的安全功能:通常需要额外的工具 提供增强的安全性,内置身份验证和授权,SELinux 集成
CI/CD 集成 需要插件和第三方工具 内置 CI/CD 工具,如 OpenShift Pipelines 和 Source-to-Image (S2I)
网络 可插拔的 容器网络 接口 (CNI) 默认 SDN,附加网络功能
存储 支持 PersistentVolumes,需手动配置 简化的存储集成,自动化供应
开发者工具 内置工具有限 包括 OpenShift Do (odo)、S2I 和 DevSpaces 在内的广泛工具
监控 和日志记录 基本的第三方集成(例如,Prometheus) 集成的监控和日志记录堆栈
注册表 需要外部或第三方注册表 集成的容器镜像注册表
企业支持 通过第三方提供商提供 来自 Red Hat 的直接支持
社区 和支持 大型开源社区 拥有强大的开源社区和企业支持
定价 免费,但与云服务商或基础设施相关的成本 基于订阅的定价,提供多种企业使用计划

表 8.1 – Kubernetes 和 Red Hat OpenShift 功能/方面对比

在结束我们对 Kubernetes 和 Red Hat OpenShift 的对比时,我们揭示了每个平台的独特特性、优势和考虑因素。这一分析使您能够根据具体的操作需求和目标做出明智的决策。接下来,让我们将这些理解应用于进一步增强我们的部署策略和操作效率,尤其是在容器编排和云原生开发的背景下。

总结

在本章中,我们深入探索了如何在 Red Hat OpenShift 环境中利用 GitOps,强调了自动化和配置最佳实践的整合,以提升操作效率和安全性。我们首先通过使用 CRC 设置了一个本地 OpenShift 集群,为读者提供了一个沙盒环境,可以应用 GitOps 原则的实际应用。这个实践方法让容器化应用使用声明性配置和自动化工作流的部署与管理过程变得更加清晰。

我们深入探讨了各种最佳实践,从使用受信任的基础镜像、设置适当的资源限制,到实施强大的安全措施,如用于组件间通信的 TLS。每项实践都旨在加强部署过程,减少漏洞,并确保应用保持弹性和可用性。通过将 Kubernetes 与 Red Hat OpenShift 进行对比,我们提供了 OpenShift 如何扩展 Kubernetes 能力的见解,展示了为满足企业需求而增强的特性。

本章中,重点放在了实际操作示例上,确保读者不仅理解理论概念,还能有效地将其应用于自己的 OpenShift 环境中。随着我们结束讨论,这里提到的知识和策略为更安全、高效、可靠的应用部署铺平了道路,反映了云原生开发的不断变化的格局以及 GitOps 方法论日益重要的趋势。

在下一章中,我们将探索 GitOps 实践在 Azure 和 AWS 中的整合,揭示云原生部署的先进策略。

第八章:Azure 和 AWS 部署的 GitOps

在不断发展的云计算环境中,GitOps 实践的采用作为一种变革性方法,突显了简化应用程序和基础设施部署与管理的优势。本章将详细探讨如何在 Azure 和 亚马逊 Web 服务 (AWS) 这两大领先的云平台中应用 GitOps 原则。本章旨在解开利用云原生能力的复杂性,向读者全面展示如何在 GitOps 工作流中充分发挥 Azure Kubernetes 服务 (AKS)、Azure DevOps弹性 Kubernetes 服务 (EKS) 和 AWS CodePipeline 的潜力。

通过真实案例研究、专家见解和实用指导,我们将深入探讨如何设置 持续集成/持续部署 (CI/CD) 管道、管理配置,并确保在这些平台上的一致性和自动化部署。到本章结束时,读者将具备实施高效、安全、可扩展的 GitOps 工作流的知识,迈出云原生之旅的重要一步。

本章将重点关注以下几个关键领域:

  • 云 GitOps 基础知识 – Azure 和 AWS

  • 在 Azure 和 AWS 上使用 GitOps 部署

  • 在 GitOps 工作流中集成 Azure 和 AWS

  • GitOps 在云环境中的应用

  • Azure 和 AWS 部署的 Kubernetes GitOps 策略

技术要求

在深入探讨如何为 Azure 和 AWS 部署实现 GitOps 之前,必须基于本书前几章中建立的基础知识进行学习。此前讨论的 GitOps 原则、Docker 等容器化技术、Kubernetes 概念以及 CI/CD 原则,为理解本章中突出的高级应用提供了坚实的起点。此外,访问 Azure 和 AWS 账户以及对其服务的基本理解,将对跟随实际操作和案例研究至关重要。对版本控制系统的熟悉,尤其是 Git,不仅能提高理解力,还能促进有效应用我们在 Azure 和 AWS 上的云原生部署过程中详细介绍的 GitOps 实践。

本章的相关代码和资源文件可以在我们的专用 GitHub 仓库中的 Chapter09 文件夹找到:github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

Azure 和 AWS 账户

本书深入探讨了在 Azure 和 AWS 生态系统中实施 GitOps 的复杂性,全面探索了各自的工具和实践,但详细的创建 Azure 和 AWS 账户的步骤超出了本书的范围。为了开始实际应用接下来各章节中阐述的概念和示例,读者必须拥有有效的 Azure 和 AWS 账户。我们鼓励您查阅 Azure 官方文档 azure.microsoft.com/en-us/ 和 AWS 官方文档 aws.amazon.com/,以获取最新和最详细的账户设置说明。这些账户对于部署示例和应用讨论中的 GitOps 实践至关重要,是您构建和实验 Azure 和 AWS 云原生功能的基础。

在接下来的章节中,我们假设读者拥有一个有效且已正确配置的 Azure 或 AWS 账户,并具备 Azure CLIAWS CLI 或相应网页门户的基础知识。

云 GitOps 基础知识 – Azure 和 AWS

随着云计算领域的不断发展,GitOps 原则的采用已成为实现 云原生部署操作卓越性和自动化的基石。本章介绍了 Azure 和 AWS 的 GitOps 基础知识,展示了这两大云平台如何支持 GitOps 工作流的无缝集成,以提升部署速度、可靠性和可扩展性。

云原生开发与部署

云原生开发代表了一种变革性的应用构建与部署方法,充分利用了云计算模型的优势。其核心在于利用托管服务、微服务架构、容器和声明式 API 来创建具有可扩展性、韧性并且易于更新的应用。这个范式的转变鼓励组织摆脱单体架构,实现更快速的开发周期、更强的可扩展性,以及在应对市场需求时的更大灵活性。云原生技术,包括 Kubernetes、Docker 和无服务器功能,在这一生态系统中扮演着至关重要的角色,提供了开发人员构建不仅具有高可用性和容错能力,而且能够在动态的云环境中蓬勃发展的应用所需的工具。通过采用云原生实践,企业能够加速其数字化转型,提升创新和竞争能力,以应对日益数字化的世界。

Azure 和 AWS 各自提供独特的工具和服务——如 AKS、Azure DevOps、EKS 和 AWS CodePipeline——这些工具帮助团队有效实施 GitOps 实践。通过对这些基础内容的全面探索,读者将深入了解如何利用 Azure 和 AWS 的云原生能力来简化部署流程,确保基础设施和应用管理尽可能高效且无错误。这种统一的方法为理解如何在 Azure 和 AWS 这两个各具特色但互补的生态系统中最佳地应用 GitOps 提供了坚实的基础。

Azure GitOps 基础

Azure 以其丰富的生态系统和集成功能为实施 GitOps 原则提供了肥沃的土壤,增强了部署过程中的自动化、一致性和可扩展性。在 Azure 的 GitOps 能力核心中,AKS 简化了 Kubernetes 的部署、管理和操作,实现了无缝的 GitOps 工作流。结合 Azure DevOps —— 一个提供多种工具套件,包括用于 Git 托管的 Azure Repos 和用于 CI/CD 的 Azure Pipelines —— 开发者可以建立一个强大的 GitOps 流水线,确保持续集成和部署,最大限度减少人工干预。通过利用这些服务,用户可以保持对部署的高度控制和可视化,借助 GitOps 的声明性特点,高效地管理基础设施和应用。

Azure DevOps

Azure DevOps 是微软提供的一套开发工具,旨在支持完整的软件开发生命周期。在其核心,Azure DevOps 促进了 CI/CD 实践,使团队能够自动化应用程序的构建、测试和部署阶段。特别是在 GitOps 环境下,Azure DevOps 成为一个强大的盟友,允许团队在 Git 仓库中管理基础设施和应用代码,自动将更改应用于 Kubernetes 环境,并在开发、测试和生产环境中保持一致的状态。

在使用 Azure DevOps 实施 Kubernetes GitOps 部署时,以下基本步骤可以帮助你完成该过程:

  1. 设置 Git 仓库:首先在 Azure Repos 或任何其他 Git 托管服务中设置一个 Git 仓库。这个仓库将保存你的 Kubernetes 清单文件,以声明性方式表示应用和基础设施的期望状态。

  2. 创建 Azure Pipelines:利用 Azure Pipelines 来定义你的 CI/CD 工作流。对于 GitOps,CD 流水线起着至关重要的作用。它应当被配置为在仓库主分支发生更改时自动触发,主分支存放着 Kubernetes 清单文件。

  3. 定义环境:在 Azure DevOps 中,定义环境来表示你的部署目标,例如开发、预发布和生产环境。这些环境可以与由 AKS 管理的 Kubernetes 集群或任何 Kubernetes 集群相关联。

  4. 使用 Helm 或 Kustomize 自动化部署:使用 Helm charts 或 Kustomize 来管理复杂的 Kubernetes 应用程序。可以配置 Azure Pipelines 来使用 Helm 或 Kustomize 打包和部署应用程序,遵循 GitOps 声明式配置的原则。

  5. kubectl、Helm 或 GitOps 工具,如 Flux 或 Argo CD。此步骤涉及从你的 Git 仓库中获取最新配置,并将其应用到指定环境中,确保实际状态与 Git 中声明的期望状态相匹配。

  6. 监控与回滚:最后,利用 Azure Monitor 和其他可观察性工具来监控你的部署。如果出现任何问题,你的 GitOps 工作流应支持通过简单地还原 Git 仓库中的更改并重新运行流水线来恢复先前的状态,从而实现轻松回滚。

Kubernetes 部署与 Azure DevOps

在本节中,我们将进行实践操作,使用 Terraform、Azure 容器注册表ACR)和 Azure DevOps 流水线的强大组合,在 Azure 上部署 Kubernetes 集群。我们将从创建一个简单的 AKS 集群和 ACR 开始,然后在它们之间建立一个系统托管身份,以便进行安全的交互。我们的旅程高潮将涉及通过精心构建的 Azure DevOps 流水线,将这个镜像部署到 AKS 集群中。本实践教程旨在展示这些组件的无缝集成,说明它们如何汇聚以简化 GitOps 框架中的部署过程。通过这个示例,读者将全面了解如何使用 Azure 强大的生态系统将应用程序部署到 Kubernetes。以下是成功完成此示例所需的步骤。

在实际场景中,执行 Terraform 脚本需要创建一个具有适当权限的Azure 服务主体来配置资源。然而,在这个示例中,我们通过使用一个具有完全权限的 Azure 管理员帐户来简化这一过程。需要注意的是,由于安全问题,这种方法不推荐用于生产环境。通过在新终端窗口中输入以下命令登录 Azure:

$ az login

要初始化 Terraform,我们使用 terraform init 命令。在此步骤中,我们将使用位于 GitHub 仓库 iac/azure 文件夹中的 main.tfversions.tf Terraform 文件,这些文件与本章内容一同提供。

为什么选择 Terraform?

Terraform 是一种首选的基础设施即代码IaC)工具,因为它使用声明性配置语言,通过指定基础设施的期望最终状态,简化了复杂环境的定义和管理。它支持多个云提供商,包括 AWS、Azure 和 Google Cloud,使得不同平台间能够一致地实践 IaC。此外,Terraform 的状态管理功能能够跟踪当前的基础设施状态,允许它高效地规划和应用更改,同时最小化错误。其广泛的模块生态系统和强大的社区支持,进一步增强了它在大规模自动化和管理基础设施方面的能力。

main.tf 文件负责编排 Kubernetes 基于的部署所需的 Azure 服务的设置。首先,它在switzerlandnorth区域建立一个名为aks-k8s-deployments-rg的资源组,作为所有相关 Azure 资源的容器。接下来,在同一资源组和区域中,提供了一个名为aksgitops3003204acr的 ACR,随后创建了一个名为aksgitopsclusterAKS集群,集群配置了一个默认的节点池,资源最小化以确保成本效率。该集群配置了系统分配的身份,从而简化了 Azure 服务之间的身份验证过程。

最后,Terraform 配置确保 AKS 集群与 ACR 之间的集成,通过分配必要的角色权限,实现了从注册表到 Kubernetes 环境的无缝容器镜像拉取。你可以自由修改资源组或 ACR 的名称,以及资源部署的区域。在终端窗口中执行以下命令。整个过程将需要几分钟才能完成:

$ terraform init
$ terraform plan -out aksplan
$ terraform apply -auto-approve aksplan

等待资源成功配置,然后整合 kubectl 配置以进行集群管理:

$ az aks get-credentials --resource-group aks-k8s-deployments-rg --name aksgitopscluster

以下是创建一个新的 Azure DevOps 项目并正确设置 Azure DevOps 管道的必要步骤:

  1. 在现有的 Azure 账户中建立一个新的 Azure DevOps 项目,如图 9.1所示,用于管理 CI/CD 管道和项目工件,选择gitops-k8s-deployment,并可选择添加项目描述。将可见性设置为私有,然后点击创建按钮。

图 9.1 – 创建新项目的 Azure DevOps 窗口

图 9.1 – 创建新项目的 Azure DevOps 窗口

  1. 你的代码在哪里?窗口中,选择 GitHub 选项旁的选择,以选择你希望与之前创建的 Azure DevOps 项目关联的 GitHub 仓库。你可以直接使用本章关联的 GitHub 仓库,或者选择你创建的一个仓库,如图 9.2所示。

图 9.2 – 选择仓库面板

图 9.2 – 选择仓库面板

  1. 在此阶段,我们已准备好配置流水线。在配置面板中,选择部署到 Azure Kubernetes 服务,如图 9.3所示。

图 9.3 – 配置向导中的流水线部分

图 9.3 – 配置向导中的流水线部分

  1. 按提示操作,如图 9.4所示,选择之前使用 Terraform 脚本配置和部署的 Azure 订阅。

图 9.4 – 弹出窗口,选择 Azure 订阅

图 9.4 – 弹出窗口,选择 Azure 订阅

  1. weather-app-namespace 中。

图 9.5 – 部署到 AKS 设置窗口

图 9.5 – 部署到 AKS 设置窗口

  1. 点击 src 子目录,我们需要编辑以下代码的最后一行:

    variables:
    # Container registry service connection …
    dockerfilePath: '**/Dockerfile'
    

    我们按照如下方式编辑前面的代码:

    dockerfilePath: '**/src/dockerfile'
    
  2. 然后,点击保存并运行按钮,保持默认值不变,再次点击保存并运行按钮。流水线将按照图 9.6所示触发。

图 9.6 – 触发的 Azure DevOps 流水线示例

图 9.6 – 触发的 Azure DevOps 流水线示例

  1. 点击构建阶段以查看更多详细信息,如图 9.7所示。这一次,无需在本地构建镜像并将其推送到注册表,因为所有操作都由 Azure DevOps 流水线处理。

图 9.7 – 构建并推送镜像到容器注册表的详细信息

图 9.7 – 构建并推送镜像到容器注册表的详细信息

如果需要,授权流水线的权限,如图 9.8所示。

图 9.8 – 弹出窗口,授予当前及后续流水线运行的权限

图 9.8 – 弹出窗口,授予当前及后续流水线运行的权限

  1. 此时,几秒钟后,流水线应该成功完成,如图 9.9所示。一封邮件将发送到您的账户,通知您流水线成功完成。

图 9.9 – 流水线成功完成

图 9.9 – 流水线成功完成

  1. 为了验证部署,您可以使用 Visual Studio Code 等工具,或者在终端执行以下命令:

    $ kubectl get pods --namespace weather-app-namespace
    

    输出应如下所示:

    NAME                 READY   STATUS    RESTARTS   AGE
    myweathera…        1/1     Running   0          7m50s
    

    在此时,我们可以执行一个 port-forward 命令,将应用显示在浏览器中,如图 9.10所示。

图 9.10 – 运行在 AKS 上的容器中的 weather-app 截图

图 9.10 – 运行在 AKS 上的容器中的 weather-app 截图

  1. 现在,为了探索 Azure DevOps 的 CI/CD 功能,你可以编辑data.csv文件,将2023-01-04这一天的值从4.0改为例如5.0(参见图 9.11)。这个文件可以直接在你的 GitHub 仓库中编辑,或者通过克隆仓库到本地并使用 Git 进行编辑。

图 9.11 – 用作天气应用程序数据源的更新后的 data.csv 文件

图 9.11 – 用作天气应用程序数据源的更新后的 data.csv 文件

在此阶段,一旦再次触发,管道将自动执行,如图 9.12所示。

图 9.12 – 推送更新后的 data.csv 文件后的新执行管道

图 9.12 – 推送更新后的 data.csv 文件后的新执行管道

  1. 通过执行一个新的port-forward命令,目标是刚刚部署的新 pod,我们将有机会可视化更新后的图表(参见图 9.13)。

图 9.13 – 新部署后天气应用程序,触发条件为推送更新后的 data.csv 文件

图 9.13 – 新部署后的天气应用程序,触发条件为推送更新后的 data.csv 文件

  1. 为了避免产生不必要的费用,请记得通过输入以下命令(或使用 Azure 门户)销毁为本示例创建的所有 Azure 资源:

    $ terraform destroy --auto-approve
    

恭喜!你已经成功完成了 Azure DevOps CI/CD 管道,并将部署到 AKS,使用了 ACR 实例。现在,是时候转向 AWS 生态系统,探索那一侧的操作方式了。

AWS GitOps 基础知识

AWS 通过提供一套服务来支持 GitOps 模型,旨在以高效可靠的方式促进云原生应用程序和基础设施的管理。EKS 作为 AWS 的托管 Kubernetes 服务,相较于其他主要云服务提供商的产品,如 Google Cloud 的Google Kubernetes EngineGKE)和 Microsoft Azure 的 AKS,具有独特的功能。尽管它们提供类似的功能,但每个系统都针对其各自的生态系统进行了定制,优化了部署过程,并确保容器化应用程序的自动扩展和管理。将 EKS 与 AWS CodePipeline 集成,这是一个自动化构建、测试和部署发布过程的服务,可以实现 GitOps 方法,将整个基础设施视为代码。这种集成使团队能够实施 CD 实践,从而实现快速且安全的应用程序更新。AWS 对 GitOps 的承诺体现在其工具和服务中,这些工具支持不可变基础设施、自动化部署和详细监控,符合 GitOps 的声明式配置和版本控制原则。

AWS CodePipeline

AWS CodePipeline (https://aws.amazon.com/codepipeline/) 是一个完全托管的 CI/CD 服务,自动化了发布过程中的构建、测试和部署阶段。它允许您创建管道,自动化发布软件变更所需的步骤。通过 CodePipeline,您可以将发布过程定义为一系列阶段,每个阶段执行特定操作,如从版本控制系统获取源代码、构建和测试应用程序,以及将其部署到您的基础设施。

AWS CodePipeline 的一个关键特点是其灵活性和与其他 AWS 服务的集成。您可以轻松将 CodePipeline 与 AWS CodeBuild(用于构建应用程序)、AWS CodeDeploy(将其部署到 EC2 实例或 AWS Lambda 函数)、以及 AWS Elastic Beanstalk(用于部署和管理 Web 应用程序)等服务集成。

CodePipeline 还支持通过自定义操作与第三方工具和服务集成,允许您扩展其功能以满足您的特定需求。此外,它通过基于 Web 的控制台提供发布过程的可视化,您可以通过该控制台监控管道进度并排查出现的问题。以下是使用 AWS CodePipeline 实现 Kubernetes GitOps 部署的步骤:

  1. 设置 AWS CodePipeline:首先设置 AWS CodePipeline,它负责协调 Kubernetes 部署的 CI/CD 工作流。

  2. 连接到 GitHub 仓库:在 CodePipeline 配置中,连接到存储 Kubernetes 清单和部署脚本的 GitHub 仓库。

  3. 配置源阶段:在 CodePipeline 配置中定义源阶段,指定从中拉取 Kubernetes 清单的 GitHub 仓库和分支。

  4. 添加构建阶段:在 CodePipeline 配置中创建一个构建阶段,执行 Kubernetes 部署所需的构建步骤,例如编译代码或打包工件。

  5. 与 EKS 集成:将 EKS 纳入 CodePipeline 工作流。这可能涉及设置 AWS 服务和 CodePipeline 之间的连接或权限。

  6. 实施 GitOps 原则:确保您的 CI/CD 管道遵循 GitOps 原则,例如将所有配置和部署清单存储在版本控制中,自动化部署流程,并使用基于拉取的同步方式进行集群更新。

  7. 定义部署策略:定义 Kubernetes 应用程序的部署策略,指定如滚动策略、扩展选项和健康检查等参数。

  8. 触发部署:配置 AWS CodePipeline,使其在每次推送更改到 GitHub 仓库时自动触发部署,保持 Kubernetes 应用程序的持续部署。

  9. 监控和调试:实现监控和日志记录机制,以跟踪 Kubernetes 部署的性能和健康状况。确保您有工具来调试和排查部署过程中可能出现的任何问题。

  10. 迭代和改进:持续迭代您的 CI/CD 流水线,结合反馈并进行改进,以提高 Kubernetes 部署的效率、可靠性和安全性。

总结来说,AWS CodePipeline 精简了发布过程,帮助团队更快速、更可靠地交付软件更改。通过自动化部署流水线,CodePipeline 加速了市场投放时间,并提升了整体生产力,使组织能够迅速响应客户需求和市场变化。

AWS CodePipeline 下的 Kubernetes 部署

在本节中,我们将进行一次动手实践,通过 Terraform、EKS 和 AWS CodePipeline 部署 Kubernetes 集群。我们将从配置一个 EKS 集群和一个 Amazon Elastic Container RegistryECR)开始。我们旅程的亮点是使用 AWS CodePipeline 将此镜像部署到 EKS 集群中。就像在 Azure DevOps 下的 Kubernetes 部署 部分对 Azure 所做的那样,本实践示范展示了这些组件的无缝集成,展示了它们如何在 GitOps 框架中简化部署过程。通过这个示例,读者将全面理解如何利用 AWS 强大的服务将应用程序部署到 Kubernetes 上。

在以下演示示例中,我们假设读者已拥有有效的 AWS 账户,并已安装并配置 AWS CLI 版本 2。请参考以下 AWS 链接以供参考:

以下是成功完成本示例所需的步骤:

  1. 通过输入以下命令,确保 AWS CLI 配置正确:

    terraform init command. For this step, we will utilize the main.tf Terraform files located in the iac/aws folder of the GitHub repository accompanying this chapter.This `main.tf` Terraform configuration file orchestrates the setup of essential AWS infrastructure components for deploying a Kubernetes cluster and managing container images. It begins by defining the AWS provider and version required for the deployment. Following this, it creates an ECR repository named `eksgitops3003204ecr` to store Docker images with mutable tag mutability. Next, the configuration provisions a `terraform-aws-modules/vpc/aws` module. This VPC, named `eks-cluster-vpc`, spans across two availability zones in the `eu-central-1` AWS region. Subsequently, the configuration sets up an EKS cluster utilizing the `terraform-aws-modules/eks/aws` module. The cluster, named `eksgitopscluster`, operates on version 1.29 and allows public access to its endpoint. It’s integrated with the previously created VPC and utilizes private subnets for enhanced security.Additionally, the configuration establishes a managed node group within the EKS cluster, configured with one instance of the `t3.small` type. This node group provides the computing resources necessary for running containerized applications within the Kubernetes environment. To facilitate seamless interaction between the EKS cluster and the ECR repository, an `ecr-pull-policy` is created. This policy grants EKS nodes the permissions required to pull container images from the specified ECR repository.Finally, the IAM policy is attached to the IAM role associated with the EKS cluster, ensuring that the cluster nodes have the necessary permissions to retrieve container images for deployment.
    

IAM 策略

IAM 策略是一个定义权限的文档,用于管理对 AWS 资源的访问。IAM 策略授予用户、组或角色特定的权限,决定他们可以在哪些资源上执行什么操作。这些策略由包含以下内容的声明组成:Effect(允许或拒绝)、Action(允许或拒绝的具体操作)、Resource(操作应用的特定资源)。IAM 策略有助于确保 AWS 环境中的安全和精细化访问控制,使管理员能够通过只授予实体执行任务所需的权限来贯彻最小权限原则。

  1. 输入以下命令以启动集群创建:

    $ terraform init
    $ terraform plan -out aksplan
    $ terraform apply -auto-approve aksplan
    

    整个过程大约需要 10 分钟才能完成。图 9.14 显示了 AWS 控制台中的 EKS 集群,而 图 9.15 显示了创建的 ECR 注册表。

图 9.14 – 执行 Terraform 脚本后的 EKS 集群

图 9.14 – 执行 Terraform 脚本后的 EKS 集群

图 9.15 – 执行 Terraform 脚本后的 ECR 注册表

图 9.15 – 执行 Terraform 脚本后的 ECR 注册表

  1. 集成 kubectl 配置以进行集群管理:

    $ aws eks --region eu-central-1 update-kubeconfig --name eksgitopscluster
    
  2. 输入以下命令测试访问:

    $ kubectl cluster-info
    

    输出应如下所示:

    Kubernetes control plane is running at https://54CE9D2FAC3008E8E5B3D4873E92E7B2.yl4.eu-central-1.eks.amazonaws.com
    CoreDNS is running at https://54CE9D2FAC3008E8E5B3D4873E92E7B2.yl4.eu-central-1.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    

如果在合并集群管理后遇到身份验证问题或其他常规问题,您需要为 EKS 集群添加一个访问条目。这包括向为 AWS CLI 配置的用户添加以下权限,如本节开头所述:

  1. 在 AWS 控制台中,导航到 eksgitopscluster 并点击创建访问条目按钮,如图 9.16所示:

图 9.16 – EKS 集群页面及创建新访问条目的“访问”标签

图 9.16 – EKS 集群页面及创建新访问条目的“访问”标签

  1. IAM 主体 ARN 字段中,您需要选择已用于配置 AWS CLI 并执行 AWS CLI 命令的 IAM ARN,如图 9.17所示:

图 9.17 – AWS CLI 配置的 IAM 主体 ARN 选择

图 9.17 – AWS CLI 配置的 IAM 主体 ARN 选择

  1. 然后,点击页面底部的 下一步 按钮,并为本示例添加以下所有策略名称(参见图 9.18),选择 Cluster 作为选定的 访问范围

图 9.18 – 为新 IAM 主体附加权限的访问策略部分

图 9.18 – 为新 IAM 主体附加权限的访问策略部分

  1. 点击 下一步 按钮,然后点击 创建。现在,您应该可以使用 AWS CLI 管理集群,而不会遇到任何问题。更多信息,请参阅官方文档:https://docs.aws.amazon.com/eks/latest/userguide/access-entries.html#updating-access-entries。

  2. 在创建 AWS CodePipeline 实例之前,我们首先需要创建一个 GitOpsCodeBuildRole。该角色将允许管道在将新代码提交到仓库时为我们的 weather-app 应用程序构建新镜像,推送该镜像到创建的 ECR,并将其部署到 EKS。在 AWS 控制台中,导航到 IAM |角色,然后点击 创建角色 按钮,如图 9.19所示。

图 9.19 – AWS 管理控制台中的角色页面,您可以在此开始创建新 IAM 角色

图 9.19 – 在 AWS 管理控制台中的角色页面,您可以开始创建新的 IAM 角色

IAM 角色

在 AWS 中,IAM 角色是一组权限,用于定义可以对 AWS 资源执行哪些操作。角色用于在 AWS 内部将访问权限委托给用户、应用程序或服务,使它们能够与各种 AWS 服务安全地交互。角色通过策略定义,这些策略指定了允许或拒绝的操作,并且角色由 AWS 服务、IAM 用户或 AWS 资源等实体来承担。这种方法确保了安全的访问控制,并有助于执行最小权限原则,即用户和服务仅获得执行其任务所需的权限。

  1. 选择受信实体 部分,选择 AWS 服务,在 用例 面板中选择 CodeBuild,如 图 9.20 所示。

图 9.20 – 创建角色页面上的受信实体类型和用例部分

图 9.20 – 创建角色页面上的受信实体类型和用例部分

  1. AmazonEC2ContainerRegistryFullAccess

  2. AmazonS3FullAccess

  3. AWSCodeBuildAdminAccess

  4. AWSCodeCommitFullAccess

  5. CloudWatchLogsFullAccess

然后,添加以下 内联策略

{
     "Version": "2012-10-17",
     "Statement": [
          {
               "Effect": "Allow",
               "Action": "eks:Describe*",
               "Resource": "*"
          }
     ]
}

内联策略

内联策略是一组可以直接附加到 IAM 用户、组或角色的权限。与托管策略不同,后者是独立的实体,内联策略是直接嵌入到它们所控制的资源中的。这允许在更具体的层次上进行更细粒度的权限控制和管理。内联策略通常用于仅将某些权限应用于特定用户、组或角色,而不是在多个实体之间共享。

在审核和创建新的 IAM 角色之前,确保添加指定的信任关系以控制谁可以承担该角色,从而增强安全性和合规性。此设置可防止未经授权的访问,并确保只有指定的实体才能访问某些 AWS 资源:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codebuild.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

完成过程后,点击 创建 按钮。现在,我们已经准备好创建 AWS CodePipeline 实例。

  1. 遵循类似于 Azure DevOps 的方法,参考本章中的 Kubernetes 部署与 Azure DevOps 部分;现在是时候使用 AWS CodePipeline 自动化将应用程序部署到 AWS EKS 了。

    要正确设置 CodePipeline,请导航到 AWS 控制台,进入 weather-app-pipeline

  2. 管道 类型: V2

  3. 执行 模式: 排队中

  4. 服务角色: 新建 服务角色

然后,点击 下一步 按钮。

图 9.21 – 新的 AWS CodePipeline 的初始配置

图 9.21 – 新的 AWS CodePipeline 的初始配置

  1. GitHub (版本 2) 中选择 main。对于 CodePipeline 选择默认设置。最后,点击 下一步 按钮。

图 9.22 – 与 GitHub 仓库源的连接

图 9.22 – 与 GitHub 存储库源的连接

  1. 添加构建阶段中,选择AWS CodeBuild作为构建提供者(参见图 9.23)。选择之前已部署 EKS 和 ECR 资源的相同区域,然后点击创建项目

图 9.23 – 与选择构建提供者和区域相关的构建面板部分

图 9.23 – 与选择构建提供者和区域相关的构建面板部分

  1. weather-app-build 作为项目名称,保持其他所有值为默认,除了 arn:aws:iam::[AWS_ACCOUNT_ID]:role/GitOpsCodeBuildRole

图 9.24 – 与选择服务角色和角色相关的构建面板部分

图 9.24 – 与选择服务角色和角色相关的构建面板部分

  1. buildspec.yaml 文件中。然后,点击 ECR_REPOSITORY_URI[AWS_ACCOUNT_ID].dkr.ecr.eu-central-1.amazonaws.com

  2. IMAGE_AND_TAGweather-app:latest

图 9.25 – 与添加环境变量相关的构建面板部分

图 9.25 – 与添加环境变量相关的构建面板部分

  1. 对于构建类型,选择单一构建。点击下一步按钮。在添加部署阶段步骤中,点击跳过部署阶段按钮,然后点击下一步。在最后阶段检查流水线并点击创建流水线按钮。此时,CodePipeline 将触发并在一分钟内成功完成(见图 9.26)。

图 9.26 – 定义后的 weather-app-pipeline

图 9.26 – 定义后的 weather-app-pipeline

  1. 在流水线执行结束时,我们可以验证 weather-app 的 Docker 镜像已正确构建并推送到 ECR,如图 9.27所示。

图 9.27 – weather-app:latest 镜像成功推送到 ECR

图 9.27 – weather-app:latest 镜像成功推送到 ECR

  1. 为了验证部署是否成功完成,执行以下命令:

    $ kubectl get deployments
    

    这里是输出:

    NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
    my-city-weather-app   1/1     1            1           64m
    
  2. 在这一点上,我们可以执行 port-forward 命令,在浏览器中显示应用,如图 9.28所示。

图 9.28 – 部署后在浏览器中呈现的 weather-app

图 9.28 – 部署后在浏览器中呈现的 weather-app

  1. 尝试编辑数据源文件,按照Kubernetes 部署与 Azure DevOps部分的步骤 11进行操作。在推送更改后,weather-pipeline 将立即触发,如图 9.29所示。执行新的 port-forward 命令以查看更新后的图表版本。

图 9.29 – 推送更新后的 data.csv 文件后立即触发的流水线

图 9.29 – 推送更新后的 data.csv 文件后,管道立即触发

为了避免产生不必要的费用,请记得在完成示例后,通过执行适当的命令或使用 AWS 管理控制台删除为此示例创建的所有 AWS 资源。

恭喜!在这一阶段,你已经成功地通过 Azure DevOps 在 Azure 上部署了天气应用,并通过 CodePipeline 在 AWS 上部署了应用。接下来,让我们在下一节深入探讨云环境中的 GitOps 应用。

云环境中的 GitOps 应用

GitOps 的出现极大地革新了云环境的管理和部署方式,将版本控制和协作的原则嵌入到云原生应用的操作框架中。GitOps 应用不仅仅是自动化部署,它涵盖了云资源和服务的整个生命周期,包括资源配置、扩展、更新和退役,这一切都通过 Git 拉取请求进行管理。该方法论促进了一个透明、可审计、且易于回滚的过程,提高了云应用的安全性和合规性。此外,GitOps 实践确保了云环境的期望状态被声明性地定义并维护,促进了不同开发和生产阶段的一致性和可靠性。这种系统化方法最小化了环境间的差异,显著减少了在我机器上能运行的问题,并简化了向生产环境的过渡。

跨云策略

在今天的多云格局中,组织通常利用 Azure、AWS 和其他云提供商的独特优势来优化其操作和成本。管理跨这些多样化环境的部署可能会面临挑战,特别是在保持一致性和效率方面。GitOps 提供了一种统一的策略来管理这些部署,促进了跨云的互操作性和配置管理。以下是采用 GitOps 跨云部署的好处列表:

  • 统一的配置管理:通过将基础设施定义和配置作为代码存储在 Git 仓库中,团队可以使用相同的 GitOps 工作流来管理 Azure、AWS 和其他云平台的部署。这使得控制集中化,并确保了云环境的一致性。

  • 互操作性和可移植性:利用容器化和 Kubernetes,应用程序可以设计为无缝地跨不同的云平台运行。结合这些技术的 GitOps 实践,简化了部署和管理这些应用程序的过程,无论基础云平台如何。

  • 自动同步:像 Argo CD 或 Flux 这样的工具可以用来自动同步 Git 仓库中的期望状态与各个云环境中的实际状态。这确保了所有环境遵循相同的配置和策略,从而在跨云操作中实现顺畅一致的工作流程。

  • 环境一致性:GitOps 使团队能够在不同的云平台间以高精度复制环境。这对于测试尤其有用,在 Azure 上部署的应用可以在 AWS 上以类似的条件进行测试,从而确保应用在不同平台上的行为一致。

  • 机密管理:在跨云环境中,管理机密和敏感信息可能具有挑战性。GitOps 工作流可以与云平台特定的机密管理服务(如 Azure Key Vault 或 AWS Secrets Manager)集成,既能安全处理机密,又能保持跨云部署的灵活性。

采用 GitOps 方法进行跨云策略,不仅简化了多云环境固有的复杂性,还提高了操作效率、安全性和合规性。通过将基础设施和应用配置视为代码,团队能够迅速适应变化,确保部署始终与组织目标和行业最佳实践保持一致。在下一节中,我们将介绍在 Azure 和 AWS 上为 Kubernetes 部署应采用哪些 GitOps 策略。

Azure 和 AWS 上的 Kubernetes 部署的 GitOps 策略

在 Kubernetes 部署领域,GitOps 策略提供了一种向更高效、透明和可靠的操作方式转变的模式。通过利用 GitOps 原则,组织可以自动化部署过程,确保环境一致性,并显著提升操作工作流。以下是针对 Azure 和 AWS 上的 Kubernetes 部署量身定制的 GitOps 策略见解。

Azure GitOps 策略

采用 GitOps 策略管理 AKS 涉及将源代码控制、CI/CD 管道和配置管理集成的详细方法,以增强部署过程。一项关键策略是使用 ARM 模板或 Terraform 等工具部署基础设施即代码(IaC),这些工具存储在 Git 仓库中。这种方法使 AKS 配置的声明性管理成为可能。第十章第十一章将提供关于如何在 Azure 上使用 Terraform 自动化 IaC 的全面示例。这些自动化流程促进了自动化和可重复的部署,从而提高了应用的稳定性和可扩展性。

将 Azure Policy 与 GitOps 配合使用,进一步加强了 Kubernetes 集群的合规性和治理,确保部署符合组织和监管标准。将 Azure Monitor 与 GitOps 工作流集成,使团队能够将可观察性作为其操作的核心组成部分,进行主动监控和排除 AKS 部署的故障。

AWS GitOps 策略

AWS 提供了一个强大的生态系统,用于实施 GitOps 与 EKS。AWS GitOps 策略的基础在于利用 Amazon ECR 作为 Docker 容器注册表,AWS CodeCommit 作为源代码管理工具,AWS CodePipeline 用于持续集成和部署。与 Azure 类似,AWS 提倡使用基础设施即代码(IaC),AWS CloudFormation 或 Terraform 是首选工具,用于声明式管理 EKS 集群配置和资源。

在 AWS 上,执行有效的 GitOps 策略包括将 AWS CodeBuild 和 AWS CodeDeploy 集成到 CI/CD 管道中,从 Git 仓库直接自动化构建、测试和部署阶段。此外,AWS App Mesh 服务可以集成到 GitOps 工作流中,更有效地管理微服务,提供跨应用的端到端可见性和网络流量控制。

对于 Azure 和 AWS,实施 GitOps 进行 Kubernetes 部署围绕着四个关键原则:版本控制、自动化部署、通过合并/拉取请求进行变更管理,以及可观察性。通过遵循这些原则,组织能够实现自动化、可预测和安全的应用部署,规模化管理 Kubernetes 集群。利用 GitOps 不仅简化了 Kubernetes 集群管理,还将操作实践与开发工作流对齐,促进了协作与持续改进的文化。

总结

到目前为止,我们已经深入理解了如何在 Azure 和 AWS 云环境中有效地实施 GitOps。本章介绍了必要的工具和流程,例如 AKS、Azure DevOps、AWS EKS 和 AWS CodePipeline,用于建立强大的 CI/CD 管道并无缝管理部署。通过实际示例和专家建议,本章确保读者能够将这些概念应用于实现更自动化、一致性和安全的云原生部署。强调了 Git、Docker 和 Kubernetes 的基础知识的重要性,本章为读者准备了充分利用 GitOps 在云计算项目中发挥最大潜力的准备。在下一章中,我们将探讨 GitOps 与 Terraform 和 Flux 的集成,重点讨论基础设施方面。我们将涵盖将基础设施作为代码与实时操作对齐的关键步骤,使用 Terraform 进行资源配置,使用 Flux 实现 CD。讨论还将重点介绍这一过程中最佳实践和常见挑战。

第九章:GitOps 与基础设施自动化 – Terraform 和 Flux CD

本章将探讨 Terraform 和 Flux CD 之间强大的协同效应,这两个关键工具体现了 GitOps 和基础设施即代码IaC)的原则。随着云架构日益复杂和动态化,需要先进的自动化工具来管理这些环境变得尤为关键。Terraform 允许用户使用高级配置语言定义和提供云基础设施,创建一个可版本化和重用的资源蓝图。与之互补,Flux CD 通过持续同步 Git 仓库中的应用程序和基础设施变更到 Kubernetes 集群来实现自动化部署。这种集成不仅简化了云资源的管理,还确保了部署流水线各个阶段的一致性和可靠性。通过详细的讨论、实用的示例和专家见解,本章将帮助你掌握 Terraform 和 Flux CD 的组合力量,让你能够在云原生世界中高效、可预测地自动化你的基础设施。

本章我们将深入探讨以下关键内容:

  • 使用 Terraform 和 Flux CD 引入基础设施自动化

  • 在 GitOps 工作流中设置 Terraform

  • 探索 Flux CD – 在 Kubernetes 中启用持续部署CD

  • 结合 Terraform 和 Flux CD 实现更强的自动化

  • 使用 Terraform 和 Flux CD 进行版本控制和自动化

  • 使用 Terraform 和 Flux CD 进行多环境管理

技术要求

在深入了解 Terraform 和 Flux CD 在 GitOps 工作流中的集成之前,务必牢固掌握本书前几章中讨论的基础概念。理解 IaC 的基本原理、Kubernetes 的关键概念,以及我们专门的 GitHub 仓库中的Chapter10文件夹:github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

使用 Terraform 和 Flux CD 引入基础设施自动化

在当今快速发展的云计算环境中,管理基础设施时对敏捷性、可扩展性和可靠性的需求至关重要。传统的手动方法已不足以满足现代应用的需求。此时,IaC 和 GitOps 应运而生,重新定义了云原生环境下的基础设施管理。对于平台工程师来说,手动工作仍然至关重要,例如理解云资源以编写有效的 Terraform 脚本,通常也是更新 Terraform Git 仓库之前的第一步。通过利用 GitOps 框架,解决云原生交付中面临的挑战,比如防止配置漂移,确保安全、无误的部署。在 Kubernetes 上实施 GitOps 会带来一些挑战,包括管理复杂配置和保持 Git 仓库与集群之间的同步。IaC 是一种将基础设施供应、配置和管理视为代码的方法。从本质上讲,它使开发人员和运维团队能够使用声明式或命令式代码来定义基础设施资源,如虚拟机VMs)、网络和存储。我们在上一章已经探讨了 IaC 的概念,当时我们利用 Terraform 脚本在 Azure 和 AWS 上配置了必要的资源。

这段代码是版本控制的,可以实现可复现、一致和自动化的部署。通过将基础设施配置编码化,基础设施即代码(IaC)简化了部署过程,减少了人为错误,并增强了开发和运维团队之间的协作。

GitOps 则将 IaC 的原则扩展到持续交付和部署领域。基础设施的变化通过 Git 提交进行,实现了版本控制、审计和协作。GitOps 提倡一种声明式的基础设施管理方法,其中存储在 Git 仓库中的期望状态配置会自动与基础设施的实际状态进行协调。这一协调过程通常由 Flux CD 等专门的工具来完成。

在前面介绍的 IaC 和 GitOps 的基础原则之上,我们来考虑一个实际的示例,如图 10.1所示,展示了公司如何利用 Terraform 和 Flux CD 来高效地管理基础设施。

假设有一家公司需要在多个云环境中快速扩展其业务,同时保持严格的合规性和安全标准。通过使用 Terraform,公司可以将基础设施要求编码为版本控制的配置文件,这样可以在 AWS、Azure 或 Google Cloud 等环境中快速部署和轻松复制环境。通过将 Flux CD 集成到这一设置中,对 Git 仓库中 Terraform 配置的任何更改都会自动触发 Kubernetes 集群中的更新。这种无缝集成确保基础设施与应用程序代码一致发展,减少了差异和潜在错误。结果是一个强大、可扩展且符合合规要求的基础设施,能够迅速适应业务需求的变化,同时最大限度地减少手动监督和干预:

图 10.1 – 利用 Terraform 和 Flux CD 进行高效基础设施管理的公司示例

图 10.1 – 利用 Terraform 和 Flux CD 进行高效基础设施管理的公司示例

在现代云环境中,敏捷性和可扩展性至关重要,采用基础设施即代码(IaC)和 GitOps 提供了诸多优势。首先,它使组织能够实现基础设施自动化,快速进行资源的配置、扩展和修改。其次,它增强了不同环境间的可复制性和一致性,减少了配置漂移的风险,确保了可靠性。第三,它促进了协作和可见性,因为基础设施配置被存储并在可访问的 Git 仓库中进行版本控制。最后,它提升了弹性和可观察性,自动化的协调机制确保基础设施保持在期望的状态。我们将在本章的后续部分深入探讨 IaC 和 GitOps 的主题,并通过实际示例进行说明。

现在,是时候开始配置我们的环境了。

在 GitOps 工作流中设置 Terraform

在建立了 IaC 和 GitOps 的基础概念后,我们现在理解了 Terraform 和 Flux CD 的集成如何改变基础设施管理。在这一坚实的基础上,我们将引导您配置 Terraform,使其与 Flux CD 无缝配合,为符合现代云原生实践的、连贯且自动化的基础设施部署过程打下基础。Terraform 在第四章中介绍并简要讨论,并在第九章中进一步探讨了与使用 Azure DevOps 和 AWS CodePipeline 进行 Kubernetes 部署的相关内容。在本章的剩余部分,我们假设读者已经对 Terraform 有了扎实的理解,并且它已在本地正确安装。有关 Terraform 是什么以及如何安装的更多信息,请访问以下链接:developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli。要检查 Terraform 是否正确安装,请在新的终端中键入以下命令:

$ terraform version

前面命令的输出应该类似于以下内容:

Terraform v1.7.5

在我们设置 Terraform 与 GitOps 工作流的示例中,我们将使用 Flux 来监视包含 Terraform 脚本的 Git 存储库中的更改。然后,Flux 将应用这些更改来管理 Azure 云资源,具体目标是指定的资源组、虚拟网络和子网。

要成功实施此设置,您必须满足以下先决条件:

  • 在本地安装了minikube。另外,您也可以选择托管的集群环境,如Azure Kubernetes ServiceAKS)或Amazon Elastic Kubernetes ServiceEKS)。

  • Helm 和 kubectl:确保这两个工具已正确安装并配置。

  • GitHub 账户:虽然本示例使用 GitHub,但 Flux 引导支持其他存储库。有关更多详细信息,请参阅 Flux 文档:fluxcd.io/flux/installation/#bootstrap-providers

  • GitHub 个人访问令牌(PAT):这对于私有存储库或需要身份验证的操作是必需的。有关 PAT 的更多信息,请访问docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens

  • 一个 Azure 账户:您也可以根据个人喜好使用 Azure 账户(请注意,本节及后续部分中的示例专门为 Azure 设计)。

在深入讨论工作流的设置之前,下一节将讨论 Tofu Controller 是什么,以及它为何是对账过程的引擎和核心。

Tofu Controller(前身为 Weave TF-Controller)

Tofu Controller(请参考 https://github.com/flux-iac/tofu-controller),前身为 Weave TF-Controller,是 Flux 生态系统中的关键元素,使得 OpenTofu 和 Terraform 资源能够以 GitOps 方式进行协调。

OpenTofu

OpenTofu,前身为 OpenTF,是一个由 Linux 基金会管理的开源社区驱动的 Terraform 分支。OpenTofu 旨在增强云原生环境中 IaC 的管理,能够与现有的 GitOps 工作流无缝集成,使用户能够使用如 Terraform 等工具以声明式方式管理基础设施。OpenTofu 和 Terraform 都使用声明式的 HashiCorp 配置语言HCL)语法来配置基础设施,但在许可上有所不同:Terraform 目前采用 商业源代码许可证BSL),而 OpenTofu 采用开源的 Mozilla 公共许可证MPL)。OpenTofu 的主要目标是弥补复杂基础设施设置与现代云环境所需的可扩展、自动化管理能力之间的差距。通过利用 OpenTofu,组织可以高效地将 GitOps 原则应用于其基础设施,确保一致性、可靠性以及快速部署云资源。

使用 Tofu Controller,组织可以根据其操作需求和准备情况,按适合的节奏采用 GitOps 实践——这意味着不需要立即将所有资源都转化为 GitOps。

强调灵活性和节奏的 按自己节奏 方法,Tofu Controller 允许逐步采用 GitOps。这种灵活性对于那些可能希望逐渐转型的组织至关重要,无需进行大规模的立即转型。它使团队能够更加舒适地管理变更和适应,确保每个向 GitOps 迈进的步骤都能经过充分规划和实施。

Tofu Controller 支持多种 GitOps 模式,每种模式都针对基础设施管理的不同需求和阶段:

  • GitOps 自动化模型:该模型提供了一种全面的 GitOps 方法,涵盖了从配置到执行的各个方面。例如,它可以通过 GitOps 管理整个 AKS/EKS 集群的生命周期,自动化许多底层过程。

  • 混合 GitOps 自动化模型:适用于已有资源的环境,该模型允许选择性地采用 GitOps。例如,如果一个组织已经有 AKS/EKS 集群,它可以选择在只集成某些组件(如节点组或安全组)时使用 GitOps,同时保持现有配置。

  • TFSTATE),使用 GitOps 原则强制执行期望状态,而不做额外修改,并纠正任何偏差,以保持一致性和可靠性。

  • TFSTATE 文件,并允许组织主动处理和管理这些变更。

对于当前示例以及接下来的部分,我们将使用之前提到的 GitOps 自动化 模式。

开始设置

现在我们已经介绍了主要主题并概述了必要的要求,我们已经进入了工作流设置的实际操作部分。要完成设置的第一部分,我们需要完成以下编号步骤:

  1. minikube 集群专门用于 Flux 设置,在新的终端中,输入以下命令:

    $ minikube start --profile flux-cluster
    

    几分钟后,输出应如下所示:

    😄  [flux-cluster] minikube v1.33.0 on Ubuntu 22.04 (amd64)
    ✨  Automatically selected the docker driver
    📌  Using Docker driver with root privileges
    👍  Starting "flux-cluster" primary control-plane node in "flux-cluster" cluster
    …
    🌟  Enabled addons: storage-provisioner, default-storageclass
    🏄  Done! kubectl is now configured to use "flux-cluster" cluster and "default" namespace by default
    

    这表示您的集群已经准备好使用。

  2. 安装 Flux CLI

    1. 设置 Flux CLI,请输入以下命令:
    gitops-terraform-workflow, but feel free to create a repository according to your preferences. We will use a private repository for this setup. To create a GitHub account, please refer to the *GitHub account* section in *Chapter 3* of this book. After creating the GitHub repository, clone it locally to your laptop. For the Git commands, please refer to the *Basics of Git* section in *Chapter 3* of this book.
    
  3. flux bootstrap GitHub 命令会在 Kubernetes 集群上安装 Flux 控制器,使其能够与 GitHub 仓库同步。此设置涉及将 Flux 清单提交到仓库,并配置 Flux 从 Git 自行更新。执行后,所有集群操作,包括 Flux 更新,都可以通过 git push 管理,免去了直接与集群交互的需求。为了与 GitHub API 进行交互,该命令需要一个具有管理权限的 GitHub PAT,可以将其设置为环境变量:

$ export GITHUB_TOKEN=[GITHUB_PAT_TOKEN]
  1. 现在,您可以通过输入以下命令,在您个人的 GitHub 账户上运行仓库的引导程序:
    flux bootstrap github \
      --token-auth \
      --owner=[GITHUB_ACCOUNT] \
      --repository=gitops-terraform-workflow \
      --branch=main \
      --path=clusters/local \
      --personal

执行命令应当需要几分钟时间,成功输出应该如下所示:

► connecting to github.com
► cloning branch "main" from Git repository "https://github.com/pietrolibro/gitops-terraform-workflow.git"
…
► confirming components are healthy
✔ helm-controller: deployment ready
✔ kustomize-controller: deployment ready
✔ notification-controller: deployment ready
✔ source-controller: deployment ready
✔ all components are healthy
  1. 通过运行以下 kubectl 命令,您应该会注意到已经创建了一个 flux-system 命名空间:
$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   26m
flux-system       Active   3m30s
kube-node-lease   Active   26m
kube-public       Active   26m
kube-system       Active   26m
  • 安装 TF-Controller:现在,我们准备安装之前提到的 TF-Controller:

    1. 输入以下命令:
    $ kubectl apply -f https://raw.githubusercontent.com/flux-iac/tofu-controller/main/docs/release.yaml
    
    1. 现在,我们准备安装之前提到的 Tofu Controller。输入以下命令:
    helmrepository.source.toolkit.fluxcd.io/tf-controller created
    helmrelease.helm.toolkit.fluxcd.io/tf-controller created
    
    • Contributor 角色。为此,请键入以下命令:
    subscriptionId="$(az account list --query "[?name=='AZURE_SUBSCRIPTION_NAME'].id" --output tsv)"
    az account set --subscription=$subscriptionId
    az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/$subscriptionId" --name gitops-terraform-sp
    

    输出包含了敏感凭据,您必须保护这些凭据。确保不要将这些凭据包含在您的代码中或将其检查到源代码管理系统中。有关管理 Azure SP 的更多信息,请访问 aka.ms/azadsp-cli

    {
      "appId": "application-id",
      "displayName": "gitops-terraform-sp",
      "password": "generated-password",
      "tenant": "tenant-uid"
    }
    

    这些值对应于 Terraform 变量,具体如下:appId 作为 client_id 变量,password 用作 client_secret 变量,tenant 是之前定义的 tenant_id 变量。

    • github-repository-secret.yaml 文件位于本章仓库的定义文件夹中。文件内容如下:
apiVersion: v1
kind: Secret
metadata:
  name: github-repository-secret
  namespace: flux-system
type: Opaque
data:
  username: <github_accountname-base64>
  password: <github_pat-base64>
  1. 用户名和密码需要进行 base64 编码。要使用命令行进行编码,您可以使用以下命令:echo -n 'your-string' | base64。编码后,按照常规方式使用 kubectl 应用该秘密:
$ kubectl apply -f github-repository-secret.yaml
  1. 现在,我们需要为之前创建的 SP 的 Azure 凭据创建一个 Kubernetes 秘密。使用以下命令来完成此操作:
$ kubectl create secret generic azure-creds \
    --from-literal=ARM_SUBSCRIPTION_ID='SP_SUB_ID' \
    --from-literal=ARM_TENANT_ID='SP_TENANT_ID' \
    --from-literal=ARM_CLIENT_ID='SP_APPID' \
    --from-literal=ARM_CLIENT_SECRET='SP_PASSWORD' \
    --namespace flux-system
  1. 要验证秘密的创建,请使用以下命令:
$ kubectl get secrets -n flux-system
NAME       TYPE                       DATA   AGE
azure-creds               Opaque      4      16s
flux-system               Opaque      2      34m
github-repository-secret  Opaque      2      25s
…

Kubernetes 秘密

Kubernetes Secret 是 Kubernetes 中的一种资源,用于存储少量敏感数据,如密码、令牌或密钥。这些数据以 base64 编码格式存储,可以被 pods 用来处理需要机密性和安全性的操作,帮助防止敏感信息在应用程序代码或日志中暴露。Kubernetes Secrets 中的 opaque 一词指的是默认的 Secret 类型。当不需要指定 Secret 的具体类型(如服务账户令牌或 Docker 配置)时,会使用此类型。实质上,opaque 表示 Secret 的内容是任意的,并未按任何特定类型的机密数据进行结构化表示。

  1. 现在,我们需要通过位于定义文件夹中的 github-repository-definition.yaml 文件(在本章随附的仓库中的 flux-gitops-definitions 文件夹)将 GitHub 仓库与 GitHub 仓库 Secret 关联。使用常规命令应用它:

    $ kubectl apply -f github-repository-definition.yaml
    gitrepository.source.toolkit.fluxcd.io/gitops-terraform-repository created
    
  2. TF-Controller 的 Docker 镜像:现在,我们需要创建一个自定义的 Docker 镜像来运行 TF-Controller。Dockerfile 定义包含在 Docker 目录中。有关 Docker 命令,请参阅 第二章 中的 发布镜像到容器仓库 部分。要构建自定义 Docker 镜像,请使用以下命令:

    $ docker build -f ./Docker/dockerfile -t pietrolibro/gitops-terraform:tf_az_cli_1_1 .
    
  3. 然后,您需要将其发布到 Kubernetes 集群可以访问的仓库中。登录 Docker 后,使用以下命令推送该镜像:

    main.tf in the iac/azure/vnet subfolder of the repository accompanying this chapter.  The Terraform script provisions a set of network resources in Microsoft Azure. It configures the Azure provider and defines a resource group named gitops-terraform-rg in the Switzerland North region, serving as a container for related Azure resources. The script also establishes a virtual network called gitops-terraform-vnet within this resource group, with an address space of 10.0.0.0/16. Additionally, it creates a default subnet within this virtual network, allocated with an address range of 10.0.0.0/24. This setup structures the Azure cloud infrastructure effectively, facilitating the management and scalability of network components within the specified region.
    

此时,我们可以将代码提交并推送到 GitHub 仓库,结束我们在 GitOps 工作流中设置 Terraform 的第一部分。接下来的一部分,我们将在接下来的章节中描述,重点是使用 Flux 在 Kubernetes 中启用 CD。

探索 Flux CD – 在 Kubernetes 中启用 CD

Flux CD 根据推送到 Git 仓库的更改,自动将配置和更新应用到 Kubernetes 集群。这种方法不仅确保了各环境之间的一致性,还通过维护所有部署的清晰版本控制历史,提高了安全性和可审计性。Flux 持续监控指定的 Git 仓库,检查 Kubernetes 清单、Helm 图表或配置文件的更改。当检测到更改时,Flux 会自动将这些更新应用到相应的 Kubernetes 集群中。这种自动化是全面的,不仅适用于应用程序,还适用于 Kubernetes 基础设施本身,使得整个环境能够像代码一样进行管理。

Flux CD 的主要功能包括以下几点:

  • 自动同步:Flux 定期检查 Git 仓库的更改,并相应地同步集群的状态。

  • 不可变部署:通过将基础设施视为不可变,Flux 遏制了人工干预,并促进了可重复性。

  • 安全性与合规性:更改从 Git 中拉取,确保仅部署批准的更改,从而增强了安全性和合规性。

现在是时候回到我们在上一部分暂停的旅程了。我们需要配置 Flux 实例,以跟踪 Git 仓库中相应的目录或分支。此时,Terraform Controller 的强大之处便显现出来——它为你完成了所有繁重的工作。

我们需要创建一个 YAML 文件(参考本章中仓库中定义的azvnet-gitops-automation.yaml文件),如下所示:

apiVersion: infra.contrib.fluxcd.io/v1alpha2
kind: Terraform
metadata:
  name: gitops-terraform-automation
  namespace: flux-system
spec:
  interval: 1m
  approvePlan: auto
  destroyResourcesOnDeletion: true
  path: ./iac/azure/vnet
  sourceRef:
…
  runnerPodTemplate:
    spec:
      env:
        - name: ARM_SUBSCRIPTION_ID
          valueFrom:
            secretKeyRef:
              name: azure-creds
              key: ARM_SUBSCRIPTION_ID
        …

这个 YAML 文件定义了一个Terraform资源,供 Flux CD 框架内使用,专门设计用于自动管理 IaC(基础设施即代码)部署。配置详细说明了 API 版本,并指定资源类型为Terraform,这表明它在通过 Flux 管理和应用 Terraform 配置中的作用。

该资源命名为gitops-terraform-automation,位于flux-system命名空间中,该命名空间通常用于 Flux CD 操作。规格包括 1 分钟的间隔设置,指示 Flux 检查 Git 仓库中指定目录的变更频率。它被配置为自动批准并应用更改(approvePlan: auto),并且如果此 Terraform 配置从 Kubernetes 中删除,则销毁所有受管理的资源(destroyResourcesOnDeletion: true)。./iac/azure/vnet路径指定了 Git 仓库中 Terraform 配置的位置,Flux 将监控该路径。

sourceRef实例指向名为flux-system的 Git 仓库,标识出 Flux 应当监控的具体仓库。此设置使 Flux 能够自动管理更新,并保持仓库中指定的环境。

runnerPodTemplate部分配置了执行 Terraform 命令的 Pod 的环境变量,以确保能够安全访问 Azure 服务。ARM_SUBSCRIPTION_IDARM_CLIENT_IDARM_CLIENT_SECRETARM_TENANT_ID等变量对于 Azure 的交互至关重要,它们从一个名为azure-creds的 Kubernetes 机密中安全提取。这确保了敏感凭证得到了安全管理,并且只对必要的进程可用。

通过利用此配置,Flux CD 自动化部署和管理在仓库中指定路径的 Terraform 配置所定义的 Azure 虚拟网络。自动化包括监控更改、应用更新,并确保环境保持与仓库中声明的状态一致。此设置体现了 GitOps 的原则,通过使用 Git 作为单一****真实来源SSOT),并自动化 Git 中定义的期望状态与 Azure 中基础设施的实际状态之间的对账过程。

要实现这一魔法并使配置生效,我们需要使用kubectl来应用它:

$ kubectl apply -f ./definitions/azvnet-gitops-automation.yaml
kubectl command to query the status of resources managed by Flux. Here’s how to check the reconciliation process:

$ kubectl get terraforms.infra.contrib.fluxcd.io -n flux-system  -w


			This command displays the current status of the Terraform configuration:

名称    就绪   状态                      时间

gitops-ter… 未知  对账进行中   9 秒

gitops-ter… 未知   初始化中   15 秒

gitops-ter… 未知   Terraform 计划中   22 秒

gitops-ter… 未知   计划已生成   30 秒

gitops-ter… 未知   应用中   30 秒

gitops-ter… 未知   应用中   30 秒

gitops-ter… 未知   应用成功:main@sha1:2eeaefba687fbd3d4caea404fc332ee7c5d8b144   43 秒

gitops-ter… True   应用成功:main@sha1:2eeaefba687fbd3d4caea404fc332ee7c5d8b144   44 秒


			As indicated by the output of the previous command, the Terraform script has been successfully applied at a certain point. For further confirmation, we can open the Azure portal and visually inspect the provisioned infrastructure, as illustrated in *Figure 10**.2*:
			![Figure 10.2 – Azure resources provisioned by Terraform and GitOps](https://github.com/OpenDocCN/freelearn-devops-pt6-zh/raw/master/docs/impl-gop-k8s/img/B22100_10_02.jpg)

			Figure 10.2 – Azure resources provisioned by Terraform and GitOps
			Fantastic work! You have successfully integrated IaC using Terraform along with GitOps principles through Flux CD. By adopting this approach, you have laid a robust foundation for managing your cloud resources in a way that promotes consistency, reduces errors, and streamlines operations.
			Combining Terraform and Flux CD for enhanced automation
			Combining Terraform and Flux CD for enhanced automation offers significant advantages in managing cloud infrastructure efficiently and resiliently. Here’s how this integration can be advantageous in various practical scenarios.
			Providing new infrastructure by updating Terraform files
			One of the standout benefits of integrating Terraform with Flux CD is the simplicity with which new infrastructure components can be added. For example, suppose you need to add a new subnet to an existing Azure virtual network. By merely updating the Terraform file to include the new subnet definition and committing this change to your repository, Flux CD automatically detects the update and applies it. This seamless process eliminates the need for manual intervention in the cloud environment, thereby reducing the potential for human error and accelerating deployment times. Automation ensures that infrastructure adjustments, such as scaling out to accommodate growth, are handled promptly and accurately.
			We can immediately test this aspect by updating the `main.tf` file presented in *step 8* of the *Setting up Terraform in a GitOps workflow* section. Append the following code block to the end of the file:

资源 "azurerm_subnet" "azure_bastion_subnet" {

名称                   = «AzureBastionSubnet"

resource_group_name = azurerm_resource_group.gitops_terraform_rg.name

virtual_network_name = azurerm_virtual_network.gitops_terraform_vnet.name

address_prefixes     = [«10.0.1.0/26"]

}


			This Terraform code block creates a subnet named `AzureBastionSubnet` within a specified Azure virtual network and resource group. It assigns the subnet an IP address range of `10.0.1.0/26`. The subnet resource is identified within Terraform as `azure_bastion_subnet`, and it references the names of both the virtual network and resource group from other resources defined in the Terraform configuration.
			At this point, simply commit and push the code to trigger a reconciliation loop. You will then see the process in action, as illustrated next:

gitops-ter…   未知   对账进行中   3 小时 12 分钟

gitops-ter…   未知   初始化中   3 小时 12 分钟

gitops-ter…   未知   Terraform 计划中   3 小时 12 分钟

gitops-ter…   未知   计划已生成   3 小时 12 分钟

gitops-ter…   未知   应用中   3 小时 12 分钟

gitops-ter…   未知   应用成功:main@sha1:a3b32ed48dda027b0c5e40a65c7be56e1cc7dd50   3 小时 13 分钟

gitops-ter…   True   应用成功:main@sha1:a3b32ed48dda027b0c5e40a65c7be56e1cc7dd50   3 小时 13 分钟


			Open the Azure portal to visually verify the results, as illustrated in *Figure 10**.3*:
			![Figure 10.3 – After the reconciliation process, the gitops-terraform-vnet virtual network in the Azure portal contains two subnets](https://github.com/OpenDocCN/freelearn-devops-pt6-zh/raw/master/docs/impl-gop-k8s/img/B22100_10_03.jpg)

			Figure 10.3 – After the reconciliation process, the gitops-terraform-vnet virtual network in the Azure portal contains two subnets
			Enhanced disaster recovery capabilities
			In the event of a disaster, the combination of Terraform and Flux CD significantly enhances recovery capabilities. Terraform’s ability to describe the complete IaC means that entire environments can be replicated swiftly and accurately. Flux CD plays a crucial role by continuously ensuring that the state of the cloud environment matches the configurations defined in your Git repository. If a disaster strikes, you can quickly redeploy your infrastructure to a known good state as defined in the repository, drastically reducing downtime and the complexity often associated with recovery processes.
			Creating and managing multi-stage environments
			When managing complex deployments that involve multiple stages, such as development, staging, and production, the division of the repository becomes essential. With Terraform and Flux CD, you can split your repository appropriately to manage these environments separately yet consistently. Each environment can have its configuration files and Terraform plans, which Flux CD can manage independently. This setup not only keeps your deployments organized but also enforces consistency and isolation between environments. Changes can be tested in development or staging environments through automated pipelines and only promoted to production once verified, ensuring stability and reliability in your production deployments.
			As seen so far, this strategic integration of Terraform and Flux CD not only streamlines the operational aspects of cloud infrastructure management but also enhances strategic capabilities such as quick scaling, robust **disaster recovery** (**DR**), and effective multi-environment handling. With Flux CD, updates and changes are applied systematically and predictably, reducing the likelihood of human error and the overhead associated with manual deployments.
			In the next section, we will explore how Terraform and Flux CD utilize version control and automation to enhance infrastructure management, ensuring transparency, collaboration, and security throughout the deployment process.
			Version control and automation with Terraform and Flux CD
			Terraform uses version control to manage the state of your infrastructure, which allows for tracking changes, auditing, and collaborating on infrastructure development. By storing Terraform configurations in version-controlled repositories, teams can review changes through pull requests, maintain a history of configurations, and revert to previous states when necessary. This process enhances transparency and collaboration among team members, fostering a more controlled and secure environment for deploying infrastructure.
			Security and best practices with Terraform and Flux CD
			When combining Terraform with Flux CD, security is significantly enhanced by the inherent design of GitOps and the nature of declarative infrastructure management. All changes to the infrastructure are committed to version control, which means every change is auditable and traceable.
			To enhance security further, we can deploy the following:

				*   **Access control**: Implement strict access controls on your Git repositories. Use branch protection rules to ensure that changes are reviewed and approved before they are merged, preventing unauthorized modifications to your infrastructure.
				*   **Secrets management**: Never store secrets directly in your Git repositories. Instead, leverage Kubernetes Secrets or integrate with a secrets management tool such as HashiCorp Vault or Azure Key Vault. Flux CD can securely pull secrets and inject them into the deployment pipeline.
				*   **Automated compliance scans**: Integrate compliance scanning tools into your CI/CD pipeline to automatically check Terraform plans for compliance with security policies and best practices before they are applied.

			Best practices for configuration and maintenance
			Here are some best practices for configuration and maintenance:

				*   **Immutability**: Treat infrastructure as immutable. Rebuild infrastructure from scratch frequently to ensure that the actual state aligns with the state defined in Terraform configurations.
				*   **Code review and pair programming**: Enforce code reviews for all infrastructure changes. Pair programming can also be used for critical changes, involving more than one set of eyes before changes go live.
				*   **CI**: Integrate CI processes to test infrastructure changes automatically. This includes testing Terraform plans and applying them to a non-production environment before they affect your production infrastructure.

			Best practices for managing multi-environment configurations
			Managing multiple environments (dev, staging, production) effectively requires a well-organized repository structure.
			Here are some best practices:

				*   **Environment branching**: Maintains a single repository, but uses different branches for each environment, merging changes from development branches to production branches through a controlled process.
				*   **Parameterization**: Use variables and outputs to customize Terraform configurations for different environments. Avoid hardcoding values directly into Terraform files.
				*   **Environment parity**: Keep your development, staging, and production environments as similar as possible. This reduces the chances of encountering unexpected behaviors in production that weren’t evident in dev or staging. The optimal approach to managing multi-environment configurations hinges on several factors, such as organization size, project complexity, regulatory demands, and the balancing act between security and operational efficiency. For organizations in highly regulated industries, such as finance or healthcare, where security is paramount, using separate repositories for each environment might be advisable to enhance security by isolating production settings from development and testing environments. This method limits access to sensitive configurations and minimizes the risk of inadvertent changes. Alternatively, if rapid development and deployment are critical, a single repository with separate directories for each environment can simplify the management of changes across environments, though it necessitates strict access controls and vigilant monitoring to protect production configurations. For those seeking a balance between security and simplicity, a hybrid approach could be suitable, involving a single repository for all non-sensitive environments and a separate one for production. Regardless of the chosen strategy, implementing robust version control practices, clear access controls, and automated deployment pipelines will be essential to maintain efficiency and safeguard the integrity of environments.

			Git workflow strategies
			To effectively manage your infrastructure and streamline your development workflow, it’s essential to adopt best practices that align with your team’s dynamics and project requirements. Consider the following strategies:

				*   **Trunk-based development versus Git Flow**: Choose a Git workflow that suits your team’s needs. Trunk-based development encourages shorter-lived branches and might be more suitable for fast-paced environments, while Git Flow can provide more control through designated branches for features, releases, and hotfixes.
				*   **Automated testing and promotion**: Use automated testing to validate changes in lower environments. Only promote changes to the next environment once they pass all tests. Automate this promotion using Flux CD, which can monitor different branches or folders and apply changes to the respective environments.

			Now that we have a comprehensive understanding of Terraform, GitOps, and Flux, along with best practices, we can combine all these elements in a practical example. This example will focus on managing a multi-environment setup, which we will describe in the next section.
			Multi-environment management with Terraform and Flux CD
			In the final section of this book, you’ll explore a detailed application of the concepts we’ve discussed, using a Kubernetes cluster (`minikube`) to manage a multi-environment setup with Flux CD for IaC. This real-world example will demonstrate how to effectively deploy separate environments for `dev`), `staging`), and `prod`). *Figure 10**.4* illustrates the described example:
			![Figure 10.4 – Example of multi-environment management with Terraform and Flux CD](https://github.com/OpenDocCN/freelearn-devops-pt6-zh/raw/master/docs/impl-gop-k8s/img/B22100_10_04.jpg)

			Figure 10.4 – Example of multi-environment management with Terraform and Flux CD
			GitHub will serve as the VCS, and the directory hierarchy will be organized as follows:

|---clusters/mgmt

|---flux-gitops-definitions

|---multi-env

|---iac

|---azure

|---base

|---dev

|---staging

|---prod


			In this structure, we have the following:

				*   `clusters/mgmt`: Contains the Flux configuration files installed by the bootstrap for the management cluster (`minikube`, running locally).
				*   `multi-env/iac/azure`: Contains subdirectories for the different environments (`dev`, `staging`, and `prod`), each intended for managing infrastructure specific to that environment using Terraform scripts.
				*   `Base`: Contains the main Terraform files (`main.tf` and `variables.tf`), which define the Azure resources (such as AKS, virtual network, **Azure Container Registry** (**ACR**), and so on) from an infrastructure perspective. These files are copied into the corresponding environment subfolder as needed to tailor the infrastructure setup for each specific environment.

			The `flux-gitops-definitions` directory contains various manifest YAML files essential for configuring the GitHub repository and secret. This setup involves the following:

				*   **GitHub repository configuration**: YAML files in this directory help link the Flux installation with the GitHub repository, specifying where Flux should listen for updates and which branch to monitor.
				*   **Secrets management**: Includes the setup for Kubernetes secrets that store sensitive information, such as GitHub access tokens or cloud provider credentials. These secrets ensure that Flux can securely access the repository and interact with other services as needed.
				*   **Resource definitions**: Manifests that define how resources should be applied, rolled out, and managed across different environments.

			For the following example, we will continue using the same GitHub repository as before (although you are welcome to create a new one if you prefer). Additionally, we will initiate a new `minikube` cluster:

				1.  To do this, start by opening a new terminal window and enter the following command:

    ```

    GITHUB_TOKEN。这可以通过在终端中输入以下命令来完成:

    ```
    GITHUB_TOKEN is set, you can proceed to install Flux on your cluster using the bootstrap command. Execute the following in your terminal:

    ```

    flux bootstrap github \

    --token-auth \

    --context=mgmt-cluster \

    --owner=[GITHUB_ACCOUNT] \

    --repository=[GITHUB_REPOSITORY] \

    --branch=develop \

    --path=clusters/mgmt \

    --personal

    ```

    Once the command has finished executing, you should see an output similar to the following:

    ```

    ► 正在连接到 github.com

    ► 从 Git 仓库 "https://github.com/..." 克隆分支 "develop"

    ✔ 已克隆仓库

    ► 正在生成组件清单

    …

    ✔ kustomize-controller: 部署就绪

    ✔ notification-controller: 部署就绪

    ✔ source-controller: 部署就绪

    ✔ 所有组件正常

    ```

    ```

    ```

    				2.  Now that Flux is successfully bootstrapped, the next step is to install the TF-Controller. Here’s how to proceed:

    ```

    flux-system 命名空间或为其指定的特定命名空间:

    ```
    $ kubectl get pods -n flux-system
    NAME                      READY   STATUS    RESTARTS  AGE
    helm-controller…          1/1     Running   0         4m47s
    kustomize-contr…            1/1     Running   0         4m47s
    notification-co…          1/1     Running   0         4m47s
    Running state.
    ```

    ```

    				3.  Since we are using a new `minikube` cluster (or alternative cluster) and our goal is to provision resources on Azure, we need to create the corresponding secret:

    ```

    $ kubectl create secret generic azure-creds \

    --from-literal=ARM_SUBSCRIPTION_ID='SP_SUB_ID' \

    --from-literal=ARM_TENANT_ID='SP_TENANT_ID' \

    --from-literal=ARM_CLIENT_ID='SP_APPID' \

    --from-literal=ARM_CLIENT_SECRET='SP_PASSWORD' \

    每个环境特定子目录(dev、staging、prod)中的 main.tf 文件,位于 multi-env/iac/azure 主目录内。以下是如何为每个环境结构化 main.tf 文件:

    ```
    provider "azurerm" {
      features {}
    }
    ```

    ```

    				4.  Now, change your working directory to where `flux-gitops-definitions` is located. This directory should contain your YAML files for the GitHub repository configuration (`github-repository-definition.yaml`) and the secret (`github-repository-secret.yaml`). First, apply the *GitHub repository secret*, which contains the credentials that Flux CD will use to access your GitHub repository:

    ```

    $ kubectl apply -f github-repository-secret.yaml

    ```

    				5.  Next, apply the *GitHub repository definition*. This  definition will link your Kubernetes setup with the GitHub repository, setting the groundwork for Flux CD to monitor changes and manage resources according to GitOps principles:

    ```

    $ kubectl apply -f github-repository-definition.yaml

    ```

    				6.  Before continuing, it’s important to commit and push the changes we’ve made so far. Then, we need to apply the automation configurations for each environment by executing the following commands:

    ```

    $ kubectl apply -f dev-iac-automation.yaml

    $ kubectl apply -f staging-iac-automation.yaml

    $ kubectl apply -f prod-iac-automation.yaml

    ```

    				7.  Afterward, check the reconciling process to ensure that the configurations are being applied correctly:

    ```

    $ kubectl get terraforms.infra.contrib.fluxcd.io -n flux-system  -w

    NAME                          准备就绪   状态                                                            年龄

    dev-cluster-tf-automation       True    没有漂移: develop@sha1:c93...   3m48s

    prod-cluster-tf-automation      True    没有漂移: develop@sha1:c93...   3m31s

    staging-cluster-tf-automation   True    没有漂移: develop@sha1:c93...   3m37s

    dev-cluster-tf-automation       未知   正在进行协调                                                          3m48s

    staging-cluster-tf-automation   未知   正在进行协调                                                          3m38s

    prod-cluster-tf-automation      未知   正在进行协调                                                          3m33s

    ```

    				8.  At this point, the reconciliation process is in progress, but no resources will be provisioned because the `main.tf` file in each directory does not define any resources. To address this, copy the `main.tf` and `variables.tf` files from the `base` directory to each subdirectory corresponding to the specific environments. Then, for each environment, open the `variables.tf` file and update it according to the needs of the `dev`, `staging`, and `prod` environments:

    ```

    variable "environment" {

    …

    default     = "dev"

    }

    variable "location" {

    …

    }

    variable "rg" {

    …

    default     = «gitops-dev-rg"

    }

    ```

    				9.  Now, it’s time to commit and push the updated code to your Git repository. After doing so, you can observe the reconciliation process to see how Flux CD responds to the changes:

    ```

    $ kubectl get terraforms.infra.contrib.fluxcd.io -n flux-system  -w

    ```

    This procedure provides real-time feedback on how Flux CD manages and applies updates from your Git repository. The reconciliation process may take some time to fully provision the resources defined in the Terraform scripts. The results are illustrated in *Figure 10**.5*:

			![Figure 10.5 – Resources provisioned by the GitOps automation reconciliation process](https://github.com/OpenDocCN/freelearn-devops-pt6-zh/raw/master/docs/impl-gop-k8s/img/B22100_10_05.jpg)

			Figure 10.5 – Resources provisioned by the GitOps automation reconciliation process
			Well done! Now, you can try making changes to the infrastructure code in one of the environments and see how the GitOps automation updates and syncs the infrastructure with your repository. What we’ve explored is just a glimpse of using GitOps for managing multi-environment setups. We haven’t covered using pull requests or installing applications yet—these topics will be addressed in the next chapter.
			Summary
			In this chapter, we explored the dynamic synergy between Terraform and Flux CD, showcasing how these tools bolster infrastructure automation using GitOps and IaC principles. The chapter introduced Terraform for defining and provisioning cloud infrastructure, alongside Flux CD, which automates the deployment process by continuously syncing changes from Git repositories to Kubernetes clusters. It thoroughly covered the fundamentals of integrating Terraform within a GitOps workflow, ensuring seamless management and scaling of cloud resources. Special attention was given to best practices for maintaining multiple environments such as development, QA, and staging, emphasizing the importance of environment-specific configurations to maintain consistency, reduce errors, and streamline operations across various cloud setups. Practical examples throughout the chapter demonstrated how to utilize these tools to effectively manage complex deployments, with a strong focus on the critical roles of version control and automated reconciliation.
			Building on the foundational concepts and best practices discussed, the next chapter will delve deeper into practical applications and real-world scenarios, showcasing how these strategies can be effectively implemented to optimize cloud infrastructure management.

第十章:在 Kubernetes 上使用 GitOps 部署真实世界项目

本章将带你进行一次实践之旅,弥合理论知识与实际应用之间的鸿沟。在深入了解设置基于 GitOps 和 Kubernetes 的开发环境的复杂过程时,你将亲身体验在这一创新框架下设计、开发和部署应用程序的过程。本章通过对架构设计、持续集成和持续交付CI/CD)流程、应用程序扩展性和安全性的详细指导,旨在帮助你掌握实现这些前沿技术所需的基本技能和见解,帮助你在项目中有效地应用它们。无论你是希望提升组织能力,还是提升个人技术水平,这里提供的全面真实案例将成为任何有志于在实际环境中掌握 GitOps 和 Kubernetes 的人的宝贵资源。

本章将重点关注以下几个关键领域:

  • 建立 GitOps 和 Kubernetes 开发环境

  • 使用 GitOps 实现 CI/CD

  • 为扩展性和效率设计

  • 资源管理和扩展性

  • 监控和保护你的应用程序

技术要求

本章基于你在前面章节中学到的 Git、Kubernetes 以及 GitOps 工具(如Argo CD和 Flux CD)的知识。我们将使用一个通过 GitHub 工作流使用 Terraform 部署的Azure AKS集群。确保你能够访问 Kubernetes 环境,并且熟悉 CI/CD 原则,以便充分利用本章的练习。

所有必要的代码和资源都已提供在我们的专用 GitHub 仓库的第十一章文件夹中:

github.com/PacktPublishing/Implementing-GitOps-with-Kubernetes

建立 GitOps 和 Kubernetes 开发环境

建立一个合适的开发环境对于成功实施 GitOps 实践至关重要。这个环境作为开发和运维团队的支柱,使应用程序能够无缝集成和持续交付。一个配置良好的开发环境确保所有应用程序和基础设施的变更都经过版本控制、可追溯,并与存储在 Git 中的声明性配置对齐。这种开发环境与生产环境之间的一致性减少了错误和部署失败的可能性,从而促进了更加可靠和健壮的交付管道。通过强调从一开始就正确设置的重要性,团队可以充分发挥 GitOps 的潜力,确保自动化过程有效且高效地管理部署和基础设施。

安装和配置 Kubernetes 以支持 GitOps 涉及以一种与 GitOps 工具(如 Flux CD(参见第四章中的Flux 与 Kubernetes 集成部分))或 Argo CD(参见第四章中的Argo CD 与 Kubernetes 集成部分))无缝集成的方式来配置 Kubernetes 集群。接下来是一个逐步指南,涵盖了设置过程,确保你的 Kubernetes 环境为 GitOps 工作流做好准备:

  1. 安装一个 Kubernetes 集群并选择你的环境。对于学习和开发,考虑使用K3s(参见第二章中的探索 K3s 作为轻量级 Kubernetes 发行版部分)或minikube。这两者都适合在本地机器上运行 Kubernetes。对于生产环境或更具可扩展性的环境,考虑使用云解决方案,如Amazon EKS、Azure AKS 或 Google GKE。要安装 minikube,请参考官方的 minikube 安装指南:minikube.sigs.k8s.io。对于在云平台上部署 Kubernetes,请参阅各云提供商提供的具体设置指南。在本章描述的实际场景中,我们将使用 AKS 集群。

  2. 验证安装。确保已安装并配置了 kubectl,Kubernetes 的命令行工具,确保它可以与集群通信。你可以通过运行以下命令来验证:

    $ kubectl cluster-info
    

    此命令应返回集群的详细信息,确认 Kubernetes 已正常运行:

    Kubernetes control plane is running at https://127.0.0.1:32769
    CoreDNS is running at https://127.0.0.1:32769/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
    
  3. 设置你的命名空间。建议为你的 GitOps 工具创建一个专用的命名空间:

    $ kubectl create namespace gitops
    
  4. 设置权限。设置基于角色的访问控制RBAC)规则,以确保你的 GitOps 工具具有管理资源所需的权限。大多数 GitOps 工具在其安装指南中都列出了具体的 RBAC 配置。我们将在本章的为用户和角色管理配置 Kubernetes RBAC部分看到如何设置 RBAC 的具体示例。

  5. 安装你的 GitOps 工具。根据你的偏好,从 Flux CD、Argo CD、Helm 或 Kustomize 等工具中选择。每个工具都有独特的优点和支持的社区。有关上述 GitOps 工具的更多详细信息,请参阅第四章中的流行 GitOps 工具概览部分。此外,你还可以探索本章中关于深入了解 Helm 和 KustomizeArgo CD 与 Kubernetes 集成Flux CD 与 Kubernetes 集成的部分。

  6. 设置 Git 仓库。配置 GitOps 工具以跟踪存储 Kubernetes 清单的 Git 仓库。有关指导,请参阅 第四章 中的 使用 Azure DevOps 部署 Kubernetes使用 AWS CodePipeline 部署 Kubernetes 部分。此设置过程包括将工具指向您的仓库,并指定要监控更改的分支和路径。

  7. 验证和测试。首先,使用您的 GitOps 工具部署一个简单的应用程序,以确认 Git 仓库中的更改会自动触发 Kubernetes 集群中的部署。通过 GitOps 工具的仪表板或 CLI 监控部署,确保应用程序已按预期部署并运行。通过修改 Git 仓库中的应用程序清单并观察更改是否自动应用,测试更新和回滚。

大部分流水线的要点在前几章中已有详细介绍。它们将在下一部分重新提及,我们将看到如何实现一个真实世界的 CI/CD GitOps 场景。

使用 GitOps 实现 CI/CD

为了实现一个真实世界的 CI/CD GitOps 场景,我们需要一个不再使用模拟数据而是使用具体数据的应用程序。

在本节中,我们将为天气应用程序暴露一个后端服务,该服务从一个真实的天气服务(例如 OpenWeatherMapopenweathermap.org/)获取数据,并使其公开互联网。

鉴于在本章前一部分中已经完成了设置 GitOps 环境的要求(安装 Kubernetes 集群、选择环境、验证安装以及安装 GitOps 工具),下一步是创建一个新的 GitHub 仓库。例如,您可以创建 gitops-for-real-world,并创建一个名为 Step-01 的目录。此目录将用于添加后续步骤的代码和文件。

在继续之前,您需要在 OpenWeatherMap 服务或您选择的其他类似服务上创建一个免费账户。这类服务通常需要一个令牌来查询其 API,用于身份验证和计费目的。保护该令牌的机密性至关重要,切勿共享它。请参阅 OpenWeatherMap 文档以创建新令牌。稍后,我们将把此令牌作为 秘密 添加到 Kubernetes 集群中。

最终目标和实现

为了实现我们的最终目标,本节及其后续章节将演示如何使用 Python Flask 应用程序,并将其打包为 Docker 镜像。每次提交时,这个镜像都会使用新的标签构建,并在 Azure AKS 集群上部署,该集群由管道使用 Terraform 自动化提供,用于 基础设施即代码 (IaC) 组件。最初,整个部署链——包括 IaC 和应用程序——将完全由我们的 GitHub CI/CD 管道管理。之后,我们将过渡到使用 Argo CD 进行部署,同时保持 CI 过程在 GitHub 工作流内。

最终,为了在我们的服务公开到公共互联网后进行测试,我们将通过 URL 中的查询字符串进行天气请求,指定城市,例如 public-ip/weather?city=zurich。响应将以 JSON 格式返回,可以直接在浏览器中呈现,或者使用 curl 等工具。

我们的管道将作为 GitHub 工作流进行开发,并将按 图 11.1 所示进行组成。

图 11.1 – GitHub 工作流管道

图 11.1 – GitHub 工作流管道

使用 GitHub Actions 和 Terraform 的 CI/CD 管道

图 11.1 中的管道利用 Terraform 进行基础设施管理,并将 Docker 化的应用程序部署到 AKS 集群中,提供了现代 DevOps 实践的一个实际示例。由于管道的代码过长,无法在本章中明确添加为内容,接下来列出了一些需要考虑的重要方面,以便更好地理解。工作流描述包含在存储库的 .github/workflows/ 目录中的 gitops-for-real-ci-cd-pipeline.yml 文件中。

工作流触发条件

该管道被配置为在对主分支进行任何推送或拉取请求时触发,有一个例外:仅在 Step-01/deployment 目录中的更改不会启动工作流。此预防措施可防止在仅更新 Kubernetes 清单文件时发生冗余运行,从而确保资源的高效使用,并避免在持续部署场景中可能出现的冲突。

Terraform 计划和应用

工作流以 terraform-plan 作业开始。此作业执行几个关键步骤:

  1. 环境设置:作业开始时会检出存储库,并设置带有 GitHub 密钥安全存储的 Azure CLI 凭据。此步骤确保工作流能够访问 Azure 以管理资源。

    管道中使用的所有密码、令牌和其他敏感信息需要配置为 GitHub Actions 密钥,如 图 11.2 所示。

图 11.2 – GitHub 在 Actions 秘密和变量页面上的密钥

图 11.2 – GitHub 在 Actions 秘密和变量页面上的密钥

  1. terraform init 用于准备 Terraform 环境,并在 Azure Blob Storage 中配置 Terraform 状态文件的后端存储。以下代码摘自主管道:

    - name: Terraform Init
      run: |
        terraform init \
        --backend-config=»resource_group_name=${{ secrets.BACKEND_RESOURCE_GROUP_NAME }}» \
        --backend-config=»storage_account_name=${{ secrets.BACKEND_STORAGE_ACCOUNT_NAME }}» \
        --backend-config=»container_name=${{ secrets.BACKEND_CONTAINER_NAME }}» \
        --backend-config=»key=${{ secrets.BACKEND_KEY }}» \
        --reconfigure
        working-directory: ./Step-01/terraform
        env:
        ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
        ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
        ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
        ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
    
  2. terraform plan,该计划会自动进行审查,以确定是否有更改需要应用。该计划会保存为 terraform-apply 作业。

GitHub 工件

GitHub Actions 中的工件是工作流运行过程中生成的一个文件或文件集合。工件可以包括二进制文件、日志、测试结果或任何其他需要在作业完成后存储的数据。这些工件通常用于存储构建和测试输出,以供调试、部署或在后续步骤或未来运行中进一步处理。GitHub 会在指定时间内存储这些工件,允许在同一工作流中的不同作业之间下载或共享这些工件。该功能通过确保工作流中的一部分输出可以轻松地在其他部分访问和利用,从而促进了有效的 CI/CD 实践,增强了软件开发生命周期中的自动化和连续性。

在规划完成后,terraform-apply 作业将已批准的更改应用到基础设施,确保实际状态与在 Terraform 配置中定义的预期状态匹配。由于资源在 Azure 上的配置,这部分可能需要几分钟。在打开 Azure 门户后,最终的配置应与图 11.3中所示相似。

图 11.3 – 由 GitHub 工作流自动配置的 Azure 资源

图 11.3 – 由 GitHub 工作流自动配置的 Azure 资源

Docker 镜像构建和推送

与基础设施管理并行,docker-build-and-push 作业处理应用程序方面:

  1. Docker 准备:该作业使用 QEMU 和 Buildx 设置 Docker 环境,这些工具增强了 Docker 在 CI 环境中的功能。

  2. Step-01 目录并将其推送到 Docker Hub,使用 commit SHA 进行标记,以确保不可变性和可追溯性,如图 11.4所示。

图 11.4 – 一个 Docker 仓库,其中包含带有 SHA 编号标签的构建镜像

图 11.4 – 一个 Docker 仓库,其中包含带有 SHA 编号标签的构建镜像

Kubernetes 部署

在 Docker 镜像推送并且基础设施准备就绪后,deploy-to-kubernetes 作业继续进行:

  1. 使用 Kubernetes 集群凭证的 kubectl,确保命令在正确的集群上执行,具体代码如下所示:

    - name: Update Kubeconfig
      run: az aks get-credentials --resource-group gitops-dev-rg --name gitops-dev-aks --overwrite-existing
    
  2. 机密和配置:接着,它部署应用程序所需的 Kubernetes 机密和配置,如 API 密钥,采用最佳的机密管理实践。以下代码摘自管道:

    - name: Deploy to Kubernetes
      run: |
        cd ./Step-01/deployment
        kubectl create namespace weather-app-for-real \
           --dry-run=client -o yaml | kubectl apply -f -
        kubectl create secret generic weather-api-key \
           --from-literal=WEATHER_API_KEY=${{ secrets.WEATHER_API_TOKEN }} \
           --namespace weather-app-for-real \
           --dry-run=client -o yaml | kubectl apply -f - command sequence can play a significant role in ensuring that a Kubernetes deployment is idempotent.
    

幂等性

在部署资源的上下文中,幂等性意味着多次运行相同的部署命令将导致相同的状态,而不会在初次应用后产生不必要的更改或副作用。

  1. Step-01/deployment/backend-api-deployment.yaml),该文件引用了新构建的 Docker 镜像,确保部署的是应用的最新版本:

    $ kubectl apply -f backend-api-deployment.yaml
    

注意!

如果你想从本地开发访问远程 AKS 集群,你需要登录 Azure 并执行以下命令:az aks get-credentials --resource-group gitops-real-rg --name gitops-real-aks

  1. 测试:与本地开发不同,在这个实际的例子中,我们在部署文件中指定了一个LoadBalancer端口,因此 AKS 会自动使用公共 IP 地址将我们的服务暴露到公共互联网,如图 11.5所示。

图 11.5 – 用于将 backand-api-service 暴露到公共互联网的公共 IP 地址

图 11.5 – 用于将 backand-api-service 暴露到公共互联网的公共 IP 地址

  1. 在此时,我们可以使用类似于图 11.6所示的 URL 查询我们的服务以获取响应:

图 11.6 – 使用实时天气数据查询苏黎世市服务的示例

图 11.6 – 使用实时天气数据查询苏黎世市服务的示例

到目前为止,我们已经获得了一个完全可工作的 CI/CD 管道,将服务暴露到现实世界。我们希望更进一步,通过使用 ArgoCD 将 CI 管道和 CD 管道分开,正如下一节所述。

使用 Argo CD 进行持续部署

在现代软件交付的世界里,确保我们的部署实践尽可能可靠和可扩展至关重要。Argo CD,作为一种声明式的 GitOps 持续交付工具,专为 Kubernetes 设计,通过自动化部署过程并将 Git 仓库中定义的目标应用状态与生产环境同步,显著提升了这些方面。

向 Argo CD 过渡

在本节中,我们将通过将deploy-app-to-kubernetes阶段过渡为argo-cd-deployment阶段来发展我们的 GitHub Actions 工作流。我们 GitHub Actions 工作流中的argo-cd-deployment阶段封装了以下关键操作:

  1. Argo CD 设置:首先,如果 Kubernetes 集群中未安装 Argo CD,工作流将初始化它。这包括设置必要的命名空间,并直接从官方来源应用 Argo CD 安装清单。

  2. 仓库配置:接下来,工作流将包含 Kubernetes 清单的 Git 仓库添加到 Argo CD。此步骤涉及配置 Argo CD 来监视仓库中的更改,该仓库托管应用的部署定义。

  3. 通过 Argo CD 进行应用部署:接着,它确保为应用创建并准备好特定的命名空间以供部署。

  4. argocd_deployment.yaml 文件定义了 Argo CD 应用程序。该清单指定了 Git 仓库中 Kubernetes 部署清单的路径、修订目标(例如,branch)和同步策略。

  5. 同步触发:可选地,如果需要立即部署,此步骤会触发手动同步,尽管通常 Argo CD 会根据其轮询策略自动检测到变更。

管理停机时间并确保 Argo CD 的连续性

当 Argo CD 发生短暂停机时,主要的影响是 Kubernetes 环境中部署的同步和自动对比过程。在此期间,提交到 Git 仓库的任何更改都不会与 Kubernetes 集群同步,这意味着更新、修复和新功能的部署会被推迟。自动对比过程——即确保 Kubernetes 环境的实际状态与 Git 仓库中指定的期望状态相匹配——也会中断。这意味着,在停机期间发生的任何不一致或配置漂移都不会得到解决,直到 Argo CD 恢复上线。恢复 Argo CD 后,它将自动开始处理并应用在停机期间所做的所有更改。系统将从 Git 获取最新的配置,并进行必要的对比,以使 Kubernetes 集群与仓库中的期望状态保持一致。需要注意的是,运行中的应用程序本身不会受到 Argo CD 停机的直接影响;它们将继续按停机前的配置运行。然而,为了在此类停机期间管理关键更新,团队可能需要执行手动干预,这应该小心处理,以避免 Argo CD 恢复正常运行后出现进一步的问题。建议采用强大的监控和警报系统,以快速检测 Argo CD 的任何问题,并最大限度地减少停机带来的影响。

  1. 要查看新工作流的运行效果,我们需要将 Step-02-ArgoCD-Deployment 文件夹中 gitops-for-real-ci-cd-pipeline.yml 文件的内容替换为 .github/workflows 子目录中同名文件的内容。然后,我们必须提交并推送更新的代码,以触发工作流的运行,如图 11.7所示:

图 11.7 – 在提交并推送新的工作流定义后触发一个新的工作流运行

图 11.7 – 在提交并推送新的工作流定义后触发一个新的工作流运行

在设置过程中自动生成的外部 IP 和管理员密码可以在 Setup ArgoCD on AKS 任务的日志中找到,如图 11.8所示。请注意:此类信息不应在实际生产环境中公开。这只是本示例范围内的一个快捷方式。

图 11.8 – 包含敏感信息的 AKS 上设置 ArgoCD 任务日志

图 11.8 – 包含敏感信息的 AKS 上设置 ArgoCD 任务日志

此时,我们可以通过在首选浏览器中输入4.226.41.44/来登录到已部署实例的 Argo CD 管理员界面(见图 11.9):

图 11.9 – 登录后的 Argo CD 主页,显示 backend-api-weather-app pod 的部署情况

图 11.9 – 登录后的 Argo CD 主页,显示 backend-api-weather-app pod 的部署情况

就这样!在这个例子中,我们没有启用自动同步,所以我们只需要点击同步应用按钮来同步我们的天气应用,如图 11.10所示。

图 11.10 – Argo CD 应用已正确同步到 GitHub 仓库

图 11.10 – Argo CD 应用已正确同步到 GitHub 仓库

为了测试 Argo CD 的同步过程,尝试将backend-api-deployment.yaml文件中的副本数量从1更改为5(例如),并将更改推送到 GitHub。由于我们指定了以下值,工作流不会被触发:

paths-ignore:
- 'Step-01/deployment/**'

然而,Argo CD 会注意到不同步的状态,并且需要进行新的同步。现在,我们已经建立并完美运行了 CI/CD 流水线,接下来是介绍下一节中的可扩展性和效率主题。

可扩展性和效率设计

在本节中,我们将深入探讨可扩展性和效率的设计。这些特性在现代应用程序的架构中至关重要,以我们的天气应用为例。可扩展性确保应用能够应对增长,无论是用户数量、数据量还是交易频率的增加,而不会影响性能。效率则涉及资源使用的优化,对于降低成本和提高响应速度至关重要。我们将探讨支持可扩展性的架构原则,例如微服务和负载均衡,并讨论如何有效管理计算、存储和网络资源。此外,我们还将研究测试可扩展性的工具和策略,以确保架构能够应对现实世界的需求。通过掌握这些元素,你将学会如何设计一个可扩展且高效的架构,这种架构非常适合部署在 Kubernetes 上,提升像我们的天气应用这样的应用的整体性能和可靠性。

架构原则

设计可扩展和高效系统的架构原则在现代应用开发中至关重要,尤其是当对性能和可靠性的需求增加时。关键策略包括解耦组件以最小化依赖关系,从而便于维护和扩展。强调无状态性允许组件的复制和分布,从而增强应用的韧性和响应能力。

负载均衡对于将传入的网络负载均匀分配到多个系统至关重要,防止任何单一服务器过载,并提高应用的可用性。横向扩展,即通过增加更多实例而不是为单一实例增加资源,是一种更具成本效益的方式,并且提高了容错能力。

数据库分片将数据划分为更小、更易管理的部分,尤其对大数据集或高吞吐量的需求非常有益。分片有助于提升性能。缓存常访问的数据可以通过直接处理常见请求而不进行冗余数据处理,减少延迟并降低后端负载。

异步处理任务通过以非阻塞方式处理操作,提升了吞吐量和用户体验。采用微服务架构允许每个服务独立部署、扩展和管理。这种模块化方法不仅提高了性能,而且随着应用的演变简化了管理,使其非常适合由如 Kubernetes 这样的平台管理的云原生环境。尽管提到了微服务架构,但它不会是本章讨论的示例的一部分。

微服务架构

微服务架构是一种将应用结构化为一组松耦合服务的架构风格,每个服务实现特定的业务功能。这种方法使开发者能够独立构建和部署服务,从而提高灵活性并加速开发周期。通过将应用拆解为小的、可管理的组件,微服务使得更精细的扩展和高效的资源利用成为可能。每个服务都可以独立开发、部署和扩展,通常使用最适合任务的不同编程语言和技术。这种模块化提高了故障隔离,使得在不影响整个系统的情况下,更容易识别和修复问题。此外,微服务促进了 CI/CD 实践,推动了更加敏捷和韧性的开发过程。总体来说,微服务架构促进了一个更强大、更具可扩展性的应用环境,能够适应不断变化的业务需求和技术进步。

资源管理

有效的资源管理在应用设计和操作中至关重要,特别是在那些旨在最大化效率和性能,同时最小化成本的环境中。管理计算、存储和网络资源需要精心规划和协调,以确保应用的每个组件都拥有足够的资源,能够在没有浪费的情况下发挥最佳性能:

  • 计算管理:涉及为满足应用需求而提供适当数量的 CPU 和内存资源。像自动扩展和负载均衡等技术有助于将计算工作负载均匀分配到可用基础设施上。

  • 存储管理:确保数据存储资源得以高效分配,同时考虑数据的可访问性和冗余性。这包括选择适当的存储类型和实施数据分区策略,以提高性能和可扩展性。

  • 网络管理:重点在于高效配置网络资源,以确保应用组件之间的数据传输快速且安全。适当的网络配置能够减少延迟,防止瓶颈,这对于实时数据处理和交付至关重要。

这些资源管理实践共同确保应用能够有效扩展,并在不同的操作条件下保持稳健。实施资源管理策略还需要监控和分析资源使用情况,以做出明智的调整和改进决策,确保资源以最有效的方式被利用。

可扩展性测试

可扩展性测试对于确保应用在预期负载下能够良好运行,并且能够高效处理用户、事务和数据的增长至关重要。可扩展性测试涉及多种技术,模拟不同的环境和系统压力,旨在在问题影响用户之前发现潜在问题:

  • 负载测试:模拟特定预期数量的并发用户或事务,以评估应用在正常条件下的表现。

  • 压力测试:将应用推向其正常操作极限,以发现其最大容量并了解其在极端条件下的行为。

  • 浸泡测试:在重负载下长时间运行应用,以发现如内存泄漏或性能逐渐下降等问题。

  • 激增测试:检查应用在面对突如其来的大量流量时的处理能力。

  • 可扩展性测试:通过逐步增加负载并观察额外资源如何影响应用的容量,测试应用是否能够根据需求进行扩展或缩减。

这些测试通常使用自动化测试工具,并在阶段性环境中进行,这些环境非常接近真实的流量模式。诸如Apache JMeterLoadRunnerGatling等工具,以及AWS CloudWatchGoogle Cloud Monitoring等云服务,通常用于促进这些测试。通过在开发和部署阶段进行定期的可扩展性测试,团队可以确保他们的应用程序是强健的、可扩展的,并能够应对真实世界的操作需求。

资源管理与可扩展性

在本节中,我们将继续使用天气应用程序,看看资源管理、水平扩展和可扩展性测试在实际场景中的运作方式。我们可以从资源使用优化开始。

优化资源使用

为了优化 Kubernetes 中的资源使用,设置资源请求和限制至关重要。这些设置确保 Pod 获得正确数量的 CPU 和内存资源以正常运行,同时也防止任何单个应用程序消耗过多的集群资源,从而影响其他应用程序:

  • Requests:这是 Kubernetes 为容器保证的资源数量。如果容器所需的资源超过其请求并且节点上有足够的资源,它可以消耗更多的资源。

  • Limits:这是容器可以使用的最大资源数量。如果容器尝试超过此限制,系统将限制其 CPU 使用。如果容器超过其内存限制,Kubernetes 可能会终止它,具体情况取决于当时的情况。

为了测试请求和限制的使用,我们可以尝试更新Step-01/deployment/backend-api-deployment.yaml文件,在key: WEATHER_API_KEY row之后立即添加以下代码块:

…         key: WEATHER_API_KEY
resources:
          requests:
            cpu: «100m»
            memory: "100Mi"
          limits:
            cpu: «150m»
            memory: "150Mi"

前面提到的代码块指定了容器的资源请求和限制。以下是每行代码的含义:

  • requests

    • cpu: "100m":这请求容器使用 100 毫核(1,000 毫核等于 1 个 CPU 核心)

    • memory: "100Mi":这请求 100 MiB 的内存

  • limits

    • cpu: "150m":这设置了容器 CPU 使用的 150 毫核限制

    • memory: "150Mi":这设置了 150 MiB 的内存限制

现在我们已经定义了请求和限制,在下一节中,我们将看到如何在下一节中实现水平 Pod 自动扩展器HPA)。

实现 HPA

在 Kubernetes 中实现 HPA 是一种有效的方法,可以根据观察到的 CPU 利用率或其他选定的度量标准(如内存使用或自定义指标)自动扩展部署、复制控制器或副本集中的 Pod 副本数量。以下是设置 HPA 的逐步指南:

  1. 确保 Metrics Server 已在集群中安装,该服务器从 Kubelets 收集资源指标,并通过 Kubernetes 的 Metrics API 将其暴露。这个组件对于 HPA 做出扩缩容决策至关重要。我们可以使用以下命令进行安装:

    $ az aks update --enable-azure-monitor-metrics --name gitops-real-aks --resource-group gitops-for-real-rg
    
  2. 设置过程将需要几分钟时间。完成后,请使用以下命令验证安装是否正确:

    $ kubectl get deployment metrics-server -n kube-system
    

    该命令应返回部署详情,确认 Metrics Server 已启动并运行:

    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    metrics-server  2/2     2            2           3h37m
    
  3. 创建一个基于 CPU 利用率进行扩缩容的 HPA:

    apiVersion: autoscaling/v1
    kind: HorizontalPodAutoscaler
    metadata:
      name: weather-app-backend-api-hpa
      namespace: weather-app-for-real
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: backend-api-weather-app
      minReplicas: 1
      maxReplicas: 5
      targetCPUUtilizationPercentage: 5
    

    该 HPA 配置为保持 pod 数量在 15 之间,当 CPU 利用率达到 50% 时进行扩缩容。

  4. Step-01/deployment 文件夹中创建一个新的 hpa.yaml 文件,内容如我们所描述。提交并推送代码,然后等待 Argo CD 应用程序同步,或者如果自动同步关闭,则强制同步。

图 11.11– Argo CD 应用程序与 HPA 配置同步

图 11.11– Argo CD 应用程序与 HPA 配置同步

  1. 使用以下命令监控你的 HPA 状态和效果:

    $ kubectl get hpa -w --namespace weather-app-for-real
    

    这将显示当前的副本数,并显示 HPA 是否正在根据当前的 CPU 利用率对比设置目标进行扩缩容。

测试可扩展性——一个示例

现在我们已经实现了 HPA 并设置了监控,接下来的步骤是观察 Kubernetes 如何根据 CPU 利用率变化动态地扩缩容 pod 数量。通过模拟不同的负载,我们可以看到 HPA 如何调整 pod 数量以保持最佳性能。这个过程确保我们的应用能够高效扩展,自动应对需求的增加或减少,而无需人工干预。理解这一行为对于优化 Kubernetes 环境中的资源管理和成本效益至关重要。以下是逐步测试场景:

  1. 创建一个用于测试 HPA 的 Bash 脚本。使用 curl 命令对暴露的天气服务发起请求,使用不同的城市,并在查询字符串中加入随机值以避免缓存。你可以参考本章附带的 hpa-testing.sh 脚本。在执行脚本之前,请更新 $baseUrl,使其与天气服务的 URL 匹配。具体如下所示:

    # Base URL of your weather service
    baseUrl="http://20.250.198.208/weather"
    
  2. 运行该 Bash 脚本:

    1. 打开一个新的终端,并使用以下命令使脚本可执行:
    TARGET column should increase. To speed up the testing scenario and see the number of pods increase faster, execute another instance of the same script in another terminal.
    
  3. 检查 HPA 状态(参见本章 实现 HPA 部分的第六点)。使用以下命令检查 HPA 状态:

    $ kubectl get hpa -w --namespace weather-app-for-real
    

    你应该看到当前的副本数以及它们基于 CPU 利用率的扩缩容活动:

    NAME                TARGETS     MINPODS      MAXPODS       REPLICAS
    weather-app-…       cpu: <unk>%/5%  1     5             1
    weather-app-…    cpu: 5%/5%  1            5             1
    weather-app-…    cpu: 20%/5% 1            5             4
    …
    weather-app-…    cpu: 3%/5%  1         5             4
    weather-app-…    cpu: 1%/5%    1             5             4
    

HPA 监控部署的 CPU 利用率,并根据需要调整 pod 数量,以确保最佳性能。

最初,CPU 使用率标记为<unknown>,这可能是由于指标不可用或仍在初始化。当使用率稳定在 5% 时,且与 HPA 中设置的目标匹配,副本数量没有变化,仍保持为一个。当 CPU 使用率增加到 20%——远高于 5% 的目标时,HPA 通过将副本数量从1扩展到4来应对增加的负载。

这种较高水平的资源使用持续了一段时间,副本数保持在4。然而,当使用率显著下降至 3% 并进一步下降到 1% 时,HPA 最初并未立即缩减副本数,这可能是由于稳定性设置防止了 Pod 数量的波动。最终,随着低使用率的持续,HPA 将 Pod 数量缩减回1

该序列展示了 HPA 根据实时数据动态扩展应用资源的能力,从而确保部署能够高效地响应工作负载变化。这种动态调整有助于有效管理资源,保持应用响应能力并优化运营成本。HPA 对 CPU 使用率变化的响应示例了 Kubernetes 如何自动调整扩展,以保持性能和资源效率,而无需人工干预。

在确保资源管理和可扩展性的同时,关注监控和保护应用程序同样重要。在接下来的部分,我们将探讨运营卓越的这些关键方面。

监控和保护你的应用程序

软件部署和管理中的运营卓越是任何技术驱动型组织成功的关键因素。实现这一卓越的关键在于监控、扩展和安全,这三者作为基础支柱,确保了应用程序在生产环境中的平稳高效运行。

监控至关重要,因为它提供了实时了解应用程序和系统行为所需的可见性。有效的监控策略有助于识别性能瓶颈、预测系统故障,并收集有价值的数据,以支持决策过程。这种持续的监督使团队能够主动响应问题,在它们影响用户体验或导致更大干扰之前解决问题。

安全实践对于保护敏感数据和防止基础设施受到入侵和攻击至关重要。在网络威胁迅速演变的时代,确保采取强有力的安全措施是不可谈判的。安全协议有助于维护与客户的信任,遵守监管要求,并避免与数据泄露相关的财务和声誉损害。

监控、扩展和安全构成了运营卓越的支柱,支持一个稳定、高效、安全的环境,用于部署和管理应用程序。掌握这些方面的组织更能有效地利用技术推动业务成功,确保在不断变化的数字环境中持续为用户创造价值。

监控

Grafana 和 Prometheus 是广泛使用的强大工具,在监控和可观察性领域中具有重要价值。它们对于管理在动态环境中部署的云原生应用(如 Kubernetes)尤其有用:

  • Prometheus:Prometheus 是一个开源的监控系统,具有强大的查询语言。它将度量值作为时间序列数据收集和存储,这意味着每个度量值都会记录其准确的时间。Prometheus 在高可用性环境中记录实时度量值非常有效。它支持通过拉取模型从监控服务中获取数据,允许它按照指定的间隔主动抓取来自注册目标的数据。然后可以查询和分析这些数据,以监控应用程序的健康状况和性能。

  • Grafana:Grafana 是一个开源的分析和可视化平台,能够与多种数据源(包括 Prometheus)无缝集成。Grafana 用于创建全面的仪表板,提供度量数据的可视化。这些仪表板帮助开发人员和运维团队通过可视化的方式解读复杂数据,理解应用程序的行为和资源使用,从而更容易发现趋势、模式和潜在问题。

结合使用,Prometheus 和 Grafana 提供了强大的数据收集、存储和可视化组合,增强了观察系统行为、排查问题以及确保系统性能与用户期望和业务目标一致的能力。这个组合在 DevOps 环境中尤为有效,持续监控和反馈回路对软件开发和部署生命周期至关重要。

设置 Prometheus 和 Grafana

以下是设置 Prometheus 和 Grafana 在 AKS 集群上的必要步骤:

  1. 添加 Prometheus 和 Grafana Helm chart 仓库:

    $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    
  2. 更新 Helm 仓库。确保我们使用的是最新版本:

    gitops-real-monitoring:
    
    

    $ helm install prometheus \

    prometheus-community/kube-prometheus-stack \

    --namespace gitops-real-monitoring \

    --create-namespace

    
    
  3. 输入以下命令检查整个部署:

    LoadBalancer service’s type, to log in to Grafana, we need to execute a port-forward:
    
    

    admin 用户名和为 prom-operator 定义的密码。

    
    
  4. 使用以下命令暴露 Prometheus:

    $ kubectl port-forward svc/prometheus-kube-prometheus-prometheus -n gitops-real-monitoring 9001:9090
    
  5. 登录后,你应该能够看到 Grafana 的主页。点击仪表板菜单项,如图 11.12所示:

图 11.12 – Grafana 首页,突出显示仪表板菜单项

图 11.12 – Grafana 首页,突出显示仪表板菜单项

  1. 点击weather-app-for-real。你将看到一些关于正在运行的 Pods 的有趣指标,如图 11.13所示。

图 11.13 –  Pod 的 CPU、内存及其他指标

图 11.13 – backend-api-weather Pod 的 CPU、内存及其他指标

此时,你已经正确并成功地设置了 Grafana 和 Prometheus。现在,你可以查看关于backend-api-weather-app使用情况的有趣统计数据,这些数据可以用来微调资源限制和请求,正如本章的优化资源使用部分所讨论的那样。在接下来的部分,我们将介绍 Kubernetes 管理中的另一个重要方面:Kubernetes 安全性。

理解 Kubernetes 安全性

Kubernetes 虽然强大且可扩展,但也带来了独特的安全挑战,这些挑战源于其动态和分布式的特性。保护 Kubernetes 集群涉及保护基础设施、运行其上的应用程序以及它所处理的数据。鉴于 Kubernetes 环境的复杂性,安全性必须集成到集群的每一层。Kubernetes 安全的关键方面包括以下几点:

  • 身份验证与授权:确保只有经过验证的用户才能访问集群,方法包括证书和令牌等。它还通过 RBAC 和基于属性的访问控制ABAC)等机制控制用户的操作。

  • API 安全性:保护 Kubernetes API 服务器(它充当集群的中央控制单元)至关重要。保护 API 访问包括使用 SSL/TLS 加密、API 请求审计和通过网络策略限制 IP 访问。

  • 网络安全:强制执行控制 Pod 与外部网络之间流量的政策,有助于防止未经授权的访问,并限制集群内横向移动的潜力。

  • Pod 安全准入:这是一个 Kubernetes 准入控制器,在 Pod 创建时强制执行安全设置,使用预定义的安全配置文件(特权基准受限)确保符合最佳安全实践并防止权限升级。

  • 秘密管理:Kubernetes 使用秘密来管理敏感数据(如密码和令牌)。正确处理和保护这些秘密,包括静态和传输中的加密,对于保护敏感信息至关重要。

分层安全方法的重要性

鉴于 Kubernetes 的复杂性,单一的安全措施通常不足以应对威胁。一个包含网络分段、威胁检测、安全访问控制和持续漏洞管理的分层安全方法对于保护 Kubernetes 环境免受威胁至关重要。

在接下来的部分,我们将看到一个实际示例,展示如何使用 RBAC 管理对特定命名空间中天气应用资源的访问。

配置 Kubernetes RBAC 进行用户和角色管理

这是配置天气应用 RBAC 的逐步指南:

  1. 定义一个角色,指定管理与天气应用相关的特定资源(例如部署、服务和 Pod)所需的权限,范围是在指定命名空间内。以下是 weather-app-manager 角色的定义:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: weather-app-for-real
      name: weather-app-manager
    rules:
    - apiGroups: ["", "apps"]
      resources: ["deployments", "replicasets", "pods", "services"]
    weather-app-user role:
    
    

    apiVersion: rbac.authorization.k8s.io/v1

    类型:Role

    元数据:

    命名空间:weather-app-for-real

    名称:weather-app-user

    规则:

    • apiGroups: ["", "apps"]

    资源:["pods", "services"]

    动作:RoleBinding 资源将指定的角色授予用户。此绑定将 weather-app-manager 角色应用于名为 weather-app-user 的用户:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: weather-app-manager-binding
      namespace: weather-app-for-real
    subjects:
    - kind: User
      name: weather-app-user
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: weather-app-manager
      apiGroup: rbac.authorization.k8s.io
    
    
    
  2. 创建另一个 RoleBinding 资源,将 weather-app-user 角色授予名为 weather-app-operator 的用户:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: weather-app-operator-binding
      namespace: weather-app-for-real
    subjects:
    - kind: User
      name: weather-app-operator
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: weather-app-operator
      apiGroup: rbac.authorization.k8s.io
    
  3. 将 YAML 文件移动到 Step-01/deployment 文件夹,推送更改到 GitHub,并同步 Argo CD 应用程序。

  4. 使用 kubectl auth can-i 命令,验证 weather-app-userweather-app-operator 用户是否具备必要的权限:

    $ kubectl auth can-i delete pods --as weather-app-operator -n weather-app-for-real
    $ kubectl auth can-i delete pods --as weather-app-manager -n weather-app-for-real
    

    预期的输出应该如下所示:

    no
    yes
    
  5. 我们可以使用以下命令列出命名空间中的所有角色和角色绑定,或列出影响用户的集群角色:

    $ kubectl get rolebindings,roles,clusterrolebindings,clusterroles --all-namespaces -o yaml
    

作为参考,本章附带的代码库中的 Step-03-Security 目录包含了迄今为止所描述的角色和角色绑定定义的 YAML 文件。

小心!

为避免因 Azure 资源而产生意外费用,请记得销毁任何不需要的 Azure 提供的资源。

本部分结束了我们对实际 GitOps 流水线和部署的探讨。虽然一本书可能不足以深入探讨 GitOps 与 Kubernetes、安全性和部署的每个方面,但我们相信,到目前为止所覆盖的章节提供了一个全面的概述。它们为设置有效的 GitOps 流水线并应用于未来的 Kubernetes 项目提供了宝贵的见解。

总结

本章提供了一个关于如何在 Kubernetes 上使用 GitOps 部署真实世界项目的综合指南。通过遵循详细的指示和示例,你学会了如何设置 GitOps 和 Kubernetes 开发环境、实现 CI/CD 流程、进行可扩展性和高效性的设计、管理资源并保护应用程序。这些实践知识使你掌握了在项目中有效应用这些前沿技术的技能,增强了你的组织能力和个人技术专长。

由于你已经在 Kubernetes 上使用 GitOps 部署和管理应用程序打下了坚实的基础,下一章将深入探讨 GitOps 的可观察性,提供监控和深入了解应用程序性能与健康的关键策略。

第四部分:通过 GitOps 最佳实践实现运营卓越

在本部分中,你将专注于通过 GitOps 中的最佳实践实现运营卓越。你将学习集成可观察性、增强安全性、管理财务运营以及为 GitOps 中的未来趋势做好准备。本节旨在提供一份全面的指南,以保持高标准的运营效率和安全性,同时考虑到可持续性和财务因素,确保你的 GitOps 实践既前沿又可持续。

本部分包括以下章节:

  • [第十二章,GitOps 中的可观察性

  • 第十三章,GitOps 中的安全性

  • 第十三章,FinOps、可持续性、AI 和 GitOps 的未来趋势

第十一章:GitOps 中的可观察性

欢迎来到通过GitOps实践深入探索在 Kubernetes 环境中集成可观察性的专题。随着云原生应用的复杂性和规模不断增长,能够观察、理解并应对其行为变得愈发重要。本章旨在弥合传统操作方法与 GitOps 的动态自动化世界之间的鸿沟,提供一个通向更加可靠、响应迅速和高效的系统的路径。

本次旅程的核心是将站点可靠性工程SRE)原则与 GitOps 框架相融合。GitOps 是一个在 DevOps 社区中迅速崛起的术语,它利用 Git 作为声明式基础设施和应用程序的唯一真实来源。通过应用 GitOps,我们不仅可以自动化和简化部署流程,还能增强 Kubernetes 环境的可观察性和可管理性。

本章深入探讨了GitOps范式中可观察性的核心概念,区分了内部和外部可观察性,以便全面理解系统状态。内部可观察性通过指标日志追踪来揭示系统内部的工作原理,而外部可观察性则关注系统外部的体验,如用户互动和外部依赖。

SLO 驱动的性能管理被赋予了显著的重视。服务水平目标SLOs)作为衡量性能和可靠性的量化标准,指导着我们在系统优化和改进方面的努力。结合DevOps 研究与评估DORA)指标——部署频率、变更的交付时间、变更失败率和恢复服务的时间——这一方法为评估和提升 GitOps 实践的有效性提供了一个强有力的框架。

此外,本章介绍了分布式追踪的概念,这是理解请求在微服务架构中流动的关键组件。在 GitOps 工作流中实施分布式追踪,借助如Linkerd等工具,可以深入了解系统组件之间的互动和依赖关系,帮助快速诊断和解决问题。

最后,我们讨论了使用如OpenTelemetry等前沿工具来设置监控和报警系统。这一设置对于主动管理系统至关重要,使团队能够在问题升级为更大问题之前及时发现并应对异常。

本章主要讨论理论和思路,建议从头到尾阅读。读完后,你将能够将这些思路以特别的方式结合起来,并通过一个真实的例子亲自尝试。

开始阅读这篇中级 GitOps 可观察性指南,你正在迈向掌握保持高度可观察、性能优越、可靠的云原生应用程序的艺术与科学的一步。让我们深入探讨,释放 Kubernetes 部署的全部潜力。

因此,本章涵盖了以下主要主题:

  • 探索 GitOps 和 Kubernetes 的 SRE 基础

  • 理解内部与外部可观察性的区别

  • 探索基于 SLO 的多阶段性能与 DORA

  • 在 GitOps 中使用 Linkerd 实现分布式追踪

  • 使用 Uptime Kuma 和 OpenTelemetry 等工具在 GitOps 中实现监控

  • 在 GitOps 框架中查看告警策略

  • 使用 GitOps 扩展可观察性

探索 GitOps 和 Kubernetes 的 SRE 基础

在不断发展的云原生应用程序领域,将 SRE 原则与 GitOps 和 Kubernetes 相结合,代表了向操作卓越迈出的重要一步。本节旨在提供这些基础概念的简要概述,帮助你掌握如何在 GitOps 工作流和 Kubernetes 环境中有效应用 SRE 实践。

SRE 与 GitOps 的交集

SRE 是一门将软件工程的各个方面融入 IT 运维领域的学科。SRE 的核心理念是将运维视为一个软件问题,专注于自动化和优化系统的可靠性和性能。Google 推出 SRE 是为了维持具有高可用性和高性能目标的大规模服务。其关键原则包括定义明确的 SLO,减少组织之间的壁垒,拥抱风险,并自动化手动任务。

GitOps 是一种将 Git 版本控制系统应用于管理基础设施和应用配置的范式。它强调自动化、不变性和声明性规范,使其成为实现 SRE 实践的理想框架。GitOps 使团队能够将软件开发原则,如代码审查版本控制持续集成/持续部署CI/CD)应用于基础设施管理,确保一致性、可靠性和速度。

Kubernetes 环境中的 SRE 原则

Kubernetes 是一个开源平台,用于自动化应用容器的部署、扩展和操作,它通过提供一个动态和可扩展的环境来管理容器化应用程序,从而补充了 GitOps 方法。

通过 GitOps 将 SRE 原则集成到 Kubernetes 中涉及几个关键实践:

  • 自动化部署和扩展:利用 GitOps 自动化 Kubernetes 资源和应用程序的部署,确保它们符合预定义的 SLO。根据流量模式或系统负载自动化扩展决策,帮助保持性能和可靠性。

  • 错误预算与风险管理:将错误预算定义为 SLO 的一部分,以平衡变更速率与系统稳定性。GitOps 可以通过根据错误预算的消耗自动回滚或部署程序来帮助执行这些预算。

  • 监控与可观察性:实现全面的监控与可观察性框架,以跟踪服务的健康状况。Kubernetes 提供了内置的工具,如用于监控的 Prometheus 和用于可视化的 Grafana,可以集成到你的 GitOps 管道中,实现实时洞察和警报。

  • 事件管理:在你的 GitOps 工作流中自动化事件响应。利用 Kubernetes 的自愈功能,如自动重启失败的容器和滚动更新,来最小化停机时间并保持服务可用性。

将 SRE 原则与 GitOps 和 Kubernetes 相结合,提供了一种强大的方法来管理云原生应用程序。通过专注于自动化、监控和可靠性,团队可以实现更高效和更高性能的水平。这些基础知识为掌握现代 IT 操作的复杂性奠定了基础,使你能够在不断变化的技术环境中构建和维护具有韧性和可扩展性的系统。

在下一节中,我们将探讨内部可观察性与外部可观察性之间的区别,以及如何通过平衡这两种可观察性来实现系统性能的最佳状态。

理解内部(白盒)与外部(黑盒)可观察性的区别

理解内部可观察性与外部可观察性之间的细微差别,对于有效管理和优化云原生应用程序至关重要。这一区分指导我们如何监控和解读通过 GitOps 实践在 Kubernetes 环境中部署的系统行为。在这里,我们深入探讨了什么构成了内部和外部可观察性,它们各自的角色,以及如何利用这两者实现对系统的全面健康性能的视角。

内部或白盒可观察性的解释

内部可观察性 专注于从系统内部生成的指标、日志和追踪。这类似于在汽车运行时检查引擎和其他组件的健康状况与性能。在 Kubernetes 和 GitOps 的背景下,内部可观察性涉及以下内容:

  • 指标:表示系统在任何给定时刻状态的数值数据。这可能包括 CPU 使用率、内存消耗、网络 I/O 等。

  • 日志:记录系统中发生的事件的文本记录。日志对于调试问题和理解导致事件发生的顺序至关重要。

  • 追踪:有关请求在系统中流动的详细信息,突出显示不同组件如何交互,以及瓶颈或故障发生的位置。

为了明确在此上下文中“内部”的含义,创建了 图 12**.1。然而,在详细解释图表之前,应该先解释框架。本章并不是要解释 OpenTelemetry 等工具(请参见本章末尾的[1]“进一步阅读”部分)、Grafana Loki [2]、Prometheus [3] 或 Jaeger [4]。也不是要详细阐述 OpenTelemetry 的工作原理及最佳配置方法——这将需要一章甚至一本专门的书。稍后将在本章中概述 OpenTelemetry 的基本功能,以及 GitOps 的必要背景。因此,我们将 图 12**.1 视为一个黑箱,专注于 Kubernetes 集群中的发生的事件,以及内部可观测性与其之间的关系。

图 12.1:使用 OpenTelemetry 的内部可观测性

图 12.1:使用 OpenTelemetry 的内部可观测性

重要提示 – 日志格式

为了确保收集到的系统和应用日志(图 12**.1)能够有效地利用,它们必须采用标准化和结构化的格式。这个格式应该能够便于提取和分析相关信息。分析后的数据可以转化为具体的 SLO(服务水平目标),帮助监控和确保服务的性能与可靠性。

以下是作为 图 12**.1 中终端的工具的简要分类:

  • OpenTelemetry 是一个统一的可观测性框架,用于收集、处理和导出遥测数据(日志、指标和追踪数据),帮助理解软件的性能和行为。

  • Grafana Loki 是一个日志聚合系统,经过优化,能够高效地存储和查询大量日志数据,并与 Grafana 无缝集成,进行可视化展示。

  • Prometheus 是一个开源监控系统,拥有强大的查询语言,专为在时间序列数据库中记录实时指标而设计。

  • Jaeger 是一个分布式追踪系统,允许你监控和排查复杂分布式系统中的事务。

在我们的示例中,一切都运行在 Kubernetes 集群中。例如,我们有一个 web 应用,如在线商店,它会生成应用日志,例如用户登录记录,系统日志,如意外关机记录,指标数据,如单个容器的 CPU 和内存使用情况,以及追踪数据,映射请求在应用组件中的流转路径(1图 12**.1 中)。

然后,OpenTelemetry Collector2图 12**.1 中)收集指标、日志和追踪数据,并通过相关数据如时间戳、服务名称和环境详情进行增强。随后,Collector 中的一部分导出器将日志、指标和追踪数据提供给适当的终端(3图 12**.1 中)。

例如,日志被推送到 Grafana Loki,Grafana 可以将其用作数据库。指标被推送到 Prometheus,它也可以作为 Grafana 的数据库。追踪数据被推送到 Jaeger,Jaeger 同样可以作为 Grafana 的数据库。这使得可以在 Grafana 中构建可观测性仪表板和警报,从而提供对系统性能和健康状况的全面洞察。

当然,也可以争辩说,节点可以是全球分布式的,日志的收集也可以跨分布式集群进行,等等。

然而,这里需要理解的关键是,内部指的是运行节点上的 Pod 生成日志、指标和追踪数据。

我希望到此为止,内部的含义已经变得清晰,并且所有内容都涉及到节点层面的系统,或者是写入节点上的应用日志,或者是节点之间通过网络覆盖层传输数据包(服务网格)的网络层面。

外部或黑盒可观测性定义

外部可观测性,另一方面,关注的是从外部者的角度理解系统,主要关注最终用户的体验。它衡量系统的输出以及系统内部的变化如何影响这些输出。关键方面包括以下内容:

  • 用户体验指标:这些指标从用户的角度衡量应用程序的响应能力和可靠性,如页面加载时间、交易完成率和错误率。

  • 合成监控:通过模拟用户与应用程序的交互来测试和衡量其在全球各地的性能和可用性。

  • 依赖检查:监控应用程序所依赖的外部服务的健康状况和性能。这有助于确定系统中的问题是否源自外部依赖。

本节重点讨论外部监控。为了更好地可视化,我们使用一个名为 Uptime Kuma[5]的服务,如图 12.2所示。例如,它运行在 Kubernetes 集群上,并通过一个可在互联网上访问的 URL 监控 Web 应用,如在线商店。为了更好地说明外部方面,我们使用 packthub 网站作为示例。

获取外部可观测性意味着使用系统范围的度量标准,这些度量标准并不是我们应用程序核心功能的一部分。这包括监控外部服务和第三方组件,如网络和 CPU 使用情况。例如,在 Kubernetes 集群中,同一命名空间中的内部服务可以直接进行监控。或者,在不同的命名空间中,也可以通过内部 DNS 名称进行监控。这种方法并不在节点的系统层面上运作,而是通过在覆盖网络中使用服务网格与 kube-proxy 进行允许的访问。

重要说明

Uptime Kuma 是一款自托管的监控工具,可以在 Kubernetes 集群中运行,监控像 Web 应用程序这样的服务。通过监控互联网可访问的 URL,如在线商店,它从外部视角提供关于这些服务的正常运行时间和性能的洞察。这种外部监控不仅仅是监控节点级别的系统指标,还能通过 Kubernetes 网络模型和服务网格,通过内部 DNS 名称观察跨命名空间的服务。

图 12.2中,设置了一个简单的HTTP(s)检查,期望返回200299代码。这允许对站点进行外部监控,并在站点停机、证书到期或响应时间增加时设置警报。

图 12.2:使用 Uptime Kuma 的外部可观测性

图 12.2:使用 Uptime Kuma 的外部可观测性

图 12.3中,你可以看到正常运行时间为 100%。此外,你还可以看到证书何时过期以及响应时间或平均响应时间。

图 12.3:使用 Uptime Kuma 的外部可观测性 – 仪表板第一部分

图 12.3:使用 Uptime Kuma 的外部可观测性 – 仪表板第一部分

仪表板的第二部分(图 12.4)显示了特定时间间隔内的响应时间,以及当前的200代码。

图 12.4:使用 Uptime Kuma 的外部可观测性 – 仪表板第二部分

图 12.4:使用 Uptime Kuma 的外部可观测性 – 仪表板第二部分

此时,应该已经澄清了外部的含义,以及如何借助像 Uptime Kuma 这样的工具来实现这一点。这使得可以确定服务级别协议SLA),根据紧急程度或合同的不同,SLA 可能极其重要。理解这一点并配合警报是非常关键的。

平衡内部和外部可观测性

为了实现最佳的系统性能和可靠性,平衡内部和外部可观测性是至关重要的。内部可观测性使你能够诊断并解决基础设施和应用程序中的问题,而外部可观测性则确保这些修复能转化为更好的用户体验。将 GitOps 实践集成到 Kubernetes 中,通过自动化部署和管理可观测性工具和实践,增强了这种平衡:

  • 在 GitOps 中实施可观测性:使用 Git 仓库定义你的可观测性堆栈,确保监控、日志记录和追踪工具在所有环境中被一致地自动部署和配置。

  • 自动化反馈回路:建立自动化反馈回路,将可观测性数据集成到你的 GitOps 工作流中。这可以帮助自动回滚对系统性能或用户体验产生负面影响的更改。

总之,掌握内部与外部可观察性之间的相互作用是保持和优化云原生应用程序的关键。通过利用这两个视角,团队可以确保其系统不仅在内部运行顺利,而且能够为用户提供期望的结果和体验。将这些可观察性实践融入到 GitOps 和 Kubernetes 策略中,能够实现一种更为主动、数据驱动的系统管理和改进方法。

下一节将介绍可以收集的有用指标,以便获得跨多个阶段或集群的部署洞察。

探索基于 SLO 的多阶段性能与 DORA

在云原生应用程序领域,特别是在 Kubernetes 环境中通过 GitOps 进行管理的应用程序,采用 SLO 和集成 DORA 指标提供了一种战略框架,用于实现并保持高性能。这种方法将 SLO 的精确性与 DORA 指标提供的洞察力相结合,以指导应用程序开发和部署的多个阶段或集群中的持续改进。

此时(图 12.5),它是关于观察公司定义的指标,如延迟、错误率等,GitOps 如何帮助在整个 CI/CD 过程中衡量性能和可靠性。

图 12.5:GitOps 与 DORA 和 SLO 如何促进可观察性

图 12.5:GitOps 与 DORA 和 SLO 如何促进可观察性

可以在多个 Kubernetes 集群中评估应用程序或整个堆栈的性能和效率。GitOps 不仅在促进应用程序在这些集群中的分布式部署中起着关键作用,还能使团队更深入地理解系统行为,从而促进软件交付过程中的持续改进。

让我们首先了解什么是 SLO 以及 DORA 的作用:

  • 理解 SLO:SLO 是具体且可衡量的目标,反映了期望的服务性能和可靠性水平。SLO 源自服务级别指标SLI),它们是衡量服务水平的定量指标,如延迟、错误率或正常运行时间。设定 SLO 涉及确定这些指标的可接受阈值,并在保证可靠性与追求创新和快速开发之间找到平衡。

  • DORA 指标的作用DORA指标(部署频率变更交付时间变更失败率恢复服务时间)作为 DevOps 性能的关键指标。这些指标提供了软件交付流程效率和有效性的洞察,帮助团队识别改进的领域。在 GitOps 的上下文中,这些指标可以被密切监控,以确保 GitOps 工作流提供的自动化和编排正在优化软件交付流水线。

集成 SLO 与 DORA 指标

将 SLO 与 DORA 指标结合创建了一个强大的框架,用于管理 Kubernetes 环境中的性能:

  • 部署频率和 SLOs:通过将部署频率与 SLO 对齐,团队可以确保发布新功能和更新的速度不会影响服务的可靠性。

  • 变更交付时间和 SLOs:监控变更交付时间与 SLO 性能的关系,可以帮助团队简化开发和部署流程,确保变更迅速实施而不影响服务质量。

  • 变更失败率和 SLOs:将变更失败率保持在 SLO 定义的阈值范围内,确保大多数变更能增强而非削弱服务性能。

  • 恢复服务时间和 SLOs:当服务水平低于 SLO 阈值时,恢复服务的时间指标变得至关重要。快速恢复不仅能满足 SLO 要求,还能最大限度地减少对终端用户的干扰。

应用多阶段方法

SLO 驱动的多阶段性能方法在 GitOps 工作流的每个阶段利用 DORA 指标:

  • 规划:在项目或功能开发开始时,使用 SLO 定义性能和可靠性目标。

  • 开发:将 DORA 指标集成到开发过程中,跟踪进展并确保编码实践与 SLO 对齐。

  • 部署:通过 GitOps 自动化部署流程,保持高频率的部署,并遵守 SLO 定义的性能标准。

  • 观察:在部署后持续监控 SLI 和 DORA 指标,以评估是否达到 SLO 并识别改进的领域。

将以 SLO 为驱动的性能策略和 DORA 指标融入 GitOps 和 Kubernetes 实践,为提升云原生应用的可靠性效率质量提供了一个结构化的路径。这种方法不仅优化了运营流程,还促进了持续改进的文化,确保组织能够在快速发展的云计算世界中适应并蓬勃发展。为了实现这一反馈循环,SRE 团队应与应用开发人员合作,获得端到端的改进。

下面的部分概述了如何通过 GitOps 集成跟踪,通过自动化 Linkerd 的部署和配置来提高云原生应用程序的可观察性和可靠性实践。

在 GitOps 工作流中实现使用 Linkerd 的分布式跟踪

在复杂的云原生应用程序生态系统中,理解服务交互的复杂网是诊断问题、优化性能和确保可靠性的关键。分布式跟踪作为这一背景中的重要工具,提供了对跨微服务请求流的可见性。

重要说明 - 跟踪 OpenTelemetry 与 Linkerd

虽然之前提到过 OpenTelemetry 用于分布式跟踪,但重要的是要解释 OpenTelemetry 和 Linkerd 之间的区别及其首选用例。OpenTelemetry 是一组工具、API 和 SDK,用于对软件性能和行为进行仪表化、生成、收集和导出遥测数据(指标、日志和跟踪),以帮助理解软件的性能和行为。

在您需要在 Kubernetes 环境中管理和观察服务之间通信时,特别是在不修改应用程序代码的情况下实现无缝集成时,首选 Linkerd 作为强大的服务网格。

当与 Kubernetes 的 GitOps 工作流集成时,诸如 Linkerd 之类的工具可以简化分布式跟踪的部署和管理,增强可观察性和操作效率:

  • 分布式跟踪:分布式跟踪提供了对请求如何在微服务架构中的各个服务之间传播的详细视图。每个请求都标记有唯一标识符,可以跟踪其路径和在服务之间的交互。这种可见性对于定位故障、理解延迟和优化服务交互至关重要。

  • 为什么选择 Linkerd 进行分布式跟踪?:Linkerd 是专为 Kubernetes 设计的轻量级开源服务网格。它提供了关键功能,如安全的服务间通信、可观察性和可靠性,无需修改您的代码。Linkerd 对分布式跟踪的支持允许开发人员和运维人员深入了解请求路径、各个服务的延迟贡献以及服务网格的整体健康状况。

将 Linkerd 集成到您的 GitOps 工作流中涉及在 Git 仓库中定义服务网格配置和分布式跟踪设置。这种 GitOps 方法确保 Linkerd 的部署和配置完全自动化、一致且可追溯,适用于所有环境。让我们逐步分解集成过程:

  • 安装和配置

  • 定义 Linkerd 安装:使用 Git 管理 Linkerd 安装和配置的声明规范,确保与您组织的安全性和可观察性要求保持一致。

  • 自动化部署:利用 Argo CD 和 GitOps 自动化将 Linkerd 部署到 Kubernetes 集群中。此自动化包括安装 Linkerd 控制平面和将 Linkerd sidecar 注入到服务 Pod 中。

  • 配置 分布式追踪

  • 追踪收集器集成:在 Git 仓库中指定配置,以将 Linkerd 与分布式追踪系统(如 Jaeger 或 Zipkin)集成。这包括配置 Linkerd 将追踪数据发送到收集器。

  • 服务注释:在 Kubernetes 服务清单中添加注释,以启用与 Linkerd 的追踪。这些注释指示 Linkerd sidecar 参与分布式追踪并转发追踪数据。

  • 可视化 和分析

  • 利用追踪仪表板:使用 Jaeger(图 12.6)或 Zipkin 提供的集成追踪仪表板来可视化和分析追踪数据。这些工具提供强大的功能,能够筛选、搜索并深入查看单个追踪的详细信息。

图 12.6:Jaeger UI 用于在 Kubernetes 集群中分布式追踪服务调用

图 12.6:Jaeger UI 用于在 Kubernetes 集群中分布式追踪服务调用

在 GitOps 框架中实施 Linkerd 的分布式追踪显著增强了云原生应用程序的可观察性和可靠性。通过 GitOps 自动化部署和配置 Linkerd,团队可以确保监控微服务交互的一致性和可扩展性。这一能力对于在 Kubernetes 环境的动态变化中保持高性能和弹性应用至关重要。

在本章的下一部分,我们将讨论如何通过 GitOps 的帮助,使用像 Uptime Kuma 和 OpenTelemetry 这样的工具启用外部和内部的可观察性。

在 GitOps 中实施监控,使用像 Uptime Kuma 和 OpenTelemetry 这样的工具

在云原生应用程序的动态和分布式世界中,有效的监控和告警对于确保系统的可靠性、性能和安全性至关重要。将这些实践整合到 GitOps 框架中,不仅简化了监控工具的部署和管理,还使操作实践与基础设施即代码IaC)的原则保持一致。特别是当利用 OpenTelemetry 等强大工具时,这种方法提供了一个连贯且自动化的体系,用于观察系统行为并从内部视角响应事件。同时,你也可以使用像 Uptime Kuma 这样的工具来实现服务的外部可观察性。

在 GitOps 框架中的监控涉及从整个基础设施和应用程序中收集、分析和展示指标和日志。这种数据驱动的方法使团队能够了解系统性能、识别趋势并检测异常。通过将监控配置和仪表板作为代码定义在 Git 仓库中,团队可以将版本控制、审查流程和自动化部署应用于监控基础设施,确保一致性和可靠性。例如,这些仪表板的分发可以通过 GitOps 部署到N个集群中。

Uptime Kuma – 您在线服务的外部看门狗

Uptime Kuma是一个开源监控工具,旨在跟踪各种服务和网站的正常运行时间、停机时间和性能。它是一个自托管的解决方案,意味着它运行在您的硬件或云基础设施上,提供对监控环境的完全控制。Uptime Kuma 提供了一个用户友好的界面,因其简洁性、灵活性和高性价比,正在成为开发人员和系统管理员的热门选择。Uptime Kuma 通过定期向您的服务或网站发送请求并监控其响应来确定其可用性和响应时间。

相比之下,DatadogPrometheus 与 Grafana提供了不同的监控方法。Datadog 是一个全面的云基础监控和分析平台,提供端到端的应用程序、基础设施和日志性能可视化。它特别以其与广泛的第三方服务的集成能力和先进的分析功能而闻名。

另一方面,Prometheus 是一个开源监控和告警工具包,主要设计用于可靠性和可扩展性。它擅长收集和存储时间序列数据,然后可以使用 Grafana(一个强大的开源监控与可观察性平台)进行可视化。Grafana 允许用户创建可定制的仪表板,以可视化 Prometheus 收集的指标。虽然 Prometheus 通过使用诸如 Blackbox Exporter 之类的导出器支持监控 HTTP、HTTPS、DNS、TCP 和 ICMP Ping 等各种协议,但实现这一点需要额外的设置和配置。

在接下来的各个小节中,我们将探讨 Uptime Kuma 的各种关键功能和优势,以便更好地理解该工具。

关键功能

Uptime Kuma 的主要功能如下:

  • 多协议支持:Uptime Kuma 支持通过 HTTP(S)、TCP、DNS 等协议进行监控。

  • 可定制的警报:用户可以根据各种标准配置警报,并选择他们偏好的通知方式。

  • 性能指标:跟踪响应时间,使用户能够监控其服务的性能,而不仅仅是可用性。

  • SSL 证书监控:可以监控 SSL 证书的过期情况,在证书过期前提醒用户

  • Ping 监控:提供使用 ICMP ping 监控服务器可用性和延迟的功能

核心功能

以下是其核心功能及工作原理的详细介绍:

  • 监控服务:Uptime Kuma 可以监控多种类型的服务,包括 HTTP(S) 网站、TCP 端口、具有特定预期状态的 HTTP(s) 端点、DNS 记录等。它允许用户配置监控间隔、超时和定义每项服务可用性的特定条件。

  • 告警和通知:当服务停机或满足用户设置的特定条件(例如高响应时间)时,Uptime Kuma 可以通过多种渠道发送告警。它支持多种通知方式,包括电子邮件、短信(通过第三方服务)、Telegram、Discord、Slack 等,确保用户能及时收到状态变化的通知。

  • 状态页面:Uptime Kuma 提供一个公开或私有的状态页面,显示所有监控服务的运行状态。此页面可以用来与团队成员或客户沟通各种服务的当前状态,增强透明度和信任度。

  • 详细的报告:它提供关于监控服务的正常运行时间、停机时间和响应时间的详细报告和分析。这些信息有助于识别模式、潜在问题以及改善基础设施或应用性能的领域。

  • 简单的设置和配置:Uptime Kuma 的设置过程非常简单。它可以部署在多个平台上,包括 Docker,这使得它在大多数环境中都容易安装和运行。基于 Web 的界面提供了一种简单直观的方式来添加和配置你想要监控的服务。

Uptime Kuma 是一个多功能且易于使用的工具,用于监控网站和服务的正常运行时间及性能。其自托管特性使用户能够完全控制监控设置,从而为企业和个人用户提供了一个安全且可定制的选择。凭借其广泛的协议支持、灵活的告警系统和详细的分析功能,Uptime Kuma 为确保在线服务的可靠性和性能提供了全面的解决方案。

OpenTelemetry – 一个统一的可观察性框架

OpenTelemetry 是一个开源的可观察性框架,旨在提供对软件应用程序行为的全面洞察。它通过收集、处理和导出遥测数据——具体来说是日志、指标和追踪——来实现这一目标。OpenTelemetry 旨在使开发人员和运维人员轻松获得系统的可见性,帮助调试、优化,并确保应用程序在各种环境中的可靠性。

主要功能

OpenTelemetry 的核心是仪表化,这是一种将 OpenTelemetry 库或代理集成到应用程序代码或运行时环境中的过程。此集成使 OpenTelemetry 能够从应用程序捕获详细的遥测数据:

  • 手动仪表化:开发人员可以使用 OpenTelemetry API 手动仪表化代码。这包括添加特定的代码片段,以生成遥测数据,如自定义指标、日志或用于应用程序中具体操作的跟踪。

  • 自动仪表化:OpenTelemetry 提供了可以附加到应用程序的自动仪表化代理。这些代理自动捕获遥测数据,无需修改应用程序代码,非常适合遗留系统或常见库和框架。

OpenTelemetry 收集三种主要类型的遥测数据:

  • 日志:记录应用程序中发生的离散事件,提供有关操作、错误和其他重要活动的详细上下文。

  • 指标:表示应用程序和系统性能各个方面的数值数据,随着时间的推移,诸如请求率、错误计数和资源利用率等。

  • 跟踪:关于事务或请求执行路径的详细信息,它们在应用程序及其服务中流动,展示了系统不同部分如何互动。

核心功能

以下是其核心功能及其工作原理的细分:

  1. 处理与增强:一旦遥测数据被收集,OpenTelemetry 可以处理并增强这些数据。处理可能包括聚合指标、过滤日志或向跟踪中添加额外的上下文,以使数据更有用和有意义。这一步骤对于减少噪音并增强收集数据的相关性至关重要。

  2. 导出数据:OpenTelemetry 支持将遥测数据导出到各种后端可观察性平台,在这些平台上可以分析、可视化和监控数据。它为流行的监控解决方案、云原生可观察性工具和自定义后端提供导出工具。OpenTelemetry Collector 是一个可以作为基础设施的一部分部署的组件,在这一过程中起着关键作用。它可以接收、处理并导出来自多个来源的遥测数据,充当可观察性数据的中央枢纽。

  3. 分析与行动:OpenTelemetry 工作流中的最后一步是使用可观察性平台分析导出的遥测数据。这些平台允许团队通过仪表盘可视化数据,基于特定条件设置警报,并从中提取可用于故障排除、性能优化和决策过程的见解。

实现 OpenTelemetry 监控

以下是如何在 GitOps 中实现 OpenTelemetry 监控:

  • 将监控配置定义为代码:将 OpenTelemetry Collector 配置存储在 Git 仓库中,指定数据的收集、处理和导出方式。此设置确保监控配置与应用代码一样,受到相同的审查和部署实践的管理。

  • 监控基础设施的自动化部署:使用 GitOps 管道自动部署和更新 OpenTelemetry Collectors 以及其他监控组件,覆盖您的 Kubernetes 集群。此自动化确保监控基础设施在所有环境中始终如一地部署。

  • 应用程序的仪器化:将 OpenTelemetry SDK 集成到您的应用代码中,以捕获详细的性能指标和追踪信息。通过 Git 管理 SDK 配置,能够实现受控更新并确保跨服务的一致性。

OpenTelemetry 提供了一个统一且供应商中立的框架,用于捕获、处理和导出遥测数据,使开发人员和运维人员能够深入观察应用的性能。通过简化日志、指标和追踪的收集,并使这些数据能够轻松导出到分析工具,OpenTelemetry 有助于更好地理解软件的性能和行为,最终提升应用的可靠性和效率。

OpenTelemetry 提供了一个统一的、供应商中立的框架,用于从应用和基础设施收集追踪、指标和日志。它简化了代码的仪器化和代理的部署,提供了一种标准化的方式来收集遥测数据,这些数据可以由各种可观察性平台进行分析。

下一部分讨论了可以集成到 GitOps 框架中的可能警报策略。

查看 GitOps 框架中的警报策略

有效的警报是指在正确的时间,将正确的信息通知给正确的人。在 GitOps 框架内,警报规则和通知配置作为代码定义,并与应用和基础设施配置一起进行管理:

  • 将警报规则定义为代码:将警报规则的定义存储在 Git 仓库中,指定触发警报的条件。这种方法能够实现版本控制和警报规则的自动化部署,确保它们得到一致的应用。

  • 与通知渠道的集成:将与通知渠道(如电子邮件、Slack 或 PagerDuty)的集成配置作为 GitOps 工作流的一部分。这样可以确保警报通知可靠地发送给合适的团队或个人。

  • 持续改进的反馈循环:实施反馈循环,利用监控和警报数据来指导开发和运维实践。将这些反馈融入到 GitOps 流程中,有助于持续改进应用性能和运营效率。

图 12.7 展示了如何将 GitOps 与 Argo CD 一起使用,以将规则和通知通道作为代码部署到不同的集群中:

图 12.7:通过 GitOps 和可观察性实现持续改进

图 12.7:通过 GitOps 和可观察性实现持续改进

开发人员或平台工程师可以利用观察得到的信息,通过反馈锁的形式优化他们的应用。这可以用于例如在某些事情被忽视时定义新规则,并且借助 GitOps 方法,可以在 N 个集群中推行这些规则。

一些相关的警报规则

以下是来自不同项目的一些见解,说明平台工程师团队如何定义规则集并在各处部署 Kubernetes 集群,帮助开发人员更好地理解他们的应用,并践行 SRE 方法:

  • 动态调整阈值:实施规则,根据历史数据或当前负载调整阈值,以最小化误报并提高通知的相关性。

  • 监控依赖关系:设置规则来监控服务和组件之间的依赖关系,主动识别潜在问题,以免它们影响用户体验。

  • 确保日志完整性:建立规则,检查日志的完整性和结构化。这有助于提高故障排除和分析的有效性。

  • 资源利用率警报:创建规则来监控 CPU、内存和磁盘空间等资源的利用情况。设置警报,当使用接近临界阈值时,表明可能出现过度承诺或资源耗尽的风险。

  • 延迟监控:实施规则来监控关键操作或 API 调用的延迟。高延迟可能是系统负载过重或处理资源过度承诺的早期指示。

  • Kubernetes 中的节点过度承诺:这是我最喜欢的警报规则之一,已经帮助了大量团队,尤其是那些拥有许多小型定制集群的团队。通过监控和警报节点过度承诺,它帮助防止性能下降,并确保在 Kubernetes 上运行的应用程序的可靠性。通过为节点过度承诺设置警报规则,团队可以在节点需求超过其容量时及时采取预防措施,防止性能下降,确保应用程序保持可靠。这种方法不仅提高了系统的稳定性,还支持了资源的最佳利用,是维护 Kubernetes 集群健康和高效的重要实践。

深入了解 Kubernetes 中的节点过度承诺

我将在这里进一步拆解 Kubernetes 中的节点过度承诺 规则,让大家清楚为什么如此简单的规则及其相关警报会附加在此规则上:

  • 资源利用的可持续性:监控节点过度承诺可以更高效地使用计算资源,减少能源消耗,并有助于组织的可持续发展目标。高效的资源利用减少了不必要的工作负载和空闲资源,符合环保实践。

重要提示

FinOps,即财务运营,是一种结合了系统、最佳实践和文化的做法,旨在帮助组织更有效地管理和优化云成本。它专注于创建一个跨职能团队合作的方式,将财务问责制引入云的可变支出模型,从而使企业能够做出更快速、更明智的决策。

  • FinOps 与成本优化:通过防止过度承诺和优化资源分配,组织可以遵循 FinOps 原则,确保云支出与业务价值相一致。针对节点过度承诺发出警报有助于避免过度配置和资源未充分利用,从而带来显著的成本节约和更可预测的云开支。

  • 增强的应用性能:主动管理节点资源确保应用程序在需要时能够获得所需的计算能力,从而提升用户体验和应用性能。

  • 可靠性和可用性:避免节点过度承诺有助于提升服务的整体可靠性和可用性,因为资源得到了平衡,潜在的故障点得到了最小化。

  • 可扩展性:有效的监控和管理节点过度承诺为基础设施的可扩展性做好准备,使得在不影响性能或产生不必要成本的情况下,可以平稳地扩展以适应不断增长的工作负载。

将这些考虑因素融入 Kubernetes 资源管理实践中,不仅解决了即时的运营问题,还使组织能够更好地将技术战略与环境可持续性、财务问责制和长期可扩展性对齐。

在 GitOps 框架中采用监控和警报策略提供了一种系统化和自动化的可观察性方法。在该框架内利用像 OpenTelemetry 这样的工具可以增强遥测数据的粒度和实用性,从而推动更为明智的决策制定和运营弹性。这种方法不仅确保了系统性能和可靠性的高水平,还促进了云原生环境中持续改进和卓越运营的文化。

本章的最后部分讨论了如何借助 GitOps 实现可观察性的扩展。

使用 GitOps 扩展可观察性

随着组织的增长以及技术栈的日益复杂,确保在大规模环境下的有效可观察性变得异常具有挑战性。云原生架构、微服务和动态环境,所有这些都通过如 GitOps 等实践进行管理,带来了传统可观察性策略难以适应的复杂性。 本节探讨了为实现大规模的全面可观察性所必需的先进实践、工具和组织策略,确保系统不仅是可观察的,而且是可管理的,无论其规模和复杂性如何。

扩展可观察性组件

大规模可观察性的基础在于有效地管理三大支柱:日志记录监控追踪。这三个组件必须经过深思熟虑地扩展,以处理大型分布式系统生成的大量数据,同时不影响从数据中得出见解的速度或准确性。高效的数据管理不仅对技术性能至关重要,还对成本管理至关重要,因为存储和分析的数据量会显著影响项目开销。

接下来,我们将探讨在大规模环境下,日志记录、监控和追踪的行为表现:

  • 大规模日志记录:实施结构化日志记录,以标准化服务之间的日志格式,使它们更容易聚合和分析。利用集中式日志解决方案,处理大量数据,提供强大的搜索和分析工具,从日志中快速得出见解。

  • 大规模监控:利用支持高频数据收集的可扩展监控解决方案,并能够根据云原生环境的拓扑变化动态调整。采用像 Linkerd 或 Istio 这样的服务网格,它们为 Kubernetes 集群提供内置的可观察性功能,减少了对单个服务的开销。

  • 大规模追踪:在微服务架构中,分布式追踪变得至关重要,用于追踪请求在各个服务之间的流动。像 Jaeger、Zipkin 或服务网格提供的解决方案,结合 OpenTelemetry,提供可扩展的追踪功能。实施追踪采样策略,平衡追踪数据的粒度与收集和存储数据的开销。

大规模可观察性的高级工具

采用合适的工具对于大规模管理可观察性至关重要。像Prometheus 用于监控Elasticsearch 用于日志记录、以及OpenTelemetry 用于仪表化这样的工具之所以被选用,是因为它们是开源的,遵循 OpenTelemetry 指南,并提供强大的社区支持解决方案。将这些工具集成到 GitOps 工作流中,确保可观察性基础设施可以像其所监控的应用程序和服务一样高效地部署、扩展和管理。

我们可以使用 GitOps 实践,根据系统当前的需求和规模动态配置可观察性工具。这包括根据系统的增长自动扩展数据存储、处理能力,并部署额外的监控或追踪代理。

另一个不错的想法是结合 AI 和 ML 技术进行异常检测和预测分析,帮助在大数据集中筛选噪声,并在问题影响用户之前识别潜在问题。

在接下来的子章节中,我们将探讨如何通过跨职能合作、持续教育和战略性反馈循环来培养可观察性文化。

有效可观察性的组织策略

大规模的可观察性不仅仅是技术挑战,还是一个组织性挑战。培养可观察性的文化需要整个组织的参与,从开发人员到运维人员,再到业务利益相关者:

  • 跨职能团队:鼓励开发、运维和业务团队之间的合作,确保可观察性目标与业务目标和操作需求对齐。这种合作促进了对需要观察的内容及其原因的共同理解。

  • 教育与倡导:投资培训和资源,确保团队理解可观察性的重要性,并能够在大规模环境中有效利用工具和实践。倡导可观察性作为系统设计和操作的基本组成部分,确保其在整个开发生命周期中得到整合。

  • 持续反馈循环:建立反馈循环,将可观察性数据反馈到开发过程中,帮助决策并推动持续改进。这包括利用可观察性数据来优化性能基准、调整告警阈值,并优先考虑开发工作。

在大规模实现可观察性需要一种全面的方法,不仅仅是依赖工具,还要涵盖组织的实践和文化。通过将可扩展的可观察性工具与 GitOps 工作流结合,利用先进的数据处理技术,培养协作和持续改进的文化,组织可以确保其系统在任何规模下都能保持可观察、可管理和高效。这个全面的方法不仅解决了大规模可观察性的技术挑战,还将可观察性实践与更广泛的商业目标对齐,从而在当今动态复杂的技术环境中推动价值和竞争优势。

在接下来的部分,我将分享一些洞察,帮助你决定哪些工具可能对你的配置有用。

为特定用例选择合适的可观察性工具

选择合适的可观测性工具取决于你的具体监控需求和预期结果。通常这并不容易,因为许多使用场景看似相似,但要求不同。以下是一些见解,帮助你将不同的工具组合成最佳的可观测性堆栈。目标不是找到完美的工具,而是专注于不同的可观测性层级。为了更清晰地理解可观测性及其不同需求,我已添加了可能的相关方。这份清单并不详尽,但包含了基于多个实际项目的关键相关方及其利益。我希望这些见解能够帮助你充分利用可观测性设置。

重要提示

本节更多地关注何时使用哪些工具,而不是 GitOps 本身,提供了可观测性的全面视角。许多问题可能会出现,比如,“我理解了带有可观测性的 GitOps,但我应该在何时使用哪些工具?”通过探索各种使用场景,我们希望帮助你了解每种特定场景下哪个工具最适合。

让我们探索一些常见场景及最适合每种使用场景的工具。

监控应用程序的可用性和证书的过期

  • 使用场景:你希望确保应用程序可用,分配 SLA,监控 SSL 证书过期,并接收警报。

  • 推荐工具:Uptime Kuma

  • 解释:Uptime Kuma 非常适合这种场景,因为它支持多协议监控(HTTP(S)、TCP、DNS),并提供可定制的停机和 SSL 证书过期提醒。它操作简单且性价比高,非常适合进行基础的可用性监控。

  • 相关方

    • 服务负责人:监控整体服务健康,确保所有服务正常运行

    • 开发人员:理解变更如何影响用户体验,并诊断生产环境中的问题

    • 客户:确保服务满足所提供的 SLA

监控资源利用率和 应用日志

  • 使用场景:你需要追踪 CPU、RAM 和存储使用情况等指标,并分析应用日志。你还希望在这些指标超过某个阈值时接收通知。

  • 推荐工具:Prometheus + Grafana-Stack + Alertmanager

  • 解释:Prometheus 擅长收集和存储时间序列数据,包括资源利用率指标。Grafana-Stack 不仅提供强大的可视化功能,允许创建详细的仪表盘,还能够收集和丰富日志。Alertmanager 与 Prometheus 集成,用于基于预定义阈值处理警报。

  • 相关方

    • 站点可靠性工程师:监控系统健康和资源使用情况,确保系统的可靠性和性能

    • 开发人员:使用日志和指标调试和优化应用性能

    • DevOps 工程师:自动化监控和警报,以简化操作

检测应用程序在 主机系统中的异常行为:

  • 使用场景: 你希望在应用程序对主机系统执行未授权操作(例如打开 shell)时获得通知。

  • 推荐工具: Falco + Prometheus + Alertmanager

  • 说明: Falco 是一个运行时安全工具,它可以检测应用程序和主机系统中的异常行为。它与 Prometheus 集成用于监控,并与 Alertmanager 配合处理警报,为检测和响应安全威胁提供了全面的解决方案。

  • 利益相关者:

    • 安全团队: 监控并响应潜在的安全威胁

    • 系统管理员: 确保系统的完整性和合规性

追踪数据包丢失和 识别瓶颈:

  • 使用场景: 你需要了解为何数据包丢失以及请求在哪些地方遇到延迟,而不需要修改应用程序代码。

  • 推荐工具: Linkerd + Jaeger

  • 说明: Linkerd 是一个轻量级的服务网格,它能够提供服务间通信的可观察性,而无需修改代码。Jaeger 是一个分布式追踪系统,它与 Linkerd 集成,追踪请求在微服务中的流动,帮助你识别并优化性能瓶颈。

  • 利益相关者:

    • 网络工程师: 诊断并解决与网络相关的问题

    • 开发者: 识别并修复应用程序中的性能瓶颈

    • 站点可靠性工程师: 识别并修复性能瓶颈,以确保系统的可靠性

通过 SDK 定制和丰富日志:

  • 使用场景: 你想通过 SDK 调整和丰富应用日志。

  • 推荐 工具: OpenTelemetry

  • 说明: OpenTelemetry 提供了全面的支持,用于收集、处理和导出遥测数据(日志、指标和追踪)。它支持手动和自动化的代码仪表化,允许对日志进行详细的定制和丰富。

  • 利益相关者:

    • 开发者: 定制和丰富日志,以便更好地进行调试和性能监控

    • 站点可靠性工程师: 定制和丰富日志,以确保系统的可靠性和性能

所有提到的工具都是开源的。这一点很重要,因为使用开源工具可以确保我们避免厂商锁定,依赖强大的社区,并且在需要时具有灵活性,可以进行贡献并获取帮助。

在接下来的部分,我们将了解 GitOps 中的可观察性如何影响我们在公司中的日常工作。

企业级最佳实践:具有可观察性和 GitOps 的最佳实践

我不知道这些是否真的是企业级的最佳实践。我只能说,在本节中分享的内容是我们在多个不同项目中使用的良好实践,并将这些见解与大家分享。在本节中,我将提供关于 GitOps 如何最大化我们可观察性堆栈的效率和效果的详细见解。

接下来,我们将探讨不同的利益相关者如何使用 GitOps 方法为自己创造附加价值。

  • 服务负责人:GitOps 允许负责多个集群中不同服务的服务负责人,只需定义一次其 Grafana 仪表盘,然后可以独立地将其作为 ConfigMaps 在所有相关集群中推广。这一方法也适用于他们各自服务的警报。

  • 平台团队:GitOps 使我们作为平台团队能够部署我们的监控栈,而不受集群数量的限制。这一能力使我们能够高效地监控我们的基础设施和提供的服务,按需扩展栈,并轻松维护。

  • 实习生:例如,我们的实习生可以定义自己的 Grafana 仪表盘,以集成用于测量汉堡市桥梁下净空高度的传感器。这些仪表盘只需定义一次,然后就可以在所有必要的集群中推广。

  • 服务提供商:这些负责多个集群中的服务,如 RabbitMQ(消息中间件),并使用 GitOps 方法在所有集群中部署警报配置,并将其集成到外部警报系统中。

  • 开发人员:这些人员采用与服务提供商类似的方法,通过相应的仪表盘和警报交付他们的软件。

  • 安全团队:一种新兴但前景广阔的做法是将安全团队纳入可观察性流程。然而,这种做法并未成功,因为例如,在我们的项目中,安全团队习惯于根据公司利益独立制定规则。为此,他们使用自己的工具,这会造成额外的开销。

  • 财务运维部门:目前,这一做法无法实施,因为可观察性主题和 Kubernetes 平台在技术上都过于复杂。例如,根据与项目相对应的 Namespace 计算的成本,通过 YAML 清单创建预算警报是具有挑战性的。

目前,在大多数项目中,平台团队通过推出 Falco 规则和 Prometheus 警报配置来处理安全问题,例如,检测节点上的不必要的系统调用,如 shell 打开,并据此触发警报。然而,这通常会增加责任负担,可能导致警报未被彻底调查。

GitOps 方法显著提升了我们的可观察性实践,通过节省时间和成本,向利益相关者提供必要的自主权,并提高整体动力。通过创建一个让团队能够管理他们的可观察性配置,而无需不断往返工单的环境,我们促进了独立性和健康的错误文化。团队明白,如果出现问题,简单的提交回滚就能恢复到之前的状态,从而使得流程更加可靠和具有韧性。这种方法改变了不同部门之间的协作,确保了可观察性无缝融入我们的开发和运维工作流中。

内在动机驱动了公司内部对可观察性的基本技术理解,这是一个显著的优势。这有助于提高员工的参与度和创新能力。赋能所有员工为可观察性栈做出贡献并加以改进,使得组织更加具有韧性、适应性,并且更好地准备应对新的挑战。这种协作方法不仅提升了团队效率,还促进了持续改进和共同责任的文化。

坦白说,我真的很喜欢文化的变化方式!这是我们在传统的 DevOps 和 CI/CD 中无法实现的一点,尽管 DevOps 具有讽刺意味地正好描述了这种文化。

摘要

本章全面探讨了云原生应用中的可观察性,强调了它在 GitOps 和 Kubernetes 环境中各个维度中的关键作用。从 SRE 的基础原则入手,我们探索了这些实践如何无缝地融入 GitOps 工作流,提升了 Kubernetes 部署的可靠性和性能。明确了内部和外部可观察性的区别,突出了平衡方法对全面系统洞察的重要性。我们进一步深入探讨了与 DORA 指标对齐的 SLO 驱动的性能指标的战略实施,提供了一个持续改进的结构化框架。通过 Linkerd 的视角,我们审视了在 GitOps 中部署分布式追踪,突显了它为微服务架构带来的增强可视性和诊断能力。讨论了通过 OpenTelemetry 等工具支持的监控和告警策略,以建立主动的事件管理和系统健康监控。最后,针对满足日益复杂和庞大系统需求的可观察性扩展进行了探讨,展示了先进工具、组织策略以及重视可观察性的文化的必要性。本章概述了在现代云原生生态系统中实施和扩展可观察性的整体视角,确保系统不仅可观察,而且具有韧性和高效性。

但最重要的学习内容应该是,希望你能理解可观察性是多元化的,不仅仅是日志、指标和追踪!

在下一章,我们将探讨与 GitOps 相关的安全部分,并查看使用 Argo CD 时的攻击可能性以及如何将这些风险降到最低。

参考文献

第十二章:GitOps 安全性

实现 GitOps 为软件开发过程的安全性提供了多个好处。通过将 Git 用作配置和代码的中央源,可以确保环境的完整性和可追溯性。在本章中,我们将探讨 GitOps 背景下的安全性各个方面。

我们将从分析广为人知的 CockpitFleet 方法开始,并通过它们突出使用 Argo CD 时的各种安全考虑。接下来,我们将重点关注 Kyverno 作为 策略引擎,它充当门卫,定义集群中允许的操作以及哪些部署是被允许的。

权限问题在 GitOps 的背景中占据核心地位。因此,我们将讨论安全处理密钥,并介绍已在行业中成功采用的两种工具。

从平台团队的角度,我们将考虑为开发人员提供上下文信息,如 cert-manager、Ingress 控制器等。在这里,我们将使用经过验证的 Kubernetes 服务目录 原则,并探索其安全应用和更新。

最后,我们将看看 KubeClarity 工具,它能清晰地显示运行应用程序中的漏洞,包括以下各个层级:

  • 配置:Kubernetes 资源的错误配置

  • 镜像:容器镜像中的漏洞

  • 代码:应用代码中的安全漏洞

此外,我们还将简要介绍操作系统级别或内核级别,并查看 Falco 工具。该工具可用于检测主机上的可疑活动,例如执行不应执行的操作。

本章的目标是阐明不同层面的不同视角,从而更好地理解 GitOps 如何帮助团队提升安全性。

我们将在本章中讨论以下主要话题:

  • 加固 Kubernetes 上的声明式 GitOps CD

  • 将所有内容提交到 Git 吗?那密钥怎么办?

  • 利用策略引擎进行政策即代码实践

  • 自动化安全扫描与合规性

  • 保持平台目录的最新状态

加固 Kubernetes 上的声明式 GitOps CD

在这一部分,我们将深入探讨加固 Kubernetes 上声明式 GitOps 持续交付CD)所必需的实践,重点提升安全性并减少配置错误的风险——这是云安全漏洞的主要原因之一。向云原生技术的转变简化了系统、操作理论和技能的复杂性,为构建和管理应用提供了更清晰、更安全的框架。然而,这些系统的安全性不仅仅涉及软件开发和供应链方面;它还至关重要地涉及解决配置漏洞。

解决配置漏洞

云原生技术简化了技能组合、操作理论和系统复杂性,提升了系统架构的可理解性和安全性。然而,主要的云安全风险仍然是配置错误,这往往在专注于开发和供应链安全时被忽视。GitOps 模式的采用,特别是在渐进式应用交付方面,已经变得广泛,提供了一种比传统的直接构建到生产环境的服务器更安全的替代方案。这种方法使用 Git 仓库来管理更改,能够进行部署前的安全评估,并最大限度地减少权限提升和配置漂移。

云原生计算基金会委托ControlPlane[1]对 Argo CD 进行详细的威胁建模分析,Argo CD 是 GitOps 方法的典型工具,重点关注其在多租户 Kubernetes 环境中的部署。该分析揭示了 19 个已识别的威胁,其中 6 个被列为高优先级,强调了需要采取严格安全措施的必要性。硬化建议包括加强密码管理、集成单点登录、并应用严格的基于角色的访问控制RBAC)原则,以限制对敏感信息的访问。

来自 ControlPlane 的报告[1]还提供了最关键威胁的可视化攻击树,帮助利益相关者理解并减轻风险,同时对 Argo CD 部署架构提供全面概述。报告中包括用于复制设置的 Terraform 代码,确保能够有效验证安全控制。这些措施基于报告的发现,旨在加强 Argo CD 部署的安全性,使其符合组织的安全标准,并最大化 GitOps 在云原生生态系统中的应用优势。

我们将从报告中整合部分内容,并将其与广为人知的 Cockpit 和 Fleet 方法结合起来。该报告来自 2023 年,涉及Argo CD 版本 2.67,一些问题可能已经在更新的 Argo CD 版本中得到解决。撰写本文时,Argo CD 版本 2.10被认为是稳定版本。我们将对比报告中的具体内容与Argo CD 版本 2.10进行比较。

在本节中,我们不会逐一讲解整个报告,而是选择几个项目进行讨论。每个潜在威胁将缩写为ATM-ID,并根据优先级从低到高进行分类。这些威胁将分为三类。表 13.1展示了变更影响评估CIA)如下:

机密性 由于管理员凭证泄露导致集群接管(操作、租户)
中等 敏感信息与应用或集群状态相关被泄露
非敏感信息泄露
完整性 源代码仓库和应用部署被破坏
中等 因配置错误/无效配置导致应用同步失败
由于配置错误/无效配置,非关键操作被阻止
可用性 集群(操作、租户)面临拒绝服务DoS)风险
托管的应用程序在一段时间内被阻止
托管的应用程序同步在短时间内被阻止

表 13.1 – 变更影响评估 [1]

增强密码管理和 RBAC

现在,让我们来查看我们在 Cockpit 和 Fleet 方法中可以识别出威胁的部分。这将在图 13.1中用感叹号和 ID 标出:

图 13.1 – Cockpit 和 Fleet 方法结合威胁模型

图 13.1 – Cockpit 和 Fleet 方法结合威胁模型

现在,第一个 ID,ATM-004,位于表 13.2中的Argo CDs RBAC类别下:

ID UID 类别 优先级
ATM-004 KR-AR-002 Argo CD RBAC

表 13.2 – ATM-004:UI 本地用户的凭证永不过期,并且没有强身份验证

这里的风险在于,Argo CD UI 本地用户的凭证永不过期,且仅基于用户名和密码,没有二次身份验证。优先级已经设置得过高。考虑到 Cockpit 可以访问其他集群,我个人认为这一点变得更加关键。

危险在于,如果凭证被泄露,可能会发生未经授权的更改。

重要提示

OAuth2OpenID Connect (OIDC)是安全授权和身份验证协议。OAuth2 允许安全地访问资源,而 OIDC 则在 OAuth2 的基础上添加了用户身份验证。它们通过基于令牌的身份验证,确保在不暴露凭证的情况下安全地共享数据,从而增强了应用程序的安全性。

Dex是一个开源身份服务,使用 OIDC 对用户进行身份验证,并提供对各种应用程序和服务的访问。

Microsoft Entra ID,前身为Azure Active Directory (AAD),是微软提供的一种基于云的身份与访问管理服务。

因此,建议仅在初始配置时使用本地管理员账户,然后通过提供的 Dex 服务器和支持 OAuth2 的 OIDC 提供程序(如 Microsoft Entra ID)切换到单点登录,从而实现角色与相应组的映射。随后,应禁用管理员访问,因为管理员访问并不会提供比将管理员组映射到 Azure 组的最高权限更广泛的权限。

然后,可以在argocd-rbac-cm配置映射中进行如下调整:

apiVersion: v1
data:
  policy.csv: |
    p, role:org-admin, applications, *, */*, allow
    p, role:org-admin, clusters, get, *, allow
    p, role:org-admin, repositories, get, *, allow
    p, role:org-admin, repositories, create, *, allow
    p, role:org-admin, repositories, update, *, allow
    p, role:org-admin, repositories, delete, *, allow
    g, "GROUP_ID", role:org-admin
  policy.default: role:readonly
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-rbac-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-rbac-cm
  namespace: argocd

随后,可以在argocd-cm中禁用本地管理员:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-cm
  namespace: argocd
  labels:
    app.kubernetes.io/name: argocd-cm
    app.kubernetes.io/part-of: argocd
data:
  admin.enabled: "false"

如果我们还考虑到管理员密码(ATM-003)作为 Kubernetes Secret 存在,那么希望它能清楚地说明,如果攻击者获得了 Fleet 集群的访问权限,或者更糟的是,获得了 Cockpit 的访问权限,从而能够访问 ServiceAccounts 进而访问其他集群,这可能会有多么危险。

ID UID 类别 优先级
ATM-003 KR-AR-001 Argo CD RBAC

表 13.3 – ATM-003:初始管理员密码作为 Kubernetes Secret 存储

如果攻击者获得对 Fleet 集群的访问权限,或者更糟的是,获得对控制 ServiceAccounts 的 Cockpit 的访问权限,从而可以访问其余集群,则存在重大风险。这种情况可能导致由于未经授权读取 Argo CD 初始管理员密码从 Kubernetes Secrets 中,导致 Argo CD 配置的未经授权更改

因此,建议旋转 Argo CD 管理员密码并删除该秘密,因为 Argo CD 仅创建该秘密用于访问目的,但不需要该秘密本身。根据 Argo CD 的文档,该秘密仅用于存储初始生成的密码的明文,并且可以在任何时候安全地删除。

要修改管理员密码,请按照以下步骤操作。建议将此指南传递给每个管理舰队集群的用户或团队。最佳做法是过渡到 OIDC,然后按照之前的说明停用管理员账户。然而,如果需要更改密码,则应遵循以下程序:

重要提示

这些命令在类似 Unix 的操作系统上运行,如 Ubuntu、Debian 或其他 Linux 发行版,以及 macOS。

  1. 首先,转发到 argocd server

    kubectl port-forward --namespace argocd service/argocd-server 8080:443
    
  2. 密码可以通过 Argo CD 命令行 接口CLI)轻松访问:

    admin as username  and password, log in to Argo CD’s IP or hostname:
    
    

    argocd login <ARGOCD_SERVER>

    
    
  3. 使用以下命令更改密码:

    argocd account update-password
    
  4. 作为之前步骤的替代方法,您可以通过将命令合并成一行来使用更简洁的方法,如下所示:

    kubectl port-forward svc/argocd-server -n argocd 8080:443 & argocd login localhost:8080 --username admin --password $(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d) --insecure --grpc-web
    
  5. 然后,按如下方式更新密码:

    argocd account update-password
    
  6. 现在,按如下方式终止在后台运行的转发进程:

    kill $(ps aux | grep 'kubectl port-forward svc/argocd-server -n argocd 8080:443' | grep -v grep | awk '{print $2}')
    

现在我们已经更新了密码,让我们来看最后一部分,ATM-006表 13.4),它在 Cockpit 和 Fleet 方法的背景下尤为重要:

ID UID 类别 优先级
ATM-006 KR-ASM-001 Argo CD 秘密管理

表 13.4 – ATM-006:永不过期的租户集群凭据作为 Kubernetes Secrets 存储

这里的风险在于 Argo CD 租户集群凭据作为 Kubernetes Secrets 存储,并且租户集群上的 Argo CD argocd-manager 服务账户令牌配置为永不过期。

因此,攻击者可能会由于未经授权访问 Kubernetes Secret 中的永不过期的租户承载令牌,从而在租户集群上执行未经授权的操作。

根据提供商和 Kubernetes 分发版本的不同,可以应用不同的缓解策略。建议使用 工作负载身份或托管身份,特别是在像 Azure Kubernetes 服务等服务中,这样可以让集群在没有机密的情况下访问 Azure 资源。或者,可以考虑利用外部的 密钥管理服务(例如 AWS 密钥管理服务)来安全管理和暴露 Argo CD 租户集群凭证。至关重要的是,确保 Argo CD 租户集群的持有令牌定期轮换,遵循组织的安全政策。对于手动轮换,删除租户集群中相应的 Kubernetes Secret 将触发新令牌的创建。

然而,本节的目的是不讨论所有安全漏洞,因为我认为由于其多样性,覆盖所有漏洞是没有必要的。本节旨在提高对使用 GitOps 时可能出现的安全漏洞的意识,以及如何尝试应对这些问题。

图 13.2 现在应该能够清楚地表明,我们仅减轻了三种可能的高级攻击:

图 13.2 – Cockpit 和 Fleet 方法结合威胁模型 – 减少攻击面视图

图 13.2 – Cockpit 和 Fleet 方法结合威胁模型 – 减少攻击面视图

大多数系统常见的机制,如防火墙规则,应当被实现,以限制对 Cockpit 集群的访问,确保只有指定的 IP 地址范围可以访问。同样,访问 Fleet 集群的权限也可以通过防火墙进行限制,防火墙可能来自 Cockpit 集群本身,并且仅限于某些 IP 范围。保护集群访问尤其是 Cockpit 集群的安全至关重要,多因素身份验证MFA)可以显著减少初始攻击面。尽可能地,应该用身份解决方案替换永久令牌,从而无需使用机密就能便捷访问。

我强烈建议深入了解 ControlPlane 提供的 威胁模型 文档。文档中包括详细的 攻击树,展示了如何利用多个漏洞可能带来深远影响。对这些内容的全面了解对于有效保护你的基础设施至关重要。

下一节将讨论 GitOps 的做法,即一切都在 Git 中,但机密怎么办?本节将探讨如何在 Git 中安全存储机密。

把所有内容都提交到 Git 中?那机密怎么办?

在 GitOps 工作流中,将每一项配置提交到 Git 仓库是核心思想。这确保了您的基础设施的整个状态被声明式地表示,并且可以进行版本控制、审计和审查。然而,这种方法在处理机密信息(如密码、令牌和私钥)时会带来挑战。将这些敏感信息直接存储在 Git 仓库中并不安全。这时,像密封机密和外部机密这样的工具就派上用场,它们为在 GitOps 工作流中管理机密提供了安全的机制。

密封机密

密封机密 [2] 是一个 Kubernetes 控制器和工具集,旨在加密可以安全存储在 Git 仓库中的机密。当您将密封机密应用到集群时,Sealed Secrets 控制器会解密它并创建一个常规的 Kubernetes 机密。这个过程允许您通过 Git 管理机密的生命周期,而不会暴露敏感内容。

如下使用:

  1. 在本地机器上使用kubeseal CLI 工具,如下所示:

    helm repo add sealed-secrets https://bitnami-    labs.github.io/sealed-secrets
    helm install sealed-secrets sealed-secrets/sealed-secrets
    #Install e.g. CLI on MacOS
    brew install kubeseal
    
  2. 密钥对:生成密钥对或使用部署的 Sealed Secrets Operator 中的证书:

    kubectl -n sealed-secrets get secret sealed-secrets-… -o json -o=jsonpath="{.data.tls\.crt}" | base64 -d > sealed-secret.crt
    
  3. 密封机密:使用 kubeseal CLI 工具加密您的机密。CLI 会生成一个SealedSecret 资源,您可以将其提交到您的 Git 仓库中:

    mysealedsecret.yaml to your Git repository. When you apply this file to your cluster, the Sealed Secrets controller decrypts it and creates a standard Kubernetes secret.
    
  4. 与 GitOps 的自动化:将此过程集成到您的 GitOps 工作流中。每当您在 Git 中更新密封机密时,您的 CI/CD 流水线可以自动将其应用到集群中。

外部机密

外部机密 [3] 是一个开源项目,它将外部机密管理系统(如 AWS Secrets ManagerAzure Key VaultGoogle Secret Manager)与 Kubernetes 集成。它允许您安全地将机密注入到应用程序中,而无需在 Git 仓库中暴露这些机密。

如下使用:

  1. 部署:在您的 Kubernetes 集群中部署 External Secrets Operator:

    helm repo add external-secrets https://charts.external-secrets.io
    helm install external-secrets external-secrets/external-secrets
    
  2. 配置:定义一个ExternalSecret 资源,指定外部机密存储和机密密钥。操作器从外部存储中获取机密,并在集群中创建一个 Kubernetes 机密:

       apiVersion: external-secrets.io/v1beta1
       kind: ExternalSecret
       metadata:
         name: my-external-secret
       spec:
         secretStoreRef:
           name: my-secret-store
           kind: SecretStore
         target:
           name: my-kubernetes-secret
         data:
         - secretKey: external-secret-key
           remoteRef:
             key: name-of-the-secret-in-external-store
    
  3. 应用外部机密:将ExternalSecret 资源提交到您的 Git 仓库。External Secrets Operator 将根据外部源自动在您的集群中创建或更新 Kubernetes 机密。

  4. 与 GitOps 集成:将外部机密纳入您的 GitOps 流水线。对 Git 仓库中ExternalSecret 定义的更改会触发操作器同步机密,确保您的集群机密始终保持最新。

工具的选择取决于各种因素。例如,如果您没有用于存储机密、密钥或证书的金库,那么 External Secrets 可能不适合。最初,必须建立 External Secrets Operator 与 Secret Store 或 ClusterSecretStore 之间的连接。在我们的项目中,我们利用托管身份来确保这一点。否则,通常需要一个 ID 和一个密钥,这在大规模的 GitOps 环境中可能难以安全管理,因为 ID 和密钥必须通过 CI/CD 流水线安全传输到集群。External Secrets 的一个显著优势是它可以在运行时获取机密,而无需依赖集群。

然而,通过金库访问机密管理器并非始终可用。因此,Sealed Secrets Operator,尤其是在本地环境中,目前被认为是业界标准。

团队需要决定哪种选项更适合。在我看来,这两种选项都很稳固,并且能够很好地融入 GitOps 生态系统。这不仅可以在采用 GitOps 方法的同时安全地存储机密、密钥和证书,还为 GitOps 大规模应用开辟了全新的可能性,例如在特定注册表中部署拉取机密。平台团队通过结合 External Secrets 和 Kyverno,可以将机密部署到所有集群中,Kyverno 会将其分发到各个命名空间。因此,每个团队都有必要的拉取机密,可以从中央镜像注册表拉取镜像。这增强了安全性,因为每个镜像都可以进行扫描,并提供操作中镜像的概览。

通过利用 Sealed Secrets 和 External Secrets,您可以在安全管理机密的同时,保持 GitOps 原则,即将所有配置存储在 Git 中。这些工具帮助您自动化机密管理,保持基础设施安全并确保部署一致性。

每个添加到 Kubernetes 服务目录中的工具都会增加系统引入更多安全漏洞的可能性。我们将在下一部分讨论如何维护您的目录。

在接下来的部分,我们将深入探讨通过 GitOps 和 策略引擎增强安全性。这种方法能够在部署过程中采取主动措施,确定允许部署的内容并识别相关风险。这种前瞻性策略确保只有安全且符合要求的配置才能进入生产环境,从而强化您的安全姿态。

利用策略引擎进行政策即代码实践

在当今的软件开发领域,我们确保系统安全性和合规性的方法发生了显著变化。这一变化的关键方面是采纳了政策即代码的实践,使得治理和安全策略能够直接融入开发和操作流程。在这种背景下,Kyverno [4] 和 Open Policy Agent (OPA) [5] 等策略引擎发挥着至关重要的作用。这些工具使组织能够将其安全、合规性和治理要求定义为代码,从而确保其基础设施和应用程序的一致性和透明性。

Kyverno 和 OPA 都是功能强大、灵活的工具,专门用于在 Kubernetes 环境及其他场景中实现政策即代码。Kyverno 侧重于通过使用用户友好的、原生的 Kubernetes 语法简化 Kubernetes 安全性,允许开发人员直接在 CI/CD 管道中定义和执行安全策略。另一方面,OPA 是一个更为通用的策略引擎,采用了一种名为 Rego 的高度灵活、与领域无关的语言,使得在多种软件系统中创建和实施细粒度、上下文感知的策略成为可能。

将这些策略引擎集成到基于 GitOps 的工作流架构中显著提升了安全性,因为它确保了合规性的持续执行和验证。通过采用 GitOps,团队能够将基础设施和应用程序设置作为代码进行管理,创建一个版本化、可重复和可自动化的环境。在这一过程中融入 Kyverno 或 OPA 意味着基础设施或应用程序的更改将在实施之前自动根据预定义的策略进行验证。这确保了所有部署符合组织的安全标准,并且能够在对生产环境产生影响之前主动识别并修复潜在的安全漏洞或配置错误。

集成 Kyverno 和 OPA

本部分将探讨如何将 Kyverno 和 OPA 等工具集成到开发和操作工作流中,不仅增强安全性和合规性,还促进开发周期的效率和速度。在 GitOps 框架内 自动化 策略执行,使团队能够更快速、更安全地交付,从而打造更强大、更安全的应用程序和基础设施。

我们将重点关注 Kyverno,以便更好地理解,因为我认为这是一个用户可以更轻松理解的工具,而无需学习 Rego。然而,在深入讨论之前,让我们先看一下 Kyverno 操作的层次以及它与 GitOps 的集成。图 13.3 将详细阐述这些内容:

图 13.3 – Kyverno 操作层与 GitOps

图 13.3 – Kyverno 操作层与 GitOps

如图所示,Kyverno 在两个层次上运作,充当有效的守门人。当你尝试部署违反其规则的内容时,Kyverno 会介入,导致部署失败。然而,Kyverno 的功能不仅限于此;它还可以验证 Kubernetes 集群中已运行的服务,或对资源进行修改。这种多功能性使得将 Kyverno 放置在这些层之间成为一个有利的选择。

通过利用 GitOps,你可以在整个集群中部署 Kyverno 实例,确保一致的策略执行。此外,一次定义,处处部署的方法简化了多集群部署,优化了跨不同环境的策略管理。通过与安全团队合作,你可以实施针对特定环境的不同规则集,增强部署的安全性和合规性。Kyverno 与 GitOps 之间的协同作用不仅简化了治理,还强化了基础设施的整体安全态势。

现在,让我们来看一下它在实际操作中的表现。

实践操作 – 让我们将理论付诸实践 [6]

首先,我们为 Kubernetes 服务目录建立一个简化的文件夹结构,如下所示:

.
├── applicationsets
│   └── security
│       └── kyverno-applicationset.yaml
├── kustomize
│   └── security
│       └── kyverno
│           └── policies
│               └── base
│                   ├── disallow-latest-tag.yaml
│                   ├── kustomization.yaml
│                   └── restrict-nodeport.yaml
└── security
    └── kyverno
        ├── Chart.yaml
        └── values.yaml

通过启动 kyverno-applicationset.yaml 的部署,你将针对每个被 env=prodenv=development 标签标识的集群进行部署。该部署不仅在这些集群上设置 Kyverno 工具,还会将 kustomize 文件夹中的特定策略应用到每个集群。在我们的示例中,我们使用了一个基础的文件夹结构;然而,你可以灵活配置不同的文件夹——例如,用于不同阶段的文件夹。这些文件夹可以与集群标签对齐,从而使你能够将适当的规则集部署到相应的集群。这种安排对于在开发集群中实施更宽松的策略、在生产环境中实施更严格的策略非常有益。

现在,让我们检查一个示例策略,它将在每个匹配指定标签的集群上部署。我们将重点关注 disallow-latest-tag.yaml 策略。

在第一部分中,我们看到注释、最佳实践类别,然后是版本、严重性分类、受影响的主题,以及由此可能引发的负面后果描述。我觉得它简洁明了,清晰易懂,且易于配置:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag-example
  annotations:
    policies.kyverno.io/title: Disallow Latest Tag Example
    policies.kyverno.io/category: Best Practices
    policies.kyverno.io/minversion: 1.6.0
    policies.kyverno.io/severity: medium
    policies.kyverno.io/subject: Pod
    policies.kyverno.io/description: >-
      The ':latest' tag is mutable and can lead to unexpected errors if the
      image changes.. This policy validates that the image
      specifies a tag and that it is not called `latest`.

在随后的规范部分,我们观察到该动作被指定为 Audit 而不是 Enforce,这意味着它不是强制性的。接下来,建立了两条规则。第一条规则对容器的标签进行验证,使用 *:* 模式,确保其符合特定标准。随后,第二条规则提升到资源层级,通过直接针对 pods 来应用更广泛的范围。它规定了一个约束,禁止使用带有 latest 标签的模式,从而强化了对部署实践的治理:

spec:
  validationFailureAction: Audit
  background: true
  rules:
    - name: require-image-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "An image tag is required."
        pattern:
          spec:
            containers:
              - image: "*:*"
    - name: validate-image-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Using a mutable image tag e.g. 'latest' is not allowed."
        pattern:
          spec:
            containers:
              - image: "!*:latest"

在实践中,结果如下:当规则被应用并尝试部署一个带有 latest 标签的 pod 及其容器时,部署会被阻止。让我们尝试部署一个带有 latest 镜像标签的 Nginx pod:

kubectl run nginx --image nginx:latest

现在,你可以获得一个类似下面的 Kyverno policyreport

kubectl get policyreport fbe08ffd-bee6-497f-aee8-f96e9cd022f8  -n default -o yaml | grep image -A 8

输出应该是如下所示:

- category: Best Practices
  message: 'validation error: Using a mutable image tag e.g. ''latest'' is not allowed.
    rule validate-image-tag failed at path /spec/containers/0/image/'
  policy: disallow-latest-tag
  result: fail
  rule: validate-image-tag
  scored: true
  severity: medium
  source: kyverno

如你所见,我们违反了最佳实践策略,特别是 disallow-latest-tag 策略。

我称这种设置为门卫(gatekeeper),因为它允许你通过简单的规则来控制可以和不可以部署到集群中的内容。然而,这种设置的功能更为广泛。例如,你可以配置 Kyverno 策略来强制执行镜像签名,或确保仅允许从某些注册表拉取镜像,等等。策略引擎是一个强大的工具。与门卫不同,Kyverno 或 OPA 还可以操作已经部署的资源或那些通过门卫检查并因此被放置在两个层次之间的资源,如图 13.3所示。

当与 GitOps 方法结合时,它开辟了超越团队边界的新可能性,增强了项目的安全性。这种集成不仅简化了部署过程,还确保了操作标准的一致性,从而增强了基础设施的整体安全态势。

在接下来的部分,我们将探讨如何通过两种不同的工具在两个不同的层次上提升安全性。

自动化安全扫描和合规性

在当今快速发展的、安全意识日益增强的 IT 环境中,保持持续的安全性和合规性至关重要。自动化的安全扫描和合规性是强大网络安全战略的核心组成部分,特别是在 Kubernetes 集群中,应用程序和服务会动态扩展和更新。在这里,我们将讨论如何使用 KubeClarity [7] 或 Falco [8] 工具来增强 Kubernetes 环境中的安全态势。下图展示了 KubeClarity 操作的层级:

图 13.4 – KubeClarity 操作层

图 13.4 – KubeClarity 操作层

KubeClarity 是一款开源工具,旨在 Kubernetes 环境中进行安全扫描和合规性分析。它提供了容器镜像和 Kubernetes 配置中潜在漏洞的全面概览。

KubeClarity

首先让我们了解 KubeClarity 如何增强安全性:

  • 漏洞扫描:KubeClarity 会扫描容器镜像中的已知漏洞,利用各种数据库和漏洞跟踪源。它提供有关镜像安全缺陷的详细洞察,包括缺陷的严重性等级,帮助你优先修复问题。

  • 合规性保证:该工具会将你的 Kubernetes 配置与最佳实践和合规标准进行对比,确保你的部署符合行业和组织的安全政策。

  • 持续监控:KubeClarity 会持续监控你的容器化应用程序中的新漏洞,提供实时警报和更新。这种持续的警觉有助于维护一个安全的 Kubernetes 环境。

通过在 GitOps 框架内集成 KubeClarity,组织可以显著增强其安全性和合规性,确保其 Kubernetes 集群能够抵御不断变化的威胁。采用 GitOps 原则使得安全扫描和合规检查的自动化成为可能,从而使这些流程变得更加一致、高效和可扩展。KubeClarity 提供的主动安全保障不仅保护了你的基础设施,还通过展示对维护安全合规环境的承诺,增强了与客户的信任。GitOps 启用的持续监控和自动与安全政策的一致性,确保任何偏差都会被迅速检测并修正,从而保持强有力的防御,抵御潜在漏洞。

Falco

Falco 是一款开源工具,专门为 Kubernetes 环境设计,用于实时安全监控和分析。它充当 入侵检测系统IDS),使团队能够检测其应用程序和基础设施中可能表明安全漏洞或其他威胁的异常活动。下图展示了 Falco 的操作层级。

图 13.5 – Falco 操作层

图 13.5 – Falco 操作层

Falco 在系统级别运行(图 13.5),监控底层 Linux 内核功能,或者更准确地说,是容器编排平台的系统级活动。它利用 Linux 内核的功能,特别是 扩展 BPFBerkeley 数据包过滤器)或传统的 系统调用syscalls)监控,通过内核模块实时观察和分析系统范围的事件。Falco 可以捕获并评估在容器内运行的应用程序的系统调用,识别异常或不良行为。

集成 Falco 与 GitOps 的优势如下:

  • 自动化安全监控:通过将 Falco 集成到 GitOps 流水线中,安全策略可以作为代码定义,并自动应用于基础设施或应用程序中的每次变更,从而实现对安全标准的持续和自动化监控。

  • 实时警报:Falco 可以配置为在违反定义规则时发送实时警报。在 GitOps 环境中,这些警报有助于迅速响应潜在的安全事件。

  • 一致性和合规性:通过 GitOps,Falco 配置可以版本化、审查并自动部署,确保在不同环境中一致地执行安全策略。

  • 透明性和可追溯性:所有对 Falco 策略的更改都会记录在 Git 中,提供清晰的审计痕迹。这促进了关于安全监控的透明度,并有助于符合法规要求。

将 Falco 集成到 GitOps 策略中,不仅能增强团队的安全防护姿态,还能采取一种主动的方式来识别和应对 Kubernetes 环境中的安全威胁。

然而,每个工具的引入也伴随着潜在的风险,即使它是为了提高安全性,这就是为什么在设计或选择工具时不能忽视维护问题,并且需要特别关注这一点。这正是我们将在下一节中简要讨论的内容。

保持平台目录的最新状态

本节内容已经在第五章附加内容 – 使用 GitOps 进行大规模维护和 KSC 部分中进行了详细讲解。它提醒我们,随着每个工具的加入,目录不断扩展,必须始终保持对安全性的高度关注。

常见漏洞与曝光CVE)威胁被揭示并且您选择 Cockpit 和 Fleet 方法时,采用大规模的 GitOps 同样促进了漏洞管理的规模化战略。因此,在概念的早期阶段,尤其应考虑这一点。

实施这样的战略确保了随着基础设施的扩展,处理漏洞的策略也能相应扩展。这种主动的姿态有助于快速解决整个舰队中的安全问题,保持系统的完整性和安全性。在概念框架的早期集成这些做法,对于建立一个稳健、可扩展和安全的基础设施至关重要。

本章的总结部分,图 13.6 展示了数据包(应用程序或服务)必须经过的各个阶段或关卡,突出了不同的安全机制可以介入的地方,确保尽可能全面地扫描数据包:

图 13.6 – 多层次安全

图 13.6 – 多层次安全

然而,数据包可能会通过某些阶段,因此需要像 Falco 和 Kyverno 这样的工具来实现持续扫描。这些工具依赖于定义好的规则,幸运的是,可以通过 GitOps 容易地部署这些规则。

总结

在本章中,应该已经明确,安全性不仅仅依赖于单一层面,也不应仅由一个团队来强制执行。安全性是一个文化问题,可以通过 GitOps 等方法和像 Argo CD 等工具在大规模中进行扩展,包括定义规则集或策略。安全性不仅仅是工具的问题;它还包括如何处理敏感数据,如机密信息,并确保生态系统中的第三方工具保持最新和安全。有效的安全实践需要跨团队的协作、持续的监控和主动的管理,以确保一个强大且具有韧性的基础设施。

在下一章中,我们将探讨 FinOps 与 GitOps 的集成,以实现可持续、成本效益高的运营。我们将涵盖核心的 FinOps 原则、成本预测、优化以及碳足迹的理解。此外,我们还将探讨 GitOps 的未来趋势,包括 AI 驱动的自动化。

参考文献

第十三章:FinOps、可持续性、AI 和 GitOps 的未来趋势

在本章中,我们超越了 GitOps 的常规边界,探索了其在书籍主章节未涵盖的各个领域中的广泛范围和多方面影响。我们的旅程被结构化为若干不同但互相关联的模块,每个模块都揭示了 GitOps 扩展影响力的不同维度,提供了对这种实践潜力和多样性的全面洞察。

我们从 FinOps成本管理 的基础开始,财务智慧与操作专业知识的融合在此成为焦点。该部分阐明了 FinOps 框架如何与 GitOps 方法论结合,使组织能够精确控制其云支出。通过在 GitOps 驱动的环境中使用如 OpenCostKubecost 等工具,企业能够实现前所未有的透明度和高效性,管理集群、项目及其他领域的成本,确保每一美元的支出都是面向创新和增长的投资。

过渡到可持续性和绿色操作领域,我们深入探讨了 GitOps 如何成为推动环保 IT 实践的催化剂。该模块强调了可持续操作的重要性,不仅从经济角度看,还在于为环境保护做出贡献。我们讨论了诸如自动化关闭开发集群等实际策略,展示了 GitOps 如何将技术进步与生态责任对接,从而在科技行业中培养可持续发展的文化。

该探索扩展到包括 GitOps 和 人工智能 (AI) 驱动的自动化,这是一个连接 AI 和 GitOps 高级领域的环节。这种融合正在彻底改变组织部署、监控和管理 IT 环境的方式,超越了炒作,提供了切实有效的自动化解决方案。通过现实世界的案例和案例研究,我们考察了 AI 在提升 DevOps 实践和简化跨公司服务部署中的双重优势,所有这些都在 GitOps 框架内进行。

最后,我们回顾了 GitOps 的发展趋势,思考 GitOps 原则的持续演变及其在各个领域的变革性影响。这个总结部分预测了 GitOps 的未来发展轨迹,推测它在新兴技术中的角色以及重新定义行业标准的潜力。我们深入探讨了 GitOps 在预测和监控云成本方面的 关键 作用,从而帮助组织在现代云环境的复杂性中保持信心和战略眼光。

这些模块各自聚焦不同,但共同强调了 GitOps 的广泛影响力,展示了它作为现代 IT 战略基石的角色。本章旨在拓宽读者的视野,鼓励他们将 GitOps 视为不仅仅是提升运营效率的工具,而是一个将技术创新、财务智慧、环保意识和前瞻性适应力融合的整体方法。

本章将涵盖以下主要主题:

  • 探讨 FinOps 的基础知识

  • 使用 GitOps 进行成本预测和监控

  • 云支出优化技巧

  • 评估碳足迹并推动绿色运营

  • 探讨 GitOps 和人工智能驱动的自动化

  • GitOps 中的未来挑战与机会

  • GitOps 在新兴技术中的角色

探讨 FinOps 的基础知识

FinOps,一个将财务和 DevOps 原则融合的运营框架,根本上是一种文化实践,旨在最大化云投资的商业价值。它促进了一个协作环境,在这个环境中,工程、财务和业务团队共同工作,促进基于数据的决策,提高财务责任感并优化云成本。

FinOps 的本质在于它能够弥合传统上分隔的部门之间的鸿沟,推动一种共享责任模型,使所有利益相关者都参与到云的成本效益和运营效率中。这种跨职能的协同对于加速产品交付并确保财务透明度和控制至关重要。

FinOps 的关键方面包括实时监控云开支,使组织能够做出平衡成本、速度和质量的明智决策。这种方法不仅仅是削减成本;它是通过利用云的可变支出模型来推动创新、收入增长和在技术基础设施中的战略投资。

寻求采用 FinOps 的组织可以从探索 FinOps 基金会提供的资源开始,该基金会提供教育、最佳实践和社区参与,支持不同成熟度水平的 FinOps 之旅。FinOps 倡导的爬行、行走、跑步成熟度模型使组织能够逐步发展其财务操作,不断优化其云架构和投资策略。

爬行、行走、跑步模型

Crawl, Walk, Run 模型是描述学习和实施逐步阶段的框架。在 Crawl 阶段,个人或组织专注于理解基本原则,范围有限且高度依赖指导。Walk 阶段涉及更大的熟悉度和信心,任务变得更加复杂,效率提高。最后,在 Run 阶段,完全掌握并独立、创新地使用新概念、新流程或新技术。这个模型有助于管理期望,并提供一个结构化的成长路径,确保在进阶到更复杂的层级之前建立扎实的基础。

FinOps 框架的核心原则包括指导协作努力、个人对云资源使用的责任以及云投资与业务价值的战略对齐。这些原则确保从高管到工程师的每个团队成员都能理解并为高效、创新地使用云资源做出贡献。

将 FinOps 融入组织的运营模式,不仅承诺增强成本管理和优化,还能使云支出与业务结果对齐,确保投资转化为实际价值。这种战略对齐在当今动态的云环境中至关重要,因为适应性规划和成本效益资源利用是保持竞争优势和促进长期增长的关键。

在下一节中,我们将使用 OpenCost [1] 和 Kubecost [2] 来确定集群或命名空间的成本,举例来说,这些命名空间可以代表一个项目。

使用 GitOps 进行成本预测和监控

GitOps 可以与 FinOps 无缝集成,以增强云资源的财务治理,同时保持敏捷性和运营效率。GitOps 和 FinOps 实践的结合,使组织能够通过自动化、版本控制和持续监控,更有效地管理其云基础设施和成本。

GitOps 如何补充 FinOps

首先,让我们了解 GitOps 如何补充 FinOps:

  • 自动化成本优化:GitOps 允许自动化部署和扩展云资源,可以与 FinOps 策略结合,确保资源利用在不牺牲性能的前提下优化成本。这意味着基础设施可以自动扩展或收缩,符合财务目标和运营需求。

  • 版本控制的支出:使用 GitOps,每次对基础设施的更改都会在 Git 仓库中进行版本控制,提供对所做更改的审计追踪,包括更改内容、执行人以及更改的原因。这与 FinOps 原则一致,通过为操作变更的财务影响提供透明度,帮助更好地进行预算跟踪和成本分配。

  • 协作与可视化:GitOps 通过使用 Git 作为单一事实来源SSOT)促进开发、运维和财务团队之间的协作。这种协作环境确保了财务考虑被纳入到基础设施规划和应用开发的最早阶段,推动了一个成本意识的文化。

  • 政策执行:将政策即代码PaC)工具集成到 GitOps 工作流中,可以执行财务治理,确保资源的使用高效且在预算内。可以设定政策来防止超支,强制使用成本优化的资源,或确保遵守预算约束。

  • 持续的成本监控和反馈:GitOps 使得持续监控和反馈环路成为可能,帮助团队快速识别并解决云资源使用中的低效问题。这种持续的警觉性有助于在操作效率、成本和速度之间保持平衡,符合 FinOps 目标。

  • 主动的财务管理:通过使用 GitOps,组织可以主动管理其云端开支。存储在 Git 仓库中的基础设施即代码IaC)模板可以被分析,用来预测成本,并在执行之前了解计划更改的财务影响。

使用 GitOps 与 FinOps

以下几点描述了如何将成本监控、预算执行、资源优化和财务操作自动化集成到 GitOps 管道中,以提升成本效率并确保财务治理:

  • 实施成本监控工具:将云成本监控工具集成到 GitOps 管道中,以提供有关代码更改和基础设施更新对财务影响的实时反馈。

  • 强制执行预算政策:通过 IaC 使用 GitOps 强制执行预算政策,确保部署符合预定的财务约束和操作预算。

  • 优化资源分配:利用 GitOps 自动化成本优化资源的部署,例如使用抢占实例,并关闭利用率低的资源,确保云支出的高效性。

  • 简化财务操作:通过 GitOps 自动化财务操作任务,例如成本报告、预算提醒和资源标签,从而确保财务治理在所有云资源中得到一致应用。

通过将 GitOps 与 FinOps 实践相结合,组织可以确保其云基础设施不仅在操作上高效,而且与其财务目标保持一致,从而最大化其云投资的价值。这种全方位的方法实现了一个更加灵活、透明和成本效益高的云管理战略。

现在,让我们看看它在实践中是如何运作的。为此,我们将考察两个工具:OpenCost,作为一个开源选项,以及基于 OpenCost 构建的 Kubecost,后者在接下来的部分中提供了许多额外的功能。

OpenCost 与 Kubecost 配合 GitOps 使用

OpenCost 和 Kubecost 是在 Kubernetes 成本监控和分析领域使用的工具,它们提供关于资源利用的洞察,并帮助管理与 Kubernetes 环境相关的云端成本。我们将简要介绍这两个工具及其差异。

OpenCost

OpenCost 是一款开源工具,它为与 Kubernetes 集群相关的成本和使用情况提供透明度。它通过提供详细的资源利用和相关费用洞察,帮助团队监控、分析和优化其 Kubernetes 成本。OpenCost 提供以下功能:

  • 按 pod、部署、命名空间或集群级别进行成本拆分

  • 支持多集群环境

  • 与云服务提供商的集成,以实现更准确的成本估算

  • 永远免费且开源,由专家支持和维护

这一切如何与 GitOps 相结合,或者更具体地说,GitOps 在 FinOps 上下文中带来了什么价值?OpenCost 基于 us-central-1 区域设置本地定价配置——例如,"CPU": "0.031611"$"RAM": "0.004237"$ 按小时计算。然而,OpenCost 也允许定制定价。此时,GitOps 就派上用场了,它不仅能在不同集群间部署 OpenCost 工具(图 14.1),还可以根据需要配置价格。例如,如果你在欧洲有三个数据中心,分别位于三个不同的国家,由于电力价格、采购、折旧等因素,CPU 和 RAM 的价格会有所不同。

optimization/opencost 下有全球定义的值,此外每个特定国家还有自定义定价模型。其视觉效果如下:

图 14.1 – 配合 GitOps 和本地定价配置的 OpenCost

图 14.1 – 配合 GitOps 和本地定价配置的 OpenCost

对于图 14.1中的场景,我们建立以下文件夹结构 [3]:

.
├── applicationsets
│   └── optimization
│       └── opencost-applicationset.yaml
├── cluster
│   ├── in-cluster-austria
│   │   └── optimization
│   │       └── opencost
│   │           └── values.yaml
│   ├── in-cluster-germany
│   │   └── optimization
│   │       └── opencost
│   │           └── values.yaml
│   └── in-cluster-ireland
│       └── optimization
│           └── opencost
│               └── values.yaml
└── optimization
    └── opencost
        ├── Chart.yaml
        └── values.yaml

它还可以与混合云多云结合使用;然后,它可能看起来像这样:

图 14.2 – 配合 GitOps 和混合设置定价配置的 OpenCost

图 14.2 – 配合 GitOps 和混合设置定价配置的 OpenCost

GitOps 与 OpenCost 相结合,在 FinOps 中开辟了新的可能性,提供了跨分布式基础设施的用户和基础设施定义的成本可见性,从而加强了财务监管、精确的成本分配和云环境中的战略预算优化。

然而,如果你需要团队协作、预算规划、警报、估算月度节省等功能,则应考虑探索 Kubecost。

Kubecost

Kubecost 是一个基于 OpenCost 的产品。它是一个商业解决方案,提供比 OpenCost 项目核心功能更多的附加功能和支持。Kubecost 包含了 OpenCost 的所有功能,并且增加了以下内容:

  • 高级预算和成本预测

  • 个性化优化建议

  • 额外的安全性和合规性功能

  • 专业支持和咨询

此外,你可以灵活地利用 GitOps,不仅仅是为了在多个集群中部署 Kubecost,还可以让团队根据命名空间、集群或标签设置预算,并指定在预算超标时需要采取的行动(图 14.3):

图 14.3 – Kubecost 与 GitOps:定义预算和成本警报

图 14.3 – Kubecost 与 GitOps:定义预算和成本警报

通过将 GitOps 与 Kubecost 集成,组织能够赋予团队更多的控制权,简化这一强大工具的部署。这种协同作用不仅让团队能够高效地大规模部署 Kubecost,还能定义与预算需求对齐的关键参数。这种集成在促进成本管理的协作环境中至关重要,使组织内的各个团队能够共享最佳实践、见解和策略,共同优化资源。

Kubecost 与 GitOps 相结合的能力进一步丰富了这种协作氛围,促进了主动的成本管理。通过设置预定义的阈值并配置自动警报,团队可以积极监控和管理云支出。这种主动的立场确保了任何潜在的预算超支能迅速被识别并解决,同时有效优化整体云支出。

GitOps 和 Kubecost 的融合改变了云成本管理的方式,从反应型转变为主动型模型。团队不再对自己的支出趋势一无所知,而是提供了一个清晰的、可操作的框架,使他们能够保持财务效率,同时充分利用云资源的可扩展性和灵活性。这种集成确保了成本优化不仅仅是月底的后续工作,而是日常运营的基本组成部分,赋予团队合理经济地利用云资源的能力。

OpenCost 与 Kubecost 的区别

以下是这两个工具之间最重要的区别:

  • 开源与商业版:OpenCost 是一个开源项目,邀请社区自由使用和适配,而 Kubecost 是一个商业版,提供增强的功能和支持,面向企业客户。

  • 功能集:Kubecost 在 OpenCost 的基础上进行了扩展,增加了专门为企业客户设计的附加商业功能。例如,OpenCost 为 Kubernetes 集群提供基本的成本监控,而 Kubecost 则提供自动化成本优化建议以及为不同团队和项目提供详细的成本分配报告。

  • 支持:Kubecost 提供专业的支持和咨询服务,超出了通常从开源项目中预期的范围。

这两款工具旨在提升 Kubernetes 使用相关费用的透明度和控制力,但它们面向的用户群体和需求不同,从开源社区到大型企业均有涵盖。

GitOps 与 OpenCost 或 Kubecost 的结合,不仅简化了操作效率,还显著提升了 Kubernetes 环境的战略财务管理。

在下一部分,我们将探讨如何优化云成本,以及 GitOps 与 Kubecost 如何为此作出贡献。

云支出优化技术

对于希望最大化云投资并最小化不必要成本的组织来说,云支出优化技术至关重要。将 GitOps 与如 Kubecost 等工具结合,可以显著简化这一过程,提供一种系统化的方法来管理和减少云费用。以下是如何利用这一组合来提升云支出优化的方式。

GitOps 与 Kubecost 结合进行云支出优化

GitOps 通过自动化、可预测性和透明度将其带入云操作中。它将 Git 存储库作为整个基础设施的 SSOT,这意味着每一次变更都有版本控制、可追溯且可回滚。这种方法化的方式对云支出优化至关重要。

重要提示

在 GitHub 上的一个示例,第十四章...optimization/kubecost,展示了如何通过 Kubecost UI 和 Helm Chart 部署,利用values.yaml文件配置告警。

当 GitOps 与 Kubecost 结合使用时,它们为持续的云支出优化提供了强大的框架:

  • 自动化资源优化:GitOps 可以自动化部署 Kubecost 的建议,确保节省成本的措施能及时且一致地应用于基础设施。

  • 持续监控与调整:这一组合能够持续监控云支出,并根据预定义的策略进行自动调整,确保云环境始终以最具成本效益的方式运行。

  • 增强协作:通过整合这些工具,财务团队与运营团队可以更有效地协作,GitOps 提供操作框架,而 Kubecost 提供财务洞察,进而促进更加明智的决策。

假设有一个新项目进来。平台团队提供 Kubernetes 平台,但 FinOps 团队负责管理每个项目固定预算为 500 美元的成本。FinOps 团队可以在 UI 中创建一个预算并设置警报,或者让 GitOps 团队通过 GitOps 项目命名空间和集群预算部署警报,并设置 警报

例如,如果 FinOps 团队想知道为什么命名空间中的累计预算在 70-100 美元之间,但总支出预算约为 600 美元,他们可以使用警报和 UI 来调查根本原因。Kubecost UI (图 14**.4) 显示,集群效率低于 12%,并且通过 7 天的回顾,已经可以节省大约 50 美元:

图 14.4 – Kubecost 集群效率 ~12% 持续 7 天

图 14.4 – Kubecost 集群效率 ~12% 持续 7 天

然后,FinOps 团队会检查 图 14**.5 中的潜在节省,以了解成本的来源。很快就能明显看出,项目的集群规模过大。与平台团队合作,并利用 Kubecost,项目中的各个团队可以实施规模调整和机制,以便相应地调整行动。在这一阶段,团队之间的协作至关重要,所有团队都应以公司、可持续性和项目的利益为出发点。这就是如何合理优化云成本的方式:

图 14.5 – Kubecost 节省建议

图 14.5 – Kubecost 节省建议

总结来说,结合 GitOps 和 Kubecost 可以将云支出优化从被动转变为主动。这种整合不仅提供了关于云使用和支出的详细见解,还自动应用节省成本的策略,确保云资源得到高效和经济的利用,并使云支出与组织的预算目标和运营需求保持一致。

在接下来的部分,我们将探讨如何利用 GitOps 以及多种工具朝着可持续性目标迈进。

评估碳足迹并推动绿色运营

评估碳足迹并推动云环境中的绿色运营是实现 IT 运营可持续性的关键步骤。像 kube-green [4] 和 Armada [5] 这样的工具提供了创新的方法来管理和减少云计算的环境影响。

使用 kube-green 评估碳足迹

kube-green 工具专注于以直接与能源消耗相关的方式优化资源使用,从而减少环境影响。它是如何推动绿色运营的:

  • kube-green 工具可以智能地调度工作负载,使其在能源电网由可再生能源供应时运行,从而促进绿色能源的使用。

  • 资源优化:帮助微调资源分配,确保应用程序仅使用所需的资源,并减少数据中心的总体能耗。

  • 空闲资源管理:该工具可以自动缩减或关闭空闲资源,显著减少能源浪费和相关的碳排放。

实施kube-green使组织能够朝着碳中和计算迈进,将 IT 运营与更广泛的环境可持续性目标对齐。

通过 Armada 促进绿色运营。

虽然不像kube-green那样是一个直接的工具,Armada 代表了 Kubernetes 中的舰队管理方法的概念,可以适应以促进绿色运营。通过高效管理集群,Armada 可以在以下方面提供帮助:

  • 集群整合:根据需求优化活动集群和节点的数量,通过避免资源过度配置来减少能源消耗

  • 节能部署:以节能的方式促进应用程序的部署,可能与预测绿色能源可用性的工具集成。

  • 监控与报告:提供集群能耗和效率的洞察,帮助做出减少碳足迹的决策。

采用 Armada 这样的策略使组织能够以可持续发展的眼光监督其 Kubernetes 集群,确保基础设施尽可能节能高效。

通过与 GitOps 集成评估碳足迹。

kube-green等工具和 Armada 等概念集成到 GitOps 工作流中,可以进一步提升其效果:

  • kube-green策略和 Armada 策略在所有集群中的应用,确保统一遵循可持续发展实践。

  • 持续优化:通过 GitOps,可以在应用程序生命周期内持续调整和优化绿色政策,确保每次部署时都将可持续性作为优先考虑。

  • 透明度和问责制:GitOps 的声明式特性提供了所有绿色操作变更的清晰版本控制历史,促进了可持续发展努力中的透明度和问责制。

通过评估碳足迹并促进绿色运营,组织不仅为其云基础设施的环境可持续性做出贡献,还与全球减少碳排放的努力保持一致。这些做法与 GitOps 的整合确保了可持续云计算的系统化、可扩展性和有效性。

随着人工智能变得越来越重要,并且已有工具可以为团队提供有用的支持,我们将在下一节中详细了解这些工具。

探讨 GitOps 与 AI 驱动的自动化。

随着 IT 领域日益复杂,尤其是在没有 GitOps 或其他工具帮助的情况下,详细解析 Kubernetes 的各个方面时,许多层次逐渐堆叠,从操作系统层到网络,再到公钥基础设施PKI)。我发现现在越来越多的新员工在这个领域中,发现起步变得越来越困难,不知道从哪里开始,尤其是当他们被投入一个项目时。因此,存在一些实用的 AI 工具,可以在这一领域提供支持。

在这一章中,我们将探索两个工具。第一个工具,Robusta.dev,充当开发者的故障排除副驾驶,为他们提供实时的洞察和解决方案。第二个工具是检索增强生成RAG)模型,它是iits自实现的中间件解决方案,可以用作增强工具,支持开发者的知识库。通过将这两个工具结合起来,并通过 GitOps 在相关项目中进行部署,我相信它们不仅对新入行的开发者极为有利,对那些已经有经验的开发者同样有帮助。这种集成有可能带来生产力的提升。

Robusta.dev

Robusta [6] 是一个开源平台,旨在增强 Kubernetes 的可观察性和调试功能。它是一个帮助 DevOps 团队、站点可靠性工程师SRE)和开发者深入了解 Kubernetes 集群的工具,从而促进更好的监控、警报和故障排除。

Robusta 的主要特点包括以下几点:

  • 增强的可观察性:Robusta 提供 Kubernetes 环境的详细洞察,提供丰富的、可操作的警报和通知。它将普通的日志文件转化为更具交互性、富有数据的内容,帮助更快地理解和解决问题。

  • 自动化故障排除:该平台可以自动化常见 Kubernetes 问题的故障排除过程,从而减少诊断和解决问题所需的人工努力。

  • 可自定义的操作手册:用户可以创建自定义的操作手册,以自动化响应特定的事件或警报。这允许根据基础设施的需求演变定制响应机制。

  • 与现有工具的集成:它与现有的 DevOps 工具生态系统良好集成,提供与监控解决方案、警报工具以及像 Slack 这样的消息平台的无缝连接。

  • 开源社区:作为开源工具,它允许开发者和用户为该工具做出贡献,推动社区驱动的方式来增强 Kubernetes 的可观察性和管理能力。

我们将使用增强版的ChatGPT机器人 [7],配合可自定义的操作手册,使 Robusta 工具更加高效。但接下来让我们按照指南中的步骤进行操作。我们将在接下来的示例中使用 Prometheus 和 ChatGPT。

重要提示

Prometheus 是一个开源的监控和告警工具包,因其强大的查询语言和能够处理多维数据(如来自云和容器化环境的指标)而被广泛使用,而ChatGPT是由OpenAI开发的先进 AI 语言模型,能够生成类人文本、进行对话、回答问题,并提供涵盖广泛主题的信息。

让我们开始吧:

  1. 安装 Robusta Python CLI:

    python3 -m pip install -U robusta-cli --no-cache
    
  2. 为 Helm 生成一个 values 文件:

    robusta gen-config
    

    你将被引导完成所有必要的步骤:

    Configure Slack integration? This is HIGHLY recommended. [Y/n]: Y
    If your browser does not automatically launch, open the below url:
    https://api.robusta.dev/integrations/slack?id=05b9c718-7f2e-4749-82fe-c3f545266692
    You've just connected Robusta to the Slack of: poc-chatgpt-kubernetes
    Which slack channel should I send notifications to? # pocs
    Configure MsTeams integration? [y/N]: N
    Configure Robusta UI sink? This is HIGHLY recommended. [Y/n]: Y
    Enter your Google/Gmail/Azure/Outlook address. This will be used to……
    
  3. 在最新版本中,它们通过 Helm lint 验证 Helm,因此你需要添加 clusterName

    clusterName: "aks-excelsior-development-2"
    globalConfig:
      signing_key: ea657a0b******
      account_id: 7935371f******
    sinksConfig:
    - slack_sink:
        name: main_slack_sink
        slack_channel: pocs
        api_key: xoxb******
    enablePrometheusStack: true
    enablePlatformPlaybooks: true
    runner:
      sendAdditionalTelemetry: true
    rsa:
      private: ******
      public: ******
    

    然后,你可以修改 generated_values.yaml 文件,创建多个触发器。为了展示,我会保持简单,并在下一步通过 Helm 应用它。

  4. 使用 Helm 安装 Robusta:

    kubectl create ns robusta
    helm repo add robusta https://robusta-charts.storage.googleapis.com && helm repo update
    helm install robusta robusta/robusta -f .generated_values.yaml
    
  5. 运行示例以查看触发器(Prometheus)、动作(Logs-Enricher)和接收端(Slack)是否正常工作:

    k apply -n robusta -f https://raw.githubusercontent.com/robusta-dev/kubernetes-demos/main/pending_pods/pending_pod_resources.yaml
    robusta playbooks trigger prometheus_alert alert_name=KubePodCrashLooping namespace=robusta pod_name=pending-pod-resources-579664598d-j6s9n
    

    你应该会在 Slack 中收到一条通知,如图 14.6所示,包含元信息以及 pod 的日志:

图 14.6 – 使用 Slack 作为接收端没有 ChatGPT 的 Robusta

图 14.6 – 使用 Slack 作为接收端没有 ChatGPT 的 Robusta

  1. 我们现在需要包括 playbook 仓库,并集成为 ChatGPT 动作量身定制的自定义 playbook,如下所示:

    clusterName: "aks-excelsior-development-2"
    globalConfig:
      chat_gpt_token: sk-dw******
      signing_key: ea657a******
      account_id: 7935371f******
    sinksConfig:
    - slack_sink:
        name: main_slack_sink
        slack_channel: pocs
        api_key: xoxb******
    - robusta_sink:
        name: robusta_ui_sink
        token: eyJhY2NvdW******
    enablePrometheusStack: true
    # This part is added to the default generated_values.yaml
    enablePlatformPlaybooks: true
    runner:
      sendAdditionalTelemetry: true
    rsa:
      private: ******
      public: ******
    # This part is added to the default generated_values.yaml
    playbookRepos:
      chatgpt_robusta_actions:
        url: "https://github.com/robusta-dev/kubernetes-chatgpt-bot.git"
    # This part is added to the default generated_values.yaml
    customPlaybooks:
    # Add the 'Ask ChatGPT' button to all Prometheus alerts
    - triggers:
      - on_prometheus_alert: {}
      actions:
      - chat_gpt_enricher: {}
    

    高亮部分是额外的部分。

  2. 现在,你应该使用以下代码再次激活 Prometheus 告警:

    robusta playbooks trigger prometheus_alert alert_name=KubePodCrashLooping namespace=robusta pod_name=pending-pod-resources-579664598d-j6s9n
    

你现在应该能够看到Ask ChatGPT按钮,如图 14.7所示:

图 14.7 – 使用 Slack 作为接收端与 ChatGPT 配合的 Robusta

图 14.7 – 使用 Slack 作为接收端与 ChatGPT 配合的 Robusta

点击按钮后,你应该会收到一份关于发生情况、常见原因、潜在故障排除步骤和可行解决方案的详细说明,如图 14.8所示。此功能显著帮助开发人员节省大量时间,减少排查问题的麻烦。通过与 Argo CD 一起使用 GitOps,你不仅可以在多个集群上部署 Robusta,还可以部署扩展功能,正如本书中反复展示的那样:

图 14.8 – 使用 Slack 作为接收端与 ChatGPT 配合的 Robusta:支持

图 14.8 – 使用 Slack 作为接收端与 ChatGPT 配合的 Robusta:支持

Robusta 的目标是简化管理 Kubernetes 集群的操作复杂性,使团队更容易保持高可用性HA)、性能和容器化应用的可靠性。通过与 GitOps 集成,Robusta 提升了自动化水平,确保通过声明式配置保持一致的环境,并促进快速恢复和扩展,从而简化了部署过程并增强了基础设施的弹性。

私有 LLM 解决方案与 iitsAI

借助 Robusta.dev 等工具,我们已经在 Kubernetes 环境中为可观察性和 事件管理IM)提供了很好的支持,但我们如何进一步提高生产力、帮助新开发者上手并提升现有开发者的能力呢?我们推出了一个名为 iitsAI 的附加工具,由 iits-consulting 公司开发,运作在 iitsAI 下。该工具允许开发者在预训练模块(如 Mistral 7B)的基础上,补充自己的数据源,并利用多种 大型语言模型LLMs; 混合模型)。

重要提示

Ollama 是一个跨平台框架,允许你在本地计算机上使用 Mistral 7B 等 LLM。

LLM 是一种 AI 程序,能够识别和生成文本、翻译语言、编写各种创意内容,并以信息性方式回答你的问题。

RAG 是一种通过从外部源整合事实信息,来提高 生成性 AIGenAI)模型的准确性和可靠性的技术。

Mistral 7B 是一个拥有 73 亿参数的 神经网络NN)模型,经过大量文本和代码数据集的训练,能够执行各种任务,包括生成文本、翻译语言、撰写不同类型的创意内容,并以信息性方式回答你的问题。

iitsAI 提供一个私有 LLM 解决方案,运行在 Kubernetes 中,属于你的 自有基础设施,并且包含你自己的 数据,为你提供完整的端到端控制。或者,你也可以选择由 iits 提供的托管版本,通过德国的 主权云提供商提供。这两种解决方案都包括 单点登录SSO)和通过你定义的角色映射来对数据进行细粒度访问控制。

LLM 的功能简化如下:

  • LLM 的助手是经过大量数据训练的大型神经网络。

  • 每个 LLM 会处理其部分提示,并根据其知识和能力生成响应。

  • 来自 LLM 的响应随后会被合并,生成一个全面且信息丰富的响应给用户。

通过这种方式,复杂任务可以被分解为更小的部分,并由多个 LLM 并行处理。结果是更快速、更高效的提示处理。可以想象,一个提示被拆分成多个部分,分别发送给不同的 AI 助手。每个助手处理它的部分,然后将所有答案汇总为最终响应。

由 iits 开发的工具提供以下架构:

图 14.9 – Ollama 与 RAG:服务架构 [8]

图 14.9 – Ollama 与 RAG:服务架构 [8]

重要提示

Weaviate 是一个开源向量数据库,允许你存储数据对象和向量。

Airbyte 是一个开源数据集成平台,帮助你在不同的数据源和目标之间移动数据。

用户通过 Web UI 输入提示,正如他们习惯于使用ChatGPT,它通过Ollama引用一个模型,如Mistral 7B,并在后台提供基础 LLM 模型。然后,iitsAI 开发了一种中间件来节省资源并从提示中提取最佳结果。提示被分割成多个部分,经过几次迭代,并通过多个LLM进行处理。在这里,LLM 充当一个向量数据库(Weaviate),通过定制开发的连接器与Airbyte连接,或者使用 Airbyte 从不同来源加载文档并将其提供给 LLM 代理。最终,用户根据提供的文档收到对其询问的响应,如下所示:

图 14.10 – iitsAI 与物流行业共同开发内部知识库

图 14.10 – iitsAI 与物流行业共同开发内部知识库

该解决方案的一个有趣之处在于,它运行在 Kubernetes 上,并通过 GitOps 部署。因此,整个解决方案,从 UI 到加载基础模型和配置文件,都由公司在自己的基础设施上管理。这种自主性对于欧洲企业在使用 AI、Kubernetes 和 GitOps 等技术时至关重要。

现在让我们探讨它如何与 GitOps 集成,以及这一组合所带来的机会。

在用例 A(图 14**.11)中,提供给不同客户的产品可以由开发团队交付。同时,团队还可以为客户提供如何使用产品的知识库。用户可以通过简单的语言请求解决所有必要的查询,而无需翻阅外部文档:

图 14.11 – iitsAI 与自定义应用程序知识库

对于用例 B(图 14**.12),当平台团队部署平台时,他们还可以创建一个关于所有交付工具、潜在问题、发布、响应时间、常见问题等的内部知识库,该知识库可以通过自然语言NL)的聊天助手访问。这不仅提高了效率,还消除了多个迭代步骤,例如联系服务台,这通常需要查找提供的文档并在第一层支持中提供帮助:

图 14.12 – iitsAI 与平台知识库

得益于 GitOps,部署过程简单且可以在集群之间扩展。此外,GitOps 方法有助于节省资源,因为 LLM 是GPU 密集型的。它支持如图 14**.13所示的设置,其中只有 UI 部署在工作负载集群上,而中间件、向量数据库和基础模型可以在服务集群上运行,提供GPU 节点池

图 14.13 – iitsAI 分离 UI 和 LLM 后端以节省资源

如我们所见,GitOps 在这一阶段为我们提供了巨大的灵活性,使我们想起了之前章节中的Kubernetes 服务目录KSC),以及如何使用标签来控制自己的堆栈。这使得部署的控制更加精细。通过集成 AI,如前所示,我们可以主动协助故障排除,并提供一个互动的知识库,帮助我们清晰地展现所增加的价值。

在下一部分,我们将探讨与未来使用 GitOps 相关的潜在挑战和机遇。

GitOps 的未来挑战和机遇

在这一部分,至关重要的是要解决多个团队在相同操作框架内协作的动态和所需的总体战略,尤其是当他们需要共享像代码库这样的资源时。关键是从一开始就建立明确的协议,定义哪些是允许的,哪些需要协调,就像设定贡献指南,规定更改的顺序和考虑事项。

这种方法反映了开源软件OSS)模型,全球的贡献者在项目上有效合作,而该项目并不由单一实体拥有。这样的模型突显了 GitOps 的潜力,能够在不同的团队之间协调工作,超越传统的 DevOps 边界。GitOps 旨在统一开发、运营、财务、可持续性、隐私、安全等多个领域,使它们能够共同交付一个统一且强大的产品。

可持续性将在 GitOps 领域中发挥重要作用。与可能基于代码更改运行的传统持续集成/持续部署CI/CD)流水线不同,GitOps 通常将系统的实际状态与 Git 中定义的目标状态进行协调。虽然这确保了一致性和可靠性,但这也意味着随着应用程序数量的增加,资源消耗可能相应增加。因此,必须采取深思熟虑的方法,以优化 GitOps 实践,减少对环境的影响,同时不妥协系统的效率和可靠性。GitOps 的未来可能会出现创新,使其能够在可持续的基础上扩展,在保持高标准的自动化、一致性和声明性基础设施管理的同时,明智地管理资源消耗。

GitOps 在新兴技术中的角色

在快速发展的技术领域中,GitOps 作为一种关键的方法论脱颖而出,尤其在新兴技术领域。它代表了一种范式转变,强调将 Git 作为单一真实来源(SSOT)并自动化部署过程,从而比以往任何时候都更紧密地将开发与运维结合在一起。在组织应对现代软件部署的复杂性,特别是在云原生环境中以及处理创新技术时,这种方法论变得越来越重要。以下是 GitOps 在新兴技术中的作用总结:

  • 增强云原生生态系统:随着组织越来越多地采用云原生技术,管理这些环境的复杂性也在增加。GitOps 提供了一种结构化、可预测的方法来管理这种复杂性,使用版本控制来管理整个云原生基础设施的状态。这对于 Kubernetes、无服务器架构和服务网格技术尤为重要,因为这些技术的配置和状态至关重要。GitOps 不仅简化了这些技术的管理,还增强了安全性、可审计性和透明度,这些在云原生生态系统中至关重要。

  • 促进边缘计算:随着边缘计算的兴起,一致性和安全地管理众多远程环境已成为一项挑战。GitOps 提供了一种可靠的方法,用于跨各个边缘位置部署和管理应用程序。通过将配置保存在 Git 中,组织可以确保更改是可追溯的、可验证的,并且可以自动部署,从而减少人为错误的可能性并提高运营效率。

  • 加速人工智能和机器学习(ML)操作:GitOps 在人工智能和机器学习操作中的集成简化了复杂 AI 模型的部署和 ML 基础设施的持续交付。它确保数据科学家和 ML 工程师可以专注于模型开发和实验,而无需担心基础设施。GitOps 自动化了部署过程,确保了 AI 应用程序的一致性、可重复性和可靠交付。

  • 支持物联网(IoT)部署:物联网涉及管理大量设备,每个设备可能运行不同的软件版本。GitOps 在自动化这些设备上软件的部署和管理中发挥着至关重要的作用,确保一致性、可靠性和安全性。GitOps 的声明式方法意味着物联网基础设施的期望状态可以进行版本控制并自动应用,从而减少复杂性并提高物联网操作的可扩展性。

  • 提升 DevSecOps 中的安全性:在 DevSecOps 世界中,将安全性融入 开发与运维生命周期 是至关重要的。GitOps 通过确保所有更改都经过审查、批准并可追溯,支持这一点。这有助于严格的审计追踪、在出现问题时快速回滚,并且提供一个更加安全的基础设施部署管道,从而提升组织整体的安全态势。

GitOps 不仅仅是一个趋势,更是我们管理新兴技术的一种根本性变革。它架起了开发和运维之间的桥梁,确保了更快、更安全和更可靠的软件交付。在我们继续拥抱新技术并面对新挑战时,GitOps 的原则为管理现代 IT 环境的复杂性提供了坚实的基础,使其成为当今技术领导者必备的工具。

总结

在这一章中,我们希望你能清晰地理解 GitOps 如何通过使用各种工具,促进经济和生态行动。采用 GitOps 的文化变革的重要性也应该变得更加明显,因为它使得多个团队能够协作,并自主部署符合公司利益的工具、政策等。虽然解读未来趋势并不简单,但结合我们讨论的 AI 工具所释放的潜力现在应该显而易见。最终,GitOps 旨在大规模地在分布式集群环境或逻辑分组的集群中部署、扩展和维护来自不同团队的各种工具或政策。

在《使用 Kubernetes 实现 GitOps》一书中,我们采取了实践的方式,探索了基于实际场景的可扩展和简单解决方案。从基础概念到高级实现,本书旨在为你提供必要的知识和工具,使你能够在 Kubernetes 环境中充分发挥 GitOps 的潜力。通过实际案例、行业专家的见解以及最佳实践的详细说明,我们希望你现在已经准备好有效地实施 GitOps 策略。

在你读完本书后,下一步就是将你所学的知识应用到实际项目中。尝试不同的工具,优化你的工作流程,并不断寻找优化和保护部署的方法。保持与社区的互动,跟进最新趋势,永远不要停止学习。

祝你在接下来的 GitOps 旅程中好运。愿你在运维卓越、可扩展性和创新方面取得新高度。感谢你与我们一起踏上这段旅程,祝你在所有 GitOps 相关的事业中取得成功。祝一切顺利,Pietro 和 Artem。

参考文献

posted @ 2025-06-30 19:27  绝不原创的飞龙  阅读(11)  评论(0)    收藏  举报