前提
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(版本)中,也可以设置比重,是核心
实现流程图
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中的绑定关系示意图
注:如果是通过k8s原生ingress来访问,以上都没生效,必须使用gateway才行
后续灰度
修改VirtualService的流量百分比,直到全部打至新版本,测试完成后删除老版本的deployments。