1.3. 配置路由
您可以使用注解、标头、Cookie 等来自定义路由配置。
1.3.1. 配置路由超时 复制链接链接已复制到粘贴板!
如果您的服务需要低超时(满足服务级别可用性 (SLA) 目的)或高超时(具有慢速后端的情况),您可以为现有路由配置默认超时。
如果您在 OpenShift Container Platform 集群前面配置了用户管理的外部负载均衡器,请确保用户管理的外部负载均衡器的超时值高于路由的超时值。此配置可防止集群使用的网络的网络出现网络拥塞问题。
先决条件
- 您需要在运行的集群中部署了 Ingress Controller。
流程
使用
oc annotate命令,为路由添加超时:oc annotate route <route_name> \ --overwrite haproxy.router.openshift.io/timeout=<timeout><time_unit>$ oc annotate route <route_name> \ --overwrite haproxy.router.openshift.io/timeout=<timeout><time_unit>1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
- 支持的时间单位是微秒 (us)、毫秒 (ms)、秒钟 (s)、分钟 (m)、小时 (h)、或天 (d)。
以下示例在名为
myroute的路由上设置两秒的超时:oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2s
$ oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2sCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3.2. HTTP 标头配置 复制链接链接已复制到粘贴板!
OpenShift Container Platform 提供了不同的使用 HTTP 标头的方法。在设置或删除标头时,您可以使用 Ingress Controller 中的特定字段或单独的路由来修改请求和响应标头。您还可以使用路由注解设置某些标头。配置标头的各种方法在协同工作时可能会带来挑战。
您只能在 IngressController 或 Route CR 中设置或删除标头,您无法附加它们。如果使用值设置 HTTP 标头,则该值必须已完成,且在以后不需要附加。在附加标头(如 X-Forwarded-For 标头)时,请使用 spec.httpHeaders.forwardedHeaderPolicy 字段,而不是 spec.httpHeaders.actions。
1.3.2.1. 优先级顺序 复制链接链接已复制到粘贴板!
当在 Ingress Controller 和路由中修改相同的 HTTP 标头时,HAProxy 会根据它是请求还是响应标头来优先选择操作。
- 对于 HTTP 响应标头,Ingress Controller 中指定的操作会在路由中指定的操作后执行。这意味着 Ingress Controller 中指定的操作具有优先权。
- 对于 HTTP 请求标头,路由中指定的操作会在 Ingress Controller 中指定的操作后执行。这意味着路由中指定的操作具有优先权。
例如,集群管理员使用以下配置设置 X-Frame-Options 响应标头,其值为 DENY :
IngressController spec 示例
路由所有者设置 Ingress Controller 中设置的相同响应标头,但使用以下配置值 SAMEORIGIN :
Route 规格示例
当 IngressController spec 和 Route spec 都配置 X-Frame-Options 标头时,Ingress Controller 中的全局级别为这个标头设置的值将具有优先权,即使一个特定的路由允许帧。对于请求标头,Route spec 值会覆盖 IngressController spec 值。
发生这个优先级,因为 haproxy.config 文件使用以下逻辑,其中 Ingress Controller 被视为前端,单独的路由被视为后端。应用到前端配置的标头值 DENY 使用后端中设置的值 SAMEORIGIN 覆盖相同的标头:
另外,Ingress Controller 或路由中定义的任何操作都覆盖使用路由注解设置的值。
1.3.2.2. 特殊情况标头 复制链接链接已复制到粘贴板!
以下标头可能会阻止完全被设置或删除,或者在特定情况下允许:
| 标头名称 | 使用 IngressController spec 进行配置 | 使用 Route 规格进行配置 | 禁止的原因 | 使用其他方法进行配置 |
|---|---|---|---|---|
|
| 否 | 否 |
| 否 |
|
| 否 | 是 |
当使用 | 否 |
|
| 否 | 否 |
|
是: |
|
| 否 | 否 | HAProxy 集的 Cookie 用于会话跟踪,用于将客户端连接映射到特定的后端服务器。允许设置这些标头可能会影响 HAProxy 的会话关联,并限制 HAProxy 的 Cookie 的所有权。 | 是:
|
1.3.3. 在路由中设置或删除 HTTP 请求和响应标头 复制链接链接已复制到粘贴板!
出于合规的原因,您可以设置或删除某些 HTTP 请求和响应标头。您可以为 Ingress Controller 提供的所有路由或特定路由设置或删除这些标头。
例如,如果内容使用多种语言编写,您可能希望让 Web 应用程序在备用位置提供内容,即使 Ingress Controller 为路由指定的默认全局位置。
以下流程会创建一个设置 Content-Location HTTP 请求标头的路由,以便与应用程序关联的 URL https://app.example.com 定向到位置 https://app.example.com/lang/en-us。将应用程序流量定向到此位置意味着使用该特定路由的任何人都可以访问以美国英语编写的 Web 内容。
先决条件
-
已安装 OpenShift CLI(
oc)。 - 以项目管理员身份登录到 OpenShift Container Platform 集群。
- 您有一个 web 应用来公开端口,以及侦听端口流量的 HTTP 或 TLS 端点。
流程
创建一个路由定义,并将它保存到名为
app-example-route.yaml的文件中:使用 HTTP 标头指令创建路由的 YAML 定义
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用新创建的路由定义,创建到现有 Web 应用程序的路由:
oc -n app-example create -f app-example-route.yaml
$ oc -n app-example create -f app-example-route.yamlCopy to Clipboard Copied! Toggle word wrap Toggle overflow
对于 HTTP 请求标头,路由定义中指定的操作会在 Ingress Controller 中对 HTTP 请求标头执行的任何操作后执行。这意味着,路由中这些请求标头设置的任何值都将优先于 Ingress Controller 中设置的值。有关 HTTP 标头处理顺序的更多信息,请参阅 HTTP 标头配置。
1.3.4. 使用 Cookie 来保持路由有状态性 复制链接链接已复制到粘贴板!
OpenShift Container Platform 提供粘性会话,通过确保所有流量都到达同一端点来实现有状态应用程序流量。但是,如果端点 pod 以重启、扩展或更改配置的方式被终止,这种有状态性可能会消失。
OpenShift Container Platform 可以使用 Cookie 来配置会话持久性。ingress 控制器选择一个端点来处理任何用户请求,并为会话创建一个 Cookie。Cookie 在响应请求时返回,用户则通过会话中的下一请求发回 Cookie。Cookie 告知 Ingress Controller 哪个端点正在处理会话,确保客户端请求使用这个 Cookie 使请求路由到同一个 pod。
无法在 passthrough 路由上设置 Cookie,因为无法看到 HTTP 流量。相反,根据源 IP 地址计算数字,该地址决定了后端。
如果后端更改,可以将流量定向到错误的服务器,使其更不计。如果您使用负载均衡器来隐藏源 IP,则会为所有连接和流量都发送到同一 pod 设置相同的数字。
1.3.4.1. 使用 Cookie 标注路由 复制链接链接已复制到粘贴板!
您可以设置 Cookie 名称来覆盖为路由自动生成的默认名称。这样,接收路由流量的应用程序就能知道 Cookie 名称。通过删除 Cookie,它可以强制下一请求重新选择端点。结果是,如果服务器过载,该服务器会尝试从客户端中删除请求并重新分发它们。
流程
使用指定的 Cookie 名称标注路由:
oc annotate route <route_name> router.openshift.io/cookie_name="<cookie_name>"
$ oc annotate route <route_name> router.openshift.io/cookie_name="<cookie_name>"Copy to Clipboard Copied! Toggle word wrap Toggle overflow 其中:
<route_name>- 指定路由的名称。
<cookie_name>- 指定 Cookie 的名称。
例如,使用 cookie 名称
my_cookie标注路由my_route:oc annotate route my_route router.openshift.io/cookie_name="my_cookie"
$ oc annotate route my_route router.openshift.io/cookie_name="my_cookie"Copy to Clipboard Copied! Toggle word wrap Toggle overflow 在变量中捕获路由主机名:
ROUTE_NAME=$(oc get route <route_name> -o jsonpath='{.spec.host}')$ ROUTE_NAME=$(oc get route <route_name> -o jsonpath='{.spec.host}')Copy to Clipboard Copied! Toggle word wrap Toggle overflow 其中:
<route_name>- 指定路由的名称。
保存 cookie,然后访问路由:
curl $ROUTE_NAME -k -c /tmp/cookie_jar
$ curl $ROUTE_NAME -k -c /tmp/cookie_jarCopy to Clipboard Copied! Toggle word wrap Toggle overflow 使用上一个命令在连接到路由时保存的 cookie:
curl $ROUTE_NAME -k -b /tmp/cookie_jar
$ curl $ROUTE_NAME -k -b /tmp/cookie_jarCopy to Clipboard Copied! Toggle word wrap Toggle overflow
1.3.5. 特定于路由的注解 复制链接链接已复制到粘贴板!
Ingress Controller 可以为它公开的所有路由设置默认选项。单个路由可以通过在其注解中提供特定配置来覆盖这些默认设置。红帽不支持在 Operator 管理的路由中添加路由注解。
要创建带有多个源 IP 或子网的白名单,请使用以空格分隔的列表。任何其他限定类型会导致忽略列表,而不发出警告或错误消息。
| 变量 | 描述 | 默认的环境变量 |
|---|---|---|
|
|
设置负载平衡算法。可用选项为 |
passthrough 路由 使用 |
|
|
禁用使用 cookie 来跟踪相关连接。如果设置为 | |
|
| 指定一个可选的、用于此路由的 cookie。名称只能包含大写字母和小写字母、数字、"_" 和 "-"。默认为路由的内部密钥进行哈希处理。 | |
|
|
设置路由器支持的 pod 允许的最大连接数。 | |
|
|
设置 | |
|
|
限制通过同一源 IP 地址进行的并发 TCP 连接数。它接受一个数字值。 | |
|
|
限制具有相同源 IP 地址的客户端可以发出 HTTP 请求的速率。它接受一个数字值。 | |
|
|
限制具有相同源 IP 地址的客户端可以进行 TCP 连接的速率。它接受一个数字值。 | |
|
| 为路由设定服务器端超时。(TimeUnits) |
|
|
| 这个超时适用于隧道连接,如明文、边缘、重新加密或透传路由。使用明文、边缘或重新加密路由类型,此注解作为带有现有超时值的超时隧道应用。对于 passthrough 路由类型,注解优先于设置任何现有的超时值。 |
|
|
|
您可以设置 IngressController 或 ingress 配置。此注解重新部署路由器,并将 HA 代理配置为在全局后发出 haproxy |
|
|
| 为后端健康检查设定间隔。(TimeUnits) |
|
|
| 为路由设置允许列表。允许列表(allowlist)是以空格分开的 IP 地址和 CIDR 范围列表,用来代表批准的源地址。不是来自允许列表中的 IP 地址的请求会被丢弃。
在 | |
|
| 为 edge terminated 或 re-encrypt 路由设置 Strict-Transport-Security 标头。 | |
|
| 在后端中设置请求的重写路径。 | |
|
| 设置一个值来限制 cookies。数值是:
这个值仅适用于重新加密和边缘路由。如需更多信息,请参阅 SameSite cookies 文档。 | |
|
|
设置用于处理每个路由的
|
|
-
默认情况下,路由器会每 5 秒重新加载一次,它会从头重置容器集之间的平衡连接。因此,
roundrobin状态不会在重新加载后保留。当 pod 具有几乎相同的计算能力和存储容量时,此算法效果最佳。如果您的应用程序或服务会持续更改端点,例如,由于使用了 CI/CD 管道,可能会出现不平衡的结果。如果是这种情况下,可以使用不同的算法。 如果允许列表中的 IP 地址和 CIDR 范围超过 61,它们将被写入到一个独立的文件中,
haproxy.config会引用这个文件。此文件存储在/var/lib/haproxy/router/allowlists文件夹中。注意为确保地址被写入允许列表,请检查 Ingress Controller 配置文件中是否列出了 CIDR 范围的完整列表。etcd 对象大小限制了路由注解的大小。因此,它实际上是为您可以在允许列表中包含的 IP 地址和 CIDR 范围的最大数量创建一个阈值。
环境变量不能编辑。
路由器超时变量
TimeUnits 由一个数字及一个时间单位表示:us *(microseconds), ms(毫秒,默认)、s(秒)、m (分钟)、h *(小时) 、d (天)。
正则表达式是: [1-9][0-9]*(us\|ms\|s\|m\|h\|d)。
| 变量 | 默认 | Description |
|---|---|---|
|
|
| 后端上后续存活度检查之间的时长。 |
|
|
| 控制连接到路由的客户端的 TCP FIN 超时周期。如果发送到关闭连接的 FIN 在给定时间内没有回答,HAProxy 会关闭连接。如果设置为较低值,并且在路由器上使用较少的资源,则这不会产生任何损害。 |
|
|
| 客户端必须确认或发送数据的时长。 |
|
|
| 最长连接时间。 |
|
|
| 控制路由器到支持路由的 pod 的 TCP FIN 超时。 |
|
|
| 服务器必须确认或发送数据的时长。 |
|
|
| TCP 或 WebSocket 连接保持打开的时长。每当 HAProxy 重新加载时,这个超时期限都会重置。 |
|
|
|
设置等待出现新 HTTP 请求的最长时间。如果设置得太低,可能会导致浏览器和应用程序无法期望较小的
某些有效的超时值可以是某些变量的总和,而不是特定的预期超时。例如: |
|
|
| HTTP 请求传输可以花费的时间长度。 |
|
|
| 允许路由器至少执行重新加载和接受新更改的频率。 |
|
|
| 收集 HAProxy 指标的超时时间。 |
设置自定义超时的路由
- 1
- 使用 HAProxy 支持的时间单位(
us,ms,s,m,h,d)指定新的超时时间。如果没有提供时间单位,ms会被默认使用。
如果为 passthrough 路由设置的服务器端的超时值太低,则会导致 WebSocket 连接在那个路由上经常出现超时的情况。
只允许一个特定 IP 地址的路由
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10
允许多个 IP 地址的路由
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10 192.168.1.11 192.168.1.12
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10 192.168.1.11 192.168.1.12
允许 IP 地址 CIDR 网络的路由
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.0/24
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.0/24
允许 IP 地址和 IP 地址 CIDR 网络的路由
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 180.5.61.153 192.168.1.0/24 10.0.0.0/8
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 180.5.61.153 192.168.1.0/24 10.0.0.0/8
指定重写对象的路由
- 1
- 将
/设为后端请求的重写路径。
在路由上设置 haproxy.router.openshift.io/rewrite-target 注解,指定 Ingress Controller 在将请求转发到后端应用程序之前,应该使用此路由在 HTTP 请求中重写路径。与 spec.path 中指定的路径匹配的请求路径部分将替换为注解中指定的重写对象。
下表提供了在 spec.path、请求路径和重写对象的各种组合中重写行为的路径示例。
| Route.spec.path | 请求路径 | 重写目标 | 转发请求路径 |
|---|---|---|---|
| /foo | /foo | / | / |
| /foo | /foo/ | / | / |
| /foo | /foo/bar | / | /bar |
| /foo | /foo/bar/ | / | /bar/ |
| /foo | /foo | /bar | /bar |
| /foo | /foo/ | /bar | /bar/ |
| /foo | /foo/bar | /baz | /baz/bar |
| /foo | /foo/bar/ | /baz | /baz/bar/ |
| /foo/ | /foo | / | 不适用(请求路径不匹配路由路径) |
| /foo/ | /foo/ | / | / |
| /foo/ | /foo/bar | / | /bar |
haproxy.router.openshift.io/rewrite-target 中的某些特殊字符需要特殊处理,因为它们必须正确转义。请参阅下表以了解这些字符的处理方式。
| 对于字符 | 使用字符 | 注 |
|---|---|---|
| # | \# | 避免使用 #,因为它会终止重写表达式 |
| % | % 或 %% | 避免奇数序列,如 %%% |
| ‘ | \’ | 避免 ',因为它被忽略 |
所有其他有效的 URL 字符可以在不转义的情况下使用。
1.3.6. 吞吐量问题的故障排除方法 复制链接链接已复制到粘贴板!
有时,通过 OpenShift Container Platform 部署的应用程序可能会导致网络吞吐量问题,如特定服务间的延迟异常高。
如果 pod 日志没有显示造成问题的原因,请使用以下方法之一分析性能问题:
使用
ping或tcpdump等数据包分析器,分析 pod 与其节点之间的流量。例如,在每个 pod 上运行
tcpdump工具,同时重现导致问题的行为。检查两端的捕获信息,以便比较发送和接收时间戳来分析与 pod 往来的流量的延迟。如果节点接口被其他 pod、存储设备或者数据平面的流量过载,则 OpenShift Container Platform 中可能会出现延迟。tcpdump -s 0 -i any -w /tmp/dump.pcap host <podip 1> && host <podip 2>
$ tcpdump -s 0 -i any -w /tmp/dump.pcap host <podip 1> && host <podip 2>1 Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 1
podip是 pod 的 IP 地址。运行oc get pod <pod_name> -o wide命令来获取 pod 的 IP 地址。
tcpdump命令会在/tmp/dump.pcap中生成一个包含这两个 pod 间所有流量的文件。您可以在运行分析器后立即重现问题,并在问题重现完成后马上停止分析器,从而尽量减小文件的大小。您还可以使用以下方法在节点间运行数据包分析器 :tcpdump -s 0 -i any -w /tmp/dump.pcap port 4789
$ tcpdump -s 0 -i any -w /tmp/dump.pcap port 4789Copy to Clipboard Copied! Toggle word wrap Toggle overflow 使用
iperf等带宽测量工具来测量流吞吐量和 UDP 吞吐量。首先从 pod 运行该工具,然后从节点运行它,从而找到瓶颈。-
有关安装和使用
iperf的详情,请参考此红帽解决方案。
-
有关安装和使用
- 在某些情况下,因为延迟问题,集群可能会将带有路由器 pod 的节点标记为不健康。在执行操作前,使用 worker 延迟配置集调整集群等待节点状态更新的频率。
-
如果您的集群指定了较低延迟和较高延迟节点,请将 Ingress Controller 中的
spec.nodePlacement字段配置为控制路由器 pod 的放置。
1.3.7. 配置路由准入策略 复制链接链接已复制到粘贴板!
管理员和应用程序开发人员可在多个命名空间中运行具有相同域名的应用程序。这是针对多个团队开发的、在同一个主机名上公开的微服务的机构。
只有在命名空间间有信任的集群才会启用跨命名空间之间的声明,否则恶意用户可能会接管主机名。因此,默认的准入策略不允许在命名空间间声明主机名。
前提条件
- 必须具有集群管理员权限。
流程
使用以下命令编辑
ingresscontroller资源变量的.spec.routeAdmission 字段:oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=merge$ oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=mergeCopy to Clipboard Copied! Toggle word wrap Toggle overflow Ingress 控制器配置参数
spec: routeAdmission: namespaceOwnership: InterNamespaceAllowed ...spec: routeAdmission: namespaceOwnership: InterNamespaceAllowed ...Copy to Clipboard Copied! Toggle word wrap Toggle overflow 提示您还可以应用以下 YAML 来配置路由准入策略:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
如果您的 OpenShift Container Platform 集群是为 IPv4 和 IPv6 双栈网络配置的,则 OpenShift Container Platform 路由可从外部访问集群。
Ingress Controller 会自动提供具有 IPv4 和 IPv6 端点的服务,但您可以为单堆栈或双栈服务配置 Ingress Controller。
前提条件
- 您在裸机上部署了 OpenShift Container Platform 集群。
-
已安装 OpenShift CLI(
oc)。
流程
要使 Ingress Controller 为工作负载提供通过 IPv4/IPv6 的流量,您可以通过设置 ipFamilies 和 ipFamilyPolicy 字段来创建服务 YAML 文件,或通过设置
ipFamilies和ipFamilyPolicy字段来修改现有服务 YAML 文件。例如:服务 YAML 文件示例
Copy to Clipboard Copied! Toggle word wrap Toggle overflow 这些资源生成对应的
端点。Ingress Controller 现在监视endpointslices。要查看
端点,请输入以下命令:oc get endpoints
$ oc get endpointsCopy to Clipboard Copied! Toggle word wrap Toggle overflow 要查看
endpointslices,输入以下命令:oc get endpointslices
$ oc get endpointslicesCopy to Clipboard Copied! Toggle word wrap Toggle overflow