Istio 是一个开源的服务网格(Service Mesh)解决方案,主要用于简化微服务应用的连接、安全、观察和管理。它通过在应用服务之间插入代理(sidecars)(最新版本还支持Ambient模式),提供了统一的方式来处理包括流量管理、服务发现、负载均衡、健康检查、认证授权、可观测性和监控在内的各种功能。
服务网格(Service Mesh)是一种用于处理微服务架构中的服务间通信的基础设施层。它通过在每个服务实例之间插入轻量级的代理(sidecars)来实现这一点。这些代理负责拦截所有进出服务的网络流量,从而提供诸如负载均衡、服务发现、故障恢复、指标收集和分布式跟踪等功能。
sidecar模式
Istio 的作用原理可以看作是拦截 Kubernetes 部署 Pod 的事件,然后从 Pod 中注入一个名为 Envoy 的容器,这个容器会拦截外部到业务应用的流量。由于所有流量都被 Envoy “劫持” 了,所以 Istio 可以对流量进行分析例如收集请求信息,以及一系列的流量管理操作,也可以验证授权信息。当 Envoy 拦截流量并执行一系列操作之后,如果请求没问题,就会转发流量到业务应用的 Pod 中。
::: 左:普通 Pod;右:Istio 代理了出入口流量
(没有什么问题是加一层中间代理不能解决的。如果有,那就加两层。) :::
ambient 模式
没有使用 sidecar 代理,而是采用更细粒度的代理部署模式,代理功能在网络基础设施中实现,不需要在每个服务实例中部署代理。
Istio可以轻松在已部署服务网络上创建带有负载平衡,服务到服务的身份验证,监控等功能,并且服务代码中的代码无需变动(或变动很少)。通过在整个环境中部署一个特殊的sidecar代理来拦截微服务之间的所有网络通信,然后使用其平台控制功能配置和管理Istio,包括:
自动为HTTP,gRPC,WebSocket和TCP流量负载平衡。
通过丰富的路由规则,重试,故障转移和故障注入对流量行为进行细粒度控制。
可插拔的策略层和配置API,支持访问控制,速率限制和配额。
集群内所有流量的自动度量,日志和跟踪,包括集群的入口和出口。
通过强大的基于身份的身份验证和授权,在集群中进行安全的服务之间通信。
动态服务发现
负载均衡
TLS 终端
HTTP/2 与 gRPC 代理
熔断器
健康检查
基于百分比流量分割的分阶段发布
故障注入
丰富的指标
Istio 支持 Jaeger、Zipkin、Grafana 等链路追踪中间件,支持 Prometheus 收集指标数据,然后日志功能没有上面亮点,只是记录了请求的 HTTP 地址之类。Istio 的可观测性帮助我们了解应用程序的性能和行为,使得故障检测、性能分析和容量规划变得更加简单。
主要特点是可以实现零信任网络中的服务之间通讯加密。Istio 通过自动为服务之间的通信提供双向 TLS 加密来增强安全性,同时 Istio 还提供了强大的身份验证、授权和审计功能。
k8s集群环境安装过程省略....
curl -L https://istio.io/downloadIstio | sh -
cd istio-<version>
export PATH=$PWD/bin:$PATH
isitoctl安装isito (使用demo配置)
istioctl install --set profile=demo -y
Istio 配置档类型
istioctl profile list
ambient
ambient mesh 架构,它不使用传统的 Sidecar 模式,传统的 Istio 使用 Sidecar 代理(如 Envoy)注入到每个服务 Pod 中,而 Ambient Mesh 消除了这种 Sidecar 方式,改为使用独立的 Ztunnel 代理来处理流量。
default
default配置文件是最常用的基础配置,包含了 Istio 的大部分核心组件。适合大多数生产环境使用。
demo
demo配置文件是一个适用于演示和学习的配置,启用了更多的可观察性功能和配置。
empty
文件什么都不安装,实际上是一个空配置。这可用于完全定制自己的 Istio 安装,用户可以在此基础上根据实际需求添加特定的组件。
minimal
仅安装 Istio 的基础控制平面组件。只包含最基本的组件,如 Pilot 和 Istiod。适合资源受限的环境或对 Istio 功能要求不高的使用场景。
openshift
配置文件专门针对 OpenShift 平台进行了优化和配置。
preview
配置文件包含一些试验性和预览功能,这些功能可能还不稳定或未完全成熟。
remote
配置文件用于创建一个远程集群,以便和一个主集群配合使用,适用于多集群或多环境部署场景。
检查是否安装成功
kubectl get deployments -n istio-system --output wide
github下载地址:https://github.com/istio/istio/releases/tag/1.22.2
添加helm库
helm repo add istio https://istio-release.storage.googleapis.com/charts
helm repo update
创建空间
kubectl create namespace istio-system
部署
helm install istio-base istio/base -n istio-system --set defaultRevision=default
查看
helm ls -n istio-system
kubectl -n istio-system get service istio-ingressgateway
bookinfo这个示例部署了一个用于演示多种 Istio 特性的应用,该应用由四个单独的微服务构成。 这个应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。
Bookinfo 应用分为四个单独的微服务:
productpage: 这个微服务会调用 details 和 reviews 两个微服务,用来生成页面。
details:这个微服务中包含了书籍的信息。
reviews.:这个微服务中包含了书籍相关的评论。它还会调用 ratings 微服务。
ratings.:这个微服务中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本:
v1 版本不会调用 ratings 服务。
v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。
Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews
服务具有多个版本。
github地址:https://github.com/istio/istio
default
命名空间打上标签 istio-injection=enabled
:kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl get pod
查看Services
kubectl get svc
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
确认网关创建完成:
kubectl get gateway
最终实现的效果:
通过浏览应用的 Web 页面。如果刷新几次应用的页面,就会看到 productpage 页面中会随机展示 reviews 服务的不同版本的效果(红色、黑色的星形或者没有显示)。reviews 服务出现这种情况是因为我们还没有使用 Istio 来控制版本的路由。
http://192.168.128.1/productpage
应用目标规则设置 设置
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
查询
kubectl get destinationrules -o yaml
这一步的目的就是让Istio接管所有Pod的入口流量
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ratings
spec:
host: ratings
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v2-mysql
labels:
version: v2-mysql
- name: v2-mysql-vm
labels:
version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: details
spec:
host: details
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
当前的reviews有三个版本,在浏览器中访问 Bookinfo 应用程序的 /productpage 并刷新几次。我们发现有时书评的输出包含星级评分,有时则不包含。 这是因为没有明确的默认服务版本路由。
现在我们要做就是让istio接管路由,比如将所有流量都路由到每个微服务的v1版本,Istio实现起来是非常简单的,只需要添加虚拟服务(VirtualService)即可。
示例:将所有流量都路由到各个微服务的v1版本,创建路由规则
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
具体文件内容
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: details
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
---
此时刷新页面,发现reviews不再切换样式
实验完成后删除规则:
kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml
修改路由配置,将来自特定用户的所有流量路由到特定服务版本。比如将用户名为jason的用户的所有流量将被路由到服务 reviews:v2。
Istio 对用户身份没有任何特殊的内置机制,productpage 服务在所有到 reviews 服务的 HTTP 请求中都增加了一个自定义的 end-user 请求头 (request set header)。有点类似于k8s里面ingress灰度发布(根据header头区分)
创建路由规则
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
创建完成后使用jason用户名登录,在/productpage页面刷新,会发生什么?
可以将reviews的部分流量转移到v3版本,基于此可以实现灰度发布、A/B测试等
#将所有流量都路由到每个服务的v1版本
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
#将reviews服务 50%的流量转移到v3
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
刷新浏览器中的 /productpage 页面,大约有 50% 的几率会看到页面中出带 红色 星级的评价内容。这是因为 v3 版本的 reviews 访问了带星级评级的 ratings 服务,但 v1 版本却没有。
通过 VirtualService 配置来定义对服务请求的超时和重试策略,这些策略有助于提高服务的可靠性和抗故障能力。
HTTPFaultInjection 可用于指定在将 HTTP 请求转发到路由中指定的目标时注入的一个或多个故障。故障规范是 VirtualService 规则的一部分。故障包括中止来自下游服务的 Http 请求和/或延迟请求的代理。故障规则必须具有延迟或中止或两者。
重试:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault:
delay:
percent: 100
fixedDelay: 2s
route:
- destination:
host: ratings
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v2
timeout: 0.5s
Service1详细解释如下:
● fault:用于指定故障注入配置。
● delay:表示一种人为引入的延迟。
● percent: 100:表示对 100% 的请求引入延迟(即所有请求都会受到影响)。
● fixedDelay: 2s:表示引入的延迟时间为固定的 2 秒。
● host: ratings:目标服务是 ratings。
● subset: v1:使用 ratings 服务的 v1 版本。
Service2:
timeout:设置请求的最大允许持续时间,表示请求最多持续 0.5 秒,如果超过这个时间,Istio 将中断请求并返回错误。
retries:用于定义重试策略。
attempts: 3:表示请求失败时最多重试 3 次。
perTryTimeout: 2s:表示每次重试的最大持续时间为 2 秒。
retryOn:指定在何种情况下进行重试。
熔断器是 Istio 为创建具有弹性的微服务应用提供的有用的机制。在熔断器中,设置一个对服务中的单个主机调用的限制,例如并发连接的数量或对该主机调用失败的次数。一旦限制被触发,可以快速失败而不必让客户端尝试连接到过载或有故障的主机。
httpbin项目演示
httpbin是一个开源项目,使用Python+Flask编写,利用它可以测试各种HTTP请求和响应
部署
kubectl apply -f samples/httpbin/httpbin.yaml
配置熔断规则
添加
kubectl apply -f samples/bookinfo/networking/virtual-service-httpbin.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1 # 最大连接数
http:
http1MaxPendingRequests: 1 # http 请求 pending 状态的最大请求数
maxRequestsPerConnection: 1 # 限制一个连接上最多能发起的请求数
outlierDetection: # 熔断设置
consecutive5xxErrors: 1 # 从连接池开始拒绝连接,已经连接失败的次数,当通过 HTTP 访问时,返回代码是 5xx 错误则视为错误。
interval: 1s # 拒绝访问扫描的时间间隔,即在 interval(1s)内连续发生 1 个 consecutive5xxErrors 错误,则触发服务熔断。
baseEjectionTime: 3m # 最短拒绝访问时长。这个时间主机将保持拒绝访问,且如果拒绝访问达到一定的次数。
maxEjectionPercent: 100 # 服务在负载均衡池中被拒绝访问(被移除)的最大百分比。
客户端
创建客户端程序以发送流量到 httpbin 服务。这是一个名为 Fortio 的负载测试客户的,其可以控制连接数、并发数及发送 HTTP 请求的延迟。通过 Fortio 能够有效的触发前面 在 DestinationRule 中设置的熔断策略。
向客户端注入 Istio Sidecar 代理,以便 Istio 对其网络交互进行管理,部署客户端:
kubectl apply -f samples/bookinfo/networking/client-fortio-deploy.yaml
客户端发送请求:
# 获取客户端Pod
FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')
# 进入客户端Pod发送请求
kubectl exec -it $FORTIO_POD -c fortio -- /usr/bin/fortio load -curl http://httpbin:8000/get
#本地使用的docker destop
kubectl exec -it fortio-deploy-84bd85dc9f-zmk2r -c fortio -- /usr/bin/fortio load -curl http://httpbin:8000/get
触发熔断器
由于我们定义了 maxConnections: 1 和 http1MaxPendingRequests: 1,如果并发的连接和请求数超过一个,在 istio-proxy 进行进一步的请求和连接时,后续请求或 连接将被阻止。
提升并发请求量
kubectl exec -it $FORTIO_POD -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get
## 本地
kubectl exec -it fortio-deploy-84bd85dc9f-zmk2r -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://httpbin:8000/get
只有33%的请求成功,其余的均被熔断器拦截
istio的可观测性体现在:指标度量,日志,分布式追踪,网格可视化等方面
Kiali 是一个开源项目,专为 Istio 服务网格设计的可视化和监控工具。它提供了丰富的图形界面,帮助用户管理和监控微服务架构中的流量、依赖关系和性能情况。在Istio中可以使用 kiali 进行可视化的管理服务网格。
进入kiali面板
istioctl dashboard kiali
进入grafana面板
istioctl dashboard grafana
Jaeger 是一个开源的端到端分布式追踪系统,由 Uber Technologies 开发并贡献给开源社区。它的主要目标是帮助开发者和运维人员监控和排查微服务架构中的性能问题。
进入面板
istioctl dashboard jaeger
Prometheus 是一个功能强大且灵活的监控和报警系统,特别适用于云原生环境和微服务架构。通过其强大的数据模型、灵活的查询语言和丰富的生态系统,Prometheus 可以帮助用户全面监控系统性能、快速响应故障和深入分析数据。
进入面板
istioctl dashboard prometheus
如果您喜欢我的文章,请点击下面按钮随意打赏,您的支持是我最大的动力。
最新评论