使用 ISTIO 来做金丝雀发布

文章目录

  • 需要满足的条件
  • 背景需求
  • ISTIO 的架构和原理
    • 解决问题的大概流程
    • 类比一下 nginx
  • 几个概念
    • K8S-Service
    • ISTIO-VirtualService (简称 VR)
    • ISTIO-DestnationRule (简称 DR)
    • ISTIO-Gateway
  • 发布流程
    • 首次发布流程
    • 更新发布流程

需要满足的条件

  1. 一个可用 K8S 集群
  2. K8S && Docker && Helm 基础知识

背景需求

要搞这玩意儿的主要原因是因为项目需求,频繁新版本,一发新版本,程序崩了,用户炸了,领导火了。

虽然这个锅主要是开发和测试来背,不过如果搞的次数多了,运维也要被牵连进去的。

毕竟,项目顺利才是所有人所希望看到的。

有人说,这应该从流程上去堵住这种漏洞。嗯,说的很对!(省略5w 字吐槽)

就这样,找了几种解决方案,最终找到了istio。

istio 可以用来干很多事情,不过其他的功能我们暂时用不到。

ISTIO 的架构和原理

https://istio.io/latest/docs
请查看官网或者百度。。。

解决问题的大概流程

首先,我们的目标就是如果我们发布了新版本,那么就让一小部分的人先用用,如果小部分的人用的没问题,那就大规模推广。(嗯,很符合互联网的套路阿!)

类比一下 nginx

原理性的东西太枯燥,大家感兴趣的可以去翻源码和官方文档。

这里我讲讲自己的理解。

我拿 nginx做一个类比。配置istio就像配置nginx一样,需要配置匹配的uri,不同的是,它可以通过解析http包,拥有了更丰富的规则来实现路由重定向。

一个典型的配置如下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: pos-istio
spec:
  gateways:
 - prod-gateway
  hosts:
 - '*'
  http:
 - match:
    - headers:
        deptCode:
          exact: 30080
      uri:
        prefix: /pos
    route:
    - destination:
        host: pos-istio
        subset: master
 - match:
    - uri:
        prefix: /pos
    route:
    - destination:
        host: pos-istio
        subset: canary

这里的 http match 就是istionginx新增的功能点了。

  • 第一条规则是 如果匹配 http header中的deptCode等于30080且访问路径是/pos 那么就访问某个后端服务,这里叫master
  • 第二跳规则是访问路径是/pos 那么就访问某个后端服务,这里叫canary

翻译成nginx配置就类似

location /pos {
     
    proxypass: master
}

# 当然,这里没有经过特殊处理的 nginx 是无法通过解析 http 请求头来完成对应规则的匹配的。
location /pos {
     
    proxypass: canary
}

几个概念

有了大概的了解之后,我们再看看下面几个概念,了解这些概念之后,基本上配置istio就没什么问题了。

K8S-Service

这里的 k8s-service 就是 K8S内的 service 的概念,因为要和istio内的virtual-service的概念做区分。

ISTIO也支持在其他平台内运行,但是最匹配的还是在K8S环境内运行。

既然是在K8S的环境内运行,istio就避免不了要和K8S相关的概念打交道。

我们是使用helm3来部署应用的,部署的方式都是deploymnets。当我们需要上istio的时候,我们就需要两个charts,我们分别称之为 pos-masterpos-canary

使用默认的charts会自动生成对应的文件夹名字的k8s service。每个service的选择器都会自动选择该depoyment内的pod

因为我们要通过ISTIO定位到两个版本的部署,ISTIO定义app是以K8S Service作为选择标准,所以,我们需要一个 K8S Service ,而它的选择器是能够同时选择两个不同的版本。

因此,我们在helm charts中的deployment.yml文件中添加两个标签label

  1. appName
  2. version

其中appName用它来作为新建的K8S Service选择器的标签,version作为DestnationRule中区分不同版本的参考值。

ISTIO-VirtualService (简称 VR)

使用 ISTIO 来做金丝雀发布_第1张图片
这里的pos-istio就表示的是VR。它指向两个部署,这两个部署的含义是在 DR中定义。

典型的配置如下,含义在上文已经解释过。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: pos-istio
spec:
  gateways:
 - prod-gateway
  hosts:
 - '*'
  http:
 - match:
    - headers:
        deptCode:
          exact: 30080
      uri:
        prefix: /pos
    route:
    - destination:
        host: pos-istio
        subset: master
 - match:
    - uri:
        prefix: /pos
    route:
    - destination:
        host: pos-istio
        subset: canary

ISTIO-DestnationRule (简称 DR)

这个文件的含义就是将K8S Servicelabelversion=2020.08.27.001的部署命名为master版本,另外那个命名为canary

这些命名master canary最终在VR文件中被引用。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: pos-istio
spec:
  host: pos-istio
  subsets:
  - name: master
    labels:
      version: 2020.08.27.001
  - name: canary
    labels:
      version: 2020.08.27.002

ISTIO-Gateway

如果没有域名的话,一个集群只能有一个Gateway,它的典型配置如下:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: sinopec-gateway
spec:
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

如果有域名,hosts中的*可以改为域名地址,可以多个,类似nginx中的ServiceName

发布流程

首次发布流程

pos为例,首次发布的流程如下:

  1. 生成2个文件夹,分别是pos pos-canary
  2. 为2个文件夹的value.yml 添加参数appNameForIstio
  3. 为2个文件夹的deployment.yml添加 appNameversionlabels,使用helm install部署两个版本。
  4. 手工创建一个新的k8s service供后续的istio使用,selector选择器就是前面两个步骤定义的 appName
  5. 创建专属的dr文件,selector选择器是刚刚手工创建的k8s service,通过第三步设定的version命名两个版本,一个是master版本,一个是canary版本。
  6. 创建专属的vr文件,设定两个策略,匹配我们自定义的http header就走canary版本,否则走master版本。
  7. 前端的Andorid应用设定的api地址,需要是istio-ingress-controller网关的地址。(kubectl get svc -n istio-system 得到的istio-ingressgateway的网关端口)。

更新发布流程

  1. 修改 vr文件,把原来需要导入到canary版本的流量,全部导入master版本。(如:原来的规则是 deptCode=30080canary,把条件改成deptCode=xxxxx,因为条件不匹配,所以所有的流量全部都会走master。)
  2. 修改dr文件中canary版本的版本号信息为需要更新的最新版本。
  3. 修改canarycharts中的values.yml文件的image tag值,upgrade该应用。
  4. canary部署成功后,将vr中的规则改回正确的规则,特定的用户将使用最新的canary版本。
  5. canary版本发布2天后,如果没有重大漏洞,周四 修改master版本charts中的values.yml文件的image tag值,upgrade该应用。

欢迎大家留言交流!

你可能感兴趣的:(istio,istio,docker,kubernetes,金丝雀发布,蓝绿发布)