搜索

网络

download PDF
OpenShift Container Platform 4.15

配置和管理集群网络

Red Hat OpenShift Documentation Team

摘要

本文档提供有关配置和管理 OpenShift Container Platform 集群网络的说明,其中包括 DNS、Ingress 和 Pod 网络。

第 1 章 关于网络

Red Hat OpenShift 网络是一个功能生态系统、插件和高级网络功能,它使用高级网络相关功能来扩展 Kubernetes 网络,集群需要为其一个或多个混合集群管理网络流量。这个网络功能生态系统集成了入口、出口、负载均衡、高性能吞吐量、安全性和集群内部流量管理,并提供基于角色的可观察工具来减少其自然复杂性。

注意

从 OpenShift Container Platform 4.14 开始,OpenShift SDN CNI 已被弃用。自 OpenShift Container Platform 4.15 起,网络插件不是新安装的选项。在以后的发行版本中,计划删除 OpenShift SDN 网络插件,并不再被支持。红帽将在删除前对这个功能提供程序错误修正和支持,但不会再改进这个功能。作为 OpenShift SDN CNI 的替代选择,您可以使用 OVN Kubernetes CNI。

以下列表重点介绍集群中可用的一些最常用的 Red Hat OpenShift Networking 功能:

  • 由以下 Container Network Interface (CNI) 插件之一提供的主要集群网络:

  • 经认证的第三方替代主网络插件
  • 用于网络插件管理的 Cluster Network Operator
  • 用于 TLS 加密 Web 流量的 Ingress Operator
  • 用于名称分配的 DNS Operator
  • 用于裸机集群上的流量负载均衡的 MetalLB Operator
  • 对高可用性的 IP 故障转移支持
  • 通过多个 CNI 插件支持额外的硬件网络,包括 macvlan、ipvlan 和 SR-IOV 硬件网络
  • IPv4、IPv6 和双堆栈寻址
  • 用于基于 Windows 的工作负载的混合 Linux-Windows 主机集群
  • Red Hat OpenShift Service Mesh 用于发现、负载均衡、服务对服务身份验证、故障恢复、指标和监控服务
  • 单节点 OpenShift
  • Network Observability Operator 用于网络调试和见解
  • Submariner 用于 inter-cluster 网络
  • Red Hat Service Interconnect 用于第 7 层 inter-cluster 网络

第 2 章 了解网络

集群管理员有几个选项用于公开集群内的应用程序到外部流量并确保网络连接:

  • 服务类型,如节点端口或负载均衡器
  • API 资源,如 IngressRoute

默认情况下,Kubernetes 为 pod 内运行的应用分配内部 IP 地址。Pod 及其容器可以网络,但集群外的客户端无法访问网络。当您将应用公开给外部流量时,为每个容器集指定自己的 IP 地址意味着 pod 在端口分配、网络、命名、服务发现、负载平衡、应用配置和迁移方面可被视为物理主机或虚拟机。

注意

一些云平台提供侦听 169.254.169.254 IP 地址的元数据 API,它是 IPv4 169.254.0.0/16 CIDR 块中的 连接内部 IP 地址。

此 CIDR 块无法从 pod 网络访问。需要访问这些 IP 地址的 Pod 必须通过将 pod spec 中的 spec.hostnetwork 字段设置为 true 来获得主机网络访问。

如果允许 pod 主机网络访问,则将授予 pod 对底层网络基础架构的访问权限。

2.1. OpenShift Container Platform DNS

如果您运行多个服务,比如使用多个 pod 的前端和后端服务,则要为用户名和服务 IP 等创建环境变量,使前端 pod 可以跟后端服务通信。如果删除并重新创建服务,可以为该服务分配一个新的 IP 地址,而且需要重新创建前端 pod 来获取服务 IP 环境变量的更新值。另外,必须在任何前端 pod 之前创建后端服务,以确保正确生成服务 IP,并将它作为环境变量提供给前端 pod。

因此,OpenShift Container Platform 具有一个内置 DNS,以便服务 DNS 以及服务 IP/端口能够访问这些服务。

2.2. OpenShift Container Platform Ingress Operator

在创建 OpenShift Container Platform 集群时,在集群中运行的 Pod 和服务会各自分配自己的 IP 地址。IP 地址可供附近运行的其他容器集和服务访问,但外部客户端无法访问这些 IP 地址。Ingress Operator 实现 IngressController API,是负责启用对 OpenShift Container Platform 集群服务的外部访问的组件。

Ingress Operator 通过部署和管理一个或多个基于 HAProxy 的 Ingress Controller 来处理路由,使外部客户端可以访问您的服务。您可以通过指定 OpenShift Container Platform Route 和 Kubernetes Ingress 资源,来使用 Ingress Operator 路由流量。Ingress Controller 中的配置(如定义 endpointPublishingStrategy 类型和内部负载平衡)提供了发布 Ingress Controller 端点的方法。

2.2.1. 路由和 Ingress 的比较

OpenShift Container Platform 中的 Kubernetes Ingress 资源通过作为集群内 pod 运行的共享路由器服务来实现 Ingress Controller。管理 Ingress 流量的最常见方法是使用 Ingress Controller。您可以像任何其他常规 pod 一样扩展和复制此 pod。此路由器服务基于 HAProxy,后者是一个开源负载均衡器解决方案。

OpenShift Container Platform 路由为集群中的服务提供入口流量。路由提供了标准 Kubernetes Ingress Controller 可能不支持的高级功能,如 TLS 重新加密、TLS 直通和为蓝绿部署分割流量。

入口流量通过路由访问集群中的服务。路由和入口是处理入口流量的主要资源。Ingress 提供类似于路由的功能,如接受外部请求并根据路由委派它们。但是,对于 Ingress,您只能允许某些类型的连接:HTTP/2、HTTPS 和服务器名称识别(SNI),以及 TLS(证书)。在 OpenShift Container Platform 中,生成路由以满足 Ingress 资源指定的条件。

2.3. OpenShift Container Platform 网络的常见术语表

该术语表定义了在网络内容中使用的常用术语。

身份验证
为了控制对 OpenShift Container Platform 集群的访问,集群管理员可以配置用户身份验证,并确保只有批准的用户访问集群。要与 OpenShift Container Platform 集群交互,您必须对 OpenShift Container Platform API 进行身份验证。您可以通过在您对 OpenShift Container Platform API 的请求中提供 OAuth 访问令牌或 X.509 客户端证书来进行身份验证。
AWS Load Balancer Operator
AWS Load Balancer (ALB) Operator 部署和管理 aws-load-balancer-controller 的实例。
Cluster Network Operator
Cluster Network Operator(CNO)在 OpenShift Container Platform 集群中部署和管理集群网络组件。这包括在安装过程中为集群选择的 Container Network Interface (CNI) 网络插件部署。
配置映射
配置映射提供将配置数据注入 pod 的方法。您可以在类型为 ConfigMap 的卷中引用存储在配置映射中的数据。在 pod 中运行的应用程序可以使用这个数据。
自定义资源 (CR)
CR 是 Kubernetes API 的扩展。您可以创建自定义资源。
DNS
集群 DNS 是一个 DNS 服务器,它为 Kubernetes 服务提供 DNS 记录。由 Kubernetes 启动的容器会在其 DNS 搜索中自动包含此 DNS 服务器。
DNS Operator
DNS Operator 部署并管理 CoreDNS,以便为 pod 提供名称解析服务。这会在 OpenShift Container Platform 中启用基于 DNS 的 Kubernetes 服务发现。
部署
维护应用程序生命周期的 Kubernetes 资源对象。
domain
Domain(域)是 Ingress Controller 提供的 DNS 名称。
egress
通过来自 pod 的网络出站流量进行外部数据共享的过程。
外部 DNS Operator
External DNS Operator 部署并管理 ExternalDNS,以便为从外部 DNS 供应商到 OpenShift Container Platform 的服务和路由提供名称解析。
基于 HTTP 的路由
基于 HTTP 的路由是一个不受保护的路由,它使用基本的 HTTP 路由协议,并在未安全的应用程序端口上公开服务。
入口
OpenShift Container Platform 中的 Kubernetes Ingress 资源通过作为集群内 pod 运行的共享路由器服务来实现 Ingress Controller。
Ingress Controller
Ingress Operator 管理 Ingress Controller。使用 Ingress Controller 是允许从外部访问 OpenShift Container Platform 集群的最常用方法。
安装程序置备的基础架构
安装程序部署并配置运行集群的基础架构。
kubelet
在集群的每个节点上运行的一个主节点代理,以确保容器在 pod 中运行。
Kubernetes NMState Operator
Kubernetes NMState Operator 提供了一个 Kubernetes API,用于使用 NMState 在 OpenShift Container Platform 集群的节点上执行状态驱动的网络配置。
kube-proxy
kube-proxy 是一个代理服务,在每个节点上运行,有助于为外部主机提供服务。它有助于将请求转发到正确的容器,并且能够执行原语负载平衡。
负载均衡器
OpenShift Container Platform 使用负载均衡器从集群外部与集群中运行的服务进行通信。
MetalLB Operator
作为集群管理员,您可以将 MetalLB Operator 添加到集群中,以便在将 LoadBalancer 类型服务添加到集群中时,MetalLB 可为该服务添加外部 IP 地址。
multicast
通过使用 IP 多播,数据可同时广播到许多 IP 地址。
命名空间
命名空间隔离所有进程可见的特定系统资源。在一个命名空间中,只有属于该命名空间的进程才能看到这些资源。
networking
OpenShift Container Platform 集群的网络信息。
node
OpenShift Container Platform 集群中的 worker 机器。节点是虚拟机 (VM) 或物理计算机。
OpenShift Container Platform Ingress Operator
Ingress Operator 实现 IngressController API,是负责启用对 OpenShift Container Platform 服务的外部访问的组件。
pod
一个或多个带有共享资源(如卷和 IP 地址)的容器,在 OpenShift Container Platform 集群中运行。pod 是定义、部署和管理的最小计算单元。
PTP Operator
PTP Operator 会创建和管理 linuxptp 服务。
route
OpenShift Container Platform 路由为集群中的服务提供入口流量。路由提供了标准 Kubernetes Ingress Controller 可能不支持的高级功能,如 TLS 重新加密、TLS 直通和为蓝绿部署分割流量。
扩展
增加或减少资源容量。
service
在一组 pod 上公开正在运行的应用程序。
单根 I/O 虚拟化 (SR-IOV) Network Operator
Single Root I/O Virtualization(SR-IOV)Network Operator 管理集群中的 SR-IOV 网络设备和网络附加。
软件定义型网络 (SDN)
OpenShift Container Platform 使用软件定义网络 (SDN) 方法来提供一个统一的集群网络,它允许 OpenShift Container Platform 集群中的不同 pod 相互间进行通信。
注意

从 OpenShift Container Platform 4.14 开始,OpenShift SDN CNI 已被弃用。自 OpenShift Container Platform 4.15 起,网络插件不是新安装的选项。在以后的发行版本中,计划删除 OpenShift SDN 网络插件,并不再被支持。红帽将在删除前对这个功能提供程序错误修正和支持,但不会再改进这个功能。作为 OpenShift SDN CNI 的替代选择,您可以使用 OVN Kubernetes CNI。

流控制传输协议 (SCTP)
SCTP 是基于信息的可靠协议,可在 IP 网络之上运行。
taint
污点和容限可确保将 pod 调度到适当的节点上。您可以在节点上应用一个或多个污点。
容限 (tolerations)
您可以将容限应用到 pod。容限 (toleration) 允许调度程序调度具有匹配污点的 pod。
Web 控制台
用于管理 OpenShift Container Platform 的用户界面(UI)。

第 3 章 零信任网络

零信任(Zero trust)一个设计安全基础架构的方法,它基于内部的环境,其中的每个交流行为都从一个不受信任的状态开始。这与传统的架构不同。传统架构可能会根据交流是否是在防火墙内发起的来确定其信任性。更具体地说,零信任会尝试缩小安全基础架构中的漏洞(依赖隐式信任模型和一次性身份验证)。

OpenShift Container Platform 可以为平台上运行的容器添加一些零信任网络功能,而无需更改容器或它们中运行的软件。红帽提供的几种产品进一步增加了容器的零信任网络功能。如果您能够更改容器中运行的软件,则还有红帽支持的其他项目,可以添加进一步的功能。

探索零信任网络的以下目标功能。

3.1. 信任的根

公共证书和私钥对于零信任网络至关重要。它们用来识别另一个组件、验证和保护流量的安全组件。证书由其他证书签名,存在到根证书颁发机构 (CA) 的信任链。参与网络的所有内容需要最终具有 root CA 的公钥,以便它可以验证信任链。对于面向公共的项,通常是全局已知的根 CA,其密钥与操作系统、Web 浏览器等一起分发。但是,如果私有 CA 的证书被分发到所有方,则可以针对一个集群或一个机构运行私有 CA。

利用:

  • OpenShift Container Platform:OpenShift 在安装时会创建一个集群 CA,用于保护集群资源。但是,OpenShift Container Platform 也可以为 集群中的服务创建并签署证书,并可在请求时将集群 CA 捆绑包注入 pod。OpenShift Container Platform 创建并 签名的证书 有 26 个月的生存时间(TTL),并在 13 个月自动轮转。如有必要,也可以手动轮转它们。
  • OpenShift cert-manager Operator: cert-manager 允许您请求由外部信任根签名的证书的密钥。有许多可配置的签发者可以与外部签发者集成,以及与委派的签名证书一起运行的方法。cert-manager API 可供零信任网络中的其他软件使用,以请求必要的证书(如 Red Hat OpenShift Service Mesh),或者可由客户软件直接使用。

3.2. 流量身份验证和加密

确保网络上的所有流量都加密,并且端点是可识别的。例如,Mutual TLS 或 mTLS,这是 mutual 身份验证的方法。

利用:

3.3. 身份识别和验证

在使用 CA 最小化证书后,您可以通过验证连接端的另一端的连接身份验证一个用户或客户端机器来建立信任关系。这还需要管理证书生命周期,以便在被破坏时限制使用。

利用:

3.4. 服务间的授权

务必要根据请求者的身份控制对服务的访问。这由平台完成,不需要每个应用程序来实现它。这样可以更好地审核和检查策略。

利用:

3.5. 事务级验证

除了识别和验证连接的功能外,控制单个事务的访问也很有用。这可包括源、可观察性和语义验证的速率限制。

利用:

3.6. 风险评估

随着集群中的安全策略数量增加,策略允许和拒绝的视觉化变得越来越重要。这些工具可让您更轻松地创建、视觉化和管理集群安全策略。

利用:

3.7. 站点范围内的策略实施和分发

在集群中部署应用程序后,管理组成安全规则的所有对象就变得困难。务必要应用站点范围的策略,并审核部署的对象是否符合策略。这应该允许将某些权限委派给定义的绑定内的用户和集群管理员,并应允许例外策略。

利用:

3.8. 持续的可观察性,以及重新检查评估

运行的集群后,您希望能够观察流量,并使用定义的规则验证流量是否被端口。这对入侵检测、共识非常重要,有助于操作负载管理。

利用:

3.9. 端点安全性

务必要信任在集群中运行服务的软件没有被破坏。例如,您可能需要确保在可信硬件上运行认证的镜像,并有策略只允许基于端点特征或来自端点特征的连接。

利用:

  • OpenShift Container Platform:Secureboot 可以确保集群中的节点正在运行可信软件,因此平台本身(包括容器运行时)没有被篡改。您可以将 OpenShift Container Platform 配置为仅 运行由某些签名签名的镜像
  • Red Hat Trusted Artifact Signer:这可用于可信构建链并生成已签名的容器镜像。

3.10. 在集群外扩展信任

您可能希望通过允许集群到子域的 mint CA 来在集群外扩展信任。或者,您可能希望 attest 到集群中的工作负载身份到远程端点。

利用:

第 4 章 访问主机

了解如何创建堡垒主机来访问 OpenShift Container Platform 实例,以及使用安全 shell (SSH) 访问 control plane 节点。

4.1. 访问安装程序置备的基础架构集群中 Amazon Web Services 上的主机

OpenShift Container Platform 安装程序不会为任何置备 OpenShift Container Platform 集群的 Amazon Elastic Compute Cloud (Amazon EC2) 实例创建公共 IP 地址。为了可以 SSH 到 OpenShift Container Platform 主机,您必须按照以下步骤操作。

流程

  1. 创建一个安全组,允许 SSH 访问由 openshift-install 命令创建的虚拟私有云 (VPC) 。
  2. 在安装程序创建的某个公共子网中创建 Amazon EC2 实例。
  3. 将公共 IP 地址与您创建的 Amazon EC2 实例相关联。

    与 OpenShift Container Platform 安装不同,您应该将您创建的 Amazon EC2 实例与 SSH 密钥对关联。这与您为这个实例选择的操作系统无关,因为它只是一个 SSH 堡垒将互联网桥接到 OpenShift Container Platform 集群的 VPC。它与您使用的 Amazon Machine Image (AMI) 相关。例如,在 Red Hat Enterprise Linux CoreOS(RHCOS) 中,您可以像安装程序一样通过 Ignition 提供密钥。

  4. 一旦置备了 Amazon EC2 实例并可以 SSH 到它,您必须添加与 OpenShift Container Platform 安装关联的 SSH 密钥。这个密钥可以与堡垒实例的密钥不同,也可以相同。

    注意

    直接通过 SSH 访问仅建议在灾难恢复时使用。当 Kubernetes API 正常工作时,应该使用特权 Pod。

  5. 运行 oc get nodes,查看输出结果,然后选择一个 master 节点。主机名类似于 ip-10-0-1-163.ec2.internal
  6. 从您手动部署到 Amazon EC2 的堡垒 SSH 主机中,SSH 部署到该 control plane 主机。确定您使用了在安装过程中指定的相同的 SSH 密钥:

    $ ssh -i <ssh-key-path> core@<master-hostname>

第 5 章 网络 Operator 概述

OpenShift Container Platform 支持多种类型的网络 Operator。您可以使用这些网络 Operator 管理集群网络。

5.1. Cluster Network Operator

Cluster Network Operator(CNO)在 OpenShift Container Platform 集群中部署和管理集群网络组件。这包括在安装过程中为集群选择的 Container Network Interface (CNI) 网络插件部署。如需更多信息,请参阅 OpenShift Container Platform 中的 Cluster Network Operator

5.2. DNS Operator

DNS Operator 部署并管理 CoreDNS,以便为 pod 提供名称解析服务。这会在 OpenShift Container Platform 中启用基于 DNS 的 Kubernetes 服务发现。如需更多信息,请参阅 OpenShift Container Platform 中的 DNS Operator

5.3. Ingress Operator

创建 OpenShift Container Platform 集群时,集群中运行的 pod 和服务将为每个分配的 IP 地址。IP 地址可以被其他 pod 和服务访问,但外部客户端无法访问。Ingress Operator 实现 Ingress Controller API,并负责启用对 OpenShift Container Platform 集群服务的外部访问。如需更多信息,请参阅 OpenShift Container Platform 中的 Ingress Operator

5.4. 外部 DNS Operator

External DNS Operator 部署并管理 ExternalDNS,以便为从外部 DNS 供应商到 OpenShift Container Platform 的服务和路由提供名称解析。如需更多信息,请参阅了解外部 DNS Operator

5.5. Ingress Node Firewall Operator

Ingress Node Firewall Operator 使用扩展的 Berkley Packet Filter (eBPF) 和 eXpress Data Path (XDP) 插件来处理节点防火墙规则,更新统计信息并为丢弃的流量生成事件。Operator 管理入口节点防火墙资源,验证防火墙配置,不允许错误配置规则来防止集群访问,并将 ingress 节点防火墙 XDP 程序加载到规则对象中的所选接口。如需更多信息,请参阅了解 Ingress Node Firewall Operator

5.6. Network Observability Operator

Network Observability Operator 是一个可选 Operator,它允许集群管理员观察 OpenShift Container Platform 集群的网络流量。Network Observability Operator 使用 eBPF 技术创建网络流。然后,OpenShift Container Platform 信息会增强网络流,并存储在 Loki 中。您可以在 OpenShift Container Platform 控制台中查看和分析所存储的 netflow 信息,以进一步洞察和故障排除。如需更多信息,请参阅关于 Network Observability Operator

第 6 章 网络仪表板

网络指标可在 OpenShift Container Platform web 控制台的 dashboard 中的 ObserveDashboards 下查看。

6.1. Network Observability Operator

如果安装了 Network Observability Operator,可以通过从 Dashboards 下拉列表中选择 Netobserv 仪表板来查看网络流量指标仪表板。有关此仪表板中可用指标的更多信息,请参阅 Network Observability metrics dashboard

6.2. 网络和 OVN-Kubernetes 仪表板

您可以从仪表板中查看常规网络指标和 OVN-Kubernetes 指标。

要查看常规网络指标,请从 Dashboards 下拉列表中选择 Networking/Linux Subsystem Stats。您可以从控制面板查看以下网络指标:Network UtilisationNetwork SaturationNetwork Errors

要查看 OVN-Kubernetes 指标,请从 Dashboards 下拉列表中选择 Networking/Infrastructure。您可以查看以下 OVN-Kuberenetes 指标:Networking Configuration, TCP Latency Probes, Control Plane Resources, 和 Worker Resources

6.3. Ingress Operator 仪表板

您可以从仪表板中查看 Ingress Operator 处理的网络指标。这包括类似如下的指标:

  • 传入和传出带宽
  • HTTP 错误率
  • HTTP 服务器响应延迟

要查看这些 Ingress 指标,请从 Dashboards 下拉列表中选择 Networking/Ingress。您可以查看以下类别的 Ingress 指标: Top 10 Per Route,Top 10 Per Namespace, 和 Top 10 Per Shard

第 7 章 OpenShift Container Platform 中的 Cluster Network Operator

Cluster Network Operator (CNO)在 OpenShift Container Platform 集群上部署和管理集群网络组件,包括在安装过程中为集群选择的 Container Network Interface (CNI) 网络插件。

7.1. Cluster Network Operator

Cluster Network Operator 从 operator.openshift.io API 组实现 network API。Operator 通过使用守护进程集部署 OVN-Kubernetes 网络插件,或部署您在集群安装过程中选择的网络供应商插件。

流程

Cluster Network Operator 在安装过程中被部署为一个 Kubernetes 部署

  1. 运行以下命令,以查看部署状态:

    $ oc get -n openshift-network-operator deployment/network-operator

    输出示例

    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    network-operator   1/1     1            1           56m

  2. 运行以下命令,以查看 Cluster Network Operator 的状态:

    $ oc get clusteroperator/network

    输出示例

    NAME      VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
    network   4.5.4     True        False         False      50m

    以下字段提供有关 Operator 状态的信息:AVAILABLEProgressingDEGRADED。当 Cluster Network Operator 报告可用状态条件时,AVAILABLE 字段为 True

7.2. 查看集群网络配置

每个 OpenShift Container Platform 新安装都有一个名为 clusternetwork.config 对象。

流程

  • 使用 oc describe 命令查看集群网络配置:

    $ oc describe network.config/cluster

    输出示例

    Name:         cluster
    Namespace:
    Labels:       <none>
    Annotations:  <none>
    API Version:  config.openshift.io/v1
    Kind:         Network
    Metadata:
      Self Link:           /apis/config.openshift.io/v1/networks/cluster
    Spec: 1
      Cluster Network:
        Cidr:         10.128.0.0/14
        Host Prefix:  23
      Network Type:   OpenShiftSDN
      Service Network:
        172.30.0.0/16
    Status: 2
      Cluster Network:
        Cidr:               10.128.0.0/14
        Host Prefix:        23
      Cluster Network MTU:  8951
      Network Type:         OpenShiftSDN
      Service Network:
        172.30.0.0/16
    Events:  <none>

    1
    Spec 字段显示集群网络的已配置状态。
    2
    Status 字段显示集群网络配置的当前状态。

7.3. 查看 Cluster Network Operator 状态

您可以使用 oc describe 命令来检查状态并查看 Cluster Network Operator 的详情。

流程

  • 运行以下命令,以查看 Cluster Network Operator 的状态:

    $ oc describe clusteroperators/network

7.4. 查看 Cluster Network Operator 日志

您可以使用 oc logs 命令来查看 Cluster Network Operator 日志。

流程

  • 运行以下命令,以查看 Cluster Network Operator 的日志:

    $ oc logs --namespace=openshift-network-operator deployment/network-operator

7.5. Cluster Network Operator 配置

集群网络的配置作为 Cluster Network Operator(CNO)配置的一部分指定,并存储在名为 cluster 的自定义资源(CR)对象中。CR 指定 operator.openshift.io API 组中的 Network API 的字段。

CNO 配置在集群安装过程中从 Network.config.openshift.io API 组中的 Network API 继承以下字段:

clusterNetwork
从中分配 Pod IP 地址的 IP 地址池。
serviceNetwork
服务的 IP 地址池.
defaultNetwork.type
集群网络插件。OVNKubernetes 是安装期间唯一支持的插件。
注意

在集群安装后,您只能修改 clusterNetwork IP 地址范围。默认网络类型只能通过迁移从 OpenShift SDN 改为 OVN-Kubernetes。

您可以通过在名为 cluster 的 CNO 对象中设置 defaultNetwork 对象的字段来为集群指定集群网络插件配置。

7.5.1. Cluster Network Operator 配置对象

下表中描述了 Cluster Network Operator(CNO)的字段:

表 7.1. Cluster Network Operator 配置对象
字段类型描述

metadata.name

字符串

CNO 对象的名称。这个名称始终是 集群

spec.clusterNetwork

array

用于指定从哪些 IP 地址块分配 Pod IP 地址以及集群中每个节点的子网前缀长度的列表。例如:

spec:
  clusterNetwork:
  - cidr: 10.128.0.0/19
    hostPrefix: 23
  - cidr: 10.128.32.0/19
    hostPrefix: 23

spec.serviceNetwork

array

服务的 IP 地址块。OpenShift SDN 和 OVN-Kubernetes 网络插件只支持服务网络的一个 IP 地址块。例如:

spec:
  serviceNetwork:
  - 172.30.0.0/14

此值是只读的,在集群安装过程中从名为 clusterNetwork.config.openshift.io 对象继承。

spec.defaultNetwork

object

为集群网络配置网络插件。

spec.kubeProxyConfig

object

此对象的字段指定 kube-proxy 配置。如果使用 OVN-Kubernetes 集群网络供应商,则 kube-proxy 配置不会起作用。

defaultNetwork 对象配置

下表列出了 defaultNetwork 对象的值:

表 7.2. defaultNetwork 对象
字段类型描述

type

字符串

OVNKubernetes。Red Hat OpenShift Networking 网络插件在安装过程中被选择。此值在集群安装后无法更改。

注意

OpenShift Container Platform 默认使用 OVN-Kubernetes 网络插件。OpenShift SDN 不再作为新集群的安装选择提供。

ovnKubernetesConfig

object

此对象仅对 OVN-Kubernetes 网络插件有效。

配置 OpenShift SDN 网络插件

下表描述了 OpenShift SDN 网络插件的配置字段:

表 7.3. openshiftSDNConfig object
字段类型描述

模式

string

OpenShift SDN 的网络隔离模式。

mtu

integer

VXLAN 覆盖网络的最大传输单元(MTU)。这个值通常是自动配置的。

vxlanPort

integer

用于所有 VXLAN 数据包的端口。默认值为 4789

OpenShift SDN 配置示例

defaultNetwork:
  type: OpenShiftSDN
  openshiftSDNConfig:
    mode: NetworkPolicy
    mtu: 1450
    vxlanPort: 4789

配置 OVN-Kubernetes 网络插件

下表描述了 OVN-Kubernetes 网络插件的配置字段:

表 7.4. ovnKubernetesConfig object
字段类型描述

mtu

integer

Geneve(通用网络虚拟化封装)覆盖网络的最大传输单元(MTU)。这个值通常是自动配置的。

genevePort

整数

Geneve 覆盖网络的 UDP 端口。

ipsecConfig

object

用于描述集群的 IPsec 模式的对象。

policyAuditConfig

object

指定用于自定义网络策略审计日志的配置对象。如果未设置,则使用默认的审计日志设置。

gatewayConfig

object

可选:指定一个配置对象来自定义如何将出口流量发送到节点网关。

注意

在迁移出口流量时,工作负载和服务流量会受到一定影响,直到 Cluster Network Operator (CNO) 成功推出更改。

v4InternalSubnet

如果您的现有网络基础架构与 100.64.0.0/16 IPv4 子网重叠,您可以指定不同的 IP 地址范围供 OVN-Kubernetes 使用。您必须确保 IP 地址范围没有与 OpenShift Container Platform 安装使用的任何其他子网重叠。IP 地址范围必须大于可添加到集群的最大节点数。例如,如果 clusterNetwork.cidr 值为 10.128.0.0/14,并且 clusterNetwork.hostPrefix 值为 /23,则最大节点数量为 2^(23-14)=512

在安装后无法更改此字段。

默认值为 100.64.0.0/16

v6InternalSubnet

如果您的现有网络基础架构与 fd98::/48 IPv6 子网重叠,您可以指定不同的 IP 地址范围供 OVN-Kubernetes 使用。您必须确保 IP 地址范围没有与 OpenShift Container Platform 安装使用的任何其他子网重叠。IP 地址范围必须大于可添加到集群的最大节点数。

在安装后无法更改此字段。

默认值为 fd98::/48

表 7.5. policyAuditConfig object
字段类型描述

rateLimit

整数

每个节点每秒生成一次的消息数量上限。默认值为每秒 20 条消息。

maxFileSize

整数

审计日志的最大大小,以字节为单位。默认值为 50000000 或 50 MB。

maxLogFiles

整数

保留的日志文件的最大数量。

目的地

字符串

以下附加审计日志目标之一:

libc
主机上的 journald 进程的 libc syslog() 函数。
UDP:<host>:<port>
一个 syslog 服务器。将 <host>:<port> 替换为 syslog 服务器的主机 和端口。
Unix:<file>
<file> 指定的 Unix 域套接字文件。
null
不要将审计日志发送到任何其他目标。

syslogFacility

字符串

syslog 工具,如 as kern,如 RFC5424 定义。默认值为 local0。

表 7.6. gatewayConfig object
字段类型描述

routingViaHost

布尔值

将此字段设置为 true,将来自 pod 的出口流量发送到主机网络堆栈。对于依赖于在内核路由表中手动配置路由的高级别安装和应用程序,您可能需要将出口流量路由到主机网络堆栈。默认情况下,出口流量在 OVN 中进行处理以退出集群,不受内核路由表中的特殊路由的影响。默认值为 false

此字段与 Open vSwitch 硬件卸载功能有交互。如果将此字段设置为 true,则不会获得卸载的性能优势,因为主机网络堆栈会处理出口流量。

ipForwarding

object

您可以使用 Network 资源中的 ipForwarding 规格来控制 OVN-Kubernetes 管理接口上所有流量的 IP 转发。指定 Restricted 只允许 Kubernetes 相关流量的 IP 转发。指定 Global 以允许转发所有 IP 流量。对于新安装,默认值为 Restricted。对于到 OpenShift Container Platform 4.14 或更高版本的更新,默认值为 Global

表 7.7. ipsecConfig 对象
字段类型描述

模式

字符串

指定 IPsec 实现的行为。必须是以下值之一:

  • Disabled: 在集群节点上不启用 IPsec。
  • External :对于带有外部主机的网络流量,启用 IPsec。
  • Full: IPsec 为带有外部主机的 pod 流量和网络流量启用 IPsec。
注意

您只能在集群安装过程中更改集群网络插件的配置,但 gatewayConfig 字段可作为安装后活动在运行时更改。

启用 IPSec 的 OVN-Kubernetes 配置示例

defaultNetwork:
  type: OVNKubernetes
  ovnKubernetesConfig:
    mtu: 1400
    genevePort: 6081
      ipsecConfig:
        mode: Full

重要

使用 OVNKubernetes 可能会导致 IBM Power® 上的堆栈耗尽问题。

kubeProxyConfig 对象配置(仅限 OpenShiftSDN 容器网络接口)

kubeProxyConfig 对象的值在下表中定义:

表 7.8. kubeProxyConfig object
字段类型描述

iptablesSyncPeriod

字符串

iptables 规则的刷新周期。默认值为 30s。有效的后缀包括 smh,具体参见 Go 时间 文档。

注意

由于 OpenShift Container Platform 4.3 及更高版本中引进了性能改进,不再需要调整 iptablesSyncPeriod 参数。

proxyArguments.iptables-min-sync-period

array

刷新 iptables 规则前的最短持续时间。此字段确保刷新的频率不会过于频繁。有效的后缀包括 smh,具体参见 Go time 软件包。默认值为:

kubeProxyConfig:
  proxyArguments:
    iptables-min-sync-period:
    - 0s

7.5.2. Cluster Network Operator 配置示例

以下示例中指定了完整的 CNO 配置:

Cluster Network Operator 对象示例

apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  serviceNetwork:
  - 172.30.0.0/16
  networkType: OVNKubernetes
      clusterNetworkMTU: 8900

7.6. 其他资源

第 8 章 OpenShift Container Platform 中的 DNS Operator

DNS Operator 部署并管理 CoreDNS,以为 pod 提供名称解析服务。它在 OpenShift Container Platform 中启用了基于 DNS 的 Kubernetes 服务发现。

8.1. DNS Operator

DNS Operator 从 operator.openshift.io API 组实现 dns API。Operator 使用守护进程集部署 CoreDNS,为守护进程集创建一个服务,并将 kubelet 配置为指示 pod 使用 CoreDNS 服务 IP 地址进行名称解析。

流程

在安装过程中使用 Deployment 对象部署 DNS Operator。

  1. 使用 oc get 命令查看部署状态:

    $ oc get -n openshift-dns-operator deployment/dns-operator

    输出示例

    NAME           READY     UP-TO-DATE   AVAILABLE   AGE
    dns-operator   1/1       1            1           23h

  2. 使用 oc get 命令来查看 DNS Operator 的状态:

    $ oc get clusteroperator/dns

    输出示例

    NAME      VERSION     AVAILABLE   PROGRESSING   DEGRADED   SINCE
    dns       4.1.0-0.11  True        False         False      92m

    AVAILABLEPROGRESSINGDEGRADED 提供了有关 Operator 状态的信息。当 CoreDNS 守护进程中至少有 1 个 pod 被设置为 Available 状态时,AVAILABLETrue

8.2. 更改 DNS Operator managementState

DNS 管理 CoreDNS 组件,为集群中的 pod 和服务提供名称解析服务。默认情况下,DNS Operator 的 managementState 设置为 Managed,这意味着 DNS Operator 会主动管理其资源。您可以将其更改为 Unmanaged,这意味着 DNS Operator 不管理其资源。

以下是更改 DNS Operator managementState 的用例:

  • 您是一个开发者,希望测试配置更改来查看它是否解决了 CoreDNS 中的问题。您可以通过将 managementState 设置为 Unmanaged 来停止 DNS Operator 覆盖更改。
  • 您是一个集群管理员,报告了 CoreDNS 的问题,但在解决这个问题前需要应用一个临时解决方案。您可以将 DNS Operator 的 managementState 字段设置为 Unmanaged 以应用临时解决方案。

流程

  • 修改 managementState DNS Operator:

    oc patch dns.operator.openshift.io default --type merge --patch '{"spec":{"managementState":"Unmanaged"}}'

8.3. 控制 DNS pod 放置

DNS Operator 有两个守护进程集:一个用于 CoreDNS,另一个用于管理 /etc/hosts 文件。/etc/hosts 的守护进程集必须在每个节点主机上运行,以便为集群镜像 registry 添加条目来支持拉取镜像。安全策略可以禁止节点对之间的通信,这会阻止 CoreDNS 的守护进程集在每个节点上运行。

作为集群管理员,您可以使用自定义节点选择器将 CoreDNS 的守护进程集配置为在某些节点上运行或不运行。

先决条件

  • 已安装 oc CLI。
  • 使用具有 cluster-admin 权限的用户登陆到集群。

流程

  • 要防止某些节点间的通信,请配置 spec.nodePlacement.nodeSelector API 字段:

    1. 修改名为 default 的 DNS Operator 对象:

      $ oc edit dns.operator/default
    2. 指定在 spec.nodePlacement.nodeSelector API 字段中只包含 control plane 节点的节点选择器:

       spec:
         nodePlacement:
           nodeSelector:
             node-role.kubernetes.io/worker: ""
  • 要允许 CoreDNS 的守护进程集在节点上运行,请配置污点和容限:

    1. 修改名为 default 的 DNS Operator 对象:

      $ oc edit dns.operator/default
    2. 为污点指定污点键和一个容忍度:

       spec:
         nodePlacement:
           tolerations:
           - effect: NoExecute
             key: "dns-only"
             operators: Equal
             value: abc
             tolerationSeconds: 3600 1
      1
      如果污点是 dns-only,它可以无限期地被容许。您可以省略 tolerationSeconds

8.4. 查看默认 DNS

每个 OpenShift Container Platform 新安装都有一个名为 defaultdns.operator

流程

  1. 使用 oc describe 命令来查看默认 dns

    $ oc describe dns.operator/default

    输出示例

    Name:         default
    Namespace:
    Labels:       <none>
    Annotations:  <none>
    API Version:  operator.openshift.io/v1
    Kind:         DNS
    ...
    Status:
      Cluster Domain:  cluster.local 1
      Cluster IP:      172.30.0.10 2
    ...

    1
    Cluster Domain 字段是用来构造完全限定的 pod 和服务域名的基本 DNS 域。
    2
    Cluster IP 是 Pod 为名称解析查询的地址。IP 由服务 CIDR 范围中的第 10 个地址定义。
  2. 要查找集群的服务 CIDR,使用 oc get 命令:

    $ oc get networks.config/cluster -o jsonpath='{$.status.serviceNetwork}'

输出示例

[172.30.0.0/16]

8.5. 使用 DNS 转发

您可以使用以下方法使用 DNS 转发来覆盖 /etc/resolv.conf 文件中的默认转发配置:

  • 为每个区指定名称服务器。如果转发区是 OpenShift Container Platform 管理的 Ingress 域,那么上游名称服务器必须为域授权。
  • 提供上游 DNS 服务器列表。
  • 更改默认转发策略。
注意

默认域的 DNS 转发配置可以同时在 /etc/resolv.conf 文件和上游 DNS 服务器中指定默认服务器。

流程

  1. 修改名为 default 的 DNS Operator 对象:

    $ oc edit dns.operator/default

    发出上一命令后,Operator 会根据 Server 创建并更新名为 dns-default 的配置映射,并带有额外的服务器配置块。如果任何服务器都没有与查询匹配的区域,则名称解析会返回上游 DNS 服务器。

    配置 DNS 转发

    apiVersion: operator.openshift.io/v1
    kind: DNS
    metadata:
      name: default
    spec:
      servers:
      - name: example-server 1
        zones: 2
        - example.com
        forwardPlugin:
          policy: Random 3
          upstreams: 4
          - 1.1.1.1
          - 2.2.2.2:5353
      upstreamResolvers: 5
        policy: Random 6
        upstreams: 7
        - type: SystemResolvConf 8
        - type: Network
          address: 1.2.3.4 9
          port: 53 10

    1
    必须符合 rfc6335 服务名称语法。
    2
    必须符合 rfc1123 服务名称语法中的子域的定义。集群域 cluster.local 是对 zones 字段的无效子域。
    3
    定义用于选择上游解析器的策略。默认值为 Random。您还可以使用 RoundRobin, 和 Sequential 值。
    4
    每个 forwardPlugin 最多允许 15 个 upstreams
    5
    可选。您可以使用它来覆盖默认策略,并将 DNS 解析转发到默认域的指定 DNS 解析器(上游解析器)。如果没有提供任何上游解析器,DNS 名称查询将进入 /etc/resolv.conf 中的服务器。
    6
    决定选择上游服务器进行查询的顺序。您可以指定这些值之一: RandomRoundRobinSequential。默认值为 Sequential
    7
    可选。您可以使用它提供上游解析器。
    8
    您可以指定上游的两种类型 - SystemResolvConfNetworkSystemResolvConf 将上游配置为使用 /etc/resolv.confNetwork 定义一个 Networkresolver。您可以指定其中一个或两者都指定。
    9
    如果指定类型是 Network,则必须提供 IP 地址。address 字段必须是有效的 IPv4 或 IPv6 地址。
    10
    如果指定类型是 Network,您可以选择性地提供端口。port 字段必须是 165535 之间的值。如果您没有为上游指定端口,则会尝试默认端口 853。
  2. 可选:在高度监管的环境中工作时,您可能需要在将请求转发到上游解析器时保护 DNS 流量,以便您可以确保额外的 DNS 流量和数据隐私。集群管理员可以配置传输层安全(TLS)来转发 DNS 查询。

    使用 TLS 配置 DNS 转发

    apiVersion: operator.openshift.io/v1
    kind: DNS
    metadata:
      name: default
    spec:
      servers:
      - name: example-server 1
        zones: 2
        - example.com
        forwardPlugin:
          transportConfig:
            transport: TLS 3
            tls:
              caBundle:
                name: mycacert
              serverName: dnstls.example.com  4
          policy: Random 5
          upstreams: 6
          - 1.1.1.1
          - 2.2.2.2:5353
      upstreamResolvers: 7
        transportConfig:
          transport: TLS
          tls:
            caBundle:
              name: mycacert
            serverName: dnstls.example.com
        upstreams:
        - type: Network 8
          address: 1.2.3.4 9
          port: 53 10

    1
    必须符合 rfc6335 服务名称语法。
    2
    必须符合 rfc1123 服务名称语法中的子域的定义。集群域 cluster.local 是对 zones 字段的无效子域。集群域 cluster.local 不是 zones 中的一个有效的 subdomain
    3
    在为转发 DNS 查询配置 TLS 时,将 transport 字段设置为具有值 TLS。默认情况下,CoreDNS 缓存在 10 秒内转发连接。如果没有请求,CoreDNS 将为该 10 秒打开 TCP 连接。对于大型集群,请确保您的 DNS 服务器知道可能有多个新的连接来保存打开,因为您可以在每个节点上启动连接。相应地设置 DNS 层次结构以避免性能问题。
    4
    当为转发 DNS 查询配置 TLS 时,这是用作服务器名称的一部分(SNI)的强制服务器名称来验证上游 TLS 服务器证书。
    5
    定义用于选择上游解析器的策略。默认值为 Random。您还可以使用 RoundRobin, 和 Sequential 值。
    6
    必需。您可以使用它提供上游解析器。每个 forwardPlugin 条目最多允许 15 个 upstreams 条目。
    7
    可选。您可以使用它来覆盖默认策略,并将 DNS 解析转发到默认域的指定 DNS 解析器(上游解析器)。如果没有提供任何上游解析器,DNS 名称查询将进入 /etc/resolv.conf 中的服务器。
    8
    网络类型表示,该上游解析器应该独立于 /etc/resolv.conf 中列出的上游解析器单独处理转发请求。在使用 TLS 时,只允许网络类型,且您必须提供 IP 地址。
    9
    address 字段必须是有效的 IPv4 或 IPv6 地址。
    10
    您可以选择提供端口。port 必须是 165535 之间的值。如果您没有为上游指定端口,则会尝试默认端口 853。
    注意

    如果 servers 未定义或无效,则配置映射只包括默认服务器。

验证

  1. 查看配置映射:

    $ oc get configmap/dns-default -n openshift-dns -o yaml

    基于以上 DNS 示例的 DNS ConfigMap 示例

    apiVersion: v1
    data:
      Corefile: |
        example.com:5353 {
            forward . 1.1.1.1 2.2.2.2:5353
        }
        bar.com:5353 example.com:5353 {
            forward . 3.3.3.3 4.4.4.4:5454 1
        }
        .:5353 {
            errors
            health
            kubernetes cluster.local in-addr.arpa ip6.arpa {
                pods insecure
                upstream
                fallthrough in-addr.arpa ip6.arpa
            }
            prometheus :9153
            forward . /etc/resolv.conf 1.2.3.4:53 {
                policy Random
            }
            cache 30
            reload
        }
    kind: ConfigMap
    metadata:
      labels:
        dns.operator.openshift.io/owning-dns: default
      name: dns-default
      namespace: openshift-dns

    1
    forwardPlugin 的更改会触发 CoreDNS 守护进程集的滚动更新。

其他资源

8.6. DNS Operator 状态

您可以使用 oc describe 命令来检查状态并查看 DNS Operator 的详情。

流程

查看 DNS Operator 的状态:

$ oc describe clusteroperators/dns

8.7. DNS Operator 日志

您可以使用 oc logs 命令来查看 DNS Operator 日志。

流程

查看 DNS Operator 的日志:

$ oc logs -n openshift-dns-operator deployment/dns-operator -c dns-operator

8.8. 设置 CoreDNS 日志级别

您可以配置 CoreDNS 日志级别来确定日志记录错误信息中的详情量。CoreDNS 日志级别的有效值为 NormalDebugTrace。默认 logLevelNormal

注意

错误插件会始终被启用。以下 logLevel 设置会报告不同的错误响应:

  • logLevel: Normal 启用 "errors" 类: log . { class error }.
  • loglevelDebug 启用 "denial" 类: log . { class denial error }
  • logLevel: Trace 启用 "all" 类: log . { class all }.

流程

  • 要将 logLevel 设置为 Debug,输入以下命令:

    $ oc patch dnses.operator.openshift.io/default -p '{"spec":{"logLevel":"Debug"}}' --type=merge
  • 要将 logLevel 设置为 Trace,输入以下命令:

    $ oc patch dnses.operator.openshift.io/default -p '{"spec":{"logLevel":"Trace"}}' --type=merge

验证

  • 要确保设置了所需的日志级别,请检查配置映射:

    $ oc get configmap/dns-default -n openshift-dns -o yaml

8.9. 设置 CoreDNS Operator 的日志级别

集群管理员可以配置 Operator 日志级别来更快地跟踪 OpenShift DNS 问题。operatorLogLevel 的有效值为 NormalDebugTraceTrace 具有更详细的信息。默认 operatorlogLevelNormal。问题有七个日志记录级别: Trace、debug、info、warning、Error、Fatal 和 Panic。设置了日志级别后,具有该严重性级别或以上级别的所有内容都会记录为日志条目。

  • operatorLogLevel: "Normal" 设置 logrus.SetLogLevel("Info")
  • operatorLogLevel: "Debug" 设置 logrus.SetLogLevel("Debug")
  • operatorLogLevel: "Trace" 设置 logrus.SetLogLevel("Trace")

流程

  • 要将 operatorLogLevel 设置为 Debug,请输入以下命令:

    $ oc patch dnses.operator.openshift.io/default -p '{"spec":{"operatorLogLevel":"Debug"}}' --type=merge
  • 要将 operatorLogLevel 设置为 Trace,请输入以下命令:

    $ oc patch dnses.operator.openshift.io/default -p '{"spec":{"operatorLogLevel":"Trace"}}' --type=merge

8.10. 调整 CoreDNS 缓存

您可以配置成功或失败缓存的最长持续时间(分别也称为正缓存或负缓存),由 CoreDNS 执行。调整 DNS 查询响应缓存持续时间可减少任何上游 DNS 解析器的负载。

流程

  1. 运行以下命令来编辑名为 default 的 DNS Operator 对象:

    $ oc edit dns.operator.openshift.io/default
  2. 修改生存时间 (TTL) 缓存值:

    配置 DNS 缓存

    apiVersion: operator.openshift.io/v1
    kind: DNS
    metadata:
      name: default
    spec:
      cache:
        positiveTTL: 1h 1
        negativeTTL: 0.5h10m 2

    1
    CoreDNS 会将字符串值 1h 转换为其相应的秒数。如果省略此字段,则假定该值为 0s,集群将使用内部默认值 900s 作为回退。
    2
    字符串值可以是单元的组合(如 0.5h10m),并被 CoreDNS 转换为相应秒数。如果省略了此字段,则假定该值为 0s,集群将使用内部默认值 30s 作为回退。
    警告

    将 TTL 字段设为低值可能会导致集群、任何上游解析器或两者中负载的增加。

第 9 章 OpenShift Container Platform 中的 Ingress Operator

9.1. OpenShift Container Platform Ingress Operator

在创建 OpenShift Container Platform 集群时,在集群中运行的 Pod 和服务会各自分配自己的 IP 地址。IP 地址可供附近运行的其他容器集和服务访问,但外部客户端无法访问这些 IP 地址。Ingress Operator 实现 IngressController API,是负责启用对 OpenShift Container Platform 集群服务的外部访问的组件。

Ingress Operator 通过部署和管理一个或多个基于 HAProxy 的 Ingress Controller 来处理路由,使外部客户端可以访问您的服务。您可以通过指定 OpenShift Container Platform Route 和 Kubernetes Ingress 资源,来使用 Ingress Operator 路由流量。Ingress Controller 中的配置(如定义 endpointPublishingStrategy 类型和内部负载平衡)提供了发布 Ingress Controller 端点的方法。

9.2. Ingress 配置资产

安装程序在 config.openshift.io API 组中生成带有 Ingress 资源的资产,cluster-ingress-02-config.yml

Ingress 资源的 YAML 定义

apiVersion: config.openshift.io/v1
kind: Ingress
metadata:
  name: cluster
spec:
  domain: apps.openshiftdemos.com

安装程序将这个资产保存在 manifests/ 目录下的 cluster-ingress-02-config.yml 文件中。此 Ingress 资源定义 Ingress 的集群范围配置。此 Ingress 配置的用法如下所示:

  • Ingress Operator 使用集群 Ingress 配置中的域,作为默认 Ingress Controller 的域。
  • OpenShift API Server Operator 使用集群 Ingress 配置中的域。在为未指定显式主机的 Route 资源生成默认主机时,还会使用此域。

9.3. Ingress Controller 配置参数

Infrastructure 自定义资源(CR)包含可配置的可选配置参数,以满足您的机构的特定需求。

参数描述

domain

domain 是 Ingress Controller 服务的一个 DNS 名称,用于配置多个功能:

  • 对于 LoadBalancerService 端点发布策略,domain 被用来配置 DNS 记录。请参阅 endpointPublishingStrategy
  • 当使用生成的默认证书时,该证书对及其子域有效。请参阅 defaultCertificate
  • 该值会发布到独立的 Route 状态,以便用户了解目标外部 DNS 记录的位置。

domain 值在所有 Ingress 控制器中需要是唯一的,且不能更新。

如果为空,默认值为 ingress.config.openshift.io/cluster .spec.domain

replicas

replicas 是 Ingress Controller 副本数量。如果没有设置,则默认值为 2

endpointPublishingStrategy

endpointPublishingStrategy 用于向其他网络发布 Ingress Controller 端点,以启用负载均衡器集成,并提供对其他系统的访问。

对于云环境,使用 loadBalancer 字段为 Ingress Controller 配置端点发布策略。

在 GCP、AWS 和 Azure 上,您可以配置以下 endpointPublishingStrategy 字段:

  • loadBalancer.scope
  • loadBalancer.allowedSourceRanges

如果没有设置,则默认值基于 infrastructure.config.openshift.io/cluster .status.platform

  • Azure: LoadBalancerService (具有外部范围)
  • Google Cloud Platform(GCP): LoadBalancerService (具有外部范围)

对于大多数平台,可以更新 endpointPublishingStrategy 值。在 GCP 上,您可以配置以下 endpointPublishingStrategy 字段:

  • loadBalancer.scope
  • loadbalancer.providerParameters.gcp.clientAccess

对于非云环境,如裸机平台,请使用 NodePortServiceHostNetworkPrivate 字段来为 Ingress Controller 配置端点发布策略。

如果您没有在这些字段中设置值,则默认值基于 Infrastructure CR 中的 .status.platform 值中指定的绑定端口。

如果需要在集群部署后更新 endpointPublishingStrategy 值,您可以配置以下 endpointPublishingStrategy 字段:

  • hostNetwork.protocol
  • nodePort.protocol
  • private.protocol

defaultCertificate

defaultCertificate 的值是一个到包括由 Ingress controller 提供的默认证书的 secret 的指代。当 Routes 没有指定其自身证书时,使用 defaultCertificate

secret 必须包含以下密钥和数据:* tls.crt:证书文件内容 * tls.key:密钥文件内容

如果没有设置,则自动生成和使用通配符证书。该证书对 Ingress Controller 的子域有效,所生成的证书的 CA 会自动与集群的信任存储集成。

内部证书(无论是生成的证书还是用户指定的证书)自动与 OpenShift Container Platform 内置的 OAuth 服务器集成。

namespaceSelector

namespaceSelector 用来过滤由 Ingress 控制器提供服务的一组命名空间。这对实现分片(shard)非常有用。

routeSelector

routeSelector 用于由 Ingress Controller 提供服务的一组 Routes。这对实现分片(shard)非常有用。

nodePlacement

NodePlacement 启用对 Ingress Controller 调度的显式控制。

如果没有设置,则使用默认值。

注意

nodePlacement 参数包括两个部分: nodeSelectortolerations。例如:

nodePlacement:
 nodeSelector:
   matchLabels:
     kubernetes.io/os: linux
 tolerations:
 - effect: NoSchedule
   operator: Exists

tlsSecurityProfile

tlsSecurityProfile 指定 Ingress Controller 的 TLS 连接的设置。

如果没有设置,则默认值基于 apiservers.config.openshift.io/cluster 资源。

当使用 OldIntermediateModern配置集类型时,有效的配置集可能会在不同发行版本间有所改变。例如:使用在版本 X.Y.Z 中部署的 Intermediate 配置集,升级到版本 X.Y.Z+1 可能会导致新的配置集配置应用到 Ingress Controller,从而导致一个 rollout 操作。

Ingress Controller 的最低 TLS 版本是 1.1,最高 TLS 版本为 1.3

注意

加密器和配置的安全配置集的最小 TLS 版本反映在 TLSProfile 状态中。

重要

Ingress Operator 将 OldCustom 配置集的 TLS 1.0 转换为 1.1

clientTLS

clientTLS 验证客户端对集群和服务的访问;因此,启用了 mutual TLS 身份验证。如果没有设置,则不启用客户端 TLS。

clientTLS 具有所需的子字段 spec.clientTLS.clientCertificatePolicyspec.clientTLS.ClientCA

ClientCertificatePolicy 子字段接受以下两个值之一:RequiredOptionalClientCA 子字段指定 openshift-config 命名空间中的配置映射。配置映射应包含 CA 证书捆绑包。

AllowedSubjectPatterns 是一个可选值,用于指定正则表达式列表,该列表与有效客户端证书上的可分辨名称匹配以过滤请求。正则表达式必须使用 PCRE 语法。至少一种模式必须与客户端证书的可分辨名称匹配;否则,入口控制器拒绝证书,并拒绝连接。如果没有指定,ingress 控制器不会根据可分辨的名称拒绝证书。

routeAdmission

routeAdmission 定义了处理新路由声明的策略,如允许或拒绝命名空间间的声明。

namespaceOwnership 描述了如何处理跨命名空间的主机名声明。默认为 Strict

  • Strict:不允许路由在命名空间间声明相同的主机名。
  • InterNamespaceAllowed :允许路由在命名空间间声明相同主机名的不同路径。

wildcardPolicy 描述了 Ingress Controller 如何处理采用通配符策略的路由。

  • WildcardsAllowed:表示 Ingress Controller 允许采用任何通配符策略的路由。
  • WildcardsDisallowed:表示 Ingress Controller 只接受采用 None 通配符策略的路由。将 wildcardPolicyWildcardsAllowed 更新为 WildcardsDisallowed,会导致采用 Subdomain 通配符策略的已接受路由停止工作。这些路由必须重新创建为采用 None 通配符策略,让 Ingress Controller 重新接受。WildcardsDisallowed 是默认设置。

IngressControllerLogging

logging 定义了有关在哪里记录什么内容的参数。如果此字段为空,则会启用运行日志,但禁用访问日志。

  • access 描述了客户端请求的日志记录方式。如果此字段为空,则禁用访问日志。

    • destination 描述日志消息的目的地。

      • type 是日志的目的地类型:

        • Container 指定日志应该进入 sidecar 容器。Ingress Operator 在 Ingress Controller pod 上配置名为 logs 的容器,并配置 Ingress Controller 以将日志写入容器。管理员应该配置一个自定义日志记录解决方案,从该容器读取日志。使用容器日志意味着,如果日志速率超过容器运行时或自定义日志解决方案的容量,则可能会出现日志丢失的问题。
        • Syslog 指定日志发送到 Syslog 端点。管理员必须指定可以接收 Syslog 消息的端点。管理员应该已经配置了一个自定义 Syslog 实例。
      • container 描述了 Container 日志记录目的地类型的参数。目前没有容器日志记录参数,因此此字段必须为空。
      • syslog 描述了 Syslog 日志记录目的地类型的参数:

        • address 是接收日志消息的 syslog 端点的 IP 地址。
        • port 是接收日志消息的 syslog 端点的 UDP 端口号。
        • MaxLength 是 syslog 消息的最大长度。它必须介于 4804096 字节之间。如果此字段为空,则最大长度设置为默认值 1024 字节。
        • facility 指定日志消息的 syslog 工具。如果该字段为空,则工具为 local1。否则,它必须指定一个有效的 syslog 工具: kernusermaildaemonauthsyslog, lpr, news, uucp, cron, auth2, ftp, ntp, audit, alert, cron2, local0, local1local2local3local4local5local6local7
    • httpLogFormat 指定 HTTP 请求的日志消息格式。如果此字段为空,日志消息将使用实现中的默认 HTTP 日志格式。有关 HAProxy 的默认 HTTP 日志格式,请参阅 HAProxy 文档

httpHeaders

httpHeaders 为 HTTP 标头定义策略。

通过为 IngressControllerHTTPHeaders 设置 forwardHeaderPolicy,您可以指定 Ingress 控制器何时和如何设置 ForwardedX-Forwarded-ForX-Forwarded-HostX-Forwarded-PortX-Forwarded-ProtoX-Forwarded-Proto-Version HTTP 标头。

默认情况下,策略设置为 Append

  • Append 指定 Ingress Controller 会附加标头,并保留任何现有的标头。
  • Replace 指定 Ingress Controller 设置标头,删除任何现有的标头。
  • IfNone 指定 Ingress Controller 在尚未设置标头时设置它们。
  • Never 指定 Ingress Controller 不会设置标头,并保留任何现有的标头。

通过设置 headerNameCaseAdjustments,您可以指定 HTTP 标头名对大小写的调整。每个调整都指定一个 HTTP 标头名称需要进行相关的大小写调整。例如,指定 X-Forwarded-For 表示 x-forwarded-for HTTP 标头应调整相应的大写。

这些调整仅应用于明文、边缘终止和重新加密路由,且仅在使用 HTTP/1 时有效。

对于请求标头,这些调整仅适用于具有 haproxy.router.openshift.io/h1-adjust-case=true 注解的路由。对于响应标头,这些调整适用于所有 HTTP 响应。如果此字段为空,则不会调整任何请求标头。

actions 指定对标头执行某些操作的选项。无法为 TLS 透传连接设置或删除标头。actions 字段具有额外的子字段 spec.httpHeader.actions.responsespec.httpHeader.actions.request

  • response 子字段指定要设置或删除的 HTTP 响应标头列表。
  • request 子字段指定要设置或删除的 HTTP 请求标头列表。

httpCompression

httpCompression 定义 HTTP 流量压缩的策略。

  • mimeTypes 定义应该将压缩应用到的 MIME 类型列表。例如,text/css; charset=utf-8, text/html, text/*, image/svg+xml, application/octet-stream, X-custom/customsub,格式为 type/subtype; [;attribute=value]types 是:application, image, message, multipart, text, video, 或一个自定义类型(前面带有一个 X-;如需更详细的 MIME 类型和子类型的信息,请参阅 RFC1341

httpErrorCodePages

httpErrorCodePages 指定自定义 HTTP 错误代码响应页面。默认情况下,IngressController 使用 IngressController 镜像内构建的错误页面。

httpCaptureCookies

httpCaptureCookies 指定您要在访问日志中捕获的 HTTP cookie。如果 httpCaptureCookies 字段为空,则访问日志不会捕获 Cookie。

对于您要捕获的任何 Cookie,以下参数必须位于 IngressController 配置中:

  • name 指定 Cookie 的名称。
  • MaxLength 指定 Cookie 的最大长度。
  • matchType 指定 Cookie 的 name 字段是否与捕获 Cookie 设置完全匹配,或者是捕获 Cookie 设置的前缀。matchType 字段使用 ExactPrefix 参数。

例如:

  httpCaptureCookies:
  - matchType: Exact
    maxLength: 128
    name: MYCOOKIE

httpCaptureHeaders

httpCaptureHeaders 指定要在访问日志中捕获的 HTTP 标头。如果 httpCaptureHeaders 字段为空,则访问日志不会捕获标头。

httpCaptureHeaders 包含两个要在访问日志中捕获的标头列表。这两个标题字段列表是 requestresponse。在这两个列表中,name 字段必须指定标头名称和 maxlength 字段,必须指定标头的最大长度。例如:

  httpCaptureHeaders:
    request:
    - maxLength: 256
      name: Connection
    - maxLength: 128
      name: User-Agent
    response:
    - maxLength: 256
      name: Content-Type
    - maxLength: 256
      name: Content-Length

tuningOptions

tuningOptions 指定用于调整 Ingress Controller pod 性能的选项。

  • clientFinTimeout 指定连接在等待客户端响应关闭连接时保持打开的时长。默认超时为 1s
  • clientTimeout 指定连接在等待客户端响应时保持打开的时长。默认超时为 30s
  • headerBufferBytes 为 Ingress Controller 连接会话指定保留多少内存(以字节为单位)。如果为 Ingress Controller 启用了 HTTP/2,则必须至少为 16384。如果没有设置,则默认值为 32768 字节。不建议设置此字段,因为 headerBufferBytes 值太小可能会破坏 Ingress Controller,而 headerBufferBytes 值过大可能会导致 Ingress Controller 使用比必要多的内存。
  • headerBufferMaxRewriteBytes 指定从 headerBufferBytes 为 Ingress Controller 连接会话保留多少内存(以字节为单位),用于 HTTP 标头重写和附加。headerBufferMaxRewriteBytes 的最小值是 4096headerBufferBytes 必须大于 headerBufferMaxRewriteBytes,用于传入的 HTTP 请求。如果没有设置,则默认值为 8192 字节。不建议设置此字段,因为 headerBufferMaxRewriteBytes 值可能会破坏 Ingress Controller,headerBufferMaxRewriteBytes 值太大可能会导致 Ingress Controller 使用比必要大得多的内存。
  • healthCheckInterval 指定路由器在健康检查之间等待的时间。默认值为 5s
  • serverFinTimeout 指定连接在等待服务器响应关闭连接时保持打开的时长。默认超时为 1s
  • serverTimeout 指定连接在等待服务器响应时保持打开的时长。默认超时为 30s
  • threadCount 指定每个 HAProxy 进程创建的线程数量。创建更多线程可让每个 Ingress Controller pod 处理更多连接,而代价会增加所使用的系统资源。HAProxy 支持多达 64 个线程。如果此字段为空,Ingress Controller 将使用默认值 4 个线程。默认值可能会在以后的版本中改变。不建议设置此字段,因为增加 HAProxy 线程数量可让 Ingress Controller pod 在负载下使用更多 CPU 时间,并阻止其他 pod 收到需要执行的 CPU 资源。减少线程数量可能会导致 Ingress Controller 执行不佳。
  • tlsInspectDelay 指定路由器可以保存数据以查找匹配的路由的时长。如果把这个值设置得太短,对于 edge-terminated, reencrypted, 或 passthrough 的路由,则可能会导致路由器回退到使用默认证书,即使正在使用一个更加匹配的证书时也是如此。默认检查延迟为 5s
  • tunnelTimeout 指定隧道连接在隧道闲置期间保持打开的时长,包括 websockets。默认超时为 1h
  • maxConnections 指定每个 HAProxy 进程可建立的最大同时连接数。增加这个值可让每个入口控制器 pod 以额外的系统资源成本处理更多连接。允许的值是 0-1、以及范围为 20002000000 内的任何值,或者字段可以留空。

    • 如果此字段留空,或者值为 0,Ingress Controller 将使用默认值 50000。这个值可能在以后的版本中有所改变。
    • 如果字段的值为 -1,则 HAProxy 将根据运行中容器中的可用 ulimits 动态计算最大值。与当前默认值 50000 相比,此进程会产生很大的内存用量。
    • 如果字段的值大于当前操作系统的限制,则 HAProxy 进程将不会启动。
    • 如果您选择了一个离散值,并且路由器 pod 迁移到新节点,则新节点可能没有配置相同的 ulimit。在这种情况下,pod 无法启动。
    • 如果您配置了不同的 ulimits 的节点,并且您选择离散值,则建议为该字段使用 -1 的值,以便在运行时计算连接的最大数量。

logEmptyRequests

logEmptyRequests 指定没有接收和记录请求的连接。这些空请求来自负载均衡器健康探测或 Web 浏览器规范连接(preconnect),并记录这些请求。但是,这些请求可能是由网络错误导致的,在这种情况下,记录空请求可用于诊断错误。这些请求可能是由端口扫描导致的,记录空请求有助于检测入侵尝试。此字段允许的值有 LogIgnore。默认值为 Log

LoggingPolicy 类型接受以下两个值之一:

  • log :将此值设置为 Log 表示应记录某一事件。
  • ignore :将此值设置为 Ignore 会在 HAproxy 配置中设置 dontlognull 选项。

HTTPEmptyRequestsPolicy

HTTPEmptyRequestsPolicy 描述了在收到请求前发生超时时,如何处理 HTTP 连接。此字段允许的值是 RespondIgnore。默认值为 Respond

HTTPEmptyRequestsPolicy 类型接受以下两个值之一:

  • Respond:如果字段设置为 Respond,Ingress Controller 会发送 HTTP 400408 响应,在启用了访问日志时记录连接,并在适当的指标中计数连接。
  • ignore:将这个选项设置为 Ignore 会在 HAproxy 配置中添加 http-ignore-probes 参数。如果字段设置为 Ignore,Ingnore 会在不发送响应的情况下关闭连接,然后记录连接或递增指标。

这些连接来自负载均衡器健康探测或 Web 浏览器规范连接(预连接),可以安全地忽略。但是,这些请求可能是由网络错误造成的,因此将此字段设置为 Ignore 可能会妨碍对问题的检测和诊断。这些请求可能是由端口扫描导致的,在这种情况下,记录空请求有助于检测入侵尝试。

9.3.1. Ingress Controller TLS 安全配置集

TLS 安全配置文件为服务器提供了一种方式,以规范连接的客户端在连接服务器时可以使用哪些密码。

9.3.1.1. 了解 TLS 安全配置集

您可以使用 TLS(Transport Layer Security)安全配置集来定义各种 OpenShift Container Platform 组件需要哪些 TLS 密码。OpenShift Container Platform TLS 安全配置集基于 Mozilla 推荐的配置

您可以为每个组件指定以下 TLS 安全配置集之一:

表 9.1. TLS 安全配置集
profile描述

Old

此配置集用于旧的客户端或库。该配置集基于旧的向后兼容性建议配置。

Old 配置集要求最低 TLS 版本 1.0。

注意

对于 Ingress Controller,最小 TLS 版本从 1.0 转换为 1.1。

Intermediate

这个配置集是大多数客户端的建议配置。它是 Ingress Controller、kubelet 和 control plane 的默认 TLS 安全配置集。该配置集基于 Intermediate 兼容性推荐的配置。

Intermediate 配置集需要最小 TLS 版本 1.2。

Modern

此配置集主要用于不需要向后兼容的现代客户端。这个配置集基于 Modern 兼容性推荐的配置。

Modern 配置集需要最低 TLS 版本 1.3。

Custom

此配置集允许您定义要使用的 TLS 版本和密码。

警告

使用 Custom 配置集时要谨慎,因为无效的配置可能会导致问题。

注意

当使用预定义的配置集类型时,有效的配置集配置可能会在发行版本之间有所改变。例如,使用在版本 X.Y.Z 中部署的 Intermediate 配置集指定了一个规格,升级到版本 X.Y.Z+1 可能会导致应用新的配置集配置,从而导致推出部署。

9.3.1.2. 为 Ingress Controller 配置 TLS 安全配置集

要为 Ingress Controller 配置 TLS 安全配置集,请编辑 IngressController 自定义资源(CR)来指定预定义或自定义 TLS 安全配置集。如果没有配置 TLS 安全配置集,则默认值基于为 API 服务器设置的 TLS 安全配置集。

配置 Old TLS 安全配置集的 IngressController CR 示例

apiVersion: operator.openshift.io/v1
kind: IngressController
 ...
spec:
  tlsSecurityProfile:
    old: {}
    type: Old
 ...

TLS 安全配置集定义 Ingress Controller 的 TLS 连接的最低 TLS 版本和 TLS 密码。

您可以在 Status.Tls ProfileSpec.Tls Security Profile 下看到 IngressController 自定义资源(CR)中配置的 TLS 安全配置集的密码和最小 TLS 版本。对于 Custom TLS 安全配置集,这两个参数下列出了特定的密码和最低 TLS 版本。

注意

HAProxy Ingress Controller 镜像支持 TLS 1.3Modern 配置集。

Ingress Operator 还会将 OldCustom 配置集的 TLS 1.0 转换为 1.1

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 编辑 openshift-ingress-operator 项目中的 IngressController CR,以配置 TLS 安全配置集:

    $ oc edit IngressController default -n openshift-ingress-operator
  2. 添加 spec.tlsSecurityProfile 字段:

    Custom 配置集的 IngressController CR 示例

    apiVersion: operator.openshift.io/v1
    kind: IngressController
     ...
    spec:
      tlsSecurityProfile:
        type: Custom 1
        custom: 2
          ciphers: 3
          - ECDHE-ECDSA-CHACHA20-POLY1305
          - ECDHE-RSA-CHACHA20-POLY1305
          - ECDHE-RSA-AES128-GCM-SHA256
          - ECDHE-ECDSA-AES128-GCM-SHA256
          minTLSVersion: VersionTLS11
     ...

    1
    指定 TLS 安全配置集类型(OldIntermediateCustom)。默认值为 Intermediate
    2
    为所选类型指定适当的字段:
    • old: {}
    • intermediate: {}
    • custom:
    3
    对于 custom 类型,请指定 TLS 密码列表和最低接受的 TLS 版本。
  3. 保存文件以使改变生效。

验证

  • 验证 IngressController CR 中是否设置了配置集:

    $ oc describe IngressController default -n openshift-ingress-operator

    输出示例

    Name:         default
    Namespace:    openshift-ingress-operator
    Labels:       <none>
    Annotations:  <none>
    API Version:  operator.openshift.io/v1
    Kind:         IngressController
     ...
    Spec:
     ...
      Tls Security Profile:
        Custom:
          Ciphers:
            ECDHE-ECDSA-CHACHA20-POLY1305
            ECDHE-RSA-CHACHA20-POLY1305
            ECDHE-RSA-AES128-GCM-SHA256
            ECDHE-ECDSA-AES128-GCM-SHA256
          Min TLS Version:  VersionTLS11
        Type:               Custom
     ...

9.3.1.3. 配置 mutual TLS 身份验证

您可以通过设置 spec.clientTLS 值,将 Ingress Controller 配置为启用 mutual TLS (mTLS) 身份验证。clientTLS 值将 Ingress Controller 配置为验证客户端证书。此配置包括设置 clientCA 值,这是对配置映射的引用。配置映射包含 PEM 编码的 CA 证书捆绑包,用于验证客户端的证书。另外,您还可以配置证书主题过滤器列表。

如果 clientCA 值指定了 X509v3 证书撤销列表 (CRL) 分发点,Ingress Operator 会下载并管理基于每个提供的证书中指定的 HTTP URI X509v3 CRL 分发点的 CRL 配置映射。Ingress Controller 在 mTLS/TLS 协商过程中使用此配置映射。不提供有效证书的请求将被拒绝。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您有一个 PEM 编码的 CA 证书捆绑包。
  • 如果您的 CA 捆绑包引用 CRL 发布点,还必须将最终用户或叶证书包含在客户端 CA 捆绑包中。此证书必须在 CRL 分发点下包含 HTTP URI,如 RFC 5280 所述。例如:

     Issuer: C=US, O=Example Inc, CN=Example Global G2 TLS RSA SHA256 2020 CA1
             Subject: SOME SIGNED CERT            X509v3 CRL Distribution Points:
                    Full Name:
                      URI:http://crl.example.com/example.crl

流程

  1. openshift-config 命名空间中,从 CA 捆绑包创建配置映射:

    $ oc create configmap \
       router-ca-certs-default \
       --from-file=ca-bundle.pem=client-ca.crt \1
       -n openshift-config
    1
    配置映射数据键必须是 ca-bundle.pem,数据值必须是 PEM 格式的 CA 证书。
  2. 编辑 openshift-ingress-operator 项目中的 IngressController 资源:

    $ oc edit IngressController default -n openshift-ingress-operator
  3. 添加 spec.clientTLS 字段和子字段来配置 mutual TLS:

    指定过滤模式的 clientTLS 配置集的 IngressController CR 示例

      apiVersion: operator.openshift.io/v1
      kind: IngressController
      metadata:
        name: default
        namespace: openshift-ingress-operator
      spec:
        clientTLS:
          clientCertificatePolicy: Required
          clientCA:
            name: router-ca-certs-default
          allowedSubjectPatterns:
          - "^/CN=example.com/ST=NC/C=US/O=Security/OU=OpenShift$"

  4. 可选,输入以下命令获取 allowedSubjectPatterns 的可辨识名称 (DN)。
$ openssl  x509 -in custom-cert.pem  -noout -subject
subject= /CN=example.com/ST=NC/C=US/O=Security/OU=OpenShift

9.4. 查看默认的 Ingress Controller

Ingress Operator 是 OpenShift Container Platform 的一个核心功能,开箱即用。

每个 OpenShift Container Platform 新安装都有一个名为 default 的 ingresscontroller。它可以通过额外的 Ingress Controller 来补充。如果删除了默认的 ingresscontroller,Ingress Operator 会在一分钟内自动重新创建。

流程

  • 查看默认的 Ingress Controller:

    $ oc describe --namespace=openshift-ingress-operator ingresscontroller/default

9.5. 查看 Ingress Operator 状态

您可以查看并检查 Ingress Operator 的状态。

流程

  • 查看您的 Ingress Operator 状态:

    $ oc describe clusteroperators/ingress

9.6. 查看 Ingress Controller 日志

您可以查看 Ingress Controller 日志。

流程

  • 查看 Ingress Controller 日志:

    $ oc logs --namespace=openshift-ingress-operator deployments/ingress-operator -c <container_name>

9.7. 查看 Ingress Controller 状态

您可以查看特定 Ingress Controller 的状态。

流程

  • 查看 Ingress Controller 的状态:

    $ oc describe --namespace=openshift-ingress-operator ingresscontroller/<name>

9.8. 创建自定义 Ingress Controller

作为集群管理员,您可以创建新的自定义 Ingress Controller。因为默认 Ingress Controller 在 OpenShift Container Platform 更新过程中可能会改变,所以创建自定义 Ingress Controller 以在集群更新中手动保留配置会很有用。

这个示例为自定义 Ingress Controller 提供最小规格。要进一步定制您的自定义 Ingress Controller,请参阅"配置 Ingress Controller"。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 创建定义自定义 IngressController 对象的 YAML 文件:

    custom-ingress-controller.yaml 文件示例

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
        name: <custom_name> 1
        namespace: openshift-ingress-operator
    spec:
        defaultCertificate:
            name: <custom-ingress-custom-certs> 2
        replicas: 1 3
        domain: <custom_domain> 4

    1
    IngressController 对象指定自定义名称
    2
    使用自定义通配符证书指定 secret 名称。
    3
    最小副本需要是 ONE
    4
    指定您的域名的域。IngressController 对象中指定的域以及用于证书的域必须匹配。例如,如果 domain 值为 "custom_domain.mycompany.com",则证书必须具有 SAN *.custom_domain.mycompany.com(在域中添加了 *.)。
  2. 运行以下命令来创建对象:

    $ oc create -f custom-ingress-controller.yaml

9.9. 配置 Ingress Controller

9.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.crttls.key 文件中。替换 tls.crttls.key 的实际路径名。在创建 Secret 资源并在 IngressController CR 中引用它时,您也可以将 custom-certs-default 替换成另一名称。

注意

此操作会导致使用滚动部署策略重新部署 Ingress Controller。

  1. 使用 tls.crttls.key 文件,创建在 openshift-ingress 命名空间中包含自定义证书的 Secret 资源。

    $ oc --namespace openshift-ingress create secret tls custom-certs-default --cert=tls.crt --key=tls.key
  2. 更新 IngressController CR,以引用新的证书 Secret:

    $ oc patch --type=merge --namespace openshift-ingress-operator ingresscontrollers/default \
      --patch '{"spec":{"defaultCertificate":{"name":"custom-certs-default"}}}'
  3. 验证更新是否已生效:

    $ 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 的部署以使用自定义证书。

9.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

9.9.3. 自动扩展 Ingress Controller

自动缩放 Ingress Controller 以动态满足路由性能或可用性要求,如提高吞吐量的要求。以下流程提供了扩展默认 IngressController 的示例。

先决条件

  1. 已安装 OpenShift CLI (oc)。
  2. 您可以使用具有 cluster-admin 角色的用户访问 OpenShift Container Platform 集群。
  3. 已安装自定义 Metrics Autoscaler Operator。
  4. 您位于 openshift-ingress-operator 项目命名空间中。

流程

  1. 运行以下命令,创建一个服务帐户来与 Thanos 进行身份验证:

    $ oc create serviceaccount thanos && oc describe serviceaccount thanos

    输出示例

    Name:                thanos
    Namespace:           openshift-ingress-operator
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  thanos-dockercfg-b4l9s
    Mountable secrets:   thanos-dockercfg-b4l9s
    Tokens:              thanos-token-c422q
    Events:              <none>

  2. 可选:使用以下命令手动创建服务帐户令牌:

    重要

    如果您禁用 ImageRegistry 功能,或者在 Cluster Image Registry Operator 配置中禁用集成的 OpenShift 镜像 registry,则不会为每个服务帐户生成镜像 pull secret。在这种情况下,您必须执行此步骤。

    $ oc apply -f - <<EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: thanos-token
      annotations:
        kubernetes.io/service-account.name: thanos
      type: kubernetes.io/service-account-token
    EOF
  3. 使用服务帐户的令牌,在 openshift-ingress-operator 命名空间中定义一个 TriggerAuthentication 对象。

    1. 运行以下命令,定义包含 secret 的变量 secret:

      $ secret=$(oc get secret | grep thanos-token | head -n 1 | awk '{ print $1 }')
    2. 创建 TriggerAuthentication 对象,并将 secret 变量的值传递给 TOKEN 参数:

      $ oc process TOKEN="$secret" -f - <<EOF | oc apply -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
  4. 创建并应用角色以从 Thanos 读取指标:

    1. 创建一个新角色 thanos-metrics-reader.yaml,从 pod 和节点读取指标:

      thanos-metrics-reader.yaml

      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: thanos-metrics-reader
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        - nodes
        verbs:
        - get
      - apiGroups:
        - metrics.k8s.io
        resources:
        - pods
        - nodes
        verbs:
        - get
        - list
        - watch
      - apiGroups:
        - ""
        resources:
        - namespaces
        verbs:
        - get

    2. 运行以下命令来应用新角色:

      $ oc apply -f thanos-metrics-reader.yaml
  5. 输入以下命令在服务帐户中添加新角色:

    $ oc adm policy 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 命名空间中的查询,该命名空间需要此参数。

  6. 创建一个新的 ScaledObject YAML 文件 ingress-autoscaler.yaml,该文件以默认 Ingress Controller 部署为目标:

    ScaledObject 定义示例

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: ingress-scaler
    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

    1
    要目标的自定义资源。在本例中,Ingress Controller。
    2
    可选:最大副本数。如果省略此字段,则默认最大值设置为 100 个副本。
    3
    openshift-monitoring 命名空间中的 Thanos 服务端点。
    4
    Ingress Operator 命名空间。
    5
    此表达式评估为,部署的集群中存在很多 worker 节点。
    重要

    如果使用跨命名空间查询,您必须在 serverAddress 字段中目标端口 9091 而不是端口 9092。您还必须有升级的特权,才能从此端口读取指标。

  7. 运行以下命令来应用自定义资源定义:

    $ oc apply -f ingress-autoscaler.yaml

验证

  • 运行以下命令,验证默认 Ingress Controller 是否已扩展以匹配 kube-state-metrics 查询返回的值:

    • 使用 grep 命令搜索 Ingress Controller YAML 文件以查找副本:

      $ oc get 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

9.9.4. 扩展 Ingress Controller

手动扩展 Ingress Controller 以满足路由性能或可用性要求,如提高吞吐量的要求。oc 命令用于扩展 IngressController 资源。以下流程提供了扩展默认 IngressController 的示例。

注意

扩展不是立刻就可以完成的操作,因为它需要时间来创建所需的副本数。

流程

  1. 查看默认 IngressController 的当前可用副本数:

    $ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'

    输出示例

    2

  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

  3. 验证默认 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 值。

9.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.loggingspec.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

9.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 配置为一个适当的高值。

9.9.7. 配置 Ingress Controller 以使用内部负载均衡器

当在云平台上创建 Ingress Controller 时,Ingress Controller 默认由一个公共云负载均衡器发布。作为管理员,您可以创建一个使用内部云负载均衡器的 Ingress Controller。

警告

如果云供应商是 Microsoft Azure,则必须至少有一个指向节点的公共负载均衡器。如果不这样做,所有节点都将丢失到互联网的出站连接。

重要

如果要更改 IngressControllerscope,您可以在创建自定义资源(CR)后更改 .spec.endpointPublishingStrategy.loadBalancer.scope 参数。

图 9.1. LoadBalancer 图表

OpenShift Container Platform Ingress LoadBalancerService 端点发布策略

上图显示了与 OpenShift Container Platform Ingress LoadBalancerService 端点发布策略相关的以下概念:

  • 您可以使用 OpenShift Ingress Controller Load Balancer 在外部使用云供应商负载均衡器或内部加载负载。
  • 您可以使用负载均衡器的单个 IP 地址以及更熟悉的端口,如 8080 和 4200,如图形中所述的集群所示。
  • 来自外部负载均衡器的流量定向到 pod,并由负载均衡器管理,如下节点的实例中所述。有关实现详情请查看 Kubernetes 服务文档

先决条件

  • 安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 在名为 <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
    1
    <name> 替换为 IngressController 对象的名称。
    2
    指定控制器发布的应用程序的 domain
    3
    指定一个 Internal 值以使用内部负载均衡器。
  2. 运行以下命令,创建上一步中定义的 Ingress Controller:

    $ oc create -f <name>-ingress-controller.yaml 1
    1
    <name> 替换为 IngressController 对象的名称。
  3. 可选:通过运行以下命令确认创建了 Ingress Controller:

    $ oc --all-namespaces=true get ingresscontrollers

9.9.8. 在 GCP 上为 Ingress Controller 配置全局访问

在带有一个内部负载均衡器的 GCP 上创建的 Ingress Controller 会为服务生成一个内部 IP 地址。集群管理员可指定全局访问选项,该选项可启用同一 VPC 网络内任何区域中的客户端作为负载均衡器,以访问集群上运行的工作负载。

如需更多信息,请参阅 GCP 文档以了解全局访问

先决条件

  • 您已在 GCP 基础架构上部署了 OpenShift Container Platform 集群。
  • 已将 Ingress Controller 配置为使用内部负载均衡器。
  • 已安装 OpenShift CLI(oc)。

流程

  1. 配置 Ingress Controller 资源,以允许全局访问。

    注意

    您还可以创建 Ingress Controller 并指定全局访问选项。

    1. 配置 Ingress Controller 资源:

      $ oc -n openshift-ingress-operator edit ingresscontroller/default
    2. 编辑 YAML 文件:

      clientAccess 配置为 Global 的示例

        spec:
          endpointPublishingStrategy:
            loadBalancer:
              providerParameters:
                gcp:
                  clientAccess: Global 1
                type: GCP
              scope: Internal
            type: LoadBalancerService

      1
      gcp.clientAccess 设置为 Global
    3. 保存文件以使改变生效。
  2. 运行以下命令,以验证该服务是否允许全局访问:

    $ oc -n openshift-ingress edit svc/router-default -o yaml

    输出显示,全局访问已为带有注解 networking.gke.io/internal-load-balancer-allow-global-access 的 GCP 启用。

9.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

9.9.10. 将集群的默认 Ingress Controller 配置为内部

您可以通过删除并重新它来将默认 Ingress Controller 配置为内部。

警告

如果云供应商是 Microsoft Azure,则必须至少有一个指向节点的公共负载均衡器。如果不这样做,所有节点都将丢失到互联网的出站连接。

重要

如果要更改 IngressControllerscope,您可以在创建自定义资源(CR)后更改 .spec.endpointPublishingStrategy.loadBalancer.scope 参数。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 通过删除并重新创建集群,将 默认 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

9.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

9.9.12. 使用通配符路由

HAProxy Ingress Controller 支持通配符路由。Ingress Operator 使用 wildcardPolicy 来配置 Ingress Controller 的 ROUTER_ALLOW_WILDCARD_ROUTES 环境变量。

Ingress Controller 的默认行为是接受采用 None 通配符策略的路由,该策略与现有 IngressController 资源向后兼容。

流程

  1. 配置通配符策略。

    1. 使用以下命令来编辑 IngressController 资源:

      $ oc edit IngressController
    2. spec 下,将 wildcardPolicy 字段设置 为 WildcardsDisallowedWildcardsAllowed

      spec:
        routeAdmission:
          wildcardPolicy: WildcardsDisallowed # or WildcardsAllowed

9.9.13. HTTP 标头配置

OpenShift Container Platform 提供了不同的使用 HTTP 标头的方法。在设置或删除标头时,您可以使用 Ingress Controller 中的特定字段或单独的路由来修改请求和响应标头。您还可以使用路由注解设置某些标头。配置标头的各种方法在协同工作时可能会带来挑战。

注意

您只能在 IngressControllerRoute CR 中设置或删除标头,您无法附加它们。如果使用值设置 HTTP 标头,则该值必须已完成,且在以后不需要附加。在附加标头(如 X-Forwarded-For 标头)时,请使用 spec.httpHeaders.forwardedHeaderPolicy 字段,而不是 spec.httpHeaders.actions

9.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 或路由中定义的任何操作都覆盖使用路由注解设置的值。

9.9.13.2. 特殊情况标头

以下标头可能会阻止完全被设置或删除,或者在特定情况下允许:

表 9.2. 特殊情况标头配置选项
标头名称使用 IngressController spec 进行配置使用 Route 规格进行配置禁止的原因使用其他方法进行配置

proxy

proxy HTTP 请求标头可以通过将标头值注入 HTTP_PROXY 环境变量来利用这个安全漏洞的 CGI 应用程序。proxy HTTP 请求标头也是非标准的,在配置期间容易出错。

主机

当使用 IngressController CR 设置 host HTTP 请求标头时,HAProxy 在查找正确的路由时可能会失败。

strict-transport-security

strict-transport-security HTTP 响应标头已使用路由注解处理,不需要单独的实现。

是: haproxy.router.openshift.io/hsts_header 路由注解

cookieset-cookie

HAProxy 集的 Cookie 用于会话跟踪,用于将客户端连接映射到特定的后端服务器。允许设置这些标头可能会影响 HAProxy 的会话关联,并限制 HAProxy 的 Cookie 的所有权。

是:

  • haproxy.router.openshift.io/disable_cookie 路由注解
  • haproxy.router.openshift.io/cookie_name 路由注解

9.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 集群。

流程

  1. 编辑 Ingress Controller 资源:

    $ oc -n openshift-ingress-operator edit ingresscontroller/default
  2. 将 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
    1
    要在 HTTP 标头上执行的操作列表。
    2
    您要更改的标头类型。在本例中,请求标头。
    3
    您要更改的标头的名称。有关您可以设置或删除的可用标头列表,请参阅 HTTP 标头配置
    4
    在标头中执行的操作类型。此字段可以具有 SetDelete 的值。
    5
    在设置 HTTP 标头时,您必须提供一个 value。该值可以是该标头的可用指令列表中的字符串,如 DENY,也可以是使用 HAProxy 的动态值语法来解释的动态值。在这种情况下,会添加一个动态值。
    注意

    对于 HTTP 响应设置动态标头值,允许示例 fetchers 是 res.hdrssl_c_der。对于 HTTP 请求设置动态标头值,允许示例获取器为 req.hdrssl_c_der。请求和响应动态值都可以使用 lowerbase64 转换器。

  3. 保存文件以使改变生效。

9.9.15. 使用 X-Forwarded 标头

您可以将 HAProxy Ingress Controller 配置为指定如何处理 HTTP 标头的策略,其中包括 ForwardedX-Forwarded-For。Ingress Operator 使用 HTTPHeaders 字段配置 Ingress Controller 的 ROUTER_SET_FORWARDED_HEADERS 环境变量。

流程

  1. 为 Ingress Controller 配置 HTTPHeaders 字段。

    1. 使用以下命令来编辑 IngressController 资源:

      $ oc edit IngressController
    2. spec 下,将 HTTPHeaders 策略字段设置为 AppendReplaceIfNoneNever:

      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-nonehaproxy.router.openshift.io/set-forwarded-headers: never

    注意

    您可以根据每个路由设置 haproxy.router.openshift.io/set-forwarded-headers 注解,独立于 Ingress Controller 的全局设置值。

9.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"

9.9.17. 为 Ingress Controller 配置 PROXY 协议

当 Ingress Controller 使用 HostNetworkNodePortService私有 端点发布策略类型时,集群管理员可以配置 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 路由器设置 ForwardedX-Forwarded-For 标头,以便应用程序工作负载检查客户端源 IP 地址。

如需有关 Ingress 访问日志的更多信息,请参阅"配置 Ingress 访问日志"。

使用 LoadBalancerService 端点发布策略类型时不支持为 Ingress Controller 配置 PROXY 协议。这个限制是因为当 OpenShift Container Platform 在云平台中运行时,Ingress Controller 指定应使用服务负载均衡器,Ingress Operator 配置负载均衡器服务并根据保留源地址的平台要求启用 PROXY 协议。

重要

您必须将 OpenShift Container Platform 和外部负载均衡器配置为使用 PROXY 协议或 TCP。

云部署不支持此功能。这个限制是因为当 OpenShift Container Platform 在云平台中运行时,Ingress Controller 指定应使用服务负载均衡器,Ingress Operator 配置负载均衡器服务并根据保留源地址的平台要求启用 PROXY 协议。

重要

您必须将 OpenShift Container Platform 和外部负载均衡器配置为使用 PROXY 协议或使用传输控制协议(TCP)。

先决条件

  • 已创建一个 Ingress Controller。

流程

  1. 在 CLI 中输入以下命令来编辑 Ingress Controller 资源:

    $ oc -n openshift-ingress-operator edit ingresscontroller/default
  2. 设置 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
      # ...

9.9.18. 使用 appsDomain 选项指定备选集群域

作为集群管理员,您可以通过配置 appsDomain 字段来为用户创建的路由指定默认集群域替代内容。appsDomain 字段是 OpenShift Container Platform 使用的可选域,而不是默认值,它在 domain 字段中指定。如果您指定了其它域,它会覆盖为新路由确定默认主机的目的。

例如,您可以将您公司的 DNS 域用作集群中运行的应用程序的路由和入口的默认域。

先决条件

  • 已部署 OpenShift Container Platform 集群。
  • 已安装 oc 命令行界面。

流程

  1. 通过为用户创建的路由指定备选默认域来配置 appsDomain 字段。

    1. 编辑 ingress 集群资源 :

      $ oc edit ingresses.config/cluster -o yaml
    2. 编辑 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

      1
      指定默认域。您不能在安装后修改默认域。
      2
      可选:用于应用程序路由的 OpenShift Container Platform 基础架构域。您可以使用 测试 等替代前缀 apps,而不是默认前缀。
  2. 通过公开路由并验证路由域更改,验证现有路由是否包含 appsDomain 字段中指定的域名:

    注意

    在公开路由前,等待 openshift-apiserver 完成滚动更新。

    1. 公开路由:

      $ 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

9.9.19. 转换 HTTP 标头的大小写

默认情况下,HAProxy HTTP 的标头名称是小写的,例如,会将 Host: xyz.com 更改为 host: xyz.com。如果旧应用程序对 HTTP 标头名称中使用大小写敏感,请使用 Ingress Controller spec.httpHeaders.headerNameCaseAdjustments API 字段进行调整来适应旧的应用程序,直到它们被改变。

重要

由于 OpenShift Container Platform 包含 HAProxy 2.6,因此请确保在升级前使用 spec.httpHeaders.headerNameCaseAdjustments 添加必要的配置。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。

流程

作为集群管理员,您可以使用 oc patch 命令,或设置 Ingress Controller YAML 文件中的 HeaderNameCaseAdjustments 字段来转换 HTTP 标头的大小写。

  • 使用 oc patch 命令设置一个 HTTP 标头的大小写情况。

    1. 输入 oc patch 命令将 HTTP host 标头改为 Host

      $ oc -n openshift-ingress-operator patch ingresscontrollers/default --type=merge --patch='{"spec":{"httpHeaders":{"headerNameCaseAdjustments":["Host"]}}}'
    2. 注解应用程序的路由:

      $ oc annotate routes/my-application haproxy.router.openshift.io/h1-adjust-case=true

      然后,Ingress Controller 会根据指定调整 host 请求标头。

  • 通过配置 Ingress Controller YAML 文件,使用 HeaderNameCaseAdjustments 字段指定调整。

    1. 以下 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

    2. 以下示例路由中,使用 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。

9.9.20. 使用路由器压缩

您可以将 HAProxy Ingress Controller 配置为为特定 MIME 类型全局指定路由器压缩。您可以使用 mimeTypes 变量定义压缩应用到的 MIME 类型的格式。类型包括:application, image, message, multipart, text, video, 或带有一个 "X-" 前缀的自定义类型。要查看 MIME 类型和子类型的完整表示法,请参阅 RFC1341

注意

为压缩分配的内存可能会影响最大连接。此外,对大型缓冲区的压缩可能导致延迟,如非常复杂的正则表达式或较长的正则表达式列表。

并非所有 MIME 类型从压缩中受益,但 HAProxy 仍然使用资源在指示时尝试压缩。通常而言,文本格式(如 html、css 和 js)与压缩格式获益,但已经压缩的格式(如图像、音频和视频)可能会因为需要压缩操作而无法获得太多的好处。

流程

  1. 为 Ingress Controller 配置 httpCompression 字段。

    1. 使用以下命令来编辑 IngressController 资源:

      $ oc edit -n openshift-ingress-operator ingresscontrollers/default
    2. 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"
         ...

9.9.21. 公开路由器指标

您可以在默认统计端口 1936 上以 Prometheus 格式公开 HAProxy 路由器指标。外部指标收集和聚合系统(如 Prometheus)可以访问 HAProxy 路由器指标。您可以在浏览器中以 HTML 的形式和以逗号分隔的值 (CSV) 格式查看 HAProxy 路由器指标。

先决条件

  • 您已将防火墙配置为访问默认统计数据端口 1936。

流程

  1. 运行以下命令来获取路由器 pod 名称:

    $ oc get pods -n openshift-ingress

    输出示例

    NAME                              READY   STATUS    RESTARTS   AGE
    router-default-76bfffb66c-46qwp   1/1     Running   0          11h

  2. 获取路由器的用户名和密码,路由器 Pod 存储在 /var/lib/haproxy/conf/metrics-auth/statsUsername/var/lib/haproxy/conf/metrics-auth/statsPassword 文件中:

    1. 运行以下命令来获取用户名:

      $ oc rsh <router_pod_name> cat metrics-auth/statsUsername
    2. 运行以下命令来获取密码:

      $ oc rsh <router_pod_name> cat metrics-auth/statsPassword
  3. 运行以下命令,获取路由器 IP 和指标证书:

    $ oc describe pod <router_pod>
  4. 运行以下命令,以 Prometheus 格式获取原始统计信息:

    $ curl -u <user>:<password> http://<router_IP>:<stats_port>/metrics
  5. 运行以下命令来安全地访问指标:

    $ curl -u user:password https://<router_IP>:<stats_port>/metrics -k
  6. 运行以下命令,访问默认的 stats 端口 1936:

    $ curl -u <user>:<password> http://<router_IP>:<stats_port>/metrics

    例 9.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
    ...
  7. 通过在浏览器中输入以下 URL 来启动 stats 窗口:

    http://<user>:<password>@<router_IP>:<stats_port>
  8. 可选:通过在浏览器中输入以下 URL 来获取 CSV 格式的统计信息:

    http://<user>:<password>@<router_ip>:1936/metrics;csv

9.9.22. 自定义 HAProxy 错误代码响应页面

作为集群管理员,您可以为 503、404 或两个错误页面指定自定义错误代码响应页面。当应用 Pod 没有运行时,HAProxy 路由器会提供一个 503 错误页面,如果请求的 URL 不存在,则 HAProxy 路由器会提供 404 错误页面。例如,如果您自定义 503 错误代码响应页面,则应用 Pod 未运行时会提供页面,并且 HAProxy 路由器为不正确的路由或不存在的路由提供默认的 404 错误代码 HTTP 响应页面。

自定义错误代码响应页面在配置映射中指定,然后修补至 Ingress Controller。配置映射键有两个可用的文件名,如下所示:error-page-503.httperror-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 行结尾。

流程

  1. 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,以便使用正确的信息重新创建它们。

  2. 对 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 命名配置映射。

  3. 显示副本:

    $ oc get cm default-errorpages -n openshift-ingress

    输出示例

    NAME                       DATA   AGE
    default-errorpages         2      25s  1

    1
    配置映射名称示例为 default-errorpages,因为 default Ingress Controller 自定义资源 (CR) 已被修补。
  4. 确认包含自定义错误响应页面的配置映射挂载到路由器卷中,其中配置映射键是具有自定义 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 响应:

  1. 创建测试项目和应用程序:

     $ oc new-project test-ingress
    $ oc new-app django-psql-example
  2. 对于 503 自定义 http 错误代码响应:

    1. 停止应用的所有容器集。
    2. 运行以下 curl 命令或在浏览器中访问路由主机名:

      $ curl -vk <route_hostname>
  3. 对于 404 自定义 http 错误代码响应:

    1. 访问不存在的路由或路由不正确。
    2. 运行以下 curl 命令或在浏览器中访问路由主机名:

      $ curl -vk <route_hostname>
  4. 检查 haproxy.config 文件中的 errorfile 属性是否正确:

    $ oc -n openshift-ingress rsh <router> cat /var/lib/haproxy/conf/haproxy.config | grep errorfile

9.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 配置参数"部分中的表。

9.10. 其他资源

第 10 章 OpenShift Container Platform 中的 Ingress 分片

在 OpenShift Container Platform 中,Ingress Controller 可以服务所有路由,也可以提供路由的子集。默认情况下,Ingress Controller 提供集群中任何命名空间中创建的任何路由。您可以在集群中添加额外的 Ingress Controller,以通过创建 分片来优化路由,这些分片是基于所选特征的路由子集。要将路由标记为分片的成员,请使用 route 或 namespace metadata 字段中的标签。Ingress Controller 使用选择器 (也称为 选择表达式 )从要提供服务的整个路由池中选择路由子集。

当您希望在多个 Ingress Controller 之间负载平衡传入的流量时,当您要隔离到特定 Ingress Controller 的流量或下一部分中描述的各种其他原因时,Ingress 分片很有用。

默认情况下,每个路由都使用集群的默认域。但是,可以将路由配置为使用路由器的域。如需更多信息,请参阅为 Ingress Controller 创建路由

10.1. Ingress Controller 分片

您可以通过向路由、命名空间或两者添加标签,使用 Ingress 分片(也称为路由器分片)在多个路由器之间分发一组路由。Ingress Controller 使用一组对应的选择器来只接受具有指定标签的路由。每个 Ingress 分片都由使用给定选择表达式过滤的路由组成。

Ingress Controller 是网络流量进入集群的主要机制,因此对它们的需求可能非常大。作为集群管理员,您可以对路由进行分片,以达到以下目的:

  • 在 Ingress Controller 或路由器与一些路由之间实现平衡,由此加快对变更的响应。
  • 分配特定的路由,使其具有不同于其它路由的可靠性保证。
  • 允许特定的 Ingress Controller 定义不同的策略。
  • 只允许特定的路由使用其他功能。
  • 在不同的地址上公开不同的路由,例如使内部和外部用户能够看到不同的路由。
  • 在蓝绿部署期间,将流量从应用的一个版本转移到另一个版本。

当 Ingress Controller 被分片时,一个给定路由被接受到组中的零个或多个 Ingress Controller。路由的状态描述了 Ingress Controller 是否已接受它。只有 Ingress Controller 对其分片是唯一的时,才会接受路由。

Ingress Controller 可以使用三个分片方法:

  • 仅将命名空间选择器添加到 Ingress Controller,以便命名空间中带有与命名空间选择器匹配的标签的所有路由都位于 Ingress shard 中。
  • 只向 Ingress Controller 添加路由选择器,因此所有与路由选择器匹配的标签的路由都位于 Ingress 分片中。
  • 将命名空间选择器和路由选择器添加到 Ingress Controller 中,以便使用与命名空间选择器匹配的路由选择器匹配的标签的路由位于 Ingress shard 中。

使用分片,您可以在多个 Ingress Controller 上分发路由子集。这些子集可以是非重叠的,也称为 传统 分片,或是重叠的,也称为 overlapped 分片。

10.1.1. 传统分片示例

Ingress Controller finops-router 使用标签选择器 spec.namespaceSelector.matchLabels.name 设置为 financeops

finops-router 的 YAML 定义示例

apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: finops-router
  namespace: openshift-ingress-operator
spec:
  namespaceSelector:
    matchLabels:
      name:
        - finance
        - ops

第二个 Ingress Controller dev-router 配置有标签选择器 spec.namespaceSelector.matchLabels.name 设置为 dev

dev-router 的 YAML 定义示例

apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: dev-router
  namespace: openshift-ingress-operator
spec:
  namespaceSelector:
    matchLabels:
      name: dev

如果所有应用程序路由都位于单独的命名空间中,每个命名空间都分别使用 name:financename:opsname:dev 标记,此配置会在两个 Ingress Controller 之间有效分发您的路由。不应处理用于控制台、身份验证和其他目的的 OpenShift Container Platform 路由。

在上面的场景中,分片成为分区的一种特殊情况,没有重叠的子集。路由在路由器分片之间划分。

警告

默认 Ingress Controller 继续提供所有路由,除非 namespaceSelectorrouteSelector 字段包含用于排除的路由。有关如何从默认 Ingress Controller 中排除路由的更多信息,请参阅这个 红帽知识库解决方案 和"分片默认 Ingress Controller"。

10.1.2. 重叠的分片示例

除了上例中的 finops-routerdev-router 外,您也具有 devops-router,它被配置为标签选择器 spec.namespaceSelector.matchLabels.name,设置为 devops

devops-router 的 YAML 定义示例

apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: devops-router
  namespace: openshift-ingress-operator
spec:
  namespaceSelector:
    matchLabels:
      name:
        - dev
        - ops

标签为 name:devname:ops 的命名空间中的路由现在由两个不同的 Ingress Controller 服务。使用这个配置,您有重叠的路由子集。

通过重叠的路由子集,您可以创建更复杂的路由规则。例如,您可以在向 devops-router 发送较低优先级的流量时,将优先级更高的流量放入专用的 finops-router

10.1.3. 分片默认 Ingress Controller

创建新的 Ingress shard 后,可能会接受到默认 Ingress Controller 接受的新 Ingress 分片的路由。这是因为默认 Ingress Controller 没有选择器,并默认接受所有路由。

您可以使用命名空间选择器或路由选择器来限制 Ingress Controller 使用特定标签提供路由。以下流程限制默认 Ingress Controller,使用命名空间选择器为新分片的 financeopsdev 提供。这为 Ingress 分片增加了额外的隔离。

重要

您必须在同一 Ingress Controller 上保留所有 OpenShift Container Platform 管理路由。因此,避免在排除这些基本路由的默认 Ingress Controller 中添加额外的选择器。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您以项目管理员身份登录。

流程

  1. 运行以下命令来修改默认 Ingress Controller:

    $ oc edit ingresscontroller -n openshift-ingress-operator default
  2. 编辑 Ingress Controller 以包含一个 namespaceSelector,它排除了任何 financeopsdev 标签的路由:

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: default
      namespace: openshift-ingress-operator
    spec:
      namespaceSelector:
        matchExpressions:
          - key: type
            operator: NotIn
            values:
              - finance
              - ops
              - dev

默认 Ingress Controller 不再提供标记为 name:financename:opsname:dev 的命名空间。

10.1.4. Ingress 分片和 DNS

集群管理员负责为项目中的每个路由器生成单独的 DNS 条目。路由器不会将未知路由转发到另一个路由器。

考虑以下示例:

  • 路由器 A 驻留在主机 192.168.0.5 上,并且具有 *.foo.com 的路由。
  • 路由器 B 驻留在主机 192.168.1.9 上,并且具有 *.example.com 的路由。

单独的 DNS 条目必须将 *.foo.com 解析为托管 Router A 和 *.example.com 的节点到托管路由器 B 的节点:

  • *.foo.com A IN 192.168.0.5
  • *.example.com A IN 192.168.1.9

10.1.5. 通过路由标签(label)配置 Ingress Controller 分片

使用路由标签进行 Ingress Controller 分片,意味着 Ingress Controller 提供由路由选择器选择的任意命名空间中的所有路由。

图 10.1. 使用路由标签进行 Ingress 分片

显示带有不同路由选择器的多个 Ingress Controller 的图,它包括了与给定路由选择器匹配的标签,而不考虑路由所属的命名空间

在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。

流程

  1. 编辑 router-internal.yaml 文件:

    # cat router-internal.yaml
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: sharded
      namespace: openshift-ingress-operator
    spec:
      domain: <apps-sharded.basedomain.example.net> 1
      nodePlacement:
        nodeSelector:
          matchLabels:
            node-role.kubernetes.io/worker: ""
      routeSelector:
        matchLabels:
          type: sharded
    1
    指定 Ingress Controller 使用的域。此域必须与默认 Ingress Controller 域不同。
  2. 应用 Ingress Controller router-internal.yaml 文件:

    # oc apply -f router-internal.yaml

    Ingress Controller 选择具有 type: sharded 标签的任意命名空间中的路由。

  3. 使用 router-internal.yaml 中配置的域创建新路由:

    $ oc expose svc <service-name> --hostname <route-name>.apps-sharded.basedomain.example.net

10.1.6. 使用命名空间标签配置 Ingress Controller 分片

使用命名空间标签进行 Ingress Controller 分片,意味着 Ingress Controller 提供由命名空间选择器选择的任意命名空间中的所有路由。

图 10.2. 使用命名空间标签进行 Ingress 分片

显示多个具有不同命名空间选择器服务路由的 Ingress Controller,这些路由属于命名空间,包含与给定命名空间选择器匹配的标签

在一组 Ingress Controller 之间平衡传入的流量负载时,以及在将流量隔离到特定 Ingress Controller 时,Ingress Controller 分片会很有用处。例如,A 公司的流量使用一个 Ingress Controller,B 公司的流量则使用另外一个 Ingress Controller。

流程

  1. 编辑 router-internal.yaml 文件:

    # cat router-internal.yaml

    输出示例

    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: sharded
      namespace: openshift-ingress-operator
    spec:
      domain: <apps-sharded.basedomain.example.net> 1
      nodePlacement:
        nodeSelector:
          matchLabels:
            node-role.kubernetes.io/worker: ""
      namespaceSelector:
        matchLabels:
          type: sharded

    1
    指定 Ingress Controller 使用的域。此域必须与默认 Ingress Controller 域不同。
  2. 应用 Ingress Controller router-internal.yaml 文件:

    # oc apply -f router-internal.yaml

    Ingress Controller 选择由命名空间选择器选择的具有 type: sharded 标签的任意命名空间中的路由。

  3. 使用 router-internal.yaml 中配置的域创建新路由:

    $ oc expose svc <service-name> --hostname <route-name>.apps-sharded.basedomain.example.net

10.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。

流程

  1. 运行以下命令,创建一个名为 hello-openshift 的项目:

    $ oc new-project hello-openshift
  2. 运行以下命令,在项目中创建 pod:

    $ oc create -f https://raw.githubusercontent.com/openshift/origin/master/examples/hello-openshift/hello-pod.json
  3. 运行以下命令,创建名为 hello-openshift 的服务:

    $ oc expose pod/hello-openshift
  4. 创建名为 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

    1
    标签键及其对应标签值必须与 Ingress Controller 中指定的标签值匹配。在本例中,Ingress Controller 具有标签键和值 type: sharded
    2
    路由将使用 subdomain 字段的值公开。指定 subdomain 字段时,您必须保留主机名未设置。如果您同时指定了 hostsubdomain 字段,则路由将使用 host 字段的值,并忽略 subdomain 字段。
  5. 通过运行以下命令,使用 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

    1
    Ingress Controller 或路由器的主机名用于公开路由。host 字段的值由 Ingress Controller 自动决定,并使用它的域。在本例中,Ingress Controller 的域为 <apps-sharded.basedomain.example.net>
    2
    Ingress Controller 的主机名。
    3
    Ingress Controller 的名称。在本例中,Ingress Controller 的名称为 sharded

其它资源

第 11 章 OpenShift Container Platform 中的 Ingress Node Firewall Operator

Ingress Node Firewall Operator 允许管理员在节点级别管理防火墙配置。

11.1. Ingress Node Firewall Operator

Ingress Node Firewall Operator 通过将守护进程集部署到您在防火墙配置中指定和管理的节点,在节点级别提供入口防火墙规则。要部署守护进程集,请创建一个 IngressNodeFirewallConfig 自定义资源 (CR)。Operator 应用 IngressNodeFirewallConfig CR 来创建入口节点防火墙守护进程集 daemon,它在与 nodeSelector 匹配的所有节点上运行。

您可以配置 IngressNodeFirewall CR 的规则,并使用 nodeSelector 将值设置为 "true" 的集群。

重要

Ingress Node Firewall Operator 仅支持无状态防火墙规则。

不支持原生 XDP 驱动程序的网络接口控制器 (NIC) 将以较低性能运行。

对于 OpenShift Container Platform 4.14 或更高的版本,您必须在 RHEL 9.0 或更高版本上运行 Ingress Node Firewall Operator。

带有默认 OpenShift 安装或 Red Hat OpenShift Service on AWS (ROSA)的 Amazon Web Services (AWS)不支持 Ingress Node Firewall Operator。如需有关 Red Hat OpenShift Service on AWS 支持和入口的更多信息,请参阅 Red Hat OpenShift Service on AWS 中的 Ingress Operator

11.2. 安装 Ingress Node Firewall Operator

作为集群管理员,您可以使用 OpenShift Container Platform CLI 或 Web 控制台安装 Ingress Node Firewall Operator。

11.2.1. 使用 CLI 安装 Ingress Node Firewall Operator

作为集群管理员,您可以使用 CLI 安装 Operator。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 有管理员特权的帐户。

流程

  1. 运行以下命令来创建 openshift-ingress-node-firewall 命名空间:

    $ cat << EOF| oc create -f -
    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        pod-security.kubernetes.io/enforce: privileged
        pod-security.kubernetes.io/enforce-version: v1.24
      name: openshift-ingress-node-firewall
    EOF
  2. 运行以下命令来创建 OperatorGroup CR:

    $ cat << EOF| oc create -f -
    apiVersion: operators.coreos.com/v1
    kind: OperatorGroup
    metadata:
      name: ingress-node-firewall-operators
      namespace: openshift-ingress-node-firewall
    EOF
  3. 订阅 Ingress Node Firewall Operator。

    1. 要为 Ingress Node Firewall Operator 创建 Subscription CR,请输入以下命令:

      $ cat << EOF| oc create -f -
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: ingress-node-firewall-sub
        namespace: openshift-ingress-node-firewall
      spec:
        name: ingress-node-firewall
        channel: stable
        source: redhat-operators
        sourceNamespace: openshift-marketplace
      EOF
  4. 要验证是否已安装 Operator,请输入以下命令:

    $ oc get ip -n openshift-ingress-node-firewall

    输出示例

    NAME            CSV                                         APPROVAL    APPROVED
    install-5cvnz   ingress-node-firewall.4.15.0-202211122336   Automatic   true

  5. 要验证 Operator 的版本,请输入以下命令:

    $ oc get csv -n openshift-ingress-node-firewall

    输出示例

    NAME                                        DISPLAY                          VERSION               REPLACES                                    PHASE
    ingress-node-firewall.4.15.0-202211122336   Ingress Node Firewall Operator   4.15.0-202211122336   ingress-node-firewall.4.15.0-202211102047   Succeeded

11.2.2. 使用 Web 控制台安装 Ingress Node Firewall Operator

作为集群管理员,您可以使用 Web 控制台安装 Operator。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 有管理员特权的帐户。

流程

  1. 安装 Ingress Node Firewall Operator:

    1. 在 OpenShift Container Platform Web 控制台中,点击 OperatorsOperatorHub
    2. 从可用的 Operator 列表中选择 Ingress Node Firewall Operator,然后点 Install
    3. Install Operator 页面中,在 Installed Namespace 下选择 Operator recommended Namespace
    4. Install
  2. 验证 Ingress Node Firewall Operator 是否已成功安装:

    1. 导航到 OperatorsInstalled Operators 页面。
    2. 确保 openshift-ingress-node-firewall 项目中列出的 Ingress Node Firewall OperatorStatusInstallSucceeded

      注意

      在安装过程中,Operator 可能会显示 Failed 状态。如果安装过程结束后有 InstallSucceeded 信息,您可以忽略这个 Failed 信息。

      如果 Operator 没有 InstallSucceeded 状态,请按照以下步骤进行故障排除:

      • 检查 Operator SubscriptionsInstall Plans 选项卡中的 Status 项中是否有任何错误。
      • 进入到 WorkloadsPods 页面,在 openshift-ingress-node-firewall 项目中检查 pod 的日志。
      • 检查 YAML 文件的命名空间。如果缺少注解,您可以使用以下命令将注解 workload.openshift.io/allowed=management 添加到 Operator 命名空间中:

        $ oc annotate ns/openshift-ingress-node-firewall workload.openshift.io/allowed=management
        注意

        对于单节点 OpenShift 集群,openshift-ingress-node-firewall 命名空间需要 workload.openshift.io/allowed=management 注解。

11.3. 部署 Ingress Node Firewall Operator

前提条件

  • 已安装 Ingress Node Firewall Operator。

流程

要拒绝 Ingress Node Firewall Operator,请创建一个 IngressNodeFirewallConfig 自定义资源,该资源将部署 Operator 的守护进程集。您可以通过应用防火墙规则,将一个或多个 IngressNodeFirewall CRD 部署到节点。

  1. openshift-ingress-node-firewall 命名空间中创建 IngressNodeFirewallConfig,名为 ingressnodefirewallconfig
  2. 运行以下命令来部署 Ingress Node Firewall Operator 规则:

    $ oc apply -f rule.yaml

11.3.1. Ingress 节点防火墙配置对象

下表中描述了 Ingress Node Firewall 配置对象的字段:

表 11.1. Ingress 节点防火墙配置对象
字段类型描述

metadata.name

string

CR 对象的名称。防火墙规则对象的名称必须是 ingressnodefirewallconfig

metadata.namespace

string

Ingress Firewall Operator CR 对象的命名空间。IngressNodeFirewallConfig CR 必须在 openshift-ingress-node-firewall 命名空间中创建。

spec.nodeSelector

string

通过指定节点标签 (label) 用于目标节点的节点选择约束。例如:

spec:
  nodeSelector:
    node-role.kubernetes.io/worker: ""
注意

nodeSelector 中使用的一个标签必须与节点上的标签匹配,以便守护进程集启动。例如,如果节点标签 node-role.kubernetes.io/workernode-type.kubernetes.io/vm 应用到某个节点,则必须使用 nodeSelector 至少设置一个标签设置来使守护进程启动。

注意

Operator 使用 CR,并在与 nodeSelector 匹配的所有节点上创建一个入口节点防火墙守护进程集。

Ingress Node Firewall Operator 示例配置

以下示例中指定了完整的 Ingress Node 防火墙配置:

Ingress 节点防火墙配置对象示例

apiVersion: ingressnodefirewall.openshift.io/v1alpha1
kind: IngressNodeFirewallConfig
metadata:
  name: ingressnodefirewallconfig
  namespace: openshift-ingress-node-firewall
spec:
  nodeSelector:
    node-role.kubernetes.io/worker: ""

注意

Operator 使用 CR,并在与 nodeSelector 匹配的所有节点上创建一个入口节点防火墙守护进程集。

11.3.2. Ingress 节点防火墙规则对象

下表中描述了 Ingress Node Firewall 规则对象的字段:

表 11.2. Ingress 节点防火墙规则对象
字段类型描述

metadata.name

string

CR 对象的名称。

interfaces

数组

此对象的字段指定要应用防火墙规则的接口。例如,- en0- en1

nodeSelector

数组

您可以使用 nodeSelector 来选择节点来应用防火墙规则。将指定 nodeselector 标签的值设置为 true 以应用该规则。

ingress

object

Ingress 允许您配置允许从外部访问集群中的服务的规则。

Ingress 对象配置

ingress 对象的值在下表中定义:

表 11.3. Ingress 对象
字段类型描述

sourceCIDRs

数组

允许您设置 CIDR 块。您可以从不同地址系列配置多个 CIDR。

注意

不同的 CIDR 允许您使用相同的顺序规则。如果同一节点有多个 IngressNodeFirewall 对象,且带有重叠 CIDR 的接口,则 order 字段将指定首先应用该规则。规则以升序应用。

rules

数组

对于每个 source.CIDR,Ingress 防火墙 rules.order 对象的顺序以 1 开始,每个 CIDR 最多 100 个规则。低顺序规则会首先执行。

rules.protocolConfig.protocol 支持以下协议:TCP、UDP、SCTP、ICMP 和 ICMPv6。ICMP 和 ICMPv6 规则可以匹配 ICMP 和 ICMPv6 类型或代码。TCP、UDP 和 SCTP 规则针对单一一个目标端口或一个目标端口范围(格式为 <start : end-1>)进行匹配。

rules.action 设置为 allow 以应用规则,deny 来禁止规则。

注意

Ingress 防火墙规则使用阻止任何无效配置的验证 Webhook 进行验证。验证 Webhook 会阻止阻塞任何关键集群服务,如 API 服务器或 SSH。

Ingress 节点防火墙规则对象示例

以下示例中指定了完整的 Ingress Node 防火墙配置:

Ingress 节点防火墙配置示例

apiVersion: ingressnodefirewall.openshift.io/v1alpha1
kind: IngressNodeFirewall
metadata:
  name: ingressnodefirewall
spec:
  interfaces:
  - eth0
  nodeSelector:
    matchLabels:
      <ingress_firewall_label_name>: <label_value> 1
  ingress:
  - sourceCIDRs:
       - 172.16.0.0/12
    rules:
    - order: 10
      protocolConfig:
        protocol: ICMP
        icmp:
          icmpType: 8 #ICMP Echo request
      action: Deny
    - order: 20
      protocolConfig:
        protocol: TCP
        tcp:
          ports: "8000-9000"
      action: Deny
  - sourceCIDRs:
       - fc00:f853:ccd:e793::0/64
    rules:
    - order: 10
      protocolConfig:
        protocol: ICMPv6
        icmpv6:
          icmpType: 128 #ICMPV6 Echo request
      action: Deny

1
节点上必须存在 <label_name> 和 <label_value>,且必须与应用到您希望 ingressfirewallconfig CR 运行的节点的 nodeselector 标签和值匹配。<label_value> 可以是 truefalse。通过使用 nodeSelector 标签,您可以针对单独的节点组为目标,以使用 ingressfirewallconfig CR 应用不同的规则。
零信任 Ingress Node Firewall 规则对象示例

零信任 Ingress 节点防火墙规则可为多接口集群提供额外的安全性。例如,您可以使用零信任 Ingress Node Firewall 规则来丢弃除 SSH 之外的特定接口上的网络流量。

以下示例中指定了零信任 Ingress Node Firewall 规则集的完整配置:

重要

用户需要为其提供应用程序使用的所有端口添加到允许列表,以确保正常工作。

零信任 Ingress 节点防火墙规则示例

apiVersion: ingressnodefirewall.openshift.io/v1alpha1
kind: IngressNodeFirewall
metadata:
 name: ingressnodefirewall-zero-trust
spec:
 interfaces:
 - eth1 1
 nodeSelector:
   matchLabels:
     <ingress_firewall_label_name>: <label_value> 2
 ingress:
 - sourceCIDRs:
      - 0.0.0.0/0 3
   rules:
   - order: 10
     protocolConfig:
       protocol: TCP
       tcp:
         ports: 22
     action: Allow
   - order: 20
     action: Deny 4

1
Network-interface 集群
2
<label_name> 和 <label_value> 需要与应用到 ingressfirewallconfig CR 的特定节点的 nodeSelector 标签和值匹配。
3
0.0.0.0/0 匹配任何 CIDR
4
action 设置为 Deny

11.4. 查看 Ingress Node Firewall Operator 规则

流程

  1. 运行以下命令来查看所有当前规则:

    $ oc get ingressnodefirewall
  2. 选择返回的 <resource> 名称之一,并运行以下命令来查看规则或配置:

    $ oc get <resource> <name> -o yaml

11.5. 对 Ingress Node Firewall Operator 进行故障排除

  • 运行以下命令列出已安装的 Ingress Node Firewall 自定义资源定义 (CRD):

    $ oc get crds | grep ingressnodefirewall

    输出示例

    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    ingressnodefirewallconfigs.ingressnodefirewall.openshift.io       2022-08-25T10:03:01Z
    ingressnodefirewallnodestates.ingressnodefirewall.openshift.io    2022-08-25T10:03:00Z
    ingressnodefirewalls.ingressnodefirewall.openshift.io             2022-08-25T10:03:00Z

  • 运行以下命令,以查看 Ingress Node Firewall Operator 的状态:

    $ oc get pods -n openshift-ingress-node-firewall

    输出示例

    NAME                                       READY  STATUS         RESTARTS  AGE
    ingress-node-firewall-controller-manager   2/2    Running        0         5d21h
    ingress-node-firewall-daemon-pqx56         3/3    Running        0         5d21h

    以下字段提供有关 Operator 状态的信息: READYSTATUSAGE、和 RESTARTS。当 Ingress Node Firewall Operator 将守护进程集部署到分配的节点时,STATUS 字段为 Running

  • 运行以下命令来收集所有入口防火墙节点 pod 的日志:

    $ oc adm must-gather – gather_ingress_node_firewall

    在 sos 节点的报告中,其中包含位于 /sos_commands/ebpf 的 eBPF bpftool 输出的报告。这些报告包括用于或作为入口防火墙 XDP 处理数据包处理、更新统计信息和发出事件的查找表。

第 12 章 为手动 DNS Management 配置 Ingress Controller

作为集群管理员,在创建 Ingress Controller 时,Operator 会自动管理 DNS 记录。当所需的 DNS 区域与集群 DNS 区域不同或 DNS 区域被托管在云供应商时,这有一些限制。

作为集群管理员,您可以将 Ingress Controller 配置为停止自动 DNS 管理并启动手动 DNS 管理。将 dnsManagementPolicy 设置为指定应自动或手动管理的时间。

当您将 Ingress Controller 从 Managed 改为 Unmanaged DNS 管理策略时,Operator 不会清理在云中置备的以前的通配符 DNS 记录。当您将 Ingress Controller 从 Unmanaged 改为 Managed DNS 管理策略时,Operator 会尝试在云供应商上创建 DNS 记录(如果不存在),或更新 DNS 记录(如果已存在)。

重要

当您将 dnsManagementPolicy 设置为 unmanaged 时,您必须手动管理云供应商上的通配符 DNS 记录的生命周期。

12.1. Managed DNS 管理策略

Ingress Controller 的 Managed DNS 管理策略可确保云供应商上通配符 DNS 记录的生命周期由 Operator 自动管理。

12.2. Unmanaged DNS 管理策略

Ingress Controller 的 Unmanaged DNS 管理策略可确保云供应商上通配符 DNS 记录的生命周期不会自动管理,而是由集群管理员负责。

注意

在 AWS 云平台中,如果 Ingress Controller 上的域与 dnsConfig.Spec.BaseDomain 不匹配,则 DNS 管理策略会自动设置为 Unmanaged

12.3. 使用 Unmanaged DNS 管理策略创建自定义 Ingress Controller

作为集群管理员,您可以使用 Unmanaged DNS 管理策略创建新的自定义 Ingress Controller。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 创建名为 sample-ingress.yaml 的自定义资源 (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: External 3
          dnsManagementPolicy: Unmanaged 4
    1
    使用 IngressController 对象的名称指定 <name>
    2
    根据作为前提条件创建的 DNS 记录指定 domain
    3
    scope 指定为 External,以在外部公开负载均衡器。
    4
    dnsManagementPolicy 表示 Ingress Controller 是否管理与负载均衡器关联的通配符 DNS 记录的生命周期。有效值为 ManagedUnmanaged。默认值为 Managed
  2. 保存文件以使改变生效。

    oc apply -f <name>.yaml 1

12.4. 修改现有 Ingress Controller

作为集群管理员,您可以修改现有 Ingress Controller 以手动管理 DNS 记录生命周期。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 修改所选 IngressController 来设置 dnsManagementPolicy

    SCOPE=$(oc -n openshift-ingress-operator get ingresscontroller <name> -o=jsonpath="{.status.endpointPublishingStrategy.loadBalancer.scope}")
    
    oc -n openshift-ingress-operator patch ingresscontrollers/<name> --type=merge --patch='{"spec":{"endpointPublishingStrategy":{"type":"LoadBalancerService","loadBalancer":{"dnsManagementPolicy":"Unmanaged", "scope":"${SCOPE}"}}}}'
  2. 可选:您可以删除云供应商中的关联的 DNS 记录。

12.5. 其他资源

第 13 章 配置 Ingress Controller 端点发布策略

endpointPublishingStrategy 用于向其他网络发布 Ingress Controller 端点,启用负载均衡器集成,并提供对其他系统的访问。

重要

在 Red Hat OpenStack Platform (RHOSP)上,只有云供应商配置为创建健康监控器时,才支持 LoadBalancerService 端点发布策略。对于 RHOSP 16.2,只有使用 Amphora Octavia 供应商时,才能进行这个策略。

如需更多信息,请参阅 RHOSP 安装文档中的"设置 RHOSP Cloud Controller Manager 选项"部分。

13.1. Ingress Controller 端点发布策略

NodePortService 端点发布策略

NodePortService 端点发布策略使用 Kubernetes NodePort 服务发布 Ingress Controller。

在这个配置中,Ingress Controller 部署使用容器网络。创建了一个 NodePortService 来发布部署。特定的节点端口由 OpenShift Container Platform 动态分配; 但是,为了支持静态端口分配,您会保留对受管 NodePortService 的节点端口字段的更改

图 13.1. NodePortService 图表

OpenShift Container Platform Ingress NodePort 端点发布策略

上图显示了与 OpenShift Container Platform Ingress NodePort 端点发布策略相关的以下概念:

  • 集群中的所有可用节点均有自己的外部可访问 IP 地址。集群中运行的服务绑定到所有节点的唯一 NodePort。
  • 当客户端连接到停机的节点时,例如,通过连接图形中的 10.0.128.4 IP 地址,节点端口将客户端直接连接到运行该服务的可用节点。在这种情况下,不需要负载平衡。如图形中所显,10.0.128.4 地址已不可用,必须使用另一个 IP 地址。
注意

Ingress Operator 忽略对服务的 .spec.ports[].nodePort 字段的任何更新。

默认情况下,端口会自动分配,您可以访问集成的端口分配。但是,有时需要静态分配端口来与现有基础架构集成,这些基础架构可能无法根据动态端口进行重新配置。要实现与静态节点端口的集成,您可以直接更新受管服务资源。

如需有关 daemonset 的更多信息,请参阅关于 NodePort 的 Kubernetes 服务文档

HostNetwork 端点发布策略

HostNetwork 端点发布策略会在部署 Ingress Controller 的节点端口上发布 Ingress Controller。

带有 HostNetwork 端点发布策略的 Ingress Controller 每个节点只能有一个 pod 副本。如果您想要 n 个副本,则必须至少使用可调度这些副本的 n 个节点。因为每个 Pod 副本都会通过调度的节点主机上的端口 80443 进行请求,所以如果同一节点上的其他 pod 使用这些端口,则无法将副本调度到该节点。

HostNetwork 对象有一个 hostNetwork 字段,它有以下用于可选绑定端口的默认值: httpPort: 80,httpsPort: 443, 和 statsPort: 1936。通过为您的网络指定不同的绑定端口,您可以为 HostNetwork 策略在同一节点上部署多个 Ingress Controller。

Example

apiVersion: operator.openshift.io/v1
kind: IngressController
metadata:
  name: internal
  namespace: openshift-ingress-operator
spec:
  domain: example.com
  endpointPublishingStrategy:
    type: HostNetwork
    hostNetwork:
      httpPort: 80
      httpsPort: 443
      statsPort: 1936

13.1.1. 将 Ingress Controller 端点发布范围配置为 Internal

当集群管理员在没有指定集群为私有的情况下安装新集群时,将默认 Ingress Controller 创建,并将 scope 设置为 External。集群管理员可以将 External 范围的 Ingress Controller 更改为 Internal

先决条件

  • 已安装 oc CLI。

流程

  • 要将 External 范围的 Ingress Controller 更改为 Internal,请输入以下命令:

    $ oc -n openshift-ingress-operator patch ingresscontrollers/default --type=merge --patch='{"spec":{"endpointPublishingStrategy":{"type":"LoadBalancerService","loadBalancer":{"scope":"Internal"}}}}'
  • 要检查 Ingress Controller 的状态,请输入以下命令:

    $ oc -n openshift-ingress-operator get ingresscontrollers/default -o yaml
    • Progressing 状态条件指示您必须执行进一步的操作。例如,状态条件可以通过输入以下命令来指示需要删除该服务:

      $ oc -n openshift-ingress delete services/router-default

      如果删除了该服务,Ingress Operator 会重新创建为 Internal

13.1.2. 配置 Ingress Controller 端点发布范围到外部

当集群管理员在没有指定集群为私有的情况下安装新集群时,将默认 Ingress Controller 创建,并将 scope 设置为 External

Ingress Controller 的范围可以在安装过程中或之后配置为 Internal,集群管理员可以将 内部 Ingress Controller 更改为 External

重要

在某些平台上,需要删除并重新创建服务。

更改范围可能会导致 Ingress 流量中断,这可能会持续几分钟。这适用于需要删除和重新创建服务的平台,因为流程可能会导致 OpenShift Container Platform 取消置备现有服务负载均衡器、置备一个新服务负载均衡器并更新 DNS。

先决条件

  • 已安装 oc CLI。

流程

  • 要将 内部范围的 Ingress Controller 更改为外部,请输入以下命令:

    $ oc -n openshift-ingress-operator patch ingresscontrollers/private --type=merge --patch='{"spec":{"endpointPublishingStrategy":{"type":"LoadBalancerService","loadBalancer":{"scope":"External"}}}}'
  • 要检查 Ingress Controller 的状态,请输入以下命令:

    $ oc -n openshift-ingress-operator get ingresscontrollers/default -o yaml
    • Progressing 状态条件指示您必须执行进一步的操作。例如,状态条件可以通过输入以下命令来指示需要删除该服务:

      $ oc -n openshift-ingress delete services/router-default

      如果删除了该服务,Ingress Operator 会重新创建为 External

13.2. 其他资源

第 14 章 验证到端点的连接

Cluster Network Operator(CNO)运行一个控制器(连接检查控制器),用于在集群的资源间执行连接健康检查。通过查看健康检查的结果,您可以诊断连接问题或解决网络连接问题,将其作为您要调查的问题的原因。

14.1. 执行连接健康检查

要验证集群资源是否可以访问,请向以下集群 API 服务的每个服务都有一个 TCP 连接:

  • Kubernetes API 服务器服务
  • Kubernetes API 服务器端点
  • OpenShift API 服务器服务
  • OpenShift API 服务器端点
  • 负载均衡器

要验证服务和服务端点是否可在集群中的每个节点上访问,请对以下每个目标都进行 TCP 连接:

  • 健康检查目标服务
  • 健康检查目标端点

14.2. 连接健康检查实现

在集群中,连接检查控制器或编配连接验证检查。连接测试的结果存储在 openshift-network-diagnostics 命名空间中的 PodNetworkConnectivity 对象中。连接测试会每分钟以并行方式执行。

Cluster Network Operator(CNO)将几个资源部署到集群,以发送和接收连接性健康检查:

健康检查源
此程序部署在一个由 Deployment 对象管理的单个 pod 副本集中。程序会消耗 PodNetworkConnectivity 对象,并连接到每个对象中指定的 spec.targetEndpoint
健康检查目标
pod 作为集群中每个节点上的守护进程集的一部分部署。pod 侦听入站健康检查。在每个节点上存在这个 pod 可以测试到每个节点的连接。

14.3. PodNetworkConnectivityCheck 对象字段

PodNetworkConnectivityCheck 对象字段在下表中描述。

表 14.1. PodNetworkConnectivityCheck 对象字段
字段类型描述

metadata.name

字符串

对象的名称,其格式如下: <source>-to-<target><target> 描述的目的地包括以下字符串之一:

  • load-balancer-api-external
  • load-balancer-api-internal
  • kubernetes-apiserver-endpoint
  • kubernetes-apiserver-service-cluster
  • network-check-target
  • openshift-apiserver-endpoint
  • openshift-apiserver-service-cluster

metadata.namespace

字符串

与对象关联的命名空间。此值始终为 openshift-network-diagnostics

spec.sourcePod

字符串

连接检查来源于的 pod 的名称,如 network-check-source-596b4c6566-rgh92

spec.targetEndpoint

字符串

连接检查的目标,如 api.devcluster.example.com:6443

spec.tlsClientCert

对象

要使用的 TLS 证书配置。

spec.tlsClientCert.name

字符串

使用的 TLS 证书的名称(若有)。默认值为空字符串。

status

对象

代表连接测试条件和最近连接发生和失败的日志的对象。

status.conditions

数组

连接检查以及任何之前的状态的最新状态。

status.failures

数组

连接测试日志不会失败。

status.outages

数组

涵盖任何中断的时间连接测试日志。

status.successes

数组

成功尝试的连接测试日志。

下表描述了 status.conditions 阵列中对象的字段:

表 14.2. status.conditions
字段类型描述

lastTransitionTime

字符串

连接条件从一个状态转换到另一个状态的时间。

message

字符串

有关最后一次转换的详情(人类可读的格式)。

reason

字符串

有关最后一次转换的详情(机器可读的格式)。

status

字符串

条件的状态。

type

字符串

条件的类型。

下表描述了 status.conditions 阵列中对象的字段:

表 14.3. status.outages
字段类型描述

end

字符串

连接失败时的时间戳。

endLogs

数组

连接日志条目,包括与成功关闭相关的日志条目。

message

字符串

以人类可读格式显示停机详情概述。

开始

字符串

第一次检测到连接失败时的时间戳。

startLogs

数组

连接日志条目,包括原始失败。

连接日志字段

下表中描述了连接日志条目的字段。该对象用于以下字段:

  • status.failures[]
  • status.successes[]
  • status.outages[].startLogs[]
  • status.outages[].endLogs[]
表 14.4. 连接日志对象
字段类型描述

latency

字符串

记录操作的持续时间。

message

字符串

以人类可读格式提供的状态信息。

reason

字符串

以可读格式提供状态的原因。这个值是 TCPConnectTCPConnectErrorDNSResolveDNSError 之一。

success

布尔值

指明日志条目是否成功或失败。

time

字符串

连接检查的开始时间。

14.4. 验证端点的网络连接

作为集群管理员,您可以验证端点的连接性,如 API 服务器、负载均衡器、服务或 Pod。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 要列出当前的 PodNetworkConnectivityCheck 对象,请输入以下命令:

    $ oc get podnetworkconnectivitycheck -n openshift-network-diagnostics

    输出示例

    NAME                                                                                                                                AGE
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0   75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-1   73m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-2   75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-kubernetes-apiserver-service-cluster                               75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-kubernetes-default-service-cluster                                 75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-load-balancer-api-external                                         75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-load-balancer-api-internal                                         75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-ci-ln-x5sv9rb-f76d1-4rzrp-master-0            75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-ci-ln-x5sv9rb-f76d1-4rzrp-master-1            75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-ci-ln-x5sv9rb-f76d1-4rzrp-master-2            75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh      74m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-ci-ln-x5sv9rb-f76d1-4rzrp-worker-c-n8mbf      74m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-ci-ln-x5sv9rb-f76d1-4rzrp-worker-d-4hnrz      74m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-network-check-target-service-cluster                               75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-openshift-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0    75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-openshift-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-1    75m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-openshift-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-2    74m
    network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-openshift-apiserver-service-cluster                                75m

  2. 查看连接测试日志:

    1. 在上一命令的输出中,标识您要查看连接日志的端点。
    2. 要查看对象,请输入以下命令:

      $ oc get podnetworkconnectivitycheck <name> \
        -n openshift-network-diagnostics -o yaml

      这里的 <name> 指定 PodNetworkConnectivityCheck 对象的名称。

      输出示例

      apiVersion: controlplane.operator.openshift.io/v1alpha1
      kind: PodNetworkConnectivityCheck
      metadata:
        name: network-check-source-ci-ln-x5sv9rb-f76d1-4rzrp-worker-b-6xdmh-to-kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0
        namespace: openshift-network-diagnostics
        ...
      spec:
        sourcePod: network-check-source-7c88f6d9f-hmg2f
        targetEndpoint: 10.0.0.4:6443
        tlsClientCert:
          name: ""
      status:
        conditions:
        - lastTransitionTime: "2021-01-13T20:11:34Z"
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnectSuccess
          status: "True"
          type: Reachable
        failures:
        - latency: 2.241775ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: failed
            to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443: connect:
            connection refused'
          reason: TCPConnectError
          success: false
          time: "2021-01-13T20:10:34Z"
        - latency: 2.582129ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: failed
            to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443: connect:
            connection refused'
          reason: TCPConnectError
          success: false
          time: "2021-01-13T20:09:34Z"
        - latency: 3.483578ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: failed
            to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443: connect:
            connection refused'
          reason: TCPConnectError
          success: false
          time: "2021-01-13T20:08:34Z"
        outages:
        - end: "2021-01-13T20:11:34Z"
          endLogs:
          - latency: 2.032018ms
            message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0:
              tcp connection to 10.0.0.4:6443 succeeded'
            reason: TCPConnect
            success: true
            time: "2021-01-13T20:11:34Z"
          - latency: 2.241775ms
            message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0:
              failed to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443:
              connect: connection refused'
            reason: TCPConnectError
            success: false
            time: "2021-01-13T20:10:34Z"
          - latency: 2.582129ms
            message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0:
              failed to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443:
              connect: connection refused'
            reason: TCPConnectError
            success: false
            time: "2021-01-13T20:09:34Z"
          - latency: 3.483578ms
            message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0:
              failed to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443:
              connect: connection refused'
            reason: TCPConnectError
            success: false
            time: "2021-01-13T20:08:34Z"
          message: Connectivity restored after 2m59.999789186s
          start: "2021-01-13T20:08:34Z"
          startLogs:
          - latency: 3.483578ms
            message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0:
              failed to establish a TCP connection to 10.0.0.4:6443: dial tcp 10.0.0.4:6443:
              connect: connection refused'
            reason: TCPConnectError
            success: false
            time: "2021-01-13T20:08:34Z"
        successes:
        - latency: 2.845865ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:14:34Z"
        - latency: 2.926345ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:13:34Z"
        - latency: 2.895796ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:12:34Z"
        - latency: 2.696844ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:11:34Z"
        - latency: 1.502064ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:10:34Z"
        - latency: 1.388857ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:09:34Z"
        - latency: 1.906383ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:08:34Z"
        - latency: 2.089073ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:07:34Z"
        - latency: 2.156994ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:06:34Z"
        - latency: 1.777043ms
          message: 'kubernetes-apiserver-endpoint-ci-ln-x5sv9rb-f76d1-4rzrp-master-0: tcp
            connection to 10.0.0.4:6443 succeeded'
          reason: TCPConnect
          success: true
          time: "2021-01-13T21:05:34Z"

第 15 章 更改集群网络的 MTU

作为集群管理员,您可以在集群安装后更改集群网络的 MTU。这一更改具有破坏性,因为必须重启集群节点才能完成 MTU 更改。您只能为使用 OVN-Kubernetes 或 OpenShift SDN 网络插件的集群更改 MTU。

15.1. 关于集群 MTU

在安装集群网络的最大传输单元(MTU)期间,会根据集群中节点的主网络接口的 MTU 自动检测到。您通常不需要覆盖检测到的 MTU。

您可能希望因为以下原因更改集群网络的 MTU:

  • 集群安装过程中检测到的 MTU 不正确。
  • 集群基础架构现在需要不同的 MTU,如添加需要不同 MTU 的节点来获得最佳性能

只有 OVN-Kubernetes 集群网络插件支持更改 MTU 值。

15.1.1. 服务中断注意事项

当您为集群启动 MTU 更改时,以下效果可能会影响服务可用性:

  • 至少需要两个滚动重启才能完成迁移到新的 MTU。在此过程中,一些节点在重启时不可用。
  • 部署到集群的特定应用程序带有较短的超时间隔,超过绝对 TCP 超时间隔可能会在 MTU 更改过程中造成中断。

15.1.2. MTU 值选择

在规划 MTU 迁移时,需要考虑两个相关但不同的 MTU 值。

  • Hardware MTU :此 MTU 值根据您的网络基础架构的具体设置。
  • Cluster network MTU :此 MTU 值始终小于您的硬件 MTU,以考虑集群网络覆盖开销。具体开销由您的网络插件决定。对于 OVN-Kubernetes,开销为 100 字节。

如果您的集群为不同的节点需要不同的 MTU 值,则必须从集群中任何节点使用的最低 MTU 值中减去网络插件的开销值。例如,如果集群中的某些节点的 MTU 为 9001,而某些节点的 MTU 为 1500,则必须将此值设置为 1400

重要

为了避免选择节点无法接受的 MTU 值,请使用 ip -d link 命令验证网络接口接受的最大 MTU 值 (maxmtu)。

15.1.3. 迁移过程如何工作

下表对迁移过程进行了概述,它分为操作中的用户发起的步骤,以及在响应过程中迁移过程要执行的操作。

表 15.1. 集群 MTU 的实时迁移
用户发起的步骤OpenShift Container Platform 活动

在 Cluster Network Operator 配置中设置以下值:

  • spec.migration.mtu.machine.to
  • spec.migration.mtu.network.from
  • spec.migration.mtu.network.to

Cluster Network Operator(CNO) :确认每个字段都设置为有效的值。

  • 如果硬件的 MTU 没有改变,则 mtu.machine.to 必须设置为新硬件 MTU 或当前的硬件 MTU。这个值是临时的,被用作迁移过程的一部分。如果您指定了与现有硬件 MTU 值不同的硬件 MTU,您必须手动将 MTU 配置为持久,如机器配置、DHCP 设置或 Linux 内核命令行。
  • mtu.network.from 字段必须等于 network.status.clusterNetworkMTU 字段,这是集群网络的当前 MTU。
  • mtu.network.to 字段必须设置为目标集群网络 MTU,且必须小于硬件 MTU,以允许网络插件的覆盖开销。对于 OVN-Kubernetes,开销为 100 字节。

如果提供的值有效,CNO 会生成一个新的临时配置,它将集群网络集的 MTU 设置为 mtu.network.to 字段的值。

Machine Config Operator(MCO) :执行集群中每个节点的滚动重启。

重新配置集群中节点的主网络接口 MTU。您可以使用各种方法完成此操作,包括:

  • 使用 MTU 更改部署新的 NetworkManager 连接配置集
  • 通过 DHCP 服务器设置更改 MTU
  • 通过引导参数更改 MTU

N/A

在网络插件的 CNO 配置中设置 mtu 值,并将 spec.migration 设置为 null

Machine Config Operator(MCO) :使用新的 MTU 配置执行集群中每个节点的滚动重启。

15.2. 更改集群网络 MTU

作为集群管理员,您可以增加或减少集群的最大传输单元 (MTU)。

重要

当 MTU 更新推出时,集群中的迁移具有破坏性且节点可能会临时不可用。

以下流程解释了如何使用机器配置、动态主机配置协议 (DHCP) 或 ISO 镜像更改集群网络 MTU。如果使用 DHCP 或 ISO 方法,则必须在安装集群后保留的配置工件来完成此流程。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 cluster-admin 权限的账户访问集群。
  • 已为集群识别目标 MTU。OVN-Kubernetes 网络插件的 MTU 必须设置为比集群中的最低硬件 MTU 值小 100

流程

  1. 要获得集群网络的当前 MTU,请输入以下命令:

    $ oc describe network.config cluster

    输出示例

    ...
    Status:
      Cluster Network:
        Cidr:               10.217.0.0/22
        Host Prefix:        23
      Cluster Network MTU:  1400
      Network Type:         OVNKubernetes
      Service Network:
        10.217.4.0/23
    ...

  2. 为硬件 MTU 准备配置:

    • 如果您的硬件 MTU 通过 DHCP 指定,请使用以下 dnsmasq 配置更新 DHCP 配置:

      dhcp-option-force=26,<mtu>

      其中:

      <mtu>
      指定要公告的 DHCP 服务器的硬件 MTU。
    • 如果使用 PXE 的内核命令行指定硬件 MTU,请相应地更新该配置。
    • 如果在 NetworkManager 连接配置中指定了硬件 MTU,请完成以下步骤。如果没有使用 DHCP、内核命令行或某种其他方法显式指定网络配置,则此方法是 OpenShift Container Platform 的默认方法。集群节点必须全部使用相同的底层网络配置,才能使以下过程未经修改地工作。

      1. 查找主网络接口:

        • 如果使用 OpenShift SDN 网络插件,请输入以下命令:

          $ oc debug node/<node_name> -- chroot /host ip route list match 0.0.0.0/0 | awk '{print $5 }'

          其中:

          <node_name>
          指定集群中的节点的名称。
        • 如果使用 OVN-Kubernetes 网络插件,请输入以下命令:

          $ oc debug node/<node_name> -- chroot /host nmcli -g connection.interface-name c show ovs-if-phys0

          其中:

          <node_name>
          指定集群中的节点的名称。
      2. <interface>-mtu.conf 文件中创建以下 NetworkManager 配置:

        NetworkManager 连接配置示例

        [connection-<interface>-mtu]
        match-device=interface-name:<interface>
        ethernet.mtu=<mtu>

        其中:

        <mtu>
        指定新的硬件 MTU 值。
        <interface>
        指定主网络接口名称。
      3. 创建两个 MachineConfig 对象,一个用于 control plane 节点,另一个用于集群中的 worker 节点:

        1. control-plane-interface.bu 文件中创建以下 Butane 配置:

          variant: openshift
          version: 4.15.0
          metadata:
            name: 01-control-plane-interface
            labels:
              machineconfiguration.openshift.io/role: master
          storage:
            files:
              - path: /etc/NetworkManager/conf.d/99-<interface>-mtu.conf 1
                contents:
                  local: <interface>-mtu.conf 2
                mode: 0600
          1 1
          指定主网络接口的 NetworkManager 连接名称。
          2
          指定上一步中更新的 NetworkManager 配置文件的本地文件名。
        2. worker-interface.bu 文件中创建以下 Butane 配置:

          variant: openshift
          version: 4.15.0
          metadata:
            name: 01-worker-interface
            labels:
              machineconfiguration.openshift.io/role: worker
          storage:
            files:
              - path: /etc/NetworkManager/conf.d/99-<interface>-mtu.conf 1
                contents:
                  local: <interface>-mtu.conf 2
                mode: 0600
          1
          指定主网络接口的 NetworkManager 连接名称。
          2
          指定上一步中更新的 NetworkManager 配置文件的本地文件名。
        3. 运行以下命令,从 Butane 配置创建 MachineConfig 对象:

          $ for manifest in control-plane-interface worker-interface; do
              butane --files-dir . $manifest.bu > $manifest.yaml
            done
          警告

          在此流程的稍后明确指示之前,不要应用这些机器配置。应用这些机器配置现在会导致集群的稳定性丢失。

  3. 要开始 MTU 迁移,请输入以下命令指定迁移配置。Machine Config Operator 在集群中执行节点的滚动重启,以准备 MTU 更改。

    $ oc patch Network.operator.openshift.io cluster --type=merge --patch \
      '{"spec": { "migration": { "mtu": { "network": { "from": <overlay_from>, "to": <overlay_to> } , "machine": { "to" : <machine_to> } } } } }'

    其中:

    <overlay_from>
    指定当前的集群网络 MTU 值。
    <overlay_to>
    指定集群网络的目标 MTU。这个值相对于 <machine_to> 的值设置。对于 OVN-Kubernetes,这个值必须比 <machine_to> 的值小 100
    <machine_to>
    指定底层主机网络上的主网络接口的 MTU。

    增加集群 MTU 的示例

    $ oc patch Network.operator.openshift.io cluster --type=merge --patch \
      '{"spec": { "migration": { "mtu": { "network": { "from": 1400, "to": 9000 } , "machine": { "to" : 9100} } } } }'

  4. 当 Machine Config Operator 更新每个机器配置池中的机器时,它会逐一重启每个节点。您必须等到所有节点都已更新。输入以下命令检查机器配置池状态:

    $ oc get machineconfigpools

    成功更新的节点具有以下状态: UPDATED=trueUPDATING=falseDEGRADED=false

    注意

    默认情况下,Machine Config Operator 一次更新每个池中的一个机器,从而导致迁移总时间随着集群大小而增加。

  5. 确认主机上新机器配置的状态:

    1. 要列出机器配置状态和应用的机器配置名称,请输入以下命令:

      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

      kubernetes.io/hostname=master-0
      machineconfiguration.openshift.io/currentConfig: rendered-master-c53e221d9d24e1c8bb6ee89dd3d8ad7b
      machineconfiguration.openshift.io/desiredConfig: rendered-master-c53e221d9d24e1c8bb6ee89dd3d8ad7b
      machineconfiguration.openshift.io/reason:
      machineconfiguration.openshift.io/state: Done

    2. 验证以下语句是否正确:

      • machineconfiguration.openshift.io/state 字段的值为 Done
      • machineconfiguration.openshift.io/currentConfig 字段的值等于 machineconfiguration.openshift.io/desiredConfig 字段的值。
    3. 要确认机器配置正确,请输入以下命令:

      $ oc get machineconfig <config_name> -o yaml | grep ExecStart

      这里的 <config_name>machineconfiguration.openshift.io/currentConfig 字段中机器配置的名称。

      机器配置必须包括以下对 systemd 配置的更新:

      ExecStart=/usr/local/bin/mtu-migration.sh
  6. 更新底层网络接口 MTU 值:

    • 如果您要使用 NetworkManager 连接配置指定新 MTU,请输入以下命令。MachineConfig Operator 会自动执行集群中节点的滚动重启。

      $ for manifest in control-plane-interface worker-interface; do
          oc create -f $manifest.yaml
        done
    • 如果您要使用 DHCP 服务器选项或内核命令行和 PXE 指定新 MTU,请对基础架构进行必要的更改。
  7. 当 Machine Config Operator 更新每个机器配置池中的机器时,它会逐一重启每个节点。您必须等到所有节点都已更新。输入以下命令检查机器配置池状态:

    $ oc get machineconfigpools

    成功更新的节点具有以下状态: UPDATED=trueUPDATING=falseDEGRADED=false

    注意

    默认情况下,Machine Config Operator 一次更新每个池中的一个机器,从而导致迁移总时间随着集群大小而增加。

  8. 确认主机上新机器配置的状态:

    1. 要列出机器配置状态和应用的机器配置名称,请输入以下命令:

      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

      kubernetes.io/hostname=master-0
      machineconfiguration.openshift.io/currentConfig: rendered-master-c53e221d9d24e1c8bb6ee89dd3d8ad7b
      machineconfiguration.openshift.io/desiredConfig: rendered-master-c53e221d9d24e1c8bb6ee89dd3d8ad7b
      machineconfiguration.openshift.io/reason:
      machineconfiguration.openshift.io/state: Done

      验证以下语句是否正确:

      • machineconfiguration.openshift.io/state 字段的值为 Done
      • machineconfiguration.openshift.io/currentConfig 字段的值等于 machineconfiguration.openshift.io/desiredConfig 字段的值。
    2. 要确认机器配置正确,请输入以下命令:

      $ oc get machineconfig <config_name> -o yaml | grep path:

      这里的 <config_name>machineconfiguration.openshift.io/currentConfig 字段中机器配置的名称。

      如果机器配置被成功部署,则前面的输出会包含 /etc/NetworkManager/conf.d/99-<interface>-mtu.conf 文件路径和 ExecStart=/usr/local/bin/mtu-migration.sh 行。

  9. 要完成 MTU 迁移,请为 OVN-Kubernetes 网络插件输入以下命令:

    $ oc patch Network.operator.openshift.io cluster --type=merge --patch \
      '{"spec": { "migration": null, "defaultNetwork":{ "ovnKubernetesConfig": { "mtu": <mtu> }}}}'

    其中:

    <mtu>
    指定您使用 <overlay_to> 指定的新集群网络 MTU。
  10. 最终调整 MTU 迁移后,每个机器配置池节点都会逐个重启一个。您必须等到所有节点都已更新。输入以下命令检查机器配置池状态:

    $ oc get machineconfigpools

    成功更新的节点具有以下状态: UPDATED=trueUPDATING=falseDEGRADED=false

验证

  1. 要获得集群网络的当前 MTU,请输入以下命令:

    $ oc describe network.config cluster
  2. 获取节点的主网络接口的当前 MTU:

    1. 要列出集群中的节点,请输入以下命令:

      $ oc get nodes
    2. 要获取节点上主网络接口的当前 MTU 设置,请输入以下命令:

      $ oc debug node/<node> -- chroot /host ip address show <interface>

      其中:

      <node>
      指定上一步中的输出节点。
      <interface>
      指定节点的主网络接口名称。

      输出示例

      ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8051

15.3. 其他资源

第 16 章 配置节点端口服务范围

作为集群管理员,您可以扩展可用的节点端口范围。如果您的集群使用大量节点端口,可能需要增加可用端口的数量。

默认端口范围为 30000-32767。您永远不会缩小端口范围,即使您首先将其扩展超过默认范围。

16.1. 先决条件

  • 集群基础架构必须允许访问您在扩展范围内指定的端口。例如,如果您将节点端口范围扩展到 30000-32900,防火墙或数据包过滤配置必须允许 32768-32900 端口范围。

16.2. 扩展节点端口范围

您可以扩展集群的节点端口范围。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。

流程

  1. 要扩展节点端口范围,请输入以下命令。将 <port> 替换为新范围内的最大端口号码。

    $ oc patch network.config.openshift.io cluster --type=merge -p \
      '{
        "spec":
          { "serviceNodePortRange": "30000-<port>" }
      }'
    提示

    您还可以应用以下 YAML 来更新节点端口范围:

    apiVersion: config.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      serviceNodePortRange: "30000-<port>"

    输出示例

    network.config.openshift.io/cluster patched

  2. 要确认配置是活跃的,请输入以下命令。应用更新可能需要几分钟。

    $ oc get configmaps -n openshift-kube-apiserver config \
      -o jsonpath="{.data['config\.yaml']}" | \
      grep -Eo '"service-node-port-range":["[[:digit:]]+-[[:digit:]]+"]'

    输出示例

    "service-node-port-range":["30000-33000"]

16.3. 其他资源

第 17 章 配置集群网络范围

作为集群管理员,您可以在集群安装后扩展集群网络范围。如果额外的节点需要更多 IP 地址,您可能需要扩展集群网络范围。

例如,如果您部署了集群,并将 10.128.0.0/19 指定为集群网络范围,主机前缀为 23,则限制为 16 个节点。您可以通过将集群中的 CIDR 掩码更改为 /14 来扩展到 510 个节点。

在扩展集群网络地址范围时,您的集群必须使用 OVN-Kubernetes 网络插件。不支持其他网络插件。

修改集群网络 IP 地址范围时会有以下限制:

  • 指定的 CIDR 掩码大小必须总是小于当前配置的 CIDR 掩码大小,因为您只能向已安装的集群添加更多节点来增加 IP 空间
  • 无法修改主机前缀
  • 使用覆盖默认网关配置的 Pod 必须在集群网络扩展后重新创建

17.1. 扩展集群网络 IP 地址范围

您可以扩展集群网络的 IP 地址范围。由于这个更改需要在集群中推出新的 Operator 配置,所以最多可能需要 30 分钟才能生效。

先决条件

  • 安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 确保集群使用 OVN-Kubernetes 网络插件。

流程

  1. 要获取集群的集群网络范围和主机前缀,请输入以下命令:

    $ oc get network.operator.openshift.io \
      -o jsonpath="{.items[0].spec.clusterNetwork}"

    输出示例

    [{"cidr":"10.217.0.0/22","hostPrefix":23}]

  2. 要扩展集群网络 IP 地址范围,请输入以下命令。使用上一命令输出返回的 CIDR IP 地址范围和主机前缀。

    $ oc patch Network.config.openshift.io cluster --type='merge' --patch \
      '{
        "spec":{
          "clusterNetwork": [ {"cidr":"<network>/<cidr>","hostPrefix":<prefix>} ],
          "networkType": "OVNKubernetes"
        }
      }'

    其中:

    <network>
    指定您在上一步中获取的 cidr 字段的网络部分。您无法更改这个值。
    <cidr>
    指定网络前缀长度。例如,14。将此值更改为比上一步中的输出值小的值,以扩展集群网络范围。
    <prefix>
    指定集群的当前主机前缀。这个值必须与您在上一步中获取的 hostPrefix 字段的值相同。

    示例命令

    $ oc patch Network.config.openshift.io cluster --type='merge' --patch \
      '{
        "spec":{
          "clusterNetwork": [ {"cidr":"10.217.0.0/14","hostPrefix": 23} ],
          "networkType": "OVNKubernetes"
        }
      }'

    输出示例

    network.config.openshift.io/cluster patched

  3. 要确认配置是活跃的,请输入以下命令。可能需要 30 分钟才能使此更改生效。

    $ oc get network.operator.openshift.io \
      -o jsonpath="{.items[0].spec.clusterNetwork}"

    输出示例

    [{"cidr":"10.217.0.0/14","hostPrefix":23}]

17.2. 其他资源

第 18 章 配置 IP 故障转移

本节论述了为 OpenShift Container Platform 集群上的 pod 和服务配置 IP 故障转移。

IP 故障转移使用 Keepalived 在一组主机上托管一组外部访问的虚拟 IP (VIP) 地址。每个 VIP 地址仅由单个主机提供服务。Keepalived 使用虚拟路由器冗余协议(VRRP)决定在主机集合中使用哪个主机提供 VIP 服务。如果主机不可用,或者 Keepalived 正在监视的服务没有响应,则 VIP 会切换到主机集中的另外一个主机。这意味着只要主机可用,便始终可以提供 VIP 服务。

集合中的每个 VIP 都由从集合中选择的节点提供服务。如果单个节点可用,则会提供 VIP。无法将 VIP 显式分发到节点上,因此可能存在没有 VIP 的节点和其他具有多个 VIP 的节点。如果只有一个节点,则所有 VIP 都在其中。

管理员必须确保所有 VIP 地址都满足以下要求:

  • 可在集群外部配置的主机上访问。
  • 不用于集群中的任何其他目的。

每个节点上的 keepalived 确定所需服务是否在运行。如果是,则支持 VIP,Keepalived 参与协商来确定哪个节点服务 VIP。对于要参与的节点,服务必须侦听 VIP 上的观察端口,或者必须禁用检查。

注意

集合中的每个 VIP 都可以由不同的节点提供。

IP 故障转移会监控每个 VIP 上的端口,以确定该端口能否在节点上访问。如果端口无法访问,则不会向节点分配 VIP。如果端口设为 0,则会禁止此检查。检查脚本执行所需的测试。

当运行 Keepalived 的节点通过检查脚本时,该节点上的 VIP 可以根据其优先级和当前 master 的优先级以及抢占策略决定进入 master 状态。

集群管理员可以通过 OPENSHIFT_HA_NOTIFY_SCRIPT 变量提供一个脚本,每当节点上的 VIP 的状态发生变化时会调用此脚本。keepalived 在为 VIP 提供服务时为 master 状态;当另一个节点提供 VIP 服务时,状态为 backup;当检查脚本失败时,状态为 fault。每当状态更改时,notify 脚本都会被调用,并显示新的状态。

您可以在 OpenShift Container Platform 上创建 IP 故障转移部署配置。IP 故障转移部署配置指定 VIP 地址的集合,以及服务它们的一组节点。一个集群可以具有多个 IP 故障转移部署配置,各自管理自己的一组唯一的 VIP 地址。IP 故障转移配置中的每个节点运行 IP 故障转移 pod,此 pod 运行 Keepalived。

使用 VIP 访问带有主机网络的 pod 时,应用程序 pod 在运行 IP 故障转移 pod 的所有节点上运行。这可让任何 IP 故障转移节点成为主节点,并在需要时为 VIP 服务。如果应用程序 pod 没有在所有具有 IP 故障转移功能的节点上运行,有些 IP 故障转移节点不会为 VIP 服务,或者某些应用 pod 都不会接收任何流量。对 IP 故障转移和应用容器集使用相同的选择器和复制数,以避免这种不匹配。

在使用 VIP 访问服务时,任何节点都可以位于节点的 IP 故障转移集中,因为无论应用容器集在哪里运行,该服务都可以在所有节点上访问。任何 IP 故障转移节点可以随时变成主节点。服务可以使用外部 IP 和服务端口,或者可以使用 NodePort。设置 NodePort 是一个特权操作。

在服务定义中使用外部 IP 时,VIP 被设置为外部 IP,IP 故障转移监控端口则设为服务端口。在使用节点端口时,该端口在集群的每个节点上打开,服务则从当前服务于 VIP 的任何节点对流量进行负载平衡。在这种情况下,IP 故障转移监控端口在服务定义中设置为 NodePort

重要

即使一个服务 VIP 具有高可用性,但性能仍会受到影响。keepalived 确保每个 VIP 都由配置中的某个节点提供服务,即使其他节点没有,也可以在同一节点上出现多个 VIP。当 IP 故障转移在同一节点上放置多个 VIP 时,在一组 VIP 间进行外部负载平衡的策略可能会被破解。

当使用 ExternalIP 时,您可以将 IP 故障转移设置为与 ExternalIP 范围相同的 VIP 范围。您还可以禁用监控端口。在这种情况下,所有 VIP 都出现在集群中的同一节点上。任何用户都可以使用 ExternalIP 设置服务并使其高度可用。

重要

集群中最多有 254 个 VIP。

18.1. IP 故障转移环境变量

下表包含用于配置 IP 故障转移的变量。

表 18.1. IP 故障转移环境变量
变量名称default描述

OPENSHIFT_HA_MONITOR_PORT

80

IP 故障转移 pod 会尝试在每个虚拟 IP(VIP)上打开到此端口的 TCP 连接。如果建立连接,则服务将被视为正在运行。如果此端口设为 0,则测试会始终通过。

OPENSHIFT_HA_NETWORK_INTERFACE

 

IP 故障转移用于发送虚拟路由器冗余协议 (VRRP) 流量的接口名称。默认值为 eth0

OPENSHIFT_HA_REPLICA_COUNT

2

要创建的副本数。这必须与 IP 故障转移部署配置中的 spec.replicas 值匹配。

OPENSHIFT_HA_VIRTUAL_IPS

 

要复制的 IP 地址范围列表。必须提供.例如,1.2.3.4-6,1.2.3.9

OPENSHIFT_HA_VRRP_ID_OFFSET

0

用于设置虚拟路由器 ID 的偏移值。使用不同的偏移值可以在同一集群中存在多个 IP 故障转移配置。默认偏移值为 0,允许的范围是 0255

OPENSHIFT_HA_VIP_GROUPS

 

为 VRRP 创建的组数量。如果没有设置,则会为通过 OPENSHIFT_HA_VIP_GROUPS 变量指定的每个虚拟 IP 范围创建一个组。

OPENSHIFT_HA_IPTABLES_CHAIN

输入

iptables 链的名称,用于自动添加允许 VRRP 流量的 iptables 规则。如果没有设置值,则不会添加 iptables 规则。如果链不存在,则不会创建它。

OPENSHIFT_HA_CHECK_SCRIPT

 

定期运行的脚本的 pod 文件系统中的完整路径名称,以验证应用是否正在运行。

OPENSHIFT_HA_CHECK_INTERVAL

2

检查脚本运行的期间(以秒为单位)。

OPENSHIFT_HA_NOTIFY_SCRIPT

 

当状态发生变化时运行的脚本的 pod 文件系统的完整路径名称。

OPENSHIFT_HA_PREEMPTION

preempt_nodelay 300

处理新的具有更高优先级主机的策略。nopreempt 策略不会将 master 从较低优先级主机移到优先级更高的主机。

18.2. 在集群中配置 IP 故障切换

作为集群管理员,您可以在整个集群中或在其中的一部分节点(由标签选项器定义)中配置 IP 故障转移。您还可以在集群中配置多个 IP 故障转移部署配置,每个配置都独立于其他配置。

IP 故障转移部署配置确保故障转移 pod 在符合限制或使用的标签的每个节点上运行。

此 pod 运行 Keepalived,它可以监控端点,并在第一个节点无法访问服务或端点时使用 Virtual Router Redundancy Protocol(VRRP)从一个节点切换到另一个节点的虚拟 IP(VIP)。

对于生产环境,设置一个选择器(selector),用于选择至少两个节点,并设置与所选节点数量相等的副本

先决条件

  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 已创建一个 pull secret。

流程

  1. 创建 IP 故障转移服务帐户:

    $ oc create sa ipfailover
  2. hostNetwork 更新安全性上下文约束(SCC):

    $ oc adm policy add-scc-to-user privileged -z ipfailover
    $ oc adm policy add-scc-to-user hostnetwork -z ipfailover
  3. 创建部署 YAML 文件来配置 IP 故障转移:

    IP 故障转移配置的部署 YAML 示例

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ipfailover-keepalived 1
      labels:
        ipfailover: hello-openshift
    spec:
      strategy:
        type: Recreate
      replicas: 2
      selector:
        matchLabels:
          ipfailover: hello-openshift
      template:
        metadata:
          labels:
            ipfailover: hello-openshift
        spec:
          serviceAccountName: ipfailover
          privileged: true
          hostNetwork: true
          nodeSelector:
            node-role.kubernetes.io/worker: ""
          containers:
          - name: openshift-ipfailover
            image: quay.io/openshift/origin-keepalived-ipfailover
            ports:
            - containerPort: 63000
              hostPort: 63000
            imagePullPolicy: IfNotPresent
            securityContext:
              privileged: true
            volumeMounts:
            - name: lib-modules
              mountPath: /lib/modules
              readOnly: true
            - name: host-slash
              mountPath: /host
              readOnly: true
              mountPropagation: HostToContainer
            - name: etc-sysconfig
              mountPath: /etc/sysconfig
              readOnly: true
            - name: config-volume
              mountPath: /etc/keepalive
            env:
            - name: OPENSHIFT_HA_CONFIG_NAME
              value: "ipfailover"
            - name: OPENSHIFT_HA_VIRTUAL_IPS 2
              value: "1.1.1.1-2"
            - name: OPENSHIFT_HA_VIP_GROUPS 3
              value: "10"
            - name: OPENSHIFT_HA_NETWORK_INTERFACE 4
              value: "ens3" #The host interface to assign the VIPs
            - name: OPENSHIFT_HA_MONITOR_PORT 5
              value: "30060"
            - name: OPENSHIFT_HA_VRRP_ID_OFFSET 6
              value: "0"
            - name: OPENSHIFT_HA_REPLICA_COUNT 7
              value: "2" #Must match the number of replicas in the deployment
            - name: OPENSHIFT_HA_USE_UNICAST
              value: "false"
            #- name: OPENSHIFT_HA_UNICAST_PEERS
              #value: "10.0.148.40,10.0.160.234,10.0.199.110"
            - name: OPENSHIFT_HA_IPTABLES_CHAIN 8
              value: "INPUT"
            #- name: OPENSHIFT_HA_NOTIFY_SCRIPT 9
            #  value: /etc/keepalive/mynotifyscript.sh
            - name: OPENSHIFT_HA_CHECK_SCRIPT 10
              value: "/etc/keepalive/mycheckscript.sh"
            - name: OPENSHIFT_HA_PREEMPTION 11
              value: "preempt_delay 300"
            - name: OPENSHIFT_HA_CHECK_INTERVAL 12
              value: "2"
            livenessProbe:
              initialDelaySeconds: 10
              exec:
                command:
                - pgrep
                - keepalived
          volumes:
          - name: lib-modules
            hostPath:
              path: /lib/modules
          - name: host-slash
            hostPath:
              path: /
          - name: etc-sysconfig
            hostPath:
              path: /etc/sysconfig
          # config-volume contains the check script
          # created with `oc create configmap keepalived-checkscript --from-file=mycheckscript.sh`
          - configMap:
              defaultMode: 0755
              name: keepalived-checkscript
            name: config-volume
          imagePullSecrets:
            - name: openshift-pull-secret 13

    1
    IP 故障转移部署的名称。
    2
    要复制的 IP 地址范围列表。必须提供.例如,1.2.3.4-6,1.2.3.9
    3
    为 VRRP 创建的组数量。如果没有设置,则会为通过 OPENSHIFT_HA_VIP_GROUPS 变量指定的每个虚拟 IP 范围创建一个组。
    4
    IP 故障切换用于发送 VRRP 流量的接口名称。默认情况下使用 eth0
    5
    IP 故障转移 pod 会尝试在每个 VIP 上打开到此端口的 TCP 连接。如果建立连接,则服务将被视为正在运行。如果此端口设为 0,则测试会始终通过。默认值为 80
    6
    用于设置虚拟路由器 ID 的偏移值。使用不同的偏移值可以在同一集群中存在多个 IP 故障转移配置。默认偏移值为 0,允许的范围是 0255
    7
    要创建的副本数。这必须与 IP 故障转移部署配置中的 spec.replicas 值匹配。默认值为 2
    8
    iptables 链的名称,用于自动添加允许 VRRP 流量的 iptables 规则。如果没有设置值,则不会添加 iptables 规则。如果链不存在,则不会创建链,Keepalived 在单播模式下运行。默认为 INPUT
    9
    当状态发生变化时运行的脚本的 pod 文件系统的完整路径名称。
    10
    定期运行的脚本的 pod 文件系统中的完整路径名称,以验证应用是否正在运行。
    11
    处理新的具有更高优先级主机的策略。默认值为 preempt_delay 300,这会导致,在有一个较低优先级的 master 提供 VIP 时,Keepalived 实例在 5 分钟后会接管 VIP。
    12
    检查脚本运行的期间(以秒为单位)。默认值为 2
    13
    在创建部署之前创建 pull secret,否则您将在创建部署时收到错误。

18.3. 配置检查和通知脚本

keepalived 通过定期运行可选用户提供的检查脚本来监控应用程序的健康状况。例如,该脚本可以通过发出请求并验证响应来测试 Web 服务器。作为集群管理员,您可以提供一个可选的 notify 脚本,该脚本会在状态发生变化时调用。

检查和通知在 IP 故障转移容器集中运行的脚本,并使用容器集文件系统,而不是主机文件系统。但是,IP 故障转移 pod 使主机文件系统在 /hosts 挂载路径下可用。在配置检查或通知脚本时,您必须提供脚本的完整路径。提供脚本的建议方法是使用 ConfigMap 对象。

检查和通知脚本的完整路径名称添加到 Keepalived 配置文件 _/etc/keepalived/keepalived.conf 中,该文件会在 Keepalived 每次启动时加载。可以使用 ConfigMap 对象将脚本添加到 pod,如以下方法所述。

检查脚本

不提供检查脚本时,将运行一个简单的默认脚本来测试 TCP 连接。当监控端口为 0 时,禁止此默认测试。

每个 IP 故障转移 pod 管理一个 Keepalived 守护进程,在运行 pod 的节点上管理一个或多个虚拟 IP (VIP)地址。Keepalived 守护进程为该节点保留每个 VIP 的状态。特定节点上的特定 VIP 可能处于 masterbackupfault 状态。

如果检查脚本返回非零,节点会进入 backup 状态,并且它拥有的任何 VIP 被重新分配。

notify 脚本

keepalived 将以下三个参数传递给 notify 脚本:

  • $1 - groupinstance
  • $2 - groupinstance 的名称
  • $3 - 新状态: masterbackupfault

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。

流程

  1. 创建所需脚本,并创建 ConfigMap 对象来容纳它。脚本没有输入参数,并且必须返回 0OK)和 1fail)。

    检查脚本,mycheckscript.sh

    #!/bin/bash
        # Whatever tests are needed
        # E.g., send request and verify response
    exit 0
  2. 创建 ConfigMap 对象:

    $ oc create configmap mycustomcheck --from-file=mycheckscript.sh
  3. 将脚本添加到容器集。挂载的 ConfigMap 对象的 defaultMode 必须能够使用 oc 命令或编辑部署配置来运行。值通常为 0755493(十进制):

    $ oc set env deploy/ipfailover-keepalived \
        OPENSHIFT_HA_CHECK_SCRIPT=/etc/keepalive/mycheckscript.sh
    $ oc set volume deploy/ipfailover-keepalived --add --overwrite \
        --name=config-volume \
        --mount-path=/etc/keepalive \
        --source='{"configMap": { "name": "mycustomcheck", "defaultMode": 493}}'
    注意

    oc set env 命令对空格敏感。= 符号的两侧不能有空格。

    提示

    您还可以编辑 ipfailover-keepalived 部署配置:

    $ oc edit deploy ipfailover-keepalived
        spec:
          containers:
          - env:
            - name: OPENSHIFT_HA_CHECK_SCRIPT  1
              value: /etc/keepalive/mycheckscript.sh
    ...
            volumeMounts: 2
            - mountPath: /etc/keepalive
              name: config-volume
          dnsPolicy: ClusterFirst
    ...
          volumes: 3
          - configMap:
              defaultMode: 0755 4
              name: customrouter
            name: config-volume
    ...
    1
    spec.container.env 字段中,添加 OPENSHIFT_HA_CHECK_SCRIPT 环境变量以指向挂载的脚本文件。
    2
    添加 spec.container.volumeMounts 字段以创建挂载点。
    3
    添加新的 spec.volumes 字段以提及配置映射。
    4
    这将设置文件的运行权限。在重新读后,其显示为十进制 493

    保存更改并退出编辑器。这会重启 ipfailover-keepalived

18.4. 配置 VRRP 抢占

当一个节点上的虚拟 IP(VIP)因为通过了检查脚本的检查而脱离 fault 状态时,如果其优先级低于当前处于 master 状态的节点上的 VIP,则节点上的 VIP 将进入 backup 状态。nopreempt 策略不会将 master 从主机上的较低优先级 VIP 移到主机上的优先级更高的 VIP。当使用默认的 preempt_delay 300 时,Keepalived 会等待指定的 300 秒,并将 master 移到主机上的优先级更高的 VIP。

流程

  • 要指定抢占,输入 oc edit deploy ipfailover-keepalived 以编辑路由器部署配置:

    $ oc edit deploy ipfailover-keepalived
    ...
        spec:
          containers:
          - env:
            - name: OPENSHIFT_HA_PREEMPTION  1
              value: preempt_delay 300
    ...
    1
    设置 OPENSHIFT_HA_PREEMPTION 值:
    • preempt_delay 300:Keepalived 会等待指定的 300 秒,并将 master 移到主机上的优先级更高的 VIP。这是默认值。
    • nopreempt:不会将 master 从主机上的较低优先级 VIP 移到主机上的优先级更高的 VIP。

18.5. 部署多个 IP 故障转移实例

每个 IP 转移 pod 由 IP 故障转移部署配置管理,每个节点 1 个 pod,以一个 Keepalived 守护进程运行。配置更多 IP 故障转移部署配置后,会创建更多 pod,更多的守护进程加入常见的虚拟路由器冗余协议(VRRP)协商。此协商由所有 Keepalived 守护进程完成,它决定了哪些节点服务是哪个虚拟 IP(VIP)。

Keepalived 内部为每个 VIP 分配一个唯一的 vrrp-id。协商使用这一组 vrrp-ids,在做出决策时,胜出的 vrrp-id 对应的 VIP 将在胜出的节点上服务。

因此,对于 IP 故障转移部署配置中定义的每个 VIP,IP 故障转移 pod 必须分配对应的 vrrp-id。这可以从 OPENSHIFT_HA_VRRP_ID_OFFSET 开始,并按顺序将 vrrp-ids 分配到 VIP 列表来实现。vrrp-ids 的值可在 1..255 之间。

当存在多个 IP 故障转移部署配置时,您必须指定 OPENSHIFT_HA_VRRP_ID_OFFSET,以便在部署配置中增加 VIP 的数量,并且没有 vrrp-id 范围重叠。

18.6. 为超过 254 地址配置 IP 故障转移

IP 故障转移管理有 254 个组虚拟 IP(VIP)地址的限制。默认情况下,OpenShift Container Platform 会为每个组分配一个 IP 地址。您可以使用 OPENSHIFT_HA_VIP_GROUPS 变量进行更改,使得每个组中有多个 IP 地址,并在配置 IP 故障转移时定义每个虚拟路由器冗余协议(VRRP)实例可用的 VIP 组数量。

在 VRRP 故障转移事件中,对 VIP 进行分组会为每个 VRRP 创建更广泛的 VIP 分配范围,并在集群中的所有主机都能够从本地访问服务时很有用。例如,当服务通过 ExternalIP 公开时。

注意

使用故障转移的一个规则是,请勿将路由等服务限制到一个特定的主机。相反,服务应复制到每一主机上,以便在 IP 故障转移时,不必在新主机上重新创建服务。

注意

如果使用 OpenShift Container Platform 健康检查,IP 故障转移和组的性质意味着不会检查组中的所有实例。因此,必须使用 Kubernetes 健康检查来确保服务处于活动状态。

先决条件

  • 使用具有 cluster-admin 权限的用户登陆到集群。

流程

  • 要更改分配给每个组的 IP 地址数量,请更改 OPENSHIFT_HA_VIP_GROUPS 变量的值,例如:

    IP 故障转换配置的 Deployment YAML 示例

    ...
        spec:
            env:
            - name: OPENSHIFT_HA_VIP_GROUPS 1
              value: "3"
    ...

    1
    如果在有七个 VIP 的环境中将 OPENSHIFT_HA_VIP_GROUPS 设置为 3,它会创建三个组,将三个 VIP 分配到第一个组,为剩余的两个组各分配两个 VIP。
注意

如果 OPENSHIFT_HA_VIP_GROUPS 设置的组数量少于设置为故障的 IP 地址数量,则组包含多个 IP 地址,且所有地址都作为一个单元移动。

18.7. ExternalIP 的高可用性

在非云集群中,可以组合使用 IP 故障切换和 ExternalIP 到服务。对于使用 ExternalIP 创建服务的用户,结果是高可用性服务。

方法是指定集群网络配置的 spec.ExternalIP.autoAssignCIDRs 范围,然后在创建 IP 故障转移配置时使用相同的范围。

因为 IP 故障转移最多可支持整个集群的 255 个 VIP,所以 spec.ExternalIP.autoAssignCIDRs 必须为 /24 或更小。

18.8. 删除 IP 故障切换

在初始配置 IP 故障切换时,集群中的 worker 节点会使用 iptables 规则修改,该规则明确允许 Keepalived 在 224.0.0.18 上多播数据包。由于对节点的更改,移除 IP 故障切换需要运行一个作业来删除 iptables 规则并删除 Keepalived 使用的虚拟 IP 地址。

流程

  1. 可选:识别并删除存储为配置映射的任何检查和通知脚本:

    1. 确定任何用于 IP 故障切换的 pod 是否使用配置映射作为卷:

      $ oc get pod -l ipfailover \
        -o jsonpath="\
      {range .items[?(@.spec.volumes[*].configMap)]}
      {'Namespace: '}{.metadata.namespace}
      {'Pod:       '}{.metadata.name}
      {'Volumes that use config maps:'}
      {range .spec.volumes[?(@.configMap)]}  {'volume:    '}{.name}
        {'configMap: '}{.configMap.name}{'\n'}{end}
      {end}"

      输出示例

      Namespace: default
      Pod:       keepalived-worker-59df45db9c-2x9mn
      Volumes that use config maps:
        volume:    config-volume
        configMap: mycustomcheck

    2. 如果上一步提供了用作卷的配置映射的名称,请删除配置映射:

      $ oc delete configmap <configmap_name>
  2. 为 IP 故障切换识别现有部署:

    $ oc get deployment -l ipfailover

    输出示例

    NAMESPACE   NAME         READY   UP-TO-DATE   AVAILABLE   AGE
    default     ipfailover   2/2     2            2           105d

  3. 删除部署:

    $ oc delete deployment <ipfailover_deployment_name>
  4. 删除 ipfailover 服务帐户:

    $ oc delete sa ipfailover
  5. 运行一个作业,该作业会删除最初配置 IP 故障切换时添加的 IP 表规则:

    1. 创建一个文件,如 remove-ipfailover-job.yaml,其内容类似以下示例:

      apiVersion: batch/v1
      kind: Job
      metadata:
        generateName: remove-ipfailover-
        labels:
          app: remove-ipfailover
      spec:
        template:
          metadata:
            name: remove-ipfailover
          spec:
            containers:
            - name: remove-ipfailover
              image: quay.io/openshift/origin-keepalived-ipfailover:4.15
              command: ["/var/lib/ipfailover/keepalived/remove-failover.sh"]
            nodeSelector: 1
              kubernetes.io/hostname: <host_name>  2
            restartPolicy: Never
      1
      nodeSelector 可能与旧 IP 故障转移部署中使用的选择器相同。
      2
      为集群中配置 IP 故障切换的每个节点运行作业,并每次替换主机名。
    2. 运行作业:

      $ oc create -f remove-ipfailover-job.yaml

      输出示例

      job.batch/remove-ipfailover-2h8dm created

验证

  • 确认作业删除了 IP 故障切换的初始配置。

    $ oc logs job/remove-ipfailover-2h8dm

    输出示例

    remove-failover.sh: OpenShift IP Failover service terminating.
      - Removing ip_vs module ...
      - Cleaning up ...
      - Releasing VIPs  (interface eth0) ...

第 19 章 使用调优插件配置系统控制和接口属性

在 Linux 中,管理员可通过 sysctl 在运行时修改内核参数。您可以使用调优 Container Network Interface(CNI)元插件修改接口级网络 sysctl。tuning CNI meta 插件在一个链中运行,主 CNI 插件如下所示。

CNI 插件

主 CNI 插件分配接口,并将此接口在运行时传递给 tuning CNI meta 插件。您可以使用 tuning CNI meta 插件更改网络命名空间中的一些 sysctl 和几个接口属性,如 promiscuous 模式、all-multicast 模式、MTU 和 MAC 地址。

19.1. 使用 tuning CNI 配置系统控制

以下流程将调整 CNI 配置为更改接口级网络 net.ipv4.conf.IFNAME.accept_redirects sysctl。这个示例启用接受和发送 ICMP 重定向的数据包。在 tuning CNI meta 插件配置中,接口名称由 IFNAME 令牌表示,并替换为运行时接口的实际名称。

流程

  1. 使用以下内容创建网络附加定义,如 tuning-example.yaml

    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: <name> 1
      namespace: default 2
    spec:
      config: '{
        "cniVersion": "0.4.0", 3
        "name": "<name>", 4
        "plugins": [{
           "type": "<main_CNI_plugin>" 5
          },
          {
           "type": "tuning", 6
           "sysctl": {
                "net.ipv4.conf.IFNAME.accept_redirects": "1" 7
            }
          }
         ]
    }
    1
    指定要创建的额外网络附加的名称。名称在指定的命名空间中必须是唯一的。
    2
    指定与对象关联的命名空间。
    3
    指定 CNI 规格版本。
    4
    指定配置的名称。建议您将配置名称与网络附加定义的 name 值匹配。
    5
    指定要配置的主 CNI 插件的名称。
    6
    指定 CNI meta 插件的名称。
    7
    指定要设置的 sysctl。接口名称由 IFNAME 令牌表示,并替换为运行时接口的实际名称。

    下面显示了一个 YAML 文件示例:

    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: tuningnad
      namespace: default
    spec:
      config: '{
        "cniVersion": "0.4.0",
        "name