×

3scale Istio 适配器是一个可选适配器,允许您标记在 Red Hat OpenShift Service Mesh 中运行的服务,并将该服务与 3scale API 管理解决方案集成。Red Hat OpenShift Service Mesh 不需要它。

您只能将 3scale Istio 适配器与 Red Hat OpenShift Service Mesh 2.0 及以下版本一起使用。Mixer 组件在 2.0 版本中已弃用,在 2.1 版本中已移除。对于 Red Hat OpenShift Service Mesh 2.1.0 及更高版本,您应该使用3scale WebAssembly 模块

如果您想使用 3scale Istio 适配器启用 3scale 后端缓存,则还必须启用 Mixer 策略和 Mixer 遥测。请参阅部署 Red Hat OpenShift Service Mesh 控制平面

将 3scale 适配器与 Red Hat OpenShift Service Mesh 集成

您可以使用这些示例来配置对使用 3scale Istio 适配器的服务的请求。

先决条件
  • Red Hat OpenShift Service Mesh 2.x 版本

  • 一个可用的 3scale 账户(SaaS3scale 2.9 本地部署

  • 启用后端缓存需要 3scale 2.9 或更高版本

  • Red Hat OpenShift Service Mesh 先决条件

  • 确保启用了 Mixer 策略强制执行。更新 Mixer 策略强制执行部分提供了检查当前 Mixer 策略强制执行状态和启用策略强制执行的说明。

  • 如果您使用的是 Mixer 插件,则必须启用 Mixer 策略和遥测。

    • 升级时,您需要正确配置服务网格控制平面 (SMCP)。

要配置 3scale Istio 适配器,请参阅 Red Hat OpenShift Service Mesh 自定义资源,了解有关将适配器参数添加到自定义资源文件的说明。

请特别注意kind: handler 资源。您必须使用您的 3scale 帐户凭据更新此项。您可以选择向处理程序添加service_id,但这仅是为了向后兼容性而保留,因为它只会使处理程序对您 3scale 帐户中的一个服务有用。如果您向处理程序添加service_id,则为其他服务启用 3scale 需要您创建更多具有不同service_id 的处理程序。

按照以下步骤,为每个 3scale 帐户使用单个处理程序

步骤
  1. 为您的 3scale 帐户创建一个处理程序,并指定您的帐户凭据。省略任何服务标识符。

      apiVersion: "config.istio.io/v1alpha2"
      kind: handler
      metadata:
       name: threescale
      spec:
       adapter: threescale
       params:
         system_url: "https://<organization>-admin.3scale.net/"
         access_token: "<ACCESS_TOKEN>"
       connection:
         address: "threescale-istio-adapter:3333"

    或者,您可以在 params 部分中提供一个backend_url 字段来覆盖 3scale 配置提供的 URL。如果适配器与 3scale 本地实例在同一个集群中运行,并且您希望利用内部集群 DNS,这可能很有用。

  2. 编辑或修补属于您 3scale 帐户的任何服务的 Deployment 资源,如下所示

    1. 添加值为有效service_id"service-mesh.3scale.net/service-id" 标签。

    2. 添加值为步骤 1 中的 处理程序资源名称"service-mesh.3scale.net/credentials" 标签。

  3. 每当您打算添加更多服务时,请执行步骤 2 以将其链接到您的 3scale 帐户凭据及其服务标识符。

  4. 使用您的 3scale 配置修改规则配置,以将规则分派到 threescale 处理程序。

    规则配置示例
      apiVersion: "config.istio.io/v1alpha2"
      kind: rule
      metadata:
        name: threescale
      spec:
        match: destination.labels["service-mesh.3scale.net"] == "true"
        actions:
          - handler: threescale.handler
            instances:
              - threescale-authorization.instance

生成 3scale 自定义资源

适配器包含一个工具,允许您生成handlerinstancerule 自定义资源。

表 1. 用法
选项 描述 必需 默认值

-h, --help

生成可用选项的帮助输出

--name

此 URL、令牌对的唯一名称

-n, --namespace

生成模板的命名空间

istio-system

-t, --token

3scale 访问令牌

-u, --url

3scale 管理门户 URL

--backend-url

3scale 后端 URL。如果设置,它将覆盖从系统配置读取的值

-s, --service

3scale API/服务 ID

--auth

要指定的 3scale 身份验证模式 (1=API 密钥,2=应用 ID/应用密钥,3=OIDC)

混合

-o, --output

将生成的清单保存到的文件

标准输出

--version

输出 CLI 版本并立即退出

从 URL 示例生成模板

  • 通过从已部署的适配器生成清单中的 3scale 适配器容器映像,通过oc exec 运行以下命令。

  • 使用3scale-config-gen 命令可以避免 YAML 语法和缩进错误。

  • 如果您使用注释,可以省略--service

  • 必须通过oc exec 从容器映像内调用此命令。

步骤
  • 使用3scale-config-gen 命令自动生成模板文件,允许令牌、URL 对作为单个处理程序由多个服务共享

    $ 3scale-config-gen --name=admin-credentials --url="https://<organization>-admin.3scale.net:443" --token="[redacted]"
  • 以下示例使用嵌入在处理程序中的服务 ID 生成模板

    $ 3scale-config-gen --url="https://<organization>-admin.3scale.net" --name="my-unique-id" --service="123456789" --token="[redacted]"
其他资源

从已部署的适配器生成清单

  • NAME 是您用来标识您使用 3scale 管理的服务的标识符。

  • CREDENTIALS_NAME 引用是与规则配置中的match 部分对应的标识符。如果您使用的是 CLI 工具,则此标识符会自动设置为NAME 标识符。

  • 其值无需指定,标签值只需与规则内容匹配即可。更多信息,请参见 通过适配器路由服务流量

  1. 运行以下命令,根据 `istio-system` 命名空间中已部署的适配器生成清单文件

    $ export NS="istio-system" URL="https://replaceme-admin.3scale.net:443" NAME="name" TOKEN="token"
    oc exec -n ${NS} $(oc get po -n ${NS} -o jsonpath='{.items[?(@.metadata.labels.app=="3scale-istio-adapter")].metadata.name}') \
    -it -- ./3scale-config-gen \
    --url ${URL} --name ${NAME} --token ${TOKEN} -n ${NS}
  2. 这将在终端生成示例输出。如有需要,请编辑这些示例,然后使用 `oc create` 命令创建对象。

  3. 当请求到达适配器时,适配器需要知道服务如何映射到 3scale 上的 API。您可以通过两种方式提供此信息

    1. 标记工作负载(推荐)

    2. 将处理程序硬编码为 `service_id`

  4. 使用所需的注解更新工作负载

    只有在服务 ID 未嵌入处理程序中时,才需要更新此示例中提供的服务 ID。**处理程序中的设置优先**。

    $ export CREDENTIALS_NAME="replace-me"
    export SERVICE_ID="replace-me"
    export DEPLOYMENT="replace-me"
    patch="$(oc get deployment "${DEPLOYMENT}"
    patch="$(oc get deployment "${DEPLOYMENT}" --template='{"spec":{"template":{"metadata":{"labels":{ {{ range $k,$v := .spec.template.metadata.labels }}"{{ $k }}":"{{ $v }}",{{ end }}"service-mesh.3scale.net/service-id":"'"${SERVICE_ID}"'","service-mesh.3scale.net/credentials":"'"${CREDENTIALS_NAME}"'"}}}}}' )"
    oc patch deployment "${DEPLOYMENT}" --patch ''"${patch}"''

通过适配器路由服务流量

请按照以下步骤将服务的流量引导到 3scale 适配器。

先决条件
  • 来自您的 3scale 管理员的凭据和服务 ID。

步骤
  1. 匹配您之前在配置中创建的规则 `destination.labels["service-mesh.3scale.net/credentials"] == "threescale"`,位于 `kind: rule` 资源中。

  2. 将上述标签添加到目标工作负载部署的 `PodTemplateSpec` 中以集成服务。值 `threescale` 指的是生成的处理程序的名称。此处理程序存储调用 3scale 所需的访问令牌。

  3. 将 `destination.labels["service-mesh.3scale.net/service-id"] == "replace-me"` 标签添加到工作负载,以便在请求时通过实例将服务 ID 传递给适配器。

配置 3scale 中的集成设置

请按照此步骤配置 3scale 集成设置。

对于 3scale SaaS 客户,Red Hat OpenShift Service Mesh 作为抢先体验计划的一部分启用。

步骤
  1. 导航到 [your_API_name]集成

  2. 点击 设置

  3. 部署下选择Istio选项。

    • 身份验证下的API 密钥 (user_key)选项默认选中。

  4. 点击更新产品以保存您的选择。

  5. 点击配置

  6. 点击更新配置

缓存行为

来自 3scale 系统 API 的响应默认情况下在适配器中缓存。当条目过期超过 `cacheTTLSeconds` 值时,它们将从缓存中清除。默认情况下,还会在缓存条目过期前 `cacheRefreshSeconds` 秒尝试自动刷新缓存条目。您可以通过将此值设置为高于 `cacheTTLSeconds` 值来禁用自动刷新。

通过将 `cacheEntriesMax` 设置为非正值,可以完全禁用缓存。

通过使用刷新过程,主机不可访问的缓存值将在最终过期并被清除之前重试。

身份验证请求

此版本支持以下身份验证方法

  • 标准 API 密钥:充当标识符和密钥令牌的单个随机字符串或哈希值。

  • 应用程序标识符和密钥对:不可变的标识符和可变的密钥字符串。

  • OpenID 身份验证方法:从 JSON Web 令牌中解析的客户端 ID 字符串。

应用身份验证模式

修改 `instance` 自定义资源,如以下身份验证方法示例所示,以配置身份验证行为。您可以从以下位置接受身份验证凭据:

  • 请求头

  • 请求参数

  • 请求头和查询参数

指定来自标头中的值时,它们必须小写。例如,如果您想发送一个名为 `User-Key` 的标头,则必须在配置中将其引用为 `request.headers["user-key"]`。

API 密钥身份验证方法

Service Mesh 在查询参数和请求头中查找 API 密钥,如 `subject` 自定义资源参数中的 `user` 选项中指定。它按照自定义资源文件中给出的顺序检查值。您可以通过省略不需要的选项来限制对查询参数或请求头的 API 密钥搜索。

在此示例中,Service Mesh 首先在 `user_key` 查询参数中查找 API 密钥。如果查询参数中不存在 API 密钥,则 Service Mesh 会检查 `user-key` 头。

API 密钥身份验证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
  namespace: istio-system
spec:
  template: authorization
  params:
    subject:
      user: request.query_params["user_key"] | request.headers["user-key"] | ""
    action:
      path: request.url_path
      method: request.method | "get"

如果您希望适配器检查不同的查询参数或请求头,请根据需要更改名称。例如,要检查名为“key”的查询参数中的 API 密钥,请将 `request.query_params["user_key"]` 更改为 `request.query_params["key"]`。

应用程序 ID 和应用程序密钥对身份验证方法

Service Mesh 在查询参数和请求头中查找应用程序 ID 和应用程序密钥,如 `subject` 自定义资源参数中的 `properties` 选项中指定。应用程序密钥是可选的。它按照自定义资源文件中给出的顺序检查值。您可以通过不包含不需要的选项来限制对查询参数或请求头的凭据搜索。

在此示例中,Service Mesh 首先在查询参数中查找应用程序 ID 和应用程序密钥,然后根据需要转到请求头。

应用程序 ID 和应用程序密钥对身份验证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
  namespace: istio-system
spec:
  template: authorization
  params:
    subject:
        app_id: request.query_params["app_id"] | request.headers["app-id"] | ""
        app_key: request.query_params["app_key"] | request.headers["app-key"] | ""
    action:
      path: request.url_path
      method: request.method | "get"

如果您希望适配器检查不同的查询参数或请求头,请根据需要更改名称。例如,要检查名为 `identification` 的查询参数中的应用程序 ID,请将 `request.query_params["app_id"]` 更改为 `request.query_params["identification"]`。

OpenID 身份验证方法

要使用OpenID Connect (OIDC) 身份验证方法,请使用 `subject` 字段上的 `properties` 值设置 `client_id`,并可选地设置 `app_key`。

您可以使用前面描述的方法操作此对象。在下面显示的示例配置中,客户端标识符(应用程序 ID)是从标签为 *azp* 的 JSON Web 令牌 (JWT) 中解析的。您可以根据需要修改此项。

OpenID 身份验证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
spec:
  template: threescale-authorization
  params:
    subject:
      properties:
        app_key: request.query_params["app_key"] | request.headers["app-key"] | ""
        client_id: request.auth.claims["azp"] | ""
      action:
        path: request.url_path
        method: request.method | "get"
        service: destination.labels["service-mesh.3scale.net/service-id"] | ""

为了使此集成正常工作,仍然必须在 3scale 中完成 OIDC,以便在身份提供商 (IdP) 中创建客户端。您应该为要在与该服务相同的命名空间中保护的服务创建 请求授权。JWT 通过请求的 `Authorization` 标头传递。

在下面定义的示例 `RequestAuthentication` 中,请根据需要替换 `issuer`、`jwksUri` 和 `selector`。

OpenID策略示例
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: jwt-example
  namespace: bookinfo
spec:
  selector:
    matchLabels:
      app: productpage
  jwtRules:
  - issuer: >-
      http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak
    jwksUri: >-
      http://keycloak-keycloak.34.242.107.254.nip.io/auth/realms/3scale-keycloak/protocol/openid-connect/certs

混合身份验证方法

您可以选择不强制执行特定的身份验证方法,并接受任何两种方法的有效凭据。如果同时提供了 API 密钥和应用程序 ID/应用程序密钥对,则 Service Mesh 使用 API 密钥。

在这个示例中,服务网格会检查查询参数中的 API 密钥,然后检查请求头。如果没有 API 密钥,则会检查查询参数中的应用程序 ID 和密钥,然后检查请求头。

混合认证方法示例
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
  name: threescale-authorization
spec:
  template: authorization
  params:
    subject:
      user: request.query_params["user_key"] | request.headers["user-key"] |
      properties:
        app_id: request.query_params["app_id"] | request.headers["app-id"] | ""
        app_key: request.query_params["app_key"] | request.headers["app-key"] | ""
        client_id: request.auth.claims["azp"] | ""
    action:
      path: request.url_path
      method: request.method | "get"
      service: destination.labels["service-mesh.3scale.net/service-id"] | ""

3scale 适配器指标

适配器默认情况下会报告各种 Prometheus 指标,这些指标在端口8080/metrics 端点上公开。这些指标提供了对适配器和 3scale 之间交互性能的洞察。该服务被标记为可由 Prometheus 自动发现和抓取。

自服务网格 1.x 版本之前的版本以来,3scale Istio 适配器指标存在不兼容的更改。

在 Prometheus 中,指标已重命名,并为后端缓存添加了一个指标,因此截至服务网格 2.0,存在以下指标:

表 2. Prometheus 指标
指标 类型 描述

threescale_latency

直方图

适配器和 3scale 之间的请求延迟。

threescale_http_total

计数器

对 3scale 后端的请求的 HTTP 状态响应代码。

threescale_system_cache_hits

计数器

从配置缓存中获取的 3scale 系统的总请求数。

threescale_backend_cache_hits

计数器

从后端缓存中获取的 3scale 后端的总请求数。

3scale 后端缓存

3scale 后端缓存为 3scale 服务管理 API 的客户端提供授权和报告缓存。此缓存嵌入在适配器中,可在某些情况下实现更低的响应延迟,前提是管理员愿意接受权衡。

3scale 后端缓存默认情况下是禁用的。3scale 后端缓存功能以牺牲速率限制的准确性和自上次刷新以来潜在的命中丢失为代价,换取更低的延迟和更高的处理器和内存资源消耗。

启用后端缓存的优势

以下是启用后端缓存的优势:

  • 当您发现访问由 3scale Istio 适配器管理的服务时延迟很高时,请启用后端缓存。

  • 启用后端缓存将阻止适配器不断地与 3scale API 管理器检查请求授权,从而降低延迟。

    • 这会在内存中创建 3scale 授权的缓存,供 3scale Istio 适配器存储和重用,然后再尝试联系 3scale API 管理器进行授权。这样授权的时间就会大大缩短。

  • 当您将 3scale API 管理器托管在运行 3scale Istio 适配器的服务网格的不同地理位置时,后端缓存非常有用。

    • 对于 3scale 托管 (SaaS) 平台通常就是这样,但如果用户将其 3scale API 管理器托管在位于不同地理位置、不同可用区或网络开销到 3scale API 管理器的任何情况下,情况也是如此。

降低延迟的权衡

以下是降低延迟的权衡:

  • 每次刷新时,每个 3scale 适配器的授权状态都会更新。

    • 这意味着两个或多个适配器实例会在刷新期间引入更多的不准确性。

    • 有更大机会授予超过限制的请求,从而导致不稳定行为,导致一些请求通过而另一些请求不通过,这取决于哪个适配器处理每个请求。

  • 无法刷新其数据并更新其授权信息的适配器缓存可能会在未向 API 管理器报告其信息的情况下关闭或崩溃。

  • 当适配器缓存无法确定是否必须授予或拒绝请求时(可能是由于联系 API 管理器的网络连接问题),将应用故障转移或故障关闭策略。

  • 当发生缓存未命中时(通常是在启动适配器之后或长时间没有连接之后),查询 API 管理器的延迟会增加。

  • 与未启用缓存相比,适配器缓存必须在计算授权方面做更多工作,这将占用处理器资源。

  • 内存需求将与缓存管理的限制、应用程序和服务的数量成比例地增长。

后端缓存配置设置

以下几点解释了后端缓存配置设置:

  • 在 3scale 配置选项中查找配置后端缓存的设置。

  • 最后 3 个设置控制后端缓存的启用:

    • PARAM_USE_CACHE_BACKEND - 设置为 true 以启用后端缓存。

    • PARAM_BACKEND_CACHE_FLUSH_INTERVAL_SECONDS - 设置连续尝试将缓存数据刷新到 API 管理器之间的时间(以秒为单位)。

    • PARAM_BACKEND_CACHE_POLICY_FAIL_CLOSED - 设置当没有足够的缓存数据并且无法访问 3scale API 管理器时,是否允许/打开或拒绝/关闭对服务的请求。

3scale Istio 适配器 APIcast 模拟

当发生以下情况时,3scale Istio 适配器将像 APIcast 一样执行:

  • 当请求无法匹配任何定义的映射规则时,返回的 HTTP 代码为 404 未找到。以前是 403 禁止。

  • 当请求被拒绝因为它超过限制时,返回的 HTTP 代码为 429 请求过多。以前是 403 禁止。

  • 通过 CLI 生成默认模板时,它将使用下划线而不是短划线作为标题,例如:user_key 而不是 user-key

3scale Istio 适配器验证

您可能需要检查 3scale Istio 适配器是否按预期工作。如果您的适配器无法工作,请使用以下步骤来帮助排除问题。

步骤
  1. 确保3scale-adapter pod 正在服务网格控制平面命名空间中运行。

    $ oc get pods -n istio-system
  2. 检查3scale-adapter pod 是否已打印出有关其启动的信息,例如其版本。

    $ oc logs istio-system
  3. 当对受 3scale 适配器集成保护的服务执行请求时,始终尝试缺少正确凭据的请求并确保它们失败。检查 3scale 适配器日志以收集更多信息。

3scale Istio 适配器故障排除清单

作为安装 3scale Istio 适配器的管理员,可能有多种情况会导致您的集成无法正常运行。请使用以下列表来排查您的安装问题。

  • YAML 缩进错误。

  • 缺少 YAML 部分。

  • 忘记将 YAML 中的更改应用到集群。

  • 忘记使用service-mesh.3scale.net/credentials键标记服务工作负载。

  • 当使用不包含service_id的处理器时(以便每个帐户可重用),忘记使用service-mesh.3scale.net/service-id标记服务工作负载。

  • 规则自定义资源指向错误的处理器或实例自定义资源,或者引用缺少相应的命名空间后缀。

  • 规则自定义资源的match部分可能无法匹配您正在配置的服务,或者它指向当前未运行或不存在的目标工作负载。

  • 处理器中 3scale 管理门户的访问令牌或 URL 错误。

  • 实例自定义资源的params/subject/properties部分未能列出app_idapp_keyclient_id的正确参数,原因可能是它们指定了错误的位置(例如查询参数、标头和授权声明),或者参数名称与用于测试的请求不匹配。

  • 未能使用配置生成器,而没有意识到它实际上位于适配器容器镜像中,需要使用oc exec来调用它。