金丝雀发布实验
部署两个pod,他们分别是canary-v1和canary-v2。
随后进行service的部署:
apiVersion: v1
kind: Service
metadata:
name: canary-svc34
namespace: default
spec:
selector:
apply: canary
ports:
- port: 80
protocol: TCP
targetPort: 80
进行gateway和virtualservice以及destinationRule的部署。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: canary-gateway34
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
可以看到上面的service是TCP协议的,而这里的gateway是HTTP协议的。因为service处于传输层,他只关注传输层流量,而istio处于应用层,它可以基于http的协议执行高级的流量管理,比如路由、负载均衡和超时等等。
实际上,virtualService处理的是来自service的流量,因此这里的host名称应该和service名称对应,所以这里的host名称是:canary-svc34.default.svc.cluster.local
piVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: canary
spec:
gateways:
- canary-gateway34
hosts:
- "*"
http:
- route:
- destination:
host: canary-svc34.default.svc.cluster.local
port:
number: 80
subset: v1
weight: 50
- destination:
host: canary-svc34.default.svc.cluster.local
port:
number: 80
subset: v2
weight: 50
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: canary
spec:
host: canary-svc34.default.svc.cluster.local
subsets:
- name: v1
labels:
app: v1
- name: v2
labels:
app: v2
此时查看svc,是一个clusterIP,而这个服务在我们的istio的服务网格里面,所以我们可以通过
gateway、service、VirtualSerivce
Gateway
负责外部流量的入口,它的端口用于监听外部请求(如 80
、443
或 31400
)。这个端口不需要与 Kubernetes Service
的端口匹配。
VirtualService
负责流量路由,它将 Gateway
或其他服务的流量转发到集群内的 Kubernetes Service
。这里的 destination.port.number
必须与 Kubernetes Service
的端口匹配,因为这是服务监听流量的端口。如果你的 Kubernetes Service
是 canary-svc34
,它监听的是 80
端口,那么 VirtualService
的 destination.port.number
也应该是 80
。
virtualService资源清单
headers匹配
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason # 如果请求头中 end-user 的值为 "jason"
route:
- destination:
host: reviews
subset: v2 # 将流量路由到 reviews 服务的 v2 版本
- route:
- destination:
host: reviews
subset: v3 # 其他流量路由到 reviews 服务的 v3 版本
在virtualservice中可以设置很多的规则,比如上面这个例子中,就对用户请求头中的信息进行了匹配。注意这里http是一个层级,下面有两个并列的规则,一个是- match,另一个是 - route。
一般来说http请求头中会包含以下字段,都可以用来设置istio的match规则:
Host: 指定目标服务器的主机名。
User-Agent: 表明请求是由哪个客户端发出的(例如浏览器类型)。
Authorization: 用于携带身份验证信息。
Cookie: 用于传递与会话相关的数据。
但用户也可以自定义http请求头,设置end-user信息,一个可能的格式如下:
fetch('https://example.com/reviews', {
method: 'GET',
headers: {
'end-user': 'jason' // 手动添加 end-user 请求头
}
}).then(response => {
// 处理响应
});
那么这样就可以进行流量的分流,只允许他们去review的v2版本。
从内容上讲除了headers匹配,还有uri匹配,queryParams 匹配(参数匹配)、方法匹配(GET/POST),从规则上讲,有prefix匹配、exact匹配和regex匹配(正则匹配)。
prefix匹配
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
http:
- match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
这里的uri可能格式如下:
GET /ratings/456 HTTP/1.1
Host: bookinfo.com
则可以匹配到/ratings规则,进入host为ratings的服务。
参数匹配
https://bookinfo.com/reviews?sort=asc&filter=popular
在这个 URL 中,/reviews
是路径。?sort=asc&filter=popular
是查询参数部分。sort=asc
是一个查询参数,表示进行升序排序。filter=popular
是另一个查询参数,表示只显示受欢迎的结果。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
http:
- match:
- uri:
prefix: /reviews
headers:
User-Agent:
exact: "Mozilla/5.0"
queryParams:
sort:
exact: asc
route:
- destination:
host: reviews
- match:
- uri:
exact: /ratings/123
method:
exact: GET
route:
- destination:
host: ratings
正则匹配
- match:
- uri:
regex: "/reviews/[0-9]+"
这个配置表示:所有 URI 以 /reviews/ 开头,后面跟着一串数字的请求都会匹配规则,比如 /reviews/123、/reviews/456 等。
authority匹配
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: example-virtualservice
spec:
hosts:
- "*"
http:
- match:
- authority:
exact: "api.example.com"
route:
- destination:
host: api-service
scheme匹配
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: example-virtualservice
spec:
hosts:
- "service.example.com"
http:
- match:
- scheme:
exact: "https"
route:
- destination:
host: secure-service
sourceLabel匹配
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: example-virtualservice
spec:
hosts:
- "service.example.com"
http:
- match:
- sourceLabels:
app: "frontend"
version: "v1"
route:
- destination:
host: backend-service
端口匹配
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: example-virtualservice
spec:
hosts:
- "service.example.com"
http:
- match:
- uri:
prefix: "/api"
port: 8080
route:
- destination:
host: api-service
port:
number: 8080