7.9. 配置 Ingress Controller
7.9.1. 设置自定义默认证书
作为管理员,您可以通过创建 Secret 资源并编辑 IngressController
自定义资源 (CR),将 Ingress Controller 配置为使用自定义证书。
先决条件
- 您必须在 PEM 编码文件中有一个证书/密钥对,其中该证书由可信证书认证机构签名,或者由您在一个自定义 PKI 中配置的私有可信证书认证机构签名。
您的证书满足以下要求:
- 该证书对入口域有效。
-
证书使用
subjectAltName
扩展来指定通配符域,如*.apps.ocp4.example.com
。
您必须有一个
IngressController
CR。您可以使用默认值:$ oc --namespace openshift-ingress-operator get ingresscontrollers
输出示例
NAME AGE default 10m
如果您有中间证书,则必须将其包含在包含自定义默认证书的 secret 的 tls.crt
文件中。指定证书时指定的顺序是相关的; 在任意服务器证书后列出您的中间证书。
流程
以下步骤假定自定义证书和密钥对位于当前工作目录下的 tls.crt
和 tls.key
文件中。替换 tls.crt
和 tls.key
的实际路径名。在创建 Secret 资源并在 IngressController CR 中引用它时,您也可以将 custom-certs-default
替换成另一名称。
此操作会导致使用滚动部署策略重新部署 Ingress Controller。
使用
tls.crt
和tls.key
文件,创建在openshift-ingress
命名空间中包含自定义证书的 Secret 资源。$ oc --namespace openshift-ingress create secret tls custom-certs-default --cert=tls.crt --key=tls.key
更新 IngressController CR,以引用新的证书 Secret:
$ oc patch --type=merge --namespace openshift-ingress-operator ingresscontrollers/default \ --patch '{"spec":{"defaultCertificate":{"name":"custom-certs-default"}}}'
验证更新是否已生效:
$ echo Q |\ openssl s_client -connect console-openshift-console.apps.<domain>:443 -showcerts 2>/dev/null |\ openssl x509 -noout -subject -issuer -enddate
其中:
<domain>
- 指定集群的基域名。
输出示例
subject=C = US, ST = NC, L = Raleigh, O = RH, OU = OCP4, CN = *.apps.example.com issuer=C = US, ST = NC, L = Raleigh, O = RH, OU = OCP4, CN = example.com notAfter=May 10 08:32:45 2022 GM
提示您还可以应用以下 YAML 来设置自定义默认证书:
apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: defaultCertificate: name: custom-certs-default
证书 Secret 名称应该与用来更新 CR 的值匹配。
修改了 IngressController CR 后,Ingress Operator 将更新 Ingress Controller 的部署以使用自定义证书。
7.9.2. 删除自定义默认证书
作为管理员,您可以删除配置了 Ingress Controller 的自定义证书。
先决条件
-
您可以使用具有
cluster-admin
角色的用户访问集群。 -
已安装 OpenShift CLI(
oc
)。 - 您之前为 Ingress Controller 配置了自定义默认证书。
流程
要删除自定义证书并恢复 OpenShift Container Platform 附带的证书,请输入以下命令:
$ oc patch -n openshift-ingress-operator ingresscontrollers/default \ --type json -p $'- op: remove\n path: /spec/defaultCertificate'
集群协调新证书配置时可能会有延迟。
验证
要确认原始集群证书已被恢复,请输入以下命令:
$ echo Q | \ openssl s_client -connect console-openshift-console.apps.<domain>:443 -showcerts 2>/dev/null | \ openssl x509 -noout -subject -issuer -enddate
其中:
<domain>
- 指定集群的基域名。
输出示例
subject=CN = *.apps.<domain> issuer=CN = ingress-operator@1620633373 notAfter=May 10 10:44:36 2023 GMT
7.9.3. 自动扩展 Ingress Controller
您可以自动缩放 Ingress Controller 以动态满足路由性能或可用性要求,如提高吞吐量的要求。
以下流程提供了一个扩展默认 Ingress Controller 的示例。
先决条件
-
已安装 OpenShift CLI (
oc
)。 -
您可以使用具有
cluster-admin
角色的用户访问 OpenShift Container Platform 集群。 已安装自定义 Metrics Autoscaler Operator 和关联的 KEDA Controller。
-
您可以在 Web 控制台中使用 OperatorHub 安装 Operator。安装 Operator 后,您可以创建
KedaController
实例。
-
您可以在 Web 控制台中使用 OperatorHub 安装 Operator。安装 Operator 后,您可以创建
流程
运行以下命令,创建一个服务帐户来与 Thanos 进行身份验证:
$ oc create -n openshift-ingress-operator serviceaccount thanos && oc describe -n openshift-ingress-operator serviceaccount thanos
输出示例
Name: thanos Namespace: openshift-ingress-operator Labels: <none> Annotations: <none> Image pull secrets: thanos-dockercfg-kfvf2 Mountable secrets: thanos-dockercfg-kfvf2 Tokens: thanos-token-c422q Events: <none>
可选:使用以下命令手动创建服务帐户令牌:
重要如果您禁用
ImageRegistry
功能,或者在 Cluster Image Registry Operator 配置中禁用集成的 OpenShift 镜像 registry,则不会为每个服务帐户生成镜像 pull secret。在这种情况下,您必须执行此步骤。$ oc apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: thanos-token namespace: openshift-ingress-operator annotations: kubernetes.io/service-account.name: thanos type: kubernetes.io/service-account-token EOF
使用服务帐户的令牌,在
openshift-ingress-operator
命名空间中定义一个TriggerAuthentication
对象。运行以下命令,定义包含
secret
的 secret 变量:$ secret=$(oc get secret -n openshift-ingress-operator | grep thanos-token | head -n 1 | awk '{ print $1 }')
创建
TriggerAuthentication
对象,并将secret
变量的值传递给TOKEN
参数:$ oc process TOKEN="$secret" -f - <<EOF | oc apply -n openshift-ingress-operator -f - apiVersion: template.openshift.io/v1 kind: Template parameters: - name: TOKEN objects: - apiVersion: keda.sh/v1alpha1 kind: TriggerAuthentication metadata: name: keda-trigger-auth-prometheus spec: secretTargetRef: - parameter: bearerToken name: \${TOKEN} key: token - parameter: ca name: \${TOKEN} key: ca.crt EOF
创建并应用角色以从 Thanos 读取指标:
创建一个新角色
thanos-metrics-reader.yaml
,从 pod 和节点读取指标:thanos-metrics-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: thanos-metrics-reader namespace: openshift-ingress-operator rules: - apiGroups: - "" resources: - pods - nodes verbs: - get - apiGroups: - metrics.k8s.io resources: - pods - nodes verbs: - get - list - watch - apiGroups: - "" resources: - namespaces verbs: - get
运行以下命令来应用新角色:
$ oc apply -f thanos-metrics-reader.yaml
输入以下命令在服务帐户中添加新角色:
$ oc adm policy -n openshift-ingress-operator add-role-to-user thanos-metrics-reader -z thanos --role-namespace=openshift-ingress-operator
$ oc adm policy -n openshift-ingress-operator add-cluster-role-to-user cluster-monitoring-view -z thanos
注意只有在使用跨命名空间查询时,才需要参数
add-cluster-role-to-user
。以下步骤使用kube-metrics
命名空间中的查询,该命名空间需要此参数。创建一个新的
ScaledObject
YAML 文件ingress-autoscaler.yaml
,该文件以默认 Ingress Controller 部署为目标:ScaledObject
定义示例apiVersion: keda.sh/v1alpha1 kind: ScaledObject metadata: name: ingress-scaler namespace: openshift-ingress-operator spec: scaleTargetRef: 1 apiVersion: operator.openshift.io/v1 kind: IngressController name: default envSourceContainerName: ingress-operator minReplicaCount: 1 maxReplicaCount: 20 2 cooldownPeriod: 1 pollingInterval: 1 triggers: - type: prometheus metricType: AverageValue metadata: serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 3 namespace: openshift-ingress-operator 4 metricName: 'kube-node-role' threshold: '1' query: 'sum(kube_node_role{role="worker",service="kube-state-metrics"})' 5 authModes: "bearer" authenticationRef: name: keda-trigger-auth-prometheus
重要如果使用跨命名空间查询,您必须在
serverAddress
字段中目标端口 9091 而不是端口 9092。您还必须有升级的特权,才能从此端口读取指标。运行以下命令来应用自定义资源定义:
$ oc apply -f ingress-autoscaler.yaml
验证
运行以下命令,验证默认 Ingress Controller 是否已扩展以匹配
kube-state-metrics
查询返回的值:使用
grep
命令搜索 Ingress Controller YAML 文件以查找副本:$ oc get -n openshift-ingress-operator ingresscontroller/default -o yaml | grep replicas:
输出示例
replicas: 3
获取
openshift-ingress
项目中的 pod:$ oc get pods -n openshift-ingress
输出示例
NAME READY STATUS RESTARTS AGE router-default-7b5df44ff-l9pmm 2/2 Running 0 17h router-default-7b5df44ff-s5sl5 2/2 Running 0 3d22h router-default-7b5df44ff-wwsth 2/2 Running 0 66s
7.9.4. 扩展 Ingress Controller
手动扩展 Ingress Controller 以满足路由性能或可用性要求,如提高吞吐量的要求。oc
命令用于扩展 IngressController
资源。以下流程提供了扩展默认 IngressController
的示例。
扩展不是立刻就可以完成的操作,因为它需要时间来创建所需的副本数。
流程
查看默认
IngressController
的当前可用副本数:$ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'
输出示例
2
使用
oc patch
命令,将默认IngressController
扩展至所需的副本数。以下示例将默认IngressController
扩展至 3 个副本:$ oc patch -n openshift-ingress-operator ingresscontroller/default --patch '{"spec":{"replicas": 3}}' --type=merge
输出示例
ingresscontroller.operator.openshift.io/default patched
验证默认
IngressController
是否已扩展至您指定的副本数:$ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'
输出示例
3
提示您还可以应用以下 YAML 将 Ingress Controller 扩展为三个副本:
apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 3 1
- 1
- 如果需要不同数量的副本,请更改
replicas
值。
7.9.5. 配置 Ingress 访问日志
您可以配置 Ingress Controller 以启用访问日志。如果您的集群没有接收许多流量,那么您可以将日志记录到 sidecar。如果您的集群接收大量流量,为了避免超出日志记录堆栈的容量,或与 OpenShift Container Platform 之外的日志记录基础架构集成,您可以将日志转发到自定义 syslog 端点。您还可以指定访问日志的格式。
当不存在 Syslog 日志记录基础架构时,容器日志记录可用于在低流量集群中启用访问日志,或者在诊断 Ingress Controller 时进行简短使用。
对于访问日志可能会超过 OpenShift Logging 堆栈容量的高流量集群,或需要任何日志记录解决方案与现有 Syslog 日志记录基础架构集成的环境,则需要 syslog。Syslog 用例可能会相互重叠。
先决条件
-
以具有
cluster-admin
特权的用户身份登录。
流程
配置 Ingress 访问日志到 sidecar。
要配置 Ingress 访问日志记录,您必须使用
spec.logging.access.destination
指定一个目的地。要将日志记录指定到 sidecar 容器,您必须指定Container
spec.logging.access.destination.type
。以下示例是将日志记录到Container
目的地的 Ingress Controller 定义:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 2 logging: access: destination: type: Container
当将 Ingress Controller 配置为日志记录到 sidecar 时,Operator 会在 Ingress Controller Pod 中创建一个名为
logs
的容器:$ oc -n openshift-ingress logs deployment.apps/router-default -c logs
输出示例
2020-05-11T19:11:50.135710+00:00 router-default-57dfc6cd95-bpmk6 router-default-57dfc6cd95-bpmk6 haproxy[108]: 174.19.21.82:39654 [11/May/2020:19:11:50.133] public be_http:hello-openshift:hello-openshift/pod:hello-openshift:hello-openshift:10.128.2.12:8080 0/0/1/0/1 200 142 - - --NI 1/1/0/0/0 0/0 "GET / HTTP/1.1"
配置 Ingress 访问日志记录到 Syslog 端点。
要配置 Ingress 访问日志记录,您必须使用
spec.logging.access.destination
指定一个目的地。要将日志记录指定到 Syslog 端点目的地,您必须为spec.logging.access.destination.type
指定Syslog
。如果目的地类型是Syslog
,则必须使用spec.logging.access.destination.syslog.endpoint
指定一个目的地端点,并可使用spec.logging.access.destination.syslog.facility
指定一个工具。以下示例是将日志记录到Syslog
目的地的 Ingress Controller 定义:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 2 logging: access: destination: type: Syslog syslog: address: 1.2.3.4 port: 10514
注意Syslog
目的地端口必须是 UDP。
使用特定的日志格式配置 Ingress 访问日志。
您可以指定
spec.logging.access.httpLogFormat
来自定义日志格式。以下示例是一个 Ingress Controller 定义,它将日志记录到 IP 地址为 1.2.3.4、端口为 10514 的syslog
端点:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 2 logging: access: destination: type: Syslog syslog: address: 1.2.3.4 port: 10514 httpLogFormat: '%ci:%cp [%t] %ft %b/%s %B %bq %HM %HU %HV'
禁用 Ingress 访问日志。
要禁用 Ingress 访问日志,请保留
spec.logging
或spec.logging.access
为空:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 2 logging: access: null
允许 Ingress Controller 在使用 sidecar 时,修改 HAProxy 日志长度。
如果您使用
spec.logging.access.destination.syslog.maxLength
,请使用spec.logging.access.destination.type: Syslog
。apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 2 logging: access: destination: type: Syslog syslog: address: 1.2.3.4 maxLength: 4096 port: 10514
如果您使用
spec.logging.access.destination.container.maxLength
,请使用spec.logging.access.destination.type: Container
。apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: replicas: 2 logging: access: destination: type: Container container: maxLength: 8192
7.9.6. 设置 Ingress Controller 线程数
集群管理员可设置线程数,以增加集群可以处理的入站的连接量。您可以修补现有的 Ingress Controller 来增加线程量。
先决条件
- 以下假设您已创建了 Ingress Controller。
流程
更新 Ingress Controller 以增加线程数量:
$ oc -n openshift-ingress-operator patch ingresscontroller/default --type=merge -p '{"spec":{"tuningOptions": {"threadCount": 8}}}'
注意如果您的节点有能力运行大量资源,您可以使用与预期节点容量匹配的标签配置
spec.nodePlacement.nodeSelector
,并将spec.tuningOptions.threadCount
配置为一个适当的高值。
7.9.7. 配置 Ingress Controller 以使用内部负载均衡器
当在云平台上创建 Ingress Controller 时,Ingress Controller 默认由一个公共云负载均衡器发布。作为管理员,您可以创建一个使用内部云负载均衡器的 Ingress Controller。
如果云供应商是 Microsoft Azure,则必须至少有一个指向节点的公共负载均衡器。如果不这样做,所有节点都将丢失到互联网的出站连接。
如果要更改 IngressController
的 scope
,您可以在创建自定义资源(CR)后更改 .spec.endpointPublishingStrategy.loadBalancer.scope
参数。
图 7.1. LoadBalancer 图表
上图显示了与 OpenShift Container Platform Ingress LoadBalancerService 端点发布策略相关的以下概念:
- 您可以使用 OpenShift Ingress Controller Load Balancer 在外部使用云供应商负载均衡器或内部加载负载。
- 您可以使用负载均衡器的单个 IP 地址以及更熟悉的端口,如 8080 和 4200,如图形中所述的集群所示。
- 来自外部负载均衡器的流量定向到 pod,并由负载均衡器管理,如下节点的实例中所述。有关实现详情请查看 Kubernetes 服务文档 。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
在名为
<name>-ingress-controller.yaml
的文件中创建IngressController
自定义资源 (CR) ,如下例所示:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: namespace: openshift-ingress-operator name: <name> 1 spec: domain: <domain> 2 endpointPublishingStrategy: type: LoadBalancerService loadBalancer: scope: Internal 3
运行以下命令,创建上一步中定义的 Ingress Controller:
$ oc create -f <name>-ingress-controller.yaml 1
- 1
- 将
<name>
替换为IngressController
对象的名称。
可选:通过运行以下命令确认创建了 Ingress Controller:
$ oc --all-namespaces=true get ingresscontrollers
7.9.8. 在 GCP 上为 Ingress Controller 配置全局访问
在带有一个内部负载均衡器的 GCP 上创建的 Ingress Controller 会为服务生成一个内部 IP 地址。集群管理员可指定全局访问选项,该选项可启用同一 VPC 网络内任何区域中的客户端作为负载均衡器,以访问集群上运行的工作负载。
如需更多信息,请参阅 GCP 文档以了解全局访问。
先决条件
- 您已在 GCP 基础架构上部署了 OpenShift Container Platform 集群。
- 已将 Ingress Controller 配置为使用内部负载均衡器。
-
已安装 OpenShift CLI(
oc
)。
流程
配置 Ingress Controller 资源,以允许全局访问。
注意您还可以创建 Ingress Controller 并指定全局访问选项。
配置 Ingress Controller 资源:
$ oc -n openshift-ingress-operator edit ingresscontroller/default
编辑 YAML 文件:
clientAccess
配置为Global
的示例spec: endpointPublishingStrategy: loadBalancer: providerParameters: gcp: clientAccess: Global 1 type: GCP scope: Internal type: LoadBalancerService
- 1
- 将
gcp.clientAccess
设置为Global
。
- 保存文件以使改变生效。
运行以下命令,以验证该服务是否允许全局访问:
$ oc -n openshift-ingress edit svc/router-default -o yaml
输出显示,全局访问已为带有注解
networking.gke.io/internal-load-balancer-allow-global-access
的 GCP 启用。
7.9.9. 设置 Ingress Controller 健康检查间隔
集群管理员可以设置健康检查间隔,以定义路由器在两个连续健康检查之间等待的时间。这个值会作为所有路由的默认值进行全局应用。默认值为 5 秒。
先决条件
- 以下假设您已创建了 Ingress Controller。
流程
更新 Ingress Controller,以更改后端健康检查之间的间隔:
$ oc -n openshift-ingress-operator patch ingresscontroller/default --type=merge -p '{"spec":{"tuningOptions": {"healthCheckInterval": "8s"}}}'
注意要覆盖单个路由的
healthCheckInterval
,请使用路由注解router.openshift.io/haproxy.health.check.interval
7.9.10. 将集群的默认 Ingress Controller 配置为内部
您可以通过删除并重新它来将默认
Ingress Controller 配置为内部。
如果云供应商是 Microsoft Azure,则必须至少有一个指向节点的公共负载均衡器。如果不这样做,所有节点都将丢失到互联网的出站连接。
如果要更改 IngressController
的 scope
,您可以在创建自定义资源(CR)后更改 .spec.endpointPublishingStrategy.loadBalancer.scope
参数。
先决条件
-
安装 OpenShift CLI(
oc
)。 -
以具有
cluster-admin
特权的用户身份登录。
流程
通过删除并重新创建集群,将
默认
Ingress Controller 配置为内部。$ oc replace --force --wait --filename - <<EOF apiVersion: operator.openshift.io/v1 kind: IngressController metadata: namespace: openshift-ingress-operator name: default spec: endpointPublishingStrategy: type: LoadBalancerService loadBalancer: scope: Internal EOF
7.9.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
7.9.12. 使用通配符路由
HAProxy Ingress Controller 支持通配符路由。Ingress Operator 使用 wildcardPolicy
来配置 Ingress Controller 的 ROUTER_ALLOW_WILDCARD_ROUTES
环境变量。
Ingress Controller 的默认行为是接受采用 None
通配符策略的路由,该策略与现有 IngressController
资源向后兼容。
流程
配置通配符策略。
使用以下命令来编辑
IngressController
资源:$ oc edit IngressController
在
spec
下,将wildcardPolicy
字段设置为 WildcardsDisallowed
或WildcardsAllowed
:spec: routeAdmission: wildcardPolicy: WildcardsDisallowed # or WildcardsAllowed
7.9.13. HTTP 标头配置
OpenShift Container Platform 提供了不同的使用 HTTP 标头的方法。在设置或删除标头时,您可以使用 Ingress Controller 中的特定字段或单独的路由来修改请求和响应标头。您还可以使用路由注解设置某些标头。配置标头的各种方法在协同工作时可能会带来挑战。
您只能在 IngressController
或 Route
CR 中设置或删除标头,您无法附加它们。如果使用值设置 HTTP 标头,则该值必须已完成,且在以后不需要附加。在附加标头(如 X-Forwarded-For 标头)时,请使用 spec.httpHeaders.forwardedHeaderPolicy
字段,而不是 spec.httpHeaders.actions
。
7.9.13.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 中的全局级别为这个标头设置的值将具有优先权,即使一个特定的路由允许帧。
发生这个优先级,因为 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 或路由中定义的任何操作都覆盖使用路由注解设置的值。
7.9.13.2. 特殊情况标头
以下标头可能会阻止完全被设置或删除,或者在特定情况下允许:
标头名称 | 使用 IngressController spec 进行配置 | 使用 Route 规格进行配置 | 禁止的原因 | 使用其他方法进行配置 |
---|---|---|---|---|
| 否 | 否 |
| 否 |
| 否 | 是 |
当使用 | 否 |
| 否 | 否 |
|
是: |
| 否 | 否 | HAProxy 集的 Cookie 用于会话跟踪,用于将客户端连接映射到特定的后端服务器。允许设置这些标头可能会影响 HAProxy 的会话关联,并限制 HAProxy 的 Cookie 的所有权。 | 是:
|
7.9.14. 在 Ingress Controller 中设置或删除 HTTP 请求和响应标头
出于合规的原因,您可以设置或删除某些 HTTP 请求和响应标头。您可以为 Ingress Controller 提供的所有路由或特定路由设置或删除这些标头。
例如,您可能希望将集群中运行的应用程序迁移到使用 mutual TLS,这需要您的应用程序检查 X-Forwarded-Client-Cert 请求标头,但 OpenShift Container Platform 默认 Ingress Controller 提供了一个 X-SSL-Client-Der 请求标头。
以下流程修改 Ingress Controller 来设置 X-Forwarded-Client-Cert 请求标头,并删除 X-SSL-Client-Der 请求标头。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
您可以使用具有
cluster-admin
角色的用户访问 OpenShift Container Platform 集群。
流程
编辑 Ingress Controller 资源:
$ oc -n openshift-ingress-operator edit ingresscontroller/default
将 X-SSL-Client-Der HTTP 请求标头替换为 X-Forwarded-Client-Cert HTTP 请求标头:
apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: httpHeaders: actions: 1 request: 2 - name: X-Forwarded-Client-Cert 3 action: type: Set 4 set: value: "%{+Q}[ssl_c_der,base64]" 5 - name: X-SSL-Client-Der action: type: Delete
注意对于 HTTP 响应设置动态标头值,允许示例 fetchers 是
res.hdr
和ssl_c_der
。对于 HTTP 请求设置动态标头值,允许示例获取器为req.hdr
和ssl_c_der
。请求和响应动态值都可以使用lower
和base64
转换器。- 保存文件以使改变生效。
7.9.15. 使用 X-Forwarded 标头
您可以将 HAProxy Ingress Controller 配置为指定如何处理 HTTP 标头的策略,其中包括 Forwarded
和 X-Forwarded-For
。Ingress Operator 使用 HTTPHeaders
字段配置 Ingress Controller 的 ROUTER_SET_FORWARDED_HEADERS
环境变量。
流程
为 Ingress Controller 配置
HTTPHeaders
字段。使用以下命令来编辑
IngressController
资源:$ oc edit IngressController
在
spec
下,将HTTPHeaders
策略字段设置为Append
、Replace
、IfNone
或Never
:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: httpHeaders: forwardedHeaderPolicy: Append
使用案例示例
作为集群管理员,您可以:
配置将
X-Forwarded-For
标头注入每个请求的外部代理,然后将其转发到 Ingress Controller。要将 Ingress Controller 配置为通过未修改的标头传递,您需要指定
never
策略。然后,Ingress Controller 不会设置标头,应用程序只接收外部代理提供的标头。将 Ingress Controller 配置为通过未修改的外部代理在外部集群请求上设置
X-Forwarded-For
标头。要将 Ingress Controller 配置为在不通过外部代理的内部集群请求上设置
X-Forwarded-For
标头,请指定if-none
策略。如果 HTTP 请求已经通过外部代理设置了标头,则 Ingress Controller 会保留它。如果缺少标头,因为请求没有通过代理,Ingress Controller 会添加标头。
作为应用程序开发人员,您可以:
配置特定于应用程序的外部代理来注入
X-Forwarded-For
标头。要配置 Ingress Controller,以便在不影响其他路由策略的情况下将标头传递到应用程序的路由,请在应用程序的路由上添加注解
haproxy.router.openshift.io/set-forwarded-headers: if-none
或haproxy.router.openshift.io/set-forwarded-headers: never
。注意您可以根据每个路由设置
haproxy.router.openshift.io/set-forwarded-headers
注解,独立于 Ingress Controller 的全局设置值。
7.9.16. 启用 HTTP/2 入口连接
您可以在 HAProxy 中启用透明端到端的 HTTP/2 连接。此功能使应用程序所有者利用 HTTP/2 协议功能,包括单一连接、标头压缩、二 进制流等等。
您可以为单独的 Ingress Controller 或整个集群启用 HTTP/2 连接。
要在从客户端到 HAProxy 的连接中启用 HTTP/2,路由必须指定一个自定义证书。使用默认证书的路由无法使用 HTTP/2。这一限制是避免连接并发问题(如客户端为使用相同证书的不同路由重新使用连接)所必需的。
从 HAProxy 到应用程序 pod 的连接只能将 HTTP/2 用于 re-encrypt 路由,而不适用于 edge-terminated 或 insecure 路由。存在这个限制的原因是,在与后端协商使用 HTTP/2 时,HAProxy 要使用 ALPN(Application-Level Protocol Negotiation),它是一个 TLS 的扩展。这意味着,端到端的 HTTP/2 适用于 passthrough 和 re-encrypt 路由,而不适用于 nsecure 或 edge-terminated 路由。
对于非 passthrough 路由,Ingress Controller 会独立于客户端的连接来协商它与应用程序的连接。这意味着,客户端可以连接到 Ingress Controller 并协商 HTTP/1.1,Ingress Controller 可连接到应用程序,协商 HTTP/2 并使用 HTTP/2 连接将客户端 HTTP/1.1 连接转发请求。如果客户端随后试图将其连接从 HTTP/1.1 升级到 WebSocket 协议,这会导致问题。因为 Ingress Controller 无法将 WebSocket 转发到 HTTP/2,也无法将其 HTTP/2 的连接升级到 WebSocket。因此,如果您有一个应用程序旨在接受 WebSocket 连接,则必须允许使用 HTTP/2 协议,或者其它客户端将无法升级到 WebSocket 协议。
流程
在单一 Ingress Controller 上启用 HTTP/2。
要在 Ingress Controller 上启用 HTTP/2,请输入
oc annotate
命令:$ oc -n openshift-ingress-operator annotate ingresscontrollers/<ingresscontroller_name> ingress.operator.openshift.io/default-enable-http2=true
将
<ingresscontroller_name>
替换为要注解的 Ingress Controller 的名称。
在整个集群中启用 HTTP/2。
要为整个集群启用 HTTP/2,请输入
oc annotate
命令:$ oc annotate ingresses.config/cluster ingress.operator.openshift.io/default-enable-http2=true
提示您还可以应用以下 YAML 来添加注解:
apiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster annotations: ingress.operator.openshift.io/default-enable-http2: "true"
7.9.17. 为 Ingress Controller 配置 PROXY 协议
当 Ingress Controller 使用 HostNetwork
、NodePortService
或 Private
端点发布策略类型时,集群管理员可以配置 PROXY 协议。PROXY 协议使负载均衡器能够为 Ingress Controller 接收的连接保留原始客户端地址。原始客户端地址可用于记录、过滤和注入 HTTP 标头。在默认配置中,Ingress Controller 接收的连接只包含与负载均衡器关联的源地址。
使用 Keepalived Ingress Virtual IP (VIP) 在非云平台上带有安装程序置备的集群的默认 Ingress Controller 不支持 PROXY 协议。
PROXY 协议使负载均衡器能够为 Ingress Controller 接收的连接保留原始客户端地址。原始客户端地址可用于记录、过滤和注入 HTTP 标头。在默认配置中,Ingress Controller 接收的连接只包含与负载均衡器关联的源 IP 地址。
对于 passthrough 路由配置,OpenShift Container Platform 集群中的服务器无法观察原始客户端源 IP 地址。如果您需要知道原始客户端源 IP 地址,请为 Ingress Controller 配置 Ingress 访问日志记录,以便您可以查看客户端源 IP 地址。
对于重新加密和边缘路由,OpenShift Container Platform 路由器设置 Forwarded
和 X-Forwarded-For
标头,以便应用程序工作负载检查客户端源 IP 地址。
如需有关 Ingress 访问日志的更多信息,请参阅"配置 Ingress 访问日志"。
使用 LoadBalancerService
端点发布策略类型时不支持为 Ingress Controller 配置 PROXY 协议。具有这个限制的原因是,当 OpenShift Container Platform 在云平台中运行时,IngressController 指定应使用服务负载均衡器,Ingress Operator 会配置负载均衡器服务,并根据保留源地址的平台要求启用 PROXY 协议。
您必须将 OpenShift Container Platform 和外部负载均衡器配置为使用 PROXY 协议或使用 TCP。
云部署不支持此功能。具有这个限制的原因是,当 OpenShift Container Platform 在云平台中运行时,IngressController 指定应使用服务负载均衡器,Ingress Operator 会配置负载均衡器服务,并根据保留源地址的平台要求启用 PROXY 协议。
您必须将 OpenShift Container Platform 和外部负载均衡器配置为使用 PROXY 协议或使用传输控制协议 (TCP)。
先决条件
- 已创建一个 Ingress Controller。
流程
在 CLI 中输入以下命令来编辑 Ingress Controller 资源:
$ oc -n openshift-ingress-operator edit ingresscontroller/default
设置 PROXY 配置:
如果您的 Ingress Controller 使用
HostNetwork
端点发布策略类型,请将spec.endpointPublishingStrategy.hostNetwork.protocol
子字段设置为PROXY
:hostNetwork
配置为PROXY
的示例# ... spec: endpointPublishingStrategy: hostNetwork: protocol: PROXY type: HostNetwork # ...
如果您的 Ingress Controller 使用
NodePortService
端点发布策略类型,请将spec.endpointPublishingStrategy.nodePort.protocol
子字段设置为PROXY
:nodePort
配置为PROXY
示例# ... spec: endpointPublishingStrategy: nodePort: protocol: PROXY type: NodePortService # ...
如果您的 Ingress Controller 使用
Private
端点发布策略类型,请将spec.endpointPublishingStrategy.private.protocol
子字段设置为PROXY
:到
PROXY
的私有
配置示例# ... spec: endpointPublishingStrategy: private: protocol: PROXY type: Private # ...
其他资源
7.9.18. 使用 appsDomain 选项指定备选集群域
作为集群管理员,您可以通过配置 appsDomain
字段来为用户创建的路由指定默认集群域替代内容。appsDomain
字段是 OpenShift Container Platform 使用的可选域,而不是默认值,它在 domain
字段中指定。如果您指定了其它域,它会覆盖为新路由确定默认主机的目的。
例如,您可以将您公司的 DNS 域用作集群中运行的应用程序的路由和入口的默认域。
先决条件
- 已部署 OpenShift Container Platform 集群。
-
已安装
oc
命令行界面。
流程
通过为用户创建的路由指定备选默认域来配置
appsDomain
字段。编辑 ingress
集群
资源 :$ oc edit ingresses.config/cluster -o yaml
编辑 YAML 文件:
示例
appsDomain
配置为test.example.com
apiVersion: config.openshift.io/v1 kind: Ingress metadata: name: cluster spec: domain: apps.example.com 1 appsDomain: <test.example.com> 2
通过公开路由并验证路由域更改,验证现有路由是否包含
appsDomain
字段中指定的域名:注意在公开路由前,等待
openshift-apiserver
完成滚动更新。公开路由:
$ oc expose service hello-openshift route.route.openshift.io/hello-openshift exposed
输出示例:
$ oc get routes NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD hello-openshift hello_openshift-<my_project>.test.example.com hello-openshift 8080-tcp None
7.9.19. 转换 HTTP 标头的大小写
默认情况下,HAProxy HTTP 的标头名称是小写的,例如,会将 Host: xyz.com
更改为 host: xyz.com
。如果旧应用程序对 HTTP 标头名称中使用大小写敏感,请使用 Ingress Controller spec.httpHeaders.headerNameCaseAdjustments
API 字段进行调整来适应旧的应用程序,直到它们被改变。
OpenShift Container Platform 包括 HAProxy 2.6。如果要更新基于 web 的负载均衡器的这个版本,请确保将 spec.httpHeaders.headerNameCaseAdjustments
部分添加到集群的配置文件中。
作为集群管理员,您可以使用 oc patch
命令,或设置 Ingress Controller YAML 文件中的 HeaderNameCaseAdjustments
字段来转换 HTTP 标头的大小写。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
使用
oc patch
命令大写 HTTP 标头。运行以下命令,将 HTTP 标头从
host
更改为Host
:$ oc -n openshift-ingress-operator patch ingresscontrollers/default --type=merge --patch='{"spec":{"httpHeaders":{"headerNameCaseAdjustments":["Host"]}}}'
创建
Route
资源 YAML 文件,以便注解可应用到应用程序。名为
my-application
的路由示例apiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/h1-adjust-case: true 1 name: <application_name> namespace: <application_name> # ...
- 1
- 设置
haproxy.router.openshift.io/h1-adjust-case
,以便 Ingress Controller 能够调整指定的host
请求标头。
通过在 Ingress Controller YAML 配置文件中配置
HeaderNameCaseAdjustments
字段指定调整。以下示例 Ingress Controller YAML 文件将 HTTP/1 请求的
host
标头调整为Host
,以适当地注解路由:Ingress Controller YAML 示例
apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: httpHeaders: headerNameCaseAdjustments: - Host
以下示例路由中,使用
haproxy.router.openshift.io/h1-adjust-case
注解启用对 HTTP 响应标头名称的大小写调整:路由 YAML 示例
apiVersion: route.openshift.io/v1 kind: Route metadata: annotations: haproxy.router.openshift.io/h1-adjust-case: true 1 name: my-application namespace: my-application spec: to: kind: Service name: my-application
- 1
- 将
haproxy.router.openshift.io/h1-adjust-case
设置为 true。
7.9.20. 使用路由器压缩
您可以将 HAProxy Ingress Controller 配置为为特定 MIME 类型全局指定路由器压缩。您可以使用 mimeTypes
变量定义压缩应用到的 MIME 类型的格式。类型包括:application, image, message, multipart, text, video, 或带有一个 "X-" 前缀的自定义类型。要查看 MIME 类型和子类型的完整表示法,请参阅 RFC1341。
为压缩分配的内存可能会影响最大连接。此外,对大型缓冲区的压缩可能导致延迟,如非常复杂的正则表达式或较长的正则表达式列表。
并非所有 MIME 类型从压缩中受益,但 HAProxy 仍然使用资源在指示时尝试压缩。通常而言,文本格式(如 html、css 和 js)与压缩格式获益,但已经压缩的格式(如图像、音频和视频)可能会因为需要压缩操作而无法获得太多的好处。
流程
为 Ingress Controller 配置
httpCompression
字段。使用以下命令来编辑
IngressController
资源:$ oc edit -n openshift-ingress-operator ingresscontrollers/default
在
spec
下,将httpCompression
策略字段设置为mimeTypes
,并指定应该应用压缩的 MIME 类型列表:apiVersion: operator.openshift.io/v1 kind: IngressController metadata: name: default namespace: openshift-ingress-operator spec: httpCompression: mimeTypes: - "text/html" - "text/css; charset=utf-8" - "application/json" ...
7.9.21. 公开路由器指标
您可以在默认统计端口 1936 上以 Prometheus 格式公开 HAProxy 路由器指标。外部指标收集和聚合系统(如 Prometheus)可以访问 HAProxy 路由器指标。您可以在浏览器中以 HTML 的形式和以逗号分隔的值 (CSV) 格式查看 HAProxy 路由器指标。
先决条件
- 您已将防火墙配置为访问默认统计数据端口 1936。
流程
运行以下命令来获取路由器 pod 名称:
$ oc get pods -n openshift-ingress
输出示例
NAME READY STATUS RESTARTS AGE router-default-76bfffb66c-46qwp 1/1 Running 0 11h
获取路由器的用户名和密码,路由器 Pod 存储在
/var/lib/haproxy/conf/metrics-auth/statsUsername
和/var/lib/haproxy/conf/metrics-auth/statsPassword
文件中:运行以下命令来获取用户名:
$ oc rsh <router_pod_name> cat metrics-auth/statsUsername
运行以下命令来获取密码:
$ oc rsh <router_pod_name> cat metrics-auth/statsPassword
运行以下命令,获取路由器 IP 和指标证书:
$ oc describe pod <router_pod>
运行以下命令,以 Prometheus 格式获取原始统计信息:
$ curl -u <user>:<password> http://<router_IP>:<stats_port>/metrics
运行以下命令来安全地访问指标:
$ curl -u user:password https://<router_IP>:<stats_port>/metrics -k
运行以下命令,访问默认的 stats 端口 1936:
$ curl -u <user>:<password> http://<router_IP>:<stats_port>/metrics
例 7.1. 输出示例
... # HELP haproxy_backend_connections_total Total number of connections. # TYPE haproxy_backend_connections_total gauge haproxy_backend_connections_total{backend="http",namespace="default",route="hello-route"} 0 haproxy_backend_connections_total{backend="http",namespace="default",route="hello-route-alt"} 0 haproxy_backend_connections_total{backend="http",namespace="default",route="hello-route01"} 0 ... # HELP haproxy_exporter_server_threshold Number of servers tracked and the current threshold value. # TYPE haproxy_exporter_server_threshold gauge haproxy_exporter_server_threshold{type="current"} 11 haproxy_exporter_server_threshold{type="limit"} 500 ... # HELP haproxy_frontend_bytes_in_total Current total of incoming bytes. # TYPE haproxy_frontend_bytes_in_total gauge haproxy_frontend_bytes_in_total{frontend="fe_no_sni"} 0 haproxy_frontend_bytes_in_total{frontend="fe_sni"} 0 haproxy_frontend_bytes_in_total{frontend="public"} 119070 ... # HELP haproxy_server_bytes_in_total Current total of incoming bytes. # TYPE haproxy_server_bytes_in_total gauge haproxy_server_bytes_in_total{namespace="",pod="",route="",server="fe_no_sni",service=""} 0 haproxy_server_bytes_in_total{namespace="",pod="",route="",server="fe_sni",service=""} 0 haproxy_server_bytes_in_total{namespace="default",pod="docker-registry-5-nk5fz",route="docker-registry",server="10.130.0.89:5000",service="docker-registry"} 0 haproxy_server_bytes_in_total{namespace="default",pod="hello-rc-vkjqx",route="hello-route",server="10.130.0.90:8080",service="hello-svc-1"} 0 ...
通过在浏览器中输入以下 URL 来启动 stats 窗口:
http://<user>:<password>@<router_IP>:<stats_port>
可选:通过在浏览器中输入以下 URL 来获取 CSV 格式的统计信息:
http://<user>:<password>@<router_ip>:1936/metrics;csv
7.9.22. 自定义 HAProxy 错误代码响应页面
作为集群管理员,您可以为 503、404 或两个错误页面指定自定义错误代码响应页面。当应用 Pod 没有运行时,HAProxy 路由器会提供一个 503 错误页面,如果请求的 URL 不存在,则 HAProxy 路由器会提供 404 错误页面。例如,如果您自定义 503 错误代码响应页面,则应用 Pod 未运行时会提供页面,并且 HAProxy 路由器为不正确的路由或不存在的路由提供默认的 404 错误代码 HTTP 响应页面。
自定义错误代码响应页面在配置映射中指定,然后修补至 Ingress Controller。配置映射键有两个可用的文件名,如下所示:error-page-503.http
和 error-page-404.http
。
自定义 HTTP 错误代码响应页面必须遵循 HAProxy HTTP 错误页面配置指南。以下是默认 OpenShift Container Platform HAProxy 路由器 http 503 错误代码响应页面的示例。您可以使用默认内容作为模板来创建自己的自定义页面。
默认情况下,当应用没有运行或者路由不正确或不存在时,HAProxy 路由器仅提供一个 503 错误页面。此默认行为与 OpenShift Container Platform 4.8 及更早版本中的行为相同。如果没有提供用于自定义 HTTP 错误代码响应的配置映射,且您使用的是自定义 HTTP 错误代码响应页面,路由器会提供默认的 404 或 503 错误代码响应页面。
如果您使用 OpenShift Container Platform 默认 503 错误代码页面作为自定义的模板,文件中的标头需要编辑器而不是使用 CRLF 行结尾。
流程
在
openshift-config
命名空间中创建一个名为my-custom-error-code-pages
的配置映射:$ oc -n openshift-config create configmap my-custom-error-code-pages \ --from-file=error-page-503.http \ --from-file=error-page-404.http
重要如果没有为自定义错误代码响应页面指定正确的格式,则会出现路由器 pod 中断。要解决此中断,您必须删除或更正配置映射并删除受影响的路由器 pod,以便使用正确的信息重新创建它们。
对 Ingress Controller 进行补丁以根据名称引用
my-custom-error-code-pages
配置映射:$ oc patch -n openshift-ingress-operator ingresscontroller/default --patch '{"spec":{"httpErrorCodePages":{"name":"my-custom-error-code-pages"}}}' --type=merge
Ingress Operator 将
my-custom-error-code-pages
配置映射从openshift-config
命名空间复制到openshift-ingress
命名空间。Operator 根据openshift-ingress
命名空间中的模式<your_ingresscontroller_name>-errorpages
命名配置映射。显示副本:
$ oc get cm default-errorpages -n openshift-ingress
输出示例
NAME DATA AGE default-errorpages 2 25s 1
- 1
- 配置映射名称示例为
default-errorpages
,因为default
Ingress Controller 自定义资源 (CR) 已被修补。
确认包含自定义错误响应页面的配置映射挂载到路由器卷中,其中配置映射键是具有自定义 HTTP 错误代码响应的文件名:
对于 503 自定义 HTTP 自定义错误代码响应:
$ oc -n openshift-ingress rsh <router_pod> cat /var/lib/haproxy/conf/error_code_pages/error-page-503.http
对于 404 自定义 HTTP 自定义错误代码响应:
$ oc -n openshift-ingress rsh <router_pod> cat /var/lib/haproxy/conf/error_code_pages/error-page-404.http
验证
验证自定义错误代码 HTTP 响应:
创建测试项目和应用程序:
$ oc new-project test-ingress
$ oc new-app django-psql-example
对于 503 自定义 http 错误代码响应:
- 停止应用的所有容器集。
运行以下 curl 命令或在浏览器中访问路由主机名:
$ curl -vk <route_hostname>
对于 404 自定义 http 错误代码响应:
- 访问不存在的路由或路由不正确。
运行以下 curl 命令或在浏览器中访问路由主机名:
$ curl -vk <route_hostname>
检查
haproxy.config
文件中的errorfile
属性是否正确:$ oc -n openshift-ingress rsh <router> cat /var/lib/haproxy/conf/haproxy.config | grep errorfile
7.9.23. 设置 Ingress Controller 最大连接数
集群管理员可以设置 OpenShift 路由器部署的最大同时连接数。您可以修补现有的 Ingress Controller 来提高最大连接数。
先决条件
- 以下假设您已创建了 Ingress Controller
流程
更新 Ingress Controller,以更改 HAProxy 的最大连接数:
$ oc -n openshift-ingress-operator patch ingresscontroller/default --type=merge -p '{"spec":{"tuningOptions": {"maxConnections": 7500}}}'
警告如果您设置了大于当前操作系统的
spec.tuningOptions.maxConnections
值,则 HAProxy 进程不会启动。有关这个参数的更多信息,请参阅"Ingress Controller 配置参数"部分中的表。