关于 materialize-terraform-self-managed
这是用于指导使用 materialize-terraform-self-managed 仓库在 AWS、Azure 或 GCP 部署 Materialize 的技能。它面向运维人员和 Terraform 用户,涵盖云基础设施与 Kubernetes 模块、实例配置及发布流程。
主要功能
- 01支持 AWS、Azure 和 GCP 部署
- 02云基础设施与 Kubernetes 分层指南
- 03Materialize 实例配置说明
- 04CRD 版本与发布策略说明
- 05现有 Terraform 项目集成指南
适用场景
- 01按云平台配置 Materialize 部署
- 02调整实例资源和身份验证设置
- 03规划升级与滚动发布
- 04在现有 Terraform 项目中引用模块
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ materializeinc/ agent-skills --skill materialize-terraform-self-managed安装后在 Claude Code 中输入/materialize-terraform-self-managed确认已加载。
详细介绍
Materialize Terraform 自管理模块
生产就绪的 Terraform 模块,用于在 AWS、Azure 和 GCP 上部署 Materialize,由 materialize-terraform-self-managed 仓库维护。每个云服务提供商都有自己的一组模块,此外还有用于 Operator 和 Materialize 实例的共享 Kubernetes 模块。
本技能中的所有文件路径均指向该仓库。需要查看实际模块代码时,请克隆仓库或从 GitHub 获取单个文件。
仓库布局
aws/
modules/ # AWS-specific infra modules
examples/
simple/ # Minimal production-like deployment
enterprise/ # Adds Ory (Kratos + Hydra) for auth
azure/
modules/ # Azure-specific infra modules
examples/
simple/
enterprise/
gcp/
modules/ # GCP-specific infra modules
examples/
simple/
enterprise/
kubernetes/
modules/ # Cloud-agnostic K8s modules (operator, instance, cert-manager)
test/ # Rust-based integration test harness
scripts/ # Migration and utility scripts
如何使用本技能
- 用户想在特定云上部署 Materialize:从仓库中相关的
<cloud>/examples/simple/目录开始。在该目录中阅读main.tf和variables.tf,了解完整的可运行配置。 - 用户询问特定模块:阅读该模块的
<cloud>/modules/<name>/variables.tf和main.tf。 - 用户想自定义实例:阅读
kubernetes/modules/materialize-instance/variables.tf,了解所有实例级选项。 - 用户询问升级或滚动发布:请参阅下文的升级部分,以及
kubernetes/modules/materialize-instance/variables.tf中的滚动发布配置。 - 用户想设置企业版/身份验证:阅读
<cloud>/examples/enterprise/。 - 用户已有 Terraform 项目:请参阅下文的“在现有 Terraform 项目中使用这些模块”。
架构层
每次部署都会创建两个层:
云基础设施(特定于云的模块):
- 网络:VPC/VNet、子网、NAT、安全组
- Kubernetes:带自动扩缩容的 EKS/AKS/GKE 集群
- 数据库:用于存储 Materialize 元数据的托管 PostgreSQL
- 存储:用于持久化层的对象存储(S3/Blob/GCS)
Kubernetes 应用(kubernetes/modules/ 下的共享模块):
- 用于 TLS 证书的 cert-manager
- Materialize Operator(Helm chart)
- Materialize 实例(自定义资源)
云服务提供商模块
AWS(aws/modules/)
| 模块 | 用途 |
|---|---|
networking | VPC、子网、NAT 网关、安全组 |
eks | 带 OIDC 提供商的 EKS 集群 |
eks-node-group | 用于基础工作负载的托管节点组 |
karpenter | Karpenter 自动扩缩容控制器 |
karpenter-ec2nodeclass | 用于 Karpenter 配置资源的 EC2NodeClass |
karpenter-nodepool | 用于 Karpenter 调度的 NodePool |
database | 用于存储元数据的 RDS PostgreSQL |
storage | 配置了 IRSA 的 S3 存储桶 |
aws-lbc | AWS Load Balancer Controller |
nlb | 网络负载均衡器 |
operator | Materialize Operator(Helm) |
ebs-csi-driver | EBS CSI 驱动程序 |
vpc-cni | 支持网络策略的 VPC CNI |
AWS 主要模式:
- 通过 Karpenter 自动扩缩节点(不使用集群自动扩缩器)
- 两种 Karpenter 节点类:通用型(t4g.xlarge)和 Materialize 型(配备 NVMe 交换空间的 r8gd.2xlarge)
- 通过 IRSA(服务账户 IAM 角色)进行存储身份验证
- 使用 NLB 对外开放端口 6875(SQL)、6876(HTTP)、8080(控制台)
Azure(azure/modules/)
| 模块 | 用途 |
|---|---|
networking | VNet、子网、NAT 网关 |
aks | 使用 Cilium 网络的 AKS 集群 |
nodepool | 额外的 AKS 节点池 |
database | PostgreSQL Flexible Server |
storage | 配置了工作负载身份的 Storage Account |
load_balancers | Azure 负载均衡器 |
operator | Materialize Operator(Helm) |
Azure 主要模式:
- 使用 Cilium 提供网络和网络策略
- 通过工作负载身份联合进行存储身份验证(无密码 OIDC)
- Materialize 节点使用带交换空间的 Standard_E4pds_v6 实例
- 使用专用 DNS 区域解析 PostgreSQL
- 需要注册
EnableAPIServerVnetIntegrationPreview功能
GCP(gcp/modules/)
| 模块 | 用途 |
|---|---|
networking | VPC、子网、Cloud NAT |
gke | 使用 Workload Identity 的 GKE 集群 |
nodepool | 其他 GKE 节点池 |
database | Cloud SQL PostgreSQL |
storage | 带 HMAC 密钥的 Cloud Storage 存储桶 |
load_balancers | GCP 负载均衡器 |
operator | Materialize Operator(Helm) |
GCP 的关键模式:
- 使用 HMAC 密钥访问兼容 S3 的 GCS(这些模块使用兼容 S3 的 API)
- 通过 VPC 对等连接实现 Cloud SQL 私有访问
- 为 Materialize 节点使用带本地 SSD 和交换空间的 c4a-highmem-8-lssd 实例
- 用于 Pod 和服务的辅助 IP 范围(VPC 原生)
- 需要启用多个 GCP API(container、compute、sqladmin、servicenetworking 等)
Kubernetes 模块(kubernetes/modules/)
| 模块 | 用途 |
|---|---|
cert-manager | 安装 cert-manager Helm Chart |
self-signed-cluster-issuer | 创建自签名 ClusterIssuer |
materialize-instance | 部署 Materialize CR |
coredns | CoreDNS 配置 |
grafana | Grafana 监控 |
prometheus | Prometheus 监控堆栈 |
hpa | Horizontal Pod Autoscaling |
ory-* | 用于企业身份验证的 Ory 堆栈(Kratos、Hydra 等) |
Materialize 实例模块
这是最重要的 Kubernetes 模块。kubernetes/modules/materialize-instance/variables.tf 中的关键变量:
| 变量 | 默认值 | 备注 |
|---|---|---|
crd_version | v1alpha1 | v26.30 及更高版本使用 v1。参见下方 CRD 章节。 |
instance_name | (必填) | Materialize CR 的名称 |
instance_namespace | (必填) | 实例的命名空间 |
metadata_backend_url | (必填) | PostgreSQL 连接字符串 |
persist_backend_url | (必填) | 对象存储 URL |
license_key | null | 社区版或企业版密钥 |
environmentd_version | v26.29.0 | Materialize 版本 |
rollout_strategy | WaitUntilReady | 参见下方发布策略 |
authenticator_kind | None | 选项:None、Password、Sasl、Oidc |
cpu_request | 1 | environmentd 的 CPU 请求量 |
memory_request | 4095Mi | environmentd 的内存请求量 |
memory_limit | 4Gi | environmentd 的内存限制 |
system_parameters | {} | 系统配置参数映射 |
issuer_ref | null | 用于 TLS 的 cert-manager 颁发者 |
internal_issuer_ref | null | 内部 mTLS 证书的覆盖项 |
后端 URL 格式
Materialize 实例需要两个后端 URL:
元数据后端(PostgreSQL):
postgres://user:password@host:5432/database?sslmode=require&options=-c%20statement_timeout%3D15min
statement_timeout=15min 参数是元数据操作所必需的。
持久化后端(对象存储):
AWS S3:
s3://bucket-name/system:serviceaccount:namespace:name
Azure Blob:
https://storageaccount.blob.core.windows.net/container
GCP Cloud Storage(通过 HMAC/兼容 S3 的 API):
s3://hmac-access-id:hmac-secret@bucket-name/materialize?endpoint=https%3A%2F%2Fstorage.googleapis.com®ion=us-central1
**存储身份验证支持:**目前,Materialize 仅支持在 AWS(IRSA)和 Azure(Workload Identity Federation)的持久化后端上使用基于 IAM 的身份验证。不支持原生 GCS IAM 身份验证,因此 GCP 模块使用兼容 S3 的 API 和 HMAC 密钥。
CRD 版本:v1alpha1 与 v1
v1alpha1(默认,v26.30 之前):分两步发布。先更改 spec,再将 request_rollout 设置为新的 UUID 以触发发布。可明确控制发布时机。
v1(推荐用于 v26.30 及更高版本):spec 更改会自动触发发布。Operator 会计算哈希并处理发布。request_rollout 字段已移除。手动触发时,使用新的 UUID 设置 force_rollout。
在示例或 materialize-instance 模块中通过 crd_version 变量设置。
发布策略
| 策略 | 行为 | 资源影响 |
|---|---|---|
WaitUntilReady | 创建新 Pod,待其健康后切换 | 临时需要双倍资源 |
ManuallyPromote | 创建新 Pod,等待手动执行 forcePromote | 临时需要双倍资源 |
ImmediatelyPromoteCausingDowntime | 先拆除旧 Pod | 不需要额外资源,但会导致停机 |
部署:快速入门
每个云平台都遵循相同的模式:
git clone https://github.com/MaterializeInc/materialize-terraform-self-managed.git
cd materialize-terraform-self-managed/<cloud>/examples/simple
# Create terraform.tfvars with required variables (see below)
terraform init
terraform apply
各云平台的变量
AWS(aws/examples/simple/):
name_prefix = "my-mz" # required
aws_profile = "my-profile" # required
license_key = "your-license-key" # required
tags = { environment = "dev" } # required (no default)
aws_region = "us-east-1" # optional, defaults to us-east-1
Azure(azure/examples/simple/):
subscription_id = "12345678-..." # required
resource_group_name = "materialize-rg" # required
name_prefix = "my-mz" # required
tags = { environment = "dev" } # required (no default)
location = "westus2" # optional, defaults to westus2
license_key = "your-key" # optional (null default), needed for production
GCP(gcp/examples/simple/):
project_id = "my-gcp-project" # required
labels = { environment = "dev" } # required (no default)
license_key = "your-license-key" # optional (null default), needed for production
name_prefix = "my-mz" # optional, defaults to "materialize"
region = "us-central1" # optional, defaults to us-central1
通用可选变量(所有云平台)
| 变量 | 默认值 | 用途 |
|---|---|---|
internal_load_balancer | true | 设置为 false 以使用面向互联网的负载均衡器 |
ingress_cidr_blocks | ["0.0.0.0/0"] | 限制对 Materialize 端口的访问 |
k8s_apiserver_authorized_networks | varies | 限制对 K8s API 的访问 |
crd_version | v1alpha1 | v26.30+ 使用 v1 |
enable_observability | false | 安装 Prometheus + Grafana |
在现有 Terraform 项目中使用这些模块
无需克隆代码库,也无需将示例复制到项目中。使用 Git 源直接引用模块,并固定到某个发布标签或提交 SHA:
module "materialize_instance" {
source = "github.com/MaterializeInc/materialize-terraform-self-managed//kubernetes/modules/materialize-instance?ref=<tag-or-commit>"
# module inputs ...
}
//用于分隔代码库 URL 和模块子目录。代码库中的任何模块都可以通过这种方式引用。- 始终将
ref固定到标签或提交 SHA。切勿跟踪main,否则应用操作将无法复现,且可能引入不兼容的更改。 - 要更新,请先查看版本说明,了解当前
ref与目标版本之间的不兼容更改,然后更新ref,运行terraform init -upgrade,并在应用前检查执行计划。完整流程请参阅升级 Materialize。 - 参考相关的
<cloud>/examples/simple/main.tf,了解模块如何组合,然后在自己的项目中使用固定的 Git 源重现该组合方式。这也是 Materialize 在内部部署中采用的模式。
部署后设置
配置 kubectl
运行 terraform apply 后,配置 kubectl 以连接新集群:
AWS:
aws eks update-kubeconfig --name $(terraform output -raw eks_cluster_name) --region <region>
Azure:
az aks get-credentials --resource-group <rg> --name $(terraform output -raw aks_cluster_name)
GCP:
gcloud container clusters get-credentials $(terraform output -raw gke_cluster_name) --region <region>
连接到 Materialize
端口:
- 6875:兼容 PostgreSQL 的 SQL(pgwire)
- 6876:HTTP API
- 8080:Materialize Console(HTTPS)
使用公共(面向互联网)负载均衡器时(internal_load_balancer = false):
AWS(使用 NLB DNS):
psql "postgres://mz_system@$(terraform output -raw nlb_dns_name):6875/materialize"
open "https://$(terraform output -raw nlb_dns_name):8080/materialize"
Azure / GCP(使用负载均衡器 IP):
psql "postgres://mz_system@$(terraform output -raw balancerd_load_balancer_ip):6875/materialize"
open "https://$(terraform output -raw console_load_balancer_ip):8080/materialize"
使用私有(内部)负载均衡器时(默认):
使用 kubectl 端口转发。资源 ID 位于 terraform output materialize_instance_resource_id 中:
kubectl port-forward svc/mz<resource-id>-balancerd 6875:6875 -n materialize-environment
psql "postgres://mz_system@localhost:6875/materialize"
kubectl port-forward svc/mz<resource-id>-console 8080:8080 -n materialize-environment
open "http://localhost:8080"
启用身份验证时,使用 external_login_password_mz_system 输出作为密码。完成初始设置后,请创建专用用户;避免在常规操作中使用 mz_system。
可观测性
当 enable_observability = true 时,Prometheus 和 Grafana 会部署在 monitoring 命名空间中,并预先配置 Materialize 仪表板:
kubectl port-forward svc/grafana 3000:80 -n monitoring
# Username: admin, Password: terraform output -raw grafana_admin_password
升级 Materialize
- 首先查看目标版本的版本说明。某些版本存在不兼容更改或特殊升级要求,必须在更新版本前处理。
- 对于 v26 之前的版本,每次升级一个次要版本。从 v26+ 起,可以跳过次要版本。
- 不支持降级。
- 升级顺序:先升级 operator,再升级实例。
使用 Terraform:
在变量中更新 environmentd_version(以及可选的 operator_version),然后运行 terraform apply。对于 v1alpha1,还要将 request_rollout 更新为新的 UUID。
完整升级流程请参阅此代码库中的 materialize-docs 技能:skills/materialize-docs/self-managed-deployments/upgrading/index.md(各云平台指南位于同级的 upgrade-on-* 目录中),或参阅在线升级文档。升级前务必查看版本说明以了解不兼容更改。
实例规格
Materialize 节点应使用内存优化型实例,并配备 NVMe 本地存储用于交换空间:
| 云 | 实例类型 | vCPU | 内存 | 最大集群规模 |
|---|---|---|---|---|
| AWS | r8gd.2xlarge | 8 | 64 GiB | ~300cc |
| AWS | r8gd.4xlarge | 16 | 128 GiB | ~600cc |
| AWS | r8gd.8xlarge | 32 | 256 GiB | ~1200cc |
| AWS | r8gd.16xlarge | 64 | 512 GiB | ~3200cc |
| Azure | Standard_E4pds_v6 | 4 | 32 GiB | 不定 |
| GCP | c4a-highmem-8-lssd | 8 | 64 GiB | 不定 |
建议使用基于 ARM 的 CPU,vCPU 与内存的比例为 1:8,本地存储与内存的比例为 8:1。
常见问题
- ECR 身份验证冲突:如果
terraform apply因拉取公共镜像而失败并返回 403,请运行docker logout public.ecr.aws后重试。 - GCP API:运行 Terraform 前,必须启用多个 GCP API(container、compute、sqladmin、servicenetworking、iamcredentials、iam、storage)。
- Azure 预览功能:在 Azure 上部署前,注册
EnableAPIServerVnetIntegrationPreview。 - 自签名证书:简单示例使用自签名 TLS。生产环境请使用真实 CA 或 ACME 颁发者。使用公共 ACME 颁发者(如 Let's Encrypt)时,请单独设置
internal_issuer_ref,因为公共 CA 无法为*.cluster.local名称签名。 - statement_timeout:元数据后端 URL 必须包含
statement_timeout=15min,否则元数据操作可能超时。 - 控制台加载缓慢:如果 Console UI 加载缓慢,请通过内部 SQL 端口 6877 将
mz_catalog_server集群规模从 25cc 提高到 50cc。
故障排除
检查操作器状态:
kubectl -n materialize get all
kubectl -n materialize logs -l app.kubernetes.io/name=materialize-operator
检查 Materialize 实例:
kubectl -n materialize-environment get all
kubectl -n materialize-environment logs <pod-name>
kubectl -n materialize-environment describe pod/<pod-name>
检查 Materialize CR 状态:
kubectl get materialize -n materialize-environment -o jsonpath='{.items[0].status}'
健康时,CR 状态应显示 UpToDate。
测试
test/ 中的测试工具使用 Rust,并运行完整的生命周期测试(初始化、应用、验证、销毁):
cd test
cargo run -- run aws --owner "Name" --license-key-file key.txt \
--aws-region us-east-1 --aws-profile my-profile
验证内容:Materialize CR 状态为 UpToDate,所有 Pod(environmentd、console、balancerd、clusterd)均处于 Running 状态,并且通过 SQL 执行 SELECT 1 成功。
保持此技能为最新
frontmatter 元数据中的 verified-against 值记录了此技能上次验证所依据的上游提交。要更新此技能:
- 对比从该提交到当前
main的上游仓库差异,重点关注variables.tf文件、示例配置和 README。 - 更新此处受影响的部分(变量默认值、模块表、实例类型、常见问题)。
- 将
verified-against更新为新的提交 SHA。