Template-as-Code 这事儿

架构师老刘 中级 1小时前 777 浏览 12 点赞 约 1 分钟

Cue、Jsonnet、Dhall 这批工具把「模板即代码」落地了:强类型、schema 校验、不可变数据流、导入机制全在语言层面解决。比如 Cue 里定一个 #Deployment schema,字段缺了、类型错、值不在枚举里,cue vet 直接拦住,根本轮不到 Kubernetes API Server 返回 400。

Template-as-Code 这事儿

#Deployment: {
	apiVersion: "apps/v1"
	kind:       "Deployment"
	metadata: {
		name: string
		labels: [string]: string
	}
	spec: {
		replicas: *1 | int & >=0
		selector: {
			matchLabels: [string]: string
		}
		template: {
			metadata: labels: [string]: string
			spec: containers: [...{
				name:  string
				image: string
				ports: [...{containerPort: int & >0 & <65536}]
			}]
		}
	}
}

把上面存成 schema.cue,业务侧只写数据文件:

// prod.cue
import "schema.cue"

#Deployment & {
	metadata: name: "payment-svc"
	labels:   app: "payment", env: "prod"
	spec: {
		replicas: 3
		selector: matchLabels: app: "payment"
		template: {
			metadata: labels: app: "payment"
			spec: containers: [{
				name:  "pay"
				image: "registry.io/pay:v1.2.3"
				ports: [{containerPort: 8080}]
			}]
		}
	}
}

cue export prod.cue 直接出标准 YAML,CI 里跑 cue vet ./... 做门禁。比 Helm lint 强在哪?字段级约束、跨文件引用、默认值推导、甚至能把 OpenAPI/JSON Schema 双向互转。

Jsonnet 走的是函数式路线,Google 内部 Borg 配置全靠它,mixin 库生态做监控大盘、告警规则复用极强。Dhall 更激进,直接把类型系统做成可全程可逆的纯函数语言,配置即证明。

缺点也明显:学习曲线陡、IDE 支持不如 YAML 完善、团队不想多背一门配置语言。但如果你维护 200+ 微服务的 K8s 清单、或者要在多云、多环境、多租户场景下保证配置不漂移,Template-as-Code 省下的排查时间足够覆盖上手成本。

现在新项目我倾向于:基础设施层用 Cue 做 schema 守门员,应用层仍让开发写熟悉的 Helm values,中间用 cue trim/cue export 做一层编译校验。不追求全栈替代,只在「改配置最怕手抖」的关键路径上卡类型。

kubernetesCueJsonnetDhall配置管理

全部回复 (3)

副业中创业者 初级 1小时前
cue 报错看半天不知哪行 yaml 出问题,调试比写 helm 还累
0 回复
脚本小子阿强 初级 1小时前
cue 定好默认值后,环境差异就只改副本数和镜像 tag,别的字段全靠 schema 兜底,改动一眼就能看到 diff
0 回复
小Kevin在路上 中级 1小时前
真推进项目前,先得搞定团队学这套语法的成本,不然写 yaml 的还得改写 cue
0 回复

发表回复

支持 Markdown 格式