主题
用 Terraform 在 GCP 上部署 LangSmith
用 LangChain Terraform 模块在 GCP GKE 上预配自托管 LangSmith 的端到端演练。
用公开的 Terraform 模块把 LangSmith 部署到 GCP。以代码方式管理部署,让你能跨项目为 LangSmith 环境做版本控制、审查和复现,而非在 Google Cloud 控制台里点点点。
安装分两个阶段运行:
- 基础设施:Terraform 预配 VPC、GKE、Cloud SQL、Memorystore、GCS 和 Workload Identity。
- 应用:LangSmith chart,用部署脚本或 Terraform
app层安装。
基础安装之后,通过设置标志并重新部署来启用可选附加组件。
%%{init: {'flowchart': {'nodeSpacing': 25, 'rankSpacing': 30}}}%%
graph TB
subgraph stage1["Set up infrastructure"]
direction LR
Start["setup-env.sh<br/>secrets to Secret Manager"]
TF["terraform apply"]
Infra["VPC · GKE · Cloud SQL<br/>Memorystore · GCS<br/>Workload Identity"]
Bootstrap["Bootstrap workloads<br/>cert-manager · KEDA<br/>Envoy Gateway"]
Start --> TF --> Infra -->|GKE ready| Bootstrap
end
subgraph stage2["Deploy the application"]
direction LR
Deploy["make init-values + deploy<br/>helm install langsmith"]
DNS["Point DNS A record<br/>at Gateway IP"]
Cert["cert-manager issues<br/>Let's Encrypt cert"]
Running["LangSmith running<br/>all pods healthy"]
Deploy --> DNS --> Cert --> Running
end
stage1 --> stage2
classDef trigger fill:#F6FFDB,stroke:#6E8900,stroke-width:2px,color:#2E3900
classDef process fill:#E5F4FF,stroke:#006DDD,stroke-width:2px,color:#030710
classDef neutral fill:#F2FAFF,stroke:#40668D,stroke-width:2px,color:#2F4B68
classDef output fill:#EBD0F0,stroke:#885270,stroke-width:2px,color:#441E33
class Start,DNS trigger
class TF,Bootstrap,Deploy,Cert process
class Infra neutral
class Running output
style stage1 fill:none,stroke:#40668D,stroke-width:1px
style stage2 fill:none,stroke:#40668D,stroke-width:1px
前置条件
必需工具
| 工具 | 版本 | 用途 |
|---|---|---|
Google Cloud SDK(gcloud) | 450 | 身份验证、查询 GCP 资源、管理 GKE 凭据 |
| Terraform | 1.5 | 运行基础设施模块 |
kubectl | 1.28 | 检查 GKE 集群 |
| Helm | 3.12 | 安装并管理 LangSmith chart |
在 macOS 上安装:
bash
brew install --cask google-cloud-sdk
brew install kubectl helm
brew tap hashicorp/tap && brew install hashicorp/tap/terraform
gcloud version
terraform version
kubectl version --client
helm version必需的 GCP API
Terraform 会在首次 apply 时自动启用这些,但 cloudresourcemanager.googleapis.com 必须最先启用,Terraform 才能启用其余那些。要为快速的首次运行全部手动启用:
bash
gcloud services enable \
container.googleapis.com \
compute.googleapis.com \
sqladmin.googleapis.com \
redis.googleapis.com \
storage.googleapis.com \
iam.googleapis.com \
secretmanager.googleapis.com \
certificatemanager.googleapis.com \
servicenetworking.googleapis.com \
cloudresourcemanager.googleapis.com \
logging.googleapis.com \
monitoring.googleapis.com \
--project <your-project-id>必需的 IAM 角色
运行 Terraform 的主体在目标项目上需要以下角色。在初始部署稳定后,再收窄到最小权限。
| 角色 | 用途 |
|---|---|
roles/container.admin | 创建并管理 GKE 集群 |
roles/compute.networkAdmin | 创建 VPC、子网、防火墙规则 |
roles/iam.serviceAccountAdmin | 为 Workload Identity 创建服务账户 |
roles/cloudsql.admin | 创建并管理 Cloud SQL 实例 |
roles/redis.admin | 创建并管理 Memorystore Redis |
roles/storage.admin | 创建 GCS 存储桶和生命周期策略 |
roles/resourcemanager.projectIamAdmin | 在预配期间授予 IAM 绑定 |
roles/servicenetworking.networksAdmin | 创建私有服务连接(Cloud SQL 和 Redis 必需) |
身份验证
bash
gcloud auth login
gcloud config set project <your-project-id>
gcloud auth application-default login你还需要一个 LangSmith 许可密钥(联系我们的销售团队)和一个解析到 GCP 的域名或子域。
快速开始
TIP
make 目标、必需变量和常见约束的精简速查表,见 GCP 快速参考。
要从零到运行中的 LangSmith 实例走最快的路径,按顺序运行这些命令:
bash
# 1. Clone the public modules
git clone https://github.com/langchain-ai/terraform.git
cd terraform/modules/gcp
# 2. Generate terraform.tfvars interactively (Enter accepts current values)
make quickstart
# 3. Load secrets into Secret Manager
# Must be sourced, not executed
source infra/scripts/setup-env.sh
# 4. Validate environment
make preflight
# 5. Provision infrastructure (~25 to 35 min)
make init
make plan
make apply
# 6. Configure kubectl
make kubeconfig
kubectl get nodes
# 7. Deploy LangSmith via Helm (~8 to 12 min)
make init-values
make deploy
# 8. Get the Gateway IP for DNS
kubectl get gateway -n langsmith \
-o jsonpath='{.items[0].status.addresses[0].value}'下面的小节详细讲述每个阶段。
预配基础设施
Terraform 预配以下 GCP 资源:
| 资源 | 用途 |
|---|---|
| VPC + 子网 + Cloud NAT | 集群和托管服务的私有网络 |
| 私有服务连接 | 为 Cloud SQL 和 Memorystore 私有 IP 的 VPC 对等 |
| GKE 集群(Standard 或 Autopilot) | Kubernetes 计算,启用 Workload Identity |
| Cloud SQL PostgreSQL | LangSmith 运维数据,HA 备库,私有 IP |
| Memorystore Redis | 队列与缓存,STANDARD_HA 层级,私有 IP |
| GCS 存储桶 | 追踪载荷 blob 存储,生命周期规则 |
| Workload Identity 服务账户 | 按 pod 的 GCP 访问,无静态密钥 |
| cert-manager、KEDA、Envoy Gateway | 与基础设施一起安装的 bootstrap 工作负载 |
克隆并配置
bash
git clone https://github.com/langchain-ai/terraform.git
cd terraform/modules/gcp所有后续命令都从 modules/gcp/ 运行。运行 make help 查看完整目标列表。
用交互式向导生成 terraform.tfvars:
bash
make quickstart向导会依次提示项目 ID、命名前缀、区域、GKE 规格、TLS 来源、外部对集群内服务,以及可选附加组件标志。它写入 infra/terraform.tfvars。重跑会预选现有值;在每个提示处按 Enter 以保留当前配置。
更想手动编辑:
bash
cp infra/terraform.tfvars.example infra/terraform.tfvars
vi infra/terraform.tfvars最少必需的变量:
hcl
project_id = "<your-gcp-project-id>"
name_prefix = "ls"
environment = "prod"
langsmith_license_key = "<your-license-key>"
langsmith_domain = "langsmith.example.com"
region = "us-west2"
zone = "us-west2-a"
postgres_source = "external"
postgres_password = "<strong-password>" # or: export TF_VAR_postgres_password=...
redis_source = "external"
clickhouse_source = "in-cluster"
tls_certificate_source = "letsencrypt"
letsencrypt_email = "ops@example.com"
enable_langsmith_deployment = true每个输入变量见 GCP 变量参考。
TIP
在 apply 之前配置一个远程状态后端。把 infra/backend.tf.example 复制为 infra/backend.tf 并指向你控制的一个 GCS 存储桶。本地状态很脆弱,可能在目录重构期间丢失。
把机密加载到 Secret Manager
bash
source infra/scripts/setup-env.sh该脚本读取 terraform.tfvars,派生出机密前缀,然后对每个机密要么复用一个导出的值、要么读取现有的 Secret Manager 机密、要么自动生成一个(用于盐和 Fernet 密钥)、要么提示你。许可密钥和 admin 密码是你交互式提供的两个值。该脚本必须被 source,因为 make 无法把环境变量导出回父 shell。
验证机密存在:
bash
make secretsPreflight 检查
bash
make preflightmake preflight 验证活动的 gcloud 凭据能执行每个所需操作、必需的 GCP API 已启用,且目标区域有模块所请求的 SKU。在这里捕获缺口比在 terraform apply 中途发现更快。
Apply
NOTE
在一个干净项目上预配 GCP 云基础需要 25 到 35 分钟。不要打断 apply。
bash
make init
make plan
make applymake plan 显示拟议的差异。在 apply 之前审阅输出。make apply 按依赖顺序预配:VPC 和网络,然后 GKE(约 10 到 15 分钟)、私有服务连接、Cloud SQL(带 HA 约 10 分钟)、Memorystore、GCS 和 bootstrap 工作负载。
等价的直接 Terraform 流程:
bash
cd modules/gcp/infra
terraform init
terraform plan -var-file=terraform.tfvars
terraform apply -var-file=terraform.tfvars配置 kubectl
bash
make kubeconfig
kubectl get nodes所有节点都应报告 Ready。
验证 bootstrap 组件
bash
kubectl get pods -n cert-manager
kubectl get pods -n keda
kubectl get secrets -n langsmithcert-manager、KEDA 和 LangSmith 命名空间机密都应就位。
部署 LangSmith
使用三条受支持的部署路径之一:
| 路径 | 命令 | 何时使用 |
|---|---|---|
| 脚本驱动的 Helm 部署 (推荐) | make init-values && make deploy | 交互式输出、kubeconfig 刷新、preflight 检查。最适合首次部署和第 2 天的重新部署。 |
| Terraform 管理的 Helm release | make init-app && make apply-app | Helm release 与基础设施一起管理在 Terraform 状态中。最适合 GitOps 和 CI/CD 流水线。 |
| 手动 Helm 安装 | helm upgrade --install langsmith langchain/langsmith ... | 不用 wrapper 脚本的直接 helm 用法。最适合已有 Helm 工具的团队。 |
脚本驱动的 Helm 部署(推荐)
两条命令就用从 Terraform 输出接线好的合理默认值安装 LangSmith chart:
bash
cd modules/gcp
make init-values
make deployinit-values.sh 会提示 admin 邮箱,然后从 terraform.tfvars 读取 sizing_profile 和 enable_* 标志,并把 helm/values/examples/ 中匹配的 values 文件复制到 helm/values/。它还生成 values-overrides.yaml,含你的主机名、Workload Identity 注解和 GCS 存储桶名。
make deploy 运行 helm/scripts/deploy.sh,它会刷新 kubeconfig、运行 preflight 检查、应用分层的 values 文件,并运行 helm upgrade --install。
预计 chart 安装和 pod 就绪需要 8 到 12 分钟。
如果你完成了脚本驱动的部署,跳到验证并配置 DNS。下面两条路径是脚本驱动部署的替代方案。
Terraform 管理的 Helm release
把整个部署保持在 Terraform 下。app 层包裹与部署脚本相同的 chart 和分层 values 文件,作为一个 helm_release 资源管理。
bash
cd modules/gcp
make init-values # generate the layered values files
make init-app # pull infra outputs into app/infra.auto.tfvars.json
make apply-app # terraform apply the Helm release在 app/terraform.tfvars 中设置 app 层输入(admin_email 是必需的;hostname、chart_version、sizing 和 enable_* 标志是可选的)。app 层用它自己的变量名:sizing(而非 sizing_profile)和 enable_agent_deploys(而非 enable_deployments)。make init-app 会把从 infra 派生的输入(集群、存储桶、Workload Identity 注解)填充进 app/infra.auto.tfvars.json。
该 release 以 wait = false 应用,因为 operator 生成的 agent 在冷集群上可能要 10 多分钟;一次通过的 terraform apply 意味着 release 被接受,而非每个 pod 都就绪。
如果你完成了 Terraform 管理的 Helm release,跳到验证并配置 DNS。下面这条路径是一种替代。
手动 Helm 安装
最适合不用脚本、直接运行 helm 的团队。先生成所需的机密:
bash
export API_KEY_SALT=$(openssl rand -base64 32)
export JWT_SECRET=$(openssl rand -base64 32)
export AGENT_BUILDER_ENCRYPTION_KEY=$(python3 -c \
"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
export INSIGHTS_ENCRYPTION_KEY=$(python3 -c \
"from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
export ADMIN_EMAIL="admin@example.com"
export ADMIN_PASSWORD="<strong-password>"随附的 helm/values/values.yaml 设置 config.blobStorage.engine: GCS(原生 GCS 模式),因此 blob 存储通过 Workload Identity 认证,无需 HMAC 密钥。按组件的 Workload Identity 注解在 values-overrides.yaml 中;用 make init-values 生成它,或手动为每个组件添加 serviceAccount.annotations."iam.gke.io/gcp-service-account"。
bash
helm repo add langchain https://langchain-ai.github.io/helm
helm repo update
helm upgrade --install langsmith langchain/langsmith \
--namespace langsmith \
--create-namespace \
--version ~0.15.1 \
-f ../helm/values/values.yaml \
-f ../helm/values/values-overrides.yaml \
--set config.langsmithLicenseKey="<your-license-key>" \
--set config.apiKeySalt="$API_KEY_SALT" \
--set config.basicAuth.jwtSecret="$JWT_SECRET" \
--set config.hostname="<your-langsmith-domain>" \
--set config.basicAuth.initialOrgAdminEmail="$ADMIN_EMAIL" \
--set config.basicAuth.initialOrgAdminPassword="$ADMIN_PASSWORD" \
--set config.agentBuilder.encryptionKey="$AGENT_BUILDER_ENCRYPTION_KEY" \
--set config.insights.encryptionKey="$INSIGHTS_ENCRYPTION_KEY" \
--set config.blobStorage.bucketName="$(terraform output -raw storage_bucket_name)" \
--set gateway.enabled=true \
--set ingress.enabled=false \
--wait --timeout 15mNOTE
要改用 S3 兼容的 blob 存储而非 Workload Identity,加 --set config.blobStorage.engine=S3 并用 --set config.blobStorage.accessKey=<key> 和 --set config.blobStorage.accessKeySecret=<secret> 传入 HMAC 密钥。在 Cloud Storage → Settings → Interoperability 下创建 HMAC 密钥。
验证并配置 DNS
bash
kubectl get pods -n langsmith
EXTERNAL_IP=$(kubectl get svc -n envoy-gateway-system \
-l gateway.envoyproxy.io/owning-gateway-name=langsmith-gateway \
-o jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}')
echo "Create A record: $EXTERNAL_IP -> <your-langsmith-domain>"
kubectl get certificate -n langsmith在 DNS A 记录解析到 Gateway IP 之前,cert-manager 无法签发 Let's Encrypt 证书。在你的 DNS 提供商处创建该记录,等待传播,然后重新检查证书状态。
规格配置
在 terraform.tfvars 中设置 sizing_profile,然后重新运行 make init-values && make deploy。
hcl
sizing_profile = "production" # default | minimum | dev | production | production-large| 配置 | 何时使用 |
|---|---|
default | chart 默认,不应用 overlay |
minimum | 绝对底线,容纳 e2-standard-4。成本占位或 CI 冒烟测试 |
dev | 单副本,最小资源 |
production | 多副本带 HPA。真实工作负载推荐 |
production-large | 高内存、高 CPU。50+ 用户或 1000+ 追踪/秒 |
预期的 pod
txt
langsmith-ace-backend-xxx 1/1 Running 0
langsmith-backend-xxx 1/1 Running 0
langsmith-backend-auth-bootstrap 0/1 Completed 0
langsmith-backend-migrations 0/1 Completed 0
langsmith-clickhouse-0 1/1 Running 0
langsmith-frontend-xxx 1/1 Running 0
langsmith-ingest-queue-xxx 1/1 Running 0
langsmith-platform-backend-xxx 1/1 Running 0
langsmith-playground-xxx 1/1 Running 0
langsmith-queue-xxx 1/1 Running 0启用附加组件
每个附加组件都由 infra/terraform.tfvars 中的一个标志门控。设置该标志,重新 apply Terraform,然后重跑 make init-values && make deploy。
LangSmith Deployment
增加 host-backend、listener 和 operator。在启用 Agent Builder 或 Insights 之前必需。当 enable_langsmith_deployment = true 时 KEDA 会自动安装。
hcl
# infra/terraform.tfvars
enable_deployments = truebash
cd modules/gcp
make apply # push the enable_deployments flag
make init-values # pick up the change
make deploy # roll out host-backend + listener + operator验证:
bash
kubectl get pods -n langsmith | grep -E "host-backend|listener|operator"
kubectl get lgp -n langsmith
kubectl get crd | grep langchain
kubectl get pods -n kedaWARNING
config.deployment.url 必须包含 https://。没有协议,operator 生成的 agent 会无限期卡在 DEPLOYING。
Fleet
NOTE
Fleet 是曾被称为 Agent Builder 的功能的当前形态,作为一个独立服务部署(chart v0.15+)。
你可以用 enable_fleet 启用 Fleet。与弃用的 enable_agent_builder 路径不同,它不需要 LangSmith Deployment。Terraform 在 Cloud SQL 上预配一个专属的 fleet 数据库,并把 langsmith-fleet-postgres 和 langsmith-fleet-redis 机密接线到现有的 Cloud SQL 和 Memorystore 实例。Fleet 复用 langsmith_agent_builder_encryption_key,因此从 enable_agent_builder 迁移会保持同样的密钥和数据。
NOTE
Fleet 需要 LangSmith Helm chart 0.15.0 或更高,以及你许可证中的 Agent Builder 或 Fleet 权限。
hcl
# infra/terraform.tfvars
enable_fleet = truebash
cd modules/gcp
make apply # provision the fleet Cloud SQL database + secrets
make init-values # copy langsmith-values-fleet.yaml
make deploy # roll out the standalone-fleet-* services验证:
bash
kubectl get pods -n langsmith | grep standalone-fleetWARNING
不要同时启用 enable_fleet 和 enable_agent_builder。Fleet 的 values 文件设置 config.agentBuilder.enabled: false,所以这两个附加组件互斥。
Agent Builder(已弃用)
NOTE
在 GCP 上,enable_agent_builder 已被弃用,改推荐 Fleet(enable_fleet,chart v0.15+)。新部署请用 Fleet。本节为现有安装记录这条较老的路径。
前置条件:LangSmith Deployment 健康。增加 agent-builder-tool-server、agent-builder-trigger-server,以及一个注册 Polly agent URL 的 agentBootstrap Job。
hcl
# infra/terraform.tfvars
enable_agent_builder = truebash
make init-values
make deploy验证:
bash
kubectl get pods -n langsmith | grep -E "tool-server|trigger-server|bootstrap"在 agentBootstrap 完成后滚动前端,使它拾取 langsmith-polly-config ConfigMap:
bash
kubectl rollout restart deployment langsmith-frontend -n langsmithWARNING
跳过前端重启会让 Polly 显示“Unable to connect to LangGraph server”。
Insights 与 Polly
前置条件:Agent Builder 健康。Insights 启用 ClickHouse 支撑的追踪分析。Polly 是 AI 评估与监控 agent。一起启用两者。
hcl
# infra/terraform.tfvars
enable_insights = true
enable_polly = truebash
make init-values
make deploy验证:
bash
kubectl get pods -n langsmith | grep -E "clio|polly"
kubectl get pods -n langsmith -wWARNING
insights_encryption_key 和 polly_encryption_key 在首次启用后绝不能更改。轮换其中任一会永久破坏现有的加密数据。
按附加组件预期的 pod
LangSmith Deployment 增加: langsmith-host-backend、langsmith-listener、langsmith-operator。
Fleet 增加: standalone-fleet-api-server、standalone-fleet-tool-server、standalone-fleet-trigger-server、standalone-fleet-queue。
Agent Builder 增加: langsmith-agent-builder-tool-server、langsmith-agent-builder-trigger-server、langsmith-agent-builder-bootstrap(Completed)、agent-builder-<hash>(operator 生成)。
Insights 和 Polly 增加: clio-<hash>(Insights 分析)、smith-polly-<hash>(Polly agent)、lg-<hash>-0(LangGraph StatefulSet)。
关键注意事项
config.deployment.url必须包含https://。没有它,operator 生成的 agent 会卡在DEPLOYING。config.deployment.enabled: true对 LangSmith Deployment 是必需的。只设 URL 而不设enabled: true会让 chart 静默跳过listener和operator。- 加密密钥在首次启用后绝不能更改。轮换
insights_encryption_key或polly_encryption_key会永久破坏现有的加密数据。 - 在首次启用 Polly 后滚动前端。
agentBootstrap在注册后创建langsmith-polly-configConfigMap。在 bootstrap 完成之前启动的前端 pod 不会自动拾取它。 - Envoy Gateway IP 在拆除时会改变。当 Gateway 被删除时 GCP 会释放外部 IP。重新 apply 之后会签发一个新 IP,所以要更新你的 DNS A 记录。
langsmith-ksa注解不是永久的。operator 在运行时创建langsmith-ksa;它不跨越命名空间删除而留存。deploy.sh幂等地为它重新加注解。如果 operator pod 在集群重建后失去 GCS 访问,重跑make deploy。
后续步骤
- 参考 GCP 变量和快速参考。
- 审阅 GCP 架构了解模块结构、流量走向和 Workload Identity。
- 出问题时,查 GCP 故障排除指南。
- 用 LangSmith Deployment 在 UI 中启用 agent 部署。