Service Mesh 到底解决什么问题?从请求链路到 Istio 灰度、mTLS 与故障排查
同一个接口,Java 服务重试三次,Go 服务重试一次,另一个服务干脆没有超时。新版本想先放一点流量,客户端却各自维护地址。出了故障,应用日志都说“下游调用失败”,链路到哪一跳开始慢,没人能马上对齐。
这才是 Service Mesh 值得讨论的现场。它把服务间通信的一部分共性能力放到基础设施里,让不同语言的服务使用相近的流量规则、身份机制和观测入口。
但我不会因为 Pod 多了一个代理,就宣布治理完成。流量有没有经过代理、身份有没有被验证、调用链有没有串起来,都要逐项核验;配置写进 Kubernetes,也不等于每个代理已经收到并执行。
Service Mesh 统一的是通信规则,应用仍要对业务语义负责。 下面把架构、适用边界和一个可复现的 Istio 实验接起来,读完能知道怎么配置,也能知道配置失败该往哪查。
一次请求怎么走,控制面在哪里?
Service Mesh 是治理服务间通信的基础设施层,常用于处理微服务的东西向流量。在典型 Istio sidecar 模式下,被纳入网格的工作负载旁有 Envoy 代理。
应用发起请求,代理根据配置处理路由、连接、超时、重试、加密等,再把请求送往接收端代理和应用。
应用 A → 代理 A → 代理 B → 应用 B
↑ ↑
└── istiod 下发配置、身份材料等 ──┘Envoy 是这个模式的数据面,istiod 是控制面。两者的区别可以理解为:
- 数据面处理实际请求:转发流量、选择上游、执行访问控制、产生通信指标。
- 控制面管理规则和身份:发现服务、生成并下发代理配置、参与工作负载证书管理。
正常请求沿数据面传输,不需要每次先去问 istiod。控制面不可用时,已配置代理通常还能使用最后收到的配置继续处理流量,但新 Pod 获取配置、端点变化、规则更新、证书轮换等可能受影响。
所以,“老请求还通”不能证明控制面健康。
Mesh 不必都用 sidecar。Istio ambient 模式以 ztunnel 提供四层安全与连接能力,需要七层治理时可使用 waypoint。两种模式的流量路径、能力落点和排障方法不同,本文的实验只讨论 sidecar。
代理也不是天然接管所有流量。实际捕获范围、排除端口/IP、hostNetwork、注入与平台配置都会影响路径;绕过代理的流量不自动得到同样的治理。
手工在 Pod YAML 里增加一个 istio-proxy 容器,也不等于完成网格接入。完整注入还涉及代理启动配置、工作负载身份、网络重定向等;网络重定向可能由初始化容器或平台部署的 Istio CNI 配合完成。
我会用这张表划清职责:
| 能力 | 通常解决的问题 | 需要另外解决的问题 |
|---|---|---|
| Kubernetes Service 与具体 kube-proxy/CNI 实现 | 服务发现、稳定访问地址、四层连接选择 | 按 HTTP 请求进行版本灰度、工作负载身份授权 |
| Service Mesh | 纳管通信的身份、流量与观测治理 | 业务幂等、业务权限、应用内部计算与数据库瓶颈 |
| API 网关 | 常见于北南入口路由、认证、限流等 | 内部服务每一跳的通信治理,具体能力取决于实现 |
这些职责会交叉,关键是规则由谁拥有、在哪里生效。
Istio Gateway 能处理特定入口流量,但不等于完整 API 管理平台。开发者门户、API 产品管理、计费和业务认证等,需要根据系统需求补充。
还要分清应用 TLS 与 mesh mTLS:后者在代理之间加密原本的 HTTP,代理仍可处理七层信息;前者若只被透传,代理无法凭空看到 HTTP 路径、状态和请求内容,相关路由与观测能力就会受到限制。
先算收益与成本,再决定要不要引入
我会优先看通信规则是否频繁重复:
- 多语言服务需要统一超时、灰度和身份策略。
- 发布新版本需要协调多个调用方。
- 证书管理已经成为长期维护负担。
- 故障定位经常卡在“哪个服务调用哪个服务失败”。
- 相同治理能力散落在多个客户端库里,配置和行为难以统一。
这些信号比“达到几十个服务”更有用,服务数量没有统一入场门槛。
收益来自规则集中下发、跨语言一致性和可观测性,成本则落在代理 CPU/内存、额外网络处理、配置复杂度与控制面的运维上。
不能承诺固定增加 1~5ms 延迟。必须在代表性并发、报文大小、连接复用与加密条件下测量 P99、吞吐、代理 CPU/内存、应用 GC 和节点争用,再决定资源预算。
观测也要配置。指标端点、访问日志、采样和后端采集需要按部署核查;采集不到不能当作没有请求。
代理能够提供通信层信息,但完整分布式调用链通常仍需要应用传播追踪上下文。上下文中断时,一个请求在不同服务里可能变成多段互不相连的链路。使用哪种传播格式,应与当前追踪系统和应用配置一致。
超时与重试尤其要保留业务判断。调用方总截止时间要覆盖合理的单次尝试与排队预算,并与上游剩余时间协调;叠加应用重试和代理重试会放大请求量。
非幂等写入可能产生重复副作用,不能见到错误就给全部 POST 加重试。
选型时也别只问 Istio 和 Linkerd 谁“更轻”。两者在数据面、功能覆盖和配置方式上有差异,应按当前受支持版本比较必需功能、升级路径、故障定位能力与团队经验,再用相同业务负载测资源和延迟。
团队没人能解释生效策略、证书和回退流程时,再多功能也会成为新的不确定性。
在独享实验空间,把两个版本跑起来
以下 Bash 命令在有权限的 Linux 运维终端执行,所有 <...> 必须先替换,不能原样运行。
实验前提是已有受支持的 Istio sidecar 安装,终端 istioctl 与控制面版本匹配。确认 PodSecurity、准入策略与平台的网络重定向方式兼容;受限环境按既有 Istio CNI/注入方案运行。
镜像为固定版本演示,正式使用应经过扫描并锁定 digest。仓库访问、准入或权限失败时,按平台流程处理。
先做只读确认:
kubectl config current-context
kubectl version
istioctl version
istioctl proxy-status
kubectl -n get pods -l app=istiod
kubectl get peerauthentication,authorizationpolicy -A
istioctl analyze --help
istioctl proxy-config --help
kubectl get crd \
virtualservices.networking.istio.io \
destinationrules.networking.istio.io \
peerauthentications.security.istio.io \
authorizationpolicies.security.istio.io \
-o jsonpath='{range .items[*]}{.metadata.name}{" "}{range .spec.versions[*]}{.name}{" served="}{.served}{" "}{end}{"\n"}{end}'重点确认目标集群与版本、控制面状态,以及四种 CRD 的 v1 是否 served=true。
控制面 namespace、修订版和根命名空间策略由平台确认;不能把 istio-system 当成所有安装的固定位置。已有全局策略可能影响实验流量,即便新建 namespace 也不能跳过检查。
本文 YAML 使用这些 v1 API;版本不支持时,应对照该版本文档调整。帮助输出用于核对后面命令在当前版本的参数。
本文服务 FQDN 假设 Kubernetes 的 clusterDomain,也就是服务 DNS 后缀,为 cluster.local。若实际不同,替换全文 Service host、路由目标和 curl URL 中的后缀。
它与后面 Istio 工作负载身份的 trustDomain 是两个独立配置,示例值相同不能证明实际相同。
实验会创建新 namespace,并在其中部署工作负载和策略,属于有状态变更。先确认 mesh-lab 不存在:
kubectl get namespace mesh-lab只有服务器明确返回该 namespace NotFound 才继续。权限、网络或其他错误不能解释成不存在。
如果已有 namespace,就换新独享名字,并替换全文。确认 NotFound 后执行:
kubectl create namespace mesh-lab &&
kubectl label namespace mesh-lab istio-injection=enabled&& 确保创建成功才贴标签;任一步失败就停止,先查原因。
上面的方式适用于平台允许使用默认注入标签的安装。修订版安装将标签改为平台指定的 istio.io/rev=,仍保留创建成功的保护。两种标签二选一,不同时设置。
注入发生于新 Pod 创建时。已有 Pod 不会热加代理;共享业务滚动重建还需容量、可用性与回退准备,本文用新空间进行实验。
把下面内容保存为 mesh-apps.yaml,一次建立应用和两个客户端身份:
apiVersion: v1
kind: ServiceAccount
metadata:
name: echo
namespace: mesh-lab
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: echo-client
namespace: mesh-lab
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: echo-denied
namespace: mesh-lab
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-v1
namespace: mesh-lab
spec:
replicas: 1
selector:
matchLabels:
app: echo
version: v1
template:
metadata:
labels:
app: echo
version: v1
spec:
serviceAccountName: echo
containers:
- name: echo
image: hashicorp/http-echo:1.0.0
args: ["-listen=:5678", "-text=v1"]
ports:
- containerPort: 5678
readinessProbe:
httpGet:
path: /
port: 5678
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
cpu: 200m
memory: 64Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-v2
namespace: mesh-lab
spec:
replicas: 1
selector:
matchLabels:
app: echo
version: v2
template:
metadata:
labels:
app: echo
version: v2
spec:
serviceAccountName: echo
containers:
- name: echo
image: hashicorp/http-echo:1.0.0
args: ["-listen=:5678", "-text=v2"]
ports:
- containerPort: 5678
readinessProbe:
httpGet:
path: /
port: 5678
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
cpu: 200m
memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
name: echo
namespace: mesh-lab
spec:
selector:
app: echo
ports:
- name: http
port: 80
targetPort: 5678
---
apiVersion: v1
kind: Pod
metadata:
name: echo-client
namespace: mesh-lab
labels:
app: echo-client
spec:
serviceAccountName: echo-client
containers:
- name: curl
image: curlimages/curl:8.12.1
command: ["sh", "-c", "sleep 86400"]
resources:
requests:
cpu: 25m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi
---
apiVersion: v1
kind: Pod
metadata:
name: echo-denied
namespace: mesh-lab
labels:
app: echo-denied
spec:
serviceAccountName: echo-denied
containers:
- name: curl
image: curlimages/curl:8.12.1
command: ["sh", "-c", "sleep 86400"]
resources:
requests:
cpu: 25m
memory: 16Mi
limits:
cpu: 100m
memory: 64Mi这里有几个不能忽略的细节:
- 两个 Deployment 的 selector 与各自 Pod 标签一致。
- Service 只按
app: echo选择,所以包含两个版本。 - Service 访问端口是 80,应用实际监听端口是 5678。
- 服务端口命名为
http,帮助明确协议。 - 两个客户端使用不同 ServiceAccount,后面才能验证身份授权。
资源值仅适用于轻量演示,未包含注入代理自身的资源,以实际注入模板与集群预算为准。两个客户端是用裸 Pod 和长时间 sleep 保活的实验工具,不是生产部署模板。
预览校验通过后,再创建并确认:
kubectl apply --dry-run=server -f mesh-apps.yaml
kubectl apply -f mesh-apps.yaml
kubectl -n mesh-lab rollout status deployment/echo-v1 --timeout=3m
kubectl -n mesh-lab rollout status deployment/echo-v2 --timeout=3m
kubectl -n mesh-lab wait \
--for=condition=Ready \
pod/echo-client pod/echo-denied \
--timeout=3m
kubectl -n mesh-lab get pods
istioctl proxy-status
kubectl -n mesh-lab exec echo-client -c curl -- \
curl -fsS --max-time 3 http://echo.mesh-lab.svc.cluster.local/预期响应是 v1 或 v2。
常见 sidecar 布局显示应用容器和 istio-proxy 均就绪,即 2/2;还要查看实际容器与代理同步状态。若启用了原生 sidecar,代理可能位于 initContainers,不能固定用 2/2 判断注入。
kubectl -n mesh-lab get pod echo-client -o yaml
kubectl -n mesh-lab get pod echo-client \
-o jsonpath='{.spec.containers[*].name}{"\n"}{.spec.initContainers[*].name}{"\n"}'
kubectl -n mesh-lab get pods -l app=echo -o yamlIstio 通常会改写 HTTP 健康探针,核查实际 Pod 的 probe 与事件。Pending、注入失败或首次调用失败时,先采事件与代理状态,未通过就不要继续增加策略。
90/10 是路由规则,先用配置和响应一起证明
Service 选择两个版本的 Pod,DestinationRule 按 version 标签定义 subset,VirtualService 把到这个服务的请求分配给不同 subset。
Service、subset 与 Pod 标签必须对齐,写了 v2 不会凭空生成一个 v2 端点。
保存为 mesh-routing.yaml:
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: echo
namespace: mesh-lab
spec:
host: echo.mesh-lab.svc.cluster.local
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: echo
namespace: mesh-lab
spec:
hosts:
- echo.mesh-lab.svc.cluster.local
gateways:
- mesh
http:
- timeout: 2s
route:
- destination:
host: echo.mesh-lab.svc.cluster.local
subset: v1
port:
number: 80
weight: 90
- destination:
host: echo.mesh-lab.svc.cluster.local
subset: v2
port:
number: 80
weight: 10gateways: [mesh] 明确这条规则作用于网格内流量;这份实验没有配置入口网关。
先将两个 weight 设置为 100/0,按下方步骤建立全量 v1 基线,再恢复文件中的 90/10 重复验证。这样能比较变更前后,也有明确的回退目标。
这里只给幂等 GET 做验证,暂不加重试。若确需一次 GET 重试,可按当前版本文档增加 retries.attempts: 1 与 perTryTimeout: 500ms,并验证总截止时间、重试触发条件和实际请求放大量。
这份 echo 服务响应很快,实验能证明路由下发与版本响应,不能证明 2s 超时已经实测生效。超时需另用可控慢服务验证,也不要在同一 HTTP 规则混入故障注入来推断 timeout/retry 行为。
kubectl apply --dry-run=server -f mesh-routing.yaml
kubectl apply -f mesh-routing.yaml
istioctl analyze -n mesh-lab
istioctl proxy-config routes echo-client -n mesh-lab分析没有配置错误、路由下发后,执行统计:
kubectl -n mesh-lab exec echo-client -c curl -- sh -c '
attempted=0
v1=0
v2=0
failed=0
unexpected=0
while [ "$attempted" -lt 100 ]; do
attempted=$((attempted+1))
if body=$(curl -fsS --max-time 3 http://echo.mesh-lab.svc.cluster.local/); then
case "$body" in
v1) v1=$((v1+1)) ;;
v2) v2=$((v2+1)) ;;
*) unexpected=$((unexpected+1)) ;;
esac
else
failed=$((failed+1))
fi
done
sum=$((v1+v2+failed+unexpected))
printf "attempted=%s sum=%s v1=%s v2=%s failed=%s unexpected=%s\n" \
"$attempted" "$sum" "$v1" "$v2" "$failed" "$unexpected"
[ "$attempted" -eq 100 ] &&
[ "$sum" -eq "$attempted" ] &&
[ "$failed" -eq 0 ] &&
[ "$unexpected" -eq 0 ] || exit 1
'脚本完成 100 次尝试:
- 超时、连接错误和 HTTP 错误计入
failed。 - 成功但正文不是 v1/v2 的响应计入
unexpected。 - 任一异常让脚本以非零状态退出。
- 外层没有管道覆盖
kubectl exec的退出码。
先确认 attempted 与四项之和均为 100,再看版本分配。
100/0 基线应全为 v1 且异常计数为零;90/10 下的 100 次请求只是低负载概率演示,不保证恰好 90/10。若未见 v2,增加受控样本并核对路由。
生产灰度应观测两个版本的实际 QPS、错误率、P99 与资源,并匹配请求类型和单 Pod 负载后比较。不能用 port-forward 直连某个 Pod 来证明服务路由有效。
连接池限制与异常实例驱逐常被统称为“熔断”,但具体行为不同:
connectionPool限制连接、待处理请求等。outlierDetection根据错误驱逐异常上游端点。
它们不能自动理解余额不足、库存不足等业务语义。阈值应按服务、端口和并发压测确定;过紧会主动制造溢出或减少可用实例。
加密证明身份,授权决定谁能调用
mTLS 同时提供通信加密与对端工作负载身份验证,业务用户身份仍由应用处理。
PeerAuthentication 定义接收端接受的传输要求;AuthorizationPolicy 定义身份和请求是否允许。namespace 隔离或 NetworkPolicy 不是同一层次的替代品。
下面独立假设 Istio 身份信任域 trustDomain 为 cluster.local。其他值只替换 principal 中的信任域,不据此改服务 DNS。
保存为 mesh-security.yaml,只选择 app: echo 的实验工作负载:
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: echo-strict
namespace: mesh-lab
spec:
selector:
matchLabels:
app: echo
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: echo-allow-client
namespace: mesh-lab
spec:
selector:
matchLabels:
app: echo
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/mesh-lab/sa/echo-client
to:
- operation:
methods:
- GET
paths:
- /这里允许的是持有 echo-client ServiceAccount 工作负载身份、访问 / 的 GET。请求 principal 需要 mTLS 才能建立。
规则不是“同 namespace 都能访问”。
适用的 ALLOW 策略存在时,请求至少要匹配一条允许规则;多个 ALLOW 组成允许集合,因此其他策略也可能放行。匹配的 DENY 会优先阻断,其他高级 action 按当前版本文档核对。
已有上层策略也可能影响最终结果,执行前要检查实际生效范围。
kubectl get peerauthentication,authorizationpolicy -A
kubectl apply --dry-run=server -f mesh-security.yaml
kubectl apply -f mesh-security.yaml
istioctl analyze -n mesh-lab
istioctl proxy-status
istioctl proxy-config clusters echo-client -n mesh-lab -o json
istioctl proxy-config secret echo-client -n mesh-lab
kubectl -n mesh-lab exec echo-client -c curl -- \
curl -sS -o /dev/null -w '%{http_code}\n' \
--max-time 3 http://echo.mesh-lab.svc.cluster.local/
kubectl -n mesh-lab exec echo-denied -c curl -- \
curl -sS -o /dev/null -w '%{http_code}\n' \
--max-time 3 http://echo.mesh-lab.svc.cluster.local/等待代理同步后,允许身份预期得到 200,另一个已经注入 sidecar、使用 echo-denied 身份的客户端预期得到 403。
若返回连接错误,不能当作授权拒绝成功;应检查 mTLS、端点与路由。两个客户端都要确认代理存在和就绪,避免把“未进入网格”误解成“身份策略起作用”。
clusters 输出中核对目标 echo subset 的 TLS 传输配置与证书引用;secret 默认摘要查看证书状态和有效期,不导出私钥或整份敏感 secret。
证书存在也不能独立证明这一跳用了它,需要结合目标 cluster、接收端 STRICT 生效与现有安全观测。
403 则要与实际 ServiceAccount 和生效授权规则对应,排除应用返回的同名状态。成功返回 200,也不能证明整个网络都已加密。
出现 503,先把应用端点与代理端点对上
下面用一个脱敏后的典型场景说明。以下时间、比例、状态和配置差异均为机制推演示例,不对应真实事故。
示例中,15:00 将流量从全量 v1 调到 90/10 后出现一部分 503,v1 请求仍正常。
初判是 v2 应用坏了,但两个 Deployment 都就绪,Service 的 EndpointSlice 也能看到两个版本的地址,应用健康检查正常。
这个证据只能说明 Service 有端点,不能证明 v2 subset 有端点。
检查客户端代理配置后,路由确实指向 v2 cluster,但 v2 cluster 没有可用 endpoint。再对照 YAML:v2 Pod 的版本标签是 v2-canary,DestinationRule 却筛选 version: v2。
根因在 subset 标签不匹配。
修正 DestinationRule 的筛选标签、通过预览和分析、等待代理同步后,v2 endpoint 出现,受控请求恢复。不要为复现故障而修改 Deployment 不可变 selector;这里用配置差异说明排查路径。
我会沿这组只读命令缩小范围。日志和输出可能含地址与请求信息,只取故障时间附近,分享前脱敏:
kubectl -n mesh-lab get pods -o wide --show-labels
kubectl -n mesh-lab get service echo -o yaml
kubectl -n mesh-lab get endpointslice \
-l kubernetes.io/service-name=echo -o yaml
kubectl -n mesh-lab get networkpolicy -o yaml
kubectl get nodes
istioctl proxy-status
istioctl analyze -n mesh-lab
istioctl proxy-config routes echo-client -n mesh-lab
istioctl proxy-config clusters echo-client -n mesh-lab
istioctl proxy-config endpoints echo-client -n mesh-lab
istioctl proxy-config listeners echo-client -n mesh-lab
kubectl -n mesh-lab logs echo-client -c istio-proxy \
--since=5m --tail=200应用与节点异常、Service selector 错或 EndpointSlice 无地址时,先修基础层;基础层正常,再核对代理同步和配置。
各类代理配置分别回答不同问题:
| 检查对象 | 重点判断 |
|---|---|
| routes | 请求命中了哪个路由,指向哪个上游 cluster |
| clusters | subset、上游协议、连接与 TLS 传输设置 |
| endpoints | 代理实际得到哪些目标地址,是否可用 |
| listeners | 流量捕获、监听与协议识别是否符合预期 |
必要时对接收端 Pod 做相同检查。输出格式随版本变化,要用当前帮助与文档解释。
Envoy 响应标志能给方向:NR 常见于找不到路由,UF 指向上游连接失败,UO 指向上游溢出,UT 指向上游超时;无健康上游还可能看到 UH。
实际可见字段依赖日志配置与版本,具体 response_flags 与 response_code_details 按当前 Envoy 文档解释。
503 不唯一对应 mTLS。看到 UF,也要检查端点、网络与证书;看到 403,要结合授权拒绝原因。
临时止损是停止继续扩流量,把 VirtualService 权重恢复为 v1=100、v2=0,并确认 v1 容量可承接;再按原发布管道修正并验证标签。
保存故障时间、配置差异、代理端点前后输出和版本指标,才有完整复盘。若修正后仍不通,应回到证据分支,而不是继续加重试。
回退和清理也要有边界
正式变更前保存声明式来源与生效配置。GitOps/Helm 通过原管道恢复;手工实验则保留文件版本。
需要把本实验退回全量 v1,可复制 mesh-routing.yaml 为回退文件,将两项 weight 改成 100 和 0,服务端预览、应用、等待同步,再做请求与基线容量核验。
生产灰度的停止条件应在放流量前写清:例如错误率或 P99 越过服务 SLO、v2 资源异常、同节点其他服务恶化。apply 成功只证明配置写入,不证明流量已经按预期恢复。
安全策略的生产回退要恢复此前获准配置,不能靠删掉所有 ALLOW 或解除 STRICT 获得“恢复”。
本实验中的策略都新建在独享空间。若单独研究策略行为,可以在保存配置后删除明确的 echo-allow-client 实验对象;这可能放宽访问,删除后不等于恢复此前获准的安全基线。
实验结束后,先核对 namespace 仍是本次独享对象,再清理:
kubectl get namespace mesh-lab --show-labels
kubectl -n mesh-lab get \
deployment,pod,service,virtualservice,destinationrule,peerauthentication,authorizationpolicy
kubectl delete namespace mesh-lab最后一条会删除该 namespace 内的全部资源。执行前保存需要的实验记录,确认没有混入其他人的工作负载。
删除 namespace 注入标签不会让已有 Pod 热移除 sidecar。生产退出网格通常还涉及滚动重建、路由、身份策略与容量验证。
这份检查清单可以直接带到评审和排障现场:
- 务必确认版本、CRD 与流量模式,sidecar 和 ambient 的能力落点不同。
- 不要把注入成功当作治理完成,捕获范围、同步状态、加密和授权分别核验。
- 务必对齐 Service selector、subset 标签与代理 endpoint,否则就绪 Pod 仍可能接不到指定路由。
- 不要给非幂等请求盲加重试,多层重试会放大故障并制造重复写入。
- 务必分别确认服务 DNS 域与身份信任域,示例值相同不代表实际配置相同。
- 务必核对 ServiceAccount 和已有策略,身份字符串写错可能阻断合法调用。
- 不要只看 HTTP 状态,应用、代理响应标志、端点与传输配置一起判断。
- 务必实测 P99、代理资源与节点争用,固定延迟和服务数量门槛不能替你做容量决策。
- 务必保留版本配置、停止条件与容量退路,流量和安全策略的回退都要验证实际效果。
我建议你先在独享实验空间跑完“两个版本返回不同内容、代理路由可查、允许身份成功、未授权身份被拒绝”这四个验证,再讨论推广。
能把规则与结果对上,Service Mesh 才开始成为可管理的基础设施。
如果这份实操让你更清楚地判断何时需要网格、故障时先查哪一层,可以关注、点赞、点个在看,也转给一起维护服务链路的同事。
公众号:耕云躬行录
个人博客:躬行笔记