kubernetes框架

Vistrual Service & Destination R

2022-12-29  本文已影响0人  程序员札记

虚拟服务(Vistrual Service)是 Istio 重要的资源对象之一,作用是将流量路由到网格中的服务。支持基于权重、http header条件等优先级的路由,比Kuberentes service对于流量的管控更加的丰富,颗粒度更加精细。

有了 Kubernetes Service,为什么还需要 Istio Vistrual Service
简单来说,基于 Kubernetes Service,只可以实现简单的流量负载均衡,如果想实现基于HTTP Header,负载百分比等等复杂的流量控制就无从下手了,Istio Vistrual Service在原本 Kubernetes Service 的功能之上,提供了更加丰富的路由控制。

VirtualHost

image

VirtualService配置要点

VirtualService配置生效示意图

image

HTTP路由配置(HTTPRoute)

VirtualService and HTTPRoute CRD

image

HTTPRoute配置示例

示例一

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v2

url重写示例

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: rewrite
    match:
    - uri:
        prefix: /canary
    rewrite:
      uri: /
    route:
    - destination:
        host: demoapp
        subset: v11
  - name: redirect
    match:
    - uri:
        prefix: "/backend"
    redirect:
      uri: /
      authority: backend
      port: 8082
  - name: default
    route:
    - destination:
        host: demoapp
        subset: v10

fault-injection示例

kind: VirtualService
metadata:
  name: demoapp
spec:
  hosts:
  - demoapp
  http:
  - name: canary
    match:
    - uri:
        prefix: /canary
    rewrite:
      uri: /
    route:
    - destination:
        host: demoapp
        subset: v11
    fault:
      abort:
        percentage:
          value: 20
        httpStatus: 555
  - name: default
    route:
    - destination:
        host: demoapp
        subset: v10
    fault:
      delay:
        percentage:
          value: 20
        fixedDelay: 3s

参考文档

https://istio.io/latest/zh/docs/reference/config/networking/virtual-service/

通过例子来理解

有两个Deployment(nginx 及 httpd),通过Service关联到一起,通过访问Service只能做到简单的负载均衡,通过实验发现 nginx 和 httpd 流量各自在 50% 左右。


image.png

Deployment & Service

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        server: web
    spec:
      containers:
        - image: 'nginx:latest'
          name: nginx-deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: httpd
  name: httpd-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: httpd
        server: web
    spec:
      containers:
        - image: 'httpd:latest' 
          name: httpd-deployment 
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: httpd-service
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: httpd
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    server: web
  type: ClusterIP

如果想实现更加细颗粒度的流量管控,通过引入Istio Vistrual Service 非常简单的就实现复杂的流量管理。

VirtualService 根据 Destination 进行调度,并且设置相关的负载百分比实现精准的控制。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: web-vs
spec:
  hosts:
  - web-service
  http:
  - route:
    - destination:
        host: nginx-service
      weight: 80
    - destination:
        host: httpd-service
      weight: 20

通过客户端测试以上的实验,请留意客户端也必须经过 Istio 注入,因为只有客户端被 Istio 注入才可以接收到来自 Pilot 有关 Virtual Service 和 Destination Rule 的配置信息,才可以保证流量接管生效。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: client-deployment
  name: client-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client-deployment
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: client-deployment
    spec:
      containers:
        - image: 'busybox:latest'
          name: client-deployment
          command: [ "/bin/sh", "-c", "sleep 3600"]

进入客户端容器执行 wget -q -O - web-service观察执行结果

Vistrual Service 条件匹配

很多场景下,需要针对不同的用户已提供个性化的服务等(提前内测新版本),例如针对地理位置、是否为VIP等等,那就需要对 httpd 流量进行识别匹配。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: web-vs
spec:
  hosts:
  - web-service
  http:
  - match:
    - headers:
        end-user:
          exact: carryyip
      uri:
        prefix: "/health"
      ignoreUriCase: true
    route:
      - destination:
          host: httpd-service
  - route:
    - destination:
        host: nginx-service

基于 HttpMatchRequest,路由规则从上到下进行优先级排序,在生产环境中建议使用一个无条件的规则作为最后规则,确保流量始终会匹配到最少一条规则,防止意外情况的方式。

路由规则从 match 关键字开始匹配,可以使用精确 exact 和 前缀 prefix 或者 正则表达式进行不同场景下的匹配。

Destination Rule

目标规则(Destination Rule)是 Istio 重要的资源对象之一,它不能独自使用,必须跟 Virtual Service 共同发挥作用,作用是将流量标记分组并路由到具体服务。

Destination Rule 还可以做什么

通常在生产场景下,用使用 Destination Rule 对用户进行身份、地址位置等条件的识别后的流量路由,例如部分用户优先享用新版本,则可以通过HTTP Header附加相关的字段进行识别,路由到新版本的服务上。或者在版本更新的时候,使用灰度发布,对新旧版本标记子集,按照不同的负载百分比进行调整逐步迭代。

DestinationRule配置要点

DestinationRule配置生效示意图

image

DestinationRule CRD

image

DestinationRule配置示例

子集示例

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  subsets:
  - name: v10
    labels:
      version: v1.0
  - name: v11
    labels:
      version: v1.1

负载均衡

kind: DestinationRule
metadata:
  name: demoapp
spec:
  host: demoapp
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
  subsets:
  - name: v10
    labels:
      version: v1.0
    trafficPolicy:
      loadBalancer:
        consistentHash:
          httpHeaderName: X-User
  - name: v11
    labels:
      version: v1.1

示例三

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: bookinfo-ratings 
spec:
  host: ratings.prod.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN 
  subsets:
  - name: testversion
    labels:
      version: v3 
    trafficPolicy: 
      loadBalancer:
        simple: ROUND_ROBIN

参考文档

https://istio.io/latest/zh/docs/reference/config/networking/destination-rule/

通过例子来理解

有两个Deployment(nginx 及 httpd),通过Service关联到一起,通过访问Service只能做到简单的负载均衡,通过实验发现 nginx 和 httpd 流量各自在 50% 左右。

image.png

Deployment & Service

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
        server: web
    spec:
      containers:
        - image: 'nginx:latest'
          name: nginx-deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: httpd
  name: httpd-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpd
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: httpd
        server: web
    spec:
      containers:
        - image: 'httpd:latest' 
          name: httpd-deployment 
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    server: web
  type: ClusterIP

如果想实现更加细颗粒度的流量管控,通过引入Istio Vistrual Service 及 Destination Rule,非常简单的就实现复杂的流量管理。

DestinationRule 根据标签将流量分成不同的子集,已提供 VirtualService 进行调度,并且设置相关的负载百分比实现精准的控制。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: web-dr
spec:
  host: web-svc
  subsets:
  - name: httpd
    labels:
      app: httpd
  - name: nginx
    labels:
      app: nginx
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: web-vs
spec:
  hosts:
  - web-service
  http:
  - route:
    - destination:
        host: web-service
        subset: nginx
      weight: 80
    - destination:
        host: web-service
        subset: httpd
      weight: 20

通过客户端测试以上的实验,请留意客户端也必须经过 Istio 注入,因为只有客户端被 Istio 注入才可以接收到来自 Pilot 有关 Virtual Service 和 Destination Rule 的配置信息,才可以保证流量接管生效。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: client-deployment
  name: client-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: client-deployment
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: client-deployment
    spec:
      containers:
        - image: 'busybox:latest'
          name: client-deployment
          command: [ "/bin/sh", "-c", "sleep 3600"]

进入客户端容器执行 wget -q -O - web-service观察执行结果

更丰富的流量策略

在生产环境中,应用到的流量策略不单单只是加权的负载均衡那么简单, Destination Rule 还支持 最小连接数、随机负载等等。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: web-dr
spec:
  host: web-svc
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: httpd
    labels:
      app: httpd
  - name: nginx
    labels:
      app: nginx
    trafficPolicy:
      loadBalancer:
        simple: LEAST_CONN

Destination Rule 字段解析

上一篇下一篇

猜你喜欢

热点阅读