Think Deep,Work Lean

微服务之istio实战

Posted on By zack

前言

条件:已安装 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 等。