Ansible 在云原生 Kubernetes 环境中的作用有多大?
Ansible 在云原生 Kubernetes 环境中的作用有多大?
我最近经常听到一个问题:“为什么你们还在 Kubernetes 项目中使用 Ansible?” 接着通常会问:“既然开始使用 Kubernetes 了,写你的书 Ansible for Kubernetes 还有什么意义呢?”
我花了一些时间思考这些问题以及它们背后的动机,并希望撰写一篇博文来解答这些问题,因为很多人似乎对 Kubernetes 的作用、Ansible 的作用以及为什么这两者都是现代企业迁移到云原生技术栈(甚至完全云原生企业)中必要的技术感到困惑。
需要事先说明一个重要的注意事项,我直接引用我的书中的内容:
虽然 Ansible 几乎可以为你做任何事情,但它可能不是基础设施自动化的每个方面的正确工具。有时,其他工具可以更干净地与应用程序开发人员的工作流程集成,或者从应用程序供应商那里获得更好的支持。
我们应该始终防止 锤子定律。没有一个单一的基础设施工具——甚至最好的 Kubernetes 作为服务平台——能够满足整个企业的 IT 运营需求。如果说有什么不同的话,那就是我们已经看到了专业工具的爆炸式增长,正如 CNCF 全景图 所证明的那样。
Ansible 适用于云原生基础设施管理的多个领域,但我想在这篇文章中特别强调三个领域:
即 Ansible 如何融入容器构建、集群管理和应用程序生命周期流程。
我尤其要告诫团队不要在没有更广泛的自动化策略的情况下,一头扎进 Kubernetes。Kubernetes 无法管理你的整个应用程序生命周期,也不能自行引导;你不应该满足于自动化 Kubernetes 集群内部,同时使用手动流程来构建和管理你的集群;如果你管理多个集群,这将变得尤其危险,因为对于大多数环境来说,这是最佳实践(至少拥有一个暂存集群和一个生产集群,或者一个私有内部集群和一个面向公众的集群)。
容器构建
在过去十年中,服务器管理和应用程序部署变得越来越自动化。通常情况下,自动化变得更加直观和易于维护,尤其是在引入了配置管理和编排工具(如 CFEngine、Puppet、Chef 和 Ansible)之后。
不过,即使使用现代自动化工具,也没有一个完美的解决方案适用于所有应用程序部署。Java 有 WAR 文件和虚拟机。Python 有虚拟环境。PHP 有脚本和多个执行引擎。Ruby 有 Ruby 环境。对于运营团队来说,高效地管理五个、十个或更多开发栈的服务器和部署(有时每个栈的多个版本,例如 Java 7、Java 8 和 Java 11)是一个失败的命题。
幸运的是,容器化开始解决这个问题。开发人员不再交付源代码并期望运营团队能够处理多个环境的复杂性,而是交付容器,这些容器可以在几乎任何现代服务器环境上由兼容的容器运行时运行。
但在某些方面,容器构建领域的情况停滞不前;Dockerfile,它只不过是一个带有某些 Docker 特定 DSL 和用于解决镜像层大小问题的笨拙内联命令的 shell 脚本,在许多地方仍然被用作事实上的应用程序构建脚本。
你遇到过多少次像这样的难以理解的 Dockerfile?
我们可以做得更好。当然,Ansible 可以使用 Dockerfile 构建和管理容器,但 Ansible 也非常擅长直接构建容器镜像——如今,你甚至不需要安装 Docker!有一些更轻量级的开源构建工具,例如 Buildah,它与 Ansible 容器构建工具 ansible-bender 集成,可以使用更具表现力和可维护性的 Ansible Playbook 构建容器。
还有其他构建容器的方法。但我对许多开发人员和系统管理员选择了最低公分母 Dockerfile 来构建其关键基础设施组件感到惋惜,因为还有像 Ansible 这样更具表现力、可维护性和通用性的工具可以产生相同的最终结果。
集群管理
Kubernetes 集群并非凭空出现。根据你使用的集群类型,它们需要进行升级和集成的管理。集群管理可能会变得非常麻烦,尤其是在像大多数组织一样,你管理多个集群(多个生产集群、暂存和 QA 集群等)的情况下。
如果你在私有云或裸机服务器上运行,则需要一种方法来安装 Kubernetes 并管理集群中的各个服务器。Ansible 在编排多服务器应用程序方面有着良好的记录,而 Kubernetes 本身就是一个多服务器应用程序——它恰好通过容器化来管理一个或数千个其他多服务器应用程序。
像 Kubespray 这样的项目已经使用 Ansible 进行自定义 Kubernetes 集群构建,并且与数十种不同的基础设施配置兼容。
即使你使用托管 Kubernetes 产品(如 AKS、EKS 或 GKE),Ansible 也有 azure_rm_aks、aws_eks_cluster 和 gcp_container_cluster 等模块来管理集群,以及数千个其他模块来简化并在不同云提供商之间标准化集群管理。
即使你不需要多云功能,Ansible 也提供了有用的抽象,例如使用 cloudformation 模块管理 AWS 上的 CloudFormation 模板部署,或使用 terraform 模块管理 Terraform 部署。
一个应用程序完全存在于 Kubernetes 内部并且不需要与任何外部资源(例如网络设备、存储、外部数据库服务等)协调的情况非常罕见。如果你很幸运,可能有一个 Kubernetes Operator 来帮助你将应用程序与外部服务集成,但更多情况下没有。同样,Ansible 通过在一个用云原生的通用语言 YAML 编写的 playbook 中管理 Kubernetes 应用程序以及外部集成来提供帮助。
我再说一遍之前说过的话:你不应该满足于自动化 Kubernetes 集群内部,同时使用手动流程来构建和管理你的集群——尤其是在你有多个集群的情况下!
应用程序生命周期
Ansible 显示出巨大前景的最后一个领域是管理 Kubernetes 内部应用程序。使用 Ansible 和 Operator SDK 构建 Operator,你可以将所有应用程序的生命周期管理(部署、升级、备份等)编码到一个 Kubernetes Operator 中,并将其放置在任何 Kubernetes 集群中——即使你没有使用 Ansible 管理该集群中的任何其他内容。
与其强迫开发人员和运维团队学习 Go 或其他专门的语言来维护 Operator,你也可以使用 YAML 和 Ansible 来构建它。
这里有很多前景,尽管在某些情况下(至少在 Operator SDK 的当前状态下),你可能需要回到 Go 来处理更高级的用例。其强大之处在于能够在集群中运行的 Application Operator 内部依赖 Ansible 的数千个模块,以及任何类型的开发团队都能轻松采用。
对于已经使用 Ansible 的团队来说,将他们现有的 Ansible 知识、角色、模块和 playbook 迁移到 Kubernetes 管理 playbook 和基于 Ansible 的 Operator 是轻而易举的事情。对于 Ansible 的新用户来说,其在与 IT 自动化相关的所有方面(网络、Windows、Linux、安全等)的灵活性和易用性使其成为云原生编排的理想伴侣。