时间:2026-02-04 15:04
人气:
作者:admin
上一小节,istio成功的安装,并且还解决了常见的426的问题,本节内容主要探讨一下istio关于流量转发的问题
需要创建一个backend-v1,它与backend的selector都是app: backend,backend-v1部署完成之后,它会立即分走50%的流量,为了测试istio流控,我们需要在不改变任何配置的情况下实现9:1分流,也就是90%进入原backend,10%进入新的backend-v1

标记2个deployment,追加标签,backend为version: v0,backend-v1为version: v1
kubectl patch deployment backend -p '{"spec":{"template":{"metadata":{"labels":{"version":"v0"}}}}}'
kubectl patch deployment backend-v1 -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}'
创建istio资源:DestinationRule,该资源主要用来标记istio要往哪个地方转发
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: backend-dr
namespace: default
spec:
host: backend-service
subsets:
- labels:
version: v0
name: v0
- labels:
version: v1
name: v1
创建istio资源:VirtualService,该资源用来确定转发的权重
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
http:
- route:
- destination:
host: backend-service
subset: v0
weight: 90
- destination:
host: backend-service
subset: v1
weight: 10
测试命令: for i in {1..10}; do curl -s 10.22.12.178:30785/test > /dev/null ; done
登录到k8s的istio-proxy控制台查看: kubectl logs -f -l app=backend -c istio-proxy
[2026-01-28T08:24:55.670Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
[2026-01-28T08:24:55.687Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
[2026-01-28T08:24:55.706Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:24:55.741Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=1ms route=default
[2026-01-28T08:24:55.751Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:24:55.759Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:24:55.696Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
[2026-01-28T08:24:55.716Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
[2026-01-28T08:24:55.725Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
[2026-01-28T08:24:55.734Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
▶ kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
backend-86b958bdc-5zjgn 2/2 Running 0 21m 10.244.0.53 wilson <none> <none>
backend-v1-75ccff86dc-sl6bt 2/2 Running 0 119s 10.244.0.55 wilson <none> <none>
nginx-test-7d87875694-8vsrp 2/2 Running 0 30m 10.244.0.61 wilson <none> <none>
明显不对,10.244.0.55与10.244.0.53的比例并没有呈现9:1,转发到backend要backend-v1还是5:5
可以直接修改nginx的配置
server {
listen 80;
listen [::]:80;
server_name localhost;
location /test {
proxy_http_version 1.1;
# proxy_set_header Host $host; # 原配置
proxy_set_header Host backend-service.default.svc.cluster.local; # 新配置
proxy_pass http://backend-service:10000;
}
}
重启之后再次测试:
[2026-01-28T08:30:59.968Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:30:59.988Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=1ms route=default
[2026-01-28T08:31:00.027Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=1ms route=default
[2026-01-28T08:31:00.037Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:31:00.048Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:31:00.056Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:31:00.008Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.55:10000 duration=0ms route=default
[2026-01-28T08:31:00.066Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:31:00.074Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
[2026-01-28T08:31:00.083Z] "GET /test HTTP/1.1" 200 - upstream=10.244.0.53:10000 duration=0ms route=default
已经生效了,这次只有1次10.244.0.55:10000
有位大哥说了,如果这样配置的,明显影响了业务:
确实,固定host属于粗暴简单的写法,还有更加惊喜的解决方法,调整VirtualService,添加hosts
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
- api.wilsontest.com # 新增
http:
- route:
- destination:
host: backend-service
subset: v0
weight: 90
- destination:
host: backend-service
subset: v1
weight: 10
客户端访问的时候必须带上该域名: for i in {1..10}; do curl -s -H 'host: api.wilsontest.com' 10.22.12.178:30785/test > /dev/null ; done
这样也可以解决问题,不过坑点也来了,年久失修,从无数前人继承的祖传代码,就需要好好的梳理到底有哪些host来访问,否则漏掉host的话,就会出现配置问题。-_-!
再次凸显了istio之中,host是非常非常重要的,Istio 的路由决策、Service 的匹配完全依赖 Host 头
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
- api.wilsontest.com
http:
- match:
- headers:
hellotest:
exact: "true"
route:
- destination:
host: backend-service
subset: v1
- route:
- destination:
host: backend-service
subset: v0
curl -s -H 'host: api.wilsontest.com' -H 'hellotest: true' 10.22.12.178:30785/test。只有header里面匹配了hellotest: true才会去v1,否则全部去v0
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
- api.wilsontest.com
http:
- match:
- uri:
prefix: /test/v1
route:
- destination:
host: backend-service
subset: v1
- route:
- destination:
host: backend-service
subset: v0
带有/test/v1前缀的都会去新版本v1,满足不了条件都会走默认的版本v0
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: backend-vs
namespace: default
spec:
hosts:
- backend-service
- api.wilsontest.com
http:
- match:
- uri:
prefix: /test/v1
route:
- destination:
host: backend-service
subset: v1
- match:
- uri:
prefix: /test/v2
rewrite:
uri: /test
route:
- destination:
host: backend-service
subset: v0
- route:
- destination:
host: backend-service
subset: v0
如果是/test/v1,就访问v1版本,/test/v2重写成/test并且访问v0版本,其余的默认都会走v0版本
关于流量分流的各种操作,大部分都集中在以下场景:
| 蓝绿发布 | 金丝雀发布 | 灰度发布 | A/B测试 | |
|---|---|---|---|---|
| 主要目标 | 零停机、瞬时回滚 | 用真实流量快速发现技术风险 | 平稳、可控地逐步替换所有用户 | 验证不同版本的业务效果 |
| 流量路由 | 全量切换(100%→0%) | 极小比例引流(如1%-5%) | 按比例分阶段扩大(10%→50%→100%) | 按规则/随机分配(如50%/50%) |
| 关注重点 | 系统可用性与回滚速度 | 系统稳定性指标(错误率、延迟) | 发布过程平稳性与综合反馈 | 业务指标(转化率、留存率) |
| 所需资源 | 两套完整环境,成本高 | 一套环境,新版本实例较少 | 一套环境,新旧版本实例共存 | 一套或多套环境,并行运行多个版本 |
| 用户选择 | 全体用户同时切换 | 小部分用户随机或按基础设施选择 | 用户按比例或属性逐步迁移 | 用户随机分组或按属性定向分配 |
| 持续时间 | 极短(切换在几分钟内) | 短(几小时到一天) | 中长(几天到数周) | 长(数周到数月) |
| 典型场景 | 关键业务大版本升级、基础设施更换 | 后端服务、中间件、数据库变更 | 前端功能、用户界面更新 | UI设计、文案、算法策略、定价优化 |

至此,本文结束
在下才疏学浅,有撒汤漏水的,请各位不吝赐教...
本文来自博客园,作者:it排球君,转载请注明原文链接:https://www.cnblogs.com/MrVolleyball/p/19574573
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。