zoukankan      html  css  js  c++  java
  • istio-http流量管理

    1. 定义目标与规则
    istio 服务网格中对服务进行了进一步抽象:
    可以使用 Pod 标签对具体的服务进程进行分组;
    可以定义服务的负载均衡策略;
    可以为服务指定 TLS 要求;
    可以为服务设置连接池大小。
    istio 中,同一服务不同组别的后端被称为 子集(Subset) ,也经常被称为 服务版本 。
    在 istio 中,建议为每个网格都设置明确的目标访问规则,在通过 istio 流量控制之后,会选择明确的子集,根据规则或在子集中规定的流量策略来进行访问,
    这种规则被称为 DestinationRule ,样例如下:

    cat flaskapp-destinationrule.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: DestinationRule
    metadata:
      name: flaskapp
    spec:
      host: flaskapp.default.svc.cluster.local
      trafficPolicy:
        loadBalancer:
          simple: LEAST_CONN
      subsets:
      - name: v1
        labels:
          version: v1
        trafficPolicy:
          loadBalancer: ROUND_ROBIN
      - name: v2
        labels:
          version: v2

    规则需要注意的地方如下:
    host: 必要字段,代表1个 Service 资源,或1个 ServiceEntry 定义的外部服务。
    建议:为防止不同命名空间服务重名,可以使用完全限定名。
    trafficPolicy: 流量策略,在 DestinationRule 与 Subset 都可以定义,Subset 中的级别更高。
    subsets: 该字段使用标签选择器定义不同的子集。
    2. 定义默认路由
    2.1 定义默认路由
    建议每个服务都创建1个默认路由,在没有特定的路由规则时,使用默认路由规则访问指定子集,一以此确保服务在默认情况下的行为稳定性,样例如下:

    cat flaskapp-default-vs.yaml 
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: flaskapp
    spec:
      hosts:
      - flaskapp.default.svc.cluster.local
      http:
      - route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v1

    VirtualService: istio 流量控制过程中的枢纽,负责对流量进行甄别与转发。
    针对主机名工作,但 hosts 字段是一个数组内容,可以针对多个主机名进行工作。
    可以为多种协议的流量提供服务,如 http ,tcp ,tls等。
    在 http 的下一级,即具体的路由规则。
    支持多条路由。
    2.2 验证
    # 应用目标规则与默认路由

    kubectl apply -f flaskapp-destinationrule.yaml
    kubectl apply -f flaskapp-default-vs.yaml

    # 验证,可同步观察 kiali & Jaeger 等

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') /bin/bash
    bash-4.4# for i in `seq 100` ; do http --body http://flaskapp.default/env/version ; done

    2.3 总结
    在 istio 中部署1个业务应用时,建议:

    使用 app 标签表明应用身份;
    使用 version 标签表明应用版本;
    创建目标规则;
    创建默认路由规则,默认路由得配置清单应该成为服务网格环境下的必要部署内容。
    3. 流量拆分与迁移
    3.1 权重

    cat flaskapp-default-vs.yaml 
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: flaskapp
    spec:
      hosts:
      - flaskapp.default.svc.cluster.local
      http:
      - route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v1
          weight: 70
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v2
          weight: 30
          
    # 应用
    kubectl apply -f flaskapp-default-vs.yaml

    # 验证,可同步观察 kiali & Jaeger 等
    # 因是权重的原因,验证时样本量需要大一些

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') /bin/bash
    bash-4.4# for i in `seq 100` ; do http --body http://flaskapp.default/env/version ; done | awk -F "v1" '{print NF-1}'

    注意点:

    流量分配是有权重的,且权重总和必须是 100 ;
    如果不显示声明权重,则默认值是 100 。
    3.2 获取 istio 对象
    kubectl get , kubectl api-resources 列出当前集群支持的所有对象类型
    Kiali --> Istio Config

    4. 金丝雀部署
    金丝雀部署:在发布新版本时,部署的新版本并不对外开放,而选择一小部分用户为测试目标,这部分用户对服务的访问会指向特定的版本,通过对这些金丝雀用户的使用情况的观察,来确定新版本服务的发布效果,在确定结果之前,所有其他用户都继续使用原有版本。

    4.1 金丝雀部署

    cat flaskapp-default-vs-canary.yaml 
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: flaskapp
    spec:
      hosts:
      - flaskapp.default.svc.cluster.local
      http:
      - match:
        - headers:
            lab:
              exact: canary
        route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v2
      - route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v1

    注意点:
    match 字段提供来丰富的匹配功能,匹配范围不仅包括 http header , 还包含 uri , scheme , method , authority , 端口 , 来源标签及 gateway 等;
    exact 代表完全匹配,另有 prefix 代表前缀, regex 代表正则表达式的匹配方式
    4.2 验证

    bash-4.4# for i in `seq 10` ; do http --body http://flaskapp.default/env/version lab:canary ; done

    5. 根据来源服务进行路由

    cat flaskapp-default-vs-src.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: flaskapp
    spec:
      hosts:
      - flaskapp.default.svc.cluster.local
      http:
      - match:
        - sourceLabels:
            app: sleep
            version: v1
        route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v1
      - route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v2
    # 应用
    kubectl apply -f flaskapp-default-vs-src.yaml

    测试
    # 验证
    # sleep v1

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') /bin/bash
    bash-4.4# for i in `seq 10` ; do http --body http://flaskapp.default/env/version; done

    # sleep v2

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v2 -o jsonpath='{.items..metadata.name}') /bin/bash
    bash-4.4# for i in `seq 10` ; do http --body http://flaskapp.default/env/version; done

    6. 对URI进行重定向
    6.1 redirect

    cat flaskapp-default-vs-uri.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: flaskapp
    spec:
      hosts:
      - flaskapp.default.svc.cluster.local
      http:
      - match:
        - sourceLabels:
            app: sleep
            version: v1
          uri:
            exact: "/env/HOSTNAME"
        redirect:
          uri: "/env/version"
      - route:
        - destination:
            host: flaskapp.default.svc.cluster.local
            subset: v2
    
    # 应用
    kubectl apply -f flaskapp-default-vs-uri.yaml

    测试
    # 验证 sleep v2,正常返回

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v2 -o jsonpath='{.items..metadata.name}') -- 
    http http://flaskapp.default/env/HOSTNAME
    
    HTTP/1.1 200 OK
    content-length: 28
    content-type: text/html; charset=utf-8
    date: Wed, 12 Jun 2019 08:05:25 GMT
    server: envoy
    x-envoy-upstream-service-time: 1
    
    flaskapp-v2-59b5b6cb94-jdfp4

    # 验证 sleep v1
    # 返回 "301" 重定向代码

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') -- 
    http http://flaskapp.default/env/HOSTNAME
    
    HTTP/1.1 301 Moved Permanently
    content-length: 0
    date: Wed, 12 Jun 2019 08:06:17 GMT
    location: http://flaskapp.default/ev/version
    server: envoy

    # "--follow" 跟随重定向指令,重验证

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v1 -o jsonpath='{.items..metadata.name}') -- 
    http --follow http://flaskapp.default/env/HOSTNAME
    
    HTTP/1.1 200 OK
    content-length: 2
    content-type: text/html; charset=utf-8
    date: Wed, 12 Jun 2019 08:09:26 GMT
    server: envoy
    x-envoy-upstream-service-time: 2

    v2
    注意点:
    redirect 指令会把 URI 整体替换,灵活性不高;
    301 指令无法支持 Post 方法, istio 提供了 rewrite 方式来提供这种在调用前进行 URI 重写的支持。
    6.2 rewrite

    cat httpbin-default-vs.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: httpbin
    spec:
      hosts:
      - httpbin.default.svc.cluster.local
      http:
      - match:
        - uri:
          exact: "/get"
        rewrite:
          uri: "/post"
        route:
        - destination:
            host: httpbin.default.svc.cluster.local
      - route:
        - destination:
            host: httpbin.default.svc.cluster.local

    测试
    # 访问测试

    kubectl exec -it -c sleep $(kubectl get pod -l app=sleep,version=v2 -o jsonpath='{.items..metadata.name}') -- http -f POST http://httpbin:8000/get data=nothing

    # 返回信息
    HTTP/1.1 405 Method Not Allowed
    access-control-allow-credentials: true
    access-control-allow-origin: *
    allow: GET, OPTIONS, HEAD
    content-length: 178
    content-type: text/html
    date: Wed, 12 Jun 2019 12:39:28 GMT
    server: envoy
    x-envoy-upstream-service-time: 5

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
    <title>405 Method Not Allowed</title>
    <h1>Method Not Allowed</h1>
    <p>The method is not allowed for the requested URL.</p>
    注意点:
    rewrite 方法与 redirect 方法的不同之处在于: 在 rewrite 方法的 match 字段必须包含对目标的定义;
    rewrite 方法与 redirect 方法不能共存。

    转载于:

    https://www.cnblogs.com/netonline/p/12609021.html
    https://www.cnblogs.com/netonline/p/13237722.html

    如有侵权请联系删除

  • 相关阅读:
    BZOJ3483 : SGU505 Prefixes and suffixes(询问在线版)
    BZOJ3067 : Hyperdrome
    BZOJ3461 : Jry的时间表
    BZOJ3024 : [Balkan2012]balls
    BZOJ1111 : [POI2007]四进制的天平Wag
    BZOJ1107 : [POI2007]驾驶考试egz
    BZOJ1109 : [POI2007]堆积木Klo
    BZOJ4158 : [POI2007]Railway
    BZOJ1110 : [POI2007]砝码Odw
    BZOJ1105 : [POI2007]石头花园SKA
  • 原文地址:https://www.cnblogs.com/huanglingfa/p/13895982.html
Copyright © 2011-2022 走看看