第 22 章 配置路由
22.1. 路由配置
22.1.1. 创建基于 HTTP 的路由
路由允许您在公共 URL 托管应用程序。根据应用程序的网络安全配置,它可以安全或不受保护。基于 HTTP 的路由是一个不受保护的路由,它使用基本的 HTTP 路由协议,并在未安全的应用程序端口上公开服务。
以下流程描述了如何使用 hello-openshift
应用程序创建基于 HTTP 的简单路由,作为示例。
前提条件
-
已安装 OpenShift CLI(
oc
)。 - 以管理员身份登录。
- 您有一个 web 应用,用于公开端口和侦听端口上流量的 TCP 端点。
流程
运行以下命令,创建一个名为
hello-openshift
的项目:$ oc new-project hello-openshift
运行以下命令,在项目中创建 pod:
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
运行以下命令,创建名为
hello-openshift
的服务:$ oc expose pod/hello-openshift
运行以下命令,创建一个没有安全安全的路由到
hello-openshift
应用程序:$ oc expose svc hello-openshift
验证
要验证您创建的
路由
资源,请运行以下命令:$ oc get routes -o yaml <name of resource> 1
- 1
- 在本例中,路由名为
hello-openshift
。
创建的未安全路由的 YAML 定义示例
apiVersion: route.openshift.io/v1 kind: Route metadata: name: hello-openshift spec: host: hello-openshift-hello-openshift.<Ingress_Domain> 1 port: targetPort: 8080 2 to: kind: Service name: hello-openshift
22.1.2. 为 Ingress Controller 分片创建路由
通过使用路由,您可以通过 URL 托管应用程序。在这种情况下,主机名没有被设置,路由会使用子域。当您指定子域时,会自动使用公开路由的 Ingress Controller 域。对于由多个 Ingress Controller 公开路由的情况,路由由多个 URL 托管。
以下流程描述了如何为 Ingress Controller 分片创建路由,使用 hello-openshift
应用程序作为示例。
在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。
先决条件
-
已安装 OpenShift CLI(
oc
)。 - 您以项目管理员身份登录。
- 您有一个 web 应用来公开端口,以及侦听端口流量的 HTTP 或 TLS 端点。
- 您已为分片配置了 Ingress Controller。
流程
运行以下命令,创建一个名为
hello-openshift
的项目:$ oc new-project hello-openshift
运行以下命令,在项目中创建 pod:
$ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
运行以下命令,创建名为
hello-openshift
的服务:$ oc expose pod/hello-openshift
创建名为
hello-openshift-route.yaml
的路由定义:为分片创建的路由的 YAML 定义
apiVersion: route.openshift.io/v1 kind: Route metadata: labels: type: sharded 1 name: hello-openshift-edge namespace: hello-openshift spec: subdomain: hello-openshift 2 tls: termination: edge to: kind: Service name: hello-openshift
通过运行以下命令,使用
hello-openshift-route.yaml
创建到hello-openshift
应用程序的路由:$ oc -n hello-openshift create -f hello-openshift-route.yaml
验证
使用以下命令获取路由的状态:
$ oc -n hello-openshift get routes/hello-openshift-edge -o yaml
生成的
Route
资源应类似以下示例:输出示例
apiVersion: route.openshift.io/v1 kind: Route metadata: labels: type: sharded name: hello-openshift-edge namespace: hello-openshift spec: subdomain: hello-openshift tls: termination: edge to: kind: Service name: hello-openshift status: ingress: - host: hello-openshift.<apps-sharded.basedomain.example.net> 1 routerCanonicalHostname: router-sharded.<apps-sharded.basedomain.example.net> 2 routerName: sharded 3
22.1.3. 配置路由超时
如果您的服务需要低超时(满足服务级别可用性 (SLA) 目的)或高超时(具有慢速后端的情况),您可以为现有路由配置默认超时。
前提条件
- 您需要在运行的集群中部署了 Ingress Controller。
流程
使用
oc annotate
命令,为路由添加超时:$ oc annotate route <route_name> \ --overwrite haproxy.router.openshift.io/timeout=<timeout><time_unit> 1
- 1
- 支持的时间单位是微秒 (us)、毫秒 (ms)、秒钟 (s)、分钟 (m)、小时 (h)、或天 (d)。
以下示例在名为
myroute
的路由上设置两秒的超时:$ oc annotate route myroute --overwrite haproxy.router.openshift.io/timeout=2s
22.1.4. HTTP 严格传输安全性
HTTP 严格传输安全性 (HSTS) 策略是一种安全增强,向浏览器客户端发送信号,表示路由主机上仅允许 HTTPS 流量。HSTS 也通过信号 HTTPS 传输来优化 Web 流量,无需使用 HTTP 重定向。HSTS 对于加快与网站的交互非常有用。
强制 HSTS 策略时,HSTS 会向站点的 HTTP 和 HTTPS 响应添加 Strict Transport Security 标头。您可以在路由中使用 insecureEdgeTerminationPolicy
值,以将 HTTP 重定向到 HTTPS。强制 HSTS 时,客户端会在发送请求前将所有请求从 HTTP URL 更改为 HTTPS,无需重定向。
集群管理员可将 HSTS 配置为执行以下操作:
- 根据每个路由启用 HSTS
- 根据每个路由禁用 HSTS
- 对一组域强制每个域的 HSTS,或者结合使用命名空间标签与域
HSTS 仅适用于安全路由,可以是 edge-terminated 或 re-encrypt。其配置在 HTTP 或传递路由上无效。
22.1.4.1. 根据每个路由启用 HTTP 严格传输安全性
HTTP 严格传输安全 (HSTS) 实施在 HAProxy 模板中,并应用到具有 haproxy.router.openshift.io/hsts_header
注解的边缘和重新加密路由。
前提条件
- 您可以使用具有项目的管理员特权的用户登陆到集群。
-
已安装 OpenShift CLI(
oc
)。
流程
要在路由上启用 HSTS,请将
haproxy.router.openshift.io/hsts_header
值添加到 edge-terminated 或 re-encrypt 路由中。您可以运行以下命令来使用oc annotate
工具来实现此目的:$ oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000;\ 1 includeSubDomains;preload"
- 1
- 在本例中,最长期限设置为
31536000
ms,大约为 8.5 小时。
注意在这个示例中,等号 (
=
) 包括在引号里。这是正确执行注解命令所必需的。配置了注解的路由示例
apiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload 1 2 3 ... spec: host: def.abc.com tls: termination: "reencrypt" ... wildcardPolicy: "Subdomain"
- 1
- 必需。
Max-age
测量 HSTS 策略生效的时间长度,以秒为单位。如果设置为0
,它将对策略进行求反。 - 2
- 可选。包含时,
includeSubDomains
告知客户端主机的所有子域都必须与主机具有相同的 HSTS 策略。 - 3
- 可选。当
max-age
大于 0 时,您可以在haproxy.router.openshift.io/hsts_header
中添加preload
,以允许外部服务将这个站点包括在 HSTS 预加载列表中。例如,Google 等站点可以构造设有preload
的站点的列表。浏览器可以使用这些列表来确定哪些站点可以通过 HTTPS 通信,即使它们与站点交互之前也是如此。如果没有设置preload
,浏览器必须已经通过 HTTPS 与站点交互(至少一次)才能获取标头。
22.1.4.2. 根据每个路由禁用 HTTP 严格传输安全性
要禁用 HTTP 严格传输安全性 (HSTS),您可以将路由注解中的 max-age
值设置为 0
。
前提条件
- 您可以使用具有项目的管理员特权的用户登陆到集群。
-
已安装 OpenShift CLI(
oc
)。
流程
要禁用 HSTS,请输入以下命令将路由注解中的
max-age
值设置为0
:$ oc annotate route <route_name> -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
提示您还可以应用以下 YAML 来创建配置映射:
根据每个路由禁用 HSTS 的示例
metadata: annotations: haproxy.router.openshift.io/hsts_header: max-age=0
要为命名空间中的所有路由禁用 HSTS,请输入以下命令:
$ oc annotate route --all -n <namespace> --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=0"
验证
要查询所有路由的注解,请输入以下命令:
$ oc get route --all-namespaces -o go-template='{{range .items}}{{if .metadata.annotations}}{{$a := index .metadata.annotations "haproxy.router.openshift.io/hsts_header"}}{{$n := .metadata.name}}{{with $a}}Name: {{$n}} HSTS: {{$a}}{{"\n"}}{{else}}{{""}}{{end}}{{end}}{{end}}'
输出示例
Name: routename HSTS: max-age=0
22.1.4.3. 强制每个域 HTTP 严格传输安全性
要为安全路由强制实施 HTTP Strict Transport Security (HSTS),在 Ingress spec 中添加 requiredHSTSPolicies
记录来捕获 HSTS 策略的配置。
如果您将 requiredHSTSPolicy
配置为强制 HSTS,则任何新创建的路由都必须配置有兼容的 HSTS 策略注解。
要使用不合规的 HSTS 路由处理升级的集群,您可以在源更新清单并应用更新。
您无法使用 oc expose route
或 oc create route
命令在强制 HSTS 的域中添加路由,因为这些命令的 API 不接受注解。
HSTS 无法应用到不安全或非 TLS 路由,即使 HSTS 全局请求了 HSTS。
先决条件
- 您可以使用具有项目的管理员特权的用户登陆到集群。
-
已安装 OpenShift CLI(
oc
)。
流程
运行以下命令来编辑 Ingress 配置 YAML,并根据需要更新字段:
$ oc edit ingresses.config.openshift.io/cluster
HSTS 策略示例
apiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster spec: domain: 'hello-openshift-default.apps.username.devcluster.openshift.com' requiredHSTSPolicies: 1 - domainPatterns: 2 - '*hello-openshift-default.apps.username.devcluster.openshift.com' - '*hello-openshift-default2.apps.username.devcluster.openshift.com' namespaceSelector: 3 matchLabels: myPolicy: strict maxAge: 4 smallestMaxAge: 1 largestMaxAge: 31536000 preloadPolicy: RequirePreload 5 includeSubDomainsPolicy: RequireIncludeSubDomains 6 - domainPatterns: - 'abc.example.com' - '*xyz.example.com' namespaceSelector: matchLabels: {} maxAge: {} preloadPolicy: NoOpinion includeSubDomainsPolicy: RequireNoIncludeSubDomains
- 1
- 必需。
requiredHSTSPolicies
会被按顺序验证,并应用第一个匹配的domainPatterns
。 - 2
- 必需。您必须至少指定一个
domainPatterns
主机名。可以列出任意数量的域。您可以为不同的domainPatterns
包括多个强制选项部分。 - 3
- 可选。如果包含
namespaceSelector
,它必须与路由所在项目的标签匹配,以便在路由上强制执行设定 HSTS 策略。仅与namespaceSelector
而不是domainPatterns
匹配的路由不会被验证。 - 4
- 必需。
Max-age
测量 HSTS 策略生效的时间长度,以秒为单位。此策略设置允许强制实施最小和最大的max-age
。-
largestMaxAge
值必须在0
到2147483647
之间。它可以不指定,这意味着不强制实施上限。 -
smallestMaxAge
值必须在0
到2147483647
之间。输入0
来禁用 HSTS 以进行故障排除,或者如果您不需要禁用 HSTS,输入1
。它可以不知道,这意味着不强制实施较低限制。
-
- 5
- 可选。在
haproxy.router.openshift.io/hsts_header
中包含preload
会使外部服务将此站点包括在 HSTS 预加载列表中。浏览器可以使用这些列表来决定哪些站点可通过 HTTPS 进行通信,然后再与站点交互。如果没有设置preload
,浏览器需要至少与站点交互一次,才能获取该标头。可使用以下方法之一设置preload
:-
RequirePreload
:RequiredHSTSPolicy
需要preload
。 -
RequireNoPreload
:preload
被RequiredHSTSPolicy
禁止。 -
NoOpinion
:preload
与RequiredHSTSPolicy
没有关系。
-
- 6
- 可选。
includeSubDomainsPolicy
可使用以下之一设置:-
RequireIncludeSubDomains
:RequiredHSTSPolicy
需要includeSubDomains
。 -
RequireNoIncludeSubDomains
:includeSubDomains
被RequiredHSTSPolicy
禁止。 -
NoOpinion
:includeSubDomains
与RequiredHSTSPolicy
没有关系。
-
您可以通过输入
oc annotate command
,将 HSTS 应用到集群或特定命名空间中的所有路由。要将 HSTS 应用到集群中的所有路由,请输入
oc annotate command
。例如:$ oc annotate route --all --all-namespaces --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000"
要将 HSTS 应用到特定命名空间中的所有路由,请输入
oc annotate command
。例如:$ oc annotate route --all -n my-namespace --overwrite=true "haproxy.router.openshift.io/hsts_header"="max-age=31536000"
验证
您可以查看您配置的 HSTS 策略。例如:
要查看所需的 HSTS 策略的
maxAge
设置,请输入以下命令:$ oc get clusteroperator/ingress -n openshift-ingress-operator -o jsonpath='{range .spec.requiredHSTSPolicies[*]}{.spec.requiredHSTSPolicies.maxAgePolicy.largestMaxAge}{"\n"}{end}'
要查看所有路由上的 HSTS 注解,请输入以下命令:
$ oc get route --all-namespaces -o go-template='{{range .items}}{{if .metadata.annotations}}{{$a := index .metadata.annotations "haproxy.router.openshift.io/hsts_header"}}{{$n := .metadata.name}}{{with $a}}Name: {{$n}} HSTS: {{$a}}{{"\n"}}{{else}}{{""}}{{end}}{{end}}{{end}}'
输出示例
Name: <_routename_> HSTS: max-age=31536000;preload;includeSubDomains
22.1.5. 吞吐量问题的故障排除方法
有时,通过 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> 1
- 1
podip
是 pod 的 IP 地址。运行oc get pod <pod_name> -o wide
命令来获取 pod 的 IP 地址。
tcpdump
命令会在/tmp/dump.pcap
中生成一个包含这两个 pod 间所有流量的文件。您可以在运行分析器后立即重现问题,并在问题重现完成后马上停止分析器,从而尽量减小文件的大小。您还可以通过以下命令,在节点之间运行数据包分析器(从考量范围中剔除 SDN):$ tcpdump -s 0 -i any -w /tmp/dump.pcap port 4789
使用
iperf
等带宽测量工具来测量流吞吐量和 UDP 吞吐量。首先从 pod 运行该工具,然后从节点运行它,从而找到瓶颈。-
有关安装和使用
iperf
的详情,请参考此红帽解决方案。
-
有关安装和使用
- 在某些情况下,因为延迟问题,集群可能会将带有路由器 pod 的节点标记为不健康。在执行操作前,使用 worker 延迟配置集调整集群等待节点状态更新的频率。
-
如果您的集群指定了较低延迟和较高延迟节点,请将 Ingress Controller 中的
spec.nodePlacement
字段配置为控制路由器 pod 的放置。
22.1.6. 使用 Cookie 来保持路由有状态性
OpenShift Container Platform 提供粘性会话,通过确保所有流量都到达同一端点来实现有状态应用程序流量。但是,如果端点 pod 以重启、扩展或更改配置的方式被终止,这种有状态性可能会消失。
OpenShift Container Platform 可以使用 Cookie 来配置会话持久性。ingress 控制器选择一个端点来处理任何用户请求,并为会话创建一个 Cookie。Cookie 在响应请求时返回,用户则通过会话中的下一请求发回 Cookie。Cookie 告知 Ingress Controller 哪个端点正在处理会话,确保客户端请求使用这个 Cookie 使请求路由到同一个 pod。
无法在 passthrough 路由上设置 Cookie,因为无法看到 HTTP 流量。相反,根据源 IP 地址计算数字,该地址决定了后端。
如果后端更改,可以将流量定向到错误的服务器,使其更不计。如果您使用负载均衡器来隐藏源 IP,则会为所有连接和流量都发送到同一 pod 设置相同的数字。
22.1.6.1. 使用 Cookie 标注路由
您可以设置 Cookie 名称来覆盖为路由自动生成的默认名称。这样,接收路由流量的应用程序就能知道 Cookie 名称。通过删除 Cookie,它可以强制下一请求重新选择端点。结果是,如果服务器过载,该服务器会尝试从客户端中删除请求并重新分发它们。
流程
使用指定的 Cookie 名称标注路由:
$ oc annotate route <route_name> router.openshift.io/cookie_name="<cookie_name>"
其中:
<route_name>
- 指定路由的名称。
<cookie_name>
- 指定 Cookie 的名称。
例如,使用 cookie 名称
my_cookie
标注路由my_route
:$ oc annotate route my_route router.openshift.io/cookie_name="my_cookie"
在变量中捕获路由主机名:
$ ROUTE_NAME=$(oc get route <route_name> -o jsonpath='{.spec.host}')
其中:
<route_name>
- 指定路由的名称。
保存 cookie,然后访问路由:
$ curl $ROUTE_NAME -k -c /tmp/cookie_jar
使用上一个命令在连接到路由时保存的 cookie:
$ curl $ROUTE_NAME -k -b /tmp/cookie_jar
22.1.7. 基于路径的路由
基于路径的路由指定了一个路径组件,可以与 URL 进行比较,该 URL 需要基于 HTTP 的路由流量。因此,可以使用同一主机名提供多个路由,每个主机名都有不同的路径。路由器应该匹配基于最具体路径的路由。
下表显示了路由及其可访问性示例:
Route(路由) | 当比较到 | 可访问 |
---|---|---|
www.example.com/test | www.example.com/test | 是 |
www.example.com | 否 | |
www.example.com/test 和 www.example.com | www.example.com/test | 是 |
www.example.com | 是 | |
www.example.com | www.example.com/text | yes(由主机匹配,而不是路由) |
www.example.com | 是 |
带有路径的未安全路由
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: route-unsecured
spec:
host: www.example.com
path: "/test" 1
to:
kind: Service
name: service-name
- 1
- 该路径是基于路径的路由的唯一添加属性。
使用 passthrough TLS 时,基于路径的路由不可用,因为路由器不会在这种情况下终止 TLS,且无法读取请求的内容。
22.1.8. HTTP 标头配置
OpenShift Container Platform 提供了不同的使用 HTTP 标头的方法。在设置或删除标头时,您可以使用 Ingress Controller 中的特定字段或单独的路由来修改请求和响应标头。您还可以使用路由注解设置某些标头。配置标头的各种方法在协同工作时可能会带来挑战。
您只能在 IngressController
或 Route
CR 中设置或删除标头,您无法附加它们。如果使用值设置 HTTP 标头,则该值必须已完成,且在以后不需要附加。在附加标头(如 X-Forwarded-For 标头)时,请使用 spec.httpHeaders.forwardedHeaderPolicy
字段,而不是 spec.httpHeaders.actions
。
22.1.8.1. 优先级顺序
当在 Ingress Controller 和路由中修改相同的 HTTP 标头时,HAProxy 会根据它是请求还是响应标头来优先选择操作。
- 对于 HTTP 响应标头,Ingress Controller 中指定的操作会在路由中指定的操作后执行。这意味着 Ingress Controller 中指定的操作具有优先权。
- 对于 HTTP 请求标头,路由中指定的操作会在 Ingress Controller 中指定的操作后执行。这意味着路由中指定的操作具有优先权。
例如,集群管理员使用以下配置设置 X-Frame-Options 响应标头,其值为 DENY
:
IngressController
spec 示例
apiVersion: operator.openshift.io/v1 kind: IngressController # ... spec: httpHeaders: actions: response: - name: X-Frame-Options action: type: Set set: value: DENY
路由所有者设置 Ingress Controller 中设置的相同响应标头,但使用以下配置值 SAMEORIGIN
:
Route
规格示例
apiVersion: route.openshift.io/v1 kind: Route # ... spec: httpHeaders: actions: response: - name: X-Frame-Options action: type: Set set: value: SAMEORIGIN
当 IngressController
spec 和 Route
spec 都配置 X-Frame-Options 标头时,Ingress Controller 中的全局级别为这个标头设置的值将具有优先权,即使一个特定的路由允许帧。对于请求标头,Route
spec 值会覆盖 IngressController
spec 值。
发生这个优先级,因为 haproxy.config
文件使用以下逻辑,其中 Ingress Controller 被视为前端,单独的路由被视为后端。应用到前端配置的标头值 DENY
使用后端中设置的值 SAMEORIGIN
覆盖相同的标头:
frontend public http-response set-header X-Frame-Options 'DENY' frontend fe_sni http-response set-header X-Frame-Options 'DENY' frontend fe_no_sni http-response set-header X-Frame-Options 'DENY' backend be_secure:openshift-monitoring:alertmanager-main http-response set-header X-Frame-Options 'SAMEORIGIN'
另外,Ingress Controller 或路由中定义的任何操作都覆盖使用路由注解设置的值。
22.1.8.2. 特殊情况标头
以下标头可能会阻止完全被设置或删除,或者在特定情况下允许:
标头名称 | 使用 IngressController spec 进行配置 | 使用 Route 规格进行配置 | 禁止的原因 | 使用其他方法进行配置 |
---|---|---|---|---|
| 否 | 否 |
| 否 |
| 否 | 是 |
当使用 | 否 |
| 否 | 否 |
|
是: |
| 否 | 否 | HAProxy 集的 Cookie 用于会话跟踪,用于将客户端连接映射到特定的后端服务器。允许设置这些标头可能会影响 HAProxy 的会话关联,并限制 HAProxy 的 Cookie 的所有权。 | 是:
|
22.1.9. 在路由中设置或删除 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 定义
apiVersion: route.openshift.io/v1 kind: Route # ... spec: host: app.example.com tls: termination: edge to: kind: Service name: app-example httpHeaders: actions: 1 response: 2 - name: Content-Location 3 action: type: Set 4 set: value: /lang/en-us 5
使用新创建的路由定义,创建到现有 Web 应用程序的路由:
$ oc -n app-example create -f app-example-route.yaml
对于 HTTP 请求标头,路由定义中指定的操作会在 Ingress Controller 中对 HTTP 请求标头执行的任何操作后执行。这意味着,路由中这些请求标头设置的任何值都将优先于 Ingress Controller 中设置的值。有关 HTTP 标头处理顺序的更多信息,请参阅 HTTP 标头配置。
22.1.10. 特定于路由的注解
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 文档。 | |
|
设置用于处理每个路由的
|
|
如果允许列表中的 IP 地址和 CIDR 范围超过 61,它们将被写入到一个独立的文件中,
haproxy.config
会引用这个文件。此文件存储在var/lib/haproxy/router/whitelists
文件夹中。注意为确保地址被写入允许列表,请检查 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 指标的超时时间。 |
设置自定义超时的路由
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/timeout: 5500ms 1
...
- 1
- 使用 HAProxy 支持的时间单位(
us
,ms
,s
,m
,h
,d
)指定新的超时时间。如果没有提供时间单位,ms
会被默认使用。
如果为 passthrough 路由设置的服务器端的超时值太低,则会导致 WebSocket 连接在那个路由上经常出现超时的情况。
只允许一个特定 IP 地址的路由
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
允许 IP 地址 CIDR 网络的路由
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
指定重写对象的路由
apiVersion: route.openshift.io/v1
kind: Route
metadata:
annotations:
haproxy.router.openshift.io/rewrite-target: / 1
...
- 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 字符可以在不转义的情况下使用。
22.1.11. 配置路由准入策略
管理员和应用程序开发人员可在多个命名空间中运行具有相同域名的应用程序。这是针对多个团队开发的、在同一个主机名上公开的微服务的机构。
只有在命名空间间有信任的集群才会启用跨命名空间之间的声明,否则恶意用户可能会接管主机名。因此,默认的准入策略不允许在命名空间间声明主机名。
先决条件
- 必须具有集群管理员权限。
流程
使用以下命令编辑
ingresscontroller
资源变量的.spec.
routeAdmission 字段:$ oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=merge
Ingress 控制器配置参数
spec: routeAdmission: namespaceOwnership: InterNamespaceAllowed ...
提示您还可以应用以下 YAML 来配置路由准入策略:
apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: routeAdmission: namespaceOwnership: InterNamespaceAllowed
22.1.12. 通过 Ingress 对象创建路由
一些生态系统组件与 Ingress 资源集成,但与路由资源不集成。要涵盖此问题单,OpenShift Container Platform 会在创建 Ingress 对象时自动创建受管路由对象。当相应 Ingress 对象被删除时,这些路由对象会被删除。
流程
在 OpenShift Container Platform 控制台中或通过
oc create
命令来定义 Ingress 对象:Ingress 的 YAML 定义
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: frontend annotations: route.openshift.io/termination: "reencrypt" 1 route.openshift.io/destination-ca-certificate-secret: secret-ca-cert 2 spec: rules: - host: www.example.com 3 http: paths: - backend: service: name: frontend port: number: 443 path: / pathType: Prefix tls: - hosts: - www.example.com secretName: example-com-tls-certificate
- 1
route.openshift.io/termination
注解可用于配置Route
的spec.tls.termination
字段,因为Ingress
没有此字段。可接受的值为edge
、passthrough
和reencrypt
。所有其他值都会被静默忽略。当注解值未设置时,edge
是默认路由。模板文件中必须定义 TLS 证书详细信息,才能实现默认的边缘路由。- 3
- 在使用
Ingress
对象时,您必须指定一个显式主机名,这与使用路由时不同。您可以使用<host_name>.<cluster_ingress_domain>
语法(如apps.openshiftdemos.com
)以利用*.<cluster_ingress_domain>
通配符 DNS 记录,为集群提供证书。否则,您必须确保有一个用于所选主机名的 DNS 记录。如果您在
route.openshift.io/termination
注解中指定passthrough
值,在 spec 中将path
设置为''
,将pathType
设置为ImplementationSpecific
:spec: rules: - host: www.example.com http: paths: - path: '' pathType: ImplementationSpecific backend: service: name: frontend port: number: 443
$ oc apply -f ingress.yaml
- 2
route.openshift.io/destination-ca-certificate-secret
可用于 Ingress 对象来定义带有自定义目的地证书(CA)的路由。该注解引用一个 kubernetes secret,secret-ca-cert
将插入到生成的路由中。-
要从 ingress 对象使用目标 CA 指定路由对象,您必须在 secret 的
data.tls.crt
specifier 中创建一个带有 PEM 编码格式的证书的kubernetes.io/tls
或Opaque
类型 secret。
-
要从 ingress 对象使用目标 CA 指定路由对象,您必须在 secret 的
列出您的路由:
$ oc get routes
结果包括一个自动生成的路由,其名称以
frontend-
开头:NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD frontend-gnztq www.example.com frontend 443 reencrypt/Redirect None
如果您检查这个路由,它会类似于:
自动生成的路由的 YAML 定义
apiVersion: route.openshift.io/v1 kind: Route metadata: name: frontend-gnztq ownerReferences: - apiVersion: networking.k8s.io/v1 controller: true kind: Ingress name: frontend uid: 4e6c59cc-704d-4f44-b390-617d879033b6 spec: host: www.example.com path: / port: targetPort: https tls: certificate: | -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- insecureEdgeTerminationPolicy: Redirect key: | -----BEGIN RSA PRIVATE KEY----- [...] -----END RSA PRIVATE KEY----- termination: reencrypt destinationCACertificate: | -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- to: kind: Service name: frontend
22.1.13. 通过 Ingress 对象使用默认证书创建路由
如果您在没有指定 TLS 配置的情况下创建 Ingress 对象,OpenShift Container Platform 会生成一个不安全的路由。要创建使用默认入口证书生成安全边缘终止路由的 Ingress 对象,您可以指定一个空的 TLS 配置,如下所示:
前提条件
- 您有一个要公开的服务。
-
您可以访问 OpenShift CLI(
oc
)。
流程
为 Ingress 对象创建 YAML 文件。在本例中,该文件名为
example-ingress.yaml
:Ingress 对象的 YAML 定义
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: frontend ... spec: rules: ... tls: - {} 1
- 1
- 使用此精确的语法指定 TLS,而不指定自定义证书。
运行以下命令来创建 Ingress 对象:
$ oc create -f example-ingress.yaml
验证
运行以下命令,验证 OpenShift Container Platform 是否为 Ingress 对象创建了预期的路由:
$ oc get routes -o yaml
输出示例
apiVersion: v1 items: - apiVersion: route.openshift.io/v1 kind: Route metadata: name: frontend-j9sdd 1 ... spec: ... tls: 2 insecureEdgeTerminationPolicy: Redirect termination: edge 3 ...
22.1.14. 在 Ingress 注解中使用目标 CA 证书创建路由
在 Ingress 对象上可以使用 route.openshift.io/destination-ca-certificate-secret
注解来定义带有自定义目标 CA 证书的路由。
前提条件
- 您可以在 PEM 编码文件中有一个证书/密钥对,其中的证书对路由主机有效。
- 您可以在 PEM 编码文件中有一个单独的 CA 证书来补全证书链。
- 您必须在 PEM 编码文件中有单独的目标 CA 证书。
- 您必须具有要公开的服务。
流程
将
route.openshift.io/destination-ca-certificate-secret
添加到 Ingress 注解中:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: frontend annotations: route.openshift.io/termination: "reencrypt" route.openshift.io/destination-ca-certificate-secret: secret-ca-cert 1 ...
- 1
- 该注解引用 kubernetes secret。
此注解中引用的机密将插入到生成的路由中。
输出示例
apiVersion: route.openshift.io/v1 kind: Route metadata: name: frontend annotations: route.openshift.io/termination: reencrypt route.openshift.io/destination-ca-certificate-secret: secret-ca-cert spec: ... tls: insecureEdgeTerminationPolicy: Redirect termination: reencrypt destinationCACertificate: | -----BEGIN CERTIFICATE----- [...] -----END CERTIFICATE----- ...
22.1.15. 为双栈网络配置 OpenShift Container Platform Ingress Controller
如果您的 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 文件示例
apiVersion: v1 kind: Service metadata: creationTimestamp: yyyy-mm-ddT00:00:00Z labels: name: <service_name> manager: kubectl-create operation: Update time: yyyy-mm-ddT00:00:00Z name: <service_name> namespace: <namespace_name> resourceVersion: "<resource_version_number>" selfLink: "/api/v1/namespaces/<namespace_name>/services/<service_name>" uid: <uid_number> spec: clusterIP: 172.30.0.0/16 clusterIPs: 1 - 172.30.0.0/16 - <second_IP_address> ipFamilies: 2 - IPv4 - IPv6 ipFamilyPolicy: RequireDualStack 3 ports: - port: 8080 protocol: TCP targetport: 8080 selector: name: <namespace_name> sessionAffinity: None type: ClusterIP status: loadbalancer: {}
这些资源生成对应的
端点
。Ingress Controller 现在监视endpointslices
。要查看
端点
,请输入以下命令:$ oc get endpoints
要查看
endpointslices
,输入以下命令:$ oc get endpointslices