1917年1月,德国向墨西哥发送了一封秘密电报,提出以领土为条件换取墨西哥加入对美国的战争。电报原本只面向特定收件人,却因为通信链路、密码体系和情报拦截等环节暴露出来,最终成为改变局势的重要事件。
这段历史对云原生系统有一个直接启发:数据主权从来不只是“数据存在哪个国家”。更关键的问题是,谁能访问数据,谁控制密钥,谁决定平台策略,谁能够调取审计记录,以及当服务商或法律环境发生变化时,组织是否仍然有选择权。
“存储地点”只是问题的一部分
在云环境中,一家公司可能把数据库放在本国区域,但仍然使用境外控制的云平台、第三方备份服务、外部密钥管理系统或跨境运维工具。此时,地理位置并不能完整描述数据的治理边界。
可以把数据主权拆成几项需要单独确认的控制面:
- 数据驻留:数据、备份和日志保存在哪些区域。
- 访问控制:哪些用户、服务账号和运维人员可以读取数据。
- 密钥控制:加密密钥由谁生成、托管、轮换和撤销。
- 运营控制:谁能够修改集群、网络、身份和策略配置。
- 法律与供应商边界:哪些主体可能依据合同、司法管辖或平台权限访问数据。
- 可迁移性:平台不可用或合作关系变化时,能否导出数据并迁移工作负载。
如果只检查第一项,得到的往往是“数据在本地”的表面结论,而不是完整的主权评估。
云原生系统的暴露面更分散
传统单体系统通常有较清晰的边界。云原生应用则会把一次业务请求拆成多个服务,并依赖容器镜像仓库、Kubernetes 控制面、服务网格、可观测性平台、CI/CD 系统和备份系统。
一条看似普通的请求可能经过以下路径:
用户请求
-> API 网关
-> 应用服务
-> 消息队列
-> 数据库
-> 日志与指标平台
-> 备份与灾难恢复系统
每个箭头都可能产生数据复制、元数据记录、身份令牌或运维痕迹。即使业务数据库满足区域要求,调试日志、异常堆栈、消息副本和快照也可能被发送到另一个区域。
这与秘密电报的教训相似:不能只保护“正文”,还要理解传输、转发、存档和访问链路。云原生的数据主权设计也应从数据流开始,而不是从云厂商的区域列表开始。
一个可落地的 Kubernetes 约束示例
下面的 YAML 是一个可以改造的 Kubernetes 示例。它假设集群节点已经通过 topology.kubernetes.io/region 标记区域,并且集群安装了 Gatekeeper 或其他策略控制器。示例通过节点选择、持久卷拓扑和网络策略,减少工作负载被调度到非目标区域的机会。
运行前需要根据实际环境修改区域名称、命名空间、镜像地址和标签规则。仅部署这些资源并不能自动证明合规性,还需要配合云平台配置、备份策略、密钥管理和审计验证。
apiVersion: v1
kind: Namespace
metadata:
name: sovereign-app
labels:
data-residency: domestic
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: domestic-ssd
provisioner: pd.csi.storage.gke.io # 按云平台替换
volumeBindingMode: WaitForFirstConsumer
allowedTopologies:
- matchLabelExpressions:
- key: topology.kubernetes.io/region
values:
- domestic-region-1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: records-api
namespace: sovereign-app
spec:
replicas: 2
selector:
matchLabels:
app: records-api
template:
metadata:
labels:
app: records-api
data-classification: restricted
spec:
nodeSelector:
topology.kubernetes.io/region: domestic-region-1
containers:
- name: api
image: registry.example.com/records-api:1.4.2
env:
- name: LOG_REDACTION
value: "strict"
ports:
- name: http
containerPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: records-api-egress
namespace: sovereign-app
spec:
podSelector:
matchLabels:
app: records-api
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
name: sovereign-app
ports:
- protocol: TCP
port: 5432
这个例子解决的是调度和网络边界问题,但它没有解决所有主权问题。例如,容器镜像可能来自另一个司法管辖区,控制面管理员仍可能拥有高权限,日志收集器可能把敏感字段发送到外部平台,云端快照也可能没有使用组织自己控制的密钥。
因此,实践中还需要建立配套检查:
# 检查工作负载所在节点及区域
kubectl get pods -n sovereign-app -o wide
kubectl get nodes \
-L topology.kubernetes.io/region,topology.kubernetes.io/zone
# 检查命名空间中的镜像来源
kubectl get pods -n sovereign-app \
-o jsonpath='{range .items[*].spec.containers[*]}{.image}{"\n"}{end}'
# 检查是否存在跨命名空间或外部出口策略
kubectl get networkpolicy -n sovereign-app -o yaml
从“相信平台”转向“验证控制权”
数据主权方案需要把责任落到可验证的控制上,而不是停留在合同和宣传材料层面。一个较实用的评估流程如下:
- 绘制数据流:列出生产数据、备份、日志、指标、追踪信息和临时文件的流向。
- 标注分类:为个人数据、商业秘密、监管数据和普通业务数据设定不同等级。
- 逐项确认控制者:明确云平台、托管服务商、内部团队和第三方工具各自拥有的权限。
- 验证密钥路径:确认密钥是否由组织控制,是否支持独立轮换、撤销和审计。
- 限制跨境复制:检查快照、日志、容器镜像、CI 缓存和灾备副本,而不只是主数据库。
- 执行故障演练:验证在区域不可用、供应商受限或凭证泄露时,能否恢复和迁移。
- 保留证据:将策略、访问日志、密钥操作记录和迁移测试结果纳入审计资料。
这里的核心变化是:问题不再是“我们用了哪一家云”,而是“在关键时刻,我们是否能证明并执行自己的控制权”。
采用建议与边界
云原生数据主权通常需要在便利性、成本、全球可用性和控制能力之间做取舍。把所有系统都部署到完全隔离的环境,可能提高运维成本;把所有数据交给单一平台,又可能增加供应商锁定和法律风险。
可以从高敏感度工作负载开始,逐步建立基线:
- 将敏感数据与普通数据分级部署。
- 让日志默认脱敏,并禁止把原始请求体写入日志。
- 使用组织可控制的密钥管理方案。
- 为存储、备份、镜像和遥测分别定义区域要求。
- 用策略即代码阻止不符合区域和身份要求的部署。
- 定期测试数据导出、恢复和跨平台迁移。
1917年的电报提醒我们,保密不是某一个密码算法或某一段网络链路的属性,而是整个通信系统的属性。对今天的云原生平台来说,数据主权也是如此:位置、权限、密钥、运营和迁移能力必须作为一个整体接受验证。