Istio 学习笔记

avatar
作者
筋斗云
阅读量:0

Istio 学习笔记

作者:王珂

邮箱:49186456@qq.com


文章目录

前言

本文主要讲解在使用Istio开发微服务过程中涉及到的一些基本概念,Istio环境安装,Istio组件作用和使用方法。最后再通过实战讲解来结束Istio的学习。

我的Kubernetes信息

节点名称IP说明
node21192.168.1.21主节点名称为node21
node26192.168.1.26工作节点名称为node26
node27192.168.1.27工作节点名称为node27
node28192.168.1.28工作节点名称为node28

一、基本概念

服务网格

服务网格 Service Mesh

Kubernetes Ingress, Gateway和Istio Gateway的区别

2022年5月份Kubernetes Gateway API才发布了 Beta 版本,当前大多数组织应该还在使用稳定的 Ingress API。

  • Kubernetes Ingress

    Kubernetes Ingress 是一个资源对象,用于控制进入 Kubernetes 集群的流量。
    它可以配置外部 IP 地址、端口、域名、以及路径等信息,将流量路由到不同的服务。
    Ingress 通常使用 Nginx 或 HAProxy 等代理服务器来实现。
    在这里插入图片描述

  • Kubernetes Gateway

    Kubernetes Gateway 是一个 API 对象,用于定义网络流量的入口点。
    它可以配置服务、端口、协议等信息,以及如何将流量路由到不同的服务。
    Gateway 旨在替代 Ingress 成为 Kubernetes 中流量管理的标准 API。

    Gateway API 在 Ingress API 的基础上增加了更多特性,例如 HTTP 头匹配、加权流量分割、多协议支持(如 HTTP、gRpc)以及其他各种后端功能(如桶、函数)。

    Gateway API 比 Ingress API 更好的分离了关注点。使用 Ingress,集群运维人员和应用开发人员在同一个 Ingress 对象上操作,却不知道彼此的角色,可能会导致设置错误。

    Route 和 Gateway 对象是由 Gateway API 独立于配置创建的,从而为集群运维人员和应用开发人员提供了自主权。
    在这里插入图片描述

  • Istio Gateway

    Istio Gateway 是 Istio 服务网格中的一个组件,用于控制进入服务网格的流量。
    它可以配置虚拟服务、端口、协议等信息,以及如何将流量路由到不同的服务。
    Istio Gateway 使用 Envoy 代理来实现,并支持更丰富的流量管理功能,例如服务发现、负载均衡、熔断、超时、重试等。

简而言之:

Kubernetes Ingress 和 Gateway 都是用于控制进入 Kubernetes 集群的流量的资源对象。
Gateway 是 Ingress 的下一代 API,旨在提供更强大的功能和灵活性。
Istio Gateway 是 Istio 服务网格中用于控制进入服务网格的流量的组件,并支持更丰富的流量管理功能。

三个对象对比

特性 Kubernetes Ingress Kubernetes Gateway Istio Gateway
API 对象 Ingress Gateway Gateway
代理服务器 Nginx, HAProxy Envoy Envoy
支持的流量管理功能 基本 增强 丰富
服务发现 不支持 支持 支持
负载均衡 支持 支持 支持
熔断 不支持 支持 支持
超时 不支持 支持 支持
重试 不支持 支持 支持

使用场景:
如果您只需要基本的流量管理功能,可以使用 Kubernetes Ingress。
如果您需要更强大的流量管理功能,可以使用 Kubernetes Gateway 或 Istio Gateway。
如果您使用 Istio 服务网格,则建议使用 Istio Gateway。

1.1 Istio定义

官网(英文):

https://istio.io/latest/ 

官网(中文):

https://istio.io/latest/zh/ 

Istio是一个开源的服务网格。

特性

  • 自动负载均衡HTTP, gRPC, WebSocket和TCP流量

架构

Istio服务网格从逻辑上分为数据平面和控制平面

  • 数据平面

    由一组被部署为 Sidecar 的智能代理(Envoy) 组成。这些代理负责协调和控制微服务之间的所有网络通信。 它们还收集和报告所有网格流量的遥测数据。

  • 控制平面

    管理并配置代理来进行流量路由。
    在这里插入图片描述

二、Istio的安装

2.1 通过Istioctl安装

Kubernetes与Istio对应关系

https://istio.io/latest/docs/releases/supported-releases/#support-status-of-istio-releases 

下载

curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.16.6 sh - 

目录说明

./istio-1.16.6 ├── bin           # 存放istioctl二进制文件 ├── LICENSE ├── manifests     # istio内置的chart目录,默认使用这些内置的chart生成安装清单,安装过程也可以自行设置 ├── manifest.yaml # 指定外部chart ├── README.md  ├── samples       # 提供一些示例应用程序 └── tools         # 一些工具,如certs用于生成证书 

1)配置环境变量

cat <<EOF > /etc/profile.d/custom.sh #! /bin/bash export ISTIO_HOME=/opt/istio/istio-1.16.6  export PATH=$ISTIO_HOME/bin:$PATH EOF 

查看istio的profile

istioctl profile list 

Istio configuration profiles:
ambient
default
demo
empty
external
minimal
openshift
preview
remote

① default: 根据 lstioOperator AP!的默认设置启动组件。建议用于生产部署和 Multicluster Mesh 中的 Primary Cluster。您可以运行 istioct profile dump 命令来查看默认设置,
② demo: 这一配置具有适度的资源需求,旨在展示lstio 的功能。它适合运行 Bookinfo 应用程序和相关任务。 此配置文件启用了高级别的追踪和访问日志,因此不适合进行性能测试。
③ minimal: 与默认配置文件相同,但只安装了控制平面组件。它允许您使用 Separate Profile 配置控制平面和数据平面组件(例如 Gateway)。
④ remote: 配置Multicluster Mesh 的 Remote Cluster.
⑤ empty: 不部署任何东西。可以作为自定义配置的基本配置文件。
⑥ preview: 预览文件包含的功能都是实验性。这是为了探索 lstio 的新功能。不确保稳定性、安全性和性能(使用风险需自负)。

组件defaultdemominimalremoteemptypreview
核心组件
istio-ingressgateway
istio-egressgateway
istiod

2)执行安装

istioctl install --set profile=demo 

3)给命名空间添加标签

创建ns-istio命名空间

kubectl create namespace ns-istio 

给命ns-istio名空间添加标签,指示istio在部署应用的时候,自动注入Envoy边车代理

kubectl label namespace ns-istio istio-injection=enabled 

查看安装结果

kubectl get svc,pod -n istio-system 

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istio-egressgateway ClusterIP 10.102.75.82 80/TCP,443/TCP 14h
service/istio-ingressgateway LoadBalancer 10.108.158.227 15021:31495/TCP,80:30645/TCP,443:30754/TCP,31400:31434/TCP,15443:31846/TCP 14h
service/istiod ClusterIP 10.105.204.23 15010/TCP,15012/TCP,443/TCP,15014/TCP 14h

NAME READY STATUS RESTARTS AGE
pod/istio-egressgateway-66d96985c-2xc4x 1/1 Running 2 (10h ago) 14h
pod/istio-ingressgateway-c5fd879b5-f4wkh 1/1 Running 2 (10h ago) 14h
pod/istiod-98988c6b6-8qvr8 1/1 Running 2 (10h ago) 14h

4)卸载

istioctl uninstall --purge 

删除istio-system命名空间

kubectl delete namespace istio-system 

2.2 通过Helm安装

TODO

三、Istio组件

3.1 Gateway

在安装Istio的时候,安装了入口网关和出口网关。这两个网关实际都运行了一个Envoy代理实例,他们在网格的边缘做为负载均衡器运行。入口网关接收入站连接,而出口网关接收从集群出去的连接。

有一个指向入口网关单一的外部IP地址,并根据Header将流量路由到集团内的不同的服务。通过入口网关,可以对进入集群的流量应用路由规则。

使用Gateway配置网关资源

apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata:   name: gateway-hello   namespace: ns-istio spec:   selector:     istio: ingressgateway # 通过这个标签选中了istio=ingressgateway的service   servers:   - port:       number: 80       name: http       protocol: HTTP     hosts:     - hello.alisls.com 

上述配置解释:

  • 配置了一个代理,做为负载均衡器

  • 为入口暴露80端口

  • 配置应用于istio入口网关代理

  • hosts字段做为一个过滤器,只有以hello.alisls.com为目的地的流量才被允许通过

网关资源描述了负载均衡器的暴露端口、协议、SNI配置等

Gateway字段名称字段含义
metadata.nameGateway名称
metadata.namespace
spec.selectorGateway使用填写的标签键值对匹配配置下发的边缘代理网关实例
spec.servers.port.number端口
spec.servers.hosts域名,支持通配符*
spec.servers.tls.httpsRedirect值为true时,边缘代理网关会对所有http请求返回301重定向,要求客户端发起https请求
spec.servers.tls.mode配置当前端口的 TLS 安全认证模式,如需要开启当前端口的安全认证则需要填写。支持PASSTHROUGH, SIMPLE, MUTUALAUTO PASSTHROUGH, ISTIO MUTUAL
spec.servers.tls.credentialName配置发现 TLS 证书密钥的 secret 的名称
spec.servers.tls.serverCertificate设置端口的 TLS 证书密钥通过 file mount 形式(不推荐,推荐采用填写 credentialName 字段加载证书私钥)挂载时需要填写的证书路径字段Istio 默认使用网关所在命名空间下 istio-ingressgateway-certssecret加载证书至路径/etc/istio/ingressgateway-certs
spec.servers.tls.privateKey设置端口的 TLS 证书密钥通过 file mount 形式(不推荐,推荐采用填写 credentialName 字段加载证书私钥)挂载时需要填写的私钥路径字段Istio 默认使用网关所在命名空间下 istio.ingressgateway-certs secret 加载私钥至路径/etc/istio/ingressgateway-certs
spec.servers.tls.caCertificates设置端口的 TLS 证书密钥通过 file mount 形式(不推荐,推荐采用填写 credentialName 字段加载证书私钥)挂载时需要填写的跟证书路径字段Istio 默认使用网关所在命名空间下 istio-ingressgateway-ca-certs 加载根证书至路径/etc/istio/ingressgateway-ca-certs,双向认证时需要配置根证书

SNI, 服务器名称指示,是TLS协议的扩展。它指示在”握手“过程开始时浏览器正在联系哪个主机名;允许服务器为多个站点安全地托管多个SSL证书,多个网站存在于同一IP地址上。

为了控制和转发流量到集群内部运行实例的Kubernetes服务,我们必须用特定的主机名(例如:hello.alisls.com)配置一个VirtualService,让后将网关连接到它。
在这里插入图片描述

3.2 VirtulService

使用VirtualService资源在Istio服务网格中进行流量路由。通过VirtualService定义流量路由规则。

VirtualService字段名称字段说明
spec.hosts定义路由规则关联一组的 hosts,可以是带有通配符的 DNS 名称或者IP 地址(IP 地址仅能应用于来源流量为边缘代理网关)。该字段能应用于HTTP 和 TCP 流量。在 Kubernetes 环境中,可以使用 service 的名称作为缩写,lstio 会按照VirtualService所在 namespace 补齐缩写,例如在default namespace 的VirtualService 包含host 缩写 reviews 会被补齐为reviews.default.svc.cluster.local。为避免误配置,推荐填写 host 全称
spec.gateways定义应用路由规则的来源流量,可以是一个或多个网关,或网格内部的 sidecar,指定方式为/,保留字段 mesh 表示网格内部所有的 sidecar,当该参数缺省时,会默认填写 mesh,即该路由规则的来源流量为网格内部所有 sidecar
spec.http定义一组有序的(优先匹配靠前的路由规则)应用于 HTTP 流量的路由规则,HTTP 路由规则会应用于网格内部的 service 端口命名为 http-,http2-,grpc-开头的流量以及来自 gateway 的协议为HTTP HTTP2,GRPC, TLS-Terminated-HTTPS 的流量
spec.http.match定义路由的匹配规则列表,单个匹配规则项内所有条件是且关系,列表中多个匹配规则之间为或关系
spec.http.route定义路由转发目的地列表,一条 HTTP 路由可以是重定向或转发(默认),转发的目的地可以是一个或多个服务(服务版本)。同时也可以配置权重、header 操作等行为
spec.http.redirect定义路由重定向,一条 HTTP 路由可以是重定向或转发(默认),如规则中指定了 passthrough 选项,route、redirect 均会被忽略。可将 HTTP301 重定向到另外的 URL 或 Authority
spec.http.rewrite定义重写 HTTP URL或 Authority headers,不能与重定向同时配置,重写操作会在转发前执行
spec.http.timeout定义HTTP请求的超时时间
spec.http.retries定义HTTP请求的重试策略
spec.http.fault定义HTTP流量的故障注入策略,开启时超时和重试策略不会开启
spec.http.mirror定义将 HTTP 流量复制到另一个指定的目的端,被复制的流量按照“best effort”原则,sidecar/网关不会等待复制流量的响应结果就会从源目的端返回响应。镜像流量的目的服务端会产生监控指标。
spec.http.mirrorPercent定义流量镜像的复制百分比,缺省时复制100%的流量。最大值为100
spec.http.corsPolicy定义 CORS 策略(跨域资源共享,Cross-OriginResource Sharing, CORS)
spec.http.headers定义 header 操作规则,包括 request 和response header 的更新,增加,移除操作
spec.tcp定义一组有序的(优先匹配靠前的路由规则)应用于 TCP 流量的路由规则,该路由规则会应用于任何非 HTTP 和 TLS 的端口
spec.tcp.match定义 TCP 流量路由的匹配规则列表,单个匹配规则项内所有条件是且关系,列表中多个匹配规则之间为或关系
spec.tcp.route定义 TCP 连接转发的目的端
spec.tls定义一组有序的(优先匹配靠前的路由规则)应用于未终止的 TLS 或 HTTPS 流量的路由规则,该路由规则会应用于网格内部的 service 端口命名为https-,tls-开头的流量,来自 gateway 的端口协议为 HTTPS, TLS 的未终止加密流量,ServiceEntry 使用 HTTPS, TLS 协议的端口。当 https-,tls-端口未关联 VirtualService 规则时将会被视为TCP 流量
spec.tls.match定义 TLS 流量路由的匹配规则列表,单个匹配规则项内所有条件是且关系,列表中多个匹配规则之间为或关系
spec.tls.route定义连接转发的目的端

3.2.1 route详解

HTTPRoute规则的功能是:满足HTTPMatchRequest条件的流量都被路由到HTTPRouteDestination,执行重定向(HTTPRedirect)、重写(HTTPRewrite)、重试(HTTPRetry)、故障注入(HTTPFaultlnjection)、跨站(CorsPolicy)策略等。HTTPRoute不仅可以做路由匹配,还可以做一些写操作来修改请求本身。

3.2.2 match详解

match定义路由的匹配条件。

支持以下字段的定义:

  • uri, schema, method, authority: 这四个字段都是StringMatch类型,匹配请求时都支持exact, prefix和regex三种模式的匹配

    - match:   - uri:       prefix: /hello 
  • headers: 匹配请求中的Header,是一个map类型。map的key是字符串类型,value是StringMatch类型。即对每一个Header的值,都可以使用精确、前缀和正则三种方式进行匹配。

    - match:   - headers:       source:         exact: north 
  • port: 表示请求服务的端口,大多数服务只开放一个端口,这也是在微服务中推荐的做法,在这种场景下可以不指定port;

  • sourceLabels: 是一个map类型的键值对,表示请求来源负载匹配标签。这在很多情况有用,可以对一组服务都打一个相同的标签,然后使用sourceLabels字段对这些服务实施相同的流量规则。在Kubernetes平台上,这里的Label就是Pod上的标签。

    http: - match:   - sourceLabels:       app: testA       version: v2 
  • gateway: 表示规则应用的Gateway名称,语义同VirtualService 上面的gateway定义,是一个更细的Match条件,会覆盖在VirtualService上配置的gateway。

在VirtualServite中match字段都是数组类型。HTTPMatchRequest中的诸多属性如uri、header、method等都是“与”逻辑,而数组中几个元素间关系是“或”逻辑。

- match:   - headers:       source:         exact: north     uri:       prefix: "/hello"   - uri:       prefix: "/hello2" 

match包含两个HTTPMatchRequest元素,其条件的语义是:headers中的source取值为“north”,且uri以“/hello”开头的请求,或者uri以“/hello2”开头的请求。

3.2.3 路由目标

路由目标,RouteDestination

route字段是一个HTTPRouteDestination类型的数组,表示满足条件的流量目标。

  • destination 请求目标,包含host, subset, port三个属性

    1)host 在istio中注册的服务名

    2)subset 表示在host上定义的一个子集

    3)port

    spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:         host: hello.alisls.com         subset: v2     - destination:         host: hello.alisls.com         subset: v1 
  • weight 权重

    weight表示流量分配的比例,在一个route下多个destination的weight总和要求是100。默认也是100,必填字段。

    示例:从原有的v1版本中切分20%的流量到v2版本,这也是灰度发布常用的一个流量策略,即不区分内容,平等的从总流量中切出一部分给新版本。

    spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:         host: hello.alisls.com         subset: v2       weight: 20     - destination:         host: hello.alisls.com         subset: v1       weight: 80 
  • headers

    提供了对HTTP header的一种操作机制,可以修改一次HTTP请求中的Request或Response的值。包含request和response两个字段。

    • request

      表示发请求给目标地址时修改request的header

    • response

      表示返回应答时修改response的header

    对应的类型都是HeaderOperation类型,使用set, add, remove字段来定义对Header的操作。

    • set: 使用map上的key和value覆盖request和response中对应的header

    • add: 追加map上的key和value到原有的header

    • remove: 删除在列表中指定的header

3.2.4 HTTP重定向

HTTPRedirect包括两个重要的字段来表示重定向的目标

  • uri 替换URL中的uri部分

  • authority 替换URL中的Authority部分

1)用户请求老地址

http://hello.alisls.com/hello 

2)服务端返回301重定向新地址

http://welcom.alisls.com/welcome 

3)用户请求新地址

http://welcom.alisls.com/welcome 
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: gateway-hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - match:     - uri:         prefix: /hello     redirect:       uri: /welcome       authority: welcome.alisls.com 

对hello.alisls.com服务所有前缀是/hello的请求都会被重定向到welcome.alisls.com的/welcome地址。

3.2.5 HTTP重写

通过HTTP重写可以在将请求转发给目标服务前修改HTTP请求中指定部分的内容,不同于重定向,用户是可见的(HTTP重写对用户实不可见的,因为在服务端进行的)。

重写HTTP也包括uri和authority两个字段

  • uri 重写URL中的Path部分

  • authority 重写URL中的Authority

和HTTPRedirect规则稍有不同的是,HTTPRedirect替换全部的Path;HTTPRewrite的uri是可以重写前缀的,即如果原来匹配条件是前缀匹配,则修改后只修改匹配到的前缀。

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - match:     - uri:         prefix: /hello     rewrite:       uri: /welcome     route:     - destination:       host: hello 

前缀匹配/hello的请求,其请求uri中的这部分前缀会被/welcome替换。

3.2.6 HTTP重试

HTTP重试是解决很多请求异常最直接、简单的方法。尤其是在工作环境比较复杂的场景下,可提高总体服务质量。

但重试使用不当也会有问题,最糟糕的情况是重试一直不成功,反而增加延迟和性能开销。所以根据系统运行环境、服务自身特点,配置适当的重试规则显得尤为重要。

HTTPRetry可以定义请求失败时的重试策略,重试策略包括重试次数,超时,重试条件等,这里分别描述相应的三个字段:

  • attempts

    必选字段,定义重试次数

  • perTryTimeout

    每次重试超时的时间,单位可以是ms, s, m和h

  • retryOn

    进行重试的条件,可以是多个条件,以逗号分隔。

    取值包括以下几种:

    • 5xx: 在上游服务返回5xx应答码,或者在没有返回时重试

    • gateway-error: 类似5xx异常,只对502,503和504应答码进行重试

    • connect-failure: 在链接上游服务失败时重试

    • retriable-4xx: 在上游服务返回可重试的4xx应答码时执行重试

    • refused-stream: 在上游服务使用REFUSED_STREAM错误码重置时执行重试

    • cancelled: gRPC应答的Header中状态码是cancelled时执行重试

    • deadline-exceeded: 在gRPC应答的Header中状态码是deadline-exceeded时执行重试

    • internal: 在gRPC应答的header中状态码是internal时执行重试

    • resource-exhausted: 在gRPC应答的Header中状态码是resource-exhausted时执行重试

    • unavailable: 在gRPC应答的Header中状态码是unavailable时执行重试

    示例:

    配置一个重试策略,在5xx, connect-failure条件下进行最多5次重试,每次重试超时为3秒

    apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:       host: hello     retries:       attempts: 3       perTryTimeout: 3s       retryOn: 5xx, connect-failure 

3.2.7 HTTP流量镜像

HTTP流量镜像是指将流量转发到原目标地址的同时,将流量给另外一个目标地址镜像一份。把生产环境中的实际流量镜像一份到另一个系统上,完全不会对生产系统产生影响。这里只镜像了一份流量,数据面代理只需要关注原来转发的流量就可以,不用等待原镜像目标地址的返回。

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:         host: hello         subset: v1     mirror:       host: hello       subset: v2 

3.2.8 HTTP故障注入

延时故障注入HTTPFaultInjection通过delay和abort两个字段设置延时和中止两种故障,分别表示Proxy延时转发HTTP请求和中止HTTP请求。

延时故障注入

使用HTTPFaultInjection.Delay类型描述延时故障。表示发送请求前进行一段延时,模拟网络、远端服务负载均衡等各种原因导致的失败,主要有以下两个字段:

  • fixedDelay

    必选字段,表示延时时间,单位可也是毫秒、秒、分钟和小时。至少大于1毫秒。

  • percentage

    配置的延迟故障作用在多少比例的请求上,通过这种方式可以只让部分请求发生故障。

示例:

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:         host: hello         subset: v1     fault:       delay:         percentage:           value: 1.5         fixedDelay: 10s 

请求中止故障注入

使用HTTPFaultInjection.Abort描述中止故障,模拟服务端异常,给调用的客户端返回预先预先定义的错误状态码,主要有以下两个字段:

  • httpStatus 是一个必选字段,表示中止的HTTP状态码

  • percentage 配置中止故障作用在多少比例的请求上,通过这种方式可以只能让部分请求发生故障,用法同延时故障

示例:让hello的v1版本的服务1.5%的请求返回500

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:         host: hello         subset: v1     fault:       abort:         percentage:           value: 1.5         httpStatus: 500 

3.2.9 HTTP跨域资源共享

HTTP跨域资源共享 CORS(Cross Origin Resource Sharing)

当一个资源向该资源所在服务器的不同领域发起请求时,就会产生一个跨域的HTTP请求。出于安全考虑,浏览器会限制从脚本发起的跨域HTTP请求。通过跨域资源共享CORS机制可以允许Web应用服务器进行跨域访问控制,使跨域数据传递安全进行。在实现上是在HTTP Header中追加一些额外的信息来通知浏览器准许以上访问。

在VirtualService中可以对满足条件的请求配置跨域资源共享。有allowOrigin, allowMethods, allowHeader, exposeHeader, maxAge, allowCredentials, 其实都是被转化成Access-Control-*的Header。

示例:允许来在news.com的GET方法的请求的访问:

apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: vs-hello   namespace: ns-istio spec:   hosts:   - hello.alisls.com   http:   - route:     - destination:         host: hello       corsPolicy:         allowOrigin:         - news.com         allowMethods:         - GET         maxAge: "2d" 

3.3 DestinationRule

VirtualService中的destination中会包含Service子集的subset字段,这个服务子集就是通过DestinationRule定义的。

字段名称字段含义
spec.host关联 DestinationRule 配置的服务名称,可以是自动发现的服务(例如 Kubernetes servicename),或通过ServiceEntry声明的 hosts。如填写的服务名无法在上述源中找到,则该DestinationRule 中定义的规则无效
spec.subsets定义服务的版本(subsets),版本可通过标签键值对匹配匹配服务中的endpoints。可以在subsets 级覆盖流量策略配置
spec.trafficPolicy定义流量策略,包括负载均衡、连接池、健康检查、TLS 策略
spec.trafficPolicy.loadBalancer配置负载均衡算法,可配置:简单负载均衡算法(round robin, least conn, random…),一致性哈希(会话保持,支持按 headername,cookie,IP,query parameter 哈希),地域感知负载均衡算法
spec.trafficPolicy.connectionPool配置与上游服务的连接量,可设置 TCP/HTTP 的连接池
spec.trafficPolicy.outlierDetection配置从负载均衡池中驱逐不健康的 hosts
spec.trafficPolicy.tls连接上游服务的 client 端 TLS 相关配置,与PeerAuthentication 策略(server 端 TLS 模式配置)配合使用
spec.trafficPolicy.portLevelSettings配置端口级别的流量策略,端口级别的流量策略会覆盖服务/subsets 级别的流量策略配置

通过DestinationRule,我们可以定义设置,如负载均衡配置,连接池大小,局部异常检测,在路由发生后应用于流量。我们可以在trafficPolicy字段下设置流量策略。

  • 负载均衡器设置

  • 连接池设置

  • 局部异常点检测

  • 客户端TLS设置

  • 端口流量策略

示例:

apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata:   name: dr-hello   namespace: ns-istio spec:   host: hello.ns-istio.svc.cluster.local   subsets:   - name: v1     labels:       version: v1   - name: v1     labels:       version: v2                  

3.3.1 负载均衡器设置

通过负载均衡器设置,我们可以控制目的地使用哪种负载均衡算法。

apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata:   name: dr-hello   namespace: ns-istio spec:   host: hello.ns-istio.svc.cluster.local   trafficPolicy:     loadBalancer:       simple: ROUND_ROBIN # 轮询算法   subsets:   - name: v1     labels:       version: v1   - name: v2     labels:       version: v2 
  • simple字段指定负载均衡算法

    1)ROUND_ROBIN 轮询算法,默认

    2)LEAST_CONN 最少连接算法

    3)RANDOM 随机

    4)PASSTHROUGH 直接转发连接到客户端连接的目标地址,即没有做负载均衡

  • consistentHash字段

    一致性hash,并根据HTTP头,cookies或其他请求属性提供会话亲和性。

    httpHeaderName: 基于Header

    httpCookie: 基于Cookie

    useSourceIP: 基于源IP计算哈希值

    minimumRingSize: 哈希环上虚拟节点数的最小值,节点数越多则负载均衡越精细

    ...   trafficPolicy:     loadBalancer:       consistentHash:         httpCookie:           name: location           ttl: 4s 

3.3.2 连接池配置

可以在TCP和HTTP层面应用于上游服务的每个主机,可用用来控制连接数量。

TCP连接池配置

1)maxConnections

上游服务的所有实例建立的最大连接数,默认是1024,属于TCP层面的配置,对于HTTP,只用于HTTP/1.1,因为HTTP/2对每个主机都使用单个连接。

2)connectTimeout: TCP连接超时,表示主机网络连接超时,可以改善因调用服务变慢导致整个链路变慢的情况。

3)tcpKeepalive: 设置TCP keepalives,属于istio1.1新支持的配置,定期给端发送一个keepalive的探测包,判断连接是否可用。

spec:   host: hello.ns-istio.svc.cluter.local   trafficPolicy:     connectionPool:       tcp:         maxConnections: 50         connectTimeout: 25ms         tcpKeepalive:           probes: 5           time: 3600           interval: 60s 

Http连接池配置

1)http1MaxPendingRequests: 最大等待 HTTP 请求数,默认值是 1024,只适用于HTTP/1.1 的服务,因为 HTTP/2 协议的请求在到来时会立即复用连接,不会在连接池等待。

2)http2MaxRequests: 最大请求数,默认是1024。只适用于HTTP/2服务,因为HTTP/1.1使用最大连接数maxConnections即可,表示上游服务的所有实例处理的最大请求数。

3)maxRetries: 最大重试次数,默认是3,表示服务可以执行的最大重试次数。如果调用端因为偶尔抖动导致请求直接失败,则可能会带来业务损失,一般建议配置重试,若重试成功则可正常返回数据,只不过比原来响应得慢一点,但重试次数太多会影响性能,要谨使用。

4)idleTimeout: 空闲超时,定义在多长时间内没有活动请求则关闭连接。

http可用和tcp配合使用,示例:

spec:   host: hello.ns-istio.svc.cluter.local   trafficPolicy:     connectionPool:       tcp:         maxConnections: 80         connectTimeout: 25ms       http:         http2MaxRequests: 800         maxRequestsPerConnection: 10 

配置最大80个连接,只允许最多800个并发请求,每个连接的请求数不超过10个,连接超时是25毫秒。

3.3.3 异常点检查

异常点检测是一个断路器的实现,它跟踪上游服务中每个主机(Pod)的状态。如果一个主机开始返回5xx HTTP错误,它就会在预定的时间内被从负载均衡池中弹出。对于TCP服务,Envoy将连接超时或失败计算为错误。

两种健康检测:

  • 主动性

    定期探测目标服务实例,根据应答来判断服务实例的健康状态。如负载均衡器中的健康检查。

  • 被动性

    通过实际的访问情况来找出不健康的实例,如istio中的异常检查点。

异常实例检查相关配置:

  • consecutiveErrors:

    实例被驱逐前的连续错误次数,默认是5。

    对于HTTP服务,返回502,503和504的请求会被认为异常;

    对于TCP服务,连接超时或者连接错误事件会被认为异常;

  • interval

    驱逐的时间间隔,默认值为10s, 要求大于1ms,单位可以是时、分、毫秒;

  • baseEjectionTime

    最小驱逐时间。一个实例被驱逐的时间等于这个最小驱逐时间*驱逐次数。这样一个因多次异常被驱逐的实例,被驱逐的时间会越来越长。默认为30s,要求大于1ms,单位可以是时、分、毫秒。

  • maxEjectionPercent

    负载均衡池中可以被驱逐的故障实例的最大比例,默认为10%,设置这个值是为了避免太多的服务实例被驱逐导致服务整体能力下降。

  • minHealthPercent

    最小健康实例比例,是lstio 1.1新增的配置。当负载均衡池中的健康实例数的 例大于这个比例时,异常点检查机制可用;当可用实例数的比例小于这个比例时,异常点检查功能将被禁用,所有服务实例不管被认定为健康还是不健康,都可以接收请求。参数的默认值为50%。

trafficPolicy:   connectionPool:     http:       http2MaxRequests: 500       maxRequestsPerConnection: 10   outlierDetection:     consecutiveErrors: 10     interval: 5m     baseEjectionTime: 10m 

3.3.4 TLS设置

包含任何与上游服务连接的 TLS 相关设置。下面是一个使用提供的证书配置 mTLS 的例子:

... trafficPolicy:   tls:     mode: MUTUAL     clientCertificate: /etc/certs/cert.pem     privateKey: /etc/certs/key.pem     caCertificates: /etc/certs/ca.pem 

mtls: 双向认证,客户机和服务器都通过证书颁发机构彼此验证身份。

由同一个 root ca 生成两套证书,即客户端证书和服务端证书。客户端使用 https 访问服务端时,双方会交换证书,并进行认证,认证通过方可通信。

其他支持的 TLS 模式有 DISABLE(没有 TLS 连接),SIMPLE(在上游端点发起 TLS 连接),以及ISTIO MUTUAL(与MUTUAL类似,使用Istio的mTLS 证书)。

3.3.5 端口流量策略

在端口上配置流量策略,且端口上流量策略会覆盖全局的流量策略。

trafficPolicy:   connectionPool:     tcp:       maxConnections: 80   portLevelSettings:   - port:       number: 80     loadBalancer:       simple: LEAST_CONN     connectionPool:       tcp:         maxConnections: 100    - port:        number: 8000      loadBalancer:        simple: ROUND_ROBIN 

3.3.6 服务子集

subset,定义服务子集

  • name 服务子集的名字

  • labels subset上的标签,通过一组标签定义了属于这个subset的服务实例。比如最常用的标识服务版本version标签

  • trafficPolicy 应用到这个subset上的流量策略

示例:

...... spec:   hosts: hello   subsets:   - name: v2     labels:       version: v2     trafficPolicy:       connectionPool:         tcp:           maxConnections: 80 # 给一个特定的subset配置最大连接数 

四、Kiali组件

kiali组件位于:安装包/samples/addons,将这个目录下的所有插件都安装

执行安装

kubectl apply -f ./addons/ 

注意:如果在安装插件时出错,再运行一次命令。有一些和时间相关的问题,再次运行就能解决。

查看安装结果

kubectl get svc,pod -n istio-system 
[root@node21 samples]# kubectl get svc,pod -n istio-system NAME                           TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE service/grafana                ClusterIP      10.99.8.238      <none>        3000/TCP                                                                     6m50s service/istio-egressgateway    ClusterIP      10.102.75.82     <none>        80/TCP,443/TCP                                                               16h service/istio-ingressgateway   LoadBalancer   10.108.158.227   <pending>     15021:31495/TCP,80:30645/TCP,443:30754/TCP,31400:31434/TCP,15443:31846/TCP   16h service/istiod                 ClusterIP      10.105.204.23    <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP                                        16h service/jaeger-collector       ClusterIP      10.96.79.13      <none>        14268/TCP,14250/TCP,9411/TCP                                                 6m49s service/kiali                  NodePort       10.96.12.6       <none>        20001:30418/TCP,9090:30171/TCP                                               17m service/prometheus             ClusterIP      10.99.107.205    <none>        9090/TCP                                                                     6m49s service/tracing                ClusterIP      10.111.187.36    <none>        80/TCP,16685/TCP                                                             6m49s service/zipkin                 ClusterIP      10.98.207.250    <none>        9411/TCP                                                                     6m49s  NAME                                       READY   STATUS    RESTARTS      AGE pod/grafana-b854c6c8-ts8c5                 1/1     Running   0             6m50s pod/istio-egressgateway-66d96985c-2xc4x    1/1     Running   2 (12h ago)   16h pod/istio-ingressgateway-c5fd879b5-f4wkh   1/1     Running   2 (12h ago)   16h pod/istiod-98988c6b6-8qvr8                 1/1     Running   2 (12h ago)   16h pod/jaeger-54b7b57547-k5jxh                1/1     Running   0             6m49s pod/kiali-5ff88f8595-7m4qb                 1/1     Running   0             17m pod/prometheus-7b8b9dd44c-smvnn            2/2     Running   0             6m49s 

修改kiali的Service类型为NodePort,方便外部可以访问

kubectl edit service kiali -n istio-system 

访问

http://node21:30418/ 

五、实战

5.1 Hello服务实战

1)开发一个SpringBoot服务

2)发布Docker镜像

3)部署服务到Kubernetes

hello.yaml

apiVersion: v1 kind: Service metadata:   name: hello   namespace: ns-istio spec:   type: ClusterIP # Service的类型:ClusterIP, NodePort, LoadBalancer, ExternalName   ports: # 端口信息     - port: 8080 # service端口       targetPort: 8080 # pod端口   selector: # 标签选择器,用于确定当前service代理哪些pod     app: hello --- apiVersion: apps/v1 kind: Deployment metadata:   name: hello   namespace: ns-istio spec:   replicas: 1 # 副本数量   selector: # 选择器,通过它指定该控制器管理哪些pod     matchLabels:       app: hello   template:     metadata:       labels:         app: hello     spec:       containers:         - name: hello           image: com.alisls/hello:1.0           ports:             - containerPort: 8080               protocol: TCP       nodeName: node26 # 为了调试方便,只发布到node26节点 

4)部署Gateway和VirtualService

apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata:   name: gateway-hello   namespace: ns-istio spec:   selector:     istio: ingressgateway # use istio default controller   servers:   - port:       protocol: HTTP       name: http       number: 80     hosts:     - "*" --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata:   name: hello   namespace: ns-istio spec:   hosts:   - "*"   gateways:   - gateway-hello   http:   - match:     - uri:         prefix: /hello     route:     - destination:         host: hello # service name         port:           number: 8080 # service port 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!