本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

使用 Terraform 和 Kubernetes

我维护着 Kubestack,这是一个开源的用于 Kubernetes 的 Terraform GitOps 框架,因此我花费大量时间使用 Terraform 和 Kubernetes 也就不足为奇了。Kubestack 使用 Terraform 配置诸如 AKS、EKS 和 GKE 等托管的 Kubernetes 服务,同时还将来自 Kustomize 基础的集群服务集成到 GitOps 工作流中。可以将集群服务视为在部署应用程序工作负载之前 Kubernetes 集群上所需的一切。

Hashicorp 最近宣布了 Terraform 与 Kubernetes 之间更好的集成。我借此机会概述一下目前如何将 Terraform 与 Kubernetes 一起使用以及需要注意的事项。

在这篇文章中,我将只关注使用 Terraform 来配置 Kubernetes API 资源,而不是 Kubernetes 集群。

Terraform 是一种流行的基础设施即代码解决方案,所以我在这里只做非常简短的介绍。简而言之,Terraform 允许将资源的期望状态声明为代码,并会确定并执行一个计划,将基础设施从当前状态转变为期望状态。

为了能够支持不同的资源,Terraform 需要集成相应 API 的提供程序。因此,要创建 Kubernetes 资源,我们需要一个 Kubernetes 提供程序。以下是我们的选择:

Terraform kubernetes 提供程序(官方)

首先是 官方 Kubernetes 提供程序。毫无疑问,这个提供程序是三者中最成熟的。然而,它有一个很大的警告,这可能也是使用 Terraform 来维护 Kubernetes 资源不是一个受欢迎的选择的主要原因。

Terraform 需要每个资源的模式,这意味着维护者必须将每个 Kubernetes 资源的模式转换为 Terraform 模式。这是一项巨大的工作,这也是为什么很长一段时间内支持的资源非常有限的原因。虽然这种情况随着时间的推移有所改善,但仍然不是所有资源都受支持。特别是自定义资源无法以这种方式支持。

这种模式转换还会导致一些需要注意的边缘情况。例如,Terraform 模式中的 metadata 是一个映射列表。这意味着您必须在 Terraform 中像这样引用 Kubernetes 资源的 metadata.namekubernetes_secret.example.metadata.0.name

然而,从好的方面来说,拥有 Terraform 模式意味着 Kubernetes 和其他 Terraform 资源之间的完全集成。例如,举例来说,使用 Terraform 创建一个类型为 LoadBalancer 的 Kubernetes 服务,然后在 Route53 记录中使用返回的 ELB 主机名来配置 DNS。

使用 Terraform 来维护 Kubernetes 资源的最大好处是集成到 Terraform 的计划/应用生命周期中。因此,您可以在应用更改之前查看计划的更改。此外,使用 kubectl,在没有人工干预的情况下从集群中清除资源并非易事。Terraform 可以可靠地完成这项工作。

Terraform kubernetes-alpha 提供程序

其次是新的 alpha Kubernetes 提供程序。为了应对当前 Kubernetes 提供程序的局限性,Hashicorp 团队最近发布了新提供程序的 alpha 版本。

此提供程序使用动态资源类型和服务器端应用来支持所有 Kubernetes 资源。我个人认为这个提供程序有可能成为一个游戏规则的改变者 - 即使 在 HCL 中管理 Kubernetes 资源 可能仍然不适合所有人。也许下面的 Kustomize 提供程序会有所帮助。

唯一真正的缺点是,明确不鼓励将其用于测试之外的任何用途。但是测试的人越多,它就越早准备好投入使用。所以我鼓励大家试一试。

Terraform kustomize 提供程序

最后,我们有 kustomize 提供程序。Kustomize 提供了一种使用继承而不是模板化来定制 Kubernetes 资源的方法。它旨在将结果输出到 stdout,您可以使用 kubectl 从那里应用更改。这种方法意味着 kubectl 的边缘情况,例如不清除或更改不可变属性,仍然使完全自动化变得困难。

Kustomize 是一种处理自定义的流行方法。但我正在寻找一种更可靠的方式来自动化应用更改。由于这正是 Terraform 的优势所在,因此诞生了 Kustomize 提供程序。

这里不赘述太多细节,但从 Terraform 的角度来看,此提供程序将每个 Kubernetes 资源视为 JSON 字符串。这样,它可以处理从 Kustomize 构建产生的任何 Kubernetes 资源。但是它有一个很大的缺点,即 Kubernetes 资源不能轻易地与其他 Terraform 资源集成。还记得上面的负载均衡器示例吗?

在底层,与新的 Kubernetes alpha 提供程序类似,Kustomize 提供程序也使用动态 Kubernetes 客户端和服务器端应用。展望未来,我计划弃用 Kustomize 提供程序中与新 Kubernetes 提供程序重叠的部分,并仅保留 Kustomize 集成。

结论

对于已经投资于 Terraform 的团队,或者正在寻找替代自动化中的 kubectl 方法的团队来说,Terraform 的计划/应用生命周期一直是自动化更改 Kubernetes 资源的一个有希望的选择。然而,官方 Kubernetes 提供程序的局限性导致其未被广泛采用。

新的 alpha 提供程序消除了这些局限性,并有可能使 Terraform 成为自动化更改 Kubernetes 资源的主要选择。

已经采用 Kustomize 的团队可能会发现使用 Kustomize 提供程序集成 Kustomize 和 Terraform 比使用 kubectl 更有益,因为它避免了常见的边缘情况。即使在这种设置中,Terraform 也只能轻松地用于计划和应用更改,而不能用于调整 Kubernetes 资源。未来,这个问题可以通过将 Kustomize 提供程序与新的 Kubernetes 提供程序结合使用来解决。

如果您对这三个选项有任何疑问,请随时在 Kubernetes Slack 中的 #kubestack#kustomize 频道上联系我。如果您碰巧尝试了任何提供程序并遇到问题,请提交 GitHub 问题,以帮助维护者修复它。