CloudFront SaaS Manager 多租户架构深度解析:从域名解耦到零停机配置迁移

域名与配置的解耦:多租户架构的技术分析

Amazon CloudFront 的传统"多域名"架构有一个根本性限制:所有域名绑定在同一个 Distribution 上,共享源站、WAF、缓存策略等全部配置。这意味着缓存刷新、WAF 变更、源站切换都是全局操作,无法针对单个域名执行。

CloudFront SaaS Manager 引入了多租户架构来解决这个问题。本文分析其核心数据模型、迁移路径和工程实践中需要注意的细节。

核心数据模型

SaaS Manager 的架构建立在三个基础对象上。

Tenant(租户)

租户与域名一对一映射,是独立管理的基本单元:

  • 绑定独立域名
  • 关联独立 WAF WebACL
  • 支持独立缓存刷新
  • 动态切换 Distribution 和 Connection Group

Distribution(分配)

在多租户架构中作为配置模板存在:

  • 定义源站配置(Origin)
  • 定义 CDN 行为(缓存策略、压缩、协议版本)
  • 可被多个租户共享

Connection Group(连接组)

定义网络层配置:

  • Unicast 或 Anycast 网络类型
  • 网络优化策略
  • 多租户共享

三者通过动态关联组合。租户可以在运行时切换 Distribution 或 Connection Group,实现零停机配置变更。

传统架构 vs 多租户架构

传统架构的核心问题是配置耦合:所有域名共享一切。多租户架构在保持配置共享的同时引入了域名级别的独立管理。

关键差异体现在三个场景:

独立 WAF 关联。 不同域名可以绑定不同的 WAF WebACL。电商域名防爬虫、API 域名防 DDoS,各自独立。

精准缓存刷新。 只刷单个租户的缓存,不影响其他域名。减少不必要的回源流量。

零停机配置迁移。 租户的缓存独立于 Distribution 存在。切换 Distribution 时缓存自动保留。

特性 传统架构 多租户架构
配置切换时间 15-30 分钟 即时生效
缓存丢失 ✗ 全部丢失 ✓ 完全保留
回滚能力 ✗ 困难 ✓ 即时回滚
影响范围 所有域名 单个租户
灰度测试 ✗ 不支持 ✓ 支持

迁移实操

以下是完整的迁移路径。核心思路:先创建多租户资源,再逐步将域名迁入。

步骤 1:创建 Connection Group

aws cloudfront get-distribution --id <OLD_DISTRIBUTION_ID>

aws cloudfront create-connection-group \
    --name "anycast-ipv6-connection-group" \
    --ipv6-enabled \
    --enabled

步骤 2:创建多租户 Distribution

aws cloudfront create-distribution \
    --distribution-config file://distribution-template-a.json \
    --tags Items=[{Key=Type,Value=SaaSTemplate},{Key=Name,Value=TemplateA}]

步骤 3:创建租户(占位符域名)

目标域名已存在于旧 Distribution,直接使用会报域名冲突。先用占位符域名创建租户:

cat > tenant1.json << 'EOF'
{
    "DistributionId": "<MULTI_TENANT_DISTRIBUTION_ID>",
    "Name": "tenant-domain1",
    "Domains": [
        {
            "Domain": "domain1-placeholder.example.com"
        }
    ],
    "ConnectionGroupId": "<CONNECTION_GROUP_ID>",
    "Customizations": {
        "WebAcl": {
            "Action": "override",
            "Arn": "arn:aws:wafv2:us-east-1:<AWS_ACCOUNT_ID>:global/webacl/tenant1-acl/<WAF_ACL_ID>"
        }
    },
    "Enabled": true
}
EOF

aws cloudfront create-distribution-tenant \
    --cli-input-json file://tenant1.json

细节: Customizations.WebAcl.Action 必须是 "override"(小写),大小写敏感。

步骤 4:测试验证

aws cloudfront get-connection-group \
    --id "<CONNECTION_GROUP_ID>" \
    --query 'ConnectionGroup.RoutingEndpoint' --output text

aws cloudfront create-invalidation \
    --distribution-id "<MULTI_TENANT_DISTRIBUTION_ID>" \
    --paths "/*"

curl -H "User-Agent: BadBot" https://domain1-placeholder.example.com/

步骤 5:旧 Distribution 备用域名改通配符

将 Aliases 从具体域名改为 *.example.com

aws cloudfront update-distribution \
    --id <OLD_DISTRIBUTION_ID> \
    --distribution-config file://old-dist-config-updated.json \
    --if-match <ETAG_VALUE>

aws cloudfront wait distribution-deployed --id <OLD_DISTRIBUTION_ID>

通配符继续匹配所有子域名,服务不中断。

步骤 6:更新租户域名

ETAG1=$(aws cloudfront get-distribution-tenant \
    --id "<TENANT1_ID>" \
    --query 'ETag' --output text)

aws cloudfront update-distribution-tenant \
    --id "<TENANT1_ID>" \
    --if-match "$ETAG1" \
    --domains Domain="domain1.example.com"

步骤 7:DNS 切换

ROUTING_ENDPOINT=$(aws cloudfront get-connection-group \
    --id "<CONNECTION_GROUP_ID>" \
    --query 'ConnectionGroup.RoutingEndpoint' --output text)

aws route53 change-resource-record-sets \
    --hosted-zone-id <HOSTED_ZONE_ID> \
    --change-batch '{
        "Changes": [{
            "Action": "UPSERT",
            "ResourceRecordSet": {
                "Name": "domain1.example.com",
                "Type": "CNAME",
                "TTL": 300,
                "ResourceRecords": [{"Value": "'"$ROUTING_ENDPOINT"'"}]
            }
        }]
    }'

步骤 8:验证

dig domain1.example.com CNAME
curl -v https://domain1.example.com/ 2>&1 | grep "subject:"
curl -I https://domain1.example.com/test-path | grep "X-Cache"

aws cloudwatch get-metric-statistics \
    --namespace AWS/CloudFront \
    --metric-name 4xxErrorRate \
    --dimensions Name=DistributionId,Value=<MULTI_TENANT_DISTRIBUTION_ID> \
    --start-time 2026-04-01T00:00:00Z \
    --end-time 2026-04-01T23:59:59Z \
    --period 300 \
    --statistics Average

工程实践要点

证书管理。 多租户 Distribution 的 SSL/TLS 证书需要覆盖所有待迁移域名。通配符证书是最简方案。

分批策略。 建议先迁移低流量域名(3-5 个),观察 24 小时确认无异常后再迁移核心域名。

ETag 机制。 CloudFront 的乐观锁基于 ETag。每次更新操作前必须重新获取 ETag,使用过期值会返回 PreconditionFailed

监控覆盖。 迁移前设置 CloudWatch 告警,监控 4xx/5xx 错误率和延迟。异常时可以即时回滚到旧 Distribution。

旧资源保留。 迁移完成后不要立即删除旧 Distribution,保留至少 7 天作为回滚通道。

适用场景评估

适合改造的条件(满足任一):

  • Distribution 下域名 > 10 个
  • 不同域名需要不同 WAF 策略
  • 频繁需要单域名缓存刷新
  • 有源站迁移或灰度测试需求

不需要改造:域名 < 5 个且配置需求一致的场景。

多租户架构的核心价值是域名与配置的解耦——共享配置降低管理成本,独立操作消除连坐效应。更多细节参考 Amazon CloudFront SaaS Manager 介绍


本文基于亚马逊云科技官方博客内容整理撰写。原文:Amazon CloudFront部署小指南(二十四):将CloudFront "多域名"改造为"多租户"架构

posted @ 2026-04-09 11:07  亚马逊云开发者  阅读(4)  评论(0)    收藏  举报