背景
在生产环境中使用rancher2.0来操作k8s平台,并启用了istio做灰度发布。由于在灰度发布中需要频繁修改virtualservice,故没有使用istio-gateway做为流量入口(使用istio-gateway作为流量入口,需要在virtualservice中配置url路由匹配规则),而是使用traefik做为流量入口。traefik做url路由匹配,istio做流量策略,避免在发布中频繁修改virtualservice出现url路由未配置而导致的事故。当使用traefik作为流量入口时,又出现了另外一个问题,traefik是通过ingress规则来获取pod的ip作为upstream,从而外部的流量会被traefik直接代理到对应的pod,从而绕过istio规则,导致istio流量控制不能生效。
解决方案
通过在网上查阅资料发现,istio可以根据http请求中的host字段来匹配流量控制策略,故在traefik文中中发现使用middleware可以对ingress添加自定义headers。例如在namespace为test的service名称为web。
middleware
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: web-header
spec:
headers:
customRequestHeaders:
Host: test.web.svc
ingress
添加traefik.ingress.kubernetes.io/router.middlewares: test-web-header@kubernetescrd这个annotations来将ingress和middleware进行关联。test-web-heare=namespace-middlewarename。
?? 一个ingress只能配置一个svc,不能配置多个否则会出现访问错误,但是可以通过多个ingress来配置多个svc(域名相同也可以配置多个ingress,但是需要url不一致)。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: test-web-header@kubernetescrd
name: web
spec:
rules:
- host: web.test.com
http:
paths:
- backend:
service:
name: web
port:
number: 80
pathType: ImplementationSpecific
需要对traefik启用istio注入