【K8S 运维实战】33-ServiceMeshIstio

📅 2026/8/4 2:49:05
【K8S 运维实战】33-ServiceMeshIstio
Service Mesh:Istio 流量治理与可观测 业务代码不改一行,灰度、熔断、mTLS 全靠 Sidecar 来做写在前面你可能听过 Service Mesh 的宣传:“不改业务代码就能实现灰度发布、流量熔断、加密通信”。听起来很美好,但现实是:注入 Sidecar 后 Pod 启动变慢了,服务间调用延迟多了 2ms,Envoy 的 CPU 吃了你 5% 的节点资源,排查问题时 iptables 规则让你抓包都看不懂了。这篇文章不是 Istio 的入门教程,而是一个 8 年运维老兵踩过的坑和沉淀的方法论:流量治理怎么配置才不会踩坑,mTLS 怎么从 permissive 到 strict 安全过渡,Sidecar 的性能开销到底多大,以及 Ambient Mesh(无 Sidecar 模式)什么时候值得试。读完这篇,你就能回答那个关键问题:业务侵入式治理太痛,Sidecar 能解决吗——能,但有代价。核心问题业务侵入式治理太痛,Sidecar 能解决吗?能,但要理解代价,掌握治理边界。一、原理剖析1.1 Istio 架构:istiod 一体化控制面Istio 从 1.5 开始把 Pilot、Citadel、Galley 合并成一个组件istiod,架构简洁了很多:Istio 架构(K8s 1.30 / Istio 1.22) ┌──────────────────────────┐ │ istiod │ │ ┌─────────┬───────────┐ │ │ │ Pilot │ Citadel │ │ │ │(流量配置│(证书管理) │ │ │ │ 分发) │ │ │ │ ├─────────┴───────────┤ │ │ │ Config Validator │ │ │ └─────────────────────┘ │ └──────────┬───────────────┘ │ xDS API(gRPC) │ │ ┌────────────────┼────────────────┐ │ │ │ ┌─────────▼───┐ ┌─────────▼───┐ ┌─────────▼───┐ │ Envoy │ │ Envoy │ │ Envoy │ │ (Sidecar) │ │ (Sidecar) │ │ (Sidecar) │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │Inbound │ │ │ │Inbound │ │ │ │Inbound │ │ │ │Listener │ │ │ │Listener │ │ │ │Listener │ │ │ ├─────────┤ │ │ ├─────────┤ │ │ ├─────────┤ │ │ │Outbound │ │ │ │Outbound │ │ │ │Outbound │ │ │ │Listener │ │ │ │Listener │ │ │ │Listener │ │ │ └─────────┘ │ │ └─────────┘ │ │ └─────────┘ │ │ Pod: myapp │ │ │ Pod: redis │ │ │ Pod: api │ │ └─────────────┘ └─────────────┘ └─────────────┘ 流量劫持路径: Pod 出站 → iptables 重定向到 Envoy Outbound(15001) → Envoy 路由(根据 VirtualService/DestinationRule) → Envoy 转发到目标 Pod → 目标 Pod iptables 重定向到 Envoy Inbound(15006) → Envoy 转发给业务容器关键流程:Sidecar 自动注入: Namespace 打上istio-injectionenabled标签后,Pod 创建时 MutatingWebhook 自动注入 Envoy Sidecar 容器 istio-init iptables 初始化容器流量劫持: Pod 所有进出流量被 iptables REDIRECT 到 Envoy,Envoy 根据 xDS 配置做路由/负载均衡/安全/可观测istiod 推送配置: istiod watch K8s API(VirtualService/DestinationRule 等),转换成 Envoy xDS 配置,通过 gRPC 推送到所有 Envoy1.2 流量治理:VirtualService 与 DestinationRuleIstio 流量治理的核心是两个 CRD 的配合:VirtualService: 路由规则(怎么走) - 路由匹配(host/path/header/query) - 流量分割(weight A/B) - 重试(retries) - 超时(timeout) - 故障注入(fault injection) - 流量镜像(mirror) - 请求头操作(headers add/remove/set) DestinationRule: 目标策略(走到目标后怎么处理) - 负载均衡(roundRobin/random/leastConn) - 连接池(connectionPool tcp/http) - 异常检测(outlierDetection) - TLS 设置 - 子集定义(subset: v1/v2/canary) 配合逻辑: VirtualService.route.destination → 指向 DestinationRule 的 subset DestinationRule 定义 subset 的流量策略灰度发布配置链路:客户端 → VirtualService(按 weight 分割流量) ├─ 90% → DestinationRule subset: stable(v1) └─ 10% → DestinationRule subset: canary(v2) DestinationRule 定义两个 subset: - stable: labels: versionv1, 连接池异常检测 - canary: labels: versionv2, 不同的连接池策略熔断机制(outlierDetection):熔断触发条件: 连续 e 次错误(5xx) → 该实例从负载均衡池中剔除 剔除时间 baseEjectionTime × min(ejections, maxEjections) 最大剔除比例 maxEjectionPercent(默认 10%) 例如: outlierDetection: consecutive5xxErrors: 3 # 连续 3 次 5xx interval: 30s # 每 30s 检查一次 baseEjectionTime: 60s # 基础剔除 60s maxEjectionPercent: 50 # 最多剔除 50% 实例1.3 mTLS 与零信任Istio 的 mTLS 机制基于 istiod(Citadel)自动签发证书,Envoy 自动完成 TLS 握手:mTLS 流程: 1. istiod 为每个 ServiceAccount 签发 SPIFFE 证书(SVID) 证书格式: spiffe://cluster.local/ns/ns/sa/sa 证书有效期: 24h(默认),自动轮转 2. 客户端 Envoy 发起连接 → 服务端 Envoy 回传证书 双方验证对方的 SPIFFE ID 是否匹配目标 ServiceAccount 3. mTLS 模式: - DISABLED: 不加密 - PERMISSIVE: 同时接受 plaintext 和 mTLS(过渡期) - STRICT: 只接受 mTLS(零信任目标) 生产落地路径: PERMISSIVE(所有服务) → 逐个切 STRICT → 全部 STRICT1.4 Ambient Mesh:无 Sidecar 的新模式Istio 1.22 引入 Ambient Mesh(之前叫 Istio Mesh Expansion),核心变化:不再给每个 Pod 注入 Sidecar,改用节点级 ztunnel waypoint 代理:Sidecar 模式 vs Ambient 模式对比: Sidecar 模式(当前): Pod → Envoy Sidecar(每个 Pod 一个) 延迟: 1-2ms(出入各一次 Envoy) CPU: 每个 Pod 50-100m 内存: 每个 Pod 50-100Mi Ambient 模式(新): Node → ztunnel(节点级 L4 代理,每个 Node 一个 DaemonSet) Service → waypoint(按 Service 部署的 L7 代理) 延迟: L4 只有 0.5ms(ztunnel);L7 多一层 waypoint CPU: 每个节点 200m(共享) 内存: 每个节点 200Mi(共享) 优势: 不侵入 Pod,不影响 Pod 启动速度 限制: L7 策略(灰度/重试/熔断) 需要 waypoint,不是所有流量都有 ┌──────────────────────────────────────┐ │ Node │ │ │ │ ┌──────────┐ ┌──────────┐ │ │ │ Pod A │ │ Pod B │ │ │ │(无Sidecar│ │(无Sidecar│ │ │ └──────────┘ └──────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ ztunnel (DaemonSet) │ │ │ │ L4: mTLS L4 路由 │ │ │ └──────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ waypoint (per-Service) │ │ │ │ L7: 灰度/重试/熔断 │ │ │ └──────────────────────────┘ │ └──────────────────────────────────────┘二、实战操作2.1 Istio Helm 生产部署# 添加 Helm 仓库helm repoaddistio https://istio-release.storage.googleapis.com/charts helm repo update# 创建 namespacekubectl create namespace istio-system# 安装 istiod(控制面)helminstallistiod istio/istiod\-nistio-system\--setglobal.hubgcr.io/istio-release\--setglobal.tag1.22.0\--setpilot.replicaCount3\--setpilot.resources.requests.cpu500m\--setpilot.resources.requests.memory1Gi\--setpilot.resources.limits.cpu1\--setpilot.resources.limits.memory2Gi\--setpilot.autoscaleMin3\--setpilot.autoscaleMax5\--setmeshConfig.defaultConfig.holdApplicationUntilProxyStartstrue\--setmeshConfig.defaultConfig.proxyMetadata.PROXY_CONFIG_XDS_AGENTv3\--setglobal.proxy.resources.requests.cpu100m\--setglobal.proxy.resources.requests.memory128Mi\--setglobal.proxy.resources.limits.cpu500m\--setglobal.proxy.resources.limits.memory512Mi\--setsidecarInjectorWebhook.enableDefaulttrue\--setsidecarInjectorWebhook.injectLabelistio-injection\--wait# 安装 istio-gateway(入口网关,替代 nginx-ingress)helminstallistio-ingress istio/gateway\-nistio-system\--setgateway.ports[0].namestatus\--setgateway.ports[0].port15021\--setgateway.ports[0].targetPort15021\--setgateway.ports[1].namehttp2\--setgateway.ports[1].port80\--setgateway.ports[1].targetPort80\--setgateway.ports[2].namehttps\--setgateway.ports[2].port443\--setgateway.ports[2].targetPort443\--setgateway.replicaCount3\--setgateway.resources.requests.cpu200m\--setgateway.resources.requests.memory256Mi\--setgateway.resources.limits.cpu1\--setgateway.resources.limits.memory1Gi\--wait# 启用 Sidecar 自动注入(对目标 namespace)kubectl label namespace myapp istio-injectionenabled# 验证kubectl get pods-nistio-system istioctl analyze-nmyapp关键参数说明:holdApplicationUntilProxyStartstrue:必须开启。Pod 启动时先等 Envoy 就绪再启动业务容器,避免冷启动流量丢失。pilot.replicaCount3: 生产必须 3 个以上 Pilot 实例,保证配置推送不中断。proxy.resources: Sidecar 的资源限制,生产建议 500m CPU / 512Mi 内存。2.2 流量治理 YAML 示例集灰度发布(VirtualService DestinationRule):apiVersion:networking.istio.io/v1beta1kind:DestinationRulemetadata:name:myapp-drnamespace:myappspec:host:myapptrafficPolicy:connectionPool:tcp:maxConnections:100http:h2UpgradePolicy:DEFAULTmaxRequestsPerConnection:10outlierDetection:consecutive5xxErrors:3interval:30sbaseEjectionTime:60smaxEjectionPercent:50subsets:-name:stablelabels:version:v1trafficPolicy:connectionPool:http:maxPendingRequests:50-name:canarylabels:version:v2trafficPolicy:connectionPool:http:maxPendingRequests:20# 金丝雀连接池更保守apiVersion:networking.istio.io/v1beta1kind:VirtualServicemetadata:name:myapp-vsvcnamespace:myappspec:hosts:-myapphttp:-route:-destination:host:myappsubset:stableweight:90-destination:host:myappsubset:canaryweight:10重试与超时:apiVersion:networking.istio.io/v1beta1kind:VirtualServicemetadata:name:myapp-retrynamespace:myappspec:hosts:-myapphttp:-route:-destination:host:myappsubset:stableretries:attempts:3perTryTimeout:2sretryOn:5xx,connect-failure,refused-streamtimeout:10s故障注入(测试用):apiVersion:networking.istio.io/v1beta1kind:VirtualServicemetadata:name:myapp-fault-testnamespace:myappspec:hosts:-myapphttp:-fault:abort:percentage:value:10# 10% 的请求返回 500httpStatus:500delay:percentage:value:5# 5% 的请求延迟 3sfixedDelay:3sroute:-destination:host:myapp流量镜像(把请求镜像到新版本不影响主流量):apiVersion:networking.istio.io/v1beta1kind:VirtualServicemetadata:name:myapp-mirrornamespace:myappspec:hosts:-myapphttp:-route:-destination:host:myappsubset:stableweight:100mirror:host:myappsubset:canary# 所有请求同时发到 canary,但不等 canary 响应mirrorPercentage:value:100# 镜像 100% 流量2.3 mTLS 零信任配置PeerAuthentication — 逐步从 PERMISSIVE 到 STRICT:# 第一步:全集群设为 PERMISSIVE(兼容期,不阻断 plaintext)apiVersion:security.istio.io/v1beta1kind:PeerAuthenticationmetadata:name:defaultnamespace:istio-systemspec:mtls:mode:PERMISSIVE# 第二步:对已确认支持 mTLS 的服务单独切 STRICTapiVersion:security.istio.io/v1beta1kind:PeerAuthenticationmetadata:name:myapp-strictnamespace:myappspec:selector:matchLabels:app:myappmtls:mode:STRICTportLevelMtls:8080:mode:STRICT# 业务端口 STRICT9090:mode:PERMISSIVE# metrics 端口允许 plaintext(Prometheus 不在 Mesh 内)# 第三步:全部切 STRICT(零信任目标)apiVersion:security.istio.io/v1beta1kind:PeerAuthenticationmetadata:name:defaultnamespace:istio-systemspec:mtls:mode:STRICT验证 mTLS 状态:# 查看 mTLS 配置istioctl analyze-A--all-namespaces# 查看某个服务的 TLS 统计kubectlexec-nmyapp deploy/myapp-cistio-proxy --\pilot-agent request GET stats|greptls# 用 Kiali 可视化查看 mTLS 状态# Kiali → Traffic → 看每个服务的 mTLS 图标2.4 可观测增强Prometheus Grafana Kiali 集成:Istio 自带 Prometheus 配置,生产建议用独立 Prometheus 但保留 Istio 指标采集:# Prometheus Istio 指标采集 Job(追加到现有 Prometheus 配置)-job_name:istio-meshkubernetes_sd_configs:-role:endpointsrelabel_configs:-source_labels:[__meta_kubernetes_service_name]regex:istio-telemetryaction:keepscheme:http-job_name:envoy-statsmetrics_path:/stats/prometheuskubernetes_sd_configs:-role:endpointsrelabel_configs:-source_labels:[__meta_kubernetes_namespace,__meta_kubernetes_service_name]regex:myapp;myappaction:keep-source_labels:[__meta_kubernetes_pod_label_istio]regex:.*action:keep安装 Kiali(可视化 Service Mesh):helm repoaddkiali https://kiali.org/helm-charts helminstallkiali kiali/kiali-server\-nistio-system\--setcr.createtrue\--setcr.spec.external_services.prometheus.urlhttp://prometheus.monitoring:9090\--setcr.spec.external_services.grafana.urlhttp://grafana.monitoring:3000\--setcr.spec.authentication.strategyopenid\--waitKiali 核心功能:Traffic Graph: 实时可视化服务间调用关系和流量mTLS 状态: 一眼看到哪些服务 mTLS 启用/未启用VirtualService/DestinationRule 可视化: 查看灰度规则/熔断配置的实际效果工作负载健康: 基于 Envoy metrics 判断服务健康度2.5 Sidecar 性能影响评估指标无 Sidecar有 Sidecar增量备注Pod 启动时间2-3s5-8s3-5sEnvoy 初始化iptables 规则设置请求延迟(P99)10ms12-14ms2-4ms出入各一次 Envoy,L4 1ms,L7 2msCPU(每个 Pod)业务容器自身50-100m50-100m高流量场景更多内存(每个 Pod)业务容器自身50-100Mi50-100Mi配置越多内存越大节点总 CPU 开销N × 业务N × (业务100m)每个Pod100m100 Pod 的节点 10CPU连接追踪无conntrack 表增大可能耗尽高并发需要调 sysctl生产建议: 对于延迟敏感的服务(如实时交易),2ms 可能不可接受。评估方法:# 方法 1:Fortio 延迟测试kubectl run fortio--imagefortio/fortio--restartNever-nmyapp kubectlexecfortio-nmyapp -- fortio load-qps1000-t30s-c8http://myapp:8080# 方法 2:对比有/无 Sidecar 的延迟# 临时给某个 namespace 关闭注入kubectl label namespace myapp-test istio-injectiondisabled--overwrite# 在 myapp-test 里跑同一个服务,对比延迟# 方法 3:用 istioctl proxy-status 查看 Envoy 配置同步延迟istioctl proxy-status# CONFIG STALE 表示 Envoy 配置落后,可能导致路由不一致三、踩坑与排查踩坑 1:Pod 启动后短暂流量丢失——Envoy 还没就绪,业务容器已经发请求现象: Pod 刚创建,前几秒的出站请求失败(connection refused/timeout),几秒后恢复。原因: 默认情况下,K8s 不保证 Envoy Sidecar 先于业务容器就绪。iptables 规则生效(流量被劫持)但 Envoy 还没启动完成,所有出站请求被 redirect 到一个还没 listen 的端口——直接失败。解决:# 方法 1(推荐):开启 holdApplicationUntilProxyStarts# Istio Helm 安装时:--set meshConfig.defaultConfig.holdApplicationUntilProxyStartstrue# 这会让 K8s 在 Pod 启动时先等 istio-proxy 容器就绪(readinessProbe 通过)# 再启动业务容器,保证 Envoy 就绪后才发出流量# 方法 2:业务容器加 preStop hook 延迟关闭# 防止 Envoy 先关闭导致关闭期间的流量丢失:# Deployment 中业务容器配置lifecycle:preStop:exec:command:[sh,-c,sleep 15]# 给 Envoy 时间排空连接terminationGracePeriodSeconds:30# 至少 15Envoy 排空时间蹈坑 2:VirtualService 灰度不生效——流量全走 v1现象: 配了 VirtualService 90% stable 10% canary,但所有流量还是走 v1,canary Pod 没有收到请求。原因排查步骤:# 1. 检查 VirtualService 是否被 Envoy 接收istioctl proxy-config routes deploy/myapp-v1-nmyapp--name-ojson# 如果看不到 canary route → istiod 推送有问题# 2. 检查 DestinationRule 的 subset label 是否和 Pod label 匹配kubectl get pods-nmyapp-Lversion# DestinationRule subset canary: labels: versionv2# Pod 必须有 label: versionv2 (不是 appv2!)# 3. 检查 host 是否匹配# VirtualService hosts: [myapp]# 调用方用的 Service 名称必须完全匹配(包括跨 namespace 的 FQDN)# 如果调用方在 ns-b,目标是 myapp.myapp.svc.cluster.local# VirtualService hosts 必须包含: myapp.myapp.svc.cluster.local最常见的原因: Pod 上没有versionlabel。Istio 的 DestinationRule subset 匹配的是 Pod 的 label,不是 Deployment 的 label。Deployment 的 label 只影响 selector,Pod 的 label 由spec.template.metadata.labels决定:# Deployment 必须在 template.metadata.labels 上加 versionspec:template:metadata:labels:app:myappversion:v2# 这个!不是 spec.selector.matchLabels 里的!踩坑 3:mTLS STRICT 切换后外部服务调用失败现象: 给 namespace 切了PeerAuthentication STRICT,集群内服务没问题,但调用外部 API(如api.github.com)全部返回 503。原因: STRICT 模式要求所有出站流量也走 mTLS,但外部服务不支持 mTLS。Envoy 尝试 TLS 握手失败。解决: 创建 ServiceEntry DestinationRule,告诉 Istio 这个外部服务不用 mTLS:apiVersion:networking.istio.io/v1beta1kind:ServiceEntrymetadata:name:github-apinamespace:myappspec:hosts:-api.github.comlocation:MESH_EXTERNALports:-number:443name:httpsprotocol:TLSresolution:DNSapiVersion:networking.istio.io/v1beta1kind:DestinationRulemetadata:name:github-api-tlsnamespace:myappspec:host:api.github.comtrafficPolicy:tls:mode:SIMPLE# 简单 TLS(不是 mTLS),Envoy 作为客户端发起 TLSsni:api.github.com踩坑 4:iptables conntrack 表耗尽导致高并发丢连接现象: 高并发场景(5000 QPS)下,间歇性连接失败,Pod 日志没有错误,但 Envoy 日志大量connection reset。原因: Istio 的 iptables 规则使用 conntrack 模块跟踪连接。当并发连接数超过nf_conntrack_max系统参数时,新连接被丢弃。# 查看当前 conntrack 状态sysctlnet.netfilter.nf_conntrack_maxsysctlnet.netfilter.nf_conntrack_count# 如果 count 接近 max,就是这个问题解决:# 方法 1:增大 conntrack 表(节点级)sysctl-wnet.netfilter.nf_conntrack_max262144# 从默认 65536 翻 4 倍sysctl-wnet.netfilter.nf_conntrack_tcp_timeout_established54000# 缩短 TCP established 超时# 持久化(写入 /etc/sysctl.d/99-istio.conf)echonet.netfilter.nf_conntrack_max262144/etc/sysctl.d/99-istio.confechonet.netfilter.nf_conntrack_tcp_timeout_established54000/etc/sysctl.d/99-istio.confsysctl--system# 方法 2:对不需要 Mesh 的流量绕过 iptables# 在 Pod annotation 中排除某些端口:annotations:traffic.sidecar.istio.io/excludeOutboundPorts:9090,3306# 排除 metrics 和数据库端口traffic.sidecar.istio.io/excludeInboundPorts:9090# 排除 metrics 入站四、最佳实践Istio 生产落地清单阶段检查项通过标准规划确认 Mesh 边界哪些 namespace/服务进入 Mesh,哪些不进入规划性能预算评估2ms 延迟是否可接受;每个节点额外 CPU/内存预算规划外部服务清单列出所有调用外部 API/数据库,提前建 ServiceEntry安装holdApplicationUntilProxyStartstrue防止 Pod 启动流量丢失安装pilot replicaCount3HA 配置推送安装ingress gateway replicaCount3入口网关 HA安装资源限制配置proxy 500m/512Mi, pilot 1CPU/2Gi注入逐 namespace 开启注入不要全集群一次性开启,逐步推进注入Pod 必须有 version labelDestinationRule subset 匹配 Pod label注入preStop sleep 15s terminationGracePeriodSeconds 30s防止关闭期间流量丢失流量VirtualService DestinationRule 配对路由规则和目标策略分开管理流量先 mirror 后 canary灰度先用流量镜像验证,再切 weight流量故障注入只在 test namespace生产环境绝不注入故障安全mTLS 先 PERMISSIVE 再 STRICT逐步切换,不要一步到位安全外部服务建 ServiceEntrySTRICT 下外部调用必须声明安全conntrack 参数调优高并发节点必须增大 nf_conntrack_max可观测Kiali Prometheus Grafana三件套缺一不可可观测istioctl proxy-status 定期检查STALE 配置意味着风险排查Fortio 延迟基准测试注入前后对比排查Envoy 日志级别调整默认 INFO,排查时切 DEBUG(临时)Sidecar 排查命令速查# 查看 Envoy 配置同步状态istioctl proxy-status# 查看 Envoy 路由配置istioctl proxy-config routespod-name-nns# 查看 Envoy 集群配置istioctl proxy-config clusterspod-name-nns# 查看 Envoy 监听器istioctl proxy-config listenerspod-name-nns# 查看 Envoy 统计指标istioctl proxy-config endpointspod-name-nns# 调整 Envoy 日志级别(临时排查)kubectlexecpod-name-nns-cistio-proxy --\pilot-agent request POST log?leveldebug# 查看 iptables 规则(确认流量劫持)kubectlexecpod-name-nns-cistio-proxy --\iptables-tnat-L-n-v# 分析所有 Istio 配置istioctl analyze-A--all-namespaces五、小结Service Mesh 的本质是:把流量治理、安全加密、可观测这些横切关注点从业务代码里抽出来,交给 Sidecar(或节点级代理)。Istio 的 VirtualServiceDestinationRule 组合可以实现灰度、重试、熔断、故障注入、流量镜像,不改一行业务代码;mTLS 可以从 PERMISSIVE 渐进到 STRICT 实现零信任;Kiali 可视化让 Mesh 状态一目了然。但 Sidecar 有代价:2ms 延迟、50-100m CPU/Pod、conntrack 表耗尽风险、Pod 启动变慢。Ambient Mesh 的 ztunnelwaypoint 模式是未来方向,但目前还不成熟,生产落地建议先在 Sidecar 模式上积累经验。落地顺序:先规划边界→逐 namespace 注入→先 mirror 验证→mTLS PERMISSIVE→再逐步 STRICT→最后才考虑灰度/熔断等 L7 策略。思考题你的服务有 P99 延迟 5ms 的严格要求,2ms 的 Sidecar 延迟不可接受。你会选择:放弃 Mesh,还是用 Ambient Mesh 的 L4 模式只做 mTLS?一个 namespace 里有 50 个微服务,你想全开 Sidecar 注入,但担心 conntrack 表耗尽。你会怎么逐步推进?mTLS STRICT 模式下,同一个 Pod 的业务容器访问自己的 metrics 端口(localhost:9090)会被 Envoy 劫持吗?怎么排除?延伸阅读Istio 官方文档Istio Performance BenchmarkAmbient Mesh 简介Kiali 官方文档Envoy xDS 协议SPIFFE/SPIRE 身份框架