当前位置: 首页 > news >正文

十八、k8s细粒度流量管理:服务网格

十八、k8s细粒度流量管理:服务网格

文章目录

  • 十八、k8s细粒度流量管理:服务网格
    • 1、服务网格
      • 1.1 服务网格初识
      • 1.2 服务网格核心功能
    • 2、Istio初识
      • 2.1 什么是Istio?
      • 2.2 Istio功能
      • 2.3 Istio架构平台
      • 2.4 Istio Sidecar和Ambient模式对比
      • 2.5 Istio控制平面组件介绍
      • 2.6 Istio数据平面组件介绍
      • 2.7 Istio核心资源DestinationRule介绍
      • 2.8 Istio核心资源VirtualService介绍
      • 2.9 Istio核心资源Gateway介绍
      • 2.10 Istio核心资源关系总结
    • 3、Istio 安装
      • 3.1 使用 istioctl 部署 Istio
      • 3.2 Istio 自动注入 Sidecar
        • 3.2.1 Namespace 级别
        • 3.2.2 Pod 级别
      • 3.3 可视化工具 Kiali
      • 3.4 Prometheus 和 Grafana
    • 4、Istio 流量治理实践
      • 4.1 部署 Istio 测试用例
      • 4.2 使用 Istio 发布项目
      • 4.3 Istio 地址重写和重定向
      • 4.4 Istio 实现灰度部署
      • 4.5 Istio 实现 AB 测试
      • 4.6 Istio 负载均衡算法
      • 4.7 Istio 熔断
      • 4.8 Istio 注入延迟故障
      • 4.9 Istio 注入中断故障
    • 5、企业内项目接入 Istio 流程
      • 5.1 部署企业测试项目
        • 5.1.1 部署 mysql 服务
        • 5.1.2 部署 order 服务
        • 5.1.3 部署 handler 服务
        • 5.1.4 部署 receive 服务
        • 5.1.5 部署 前端ui 服务
      • 5.2 Istio 南北流量网关改造
        • 5.2.1 创建Gateway
        • 5.2.2 改造 order 服务的 Ingress 为 VirtualService
        • 5.2.3 改造 receive 服务的 Ingress 为 VirtualService
        • 5.2.4 改造 前端ui 服务的 Ingress 为 VirtualService
      • 5.3 Istio 东西流量改造

1、服务网格

1.1 服务网格初识

Service Mesh(服务网格)是由Buoyant公司的CEO William Morgan发起,目标为解决微服务之间复杂的链路关系

Service Mesh将程序开发的网络功能和程序本身解耦,网络功能下沉到基础架构,由服务网格实现服务之间的负载均衡等功能,并且除网络功能外,也提供了其他更高级的功能,比如全链路加密、监控、链路追踪等。

1.2 服务网格核心功能

  • 负载均衡
  • 服务发现
  • 熔断降级
  • 动态路由
  • 故障注入
  • 错误重试
  • 安全通信
  • 语言无关

2、Istio初识

2.1 什么是Istio?

Istio是一个开源的服务网格(Service Mesh)产品,专为微服务架构设计,用于透明地管理服务间通信、安全、监控和流量策略。Istio通过Sidecar拦截并控制服务间的所有流量,将复杂的微服务治理(如流量管理、安全策略)从业务代码中剥离,并下沉到基础设施层,使开发者更专注于业务逻辑,以提升开发效率。

2.2 Istio功能

Istio几乎无需修改任何代码就可以实现如下功能:

  • 双向TLS加密
  • HTTP、gRPC、WebSocket和TCP流量的自动负载均衡
  • 错误重试、故障转移和故障注入等
  • 访问控制、限流、认证、鉴权等
  • 可观测性指标、链路追踪、日志等
  • 集群内入口和出口的流量管理

2.3 Istio架构平台

Istio从逻辑上分数据平面和控制平面:

  • 控制平面:Control Plane负责管理和配置数据平面的流量策略,由管理员创建的Istio资源会解析成相关的配置下发到数据平面
  • 数据平面:Data Plane负责拦截并处理所有入站(Inbound)和出站(Outbound)流量,用来执行由控制平台下发的策略,比如路由、负载均衡、重试、熔断、TLS加密等,同时数据平台还可以收集流量目标、日志和追踪数据,并发送给监控系统。
    • Sidecar模式:此模式会为集群中启动的每个pod都部署一个Envoy代理,或者为在虚拟机上运行的服务运行一个Envoy代理
    • Ambient模式:此模式在每个节点上启动一个四层代理,也可以为每个命名空间启动一个Envoy代理实现七层功能(1.22版本之后新加入的)

在这里插入图片描述

2.4 Istio Sidecar和Ambient模式对比

对比项对比维度Sidecar模式Ambient模式
核心架构
代理部署方式每个Pod注入一个Envoy Sidecar容器分层部署:
L4:每个阶段部署一个Ztunnel代理
L7:每个空间部署一个或多个Waypoint代理
流量管理通过iptables/IPVS规则劫持Pod的进出流量四层由Ztunnel处理,七层由Waypoint处理
覆盖范围所有注入Sidecar的Pod默认纳入所有Pod,无需添加任何注解
故障可用性只影响某个故障的Pod影响当前节点或当前空间下的所有服务
资源开销
代理数量每一个Pod一个EnvoyZtunnel:每一个节点一个代理
Waypoint:通常每个命名空间一个或多个
内存/CPU消耗较高较低
启动延迟Pod启动需等待Sidecar就绪Pod启动无需等待代理,延迟更低
性能对比调用延迟每个请求经过两次Ztunnel代理L4经过Ztunnel,L7经过由Waypoint,可能更多

2.5 Istio控制平面组件介绍

Istiod为Istio的控制平面,提供服务发现、配置、证书管理、加密通信和认证。早期的Istio控制平台并没有Istiod这个容器,而是由Mixer(新版本已废弃)、Pilot、Citadel共同组成,后来为了简化Istio的架构,将其合并为Istiod,所有对新版本的Istio(V1.5+),部署后仅能看见Istiod一类Pod。

  • Pilot:主要用于监听APIServer,动态获取集群中Service和Endpoints信息,并将配置的路由规则、负载均衡策略转换为Envoy可理解的配置,并下发至各个Sidecar中
  • Citadel:主要用于提供强大的服务与服务之间的最终用户身份验证,可用于升级服务网格中未加密的流量,实现双向TLS加密
  • Galley:负责配置管理的组件,用于验证配置信息的格式和正确性。galley使用网格配置协议(Mesh Configuration Protocol)和其它组件进行配置的交互

在这里插入图片描述

2.6 Istio数据平面组件介绍

Istio的数据平面使用的是Envoy,Envoy是用C++开发的高性能代理,用于调解服务网格中所有服务的所有入站和出站流量。Envoy代理是唯一一个与数据平面流量交互的Istio组件,并以Sidecar的方式注入到网格中的每一个Pod中。

主要提供如下功能:

  • 动态服务发现
  • 负载均衡
  • HTTP/2 & gRPC代理
  • 熔断器
  • 健康检查
  • 基于百分比流量拆分的灰度发布
  • 故障注入
  • 丰富的度量指标

在这里插入图片描述

2.7 Istio核心资源DestinationRule介绍

DestinationRule:目标规划,主要用于将服务划分为多个版本(子集),同时可以对不同的版本进行配置负载均衡和连接池等策略。

使用场景:

  • 版本划分:根据标签划分同一个服务的不同版本
  • 负载均衡策略:支持配置各种负载均衡算法(如轮询、随机、最少连接)
  • 熔断器:支持配置最大连接数、熔断等

在这里插入图片描述

2.8 Istio核心资源VirtualService介绍

VirtualService:虚拟主机,是Istio路由规则的核心,用于控制流量走向,和Ingress类似,支持HTTP、gRPC、TCP等协议。通常和DestinationRule结合实现更细粒度的流量分配。

主要应用场景:

  • 灰度发布:支持基于比例的流量分配
  • A/B测试:支持基于请求头、URI、权重等条件的流量分配
  • 重试:支持错误重试、故障注入、链接超时等策略

在这里插入图片描述

2.9 Istio核心资源Gateway介绍

Gateway:网关,Istio集群的出入口网关,主要用于处理对外的流量。通常和VirtualService结合实现内外流量的统一治理。

主要应用场景:

  • 端口监听:可根据协议指定对外暴露的端口
  • TLS:可以添加域名证书提供http访问
  • 域名:可以根据域名进行路由分发
  • 出口管控:可以将出口的流量固定从EgressGateway的服务中代理出去

在这里插入图片描述

2.10 Istio核心资源关系总结

  • DestinationRule:定义服务子集和流量策略,路由的最终目标。
  • VirtualService:路由规则的核心,控制流量去向。
  • Gateway:管理外部流量入口和出口,与VirtualService协同实现内外流量统一治理

在这里插入图片描述

3、Istio 安装

版本选择: https://istio.io/latest/docs/releases/supported-releases/#support-status-of-istioreleases

3.1 使用 istioctl 部署 Istio

首先下载 Istio 的安装包:

# 下载 Istio 的安装包
[root@k8s-master01 ~]# wget https://github.com/istio/istio/releases/download/1.26.0/istio-1.26.0-linux-amd64.tar.gz# 解压后,将 Istio 的客户端工具 istioctl,移动到/usr/local/bin 目录下:
[root@k8s-master01 ~]# tar xf istio-1.26.0-linux-amd64.tar.gz 
[root@k8s-master01 ~]# mv istio-1.26.0/bin/istioctl /usr/local/bin/# 查看安装版本,这个报错是因为还没有安装istio-system
[root@k8s-master01 ~]# istioctl version
Istio is not present in the cluster: no running Istio pods in namespace "istio-system"
client version: 1.26.0

之后通过定义 IstioOperator 资源,在 Kubernetes 中安装 Istio:

[root@k8s-master01 ~]# cd istio-1.26.0
[root@k8s-master01 istio-1.26.0]# vim istio-operator.yaml 
[root@k8s-master01 istio-1.26.0]# cat istio-operator.yaml 
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:name: example-istionamespace: istio-system
spec:components:base:enabled: truecni:enabled: falseegressGateways:- enabled: falsename: istio-egressgatewaypilot:k8s:hpaSpec:minReplicas: 2        # 默认为 1maxReplicas: 5        # 默认为 5resources:              # 注意资源配置,练习环境可以把 requests 调小limits:cpu: "2"memory: 2Girequests:cpu: "100m"         # 生产环境调整为 2Gimemory: 512Mi       # 生产环境调整为 2Gi ingressGateways:- enabled: truename: istio-ingressgatewayk8s:hpaSpec:minReplicas: 2        # 默认为 1maxReplicas: 5        # 默认为 5resources:              # 注意资源配置,练习环境可以把 requests 调小limits:cpu: "2"memory: 2Girequests:cpu: "100m"         # 生产环境调整为 2Gimemory: 512Mi       # 生产环境调整为 2Giservice:type: NodePort        # 将 Service 类型改成 NodePortports:- port: 15020nodePort: 30520name: status-port- port: 80            # 流量入口 80 端口映射到 NodePort 的 30080,之后通过节点IP+30080 即可访问 Istio 服务nodePort: 30080name: http2targetPort: 8080- port: 443nodePort: 30443name: httpstargetPort: 8443hub: m.daocloud.io/docker.io/istiomeshConfig:accessLogEncoding: JSONaccessLogFile: /dev/stdoutprofile: default

更多 Istio 安装配置:https://istio.io/latest/docs/setup/additional-setup/customize-installation/

安装 Istio:

[root@k8s-master01 istio-1.26.0]# istioctl install -f istio-operator.yaml |\          | \         |  \        |   \       /||    \      / ||     \     /  ||      \    /   ||       \   /    ||        \  /     ||         \ 
/______||__________\
____________________\__       _____/  \_____/        This will install the Istio 1.26.0 profile "default" into the cluster. Proceed? (y/N) y
✔ Istio core installed ⛵️                                                                            
✔ Istiod installed 🧠                                                                                
✔ Ingress gateways installed 🛬                                                                      
✔ Installation complete          

查看创建的 Service 和 Pod:

[root@k8s-master01 istio-1.26.0]# kubectl get pod,svc -n istio-system
NAME                                       READY   STATUS    RESTARTS   AGE
pod/istio-ingressgateway-d97b99d5d-czzp7   1/1     Running   0          103s
pod/istio-ingressgateway-d97b99d5d-wtbjl   1/1     Running   0          88s
pod/istiod-554d99f48b-7xfhs                1/1     Running   0          111s
pod/istiod-554d99f48b-wz7kn                1/1     Running   0          97sNAME                           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
service/istio-ingressgateway   NodePort    10.103.74.144   <none>        15020:30520/TCP,80:30080/TCP,443:30443/TCP   103s
service/istiod                 ClusterIP   10.101.187.27   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        112s

3.2 Istio 自动注入 Sidecar

Istio 注入 Sidecar 的常用方式有两种:

  • Namespace 级别:添加 istio-injection=enabled(disabled关闭自动注入)的标签到指
    定的 Namespace,那么该 Namespace 下的 Pod 都会被自动注入一个 Sidecar
  • Pod 级别:添加 sidecar.istio.io/inject=true(false 关闭自动注入)的标签到指定的 Pod,那么该 Pod 会被注入一个 Sidecar
3.2.1 Namespace 级别

接下来创建一个测试的 Namespace,并添加一个 istio-injection=enabled 的标签,之后在该 Namespace 下创建 Pod,测试 Istio Sidecar 的自动注入。

# 创建 Namespace 并添加 Label:
[root@k8s-master01 istio-1.26.0]# kubectl create ns istio-test
[root@k8s-master01 istio-1.26.0]# kubectl label namespace istio-test istio-injection=enabled

切换目录至 istio 的安装包,然后创建测试应用,此时创建的 Pod 会被自动注入一个istioproxy 的容器:


# 更改测试服务的镜像地址
[root@k8s-master01 istio-1.26.0]# sed -i 's|image: curlimages|image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01|' samples/sleep/sleep.yaml[root@k8s-master01 istio-1.26.0]# grep -rn "image:" samples/sleep/sleep.yaml
55:        image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/curl# 创建测试服务
[root@k8s-master01 istio-1.26.0]# kubectl create -f samples/sleep/sleep.yaml -n istio-test
# 查看部署的容器:
[root@k8s-master01 istio-1.26.0]# kubectl get po -n istio-test
NAME                    READY   STATUS    RESTARTS   AGE
sleep-85fb677ff-57n27   2/2     Running   0          43s

查看 Pod 详情:

[root@k8s-master01 istio-1.26.0]# kubectl describe po sleep-85fb677ff-57n27 -n istio-test

在这里插入图片描述

如果想要关闭该 Namespace 的自动注入,直接去除标签即可(已注入的 Pod 不受影响, 下次重建后,不再有 isito-proxy 的容器):

[root@k8s-master01 istio-1.26.0]# kubectl label namespace istio-test istio-injection-# 此时 Pod 不受影响:
[root@k8s-master01 istio-1.26.0]# kubectl get po -n istio-test
NAME                    READY   STATUS    RESTARTS   AGE
sleep-85fb677ff-57n27   2/2     Running   0          30m# 重建后不会再有 istio-proxy:
[root@k8s-master01 istio-1.26.0]# kubectl delete po sleep-85fb677ff-57n27 -n istio-test[root@k8s-master01 istio-1.26.0]# kubectl get po -n istio-test
NAME                    READY   STATUS    RESTARTS   AGE
sleep-85fb677ff-bjjdg   1/1     Running   0          11s

如果某个服务不想被 istio 注入,可以添加 sidecar.istio.io/inject=false 的标签即可:

[root@k8s-master01 istio-1.26.0]# cat samples/sleep/sleep.yaml 
....template:metadata:labels:app: sleepsidecar.istio.io/inject: "false"spec:terminationGracePeriodSeconds: 0serviceAccountName: sleep
....
3.2.2 Pod 级别

如果需要给 Pod 单独添加 istio-proxy,可以给 Pod 添加 sidecar.istio.io/inject=true 标签即可:

[root@k8s-master01 istio-1.26.0]# vim samples/sleep/sleep.yaml 
[root@k8s-master01 istio-1.26.0]# cat samples/sleep/sleep.yaml 
....template:metadata:labels:app: sleepsidecar.istio.io/inject: "true"spec:terminationGracePeriodSeconds: 0serviceAccountName: sleep
....[root@k8s-master01 istio-1.26.0]# kubectl replace -f samples/sleep/sleep.yaml -n istio-test[root@k8s-master01 istio-1.26.0]# kubectl get po -n istio-test
NAME                    READY   STATUS    RESTARTS   AGE
sleep-774748f5b-tnvhh   2/2     Running   0          30s

3.3 可视化工具 Kiali

Kiali 为 Istio 提供了可视化的界面,可以在 Kiali 上进行观测流量的走向、调用链,同时还可以使用 Kiali 进行配置管理,给用户带来了很好的体验。

接下来在 Kubernetes 中安装 Kiali 工具:

# 修改 kiali 的 Service 类型为 NodePor
[root@k8s-master01 istio-1.26.0]# vim samples/addons/kiali.yaml
[root@k8s-master01 istio-1.26.0]# cat samples/addons/kiali.yaml
....
apiVersion: v1
kind: Service
metadata:name: kialinamespace: "istio-system"
....annotations:
spec:type: NodePort
....# 安装Kiali服务
[root@k8s-master01 istio-1.26.0]# kubectl create -f samples/addons/kiali.yaml# 查看部署状态:
[root@k8s-master01 istio-1.26.0]# kubectl get po,svc -n istio-system -l app=kiali
NAME                         READY   STATUS    RESTARTS   AGE
pod/kiali-6d774d8bb8-ckszt   1/1     Running   0          110sNAME            TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                          AGE
service/kiali   NodePort   10.106.203.41   <none>        20001:31365/TCP,9090:32392/TCP   110s

之后可以通过 任意IP+31365 访问 Kiali 服务:

在这里插入图片描述

除了 Kiali 之外,还可以安装一个链路追踪的工具,安装该工具可以在 Kiali 的 Workloads 页面,查看某个服务的 Traces 信息:

# 首先更改镜像地址
[root@k8s-master01 istio-1.26.0]# sed -i 's|docker.io/jaegertracing|crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01|' samples/addons/jaeger.yaml [root@k8s-master01 istio-1.26.0]# grep -rn "image:" samples/addons/jaeger.yaml 
23:          image: "crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/all-in-one:1.67.0"# 创建服务
[root@k8s-master01 istio-1.26.0]# kubectl create -f samples/addons/jaeger.yaml
# 查看部署状态:
[root@k8s-master01 istio-1.26.0]# kubectl get po,svc -n istio-system -l app=jaeger
NAME                          READY   STATUS    RESTARTS   AGE
pod/jaeger-6498f6596f-tcbq8   1/1     Running   0          73sNAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                          AGE
service/jaeger-collector   ClusterIP   10.98.59.72     <none>        14268/TCP,14250/TCP,9411/TCP,4317/TCP,4318/TCP   73s
service/tracing            ClusterIP   10.96.238.231   <none>        80/TCP,16685/TCP                                 73s

3.4 Prometheus 和 Grafana

Istio 默认暴露了很多监控指标,比如请求数量统计、请求持续时间以及 Service 和工作负载的指标,这些指标可以使用 Prometheus 进行收集,Grafana 进行展示。

Istio内置了Prometheus 和Grafana的安装文件,直接安装即可(也可以使用外置的 Prometheus 和 Grafana):

# 同样需要修改镜像地址
[root@k8s-master01 istio-1.26.0]# sed -i 's|image: "prom|image: "crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01|' samples/addons/prometheus.yaml [root@k8s-master01 istio-1.26.0]# sed -i 's|docker.io/grafana|crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01|' samples/addons/grafana.yaml[root@k8s-master01 istio-1.26.0]# grep -rn "image:" samples/addons/prometheus.yaml samples/addons/grafana.yaml 
samples/addons/prometheus.yaml:487:          image: "ghcr.io/prometheus-operator/prometheus-config-reloader:v0.81.0"
samples/addons/prometheus.yaml:515:          image: "crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/prometheus:v3.2.1"
samples/addons/grafana.yaml:142:          image: "crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/grafana:11.3.1"
# 将 Service 类型改成 NodePort
[root@k8s-master01 istio-1.26.0]# sed -i "s|ClusterIP|NodePort|" samples/addons/prometheus.yaml
[root@k8s-master01 istio-1.26.0]# sed -i "s|ClusterIP|NodePort|" samples/addons/grafana.yaml [root@k8s-master01 istio-1.26.0]# grep -rn NodePort samples/addons/prometheus.yaml samples/addons/grafana.yaml 
samples/addons/prometheus.yaml:445:  type: "NodePort"
samples/addons/grafana.yaml:93:  type: NodePort
# 修改时区
[root@k8s-master01 istio-1.26.0]# sed -i 's/"timezone":"utc"/"timezone": "Asia\/Shanghai"/g' samples/addons/grafana.yaml
# 创建服务
[root@k8s-master01 istio-1.26.0]# kubectl create -f samples/addons/prometheus.yaml -f samples/addons/grafana.yaml# 查看部署状态:
[root@k8s-master01 istio-1.26.0]#  kubectl get po,svc -n istio-system | egrep "prometheus|grafana"
pod/grafana-5574c54c77-wf6zh               1/1     Running   0          36s
pod/prometheus-687c9cbcd7-kbdsj            2/2     Running   0          36s
service/grafana                NodePort    10.102.66.151   <none>        3000:31875/TCP                                   36s
service/prometheus             NodePort    10.108.187.88   <none>        9090:31225/TCP                                   36s

同样的方式,将 Grafana 的 Service 改成 NodePort 或者添加 Ingress,之后访问即可:

在这里插入图片描述

默认监控模版

在这里插入图片描述

4、Istio 流量治理实践

4.1 部署 Istio 测试用例

Bookinfo 项目介绍:https://istio.io/latest/docs/examples/bookinfo/

首先在 Kubernetes 集群中,部署 Bookinfo 项目。

Istio 提供了用于测试功能的应用程序 Bookinfo,可以直接通过下述命令创建 Bookinfo:

# 创建 Namespace 并添加 Label:
[root@k8s-master01 istio-1.26.0]# kubectl create ns bookinfo
[root@k8s-master01 istio-1.26.0]# kubectl label ns bookinfo istio-injection=enabled
# 修改镜像地址
[root@k8s-master01 istio-1.26.0]# sed -i 's|docker.io/istio|crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01|' samples/bookinfo/platform/kube/bookinfo.yaml [root@k8s-master01 istio-1.26.0]# grep "image:" samples/bookinfo/platform/kube/bookinfo.yaml image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/examples-bookinfo-details-v1:1.20.3image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/examples-bookinfo-ratings-v1:1.20.3image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/examples-bookinfo-reviews-v1:1.20.3image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/examples-bookinfo-reviews-v2:1.20.3image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/examples-bookinfo-reviews-v3:1.20.3image: crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/examples-bookinfo-productpage-v1:1.20.3# 创建Bookinfo服务
[root@k8s-master01 istio-1.26.0]# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo# 查看部署的 Pod 和 Service:
[root@k8s-master01 istio-1.26.0]# kubectl get po,svc -n bookinfo
NAME                                  READY   STATUS    RESTARTS   AGE
pod/details-v1-859dcddd6d-lxxlm       2/2     Running   0          87s
pod/productpage-v1-5f8d8bf969-tdfqn   2/2     Running   0          87s
pod/ratings-v1-68dcbc5d5b-dk47p       2/2     Running   0          87s
pod/reviews-v1-874fd588-kkwz9         2/2     Running   0          87s
pod/reviews-v2-cb8778f48-5gglc        2/2     Running   0          87s
pod/reviews-v3-5998b9d9dd-g49vt       2/2     Running   0          87sNAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/details       ClusterIP   10.96.115.151    <none>        9080/TCP   87s
service/productpage   ClusterIP   10.98.96.114     <none>        9080/TCP   87s
service/ratings       ClusterIP   10.106.215.139   <none>        9080/TCP   87s
service/reviews       ClusterIP   10.100.32.85     <none>        9080/TCP   87s
# 之后可以通过 productpage Service 的 ClusterIP 访问 Bookinfo 项目:
[root@k8s-master01 istio-1.26.0]# curl 10.98.96.114:9080<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
....

4.2 使用 Istio 发布项目

接下来创建 Istio 的 Gateway 和 VirtualService 实现域名访问 Bookinfo 项目。

首先创建 Gateway,假设发布的域名是 bookinfo.kubeasy.com

[root@k8s-master01 istio-1.26.0]# vim samples/bookinfo/networking/bookinfo-gateway.yaml
[root@k8s-master01 istio-1.26.0]# cat samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1      # Gateway 配置如下所示
kind: Gateway
metadata:name: bookinfo-gateway
spec:selector:istio: ingressgateway # use istio default controllerservers:- port:number: 80name: httpprotocol: HTTPhosts:- "bookinfo.kubeasy.com"        # 发布域名
---
apiVersion: networking.istio.io/v1      # 接下来配置 VirtualService,实现对不同微服务的路由
kind: VirtualService
metadata:name: bookinfo
spec:hosts:- "bookinfo.kubeasy.com"          # 发布域名gateways:- bookinfo-gatewayhttp:- match:- uri:exact: /productpage- uri:prefix: /static- uri:exact: /login- uri:exact: /logout- uri:prefix: /api/v1/productsroute:- destination:host: productpageport:number: 9080
# 创建资源
[root@k8s-master01 istio-1.26.0]# kubectl create -f samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo# 查看资源:
[root@k8s-master01 istio-1.26.0]# kubectl get gw,vs -n bookinfo
NAME                                           AGE
gateway.networking.istio.io/bookinfo-gateway   58sNAME                                          GATEWAYS               HOSTS                      AGE
virtualservice.networking.istio.io/bookinfo   ["bookinfo-gateway"]   ["bookinfo.kubeasy.com"]   58s

接下来将域名 bookinfo.kubeasy.com 解析至集群任意一个安装了 kube-proxy 的节点 IP 上,然后通过 ingressgateway 的 Service 的 NodePort 即可访问到 Bookinfo:

[root@k8s-master01 istio-1.26.0]# kubectl get svc -n istio-system istio-ingressgateway
NAME                   TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
istio-ingressgateway   NodePort   10.103.74.144   <none>        15020:30520/TCP,80:30080/TCP,443:30443/TCP   5h1m

绑定 hosts 后,通过 bookinfo.kubeasy.com+ingressgateway 80 端口的 NodePort 即可访问该服务,比如本次示例的 http://bookinfo.kubeasy.com:30080/productpage:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

多次刷新可以看到 Reviewer 处的星星会在黑色、红色和消失之间来回替换,是因为之前部署了三个不同版本的 reviews,每个版本具有不同的显示效果.

此时通过 Kiali 页面可以看到 Bookinfo 的调用链路:

在这里插入图片描述

4.3 Istio 地址重写和重定向

Istio 同样支持访问地址的重写和重定向,详细配置->:

比如将 bookinfo.kubeasy.com/yunwei,跳转到 blog.csdn.net/weixin_43279138?type=blog

[root@k8s-master01 istio-1.26.0]# kubectl edit vs bookinfo -n bookinfo
....
spec:gateways:- bookinfo-gatewayhosts:- bookinfo.kubeasy.comhttp:- match:- uri:prefix: /yunwei                     # 匹配/yunweiredirect:authority: blog.csdn.net              # 跳转的域名uri: /weixin_43279138?type=blog       # 跳转的路径- match:- uri:exact: /productpage
....

通过浏览器访问 http://bookinfo.kubeasy.com:30080/yunwei(如果是学习环境需要加上端口号)即可跳转
到 https://blog.csdn.net/weixin_43279138?type=blog。当然也可以用 curl 进行测试:

[root@k8s-master01 istio-1.26.0]# curl -H "Host:bookinfo.kubeasy.com" 192.168.200.50:30080/yunwei -I
HTTP/1.1 301 Moved Permanently
location: http://blog.csdn.net/weixin_43279138?type=blog
date: Tue, 29 Jul 2025 12:08:22 GMT
server: istio-envoy
transfer-encoding: chunked

Istio 地址重写可用于多个后端的路由,比如将/paymentapi/重写为/,此时就可以通过 VirtualService 实现。

Istio 地址重写配置方式和重定向类似,假如将/重写为/productpage,配置如下:

[root@k8s-master01 istio-1.26.0]# kubectl edit vs bookinfo -n bookinfo
....
spec:gateways:- bookinfo-gatewayhosts:- bookinfo.kubeasy.comhttp:- match:- uri:exact: /                # 匹配根路径rewrite:uri: /productpage         # 重写为/productpageroute:- destination:host: productpageport:number: 9080
....

保存退出后,访问 bookinfo.kubeasy.com 即可打开 bookinfo 的页面(未配置地址重写前,访问根路径会限制 404 错误)。

在这里插入图片描述

4.4 Istio 实现灰度部署

使用 Istio 进行细粒度的流量管理,需要使用 DestinationRule 资源对不同标签的 Pod 划分版本。

首先通过 DestinationRule 将 reviews 分成三个版本:

[root@k8s-master01 istio-1.26.0]# mkdir bookinfo
[root@k8s-master01 istio-1.26.0]# cd bookinfo/
[root@k8s-master01 bookinfo]# vim reviews-dr.yaml
[root@k8s-master01 bookinfo]# cat reviews-dr.yaml
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:name: reviews
spec:host: reviewssubsets:- name: v1labels:version: v1       # subset v1 指向具有 version=v1 的 Pod- name: v2labels:version: v2       # subset v2 指向具有 version=v2 的 Pod- name: v3labels:version: v3       # subset v3 指向具有 version=v3 的 Pod# 创建并查看该 DestinationRule:
[root@k8s-master01 bookinfo]# kubectl create -f reviews-dr.yaml -n bookinfo# 查看资源:
[root@k8s-master01 bookinfo]# kubectl get dr -n bookinfo
NAME      HOST      AGE
reviews   reviews   20s

此时只是创建了 DestinationRule,并没有做任何限制,所以通过浏览器访问该服务时,并没有什么变化。但是 Kiali 中可以看到 reviews 变成了三个版本:

在这里插入图片描述

接下来使用 VirtualService 将所有访问 reviews 服务的流量指向 reviews 的 v1 版本:

[root@k8s-master01 bookinfo]# vim reviews-v1-all.yaml
[root@k8s-master01 bookinfo]# cat reviews-v1-all.yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: reviews
spec:hosts:- reviewshttp:- route:- destination:host: reviewssubset: v1          # 将流量指向 v1# 创建该 VirtualService
[root@k8s-master01 bookinfo]# kubectl create -f reviews-v1-all.yaml -n bookinfo

此时再次刷新浏览器,Reviews 处不再显示评分:

在这里插入图片描述

同时 Kiali 也不再显示 reviews 服务调用 ratings 服务:

在这里插入图片描述

假如有新版本上线,不想直接接入所有流量,可以使用 VirtualService 控制流量分配比例,比如将 20%的流量路由到 v2 版本,其余的流量依旧路由到 v1 版本:

[root@k8s-master01 bookinfo]# vim reviews-80v1-20v2.yaml 
[root@k8s-master01 bookinfo]# cat reviews-80v1-20v2.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: reviews
spec:hosts:- reviewshttp:- route:- destination:host: reviewssubset: v1weight: 80            # 将 80%流量指向 v1- destination:host: reviewssubset: v2  weight: 20            # 将 20%流量指向 v2# 更新该 VirtualService
[root@k8s-master01 bookinfo]# kubectl replace -f reviews-80v1-20v2.yaml -n bookinfo

再次使用浏览器访问时,会有 20%的访问会出现评分(仅有黑色):

在这里插入图片描述

此时从 Kiali 页面即可看到 v2 版本的 review 调用 ratings:

在这里插入图片描述

假设新版本已经没有任何问题,可以将流量全部指向新版本

4.5 Istio 实现 AB 测试

stio 也支持基于请求头、uri、schema 等方式的细粒度流量管理,这种路由方式比较适用于新版本上线时的 AB 测试。

Istio 请求头匹配介绍:

假如又开发了一个新版,此时只想要公司内部先进行测试,可以配置 VirtualService 指定部分用户访问新版本。

再次修改 reviews 的 VirtualService,将 jason 用户指向 v3,其他用户依旧使用 v2 版本:

[root@k8s-master01 bookinfo]# vim reviews-jasonv3.yaml 
[root@k8s-master01 bookinfo]# cat reviews-jasonv3.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: reviews
spec:hosts:- reviewshttp:- match:- headers:end-user:exact: jasonroute:- destination:host: reviewssubset: v3- route:- destination:host: reviewssubset: v2# 更新该 VirtualService
[root@k8s-master01 bookinfo]# kubectl replace -f reviews-jasonv3.yaml -n bookinfo

接下来首先登录 非 jason 用户, 可以看到页面只显示黑色五角星:

在这里插入图片描述

接下来登录 jason 用户,登录后页面评分只显示红色:

在这里插入图片描述

4.6 Istio 负载均衡算法

Istio 原生支持多种负载均衡算法,比如 ROUND_ROBIN、LEAST_REQUEST、LEAST_CONN、RANDOM 等。假如一个应用存在多个副本(Pod),可以使用上述算法对多个 Pod 进行定制化的负载均衡配置

常见的负载均衡策略如下:

  • ROUND_ROBIN:轮询算法,将请求依次分配给每一个实例,不推荐使用;
  • LEAST_REQUEST:最小链接算法,从池中随机选择两个实例,并将请求路由给当前活跃请求数较少的那个主机;
  • RANDOM:随机算法,将请求随机分配给其中一个实例;
  • PASSTHROUGH:将连接转发到调用者请求的原始 IP 地址,而不进行任何形式的负载均衡,目前不推荐使用;
  • UNSPECIFIED:未指定负载均衡算法,Istio 将选择一个合适的默认算法,不推荐使用。

首先去除之前配置的一些路由策略,之后观看 Kiali 中 reviews 的流量分配:

[root@k8s-master01 bookinfo]# kubectl delete vs -n bookinfo reviews

在这里插入图片描述

此时可以看到流量分配比较低的实例多次访问会慢慢提高,符合最小连接数的算法。接下来将算法改成 RANDOM(生产环境建议使用 LEAST_REQUEST):

[root@k8s-master01 bookinfo]# vim reviews-dr.yaml 
[root@k8s-master01 bookinfo]# cat reviews-dr.yaml 
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:name: reviews
spec:trafficPolicy:        # 添加路由策略,在 spec 下对所有的 subset 生效,也可以在 subset 中配置loadBalancer:       # 配置负载均衡simple: RANDOM    # 策略为 RANDOMhost: reviewssubsets:- name: v1labels:version: v1- name: v2labels:version: v2- name: v3labels:version: v3[root@k8s-master01 bookinfo]# kubectl replace -f reviews-dr.yaml -n bookinfo

在这里插入图片描述

4.7 Istio 熔断

Istio 支持熔断机制,可以实现在高并发时对服务进行过载保护。

假设对 ratings 进行熔断,希望在并发请求数超过 3,并且存在 1 个以上的待处理请求,就触发熔断,此时可以配置 ratings 的 DestinationRule 如下所示:

[root@k8s-master01 bookinfo]# vim ratings-dr.yaml
[root@k8s-master01 bookinfo]# cat ratings-dr.yaml 
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:name: ratingsnamespace: bookinfo
spec:host: ratingstrafficPolicy:               # trafficPolicy 配置,可以配置在 subsets 级别connectionPool:            # 连接池配置,可以单独使用限制程序的并发数tcp:maxConnections: 3      # 最大并发数为 3http:http1MaxPendingRequests: 1      # 最大的待处理请求outlierDetection:               # 熔断探测配置consecutive5xxErrors: 1       # 如果连续出现的错误超过 1 次,就会被熔断interval: 10s                 # 每 10 秒探测一次后端实例baseEjectionTime: 3m          # 熔断的时间maxEjectionPercent: 100       # 被熔断实例最大的百分比subsets:- labels:version: v1name: v1[root@k8s-master01 bookinfo]# kubectl create -f ratings-dr.yaml -n bookinfo

保存退出后,部署测试工具 fortio,用于对容器业务进行压力测试:

[root@k8s-master01 bookinfo]# kubectl apply -f ../samples/httpbin/sample-client/fortio-deploy.yaml -n bookinfo

等待 fortio 容器启动后,获取 fortio 容器 id:

[root@k8s-master01 bookinfo]# kubectl get po -n bookinfo | grep fortio
fortio-deploy-74ffb9b4d6-j28bh    2/2     Running   0              55s

发送一个请求,可以看到当前状态码为 200,即连接成功:

[root@k8s-master01 bookinfo]# kubectl exec -ti fortio-deploy-74ffb9b4d6-j28bh -n bookinfo -- fortio load -curl http://ratings:9080/ratings/0
....
HTTP/1.1 200 OK
....

接下来更改为两个并发连接(-c 2),发送 20 请求(-n 20):

[root@k8s-master01 bookinfo]# kubectl exec -ti fortio-deploy-74ffb9b4d6-j28bh -n bookinfo -- fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://ratings:9080/ratings/0 | grep Code
Code 200 : 20 (100.0 %)

可以看到 503 的结果为 12,说明触发了熔断。如果提高并发量,会触发更高的熔断:

[root@k8s-master01 bookinfo]# kubectl exec -ti fortio-deploy-74ffb9b4d6-j28bh -n bookinfo -- fortio load -c 20 -qps 0 -n 20 -loglevel Warning http://ratings:9080/ratings/0 | grep Code
Code 200 : 8 (40.0 %)
Code 503 : 12 (60.0 %)

4.8 Istio 注入延迟故障

Istio 支持为服务添加延迟和中断,可以用于测试链路的可靠性,添加延迟只需要在 VirtualService 添加 fault 字段即可。

首先不添加任何延迟,看一下访问速度如何

# 创建一个用于测试的工具
[root@k8s-master01 bookinfo]# kubectl create deploy -n bookinfo debug-tools --image=crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/debug-tools -- sleep 36000# 查看pod
[root@k8s-master01 bookinfo]# kubectl get po -n bookinfo | grep debug-tools
debug-tools-6447995767-bq2hd      2/2     Running   0              99s[root@k8s-master01 bookinfo]# kubectl exec -it debug-tools-6447995767-bq2hd -n bookinfo -- bash
(08:23 debug-tools-6447995767-bq2hd:/) time curl -I -s details:9080
....real	0m0.095s
user	0m0.003s
sys	0m0.009s

不添加任何故障延迟时,095 秒左右就会返回结果。接下来注入一个 5s 的延迟:

[root@k8s-master01 bookinfo]# vim details-delay.yaml
[root@k8s-master01 bookinfo]# cat details-delay.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: details
spec:hosts:- detailshttp:- fault:                  # 添加一个错误delay:                # 添加类型为 delay 的故障percentage:         # 故障注入的百分比value: 100        # 对所有请求注入故障fixedDelay: 5s      # 注入的延迟时间route:- destination:host: details[root@k8s-master01 bookinfo]# kubectl create -f details-delay.yaml -n bookinfo

再次进行测试,返回时间已经达到了五秒:

(08:31 debug-tools-6447995767-bq2hd:/) time curl -I -s details:9080
....real	0m5.022s
user	0m0.003s
sys	0m0.007s

4.9 Istio 注入中断故障

中断故障注入只需要将 fault 的 delay 更改为 abort 即可:

[root@k8s-master01 bookinfo]# vim details-abort.yaml
[root@k8s-master01 bookinfo]# cat details-abort.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: details
spec:hosts:- detailshttp:- fault:abort:                # 更改为 abort 类型的故障percentage:value: 100httpStatus: 400     # 故障状态码route:- destination:host: details# 替换该 VirtualService,再次访问测试:      
[root@k8s-master01 bookinfo]# kubectl replace -f details-abort.yaml -n bookinfo# 直接返回 400 错误
(08:40 debug-tools-6447995767-bq2hd:/) curl -I -s details:9080
HTTP/1.1 400 Bad Request
content-length: 18
content-type: text/plain
date: Wed, 30 Jul 2025 08:40:13 GMT
server: envoy
connection: close

5、企业内项目接入 Istio 流程

企业内项目接入 Istio 常见的有两种情况:

  • 需要注入 Istio Sidecar 进行流量管理的
  • 不需要 Sidecar,只需要使用 ingressgateway

针对第一种情况,在建立服务时,最好配置 version 标签,第二种情况一般无需特殊处理。

同时也需要考虑项目是否已经部署在 Kubernetes 集群内:

  • 新项目还未部署:按照 Istio 的规范创建 Deployment 及 Service,及 Istio 的核心资源
  • 已部署在集群中的:需要修改 Deployment、Service,以及按需转为 Istio IngressGateway 对外提供服务

接下来以一个 Demo 项目为例,用于接入 Istio 并测试。
项目架构:

5.1 部署企业测试项目

5.1.1 部署 mysql 服务
[root@k8s-master01 demo]# kubectl create ns demo# 部署数据库
[root@k8s-master01 demo]# kubectl create -f mysql.yaml -f mysql-svc.yaml -f mysql-pvc.yaml -n demo# 查看部署pod
[root@k8s-master01 demo]# kubectl get po -n demo
NAME                     READY   STATUS    RESTARTS   AGE
mysql-6d698b4676-75g2x   1/1     Running   0          66s# 创建数据库、用户/密码
[root@k8s-master01 demo]# kubectl exec -it mysql-6d698b4676-75g2x -n demo -- bash
root@mysql-6d698b4676-75g2x:/# mysql -uroot -p
....
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> create database orders;
Query OK, 1 row affected (0.03 sec)mysql> CREATE USER 'order'@'%' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.04 sec)mysql> GRANT ALL ON orders.* TO 'order'@'%';
Query OK, 0 rows affected (0.02 sec)
5.1.2 部署 order 服务
# 创建Ingress
[root@k8s-master01 demo]# kubectl label node k8s-node02 ingress=true
[root@k8s-master01 demo]# kubectl create -f ingress-nginx-daemonset.yaml# 添加 Version 字段
[root@k8s-master01 demo]# vim demo-order-deploy.yaml
[root@k8s-master01 demo]# cat demo-order-deploy.yaml
....template:metadata:creationTimestamp: nulllabels:app: demo-orderversion: v1spec:containers:
....# 启动 order 服务
[root@k8s-master01 demo]# kubectl create -f demo-order-deploy.yaml -f demo-order-svc.yaml -f demo-order-ingress.yaml -n demo# 查看资源信息
[root@k8s-master01 demo]# kubectl get po,svc,ingress -n demo
NAME                              READY   STATUS    RESTARTS   AGE
pod/demo-order-7c6ccb7865-b8btq   1/1     Running   0          83s
pod/mysql-6d698b4676-75g2x        1/1     Running   0          10mNAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/mysql   NodePort    10.102.167.87   <none>        3306:32541/TCP   10m
service/order   ClusterIP   10.98.35.104    <none>        80/TCP           83sNAME                                   CLASS   HOSTS           ADDRESS        PORTS   AGE
ingress.networking.k8s.io/demo-order   nginx   demo.test.com   192.168.200.52   80      82s# 测试访问:
[root@k8s-master01 demo]# echo "192.168.200.52 demo.test.com" >> /etc/hosts
[root@k8s-master01 demo]# curl demo.test.com/orders
[{"id":1,"name":"Order 1","price":10},{"id":2,"name":"Order 2","price":20}]
5.1.3 部署 handler 服务
# 添加 Version 字段
[root@k8s-master01 demo]# vim demo-handler-deploy.yaml 
[root@k8s-master01 demo]# cat demo-handler-deploy.yaml 
....template:metadata:creationTimestamp: nulllabels:app: demo-handlerversion: v1spec:containers:
....# 启动 handler 服务
[root@k8s-master01 demo]# kubectl create -f demo-handler-deploy.yaml -f demo-handler-svc.yaml -n demo
5.1.4 部署 receive 服务
# 添加 Version 字段
[root@k8s-master01 demo]# vim demo-receive-deploy.yaml
[root@k8s-master01 demo]# cat demo-receive-deploy.yaml
....template:metadata:creationTimestamp: nulllabels:app: demo-receiveversion: v1spec:volumes:
....# 启动 receive 服务
[root@k8s-master01 demo]# kubectl create -f demo-receive-deploy.yaml -f demo-receive-svc.yaml -f demo-receive-ingress.yaml -n demo
5.1.5 部署 前端ui 服务
# 添加 Version 字段
[root@k8s-master01 demo]# vim demo-ui-deploy.yaml
[root@k8s-master01 demo]# cat demo-ui-deploy.yaml
....template:metadata:creationTimestamp: nulllabels:app: demo-uiversion: v1spec:containers:
....# 启动 前端ui 服务
[root@k8s-master01 demo]# kubectl create -f demo-ui-deploy.yaml -f demo-ui-svc.yaml -f demo-ui-ingress.yaml -n demo
# 部署完毕后,最终的服务如下:
[root@k8s-master01 demo]# kubectl get po,svc -n demo
NAME                                READY   STATUS    RESTARTS   AGE
pod/demo-handler-775df45c67-gc55g   1/1     Running   0          32m
pod/demo-order-7c6ccb7865-b8btq     1/1     Running   0          75m
pod/demo-receive-6cf94f6d9f-6b6lh   1/1     Running   0          5m33s
pod/demo-ui-88c9b5f76-jmjb4         1/1     Running   0          43s
pod/mysql-6d698b4676-75g2x          1/1     Running   0          84mNAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/demo-receive   ClusterIP   10.96.97.54     <none>        8080/TCP         5m32s
service/demo-ui        ClusterIP   10.98.249.2     <none>        80/TCP           43s
service/handler        ClusterIP   10.99.3.59      <none>        80/TCP           32m
service/mysql          NodePort    10.102.167.87   <none>        3306:32541/TCP   84m
service/order          ClusterIP   10.98.35.104    <none>        80/TCP           75m

接下来通过浏览器访问:

在这里插入图片描述

5.2 Istio 南北流量网关改造

如果想要使用 Istio 管理流量,建议服务的入口使用 IngressGateway 进行管理,也就是需要把之前由其他控制器管理的 Ingress 改造为由 Istio Gateway 管理(新项目直接创建即可,无需改造)。

5.2.1 创建Gateway

首先确认当前项目的 Ingress 配置有哪些:

[root@k8s-master01 demo]# kubectl get ingress -n demo
NAME           CLASS   HOSTS           ADDRESS        PORTS   AGE
demo-order     nginx   demo.test.com   192.168.200.52   80      108m
demo-receive   nginx   demo.test.com   192.168.200.52   80      38m
demo-ui        nginx   demo.test.com   192.168.200.52   80      33m

接下来为该项目创建一个 Gateway:

[root@k8s-master01 demo]# vim demo-gateway.yaml
[root@k8s-master01 demo]# cat demo-gateway.yaml 
apiVersion: networking.istio.io/v1
kind: Gateway
metadata:name: demo-gateway
spec:selector:istio: ingressgateway       # 使用默认的 istio ingress gatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "demo.test.com"           # 发布域名# 创建资源
[root@k8s-master01 demo]# kubectl create -f demo-gateway.yaml -n demo
[root@k8s-master01 demo]# kubectl get gw -n demo
NAME           AGE
demo-gateway   14s
5.2.2 改造 order 服务的 Ingress 为 VirtualService

查看 order 服务的配置详情:

[root@k8s-master01 demo]# cat demo-order-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: demo-ordernamespace: demo
spec:ingressClassName: nginxrules:- host: demo.test.comhttp:paths:- backend:service:name: orderport:number: 80path: /orderspathType: ImplementationSpecific

改造后的 VirtualService:

[root@k8s-master01 demo]# vim demo-order-vs.yaml 
[root@k8s-master01 demo]# cat demo-order-vs.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: demo-order
spec:hosts:- "demo.test.com"gateways:- demo-gatewayhttp:- match:- uri:prefix: /ordersroute:- destination:host: orderport:number: 80# 创建资源
[root@k8s-master01 demo]# kubectl create -f demo-order-vs.yaml -n demo
[root@k8s-master01 demo]# kubectl get vs -n demo
NAME         GATEWAYS           HOSTS               AGE
demo-order   ["demo-gateway"]   ["demo.test.com"]   7s

接下来通过浏览器访问:

在这里插入图片描述

5.2.3 改造 receive 服务的 Ingress 为 VirtualService

查看 receive 服务的配置详情:

[root@k8s-master01 demo]# cat demo-receive-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:annotations:nginx.ingress.kubernetes.io/rewrite-target: /$2name: demo-receivenamespace: demo
spec:ingressClassName: nginxrules:- host: demo.test.comhttp:paths:- backend:service:name: demo-receiveport:number: 8080path: /receiveapi(/|$)(.*)pathType: ImplementationSpecific

改造后的 VirtualService:

[root@k8s-master01 demo]# vim demo-receive-vs.yaml 
[root@k8s-master01 demo]# cat demo-receive-vs.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: demo-receive
spec:hosts:- "demo.test.com"gateways:- demo-gatewayhttp:- match:- uri:prefix: /receiveapi/rewrite:uri: /route:- destination:host: demo-receiveport:number: 8080# 创建资源
[root@k8s-master01 demo]# kubectl create -f demo-receive-vs.yaml -n demo
[root@k8s-master01 demo]# kubectl get vs -n demo
NAME           GATEWAYS           HOSTS               AGE
demo-order     ["demo-gateway"]   ["demo.test.com"]   78m
demo-receive   ["demo-gateway"]   ["demo.test.com"]   7s
5.2.4 改造 前端ui 服务的 Ingress 为 VirtualService

查看 前端ui 服务的配置详情:

[root@k8s-master01 demo]# cat demo-ui-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: demo-uinamespace: demo
spec:ingressClassName: nginxrules:- host: demo.test.comhttp:paths:- backend:service:name: demo-uiport:number: 80path: /pathType: ImplementationSpecific

改造后的 VirtualService:

[root@k8s-master01 demo]# vim demo-ui-vs.yaml 
[root@k8s-master01 demo]# cat demo-ui-vs.yaml 
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: demo-ui
spec:hosts:- "demo.test.com"gateways:- demo-gatewayhttp:- match:- uri:prefix: /route:- destination:host: demo-uiport:number: 80# 创建资源
[root@k8s-master01 demo]# kubectl create -f demo-ui-vs.yaml -n demo
[root@k8s-master01 demo]# kubectl get vs -n demo
NAME           GATEWAYS           HOSTS               AGE
demo-order     ["demo-gateway"]   ["demo.test.com"]   83m
demo-receive   ["demo-gateway"]   ["demo.test.com"]   5m13s
demo-ui        ["demo-gateway"]   ["demo.test.com"]   7s

接下来即可通过 http://demo.test.com:30080 访问该服务:

在这里插入图片描述

5.3 Istio 东西流量改造

如果需要 Istio 管理东西流量,需要注入 Istio 的 Sidecar。首先向 demo 的空间添加 Istio 注入的标签:

[root@k8s-master01 demo]# kubectl label ns demo istio-injection=enabled

接下来重建所有 Pod,注入 Sidecar:

# 删除所有pod
[root@k8s-master01 demo]# kubectl delete po -n demo --all# 查看重新建立的pod
[root@k8s-master01 demo]# kubectl get po -n demo
NAME                            READY   STATUS    RESTARTS      AGE
demo-handler-775df45c67-f42pv   2/2     Running   2 (52s ago)   2m47s
demo-order-7c6ccb7865-5gnw7     2/2     Running   3 (91s ago)   2m47s
demo-receive-6cf94f6d9f-d7794   2/2     Running   0             2m47s
demo-ui-88c9b5f76-l4qsx         2/2     Running   0             2m47s
mysql-6d698b4676-ns6qw          2/2     Running   0             2m48s

之后给需要管理东西流量的 Service 创建 VirtualService 和 DestinationRule,比如给 handler服务创建 VirtualService 和 DestinationRule:

[root@k8s-master01 demo]# vim demo-handler-dr.yaml
[root@k8s-master01 demo]# cat demo-handler-dr.yaml 
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:name: handler
spec:host: handlersubsets:- name: v1labels:version: v1
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:name: handlernamespace: demo
spec:hosts:- handlerhttp:- route:- destination:host: handlerport:number: 80subset: v1# 创建资源
[root@k8s-master01 demo]# kubectl create -f demo-handler-dr.yaml 
[root@k8s-master01 demo]# kubectl get -f demo-handler-dr.yaml 
NAME                                          HOST      AGE
destinationrule.networking.istio.io/handler   handler   8sNAME                                         GATEWAYS   HOSTS         AGE
virtualservice.networking.istio.io/handler              ["handler"]   8s

访问测试后,查看 kiali 流量:

在这里插入图片描述


此博客来源于:https://edu.51cto.com/lecturer/11062970.html

http://www.dtcms.com/a/319505.html

相关文章:

  • UiPath Studio介绍
  • CS231n2017 Assignment3 RNN、LSTM部分
  • 仁懋高压MOSFET在新能源汽车充电领域的应用
  • Java并发与数据库锁机制:悲观锁、乐观锁、隐式锁与显式锁
  • Java基础学习1(Java语言概述)
  • 音视频时间戳获取与同步原理详解
  • 如何为WordPress启用LiteSpeed缓存
  • --- Eureka 服务注册发现 ---
  • 安卓Handler和Looper的学习记录
  • 计算机视觉-OpenCV
  • GPT-5 将在周五凌晨1点正式发布,王炸模型将免费使用??
  • Android 之 Kotlin 扩展库KTX
  • 突破距离桎梏:5G 高清视频终端如何延伸无人机图传边界
  • RK3568项目(十三)--linux驱动开发之基础通讯接口(下)
  • 闪迪 SN8100 旗舰固态评测:读 14.9GB/s,写 14.0GB/s 的性能怪兽
  • 8.结构健康监测选自动化:实时数据 + 智能分析,远超人工
  • 深度学习中主要库的使用:(一)pandas,读取 excel 文件,支持主流的 .xlsx/.xls 格式
  • Flink-1.19.0-核心源码详解
  • 网站IP被劫持?三步自建防护盾
  • 【中微半导体】BAT32G139 逆变器,中微半导体pack包安装使用说明(参考例程获取DemoCode)
  • 51c大模型~合集165
  • 【动态规划 | 完全背包】动态规划经典应用:完全背包问题详解
  • 【CS创世SD NAND征文】额贴式睡眠监测仪的数据守护者:存储芯片如何实现7×24小时安眠状态下的全时稳定记录
  • Redis面试精讲 Day 13:Redis Cluster集群设计与原理
  • Flutter 三棵树
  • 数字取证:可以恢复手机上被覆盖的数据吗?
  • 【免费】小学数学算术专项突破随机生成加法减法乘法除法
  • 无人机计算机视觉数据集-7,000 张图片 空域安全监管 无人机反制系统 智能安防监控 交通执法应用 边境管控系统 赛事安保服务
  • 香港网站服务器被占用的资源怎么释放?
  • 《深入Java包装类体系:类型转换原理与Integer缓存实战指南》