- 文档/教程
【免费下载链接】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.
在 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 机制将公共部分抽取复用,把重复降到最低。
从仓库源码看本课的延伸印证
仓库中与本课直接相关的证据主要有三处,可以作为进一步学习的入口:
- Kubernetes/kubernetes.tf:本课核心配置的真实落盘版本,与文档示例一致,可作为模板直接复制使用;
- Docker/docker.tf 与 Docker-Wordpress/docker-wordpress.tf:前一课(Day 60)的 Docker 容器与 WordPress 多容器示例,与 Kubernetes 一课形成"容器 → 编排"的递进关系;
- 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.
相关推荐
90DaysOfDevOps 第 61 天实战:用 Terraform 管理 Kubernetes 资源与多环境部署
90DaysOfDevOps 第 61 天实战:用 Terraform 管理 Kubernetes 资源与多环境部署 导读 本篇文章是 90DaysOfDevO
文档/教程90DaysOfDevOps 第 61 天:用 Terraform 编排 Kubernetes 资源与多环境部署
90DaysOfDevOps 第 61 天:用 Terraform 编排 Kubernetes 资源与多环境部署 本文是 90DaysOfDevOps 挑战中“
文档/教程90DaysOfDevOps 实战:用 Terraform 管理 Kubernetes 资源与多环境部署(Day 61)
90DaysOfDevOps 实战:用 Terraform 管理 Kubernetes 资源与多环境部署(Day 61) 导读 本文是 90DaysOfDevO
文档/教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考