kubernetes 中服务接入istio

时间:2019-12-03 14:16:57   收藏:0   阅读:396

目标

istio 的几个基本资源对象:

  1. VirtualService
    配置影响流量路由的参数,VirtualService 定义了对特定目标服务的一组流量规则。如其名字所示, VirtualService在形式上表示一个虚拟服务,将满足条件的流量都转发到对应的服务后端,这个服务后端可以是一个服务,也可以是在Dest in at i onRu l e 中定义的服务的子集
  2. DestinationRule
    配置目标规则,DestinationRule定义了在路由发生后应用于服务流量的策略。这些规则指定负载平衡的配置,边车的连接池大小以及离群值检测设置,以从负载平衡池中检测和清除不正常的主机。
  3. Gateway
    服务网关,入口.Gateway描述了一个负载均衡器,该负载均衡器在网格的边缘运行,以接收传入或传出的HTTP / TCP连接。
  4. Service Entry
    外部服务配置,通过ServiceEntry,可以在Istio的内部服务注册表中添加其他条目,以便网格中自动发现的服务可以访问/路由到这些手动指定的服务。

网关功能 -- Gateway

Gateway 在网格边缘接收外部访问,并将流量转发到网格内的服务。Istio 通过Gateway将网格内的服务发布成外部可访问的服务,还可以通过Gateway 配置外部访问的端口、协议及与内部服务的映射关系。
网关功能常见的应用

  1. 将网格内的HTTP 服务发布为HTTP 外部访问
  2. 将网格内的HTTPS 服务发布为HTTPS 外部访问
  3. 将网格内的HTTP 服务发布为HTTPS 外部访问
  4. 将网格内的HTTP 服务发布为双向HTTPS 外部访问
  5. 将网格内的HTTP 服务发布为HTTPS 外部访问和HTTPS 内部访问

在实践中。我们更多需要的是1,3两个场景
在dfb服务中。 dfb-login 作为最外层的前端。是几个服务中唯一和外部用户产生交互的服务。 因此我们通过网关功能,将dfb-login 通过域名暴露给用户
创建gateway 的yml文件

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: login-gateway
  namespace: dfb-istio
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - istio-login.dfb.com
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      privateKey: /etc/istio/ingressgateway-certs/dfb.pem
      serverCertificate: /etc/istio/ingressgateway-certs/dfb.pem
  - hosts:
    - istio-login.dfb.com
    port:
      name: http
      number: 80
      protocol: HTTP

创建virtualservice.yml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: dfb-login
  namespace: dfb-istio
spec:
  gateways:
  - login-gateway
  hosts:
  - '*'
  http:
  - uri:
      prefix: /
  - route:
    - destination:
        host: dfb-login.dfb-istio.svc.cluster.local

我们创建了两个资源对象,一个VirtualService 用来描述流量的路由关系。所有url 前缀为/ 的请求都route 到后端dfb-login.dfb-istio.svc.cluster.local 服务。
这个virtuaservice 通过gateways 字段和我们申明的另一个gateway 资源相互绑定。在Gateway 资源对象中。 定义了入口的域名,协议,以及TLS 相关的配置。在istio 中。默认的ingressgateway 会监听gateway 资源对象的变更。多个ingressgateway 通过selector 进行选择.默认ingressgateway 是一个loadbalancer的service 。 我们将这个ingressgateway 修改为宿主机网络,并固定到一个单独的节点。这样我们就可以通过将域名解析到这个node节点的方式访问部署好的入口

流量分配:按比例,根据请求内容

我们设置了两个版本的login 服务。 V1 版本用户登录后显示的余额是从数据库取出来的。V2版本则是0。根据这两个版本的差异来判断流量的流向。
首先通过DestinationRule定义两个版本

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: dfb-login
  namespace: dfb-istio
spec:
  host: dfb-login
  subsets:
  - labels:
      version: v1
    name: v1
  - labels:
      version: v2
    name: v2

根据比例

修改在网关功能中创建的virtualservice

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: dfb-login
  namespace: dfb-istio
spec:
  hosts:
    - '*'
  gateways:
    - login-gateway
  http:
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: dfb-login.dfb-istio.svc.cluster.local
            subset: v1
          weight: 50
        - destination:
            host: dfb-login.dfb-istio.svc.cluster.local
            subset: v2
          weight: 50

此时多次刷新页面。可以看到用户的现金账户余额在0 和真实额度之间变动

根据请求内容决定路由

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: dfb-login
  namespace: dfb-istio
spec:
  hosts:
    - '*'
  gateways:
    - login-gateway
  http:
    - match:
        - headers:
            version:
              exact: v2
      route:
        - destination:
            host: dfb-login.dfb-istio.svc.cluster.local
            subset: v2
    - route:
        - destination:
            host: dfb-login.dfb-istio.svc.cluster.local
            subset: v1

修改上文yml 。 通过postman请求dfb服务/home页面。默认情况下会路由指向V1版本的login服务。在请求头添加version=v2的header。 则会转到v2的服务。

超时,重试功能

我们首先在扩容dfb-api 这个服务为2个pod,在其中一个pod中拦截用户资产接口, 直接返回500 ,另一个pod 正常返回。 此时在dfb-login服务中请求。 我们可以发现,接口500 和200 状态码交替出现。

        location =/user/account/list/338fbcd2-1be6-4dde-9918-84b7629b1ba5 {
            return 500;
        }

此时应用下面的重试规则,再次调用接口。此时接口状态码一直返回200.

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: dfb-api
  namespace: dfb-istio
spec:
  hosts:
    - dfb-api.dfb-istio.svc.cluster.local
  gateways: ~
  http:
  - route:
      - destination:
          host: dfb-api.dfb-istio.svc.cluster.local
          port:
            number: 80
        weight: 100
    retries:
      attempts: 3
      perTryTimeout: 2s
      retryOn: 5xx,gateway-error,connect-failure,refused-stream

通过jaeger查看调用链,可以看到调用了两次dfb-api。虽然中间调用失败了,但是最终的状态码是200
技术图片

istio 中硬编码了retryOn 默认值为connect-failure,refused-stream(因为连接失败和流拒接是安全的),如果拦截的时候返回502 , 则istio会自动重试。无法在应用重试规则前观察到200和500 状态码交替出现。
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!