istio完成金丝雀、灰度发布

前提

1.已有集群已经安装istio
2.已经了解灰度的远离
3.对istio的概念有大致了解,比如已经完成官网的初始事例:https://istio.io/docs/examples/bookinfo/

前言

其实istio的组件很多,据我了解,各大云厂商大多是会自己用golang去自定义一些组件。所以如果要做灰度,金丝雀等,最好是直接使用大型云厂商的容器云服务。
本文主要介绍在原生的k8s集群只装了istio的情况下如何实现简介的灰度

项目背景

首先我们的项目必须是依赖deployment来实现pod的,很多老的发布方式可能会用k8s的rc来发布项目,这与istio的理念不合适。

引入概念

Gateway

Gateway:流量的入口,用来设定域名等,取代ingress
注:如果原来线上就是用的ingress,则不建议引入istio,istio必须依赖gateway来取代ingress,线上的ingress如果要替换成gateway,免不了的是大量的工作量及线上无法访问的风险。

DestinationRule:

绑定svc
根据deployment的label标签来指定subset(版本)

VirtualService:

gateway的下一层,可以绑定gateway,以及svc,把控svc的流量,打到不同的subset(版本)中,也可以设置比重,是核心

实现流程图

istio完成金丝雀、灰度发布_第1张图片

charts编写

deployments(老版本)

关键点在label,可以自定义!我这边叫canary,大家可以随意,后面subset标实出来就好

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: [deployment的名字]
  labels:
    app: [deployment的名字] #打个标签
    canary: "false" #关键点在这!自定义的标签我给一个false,用来表示老版本
spec:
  replicas: 1 #副本数
  minReadySeconds: 5
  template:
    metadata:
      labels:
        app: [deployment的名字]
    spec:
      containers:
      - name: [容器的名字]
        image: [镜像]
        ...
        #以下就省略了,什么健康检查啥的,根据要求定义
deployments(金丝雀,新版本)

新版本的label一定要跟老版本的不一样,后面才能用subset根据label不同来给流量

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: [deployment的名字]
  labels:
    app: [deployment的名字] #打个标签
    canary: "true" #关键点在这!自定义的标签我给一个false,用来表示老版本
spec:
  replicas: 1 #副本数
  minReadySeconds: 5
  template:
    metadata:
      labels:
        app: [deployment的名字]
    spec:
      containers:
      - name: [容器的名字]
        image: [镜像]
        ...
        #以下就省略了,什么健康检查啥的,根据要求定义

svc

关键点在selector,选择器,也就说所有的流量都会通过svc打到有app标签的deployment里面

apiVersion: v1
kind: Service
metadata:
  name: [svc的名字]
  labels:
    app: [svc的名字]
spec:
  ports:
  - port: 8080
    name: http
    targetPort: 8080
  selector:
    app: [deployment的label里的标签]#这里很关键,svc绑定的是所有app标签等于deployment的name的deployment

DestinationRule

关键点在于两点:
1.绑定svc,名字不要错
2.新建subset,根据label绑定到我们之前的deployment

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: [DestinationRule的名字]#随便取,后续没有绑定关系
spec:
  host: [svc的名字]#这里很关键,这里绑定了svc
  subsets: #最关键的标签
  - name: production #subset的名字
    labels:
      canary: "false" #subset要绑定的deployment的标签!,指定要到老版本
  - name: canary #subset的名字
    labels: 
      canary: "true" #subset要绑定的deployment的标签!,指定要到新版本

现在我们已经新建了两个不同版本的subset,每个subset绑定了不同的deployment

VirtualService

两个点:
1.绑定svc,名字不要错
2.绑定subset,同时指定流量

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: [VirtualService的名字]
spec:
  http:
    route:
    - destination:
        host: [svc的名字]#很关键,绑定svc
        name: production #很关键,绑定前面定义的subset
        port:
          number: 8080
        weight: 90 #很关键,把90%的流量打到老版本
    - destination:
        host: [svc的名字]#很关键,绑定svc
         name: canary #很关键,绑定前面定义的subset
         port:
           number: 8080
         weight: 10 #很关键,把10%的流量打到新版本

至此所有svc的流量已经会按照比例分配至新老版本了

yaml中的绑定关系示意图

istio完成金丝雀、灰度发布_第2张图片
注:如果是通过k8s原生ingress来访问,以上都没生效,必须使用gateway才行

后续灰度

修改VirtualService的流量百分比,直到全部打至新版本,测试完成后删除老版本的deployments。

你可能感兴趣的:(k8s,k8s之应用实践)