$ oc new-project hello-openshift
路由允许您在公共URL上托管您的应用程序。根据应用程序的网络安全配置,它可以是安全的或不安全的。基于HTTP的路由是不安全的路由,它使用基本的HTTP路由协议并在不安全的应用程序端口上公开服务。
以下步骤描述了如何使用hello-openshift
应用程序为例,创建一个简单的基于HTTP的路由到Web应用程序。
您已安装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
要验证您创建的route
资源,请运行以下命令
$ oc get routes -o yaml <name of resource> (1)
1 | 在此示例中,路由名为hello-openshift 。 |
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
1 | <Ingress_Domain> 是默认的入口域名。ingresses.config/cluster 对象在安装过程中创建,不能更改。如果您想指定不同的域名,可以使用appsDomain 选项指定备用集群域名。 |
||
2 | targetPort 是由此路由指向的服务选择的pod上的目标端口。
|
当您的服务需要低超时(服务级别协议 (SLA) 所需)或高超时(后端速度慢的情况)时,您可以为现有路由配置默认超时。
您需要在运行的集群上部署 Ingress 控制器。
使用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
HTTP严格传输安全(HSTS)策略是一种安全增强功能,它向浏览器客户端发出信号,表明仅允许在路由主机上使用HTTPS流量。HSTS还可以通过发出HTTPS传输所需的信号来优化Web流量,而无需使用HTTP重定向。HSTS有助于加快与网站的交互速度。
强制执行HSTS策略时,HSTS会将严格传输安全标头添加到来自站点的HTTP和HTTPS响应中。您可以使用路由中的insecureEdgeTerminationPolicy
值将HTTP重定向到HTTPS。强制执行HSTS时,客户端会在发送请求之前将所有来自HTTP URL的请求更改为HTTPS,从而无需重定向。
集群管理员可以配置HSTS执行以下操作:
按路由启用HSTS
按路由禁用HSTS
为一组域名强制执行每个域的HSTS,或将命名空间标签与域名结合使用
HSTS仅适用于安全路由(边缘终止或重新加密)。此配置对HTTP或直通路由无效。 |
HTTP严格传输安全(HSTS)在HAProxy模板中实现,并应用于具有haproxy.router.openshift.io/hsts_header
注释的边缘和重新加密路由。
您已使用具有项目管理员权限的用户登录到集群。
您已安装OpenShift CLI (oc
)。
要在路由上启用HSTS,请将haproxy.router.openshift.io/hsts_header
值添加到边缘终止或重新加密路由。您可以使用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交互一次才能获得标头。 |
要按路由禁用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的示例
|
要禁用命名空间中每个路由的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
AWS上的Red Hat OpenShift服务提供粘性会话,通过确保所有流量都命中相同的端点来启用有状态应用程序流量。但是,如果端点Pod终止(无论是通过重启、缩放还是配置更改),这种状态可能会消失。
AWS上的Red Hat OpenShift服务可以使用cookie配置会话持久性。入口控制器选择一个端点来处理任何用户请求,并为会话创建一个cookie。cookie在响应请求时返回给用户,用户在会话中的下一个请求中将cookie发回。cookie告诉入口控制器哪个端点正在处理会话,确保客户端请求使用cookie以便它们被路由到同一个Pod。
由于无法看到HTTP流量,因此无法在直通路由上设置cookie。相反,将根据源IP地址计算一个数字,该数字确定后端。 如果后端发生更改,流量可能会被定向到错误的服务器,使其粘性降低。如果您使用的是负载均衡器(它隐藏源IP),则所有连接都设置相同的数字,并且流量被发送到同一个Pod。 |
您可以设置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
基于路径的路由指定一个路径组件,可以将其与URL进行比较,这需要路由的流量基于HTTP。因此,可以使用相同的主机名提供多个路由,每个路由具有不同的路径。路由器应根据最具体的路径到最不具体的路径来匹配路由。
下表显示了示例路由及其可访问性
路由 | 与…比较时 | 是否可访问 |
---|---|---|
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 |
是(由主机匹配,而不是路由) |
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 | 路径是基于路径路由的唯一附加属性。 |
使用直通TLS时,基于路径的路由不可用,因为在这种情况下路由器不终止TLS,并且无法读取请求的内容。 |
AWS上的Red Hat OpenShift服务提供了不同的方法来处理HTTP头。在设置或删除头时,您可以使用入口控制器或单个路由中的特定字段来修改请求和响应头。您还可以使用路由注解来设置某些头。各种配置头的方法在协同工作时可能会带来挑战。
您只能在 |
当在入口控制器和路由中都修改了相同的HTTP头时,HAProxy会根据它是请求头还是响应头以某种方式优先处理操作。
对于HTTP响应头,入口控制器中指定的操作将在路由中指定的操作之后执行。这意味着入口控制器中指定的操作具有优先级。
对于HTTP请求头,路由中指定的操作将在入口控制器中指定的操作之后执行。这意味着路由中指定的操作具有优先级。
例如,集群管理员使用以下配置在入口控制器中使用值DENY
设置X-Frame-Options响应头
IngressController
规范示例apiVersion: operator.openshift.io/v1
kind: IngressController
# ...
spec:
httpHeaders:
actions:
response:
- name: X-Frame-Options
action:
type: Set
set:
value: DENY
路由所有者设置了与集群管理员在入口控制器中设置的相同的响应头,但使用以下配置使用值SAMEORIGIN
Route
规范示例apiVersion: route.openshift.io/v1
kind: Route
# ...
spec:
httpHeaders:
actions:
response:
- name: X-Frame-Options
action:
type: Set
set:
value: SAMEORIGIN
当IngressController
规范和Route
规范都在配置X-Frame-Options响应头时,即使特定路由允许框架,在入口控制器中全局级别为此头设置的值也具有优先级。对于请求头,Route
规范值会覆盖IngressController
规范值。
出现此优先级是因为haproxy.config
文件使用以下逻辑,其中入口控制器被认为是前端,各个路由被认为是后端。应用于前端配置的头值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'
此外,在入口控制器或路由中定义的任何操作都会覆盖使用路由注解设置的值。
以下头要么完全禁止设置或删除,要么在特定情况下允许
头名称 | 可以使用IngressController 规范配置 |
可以使用Route 规范配置 |
不允许的原因 | 可以使用其他方法配置 |
---|---|---|---|---|
|
否 |
否 |
|
否 |
|
否 |
是 |
当使用 |
否 |
|
否 |
否 |
|
是: |
|
否 |
否 |
HAProxy设置的cookie用于会话跟踪,以将客户端连接映射到特定的后端服务器。允许设置这些头可能会干扰HAProxy的会话亲和性并限制HAProxy对cookie的所有权。 |
是
|
出于合规性或其他原因,您可以设置或删除某些 HTTP 请求和响应头。您可以为 Ingress 控制器提供服务的所有路由或特定路由设置或删除这些头。
例如,如果您想让 Web 应用程序为特定路由提供备用位置的内容(即使 Ingress 控制器为这些路由指定了默认全局位置),则可能需要启用此功能,特别是当内容有多种语言版本时。
以下步骤创建一个设置 Content-Location HTTP 请求头的路由,以便与应用程序关联的 URL(https://app.example.com
)指向位置 https://app.example.com/lang/en-us
。将应用程序流量定向到此位置意味着任何使用该特定路由的人都访问的是美式英语编写的 Web 内容。
您已安装 OpenShift CLI(oc
)。
您已以项目管理员身份登录到 AWS 集群上的 Red Hat OpenShift Service。
您有一个 Web 应用程序,它公开一个端口和一个 HTTP 或 TLS 端点,用于侦听该端口上的流量。
创建一个路由定义并将其保存在名为 app-example-route.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)
1 | 您想对 HTTP 头执行的操作列表。 |
2 | 您想更改的头类型。在本例中,是响应头。 |
3 | 您想更改的头的名称。有关您可以设置或删除的可用头的列表,请参阅HTTP 头配置。 |
4 | 对头执行的操作类型。此字段的值可以是Set 或 Delete 。 |
5 | 设置 HTTP 头时,必须提供一个value 。该值可以是该头可用指令列表中的字符串(例如 DENY ),也可以是使用 HAProxy 的动态值语法解释的动态值。在本例中,该值设置为内容的相对位置。 |
使用新创建的路由定义创建到现有 Web 应用程序的路由。
$ oc -n app-example create -f app-example-route.yaml
对于 HTTP 请求头,路由定义中指定的操作会在 Ingress 控制器对 HTTP 请求头执行的任何操作之后执行。这意味着在路由中为这些请求头设置的任何值都将优先于在 Ingress 控制器中设置的值。有关 HTTP 头处理顺序的更多信息,请参阅HTTP 头配置。
Ingress 控制器可以为其公开的所有路由设置默认选项。单个路由可以通过在其注释中提供特定配置来覆盖其中一些默认值。Red Hat 不支持向运营商管理的路由添加路由注释。
要创建具有多个源 IP 或子网的白名单,请使用空格分隔的列表。任何其他分隔符类型都会导致忽略该列表,而不会发出警告或错误消息。 |
变量 | 描述 | 用作默认值的環境變數 |
---|---|---|
|
设置负载均衡算法。可用选项包括 |
对于直通路由,使用 |
|
禁用使用 Cookie 来跟踪相关连接。如果设置为 |
|
|
指定此路由要使用的可选 Cookie。名称必须由任意组合的大写和小写字母、数字、“_”和“-”组成。默认为路由的哈希内部密钥名称。 |
|
|
设置路由器允许从路由器到后端 Pod 的最大连接数。 |
|
|
设置 |
|
|
限制通过同一源 IP 地址进行的并发 TCP 连接数。它接受数值。 |
|
|
限制具有相同源 IP 地址的客户端可以发出 HTTP 请求的速率。它接受数值。 |
|
|
限制具有相同源 IP 地址的客户端可以进行 TCP 连接的速率。它接受数值。 |
|
|
设置路由的服务器端超时。(时间单位) |
|
|
此超时适用于隧道连接,例如通过明文、边缘、重新加密或直通路由的 WebSocket。对于明文、边缘或重新加密路由类型,此注释将作为具有现有超时值的超时隧道应用。对于直通路由类型,此注释优先于任何已设置的现有超时值。 |
|
|
您可以设置 IngressController 或 ingress config。此注释重新部署路由器并将 HA 代理配置为发出 haproxy |
|
|
设置后端健康检查的间隔。(时间单位) |
|
|
设置路由的白名单。白名单是批准的源地址的 IP 地址和 CIDR 范围的空格分隔列表。来自不在白名单中的 IP 地址的请求将被丢弃。
|
|
|
为边缘终止或重新加密路由设置严格传输安全标头。 |
|
|
设置后端上请求的重写路径。 |
|
|
设置一个值来限制 Cookie。这些值是
此值仅适用于重新加密和边缘路由。有关更多信息,请参阅SameSite Cookie 文档。 |
|
|
设置每个路由处理
|
|
如果允许列表中的 IP 地址和 CIDR 范围数量超过 61 个,则将其写入一个单独的文件,然后从haproxy.config
中引用该文件。此文件存储在var/lib/haproxy/router/whitelists
文件夹中。
要确保将地址写入允许列表,请检查 Ingress 控制器配置文件中是否列出了 CIDR 范围的完整列表。etcd 对象大小限制会限制路由批注可以有多大。因此,它会为允许列表中可以包含的 IP 地址和 CIDR 范围的最大数量设置一个阈值。 |
环境变量无法编辑。 |
TimeUnits
由一个数字后跟单位表示:us
(微秒)、ms
(毫秒,默认)、s
(秒)、m
(分钟)、h
(小时)、d
(天)。
正则表达式为:[1-9][0-9]*(us
\|ms
\|s
\|m
\|h
\|d
)。
变量 | 默认值 | 描述 |
---|---|---|
|
|
后端后续存活检查之间的时间间隔。 |
|
|
控制连接到路由的客户端的 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 。 |
将直通路由的服务器端超时值设置得太低可能会导致该路由上的 WebSocket 连接频繁超时。 |
metadata:
annotations:
haproxy.router.openshift.io/ip_whitelist: 192.168.1.10
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.0/24
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 控制器应在将请求转发到后端应用程序之前,使用此路由重写 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 |
/ |
N/A(请求路径与路由路径不匹配) |
/foo/ |
/foo/ |
/ |
/ |
/foo/ |
/foo/bar |
/ |
/bar |
haproxy.router.openshift.io/rewrite-target
中的某些特殊字符需要特殊处理,因为必须正确转义它们。请参考下表了解如何处理这些字符。
对于字符 | 使用字符 | 备注 |
---|---|---|
# |
\# |
避免使用 #,因为它会终止重写表达式 |
% |
% 或 %% |
避免使用奇数序列,例如 %%% |
‘ |
\’ |
避免使用 ‘,因为它会被忽略 |
所有其他有效的 URL 字符无需转义即可使用。
如果创建 Ingress 对象时未指定任何 TLS 配置,则 Red Hat OpenShift Service on AWS 会生成一个不安全的路由。要创建使用默认 Ingress 证书生成安全、边缘终止路由的 Ingress 对象,您可以按如下方式指定空的 TLS 配置。
您有一个要公开的服务。
您可以访问 OpenShift CLI(oc
)。
为 Ingress 对象创建一个 YAML 文件。在此示例中,该文件名为example-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
运行以下命令验证 Red Hat OpenShift Service on AWS 是否已为 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)
...
1 | 路由的名称包括 Ingress 对象的名称以及随机后缀。 |
2 | 为了使用默认证书,路由不应该指定spec.certificate 。 |
3 | 路由应该指定edge 终止策略。 |
可以在 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 密钥。 |
此注解中引用的密钥将被插入到生成的路由中。
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-----
...