美文网首页kubernetes框架
Vistrual Service & Destination R

Vistrual Service & Destination R

作者: 程序员札记 | 来源:发表于2022-12-29 21:47 被阅读0次

    虚拟服务(Vistrual Service)是 Istio 重要的资源对象之一,作用是将流量路由到网格中的服务。支持基于权重、http header条件等优先级的路由,比Kuberentes service对于流量的管控更加的丰富,颗粒度更加精细。

    有了 Kubernetes Service,为什么还需要 Istio Vistrual Service
    简单来说,基于 Kubernetes Service,只可以实现简单的流量负载均衡,如果想实现基于HTTP Header,负载百分比等等复杂的流量控制就无从下手了,Istio Vistrual Service在原本 Kubernetes Service 的功能之上,提供了更加丰富的路由控制。

    VirtualHost

    • VirtualHost

      • 几个关键术语

        • Service:服务注册表上用于标识一组应用实例的独立单元,列如Kubernetes上的Service资源对象

        • Service Version:Service的一至多个版本(通常称为subset),通常表现为CD场景中,同时运行着的同一应用的不版本的实例组合,用于支撑实现A/B测试、Canary发布等,以及相应的流量分配机制;

        • Host:客户端请求报文中的“主机”,用于支撑基于虚拟主机的流量过滤;

      • VirtualHost的定义:一组关乎到特定“主机(客户端访问的目标地址或主机名)”的流量路由规则

    image

    VirtualService配置要点

    • VirtualService的关键字段
      • hosts: 必选字段,用于指定流量请求的目标,可以是一个DNS名称或IP地址;

        • DNS名称可以使用通配符,也可以使用短格式的Service名称;
      • gateways:指定应用流量规则的Gateway资源,在VirtualService上使用gateways字段时遵循如下规则

        • 仅应用于网格内的东西流量时,应省略gateways字段;

        • 仅用于引入网格外的流量,为gateways字段赋予合适的值(Gateway名称列表)即可

          • 客户端源自网格外部

          • Gateway负责接入这部分流量,VirtualService负责将这部分流量完成在网格内的路由

        • 同时用于网格内和网格外的流量时,需要将gateways字段的列表值的其中一项指定为“mesh”

          • 客户端既可源自网格外部,也可以是网格内部的流量
      • http: 配置http协议的流量管理机制的有序列表,其配置框架称为HTTPRoute

      • tls:用于处理非终结的TLS和HTTPS流量的有序列表,其配置框架称为TLSRoute

      • tcp:管理四层的TCP流量的有序列表,其配置框架称为TCPRoute

    VirtualService配置生效示意图

    image

    HTTP路由配置(HTTPRoute)

    • virtualservice.http配置如何处理http流量

      • 服务的端口协议是HTTP、HTTP2和GRPC,即在服务的端口名中包含http-、http2-和grpc-等;

      • Gateway的端口协议是HTTP、HTTP2和GRPC,或者Gateway终结了TLS;

      • ServiceEntry的端口协议是HTTP、HTTP2和GRPC;

    • 路由机制及服务韧性等相关的配置,即满足HTTPMatchRequest条件的流量可以做如下处理

      • 路由到指定目标(HTTPRouteDestination)

      • 执行重定向(HTTPRedirect)

      • URL重写(HTTPRewrite)

      • 请求重试(HTTPRetry)

      • 故障注入(HTTPFaultInjection)

      • 跨站资源引用(CorsPolicy)

    VirtualService and HTTPRoute CRD

    image

    HTTPRoute配置示例

    示例一

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productpage
    spec:
      hosts:
      - productpage
      http:
      - route:
        - destination:
            host: productpage
            subset: v1
    ---
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - route:
        - destination:
            host: ratings
            subset: v2
    

    url重写示例

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: demoapp
    spec:
      hosts:
      - demoapp
      http:
      - name: rewrite
        match:
        - uri:
            prefix: /canary
        rewrite:
          uri: /
        route:
        - destination:
            host: demoapp
            subset: v11
      - name: redirect
        match:
        - uri:
            prefix: "/backend"
        redirect:
          uri: /
          authority: backend
          port: 8082
      - name: default
        route:
        - destination:
            host: demoapp
            subset: v10
    

    fault-injection示例

    kind: VirtualService
    metadata:
      name: demoapp
    spec:
      hosts:
      - demoapp
      http:
      - name: canary
        match:
        - uri:
            prefix: /canary
        rewrite:
          uri: /
        route:
        - destination:
            host: demoapp
            subset: v11
        fault:
          abort:
            percentage:
              value: 20
            httpStatus: 555
      - name: default
        route:
        - destination:
            host: demoapp
            subset: v10
        fault:
          delay:
            percentage:
              value: 20
            fixedDelay: 3s
    

    参考文档

    https://istio.io/latest/zh/docs/reference/config/networking/virtual-service/

    通过例子来理解

    有两个Deployment(nginx 及 httpd),通过Service关联到一起,通过访问Service只能做到简单的负载均衡,通过实验发现 nginx 和 httpd 流量各自在 50% 左右。


    image.png

    Deployment & Service

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: nginx
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: nginx
            server: web
        spec:
          containers:
            - image: 'nginx:latest'
              name: nginx-deployment
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: httpd
      name: httpd-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpd
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: httpd
            server: web
        spec:
          containers:
            - image: 'httpd:latest' 
              name: httpd-deployment 
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: nginx
      type: ClusterIP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: httpd-service
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: httpd
      type: ClusterIP
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: web-service
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        server: web
      type: ClusterIP
    

    如果想实现更加细颗粒度的流量管控,通过引入Istio Vistrual Service 非常简单的就实现复杂的流量管理。

    VirtualService 根据 Destination 进行调度,并且设置相关的负载百分比实现精准的控制。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: web-vs
    spec:
      hosts:
      - web-service
      http:
      - route:
        - destination:
            host: nginx-service
          weight: 80
        - destination:
            host: httpd-service
          weight: 20
    

    通过客户端测试以上的实验,请留意客户端也必须经过 Istio 注入,因为只有客户端被 Istio 注入才可以接收到来自 Pilot 有关 Virtual Service 和 Destination Rule 的配置信息,才可以保证流量接管生效。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: client-deployment
      name: client-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: client-deployment
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: client-deployment
        spec:
          containers:
            - image: 'busybox:latest'
              name: client-deployment
              command: [ "/bin/sh", "-c", "sleep 3600"]
    

    进入客户端容器执行 wget -q -O - web-service观察执行结果

    Vistrual Service 条件匹配

    很多场景下,需要针对不同的用户已提供个性化的服务等(提前内测新版本),例如针对地理位置、是否为VIP等等,那就需要对 httpd 流量进行识别匹配。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: web-vs
    spec:
      hosts:
      - web-service
      http:
      - match:
        - headers:
            end-user:
              exact: carryyip
          uri:
            prefix: "/health"
          ignoreUriCase: true
        route:
          - destination:
              host: httpd-service
      - route:
        - destination:
            host: nginx-service
    

    基于 HttpMatchRequest,路由规则从上到下进行优先级排序,在生产环境中建议使用一个无条件的规则作为最后规则,确保流量始终会匹配到最少一条规则,防止意外情况的方式。

    路由规则从 match 关键字开始匹配,可以使用精确 exact 和 前缀 prefix 或者 正则表达式进行不同场景下的匹配。

    Destination Rule

    目标规则(Destination Rule)是 Istio 重要的资源对象之一,它不能独自使用,必须跟 Virtual Service 共同发挥作用,作用是将流量标记分组并路由到具体服务。

    Destination Rule 还可以做什么

    通常在生产场景下,用使用 Destination Rule 对用户进行身份、地址位置等条件的识别后的流量路由,例如部分用户优先享用新版本,则可以通过HTTP Header附加相关的字段进行识别,路由到新版本的服务上。或者在版本更新的时候,使用灰度发布,对新旧版本标记子集,按照不同的负载百分比进行调整逐步迭代。

    DestinationRule配置要点

    • DestinationRule用于配置路由完成之后的应用于服务的流量策略,即配置如何将流量调度至上游端点,同时也是为VirtualService的Destination指定的目标提供具体的定义和实现;主要包括以下配置项

      • 负载均衡配置

      • Sidecar连接池

      • 异常值检测相关的配置,即异常端点驱逐机制

    • DestinationRule的关键字段

      • host:必选字段,指定规则的适用对象,可以使用短域名;可用值是在服务注册中心注册的服务名,即网格内的服务或者是以ServiceEntry注册的网格外的服务;

      • trafficPolicy:具体的规则内容,包括负载均衡、连接池策略和异常值检测;

      • subsets:服务的子集定义,通常一个子集用于定义一个服务版本;

      • exportTo:用于控制DestinationRule跨名称空间的可见性,即控制一个名称空间下定义的DestinationRule资源对象是否可被其它名称空间下的Sidecar执行;

        • “.”:表示仅应用于当前名称空间;

        • “*”:表示应用于所有名称空间;

    • Subset:服务子集

      • name:子集名称、

      • labels:子集上的标签

      • trafficPolicy:应用于当前子集的流量策略

    • TrafficPolicy主要包含如下几项重要配置

      • loadBalancer:定义使用的负载均衡器,即负载均衡算法;

        • 简单负载均衡:

          • ROUND_ROBIN、LEAST_CONN、RANDOM和PASSTHROUTH
        • 一致性哈希:consistentHash仅对HTTP协议有效,它支持基于httpHeaderName、httpCookie、useSoureIp进行hash计算,并能够通过minimumRingSize指定Hash环大小;

          • httpHeaderName

          • httpCookie

          • useSourceIp

          • httpQueryParameterName

          • minimumRingSize

        • localityLbSetting:位置权重负载均衡相关的设置,基于Client和Server端Pod上的annotation时设置

          • 常用参数:distribute、failover、failoverPriority、enabled

          • 常用Annotation:topology.kubernetes.io/region、topology.kubernetes.io/zone、topology.istio.io/subzone

      • outlierDetection:异常值检测;

        • consecutiveErrors:实例被驱逐前的连续错误次数和,默认值为5;

        • interval:驱逐的时间间隔,默认值为10秒,支持以时、分、秒和毫秒为单位;

        • baseEjectionTime:基准驱逐时长,具体时长取决于退避算法;

        • maxEjectionPercent:可被驱逐的最大实例比例,默认为10%;

        • minHealthPercent:启用异常值检测时要满足的最小健康状态实例比例,小于此比例,异常值检测将被禁用;默认为50%;

      • connectionPool:连接池配置

        • TCP连接池配置:

          • maxConnections:为上游服务的所有实例建立的最大连接数,默认为1024;

          • connectTimeout:TCP连接超时时长;对于HTTP协议来说,它仅适用于HTTP/1;

          • tcpKeepalive:TCP keepalives机制,通过定期给发送一个keepalive探测报文来判断连接是否可用;

        • HTTP连接池配置

          • http1MaxPendingRequests:允许挂起的最大HTTP请求数,默认为1024,仅适用于HTTP/1.1;

          • http2MaxRequests:允许的HTTP/2最大请求数,默认为1024;HTTP/1.1的由maxConnections设置即能实现;

          • maxRequestsPerConnection:每连接的最大请求数,默认为无限制,而1则表示禁用Keep-alive;

          • maxRetries:最大重试次数,默认为3;

          • idleTimeout:空闲超时时长;

      • PortTrafficPolicy:流量策略要应用的目标端口;

    DestinationRule配置生效示意图

    image

    DestinationRule CRD

    image

    DestinationRule配置示例

    子集示例

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: demoapp
    spec:
      host: demoapp
      subsets:
      - name: v10
        labels:
          version: v1.0
      - name: v11
        labels:
          version: v1.1
    

    负载均衡

    kind: DestinationRule
    metadata:
      name: demoapp
    spec:
      host: demoapp
      trafficPolicy:
        loadBalancer:
          simple: LEAST_CONN
      subsets:
      - name: v10
        labels:
          version: v1.0
        trafficPolicy:
          loadBalancer:
            consistentHash:
              httpHeaderName: X-User
      - name: v11
        labels:
          version: v1.1
    

    示例三

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: bookinfo-ratings 
    spec:
      host: ratings.prod.svc.cluster.local
      trafficPolicy:
        loadBalancer:
          simple: LEAST_CONN 
      subsets:
      - name: testversion
        labels:
          version: v3 
        trafficPolicy: 
          loadBalancer:
            simple: ROUND_ROBIN
    

    参考文档

    https://istio.io/latest/zh/docs/reference/config/networking/destination-rule/

    通过例子来理解

    有两个Deployment(nginx 及 httpd),通过Service关联到一起,通过访问Service只能做到简单的负载均衡,通过实验发现 nginx 和 httpd 流量各自在 50% 左右。

    image.png

    Deployment & Service

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: nginx
      name: nginx-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: nginx
            server: web
        spec:
          containers:
            - image: 'nginx:latest'
              name: nginx-deployment
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: httpd
      name: httpd-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpd
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: httpd
            server: web
        spec:
          containers:
            - image: 'httpd:latest' 
              name: httpd-deployment 
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: web-service
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 80
      selector:
        server: web
      type: ClusterIP
    

    如果想实现更加细颗粒度的流量管控,通过引入Istio Vistrual Service 及 Destination Rule,非常简单的就实现复杂的流量管理。

    DestinationRule 根据标签将流量分成不同的子集,已提供 VirtualService 进行调度,并且设置相关的负载百分比实现精准的控制。

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: web-dr
    spec:
      host: web-svc
      subsets:
      - name: httpd
        labels:
          app: httpd
      - name: nginx
        labels:
          app: nginx
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: web-vs
    spec:
      hosts:
      - web-service
      http:
      - route:
        - destination:
            host: web-service
            subset: nginx
          weight: 80
        - destination:
            host: web-service
            subset: httpd
          weight: 20
    

    通过客户端测试以上的实验,请留意客户端也必须经过 Istio 注入,因为只有客户端被 Istio 注入才可以接收到来自 Pilot 有关 Virtual Service 和 Destination Rule 的配置信息,才可以保证流量接管生效。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: client-deployment
      name: client-deployment
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: client-deployment
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: client-deployment
        spec:
          containers:
            - image: 'busybox:latest'
              name: client-deployment
              command: [ "/bin/sh", "-c", "sleep 3600"]
    

    进入客户端容器执行 wget -q -O - web-service观察执行结果

    更丰富的流量策略

    在生产环境中,应用到的流量策略不单单只是加权的负载均衡那么简单, Destination Rule 还支持 最小连接数、随机负载等等。

    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: web-dr
    spec:
      host: web-svc
      trafficPolicy:
        loadBalancer:
          simple: RANDOM
      subsets:
      - name: httpd
        labels:
          app: httpd
      - name: nginx
        labels:
          app: nginx
        trafficPolicy:
          loadBalancer:
            simple: LEAST_CONN
    

    Destination Rule 字段解析

    • host - 指的是 Kuberentes 中的服务
    • subsets - 针对不同标签选择的流量子集
    • loadBalancer - 负载均衡路由策略

    相关文章

      网友评论

        本文标题:Vistrual Service & Destination R

        本文链接:https://www.haomeiwen.com/subject/kptxcdtx.html