因语雀与csdn markdown 格式有区别,请查看原文:
https://www.yuque.com/dycloud/pss8ys

一、流量治理重要配置详解

1.1 Pilot 配置分发机制

Pilot 负责网格中数据平面相关配置信息的获取、生成及分发,它通过用户配置及服务注册表获取网格配置信息并将其转换成 xDS 接口的标准数据格式,然后经 gRPC 分发至相关的 Envoy。

**<font style="color:#DF2A3F;">Service Registry</font>**:服务注册表中存储有相关平台上注册的各 Service 相关信息,例如 Kubernetes 的 Service 等。

**<font style="color:#DF2A3F;">Config Storage</font>**:配置存储,例如 K8S 中的 APIServer,配置信息通常是由用户提供,对于 k8s 来说,他们以 k8s crd 格式提供并存储在 APIServer 中。

1.2 Pilot 流量管理的相关组件

Pilot工作架构的相关组件包括:<font style="color:#DF2A3F;">pilot-discovery</font><font style="color:#DF2A3F;">k8s apiserver</font><font style="color:#DF2A3F;">Envoy(istio-proxy)</font><font style="color:#DF2A3F;">pilot-agent</font>,以及命令工具<font style="color:#DF2A3F;">istioctl</font><font style="color:#DF2A3F;">kubectl</font>

Pilot项目自身的组件也是由工作于控制平面的<font style="color:#DF2A3F;">polit-discovery</font>和工作于数据平面的<font style="color:#DF2A3F;">pilot-agent</font>共同组成;

控制平面相关组件

  • **<font style="color:#DF2A3F;">pilot-discovery</font>**:它主要完成以下功能
    • <font style="color:#DF2A3F;">Service Registry(Service)</font>中获取服务信息;
    • <font style="color:#DF2A3F;">API Server</font>中获取配置信息;
    • 将服务信息和配置信息转化为<font style="color:#DF2A3F;">Envoy</font>的配置格式,并通过<font style="color:#DF2A3F;">xDS API</font>完成分发;
  • **<font style="color:#DF2A3F;">Kubernetes API Server </font>**
    • 配置存储系统,负责存储用户以kubernetes crd格式(例如**<font style="color:#DF2A3F;">VirtualService</font>****<font style="color:#DF2A3F;">DestinationRule</font>**等)提供的配置信息;

数据平面相关组件:

  • **<font style="color:#DF2A3F;">Istio proxyv2</font>**镜像启动的容器中会运行<font style="color:#DF2A3F;">pilot-agent</font><font style="color:#DF2A3F;">envoy</font>两个进程;
istio-proxy@client-f98d4768d-c6m7b:/$ ps aux
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
istio-p+      1  0.5  0.1 1253196 36924 ?       Ssl  06:04   0:00 /usr/local/bin/pilot-agent proxy sidecar --domain app.svc.cluster.local --proxyLogLevel=warning --proxyComponentLogLevel=misc:error --log_output_leve
istio-p+     11  0.7  0.2 3328592 85900 ?       Sl   06:04   0:00 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev.json --drain-time-s 45 --drain-strategy immediate --local-address-ip-version v4 --file-flush-interv
istio-p+     25  0.0  0.0   4584  3904 pts/0    Ss   06:05   0:00 bash
istio-p+     32  0.0  0.0   7884  3968 pts/0    R+   06:05   0:00 ps aux
  • **<font style="color:#DF2A3F;">pilot-agent </font>**
    • 基于k8s api server为envoy初始化出可用的<font style="color:#DF2A3F;">boostrap</font>配置文件并启动envoy;
    • 监控并管理envoy的运行状态,包括envoy出错时重启envoy,以及envoy配置变更后将其重载等;
  • **<font style="color:#DF2A3F;">envoy</font>****<font style="color:rgb(0,0,0);"> </font>**
    • envoy由<font style="color:#DF2A3F;">pilot-agent</font>进程基于生成bootstrap配置进行启动,而后根据配置中指定的pilot地址,通过<font style="color:#DF2A3F;">xDS API</font>获取动态配置信息;
    • Sidecar形式的Envoy通过流量拦截机制为应用程序实现入站和出站代理功能;

1.3 流量治理

  • Istio的流量路由规则使运维人员可以轻松控制服务之间的流量和API调用
    • Istio简化了诸如断路器,超时和重试之类的服务级别属性的配置,并使其易于设置重要任务(如A/B测试, canary部署和基于百分比的流量拆分的分段部署)
    • 它还提供了开箱即用的故障恢复功能,有助于使应用程序更强大,以防止相关服务或网络的故障
  • 使用Istio进行流量管理从本质上是将流量与底层基础架构的伸缩机制相解耦,从而让运维工程师能够通过<font style="color:#DF2A3F;">Pilot</font>指定他们希望流量自身需要遵循哪些规则,而非仅仅只能定义由哪些特定的pod/VM接收流量,并在这些pod/VM之间以受限于数量比例的方式分配流量;
    • <font style="color:#DF2A3F;">Pilot</font><font style="color:#DF2A3F;">Envoy proxy</font>负责实现流量规则中定义的流量传输机制
    • 例如,可以通过Pilot指定希望特定服务的5%流量转到Canary版本,而与Canary部署的大小无关,或者根据请求的内容将流量发送到特定版本
  • Istio的所有路由规则和控制策略都基于Kubernetes CRD实现,这包括网络功能相关的**<font style="color:#DF2A3F;">VirtualService</font>****<font style="color:#DF2A3F;">DestinationRule</font>****<font style="color:#DF2A3F;">Gateway</font>****<font style="color:#DF2A3F;">ServiceEntry</font>****<font style="color:#DF2A3F;">EnvoyFilter</font>**等;

1.4 VirtualService 配置详解

前面其实已经学习了 Istio 中南北、东西向流量的部署服务的方式以及路由规则等,现在来学习一下 virtualService 到底是什么,有哪些配置。

VirtualService(虚拟服务) 是Istio流量管理的核心API,用于定义如何将请求路由到服务网格内的服务。它允许配置:

  • 请求路由规则(基于HTTP/HTTPS/TCP等协议)
  • 流量拆分和镜像
  • 重试、超时和故障注入策略

1.4.1 关键术语

术语 说明
Host 目标服务标识(K8s Service 名称或 FQDN)
Subset 服务子集(由 DestinationRule 定义的服务版本)
Gateway 流量入口点(网格入口/出口网关)
Route 具体的路由规则(HTTP/TCP/TLS)
Destination 路由目标(服务+子集+端口)
Match Condition 流量匹配条件(URI/Header/端口等)
  • <font style="color:#DF2A3F;">hosts</font>: 必选字段,用于指定流量请求的目标,可以是一个DNS名称或IP地址;
    • DNS名称可以使用通配符,也可以使用短格式的Service名称;
  • <font style="color:#DF2A3F;">gateways</font>:指定应用流量规则的Gateway资源,在<font style="color:#DF2A3F;">VirtualService</font>上使用<font style="color:#DF2A3F;">gateways</font>字段时遵循如下规则
    • 仅应用于网格内的东西流量时,应省略**<font style="color:#DF2A3F;">gateways</font>**字段
    • 仅用于引入网格外的流量,为<font style="color:#DF2A3F;">gateways</font>字段赋予合适的值(Gateway名称列表)即可
      • 客户端源自网格外部
      • <font style="color:#DF2A3F;">Gateway</font>负责接入这部分流量,<font style="color:#DF2A3F;">VirtualService</font>负责将这部分流量完成在网格内的路由
    • 同时用于网格内和网格外的流量时,需要将<font style="color:#DF2A3F;">gateways</font>字段的列表值的其中一项指定为“<font style="color:#DF2A3F;">mesh</font>
      • 客户端既可源自网格外部,也可以是网格内部的流量
  • <font style="color:#DF2A3F;">http</font>: 配置http协议的流量管理机制的有序列表,其配置框架称为<font style="color:#DF2A3F;">HTTPRoute</font>
  • <font style="color:#DF2A3F;">tls</font>:用于处理非终结的TLS和HTTPS流量的有序列表,其配置框架称为<font style="color:#DF2A3F;">TLSRoute</font>
  • <font style="color:#DF2A3F;">tcp</font>:管理四层的TCP流量的有序列表,其配置框架称为<font style="color:#DF2A3F;">TCPRoute</font>
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: product-service-route
spec:
  # 1. 目标服务(必填)
  hosts:
  - "product-service.svc.cluster.local"  # K8s服务名
  - "store.example.com"                  # 外部域名

  # 2. 应用网关(默认应用网格内流量)
  gateways:
  - istio-ingressgateway   # 入口网关
  - mesh                   # 网格内部流量

  # 3. HTTP路由规则(核心配置)
  http:
  - name: v1-route         # 规则名称
    # 匹配条件
    match:
    - uri:
        prefix: "/v1"      # URI前缀匹配
      headers:             # Header匹配
        x-user-type: 
          exact: "vip"
    # 路由目标
    route:
    - destination:
        host: product-service
        subset: v1         # 服务子集
        port: 
          number: 8080
      weight: 80           # 流量权重
    # 高级策略
    timeout: 2s            # 超时设置
    retries:               # 重试策略
      attempts: 3
      perTryTimeout: 1s
    fault:                 # 故障注入
      delay:
        percentage: 
          value: 10
        fixedDelay: 5s

  # 4. 默认路由(无匹配条件时生效)
  - route:
    - destination:
        host: product-service
        subset: v2

1.4.2 HTTPRoute

HTTPRoute 是 VirtualService 的核心组成部分,用于定义 HTTP/HTTPS 流量的路由规则:

  1. 与 VirtualService 的关系
    • VirtualService 是顶层对象
    • <font style="color:#DF2A3F;">HTTPRoute</font> 是其 <font style="color:#DF2A3F;">spec.http</font> 字段下的路由规则定义
    • **一个 **<font style="color:#DF2A3F;">VirtualService</font>** 可包含多个 ****<font style="color:#DF2A3F;">HTTPRoute</font>**
  2. 核心结构
http:
- name: "路由规则名称"
  match: [...]     # 匹配条件
  route: [...]     # 路由目标
  redirect: [...]  # 重定向
  rewrite: [...]   # URI重写
  timeout: ...     # 超时
  retries: ...     # 重试
  fault: ...       # 故障注入

匹配条件(match)类型

  • <font style="color:rgb(251, 71, 135);">uri</font>:路径匹配(<font style="color:#DF2A3F;">prefix</font>/<font style="color:#DF2A3F;">exact</font>/<font style="color:#DF2A3F;">reg</font><font style="color:rgb(51, 54, 57);">ex</font>
  • <font style="color:rgb(251, 71, 135);">headers</font>:请求头匹配
  • <font style="color:rgb(251, 71, 135);">method</font>:HTTP方法(GET/POST等)
  • <font style="color:rgb(251, 71, 135);">authority</font>:Host头匹配
  • <font style="color:rgb(251, 71, 135);">queryParams</font>:查询参数匹配

<font style="color:#DF2A3F;">virtualservice.http</font>配置如何处理http流量

  • 服务的端口协议是HTTP、HTTP2和GRPC,即在服务的端口名中包含http-、http2-和grpc-等;
  • Gateway的端口协议是HTTP、HTTP2和GRPC,或者Gateway终结了TLS;
  • ServiceEntry的端口协议是HTTP、HTTP2和GRPC;

路由机制及服务韧性等相关的配置,即满足<font style="color:#DF2A3F;">HTTPMatchRequest</font>条件的流量可以做如下处理

  • 路由到指定目标(HTTPRouteDestination)
  • 执行重定向(HTTPRedirect)
  • URL重写(HTTPRewrite)
  • 请求重试(HTTPRetry)
  • 故障注入(HTTPFaultInjection)
  • 跨站资源引用(CorsPolicy)

Envoy 中的路由配置可以查看这里:https://www.yuque.com/dycloud/pss8ys/og9o5a4y3o26xzu6

而 Istio 简化了 Envoy 中的路由配置:

1.4.3 HTTPRoute 配置示例

# VirtualService:为 productpage 服务定义路由,将流量全部发往 v1 版本
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productpage        # VirtualService 的名称
spec:
  hosts:
    - productpage          # 作用的服务名称(Service 名)
  http:
    - route:
        - destination:
            host: productpage  # 后台服务名
            subset: v1        # 指定发往 v1 版本的 Pod(需有对应 DestinationRule)
---
# VirtualService:为 ratings 服务定义路由,将流量全部发往 v2 版本
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
    - ratings              # 作用的服务名称
  http:
    - route:
        - destination:
            host: ratings     # 后台服务名
            subset: v2        # 指定发往 v2 版本的 Pod
            
---

# VirtualService:为 reviews 服务(FQDN)定义路由及路径重写
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: reviews-route            # VirtualService 的名称
spec:
  hosts:
    - reviews.prod.svc.cluster.local  # 完整域名,K8s 内部 DNS 名
  http:
    # 路由1:当路径匹配 /wpcatalog 或 /consumercatalog 时
    - name: "reviews-v2-routes"   # 路由规则名称
      match:
        - uri:
            prefix: "/wpcatalog"         # 匹配以 /wpcatalog 前缀的请求
        - uri:
            prefix: "/consumercatalog"   # 匹配以 /consumercatalog 前缀的请求
      rewrite:
        uri: "/newcatalog"               # 将请求路径重写为 /newcatalog
      route:
        - destination:
            host: reviews.prod.svc.cluster.local   # 服务的域名
            subset: v2                            # v2 版本
    # 路由2:其余所有流量默认发往 v1
    - name: "reviews-v1-route"
      route:
        - destination:
            host: reviews.prod.svc.cluster.local   # 服务的域名
            subset: v1                            # v1 版本

---
# VirtualService:为 details 服务注入故障,百分百中止并返回555
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
    - details                             # 作用的服务名称
  http:
    - fault:                             # 故障注入配置
        abort:
          httpStatus: 555                # 返回 555 状态码
          percent: 100                   # 百分之百请求被中止
      route:
        - destination:
            host: details                # 路由目标服务
            subset: v1                   # v1 版本

1.5 DestinationRule 配置详解

<font style="color:rgb(251, 71, 135);">DestinationRule</font> 是 Istio Service Mesh 流量管理的核心资源对象之一,作用是针对服务流量的“下游路由”指定详细细粒度的策略
部署到 Mesh 的控制面后,Envoy Proxy 会根据规则执行相应的流量调度策略,保障微服务间通信的安全、稳定与弹性。它可以实现:

  • 指定服务的负载均衡算法
    决定同一目标服务不同 Pod 实例间如何分配请求
  • 细化服务子集(subset)
    通常配合 <font style="color:rgb(251, 71, 135);">VirtualService</font> 做灰度、金丝雀、多版本流量分配,例如 product-v1, product-v2
  • 连接池控制
    限制上游连接数量/保持/超时等,有效防止雪崩、探活问题放大
  • 异常实例剔除(Outlier Detection)
    实时检测/剔除故障实例,提升可用性
  • 跨命名空间可见性
    通过 <font style="color:rgb(251, 71, 135);">exportTo</font> 控制规则应用范围
  • TLS/加密通讯策略
    可为服务间通讯设置自定义的TLS相关配置

1.5.1 资源结构与字段详解

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: productpage-destination   # 规则对象名称
spec:
  host: productpage              # 适用的服务名,支持svc短名或FQDN
  trafficPolicy:                 # 整体服务级别的流量控制策略
    loadBalancer:                # 负载均衡策略
      simple: ROUND_ROBIN        # 常见类型还有 LEAST_CONN、RANDOM、PASSTHROUGH
    outlierDetection:            # 异常实例剔除
      consecutiveErrors: 3
      interval: 5s
      baseEjectionTime: 15s
      maxEjectionPercent: 50
    connectionPool:              # 连接池配置(HTTP和TCP)
      tcp:
        maxConnections: 500
        connectTimeout: 30ms
      http:
        http1MaxPendingRequests: 1000
        http2MaxRequests: 1000
        maxRequestsPerConnection: 100
        maxRetries: 3
  subsets:                       # 定义服务的多个子集(一般对应服务版本等标签组合)
    - name: v1
      labels:
        version: v1
      trafficPolicy:             # 可为各个子集单独配置流量策略(如自定义v1的负载均衡)
        loadBalancer:
          simple: LEAST_CONN
    - name: v2
      labels:
        version: v2

字段名 作用及典型用法
<font style="color:rgb(251, 71, 135);">host</font> 必填项。规则应用的目标服务名称。可用短名、全名、ServiceEntry等
<font style="color:rgb(251, 71, 135);">subsets</font> 定义服务的“子集”——常以 labels 区分(如版本、区域、多活等)
<font style="color:rgb(251, 71, 135);">trafficPolicy</font> 全局流量策略,包括负载均衡、连接池、驱逐、TLS、端口级策略
<font style="color:rgb(251, 71, 135);">exportTo</font> 控制当前规则在哪些命名空间下 Sidecar 可见 (<font style="color:rgb(251, 71, 135);">.</font>当前,<font style="color:rgb(251, 71, 135);">*</font>全局)

子集 subset

  • <font style="color:#DF2A3F;">name</font>: 子集名称,与 <font style="color:#DF2A3F;">VirtualService</font> 使用的 <font style="color:#DF2A3F;">subset</font> 保持一致
  • <font style="color:#DF2A3F;">labels</font>: 服务实例上需匹配的 <font style="color:#DF2A3F;">label</font>(用于分组/区分版本)
  • <font style="color:#DF2A3F;">trafficPolicy</font>: 子集专有的流量策略

1.5.2 TrafficPolicy 内部主要子配置

1、<font style="color:#DF2A3F;">loadBalancer</font>
  • 常用策略
    • <font style="color:rgb(251, 71, 135);">ROUND_ROBIN</font>(轮询,默认参数)
    • <font style="color:rgb(251, 71, 135);">LEAST_CONN</font>(最少连接)
    • <font style="color:rgb(251, 71, 135);">RANDOM</font>(随机)
    • <font style="color:rgb(251, 71, 135);">PASSTHROUGH</font>(跳过流量管理)
  • 一致性哈希
loadBalancer:
  consistentHash:
    httpHeaderName: "X-User"
    minimumRingSize: 1024
2、<font style="color:#DF2A3F;">outlierDetection</font>(异常驱逐)
  • 实现健康探测/容错/自动剔除异常实例
    • <font style="color:rgb(251, 71, 135);">consecutiveErrors</font>:触发剔除的连续错误阈值
    • <font style="color:rgb(251, 71, 135);">interval</font>:错误采样时间窗
    • <font style="color:rgb(251, 71, 135);">baseEjectionTime</font>:单实例被摘除的基准时间
    • <font style="color:rgb(251, 71, 135);">maxEjectionPercent</font>:最多剔除比例
    • <font style="color:rgb(251, 71, 135);">minHealthPercent</font>:剔除后剩余健康实例的最小比例
3、<font style="color:#DF2A3F;">connectionPoll</font>
  • TCP 连接池
    • <font style="color:rgb(251, 71, 135);">maxConnections</font>:为上游服务的所有实例简历的最大连接数,默认 1024
    • <font style="color:rgb(251, 71, 135);">connectTimeout</font>:TCP 连接超时时长
    • <font style="color:rgb(251, 71, 135);">tcpKeepalive</font>:TCP 存活配置,定期给发送一个 keepalived 探测报文来判断连接是否可用。
  • HTTP 连接池
    • <font style="color:rgb(251, 71, 135);">http1MaxPendingRequests</font>:HTTP1.1最大挂起请求数,默认 1024
    • <font style="color:rgb(251, 71, 135);">http2MaxRequests</font>:HTTP2最大请求数,默认 1024
    • <font style="color:rgb(251, 71, 135);">maxRequestsPerConnection</font>:每连接的最大请求数,默认无限制,1 表示禁用 keepalive
    • <font style="color:rgb(251, 71, 135);">maxRetries</font>:最大自动重试次数,默认为 3
    • <font style="color:rgb(251, 71, 135);">idleTimeout</font>:空闲连接自动回收时间
4、<font style="color:#DF2A3F;">tls</font>
  • 配置 mTLS/TLS 上下游通讯
trafficPolicy:
  tls:
    mode: ISTIO_MUTUAL

1.5.3 DestinationRule 配置示例

# 1. reviews 服务的 DestinationRule,定义了三个子集(版本v1、v2、v3)
# 用于 VirtualService 按不同子集路由流量
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: reviews          # 规则名称(推荐唯一,便于管理)
spec:
  host: reviews          # 目标服务(短名,K8s Service名)
  subsets:
    - name: v1           # 子集名称,与 VirtualService 中 subset 字段对应
      labels:
        version: v1      # 匹配带有 version=v1 标签的 Pod
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3

---

# 2. ratings 服务的 DestinationRule,设置了全局负载均衡与版本子集专属策略
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: bookinfo-ratings               # 规则名称
spec:
  host: ratings.prod.svc.cluster.local # 完整域名(推荐用 FQDN,防止多namespace歧义)
  trafficPolicy:                       # 全局流量策略
    loadBalancer:
      simple: LEAST_CONN               # 全局默认最少连接数优先
  subsets:
    - name: testversion                # 定义一个子集,名为 testversion
      labels:
        version: v3                    # 匹配 version=v3 的 Pod
      trafficPolicy:                   # 子集专属流量策略
        loadBalancer:
          simple: ROUND_ROBIN          # testversion 子集单独用轮询分流

---

# 3. reviews 服务的 DestinationRule(含全局随机负载均衡)
# 注意:如需多个 DestinationRule 操作同一个 host,只能在不同 namespace 下!
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: reviews-random
spec:
  host: reviews
  trafficPolicy:
    loadBalancer:
      simple: RANDOM                   # 全局负载均衡使用随机分发
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
    - name: v3
      labels:
        version: v3

# 提示:
# 如果在同一个 namespace 下有多个 DestinationRule,host 必须不同,否则配置会冲突。
# 如果 reviews 服务下需要多份流量策略和不同名字的 DR,请合理区分 namespace。

1.6 Gateway

Gateway(网关)是 Istio 网络流量管理体系中的入口资源,用于声明和配置网格边界的流量接入/转发规则。它定义在边缘(如 Ingress Gateway Pod 所在位置),负责允许外部用户或系统通过HTTP/HTTPS/TCP 协议安全、灵活地接入 Service Mesh

  • 直观地说:
    Gateway ≈ “Kubernetes Ingress” 的升级版,但更灵活、可配合 Istio 强大流量管理功能(如灰度、TLS、观测等)。
  • 重要补充:
    Gateway 只负责暴露端口和协议,不决定流量路由,内部实际路由还靠 VirtualService。

1.6.1 Gateway 资源的核心字段

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: my-gateway
  namespace: istio-system        # 推荐部署和ingressgateway pod同一个namespace
spec:
  selector:                     # Pod 选择器,绑定到特定的 Ingress Gateway 组件(通常由 Istio 自动部署,标签名如 istio=ingressgateway)
    istio: ingressgateway
  servers:                      # 可以配置多个 server,分别定义监听的端口和协议
    - port:
        number: 80              # 接收请求的端口号
        name: http              # 端口名称
        protocol: HTTP          # 协议类型,如 HTTP/HTTPS/TCP/TLS
      hosts:
        - "*.example.com"       # 支持 * 通配符,必须为FQDN格式
        - "www.example.com"
    - port:
        number: 443
        name: https
        protocol: HTTPS
      hosts:
        - "secure.example.com"
      tls:                      # 若发布为HTTPS,需要配置TLS
        mode: SIMPLE            # 支持 SIMPLE(单向TLS)、MUTUAL(双向TLS)、PASSTHROUGH 等
        credentialName: example-credential   # 证书密钥,需预先创建 Secret
        minProtocolVersion: TLSV1_2
        maxProtocolVersion: TLSV1_3

  • <font style="color:rgb(251, 71, 135);">selector</font>:Pod标签选择器
    绑定到某个具体的 Istio Ingress Gateway Deployment(默认<font style="color:#DF2A3F;"> istio: ingressgateway</font>);只有标签匹配的 Pod 会被此 gateway 控制
  • <font style="color:rgb(251, 71, 135);">servers</font>:服务监听组,可以有多个
    • <font style="color:rgb(251, 71, 135);">port</font>:服务开放的监听端口,外部流量的入口
    • <font style="color:rgb(251, 71, 135);">hosts</font>:绑定的 FQDN 域名(或 *),决定哪些 Host 头才会被此 gateway 接收入站流量
    • <font style="color:rgb(251, 71, 135);">tls</font>:如果监听 HTTPS,还可声明 TLS 一系列加密配置
  • <font style="color:rgb(251, 71, 135);">tls.credentialName</font>:引用 Kubernetes Secret,实现 TLS 证书热更新
  • <font style="color:rgb(251, 71, 135);">tls.mode: MUTUAL</font>:实现双向 TLS(客户端/服务端双方证书验证)
  • 支持多端口、多协议同一 Gateway
  • SNI 路由、通配符域名、大规模多租户支持

1.6.2 Gateway 与 VirtualService 的关系

  • Gateway 只是暴露入口端口和协议,真正的 HTTP 路由、流量分配和各类规则需要 **<font style="color:#DF2A3F;">VirtualService</font>** 绑定 **<font style="color:#DF2A3F;">Gateway</font>** 共同实现
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: my-vs
spec:
  hosts:
    - "www.example.com"
  gateways:
    - my-gateway           # 绑定上面定义的Gateway
  http:
    - match:
        - uri:
            prefix: /api
      route:
        - destination:
            host: backend-service.default.svc.cluster.local
            port:
              number: 8080

  • 如果 VirtualService 的 <font style="color:rgb(251, 71, 135);">gateways</font> 设置为 <font style="color:rgb(251, 71, 135);">mesh</font>,则作用于网格内部流量,否则会作用在指定的 Gateway 上,实现真实外网<->内部服务的流量路由。

  1. Gateway 与 **<font style="color:#DF2A3F;">Ingress Gateway Pod</font>** 必须同 namespace否则无法正确调度
  2. hosts 必须为 FQDN(支持 * 通配),不接受非域名字符串
  3. tls 相关配置需要提前准备好 Kubernetes Secret
  4. selector 控制配置应用到哪些 Ingress Gateway Pod,支持一套 Mesh 多套边界网关并行
  5. Ingress Gateway Controller (istio-ingressgateway) 通常是一个 Deployment,默认在<font style="color:#DF2A3F;"> istio-system</font> 命名空间
  6. Gateway 实际“只监听端口”,不做流量分配。需要配合 VirtualService,使用 <font style="color:rgb(251, 71, 135);">hosts</font><font style="color:rgb(251, 71, 135);">uri</font> 等精准转发路径规则

1.6.3 Gateway 配置示例

# 1. my-gateway
# 用于暴露 uk.bookinfo.com 和 eu.bookinfo.com 两个域名的流量入口
# 支持 HTTP(自动跳转到 HTTPS)和 HTTPS(443 端口证书配置)
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: my-gateway                     # Gateway 对象的名称
  namespace: some-config-namespace     # 需保证与目标 IngressGateway Pod 在同命名空间
spec:
  selector:
    app: my-gateway-controller         # 该 Gateway 规则只会应用到带此标签的 ingressgateway Pod
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - uk.bookinfo.com
        - eu.bookinfo.com
      tls:
        httpsRedirect: true            # 自动将 HTTP 301 跳转至 HTTPS
    - port:
        number: 443
        name: https-443
        protocol: HTTPS
      hosts:
        - uk.bookinfo.com
        - eu.bookinfo.com
      tls:
        mode: SIMPLE                   # SIMPLE 表示单向 TLS(HTTPS 服务)
        serverCertificate: /etc/certs/servercert.pem   # 服务端证书路径
        privateKey: /etc/certs/privatekey.pem          # 私钥路径

---

# 2. grafana-gateway
# 用于暴露 Grafana 面板,监听 15031 端口,支持所有域名流量进入
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: grafana-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway       # 绑定到 istio 默认部署的 ingressgateway Pod
  servers:
    - port:
        number: 15031
        name: http-grafana
        protocol: HTTP
      hosts:
        - "*"                         # 支持所有主机头(Host)

---

# 3. kiali-gateway
# 用于暴露 Kiali 面板,监听 15029 端口,支持所有域名流量进入
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: kiali-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway              # 绑定到 istio 默认部署的 ingressgateway Pod
  servers:
    - port:
        number: 15029
        name: http-kiali
        protocol: HTTP
      hosts:
        - "*"                         # 支持所有主机头(Host)


二、流量治理高级案例

https://istio.io/latest/docs/reference/config/networking/virtual-service/

2.1 URL 重定向

2.1.1 Istio URL重定向配置

Istio 的 URL 重定向一般是在 VirtualService 资源中实现的。当请求进入服务网格后,基于 <font style="color:#DF2A3F;">VirtualService</font> 规则,Istio 可以把请求重定向到新的 URL,实现路径主机端口协议等的改变

这种功能通常用于:

  • HTTP → HTTPS 安全升级
  • 统一入口(如 /v1/xxx → /v2/xxx)
  • 域名跳转
  • 更换后端服务端口
  • 其他自定义 URL 路径变换

Istio中的<font style="color:#DF2A3F;">HTTP Redirect</font>操作,通过向客户端返回<font style="color:#DF2A3F;">301</font>响应码,指示其向新的<font style="color:#DF2A3F;">uri</font><font style="color:#DF2A3F;">authority</font>指向的新目标进行重新请求

字段名 用法/含义
**<font style="color:#DF2A3F;">uri</font>** 重定向时覆盖原 URL 的 Path 部分。配置后,请求的路径会被完全替换,无论原路径是什么。
**<font style="color:#DF2A3F;">authority</font>** 覆盖原 URL 的 Host(域名/authority)部分,可以实现主机名切换跳转。
**<font style="color:#DF2A3F;">port</font>** 覆盖 URL 的端口部分。指定目标端口号。
**<font style="color:#DF2A3F;">derivePort</font>** 动态设置端口:可选 FROM_PROTOCOL_DEFAULT(HTTP用80,HTTPS用443),或 FROM_REQUEST_PORT(使用原始请求端口)。
**<font style="color:#DF2A3F;">scheme</font>** 覆盖 URL 的协议部分(如 http/https)。未设置时用原协议。如配合 derivePort 为 FROM_PROTOCOL_DEFAULT,可以自动影响端口。
**<font style="color:#DF2A3F;">redirectCode</font>** 设置 HTTP 重定向的返回码。默认是 301(永久重定向)。可自定义为 302/303 等。

2.1.2 URL 重定向案例

还是基于之前的 frontend 和 demoapp 案例来做案例:

  • 访问 frontend 服务的"<font style="color:#DF2A3F;">/backend</font>“路径,将会被自动重定向到”<font style="color:#DF2A3F;">http://dycloud.fun</font>"
  • 访问 demoapp 服务的"<font style="color:#DF2A3F;">/frontend</font>“路径,将会被自动重定向到”<font style="color:#DF2A3F;">http://frontend</font>"

**配置 frontend 的 ****<font style="color:#DF2A3F;">virtualService</font>**

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: frontend
spec:
  hosts:
  - "fe.dujie.com"
  - "frontend.dujie.com"
  gateways:
  - frontend-gateway
  #- mesh
  http:
  - name: redirect
    match:
    - uri:
        prefix: "/backend"
    redirect:
      uri: /
      authority: dycloud.fun
      port: 80
  - name: default
    match:
    - uri: 
        prefix: /
    route:
    - destination:
        host: frontend
        port:
          number: 80

配置 demoapp 的 <font style="color:#DF2A3F;">virtualService</font>

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: redirect
    match:
    - uri:
        prefix: "/frontend"
    redirect:
      uri: /
      authority: frontend
      port: 80
  - name: canary
    match:
    - uri:
        prefix: /canary  # 访问/canary 路由给v2-canary子集
    rewrite:
      uri: /
    route:
    - destination:
        host: demoapp
        subset: v2-canary
  - name: default  # 其他路径,路由给v2子集
    route:
    - destination:
        host: demoapp
        subset: v2

2.1.3 验证前端应用

可以访问frontend.dujie.com/backend 验证是否会自动重定向到 <font style="color:#DF2A3F;">dycloud.fun</font>

[root@k8s-master01 /usr/local/src]# curl -I frontend.dujie.com/backend
HTTP/1.1 301 Moved Permanently
location: http://dycloud.fun/
date: Mon, 04 Aug 2025 08:03:07 GMT
server: istio-envoy
connection: close
transfer-encoding: chunked

2.1.4 验证 demoapp

验证访问 demoapp:8080/frontend 时是否会自动重定向到/frontend

[root@k8s-master01 /usr/local/src]# kubectl exec -it -n app  client-f98d4768d-c6m7b  bash
root@client-f98d4768d-c6m7b /# curl -I demoapp:8080/frontend
HTTP/1.1 301 Moved Permanently
location: http://frontend/
date: Mon, 04 Aug 2025 08:07:08 GMT
server: envoy
transfer-encoding: chunked

验证/canary 路径是否路由到 v2-canary 子集

root@client-f98d4768d-c6m7b /# while true; do curl demoapp:8080/canary; sleep 0.$RANDOM; done

2.2 操作报文标头示例

Headers为Istio提供了操作HTTP Header的途径,用于操作HTTP 请求报文中Request或者Response标头

  • headers字段支持<font style="color:#DF2A3F;">request</font><font style="color:#DF2A3F;">response</font>两个内嵌字段
    • <font style="color:#DF2A3F;">request</font>:操纵发送给Destination的请求报文中的标头
    • <font style="color:#DF2A3F;">response</font>:操纵发送给客户端的响应报文中的标头
  • ◼ 以上两个对应的类型都是 <font style="color:#DF2A3F;">HeaderOperations</font> 类型,都支持使用<font style="color:rgb(0,0,0);">set</font><font style="color:rgb(0,0,0);">add</font><font style="color:rgb(0,0,0);">remove</font>字段操纵指定的标头
    • <font style="color:#DF2A3F;">set</font>:使用map上的Key和Value覆盖Request或者Response中对应的Header
    • <font style="color:#DF2A3F;">add</font>:追加map上的Key和Value到原有 Header
    • <font style="color:#DF2A3F;">remove</font>:删除在列表中指定的Header

2.2.1 修改 demoapp 的 virtualService

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - headers:   # 匹配请求头中带有x-canary并且值为true的
        x-canary: 
          exact: "true"
    route:     # 将上面的匹配请求都发送到v2-canary子集
    - destination:
        host: demoapp
        subset: v2-canary
      headers:   # 并且在请求头中配置User-Agent 的值为wget
        request:
          set:
            User-Agent: wget
        response:   # 在响应头中添加x-canary等于true 字段
          add:
            x-canary: "true"
  - name: default   # 其余的请求在响应头中添加X-Envoy等于test字段
    headers:
      response:
        add:
          X-Envoy: test
    route:
    - destination:  # 将其余请求都发往v2子集
        host: demoapp
        subset: v2

2.2.2 测试

在 client pod 中测试,在 curl 命令中添加请求头参数,可以看到请求到达的子集是 <font style="color:#DF2A3F;">v2-canary</font>,并且在响应报文中添加了<font style="color:#DF2A3F;"> x-canary: true </font>字段

root@client-f98d4768d-c6m7b /# curl -I -H "x-canary: true" frontend
HTTP/1.1 200 OK
server: envoy
date: Mon, 04 Aug 2025 08:16:36 GMT
content-type: text/html; charset=utf-8
content-length: 145
x-envoy-upstream-service-time: 6
x-canary: true
root@client-f98d4768d-c6m7b /# curl  -H "x-canary: true" frontend
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~

还可以循环访问

root@client-f98d4768d-c6m7b /# while true; do curl -H "x-canary: true" frontend;  sleep 0.$RANDOM; done


然后查看 canary 的日志,可以看到 user agent 信息已经被替换成 wget 了


04/Aug/2025:08:23:59 +0000 127.0.0.6 - - [None] "GET /? HTTP/1.1" - "wget" "127.0.0.6"
04/Aug/2025:08:24:00 +0000 127.0.0.6 - - [None] "GET /? HTTP/1.1" - "wget" "127.0.0.6"
04/Aug/2025:08:24:00 +0000 127.0.0.6 - - [None] "GET /? HTTP/1.1" - "wget" "127.0.0.6"

2.3 故障注入

故障注入(Fault Injection)是Istio流量管理能力的一部分,允许开发者和运维人员在服务通信过程中“模拟”异常,如强制延迟请求返回、注入错误响应等。
其作用主要有:

  • 验证应用的容错和降级能力(如服务超时、重试、熔断等逻辑是否生效)
  • 帮助定位在下游服务不稳定、网络有抖动时,系统整体的弹性表现问题
  • 测试微服务环境下的稳健性

Istio 支持两种类型的故障注入:

  1. 延迟注入(Delay Injection)
    • 人为让响应耗时增加

字段 含义说明
fixedDelay 固定延迟时长,即 Istio 在请求转发前人为增加的延迟(如 1h/1m/1s/1ms),最小为 1ms。
percentage 指定被延迟的流量百分比(建议用这个)。如设为 50,表示50%的请求会被加延迟。
percent 被延迟的流量百分比(0~100),已过时,推荐用 <font style="color:rgb(251, 71, 135);">percentage</font>
字段替代。
  1. 中断注入(Abort Injection)
    • 人为返回异常状态码而非正常接口响应

字段 含义说明
httpStatus 终止 HTTP 请求时返回给客户端的状态码(如 500、503 等),模拟 HTTP 服务端异常。
grpcStatus 终止 gRPC 请求时返回的错误码,必须为 gRPC文档里的字符串全写形式,如 <font style="color:rgb(251, 71, 135);">UNAVAILABLE</font>
percentage 指定被中断(即被返回错误码)的流量百分比。如设置为 50,表示有50%的请求会被强制返回 <font style="color:rgb(51, 54, 57);">httpStatus</font><font style="color:rgb(51, 54, 57);">grpcStatus</font>

2.3.1 修改 demoapp 的 virtualService

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - headers:
        x-canary:        # 匹配请求头中带有x-canary等于true的
          exact: "true"
    route:
    - destination:
        host: demoapp   # 路由到v2-canary
        subset: v2-canary
      headers:
        request:  # 并在请求头中设置User-Agent的值为wget
          set:
            User-Agent: wget
        response:   # 在响应头中添加x-canary等于true
          add:
            x-canary: "true"
    fault:   # 配置故障注入,20%的流量返回555错误
      abort:
        percentage:
          value: 20
        httpStatus: 555
  - name: default   # 其余流量路由到v2子集
    route:
    - destination:
        host: demoapp
        subset: v2
    fault:   # 配置故障注入,20%的流量延时5秒
      delay:
        percentage:
          value: 20
        fixedDelay: 5s

2.3.2 测试故障注入

进行请求测试,可于集群上的客户端Pod中直接请求<font style="color:#DF2A3F;">frontend.default.svc</font>主机, 或者于集群外请求<font style="color:#DF2A3F;">frontend.dujie.com</font>主机

MacBook-Pro:~ root# while true; do curl frontend.dujie.com/services; sleep 0.$RANDOM; done
frontend (frontend-7c55c868cf-6mpj7) successfully connects to demoapp-v2.1 (demoapp-59598585bf-ddw4b) in 5.55 ms.
frontend (frontend-7c55c868cf-6mpj7) successfully connects to demoapp-v2.1 (demoapp-59598585bf-h5z7b) in 4.16 ms.
frontend (frontend-7c55c868cf-srjmj) successfully connects to demoapp-v2.1 (demoapp-59598585bf-ddw4b) in 5009.27 ms.
frontend (frontend-7c55c868cf-6mpj7) successfully connects to demoapp-v2.1 (demoapp-59598585bf-h5z7b) in 4.89 ms.
frontend (frontend-7c55c868cf-srjmj) successfully connects to demoapp-v2.1 (demoapp-59598585bf-ddw4b) in 3.87 ms.
frontend (frontend-7c55c868cf-6mpj7) successfully connects to demoapp-v2.1 (demoapp-59598585bf-h5z7b) in 3.59 ms.
frontend (frontend-7c55c868cf-srjmj) successfully connects to demoapp-v2.1 (demoapp-59598585bf-h5z7b) in 4.15 ms.
frontend (frontend-7c55c868cf-srjmj) successfully connects to demoapp-v2.1 (demoapp-59598585bf-ddw4b) in 3.60 ms.
frontend (frontend-7c55c868cf-srjmj) successfully connects to demoapp-v2.1 (demoapp-59598585bf-dlc6r) in 3.88 ms.
frontend (frontend-7c55c868cf-6mpj7) successfully connects to demoapp-v2.1 (demoapp-59598585bf-dlc6r) in 5007.23 ms.
...

(base) dujie@MacBook-Pro ~ % while true; do CONTENT=$(curl -s -H "x-canary: true" frontend.dujie.com); echo $CONTENT; sleep 0.$RANDOM; done
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-szdbw, Server IP: 172.16.85.217 ~
fault filter abort
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-szdbw, Server IP: 172.16.85.217 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-szdbw, Server IP: 172.16.85.217 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~
fault filter abort
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
fault filter abort
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-szdbw, Server IP: 172.16.85.217 ~



查看 kiali 可以看到有大概 20%的流量是异常的

2.4 请求重试和超时

在微服务架构下,服务间网络请求经常遇到瞬时失败(如临时网络抖动、节点重启等)。Istio 支持自动对这些蓝本失败进行无感重试,帮助增强应用的健壮性和容错性。

Istio 的重试是由 Sidecar 代理(Envoy)在应用侧透明执行的,无需业务代码修改。

  • 重试机制是在 VirtualService 的 <font style="color:rgb(251, 71, 135);">http.route</font> 路由规则下通过 <font style="color:rgb(251, 71, 135);">retries</font> 字段配置的。
  • 当下游(被调用服务)出现某些可恢复的异常(如 5xx、连接超时等),Envoy 会自动把请求再发出去,充当应用的弹性保护墙
  • 重试间隔和次数由用户自定义;可防喷射(防止瞬时高并发因重试而冲击服务)。
字段 含义与作用
attempts 最大重试次数(不含首次请求,即最多会发出 attempts 次请求)
perTryTimeout 每次重试的最大等待时间(如 2s)。和 route/http.timeout 配合使用。
retryOn 声明哪些返回码或错误类型才触发重试。常见如:5xx,connect-failure,timeout,reset
retryRemoteLocalReset 是否对局域网/远程服务主动断开也进行重试

2.4.1 HTTP 请求重试条件(route.RetryPolicy)

  • 重试条件(同**<font style="color:#DF2A3F;">x-envoy-retry-on</font>**标头)
    • <font style="color:#DF2A3F;">5xx</font>:上游主机返回5xx响应码,或者根本未予响应(断开/重置/读取超时)
    • <font style="color:#DF2A3F;">gateway-error</font>:网关错误,类似于5xx策略,但仅为502、503或504的应用进行重试
    • <font style="color:#DF2A3F;">connection-failure</font>:在TCP级别与上游服务建立连接失败时进行重试
    • <font style="color:#DF2A3F;">retriable-4xx</font>:上游服务器返回可重复的4xx响应码时进行重试
    • <font style="color:#DF2A3F;"> refused-stream</font>:上游服器务使用REFUSED——STREAM错误码重置时进行重试
    • <font style="color:#DF2A3F;">retriable-status-codes</font>:上游服务器的响应码与重试策略或<font style="color:#DF2A3F;">x-envoy-retriable-status-codes</font>标头值中定义的响应码匹配时进行重试
    • <font style="color:#DF2A3F;">reset</font>:上游主机完全不响应时(disconnect/reset/read超时),Envoy将进行重试;
    • <font style="color:#DF2A3F;">retriable-headers</font>:如果上游服务器响应报文匹配重试策略或<font style="color:#DF2A3F;"> x-envoy-retriable-header-names</font>标头中包含的任何标头,则Envoy将尝试重试
    • <font style="color:#DF2A3F;">envoy-ratelimited</font>:标头中存在x-envoy-ratelimited时进行重试
  • 重试条件2(同x-envoy-retry-grpc-on标头)
    • <font style="color:#DF2A3F;">cancelled</font>:gRPC应答标头中的状态码是“cancelled”时进行重试
    • <font style="color:#DF2A3F;">deadline-exceeded</font>:gRPC应答标头中的状态码是“deadline-exceeded”时进行重试
    • <font style="color:#DF2A3F;">internal</font>:gRPC应答标头中的状态码是“internal”时进行重试
    • <font style="color:#DF2A3F;">resource-exhausted</font>:gRPC应答标头中的状态码是“resource-exhausted”时进行重试
    • <font style="color:#DF2A3F;">unavailable</font>:gRPC应答标头中的状态码是“unavailable”时进行重试
  • 默认情况下,Envoy不会进行任何类型的重试操作,除非明确定义

2.4.2 修改 frontend 的 virtualservice 配置

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: frontend
spec:
  hosts:
  - "fe.dujie.com"
  - "frontend.dujie.com"
  - "frontend"
  gateways:
  - frontend-gateway   
  - mesh
  http:
  - name: default
    route:
    - destination:
        host: frontend
    timeout: 1s
    retries:       # 添加超时配置,1秒中就超时
      attempts: 5
      perTryTimeout: 1s
      retryOn: 5xx,connect-failure,refused-stream
      
  • **<font style="color:#DF2A3F;">timeout</font>**:
    • 每个 HTTP 请求最多只能处理 1 秒,超时则返回错误。
  • **<font style="color:#DF2A3F;">retries</font>**:
    • 启用重试机制:
      • **<font style="color:#DF2A3F;">attempts</font>**: 5:最多重试5次(总共可能发6次请求:1次原始+5次重试)。
      • **<font style="color:#DF2A3F;">perTryTimeout</font>**: 1s:每次重试最多等1秒,超时就再重试或返回错误。
      • **<font style="color:#DF2A3F;">retryOn</font>**: 5xx,connect-failure,refused-stream:只有响应为5xx、连接失败、被重置时才自动重试。

作用:保证在后端 frontend 服务临时出现 5xx 或网络闪断时,前端请求可以自动快速重试,提高系统的鲁棒性,同时防止单个请求卡太久(配合超时)。

2.4.3 修改 demoapp 的 virtualservice 配置

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - headers:
        x-canary:
          exact: "true"
    route:
    - destination:
        host: demoapp
        subset: v2-canary
      headers:
        request:
          set:
            User-Agent: wget
        response:
          add:
            x-canary: "true"
    fault:
      abort:
        percentage:
          value: 50   # 将比例调整到50%
        httpStatus: 555
  - name: default
    route:
    - destination:
        host: demoapp
        subset: v2
    fault:
      delay:
        percentage:
          value: 50   # 将比例调整到50%
        fixedDelay: 5s

2.4.4 测试

重试操作能解决部分程度上的局部故障,从如下的请求结果中可以看出,在50%的请求上注入“中断”故障的场景中,通过重试有效降低了错误响应的比例

MacBook-Pro:~ root# while true; do CONTENT=$(curl -s -H "x-canary: true" frontend.dujie.com); echo $CONTENT; sleep 0.$RANDOM; done
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-szdbw, Server IP: 172.16.85.217 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-4lkfz, Server IP: 172.16.54.222 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-szdbw, Server IP: 172.16.85.217 ~
Demoapp by iKubernetes! App Version: v2.1-canary, Client IP: 127.0.0.6, Server Name: demoapp-canary-559b56b85f-fhxzq, Server IP: 172.16.58.240 ~

注入了5s延迟的请求中,则直接以超时进行响应

MacBook-Pro:~ root# while true; do curl frontend.dujie.com; sleep 0.$RANDOM; done
upstream request timeoutDemoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-dlc6r, Server IP: 172.16.248.4 ~
Demoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-dlc6r, Server IP: 172.16.248.4 ~
Demoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-ddw4b, Server IP: 172.16.135.191 ~
upstream request timeoutDemoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-h5z7b, Server IP: 172.16.217.111 ~
Demoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-dlc6r, Server IP: 172.16.248.4 ~
Demoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-h5z7b, Server IP: 172.16.217.111 ~
Demoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-dlc6r, Server IP: 172.16.248.4 ~
Demoapp by iKubernetes! App Version: v2.1, Client IP: 127.0.0.6, Server Name: demoapp-59598585bf-h5z7b, Server IP: 172.16.217.111 ~

2.5 HTTP 流量镜像

  • HTTP 流量镜像指的是在将流量转发到原目标地址的同时将流量给另外一个目标地址镜像一份
  • 流量镜像一份到另外一个系统上,完全不会对生产系统产生影响,数据平面的代理只需关注原来转发的流量就可以,不用等待镜像目标地址的返回
  • 用户请求主服务A,Istio会把同样的请求复制一份,同时悄悄发给镜像服务B,B处理后并不返回给用户,仅用于分析和测试。

主要用于:

  1. 新版本回放验证(灰度/影子发布)
    • 在新版本正式切流前,用真实业务流量检测新版本是否兼容、稳定。
  2. 线上问题排查
    • 在不影响用户的情况下,复现场景,辅助定位BUG。
  3. 性能测试与容量评估
    • 通过生产流量镜像,测新服务/新集群的真实承载力。
  4. 安全/合规分析
    • 例如检测新服务是否有异常行为、符合规范等。

关键配置参数:

  1. mirror
    • 指定流量镜像要发送到哪个服务(destination)
  2. mirrorPercentage
    • 可选,指定被镜像的流量百分比(默认 100%),即复制多少比例的主请求。

2.5.1 修改 demoapp 的 virtualService

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: traffic-mirror
    route:
    - destination:
        host: demoapp
        subset: v2
    mirror:
      host: demoapp
      subset: v2-canary  

2.5.2 测试

MacBook-Pro:~ root# while true; do CONTENT=$(curl -s -H "x-canary: true" frontend.dujie.com); echo $CONTENT; sleep 0.$RANDOM; done

可以看到发往 v2 子集的所有流量都会往 v2-canary 子集完整的发送一份

2.6 DestinationRule 常用配置

https://istio.io/latest/docs/reference/config/networking/destination-rule/#TrafficPolicy

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: product-dr
spec:
  host: product-service.svc.cluster.local  # 目标服务(必填)
  # 以下为可选配置
  subsets: []           # 服务子集定义
  trafficPolicy:        # 流量策略(全局/子集级)
    loadBalancer: {}    # 负载均衡策略
    connectionPool: {}  # 连接池设置
    outlierDetection: {} # 异常实例检测
    tls: {}             # TLS设置
    portLevelSettings: [] # 端口级策略

2.6.1 subsets(服务子集)

定义服务的版本/分组,用于金丝雀发布、A/B 测试等场景

subsets:
- name: v1  # 子集名称(VirtualService中引用)
  labels:   # 匹配Pod标签
    version: v1
  trafficPolicy: # 子集专属策略(覆盖全局)
    loadBalancer: { ... }

- name: v2-canary
  labels:
    version: v2
    env: canary

通过标签将服务实例分组,配合 VirtualService 实现流量分割

2.6.2 loadbalancer(负载均衡策略)

支持的算法及参数

trafficPolicy:
  loadBalancer:
    # 简单负载均衡算法(四选一)
    simple: ROUND_ROBIN | LEAST_CONN | RANDOM | PASSTHROUGH
    
    # 一致性哈希(会话保持)
    consistentHash:
      # 请求特征选择(四选一)
      httpHeaderName: "x-user-id"  # 按Header哈希
      httpCookie:                  # 按Cookie哈希
        name: "user-session"
        ttl: 3600s                 # Cookie有效期
        path: "/"                  # Cookie路径
      useSourceIp: true            # 按源IP哈希
      minimumRingSize: 1024        # 最小哈希环大小(默认1024)
      httpQueryParameterName:      # 按照URL查询参数名
      # 哈希算法配置(二选一)
      ringHash:                           # 环哈希算法
        minimumRingSize: 1024             # 最小环大小
        maximumRingSize: 8388608           # 最大环大小(默认8M)
      maglev:                             # Maglev哈希算法
        tableSize: 65537                  # 哈希表大小(质数)

2.6.3 connection pool

Traffic Policy支持connectionPool设定;存在两种类型的pool

2.6.3.1 TCP 连接池配置:
connectionPool:
  tcp:
    maxConnections: 100     # 到目标主机的最大TCP连接数(默认1024)
    connectTimeout: 10ms    # TCP连接超时时间
    tcpKeepalive:           # Keepalive探活
      interval: 75s         # 探测间隔(默认7200s)
      time: 7200s           # 每次探测持续时间
      probes: 3             # 最大探测次数

字段 类型 说明
maxConnections int32 最大HTTP1/TCP连接数到目标主机。默认2^32-1。
connectTimeout Duration TCP连接的超时时间。格式如:1h/1m/1s/1ms。必须≥1ms,默认10秒。
tcpKeepalive TcpKeepalive 是否设置SO_KEEPALIVE套接字选项以启用TCP Keepalives。
maxConnectionDuration Duration 单个连接最大持续时长。从连接建立开始计时,超时后关闭连接。未设置则无最大时长。最小为1ms。
idleTimeout Duration TCP连接的空闲断开时间(读写都没有数据时)。默认1小时,0表示禁用。作为Listener属性,权重路由时仅第一个生效。

TCPSettings 支持如下参数

字段 类型 说明
probes uint32 判断连接死掉前,最多发送的保活探针数量。默认值参考系统级(Linux为9)。
time Duration 空闲多久后开始发送keep-alive探针。默认值使用操作系统配置(Linux为7200s=2小时)。
interval Duration 发送两次keep-alive探针之间的间隔。默认值参考系统级(Linux为75s)。
2.6.3.2 HTTP Pool
  http:
    http1MaxPendingRequests: 1024  # 等待队列长度(默认1024)
    http2MaxRequests: 1024         # 最大请求数(默认1024)
    maxRequestsPerConnection: 32   # 单连接最大请求数(默认无限制)
    maxRetries: 3                  # 最大重试次数(默认1024)
    idleTimeout: 3600s             # 连接空闲超时(默认1h)

字段 类型 说明
http1MaxPendingRequests int32 等待就绪连接池连接的最大排队请求数,默认2^32-1。HTTP1和HTTP2通用。
http2MaxRequests int32 目标主机的最大活跃请求数,默认2^32-1。HTTP1和HTTP2通用。
maxRequestsPerConnection int32 到后端的最大请求数;如设置为1会禁用<font style="color:rgb(51, 54, 57);">keep-alive</font>。默认0(无限制)。
maxRetries int32 给cluster所有主机的最大重试数。默认2^32-1。
idleTimeout Duration 上游连接空闲超时时间,默认1小时。连接空闲超过此时间会关闭。
h2UpgradePolicy H2UpgradePolicy 是否应将HTTP1.1连接升级到HTTP2。
useClientProtocol bool 是否在连接后端时保留客户端协议。如果true,则h2UpgradePolicy失效。
maxConcurrentStreams int32 单一HTTP2连接允许的最大并发流数,默认2^31-1。

2.7 负载均衡配置示例

2.7.1 frontend virtualService 配置:

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: frontend
spec:
  hosts:
  - "fe.dujie.com"
  - "frontend.dujie.com"
  gateways:
  - frontend-gateway
  - mesh
  http:
  - name: default
    match:
    - uri: 
        prefix: /
    route:
    - destination:
        host: frontend
        port:
          number: 80

2.7.2 demoapp virtualService 配置

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - headers:
        x-canary: 
          exact: "true"
    route:
    - destination:
        host: demoapp
        subset: v2-canary
      headers:
        request:
          set:
            User-Agent: wget
        response:
          add:
            x-canary: "true"
  - name: default
    headers:
      response:
        add:
          X-Envoy: test
    route:
    - destination:
        host: demoapp
        subset: v2

2.7.3 demoapp destinationRule 配置:

为 v2 子集启动了 SessionSticky,所有带有"x-user"标头的请求报文,同一标头值得请求都会被调度到同一个后端端点。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
  subsets:
  - name: v2
    labels:
      version: v2.1
    trafficPolicy:
      loadBalancer:
        consistentHash:
          httpHeaderName: x-user
  - name: v2-canary
    labels:
      version: v2.1-canary

2.7.4 测试

进行请求测试;由于proxy不能向后转发标头,因而下面将直接向demoapp发起请求以进行测试

MacBook-Pro:~ root# while true; do curl frontend.dujie.com/hostname; sleep 0.$RANDOM; done
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-dlc6r
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-dlc6r
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-dlc6r
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-dlc6r

为X-User标头使用了不同值的请求,可能被调度至另一端点,但该类请求同样会被sticky至同一端点

MacBook-Pro:~ root# while true; do curl -H "x-user: dujie" frontend.dujie.com/hostname; sleep 0.$RANDOM; done
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b
ServerName: demoapp-59598585bf-h5z7b

更换另一个标头值,请求可能会被分发到另一个后端节点了

MacBook-Pro:~ root# while true; do curl -H "x-user: zhangsan" frontend.dujie.com/hostname; sleep 0.$RANDOM; done
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-ddw4b
ServerName: demoapp-59598585bf-ddw4b

2.8 Connection pool 配置示例

2.8.1 修改 DestinationRule 配置

负载均衡方式

  • <font style="color:rgb(251, 71, 135);">simple: LEAST_CONN</font>
    表示采用最少连接数(Least Connection)方式分配流量,即总是转发给当前活跃连接数最少的后端 Pod。适合请求处理时间长短差异较大场景。

连接池设置

TCP 部分

  • <font style="color:rgb(251, 71, 135);">maxConnections: 100</font>
    单个目的主机(即某个 pod 的 IP:端口)最大并发 TCP/HTTP1 连接数,超过则排队等候。
  • <font style="color:rgb(251, 71, 135);">connectTimeout: 30ms</font>
    TCP 连接建立超时时间为 30 毫秒,超时则视为连接失败。
  • <font style="color:rgb(251, 71, 135);">tcpKeepalive:</font>
    • <font style="color:rgb(251, 71, 135);">time: 7200s</font> 单个连接空闲 7200 秒(2 小时)后才开始发送 keepalive 探针。
    • <font style="color:rgb(251, 71, 135);">interval: 75s</font> 每隔 75 秒发送一次 keepalive 包,检测连接存活状态。

HTTP 部分

  • <font style="color:rgb(251, 71, 135);">http2MaxRequests: 1000</font>
    单一 HTTP2 连接上允许最大并发 1000 个请求。
  • <font style="color:rgb(251, 71, 135);">maxRequestsPerConnection: 10</font>
    每个连接最多允许 10 个 HTTP 请求,之后会关闭该连接(可帮助均衡后端及清理长连接占用)。

subsets:分 subset 配置独立流量策略

定义 demoapp 的子版本,让流量按规则打到不同 Pod 版本。

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
    connectionPool:
      tcp:
        maxConnections: 100
        connectTimeout: 30ms
        tcpKeepalive:
          time: 7200s
          interval: 75s
      http:
        http2MaxRequests: 1000
        maxRequestsPerConnection: 10
  subsets:
  - name: v2
    labels:
      version: v2.1
    trafficPolicy:
      loadBalancer:
        consistentHash:
          httpHeaderName: x-user
  - name: v2-canary
    labels:
      version: v2.1-canary

2.9 outlier Detection 配置示例

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
    connectionPool:
      tcp:
        maxConnections: 100
        connectTimeout: 30ms
        tcpKeepalive:
          time: 7200s
          interval: 75s
      http:
        http2MaxRequests: 1000
        maxRequestsPerConnection: 10
    outlierDetection:
      maxEjectionPercent: 50
      consecutive5xxErrors: 5
      interval: 10s 
      baseEjectionTime: 1m
      minHealthPercent: 40
  subsets:
  - name: v2
    labels:
      version: v2.1
  - name: v2-canary
    labels:
      version: v2.1-canary
  • **<font style="color:rgb(51, 54, 57);">maxEjectionPercent: 50</font>**
    最多可以剔除目标服务实例(pod)的数量不超过所有实例的50%。
  • **<font style="color:rgb(51, 54, 57);">consecutive5xxErrors: 5</font>**
    某实例连续返回5次5xx错误(如500),就认为该实例异常可被剔除。
  • **<font style="color:rgb(51, 54, 57);">interval: 10s</font>**
    检测异常的时间间隔,10秒检查一次。
  • **<font style="color:rgb(51, 54, 57);">baseEjectionTime: 1m</font>**
    实例被剔除的最短时间是1分钟,1分钟后才可以再次被健康检查恢复。
  • **<font style="color:rgb(51, 54, 57);">minHealthPercent: 40</font>**
    剔除后健康实例的最小占比为40%,即使其他实例也异常,也不会再剔除,保证基础可用性。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐