1.21. 使用 3scale Istio 适配器
3scale Istio 适配器是一个可选适配器,允许您在 Red Hat OpenShift Service Mesh 中标记运行的服务,并将该服务与 3scale API 管理解决方案集成。Red Hat OpenShift Service Mesh 不需要该适配器。
您只能在 Red Hat OpenShift Service Mesh 版本 2.0 及以下中使用 3scale Istio 适配器。Mixer 组件在版本 2.0 中已弃用,并在版本 2.1 中删除。对于 Red Hat OpenShift Service Mesh 2.1.0 及之后的版本,您应该使用 3scale WebAsembly 模块。
如果要使用 3scale Istio 适配器启用 3scale 后端缓存,还必须启用 Mixer 策略和 Mixer 遥测。请参阅部署 Red Hat OpenShift Service Mesh control plane。
1.21.1. 将 3scale 适配器与 Red Hat OpenShift Service Mesh 集成
您可以使用这些示例来配置对使用 3scale Istio 适配器的服务的请求。
先决条件
- Red Hat OpenShift Service Mesh 版本 2.x
- 一个有效的 3scale 帐户(SaaS 或 3scale 2.9 On-Premises)
- 启用后端缓存需要 3scale 2.9 或更高版本
- Red Hat OpenShift Service Mesh 的先决条件
- 启用了 Mixer 强制功能。“更新 Mixer 策略强制”部分提供了检查当前 Mixer 策略实施状态和启用策略强制状态的信息。
如果您使用混合器插件,则必须启用混合器策略和遥测。
- 升级时,您需要正确配置 Service Mesh Control Plane(SMCP)。
要配置 3scale Istio 适配器,请参考“Red Hat OpenShift Service Mesh 自定义资源”来获得在自定义资源文件中添加适配器参数的说明。
请特别注意 kind: handler
资源。您必须使用 3scale 帐户凭证更新它。您可以选择将 service_id
添加到处理程序,但这仅用于向后兼容性,因为它会使处理程序仅对 3scale 帐户中的一个服务有用。如果将 service_id
添加到处理程序,则为其他服务启用 3scale 需要使用不同的 service_ids
创建更多处理程序。
按照以下步骤,每个 3scale 帐户使用一个处理器:
流程
为您的 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,这可能很有用。编辑或修补属于 3scale 帐户的所有服务的 Deployment 资源,如下所示:
-
添加
"service-mesh.3scale.net/service-id"
标签,其值与有效的service_id
对应。 -
添加
"service-mesh.3scale.net/credentials"
标签,其值为第 1 步中的 handler 资源的名称。
-
添加
- 每当您想要添加更多服务时,请执行第 2 步将其链接到您的 3scale 帐户凭证及其服务标识符。
用 3scale 配置来修改规则配置,将规则发送到 3scale 处理器。
规则配置示例
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
1.21.1.1. 生成 3scale 自定义资源
适配器包括了一个可以用来生成 handler
、instance
和 rule
自定义资源的工具。
选项 | 描述 | 必需的 | 默认值 |
---|---|---|---|
| 显示可用选项的帮助信息 | 不是 | |
| 这个 URL 的唯一名称,令牌对 | 是 | |
| 生成模板的命名空间 | 不是 | istio-system |
| 3scale 访问令牌 | 是 | |
| 3scale Admin Portal URL | 是 | |
| 3scale 后端 URL。如果设定,它会覆盖从系统配置中读取的值。 | 不是 | |
| 3scale API/Service ID | 不是 | |
| 3scale 的认证方法(1=API Key, 2=App Id/App Key, 3=OIDC) | 不是 | 混合 |
| 保存产生的清单的文件 | 不是 | 标准输出 |
| 输出 CLI 版本并立即退出 | 不是 |
1.21.1.1.1. 从 URL 示例生成模板
-
通过
oc exec
运行以下命令从 3scale adapter 容器镜像生成清单(请参阅 从一个部署的 adapter 生成清单)。 -
使用
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]"
其他资源
- 令牌.
1.21.1.2. 从部署的适配器生成清单
-
NAME
是用于标识您使用 3scale 管理的服务的标识符。 -
CREDENTIALS_NAME
引用是一个标识符,对应于规则配置中的match
部分。如果您使用 CLI 工具,这会自动设置为NAME
标识符。 - 其值不需要任何特定内容:标签值应当仅与规则的内容匹配。如需更多信息,请参阅通过适配器路由服务流量。
运行这个命令从在
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}
-
这将在终端中输出示例。如果需要,请编辑这些样本,并使用
oc create
命令创建对象。 当请求到达适配器时,适配器需要知道服务如何被映射到一个 3scale 中的 API。您可以以两种方式提供这个信息:
- 标记(label)工作负载(推荐)
-
硬编码处理器为
service_id
使用所需注解更新工作负载:
注意如果服务 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}"''
1.21.1.3. 通过适配器的路由服务流量
按照以下步骤,通过 3scale 适配器为您的服务驱动流量。
先决条件
- 3scale 管理员的凭据和服务 ID。
流程
-
匹配在以前创建的配置中的
destination.labels["service-mesh.3scale.net/credentials"] == "threescale"
(在kind: rule
资源中)。 -
在部署目标负载时为
PodTemplateSpec
添加上面的标签以集成服务 。threescale
是生成的处理器的名称。这个处理器存储了调用 3scale 所需的访问令牌。 -
为工作负载添加
destination.labels["service-mesh.3scale.net/service-id"] == "replace-me"
标签,以便在请求时通过实例将服务 ID 传递给适配器。
1.21.2. 在 3scale 中配置集成设置
按照以下步骤配置 3scale 集成设置。
对于 3scale SaaS 客户,Red Hat OpenShift Service Mesh 作为 Early Access 项目的一部分被启用。
流程
-
进入 [your_API_name]
Integration - 单击 Settings。
在 Deployment 下选择 Istio 选项。
- Authentication 下的 API Key (user_key) 选项会被默认选择。
- 单击 Update Product 以保存您的选择。
- 单击 Configuration。
- 单击 Update Configuration。
1.21.3. 缓存行为
在适配器中,来自 3scale System API 的响应会被默认缓存。当条目存在的时间超过 cacheTTLSeconds
所指定的值时,条目会从缓存清除 。另外,默认情况下,根据cacheRefreshSeconds
的值,在缓存的条目过期前会尝试进行自动刷新。您可以通过设置高于 cacheTTLSeconds
的值来禁用自动刷新。
把 cacheEntriesMax
设置为一个非正数的值可以完全禁用缓存。
通过使用刷新功能,那些代表已无法访问的主机的缓存项,会在其过期并最终被删除前重新尝试进行检索。
1.21.4. 身份验证请求
这个发行版本支持以下验证方法:
- 标准 API 键:使用一个随机字符串或哈希值作为标识符和 secret 令牌。
- 应用程序标识符和键对:不可改变的标识符和可变的密键字符串。
- OpenID 验证方法:从 JSON Web Token 解析的客户端 ID 字符串。
1.21.4.1. 应用验证模式
如以下验证方法示例所示,修改 instance
自定义资源来配置身份验证的方法。您可以接受以下身份验证凭证:
- 请求的标头(header)
- 请求参数
- 请求标头和查询参数
当通过标头指定值时,必须为小写。例如,如果需要发送一个标头为 User-Key
,则需要在配置中使用 request.headers["user-key"]
来指代它。
1.21.4.1.1. API 键验证方法
根据在 subject
自定义资源参数的 user
选项,Service Mesh 在查询参数和请求标头中查找 API 键。它会按照自定义资源文件中给出的顺序检查这些值。您可以通过跳过不需要的选项,把对 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"]
改为 query_params["key"]
。
1.21.4.1.2. 应用程序 ID 和应用程序键对验证方法
根据 subject
自定义资源参数中的 properties
选项,Service Mesh 在查询参数和请求标头中查找应用程序 ID 和应用程序键。应用程序键是可选的。它会按照自定义资源文件中给出的顺序检查这些值。通过不使用不需要的选项,可以将搜索凭证限制为只搜索查询参数或只搜索请求标头。
在这个示例中,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"]
。
1.21.4.1.3. OpenID 验证方法
要使用 OpenID Connect (OIDC) 验证方法,使用 subject
字段中的 properties
值设定 client_id
及可选的 app_key
。
您可以使用前面描述的方法操作这个对象。在下面的示例配置中,客户标识符(应用程序 ID)是从标签 azp 下的 JSON Web Token (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"] | ""
要使这个集成服务可以正常工作,OIDC 必须在 3scale 中完成,以便客户端在身份提供者 (IdP) 中创建。您应该为您要保护的服务在与该服务相同的命名空间中创建 Request 授权。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
1.21.4.1.4. 混合验证方法
您可以选择不强制使用一个特定的验证方法,而是接受任何有效的凭证。如果 API 键和应用程序 ID/应用程序键对都被提供,则 Service Mesh 会使用 API 键。
在这个示例中,Service Mesh 在查询参数中检查一个 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"] | ""
1.21.5. 3scale Adapter 指标数据
在默认情况下,适配器默会通过 /metrics
端点的端口 8080
提供各种 Prometheus 指标数据。这些指标可让您了解适配器和 3scale 之间的交互是如何执行的。该服务被标记为由 Prometheus 自动发现和弃用。
与之前的 Service Mesh 1.x 版本相比,3scale Istio 适配器指标有不兼容的更改。
在 Prometheus 中,指标被重命名为后端缓存的新增名称,以便在 Service Mesh 2.0 中存在以下指标:
指标 | 类型 | 描述 |
---|---|---|
| Histogram | 适配器和 3scale 之间的请求延迟。 |
| 计数 | 到 3scale 后端的请求的 HTTP 状态响应代码。 |
| 计数 | 从配置缓存获取到 3scale 系统的请求总数。 |
| 计数 | 从后端缓存获取到 3scale 后端的请求总数。 |
1.21.6. 3scale 后端缓存
3scale 后端缓存为 3scale 服务管理 API 的客户端提供授权和报告缓存。这个缓存是嵌入到适配器中,在某些情况下可以降低响应速度,假设管理员接受利弊取而代之。
默认情况下禁用 3scale 后端缓存。3scale 后端缓存功能会带来速率限制,以及因为处理器和内存中资源消耗较低延迟和较高消耗,自上次同步以来可能会丢失点击。
1.21.6.1. 启用后端缓存的优点
以下是启用后端缓存的优点:
- 当您在访问由 3scale Istio Adapter 管理的服务时,当您找到时,启用后端缓存。
启用后端缓存将停止适配器不断与 3scale API 管理器签注请求授权,这样可降低延迟。
- 这会创建一个 3scale Istio 适配器的 3scale 授权内存缓存,以便在试图联系 3scale API Manager 获取授权前进行存储和重复使用。这样一来,授予或拒绝授权的时间要短得多。
当您从运行 3scale Istio 适配器的服务网格的其他地理位置托管 3scale API manager 时,后端缓存很有用。
- 这通常是 3scale 托管(SaaS)平台的情况。另外,当用户将 3scale API Manager 托管在另一个群集中时,位于不同地理位置,位于不同的可用区,或者在需要到达 3scale API 管理器的网络开销的情况下也是如此。
1.21.6.2. 具有较低延迟的利弊得失
以下是具有较低延迟的利弊得失:
每个 3scale 适配器的授权状态会在每次 flush 发生时更新。
- 这意味着,两个或者多个适配器实例将在刷新周期之间引入更多不准确。
- 授予太多请求的几率超过限制并引入异常行为,这会导致一些请求被处理,以及一些请求没有完成,这取决于每个适配器处理的请求。
- 如果适配器缓存无法清除其数据并更新其授权信息,而不向 API Manager 报告其信息,则可能会关闭或崩溃。
- 当适配器缓存无法决定请求是否被授予或拒绝时,会应用一个失败的打开策略或已关闭策略,这可能是因为与 API Manager 联系时存在网络连接问题。
- 当缓存丢失时(通常是在引导适配器后或者长时间没有连接后),查询 API 管理器时会增大延迟。
- 适配器缓存必须在计算授权上做很多工作,而不必启用缓存,这会消耗处理器资源。
- 内存需求会与由缓存管理的限值、应用程序和服务的数量成比例增长。
1.21.6.3. 后端缓存配置设置
以下解释了后端缓存配置设置:
- 在 3scale 配置选项中找到用于配置后端缓存的设置。
最后的 3 设置控制启用后端缓存:
-
PARAM_USE_CACHE_BACKEND
- 设置为 true 以启用后端缓存。 -
PARAM_BACKEND_CACHE_FLUSH_INTERVAL_SECONDS
- 以秒为单位设置连续尝试刷新 API 管理器缓存数据的时间(以秒为单位)。 -
PARAM_BACKEND_CACHE_POLICY_FAIL_CLOSED
- 当没有足够的缓存数据且无法到达 3scale API Manager 时,设定是否允许/打开或拒绝对服务的请求。
-
1.21.7. 3scale Istio Adapter APIcast emulation
当出现以下情况时,3scale Istio Adapter 会以 APIcast 的形式执行:
- 当请求无法与定义的任何映射规则匹配时,返回的 HTTP 代码为 404 Not Found。之前是 403 Forbidden。
- 当一个请求因为超过限制而被拒绝时,返回的 HTTP 代码为 429 Too Many Requests。之前是 403 Forbidden。
-
在通过 CLI 生成默认模板时,对于标头使用下划线而不是横线,例如:
user_key
而不是user-key
。
1.21.8. 3scale Istio 适配器验证
您可能需要检查 3scale Istio 适配器是否按预期工作。如果您的适配器无法正常工作,请按照以下步骤帮助排除此问题。
流程
确保 3scale-adapter pod 在 Service Mesh control plane 命名空间中运行:
$ oc get pods -n <istio-system>
检查 3scale-adapter pod 是否已输出有关自身引导的信息,比如它的版本:
$ oc logs <istio-system>
- 在对 3scale 适配器集成保护的服务执行请求时,请始终尝试缺少正确凭证的请求,并确保它们失败。检查 3scale 适配器日志来收集其他信息。
其他资源
1.21.9. 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 错误。
-
Instance 自定义资源的
params/subject/properties
部分无法列出app_id
、app_key
或client_id
的正确参数,因为它们指定了错误的位置,如查询参数、标头和授权声明,或者参数名称与用于测试的请求不匹配。 -
在未意识到它实际存放在适配器容器镜像中,并且需要
oc exec
调用它的情况下,未能使用配置生成器。