×

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. 匹配您之前在配置中创建的 kind: rule 资源中的规则 destination.labels["service-mesh.3scale.net/credentials"] == "threescale"

  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 密钥身份验证方法

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

在此示例中,服务网格首先在 user_key 查询参数中查找 API 密钥。如果查询参数中不存在 API 密钥,则服务网格将检查 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 和应用程序密钥对身份验证方法

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

在此示例中,服务网格首先在查询参数中查找应用程序 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)是从 JSON Web 令牌 (JWT) 的标签 *azp* 中解析的。您可以根据需要修改此项。

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 中,请根据需要替换 issuerjwksUriselector

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/应用程序密钥对,服务网格将使用 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 Istio 适配器的服务网格不同的地理位置托管 3scale API 管理器时,后端缓存非常有用。

    • 对于 3scale 托管 (SaaS) 平台通常如此,但如果用户在其位于不同地理位置、不同可用区或任何情况下网络开销明显的其他集群中托管其 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标记服务工作负载。

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

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

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

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

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