Istio 是什么

Istio 是什么

Istio 是 CNCF 毕业的开源服务网格(Service Mesh),主要跑在 Kubernetes 之上,由 Google、IBM、Lyft 联合发起Istio。

简单理解:专门管微服务之间网络通信的基础设施层,业务代码几乎不用改,就可以获得流量治理、安全、可观测能力Istio。

架构两大部分

  1. 控制平面(istiod):统一下发规则、配置,不处理业务流量。
  2. 数据平面(Envoy 代理):拦截所有服务之间进出流量,真正执行路由、加密、限流、监控。
    • 传统模式:每个业务 Pod 注入 sidecar 代理;
    • 新版 Ambient 模式:不再每个 Pod 挂代理,降低资源开销,命名空间打标签即可接入网格Istio。

四大核心能力Istio

  1. 流量治理(L7 七层)
    金丝雀发布、蓝绿发布、A/B 测试、按权重 / 请求头路由、超时、重试、熔断、故障注入、限流。
  2. 服务安全
    服务间自动 mTLS 双向加密、基于服务身份鉴权、访问策略,实现零信任,不用业务改代码做证书。
  3. 可观测性
    自动生成调用指标、访问日志、分布式链路追踪,看服务之间调用情况、延迟、错误率。
  4. 多环境统一治理
    K8s 集群、虚拟机、混合云、多 K8s 集群,统一纳入同一个服务网格管理Istio。

📌 Istio 不是网关,Ingress‑Gateway 只是它其中一个组件;网关主要管外部进集群,Istio 重点管服务和服务之间内部调用。


Istio 用在哪(适用场景)

✅ 适合用 Istio 的场景

  1. 大规模微服务(几十上百个服务)跑在 K8s
    服务数量多,需要统一做灰度发布、熔断限流,不想每个业务自己写 SDK 实现重试熔断。
  2. 微服务安全要求高
    希望所有服务之间通信自动加密,细粒度控制谁能调用谁,实现零信任安全架构。
  3. 混合架构:K8s + 虚拟机 / 物理机共存
    老系统还跑在 VM,新业务上 K8s,把 VM 服务也接入网格,统一治理新旧系统之间的调用。
  4. 多 K8s 集群、混合云 / 多云环境
    多个 K8s 集群,跨集群服务调用统一路由、安全、监控。
  5. 需要统一可观测
    不想每个业务埋点日志、链路,网格自动采集全部服务之间的流量指标、trace。

❌ 不太建议上 Istio 的场景

  1. 服务很少(几个、十几个以内):Istio 运维复杂度高,杀鸡用牛刀;K8s 原生资源足够搞定。
  2. 资源紧张的小集群:老 sidecar 模式每个 Pod 多一个代理,会消耗 CPU 内存;可评估 Ambient 模式降低开销。
  3. 简单单体应用,没有微服务:完全没必要。
  4. 团队没有熟悉云原生运维人员: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 能干的事:

  1. 流量:10% 的电话转给新办公室(金丝雀),超时就重试,对方办公室故障就直接熔断,不把电话打过去;还可以故意模拟对方慢、故意报错做测试(故障注入)。
  2. 安全:所有办公室之间通话自动加密,规定 A 办公室不能打给 B 办公室。
  3. 观测:每一通电话记录耗时、是否失败,上报监控链路系统。

而 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 做统一流量和安全。

简单决策口诀

  1. 多语言微服务、上百个服务、混合 VM/K8s、要服务间加密 → 选 Istio
  2. 全栈 Java、服务不多、不想增加运维负担 → Spring Cloud 足够
  3. 小项目,几个微服务:两个都别上,直接 K8s Service + Ingress。

常见坑补充(工作中常踩)

  1. Sidecar 旧模式:小 Pod 多的时候 CPU 内存开销明显,现在优先看 Ambient;
  2. 版本坑:Istio 版本迭代快,版本不匹配会导致规则不生效;
  3. 排障难:流量经过 Envoy,出问题要看代理日志,不只看业务日志;
  4. 不要拿 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 轮询。


关键概念小结(面试常问)

  1. VirtualService:管「怎么路由」,匹配请求,分配流量到子集。
  2. DestinationRule:管「后端怎么分组、连接池、熔断、负载均衡」,定义 subsets 版本集合。

记忆口诀:VS 管去哪,DR 管后端长啥样。

高频踩坑点

  1. subsets 名字写错、DR 没 apply,VS 配置看着没问题,流量完全不生效。
  2. host 要写 service 短域名,命名空间跨 ns 时要写完整 reviews.ns.svc.cluster.local。
  3. pod 没有 istio sidecar,流量完全不走 istio 规则。
  4. Ambient 模式下,需要 namespace 打标签开启网格,否则 CRD 不生效。
posted @ 2026-09-20 23:50  JacobJacob  阅读(29)  评论(0)    收藏  举报