<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>gitops | 伪架构师</title>
    <link>/tags/gitops/</link>
      <atom:link href="/tags/gitops/index.xml" rel="self" type="application/rss+xml" />
    <description>gitops</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Wed, 04 May 2022 15:12:39 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>gitops</title>
      <link>/tags/gitops/</link>
    </image>
    
    <item>
      <title>Crossplane vs Terraform</title>
      <link>/post/crossplane.vs.terraform/</link>
      <pubDate>Wed, 04 May 2022 15:12:39 +0800</pubDate>
      <guid>/post/crossplane.vs.terraform/</guid>
      <description>

&lt;p&gt;原文：&lt;a href=&#34;https://blog.crossplane.io/crossplane-vs-terraform/&#34; target=&#34;_blank&#34;&gt;Crossplane vs Terraform&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;作者：&lt;a href=&#34;https://blog.crossplane.io/author/negz/&#34; target=&#34;_blank&#34;&gt;Nic Cope&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Crossplane 经常被拿来和 HashiCorp 的 Terraform 作比较。企业平台团队往往会在淘汰 Terraform 寻求替代品的过程中发现 Crossplane。这两个项目还是有些相似的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;这两个产品都支持工程师用声明式的配置来对基础设施进行建模&lt;/li&gt;
&lt;li&gt;它们都可以用 &lt;code&gt;Provider&lt;/code&gt; 的形式支持多种多样的基础设施&lt;/li&gt;
&lt;li&gt;这两个产品都是具有强大社区的开源工具&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;二者的最大区别在于，Crossplane 是一个控制平面，而 Terraform 是一个命令行工具——或者说是一个控制平面的界面。本文会谈到企业在规模化应用 Terraform 的时候遇到的诸多痛点，并阐明 Crossplane 的解决之道。&lt;/p&gt;

&lt;h2 id=&#34;协作&#34;&gt;协作&lt;/h2&gt;

&lt;p&gt;通常情况下，Terraform 是由运维团队引入企业的。对于较小的工程师团队来说，Terraform 是一个很好的基础设施治理方案。用声明式配置的方法来表达基础设施，运维团队就可以采用软件工程的最佳实践进行工作——用版本控制的方式对配置进行管理，并对变更进行评审，而且还能在必要的时候进行回滚。&lt;/p&gt;

&lt;p&gt;在较多工程师协作管理组织的基础设施的情况下，Terraform 就显得有些凌乱了。Terraform 依赖一个单体式的状态文件，以此在基础设施的目标状态和实际状态之间进行映射。在应用配置时，必须锁定状态文件，所以 Terraform 的配置应用过程可能会产生一个数分钟的阻塞。在这个阻塞时间内，配置被独占，其他工程师或者实体都无法进行变更。类似地，Terraform 使用了一个单体式的 &lt;code&gt;apply&lt;/code&gt; 进程——并没有什么最佳实践来完成在配置中只修改一部分基础设施的操作。如果缓存和数据库在同一个配置里，就只能同时更新，而无法仅仅更新缓存。&lt;/p&gt;

&lt;p&gt;Terraform 推荐把单体式的配置分离为小粒度的配置。运维团队可能从一个 &lt;code&gt;production&lt;/code&gt; 配置开始，然后被鼓励分为 &lt;code&gt;production billing&lt;/code&gt;、&lt;code&gt;production auth&lt;/code&gt; 等小配置。这很难一蹴而就，所以随着时间的推移，需要进行大量的重构，并可能产生网状依赖的 Terraform 配置，其输入和输出也可能产生耦合。&lt;/p&gt;

&lt;p&gt;Crossplane 的资源模型被称为 XRM（Crossplane Resource Model），这个模型具备松耦合以及最终一致性的特征，因此提高了规模化协作的能力。在 Crossplane 中，基础设施中的每一块都是一个支持增删改查的 API 端点。Crossplane 的变更不需要依赖关系图，所以用单个数据库也能够管理整个生产环境。&lt;/p&gt;

&lt;h2 id=&#34;自助服务&#34;&gt;自助服务&lt;/h2&gt;

&lt;p&gt;现代化组织的基础设施管理模式，正在从中心化向自助化演进。运维团队（也称为平台团队）对基础设施进行抽象，研发团队可以根据需求进行消费。Terraform 通过 &lt;code&gt;Module&lt;/code&gt; 这样类似软件库的形式来支持这种进化，Terraform 和 Crossplane 一样，其资源都是外部 API 资源的忠实再现。模块对资源的配置基础上进行了简化的抽象，例如 &lt;a href=&#34;https://registry.terraform.io/modules/terraform-aws-modules/rds/aws/latest&#34; target=&#34;_blank&#34;&gt;RDS 模块&lt;/a&gt; 用八个（现在是九个了） Terraform 资源来表达 RDS 实例的概念。&lt;/p&gt;

&lt;p&gt;把应用团队当做 Terraform 配置的消费者意味着他们就是 Terraform 协作的主体。应用开发者被邀请参与组织基础设施的协作，像运维团队一样。平台团队邀请应用开发团队参与他们的工作流，而不仅是给他们提供服务。也就是说，应用团队必须学习新的、特定目标的工具集和语言——Terraform and the HashiCorp Configuration Language（HCL）。对于应用开发者来说，配置的抽象程度提高了，但是访问控制的抽象并没有随之提高。平台团队可以发布一个模块，让应用团队可以管理 RDS 实例，访问控制还是存在于云供应商的 API 级别，围绕着 &lt;code&gt;database subnet groups&lt;/code&gt; 和 &lt;code&gt;database parameter groups&lt;/code&gt; 进行。&lt;/p&gt;

&lt;p&gt;和 Terraform 模块等价的 Crossplane 概念是一个符合对象-XR。每个 XR 都是一个 API 端点。平台团队需要给每个 XR 定义 OpenAPI 结构并输出文档，并在 API 级别实现 RBAC。这样平台团队如果供应给应用开发团队数据库实例，开发团队就有权进行增删改查，而无需关注底层的 RDS 实例和 Subnet 等概念了。Crossplane 构建在 Kubernetes RBAC 基础之上，平台团队能够用轻松地同一个控制平面支持多个应用团队。每个团队都只具备自己需要的权限——有的可能只需要管理存储桶、其他的可能有权使用缓存和数据库。&lt;/p&gt;

&lt;p&gt;不仅如此，Crossplane 的 XR 能提供多种服务，Crossplane 用 Kubernetes 对象 &lt;code&gt;spec&lt;/code&gt; 和 &lt;code&gt;status&lt;/code&gt; 的方式，把 XR 的输入输出和它的实现进行解耦。如果应用程序团队被授权创建 PostgreSQL，他们可以轻松地从平台团队已经兼容的数据库中进行选择。这些服务类别可以表达生产、预发布和开发；AWS、Azure 以及 GCP；快或慢；以及各种条件的组合。&lt;/p&gt;

&lt;h2 id=&#34;集成和自动化&#34;&gt;集成和自动化&lt;/h2&gt;

&lt;p&gt;Terraform 的背后是很多 API，但其自身并没有 API。所以很多团队的自动化方式就是：向版本管理系统（例如 GIT）提交 Terraform 配置的办法融入到 CI/CD 管线之中。这种方式自然要优于从自己的笔记本上运行 Terraform。但这种做法在规模扩张的时候会出现问题。Terraform 是一个命令行工具，而不是一个控制平面，他是短寿的、一次性的进程；所以他只能在调用期间，对基础设施进行面向期待状态的调谐。不管从 CI/CD 还是笔记本上运行，Terraform 一般都是在工程师需要对基础设施进行更新时被执行的。&lt;/p&gt;

&lt;p&gt;Terraform 保守的按需执行的方式，可能会导致一个死锁。如前所述，应用 Terraform 配置的过程是全有或者全无的——如果在同一个配置中对缓存和数据库进行描述，那么无论更新哪个对象，都需要同时更新这两个配置。这样一来，如果有人绕开了 Terraform（直接变更基础设施），那么接下来运行 Terraform 计划的人会发现，Terraform 要试图撤销前面的变更。想象一下，一个工程师在半夜被叫醒，处理一个现场问题，他通过 AWS 控制台对生产环境的缓存配置进行了修改，并忘记通知给 Terraform。因此就有一种可能：基础设施的变化越频繁，应用 Terraform 配置的风险就越大。&lt;/p&gt;

&lt;p&gt;而在 Crossplane 来说，他构建的是一系列的长期运行的、一直在线的控制循环。他会持续地对基础设施进行观察和矫正，以使环境符合预期。这样就一定程度上阻止了绕过 Crossplane 的企图。当 Crossplane 接管资源之后，所有在 Crossplane 之外修改资源的尝试都会被自动地、持续地修正回预期状态。&lt;/p&gt;

&lt;p&gt;不提供 API 是企业应用 Terraform 的一大痛点。和 Terraform 进行集成是一个挑战——他的 操作语言是面向特定领域的 HCL 语言，而且使用命令行工具进行调用。Crossplane 开放了 REST API，这无疑是对自动化更加友好。不管是用 Shell 脚本、Python、或者 Erlang，都有途径和 REST API 进行集成——也就是说和 Crossplane 进行集成。&lt;/p&gt;

&lt;p&gt;Crossplane 不会暴露旧的 REST API。在 Kubernetes API 的基础上进行构建的 Crossplane API，让团队可以用 &lt;code&gt;kubectl&lt;/code&gt; 的方式对所有云或非云的基础设施进行编排，这样就和编排容器化应用的方式保持了一致。Crossplane 还能用 Kubernetes Secret 的方式来表达应用连接基础设施的凭据，简化集成过程。它可以和 ArgoCD、Gatekeeper 或者 Velero 进行协作，来进行 GitOps、策略支持以及备份等工作。构建 Kubernetes Operator，和 Crossplane 集成，有利于建设可靠的自动化过程。&lt;/p&gt;

&lt;h2 id=&#34;鱼与熊掌&#34;&gt;鱼与熊掌&lt;/h2&gt;

&lt;p&gt;Crossplane 和 Terraform 都能够编排基础设施。二者有一定的相似之处，但具体的编排方式却迥然不同。Terraform 用命令行界面来管理底层控制平面的 API；而 Crossplane 自己就是一个控制平面，能够在其他控制平面上建设抽象的编排能力。因为 Crossplane 让平台团队能够提供自己的控制平面，从而避免了 Terraform 面临的很多问题。&lt;/p&gt;

&lt;p&gt;读者可能会注意到，这两个项目是互补的——Terraform 是控制平面的界面，并且它的 Kubernetes Provider 能够对 Kubernetes 控制平面进行管理。这也就产生了 Terraform 和 Crossplane 进行协作的可能性。假设你的组织偏爱 HCL 而非 YAML，那么就可以使用 Terraform 来对 XR 及其组合进行定义，而应用团队则可以使用 Terraform 来对 Crossplane 对象的期待状态进行编排。&lt;/p&gt;

&lt;p&gt;我们认为 Crossplane 方案让平台团队为应用开发者赋能，使得开发者能够自助管理基础设施。如果有兴趣&lt;a href=&#34;https://crossplane.io/docs&#34; target=&#34;_blank&#34;&gt;开始尝试 Crossplane&lt;/a&gt;，或者有问题或者反馈，可以&lt;a href=&#34;https://slack.crossplane.io/&#34; target=&#34;_blank&#34;&gt;通过 Slack 联系我们&lt;/a&gt;。&lt;/p&gt;

&lt;h2 id=&#34;相关链接&#34;&gt;相关链接&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Crossplane 文档：&lt;code&gt;https://crossplane.io/docs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Slack：&lt;code&gt;https://slack.crossplane.io/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
