配置请求路由
此任务将展示如何将请求动态路由到微服务的多个版本。
Istio 包括了对 Kubernetes Gateway API 的 Beta 支持, 打算未来使其成为流量管理的默认 API。 以下说明指导您在网格中配置流量管理时如何选择使用 Gateway API 或 Istio 配置 API。 请按照您的首选项遵循 Gateway API
或 Istio APIs
页签中的指示说明。
本文使用 Gateway API 配置内部网格(东西)流量。 使用 Gateway API 配置内部网格流量目前是一个还在开发的实验性特性, 也是 Istio 特有的功能。在使用 Gateway API 指令之前,请确保:
安装 实验版本 的 Gateway API CRD:
$ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.1.0" | kubectl apply -f -
安装 Istio 时,通过将
PILOT_ENABLE_ALPHA_GATEWAY_API
环境变量设置为true
使 Istio 读取 Alpha 版本的 Gateway API 资源:$ istioctl install --set values.pilot.env.PILOT_ENABLE_ALPHA_GATEWAY_API=true --set profile=minimal -y
开始之前
按照安装指南中的说明安装 Istio。
部署 Bookinfo 示例应用程序。
查看流量管理的概念文档。在尝试此任务之前, 您应该熟悉一些重要的术语,例如 Destination Rule、Virtual Service 和 Subset。
关于这个任务
Istio Bookinfo 示例包含四个独立的微服务, 每个微服务都有多个版本。其中一个微服务 reviews
的三个不同版本已经部署并同时运行。 为了说明这导致的问题,在浏览器中访问 Bookinfo 应用程序的 /productpage
并刷新几次。 URL 是 http://$GATEWAY_URL/productpage
,$GATEWAY_URL
是 Ingress 的外部访问 IP 地址, 正如在 Bookinfo 文档中所解释的那样。
您会注意到,有时书评的输出包含星级评分,有时则不包含。这是因为没有明确的默认服务版本可路由, Istio 将以循环方式将请求路由到所有可用版本。
此任务的最初目标是应用将所有流量路由到微服务的 v1
(版本 1)的规则。稍后,您将应用规则根据 HTTP 请求 header 的值路由流量。
路由到版本 1
要仅路由到一个版本,请应用为微服务设置默认版本的 Virtual Service。
如果尚未定义服务版本,请按照定义服务版本中的说明进行操作。
运行以下命令以创建路由规则:
Istio 使用 Virtual Service 来定义路由规则。 运行以下命令以应用 Virtual Service, 在这种情况下,Virtual Service 将所有流量路由到每个微服务的
v1
版本。$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
由于配置传播是最终一致的,因此请等待几秒钟以使 Virtual Service 生效。
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- group: ""
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: reviews-v1
port: 9080
EOF
使用以下命令显示已定义的路由:
$ kubectl get virtualservices -o yaml
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
您还可以使用以下命令显示相应的 subset
定义:
$ kubectl get destinationrules -o yaml
$ kubectl get httproute reviews -o yaml
...
spec:
parentRefs:
- group: gateway.networking.k8s.io
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- group: ""
kind: Service
name: reviews-v1
port: 9080
weight: 1
matches:
- path:
type: PathPrefix
value: /
status:
parents:
- conditions:
- lastTransitionTime: "2022-11-08T19:56:19Z"
message: Route was valid
observedGeneration: 8
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2022-11-08T19:56:19Z"
message: All references resolved
observedGeneration: 8
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
group: gateway.networking.k8s.io
kind: Service
name: reviews
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
是包含星级评分功能的版本。
- 运行以下命令以启用基于用户的路由:
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@
您可以使用以下命令确认规则已创建:
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
$ kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- group: ""
kind: Service
name: reviews
port: 9080
rules:
- matches:
- headers:
- name: end-user
value: jason
backendRefs:
- name: reviews-v2
port: 9080
- backendRefs:
- name: reviews-v1
port: 9080
EOF
在 Bookinfo 应用程序的
/productpage
上,以用户jason
身份登录。刷新浏览器。您看到了什么?星级评分显示在每个评论旁边。
以其他用户身份登录(选择您想要的任何名称)。
刷新浏览器。现在星星消失了。这是因为除了 Jason 之外,所有用户的流量都被路由到
reviews:v1
。
您已成功配置 Istio 以根据用户身份路由流量。
理解原理
在此任务中,您首先使用 Istio 将 100% 的请求流量都路由到了 Bookinfo 服务的 v1
版本。 然后设置了一条路由规则,它根据 productpage
服务发起的请求中的 end-user
自定义请求头内容, 选择性地将特定的流量路由到了 reviews
服务的 v2
版本。
请注意,Kubernetes 中的服务,如本任务中使用的 Bookinfo 服务,必须遵守某些特定限制,才能利用到 Istio 的 L7 路由特性优势。参考 Pod 和 Service 需求了解详情。
在流量转移任务中, 您将按照在此处学习到的相同的基本模式来配置路由规则,以逐步将流量从服务的一个版本迁移到另一个版本。
清除
- 删除应用程序的路由规则:
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
$ kubectl delete httproute reviews
- 如果您不打算探索任何后续任务,请参阅 Bookinfo 清理的说明关闭应用程序。