写点什么

从 IaC 到 IaD

作者:俞凡
  • 2022 年 1 月 31 日
  • 本文字数:6422 字

    阅读完需:约 21 分钟

用代码定义基础设施可以帮助我们方便的构建、跟踪基础设施,但代码本身隐含着逻辑和变化,对于基础设施来说,定义为数据更为恰当。原文:Shifting from Infrastructure as Code to Infrastructure as Data[1]

图片来源:Dzero Labs

人人想要 IaC


我一直被“基础设施即代码”(IaC,Infrastructure as Code)的理念所吸引。早在 2014 年,我的职责就是帮助团队安装供应商产品的新版本,不仅包括安装新软件,还包括配置新硬件。那时还没有云计算(至少在我工作的组织中是这样),意味着我们只能以非常痛苦的手动过程来配置新的虚拟机,需要写大量的文档和通过很多审批。尽管我们已经设法提供了虚拟机并装好了软件,但还是有很多技术和政治障碍。


那时候我就想,“这真的很有趣!(呃……也许除了政治……)如果能找到一份既能配置硬件,又能应用软件技能的工作,那就太好了。”我感觉好像发现了一些东西……😉


快进到 2021 年,现在处于云时代,如果不是通过编程的方式,根本无法想象如何配置和管理 IT 基础设施(网络、虚拟机、Kubernetes 集群、负载均衡器等),我们进入了基础设施即代码(IaC)的时代。

凭空创造基础设施?


图片来源:Sanketh Hiremath @unsplash


最重要的是,我们需要理解当使用 IaC 时,基础设施不是凭空产生的。让我们再深入挖掘一下……

很多人都知道公有云。公共云包括亚马逊的 AWS[2]、谷歌的 GCP[3]、微软的 Azure[4]、甲骨文的 OCI[5]、IBM Cloud[6]等等。这些公有云的底层是一个遍布全球的庞大数据中心网络,拥有堆积如山的硬件,所有这些硬件都由云服务商自己的框架管理。


尽管基础设施可能会被认为是无限的,但实际上私有云只有有限的物理基础设施。有两种私有云类型:内部的和托管的。内部私有云托管在组织自己的机房或数据中心,托管私有云由第三方服务提供商拥有和运营。托管私有云可以是单租户(专用于一个公司的数据中心),也可以是多租户(托管多个公司的数据中心)。 像 OpenStack[7]、Apache CloudStack[8]、Azure Stack[9]、IBM Cloud Private[10]等框架都可以用来管理私有云。


当我们在公有云或私有云中提供基础设施时,一般会通过 API 进行配置,API 与数据中心管理框架通信,数据中心管理框架从可用物理资源池中为我们提供虚拟资源(如虚拟磁盘、虚拟网络、虚拟机)。

最佳实践


在配置云基础设施时,我们应该始终遵循以下关键实践,从而让我们始终保持愉悦、减少压力:

1. 短生命周期(Ephemerality)

云基础设施的生命周期应该比较短,如果需要对基础架构进行变更,请将其拆除并重新创建。如果现在还是手动变更的,那就更有理由需要这样做了。更新配置文件,把变更纳入版本控制,这样就可以跟踪所有变更。


永远不要害怕多次创建和破坏基础设施。如果很好的定义了基础架构,每次重新创建时,它都会以相同的方式运行,所以有什么可怕的呢?


注意:基础架构应该是不可变的,无状态组件的生命周期应该是短暂的,而有状态组件则不是。数据库和事件中心不能随便拆除和重新配置。这个过程应该完全自动化,但是重新分配一个数据库或者像 Kafka 这样的事件中心可能会非常复杂并具有破坏性。

2. 版本控制(Versioning)

始终对基础架构定义进行版本控制,以便在需要时轻松重新创建资源。

3. 简单化(Simplicity)

一旦基础设施自动化过程变得过于复杂,并发现自己试图方枘圆凿,请立即停下来。例如,如果发现自己的工作超出了 API 或基础设施配置工具的限制,那么是时候进行备份并重新考虑策略了。

基础设施即数据(Infrastructure as Data)


撇开最佳实践不谈,在供应云基础设施时,还有一件事我们还没有解决。当我们为云基础设施编写代码时,我们真的是在编写代码吗?答案是否定的。😱


让我们回到开始的地方,当我不得不以老式的方式提供基础设施时,必须将一组规格或清单交给能够满足我要求的团队。对于基于云的基础设施,我们也在做同样的事情——只是我们的规范现在是由 API 传递和实现的,而不是由一个人。你不用关心这个请求是如何被实现的,只需要知道它被准确的实现了。


举个例子,如果你准备创建一个有 5 个节点的 Kubernetes 集群,集群上的工作负载是内存密集型的,你希望节点拥有高 RAM 和中等计算能力。当你告诉谷歌启动 GKE 集群时,只需要告诉它启动 5 个 RAM 密集型计算节点。当你创建集群时,不会在意幕后发生了什么,只关心最终得到了想要的那个集群。


因此,我们需要做的只是描述想要创建的资源,这意味着我们应该使用一些常见的格式,如 JSON 或 YAML 来描述它们。什么是 JSON 和 YAML?它们只是表示数据的纯文本。🤯


这个概念不是最近才出现的,事实上,Ansible 的创始人迈克尔·德哈恩(Michael DeHaan)[11]在 2013 年的一篇博客文章[12]中就说过:


"...基础设施最好的建模方式不是代码,也不是 GUI,而是基于文本的、中立的、数据驱动的策略。"


在文章的后面,他创造了一个术语“基础设施即数据”(IaD,Infrastructure as Data)来描述这个概念。

IaD 是一种对基础设施的声明式方法——也就是说,你只要说出想要的内容,而不指定实现它的精确操作或步骤。这是 Kubernetes Controllers[13],许多 CI/CD 工具(比如 GitHub Actions[14]),当然还有 Ansible[15]的概念。

谁会关心?


到这个时候,你可能想知道为什么我要花这么多精力试图说服你,IaD 是比 IaC 更好的范式。嗯,这么想很正常。


实话实说,这可以归结为一个词:简单。我已经花了足够的时间在 GCP 和 Azure 上配置云基础设施,可以告诉你,当你开始扩展基础设施时,事情会变得非常复杂。


当然,你会希望以一种良好的、结构化的方式配置和管理基础设施。老兄,这就是 JSON 的作用。但是要编写代码来实现?老实说,这毫无意义,基础设施是静态的,不是应用程序。


将基础设施视为代码打开了技术债的大门。记住,并不是所有的代码都是平等的,糟糕的代码会让你的生活变成人间地狱。


它也会带来不必要的复杂性。为什么你需要管理一大堆代码来定义基础设施,而实际上你所需要做的只是描述它?

配置云基础设施的方法


我们暂时把 IaD 放在一边,转而讨论配置云基础设施。我保证这是有意义的,请耐心听我说。


配置云基础设施的方法有很多。当我们进行配置时,这些方法会执行我们的代码,或者某些框架会解释我们的基础架构定义。下面我们粗略看一下这些不同的方法。

Terraform

Hashicorp[16]的 Terraform[17]是非常流行的平台中立工具,用于为各种公有云和私有云框架提供基础设施。它基于专有的类 JSON 的语言 HCL(Hashicorp Configuration Language)[18]来定义基础设施,支持一些非常简陋的循环、条件以及变量。Terraform 依赖一个 JSON 状态文件[19]来跟踪创建的基础设施,可以将此文件视为结构化日志。

Pulumi

几个前微软员工[20]创立了 Pulumi[21],目标直指广阔的 Terraform 市场。它也是平台中立的,借用了 Terraform 的许多概念,包括状态文件。主要的区别是 Pulumi 允许通过使用常规的 ole 编程语言来创建基础设施。Pulumi 目前支持的语言包括:TypeScript、Javascript、Python、Go 和 C#。


注:Terraform 最近通过推出 Pulumi 风格的 Terraform CDK[22]来反击 Pulumi。

Ansible

虽然一开始 Ansible 只是一个配置管理工具,但现在也可以用来配置和管理云基础设施[23]。Ansible 使用 YAML 来定义基础设施。与 Terraform 和 Pulumi 不同的是,Ansible 是无状态的。

Crossplane

Crossplane[24]是一个运行在 Kubernetes 上的云中立工具,用于在 Kubernetes 之外提供云资源。(我知道……这会让你很困惑!)因为它是原生支持 Kubernetes 的,所以是声明式的,并且使用 YAML 来描述正在配置的基础设施。Crossplane 还很新,因此,虽然它支持许多 AWS 资源[25],但对其他云服务商(如 Azure[26]和 GCP[27])的支持相对较少。我写了一篇文章[28]记录了用 Crossplane 配置 GCP 集群的探索。

云服务商的命令行工具(Cloud Provider CLIs)

值得一提的是,云服务商的命令行工具是另一种配置基础设施的流行方式。当我说“云服务商的命令行”时,我指的是像 Azure 的 az[29]命令行和谷歌云平台的 gcloud[30]命令行。其他云服务商也有类似的命令行工具。这些命令行工具有一个共同点:它们提供了一种与云服务商 API 交互的方式,从而可以创建和管理资源。如果采用这种方式,我们需要编写包装器代码或者脚本来进行不同的命令行调用,从而实现基础设施的配置。

哪个工具最好?

图片来源:wearearmadillo.com


上面列出的所有工具中,我认为只有两个真正将基础设施视为数据,并且提供了云基础设施的最佳实践:Ansible 和 Crossplane


为什么?


Terraform(声明式)和 Pulumi(基于代码)都使用状态文件,我意识到我可能是为数不多的被这个问题困扰的人之一。状态文件的存在是为了跟踪 Terraform 创建了哪些资源,从而确保它们不会被不必要的意外重新创建。虽然这是一个勇敢的想法,但我发现这违背了云基础设施的短生命周期原则——我们就应该重新创建它。


同样的,假设我们开始使用 Terraform 创建 3 个云资源。然后添加另一个资源,因为最初的 3 个资源在状态文件中,所以它们会保持原样,只有新资源被添加进去。但是你怎么知道这四种资源是和谐共存的呢?你不知道。除非你删除所有 4 个资源,然后从头开始重新创建它们。


最后,假设我们使用 Terraform 创建了云资源。然后,使用云服务商的管理控制台或 CLI 修改了它。你猜怎么着?Terraform 不知道发生了什么。状态文件不再与资源的实际状态同步。你完了!


作为个人偏好,我很不喜欢 Terraform 的 HCL,我完全读不懂 HCL 的代码。(对不起,Hashi 的粉丝!)此外,我也不喜欢 Terraform 在控制流和循环方面的尝试。对我来说,这让我头晕,我讨厌这样。🤢


作为软件工程师,我对 Pulumi 更感兴趣——我随时有可能用它接管 Terraform。然而,从 SRE 的角度来看,它并不是声明式设计。虽然编程语言很好,但也可能导致自动化过度复杂。记住:有一种东西叫做糟糕的代码,而糟糕的代码会导致技术债。


云服务商 CLI 是无状态的,我喜欢,但它们也不是声明式的。此外,为了使它们更加有效,还需要将它们包装在代码或脚本中。放弃了。


那我们就只剩下 Ansible 和 Crossplane 了。根据定义,Ansible 是声明式和无状态的,并且使用 YAML,这非常容易阅读——甚至比 JSON 更容易阅读。赢了!此外,让我惊讶的是,通过各种云服务商提供的库,Ansible 非常容易创建云基础设施。


Crossplane,作为原生支持 Kubernetes 的工具,也是声明式的,但不是完全无状态的。你看,因为 Crossplane 运行在 Kubernetes 上,利用了 etcd[31](Kubernetes 的分布式键值存储),每当我们更改 Crossplan 基础架构定义时,都会被记录在 etcd 中,这让你觉得它的行为就像 Terraform/Pulumi 的状态文件一样,只是稍微有点不同。Crossplane 的博客[32]上说:“无论变更是否在预期内,它都会不断观察和纠正组织的基础设施,使其符合预期的配置。”我真的太喜欢这一点了!

结论


该死,太让人难以接受了!我们回顾一下前面的内容:


  • 云上创建的资源(无论是公共的还是私有的)并不是凭空创建的,而是从现有的(有限的)物理资源中分配出来的虚拟资源。

  • 基于云的基础设施应该是短暂的、简单的和版本控制的。

  • 最好将基础设施视为数据,而不是代码。

  • 基础设施即数据(IaD)不是一个新概念——它至少可以追溯到 2013 年!

  • 大多数云配置工具都不适合 IaD,只有 Ansible 和 Crossplane 符合要求。


最后奖励你一幅老鼠 Susie 的照片。


老鼠 Susie 喜欢拥抱,基础设施就是数据!图片由 Dzero 实验室提供。


Peace, love, and code.


相关文章:

Using Ansible's GCP Library to Provision a Kubernetes Cluster in Google Cloud: https://medium.com/dzerolabs/using-ansibles-gcp-library-to-provision-a-kubernetes-cluster-in-google-cloud-6fd1910f1700

Using Crossplane to Provision a Kubernetes Cluster in Google Cloud: https://medium.com/dzerolabs/using-crossplane-to-provision-a-kubernetes-cluster-in-google-cloud-cf5374d765ee


延伸阅读:


References:

[1] Shifting from Infrastructure as Code to Infrastructure as Data: https://medium.com/dzerolabs/shifting-from-infrastructure-as-code-to-infrastructure-as-data-bdb1ae1840e3

[2] AWS: https://aws.amazon.com/

[3] GCP: https://cloud.google.com/

[4] Azure: https://azure.microsoft.com/en-ca/

[5] OCI: https://www.oracle.com/ca-en/cloud/

[6] IBM Cloud: https://www.ibm.com/cloud

[7] OpenStack: https://www.openstack.org/

[8] Apache CluodStack: https://cloudstack.apache.org/

[9] Azure Stack: https://azure.microsoft.com/en-ca/overview/azure-stack/

[10] IBM Cloud Private: https://www.ibm.com/blogs/cloud-computing/2017/10/31/what-is-ibm-cloud-private/

[11] Ansible: https://en.wikipedia.org/wiki/Ansible_%28software%29

[12] The Rise of Instrastructure as Data: http://radar.oreilly.com/2013/08/the-rise-of-infrastructure-as-data.html

[13] Just-in-Time Kubernetes: A Beginner’s Guide to Understanding Kubernetes Core Concepts:https://medium.com/dzerolabs/just-in-time-kubernetes-a-beginners-guide-to-kubernetes-core-concepts-19ee7acbafa1

[14] Workflow syntax for GitHub Actions: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions

[15] Ansible: https://www.ansible.com/

[16] Hashicorp: https://www.hashicorp.com/

[17] Terraform: https://www.terraform.io/

[18] Hashicorp Configuration Language: https://github.com/hashicorp/hcl

[19] The Terraform State File: An Overview: https://www.infrastructurecode.io/blog/the-terraform-state-file-an-overview

[20] Former Microsoft Midori team members launch Pulumi, an open-source cloud development company: https://www.zdnet.com/article/former-microsoft-midori-team-members-launch-pulumi-an-open-source-cloud-development-company/

[21] Pulumi: https://www.pulumi.com/

[22] Terraform CDK: https://github.com/hashicorp/terraform-cdk

[23] Cloud Support with Ansible: https://www.ansible.com/integrations/cloud

[24] Crossplane: https://crossplane.io/

[25] crossplane/provider-aws: https://doc.crds.dev/github.com/crossplane/provider-aws

[26] crossplane/provider-azure: https://doc.crds.dev/github.com/crossplane/provider-azure

[27] crossplane/provider-gcp: https://doc.crds.dev/github.com/crossplane/provider-gcp

[28] Using Crossplane to provision a Kubernetes cluster in Google Cloud: https://medium.com/dzerolabs/using-crossplane-to-provision-a-kubernetes-cluster-in-google-cloud-cf5374d765ee

[29] Azure Command-Line Interface (CLI) documentation: https://docs.microsoft.com/en-us/cli/azure/

[30] gcloud tool overview: https://cloud.google.com/sdk/gcloud

[31] About etcd: The data backbone of Kubernetes: https://medium.com/pradpoddar/about-etcd-the-data-backbone-of-kubernetes-e86ea1d4feeb

[32] Crossplane vs Terraform: https://blog.crossplane.io/crossplane-vs-terraform/


你好,我是俞凡,在 Motorola 做过研发,现在在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。

微信公众号:DeepNoMind

发布于: 刚刚阅读数: 2
用户头像

俞凡

关注

还未添加个人签名 2017.10.18 加入

俞凡,Mavenir Systems研发总监,关注高可用架构、高性能服务、5G、人工智能、区块链、DevOps、Agile等。公众号:DeepNoMind

评论

发布
暂无评论
从IaC到IaD