灰度分流方案

页面场景主要划分成

  • 分流规则管理:分流规则会存储在数据库中, 提供增删改查接口。当该分流规则已被应用配置调用,则不允许删改。
  • 应用配置分流规则:维护ingress annotation的配置,保证页面配置的规则映射到ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gray-release
  annotations:
    nginx.ingress.kubernetes.io/service-match: '[{"path":"/","newRules":[{"name":"rule1","value":"rule-value1"},{"name":"rule2","value":"rule-value2"}],"oldRules":[{"name":"rule1","value":"rule-value1"},{"name":"rule2","value":"rule-value2"}]},{"path":"/first","newRules":[{"name":"rule1","value":"rule-value1"},{"name":"rule2","value":"rule-value2"}],"oldRules":[{"name":"rule1","value":"rule-value1"},{"name":"rule2","value":"rule-value2"}]}]'       
spec:
  rules:
  - host: www.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80
       - path: /first 
         backend:
           serviceName: nginx1
           servicePort: 80

在annotations[].nginx.ingress.kubernetes.io/service-match中 ,其代表的是分流规则配置, 一条path 分流规则配置内 ,其oldRules 与 newRules 只能存在其中一个 ,不能共存

[
    {
        "path": "/",
        "newRules": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ],
        "oldRules": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ]
    },
    {
        "path": "/first",
        "newRule": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ],
        "oldRule": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ]
    }
][
    {
        "path": "/",
        "newRules": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ],
        "oldRules": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ]
    },
    {
        "path": "/first",
        "newRules": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ],
        "oldRules": [
            {
                "name": "rule1",
                "value": "rule-value1"
            },
            {
                "name": "rule2",
                "value": "rule-value2"
            }
        ]
    }
]

service-match 内的数据,根据path不同,映射到不同的service,那么其配置oldRule 或者 newRule,其配置的rules,满足这些rules,则将流量导向到旧服务/新服务

当前的设计方案是根据ingress-controller最新版本0.18.0 设计的, 当前ingress-controller 逻辑流程 与 现有的代码逻辑流程差别在于upstream 归于dynamic module 管理, 保证upstream 数据在nginx 在不进行reload 场景下,可以动态维护其ip组。

0.18.0 版本 ingress-controller 逻辑流程

根据逻辑流程以及对当前分流需求分析, 主要要进行两个模块进行修改:nginx.conf 维护, dynamic configuration 更新

更新nginx.conf , 来保证其支持分流配置; 首先要进行对ingress-controller 进行修改,添加上关于分流配置的代码, 之后是对nginx.tmpl 进行修改, 从而保证生成的nginx.conf 能够有分流配置,nginx reload 操作 只会影响长连接服务, 其他不会影响, 故当前nginx-ingress 支撑长连接服务,则进行灰度分流配置的时候, 需要在晚间进行该操作

ingress-controller 代码修改达到满足场景:
根据当前ingress,区分出是否是需要进行分流的灰度场景, 将新旧endpoint 进行区分, 整合进TemplateConfig 结构体内(还需要加入分流标志,来保证在nginx.tmpl层面能够进行判断), 并改造结构体,提供关于分流规则判断

为了分流,其nginx.tmpl需要进行对应修改, 将 $proxy_upstream_name 修改为指定的值;
当前为当前ingress-controller 其某一服务例子, 其 $proxy_upstream_name 对应为{namespace-svcname-port}

// 或者 return 503;  这个场景是在没有endpoint 
proxy_pass http://upstream_balancer;

修改后其nginx.conf 配置场景

 if ($rule-new){
  set $proxy_upstream_name "svc-test-new";
    // 或者 return 503;  这个场景是在新rs没有endpoint 
    proxy_pass http://upstream_balancer;
}
 if ($rule-old){
    set $proxy_upstream_name "svc-test-old";
    // 或者 return 503;  这个场景是在旧rs没有endpoint 
   proxy_pass http://upstream_balancer;
}

从而达到当满足 $rule-new 条件下, 其proxy_upstream_name 为 {namespace-svcname-port}-new ; 当满足 $rule-old 条件下, 其proxy_upstream_name 为 {namespace-svcname-port}-old 。

更新 dynamicconfiguration , 主要是通过调用http 接口: /configuration/backends 进行全量更新upstream, 为了能够让nginx 的server 找到对应的分流server , 需要在调用接口更新upstream 时, 将相应的分流upstream name 传递过去, 比如以上述例子,则需要额外新增两种upstream: cmos-im-xc-svc-test-80-new , cmos-im-xc-svc-test-80-old

你可能感兴趣的:(K8S,网络)