配置请求路由

此任务将展示如何将请求动态路由到微服务的多个版本。

Istio 支持 Kubernetes Gateway API, 并计划将其作为未来流量管理的默认 API。 以下说明指导您在网格中配置流量管理时如何选择使用 Gateway API 或 Istio 配置 API。 请按照您的首选项遵循 Gateway APIIstio APIs 页签中的指示说明。

请注意,Kubernetes Gateway API CRD 不会默认安装在大多数 Kubernetes 集群上, 因此请确保在使用 Gateway API 之前已安装好这些 CRD:

  1. $ kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
  2. { kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml; }

开始之前

  • 按照安装指南中的说明安装 Istio。

  • 部署 Bookinfo 示例应用程序。

  • 查看流量管理的概念文档。在尝试此任务之前, 您应该熟悉一些重要的术语,例如 Destination RuleVirtual ServiceSubset

关于这个任务

Istio Bookinfo 示例包含四个独立的微服务, 每个微服务都有多个版本。其中一个微服务 reviews 的三个不同版本已经部署并同时运行。 为了说明这导致的问题,在浏览器中访问 Bookinfo 应用程序的 /productpage 并刷新几次。 URL 是 http://$GATEWAY_URL/productpage$GATEWAY_URL 是 Ingress 的外部访问 IP 地址, 正如在 Bookinfo 文档中所解释的那样。

您会注意到,有时书评的输出包含星级评分,有时则不包含。这是因为没有明确的默认服务版本可路由, Istio 将以循环方式将请求路由到所有可用版本。

此任务的最初目标是应用将所有流量路由到微服务的 v1 (版本 1)的规则。稍后,您将应用规则根据 HTTP 请求 header 的值路由流量。

路由到版本 1

要仅路由到一个版本,请应用为微服务设置默认版本的 Virtual Service。

如果尚未定义服务版本,请按照定义服务版本中的说明进行操作。

  1. 运行以下命令以创建路由规则:

    Istio 使用 Virtual Service 来定义路由规则。 运行以下命令以应用 Virtual Service, 在这种情况下,Virtual Service 将所有流量路由到每个微服务的 v1 版本。

    Zip

    1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

    由于配置传播是最终一致的,因此请等待几秒钟以使 Virtual Service 生效。

    1. $ kubectl apply -f - <<EOF
    2. apiVersion: gateway.networking.k8s.io/v1
    3. kind: HTTPRoute
    4. metadata:
    5. name: reviews
    6. spec:
    7. parentRefs:
    8. - group: ""
    9. kind: Service
    10. name: reviews
    11. port: 9080
    12. rules:
    13. - backendRefs:
    14. - name: reviews-v1
    15. port: 9080
    16. EOF
  2. 使用以下命令显示已定义的路由:

  1. $ kubectl get virtualservices -o yaml
  2. - apiVersion: networking.istio.io/v1
  3. kind: VirtualService
  4. ...
  5. spec:
  6. hosts:
  7. - details
  8. http:
  9. - route:
  10. - destination:
  11. host: details
  12. subset: v1
  13. - apiVersion: networking.istio.io/v1
  14. kind: VirtualService
  15. ...
  16. spec:
  17. hosts:
  18. - productpage
  19. http:
  20. - route:
  21. - destination:
  22. host: productpage
  23. subset: v1
  24. - apiVersion: networking.istio.io/v1
  25. kind: VirtualService
  26. ...
  27. spec:
  28. hosts:
  29. - ratings
  30. http:
  31. - route:
  32. - destination:
  33. host: ratings
  34. subset: v1
  35. - apiVersion: networking.istio.io/v1
  36. kind: VirtualService
  37. ...
  38. spec:
  39. hosts:
  40. - reviews
  41. http:
  42. - route:
  43. - destination:
  44. host: reviews
  45. subset: v1

您还可以使用以下命令显示相应的 subset 定义:

  1. $ kubectl get destinationrules -o yaml
  1. $ kubectl get httproute reviews -o yaml
  2. ...
  3. spec:
  4. parentRefs:
  5. - group: gateway.networking.k8s.io
  6. kind: Service
  7. name: reviews
  8. port: 9080
  9. rules:
  10. - backendRefs:
  11. - group: ""
  12. kind: Service
  13. name: reviews-v1
  14. port: 9080
  15. weight: 1
  16. matches:
  17. - path:
  18. type: PathPrefix
  19. value: /
  20. status:
  21. parents:
  22. - conditions:
  23. - lastTransitionTime: "2022-11-08T19:56:19Z"
  24. message: Route was valid
  25. observedGeneration: 8
  26. reason: Accepted
  27. status: "True"
  28. type: Accepted
  29. - lastTransitionTime: "2022-11-08T19:56:19Z"
  30. message: All references resolved
  31. observedGeneration: 8
  32. reason: ResolvedRefs
  33. status: "True"
  34. type: ResolvedRefs
  35. controllerName: istio.io/gateway-controller
  36. parentRef:
  37. group: gateway.networking.k8s.io
  38. kind: Service
  39. name: reviews
  40. port: 9080

在资源状态中,确保 reviews 父级的 Accepted 条件为 True

您已将 Istio 配置为路由到 Bookinfo 微服务的 v1 版本,最重要的是 reviews 服务的版本 1。

测试新的路由配置

您可以通过再次刷新 Bookinfo 应用程序的 /productpage 轻松测试新配置。 在浏览器中打开 Bookinfo 站点。网址为 http://$GATEWAY_URL/productpage,其中 $GATEWAY_URL 是外部的入口 IP 地址,如 Bookinfo 文档中所述。请注意,无论您刷新多少次,页面的评论部分都不会显示评级星标。这是因为您将 Istio 配置为将评论服务的所有流量路由到版本 reviews:v1,而此版本的服务不访问星级评分服务。

您已成功完成此任务的第一部分:将流量路由到服务的某一个版本。

基于用户身份的路由

接下来,您将更改路由配置,以便将来自特定用户的所有流量路由到特定服务版本。在这种情况下, 来自名为 Jason 的用户的所有流量将被路由到服务 reviews:v2

请注意,Istio 对用户身份没有任何特殊的内置机制。事实上,productpage 服务在所有到 reviews 服务的 HTTP 请求中都增加了一个自定义的 end-user 请求头,从而达到了本例子的效果。

Istio 还支持在入口网关上基于强认证 JWT 的路由,参考 JWT 基于声明的路由

请记住,reviews:v2 是包含星级评分功能的版本。

  1. 运行以下命令以启用基于用户的路由:

Zip

  1. $ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@

您可以使用以下命令确认规则已创建:

  1. $ kubectl get virtualservice reviews -o yaml
  2. apiVersion: networking.istio.io/v1
  3. kind: VirtualService
  4. ...
  5. spec:
  6. hosts:
  7. - reviews
  8. http:
  9. - match:
  10. - headers:
  11. end-user:
  12. exact: jason
  13. route:
  14. - destination:
  15. host: reviews
  16. subset: v2
  17. - route:
  18. - destination:
  19. host: reviews
  20. subset: v1
  1. $ kubectl apply -f - <<EOF
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: reviews
  6. spec:
  7. parentRefs:
  8. - group: ""
  9. kind: Service
  10. name: reviews
  11. port: 9080
  12. rules:
  13. - matches:
  14. - headers:
  15. - name: end-user
  16. value: jason
  17. backendRefs:
  18. - name: reviews-v2
  19. port: 9080
  20. - backendRefs:
  21. - name: reviews-v1
  22. port: 9080
  23. EOF
  1. 在 Bookinfo 应用程序的 /productpage 上,以用户 jason 身份登录。

    刷新浏览器。您看到了什么?星级评分显示在每个评论旁边。

  2. 以其他用户身份登录(选择您想要的任何名称)。

    刷新浏览器。现在星星消失了。这是因为除了 Jason 之外,所有用户的流量都被路由到 reviews:v1

您已成功配置 Istio 以根据用户身份路由流量。

理解原理

在此任务中,您首先使用 Istio 将 100% 的请求流量都路由到了 Bookinfo 服务的 v1 版本。 然后设置了一条路由规则,它根据 productpage 服务发起的请求中的 end-user 自定义请求头内容, 选择性地将特定的流量路由到了 reviews 服务的 v2 版本。

请注意,Kubernetes 中的服务,如本任务中使用的 Bookinfo 服务,必须遵守某些特定限制,才能利用到 Istio 的 L7 路由特性优势。参考 Pod 和 Service 需求了解详情。

流量转移任务中, 您将按照在此处学习到的相同的基本模式来配置路由规则,以逐步将流量从服务的一个版本迁移到另一个版本。

清除

  1. 删除应用程序的路由规则:

Zip

  1. $ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
  1. $ kubectl delete httproute reviews
  1. 如果您不打算探索任何后续任务,请参阅 Bookinfo 清理的说明关闭应用程序。