Istio 是什么
Istio 是什么
Istio 是 CNCF 毕业的开源服务网格(Service Mesh),主要跑在 Kubernetes 之上,由 Google、IBM、Lyft 联合发起Istio。
简单理解:专门管微服务之间网络通信的基础设施层,业务代码几乎不用改,就可以获得流量治理、安全、可观测能力Istio。
架构两大部分
- 控制平面(istiod):统一下发规则、配置,不处理业务流量。
- 数据平面(Envoy 代理):拦截所有服务之间进出流量,真正执行路由、加密、限流、监控。
- 传统模式:每个业务 Pod 注入 sidecar 代理;
- 新版 Ambient 模式:不再每个 Pod 挂代理,降低资源开销,命名空间打标签即可接入网格Istio。
四大核心能力Istio
- 流量治理(L7 七层)
金丝雀发布、蓝绿发布、A/B 测试、按权重 / 请求头路由、超时、重试、熔断、故障注入、限流。 - 服务安全
服务间自动 mTLS 双向加密、基于服务身份鉴权、访问策略,实现零信任,不用业务改代码做证书。 - 可观测性
自动生成调用指标、访问日志、分布式链路追踪,看服务之间调用情况、延迟、错误率。 - 多环境统一治理
K8s 集群、虚拟机、混合云、多 K8s 集群,统一纳入同一个服务网格管理Istio。
📌 Istio 不是网关,Ingress‑Gateway 只是它其中一个组件;网关主要管外部进集群,Istio 重点管服务和服务之间内部调用。
Istio 用在哪(适用场景)
✅ 适合用 Istio 的场景
- 大规模微服务(几十上百个服务)跑在 K8s
服务数量多,需要统一做灰度发布、熔断限流,不想每个业务自己写 SDK 实现重试熔断。 - 微服务安全要求高
希望所有服务之间通信自动加密,细粒度控制谁能调用谁,实现零信任安全架构。 - 混合架构:K8s + 虚拟机 / 物理机共存
老系统还跑在 VM,新业务上 K8s,把 VM 服务也接入网格,统一治理新旧系统之间的调用。 - 多 K8s 集群、混合云 / 多云环境
多个 K8s 集群,跨集群服务调用统一路由、安全、监控。 - 需要统一可观测
不想每个业务埋点日志、链路,网格自动采集全部服务之间的流量指标、trace。
❌ 不太建议上 Istio 的场景
- 服务很少(几个、十几个以内):Istio 运维复杂度高,杀鸡用牛刀;K8s 原生资源足够搞定。
- 资源紧张的小集群:老 sidecar 模式每个 Pod 多一个代理,会消耗 CPU 内存;可评估 Ambient 模式降低开销。
- 简单单体应用,没有微服务:完全没必要。
- 团队没有熟悉云原生运维人员:Istio 排障、调参门槛高,容易踩坑。
实际业务举例
- 互联网业务:新版本金丝雀灰度,10% 流量切新版本,出错快速回滚;
- 金融企业:服务间通信强制加密,严格控制服务访问权限;
- 中台平台:给各个业务团队提供统一流量治理能力,业务开发不用关心网络问题。
和同类简单对比
- Spring Cloud:应用 SDK 侵入业务代码;Istio 是基础设施层,业务无侵入。
- Nginx / APISIX:侧重南北向流量(外部访问内部);Istio 重点东西向(服务之间互调),当然也可以处理南北向。
如果你需要,我可以用通俗例子讲下 sidecar 原理,或者对比 Spring Cloud 和 Istio 选型。
Sidecar 通俗例子理解 Istio
假设你公司一栋大楼里有很多办公室,每个办公室就是一个微服务 Pod,办公室之间要互相打电话(服务调用)。
没有 Istio 的情况:
每个办公室员工自己管打电话:自己处理超时、报错、加密通话、记通话日志。
- 新版本灰度:需要改每个办公室内部的业务代码(SDK),写逻辑控制多少电话打去新办公室。
- 熔断:某个办公室挂了,其他办公室自己写代码判断要不要不再打过去。
对应 Spring Cloud:业务代码里面引入 SDK,所有流量能力写在业务程序里。
Sidecar 模式(传统 Istio):
每个办公室门口强制安排一个接待员,就是 Envoy sidecar 代理。
✅ 业务办公室里面的人完全不用改,只管干自己业务,所有进出电话全部先过接待员。
接待员 Envoy 能干的事:
- 流量:10% 的电话转给新办公室(金丝雀),超时就重试,对方办公室故障就直接熔断,不把电话打过去;还可以故意模拟对方慢、故意报错做测试(故障注入)。
- 安全:所有办公室之间通话自动加密,规定 A 办公室不能打给 B 办公室。
- 观测:每一通电话记录耗时、是否失败,上报监控链路系统。
而 istiod(控制平面) 就是大楼的总管理处:管理员写规则,总管理处把规则下发给每一个门口接待员,接待员本身不找总管理处,独立处理通话流量。
关键点:控制平面挂掉,已经正在跑的服务调用不受影响,只是不能更新规则。
Ambient 新模式(Istio 新方案,干掉每个 Pod 的 sidecar)
不再每个办公室配接待员。
改成楼层级代理:同一层(namespace 命名空间)共用一组接待员,接管整个楼层所有办公室流量。
好处:减少大量额外 CPU 内存消耗;缺点架构理解稍微复杂一点。
Istio vs Spring Cloud 怎么选
表格
| 维度 | Istio(ServiceMesh) | Spring Cloud |
|---|---|---|
| 侵入性 | 无侵入,业务代码不用改 | 强侵入,业务引入 SDK,Java 技术栈绑定 |
| 运行位置 | K8s 基础设施层,Envoy 代理 | 业务进程内部,和业务跑在一起 |
| 支持服务 | Java、Go、Python,任意语言微服务 | 主要 Java/Spring 体系 |
| 能力范围 | 流量治理、mTLS 安全、观测、多集群、虚拟机接入 | 注册发现、配置、限流熔断、网关 |
| 运维成本 | 高,需要懂 K8s+Istio 运维;配置复杂 | 开发成本高,运维相对简单,堆业务逻辑 |
| 适用规模 | 大量微服务,多语言,混合云,安全要求高 | Java 为主、服务数量中等,团队熟悉 Spring |
现实企业里也可以混用:SpringCloud 做业务开发,部署到 K8s 再套 Istio 做统一流量和安全。
简单决策口诀
- 多语言微服务、上百个服务、混合 VM/K8s、要服务间加密 → 选 Istio
- 全栈 Java、服务不多、不想增加运维负担 → Spring Cloud 足够
- 小项目,几个微服务:两个都别上,直接 K8s Service + Ingress。
常见坑补充(工作中常踩)
- Sidecar 旧模式:小 Pod 多的时候 CPU 内存开销明显,现在优先看 Ambient;
- 版本坑:Istio 版本迭代快,版本不匹配会导致规则不生效;
- 排障难:流量经过 Envoy,出问题要看代理日志,不只看业务日志;
- 不要拿 Istio 替代业务网关:Ingress‑Gateway 负责外部进来,istio 核心解决**东西向(服务之间)。
如果你想,我可以给你讲一个极简实操流程:Istio 最经典的金丝雀发布完整流程,讲清楚 VirtualService、DestinationRule 这两个核心 CRD 干什么。
Istio 金丝雀(灰度发布)完整流程
核心两个 CRD:
- VirtualService:流量路由规则(决定流量往哪走)
- DestinationRule:定义服务子集(版本标签,比如 v1、v2)
业务场景:
- 服务叫
reviews - v1:老版本,稳定版本
- v2:新版本,要灰度,只放 10% 流量 到 v2,90% 留在 v1
- Pod 上打标签
version: v1/version: v2
前提:已经装好 Istio,Pod 已经注入 sidecar。
1. 先部署两套业务版本
deployment 要带上标签 version
# reviews-v1
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
spec:
replicas: 2
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1 # 关键标签
spec:
containers:
- name: reviews
image: xxx/reviews:v1
---
# reviews-v2
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
spec:
replicas: 2
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
containers:
- name: reviews
image: xxx/reviews:v2
---
# 统一service,selector只匹配 app:reviews,不区分version
apiVersion: v1
kind: Service
metadata:
name: reviews
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: reviews
Kubernetes 原生 Service 不知道 v1/v2,默认会随机把流量打给所有 Pod;Istio 通过 CRD 接管拆分流量。
2. DestinationRule:定义版本子集
告诉 Istio:reviews 服务内部有两个子集 v1、v2,用 label version 区分。
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: reviews-dr
spec:
host: reviews # 对应k8s service名字
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
apply:kubectl apply -f dr.yaml
⚠️注意:VirtualService 引用的 subsets 必须在 DestinationRule 里预先定义,否则路由不生效!很多人踩这个坑。
3. VirtualService 设置权重,10% 流量切 v2
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews-vs
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90
- destination:
host: reviews
subset: v2
weight: 10
apply:kubectl apply -f vs.yaml
现在效果
访问 reviews 服务,90% 请求到 v1 老版本,10% 到 v2 新版本,业务代码一行不改。
4. 几种常见路由变体
4‑1 完全切流(全量上线 v2)
修改 VirtualService weight:v1=0,v2=100
- destination:
host: reviews
subset: v1
weight: 0
- destination:
host: reviews
subset: v2
weight: 100
4‑2 基于请求头灰度(特定用户全部走 v2,其余走 v1)
比如 header x-canary: true 的请求全部进 v2,普通用户全部 v1:
spec:
hosts:
- reviews
http:
- match:
- headers:
x-canary:
exact: "true"
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
4‑3 故障注入,测试新版本容错(混沌测试)
给 v2 版本故意返回 50% 概率 503 错误,验证上游服务的重试 / 熔断逻辑:
spec:
hosts:
- reviews
http:
- fault:
abort:
percentage:
value: 50
httpStatus: 503
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
5. 观察验证流量
持续调用服务,看流量分配:
# 循环访问
while true; do curl http://reviews; echo; sleep 0.2; done
也可以看 kiali 面板,直接可视化流量占比。
6. 回滚操作
方案 A:直接修改 VirtualService,把 v2 weight=0,流量立刻全部切回 v1。
方案 B:删除 VirtualService,Istio 就退回到 K8s 原生 service 轮询。
关键概念小结(面试常问)
- VirtualService:管「怎么路由」,匹配请求,分配流量到子集。
- DestinationRule:管「后端怎么分组、连接池、熔断、负载均衡」,定义 subsets 版本集合。
记忆口诀:VS 管去哪,DR 管后端长啥样。
高频踩坑点
- subsets 名字写错、DR 没 apply,VS 配置看着没问题,流量完全不生效。
- host 要写 service 短域名,命名空间跨 ns 时要写完整
reviews.ns.svc.cluster.local。 - pod 没有 istio sidecar,流量完全不走 istio 规则。
- Ambient 模式下,需要 namespace 打标签开启网格,否则 CRD 不生效。
浙公网安备 33010602011771号