1、Sidecar 模式(传统模式)
- istio有两种模式Sidecar模式和Ambient模式
架构
- 分为数据平面和控制平面,数据平面决定谁来执行路由,控制平面决定流量怎么走,即指定路由规则
![image]()
数据平面
- 数据平面的组件就一个,每个容器都有一个istio代理,称为Envoy。
- 数据平面架构
Pod
├── 应用容器
└── istio-proxy (Envoy)
- 所有流量都必须经过 Sidecar。数据流向:应用 → 本地 Envoy → 网络 → 对方 Envoy → 对方应用
- 注意:严格来说Envoy和SideCar不是一个东西,但通常在istio语境下不做区分。Envoy 是一个高性能 L4/L7 代理服务器,Sidecar 是一种架构模式,Istio的Sidecar容器里运行的程序是Envoy
控制平面
- 组件Istiod,从istio1.5版本起Istiod集成了 Pilot、Citadel、Galley的功能,提供服务发现、配置和证书管理
- Pilot(/ˈpaɪlət/飞行员),负责下发流量规则
- Citadel(/ˈsɪtədəl/城堡),提供 mTLS 证书管理
- Galley(/ˈɡæli/厨房),配置验证
优缺点
- 优点:能实现流量的精细控制,支持基于header的路由,故障注入、超时、重试、流量镜像、mTLS
- 缺点:每个Pod中会多一个容器,占用CPU和内存,启动慢,运维复杂,Sidecar注入管理麻烦
3、istio的流量管理API
3.1、虚拟服务(VirtualService)
- 用于定义流量路由规则,控制请求如何被路由到特定的服务或版本,还可以做流量拆分(例如:20/80)、超时、重试、故障注入,作用对象是envoy
作用
- 动态路由:将请求按条件(如路径、Header、用户等)路由到不同服务或版本。
- 灰度发布:先让部分用户访问新版本,其他用户继续使用旧版本。安全地逐步上线新版本,降低发布风险。
- A/B 测试:基于用户画像(如年龄、性别、行为特征)设备等做流量的分流。对比不同版本的效果。
- 负载均衡:控制请求在不同服务实例间的分配比例(使用weight字段)。
示例
- 这段Istio VirtualService配置的目的是根据 HTTP 请求头中的用户标识,将流量路由到服务的不同版本
- 当用户访问名为reviews的service时,会根据请求头将请求分发到reviews背后的不同版本的Pod中(pod有标签version=v2或version=v3)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews # 规则应用的目标服务(K8s Service 名称)
http:
- match: # 第一个路由规则:匹配条件
- headers:
end-user:
exact: jason # 仅当请求头 end-user 的值为 "jason" 时生效
route:
- destination:
host: reviews
subset: v2 # 满足条件时,路由到 v2 版本
- route: # 第二个路由规则:默认路由(无匹配条件)
- destination:
host: reviews
subset: v3 # 其他所有请求路由到 v3 版本
hosts字段
- spec.hosts字段定义该 VirtualService 规则生效的域名或服务名称列表。还可以指定如下格式
hosts:
# 域名(FQDN)
- "example.com" # 精确匹配
- "*.foo.com" # 匹配所有 foo.com 的子域名
# Kubernetes 服务名称
- "reviews.default.svc.cluster.local" # 标准全限定名<service-name>.<namespace>.svc.cluster.local
- "product.prod.svc" # 短格式(自动补全)<service-name>.<namespace>
# IP 地址
- 192.168.1.12
路由规则
- http.match字段指定路由匹配条件,可以有多个匹配规则(如 URI、Method 等)
- 路由规则按从上到下的顺序选择,虚拟服务中定义的第一条规则有最高优先级
# 匹配请求头
http:
- match:
- headers: # 指定匹配请求头的条件
end-user: # 要匹配的 请求头名称(这里是自定义头 end-user)
exact: jason # end-user 头的值必须完全等于 jason
route:
- destnation:
host: reviews
subset: v2
# 匹配请求路径前缀
http:
- match:
- uri:
prefix: /reviews # 要求请求路径 以 /reviews 开头(前缀匹配)
route:
- destnation:
host: reviews
subset: v3
- 使用”权重“分发请求。这在 A/B 测试和金丝雀发布中非常有用
- 下面这个例子如果不指定权重,v1和v2各得到50%的流量
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 75
- destination:
host: reviews
subset: v2
weight: 25
3.2、目标规则(Destination Rule)
- 用于定义流量路由到目标服务后的具体规则。通常与VirtualService配合使用,作用于envoy
作用
- 定义服务子集(Subset)。将一个服务按版本、环境等标签划分为多个逻辑子集(例如:v1、v2 或prod、staging),方便灰度发布或 A/B 测试。
- 配置负载均衡策略。指定如何将流量分发给后端实例,例如:轮询、随机、最少连接、一致性哈希(基于请求头或 Cookie 的会话保持)。
- 连接池管理。控制到目标服务的 TCP/HTTP 连接池大小、超时设置,防止过载。
- 异常检测。自动剔除故障实例(如连续返回 5xx 错误的 Pod),提高系统弹性。
- TLS 安全设置。 配置服务间通信的加密模式(如 mTLS)。
示例
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-dr
spec:
host: reviews # 目标服务名
subsets:
- name: v1 # 子集1。v1版本
labels:
version: v1
- name: v2 # 子集2。v2版本
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: RANDOM # 全局负载均衡策略
outlierDetection:
consecutive5xxErrors: 3 # 3次5xx错误触发剔除
interval: 30s
3.3、网关(Gateway)
- 下面的示例展示了一个外部 HTTPS 入口流量的网关配置
- 这个网关配置让 HTTPS 流量从 ext-host.example.com 通过 443 端口流入网格,但没有为请求指定任何路由规则。
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
tls:
mode: SIMPLE
credentialName: ext-host-cert #指定保存证书和私钥的 Secret
# tls.mode字段的常见值
- SIMPLE:单向 TLS(客户端验证服务端证书)。
- MUTUAL:双向 mTLS(客户端和服务端互相验证证书)。
- PASSTHROUGH:透传 TLS 流量(由后端服务处理解密)。
- 要指定路由并让网关按预期工作,您必须把网关绑定到虚拟服务上。
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwy
3.4、服务入口(Service Entry)
- 服务入口(Service Entry) 是 Istio 服务网格中的一种资源类型,用于将网格外部的服务(如第三方 API、传统系统或非 Istio 管理的服务)纳入 Istio 的流量管理体系,使它们能够像网格内服务一样被统一管理、监控和安全控制
- 默认情况下,Istio 会阻止网格内服务访问外部服务。通过 ServiceEntry 显式声明后,才能受控访问。
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: svc-entry
spec:
hosts: # 定义外部服务的主机名(必填)
- ext-svc.example.com # 允许网格内服务通过该域名访问外部服务
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL # 表示服务位置(网格外部)
resolution: DNS # 服务发现方式(DNS/IP/STATIC)
3.5、边车(Sidecar)
- 在 Istio 服务网格中,Sidecar 是一个核心组件,它是一个与应用程序容器共同运行的轻量级代理容器(基于 Envoy),负责接管应用程序的网络通信,实现流量管理、安全策略和可观测性等功能,而无需修改应用代码
Sidecar 注入
- 在 Istio 中,Sidecar 注入是指将 Istio 的代理容器(通常是 Envoy)自动或手动添加到应用程序的 Pod 中,使其成为 Pod 的一部分,从而拦截和管理应用程序的网络流量。这一过程是 Istio 实现服务网格功能的核心机制
- Sidecar注入有自动注入和手动改注入两种方式
自动注入
- 利用 Kubernetes 的 Mutating Admission Webhook 机制,在 Pod 创建时自动修改其配置,插入 Sidecar 容器。
- 示例
// 首先为命名空间打标签 istio-injection=enabled 。之后在该命名空间下新建的 Pod 会自动注入 Sidecar。
kubectl label namespace <命名空间> istio-injection=enabled
// 查看命名空间是否启用注入,即是否有istio-injection=enabled这个标签
kubectl get namespace <命名空间> -L istio-injection
![image]()
// 部署应用后验证 Sidecar 是否存在。输出示例:app istio-proxy。app是应用容器,istio-proxy 即为 Sidecar
kubectl get pod <Pod名称> -o jsonpath='{.spec.containers[*].name}'
![image]()
手动注入
- 使用 istioctl 工具直接修改 Kubernetes 资源定义(如 Deployment YAML),添加 Sidecar 配置。
istioctl kube-inject -f <应用YAML文件> | kubectl apply -f -
注入后pod的结构变化
# 原始 Pod(无 Sidecar)
containers:
- name: app
image: my-app:1.0
# 注入后的 Pod(带 Sidecar)
containers:
- name: app
image: my-app:1.0
- name: istio-proxy # 注入的 Sidecar 容器
image: envoyproxy/envoy:v1.25.1
... # 省略 Sidecar 的配置和启动参数
initContainers:
- name: istio-init # Init 容器,用于设置 iptables 规则
image: istio/proxyv2:1.18.0
注入失败的可能原因
- 命名空间未正确标记 istio-injection=enabled。
- Pod 含有
sidecar.istio.io/inject: "false" 注解。
- Istio 的 Webhook 服务未正常运行(检查 istiod Pod 状态)
网络弹性与测试
1. 超时(Timeout)
- 定义请求在失败前允许的最大等待时间。若超时未收到响应,则终止请求并标记为失败。
场景举例
- 用户访问电商商品页,后端服务因高负载响应缓慢,前端在2秒后超时并展示降级内容。
- 支付接口调用银行网关时,设置 5秒超时,避免用户长时间等待。
2. 重试(Retry)
- 当请求失败时自动重新发起请求,通常针对临时性错误(如网络抖动)。
场景举例
- 订单服务因瞬时数据库连接失败返回 503,重试3次 后成功。
- 文件上传接口因网络波动失败,客户端 间隔1秒重试2次。
Istio 应用(超时+重试)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: orders
spec:
hosts:
- orders-service
http:
- route:
- destination:
host: orders-service
timeout: 3s # 设置超时为3秒
retries:
attempts: 2 # 最大重试次数
perTryTimeout: 1s # 每次重试的超时时间
retryOn: 503,gateway-error # 仅在503或网关错误时重试
3. 熔断器(Circuit Breaker)
- 当服务失败率达到阈值时,自动拒绝新请求(快速失败),避免雪崩效应。
场景举例
- 评论服务因数据库崩溃持续返回错误,熔断器 10秒内拒绝所有请求,直接返回缓存或默认值。
- 支付服务响应成功率低于90%,触发熔断 5分钟。
Istio 应用
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: payments
spec:
host: payments-service
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 3 # 连续3次5xx错误触发熔断
interval: 1m # 每1分钟检查一次,过去1分钟内consecutive5xxErrors的错误计数
baseEjectionTime: 1m # 首次触发熔断时,实例会被隔离1分钟,若该实例后续继续报错,隔离时间会按指数增长(2m、4m、8m)
maxEjectionPercent: 50 # 最多熔断50%的实例
4. 故障注入(Fault Injection)
- 主动向系统中注入故障(如延迟或错误),测试系统的容错能力。
场景举例
- 模拟 100ms 延迟,测试前端页面加载动画是否正常显示。
- 注入 HTTP 500错误,验证降级策略是否生效。
Istio 应用
http:
- fault:
delay:
percentage:
value: 10 # 10%的请求注入延迟
fixedDelay: 1s
route:
- destination:
host: cart-service
5.降级(Degradation)
- 当系统资源不足、依赖服务故障或流量过载时,主动关闭非核心功能或返回简化结果,保证核心功能可用。
- 核心思想:牺牲部分功能或用户体验,确保系统整体可用。
- 与熔断的区别:熔断是直接拒绝请求,降级是提供有损服务。
场景举例
- 电商大促期间,关闭商品详情页的部分展示,仅展示基础信息,减轻后端压力。
- 支付服务不可用时,提示“稍后支付”并生成离线订单。
Istio 中的应用
- Istio 原生不直接提供降级配置,但可通过以下方式间接实现:
- 通过 VirtualService 返回固定响应(模拟降级)
http:
- match:
- headers:
user-tier:
exact: free # 免费用户触发降级
fault:
abort:
percentage: 100
httpStatus: 200
responseHeaders:
content-type: "application/json"
body:
string: '{"status": "degraded", "data": "cached"}' # 返回降级响应
route:
- destination:
host: premium-service # 正常用户仍路由到原服务
- 结合服务网格与业务代码
- 这个案例的原理是,在应用代码中已经实现降级逻辑,并且指定了标签version: degraded。使用 Istio 的 DestinationRule 标记服务实例状态(如 version: degraded)。通过 VirtualService 将部分流量路由到降级版本:
http:
- match:
- headers:
x-degrade: "true"
route:
- destination:
host: service.default.svc.cluster.local
subset: degraded # 指向降级版本
Istio中的资源
- VirtualService + DestinationRule + Gateway 是流量管理的核心组合
- PeerAuthentication + AuthorizationPolicy用于实现零信任网络
- 在Istio服务网格中,有多种核心资源配置,以下是主要资源及其作用
1. 流量管理(Traffic Management)
| 资源类型 |
作用 |
典型场景 |
VirtualService |
定义流量路由规则(如基于路径、Header、权重等)。 |
A/B 测试、金丝雀发布、蓝绿部署。 |
Gateway |
配置服务网格的入口/出口流量规则(如暴露 HTTP/HTTPS 端口)。 |
对外暴露服务、定义 TLS 证书。 |
ServiceEntry |
将外部服务(如第三方 API)注册到网格内,使其可被内部服务访问。 |
访问云厂商 API 或遗留系统。 |
Sidecar |
限制 Sidecar 代理的流量范围(减少配置负载,隔离命名空间)。 |
优化大型网格的性能。 |
2. 安全(Security)
| 资源类型 |
作用 |
典型场景 |
AuthorizationPolicy |
定义访问控制规则(如允许哪些服务访问特定路径)。 |
实现零信任安全(RBAC)。 |
PeerAuthentication |
配置服务间通信的mTLS 模式(严格/宽松/禁用)。 |
强制服务间加密。 |
RequestAuthentication |
验证请求的 JWT 令牌,实现身份认证。 |
集成 OAuth2、OIDC 认证。 |
3. 可观测性(Observability)
| 资源类型 |
作用 |
典型场景 |
Telemetry |
自定义指标、日志和跟踪的生成规则(需配合 Istio 1.12+)。 |
监控特定请求的延迟或错误率。 |
EnvoyFilter |
直接修改 Envoy 代理的底层配置(高级功能,慎用)。 |
注入自定义 HTTP 头或过滤器。 |
4. 扩展与实验性功能
| 资源类型 |
作用 |
注意 |
WorkloadEntry |
将非 Kubernetes 工作负载(如虚拟机)接入服务网格。 |
混合云场景。 |
WorkloadGroup |
定义一组工作负载的模板,用于自动生成 WorkloadEntry。 |
批量管理 VM 服务。 |
配置示例
VirtualService(路由到子集)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews-vs
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1 # 使用 DestinationRule 定义的子集
weight: 80 # 80%流量到v1
- destination:
host: reviews
subset: v2
weight: 20 # 20%流量到v2
AuthorizationPolicy(访问控制)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY # 默认拒绝所有请求
rules:
- to:
- operation:
paths: ["/admin"] # 仅拦截 /admin 路径