前言
条件:已安装 k8s, istio,并部署了 bookinfo。
需要了解 destination rule, virtual service, and subset gateway这些概念。
Virtual services
virtual service 可以配置请求到你的 service 的路由。如果不用它,envoy 分发路由只能用 rr 模式。使用它,可以在 A/B 测试的时候,给指定版本分配具体比例的请求数量。或是把流量导到指定的实例上。route destination 可以是服务的不同版本,也可以是不同的服务。
Sample:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews # 这个host对应k8s上面的服务,即reviews.ns.svc.cluster.local
http:
- match:
- headers:
end-user:
exact: jason # 匹配 http 协议的流量,匹配 header中的: end-user: jason
route:
- destination:
host: reviews
subset: v2 # 一个 match 对就一个 route,匹配到的流量路由到哪里。这里是路由到 reviews的 host 上,v2 的 subset。这些 host 是啥意思?host 在这里表示的是路由到主机,其实是 nginx 内部流量的转发到哪个 Host 的习惯性表达,在这里对应的是 svc,意思是这个流量要转发到哪个服务上。k get svc 可以看到相应的一些服务。通过 subset 可以控制流量到这个服务的哪个版本上面。
- match:
- uri:
prefix: /reviews # 匹配 uri,如果 uri 中有/reviews,就匹配上
route:
- destination:
host: reviews # 路由到 reviews,这个reviews非k8s服务发现的服务,而是Istio entry本身的服务,需要与destination rule中对应。因此vitualservice 与destinationrule是成对出现的,原因就在这个地方。
- match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
- route:
- destination:
host: reviews
subset: v3
如上面:virtual service,翻译过来就是虚拟服务
-
hosts
-
routing rules
可以是 http (HTTP/1.1, HTTP2, gRPC(gRPC 使用了 http2)) 或是 tcp 或是 tls
包含 match(可以匹配流量的端口、header、uri 等)和 destination(流量的走向)
注意 route 的匹配是从上到下的,最后一个优先级最低,默认路由,都没有匹配上才走到它。
Destination rules
定义了 lb 的选项及路由,这个发生在 virtual service 路由之后。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-svc
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3
labels:
version: v3
关于 subset: Each subset is defined based on one or more labels, which in Kubernetes are key/value pairs that are attached to objects such as Pods. These labels are applied in the Kubernetes service’s deployment as metadata to identify different versions. 当一个路由明确发往这个子集时,前面的 trafficPolicy 将不会生效。 另外还可以按照端口来定义请求的策略、可以定义连接池的一些参数,如最大连接数、连接超时时间、tcp keepalive的时间和周期等,详见官网
Gateways
使用 gateway 来管理网格进口和出口的流量。应用到运行在网格边缘的单独的 envoy proxy上,而不是 运行在你的服务负载的envoy proxy 的 sidecar 里面。用的镜像也是 proxyv2。
istio-ingressgateway and istio-egressgateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
同时在 virtual service 里面也需要指定这个 gateway
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwyggguf
Service entries
Sidecars
网络弹性和测试
超时(virtualservice)
重试(virtualservice)
熔断(destinationrule)
错误注入(virtualservice)
流量管理
Request Routing
请求路由,该示例将演示如何将流量动态分发到微服务的多个版本。
附kubesphere 2.1 版本的一些 destinationrules/virtualservices
root@ks-allinone:/root # k get virtualservices
NAME GATEWAYS HOSTS AGE
details [details] 10d
productpage [productpage] 10d
ratings [ratings] 10d
reviews [reviews] 10d
root@ks-allinone:/root # k get virtualservices productpage -o yaml | k neat
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
labels:
app: productpage
app.kubernetes.io/name: bookinfo
app.kubernetes.io/version: v1
name: productpage
namespace: pj-demo
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
port:
number: 9080
subset: v1
weight: 100
root@ks-allinone:/root # k get dr
NAME HOST AGE
details details 10d
productpage productpage 10d
ratings ratings 10d
reviews reviews 10d
root@ks-allinone:/root # k get dr productpage -o yaml | k neat
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
labels:
app: productpage
app.kubernetes.io/name: bookinfo
app.kubernetes.io/version: v1
name: productpage
namespace: pj-demo
spec:
host: productpage
subsets:
- labels:
version: v1
name: v1
思考:如何做到可以路由到相同服务不同的版本上的?
如果要让流量路由到相同服务的不同版本上,是不是对应的基础资源需要创建出来,如:这两个不同版本的 pod/svc 等。