☰
90DaysOfDevOps 第 61 天:使用 Terraform 管理 Kubernetes 集群内资源与多环境部署
2026/10/8 15:35:13 网站建设 项目流程
  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

在 90DaysOfDevOps 的 IaC(基础设施即代码)学习路线中,前几课已经分别用 Terraform 部署了 VirtualBox 虚拟机与 Docker 容器。本篇第 61 天的内容将把 Terraform 的使用范围延伸到 Kubernetes:不仅可以用 Terraform 编排集群本身,还能直接管理集群内部的对象(namespace、deployment、service),并通过terraform workspaces或目录文件结构两种方式,将同一套代码复用到 dev、staging、production 多环境。读完本篇,你将掌握 Kubernetes Provider 的核心用法、一条完整的 nginx 应用部署链路,以及多环境隔离方案的选择依据。

从虚拟机、容器到 Kubernetes:为什么用 Terraform 管理集群内对象

到目前为止,本部分课程已经演示过两条 IaC 路径:用 Terraform 定义并部署 VirtualBox 虚拟机(见 virtualbox.tf),以及用 Terraform 拉取 nginx 镜像并启动 Docker 容器(见 docker.tf)。它们的原则一致:用代码声明"最终应该长什么样",再由工具执行部署。

本课的主题是第三条路径——Kubernetes。Terraform 可以从两个层面与 Kubernetes 交互:

  • 集群层面:用于创建、销毁整个 Kubernetes 集群。作者本人曾用它跨三大主流云厂商部署演示用集群。
  • 集群内部层面:管理集群中的对象,例如 namespace、deployment、service 等。这可以通过两个官方 Provider 实现:
    • Kubernetes Provider:直接管理原生的 Kubernetes 资源对象;
    • Helm Provider:管理 Helm Chart 的部署与发布。

为什么不用 kubectl 而用 Terraform

前面课程已经展示过kubectl的用法,但在 Kubernetes 环境中使用 Terraform 仍有其独特价值:

  • 统一的工作流:如果你已经用 Terraform 部署了集群,那么可以继续用同一套工作流和工具来管理集群内部资源,无需在 kubectl 与 Terraform 之间来回切换心智模型;
  • 生命周期管理:Terraform 不只是"一次性供给"工具,它同时支持变更、更新与删除。通过 state 文件跟踪资源现状,任何修改都能以声明式方式收敛到目标状态。

简单 Kubernetes 实战:用 Terraform 部署 nginx 到 minikube

为了延续前几课的演示风格,本课同样选用 minikube 作为本地 Kubernetes 环境。完整的配置文件保存在仓库的 kubernetes.tf 中,与文档中的示例完全一致。它的目标很明确:定义 Kubernetes Provider、指向本机 kubeconfig、创建一个名为nginx的 namespace,再创建一个 2 副本的 deployment,最后暴露一个 service。

完整的kubernetes.tf内容如下:

terraform { required_providers { kubernetes = { source = "hashicorp/kubernetes" version = ">= 2.0.0" } } } provider "kubernetes" { config_path = "~/.kube/config" } resource "kubernetes_namespace" "test" { metadata { name = "nginx" } } resource "kubernetes_deployment" "test" { metadata { name = "nginx" namespace = kubernetes_namespace.test.metadata.0.name } spec { replicas = 2 selector { match_labels = { app = "MyTestApp" } } template { metadata { labels = { app = "MyTestApp" } } spec { container { image = "nginx" name = "nginx-container" port { container_port = 80 } } } } } } resource "kubernetes_service" "test" { metadata { name = "nginx" namespace = kubernetes_namespace.test.metadata.0.name } spec { selector = { app = kubernetes_deployment.test.spec.0.template.0.metadata.0.labels.app } type = "NodePort" port { node_port = 30201 port = 80 target_port = 80 } } }

逐段解读这份配置:

  • Provider 声明:required_providers锁定hashicorp/kubernetes且要求版本>= 2.0.0;provider "kubernetes"块通过config_path指向~/.kube/config,即复用本机 kubectl 的认证配置,无需额外保存集群凭据;
  • namespace:创建名为nginx的命名空间,作为后续资源的隔离边界;
  • deployment:通过replicas = 2声明两个副本,selector 与 template 使用一致的标签app = "MyTestApp"(这是 Kubernetes 将 Pod 与 Deployment 关联起来的关键),容器镜像为nginx,容器名nginx-container,暴露 80 端口;
  • service:类型为NodePort,node_port固定为30201,将容器 80 端口映射到节点端口,selector直接引用 deployment 模板中的标签值(kubernetes_deployment.test.spec.0.template.0.metadata.0.labels.app),实现了资源之间的显式引用而非手写字符串,这是 Terraform 管理 Kubernetes 的一个典型技巧。

执行流程:terraform init → apply → 验证

在新建的项目目录中,第一步执行terraform init,它会下载并初始化 kubernetes Provider 到本地插件目录:

执行terraform apply之前可以先确认集群中还没有任何 namespace(示例中 minikube 的默认集群此时没有任何 namespace):

随后运行terraform apply,Terraform 会按依赖关系依次创建三个新资源——namespace、deployment 和 service:

apply 完成后,可以用kubectl get namespaces、kubectl get deployments -n nginx、kubectl get services -n nginx等命令查看集群内的实际部署结果:

访问应用:kubectl port-forward

由于演示环境是 minikube,直接依赖 Docker 网络的 ingress 方案存在一些限制。本课采用最直接的验证方式:执行kubectl port-forward -n nginx svc/nginx 30201:80,将集群内的 Service 转发到本机端口,然后在浏览器中访问http://localhost:30201/,即可看到 NGINX 的默认欢迎页:

至此,一套"代码声明 → Terraform 执行 → kubectl 验证"的 Kubernetes 应用交付闭环已经跑通。从仓库结构来看,这正是整个 IaC 学习路径的一部分:本课对应的 kubernetes.tf 与前一课 docker.tf、Docker-WordPress/docker-wordpress.tf 同处于 IaC 目录下,展示了同一份学习代码库如何从单机容器逐步演进到容器编排平台。

多环境部署:workspaces 与文件结构之争

学会了单环境部署后,自然会遇到这样的问题:如果想把 dev、staging、production 三个环境做得一模一样并复用同一份代码,Terraform 提供了两种主流做法:

  • terraform workspaces:在一个 backend 中划分多个命名的 state 段;
  • 文件结构(file structure):用目录布局实现环境分离,用 module 实现代码复用。

两种方案各有利弊,选择时取决于团队的隔离需求与运维习惯。

Terraform workspaces

优点:

  • 上手简单:创建独立 workspace 非常直接,几乎零学习成本;
  • 表达式便利:可以在配置中直接使用terraform.workspace表达式,按当前环境动态生成资源命名或参数;
  • 减少代码重复:一份配置同时服务多个环境,无需复制目录。

缺点:

  • 易受人为错误影响:多个环境共享同一份 state backend,误切 workspace 可能导致操作错环境(而这恰恰是引入 IaC 想要消除的风险);
  • state 集中存储:所有环境的 state 保存在同一个 backend 中,隔离度低;
  • 代码可读性不足:从代码库本身无法一眼看出某个环境对应的部署配置,环境差异隐含在 workspace 切换中。

文件结构(目录分离)

优点:

  • backend 隔离:每个环境拥有独立的 state backend,安全性与环境边界更清晰;
  • 降低人为错误:环境之间物理隔离,误操作面更小;
  • 代码即事实:代码库的目录结构完整、明确地呈现了各环境的部署状态。

缺点:

  • 多次 apply:要为多个环境分别运行terraform apply,部署次数随环境数线性增加;
  • 代码重复:目录复制会带来一定量的重复代码,但可以通过 module 机制将公共部分抽取复用,把重复降到最低。

从仓库源码看本课的延伸印证

仓库中与本课直接相关的证据主要有三处,可以作为进一步学习的入口:

  1. Kubernetes/kubernetes.tf:本课核心配置的真实落盘版本,与文档示例一致,可作为模板直接复制使用;
  2. Docker/docker.tf 与 Docker-Wordpress/docker-wordpress.tf:前一课(Day 60)的 Docker 容器与 WordPress 多容器示例,与 Kubernetes 一课形成"容器 → 编排"的递进关系;
  3. Terratest:仓库还提供了面向 AWS 的 Terratest 示例(examples 下的instance.tf、provider.tf、securitygroup.tf、versions.tf等,以及 test/terraform_test.go 的 Go 测试代码),展示了"基础设施代码 + 自动化测试"的进阶方向——当你把环境数量变多后,为 Terraform 代码编写可重复的测试是降低多环境运维风险的实用手段。

小结

本课完成了一次"Terraform × Kubernetes"的完整闭环:用 Kubernetes Provider 在 minikube 中声明式地创建 namespace、deployment 与 service,用terraform init/apply驱动部署,再用kubectl port-forward完成访问验证。在此基础上,terraform workspaces与目录文件结构给出了多环境复用的两条路径:前者胜在快捷、代码少,但隔离与可读性弱;后者隔离彻底、代码即事实,代价是多次 apply 与一定的代码重复(可用 module 化解)。实际选型时,建议先明确团队对 state 隔离、安全边界与运维粒度的要求,再决定采用哪一种模式。

继续学习下一课:Ngày 62(第 62 天)。

  • 文档/教程

【免费下载链接】90DaysOfDevOps

This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询