24.10. 配置出口 IP 地址
作为集群管理员,您可以配置 OVN-Kubernetes Container Network Interface (CNI) 网络插件,为命名空间分配一个或多个出口 IP 地址,或分配给命名空间中的特定 pod。
24.10.1. 出口 IP 地址架构设计和实施
OpenShift Container Platform 出口 IP 地址功能可确保来自一个或多个命名空间中的一个或多个 pod 的流量具有集群网络之外的服务具有一致的源 IP 地址。
例如,您可能有一个 pod 定期查询托管在集群外服务器上的数据库。要强制对服务器进行访问要求,将数据包过滤设备配置为只允许来自特定 IP 地址的流量。为确保您可以可靠地允许从该特定 pod 访问服务器,您可以为向服务器发出请求的 pod 配置特定的出口 IP 地址。
分配给命名空间的出口 IP 地址与用来向特定目的地发送流量的出口路由器不同。
在一些集群配置中,应用程序 Pod 和入口路由器 pod 在同一个节点上运行。如果您在这种情况下为应用程序项目配置出口 IP 地址,当您向应用程序项目发送请求时,不会使用 IP 地址。
不能在任何 Linux 网络配置文件中配置出口 IP 地址,比如 ifcfg-eth0
。
24.10.1.1. 平台支持
下表概述了对不同平台中的出口 IP 地址功能的支持:
平台 | 支持 |
---|---|
裸机 | 是 |
VMware vSphere | 是 |
Red Hat OpenStack Platform(RHOSP) | 是 |
Amazon Web Services (AWS) | 是 |
Google Cloud Platform (GCP) | 是 |
Microsoft Azure | 是 |
IBM Z® 和 IBM® LinuxONE | 是 |
IBM Z® and IBM® LinuxONE for Red Hat Enterprise Linux (RHEL) KVM | 是 |
IBM Power® | 是 |
Nutanix | 是 |
在 Amazon Web Services(AWS)上置备的集群中不支持使用 EgressIP 功能将出口 IP 地址分配给 control plane 节点。(BZ#2039656)。
24.10.1.2. 公共云平台注意事项
对于在公共云基础架构上置备的集群,每个节点绝对的 IP 地址会有一个约束。如下公式描述了每个节点的可分配 IP 地址或 IP 容量 上限:
IP capacity = public cloud default capacity - sum(current IP assignments)
虽然 Egress IP 功能管理每个节点的 IP 地址容量,但在部署中计划这个约束非常重要。例如,对于在具有 8 个节点的裸机基础架构上安装的集群,您可以配置 150 个出口 IP 地址。但是,如果公共云提供商将 IP 地址容量限制为每个节点 10 个 IP 地址,则可分配 IP 地址总数仅为 80。为了在这个示例中获得相同的 IP 地址容量,您需要分配 7 个节点。
要确认公共云环境中任何节点的 IP 容量和子网,您可以输入 oc get node <node_name> -o yaml
命令。cloud.network.openshift.io/egress-ipconfig
注解包括节点的容量和子网信息。
注解值是一个带有单个对象的数组,其中包含为主网络接口提供以下信息的字段:
-
interface
:指定 AWS 和 Azure 上的接口 ID,以及 GCP 上的接口名称。 -
ifaddr
:为一个或多个 IP 地址系列指定子网掩码。 -
capacity
:指定节点的 IP 地址容量。在 AWS 上,IP 地址容量为每个 IP 地址系列提供。在 Azure 和 GCP 上,IP 地址容量同时包括 IPv4 和 IPv6 地址。
为节点之间的流量自动附加和分离出口 IP 地址。这允许命名空间中许多 pod 的流量在集群外的位置上具有一致的源 IP 地址。这还支持 OpenShift SDN 和 OVN-Kubernetes,这是 OpenShift Container Platform 4.16 中 Red Hat OpenShift Networking 中的默认网络插件。
RHOSP 出口 IP 地址功能会创建一个名为 egressip-<IP address>
的 neutron 保留端口。使用与 OpenShift Container Platform 集群安装相同的 RHOSP 用户,您可以为此保留端口分配一个浮动 IP 地址,以便为出口流量具有可预测的 SNAT 地址。当 RHOSP 网络上的出口 IP 地址从一个节点移到另一个节点时,因为节点故障转移(例如,neutron 保留端口会被删除并重新创建)。这意味着浮动 IP 关联丢失,您需要手动将浮动 IP 地址重新分配给新的保留端口。
当 RHOSP 集群管理员为保留端口分配一个浮动 IP 时,OpenShift Container Platform 无法删除保留端口。CloudPrivateIPConfig
对象无法执行删除和移动操作,直到 RHOSP 集群管理员从保留端口取消分配浮动 IP。
以下示例演示了来自多个公共云提供商上节点的注解。注解被缩进以便于阅读。
AWS 上的 cloud.network.openshift.io/egress-ipconfig
注解示例
cloud.network.openshift.io/egress-ipconfig: [ { "interface":"eni-078d267045138e436", "ifaddr":{"ipv4":"10.0.128.0/18"}, "capacity":{"ipv4":14,"ipv6":15} } ]
GCP 上的 cloud.network.openshift.io/egress-ipconfig
注解示例
cloud.network.openshift.io/egress-ipconfig: [ { "interface":"nic0", "ifaddr":{"ipv4":"10.0.128.0/18"}, "capacity":{"ip":14} } ]
以下小节描述了支持公共云环境的 IP 地址容量,用于容量计算。
24.10.1.2.1. Amazon Web Services(AWS)IP 地址容量限制
在 AWS 上,IP 地址分配的限制取决于配置的实例类型。如需更多信息,请参阅 每个实例类型的每个网络接口的 IP 地址
24.10.1.2.2. Google Cloud Platform(GCP)IP 地址容量限制
在 GCP 中,网络模型通过 IP 地址别名而不是 IP 地址分配来实施额外的节点 IP 地址。但是,IP 地址容量直接映射到 IP 别名容量。
IP 别名分配存在以下容量限制:
- 每个节点,IPv4 和 IPv6 的最大 IP 别名数为 100 个。
- 对于每个 VPC,IP 别名的最大数量没有被指定,但 OpenShift Container Platform 可扩展性测试显示最大为 15,000 个。
如需更多信息,请参阅 Per instance 配额和 Alias IP 范围概述。
24.10.1.2.3. Microsoft Azure IP 地址容量限制
在 Azure 上,IP 地址分配有以下容量限制:
- 对于每个 NIC,对于 IPv4 和 IPv6,可分配 IP 地址的最大数量为 256。
- 对于每个虚拟网络,分配的 IP 地址的最大数量不能超过 65,536。
如需更多信息,请参阅网络限制。
24.10.1.3. 在额外网络接口中使用出口 IP 的注意事项
在 OpenShift Container Platform 中,出口 IP 为管理员提供了一种控制网络流量的方法。出口 IP 可以与 br-ex
或主网络接口一起使用,它是与 Open vSwitch 关联的 Linux 网桥接口,或者可与额外的网络接口一起使用。
您可以运行以下命令来检查网络接口类型:
$ ip -details link show
主网络接口被分配一个节点 IP 地址,该地址还包含子网掩码。此节点 IP 地址的信息可以通过检查 k8s.ovn.org/node-primary-ifaddr
注解从集群中的每个节点检索。在 IPv4 集群中,此注解类似以下示例:"k8s.ovn.org/node-primary-ifaddr: {"ipv4":"192.168.111.23/24"}"
。
如果出口 IP 不在主网络接口子网的子网中,您可以在不是主网络接口类型的另一个 Linux 网络接口中使用出口 IP。这样一来,OpenShift Container Platform 管理员提供了对网络方面的更高级别控制,如路由、寻址、分段和安全策略。此功能允许用户选择通过特定网络接口路由工作负载流量,如流量分段或满足特殊要求。
如果出口 IP 不在主网络接口的子网中,如果节点上存在另一个网络接口,则可能会出现为出口流量选择另一个网络接口。
您可以通过检查 k8s.ovn.org/host-cidrs
Kubernetes 节点注解来确定其他哪些网络接口可能支持出口 IP。此注释包含为主网络接口找到的地址和子网掩码。它还包含其他网络接口地址和子网掩码信息。这些地址和子网掩码分配给使用最长前缀匹配路由机制的网络接口,以确定哪个网络接口支持出口 IP。
OVN-Kubernetes 提供了一种机制来控制和直接从特定命名空间和 pod 出站网络流量。这样可确保它通过特定的网络接口和特定的出口 IP 地址退出集群。
为不是主网络接口的网络接口分配出口 IP 的要求
对于希望出口 IP 和流量通过不是主网络接口的特定接口路由的用户,必须满足以下条件:
- OpenShift Container Platform 安装在裸机集群中。此功能在云或 hypervisor 环境中被禁用。
- 您的 OpenShift Container Platform pod 没有配置为 host-networked。
- 如果删除了网络接口,或者 IP 地址和子网掩码允许删除在接口上托管的出口 IP,则会重新配置出口 IP。因此,它可以分配给另一个节点和接口。
对于网络接口,必须启用 IP 转发。要启用 IP 转发,您可以使用
oc edit network.operator
命令并编辑类似以下示例的对象:# ... spec: clusterNetwork: - cidr: 10.128.0.0/14 hostPrefix: 23 defaultNetwork: ovnKubernetesConfig: gatewayConfig: ipForwarding: Global # ...
24.10.1.4. 将出口 IP 分配给 pod
要将一个或多个出口 IP 分配给命名空间中的命名空间或特定 pod,必须满足以下条件:
-
集群中至少有一个节点必须具有
k8s.ovn.org/egress-assignable: ""
标签。 -
存在一个
EgressIP
对象定义一个或多个出口 IP 地址,用作从命名空间中离开集群的流量的源 IP 地址。
如果您在为出口 IP 分配标记集群中的任何节点之前创建 EgressIP
对象,OpenShift Container Platform 可能会将每个出口 IP 地址分配给第一个节点,并使用 k8s.ovn.org/egress-assignable: ""
标签。
要确保出口 IP 地址在集群中的不同节点广泛分发,请在创建任何 EgressIP
对象前,始终将标签应用到您想托管出口 IP 地址的节点。
24.10.1.5. 将出口 IP 分配给节点
在创建 EgressIP
对象时,以下条件适用于标记为 k8s.ovn.org/egress-assignable: ""
标签的节点:
- 每次不会将出口 IP 地址分配给多个节点。
- 出口 IP 地址可在可以托管出口 IP 地址的可用节点之间平衡。
如果
EgressIP
对象中的spec.EgressIPs
数组指定了多个 IP 地址,则适用以下条件:- 任何节点都不会托管超过一个指定的 IP 地址。
- 流量在给定命名空间的指定 IP 地址之间大致相等。
- 如果节点不可用,则会自动重新分配给它的所有出口 IP 地址,但符合前面描述的条件。
当 Pod 与多个 EgressIP
对象的选择器匹配时,无法保证在 EgressIP
对象中指定的出口 IP 地址被分配为 pod 的出口 IP 地址。
另外,如果 EgressIP
对象指定了多个出口 IP 地址,则无法保证可以使用哪些出口 IP 地址。例如,如果 pod 与带有两个出口 IP 地址 (10.10.20.1
和 10.10.20.2
) 的 EgressIP
对象的选择器匹配,其中任何一个都可以用于每个 TCP 连接或 UDP 对话。
24.10.1.6. 出口 IP 地址配置架构图
下图显示了出口 IP 地址配置。图中描述了,在一个集群的三个节点上运行的两个不同命名空间中的四个 pod。节点从主机网络上的 192.168.126.0/18
CIDR 块中分配 IP 地址。
Node 1 和 Node 3 都标记为 k8s.ovn.org/egress-assignable: ""
,因此可用于分配出口 IP 地址。
图中的横线描述了 pod1、pod2 和 pod 3 的流量流,通过 pod 网络来从 Node 1 和 Node 3 出口集群。当外部服务从示例 EgressIP
对象选择的任何 pod 接收流量时,源 IP 地址为 192.168.126.10
或 192.168.126.102
。这两个节点之间流量大致平衡。
图中的以下资源被详细描述:
命名空间
对象命名空间在以下清单中定义:
命名空间对象
apiVersion: v1 kind: Namespace metadata: name: namespace1 labels: env: prod --- apiVersion: v1 kind: Namespace metadata: name: namespace2 labels: env: prod
EgressIP
对象以下
EgressIP
对象描述了一个配置,该配置选择将env
标签设置为prod
的任意命名空间中的所有 pod。所选 pod 的出口 IP 地址为192.168.126.10
和192.168.126.102
。EgressIP
对象apiVersion: k8s.ovn.org/v1 kind: EgressIP metadata: name: egressips-prod spec: egressIPs: - 192.168.126.10 - 192.168.126.102 namespaceSelector: matchLabels: env: prod status: items: - node: node1 egressIP: 192.168.126.10 - node: node3 egressIP: 192.168.126.102
对于上例中的配置,OpenShift Container Platform 会为可用节点分配两个出口 IP 地址。
status
字段显示是否以及在哪里分配了出口 IP 地址。
24.10.2. EgressIP 对象
以下 YAML 描述了 EgressIP
对象的 API。对象有效的范围为集群,它不是在命名空间中创建的。
apiVersion: k8s.ovn.org/v1 kind: EgressIP metadata: name: <name> 1 spec: egressIPs: 2 - <ip_address> namespaceSelector: 3 ... podSelector: 4 ...
以下 YAML 描述了命名空间选择器的小节:
命名空间选择器小节
namespaceSelector: 1
matchLabels:
<label_name>: <label_value>
- 1
- 命名空间的一个或多个匹配规则。如果提供多个匹配规则,则会选择所有匹配的命名空间。
以下 YAML 描述了 pod 选择器的可选小节:
Pod 选择器片段
podSelector: 1
matchLabels:
<label_name>: <label_value>
- 1
- 可选:与指定
namespaceSelector
规则匹配的命名空间中 pod 的一个或多个匹配规则。如果指定,则仅选择匹配的 pod。命名空间中的其他 Pod 不会被选择。
在以下示例中,EgressIP
对象将 192.168.126.11
和 192.168.126.102
出口 IP 地址与将 app
标签设置为 web
的 pod 关联,并位于将 env
标签设置为 prod
的命名空间中:
EgressIP
对象示例
apiVersion: k8s.ovn.org/v1 kind: EgressIP metadata: name: egress-group1 spec: egressIPs: - 192.168.126.11 - 192.168.126.102 podSelector: matchLabels: app: web namespaceSelector: matchLabels: env: prod
在以下示例中,EgressIP
对象将 192.168.127.30
和 192.168.127.40
出口 IP 地址与任何没有将 environment
标签设置为 development
的 pod 相关联:
EgressIP
对象示例
apiVersion: k8s.ovn.org/v1 kind: EgressIP metadata: name: egress-group2 spec: egressIPs: - 192.168.127.30 - 192.168.127.40 namespaceSelector: matchExpressions: - key: environment operator: NotIn values: - development
24.10.3. egressIPConfig 对象
作为出口 IP 的功能,reachabilityTotalTimeoutSeconds
参数配置 EgressIP 节点可访问性检查总超时时间(以秒为单位)。如果在这个超时时间内无法访问 EgressIP 节点,则会声明该节点。
您可以在配置文件中为 egressIPConfig
对象设置 reachabilityTotalTimeoutSeconds
的值。设置较大的值可能会导致 EgressIP 实现对节点更改做出反应的速度较慢。对于有问题的 EgressIP 节点,这个实现的反应会较慢。
如果您从 egressIPConfig
对象中省略了 reachabilityTotalTimeoutSeconds
参数,则平台会选择一个合理的默认值,这可能会随时间变化。当前的默认值为 1
秒。0
代表禁用 EgressIP 节点的访问性检查。
以下 egressIPConfig
对象描述了将 reachabilityTotalTimeoutSeconds
从默认的 1
秒探测改为 5
秒探测:
apiVersion: operator.openshift.io/v1 kind: Network metadata: name: cluster spec: clusterNetwork: - cidr: 10.128.0.0/14 hostPrefix: 23 defaultNetwork: ovnKubernetesConfig: egressIPConfig: 1 reachabilityTotalTimeoutSeconds: 5 2 gatewayConfig: routingViaHost: false genevePort: 6081
24.10.4. 标记节点以托管出口 IP 地址
您可以将 k8s.ovn.org/egress-assignable=""
标签应用到集群中的节点,以便 OpenShift Container Platform 可以为该节点分配一个或多个出口 IP 地址。
先决条件
-
安装 OpenShift CLI(
oc
)。 - 以集群管理员身份登录集群。
流程
要标记节点,使其可以托管一个或多个出口 IP 地址,请输入以下命令:
$ oc label nodes <node_name> k8s.ovn.org/egress-assignable="" 1
- 1
- 要标记的节点的名称。
提示您还可以应用以下 YAML 将标签添加到节点:
apiVersion: v1 kind: Node metadata: labels: k8s.ovn.org/egress-assignable: "" name: <node_name>