如何根据 URL id 在 Istio 上设置哈希?

问题描述

在改进 Kubernetes 上的 API 的背景下,我正在考虑使用分布式哈希表。我的 API 总是接收对具有此方案的 URL 的请求:

www.myapi.com/id

阅读 Istio 的文档,似乎很直接也很容易得到我想要的东西。事实上,Istio 处理称为 ConsistentHashLB负载平衡方案。在这样的方案中,根据从几个可能的字段计算出的哈希值来选择服务目的地:HTTP 标头名称、cookie、源 IP 和 HTTP 查询参数名称

就我而言,我需要根据与请求关联的 id 计算哈希值。

我的问题是双重且有条件的:

  1. 是否可以将 id 读取为 HTTP 参数名称
  2. 如果是肯定的,我应该如何在清单中指定规则? (我读过的文档在这方面不够清楚)。

如果是否定的,有什么想法吗?一些技巧?例如,我正在考虑将 id 添加为带有 `Nginx 的 HTTP 标头,但这会增加一个额外的步骤。

解决方法

正如我在评论中提到的,如果我理解正确的话,您正在寻找 ConsistenHashLB 路径,关于该路径有 documentation

还有github issue关于这一点。


至于 http 标头问题,您应该可以添加:

  1. Virtual Service

istio 文档中的 Headers 部分展示了如何通过示例添加/删除标头。

当 Envoy 将请求转发到目标服务或从目标服务转发响应时,可以操纵消息头。可以为特定路由目的地或所有目的地指定标头操作规则。以下 VirtualService 向路由到任何评论服务目标的请求添加了一个值为 true 的测试标头。它还删除了 foo 响应标头,但仅限于来自评论服务的 v1 子集(版本)的响应。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - headers:
      request:
        set:
          test: "true"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
      weight: 25
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1
      headers:
        response:
          remove:
          - foo
      weight: 75
  1. Envoy Filter

EnvoyFilter 提供了一种机制来自定义 Istio Pilot 生成的 Envoy 配置。使用 EnvoyFilter 修改某些字段的值,添加特定过滤器,甚至添加全新的侦听器、集群等。

在 envoy 过滤器下方,向所有通过 istio 入口网关的请求添加名为 customer-id 的请求标头,其中包含 alice 值。我还评论了响应标头的代码。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: lua-filter
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: HTTP_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
            subFilter:
              name: "envoy.router"
    patch:
      operation: INSERT_BEFORE
      value:
       name: envoy.lua
       typed_config:
         "@type": "type.googleapis.com/envoy.config.filter.http.lua.v2.Lua"
         inlineCode: |
            function envoy_on_request(request_handle)
                request_handle:headers():add("customer-id","alice")
            end
           # function envoy_on_response(response_handle)
           #     response_handle:headers():add("customer-id","alice")
           # end
,

使用 webassembly 应该是可能的:https://istio.io/latest/docs/concepts/wasm/

(但你需要做一些工作来部署它)