Cloud Service Mesh:身份策略与变更
验证:静态检查 · 核验于 2026-09-28
- 适用版本
- 云环境版本未实测;适用条件见正文
- 验证范围
- 已检查文档构建、链接与脚本语法;未执行云端实验。
用于需要服务间身份、mTLS 与流量治理的 GKE 工作负载。
推荐做法#
- 确认托管 implementation、版本与支持矩阵;代理资源和出站依赖纳入容量规划。
- 先在隔离 namespace 验证 baseline,再逐步启用 STRICT / ALLOW。
- principal 从实际工作负载证书 SAN 获取;正确/错误 SA、无代理客户端分别验证。
常用操作#
替换为实际资源;本段不依赖 lab.env。
PROJECT_ID='REPLACE_PROJECT_ID'
gcloud container fleet mesh describe --project="$PROJECT_ID"
kubectl config current-context
kubectl get pods -A容易踩的坑#
- mTLS 验证不等于业务租户授权;IAM/RBAC/mesh policy 是不同层。
不要用 OSS Istio 的覆盖安装或 Helm downgrade 操作托管控制面。 先核对当前 implementation 的支持路径;本例已有自建网格采用新集群迁移。
配置说明与完整示例(按需展开)
GCP 有 Cloud Service Mesh;旧资料常叫 Anthos Service Mesh。本文采用 GKE 托管控制面、Istio APIs。它管理服务间流量与身份;IAM 管理 Google Cloud 资源权限,Kubernetes RBAC 管理 Kubernetes API,三者不能互相替代。
1. 实验范围与前置#
使用 GKE Standard 私有集群 的独立预生产集群,fleet、cluster、VPC 同项目;开启 Workload Identity, node pool 也启用,使用受支持版本/区域和既定 release channel。现有 OSS Istio/自建 ASM 集群走新集群迁移,不能直接套本文覆盖控制面。
管理员具备 fleet 管理、API enable、必要 GKE 管理及 Kubernetes namespace/RBAC 权限;业务 SA 不获得这些权限。网格 service agent 与业务身份分离。规划 sidecar/CNI 资源和费用;确认代理可访问 CA/控制面,业务不得使用不支持的 hostNetwork/GKE Sandbox 组合。支持矩阵
除第 3 节注明的本机构建/复制外,命令均在 GKE 篇创建的私网 runner 执行;本机或 Cloud Shell 不能直接访问本实验私有 endpoint。
set -euo pipefail
export PROJECT_ID='REPLACE_SANDBOX_PROJECT'
export CLUSTER='REPLACE_STAGING_CLUSTER'
export LOCATION='REPLACE_CLUSTER_REGION_OR_ZONE'
gcloud container clusters describe "$CLUSTER" --location "$LOCATION" --project "$PROJECT_ID" --format='yaml(workloadIdentityConfig,releaseChannel,nodePools.config.workloadMetadataConfig)'
gcloud services enable mesh.googleapis.com meshconfig.googleapis.com meshca.googleapis.com container.googleapis.com gkehub.googleapis.com monitoring.googleapis.com stackdriver.googleapis.com connectgateway.googleapis.com trafficdirector.googleapis.com networkservices.googleapis.com networksecurity.googleapis.com --project "$PROJECT_ID"
gcloud container fleet mesh enable --project "$PROJECT_ID"
gcloud container clusters update "$CLUSTER" --location "$LOCATION" --project "$PROJECT_ID" --fleet-project "$PROJECT_ID"
gcloud container fleet memberships list --project "$PROJECT_ID"2. 开启托管控制面#
export MEMBERSHIP='REPLACE_MEMBERSHIP_NAME_FROM_LIST'
export MEMBERSHIP_LOCATION='REPLACE_MEMBERSHIP_LOCATION_FROM_LIST'
gcloud container fleet mesh update --management automatic --memberships "$MEMBERSHIP" --location "$MEMBERSHIP_LOCATION" --project "$PROJECT_ID"
gcloud container fleet mesh describe --project "$PROJECT_ID"
gcloud container clusters get-credentials "$CLUSTER" --location "$LOCATION" --project "$PROJECT_ID" --internal-ip等待该 membership 的 controlPlaneManagement 和 dataPlaneManagement 为 ACTIVE、state 为 OK,记录 READY revision 和 implementation。托管实现可能为 TRAFFIC_DIRECTOR;不能照搬 OSS Istio 的所有 API/debug 命令。例如 network project 与 fleet project 不同时,官方流程要求把 fleet 的 service-FLEET_PROJECT_NUMBER@gcp-sa-servicemesh.iam.gserviceaccount.com 在 network project 授予 roles/anthosservicemesh.serviceAgent;cluster project 也独立时,另执行官方跨项目 API/IAM 步骤。不要把此角色给应用 SA;本单项目命令不包含这些跨项目授权。开通步骤
3. 真实业务试点#
使用仓库 static/examples/enterprise-orders/gcp/mesh 配套 overlay;namespace=orders-mesh,复用订单 API、异步 SQL outbox worker、三副本和 PDB。本 worker 消费数据库任务,测试客户端用 orders-worker 身份调用 API;不要误认为部署 worker 本身就会产生 HTTP 调用。
先完成 企业项目 第 1–3 节。GKE 必须在同一 orders-enterprise VPC;不要对共享生产数据库跑初始化。镜像复用已测试/签名的摘要。在本机企业项目工作目录,用 Helm 生成共同基线再渲染专用 overlay:
export IMAGE=$(cat evidence/image.txt)
export DB_IP=$(terraform -chdir=gcp output -raw database_ip)
python3 render_kustomize.py "$IMAGE" "$DB_IP/32"
kubectl kustomize gcp/mesh > gcp/mesh/rendered.yaml
gcloud compute scp gcp/mesh/rendered.yaml gcp/mesh/check.py orders-gke-runner:~/ --zone="$RUNNER_ZONE" --tunnel-through-iap
gcloud compute scp secrets/token orders-gke-runner:~/mesh-test-token --zone="$RUNNER_ZONE" --tunnel-through-iap仅把合成租户测试 token 传给专属 runner;文件权限设为 600,实验后删除。后续命令都在 runner 执行,复用已登录的短期身份;身份需读取下面四个指定 Secret Manager 秘密的权限。生产常驻应用由秘密同步控制器/CSI 获取,不能把操作者身份赋给 Pod。此处采用一次性导入,Kubernetes Secret 不进入 Git;限定 namespace RBAC。
kubectl create namespace orders-mesh --dry-run=client -o yaml | kubectl apply -f -
export REVISION='REPLACE_READY_REVISION_FROM_MESH_STATUS'
kubectl label namespace orders-mesh istio-injection- istio.io/rev="$REVISION" --overwrite
umask 077
chmod 600 ~/mesh-test-token
export SECRET_DIR=$(mktemp -d)
gcloud secrets versions access 1 --secret=orders-api-dsn > "$SECRET_DIR/api-dsn"
gcloud secrets versions access 1 --secret=orders-worker-dsn > "$SECRET_DIR/worker-dsn"
gcloud secrets versions access 1 --secret=orders-auth > "$SECRET_DIR/auth.json"
gcloud secrets versions access 1 --secret=orders-db-ca > "$SECRET_DIR/ca.pem"
kubectl -n orders-mesh create secret generic orders-runtime --from-file=DATABASE_URL="$SECRET_DIR/api-dsn"
kubectl -n orders-mesh create secret generic orders-worker-runtime --from-file=DATABASE_URL="$SECRET_DIR/worker-dsn"
kubectl -n orders-mesh create secret generic orders-auth --from-file=auth.json="$SECRET_DIR/auth.json"
kubectl -n orders-mesh create configmap orders-db-ca --from-file=ca.pem="$SECRET_DIR/ca.pem"
kubectl -n orders-mesh create secret generic orders-test-token --from-file=token="$HOME/mesh-test-token"
rm -r "$SECRET_DIR"
kubectl apply --dry-run=server -f ~/rendered.yaml
kubectl apply -f ~/rendered.yaml
kubectl -n orders-mesh rollout status deployment/orders-api --timeout=10m
kubectl -n orders-mesh rollout status deployment/orders-worker --timeout=10m
kubectl -n orders-mesh get pods -o jsonpath='{range .items[*]}{.metadata.name}{" "}{.spec.containers[*].name}{"\n"}{end}'以上数字版本 1 对应首次初始化;若已轮换,先取企业项目批准的版本替换。默认业务网络策略保留数据库 /32、DNS 出站,并为托管控制面开放 TCP 443/15012、GKE 元数据服务 80;在 VPC 出口进一步限制批准的目的地址。自定义 DNS、层级防火墙或网格实现需要按实际 endpoint 调整,不能删除全部网络策略排障。
必须看到代理实际注入(原生 sidecar 也可能列在 initContainers);已有 Pod 需要滚动重建。先在未安装本篇 STRICT/ALLOW 策略的专用 namespace 运行对照测试:
export IMAGE='REPLACE_APPROVED_IMAGE_AT_SHA256_DIGEST'
python3 ~/check.py baseline --image="$IMAGE"三个客户端应都能下单并完成异步账本,且幂等重复返回同一订单。baseline 创建同网络、同应用 token 的正确 SA、错误 SA、无代理客户端;如果此时已有拒绝,先检查继承策略和网络,不能把它算作后续 mTLS 成功。
使用当前 gcloud beta 组件的托管网格调试接口获取证书配置;先 gcloud beta container fleet mesh debug proxy-config --help 确认组件和参数可用。以下仅保存证书详情,不导出私钥;证据文件限制访问:
gcloud beta container fleet mesh debug proxy-config mesh-good.orders-mesh --type=secret --membership="$MEMBERSHIP" --location="$MEMBERSHIP_LOCATION" --project="$PROJECT_ID" --output=json > mesh-certificates.json在输出的工作负载叶证书详情中核对有效期与 URI SAN(Subject Alternative Name,证书身份扩展),复制 spiffe://.../ns/orders-mesh/sa/orders-worker。若实现返回证书正文,将该叶证书保存为 PEM,运行 openssl x509 -in workload.pem -noout -dates -ext subjectAltName;不要将 trust domain 猜成 cluster.local。若当前实现不返回所需详情,按托管调试说明取证后再继续。
4. 强制 mTLS 与最小调用权限#
保存 mesh-policy.yaml。用证书实际 SAN 去掉 spiffe:// 后的身份替换 principal(典型格式为 TRUST_DOMAIN/ns/orders-mesh/sa/orders-worker),否则合法 worker 也会被拒绝。
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata: {name: strict, namespace: orders-mesh}
spec:
mtls: {mode: STRICT}
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata: {name: worker-to-api, namespace: orders-mesh}
spec:
selector:
matchLabels: {app.kubernetes.io/name: orders-api}
action: ALLOW
rules:
- from:
- source:
principals: [REPLACE_ACTUAL_WORKER_CERTIFICATE_PRINCIPAL]
to:
- operation:
ports: ['8080']kubectl apply --dry-run=server -f mesh-policy.yaml
kubectl apply -f mesh-policy.yaml
gcloud container fleet mesh describe --project "$PROJECT_ID"
kubectl -n orders-mesh get peerauthentication,authorizationpolicy -o yaml等待策略下发后,对原先的三个客户端再次测试:
python3 ~/check.py enforced --image="$IMAGE"
kubectl -n orders-mesh get peerauthentication strict -o yaml > mesh-strict-evidence.yaml
kubectl -n orders-mesh get authorizationpolicy worker-to-api -o yaml > mesh-authz-evidence.yaml验收:正确 SA 完成订单、重复请求幂等、账本金额 1200;错误应用 token 返回 401、跨租户返回 403;错误 SA 返回网格 RBAC 403;无代理客户端连接被拒绝,不能到达应用 HTTP。baseline 全通过、STRICT 后明文失败、正确身份仍成功,加上有效工作负载证书共同构成 mTLS 证据。本参考应用使用租户 bearer token,不声称实现 JWT 登录。
网关/监控后续接入需明确增加真实 principal。探针由 sidecar 重写处理;不能为了让探针变绿开放所有调用。策略刚下发时失败可在确认配置收敛后重测;持续失败保留结果排障,不修改测试使其通过。
5. 升级、失败恢复与清理#
托管数据面可能逐步重建业务 Pod:准备 PDB、surge 容量、长连接排空和应用重试预算。先试点集群,再扩大;不要同窗口做 GKE 大幅升级、CA 轮换和应用不兼容发布。检查服务 NEG 注解的控制器所有权,避免 GitOps 移除云端注入字段。
策略错误时恢复上一版已验证的 policy,重新验证合法/非法调用;初次试点失败则让正式流量继续留在原环境,修复后再切换。托管控制面不按 OSS Istio 方式 Helm downgrade;遵循支持路径或新集群迁移。移除前先停止业务接流、迁走调用方,再删除试点工作负载/策略;不能先删 fleet feature、CRD 或禁用共享 API。
验收记录包含实际 implementation/revision、证书身份、拒绝用例、延迟/资源开销、代理重建过程及业务结果。
仅删除本篇 namespace;数据库、集群和镜像先保留给升级/灾备实验。清理测试客户端及 runner 上 token:
kubectl -n orders-mesh delete pod mesh-good mesh-wrong mesh-plain --ignore-not-found
kubectl -n orders-mesh delete secret orders-test-token
rm ~/mesh-test-token
# 确认业务已经停止且证据留存后执行。
kubectl delete namespace orders-mesh