服务网格之Istio实践
服务网格
在设计并开发程序时,主要分为两部分功能:业务逻辑和网络功能。对于一个开发者而言,需要关注的问题是业务逻辑而非网络功能。但是在一个项目开发中,由于涉及很多微服务之间的通信,因此就不得不考虑网络上的问题,比如负载均衡、服务发现、错误重试等。
服务网格的诞生将程序开发的网络功能和程序本身解耦,网络功能下沉到基础设施,由服务网格实现服务之间的负载均衡等功能,并且除网络功能外,还提供了其他更高级的功能,比如全链路加密、监控、链路追踪等。
服务网格产品
2016 年 Service Mesh 一词诞生至今不过短短四年时间,服务网格已经从研究理论变成了在工业界中广泛采用的技术,用户的态度也从观望走向落地生产。
在数据平面的产品有:
Linkerd:2016 年 1 月发布的Linkerd是服务网格的鼻祖,使用 Scala 语言开发的 Linkerd-proxy 也就成为了业界第一款正式的边车代理。一年后的 2017 年 1 月,Linkerd 成功进入 CNCF,成为云原生基金会的孵化项目,但此时的 Linkerd 其实已经显露出了明显的颓势:由于 Linkerd-proxy 运行需要 Java 虚拟机的支持,在启动时间、预热、内存消耗等方面,相比起晚它半年发布的挑战者 Envoy 均处于全面劣势,因而很快 Linkerd 就被 Istio 与 Envoy 的组合所击败,结束了它短暂的统治期。
Envoy:2016 年 9 月开源的Envoy是目前边车代理产品中市场占有率最高的一款,已经在很多个企业的生产环境里经受过大量检验。Envoy 最初由 Lyft 公司开发,后来 Lyft 与 Google 和 IBM 三方达成合作协议,Envoy 就成了 Istio 的默认数据平面。Envoy 使用 C++语言实现,比起 Linkerd 在资源消耗方面有了明显的改善。此外,由于采用了公开的 xDS 协议进行控制,Envoy 并不只为 Istio 所私有,这个特性让 Envoy 被很多其他的管理平面选用,为它夺得市场占有率桂冠做出了重要贡献。2017 年 9 月,Envoy 加入 CNCF,成为 CNCF 继 Linkerd 之后的第二个数据平面项目。
MOSN:2018 年 6 月,来自蚂蚁金服的MOSN宣布开源,MOSN 是 SOFAStack 中的一部分,使用 Golang 语言实现,在阿里巴巴及蚂蚁金服中经受住了大规模的应用考验。由于 MOSN 是阿里技术生态的一部分,对于使用了 Dubbo 框架,或者 SOFABolt 这样的 RPC 协议的微服务应用,MOSN 往往能够提供些额外的便捷性。
在控制平面的产品有:
- Istio:Google、IBM 和 Lyft 公司联手打造的产品,以自己的 Envoy 为默认数据平面。Istio 是目前功能最强大的服务网格。
- OSM:Open Service Mesh(OSM)是微软公司在 2020 年 8 月开源的服务网格,同样以 Envoy 为数据平面。
- Consul Connect:Consul Connect 是来自 HashiCorp 公司的服务网格,Consul Connect 的目标是将现有由 Consul 管理的集群平滑升级为服务网格的解决方案。
本文主要学习以 Istio 与 Envoy 组合实现的服务网格,这也是当前业界主流的服务网格产品。
Istio
Istio 项目最初由 Google、IBM 和 Lyft 共同开发,并于 2017 年成立了独立的开源项目。很快,该项目引起了广泛的关注和采用,成为当今最受欢迎的服务网格解决方案之一。
在微服务架构中,应用程序被拆分为多个小型、自治的服务,每个服务都有自己的特定功能。然而,服务之间的通信管理变得复杂,包括负载均衡、服务发现、流量控制、故障恢复等。这就是为什么需要服务网格来解决这些挑战。
Istio 的目标是提供一种简化和增强微服务之间通信的方式。它通过在应用程序之间插入专用代理(Envoy)来实现对流量的细粒度控制和管理。Istio 能够提供服务发现、负载均衡、流量路由、故障恢复、检测和监控等功能,同时保持对应用程序无感知。
发展历史
时间 | 描述 |
---|---|
2017年 | 由 Google、IBM 和 Lyft 共同推出 |
2018 年 | 发布1.0版本 |
2019 - 2021 年 | 快速发展期 |
2022 年 | Istio 被纳入 CNCF 的孵化项目 |
2023 年 | 2023 年7月12日正式成为CNCF毕业项目! |
功能特性
服务网格作为透明代理,可以运行于任何基础设施环境,而且和应用非常靠近,服务网格的功能大致如下:
- 服务发现
- 负载均衡
- 重试和最后期限
- 熔断
- 动态路由
- 安全通信
- 多协议支持
- 多语言支持
架构
Istio的架构主要由两部分组成:
- 数据平面 Envoy
- 控制平面 Istiod

Envoy
Istio的数据平面使用的是Envoy,Envoy是以C++开发的高性能代理,用于调解服务网格中所有服务的所有入站和出站流量。Envoy代理是唯一一个与数据平面流量交互的Istio组件。Envoy通过Sidecar的方式和业务应用部署在同一个Pod内,在逻辑上为服务增加了许多内置特性,例如:
- 动态服务发现。
- 负载均衡。
- TLS终止。
- HTTP/2 & gRPC代理。
- 熔断器。
- 健康检查、基于百分比流量拆分的灰度发布。
- 故障注入。
- 丰富的度量指标。
使用Sidecar的方式将Envoy注入业务Pod,可以让Istio执行策略决策,并提取丰富的遥测数据,然后将这些数据发送到监控系统,以提供整个网格的监控面板。
Istiod
Istiod为Istio的控制平面,提供服务发现、配置、证书管理、加密通信和认证功能 。
在使用服务网格时,在不更改代码的情况下就可以实现比较复杂的网络功能。所以在设计云原生应用时,这也是比较流行、比较推荐的方式,即把网络功能下沉到基础设施,让开发人员只需要关注业务逻辑即可,这样可以大幅度降低开发人员的工作难度。
技术组件
采用基于 Istio 的服务网格架构,其中主要的技术组件包括:
- 配置中心:通过 Kubernetes 的 ConfigMap 来管理。
- 服务发现:通过 Kubernetes 的 Service 来管理,由于已经不再引入 Spring Cloud Feign 了,所以在 OpenFeign 中,直接使用短服务名进行访问。
- 负载均衡:未注入边车代理时,依赖 KubeDNS 实现基础的负载均衡,一旦有了 Envoy 的支持,就可以配置丰富的代理规则和策略。
- 服务网关:依靠 Istio Ingress Gateway 来实现,已经移除了 Kubernetes 版本中保留的 Zuul 网关。
- 服务容错:依靠 Envoy 来实现,已经移除了 Kubernetes 版本中保留的 Hystrix。
- 认证授权:依靠 Istio 的安全机制来实现,实质上已经不再依赖 Spring Security 进行 ACL 控制,但 Spring Security OAuth 2 仍然以第三方 JWT 授权中心的角色存在,为系统提供终端用户认证,为服务网格提供令牌生成、公钥JWKS等支持。
安装部署
下载:https://github.com/istio/istio/releases
此外还要查看Istio与k8s的版本对应关系:https://istio.io/latest/zh/docs/releases/supported-releases/
istio-opeartor.yaml 内容
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: istio-controlplane-example
spec:
values:
gateways:
istio-ingressgateway:
runAsRoot: true
global:
proxy:
autoInject: disabled #关闭自动注入
addonComponents:
pilot:
enabled: true # 开启pilot插件
components: #自定义组件配置
ingressGateways:
- name: istio-ingressgateway
enabled: true
k8s:
service:
type: NodePort
ports:
- port: 15020
nodePort: 30020
name: status-port
- port: 80
nodePort: 30080
name: http2
- port: 443
nodePort: 30443
name: https
安装:
# 使用default profile安装Istio
istioctl install
istioctl install --set profile=default
# 使用不同的profile
istioctl install --set profile=demo
istioctl install --set profile=minimal
学习用,建议就使用demo这个内置的配置,这个配置会使用较小的内存,并且部署上ingress组件。如果使用 profile=default,则需要k8s集群中,至少有2G内存的富余量,才能正常启动pod,否则启动失败。
给需要istio转发的namespace增加label,增加后,启动的pod会自动注入sidecar
kubectl label namespace default istio-injection=enabled
查看istio的Pod的启动状态
[root@k8s-master01 ~]# kubectl get pods -n istio-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE
istio-egressgateway-5b9dd6fb4-mvpjg 1/1 Running 1 (12h ago) 14h 192.168.32.155 k8s-master01
istio-ingressgateway-696d78f74d-z4sr5 1/1 Running 1 (12h ago) 14h 192.168.32.153 k8s-master01
istiod-5cf9496ddb-px4h4 1/1 Running 1 (12h ago) 14h 192.168.32.158 k8s-master01
卸载
# 使用 --purge 进行完全卸载,包含集群范围的资源,这些资源有可能是和其他Istio控制面共享的
istioctl x uninstall --purge
部署istio的gateway网关
流量管理
流量管理的几个组件:
虚拟服务 VirtualService
目标规则 DestinationRule
网关 Gateway
服务入口 ServiceEntry
网络弹性
超时
重试
熔断
在虚拟服务中配置超时和重试:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
timeout: 10s # 超时配置
retries: # 重试配置
attempts: 3
perTryTimeout: 2s
在目标规则中配置熔断:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
安全管理
身份
认证
授权
安全架构:
可观测性
Prometheus
Prometheus 是一个开源的监控系统、时间序列数据库。您可以利用 Prometheus 与 Istio 集成来收集指标,通过这些指标判断 Istio 和网格内的应用的运行状况。您可以使用 Grafana 和 Kiali 来可视化这些指标。
Kiali 仪表板
README
参考: