Skip to content
LangSmith 文档版本 跟随上游 源快照 a498b765 更新于 2026-10-18

AWS Terraform 故障排除

用 LangChain Terraform 模块部署、在 AWS EKS 上自托管 LangSmith 的常见问题、修复和诊断命令。

本页记录用 AWS Terraform 模块预配的 LangSmith 部署的常见问题、修复和诊断命令。

TIP

升级之前,查阅 LangSmith 自托管变更日志了解破坏性变更和必需的变量更新。在运行任何 kubectl 命令之前,先运行 aws eks update-kubeconfig --region <region> --name <cluster-name>。

有关本页各处所用 kubectl、helm 和 aws 调用的可复制粘贴参考,跳到诊断命令。

自动诊断

在运行单个命令之前,先试试随附的脚本:

bash
# Deployment status across all layers + next-step guidance
make status

# SSM parameter validation
./infra/scripts/manage-ssm.sh validate

已知问题

EKS 节点组创建失败:CREATE_FAILED

症状

Error: waiting for EKS Node Group creation: unexpected state 'CREATE_FAILED'

原因: 节点组创建开始时,EKS 控制平面尚未完全活动。在一次被打断的 apply 之后常见。

修复

bash
aws eks wait cluster-active --name <cluster-name> --region <region>

aws eks describe-nodegroup \
  --cluster-name <cluster-name> \
  --nodegroup-name <nodegroup-name> \
  --region <region> \
  --query "nodegroup.health"

terraform apply -var-file=terraform.tfvars

kubectl 失败:"You must be logged in to the server"

症状: 所有 kubectl 命令都失败并报 error: You must be logged in to the server (Unauthorized)。

原因: kubeconfig 陈旧、AWS 凭据与创建集群者不同,或令牌已过期。

修复

bash
aws eks update-kubeconfig --region <region> --name <cluster-name>
kubectl cluster-info

aws sts get-caller-identity

如果集群是用另一个 IAM 角色创建的,通过 aws-auth ConfigMap 授予访问:

bash
kubectl edit configmap aws-auth -n kube-system
# Add your IAM user or role under mapUsers / mapRoles

Helm 安装后未创建 ALB

症状: 几分钟后 kubectl get ingress -n langsmith 不显示 ADDRESS。

原因: AWS Load Balancer Controller 未运行或缺少 IRSA 权限、Terraform 预配的 ALB 未被正确引用,或设了 alb_scheme = "internal"(内部 ALB 无公共地址;见 ALB 无公共地址)。

修复

bash
kubectl get pods -n kube-system | grep aws-load-balancer
kubectl logs -n kube-system -l app.kubernetes.io/name=aws-load-balancer-controller --tail=50
kubectl get sa -n kube-system aws-load-balancer-controller -o yaml | grep eks.amazonaws.com

terraform output alb_dns_name
aws elbv2 describe-load-balancers --query "LoadBalancers[?DNSName=='<alb-dns-name>'].State"

EKS pod 连接 RDS 被拒

症状: 后端日志显示到 RDS 端点的 connection refused 或 timeout。

原因: RDS 安全组不允许来自 EKS 节点或集群安全组的入站 TCP 5432。

修复

bash
aws eks describe-cluster --name <cluster-name> \
  --query "cluster.resourcesVpcConfig.clusterSecurityGroupId"

aws rds describe-db-instances \
  --db-instance-identifier <db-id> \
  --query "DBInstances[0].VpcSecurityGroups"

aws ec2 describe-security-group-rules \
  --filter "Name=group-id,Values=<rds-sg-id>"

postgres 模块会自动设置安全组。如果规则缺失,重新 apply:

bash
terraform apply -var-file=terraform.tfvars -target=module.postgres

pod 访问 S3 被拒(未配置 IRSA)

症状: 后端日志显示读写 S3 时 AccessDenied。

原因: LangSmith 服务账户缺少 IRSA 注解,或 S3 VPC Gateway Endpoint 未正确路由。

修复

bash
kubectl get sa langsmith -n langsmith -o yaml | grep eks.amazonaws.com

aws ec2 describe-vpc-endpoints \
  --filters "Name=service-name,Values=com.amazonaws.<region>.s3" \
  --query "VpcEndpoints[].State"

kubectl run s3-test --rm -it --image=amazon/aws-cli -n langsmith -- \
  s3 ls s3://<bucket-name>

如果缺少 IRSA 注解,核实 terraform.tfvars 中有 create_langsmith_irsa_role = true,且 Helm values 中的服务账户名与 langsmith 相匹配。

ElastiCache Redis 连接超时

症状: pod 无法连接 Redis。日志显示 dial tcp: i/o timeout。

原因: ElastiCache 安全组不允许来自 EKS 节点安全组的入站 TCP 6379。

修复

bash
aws elasticache describe-cache-clusters \
  --cache-cluster-id <cluster-id> \
  --query "CacheClusters[0].SecurityGroups"

kubectl run redis-test --rm -it --image=redis:7 -n langsmith -- \
  redis-cli -h <elasticache-endpoint> -a <auth-token> ping

EKS 节点不自动伸缩

症状: pod 保持 Pending。节点数不增加。

原因: Cluster Autoscaler 缺少 IAM 权限、指向了错误的 ASG,或节点组上 min_size = max_size。

修复

bash
kubectl logs -n kube-system -l app=cluster-autoscaler --tail=50

aws autoscaling describe-auto-scaling-groups \
  --query "AutoScalingGroups[?contains(Tags[].Key, 'k8s.io/cluster-autoscaler/<cluster-name>')].[AutoScalingGroupName]" \
  --output table

cert-manager 无法签发 Let's Encrypt 证书

症状: kubectl get certificate -n langsmith 显示 READY=False。HTTP01 质询失败。

原因: ALB 未把端口 80 转发到 cert-manager 求解器 pod,或该域名的 DNS 记录没指向 ALB。

修复

bash
kubectl describe certificate <cert-name> -n langsmith
kubectl get challenges -n langsmith

aws elbv2 describe-listeners --load-balancer-arn <alb-arn>

dig +short <your-langsmith-domain>
# Expected: CNAME to the ALB DNS name

postgres_deletion_protection 阻止 terraform destroy

症状

Error: deleting RDS DB Instance: InvalidParameterCombination:
Cannot delete, DeletionProtection is enabled.

修复: 在 terraform.tfvars 中禁用删除保护,apply,然后 destroy:

hcl
postgres_deletion_protection = false
bash
terraform apply -var-file=terraform.tfvars
terraform destroy

ESO 同步失败:langsmith-config secret 缺失

症状: pod 卡在 CreateContainerConfigError。kubectl get secret langsmith-config -n langsmith 返回 NotFound。

原因: ESO 同步是全有或全无。如果 ExternalSecret 引用的任何一个 SSM 参数缺失,ESO 会拒绝创建 Kubernetes Secret。所有 pod 都失败,包括与缺失参数无关的那些。

修复

bash
kubectl get externalsecret langsmith-config -n langsmith
kubectl describe externalsecret langsmith-config -n langsmith

./infra/scripts/manage-ssm.sh validate

source ./infra/scripts/setup-env.sh
./helm/scripts/apply-eso.sh

describe 输出会显示哪个 remoteRef.key 失败。把它与 SSM 前缀 /langsmith/{name_prefix}-{environment}/ 对照匹配。

SSM 参数前缀不匹配

症状: manage-ssm.sh validate 通过但 ESO 仍无法同步。或 setup-env.sh 把参数写到了 ESO 所期望之外的另一个前缀下。

原因: SSM 前缀由 terraform.tfvars 中的 name_prefix 和 environment 派生。如果这些在初始设置后改变了,旧参数生活在旧前缀下,而 ESO 在新前缀下查找。

修复

bash
kubectl get externalsecret langsmith-config -n langsmith -o yaml | grep 'key:'

./infra/scripts/manage-ssm.sh list

./infra/scripts/migrate-ssm.sh

WARNING

绝不要在现有部署上更改 name_prefix 或 environment。

Terraform 校验拒绝 Postgres 密码

症状

Error: Invalid value for variable "postgres_password"
RDS master password must not contain '/', '@', '"', single quotes, or spaces.

原因: 密码含有 RDS 不允许出现在主密码中的字符。

修复: 重新生成一个不含受限字符的密码。setup-env.sh 会自动生成一个合规密码;要手动更新:

bash
./infra/scripts/manage-ssm.sh set postgres-password "$(openssl rand -base64 24 | tr -d '/+= ')"
source ./infra/scripts/setup-env.sh
terraform apply -var-file=terraform.tfvars

私有 EKS 集群不可达(需要 bastion)

症状: 当 enable_public_eks_cluster = false 时,kubectl 和 terraform apply 超时。

原因: EKS API 端点是私有的。命令必须在 VPC 内运行,通过 bastion 主机或 VPN 连接。

修复

bash
# If the bastion was provisioned (create_bastion = true)
aws ssm start-session --target <bastion-instance-id>

# From the bastion
aws eks update-kubeconfig --region <region> --name <cluster-name>
kubectl get nodes

如果没有预配 bastion,设 create_bastion = true 并重新 apply,或临时设 enable_public_eks_cluster = true。

ALB 无公共地址(internal 方案)

症状: kubectl get ingress -n langsmith 显示一个 ADDRESS,但它只在 VPC 内解析。

原因: 在 terraform.tfvars 中设了 alb_scheme = "internal"。内部 ALB 只能从 VPC 内(VPN、对等或 PrivateLink)访问。

修复: 对私有部署是有意为之。要让 ALB 可被公共访问:

hcl
alb_scheme = "internet-facing"
bash
terraform apply -var-file=terraform.tfvars
# Then redeploy Helm to pick up the new ALB

ingress 重建后 ALB 主机名改变

症状: LangSmith URL 停止工作。agent 部署卡在 DEPLOYING。DNS 记录或书签指向一个不再解析的旧 ALB 主机名。

原因: 删除 Kubernetes ingress(通过 helm uninstall、kubectl delete ingress 或命名空间删除)会撤销预配 ALB。当 ingress 被重建时,会签发一个带不同主机名的新 ALB。Helm values 中的 config.deployment.url 仍指向旧主机名,所以 operator 的健康检查失败,部署一直卡住。

如果 ALB 控制器创建了一个新 ALB 而非复用 Terraform 预配的那个,也会发生这种情况。要防止这一点,group.name 注解必须与 load-balancer-arn 一起设置。

预防

  • 确保 group.name 和 load-balancer-arn 注解都设置了。当存在一个预配的 ALB 时,init-values.sh 会自动这样设置。
  • 除非你打算更新所有依赖主机名的配置,否则不要删除 ingress。
  • 避免不带 --server-side=false 的 helm rollback。ingress 的 SSA 冲突可能触发一次删除/重建循环。

修复

bash
# 1. Check what hostname the ingress currently has
kubectl get ingress langsmith-ingress -n langsmith \
  -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'

# 2. Check what Terraform expects
terraform output alb_dns_name

# 3. If they differ, re-run init-values.sh and redeploy
make init-values
make deploy

Terraform 未应用节点组伸缩更改

症状: 在 terraform.tfvars 中更改 min_size 或 max_size,terraform plan 显示“No changes”。

原因: ASG 被带外更改(AWS CLI、控制台或 cluster autoscaler),且 Terraform 状态已反映新值。社区 EKS 模块忽略 desired_size 更改以便 autoscaler 能管理它;min_size 和 max_size 应当正常传播。

修复

bash
terraform refresh
terraform plan

# For an immediate change, use the AWS CLI directly
aws eks update-nodegroup-config \
  --cluster-name <cluster> \
  --nodegroup-name <nodegroup> \
  --scaling-config minSize=3,maxSize=8,desiredSize=5 \
  --region <region>

诊断命令

集群访问

bash
aws eks update-kubeconfig --region <region> --name <cluster-name>
kubectl config current-context
kubectl get nodes -o wide
aws sts get-caller-identity

Pod

bash
kubectl get pods -n langsmith
kubectl get pods -n langsmith -w
kubectl describe pod <pod-name> -n langsmith
kubectl logs <pod-name> -n langsmith --tail=50
kubectl logs <pod-name> -n langsmith --previous --tail=50
kubectl logs -n langsmith deploy/langsmith-backend --tail=100 -f

ALB 与 ingress

bash
kubectl get ingress -n langsmith
kubectl describe ingress -n langsmith
aws elbv2 describe-load-balancers --query "LoadBalancers[?contains(LoadBalancerName, 'langsmith')]"

TLS 与证书

bash
kubectl get certificate -n langsmith
kubectl describe certificate <cert-name> -n langsmith
kubectl get challenges -n langsmith
kubectl get clusterissuer

ESO 与机密

bash
kubectl get externalsecret -n langsmith
kubectl describe externalsecret langsmith-config -n langsmith
kubectl get clustersecretstore langsmith-ssm
kubectl get secret langsmith-config -n langsmith -o jsonpath='{.data}' | jq 'keys'
./infra/scripts/manage-ssm.sh validate
./infra/scripts/manage-ssm.sh diff

Helm

bash
helm status langsmith -n langsmith
helm history langsmith -n langsmith
helm get values langsmith -n langsmith

IRSA 与 IAM

bash
kubectl get sa langsmith -n langsmith -o yaml | grep eks.amazonaws.com
terraform output langsmith_irsa_role_arn
aws iam get-role --role-name <irsa-role-name>

LangSmith Deployment

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 keda

快速健康检查

bash
echo "=== Context ===" && kubectl config current-context
echo "=== Nodes ===" && kubectl get nodes
echo "=== Pods ===" && kubectl get pods -n langsmith
echo "=== Ingress ===" && kubectl get ingress -n langsmith
echo "=== Helm ===" && helm status langsmith -n langsmith 2>/dev/null | grep -E "STATUS|LAST DEPLOYED"

BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。