Terraform 统一流(terraform-k8s 实现剖析)
本文解释 terraform-k8s/ 如何作为本仓库的主交付路径,把应用、入口与观测统一到单条 Terraform 流程。
0. 基础概念速记(高密度)
- Root Module:可直接执行
terraform命令的入口目录;本仓库是envs/dev与envs/prod。 - Child Module:被 root 调用的可复用模块;本仓库是
modules/app|platform|observability。 - Backend/State 边界:状态文件归属边界;不同环境 root module 形成天然状态隔离。
- Kubernetes Provider:声明原生 K8s 资源(Deployment/Service/Ingress 等)。
- Helm Provider:声明 Helm release,把 chart 安装也纳入 Terraform 状态机。
- depends_on:显式跨模块依赖;避免平台组件未就绪时就下发观测资产。
- TF_VAR_*:敏感参数注入通道;用于替代把 secret 写入
tfvars。
1. 架构定位
terraform-k8s 不是“又一套脚本”,而是统一控制平面:
- Root module(
envs/dev、envs/prod)负责环境参数与状态边界。 modules/app负责业务运行面(app/postgres/edge-proxy + ingress)。modules/platform负责平台能力(ingress-nginx、kube-prometheus-stack Helm release)。modules/observability负责监控资产下发(Grafana dashboard/alert ConfigMap)。
即:环境编排在 env,资源语义在 module,第三方平台通过 Helm provider 接管。
2. 调用图与依赖关系
envs/dev/main.tf(prod 同构):
module "app":传入namespace/app_image/app_replicas/database_url/ingress_host。module "platform":传入grafana_admin_password。module "observability":depends_on = [module.platform],确保监控栈先存在再投递 dashboard/alert 配置。
这条依赖链避免“资产先下发但接收方未就绪”的竞态问题。
3. module 语义拆解
3.1 modules/app
管理对象(同一 namespace):
kubernetes_namespace_v1kubernetes_config_map_v1(Nginx 配置)kubernetes_deployment_v1(app/postgres/edge-proxy)kubernetes_service_v1(app/postgres/edge-proxy)kubernetes_ingress_v1
关键实现点:
DATABASE_URL由变量注入,不硬编码到镜像。- app Deployment 包含 requests/limits + readiness/liveness。
- ingress host 变量化,支持 dev/prod 分离域名。
3.2 modules/platform
通过 Helm release 安装:
ingress-nginxkube-prometheus-stack
关键实现点:
create_namespace = true,避免外部预建命名空间耦合。- Grafana admin 密码通过变量注入。
kube-prometheus-stack显式依赖 ingress release,降低首次安装波动。
3.3 modules/observability
向 monitoring namespace 下发两个 ConfigMap:
- Dashboard JSON(label:
grafana_dashboard=1) - Alert rule YAML(label:
grafana_alert=1)
这与 platform 模块中的 Grafana sidecar label 配置形成闭环:配置即资产,资产即 Git。
4. Secret 与环境边界
环境目录用 variables.tf 声明必填:
database_urlgrafana_admin_password
推荐注入路径:
source ./secrets.example.env(模板)- 本地真实值放
secrets.env(应被.gitignore忽略) - 或直接导出
TF_VAR_*
核心原则:tfvars 保存拓扑参数,敏感值由环境变量注入。
5. 统一流执行语义
以 dev 为例:
- 准备镜像:
docker build ...+kind load ... - 进入环境根:
cd terraform-k8s/envs/dev - 变量注入:
source ./secrets.example.env(或secrets.env) terraform init/validate/plan/apply
此时 Terraform 同时驱动:
- Kubernetes provider(原生对象)
- Helm provider(平台组件)
因此这是一条真正的“单入口多控制器”交付链。
6. 故障面与优先排查顺序
plan/apply报 provider 初始化问题:- 先
terraform init -upgrade或重新init。
- 先
apply报 kube API 不可达:- 检查
kubectl config current-context与集群状态。
- 检查
- Pod 未 Ready:
- 查 namespace 下 deployment/pod/events/logs。
- Grafana 无面板:
- 查
monitoring下 ConfigMap label 与 sidecar 配置是否一致。
- 查
7. 与其他路线的关系
- 对
serving-lab/docker-compose:统一流复用其镜像产物,但把运行面迁移到集群。 - 对
k8s/:统一流管理等价对象,但拥有环境隔离、模块复用和审计能力。 - 对
terraform/:统一流是其复杂版落地,继承同样的 state/plan/apply/destroy 心智模型。
8. 结论(仓库语义)
terraform-k8s 在本仓库中的角色是:唯一工业化主路径。
它把“应用部署 + 平台安装 + 观测资产下发”收敛为单次 Terraform 事务,具备可复用、可审计、可环境隔离的交付属性。