网络


OpenShift Container Platform 4.12

配置和管理集群网络

Red Hat OpenShift Documentation Team

摘要

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

第 1 章 关于网络

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

以下列表重点介绍集群中可用的一些最常用的 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 相互间进行通信。
流控制传输协议 (SCTP)
SCTP 是基于信息的可靠协议,可在 IP 网络之上运行。
taint
污点和容限可确保将 pod 调度到适当的节点上。您可以在节点上应用一个或多个污点。
容限 (tolerations)
您可以将容限应用到 pod。容限 (toleration) 允许调度程序调度具有匹配污点的 pod。
Web 控制台
用于管理 OpenShift Container Platform 的用户界面(UI)。

第 3 章 访问主机

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

3.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 密钥:

    Copy to Clipboard Toggle word wrap
    $ ssh -i <ssh-key-path> core@<master-hostname>

第 4 章 网络 Operator 概述

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

4.1. Cluster Network Operator

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

4.2. DNS Operator

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

4.3. Ingress Operator

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

4.4. 外部 DNS Operator

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

4.5. Ingress Node Firewall Operator

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

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

第 5 章 OpenShift Container Platform 中的 Cluster Network Operator

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

5.1. Cluster Network Operator

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

流程

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

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

    Copy to Clipboard Toggle word wrap
    $ oc get -n openshift-network-operator deployment/network-operator

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    network-operator   1/1     1            1           56m

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

    Copy to Clipboard Toggle word wrap
    $ oc get clusteroperator/network

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME      VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
    network   4.5.4     True        False         False      50m

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

5.2. 查看集群网络配置

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc describe network.config/cluster

    输出示例

    Copy to Clipboard Toggle word wrap
    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 字段显示集群网络配置的当前状态。

5.3. 查看 Cluster Network Operator 状态

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc describe clusteroperators/network

5.4. 查看 Cluster Network Operator 日志

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc logs --namespace=openshift-network-operator deployment/network-operator

5.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
集群网络插件,如 OpenShift SDN 或 OVN-Kubernetes。
注意

在集群安装后,您无法修改上一节中列出的字段。

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

5.5.1. Cluster Network Operator 配置对象

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

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

metadata.name

字符串

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

spec.clusterNetwork

array

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

Copy to Clipboard Toggle word wrap
spec:
  clusterNetwork:
  - cidr: 10.128.0.0/19
    hostPrefix: 23
  - cidr: 10.128.32.0/19
    hostPrefix: 23

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

spec.serviceNetwork

array

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

Copy to Clipboard Toggle word wrap
spec:
  serviceNetwork:
  - 172.30.0.0/14

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

spec.defaultNetwork

object

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

spec.kubeProxyConfig

object

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

重要

对于需要在多个网络间部署对象的集群,请确保为 install-config.yaml 文件中定义的每种网络类型指定与 clusterNetwork.hostPrefix 参数相同的值。为每个 clusterNetwork.hostPrefix 参数设置不同的值可能会影响 OVN-Kubernetes 网络插件,其中插件无法有效地在不同节点间路由对象流量。

defaultNetwork 对象配置

下表列出了 defaultNetwork 对象的值:

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

type

字符串

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

注意

OpenShift Container Platform 默认使用 OVN-Kubernetes 网络插件。

openshiftSDNConfig

object

此对象仅对 OpenShift SDN 网络插件有效。

ovnKubernetesConfig

object

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

配置 OpenShift SDN 网络插件

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

表 5.3. openshiftSDNConfig object
字段类型描述

模式

string

OpenShift SDN 的网络隔离模式。

mtu

integer

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

vxlanPort

integer

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

OpenShift SDN 配置示例

Copy to Clipboard Toggle word wrap
defaultNetwork:
  type: OpenShiftSDN
  openshiftSDNConfig:
    mode: NetworkPolicy
    mtu: 1450
    vxlanPort: 4789

配置 OVN-Kubernetes 网络插件

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

表 5.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

表 5.5. policyAuditConfig object
字段类型描述

rateLimit

整数

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

maxFileSize

整数

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

目的地

字符串

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

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

syslogFacility

字符串

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

表 5.6. gatewayConfig object
字段类型描述

routingViaHost

布尔值

将此字段设置为 true,将来自 pod 的出口流量发送到主机网络堆栈。

注意

在 OpenShift Container Platform {version} 中,出口 IP 仅分配给主接口。因此,将 routingViaHost 设置为 true 将无法用于 OpenShift Container Platform {version} 中的出口 IP。

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

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

注意

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

启用 IPSec 的 OVN-Kubernetes 配置示例

Copy to Clipboard Toggle word wrap
defaultNetwork:
  type: OVNKubernetes
  ovnKubernetesConfig:
    mtu: 1400
    genevePort: 6081
    ipsecConfig: {}

kubeProxyConfig object configuration

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

表 5.7. kubeProxyConfig object
字段类型描述

iptablesSyncPeriod

字符串

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

注意

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

proxyArguments.iptables-min-sync-period

array

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

Copy to Clipboard Toggle word wrap
kubeProxyConfig:
  proxyArguments:
    iptables-min-sync-period:
    - 0s

5.5.2. Cluster Network Operator 配置示例

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

Cluster Network Operator 对象示例

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  clusterNetwork: 
1

  - cidr: 10.128.0.0/14
    hostPrefix: 23
  serviceNetwork: 
2

  - 172.30.0.0/16
  defaultNetwork: 
3

    type: OpenShiftSDN
    openshiftSDNConfig:
      mode: NetworkPolicy
      mtu: 1450
      vxlanPort: 4789
  kubeProxyConfig:
    iptablesSyncPeriod: 30s
    proxyArguments:
      iptables-min-sync-period:
      - 0s

1 2 3
仅在集群安装过程中配置。

5.6. 其他资源

第 6 章 OpenShift Container Platform 中的 DNS Operator

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

6.1. DNS Operator

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

流程

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

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

    Copy to Clipboard Toggle word wrap
    $ oc get -n openshift-dns-operator deployment/dns-operator

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME           READY     UP-TO-DATE   AVAILABLE   AGE
    dns-operator   1/1       1            1           23h

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

    Copy to Clipboard Toggle word wrap
    $ oc get clusteroperator/dns

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME      VERSION     AVAILABLE   PROGRESSING   DEGRADED   SINCE
    dns       4.1.0-0.11  True        False         False      92m

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

6.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:

    Copy to Clipboard Toggle word wrap
    oc patch dns.operator.openshift.io default --type merge --patch '{"spec":{"managementState":"Unmanaged"}}'

6.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 对象:

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

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

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

      Copy to Clipboard Toggle word wrap
      $ oc edit dns.operator/default
    2. 为污点指定污点键和一个容忍度:

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

6.4. 查看默认 DNS

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc describe dns.operator/default

    输出示例

    Copy to Clipboard Toggle word wrap
    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 命令:

    Copy to Clipboard Toggle word wrap
    $ oc get networks.config/cluster -o jsonpath='{$.status.serviceNetwork}'

输出示例

Copy to Clipboard Toggle word wrap
[172.30.0.0/16]

6.5. 使用 DNS 转发

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

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

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc edit dns.operator/default

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

    配置 DNS 转发

    Copy to Clipboard Toggle word wrap
    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 转发

    Copy to Clipboard Toggle word wrap
    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. 查看配置映射:

    Copy to Clipboard Toggle word wrap
    $ oc get configmap/dns-default -n openshift-dns -o yaml

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

    Copy to Clipboard Toggle word wrap
    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 守护进程集的滚动更新。

其他资源

6.6. DNS Operator 状态

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

流程

查看 DNS Operator 的状态:

Copy to Clipboard Toggle word wrap
$ oc describe clusteroperators/dns

6.7. DNS Operator 日志

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

流程

查看 DNS Operator 的日志:

Copy to Clipboard Toggle word wrap
$ oc logs -n openshift-dns-operator deployment/dns-operator -c dns-operator

6.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,输入以下命令:

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

    Copy to Clipboard Toggle word wrap
    $ oc patch dnses.operator.openshift.io/default -p '{"spec":{"logLevel":"Trace"}}' --type=merge

验证

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

    Copy to Clipboard Toggle word wrap
    $ oc get configmap/dns-default -n openshift-dns -o yaml

6.9. 查看 CoreDNS 日志

您可以使用 oc logs 命令查看 CoreDNS 日志。

流程

  • 输入以下命令来查看特定 CoreDNS pod 的日志:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-dns logs -c dns <core_dns_pod_name>
  • 输入以下命令遵循所有 CoreDNS pod 的日志:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-dns logs -c dns -l dns.operator.openshift.io/daemonset-dns=default -f --max-log-requests=<number> 
    1
    1
    指定要流传输日志的 DNS pod 数量。最大值为 6。

6.10. 设置 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,请输入以下命令:

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

    Copy to Clipboard Toggle word wrap
    $ oc patch dnses.operator.openshift.io/default -p '{"spec":{"operatorLogLevel":"Trace"}}' --type=merge

6.11. 调整 CoreDNS 缓存

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc edit dns.operator.openshift.io/default
  2. 修改生存时间 (TTL) 缓存值:

    配置 DNS 缓存

    Copy to Clipboard Toggle word wrap
    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 字段设为低值可能会导致集群、任何上游解析器或两者中负载的增加。

第 7 章 OpenShift Container Platform 中的 Ingress Operator

7.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 端点的方法。

7.2. Ingress 配置资产

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

Ingress 资源的 YAML 定义

Copy to Clipboard Toggle word wrap
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 资源生成默认主机时,还会使用此域。

7.3. Ingress Controller 配置参数

IngressController 自定义资源(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

  • Amazon Web Services (AWS): LoadBalancerService (带有外部范围)
  • Azure: LoadBalancerService (具有外部范围)
  • Google Cloud Platform(GCP): LoadBalancerService (具有外部范围)

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

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

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

如果您没有在这些字段中设置值,则默认值基于 IngressController 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。例如:

Copy to Clipboard Toggle word wrap
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 响应。如果此字段为空,则不会调整任何请求标头。

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 参数。

例如:

Copy to Clipboard Toggle word wrap
  httpCaptureCookies:
  - matchType: Exact
    maxLength: 128
    name: MYCOOKIE

httpCaptureHeaders

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

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

Copy to Clipboard Toggle word wrap
  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 可能会妨碍对问题的检测和诊断。这些请求可能是由端口扫描导致的,在这种情况下,记录空请求有助于检测入侵尝试。

7.3.1. Ingress Controller TLS 安全配置集

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

7.3.1.1. 了解 TLS 安全配置集

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

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

表 7.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 可能会导致应用新的配置集配置,从而导致推出部署。

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

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

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

Copy to Clipboard Toggle word wrap
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 安全配置集:

    Copy to Clipboard Toggle word wrap
    $ oc edit IngressController default -n openshift-ingress-operator
  2. 添加 spec.tlsSecurityProfile 字段:

    Custom 配置集的 IngressController CR 示例

    Copy to Clipboard Toggle word wrap
    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 中是否设置了配置集:

    Copy to Clipboard Toggle word wrap
    $ oc describe IngressController default -n openshift-ingress-operator

    输出示例

    Copy to Clipboard Toggle word wrap
    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
     ...

7.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 所述。例如:

    Copy to Clipboard Toggle word wrap
     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 捆绑包创建配置映射:

    Copy to Clipboard Toggle word wrap
    $ 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 资源:

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

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

    Copy to Clipboard Toggle word wrap
      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)。
Copy to Clipboard Toggle word wrap
$ openssl  x509 -in custom-cert.pem  -noout -subject
subject= /CN=example.com/ST=NC/C=US/O=Security/OU=OpenShift

7.4. 查看默认的 Ingress Controller

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

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

流程

  • 查看默认的 Ingress Controller:

    Copy to Clipboard Toggle word wrap
    $ oc describe --namespace=openshift-ingress-operator ingresscontroller/default

7.5. 查看 Ingress Operator 状态

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

流程

  • 查看您的 Ingress Operator 状态:

    Copy to Clipboard Toggle word wrap
    $ oc describe clusteroperators/ingress

7.6. 查看 Ingress Controller 日志

您可以查看 Ingress Controller 日志。

流程

  • 查看 Ingress Controller 日志:

    Copy to Clipboard Toggle word wrap
    $ oc logs --namespace=openshift-ingress-operator deployments/ingress-operator -c <container_name>

7.7. 查看 Ingress Controller 状态

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

流程

  • 查看 Ingress Controller 的状态:

    Copy to Clipboard Toggle word wrap
    $ oc describe --namespace=openshift-ingress-operator ingresscontroller/<name>

7.8. 配置 Ingress Controller

7.8.1. 设置自定义默认证书

作为管理员,您可以通过创建 Secret 资源并编辑 IngressController 自定义资源 (CR),将 Ingress Controller 配置为使用自定义证书。

先决条件

  • 您必须在 PEM 编码文件中有一个证书/密钥对,其中该证书由可信证书认证机构签名,或者由您在一个自定义 PKI 中配置的私有可信证书认证机构签名。
  • 您的证书满足以下要求:

    • 该证书对入口域有效。
    • 证书使用 subjectAltName 扩展来指定通配符域,如 *.apps.ocp4.example.com
  • 您必须有一个 IngressController CR。您可以使用默认值:

    Copy to Clipboard Toggle word wrap
    $ oc --namespace openshift-ingress-operator get ingresscontrollers

    输出示例

    Copy to Clipboard Toggle word wrap
    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 资源。

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

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

    Copy to Clipboard Toggle word wrap
    $ echo Q |\
      openssl s_client -connect console-openshift-console.apps.<domain>:443 -showcerts 2>/dev/null |\
      openssl x509 -noout -subject -issuer -enddate

    其中:

    <domain>
    指定集群的基域名。

    输出示例

    Copy to Clipboard Toggle word wrap
    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 来设置自定义默认证书:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: default
      namespace: openshift-ingress-operator
    spec:
      defaultCertificate:
        name: custom-certs-default

    证书 Secret 名称应该与用来更新 CR 的值匹配。

修改了 IngressController CR 后,Ingress Operator 将更新 Ingress Controller 的部署以使用自定义证书。

7.8.2. 删除自定义默认证书

作为管理员,您可以删除配置了 Ingress Controller 的自定义证书。

先决条件

  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已安装 OpenShift CLI(oc)。
  • 您之前为 Ingress Controller 配置了自定义默认证书。

流程

  • 要删除自定义证书并恢复 OpenShift Container Platform 附带的证书,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc patch -n openshift-ingress-operator ingresscontrollers/default \
      --type json -p $'- op: remove\n  path: /spec/defaultCertificate'

    集群协调新证书配置时可能会有延迟。

验证

  • 要确认原始集群证书已被恢复,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ echo Q | \
      openssl s_client -connect console-openshift-console.apps.<domain>:443 -showcerts 2>/dev/null | \
      openssl x509 -noout -subject -issuer -enddate

    其中:

    <domain>
    指定集群的基域名。

    输出示例

    Copy to Clipboard Toggle word wrap
    subject=CN = *.apps.<domain>
    issuer=CN = ingress-operator@1620633373
    notAfter=May 10 10:44:36 2023 GMT

7.8.3. 自动扩展 Ingress Controller

您可以自动缩放 Ingress Controller 以动态满足路由性能或可用性要求,如提高吞吐量的要求。

以下流程提供了一个扩展默认 Ingress Controller 的示例。

先决条件

  • 已安装 OpenShift CLI (oc)。
  • 您可以使用具有 cluster-admin 角色的用户访问 OpenShift Container Platform 集群。
  • 已安装自定义 Metrics Autoscaler Operator 和关联的 KEDA Controller。

    • 您可以在 Web 控制台中使用 OperatorHub 安装 Operator。安装 Operator 后,您可以创建 KedaController 实例。

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc create -n openshift-ingress-operator serviceaccount thanos && oc describe -n openshift-ingress-operator serviceaccount thanos

    输出示例

    Copy to Clipboard Toggle word wrap
    Name:                thanos
    Namespace:           openshift-ingress-operator
    Labels:              <none>
    Annotations:         <none>
    Image pull secrets:  thanos-dockercfg-kfvf2
    Mountable secrets:   thanos-dockercfg-kfvf2
    Tokens:              thanos-token-c422q
    Events:              <none>

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

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

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

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

      Copy to Clipboard Toggle word wrap
      $ oc process TOKEN="$secret" -f - <<EOF | oc apply -n openshift-ingress-operator -f -
      apiVersion: template.openshift.io/v1
      kind: Template
      parameters:
      - name: TOKEN
      objects:
      - apiVersion: keda.sh/v1alpha1
        kind: TriggerAuthentication
        metadata:
          name: keda-trigger-auth-prometheus
        spec:
          secretTargetRef:
          - parameter: bearerToken
            name: \${TOKEN}
            key: token
          - parameter: ca
            name: \${TOKEN}
            key: ca.crt
      EOF
  4. 创建并应用角色以从 Thanos 读取指标:

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

      thanos-metrics-reader.yaml

      Copy to Clipboard Toggle word wrap
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: thanos-metrics-reader
        namespace: openshift-ingress-operator
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        - nodes
        verbs:
        - get
      - apiGroups:
        - metrics.k8s.io
        resources:
        - pods
        - nodes
        verbs:
        - get
        - list
        - watch
      - apiGroups:
        - ""
        resources:
        - namespaces
        verbs:
        - get

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

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

    Copy to Clipboard Toggle word wrap
    $ oc adm policy -n openshift-ingress-operator add-role-to-user thanos-metrics-reader -z thanos --role-namespace=openshift-ingress-operator
    Copy to Clipboard Toggle word wrap
    $ 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 定义示例

    Copy to Clipboard Toggle word wrap
    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: ingress-scaler
      namespace: openshift-ingress-operator
    spec:
      scaleTargetRef: 
    1
    
        apiVersion: operator.openshift.io/v1
        kind: IngressController
        name: default
        envSourceContainerName: ingress-operator
      minReplicaCount: 1
      maxReplicaCount: 20 
    2
    
      cooldownPeriod: 1
      pollingInterval: 1
      triggers:
      - type: prometheus
        metricType: AverageValue
        metadata:
          serverAddress: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 
    3
    
          namespace: openshift-ingress-operator 
    4
    
          metricName: 'kube-node-role'
          threshold: '1'
          query: 'sum(kube_node_role{role="worker",service="kube-state-metrics"})' 
    5
    
          authModes: "bearer"
        authenticationRef:
          name: keda-trigger-auth-prometheus

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

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

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

    Copy to Clipboard Toggle word wrap
    $ oc apply -f ingress-autoscaler.yaml

验证

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

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

      Copy to Clipboard Toggle word wrap
      $ oc get -n openshift-ingress-operator ingresscontroller/default -o yaml | grep replicas:

      输出示例

      Copy to Clipboard Toggle word wrap
        replicas: 3

    • 获取 openshift-ingress 项目中的 pod:

      Copy to Clipboard Toggle word wrap
      $ oc get pods -n openshift-ingress

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                             READY   STATUS    RESTARTS   AGE
      router-default-7b5df44ff-l9pmm   2/2     Running   0          17h
      router-default-7b5df44ff-s5sl5   2/2     Running   0          3d22h
      router-default-7b5df44ff-wwsth   2/2     Running   0          66s

7.8.4. 扩展 Ingress Controller

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

注意

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'

    输出示例

    Copy to Clipboard Toggle word wrap
    2

  2. 使用 oc patch 命令,将默认 IngressController 扩展至所需的副本数。以下示例将默认 IngressController 扩展至 3 个副本:

    Copy to Clipboard Toggle word wrap
    $ oc patch -n openshift-ingress-operator ingresscontroller/default --patch '{"spec":{"replicas": 3}}' --type=merge

    输出示例

    Copy to Clipboard Toggle word wrap
    ingresscontroller.operator.openshift.io/default patched

  3. 验证默认 IngressController 是否已扩展至您指定的副本数:

    Copy to Clipboard Toggle word wrap
    $ oc get -n openshift-ingress-operator ingresscontrollers/default -o jsonpath='{$.status.availableReplicas}'

    输出示例

    Copy to Clipboard Toggle word wrap
    3

    提示

    您还可以应用以下 YAML 将 Ingress Controller 扩展为三个副本:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: default
      namespace: openshift-ingress-operator
    spec:
      replicas: 3               
    1
    1
    如果需要不同数量的副本,请更改 replicas 值。

7.8.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 定义:

    Copy to Clipboard Toggle word wrap
    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 的容器:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress logs deployment.apps/router-default -c logs

    输出示例

    Copy to Clipboard Toggle word wrap
    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 定义:

    Copy to Clipboard Toggle word wrap
    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 端点:

    Copy to Clipboard Toggle word wrap
    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 为空:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: default
      namespace: openshift-ingress-operator
    spec:
      replicas: 2
      logging:
        access: null

7.8.6. 设置 Ingress Controller 线程数

集群管理员可设置线程数,以增加集群可以处理的入站的连接量。您可以修补现有的 Ingress Controller 来增加线程量。

先决条件

  • 以下假设您已创建了 Ingress Controller。

流程

  • 更新 Ingress Controller 以增加线程数量:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress-operator patch ingresscontroller/default --type=merge -p '{"spec":{"tuningOptions": {"threadCount": 8}}}'
    注意

    如果您的节点有能力运行大量资源,您可以使用与预期节点容量匹配的标签配置 spec.nodePlacement.nodeSelector,并将 spec.tuningOptions.threadCount 配置为一个适当的高值。

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

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

警告

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

重要

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

图 7.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) ,如下例所示:

    Copy to Clipboard Toggle word wrap
    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:

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

    Copy to Clipboard Toggle word wrap
    $ oc --all-namespaces=true get ingresscontrollers

7.8.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 资源:

      Copy to Clipboard Toggle word wrap
      $ oc -n openshift-ingress-operator edit ingresscontroller/default
    2. 编辑 YAML 文件:

      clientAccess 配置为 Global 的示例

      Copy to Clipboard Toggle word wrap
        spec:
          endpointPublishingStrategy:
            loadBalancer:
              providerParameters:
                gcp:
                  clientAccess: Global 
      1
      
                type: GCP
              scope: Internal
            type: LoadBalancerService

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

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress edit svc/router-default -o yaml

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

7.8.9. 设置 Ingress Controller 健康检查间隔

集群管理员可以设置健康检查间隔,以定义路由器在两个连续健康检查之间等待的时间。这个值会作为所有路由的默认值进行全局应用。默认值为 5 秒。

先决条件

  • 以下假设您已创建了 Ingress Controller。

流程

  • 更新 Ingress Controller,以更改后端健康检查之间的间隔:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress-operator patch ingresscontroller/default --type=merge -p '{"spec":{"tuningOptions": {"healthCheckInterval": "8s"}}}'
    注意

    要覆盖单个路由的 healthCheckInterval,请使用路由注解 router.openshift.io/haproxy.health.check.interval

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

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

警告

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

重要

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

先决条件

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

流程

  1. 通过删除并重新创建集群,将 默认 Ingress Controller 配置为内部。

    Copy to Clipboard Toggle word wrap
    $ oc replace --force --wait --filename - <<EOF
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      namespace: openshift-ingress-operator
      name: default
    spec:
      endpointPublishingStrategy:
        type: LoadBalancerService
        loadBalancer:
          scope: Internal
    EOF

7.8.11. 配置路由准入策略

管理员和应用程序开发人员可在多个命名空间中运行具有相同域名的应用程序。这是针对多个团队开发的、在同一个主机名上公开的微服务的机构。

警告

只有在命名空间间有信任的集群才会启用跨命名空间之间的声明,否则恶意用户可能会接管主机名。因此,默认的准入策略不允许在命名空间间声明主机名。

先决条件

  • 必须具有集群管理员权限。

流程

  • 使用以下命令编辑 ingresscontroller 资源变量的.spec. routeAdmission 字段:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress-operator patch ingresscontroller/default --patch '{"spec":{"routeAdmission":{"namespaceOwnership":"InterNamespaceAllowed"}}}' --type=merge

    Ingress 控制器配置参数

    Copy to Clipboard Toggle word wrap
    spec:
      routeAdmission:
        namespaceOwnership: InterNamespaceAllowed
    ...

    提示

    您还可以应用以下 YAML 来配置路由准入策略:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: IngressController
    metadata:
      name: default
      namespace: openshift-ingress-operator
    spec:
      routeAdmission:
        namespaceOwnership: InterNamespaceAllowed

7.8.12. 使用通配符路由

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

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

流程

  1. 配置通配符策略。

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

      Copy to Clipboard Toggle word wrap
      $ oc edit IngressController
    2. spec 下,将 wildcardPolicy 字段设置 为 WildcardsDisallowedWildcardsAllowed

      Copy to Clipboard Toggle word wrap
      spec:
        routeAdmission:
          wildcardPolicy: WildcardsDisallowed # or WildcardsAllowed

7.8.13. 使用 X-Forwarded 标头

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

流程

  1. 为 Ingress Controller 配置 HTTPHeaders 字段。

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

      Copy to Clipboard Toggle word wrap
      $ oc edit IngressController
    2. spec 下,将 HTTPHeaders 策略字段设置为 AppendReplaceIfNoneNever:

      Copy to Clipboard Toggle word wrap
      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 的全局设置值。

7.8.14. 启用 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 路由。

警告

使用带有重新加密路由的 WebSockets,并在 Ingress Controller 上启用 HTTP/2 需要 WebSocket 支持 HTTP/2。通过 HTTP/2 的 websocket 是 HAProxy 2.4 的 Websocket 功能,目前在 OpenShift Container Platform 中不支持它。

重要

对于非 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 命令:

    Copy to Clipboard Toggle word wrap
    $ 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 命令:

    Copy to Clipboard Toggle word wrap
    $ oc annotate ingresses.config/cluster ingress.operator.openshift.io/default-enable-http2=true
    提示

    您还可以应用以下 YAML 来添加注解:

    Copy to Clipboard Toggle word wrap
    apiVersion: config.openshift.io/v1
    kind: Ingress
    metadata:
      name: cluster
      annotations:
        ingress.operator.openshift.io/default-enable-http2: "true"

7.8.15. 为 Ingress Controller 配置 PROXY 协议

当 Ingress Controller 使用 HostNetworkNodePortService 端点发布策略类型时,集群管理员可配置 PROXY 协议。PROXY 协议使负载均衡器能够为 Ingress Controller 接收的连接保留原始客户端地址。原始客户端地址可用于记录、过滤和注入 HTTP 标头。在默认配置中,Ingress Controller 接收的连接只包含与负载均衡器关联的源地址。

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

重要

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

警告

在使用 Keepalived Ingress VIP 的非云平台上带有安装程序置备的集群的默认 Ingress Controller 不支持 PROXY 协议。

先决条件

  • 已创建一个 Ingress Controller。

流程

  1. 编辑 Ingress Controller 资源:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress-operator edit ingresscontroller/default
  2. 设置 PROXY 配置:

    • 如果您的 Ingress Controller 使用 hostNetwork 端点发布策略类型,将 spec.endpointPublishingStrategy.hostNetwork.protocol 子字段设置为 PROXY

      hostNetwork 配置为 PROXY 的示例

      Copy to Clipboard Toggle word wrap
        spec:
          endpointPublishingStrategy:
            hostNetwork:
              protocol: PROXY
            type: HostNetwork

    • 如果您的 Ingress Controller 使用 NodePortService 端点发布策略类型,将 spec.endpointPublishingStrategy.nodePort.protocol 子字段设置为 PROXY

      nodePort 配置为 PROXY 示例

      Copy to Clipboard Toggle word wrap
        spec:
          endpointPublishingStrategy:
            nodePort:
              protocol: PROXY
            type: NodePortService

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

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

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

先决条件

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

流程

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

    1. 编辑 ingress 集群资源 :

      Copy to Clipboard Toggle word wrap
      $ oc edit ingresses.config/cluster -o yaml
    2. 编辑 YAML 文件:

      示例 appsDomain 配置为 test.example.com

      Copy to Clipboard Toggle word wrap
      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. 公开路由:

      Copy to Clipboard Toggle word wrap
      $ oc expose service hello-openshift
      route.route.openshift.io/hello-openshift exposed

      输出示例:

      Copy to Clipboard Toggle word wrap
      $ oc get routes
      NAME              HOST/PORT                                   PATH   SERVICES          PORT       TERMINATION   WILDCARD
      hello-openshift   hello_openshift-<my_project>.test.example.com
      hello-openshift   8080-tcp                 None

7.8.17. 转换 HTTP 标头的大小写

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

重要

OpenShift Container Platform 包括 HAProxy 2.2。如果要更新基于 web 的负载均衡器的这个版本,请确保将 spec.httpHeaders.headerNameCaseAdjustments 部分添加到集群的配置文件中。

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

先决条件

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

流程

  • 使用 oc patch 命令大写 HTTP 标头。

    1. 运行以下命令,将 HTTP 标头从 host 更改为 Host

      Copy to Clipboard Toggle word wrap
      $ oc -n openshift-ingress-operator patch ingresscontrollers/default --type=merge --patch='{"spec":{"httpHeaders":{"headerNameCaseAdjustments":["Host"]}}}'
    2. 创建 Route 资源 YAML 文件,以便注解可应用到应用程序。

      名为 my-application 的路由示例

      Copy to Clipboard Toggle word wrap
      apiVersion: route.openshift.io/v1
      kind: Route
      metadata:
        annotations:
          haproxy.router.openshift.io/h1-adjust-case: true 
      1
      
        name: <application_name>
        namespace: <application_name>
      # ...

      1
      设置 haproxy.router.openshift.io/h1-adjust-case,以便 Ingress Controller 能够调整指定的 host 请求标头。
  • 通过在 Ingress Controller YAML 配置文件中配置 HeaderNameCaseAdjustments 字段指定调整。

    1. 以下示例 Ingress Controller YAML 文件将 HTTP/1 请求的 host 标头调整为 Host,以适当地注解路由:

      Ingress Controller YAML 示例

      Copy to Clipboard Toggle word wrap
      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 示例

      Copy to Clipboard Toggle word wrap
      apiVersion: route.openshift.io/v1
      kind: Route
      metadata:
        annotations:
          haproxy.router.openshift.io/h1-adjust-case: true 
      1
      
        name: my-application
        namespace: my-application
      spec:
        to:
          kind: Service
          name: my-application

      1
      haproxy.router.openshift.io/h1-adjust-case 设置为 true。

7.8.18. 使用路由器压缩

您可以将 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 资源:

      Copy to Clipboard Toggle word wrap
      $ oc edit -n openshift-ingress-operator ingresscontrollers/default
    2. spec 下,将 httpCompression 策略字段设置为 mimeTypes,并指定应该应用压缩的 MIME 类型列表:

      Copy to Clipboard Toggle word wrap
      apiVersion: operator.openshift.io/v1
      kind: IngressController
      metadata:
        name: default
        namespace: openshift-ingress-operator
      spec:
        httpCompression:
          mimeTypes:
          - "text/html"
          - "text/css; charset=utf-8"
          - "application/json"
         ...

7.8.19. 公开路由器指标

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

先决条件

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ingress

    输出示例

    Copy to Clipboard Toggle word wrap
    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. 运行以下命令来获取用户名:

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

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

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

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

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

    Copy to Clipboard Toggle word wrap
    $ curl -u <user>:<password> http://<router_IP>:<stats_port>/metrics

    例 7.1. 输出示例

    Copy to Clipboard Toggle word wrap
    ...
    # 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 窗口:

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

    Copy to Clipboard Toggle word wrap
    http://<user>:<password>@<router_ip>:1936/metrics;csv

7.8.20. 自定义 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 的配置映射:

    Copy to Clipboard Toggle word wrap
    $ 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 配置映射:

    Copy to Clipboard Toggle word wrap
    $ 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. 显示副本:

    Copy to Clipboard Toggle word wrap
    $ oc get cm default-errorpages -n openshift-ingress

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                       DATA   AGE
    default-errorpages         2      25s  
    1

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

    • 对于 503 自定义 HTTP 自定义错误代码响应:

      Copy to Clipboard Toggle word wrap
      $ oc -n openshift-ingress rsh <router_pod> cat /var/lib/haproxy/conf/error_code_pages/error-page-503.http
    • 对于 404 自定义 HTTP 自定义错误代码响应:

      Copy to Clipboard Toggle word wrap
      $ oc -n openshift-ingress rsh <router_pod> cat /var/lib/haproxy/conf/error_code_pages/error-page-404.http

验证

验证自定义错误代码 HTTP 响应:

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

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

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

      Copy to Clipboard Toggle word wrap
      $ curl -vk <route_hostname>
  3. 对于 404 自定义 http 错误代码响应:

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

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

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress rsh <router> cat /var/lib/haproxy/conf/haproxy.config | grep errorfile

7.8.21. 设置 Ingress Controller 最大连接数

集群管理员可以设置 OpenShift 路由器部署的最大同时连接数。您可以修补现有的 Ingress Controller 来提高最大连接数。

先决条件

  • 以下假设您已创建了 Ingress Controller

流程

  • 更新 Ingress Controller,以更改 HAProxy 的最大连接数:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ingress-operator patch ingresscontroller/default --type=merge -p '{"spec":{"tuningOptions": {"maxConnections": 7500}}}'
    警告

    如果您设置了大于当前操作系统的 spec.tuningOptions.maxConnections 值,则 HAProxy 进程不会启动。有关这个参数的更多信息,请参阅"Ingress Controller 配置参数"部分中的表。

7.9. 其他资源

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

Ingress Node Firewall Operator 提供了一个无状态的、基于 eBPF 的防火墙,用于管理 OpenShift Container Platform 中的节点级别的入口流量。

8.1. Ingress Node Firewall Operator

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

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

重要

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

最大传输单元 (MTU) 参数是 OpenShift Container Platform 4.12 中的 4Kb (kilobytes)。

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

带有默认 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

8.2. 安装 Ingress Node Firewall Operator

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

8.2.1. 使用 CLI 安装 Ingress Node Firewall Operator

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

先决条件

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ 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:

    Copy to Clipboard Toggle word wrap
    $ 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,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ 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,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get ip -n openshift-ingress-node-firewall

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME            CSV                                         APPROVAL    APPROVED
    install-5cvnz   ingress-node-firewall.4.12.0-202211122336   Automatic   true

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

    Copy to Clipboard Toggle word wrap
    $ oc get csv -n openshift-ingress-node-firewall

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                        DISPLAY                          VERSION               REPLACES                                    PHASE
    ingress-node-firewall.4.12.0-202211122336   Ingress Node Firewall Operator   4.12.0-202211122336   ingress-node-firewall.4.12.0-202211102047   Succeeded

8.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 命名空间中:

        Copy to Clipboard Toggle word wrap
        $ oc annotate ns/openshift-ingress-node-firewall workload.openshift.io/allowed=management
        注意

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

8.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 规则:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f rule.yaml

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

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

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

metadata.name

string

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

metadata.namespace

string

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

spec.nodeSelector

string

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

Copy to Clipboard Toggle word wrap
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 节点防火墙配置对象示例

Copy to Clipboard Toggle word wrap
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 匹配的所有节点上创建一个入口节点防火墙守护进程集。

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

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

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

metadata.name

string

CR 对象的名称。

interfaces

数组

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

nodeSelector

数组

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

ingress

object

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

Ingress 对象配置

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

表 8.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 节点防火墙配置示例

Copy to Clipboard Toggle word wrap
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 节点防火墙规则示例

Copy to Clipboard Toggle word wrap
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

8.4. 查看 Ingress Node Firewall Operator 规则

流程

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

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

    Copy to Clipboard Toggle word wrap
    $ oc get <resource> <name> -o yaml

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

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

    Copy to Clipboard Toggle word wrap
    $ oc get crds | grep ingressnodefirewall

    输出示例

    Copy to Clipboard Toggle word wrap
    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 的状态:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ingress-node-firewall

    输出示例

    Copy to Clipboard Toggle word wrap
    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 的日志:

    Copy to Clipboard Toggle word wrap
    $ oc adm must-gather – gather_ingress_node_firewall

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

第 9 章 为手动 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 记录的生命周期。

9.1. Managed DNS 管理策略

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

9.2. Unmanaged DNS 管理策略

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

注意

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

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

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

先决条件

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

流程

  1. 创建名为 sample-ingress.yaml 的自定义资源 (CR) 文件,包含以下内容:

    Copy to Clipboard Toggle word wrap
    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. 保存文件以使改变生效。

    Copy to Clipboard Toggle word wrap
    oc apply -f <name>.yaml 
    1

9.4. 修改现有 Ingress Controller

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

先决条件

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

流程

  1. 修改所选 IngressController 来设置 dnsManagementPolicy

    Copy to Clipboard Toggle word wrap
    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 记录。

9.5. 其他资源

第 10 章 验证到端点的连接

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

10.1. 执行连接健康检查

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

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

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

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

10.2. 连接健康检查实现

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

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

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

10.3. PodNetworkConnectivityCheck 对象字段

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

表 10.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 阵列中对象的字段:

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

lastTransitionTime

字符串

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

message

字符串

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

reason

字符串

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

status

字符串

条件的状态。

type

字符串

条件的类型。

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

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

end

字符串

连接失败时的时间戳。

endLogs

数组

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

message

字符串

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

开始

字符串

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

startLogs

数组

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

连接日志字段

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

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

latency

字符串

记录操作的持续时间。

message

字符串

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

reason

字符串

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

success

布尔值

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

time

字符串

连接检查的开始时间。

10.4. 验证端点的网络连接

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

先决条件

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc get podnetworkconnectivitycheck -n openshift-network-diagnostics

    输出示例

    Copy to Clipboard Toggle word wrap
    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. 要查看对象,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get podnetworkconnectivitycheck <name> \
        -n openshift-network-diagnostics -o yaml

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

      输出示例

      Copy to Clipboard Toggle word wrap
      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"

第 11 章 更改集群网络的 MTU

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

11.1. 关于集群 MTU

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

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

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

您只能为 OVN-Kubernetes 和 OpenShift SDN 集群网络插件更改集群 MTU。

11.1.1. 服务中断注意事项

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

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

11.1.2. MTU 值选择

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

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

    • OVN-Kubernetes:100 字节
    • OpenShift SDN: 50 字节

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

重要

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

11.1.3. 迁移过程如何工作

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

表 11.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 字节,OpenShift SDN 的开销为 50 字节。

如果提供的值有效,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 配置执行集群中每个节点的滚动重启。

11.2. 更改集群 MTU

作为集群管理员,您可以更改集群的最大传输单元(MTU)。当 MTU 更新推出时,集群中的迁移具有破坏性且节点可能会临时不可用。

以下流程描述了如何使用机器配置、DHCP 或 ISO 更改集群 MTU。如果使用 DHCP 或 ISO 方法,则必须在安装集群后保留的配置工件来完成此流程。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 已为集群识别目标 MTU。正确的 MTU 因集群使用的网络插件而异:

    • OVN-Kubernetes: 集群 MTU 必须设置为比集群中的最低硬件 MTU 值小 100
    • OpenShift SDN :集群 MTU 必须设置为比集群中的最低硬件 MTU 值小 50
  • 如果您的节点是物理计算机,请确保集群网络和连接的网络交换机支持巨型帧。
  • 如果您的节点是虚拟机(VM),请确保虚拟机监控程序和连接的网络交换机支持巨型帧。

流程

要增加或减少集群网络的 MTU,请完成以下步骤。

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

    Copy to Clipboard Toggle word wrap
    $ oc describe network.config cluster

    输出示例

    Copy to Clipboard Toggle word wrap
    ...
    Status:
      Cluster Network:
        Cidr:               10.217.0.0/22
        Host Prefix:        23
      Cluster Network MTU:  1400
      Network Type:         OpenShiftSDN
      Service Network:
        10.217.4.0/23
    ...

  2. 为硬件 MTU 准备配置:

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

      Copy to Clipboard Toggle word wrap
      dhcp-option-force=26,<mtu>

      其中:

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

      1. 查找主网络接口:

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

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

          其中:

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

          Copy to Clipboard Toggle word wrap
          $ 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 连接配置示例

        Copy to Clipboard Toggle word wrap
        [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 配置:

          注意

          您在 配置文件中指定的 Butane 版本 应与 OpenShift Container Platform 版本匹配,并且始终以 0 结尾。例如: 4.12.0。有关 Butane 的信息,请参阅"使用 Butane 创建机器配置"。

          Copy to Clipboard Toggle word wrap
          variant: openshift
          version: 4.12.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 配置:

          注意

          您在 配置文件中指定的 Butane 版本 应与 OpenShift Container Platform 版本匹配,并且始终以 0 结尾。例如: 4.12.0。有关 Butane 的信息,请参阅"使用 Butane 创建机器配置"。

          Copy to Clipboard Toggle word wrap
          variant: openshift
          version: 4.12.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 对象:

          Copy to Clipboard Toggle word wrap
          $ for manifest in control-plane-interface worker-interface; do
              butane --files-dir . $manifest.bu > $manifest.yaml
            done
  3. 要开始 MTU 迁移,请输入以下命令指定迁移配置。Machine Config Operator 在集群中执行节点的滚动重启,以准备 MTU 更改。

    Copy to Clipboard Toggle word wrap
    $ 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,值必须小 100,OpenShift SDN 必须小 50
    <machine_to>
    指定底层主机网络上的主网络接口的 MTU。

    增加集群 MTU 的示例

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

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

    Copy to Clipboard Toggle word wrap
    $ oc get mcp

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

    注意

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

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

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

      Copy to Clipboard Toggle word wrap
      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

      Copy to Clipboard Toggle word wrap
      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. 要确认机器配置正确,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get machineconfig <config_name> -o yaml | grep ExecStart

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

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

      Copy to Clipboard Toggle word wrap
      ExecStart=/usr/local/bin/mtu-migration.sh
  6. 更新底层网络接口 MTU 值:

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

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

    Copy to Clipboard Toggle word wrap
    $ oc get mcp

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

    注意

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

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

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

      Copy to Clipboard Toggle word wrap
      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

      Copy to Clipboard Toggle word wrap
      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. 要确认机器配置正确,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ 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 网络插件:

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

      其中:

      <mtu>
      指定您使用 <overlay_to> 指定的新集群网络 MTU。
    • 如果使用 OpenShift SDN 网络插件:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.operator.openshift.io cluster --type=merge --patch \
        '{"spec": { "migration": null, "defaultNetwork":{ "openshiftSDNConfig": { "mtu": <mtu> }}}}'

      其中:

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

    Copy to Clipboard Toggle word wrap
    $ oc get mcp

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

验证

您可以验证集群中的节点是否使用上一步中指定的 MTU。

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

    Copy to Clipboard Toggle word wrap
    $ oc describe network.config cluster
  2. 获取节点的主网络接口的当前 MTU。

    1. 要列出集群中的节点,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get nodes
    2. 要获取节点上主网络接口的当前 MTU 设置,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc debug node/<node> -- chroot /host ip address show <interface>

      其中:

      <node>
      指定上一步中的输出节点。
      <interface>
      指定节点的主网络接口名称。

      输出示例

      Copy to Clipboard Toggle word wrap
      ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 8051

11.3. 其他资源

第 12 章 配置节点端口服务范围

作为集群管理员,您可以扩展可用的节点端口范围。如果您的集群使用大量节点端口,可能需要增加可用端口的数量。

默认端口范围为 30000-32767。您永远不会缩小端口范围,即使您首先将其扩展超过默认范围。

12.1. 先决条件

  • 集群基础架构必须允许访问您在扩展范围内指定的端口。例如,如果您将节点端口范围扩展到 30000-32900,防火墙或数据包过滤配置必须允许 32768-32900 端口范围。

12.2. 扩展节点端口范围

您可以扩展集群的节点端口范围。

先决条件

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

流程

  1. 要扩展节点端口范围,请输入以下命令。将 <port> 替换为新范围内的最大端口号码。

    Copy to Clipboard Toggle word wrap
    $ oc patch network.config.openshift.io cluster --type=merge -p \
      '{
        "spec":
          { "serviceNodePortRange": "30000-<port>" }
      }'
    提示

    您还可以应用以下 YAML 来更新节点端口范围:

    Copy to Clipboard Toggle word wrap
    apiVersion: config.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      serviceNodePortRange: "30000-<port>"

    输出示例

    Copy to Clipboard Toggle word wrap
    network.config.openshift.io/cluster patched

  2. 要确认配置是活跃的,请输入以下命令。应用更新可能需要几分钟。

    Copy to Clipboard Toggle word wrap
    $ oc get configmaps -n openshift-kube-apiserver config \
      -o jsonpath="{.data['config\.yaml']}" | \
      grep -Eo '"service-node-port-range":["[[:digit:]]+-[[:digit:]]+"]'

    输出示例

    Copy to Clipboard Toggle word wrap
    "service-node-port-range":["30000-33000"]

12.3. 其他资源

第 13 章 配置 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。

13.1. IP 故障转移环境变量

下表包含用于配置 IP 故障转移的变量。

表 13.1. IP 故障转移环境变量
变量名称default描述

OPENSHIFT_HA_MONITOR_PORT

80

IP 故障转移 pod 会尝试在每个虚拟 IP(VIP)上打开到此端口的 TCP 连接。如果建立连接,则服务将被视为正在运行。如果此端口设为 0,则测试会始终通过。

OPENSHIFT_HA_NETWORK_INTERFACE

 

IP 故障转移用于发送虚拟路由器冗余协议 (VRRP) 流量的接口名称。默认值为 eth0

如果您的集群使用 OVN-Kubernetes 网络插件,请将此值设置为 br-ex 以避免数据包丢失。对于使用 OVN-Kubernetes 网络插件的集群,所有侦听接口都不提供 VRRP,而是预期入站流量通过 br-ex 网桥。

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 从较低优先级主机移到优先级更高的主机。

13.2. 在集群中配置 IP 故障切换

作为集群管理员,您可以在整个集群中或在其中的一部分节点(由标签选项器定义)中配置 IP 故障转移。您还可以在集群中配置多个 IP 故障转移部署,每个 IP 故障转移部署相互独立。

IP 故障转移部署确保故障转移 pod 在符合限制或使用的标签的每个节点上运行。

此 pod 运行 Keepalived,它可以监控端点,并在第一个节点无法访问服务或端点时使用 Virtual Router Redundancy Protocol(VRRP)从一个节点切换到另一个节点的虚拟 IP(VIP)。

对于生产环境,设置一个选择器(selector),用于选择至少两个节点,并设置与所选节点数量相等的副本

先决条件

流程

  1. 创建 IP 故障转移服务帐户:

    Copy to Clipboard Toggle word wrap
    $ oc create sa ipfailover
  2. hostNetwork 更新安全性上下文约束(SCC):

    Copy to Clipboard Toggle word wrap
    $ oc adm policy add-scc-to-user privileged -z ipfailover
    Copy to Clipboard Toggle word wrap
    $ oc adm policy add-scc-to-user hostnetwork -z ipfailover
  3. 仅限 Red Hat OpenStack Platform (RHOSP):完成以下步骤,使在 RHOSP 端口上可以访问故障转移 VIP 地址。

    1. 使用 RHOSP CLI 在 RHOSP 集群的 allowed_address_pairs 参数中显示默认的 RHOSP API 和 VIP 地址:

      Copy to Clipboard Toggle word wrap
      $ openstack port show <cluster_name> -c allowed_address_pairs

      输出示例

      Copy to Clipboard Toggle word wrap
      *Field*                  *Value*
      allowed_address_pairs    ip_address='192.168.0.5', mac_address='fa:16:3e:31:f9:cb'
                               ip_address='192.168.0.7', mac_address='fa:16:3e:31:f9:cb'

    2. 为 IP 故障转移部署设置不同的 VIP 地址,并通过在 RHOSP CLI 中输入以下命令使 RHOSP 端口上的地址访问。不要将任何默认的 RHOSP API 和 VIP 地址设置为 IP 故障转移部署的故障转移 VIP 地址。

      在 RHOSP 端口中添加 1.1.1.1 故障转移 IP 地址作为允许的地址的示例。

      Copy to Clipboard Toggle word wrap
      $ openstack port set <cluster_name> --allowed-address ip-address=1.1.1.1,mac-address=fa:fa:16:3e:31:f9:cb

    3. 创建部署 YAML 文件,为您的部署配置 IP 故障切换。请参阅后续步骤中的"IP 故障转移配置的部署 YAML 示例"。
    4. 在 IP 故障转移部署中指定以下规格,以便将故障转移 VIP 地址传递给 OPENSHIFT_HA_VIRTUAL_IPS 环境变量:

      1.1.1.1 VIP 地址添加到 OPENSHIFT_HA_VIRTUAL_IPS 的示例

      Copy to Clipboard Toggle word wrap
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: ipfailover-keepalived
      # ...
            spec:
                env:
                - name: OPENSHIFT_HA_VIRTUAL_IPS
                value: "1.1.1.1"
      # ...

  4. 创建部署 YAML 文件来配置 IP 故障切换。

    注意

    对于 Red Hat OpenStack Platform (RHOSP),您不需要重新创建部署 YAML 文件。您已作为之前说明的一部分创建了此文件。

    IP 故障转移配置的部署 YAML 示例

    Copy to Clipboard Toggle word wrap
    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: registry.redhat.io/openshift4/ose-keepalived-ipfailover:v4.12
            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,否则您将在创建部署时收到错误。

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

    Copy to Clipboard Toggle word wrap
    #!/bin/bash
        # Whatever tests are needed
        # E.g., send request and verify response
    exit 0
  2. 创建 ConfigMap 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create configmap mycustomcheck --from-file=mycheckscript.sh
  3. 将脚本添加到容器集。挂载的 ConfigMap 对象的 defaultMode 必须能够使用 oc 命令或编辑部署配置来运行。值通常为 0755493(十进制):

    Copy to Clipboard Toggle word wrap
    $ oc set env deploy/ipfailover-keepalived \
        OPENSHIFT_HA_CHECK_SCRIPT=/etc/keepalive/mycheckscript.sh
    Copy to Clipboard Toggle word wrap
    $ 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 部署配置:

    Copy to Clipboard Toggle word wrap
    $ oc edit deploy ipfailover-keepalived
    Copy to Clipboard Toggle word wrap
        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

13.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 以编辑路由器部署配置:

    Copy to Clipboard Toggle word wrap
    $ oc edit deploy ipfailover-keepalived
    Copy to Clipboard Toggle word wrap
    ...
        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。

13.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 范围重叠。

13.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 示例

    Copy to Clipboard Toggle word wrap
    ...
        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 地址,且所有地址都作为一个单元移动。

13.7. ExternalIP 的高可用性

在非云集群中,可以组合使用 IP 故障切换和 ExternalIP 到服务。对于使用 ExternalIP 创建服务的用户,结果是高可用性服务。

方法是指定集群网络配置的 spec.ExternalIP.autoAssignCIDRs 范围,然后在创建 IP 故障转移配置时使用相同的范围。

因为 IP 故障转移最多可支持整个集群的 255 个 VIP,所以 spec.ExternalIP.autoAssignCIDRs 必须为 /24 或更小。

13.8. 删除 IP 故障切换

在初始配置 IP 故障切换时,集群中的 worker 节点会使用 iptables 规则修改,该规则明确允许 Keepalived 在 224.0.0.18 上多播数据包。由于对节点的更改,移除 IP 故障切换需要运行一个作业来删除 iptables 规则并删除 Keepalived 使用的虚拟 IP 地址。

流程

  1. 可选:识别并删除存储为配置映射的任何检查和通知脚本:

    1. 确定任何用于 IP 故障切换的 pod 是否使用配置映射作为卷:

      Copy to Clipboard Toggle word wrap
      $ 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}"

      输出示例

      Copy to Clipboard Toggle word wrap
      Namespace: default
      Pod:       keepalived-worker-59df45db9c-2x9mn
      Volumes that use config maps:
        volume:    config-volume
        configMap: mycustomcheck

    2. 如果上一步提供了用作卷的配置映射的名称,请删除配置映射:

      Copy to Clipboard Toggle word wrap
      $ oc delete configmap <configmap_name>
  2. 为 IP 故障切换识别现有部署:

    Copy to Clipboard Toggle word wrap
    $ oc get deployment -l ipfailover

    输出示例

    Copy to Clipboard Toggle word wrap
    NAMESPACE   NAME         READY   UP-TO-DATE   AVAILABLE   AGE
    default     ipfailover   2/2     2            2           105d

  3. 删除部署:

    Copy to Clipboard Toggle word wrap
    $ oc delete deployment <ipfailover_deployment_name>
  4. 删除 ipfailover 服务帐户:

    Copy to Clipboard Toggle word wrap
    $ oc delete sa ipfailover
  5. 运行一个作业,该作业会删除最初配置 IP 故障切换时添加的 IP 表规则:

    1. 创建一个文件,如 remove-ipfailover-job.yaml,其内容类似以下示例:

      Copy to Clipboard Toggle word wrap
      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: registry.redhat.io/openshift4/ose-keepalived-ipfailover:v4.12
              command: ["/var/lib/ipfailover/keepalived/remove-failover.sh"]
            nodeSelector: 
      1
      
              kubernetes.io/hostname: <host_name>  
      2
      
            restartPolicy: Never
      1
      nodeSelector 可能与旧 IP 故障转移部署中使用的选择器相同。
      2
      为集群中配置 IP 故障切换的每个节点运行作业,并每次替换主机名。
    2. 运行作业:

      Copy to Clipboard Toggle word wrap
      $ oc create -f remove-ipfailover-job.yaml

      输出示例

      Copy to Clipboard Toggle word wrap
      job.batch/remove-ipfailover-2h8dm created

验证

  • 确认作业删除了 IP 故障切换的初始配置。

    Copy to Clipboard Toggle word wrap
    $ oc logs job/remove-ipfailover-2h8dm

    输出示例

    Copy to Clipboard Toggle word wrap
    remove-failover.sh: OpenShift IP Failover service terminating.
      - Removing ip_vs module ...
      - Cleaning up ...
      - Releasing VIPs  (interface eth0) ...

第 14 章 配置接口级别网络 sysctl

在 Linux 中,管理员可通过 sysctl 在运行时修改内核参数。您可以使用调优 Container Network Interface(CNI)元插件修改接口级网络 sysctl。tuning CNI meta 插件在一个链中运行,主 CNI 插件如下所示。

CNI 插件

主 CNI 插件分配接口,并在运行时传递至 tuning CNI meta 插件。您可以使用调优 CNI 元插件在网络命名空间中更改一些 sysctl 和几个接口属性(promiscuous 模式、all-multicast 模式、MTU 和 MAC 地址)。在 tuning CNI meta 插件配置中,接口名称由 IFNAME 令牌表示,并替换为运行时接口的实际名称。

注意

在 OpenShift Container Platform 中,tuned CNI meta 插件只支持更改接口级网络 sysctl。

14.1. 配置调优 CNI

以下流程将调整 CNI 配置为更改接口级网络 net.ipv4.conf.IFNAME.accept_redirects sysctl。这个示例启用接受和发送 ICMP 重定向的数据包。

流程

  1. 使用以下内容创建网络附加定义,如 tuning-example.yaml

    Copy to Clipboard Toggle word wrap
    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。

    显示 yaml 文件示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: tuningnad
      namespace: default
    spec:
      config: '{
        "cniVersion": "0.4.0",
        "name": "tuningnad",
        "plugins": [{
          "type": "bridge"
          },
          {
          "type": "tuning",
          "sysctl": {
             "net.ipv4.conf.IFNAME.accept_redirects": "1"
            }
        }
      ]
    }'
  2. 运行以下命令来应用 yaml:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f tuning-example.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    networkattachmentdefinition.k8.cni.cncf.io/tuningnad created

  3. 使用类似以下示例的网络附加定义,创建示例 pod.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: tunepod
      namespace: default
      annotations:
        k8s.v1.cni.cncf.io/networks: tuningnad 
    1
    
    spec:
      containers:
      - name: podexample
        image: centos
        command: ["/bin/bash", "-c", "sleep INF"]
        securityContext:
          runAsUser: 2000 
    2
    
          runAsGroup: 3000 
    3
    
          allowPrivilegeEscalation: false 
    4
    
          capabilities: 
    5
    
            drop: ["ALL"]
      securityContext:
        runAsNonRoot: true 
    6
    
        seccompProfile: 
    7
    
          type: RuntimeDefault
    1
    指定配置的 NetworkAttachmentDefinition 的名称。
    2
    runAsUser 控制使用哪个用户 ID 运行容器。
    3
    runAsGroup 控制容器使用哪个主要组 ID。
    4
    allowPrivilegeEscalation 决定 pod 是否请求允许特权升级。如果未指定,则默认为 true。这个布尔值直接控制在容器进程中是否设置了 no_new_privs 标志。
    5
    capabilities 允许特权操作,而不提供完整的 root 访问权限。此策略可确保从 pod 中丢弃了所有功能。
    6
    runAsNonRoot: true 要求容器使用 0 以外的任何 UID 运行。
    7
    RuntimeDefault 为 pod 或容器工作负载启用默认的 seccomp 配置集。
  4. 运行以下命令来应用 yaml:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f examplepod.yaml
  5. 运行以下命令验证 pod 是否已创建:

    Copy to Clipboard Toggle word wrap
    $ oc get pod

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME      READY   STATUS    RESTARTS   AGE
    tunepod   1/1     Running   0          47s

  6. 运行以下命令登录到 pod:

    Copy to Clipboard Toggle word wrap
    $ oc rsh tunepod
  7. 验证配置的 sysctl 标记的值。例如,通过运行以下命令查找 net.ipv4.conf.net1.accept_redirects 的值:

    Copy to Clipboard Toggle word wrap
    sh-4.4# sysctl net.ipv4.conf.net1.accept_redirects

    预期输出

    Copy to Clipboard Toggle word wrap
    net.ipv4.conf.net1.accept_redirects = 1

14.2. 其他资源

第 15 章 使用流控制传输协议(SCTP)

作为集群管理员,您可以使用裸机集群上的流控制传输协议(SCTP)。

15.1. 在 OpenShift Container Platform 上支持 SCTP

作为集群管理员,您可以在集群中的主机上启用 SCTP。在 Red Hat Enterprise Linux CoreOS (RHCOS) 上,SCTP 模块被默认禁用。

SCTP 是基于信息的可靠协议,可在 IP 网络之上运行。

启用后,您可以使用 SCTP 作为带有 pod、服务和网络策略的协议。Service 对象必须通过将 type 参数设置为 ClusterIPNodePort 值来定义。

15.1.1. 使用 SCTP 协议的示例配置

您可以通过将 pod 或服务对象中的 protocol 参数设置为 SCTP 来将 pod 或服务配置为使用 SCTP。

在以下示例中,pod 被配置为使用 SCTP:

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  namespace: project1
  name: example-pod
spec:
  containers:
    - name: example-pod
...
      ports:
        - containerPort: 30100
          name: sctpserver
          protocol: SCTP

在以下示例中,服务被配置为使用 SCTP:

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Service
metadata:
  namespace: project1
  name: sctpserver
spec:
...
  ports:
    - name: sctpserver
      protocol: SCTP
      port: 30100
      targetPort: 30100
  type: ClusterIP

在以下示例中,NetworkPolicy 对象配置为对来自具有特定标签的任何 pod 的端口 80 应用 SCTP 网络流量:

Copy to Clipboard Toggle word wrap
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-sctp-on-http
spec:
  podSelector:
    matchLabels:
      role: web
  ingress:
  - ports:
    - protocol: SCTP
      port: 80

15.2. 启用流控制传输协议 (SCTP)

作为集群管理员,您可以在集群中的 worker 节点上加载并启用列入黑名单的 SCTP 内核模块。

先决条件

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

流程

  1. 创建名为 load-sctp-module.yaml 的文件,其包含以下 YAML 定义:

    Copy to Clipboard Toggle word wrap
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      name: load-sctp-module
      labels:
        machineconfiguration.openshift.io/role: worker
    spec:
      config:
        ignition:
          version: 3.2.0
        storage:
          files:
            - path: /etc/modprobe.d/sctp-blacklist.conf
              mode: 0644
              overwrite: true
              contents:
                source: data:,
            - path: /etc/modules-load.d/sctp-load.conf
              mode: 0644
              overwrite: true
              contents:
                source: data:,sctp
  2. 运行以下命令来创建 MachineConfig 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f load-sctp-module.yaml
  3. 可选: 要在 MachineConfig Operator 应用配置更改时监测节点的状态,请使用以下命令。当节点状态变为 Ready时,则代表配置更新已被应用。

    Copy to Clipboard Toggle word wrap
    $ oc get nodes

15.3. 验证流控制传输协议 (SCTP) 已启用

您可以通过创建一个 pod 以及侦听 SCTP 流量的应用程序,将其与服务关联,然后连接到公开的服务,来验证 SCTP 是否在集群中工作。

先决条件

  • 从集群访问互联网来安装 nc 软件包。
  • 安装 OpenShift CLI (oc) 。
  • 使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 创建 pod 启动 SCTP 侦听程序:

    1. 创建名为 sctp-server.yaml 的文件,该文件使用以下 YAML 定义 pod:

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Pod
      metadata:
        name: sctpserver
        labels:
          app: sctpserver
      spec:
        containers:
          - name: sctpserver
            image: registry.access.redhat.com/ubi8/ubi
            command: ["/bin/sh", "-c"]
            args:
              ["dnf install -y nc && sleep inf"]
            ports:
              - containerPort: 30102
                name: sctpserver
                protocol: SCTP
    2. 运行以下命令来创建 pod:

      Copy to Clipboard Toggle word wrap
      $ oc create -f sctp-server.yaml
  2. 为 SCTP 侦听程序 pod 创建服务。

    1. 创建名为 sctp-service.yaml 的文件,该文件使用以下 YAML 定义服务:

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Service
      metadata:
        name: sctpservice
        labels:
          app: sctpserver
      spec:
        type: NodePort
        selector:
          app: sctpserver
        ports:
          - name: sctpserver
            protocol: SCTP
            port: 30102
            targetPort: 30102
    2. 要创建服务,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc create -f sctp-service.yaml
  3. 为 SCTP 客户端创建 pod。

    1. 使用以下 YAML 创建名为 sctp-client.yaml 的文件:

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Pod
      metadata:
        name: sctpclient
        labels:
          app: sctpclient
      spec:
        containers:
          - name: sctpclient
            image: registry.access.redhat.com/ubi8/ubi
            command: ["/bin/sh", "-c"]
            args:
              ["dnf install -y nc && sleep inf"]
    2. 运行以下命令来创建 Pod 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f sctp-client.yaml
  4. 在服务器中运行 SCTP 侦听程序。

    1. 要连接到服务器 pod,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc rsh sctpserver
    2. 要启动 SCTP 侦听程序,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ nc -l 30102 --sctp
  5. 连接到服务器上的 SCTP 侦听程序。

    1. 在终端程序里打开一个新的终端窗口或标签页。
    2. 获取 sctpservice 服务的 IP 地址。使用以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get services sctpservice -o go-template='{{.spec.clusterIP}}{{"\n"}}'
    3. 要连接到客户端 pod,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc rsh sctpclient
    4. 要启动 SCTP 客户端,请输入以下命令。将 <cluster_IP> 替换为 sctpservice 服务的集群 IP 地址。

      Copy to Clipboard Toggle word wrap
      # nc <cluster_IP> 30102 --sctp

第 16 章 使用精确时间协议硬件

您可以配置 linuxptp 服务,并在 OpenShift Container Platform 集群节点中使用具有 PTP 功能的硬件。

16.1. 关于 PTP 硬件

您可以通过部署 PTP Operator,使用 OpenShift Container Platform 控制台或 OpenShift CLI(oc)安装 PTP。PTP Operator 会创建和管理 linuxptp 服务,并提供以下功能:

  • 在集群中发现具有 PTP 功能的设备。
  • 管理 linuxptp 服务的配置。
  • PTP 时钟事件通知会使用 PTP Operator cloud-event-proxy sidecar 会对应用程序的性能和可靠性造成负面影响。
注意

PTP Operator 只适用于仅在裸机基础架构上置备的集群上具有 PTP 功能的设备。

16.2. 关于 PTP

精度时间协议(PTP)用于同步网络中的时钟。与硬件支持一起使用时,PTP 能够达到微秒级的准确性,比网络时间协议 (NTP) 更加准确。

linuxptp 软件包包括用于时钟同步的 ptp4lphc2sys 程序。ptp4l 实现 PTP 边界时钟和普通时钟。ptp4l 将 PTP 硬件时钟与硬件时间戳同步,并将系统时钟与源时钟与软件时间戳同步。phc2sys 用于硬件时间戳,将系统时钟与网络接口控制器 (NIC) 上的 PTP 硬件时钟同步。

16.2.1. PTP 域的元素

PTP 用于将网络中连接的多个节点与每个节点的时钟同步。PTP 同步时钟以源目标层次结构进行组织。层次结构由最佳 master 时钟 (BMC) 算法自动创建和更新,该算法在每个时钟上运行。目标时钟与源时钟同步,目标时钟本身也可以是其他下游时钟的源。以下时钟类型可以包含在配置中:

Grandmaster 时钟
grandmaster 时钟向网络上的其他时钟提供标准时间信息并确保准确和稳定的同步。它写入时间戳并响应来自其他时钟的时间间隔。Grandmaster 时钟可同步到全球位置系统(GPS)时间源。
Ordinary 时钟
Ordinary(普通)时钟具有一个端口连接,可根据其在网络中的位置扮演源或目标时钟的角色。普通时钟可以读取和写入时间戳。
Boundary 时钟
Boundary(边界)时钟在两个或更多个通信路径中具有端口,并且可以是指向其他目标时钟的源和目标。边界时钟作为上游目标时钟工作。目标时钟接收计时消息,针对延迟进行调整,然后创建一个新的源时间信号来传递网络。边界时钟生成一个新的计时数据包,它仍然与源时钟正确同步,并可减少直接报告到源时钟的连接设备数量。

16.2.2. PTP 优于 NTP 的优点

PTP 与 NTP 相比有一个主要优势,即各种网络接口控制器 (NIC) 和网络交换机中存在的硬件支持。特殊硬件允许 PTP 考虑消息传输的延迟,并提高时间同步的准确性。为了获得最佳准确性,建议启用 PTP 时钟间的所有网络组件。

基于硬件的 PTP 提供最佳准确性,因为 NIC 可以在准确发送和接收时对 PTP 数据包进行时间戳。这与基于软件的 PTP 进行比较,这需要操作系统对 PTP 数据包进行额外的处理。

重要

在启用 PTP 前,请确保为所需节点禁用 NTP。您可以使用 MachineConfig 自定义资源禁用 chrony 时间服务 (chronyd)。如需更多信息,请参阅禁用 chrony 时间服务

16.2.3. 使用带有双 NIC 硬件的 PTP

OpenShift Container Platform 支持单和双 NIC 硬件来保证集群中 PTP 时间。

对于提供中等范围的 5G 电信网络,每个虚拟分布式单元(vDU)需要连接到 6 个无线电单元(RU)。要使这些连接,每个 vDU 主机都需要 2 个 NIC 被配置为边界时钟。

双 NIC 硬件允许您将每个 NIC 连接到相同的上游领导时钟,并将每个 NIC 的 ptp4l 实例连接给下游时钟。

16.3. 使用 CLI 安装 PTP Operator

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

先决条件

  • 在裸机中安装有支持 PTP 硬件的节点的集群。
  • 安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。

流程

  1. 为 PTP Operator 创建命名空间。

    1. 将以下 YAML 保存到 ptp-namespace.yaml 文件中:

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Namespace
      metadata:
        name: openshift-ptp
        annotations:
          workload.openshift.io/allowed: management
        labels:
          name: openshift-ptp
          openshift.io/cluster-monitoring: "true"
    2. 创建 Namespace CR:

      Copy to Clipboard Toggle word wrap
      $ oc create -f ptp-namespace.yaml
  2. 为 PTP Operator 创建 Operator 组。

    1. ptp-operatorgroup.yaml 文件中保存以下 YAML:

      Copy to Clipboard Toggle word wrap
      apiVersion: operators.coreos.com/v1
      kind: OperatorGroup
      metadata:
        name: ptp-operators
        namespace: openshift-ptp
      spec:
        targetNamespaces:
        - openshift-ptp
    2. 创建 OperatorGroup CR:

      Copy to Clipboard Toggle word wrap
      $ oc create -f ptp-operatorgroup.yaml
  3. 订阅 PTP Operator。

    1. 将以下 YAML 保存到 ptp-sub.yaml 文件中:

      Copy to Clipboard Toggle word wrap
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: ptp-operator-subscription
        namespace: openshift-ptp
      spec:
        channel: "stable"
        name: ptp-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace
    2. 创建 Subscription CR:

      Copy to Clipboard Toggle word wrap
      $ oc create -f ptp-sub.yaml
  4. 要验证是否已安装 Operator,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get csv -n openshift-ptp -o custom-columns=Name:.metadata.name,Phase:.status.phase

    输出示例

    Copy to Clipboard Toggle word wrap
    Name                         Phase
    4.12.0-202301261535          Succeeded

16.4. 使用 Web 控制台安装 PTP Operator

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

注意

如上一节所述,您必须创建命名空间和 operator 组。

流程

  1. 使用 OpenShift Container Platform Web 控制台安装 PTP Operator:

    1. 在 OpenShift Container Platform Web 控制台中,点击 OperatorsOperatorHub
    2. 从可用的 Operator 列表中选择 PTP Operator,然后点 Install
    3. Install Operator 页面中,在 A specific namespace on the cluster 下选择 openshift-ptp。然后点击 Install
  2. 可选:验证是否成功安装了 PTP Operator:

    1. 切换到 OperatorsInstalled Operators 页面。
    2. 确保 openshift-ptp 项目中列出的 PTP OperatorStatusInstallSucceeded

      注意

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

      如果 Operator 没有被成功安装,请按照以下步骤进行故障排除:

      • 进入 OperatorsInstalled Operators 页面,检查 Operator SubscriptionsInstall Plans 选项卡中的 Status 项中是否有任何错误。
      • 进入 WorkloadsPods 页面,检查 openshift-ptp 项目中 pod 的日志。

16.5. 配置 PTP 设备

PTP Operator 将 NodePtpDevice.ptp.openshift.io 自定义资源定义(CRD)添加到 OpenShift Container Platform。

安装后,PTP Operator 会在每个节点中搜索具有 PTP 功能的网络设备。它为提供兼容 PTP 的网络设备的每个节点创建并更新 NodePtpDevice 自定义资源(CR)对象。

16.5.1. 在集群中发现支持 PTP 的网络设备

识别集群中存在的 PTP 功能网络设备,以便您可以配置它们

先决条件

  • 已安装 PTP Operator。

流程

  • 要返回集群中具有 PTP 功能网络设备的完整列表,请运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get NodePtpDevice -n openshift-ptp -o yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    items:
    - apiVersion: ptp.openshift.io/v1
      kind: NodePtpDevice
      metadata:
        creationTimestamp: "2022-01-27T15:16:28Z"
        generation: 1
        name: dev-worker-0 
    1
    
        namespace: openshift-ptp
        resourceVersion: "6538103"
        uid: d42fc9ad-bcbf-4590-b6d8-b676c642781a
      spec: {}
      status:
        devices: 
    2
    
        - name: eno1
        - name: eno2
        - name: eno3
        - name: eno4
        - name: enp5s0f0
        - name: enp5s0f1
    ...

    1
    name 参数的值与父节点的名称相同。
    2
    devices 集合包含 PTP Operator 发现节点的 PTP 功能设备列表。

16.5.2. 将 linuxptp 服务配置为 grandmaster 时钟

您可以通过创建一个配置主机 NIC 的 PtpConfig 自定义资源 (CR) 将 linuxptp 服务 (ptp4lphc2systs2phc) 配置为 grandmaster 时钟。

ts2phc 工具允许您将系统时钟与 PTP grandmaster 时钟同步,以便节点可以将精度时钟信号流传输到下游 PTP 普通时钟和边界时钟。

注意

使用 PtpConfig CR 示例,将 linuxptp 服务配置为特定硬件和环境的 grandmaster 时钟。这个示例 CR 没有配置 PTP 快速事件。要配置 PTP 快速事件,请为 ptp4lOptsptp4lConfptpClockThreshold 设置适当的值。ptpClockThreshold 仅在启用事件时使用。如需更多信息,请参阅"配置 PTP 快速事件通知发布程序"。

先决条件

  • 在裸机集群主机上安装 Intel Westport Channel 网络接口。
  • 安装 OpenShift CLI (oc) 。
  • 以具有 cluster-admin 特权的用户身份登录。
  • 安装 PTP Operator。

流程

  1. 创建 PtpConfig 资源。例如:

    1. 将以下 YAML 保存到 grandmaster-clock-ptp-config.yaml 文件中:

      PTP grandmaster 时钟配置示例

      Copy to Clipboard Toggle word wrap
      apiVersion: ptp.openshift.io/v1
      kind: PtpConfig
      metadata:
        name: grandmaster-clock
        namespace: openshift-ptp
        annotations: {}
      spec:
        profile:
          - name: grandmaster-clock
            # The interface name is hardware-specific
            interface: $interface
            ptp4lOpts: "-2"
            phc2sysOpts: "-a -r -r -n 24"
            ptpSchedulingPolicy: SCHED_FIFO
            ptpSchedulingPriority: 10
            ptpSettings:
              logReduce: "true"
            ptp4lConf: |
              [global]
              #
              # Default Data Set
              #
              twoStepFlag 1
              slaveOnly 0
              priority1 128
              priority2 128
              domainNumber 24
              #utc_offset 37
              clockClass 255
              clockAccuracy 0xFE
              offsetScaledLogVariance 0xFFFF
              free_running 0
              freq_est_interval 1
              dscp_event 0
              dscp_general 0
              dataset_comparison G.8275.x
              G.8275.defaultDS.localPriority 128
              #
              # Port Data Set
              #
              logAnnounceInterval -3
              logSyncInterval -4
              logMinDelayReqInterval -4
              logMinPdelayReqInterval -4
              announceReceiptTimeout 3
              syncReceiptTimeout 0
              delayAsymmetry 0
              fault_reset_interval -4
              neighborPropDelayThresh 20000000
              masterOnly 0
              G.8275.portDS.localPriority 128
              #
              # Run time options
              #
              assume_two_step 0
              logging_level 6
              path_trace_enabled 0
              follow_up_info 0
              hybrid_e2e 0
              inhibit_multicast_service 0
              net_sync_monitor 0
              tc_spanning_tree 0
              tx_timestamp_timeout 50
              unicast_listen 0
              unicast_master_table 0
              unicast_req_duration 3600
              use_syslog 1
              verbose 0
              summary_interval 0
              kernel_leap 1
              check_fup_sync 0
              clock_class_threshold 7
              #
              # Servo Options
              #
              pi_proportional_const 0.0
              pi_integral_const 0.0
              pi_proportional_scale 0.0
              pi_proportional_exponent -0.3
              pi_proportional_norm_max 0.7
              pi_integral_scale 0.0
              pi_integral_exponent 0.4
              pi_integral_norm_max 0.3
              step_threshold 2.0
              first_step_threshold 0.00002
              max_frequency 900000000
              clock_servo pi
              sanity_freq_limit 200000000
              ntpshm_segment 0
              #
              # Transport options
              #
              transportSpecific 0x0
              ptp_dst_mac 01:1B:19:00:00:00
              p2p_dst_mac 01:80:C2:00:00:0E
              udp_ttl 1
              udp6_scope 0x0E
              uds_address /var/run/ptp4l
              #
              # Default interface options
              #
              clock_type OC
              network_transport L2
              delay_mechanism E2E
              time_stamping hardware
              tsproc_mode filter
              delay_filter moving_median
              delay_filter_length 10
              egressLatency 0
              ingressLatency 0
              boundary_clock_jbod 0
              #
              # Clock description
              #
              productDescription ;;
              revisionData ;;
              manufacturerIdentity 00:00:00
              userDescription ;
              timeSource 0xA0
        recommend:
          - profile: grandmaster-clock
            priority: 4
            match:
              - nodeLabel: "node-role.kubernetes.io/$mcp"

    2. 运行以下命令来创建 CR:

      Copy to Clipboard Toggle word wrap
      $ oc create -f grandmaster-clock-ptp-config.yaml

验证

  1. 检查 PtpConfig 配置集是否已应用到节点。

    1. 运行以下命令,获取 openshift-ptp 命名空间中的 pod 列表:

      Copy to Clipboard Toggle word wrap
      $ oc get pods -n openshift-ptp -o wide

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                          READY   STATUS    RESTARTS   AGE     IP             NODE
      linuxptp-daemon-74m2g         3/3     Running   3          4d15h   10.16.230.7    compute-1.example.com
      ptp-operator-5f4f48d7c-x7zkf  1/1     Running   1          4d15h   10.128.1.145   compute-1.example.com

    2. 检查配置集是否正确。检查与 PtpConfig 配置集中指定的节点对应的 linuxptp 守护进程的日志。运行以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc logs linuxptp-daemon-74m2g -n openshift-ptp -c linuxptp-daemon-container

      输出示例

      Copy to Clipboard Toggle word wrap
      ts2phc[94980.334]: [ts2phc.0.config] nmea delay: 98690975 ns
      ts2phc[94980.334]: [ts2phc.0.config] ens3f0 extts index 0 at 1676577329.999999999 corr 0 src 1676577330.901342528 diff -1
      ts2phc[94980.334]: [ts2phc.0.config] ens3f0 master offset         -1 s2 freq      -1
      ts2phc[94980.441]: [ts2phc.0.config] nmea sentence: GNRMC,195453.00,A,4233.24427,N,07126.64420,W,0.008,,160223,,,A,V
      phc2sys[94980.450]: [ptp4l.0.config] CLOCK_REALTIME phc offset       943 s2 freq  -89604 delay    504
      phc2sys[94980.512]: [ptp4l.0.config] CLOCK_REALTIME phc offset      1000 s2 freq  -89264 delay    474

16.5.3. 将 linuxptp 服务配置为常规时钟

您可以通过创建 PtpConfig 自定义资源(CR)对象将 linuxptp 服务(ptp4lphc2sys)配置为常规时钟。

注意

使用 PtpConfig CR 示例,将 linuxptp 服务配置为特定硬件和环境的普通时钟。这个示例 CR 没有配置 PTP 快速事件。要配置 PTP 快速事件,请为 ptp4lOptsptp4lConfptpClockThreshold 设置适当的值。只有在启用事件时才需要 ptpClockThreshold。如需更多信息,请参阅"配置 PTP 快速事件通知发布程序"。

先决条件

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

流程

  1. 创建以下 PtpConfig CR,然后在 ordinary-clock-ptp-config.yaml 文件中保存 YAML。

    PTP 普通时钟配置示例

    Copy to Clipboard Toggle word wrap
    apiVersion: ptp.openshift.io/v1
    kind: PtpConfig
    metadata:
      name: ordinary-clock
      namespace: openshift-ptp
      annotations: {}
    spec:
      profile:
        - name: ordinary-clock
          # The interface name is hardware-specific
          interface: $interface
          ptp4lOpts: "-2 -s"
          phc2sysOpts: "-a -r -n 24"
          ptpSchedulingPolicy: SCHED_FIFO
          ptpSchedulingPriority: 10
          ptpSettings:
            logReduce: "true"
          ptp4lConf: |
            [global]
            #
            # Default Data Set
            #
            twoStepFlag 1
            slaveOnly 1
            priority1 128
            priority2 128
            domainNumber 24
            #utc_offset 37
            clockClass 255
            clockAccuracy 0xFE
            offsetScaledLogVariance 0xFFFF
            free_running 0
            freq_est_interval 1
            dscp_event 0
            dscp_general 0
            dataset_comparison G.8275.x
            G.8275.defaultDS.localPriority 128
            #
            # Port Data Set
            #
            logAnnounceInterval -3
            logSyncInterval -4
            logMinDelayReqInterval -4
            logMinPdelayReqInterval -4
            announceReceiptTimeout 3
            syncReceiptTimeout 0
            delayAsymmetry 0
            fault_reset_interval -4
            neighborPropDelayThresh 20000000
            masterOnly 0
            G.8275.portDS.localPriority 128
            #
            # Run time options
            #
            assume_two_step 0
            logging_level 6
            path_trace_enabled 0
            follow_up_info 0
            hybrid_e2e 0
            inhibit_multicast_service 0
            net_sync_monitor 0
            tc_spanning_tree 0
            tx_timestamp_timeout 50
            unicast_listen 0
            unicast_master_table 0
            unicast_req_duration 3600
            use_syslog 1
            verbose 0
            summary_interval 0
            kernel_leap 1
            check_fup_sync 0
            clock_class_threshold 7
            #
            # Servo Options
            #
            pi_proportional_const 0.0
            pi_integral_const 0.0
            pi_proportional_scale 0.0
            pi_proportional_exponent -0.3
            pi_proportional_norm_max 0.7
            pi_integral_scale 0.0
            pi_integral_exponent 0.4
            pi_integral_norm_max 0.3
            step_threshold 2.0
            first_step_threshold 0.00002
            max_frequency 900000000
            clock_servo pi
            sanity_freq_limit 200000000
            ntpshm_segment 0
            #
            # Transport options
            #
            transportSpecific 0x0
            ptp_dst_mac 01:1B:19:00:00:00
            p2p_dst_mac 01:80:C2:00:00:0E
            udp_ttl 1
            udp6_scope 0x0E
            uds_address /var/run/ptp4l
            #
            # Default interface options
            #
            clock_type OC
            network_transport L2
            delay_mechanism E2E
            time_stamping hardware
            tsproc_mode filter
            delay_filter moving_median
            delay_filter_length 10
            egressLatency 0
            ingressLatency 0
            boundary_clock_jbod 0
            #
            # Clock description
            #
            productDescription ;;
            revisionData ;;
            manufacturerIdentity 00:00:00
            userDescription ;
            timeSource 0xA0
      recommend:
        - profile: ordinary-clock
          priority: 4
          match:
            - nodeLabel: "node-role.kubernetes.io/$mcp"

    表 16.1. PTP 普通时钟 CR 配置选项
    自定义资源字段描述

    名称

    PtpConfig CR 的名称。

    配置集

    指定包括一个或多个 profile 的数组。每个配置集的名称都需要是唯一的。

    interface

    指定 ptp4l 服务要使用的网络接口,如 ens787f1

    ptp4lOpts

    ptp4l 服务指定系统配置选项,例如 -2 来选择 IEEE 802.3 网络传输。该选项不应包含网络接口名称 -i <interface> 和服务配置文件 -f /etc/ptp4l.conf,因为网络接口名称和服务配置文件会被自动附加。附加 --summary_interval -4 来对此接口使用 PTP 快速事件。

    phc2sysOpts

    phc2sys 服务指定系统配置选项。如果此字段为空,PTP Operator 不会启动 phc2sys 服务。对于 Intel Columbiaville 800 Series NIC,将 phc2sysOpts 选项设置为 -a -r -m -n 24 -N 8 -R 16.-m 将消息输出到 stdoutlinuxptp-daemon DaemonSet 解析日志并生成 Prometheus 指标。

    ptp4lConf

    指定一个字符串,其中包含要替换默认的 /etc/ptp4l.conf 文件的配置。要使用默认配置,请将字段留空。

    tx_timestamp_timeout

    对于 Intel Columbiaville 800 系列 NIC,将 tx_timestamp_timeout 设置为 50

    boundary_clock_jbod

    对于 Intel Columbiaville 800 系列 NIC,将 boundary_clock_jbod 设置为 0。

    ptpSchedulingPolicy

    ptp4lphc2sys 进程的调度策略。默认值为 SCHED_OTHER。在支持 FIFO 调度的系统上使用 SCHED_FIFO

    ptpSchedulingPriority

    ptpSchedulingPolicy 设置为 SCHED_FIFO 时,用于为 ptp4lphc2sys 进程设置 FIFO 优先级的整数值(1 到 65)。当 ptpSchedulingPolicy 设置为 SCHED_OTHER 时,不使用 ptpSchedulingPriority 字段。

    ptpClockThreshold

    可选。如果没有 ptpClockThreshold,用于 ptpClockThreshold 字段的默认值。ptpClockThreshold 配置在触发 PTP 时间前,PTP master 时钟已断开连接的时长。holdOverTimeout 是在 PTP master clock 断开连接时,PTP 时钟事件状态更改为 FREERUN 前的时间值(以秒为单位)。maxOffsetThresholdminOffsetThreshold 设置以纳秒为单位,它们与 CLOCK_REALTIME (phc2sys) 或 master 偏移 (ptp4l) 的值进行比较。当 ptp4lphc2sys 偏移值超出这个范围时,PTP 时钟状态被设置为 FREERUN。当偏移值在这个范围内时,PTP 时钟状态被设置为 LOCKED

    建议

    指定包括一个或多个 recommend 对象的数组,该数组定义了如何将配置集应用到节点的规则。

    .recommend.profile

    指定在 profile 部分定义的 .recommend.profile 对象名称。

    .recommend.priority

    对于普通时钟,将 .recommend.priority 设置为 0。

    .recommend.match

    使用 nodeLabelnodeName 值指定 .recommend.match 规则。

    .recommend.match.nodeLabel

    通过 oc get nodes --show-labels 命令,使用来自节点对象的 node.Labelskey 设置 nodeLabel。例如,node-role.kubernetes.io/worker

    .recommend.match.nodeName

    使用 oc get nodes 命令,将 nodeName 设置为来自节点对象的 node.Name 值。例如,compute-1.example.com

  2. 运行以下命令来创建 PtpConfig CR:

    Copy to Clipboard Toggle word wrap
    $ oc create -f ordinary-clock-ptp-config.yaml

验证

  1. 检查 PtpConfig 配置集是否已应用到节点。

    1. 运行以下命令,获取 openshift-ptp 命名空间中的 pod 列表:

      Copy to Clipboard Toggle word wrap
      $ oc get pods -n openshift-ptp -o wide

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE
      linuxptp-daemon-4xkbb           1/1     Running   0          43m   10.1.196.24      compute-0.example.com
      linuxptp-daemon-tdspf           1/1     Running   0          43m   10.1.196.25      compute-1.example.com
      ptp-operator-657bbb64c8-2f8sj   1/1     Running   0          43m   10.129.0.61      control-plane-1.example.com

    2. 检查配置集是否正确。检查与 PtpConfig 配置集中指定的节点对应的 linuxptp 守护进程的日志。运行以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc logs linuxptp-daemon-4xkbb -n openshift-ptp -c linuxptp-daemon-container

      输出示例

      Copy to Clipboard Toggle word wrap
      I1115 09:41:17.117596 4143292 daemon.go:107] in applyNodePTPProfile
      I1115 09:41:17.117604 4143292 daemon.go:109] updating NodePTPProfile to:
      I1115 09:41:17.117607 4143292 daemon.go:110] ------------------------------------
      I1115 09:41:17.117612 4143292 daemon.go:102] Profile Name: profile1
      I1115 09:41:17.117616 4143292 daemon.go:102] Interface: ens787f1
      I1115 09:41:17.117620 4143292 daemon.go:102] Ptp4lOpts: -2 -s
      I1115 09:41:17.117623 4143292 daemon.go:102] Phc2sysOpts: -a -r -n 24
      I1115 09:41:17.117626 4143292 daemon.go:116] ------------------------------------

其他资源

16.5.4. 将 linuxptp 服务配置为边界时钟

您可以通过创建 PtpConfig 自定义资源(CR)对象将 linuxptp 服务(ptp4lphc2sys)配置为边界时钟。

注意

使用 PtpConfig CR 示例,将 linuxptp 服务配置为特定硬件和环境的边界时钟。这个示例 CR 没有配置 PTP 快速事件。要配置 PTP 快速事件,请为 ptp4lOptsptp4lConfptpClockThreshold 设置适当的值。ptpClockThreshold 仅在启用事件时使用。如需更多信息,请参阅"配置 PTP 快速事件通知发布程序"。

先决条件

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

流程

  1. 创建以下 PtpConfig CR,然后在 boundaries-clock-ptp-config.yaml 文件中保存 YAML。

    PTP 边界时钟配置示例

    Copy to Clipboard Toggle word wrap
    apiVersion: ptp.openshift.io/v1
    kind: PtpConfig
    metadata:
      name: boundary-clock
      namespace: openshift-ptp
      annotations: {}
    spec:
      profile:
        - name: boundary-clock
          ptp4lOpts: "-2"
          phc2sysOpts: "-a -r -n 24"
          ptpSchedulingPolicy: SCHED_FIFO
          ptpSchedulingPriority: 10
          ptpSettings:
            logReduce: "true"
          ptp4lConf: |
            # The interface name is hardware-specific
            [$iface_slave]
            masterOnly 0
            [$iface_master_1]
            masterOnly 1
            [$iface_master_2]
            masterOnly 1
            [$iface_master_3]
            masterOnly 1
            [global]
            #
            # Default Data Set
            #
            twoStepFlag 1
            slaveOnly 0
            priority1 128
            priority2 128
            domainNumber 24
            #utc_offset 37
            clockClass 248
            clockAccuracy 0xFE
            offsetScaledLogVariance 0xFFFF
            free_running 0
            freq_est_interval 1
            dscp_event 0
            dscp_general 0
            dataset_comparison G.8275.x
            G.8275.defaultDS.localPriority 128
            #
            # Port Data Set
            #
            logAnnounceInterval -3
            logSyncInterval -4
            logMinDelayReqInterval -4
            logMinPdelayReqInterval -4
            announceReceiptTimeout 3
            syncReceiptTimeout 0
            delayAsymmetry 0
            fault_reset_interval -4
            neighborPropDelayThresh 20000000
            masterOnly 0
            G.8275.portDS.localPriority 128
            #
            # Run time options
            #
            assume_two_step 0
            logging_level 6
            path_trace_enabled 0
            follow_up_info 0
            hybrid_e2e 0
            inhibit_multicast_service 0
            net_sync_monitor 0
            tc_spanning_tree 0
            tx_timestamp_timeout 50
            unicast_listen 0
            unicast_master_table 0
            unicast_req_duration 3600
            use_syslog 1
            verbose 0
            summary_interval 0
            kernel_leap 1
            check_fup_sync 0
            clock_class_threshold 135
            #
            # Servo Options
            #
            pi_proportional_const 0.0
            pi_integral_const 0.0
            pi_proportional_scale 0.0
            pi_proportional_exponent -0.3
            pi_proportional_norm_max 0.7
            pi_integral_scale 0.0
            pi_integral_exponent 0.4
            pi_integral_norm_max 0.3
            step_threshold 2.0
            first_step_threshold 0.00002
            max_frequency 900000000
            clock_servo pi
            sanity_freq_limit 200000000
            ntpshm_segment 0
            #
            # Transport options
            #
            transportSpecific 0x0
            ptp_dst_mac 01:1B:19:00:00:00
            p2p_dst_mac 01:80:C2:00:00:0E
            udp_ttl 1
            udp6_scope 0x0E
            uds_address /var/run/ptp4l
            #
            # Default interface options
            #
            clock_type BC
            network_transport L2
            delay_mechanism E2E
            time_stamping hardware
            tsproc_mode filter
            delay_filter moving_median
            delay_filter_length 10
            egressLatency 0
            ingressLatency 0
            boundary_clock_jbod 0
            #
            # Clock description
            #
            productDescription ;;
            revisionData ;;
            manufacturerIdentity 00:00:00
            userDescription ;
            timeSource 0xA0
      recommend:
        - profile: boundary-clock
          priority: 4
          match:
            - nodeLabel: "node-role.kubernetes.io/$mcp"

    表 16.2. PTP 边界时钟 CR 配置选项
    自定义资源字段描述

    名称

    PtpConfig CR 的名称。

    配置集

    指定包括一个或多个 profile 的数组。

    名称

    指定唯一标识配置集对象的配置集对象的名称。

    ptp4lOpts

    ptp4l 服务指定系统配置选项。该选项不应包含网络接口名称 -i <interface> 和服务配置文件 -f /etc/ptp4l.conf,因为网络接口名称和服务配置文件会被自动附加。

    ptp4lConf

    指定启动 ptp4l 作为边界时钟所需的配置。例如,ens1f0 同步来自 Pumaster 时钟,ens1f3 同步连接的设备。

    <interface_1>

    接收同步时钟的接口。

    <interface_2>

    发送同步时钟的接口。

    tx_timestamp_timeout

    对于 Intel Columbiaville 800 系列 NIC,将 tx_timestamp_timeout 设置为 50

    boundary_clock_jbod

    对于 Intel Columbiaville 800 系列 NIC,请确保 boundary_clock_jbod 设置为 0。对于 Intel Fortville X710 系列 NIC,请确保 boundary_clock_jbod 设置为 1

    phc2sysOpts

    phc2sys 服务指定系统配置选项。如果此字段为空,PTP Operator 不会启动 phc2sys 服务。

    ptpSchedulingPolicy

    ptp4l 和 phc2sys 进程的调度策略。默认值为 SCHED_OTHER。在支持 FIFO 调度的系统上使用 SCHED_FIFO

    ptpSchedulingPriority

    ptpSchedulingPolicy 设置为 SCHED_FIFO 时,用于为 ptp4lphc2sys 进程设置 FIFO 优先级的整数值(1 到 65)。当 ptpSchedulingPolicy 设置为 SCHED_OTHER 时,不使用 ptpSchedulingPriority 字段。

    ptpClockThreshold

    可选。如果没有 ptpClockThreshold,用于 ptpClockThreshold 字段的默认值。ptpClockThreshold 配置在触发 PTP 时间前,PTP master 时钟已断开连接的时长。holdOverTimeout 是在 PTP master clock 断开连接时,PTP 时钟事件状态更改为 FREERUN 前的时间值(以秒为单位)。maxOffsetThresholdminOffsetThreshold 设置以纳秒为单位,它们与 CLOCK_REALTIME (phc2sys) 或 master 偏移 (ptp4l) 的值进行比较。当 ptp4lphc2sys 偏移值超出这个范围时,PTP 时钟状态被设置为 FREERUN。当偏移值在这个范围内时,PTP 时钟状态被设置为 LOCKED

    建议

    指定包括一个或多个 recommend 对象的数组,该数组定义了如何将配置集应用到节点的规则。

    .recommend.profile

    指定在 profile 部分定义的 .recommend.profile 对象名称。

    .recommend.priority

    使用 099 之间的一个整数值指定 priority。大数值的优先级较低,因此优先级 99 低于优先级 10。如果节点可以根据 match 字段中定义的规则与多个配置集匹配,则优先级较高的配置集会应用到该节点。

    .recommend.match

    使用 nodeLabelnodeName 值指定 .recommend.match 规则。

    .recommend.match.nodeLabel

    通过 oc get nodes --show-labels 命令,使用来自节点对象的 node.Labelskey 设置 nodeLabel。例如,node-role.kubernetes.io/worker

    .recommend.match.nodeName

    使用 oc get nodes 命令,将 nodeName 设置为来自节点对象的 node.Name 值。例如,compute-1.example.com

  2. 运行以下命令来创建 CR:

    Copy to Clipboard Toggle word wrap
    $ oc create -f boundary-clock-ptp-config.yaml

验证

  1. 检查 PtpConfig 配置集是否已应用到节点。

    1. 运行以下命令,获取 openshift-ptp 命名空间中的 pod 列表:

      Copy to Clipboard Toggle word wrap
      $ oc get pods -n openshift-ptp -o wide

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                            READY   STATUS    RESTARTS   AGE   IP               NODE
      linuxptp-daemon-4xkbb           1/1     Running   0          43m   10.1.196.24      compute-0.example.com
      linuxptp-daemon-tdspf           1/1     Running   0          43m   10.1.196.25      compute-1.example.com
      ptp-operator-657bbb64c8-2f8sj   1/1     Running   0          43m   10.129.0.61      control-plane-1.example.com

    2. 检查配置集是否正确。检查与 PtpConfig 配置集中指定的节点对应的 linuxptp 守护进程的日志。运行以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc logs linuxptp-daemon-4xkbb -n openshift-ptp -c linuxptp-daemon-container

      输出示例

      Copy to Clipboard Toggle word wrap
      I1115 09:41:17.117596 4143292 daemon.go:107] in applyNodePTPProfile
      I1115 09:41:17.117604 4143292 daemon.go:109] updating NodePTPProfile to:
      I1115 09:41:17.117607 4143292 daemon.go:110] ------------------------------------
      I1115 09:41:17.117612 4143292 daemon.go:102] Profile Name: profile1
      I1115 09:41:17.117616 4143292 daemon.go:102] Interface:
      I1115 09:41:17.117620 4143292 daemon.go:102] Ptp4lOpts: -2
      I1115 09:41:17.117623 4143292 daemon.go:102] Phc2sysOpts: -a -r -n 24
      I1115 09:41:17.117626 4143292 daemon.go:116] ------------------------------------

其他资源

16.5.5. 将 linuxptp 服务配置为双 NIC 硬件边界时钟

重要

使用配置为边界时钟的双 NIC 的精确时间协议(PTP)硬件只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

您可以通过为每个 NIC 创建一个 PtpConfig 自定义资源(CR)对象,将 linuxptp 服务(ptp4lphc2sys)配置为双 NIC 硬件的边界时钟。

双 NIC 硬件允许您将每个 NIC 连接到相同的上游领导时钟,并将每个 NIC 的 ptp4l 实例连接给下游时钟。

先决条件

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

流程

  1. 创建两个单独的 PtpConfig CR,每个 NIC 使用 "Configuring linuxptp 服务作为边界时钟"中的引用 CR,作为每个 CR 的基础。例如:

    1. 创建 boundary-clock-ptp-config-nic1.yaml,为 phc2sysOpts 指定值:

      Copy to Clipboard Toggle word wrap
      apiVersion: ptp.openshift.io/v1
      kind: PtpConfig
      metadata:
        name: boundary-clock-ptp-config-nic1
        namespace: openshift-ptp
      spec:
        profile:
        - name: "profile1"
          ptp4lOpts: "-2 --summary_interval -4"
          ptp4lConf: | 
      1
      
            [ens5f1]
            masterOnly 1
            [ens5f0]
            masterOnly 0
          ...
          phc2sysOpts: "-a -r -m -n 24 -N 8 -R 16" 
      2
      1
      指定所需的接口来启动 ptp4l 作为一个边境时钟。例如,ens5f0 从 grandmaster 时钟同步,ens5f1 同步连接的设备。
      2
      所需的 phc2sysOpts 值。-m 将消息输出到 stdoutlinuxptp-daemon DaemonSet 解析日志并生成 Prometheus 指标。
    2. 创建 boundary-clock-ptp-config-nic2.yaml,删除 phc2sysOpts 字段,以完全禁用第二个 NIC 的 phc2sys 服务:

      Copy to Clipboard Toggle word wrap
      apiVersion: ptp.openshift.io/v1
      kind: PtpConfig
      metadata:
        name: boundary-clock-ptp-config-nic2
        namespace: openshift-ptp
      spec:
        profile:
        - name: "profile2"
          ptp4lOpts: "-2 --summary_interval -4"
          ptp4lConf: | 
      1
      
            [ens7f1]
            masterOnly 1
            [ens7f0]
            masterOnly 0
      ...
      1
      在第二个 NIC上 指定所需的接口来启动 ptp4l 作为一个边境时钟。
      注意

      您必须从第二个 PtpConfig CR 中完全删除 phc2sysOpts 字段,以禁用第二个 NIC 上的 phc2sys 服务。

  2. 运行以下命令来创建双 NIC PtpConfig CR:

    1. 创建 CR 来为第一个 NIC 配置 PTP:

      Copy to Clipboard Toggle word wrap
      $ oc create -f boundary-clock-ptp-config-nic1.yaml
    2. 创建 CR 来为第二个 NIC 配置 PTP:

      Copy to Clipboard Toggle word wrap
      $ oc create -f boundary-clock-ptp-config-nic2.yaml

验证

  • 检查 PTP Operator 是否为两个 NIC 应用了 PtpConfig CR。检查与安装了双 NIC 硬件的节点对应的 linuxptp 守护进程的日志。例如,运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc logs linuxptp-daemon-cvgr6 -n openshift-ptp -c linuxptp-daemon-container

    输出示例

    Copy to Clipboard Toggle word wrap
    ptp4l[80828.335]: [ptp4l.1.config] master offset          5 s2 freq   -5727 path delay       519
    ptp4l[80828.343]: [ptp4l.0.config] master offset         -5 s2 freq  -10607 path delay       533
    phc2sys[80828.390]: [ptp4l.0.config] CLOCK_REALTIME phc offset         1 s2 freq  -87239 delay    539

16.5.6. Intel Columbiaville E800 series NIC 作为 PTP 常规时钟参考

下表描述了您必须对引用 PTP 配置进行的更改,以便使用 Intel Columbiaville E800 系列 NIC 作为普通时钟。在应用到集群的 PtpConfig 自定义资源(CR)中进行更改。

表 16.3. Intel Columbiaville NIC 的推荐 PTP 设置
PTP 配置推荐的设置

phc2sysOpts

-a -r -m -n 24 -N 8 -R 16

tx_timestamp_timeout

50

boundary_clock_jbod

0

注意

对于 phc2sysOpts-m 会将信息输出到 stdoutlinuxptp-daemon DaemonSet 解析日志并生成 Prometheus 指标。

其他资源

16.5.7. 为 PTP 硬件配置 FIFO 优先级调度

在需要低延迟性能的电信或其他部署配置中,PTP 守护进程线程在受限制的 CPU 占用空间以及剩余的基础架构组件一起运行。默认情况下,PTP 线程使用 SCHED_OTHER 策略运行。在高负载下,这些线程可能没有获得无错操作所需的调度延迟。

要缓解潜在的调度延迟错误,您可以将 PTP Operator linuxptp 服务配置为允许线程使用 SCHED_FIFO 策略运行。如果为 PtpConfig CR 设置了 SCHED_FIFO,则 ptp4lphc2sys 将在 chrt 的父容器中运行,且由 PtpConfig CR 的 ptpSchedulingPriority 字段设置。

注意

设置 ptpSchedulingPolicy 是可选的,只有在遇到延迟错误时才需要。

流程

  1. 编辑 PtpConfig CR 配置集:

    Copy to Clipboard Toggle word wrap
    $ oc edit PtpConfig -n openshift-ptp
  2. 更改 ptpSchedulingPolicyptpSchedulingPriority 字段:

    Copy to Clipboard Toggle word wrap
    apiVersion: ptp.openshift.io/v1
    kind: PtpConfig
    metadata:
      name: <ptp_config_name>
      namespace: openshift-ptp
    ...
    spec:
      profile:
      - name: "profile1"
    ...
        ptpSchedulingPolicy: SCHED_FIFO 
    1
    
        ptpSchedulingPriority: 10 
    2
    1
    ptp4lphc2sys 进程的调度策略。在支持 FIFO 调度的系统上使用 SCHED_FIFO
    2
    必需。设置整数值 1-65,用于为 ptp4lphc2sys 进程配置 FIFO 优先级。
  3. 保存并退出,以将更改应用到 PtpConfig CR。

验证

  1. 获取 linuxptp-daemon pod 的名称以及应用 PtpConfig CR 的对应节点:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ptp -o wide

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE
    linuxptp-daemon-gmv2n           3/3     Running   0          1d17h   10.1.196.24   compute-0.example.com
    linuxptp-daemon-lgm55           3/3     Running   0          1d17h   10.1.196.25   compute-1.example.com
    ptp-operator-3r4dcvf7f4-zndk7   1/1     Running   0          1d7h    10.129.0.61   control-plane-1.example.com

  2. 检查 ptp4l 进程是否使用更新的 chrt FIFO 运行:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ptp logs linuxptp-daemon-lgm55 -c linuxptp-daemon-container|grep chrt

    输出示例

    Copy to Clipboard Toggle word wrap
    I1216 19:24:57.091872 1600715 daemon.go:285] /bin/chrt -f 65 /usr/sbin/ptp4l -f /var/run/ptp4l.0.config -2  --summary_interval -4 -m

16.5.8. 为 linuxptp 服务配置日志过滤

linuxptp 守护进程生成可用于调试目的的日志。在具有有限存储容量的电信或其他部署配置中,这些日志可以添加到存储要求中。

要减少数量日志消息,您可以配置 PtpConfig 自定义资源 (CR) 来排除报告 master offset 值的日志消息。master offset 日志消息以纳秒为单位报告当前节点时钟和 master 时钟之间的区别。

先决条件

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

流程

  1. 编辑 PtpConfig CR:

    Copy to Clipboard Toggle word wrap
    $ oc edit PtpConfig -n openshift-ptp
  2. spec.profile 中,添加 ptpSettings.logReduce 规格,并将值设为 true

    Copy to Clipboard Toggle word wrap
    apiVersion: ptp.openshift.io/v1
    kind: PtpConfig
    metadata:
      name: <ptp_config_name>
      namespace: openshift-ptp
    ...
    spec:
      profile:
      - name: "profile1"
    ...
        ptpSettings:
          logReduce: "true"
    注意

    为了进行调试,您可以将此规格恢复到 False,使其包含 master 偏移消息。

  3. 保存并退出,以将更改应用到 PtpConfig CR。

验证

  1. 获取 linuxptp-daemon pod 的名称以及应用 PtpConfig CR 的对应节点:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ptp -o wide

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE
    linuxptp-daemon-gmv2n           3/3     Running   0          1d17h   10.1.196.24   compute-0.example.com
    linuxptp-daemon-lgm55           3/3     Running   0          1d17h   10.1.196.25   compute-1.example.com
    ptp-operator-3r4dcvf7f4-zndk7   1/1     Running   0          1d7h    10.129.0.61   control-plane-1.example.com

  2. 运行以下命令,验证 master 偏移信息是否不包括在日志中:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ptp logs <linux_daemon_container> -c linuxptp-daemon-container | grep "master offset" 
    1
    1
    <linux_daemon_container> 是 linuxptp-daemon pod 的名称,如 linuxptp-daemon-gmv2n

    当您配置 logReduce 规格时,这个命令会在 linuxptp 守护进程日志中报告任何 master offset 实例。

16.6. 常见 PTP Operator 故障排除

通过执行以下步骤排除 PTP Operator 中的常见问题。

先决条件

  • 安装 OpenShift Container Platform CLI(oc)。
  • 以具有 cluster-admin 特权的用户身份登录。
  • 使用支持 PTP 的主机在裸机集群中安装 PTP Operator。

流程

  1. 检查集群中为配置的节点成功部署了 Operator 和操作对象。

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ptp -o wide

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE
    linuxptp-daemon-lmvgn           3/3     Running   0          4d17h   10.1.196.24   compute-0.example.com
    linuxptp-daemon-qhfg7           3/3     Running   0          4d17h   10.1.196.25   compute-1.example.com
    ptp-operator-6b8dcbf7f4-zndk7   1/1     Running   0          5d7h    10.129.0.61   control-plane-1.example.com

    注意

    当启用 PTP fast 事件总线时,就绪的 linuxptp-daemon pod 的数量是 3/3。如果没有启用 PTP fast 事件总线,则会显示 2/2

  2. 检查集群中是否已找到支持的硬件。

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ptp get nodeptpdevices.ptp.openshift.io

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                  AGE
    control-plane-0.example.com           10d
    control-plane-1.example.com           10d
    compute-0.example.com                 10d
    compute-1.example.com                 10d
    compute-2.example.com                 10d

  3. 检查节点的可用 PTP 网络接口:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ptp get nodeptpdevices.ptp.openshift.io <node_name> -o yaml

    其中:

    <node_name>

    指定您要查询的节点,例如 compute-0.example.com

    输出示例

    Copy to Clipboard Toggle word wrap
    apiVersion: ptp.openshift.io/v1
    kind: NodePtpDevice
    metadata:
      creationTimestamp: "2021-09-14T16:52:33Z"
      generation: 1
      name: compute-0.example.com
      namespace: openshift-ptp
      resourceVersion: "177400"
      uid: 30413db0-4d8d-46da-9bef-737bacd548fd
    spec: {}
    status:
      devices:
      - name: eno1
      - name: eno2
      - name: eno3
      - name: eno4
      - name: enp5s0f0
      - name: enp5s0f1

  4. 通过访问对应节点的 linuxptp-daemon pod,检查 PTP 接口是否已与主时钟成功同步。

    1. 运行以下命令来获取 linuxptp-daemon pod 的名称以及您要排除故障的对应节点:

      Copy to Clipboard Toggle word wrap
      $ oc get pods -n openshift-ptp -o wide

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE
      linuxptp-daemon-lmvgn           3/3     Running   0          4d17h   10.1.196.24   compute-0.example.com
      linuxptp-daemon-qhfg7           3/3     Running   0          4d17h   10.1.196.25   compute-1.example.com
      ptp-operator-6b8dcbf7f4-zndk7   1/1     Running   0          5d7h    10.129.0.61   control-plane-1.example.com

    2. 在远程 shell 到所需的 linuxptp-daemon 容器:

      Copy to Clipboard Toggle word wrap
      $ oc rsh -n openshift-ptp -c linuxptp-daemon-container <linux_daemon_container>

      其中:

      <linux_daemon_container>
      您要诊断的容器,如 linuxptp-daemon-lmvgn
    3. 在与 linuxptp-daemon 容器的远程 shell 连接中,使用 PTP Management Client (pmc) 工具诊断网络接口。运行以下 pmc 命令,以检查 PTP 设备的同步状态,如 ptp4l

      Copy to Clipboard Toggle word wrap
      # pmc -u -f /var/run/ptp4l.0.config -b 0 'GET PORT_DATA_SET'

      当节点成功同步到主时钟时的输出示例

      Copy to Clipboard Toggle word wrap
      sending: GET PORT_DATA_SET
          40a6b7.fffe.166ef0-1 seq 0 RESPONSE MANAGEMENT PORT_DATA_SET
              portIdentity            40a6b7.fffe.166ef0-1
              portState               SLAVE
              logMinDelayReqInterval  -4
              peerMeanPathDelay       0
              logAnnounceInterval     -3
              announceReceiptTimeout  3
              logSyncInterval         -4
              delayMechanism          1
              logMinPdelayReqInterval -4
              versionNumber           2

16.6.1. 收集精确时间协议 (PTP) Operator 数据

您可以使用 oc adm must-gather CLI 命令来收集有关集群的信息,包括与精确时间协议 (PTP) Operator 关联的功能和对象。

先决条件

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

流程

  • 要使用 must-gather 来收集 PTP Operator 数据,您必须指定 PTP Operator must-gather 镜像。

    Copy to Clipboard Toggle word wrap
    $ oc adm must-gather --image=registry.redhat.io/openshift4/ptp-must-gather-rhel8:v4.12

16.7. PTP 硬件快速事件通知框架

虚拟 RAN (vRAN) 等云原生应用需要访问对整个网络运行至关重要的硬件计时事件通知。PTP 时钟同步错误可能会对低延迟应用程序的性能和可靠性造成负面影响,例如:在一个分布式单元 (DU) 中运行的 vRAN 应用程序。

16.7.1. 关于 PTP 和时钟同步错误事件

丢失 PTP 同步是 RAN 网络的一个关键错误。如果在节点上丢失同步,则可能会关闭无线广播,并且网络 Over the Air (OTA) 流量可能会转移到无线网络中的另一个节点。快速事件通知允许集群节点与 DU 中运行的 vRAN 应用程序通信 PTP 时钟同步状态,从而缓解工作负载错误。

事件通知可用于在同一 DU 节点上运行的 vRAN 应用。发布-订阅 REST API 将事件通知传递到消息传递总线。发布-订阅消息传递或发布-订阅消息传递是服务通信架构的异步服务,通过服务通信架构,所有订阅者会立即收到发布到某一主题的消息。

PTP Operator 为每个支持 PTP 的网络接口生成快速事件通知。您可以通过 HTTP 或 Advanced Message Queuing Protocol (AMQP) 消息总线使用 cloud-event-proxy sidecar 容器来访问事件。

注意

PTP 快速事件通知可用于配置为使用 PTP 普通时钟或 PTP 边界时钟。

注意

HTTP 传输是 PTP 和裸机事件的默认传输。在可能的情况下,使用 HTTP 传输而不是 AMQP 用于 PTP 和裸机事件。AMQ Interconnect 于 2024 年 6 月 30 日结束生命周期(EOL)。AMQ Interconnect 的延长生命周期支持 (ELS) 于 2029 年 11 月 29 日结束。如需更多信息,请参阅 Red Hat AMQ Interconnect 支持状态

16.7.2. 关于 PTP 快速事件通知框架

使用 Precision Time Protocol (PTP) 快速事件通知框架,将集群应用程序订阅到裸机集群节点的 PTP 事件。

注意

快速事件通知框架使用 REST API 进行通信。REST API 基于 O-RAN O-Cloud Notification API Specification for Event Consumers 3.0,它包括在 O-RAN ALLIANCE Specifications 中。

框架由发布者、订阅者和 AMQ 或 HTTP 消息传递协议组成,用于处理发布者和订阅者应用程序之间的通信。应用程序以 sidecar 模式运行 cloud-event-proxy 容器,以订阅 PTP 事件。cloud-event-proxy sidecar 容器可以访问与主应用程序容器相同的资源,而无需使用主应用程序的任何资源,且没有大量延迟。

注意

HTTP 传输是 PTP 和裸机事件的默认传输。在可能的情况下,使用 HTTP 传输而不是 AMQP 用于 PTP 和裸机事件。AMQ Interconnect 于 2024 年 6 月 30 日结束生命周期(EOL)。AMQ Interconnect 的延长生命周期支持 (ELS) 于 2029 年 11 月 29 日结束。如需更多信息,请参阅 Red Hat AMQ Interconnect 支持状态

图 16.1. PTP 快速事件概述

PTP 快速事件概述
20 事件在集群主机上生成
PTP Operator 管理的 pod 中的 linuxptp-daemon 作为 Kubernetes DaemonSet 运行,并管理各种 linuxptp 进程 (ptp4lphc2sys,以及可选的用于 grandmaster 时钟 ts2phc)。linuxptp-daemon 将事件传递给 UNIX 域套接字。
20 事件传递给 cloud-event-proxy sidecar
PTP 插件从 UNIX 域套接字读取事件,并将其传递给 PTP Operator 管理的 pod 中的 cloud-event-proxy sidecar。cloud-event-proxy 将 Kubernetes 基础架构的事件提供给具有低延迟的 Cloud-Native Network Function (CNF)。
20 事件是持久的
PTP Operator 管理的 pod 中的 cloud-event-proxy sidecar 处理事件,并使用 REST API 发布云原生事件。
20 消息已传输
消息传输程序通过 HTTP 或 AMQP 1.0 QPID 将事件传送到应用程序 pod 中的 cloud-event-proxy sidecar。
20 来自 REST API 的事件
Application pod 中的 cloud-event-proxy sidecar 处理事件并使用 REST API 使其可用。
20 消费者应用程序请求订阅并接收订阅的事件
消费者应用程序向应用程序 pod 中的 cloud-event-proxy sidecar 发送 API 请求,以创建 PTP 事件订阅。cloud-event-proxy sidecar 为订阅中指定的资源创建一个 AMQ 或 HTTP 消息传递监听程序协议。

应用程序 pod 中的 cloud-event-proxy sidecar 接收来自 PTP Operator 管理的 pod 的事件,取消封装云事件对象以检索数据,并将事件发布到消费者应用程序。消费者应用程序侦听资源限定符中指定的地址,并接收和处理 PTP 事件。

16.7.3. 配置 PTP 快速事件通知发布程序

要为集群中的网络接口启动使用 PTP fast 事件通知,您必须在 PTP Operator PtpOperatorConfig 自定义资源 (CR) 中启用快速事件发布程序,并在您创建的 PtpConfig CR 中配置 ptpClockThreshold 值。

先决条件

  • 已安装 OpenShift Container Platform CLI (oc)。
  • 您已以具有 cluster-admin 权限的用户身份登录。
  • 已安装 PTP Operator。

流程

  1. 修改默认 PTP Operator 配置以启用 PTP 快速事件。

    1. ptp-operatorconfig.yaml 文件中保存以下 YAML:

      Copy to Clipboard Toggle word wrap
      apiVersion: ptp.openshift.io/v1
      kind: PtpOperatorConfig
      metadata:
        name: default
        namespace: openshift-ptp
      spec:
        daemonNodeSelector:
          node-role.kubernetes.io/worker: ""
        ptpEventConfig:
          enableEventPublisher: true 
      1
      1
      enableEventPublisher 设置为 true 以启用 PTP 快速事件通知。
      注意

      在 OpenShift Container Platform 4.12 或更高版本中,当将 HTTP 传输用于 PTP 事件时,您不需要在 PtpOperatorConfig 资源中设置 spec.ptpEventConfig.transportHost 字段。仅在 PTP 事件中使用 AMQP 传输时设置 transportHost

    2. 更新 PtpOperatorConfig CR:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f ptp-operatorconfig.yaml
  2. 为 PTP 启用接口创建 PtpConfig 自定义资源(CR),并设置 ptpClockThresholdptp4lOpts 所需的值。以下 YAML 演示了您必须在 PtpConfig CR 中设置的必要值:

    Copy to Clipboard Toggle word wrap
    spec:
      profile:
      - name: "profile1"
        interface: "enp5s0f0"
        ptp4lOpts: "-2 -s --summary_interval -4" 
    1
    
        phc2sysOpts: "-a -r -m -n 24 -N 8 -R 16" 
    2
    
        ptp4lConf: "" 
    3
    
        ptpClockThreshold: 
    4
    
          holdOverTimeout: 5
          maxOffsetThreshold: 100
          minOffsetThreshold: -100
    1
    附加 --summary_interval -4 以使用 PTP 快速事件。
    2
    所需的 phc2sysOpts 值。-m 将消息输出到 stdoutlinuxptp-daemon DaemonSet 解析日志并生成 Prometheus 指标。
    3
    指定一个字符串,其中包含要替换默认的 /etc/ptp4l.conf 文件的配置。要使用默认配置,请将字段留空。
    4
    可选。如果 ptpClockThreshold 小节不存在,则默认值用于 ptpClockThreshold 字段。小节显示默认的 ptpClockThreshold 值。ptpClockThreshold 值配置 PTP master 时钟在触发 PTP 事件前的时长。holdOverTimeout 是在 PTP master clock 断开连接时,PTP 时钟事件状态更改为 FREERUN 前的时间值(以秒为单位)。maxOffsetThresholdminOffsetThreshold 设置以纳秒为单位,它们与 CLOCK_REALTIME (phc2sys) 或 master 偏移 (ptp4l) 的值进行比较。当 ptp4lphc2sys 偏移值超出这个范围时,PTP 时钟状态被设置为 FREERUN。当偏移值在这个范围内时,PTP 时钟状态被设置为 LOCKED

其他资源

16.7.4. 迁移消费者应用程序,以使用 PTP 或裸机事件的 HTTP 传输

如果您之前部署了 PTP 或裸机事件消费者应用程序,您需要更新应用程序以使用 HTTP 消息传输。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您已以具有 cluster-admin 权限的用户身份登录。
  • 您已将 PTP Operator 或 Bare Metal Event Relay 更新至使用 HTTP 传输的版本 4.12 或更新的版本。

流程

  1. 更新您的事件消费者应用以使用 HTTP 传输。为云事件 sidecar 部署设置 http-event-publishers 变量。

    例如,在配置了 PTP 事件的集群中,以下 YAML 片断演示了一个云事件 sidecar 部署:

    Copy to Clipboard Toggle word wrap
    containers:
      - name: cloud-event-sidecar
        image: cloud-event-sidecar
        args:
          - "--metrics-addr=127.0.0.1:9091"
          - "--store-path=/store"
          - "--transport-host=consumer-events-subscription-service.cloud-events.svc.cluster.local:9043"
          - "--http-event-publishers=ptp-event-publisher-service-NODE_NAME.openshift-ptp.svc.cluster.local:9043" 
    1
    
          - "--api-port=8089"
    1
    PTP Operator 会自动将 NODE_NAME 解析为正在生成 PTP 事件的主机。例如,compute-1.example.com

    在配置了裸机事件的集群中,在云事件 sidecar 部署 CR 中将 http-event-publishers 字段设置为 hw-event-publisher-service.openshift-bare-metal-events.svc.cluster.local:9043

  2. consumer-events-subscription-service 服务与事件消费者应用程序一起部署。例如:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        service.alpha.openshift.io/serving-cert-secret-name: sidecar-consumer-secret
      name: consumer-events-subscription-service
      namespace: cloud-events
      labels:
        app: consumer-service
    spec:
      ports:
        - name: sub-port
          port: 9043
      selector:
        app: consumer
      clusterIP: None
      sessionAffinity: None
      type: ClusterIP

16.7.5. 安装 AMQ 消息传递总线

要在节点上的发布程序与订阅者之间传递 PTP 快速事件通知,您必须安装和配置 AMQ 消息传递总线,以便在节点上本地运行。要使用 AMQ 消息传递,您必须安装 AMQ Interconnect Operator。

注意

HTTP 传输是 PTP 和裸机事件的默认传输。在可能的情况下,使用 HTTP 传输而不是 AMQP 用于 PTP 和裸机事件。AMQ Interconnect 于 2024 年 6 月 30 日结束生命周期(EOL)。AMQ Interconnect 的延长生命周期支持 (ELS) 于 2029 年 11 月 29 日结束。如需更多信息,请参阅 Red Hat AMQ Interconnect 支持状态

先决条件

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

流程

验证

  1. 检查 AMQ Interconnect Operator 是否可用,且所需的 pod 是否正在运行:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n amq-interconnect

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                    READY   STATUS    RESTARTS   AGE
    amq-interconnect-645db76c76-k8ghs       1/1     Running   0          23h
    interconnect-operator-5cb5fc7cc-4v7qm   1/1     Running   0          23h

  2. 检查所需的 linuxptp-daemon PTP 事件制作者 pod 是否在 openshift-ptp 命名空间中运行。

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ptp

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                     READY   STATUS    RESTARTS       AGE
    linuxptp-daemon-2t78p    3/3     Running   0              12h
    linuxptp-daemon-k8n88    3/3     Running   0              12h

16.7.6. 将 DU 应用程序订阅到 PTP 事件 REST API 参考

使用 PTP 事件通知 REST API 将分布式单元(DU)应用程序订阅到父节点上生成的 PTP 事件。

使用资源地址 /cluster/node/<node_name>/ptp 将应用程序订阅到 PTP 事件,其中 <node_name> 是运行 DU 应用程序的集群节点。

在单独的 DU 应用程序 pod 中部署 cloud-event-consumer DU 应用程序容器和 cloud-event-proxy sidecar 容器。cloud-event-consumer DU 应用程序订阅应用程序 Pod 中的 cloud-event-proxy 容器。

使用以下 API 端点,将 cloud-event-consumer DU 应用程序订阅到 PTP 事件,这些事件由 cloud-event-proxy 容器发布,位于 DU 应用程序 pod 中的 http://localhost:8089/api/ocloudNotifications/v1/

  • /api/ocloudNotifications/v1/subscriptions

    • POST :创建新订阅
    • GET :删除订阅列表
    • DELETE :删除所有订阅
  • /api/ocloudNotifications/v1/subscriptions/<subscription_id>

    • GET :返回指定订阅 ID 的详情
    • DELETE :删除与指定订阅 ID 关联的订阅
  • /api/ocloudNotifications/v1/health

    • GET:返回 ocloudNotifications API 的健康状况
  • api/ocloudNotifications/v1/publishers

    • GET :为集群节点返回数组 os-clock-sync-stateptp-clock-class-changelock-state 消息
  • /api/ocloudnotifications/v1/{resource_address}/CurrentState

    • GET :返回以下事件类型的当前状态: os-clock-sync-stateptp-clock-class-changelock-state 事件
注意

9089 是在应用程序 Pod 中部署的 cloud-event-consumer 容器的默认端口。您可以根据需要为 DU 应用程序配置不同的端口。

16.7.6.1. api/ocloudNotifications/v1/subscriptions
HTTP 方法

GET api/ocloudNotifications/v1/subscriptions

描述

返回订阅列表。如果订阅存在,则返回 200 OK 状态代码以及订阅列表。

API 响应示例

Copy to Clipboard Toggle word wrap
[
 {
  "id": "75b1ad8f-c807-4c23-acf5-56f4b7ee3826",
  "endpointUri": "http://localhost:9089/event",
  "uriLocation": "http://localhost:8089/api/ocloudNotifications/v1/subscriptions/75b1ad8f-c807-4c23-acf5-56f4b7ee3826",
  "resource": "/cluster/node/compute-1.example.com/ptp"
 }
]

HTTP 方法

POST api/ocloudNotifications/v1/subscriptions

描述

创建新订阅。如果订阅成功创建,或者已存在,则返回 201 Created 状态代码。

表 16.4. 查询参数
参数类型

subscription

data

有效负载示例

Copy to Clipboard Toggle word wrap
{
  "uriLocation": "http://localhost:8089/api/ocloudNotifications/v1/subscriptions",
  "resource": "/cluster/node/compute-1.example.com/ptp"
}

HTTP 方法

DELETE api/ocloudNotifications/v1/subscriptions

描述

删除所有订阅。

API 响应示例

Copy to Clipboard Toggle word wrap
{
"status": "deleted all subscriptions"
}

16.7.6.2. api/ocloudNotifications/v1/subscriptions/{subscription_id}
HTTP 方法

GET api/ocloudNotifications/v1/subscriptions/{subscription_id}

描述

返回 ID 为 subscription_id 的订阅详情。

表 16.5. 全局路径参数
参数类型

subscription_id

string

API 响应示例

Copy to Clipboard Toggle word wrap
{
  "id":"48210fb3-45be-4ce0-aa9b-41a0e58730ab",
  "endpointUri": "http://localhost:9089/event",
  "uriLocation":"http://localhost:8089/api/ocloudNotifications/v1/subscriptions/48210fb3-45be-4ce0-aa9b-41a0e58730ab",
  "resource":"/cluster/node/compute-1.example.com/ptp"
}

HTTP 方法

DELETE api/ocloudNotifications/v1/subscriptions/{subscription_id}

描述

使用 ID subscription_id 删除订阅。

表 16.6. 全局路径参数
参数类型

subscription_id

string

API 响应示例

Copy to Clipboard Toggle word wrap
{
"status": "OK"
}

16.7.6.3. api/ocloudNotifications/v1/health
HTTP 方法

GET api/ocloudNotifications/v1/health/

描述

返回 ocloudNotifications REST API 的健康状况。

API 响应示例

Copy to Clipboard Toggle word wrap
OK

16.7.6.4. api/ocloudNotifications/v1/publishers
HTTP 方法

GET api/ocloudNotifications/v1/publishers

描述

返回集群节点的 os-clock-sync-stateptp-clock-class-changelock-state 详情的数组。当相关的设备状态改变时,系统会生成通知。

  • os-clock-sync-state 通知描述了主机操作系统时钟同步状态。可以是 LOCKEDFREERUN 状态。
  • ptp-clock-class-change 通知描述了 PTP 时钟类的当前状态。
  • lock-state 通知描述了 PTP 设备锁定状态的当前状态。可以处于 LOCKEDHOLDOVERFREERUN 状态。

API 响应示例

Copy to Clipboard Toggle word wrap
[
  {
    "id": "0fa415ae-a3cf-4299-876a-589438bacf75",
    "endpointUri": "http://localhost:9085/api/ocloudNotifications/v1/dummy",
    "uriLocation": "http://localhost:9085/api/ocloudNotifications/v1/publishers/0fa415ae-a3cf-4299-876a-589438bacf75",
    "resource": "/cluster/node/compute-1.example.com/sync/sync-status/os-clock-sync-state"
  },
  {
    "id": "28cd82df-8436-4f50-bbd9-7a9742828a71",
    "endpointUri": "http://localhost:9085/api/ocloudNotifications/v1/dummy",
    "uriLocation": "http://localhost:9085/api/ocloudNotifications/v1/publishers/28cd82df-8436-4f50-bbd9-7a9742828a71",
    "resource": "/cluster/node/compute-1.example.com/sync/ptp-status/ptp-clock-class-change"
  },
  {
    "id": "44aa480d-7347-48b0-a5b0-e0af01fa9677",
    "endpointUri": "http://localhost:9085/api/ocloudNotifications/v1/dummy",
    "uriLocation": "http://localhost:9085/api/ocloudNotifications/v1/publishers/44aa480d-7347-48b0-a5b0-e0af01fa9677",
    "resource": "/cluster/node/compute-1.example.com/sync/ptp-status/lock-state"
  }
]

您可以在 cloud-event-proxy 容器的日志中找到 os-clock-sync-stateptp-clock-class-changelock-state 事件。例如:

Copy to Clipboard Toggle word wrap
$ oc logs -f linuxptp-daemon-cvgr6 -n openshift-ptp -c cloud-event-proxy

os-clock-sync-state 事件示例

Copy to Clipboard Toggle word wrap
{
   "id":"c8a784d1-5f4a-4c16-9a81-a3b4313affe5",
   "type":"event.sync.sync-status.os-clock-sync-state-change",
   "source":"/cluster/compute-1.example.com/ptp/CLOCK_REALTIME",
   "dataContentType":"application/json",
   "time":"2022-05-06T15:31:23.906277159Z",
   "data":{
      "version":"v1",
      "values":[
         {
            "resource":"/sync/sync-status/os-clock-sync-state",
            "dataType":"notification",
            "valueType":"enumeration",
            "value":"LOCKED"
         },
         {
            "resource":"/sync/sync-status/os-clock-sync-state",
            "dataType":"metric",
            "valueType":"decimal64.3",
            "value":"-53"
         }
      ]
   }
}

ptp-clock-class-change 事件示例

Copy to Clipboard Toggle word wrap
{
   "id":"69eddb52-1650-4e56-b325-86d44688d02b",
   "type":"event.sync.ptp-status.ptp-clock-class-change",
   "source":"/cluster/compute-1.example.com/ptp/ens2fx/master",
   "dataContentType":"application/json",
   "time":"2022-05-06T15:31:23.147100033Z",
   "data":{
      "version":"v1",
      "values":[
         {
            "resource":"/sync/ptp-status/ptp-clock-class-change",
            "dataType":"metric",
            "valueType":"decimal64.3",
            "value":"135"
         }
      ]
   }
}

lock-state 事件示例

Copy to Clipboard Toggle word wrap
{
   "id":"305ec18b-1472-47b3-aadd-8f37933249a9",
   "type":"event.sync.ptp-status.ptp-state-change",
   "source":"/cluster/compute-1.example.com/ptp/ens2fx/master",
   "dataContentType":"application/json",
   "time":"2022-05-06T15:31:23.467684081Z",
   "data":{
      "version":"v1",
      "values":[
         {
            "resource":"/sync/ptp-status/lock-state",
            "dataType":"notification",
            "valueType":"enumeration",
            "value":"LOCKED"
         },
         {
            "resource":"/sync/ptp-status/lock-state",
            "dataType":"metric",
            "valueType":"decimal64.3",
            "value":"62"
         }
      ]
   }
}

16.7.6.5. /api/ocloudnotifications/v1/{resource_address}/CurrentState
HTTP 方法

GET api/ocloudNotifications/v1/cluster/node/<node_name>/sync/ptp-status/lock-state/CurrentState

GET api/ocloudNotifications/v1/cluster/node/<node_name>/sync/sync-status/os-clock-sync-state/CurrentState

GET api/ocloudNotifications/v1/cluster/node/<node_name>/sync/ptp-status/ptp-clock-class-change/CurrentState

描述

配置 CurrentState API 端点,以返回 os-clock-sync-stateptp-clock-class-changelock-state 事件的当前状态。

  • os-clock-sync-state 通知描述了主机操作系统时钟同步状态。可以是 LOCKEDFREERUN 状态。
  • ptp-clock-class-change 通知描述了 PTP 时钟类的当前状态。
  • lock-state 通知描述了 PTP 设备锁定状态的当前状态。可以处于 LOCKEDHOLDOVERFREERUN 状态。
表 16.7. 全局路径参数
参数类型

resource_address

string

lock-state API 响应示例

Copy to Clipboard Toggle word wrap
{
  "id": "c1ac3aa5-1195-4786-84f8-da0ea4462921",
  "type": "event.sync.ptp-status.ptp-state-change",
  "source": "/cluster/node/compute-1.example.com/sync/ptp-status/lock-state",
  "dataContentType": "application/json",
  "time": "2023-01-10T02:41:57.094981478Z",
  "data": {
    "version": "v1",
    "values": [
      {
        "resource": "/cluster/node/compute-1.example.com/ens5fx/master",
        "dataType": "notification",
        "valueType": "enumeration",
        "value": "LOCKED"
      },
      {
        "resource": "/cluster/node/compute-1.example.com/ens5fx/master",
        "dataType": "metric",
        "valueType": "decimal64.3",
        "value": "29"
      }
    ]
  }
}

os-clock-sync-state API 响应示例

Copy to Clipboard Toggle word wrap
{
  "specversion": "0.3",
  "id": "4f51fe99-feaa-4e66-9112-66c5c9b9afcb",
  "source": "/cluster/node/compute-1.example.com/sync/sync-status/os-clock-sync-state",
  "type": "event.sync.sync-status.os-clock-sync-state-change",
  "subject": "/cluster/node/compute-1.example.com/sync/sync-status/os-clock-sync-state",
  "datacontenttype": "application/json",
  "time": "2022-11-29T17:44:22.202Z",
  "data": {
    "version": "v1",
    "values": [
      {
        "resource": "/cluster/node/compute-1.example.com/CLOCK_REALTIME",
        "dataType": "notification",
        "valueType": "enumeration",
        "value": "LOCKED"
      },
      {
        "resource": "/cluster/node/compute-1.example.com/CLOCK_REALTIME",
        "dataType": "metric",
        "valueType": "decimal64.3",
        "value": "27"
      }
    ]
  }
}

ptp-clock-class-change API 响应示例

Copy to Clipboard Toggle word wrap
{
  "id": "064c9e67-5ad4-4afb-98ff-189c6aa9c205",
  "type": "event.sync.ptp-status.ptp-clock-class-change",
  "source": "/cluster/node/compute-1.example.com/sync/ptp-status/ptp-clock-class-change",
  "dataContentType": "application/json",
  "time": "2023-01-10T02:41:56.785673989Z",
  "data": {
    "version": "v1",
    "values": [
      {
        "resource": "/cluster/node/compute-1.example.com/ens5fx/master",
        "dataType": "metric",
        "valueType": "decimal64.3",
        "value": "165"
      }
    ]
  }
}

16.7.7. 监控 PTP 快速事件指标

您可以从运行 linuxptp-daemon 的集群节点监控 PTP 快速事件指标。您还可以使用预先配置和自我更新的 Prometheus 监控堆栈来监控 OpenShift Container Platform Web 控制台中的 PTP 快速事件指标。

先决条件

  • 安装 OpenShift Container Platform CLI oc
  • 以具有 cluster-admin 特权的用户身份登录。
  • 在具有 PTP 功能硬件的节点上安装和配置 PTP Operator。

流程

  1. 检查在运行 linuxptp-daemon 的任何节点上公开的 PTP 指标。例如,运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ curl http://<node_name>:9091/metrics

    输出示例

    Copy to Clipboard Toggle word wrap
    # HELP openshift_ptp_clock_state 0 = FREERUN, 1 = LOCKED, 2 = HOLDOVER
    # TYPE openshift_ptp_clock_state gauge
    openshift_ptp_clock_state{iface="ens1fx",node="compute-1.example.com",process="ptp4l"} 1
    openshift_ptp_clock_state{iface="ens3fx",node="compute-1.example.com",process="ptp4l"} 1
    openshift_ptp_clock_state{iface="ens5fx",node="compute-1.example.com",process="ptp4l"} 1
    openshift_ptp_clock_state{iface="ens7fx",node="compute-1.example.com",process="ptp4l"} 1
    # HELP openshift_ptp_delay_ns
    # TYPE openshift_ptp_delay_ns gauge
    openshift_ptp_delay_ns{from="master",iface="ens1fx",node="compute-1.example.com",process="ptp4l"} 842
    openshift_ptp_delay_ns{from="master",iface="ens3fx",node="compute-1.example.com",process="ptp4l"} 480
    openshift_ptp_delay_ns{from="master",iface="ens5fx",node="compute-1.example.com",process="ptp4l"} 584
    openshift_ptp_delay_ns{from="master",iface="ens7fx",node="compute-1.example.com",process="ptp4l"} 482
    openshift_ptp_delay_ns{from="phc",iface="CLOCK_REALTIME",node="compute-1.example.com",process="phc2sys"} 547
    # HELP openshift_ptp_offset_ns
    # TYPE openshift_ptp_offset_ns gauge
    openshift_ptp_offset_ns{from="master",iface="ens1fx",node="compute-1.example.com",process="ptp4l"} -2
    openshift_ptp_offset_ns{from="master",iface="ens3fx",node="compute-1.example.com",process="ptp4l"} -44
    openshift_ptp_offset_ns{from="master",iface="ens5fx",node="compute-1.example.com",process="ptp4l"} -8
    openshift_ptp_offset_ns{from="master",iface="ens7fx",node="compute-1.example.com",process="ptp4l"} 3
    openshift_ptp_offset_ns{from="phc",iface="CLOCK_REALTIME",node="compute-1.example.com",process="phc2sys"} 12

  2. 要在 OpenShift Container Platform web 控制台中查看 PTP 事件,请复制您要查询的 PTP 指标的名称,如 openshift_ptp_offset_ns
  3. 在 OpenShift Container Platform web 控制台中点 ObserveMetrics
  4. 将 PTP 指标名称粘贴到 Expression 字段中,然后点 Run query

其他资源

第 17 章 外部 DNS Operator

17.1. OpenShift Container Platform 中的外部 DNS Operator

External DNS Operator 部署并管理 ExternalDNS,以便为从外部 DNS 供应商到 OpenShift Container Platform 的服务和路由提供名称解析。

17.1.1. 外部 DNS Operator

External DNS Operator 从 olm.openshift.io API 组实现外部 DNS API。External DNS Operator 更新服务、路由和外部 DNS 供应商。

先决条件

  • 已安装 yq CLI 工具。

流程

您可以根据 OperatorHub 的要求部署外部 DNS Operator。部署外部 DNS Operator 会创建一个 Subscription 对象。

  1. 运行以下命令,检查安装计划的名称:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator get sub external-dns-operator -o yaml | yq '.status.installplan.name'

    输出示例

    Copy to Clipboard Toggle word wrap
    install-zcvlr

  2. 运行以下命令,检查安装计划的状态是否为 Complete

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator get ip <install_plan_name> -o yaml | yq '.status.phase'

    输出示例

    Copy to Clipboard Toggle word wrap
    Complete

  3. 运行以下命令,查看 external-dns-operator 部署的状态:

    Copy to Clipboard Toggle word wrap
    $ oc get -n external-dns-operator deployment/external-dns-operator

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                    READY     UP-TO-DATE   AVAILABLE   AGE
    external-dns-operator   1/1       1            1           23h

17.1.2. 外部 DNS Operator 日志

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

流程

  1. 运行以下命令,查看外部 DNS Operator 的日志:

    Copy to Clipboard Toggle word wrap
    $ oc logs -n external-dns-operator deployment/external-dns-operator -c external-dns-operator
17.1.2.1. 外部 DNS Operator 域名限制

External DNS Operator 使用 TXT registry,它为 TXT 记录添加前缀。这可减少 TXT 记录的域名的最大长度。没有对应的 TXT 记录时无法出现 DNS 记录,因此 DNS 记录的域名必须遵循与 TXT 记录相同的限制。例如,一个 <domain_name_from_source> DNS 记录会导致一个 external-dns-<record_type>-<domain_name_from_source> TXT 记录。

外部 DNS Operator 生成的 DNS 记录的域名有以下限制:

记录类型字符数

CNAME

44

AzureDNS 上的通配符 CNAME 记录

42

A

48

AzureDNS 上的通配符 A 记录

46

如果生成的域名超过任何域名限制,则外部 DNS Operator 日志中会出现以下错误:

Copy to Clipboard Toggle word wrap
time="2022-09-02T08:53:57Z" level=error msg="Failure in zone test.example.io. [Id: /hostedzone/Z06988883Q0H0RL6UMXXX]"
time="2022-09-02T08:53:57Z" level=error msg="InvalidChangeBatch: [FATAL problem: DomainLabelTooLong (Domain label is too long) encountered with 'external-dns-a-hello-openshift-aaaaaaaaaa-bbbbbbbbbb-ccccccc']\n\tstatus code: 400, request id: e54dfd5a-06c6-47b0-bcb9-a4f7c3a4e0c6"

17.2. 在云供应商上安装外部 DNS Operator

您可以在云供应商环境中安装外部 DNS Operator,如 AWS、Azure 和 GCP。

17.2.1. 使用 OperatorHub 安装 External DNS Operator

您可以使用 OpenShift Container Platform OperatorHub 安装外部 DNS Operator。

流程

  1. 在 OpenShift Container Platform Web 控制台中点 OperatorsOperatorHub
  2. External DNS Operator。您可以使用 Filter by keyword 文本框或过滤器列表从 Operator 列表中搜索 External DNS Operator。
  3. 选择 external-dns-operator 命名空间。
  4. External DNS Operator 页面中,点 Install
  5. Install Operator 页面中,确保选择了以下选项:

    1. 将频道更新为 stable-v1
    2. 安装模式为 A specific name on the cluster
    3. 安装的命名空间为 external-dns-operator。如果命名空间 external-dns-operator 不存在,它会在 Operator 安装过程中创建。
    4. Approval Strategy 选为 AutomaticManual。默认情况下,批准策略设置为 Automatic
    5. Install

如果选择了 Automatic 更新,Operator Lifecycle Manager(OLM)将自动升级 Operator 的运行实例,而无需任何干预。

如果选择 手动 更新,则 OLM 会创建一个更新请求。作为集群管理员,您必须手动批准该更新请求,才可将 Operator 更新至新版本。

验证

验证 External DNS Operator 是否在 Installed Operators 仪表板上显示 StatusSucceeded

17.2.2. 使用 CLI 安装 External DNS Operator

您可以使用 CLI 安装 External DNS Operator

先决条件

  • 以具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform Web 控制台。
  • 已登陆到 OpenShift CLI (oc)。

流程

  1. 创建一个 Namespace 对象:

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

      namespace.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Namespace
      metadata:
        name: external-dns-operator

    2. 运行以下命令来创建 Namespace 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f namespace.yaml
  2. 创建一个 OperatorGroup 对象:

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

      operatorgroup.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: operators.coreos.com/v1
      kind: OperatorGroup
      metadata:
        name: external-dns-operator
        namespace: external-dns-operator
      spec:
        upgradeStrategy: Default
        targetNamespaces:
        - external-dns-operator

    2. 运行以下命令来创建 OperatorGroup 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f operatorgroup.yaml
  3. 创建 Subscription 对象:

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

      subscription.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: external-dns-operator
        namespace: external-dns-operator
      spec:
        channel: stable-v1
        installPlanApproval: Automatic
        name: external-dns-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace

    2. 运行以下命令来创建 Subscription 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f subscription.yaml

验证

  1. 运行以下命令,从订阅获取安装计划的名称:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator \
        get subscription external-dns-operator \
        --template='{{.status.installplan.name}}{{"\n"}}'
  2. 运行以下命令,验证安装计划的状态是否为 Complete

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator \
        get ip <install_plan_name> \
        --template='{{.status.phase}}{{"\n"}}'
  3. 运行以下命令,验证 external-dns-operator pod 的状态是否为 Running

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator get pod

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                     READY   STATUS    RESTARTS   AGE
    external-dns-operator-5584585fd7-5lwqm   2/2     Running   0          11m

  4. 运行以下命令,验证订阅的目录源是否为 redhat-operators

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator get subscription

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                    PACKAGE                 SOURCE             CHANNEL
    external-dns-operator   external-dns-operator   redhat-operators   stable-v1

  5. 运行以下命令检查 external-dns-operator 版本:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator get csv

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                           DISPLAY                VERSION   REPLACES   PHASE
    external-dns-operator.v<1.y.z>   ExternalDNS Operator   <1.y.z>                Succeeded

17.3. 外部 DNS Operator 配置参数

External DNS Operator 包括以下配置参数。

17.3.1. 外部 DNS Operator 配置参数

External DNS Operator 包括以下配置参数:

参数描述

spec

启用云供应商的类型。

Copy to Clipboard Toggle word wrap
spec:
  provider:
    type: AWS 
1

    aws:
      credentials:
        name: aws-access-key 
2
1
定义可用选项,如 AWS、GCP、Azure 和 Infoblox。
2
为云供应商定义 secret 名称。

zones

允许您根据域指定 DNS 区域。如果没有指定区,External DNS 资源会发现云供应商帐户中存在的所有区域。

Copy to Clipboard Toggle word wrap
zones:
- "myzoneid" 
1
1
指定 DNS 区域的名称。

domains

允许您根据域指定 AWS 区域。如果没有指定域,External DNS 资源会发现云供应商帐户中存在的所有区域。

Copy to Clipboard Toggle word wrap
domains:
- filterType: Include 
1

  matchType: Exact 
2

  name: "myzonedomain1.com" 
3

- filterType: Include
  matchType: Pattern 
4

  pattern: ".*\\.otherzonedomain\\.com" 
5
1
确保 ExternalDNS 资源包含域名。
2
指示 ExternalDNS 指示域匹配必须完全匹配,而不是正则表达式匹配。
3
定义域的名称。
4
ExternalDNS 资源中设置 regex-domain-filter 标志。您可以使用 Regex 过滤器来限制可能的域。
5
定义 ExternalDNS 资源用来过滤目标区的域的 regex 模式。

source

允许您指定 DNS 记录、ServiceRoute 的源。

Copy to Clipboard Toggle word wrap
source: 
1

  type: Service 
2

  service:
    serviceType:
3

      - LoadBalancer
      - ClusterIP
  labelFilter: 
4

    matchLabels:
      external-dns.mydomain.org/publish: "yes"
  hostnameAnnotation: "Allow" 
5

  fqdnTemplate:
  - "{{.Name}}.myzonedomain.com" 
6
1
定义 DNS 记录源的设置。
2
ExternalDNS 资源使用 Service 类型作为创建 DNS 记录的源。
3
ExternalDNS 资源中设置 service-type-filter 标志。serviceType 包含以下字段:
  • 默认:LoadBalancer
  • 预期:ClusterIP
  • NodePort
  • LoadBalancer
  • ExternalName
4
确保控制器只考虑与标签过滤器匹配的资源。
5
hostnameAnnotation 的默认值为 Ignore,它指示 ExternalDNS 使用字段 fqdnTemplates 中指定的模板生成 DNS 记录。当值是 Allow,DNS 记录根据 external-dns.alpha.kubernetes.io/hostname 注解中指定的值生成。
6
外部 DNS Operator 使用一个字符串从没有定义主机名的源生成 DNS 名称,或者与 fake 源配对时添加主机名后缀。
Copy to Clipboard Toggle word wrap
source:
  type: OpenShiftRoute 
1

  openshiftRouteOptions:
    routerName: default 
2

    labelFilter:
      matchLabels:
        external-dns.mydomain.org/publish: "yes"
1
创建 DNS 记录。
2
如果源类型是 OpenShiftRoute,您可以传递 Ingress Controller 名称。ExternalDNS 资源使用 Ingress Controller 的规范名称作为 CNAME 记录的目标。

17.4. 在 AWS 上创建 DNS 记录

您可以使用外部 DNS Operator 在 AWS 和 AWS GovCloud 上创建 DNS 记录。

17.4.1. 使用 Red Hat External DNS Operator 在 AWS 公共托管区中创建 DNS 记录

您可以使用 Red Hat External DNS Operator 在 AWS 公共托管区上创建 DNS 记录。您可以使用相同的说明在 AWS GovCloud 的托管区上创建 DNS 记录。

流程

  1. 检查用户。用户必须有权访问 kube-system 命名空间。如果没有凭证,您可以从 kube-system 命名空间中获取凭证,以使用云供应商客户端:

    Copy to Clipboard Toggle word wrap
    $ oc whoami

    输出示例

    Copy to Clipboard Toggle word wrap
    system:admin

  2. kube-system 命名空间中存在的 aws-creds secret 中获取值。

    Copy to Clipboard Toggle word wrap
    $ export AWS_ACCESS_KEY_ID=$(oc get secrets aws-creds -n kube-system  --template={{.data.aws_access_key_id}} | base64 -d)
    $ export AWS_SECRET_ACCESS_KEY=$(oc get secrets aws-creds -n kube-system  --template={{.data.aws_secret_access_key}} | base64 -d)
  3. 获取路由来检查域:

    Copy to Clipboard Toggle word wrap
    $ oc get routes --all-namespaces | grep console

    输出示例

    Copy to Clipboard Toggle word wrap
    openshift-console          console             console-openshift-console.apps.testextdnsoperator.apacshift.support                       console             https   reencrypt/Redirect     None
    openshift-console          downloads           downloads-openshift-console.apps.testextdnsoperator.apacshift.support                     downloads           http    edge/Redirect          None

  4. 获取 dns zones 列表以查找与之前找到的路由域对应的 dns 区域:

    Copy to Clipboard Toggle word wrap
    $ aws route53 list-hosted-zones | grep testextdnsoperator.apacshift.support

    输出示例

    Copy to Clipboard Toggle word wrap
    HOSTEDZONES	terraform	/hostedzone/Z02355203TNN1XXXX1J6O	testextdnsoperator.apacshift.support.	5

  5. 路由源创建 ExternalDNS 资源:

    Copy to Clipboard Toggle word wrap
    $ cat <<EOF | oc create -f -
    apiVersion: externaldns.olm.openshift.io/v1beta1
    kind: ExternalDNS
    metadata:
      name: sample-aws 
    1
    
    spec:
      domains:
      - filterType: Include   
    2
    
        matchType: Exact   
    3
    
        name: testextdnsoperator.apacshift.support 
    4
    
      provider:
        type: AWS 
    5
    
      source:  
    6
    
        type: OpenShiftRoute 
    7
    
        openshiftRouteOptions:
          routerName: default 
    8
    
    EOF
    1
    定义外部 DNS 资源的名称。
    2
    默认情况下,所有托管区都被选为潜在的目标。您可以包括需要的托管区。
    3
    目标区的域匹配必须是完全准确的(与正则表达式匹配不同)。
    4
    指定您要更新的区域的确切域。路由的主机名必须是指定域的子域。
    5
    定义 AWS Route53 DNS 供应商。
    6
    定义 DNS 记录源的选项。
    7
    定义 OpenShift 路由资源,作为在之前指定的 DNS 供应商中创建的 DNS 记录来源。
    8
    如果源是 OpenShiftRoute,您可以传递 OpenShift Ingress Controller 名称。外部 DNS Operator 在创建 CNAME 记录时,选择该路由器的规范主机名作为目标。
  6. 使用以下命令,检查为 OCP 路由创建的记录:

    Copy to Clipboard Toggle word wrap
    $ aws route53 list-resource-record-sets --hosted-zone-id Z02355203TNN1XXXX1J6O --query "ResourceRecordSets[?Type == 'CNAME']" | grep console

17.5. 在 Azure 上创建 DNS 记录

您可以使用外部 DNS Operator 在 Azure 上创建 DNS 记录。

重要

在启用了 {entra-first} 的集群或在 Microsoft Azure Government (MAG) 区域中运行的集群不支持 External DNS Operator。

17.5.1. 在 Azure 公共 DNS 区域中创建 DNS 记录

您可以使用 External DNS Operator 在 Azure 公共 DNS 区域上创建 DNS 记录。

先决条件

  • 您必须具有管理员特权。
  • admin 用户必须有权访问 kube-system 命名空间。

流程

  1. 运行以下命令,从 kube-system 命名空间中获取凭证以使用云供应商客户端:

    Copy to Clipboard Toggle word wrap
    $ CLIENT_ID=$(oc get secrets azure-credentials  -n kube-system  --template={{.data.azure_client_id}} | base64 -d)
    $ CLIENT_SECRET=$(oc get secrets azure-credentials  -n kube-system  --template={{.data.azure_client_secret}} | base64 -d)
    $ RESOURCE_GROUP=$(oc get secrets azure-credentials  -n kube-system  --template={{.data.azure_resourcegroup}} | base64 -d)
    $ SUBSCRIPTION_ID=$(oc get secrets azure-credentials  -n kube-system  --template={{.data.azure_subscription_id}} | base64 -d)
    $ TENANT_ID=$(oc get secrets azure-credentials  -n kube-system  --template={{.data.azure_tenant_id}} | base64 -d)
  2. 运行以下命令来登录到 Azure:

    Copy to Clipboard Toggle word wrap
    $ az login --service-principal -u "${CLIENT_ID}" -p "${CLIENT_SECRET}" --tenant "${TENANT_ID}"
  3. 运行以下命令来获取路由列表:

    Copy to Clipboard Toggle word wrap
    $ oc get routes --all-namespaces | grep console

    输出示例

    Copy to Clipboard Toggle word wrap
    openshift-console          console             console-openshift-console.apps.test.azure.example.com                       console             https   reencrypt/Redirect     None
    openshift-console          downloads           downloads-openshift-console.apps.test.azure.example.com                     downloads           http    edge/Redirect          None

  4. 运行以下命令,获取 DNS 区域列表:

    Copy to Clipboard Toggle word wrap
    $ az network dns zone list --resource-group "${RESOURCE_GROUP}"
  5. 创建一个 YAML 文件,如 external-dns-sample-azure.yaml,该文件定义 ExternalDNS 对象:

    external-dns-sample-azure.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: externaldns.olm.openshift.io/v1beta1
    kind: ExternalDNS
    metadata:
      name: sample-azure 
    1
    
    spec:
      zones:
      - "/subscriptions/1234567890/resourceGroups/test-azure-xxxxx-rg/providers/Microsoft.Network/dnszones/test.azure.example.com" 
    2
    
      provider:
        type: Azure 
    3
    
      source:
        openshiftRouteOptions: 
    4
    
          routerName: default 
    5
    
        type: OpenShiftRoute 
    6

    1
    指定外部 DNS 名称。
    2
    定义区域 ID。
    3
    定义提供程序类型。
    4
    您可以定义 DNS 记录源的选项。
    5
    如果源类型是 OpenShiftRoute,您可以传递 OpenShift Ingress Controller 名称。外部 DNS 在创建 CNAME 记录时,选择该路由器的规范主机名作为目标。
    6
    route 资源定义为 Azure DNS 记录的来源。
  6. 运行以下命令,检查为 OpenShift Container Platform 路由创建的 DNS 记录:

    Copy to Clipboard Toggle word wrap
    $ az network dns record-set list -g "${RESOURCE_GROUP}"  -z test.azure.example.com | grep console
    注意

    要在私有 Azure DNS 上的私有托管区上创建记录,您需要在 zones 字段中指定私有区,用于在 ExternalDNS 容器参数中将供应商类型填充到 azure-private-dns

17.6. 在 GCP 上创建 DNS 记录

您可以使用 External DNS Operator 在 Google Cloud Platform (GCP) 上创建 DNS 记录。

重要

不支持在启用了 GCP Workload Identity 的集群上使用 External DNS Operator。有关 GCP Workload Identity 的更多信息,请参阅在 GCP Workload Identity 中使用手动模式

17.6.1. 在 GCP 公共管理区上创建 DNS 记录

您可以使用 External DNS Operator 在 GCP 公共受管区上创建 DNS 记录。

先决条件

  • 您必须具有管理员特权。

流程

  1. 运行以下命令,将 gcp-credentials secret 复制到 encoded-gcloud.json 文件中:

    Copy to Clipboard Toggle word wrap
    $ oc get secret gcp-credentials -n kube-system --template='{{$v := index .data "service_account.json"}}{{$v}}' | base64 -d - > decoded-gcloud.json
  2. 运行以下命令导出 Google 凭证:

    Copy to Clipboard Toggle word wrap
    $ export GOOGLE_CREDENTIALS=decoded-gcloud.json
  3. 使用以下命令激活您的帐户:

    Copy to Clipboard Toggle word wrap
    $ gcloud auth activate-service-account  <client_email as per decoded-gcloud.json> --key-file=decoded-gcloud.json
  4. 运行以下命令来设置项目:

    Copy to Clipboard Toggle word wrap
    $ gcloud config set project <project_id as per decoded-gcloud.json>
  5. 运行以下命令来获取路由列表:

    Copy to Clipboard Toggle word wrap
    $ oc get routes --all-namespaces | grep console

    输出示例

    Copy to Clipboard Toggle word wrap
    openshift-console          console             console-openshift-console.apps.test.gcp.example.com                       console             https   reencrypt/Redirect     None
    openshift-console          downloads           downloads-openshift-console.apps.test.gcp.example.com                     downloads           http    edge/Redirect          None

  6. 运行以下命令来获取受管区列表:

    Copy to Clipboard Toggle word wrap
    $ gcloud dns managed-zones list | grep test.gcp.example.com

    输出示例

    Copy to Clipboard Toggle word wrap
    qe-cvs4g-private-zone test.gcp.example.com

  7. 创建一个 YAML 文件,如 external-dns-sample-gcp.yaml,该文件定义 ExternalDNS 对象:

    external-dns-sample-gcp.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: externaldns.olm.openshift.io/v1beta1
    kind: ExternalDNS
    metadata:
      name: sample-gcp 
    1
    
    spec:
      domains:
        - filterType: Include 
    2
    
          matchType: Exact 
    3
    
          name: test.gcp.example.com 
    4
    
      provider:
        type: GCP 
    5
    
      source:
        openshiftRouteOptions: 
    6
    
          routerName: default 
    7
    
        type: OpenShiftRoute 
    8

    1
    指定外部 DNS 名称。
    2
    默认情况下,所有托管区都被选为潜在的目标。您可以包含托管区。
    3
    目标的域必须与 name 键定义的字符串匹配。
    4
    指定您要更新的区域的确切域。路由的主机名必须是指定域的子域。
    5
    定义提供程序类型。
    6
    您可以定义 DNS 记录源的选项。
    7
    如果源类型是 OpenShiftRoute,您可以传递 OpenShift Ingress Controller 名称。外部 DNS 在创建 CNAME 记录时,选择该路由器的规范主机名作为目标。
    8
    route 资源定义为 GCP DNS 记录的源。
  8. 运行以下命令,检查为 OpenShift Container Platform 路由创建的 DNS 记录:

    Copy to Clipboard Toggle word wrap
    $ gcloud dns record-sets list --zone=qe-cvs4g-private-zone | grep console

17.7. 在 Infoblox 上创建 DNS 记录

您可以使用 External DNS Operator 在 Infoblox 上创建 DNS 记录。

17.7.1. 在 Infoblox 上的公共 DNS 区域中创建 DNS 记录

您可以使用 External DNS Operator 在 Infoblox 上的公共 DNS 区域上创建 DNS 记录。

先决条件

  • 您可以访问 OpenShift CLI(oc)。
  • 您可以访问 Infoblox UI。

流程

  1. 运行以下命令,使用 Infoblox 凭证创建 secret 对象:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator create secret generic infoblox-credentials --from-literal=EXTERNAL_DNS_INFOBLOX_WAPI_USERNAME=<infoblox_username> --from-literal=EXTERNAL_DNS_INFOBLOX_WAPI_PASSWORD=<infoblox_password>
  2. 运行以下命令来获取路由列表:

    Copy to Clipboard Toggle word wrap
    $ oc get routes --all-namespaces | grep console

    输出示例

    Copy to Clipboard Toggle word wrap
    openshift-console          console             console-openshift-console.apps.test.example.com                       console             https   reencrypt/Redirect     None
    openshift-console          downloads           downloads-openshift-console.apps.test.example.com                     downloads           http    edge/Redirect          None

  3. 创建一个 YAML 文件,如 external-dns-sample-infoblox.yaml,该文件定义 ExternalDNS 对象:

    external-dns-sample-infoblox.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: externaldns.olm.openshift.io/v1beta1
    kind: ExternalDNS
    metadata:
      name: sample-infoblox 
    1
    
    spec:
      provider:
        type: Infoblox 
    2
    
        infoblox:
          credentials:
            name: infoblox-credentials
          gridHost: ${INFOBLOX_GRID_PUBLIC_IP}
          wapiPort: 443
          wapiVersion: "2.3.1"
      domains:
      - filterType: Include
        matchType: Exact
        name: test.example.com
      source:
        type: OpenShiftRoute 
    3
    
        openshiftRouteOptions:
          routerName: default 
    4

    1
    指定外部 DNS 名称。
    2
    定义提供程序类型。
    3
    您可以定义 DNS 记录源的选项。
    4
    如果源类型是 OpenShiftRoute,您可以传递 OpenShift Ingress Controller 名称。外部 DNS 在创建 CNAME 记录时,选择该路由器的规范主机名作为目标。
  4. 运行以下命令,在 Infoblox 上创建 ExternalDNS 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f external-dns-sample-infoblox.yaml
  5. 通过 Infoblox UI,检查为 console 路由创建的 DNS 记录:

    1. Data ManagementDNSZones
    2. 选择区域名称。

17.8. 在外部 DNS Operator 上配置集群范围代理

配置集群范围代理后,Operator Lifecycle Manager (OLM) 会触发对使用 HTTP_PROXYHTTPS_PROXYNO_PROXY 环境变量的新内容的所有部署的 Operator 的自动更新。

17.8.1. 信任集群范围代理的证书颁发机构

您可以将外部 DNS Operator 配置为信任集群范围代理的证书颁发机构。

流程

  1. 运行以下命令,创建配置映射以在 external-dns-operator 命名空间中包含 CA 捆绑包:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator create configmap trusted-ca
  2. 要将可信 CA 捆绑包注入配置映射中,请运行以下命令将 config.openshift.io/inject-trusted-cabundle=true 标签添加到配置映射中:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator label cm trusted-ca config.openshift.io/inject-trusted-cabundle=true
  3. 运行以下命令更新外部 DNS Operator 的订阅:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator patch subscription external-dns-operator --type='json' -p='[{"op": "add", "path": "/spec/config", "value":{"env":[{"name":"TRUSTED_CA_CONFIGMAP_NAME","value":"trusted-ca"}]}}]'

验证

  • 部署外部 DNS Operator 后,运行以下命令来验证可信 CA 环境变量是否已添加到 external-dns-operator 部署中:

    Copy to Clipboard Toggle word wrap
    $ oc -n external-dns-operator exec deploy/external-dns-operator -c external-dns-operator -- printenv TRUSTED_CA_CONFIGMAP_NAME

    输出示例

    Copy to Clipboard Toggle word wrap
    trusted-ca

第 18 章 网络策略

18.1. 关于网络策略

作为开发者,您可以定义网络策略来限制集群中 pod 的流量。

18.1.1. 关于网络策略

在使用支持 Kubernetes 网络策略的网络插件的集群中,网络隔离完全由 NetworkPolicy 对象控制。在 OpenShift Container Platform 4.12 中,OpenShift SDN 支持在默认的网络隔离模式中使用网络策略。

警告
  • 网络策略不适用于主机网络命名空间。启用主机网络的 Pod 不受网络策略规则的影响。但是,连接到 host-networked pod 的 pod 会受到网络策略规则的影响。
  • 使用没有 podSelector 字段设置为 {}namespaceSelector 字段不包括 hostNetwork pod。您必须使用带有 namespaceSelector 字段的 podSelector 设置为 {},以便在创建网络策略时目标 hostNetwork pod。
  • 网络策略无法阻止来自 localhost 或来自其驻留的节点的流量。

默认情况下,项目中的所有 pod 都可被其他 pod 和网络端点访问。要在一个项目中隔离一个或多个 Pod,您可以在该项目中创建 NetworkPolicy 对象来指示允许的入站连接。项目管理员可以在自己的项目中创建和删除 NetworkPolicy 对象。

如果一个 pod 由一个或多个 NetworkPolicy 对象中的选择器匹配,那么该 pod 将只接受至少被其中一个 NetworkPolicy 对象所允许的连接。未被任何 NetworkPolicy 对象选择的 pod 可以完全访问。

网络策略仅适用于传输控制协议(TCP)、用户数据报协议(UDP)、互联网控制消息协议(ICMP)和流控制传输协议(SCTP)协议。其他协议不会受到影响。

以下示例 NetworkPolicy 对象演示了支持不同的情景:

  • 拒绝所有流量:

    要使项目默认为拒绝流量,请添加一个匹配所有 pod 但不接受任何流量的 NetworkPolicy 对象:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
    spec:
      podSelector: {}
      ingress: []
  • 只允许 OpenShift Container Platform Ingress Controller 的连接:

    要使项目只允许 OpenShift Container Platform Ingress Controller 的连接,请添加以下 NetworkPolicy 对象。

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-from-openshift-ingress
    spec:
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              network.openshift.io/policy-group: ingress
      podSelector: {}
      policyTypes:
      - Ingress
  • 只接受项目中 pod 的连接:

    重要

    要允许同一命名空间中的 hostNetwork pod 的入站连接,您需要将 allow-from-hostnetwork 策略与 allow-same-namespace 策略一起应用。

    要使 pod 接受同一项目中其他 pod 的连接,但拒绝其他项目中所有 pod 的连接,请添加以下 NetworkPolicy 对象:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-same-namespace
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector: {}
  • 仅允许基于 pod 标签的 HTTP 和 HTTPS 流量:

    要对带有特定标签(以下示例中的 role=frontend)的 pod 仅启用 HTTP 和 HTTPS 访问,请添加类似如下的 NetworkPolicy 对象:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-http-and-https
    spec:
      podSelector:
        matchLabels:
          role: frontend
      ingress:
      - ports:
        - protocol: TCP
          port: 80
        - protocol: TCP
          port: 443
  • 使用命名空间和 pod 选择器接受连接:

    要通过组合使用命名空间和 pod 选择器来匹配网络流量,您可以使用类似如下的 NetworkPolicy 对象:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: allow-pod-and-namespace-both
    spec:
      podSelector:
        matchLabels:
          name: test-pods
      ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                project: project_name
            podSelector:
              matchLabels:
                name: test-pods

NetworkPolicy 对象是可添加的;也就是说,您可以组合多个 NetworkPolicy 对象来满足复杂的网络要求。

例如,对于以上示例中定义的 NetworkPolicy 对象,您可以在同一个项目中定义 allow-same-namespaceallow-http-and-https 策略。因此,允许带有标签 role=frontend 的 pod 接受每一策略所允许的任何连接。即,任何端口上来自同一命名空间中的 pod 的连接,以及端口 80443 上的来自任意命名空间中 pod 的连接。

18.1.1.1. 使用 allow-from-router 网络策略

使用以下 NetworkPolicy 来允许外部流量,而不考虑路由器配置:

Copy to Clipboard Toggle word wrap
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-router
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          policy-group.network.openshift.io/ingress: ""
1

  podSelector: {}
  policyTypes:
  - Ingress
1
policy-group.network.openshift.io/ingress:"" 标签支持 OpenShift-SDN 和 OVN-Kubernetes。
18.1.1.2. 使用 allow-from-hostnetwork 网络策略

添加以下 allow-from-hostnetwork NetworkPolicy 对象来指示来自主机网络 pod 的流量。

Copy to Clipboard Toggle word wrap
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-hostnetwork
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          policy-group.network.openshift.io/host-network: ""
  podSelector: {}
  policyTypes:
  - Ingress

18.1.2. 使用 OpenShift SDN 优化网络策略

使用一个网络策略来通过 pod 上的不同标签来在命名空间中将不同 pod 进行隔离。

NetworkPolicy 对象应用到单一命名空间中的大量 pod 时,效率较低。因为 Pod 标签不存在于 IP 地址一级,因此网络策略会为使用 podSelector 选择的每个 pod 之间生成单独的 Open vSwitch(OVS)流量规则 。

例如,在一个 NetworkPolicy 对象中,如果 spec podSelector 和 ingress podSelector 每个都匹配 200 个 pod,则会产生 40,000 (200*200) OVS 流规则。这可能会减慢节点的速度。

在设计您的网络策略时,请参考以下指南:

  • 使用命名空间使其包含需要隔离的 pod 组,可以减少 OVS 流规则数量。

    使用 namespaceSelector 或空 podSelector 选择整个命名空间的NetworkPolicy 对象会只生成 一个与命名空间的 VXLAN 虚拟网络 ID(VNID)匹配的 OVS 流量规则。

  • 保留不需要在原始命名空间中隔离的 pod,并将需要隔离的 pod 移到一个或多个不同的命名空间中。
  • 创建额外的目标跨命名空间网络策略,以允许来自不同隔离的 pod 的特定流量。

18.1.3. 使用 OVN-Kubernetes 网络插件优化网络策略

在设计您的网络策略时,请参考以下指南:

  • 对于具有相同 spec.podSelector spec 的网络策略,使用带有多个 ingressegress 规则的一个网络策略比带有 ingressegress 子集的多个网络策略更高效。
  • 每个基于 podSelectornamespaceSelector spec 的 ingressegress 规则会生成一个的 OVS 流数量,它与由网络策略选择的 pod 数量 + 由 ingress 或 egress 选择的 pod 数量成比例因此,最好使用在一个规则中可以选择您所需的 pod 的 podSelectornamespaceSelector 规格,而不是为每个 pod 创建单独的规则。

    例如,以下策略包含两个规则:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend
      - from:
        - podSelector:
            matchLabels:
              role: backend

    以下策略表示这两个规则与以下相同的规则:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: test-network-policy
    spec:
      podSelector: {}
      ingress:
      - from:
        - podSelector:
            matchExpressions:
            - {key: role, operator: In, values: [frontend, backend]}

    相同的指南信息适用于 spec.podSelector spec。如果不同的网络策略有相同的 ingressegress 规则,则创建一个带有通用的 spec.podSelector spec 可能更有效率。例如,以下两个策略有不同的规则:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: policy1
    spec:
      podSelector:
        matchLabels:
          role: db
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend
    ---
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: policy2
    spec:
      podSelector:
        matchLabels:
          role: client
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend

    以下网络策略将这两个相同的规则作为一个:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: policy3
    spec:
      podSelector:
        matchExpressions:
        - {key: role, operator: In, values: [db, client]}
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: frontend

    当只有多个选择器表示为一个选择器时,您可以应用此优化。如果选择器基于不同的标签,则可能无法应用此优化。在这些情况下,请考虑为网络策略优化应用一些新标签。

18.1.3.1. OVN-Kubernetes 中的 NetworkPolicy CR 和外部 IP

在 OVN-Kubernetes 中,NetworkPolicy 自定义资源(CR)强制执行严格的隔离规则。如果服务使用外部 IP 公开,网络策略可以阻止来自其他命名空间的访问,除非明确配置为允许流量。

要允许在命名空间间访问外部 IP,请创建一个 NetworkPolicy CR,该 CR 明确允许来自所需命名空间的入口流量,并确保允许流量在指定的服务端口中。在不允许流量到所需端口的情况下,访问可能仍然会被限制。

输出示例

Copy to Clipboard Toggle word wrap
  apiVersion: networking.k8s.io/v1
  kind: NetworkPolicy
  metadata:
    annotations:
    name: <policy_name>
    namespace: openshift-ingress
  spec:
    ingress:
    - ports:
      - port: 80
        protocol: TCP
    - ports:
      - port: 443
        protocol: TCP
    - from:
      - namespaceSelector:
          matchLabels:
          kubernetes.io/metadata.name: <my_namespace>
    podSelector: {}
    policyTypes:
    - Ingress

其中:

<policy_name>
指定策略的名称。
<my_namespace>
指定部署策略的命名空间的名称。

如需了解更多详细信息,请参阅"关于网络策略"。

18.1.4. 后续步骤

18.1.5. 其他资源

18.2. 创建网络策略

作为具有 admin 角色的用户,您可以为命名空间创建网络策略。

18.2.1. 示例 NetworkPolicy 对象

下文解释了示例 NetworkPolicy 对象:

Copy to Clipboard Toggle word wrap
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-27107 
1

spec:
  podSelector: 
2

    matchLabels:
      app: mongodb
  ingress:
  - from:
    - podSelector: 
3

        matchLabels:
          app: app
    ports: 
4

    - protocol: TCP
      port: 27017
1
NetworkPolicy 对象的名称。
2
描述策略应用到的 pod 的选择器。策略对象只能选择定义 NetworkPolicy 对象的项目中的 pod。
3
与策略对象允许从中入口流量的 pod 匹配的选择器。选择器与 NetworkPolicy 在同一命名空间中的 pod 匹配。
4
接受流量的一个或多个目标端口的列表。

18.2.2. 使用 CLI 创建网络策略

要定义细致的规则来描述集群中命名空间允许的入口或出口网络流量,您可以创建一个网络策略。

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建策略规则:

    1. 创建一个 <policy_name>.yaml 文件:

      Copy to Clipboard Toggle word wrap
      $ touch <policy_name>.yaml

      其中:

      <policy_name>
      指定网络策略文件名。
    2. 在您刚才创建的文件中定义网络策略,如下例所示:

      拒绝来自所有命名空间中的所有 pod 的入口流量

      这是一个基本的策略,阻止配置其他网络策略所允许的跨 pod 流量以外的所有跨 pod 网络。

      Copy to Clipboard Toggle word wrap
      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: deny-by-default
      spec:
        podSelector:
        ingress: []

      允许来自所有命名空间中的所有 pod 的入口流量

      Copy to Clipboard Toggle word wrap
      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-same-namespace
      spec:
        podSelector:
        ingress:
        - from:
          - podSelector: {}

      允许从特定命名空间中到一个 pod 的入口流量

      此策略允许流量从在 namespace-y 中运行的容器集到标记 pod-a 的 pod。

      Copy to Clipboard Toggle word wrap
      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-traffic-pod
      spec:
        podSelector:
         matchLabels:
            pod: pod-a
        policyTypes:
        - Ingress
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                 kubernetes.io/metadata.name: namespace-y
  2. 运行以下命令来创建网络策略对象:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f <policy_name>.yaml -n <namespace>

    其中:

    <policy_name>
    指定网络策略文件名。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/deny-by-default created

注意

如果您使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群中的任何命名空间中以 YAML 或 web 控制台的形式创建网络策略。

18.2.3. 创建默认拒绝所有网络策略

这是一个基本的策略,阻止其他部署网络策略允许的网络流量以外的所有跨 pod 网络。此流程强制使用默认 deny-by-default 策略。

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建以下 YAML,以定义 deny-by-default 策略,以拒绝所有命名空间中的所有 pod 的入口流量。将 YAML 保存到 deny-by-default.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
      namespace: default 
    1
    
    spec:
      podSelector: {} 
    2
    
      ingress: [] 
    3
    1
    namespace:default 将此策略部署到 default 命名空间。
    2
    podSelector: 为空,这意味着它与所有 pod 匹配。因此,该策略适用于 default 命名空间中的所有 pod。
    3
    没有指定 ingress 规则。这会导致传入的流量丢弃至所有 pod。
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f deny-by-default.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/deny-by-default created

18.2.4. 创建网络策略以允许来自外部客户端的流量

使用 deny-by-default 策略,您可以继续配置策略,允许从外部客户端到带有标签 app=web 的 pod 的流量。

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

按照以下步骤配置策略,以直接从公共互联网允许外部服务,或使用 Load Balancer 访问 pod。只有具有标签 app=web 的 pod 才允许流量。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建策略,以直接从公共互联网的流量或使用负载均衡器访问 pod。将 YAML 保存到 web-allow-external.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-external
      namespace: default
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: web
      ingress:
        - {}
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-external.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/web-allow-external created

此策略允许来自所有资源的流量,包括下图所示的外部流量:

允许来自外部客户端的流量

18.2.5. 创建网络策略,允许从所有命名空间中到应用程序的流量

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

按照以下步骤配置允许从所有命名空间中的所有 pod 流量到特定应用程序的策略。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建一个策略,允许从所有命名空间中的所有 pod 流量到特定应用。将 YAML 保存到 web-allow-all-namespaces.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-all-namespaces
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: web 
    1
    
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector: {} 
    2
    1
    仅将策略应用到 default 命名空间中的 app:web pod。
    2
    选择所有命名空间中的所有 pod。
    注意

    默认情况下,如果您省略了指定 namespaceSelector 而不是选择任何命名空间,这意味着策略只允许从网络策略部署到的命名空间的流量。

  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-all-namespaces.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/web-allow-all-namespaces created

验证

  1. 输入以下命令在 default 命名空间中启动 web 服务:

    Copy to Clipboard Toggle word wrap
    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 运行以下命令在 secondary 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-$RANDOM --namespace=secondary --rm -i -t --image=alpine -- sh
  3. 在 shell 中运行以下命令,并观察是否允许请求:

    Copy to Clipboard Toggle word wrap
    # wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

18.2.6. 创建网络策略,允许从一个命名空间中到应用程序的流量

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

按照以下步骤配置允许从特定命名空间中到带有 app=web 标签的 pod 的策略。您可能需要进行以下操作:

  • 将流量限制为部署生产工作负载的命名空间。
  • 启用部署到特定命名空间的监控工具,以从当前命名空间中提取指标。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略要应用到的命名空间中。

流程

  1. 创建一个策略,允许来自特定命名空间中所有 pod 的流量,其标签为 purpose=production。将 YAML 保存到 web-allow-prod.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-prod
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: web 
    1
    
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              purpose: production 
    2
    1
    仅将策略应用到 default 命名空间中的 app:web pod。
    2
    将流量仅限制为具有标签 purpose=production 的命名空间中的 pod。
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-prod.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/web-allow-prod created

验证

  1. 输入以下命令在 default 命名空间中启动 web 服务:

    Copy to Clipboard Toggle word wrap
    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 运行以下命令来创建 prod 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace prod
  3. 运行以下命令来标记 prod 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc label namespace/prod purpose=production
  4. 运行以下命令来创建 dev 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace dev
  5. 运行以下命令来标记 dev 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc label namespace/dev purpose=testing
  6. 运行以下命令在 dev 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-$RANDOM --namespace=dev --rm -i -t --image=alpine -- sh
  7. 在 shell 中运行以下命令,并观察请求是否被阻止:

    Copy to Clipboard Toggle word wrap
    # wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    wget: download timed out

  8. 运行以下命令,在 prod 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-$RANDOM --namespace=prod --rm -i -t --image=alpine -- sh
  9. 在 shell 中运行以下命令,并观察是否允许请求:

    Copy to Clipboard Toggle word wrap
    # wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

18.2.7. 其他资源

18.3. 查看网络策略

以具有 admin 角色的用户,您可以查看命名空间的网络策略。

18.3.1. 示例 NetworkPolicy 对象

下文解释了示例 NetworkPolicy 对象:

Copy to Clipboard Toggle word wrap
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-27107 
1

spec:
  podSelector: 
2

    matchLabels:
      app: mongodb
  ingress:
  - from:
    - podSelector: 
3

        matchLabels:
          app: app
    ports: 
4

    - protocol: TCP
      port: 27017
1
NetworkPolicy 对象的名称。
2
描述策略应用到的 pod 的选择器。策略对象只能选择定义 NetworkPolicy 对象的项目中的 pod。
3
与策略对象允许从中入口流量的 pod 匹配的选择器。选择器与 NetworkPolicy 在同一命名空间中的 pod 匹配。
4
接受流量的一个或多个目标端口的列表。

18.3.2. 使用 CLI 查看网络策略

您可以检查命名空间中的网络策略。

注意

如果使用具有 cluster-admin 角色的用户登录,您可以查看集群中的任何网络策略。

前提条件

  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略所在的命名空间中。

流程

  • 列出命名空间中的网络策略:

    • 要查看命名空间中定义的网络策略对象,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get networkpolicy
    • 可选: 要检查特定的网络策略,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc describe networkpolicy <policy_name> -n <namespace>

      其中:

      <policy_name>
      指定要检查的网络策略的名称。
      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

      例如:

      Copy to Clipboard Toggle word wrap
      $ oc describe networkpolicy allow-same-namespace

      oc describe 命令的输出

      Copy to Clipboard Toggle word wrap
      Name:         allow-same-namespace
      Namespace:    ns1
      Created on:   2021-05-24 22:28:56 -0400 EDT
      Labels:       <none>
      Annotations:  <none>
      Spec:
        PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
        Allowing ingress traffic:
          To Port: <any> (traffic allowed to all ports)
          From:
            PodSelector: <none>
        Not affecting egress traffic
        Policy Types: Ingress

注意

如果您使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群中的任何命名空间中以 YAML 或 web 控制台的形式查看网络策略。

18.4. 编辑网络策略

作为具有 admin 角色的用户,您可以编辑命名空间的现有网络策略。

18.4.1. 编辑网络策略

您可以编辑命名空间中的网络策略。

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中编辑网络策略。

先决条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略所在的命名空间中。

流程

  1. 可选: 要列出一个命名空间中的网络策略对象,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get networkpolicy

    其中:

    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
  2. 编辑网络策略对象。

    • 如果您在文件中保存了网络策略定义,请编辑该文件并进行必要的更改,然后输入以下命令。

      Copy to Clipboard Toggle word wrap
      $ oc apply -n <namespace> -f <policy_file>.yaml

      其中:

      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
      <policy_file>
      指定包含网络策略的文件的名称。
    • 如果您需要直接更新网络策略对象,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc edit networkpolicy <policy_name> -n <namespace>

      其中:

      <policy_name>
      指定网络策略的名称。
      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
  3. 确认网络策略对象已更新。

    Copy to Clipboard Toggle word wrap
    $ oc describe networkpolicy <policy_name> -n <namespace>

    其中:

    <policy_name>
    指定网络策略的名称。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
注意

如果您使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群中的任何命名空间中以 YAML 或通过 Actions 菜单从 web 控制台中的策略编辑网络策略。

18.4.2. 示例 NetworkPolicy 对象

下文解释了示例 NetworkPolicy 对象:

Copy to Clipboard Toggle word wrap
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-27107 
1

spec:
  podSelector: 
2

    matchLabels:
      app: mongodb
  ingress:
  - from:
    - podSelector: 
3

        matchLabels:
          app: app
    ports: 
4

    - protocol: TCP
      port: 27017
1
NetworkPolicy 对象的名称。
2
描述策略应用到的 pod 的选择器。策略对象只能选择定义 NetworkPolicy 对象的项目中的 pod。
3
与策略对象允许从中入口流量的 pod 匹配的选择器。选择器与 NetworkPolicy 在同一命名空间中的 pod 匹配。
4
接受流量的一个或多个目标端口的列表。

18.4.3. 其他资源

18.5. 删除网络策略

以具有 admin 角色的用户,您可以从命名空间中删除网络策略。

18.5.1. 使用 CLI 删除网络策略

您可以删除命名空间中的网络策略。

注意

如果使用具有 cluster-admin 角色的用户登录,您可以删除集群中的任何网络策略。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。
  • 您在网络策略所在的命名空间中。

流程

  • 要删除网络策略对象,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc delete networkpolicy <policy_name> -n <namespace>

    其中:

    <policy_name>
    指定网络策略的名称。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/default-deny deleted

注意

如果使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群上以 YAML 或通过 Actions 菜单从 web 控制台中的策略删除网络策略。

18.6. 为项目定义默认网络策略

作为集群管理员,您可以在创建新项目时修改新项目模板,使其自动包含网络策略。如果您还没有新项目的自定义模板,则需要首先创建一个。

18.6.1. 为新项目修改模板

作为集群管理员,您可以修改默认项目模板,以便使用自定义要求创建新项目。

创建自己的自定义项目模板:

流程

  1. 以具有 cluster-admin 特权的用户身份登录。
  2. 生成默认项目模板:

    Copy to Clipboard Toggle word wrap
    $ oc adm create-bootstrap-project-template -o yaml > template.yaml
  3. 使用文本编辑器,通过添加对象或修改现有对象来修改生成的 template.yaml 文件。
  4. 项目模板必须创建在 openshift-config 命名空间中。加载修改后的模板:

    Copy to Clipboard Toggle word wrap
    $ oc create -f template.yaml -n openshift-config
  5. 使用 Web 控制台或 CLI 编辑项目配置资源。

    • 使用 Web 控制台:

      1. 导航至 AdministrationCluster Settings 页面。
      2. 单击 Configuration 以查看所有配置资源。
      3. 找到 Project 的条目,并点击 Edit YAML
    • 使用 CLI:

      1. 编辑 project.config.openshift.io/cluster 资源:

        Copy to Clipboard Toggle word wrap
        $ oc edit project.config.openshift.io/cluster
  6. 更新 spec 部分,使其包含 projectRequestTemplatename 参数,再设置您上传的项目模板的名称。默认名称为 project-request

    带有自定义项目模板的项目配置资源

    Copy to Clipboard Toggle word wrap
    apiVersion: config.openshift.io/v1
    kind: Project
    metadata:
    # ...
    spec:
      projectRequestTemplate:
        name: <template_name>
    # ...

  7. 保存更改后,创建一个新项目来验证是否成功应用了您的更改。

18.6.2. 在新项目模板中添加网络策略

作为集群管理员,您可以在新项目的默认模板中添加网络策略。OpenShift Container Platform 将自动创建项目中模板中指定的所有 NetworkPolicy 对象。

先决条件

  • 集群使用支持 NetworkPolicy 对象的默认 CNI 网络供应商,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您需要使用具有 cluster-admin 权限的用户登陆到集群。
  • 您必须已为新项目创建了自定义的默认项目模板。

流程

  1. 运行以下命令来编辑新项目的默认模板:

    Copy to Clipboard Toggle word wrap
    $ oc edit template <project_template> -n openshift-config

    <project_template> 替换为您为集群配置的缺省模板的名称。默认模板名称为 project-request

  2. 在模板中,将每个 NetworkPolicy 对象作为一个元素添加到 objects 参数中。objects 参数可以是一个或多个对象的集合。

    在以下示例中,objects 参数集合包括几个 NetworkPolicy 对象。

    Copy to Clipboard Toggle word wrap
    objects:
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-same-namespace
      spec:
        podSelector: {}
        ingress:
        - from:
          - podSelector: {}
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-openshift-ingress
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                network.openshift.io/policy-group: ingress
        podSelector: {}
        policyTypes:
        - Ingress
    - apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-kube-apiserver-operator
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: openshift-kube-apiserver-operator
            podSelector:
              matchLabels:
                app: kube-apiserver-operator
        policyTypes:
        - Ingress
    ...
  3. 可选:通过运行以下命令创建一个新项目,来确认您的网络策略对象已被成功创建:

    1. 创建一个新项目:

      Copy to Clipboard Toggle word wrap
      $ oc new-project <project> 
      1
      1
      <project> 替换为您要创建的项目的名称。
    2. 确认新项目模板中的网络策略对象存在于新项目中:

      Copy to Clipboard Toggle word wrap
      $ oc get networkpolicy
      NAME                           POD-SELECTOR   AGE
      allow-from-openshift-ingress   <none>         7s
      allow-from-same-namespace      <none>         7s

18.7. 使用网络策略配置多租户隔离

作为集群管理员,您可以配置网络策略以为多租户网络提供隔离功能。

注意

如果使用 OpenShift SDN 网络插件,请按照本节所述配置网络策略,提供类似于多租户模式的网络隔离,但设置了网络策略模式。

18.7.1. 使用网络策略配置多租户隔离

您可以配置项目,使其与其他项目命名空间中的 pod 和服务分离。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 admin 权限的用户登陆到集群。

流程

  1. 创建以下 NetworkPolicy 对象:

    1. 名为 allow-from-openshift-ingress 的策略。

      Copy to Clipboard Toggle word wrap
      $ cat << EOF| oc create -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-openshift-ingress
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                policy-group.network.openshift.io/ingress: ""
        podSelector: {}
        policyTypes:
        - Ingress
      EOF
      注意

      policy-group.network.openshift.io/ingress: "" 是 OpenShift SDN 的首选命名空间选择器标签。您可以使用 network.openshift.io/policy-group: ingress 命名空间选择器标签,但这是一个比较旧的用法。

    2. 名为 allow-from-openshift-monitoring 的策略:

      Copy to Clipboard Toggle word wrap
      $ cat << EOF| oc create -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-openshift-monitoring
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                network.openshift.io/policy-group: monitoring
        podSelector: {}
        policyTypes:
        - Ingress
      EOF
    3. 名为 allow-same-namespace 的策略:

      Copy to Clipboard Toggle word wrap
      $ cat << EOF| oc create -f -
      kind: NetworkPolicy
      apiVersion: networking.k8s.io/v1
      metadata:
        name: allow-same-namespace
      spec:
        podSelector:
        ingress:
        - from:
          - podSelector: {}
      EOF
    4. 名为 allow-from-kube-apiserver-operator 的策略:

      Copy to Clipboard Toggle word wrap
      $ cat << EOF| oc create -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-kube-apiserver-operator
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                kubernetes.io/metadata.name: openshift-kube-apiserver-operator
            podSelector:
              matchLabels:
                app: kube-apiserver-operator
        policyTypes:
        - Ingress
      EOF

      如需了解更多详细信息,请参阅 新的kube-apiserver-operator Webhook 控制器验证 Webhook 的健康状况

  2. 可选: 要确认当前项目中存在网络策略,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc describe networkpolicy

    输出示例

    Copy to Clipboard Toggle word wrap
    Name:         allow-from-openshift-ingress
    Namespace:    example1
    Created on:   2020-06-09 00:28:17 -0400 EDT
    Labels:       <none>
    Annotations:  <none>
    Spec:
      PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
      Allowing ingress traffic:
        To Port: <any> (traffic allowed to all ports)
        From:
          NamespaceSelector: network.openshift.io/policy-group: ingress
      Not affecting egress traffic
      Policy Types: Ingress
    
    
    Name:         allow-from-openshift-monitoring
    Namespace:    example1
    Created on:   2020-06-09 00:29:57 -0400 EDT
    Labels:       <none>
    Annotations:  <none>
    Spec:
      PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
      Allowing ingress traffic:
        To Port: <any> (traffic allowed to all ports)
        From:
          NamespaceSelector: network.openshift.io/policy-group: monitoring
      Not affecting egress traffic
      Policy Types: Ingress

18.7.2. 后续步骤

18.7.3. 其他资源

第 19 章 CIDR 范围定义

您必须为以下 CIDR 范围指定非重叠范围。

注意

创建集群后无法更改机器 CIDR 范围。

重要

OVN-Kubernetes 是 OpenShift Container Platform 4.11 到 4.13 的默认网络供应商,在内部使用以下 IP 地址范围:100.64.0.0/16, 169.254.169.0/29, fd98::/64fd69::/125。如果您的集群使用 OVN-Kubernetes,请不要在集群中的任何其他 CIDR 定义中包含任何 IP 地址范围。

19.1. Machine CIDR

在 Machine classless inter-domain routing (CIDR) 字段中,您必须为机器或集群节点指定 IP 地址范围。

默认值为 10.0.0.0/16。这个范围不得与任何连接的网络冲突。

19.2. Service CIDR

在 Service CIDR 字段中,您必须为服务指定 IP 地址范围。范围必须足够大,以适应您的工作负载。该地址块不得与从集群内部访问的任何外部服务重叠。默认为 172.30.0.0/16

19.3. Pod CIDR

在 pod CIDR 字段中,您必须为 pod 指定 IP 地址范围。

pod CIDR 与 clusterNetwork CIDR 和集群 CIDR 相同。范围必须足够大,以适应您的工作负载。该地址块不得与从集群内部访问的任何外部服务重叠。默认为 10.128.0.0/14。您可以在集群安装后扩展范围。

19.4. 主机前缀

在 Host Prefix 字段中,您必须指定分配给调度到各个机器的 pod 的子网前缀长度。主机前缀决定了每台机器的 pod IP 地址池。

例如,如果主机前缀设置为 /23,则每台机器从 pod CIDR 地址范围中分配一个 /23 子网。默认值为 /23,允许 510 集群节点,以及每个节点的 510 个 pod IP 地址。

第 20 章 AWS Load Balancer Operator

20.1. AWS Load Balancer Operator 发行注记

AWS Load Balancer (ALB) Operator 部署和管理 AWSLoadBalancerController 资源的实例。

重要

AWS Load Balancer (ALB) Operator 仅在 x86_64 构架中被支持。

本发行注记介绍了 OpenShift Container Platform 中的 AWS Load Balancer Operator 的开发。

如需 AWS Load Balancer Operator 的概述,请参阅 OpenShift Container Platform 中的 AWS Load Balancer Operator

注意

AWS Load Balancer Operator 目前不支持 AWS GovCloud。

20.1.1. AWS Load Balancer Operator 1.0.0

现在,AWS Load Balancer Operator 已正式发布。AWS Load Balancer Operator 版本 1.0.0 支持 AWS Load Balancer Controller 版本 2.4.4。

以下公告可用于 AWS Load Balancer Operator 版本 1.0.0:

20.1.1.1. 主要变化
  • 此发行版本使用新的 v1 API 版本。
20.1.1.2. 程序错误修复
  • 在以前的版本中,AWS Load Balancer Operator 置备的控制器无法正确将配置用于集群范围代理。这些设置现在对控制器正确应用。(OCPBUGS-4052, OCPBUGS-5295)

20.1.2. 早期版本

AWS Load Balancer Operator 的两个最早版本作为技术预览提供。这些版本不应在生产环境中使用。有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

以下公告可用于 AWS Load Balancer Operator 版本 0.2.0 :

以下公告可用于 AWS Load Balancer Operator 版本 0.0.1:

20.2. OpenShift Container Platform 中的 AWS Load Balancer Operator

AWS Load Balancer Operator 部署和管理 AWS Load Balancer Controller。您可以使用 OpenShift Container Platform Web 控制台或 CLI 安装来自 OperatorHub 的 AWS Load Balancer Operator。

20.2.1. AWS Load Balancer Operator 的注意事项

在安装和使用 AWS Load Balancer Operator 前查看以下限制:

  • IP 流量模式仅适用于 AWS Elastic Kubernetes Service (EKS)。AWS Load Balancer Operator 禁用 AWS Load Balancer Controller 的 IP 流量模式。禁用 IP 流量模式后,AWS Load Balancer Controller 无法使用 pod 就绪度。
  • AWS Load Balancer Operator 将命令行标记(如 --disable-ingress-class-annotation--disable-ingress-group-name-annotation )添加到 AWS Load Balancer Controller。因此,AWS Load Balancer Operator 不允许在 Ingress 资源中使用 kubernetes.io/ingress.classalb.ingress.kubernetes.io/group.name 注解。
  • 您已配置了 AWS Load Balancer Operator,使 SVC 类型是 NodePort (而不是 LoadBalancerClusterIP)。

20.2.2. AWS Load Balancer Operator

如果缺少 kubernetes.io/role/elb 标签,AWS Load Balancer Operator 可以标记公共子网。另外,AWS Load Balancer Operator 从底层 AWS 云检测到以下信息:

  • 托管 Operator 的集群的虚拟私有云 (VPC) 的 ID。
  • 发现 VPC 的公共和私有子网。

AWS Load Balancer Operator 支持类型为 LoadBalancer 的 Kubernetes 服务资源,使用只有 instance 目标类型的 Network Load Balancer (NLB)。

先决条件

  • 您必须具有 AWS 凭证 secret。凭证用于提供子网标记和 VPC 发现功能。

流程

  1. 您可以通过运行以下命令来创建 Subscription 对象,以按需部署 AWS Load Balancer Operator:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator get sub aws-load-balancer-operator --template='{{.status.installplan.name}}{{"\n"}}'

    输出示例

    Copy to Clipboard Toggle word wrap
    install-zlfbt

  2. 运行以下命令,检查安装计划的状态是否为 Complete

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator get ip <install_plan_name> --template='{{.status.phase}}{{"\n"}}'

    输出示例

    Copy to Clipboard Toggle word wrap
    Complete

  3. 运行以下命令,查看 aws-load-balancer-operator-controller-manager 部署的状态:

    Copy to Clipboard Toggle word wrap
    $ oc get -n aws-load-balancer-operator deployment/aws-load-balancer-operator-controller-manager

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                           READY     UP-TO-DATE   AVAILABLE   AGE
    aws-load-balancer-operator-controller-manager  1/1       1            1           23h

20.2.3. AWS Load Balancer Operator 日志

您可以使用 oc logs 命令查看 AWS Load Balancer Operator 日志。

流程

  • 运行以下命令,查看 AWS Load Balancer Operator 的日志:

    Copy to Clipboard Toggle word wrap
    $ oc logs -n aws-load-balancer-operator deployment/aws-load-balancer-operator-controller-manager -c manager

20.3. 安装 AWS Load Balancer Operator

AWS Load Balancer Operator 部署和管理 AWS Load Balancer Controller。您可以使用 OpenShift Container Platform Web 控制台或 CLI 安装来自 OperatorHub 的 AWS Load Balancer Operator。

20.3.1. 使用 Web 控制台安装 AWS Load Balancer Operator

您可以使用 Web 控制台安装 AWS Load Balancer Operator。

先决条件

  • 已作为具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform Web 控制台。
  • 集群被配置为使用 AWS 作为平台类型和云供应商。
  • 如果您使用安全令牌服务(STS)或用户置备的基础架构,请按照相关的准备步骤操作。例如,如果您使用 AWS 安全令牌服务,请参阅使用 AWS 安全令牌服务(STS) "在集群中准备 AWS Load Balancer Operator"。

流程

  1. 在 OpenShift Container Platform Web 控制台中进入 OperatorsOperatorHub
  2. 选择 AWS Load Balancer Operator。您可以使用 Filter by keyword 文本框,或者使用过滤器列表从 Operator 列表搜索 AWS Load Balancer Operator。
  3. 选择 aws-load-balancer-operator 命名空间。
  4. Install Operator 页面中,选择以下选项:

    1. 更新频道stable-v1
    2. 安装模式All namespaces on the cluster (default)
    3. Installed Namespaceaws-load-balancer-operator。如果 aws-load-balancer-operator 命名空间不存在,它会在 Operator 安装过程中创建。
    4. 选择 Update approvalAutomaticManual。默认情况下,Update approval 设置为 Automatic。如果选择自动更新,Operator Lifecycle Manager(OLM)将自动升级 Operator 的运行实例,而无需任何干预。如果选择手动更新,OLM 将创建一个更新请求。作为集群管理员,您必须手动批准该更新请求,以便将 Operator 更新至新版本。
  5. Install

验证

  • 在 Installed Operators 仪表板中验证 AWS Load Balancer Operator 的 Status 显示为 Succeeded

20.3.2. 使用 CLI 安装 AWS Load Balancer Operator

您可以使用 CLI 安装 AWS Load Balancer Operator。

先决条件

  • 以具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform Web 控制台。
  • 集群被配置为使用 AWS 作为平台类型和云供应商。
  • 已登陆到 OpenShift CLI (oc)。

流程

  1. 创建一个 Namespace 对象:

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

      namespace.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Namespace
      metadata:
        name: aws-load-balancer-operator

    2. 运行以下命令来创建 Namespace 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f namespace.yaml
  2. 创建 CredentialsRequest 对象:

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

      credentialsrequest.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: cloudcredential.openshift.io/v1
      kind: CredentialsRequest
      metadata:
        name: aws-load-balancer-operator
        namespace: openshift-cloud-credential-operator
      spec:
        providerSpec:
          apiVersion: cloudcredential.openshift.io/v1
          kind: AWSProviderSpec
          statementEntries:
            - action:
                - ec2:DescribeSubnets
              effect: Allow
              resource: "*"
            - action:
                - ec2:CreateTags
                - ec2:DeleteTags
              effect: Allow
              resource: arn:aws:ec2:*:*:subnet/*
            - action:
                - ec2:DescribeVpcs
              effect: Allow
              resource: "*"
        secretRef:
          name: aws-load-balancer-operator
          namespace: aws-load-balancer-operator
        serviceAccountNames:
          - aws-load-balancer-operator-controller-manager

    2. 运行以下命令来创建 CredentialsRequest 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f credentialsrequest.yaml
  3. 创建一个 OperatorGroup 对象:

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

      operatorgroup.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: operators.coreos.com/v1
      kind: OperatorGroup
      metadata:
        name: aws-lb-operatorgroup
        namespace: aws-load-balancer-operator
      spec:
        upgradeStrategy: Default

    2. 运行以下命令来创建 OperatorGroup 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f operatorgroup.yaml
  4. 创建 Subscription 对象:

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

      subscription.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: aws-load-balancer-operator
        namespace: aws-load-balancer-operator
      spec:
        channel: stable-v1
        installPlanApproval: Automatic
        name: aws-load-balancer-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace

    2. 运行以下命令来创建 Subscription 对象:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f subscription.yaml

验证

  1. 从订阅中获取安装计划的名称:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator \
        get subscription aws-load-balancer-operator \
        --template='{{.status.installplan.name}}{{"\n"}}'
  2. 检查安装计划的状态:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator \
        get ip <install_plan_name> \
        --template='{{.status.phase}}{{"\n"}}'

    输出必须是 Complete

20.4. 使用 AWS 安全令牌服务在集群中准备 AWS Load Balancer Operator

您可以在使用 STS 的集群中安装 AWS Load Balancer Operator。在安装 Operator 前,按照以下步骤准备集群。

AWS Load Balancer Operator 依赖于 CredentialsRequest 对象来引导 Operator 和 AWS Load Balancer Controller。AWS Load Balancer Operator 等待所需的 secret 创建并可用。Cloud Credential Operator 不会在 STS 集群中自动置备 secret。您必须使用 ccoctl 二进制文件手动设置凭证 secret。

如果您不想使用 Cloud Credential Operator 置备凭证 secret,您可以通过在 AWS Load Balancer Controller 自定义资源 (CR) 中指定凭证 secret 在 STS 集群上配置 AWSLoadBalancerController 实例。

20.4.1. 在安全令牌服务集群中引导 AWS Load Balancer Operator

先决条件

  • 您必须提取并准备 ccoctl 二进制文件。

流程

  1. 运行以下命令来创建 aws-load-balancer-operator 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace aws-load-balancer-operator
  2. 运行以下命令,下载 AWS Load Balancer Operator 的 CredentialsRequest 自定义资源 (CR),并创建一个目录来存储它:

    Copy to Clipboard Toggle word wrap
    $ curl --create-dirs -o <path-to-credrequests-dir>/cr.yaml https://raw.githubusercontent.com/openshift/aws-load-balancer-operator/main/hack/operator-credentials-request.yaml
  3. 运行以下命令,使用 ccoctl 工具处理 AWS Load Balancer Operator 的 CredentialsRequest 对象:

    Copy to Clipboard Toggle word wrap
    $ ccoctl aws create-iam-roles \
        --name <name> --region=<aws_region> \
        --credentials-requests-dir=<path-to-credrequests-dir> \
        --identity-provider-arn <oidc-arn>
  4. 运行以下命令应用在集群 manifests 目录中生成的 secret:

    Copy to Clipboard Toggle word wrap
    $ ls manifests/*-credentials.yaml | xargs -I{} oc apply -f {}
  5. 运行以下命令,验证 AWS Load Balancer Operator 的凭证 secret 是否已创建:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator get secret aws-load-balancer-operator --template='{{index .data "credentials"}}' | base64 -d

    输出示例

    Copy to Clipboard Toggle word wrap
    [default]
    sts_regional_endpoints = regional
    role_arn = arn:aws:iam::999999999999:role/aws-load-balancer-operator-aws-load-balancer-operator
    web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token

20.4.2. 使用受管 CredentialsRequest 对象在安全令牌服务集群中配置 AWS Load Balancer Operator

先决条件

  • 您必须提取并准备 ccoctl 二进制文件。

流程

  1. AWS Load Balancer Operator 为每个 AWSLoadBalancerController 自定义资源 (CR) 在 openshift-cloud-credential-operator 命名空间中创建 CredentialsRequest 对象。您可以运行以下命令来将创建的 CredentialsRequest 对象提取到目录中:

    Copy to Clipboard Toggle word wrap
    $ oc get credentialsrequest -n openshift-cloud-credential-operator  \
        aws-load-balancer-controller-<cr-name> -o yaml > <path-to-credrequests-dir>/cr.yaml 
    1
    1
    aws-load-balancer-controller-<cr-name> 参数指定 AWS Load Balancer Operator 创建的凭证请求名称。cr-name 指定 AWS Load Balancer Controller 实例的名称。
  2. 运行以下命令,使用 ccoctl 工具处理 credrequests 目录中的所有 CredentialsRequest 对象:

    Copy to Clipboard Toggle word wrap
    $ ccoctl aws create-iam-roles \
        --name <name> --region=<aws_region> \
        --credentials-requests-dir=<path-to-credrequests-dir> \
        --identity-provider-arn <oidc-arn>
  3. 运行以下命令应用在集群 manifests 目录中生成的 secret:

    Copy to Clipboard Toggle word wrap
    $ ls manifests/*-credentials.yaml | xargs -I{} oc apply -f {}
  4. 验证 aws-load-balancer-controller pod 是否已创建:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator get pods
    NAME                                                            READY   STATUS    RESTARTS   AGE
    aws-load-balancer-controller-cluster-9b766d6-gg82c              1/1     Running   0          137m
    aws-load-balancer-operator-controller-manager-b55ff68cc-85jzg   2/2     Running   0          3h26m

20.4.3. 使用特定凭证在安全令牌服务集群中配置 AWS Load Balancer Operator

您可以使用 AWS Load Balancer Controller 自定义资源(CR) 中的 spec.credentials 字段指定凭证 secret。您可以使用控制器的预定义 CredentialsRequest 对象来知道需要哪些角色。

先决条件

  • 您必须提取并准备 ccoctl 二进制文件。

流程

  1. 运行以下命令,下载 AWS Load Balancer Controller 的 CredentialsRequest 自定义资源 (CR),并创建一个目录来存储它:

    Copy to Clipboard Toggle word wrap
    $ curl --create-dirs -o <path-to-credrequests-dir>/cr.yaml https://raw.githubusercontent.com/openshift/aws-load-balancer-operator/main/hack/controller/controller-credentials-request.yaml
  2. 使用 ccoctl 工具处理控制器的 CredentialsRequest 对象:

    Copy to Clipboard Toggle word wrap
    $ ccoctl aws create-iam-roles \
            --name <name> --region=<aws_region> \
            --credentials-requests-dir=<path-to-credrequests-dir> \
            --identity-provider-arn <oidc-arn>
  3. 将 secret 应用到集群:

    Copy to Clipboard Toggle word wrap
    $ ls manifests/*-credentials.yaml | xargs -I{} oc apply -f {}
  4. 验证控制器是否已创建凭证 secret 以供控制器使用:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator get secret aws-load-balancer-controller-manual-cluster --template='{{index .data "credentials"}}' | base64 -d

    输出示例

    Copy to Clipboard Toggle word wrap
    [default]
        sts_regional_endpoints = regional
        role_arn = arn:aws:iam::999999999999:role/aws-load-balancer-operator-aws-load-balancer-controller
        web_identity_token_file = /var/run/secrets/openshift/serviceaccount/token

  5. 创建 AWSLoadBalancerController 资源 YAML 文件,如 sample-aws-lb-manual-creds.yaml,如下所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.olm.openshift.io/v1
    kind: AWSLoadBalancerController 
    1
    
    metadata:
      name: cluster 
    2
    
    spec:
      credentials:
        name: <secret-name> 
    3
    1
    定义 AWSLoadBalancerController 资源。
    2
    定义 AWS Load Balancer Controller 实例名称。此实例名称作为后缀添加到所有相关资源。
    3
    指定包含控制器使用的 AWS 凭证的 secret 名称。

20.4.4. 其他资源

20.5. 创建 AWS Load Balancer Controller 实例

安装 AWS Load Balancer Operator 后,您可以创建 AWS Load Balancer Controller。

20.5.1. 创建 AWS Load Balancer Controller

您只能在集群中安装 AWSLoadBalancerController 对象的单个实例。您可以使用 CLI 创建 AWS Load Balancer Controller。AWS Load Balancer Operator 只协调名为 resource 的集群

先决条件

  • 您已创建了 echoserver 命名空间。
  • 您可以访问 OpenShift CLI(oc)。

流程

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

    sample-aws-lb.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.olm.openshift.io/v1
    kind: AWSLoadBalancerController 
    1
    
    metadata:
      name: cluster 
    2
    
    spec:
      subnetTagging: Auto 
    3
    
      additionalResourceTags: 
    4
    
      - key: example.org/security-scope
        value: staging
      ingressClass: alb 
    5
    
      config:
        replicas: 2 
    6
    
      enabledAddons: 
    7
    
        - AWSWAFv2 
    8

    1
    定义 AWSLoadBalancerController 对象。
    2
    定义 AWS Load Balancer Controller 名称。此实例名称作为后缀添加到所有相关资源。
    3
    配置 AWS Load Balancer Controller 的子网标记方法。以下值有效:
    • Auto :AWS Load Balancer Operator 决定属于集群的子网,并相应地标记它们。如果内部子网上不存在内部子网标签,Operator 无法正确确定角色。
    • Manual :您可以使用适当的角色标签手动标记属于集群的子网。如果在用户提供的基础架构上安装集群,则使用这个选项。
    4
    定义在置备 AWS 资源时 AWS Load Balancer Controller 使用的标签。
    5
    定义入口类名称。默认值为 alb
    6
    指定 AWS Load Balancer Controller 的副本数。
    7
    将注解指定为 AWS Load Balancer Controller 的附加组件。
    8
    启用 alb.ingress.kubernetes.io/wafv2-acl-arn 注解。
  2. 运行以下命令来创建 AWSLoadBalancerController 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sample-aws-lb.yaml
  3. 创建定义 Deployment 资源的 YAML 文件:

    sample-aws-lb.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: apps/v1
    kind: Deployment 
    1
    
    metadata:
      name: <echoserver> 
    2
    
      namespace: echoserver
    spec:
      selector:
        matchLabels:
          app: echoserver
      replicas: 3 
    3
    
      template:
        metadata:
          labels:
            app: echoserver
        spec:
          containers:
            - image: openshift/origin-node
              command:
               - "/bin/socat"
              args:
                - TCP4-LISTEN:8080,reuseaddr,fork
                - EXEC:'/bin/bash -c \"printf \\\"HTTP/1.0 200 OK\r\n\r\n\\\"; sed -e \\\"/^\r/q\\\"\"'
              imagePullPolicy: Always
              name: echoserver
              ports:
                - containerPort: 8080

    1
    定义部署资源。
    2
    指定部署名称。
    3
    指定部署的副本数量。
  4. 创建定义 Service 资源的 YAML 文件:

    service-albo.yaml 文件示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Service 
    1
    
    metadata:
      name: <echoserver> 
    2
    
      namespace: echoserver
    spec:
      ports:
        - port: 80
          targetPort: 8080
          protocol: TCP
      type: NodePort
      selector:
        app: echoserver

    1
    定义服务资源。
    2
    指定服务名称。
  5. 创建定义 Ingress 资源的 YAML 文件:

    ingress-albo.yaml 文件示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: <name> 
    1
    
      namespace: echoserver
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: instance
    spec:
      ingressClassName: alb
      rules:
        - http:
            paths:
              - path: /
                pathType: Exact
                backend:
                  service:
                    name: <echoserver> 
    2
    
                    port:
                      number: 80

    1
    Ingress 资源指定一个名称。
    2
    指定服务名称。

验证

  • 运行以下命令,将 Ingress 资源的状态保存到 HOST 变量中:

    Copy to Clipboard Toggle word wrap
    $ HOST=$(oc get ingress -n echoserver echoserver --template='{{(index .status.loadBalancer.ingress 0).hostname}}')
  • 运行以下命令,验证 Ingress 资源的状态:

    Copy to Clipboard Toggle word wrap
    $ curl $HOST

20.6. 通过单个 AWS Load Balancer 提供多个入口资源

您可以通过单个 AWS Load Balancer 将流量路由到属于单个域的不同服务。每个 Ingress 资源提供域的不同端点。

20.6.1. 通过单个 AWS Load Balancer 创建多个入口资源

您可以使用 CLI 通过单个 AWS Load Balancer 将流量路由到多个入口资源。

先决条件

  • 您可以访问 OpenShift CLI(oc)。

流程

  1. 创建一个 IngressClassParams 资源 YAML 文件,如 sample-single-lb-params.yaml,如下所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: elbv2.k8s.aws/v1beta1 
    1
    
    kind: IngressClassParams
    metadata:
      name: single-lb-params 
    2
    
    spec:
      group:
        name: single-lb 
    3
    1
    定义 IngressClassParams 资源的 API 组和版本。
    2
    指定 IngressClassParams 资源名称。
    3
    指定 IngressGroup 资源名称。此类的所有 Ingress 资源都属于此 IngressGroup
  2. 运行以下命令来创建 IngressClassParams 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sample-single-lb-params.yaml
  3. 创建 IngressClass 资源 YAML 文件,如 sample-single-lb-class.yaml,如下所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1 
    1
    
    kind: IngressClass
    metadata:
      name: single-lb 
    2
    
    spec:
      controller: ingress.k8s.aws/alb 
    3
    
      parameters:
        apiGroup: elbv2.k8s.aws 
    4
    
        kind: IngressClassParams 
    5
    
        name: single-lb-params 
    6
    1
    定义 IngressClass 资源的 API 组和版本。
    2
    指定入口类名称。
    3
    定义控制器名称。ingress.k8s.aws/alb 值表示此类的所有入口资源都应由 AWS Load Balancer Controller 管理。
    4
    定义 IngressClassParams 资源的 API 组。
    5
    定义 IngressClassParams 资源的资源类型。
    6
    定义 IngressClassParams 资源名称。
  4. 运行以下命令来创建 IngressClass 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sample-single-lb-class.yaml
  5. 创建 AWSLoadBalancerController 资源 YAML 文件,如 sample-single-lb.yaml,如下所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.olm.openshift.io/v1
    kind: AWSLoadBalancerController
    metadata:
      name: cluster
    spec:
      subnetTagging: Auto
      ingressClass: single-lb 
    1
    1
    定义 IngressClass 资源的名称。
  6. 运行以下命令来创建 AWSLoadBalancerController 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sample-single-lb.yaml
  7. 创建 Ingress 资源 YAML 文件,如 sample-multiple-ingress.yaml,如下所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-1 
    1
    
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing 
    2
    
        alb.ingress.kubernetes.io/group.order: "1" 
    3
    
        alb.ingress.kubernetes.io/target-type: instance 
    4
    
    spec:
      ingressClassName: single-lb 
    5
    
      rules:
      - host: example.com 
    6
    
        http:
            paths:
            - path: /blog 
    7
    
              pathType: Prefix
              backend:
                service:
                  name: example-1 
    8
    
                  port:
                    number: 80 
    9
    
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-2
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/group.order: "2"
        alb.ingress.kubernetes.io/target-type: instance
    spec:
      ingressClassName: single-lb
      rules:
      - host: example.com
        http:
            paths:
            - path: /store
              pathType: Prefix
              backend:
                service:
                  name: example-2
                  port:
                    number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-3
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/group.order: "3"
        alb.ingress.kubernetes.io/target-type: instance
    spec:
      ingressClassName: single-lb
      rules:
      - host: example.com
        http:
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: example-3
                  port:
                    number: 80
    1
    指定入口名称。
    2
    指明在公共子网中置备的负载均衡器,以访问互联网。
    3
    指定在负载均衡器收到请求时,来自多个入口资源的规则的顺序匹配。
    4
    表示负载均衡器将针对 OpenShift Container Platform 节点为目标,以访问该服务。
    5
    指定属于此入口的入口类。
    6
    定义用于请求路由的域名。
    7
    定义必须路由到服务的路径。
    8
    定义提供 Ingress 资源中配置的端点的服务名称。
    9
    定义服务上提供端点的端口。
  8. 运行以下命令来创建 Ingress 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sample-multiple-ingress.yaml

20.7. 添加 TLS 终止

您可以在 AWS Load Balancer 上添加 TLS 终止。

20.7.1. 在 AWS Load Balancer 中添加 TLS 终止

您可以将域的流量路由到服务的 pod,并在 AWS 负载均衡器中添加 TLS 终止。

先决条件

  • 您可以访问 OpenShift CLI(oc)。

流程

  1. 创建定义 AWSLoadBalancerController 资源的 YAML 文件:

    add-tls-termination-albc.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.olm.openshift.io/v1
    kind: AWSLoadBalancerController
    metadata:
      name: cluster
    spec:
      subnetTagging: Auto
      ingressClass: tls-termination 
    1

    1
    定义入口类名称。如果集群中没有 ingress 类,AWS Load Balancer Controller 会创建一个。如果 spec.controller 设置为 ingress.k8s.aws/alb,AWS Load Balancer Controller 会协调额外的入口类值。
  2. 创建定义 Ingress 资源的 YAML 文件:

    add-tls-termination-ingress.yaml 文件示例

    Copy to Clipboard Toggle word wrap
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: <example> 
    1
    
      annotations:
        alb.ingress.kubernetes.io/scheme: internet-facing 
    2
    
        alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:xxxxx 
    3
    
    spec:
      ingressClassName: tls-termination 
    4
    
      rules:
      - host: <example.com> 
    5
    
        http:
            paths:
              - path: /
                pathType: Exact
                backend:
                  service:
                    name: <example-service> 
    6
    
                    port:
                      number: 80

    1
    指定入口名称。
    2
    控制器在公共子网中为入口置备负载均衡器,以便通过互联网访问负载均衡器。
    3
    附加到负载均衡器的证书的 Amazon 资源名称(ARN)。
    4
    定义入口类名称。
    5
    定义流量路由的域。
    6
    定义流量路由的服务。

20.8. 配置集群范围代理

您可以在 AWS Load Balancer Operator 中配置集群范围代理。配置集群范围代理后,Operator Lifecycle Manager (OLM) 会使用 HTTP_PROXYHTTPS_PROXYNO_PROXY 等环境变量自动更新 Operator 的所有部署。这些变量由 AWS Load Balancer Operator 填充给受管控制器。

20.8.1. 信任集群范围代理的证书颁发机构

  1. 运行以下命令,创建配置映射以在 aws-load-balancer-operator 命名空间中包含证书颁发机构 (CA) 捆绑包:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator create configmap trusted-ca
  2. 要将可信 CA 捆绑包注入配置映射中,请运行以下命令将 config.openshift.io/inject-trusted-cabundle=true 标签添加到配置映射中:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator label cm trusted-ca config.openshift.io/inject-trusted-cabundle=true
  3. 运行以下命令,更新 AWS Load Balancer Operator 订阅以访问 AWS Load Balancer Operator 部署中的配置映射:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator patch subscription aws-load-balancer-operator --type='merge' -p '{"spec":{"config":{"env":[{"name":"TRUSTED_CA_CONFIGMAP_NAME","value":"trusted-ca"}],"volumes":[{"name":"trusted-ca","configMap":{"name":"trusted-ca"}}],"volumeMounts":[{"name":"trusted-ca","mountPath":"/etc/pki/tls/certs/albo-tls-ca-bundle.crt","subPath":"ca-bundle.crt"}]}}}'
  4. 部署 AWS Load Balancer Operator 后,运行以下命令来验证 CA 捆绑包是否已添加到 aws-load-balancer-operator-controller-manager 部署中:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator exec deploy/aws-load-balancer-operator-controller-manager -c manager -- bash -c "ls -l /etc/pki/tls/certs/albo-tls-ca-bundle.crt; printenv TRUSTED_CA_CONFIGMAP_NAME"

    输出示例

    Copy to Clipboard Toggle word wrap
    -rw-r--r--. 1 root 1000690000 5875 Jan 11 12:25 /etc/pki/tls/certs/albo-tls-ca-bundle.crt
    trusted-ca

  5. 可选:通过运行以下命令,每次 configmap 发生变化时重启 AWS Load Balancer Operator 的部署:

    Copy to Clipboard Toggle word wrap
    $ oc -n aws-load-balancer-operator rollout restart deployment/aws-load-balancer-operator-controller-manager

20.8.2. 其他资源

第 21 章 多网络

21.1. 了解多网络

在 Kubernetes 中,容器网络被委派给实现 Container Network Interface (CNI) 的网络插件。

OpenShift Container Platform 使用 Multus CNI 插件来串联 CNI 插件。在集群安装过程中,您要配置 default pod 网络。默认网络处理集群中的所有一般网络流量。您可以基于可用的 CNI 插件定义额外网络,并将一个或多个此类网络附加到 pod。您可以根据需要为集群定义多个额外网络。这可让您灵活地配置提供交换或路由等网络功能的 pod。

21.1.1. 额外网络使用场景

您可以在需要网络隔离的情况下使用额外网络,包括分离数据平面与控制平面。隔离网络流量对以下性能和安全性原因很有用:

性能
您可以在两个不同的平面上发送流量,以管理每个平面上流量的多少。
安全性
您可以将敏感的流量发送到专为安全考虑而管理的网络平面,也可隔离不能在租户或客户间共享的私密数据。

集群中的所有 pod 仍然使用集群范围的默认网络,以维持整个集群中的连通性。每个 pod 都有一个 eth0 接口,附加到集群范围的 pod 网络。您可以使用 oc exec -it <pod_name> -- ip a 命令来查看 pod 的接口。如果您添加使用 Multus CNI 的额外网络接口,则名称为 net1net2、…​、netN

要将额外网络接口附加到 pod,您必须创建配置来定义接口的附加方式。您可以使用 NetworkAttachmentDefinition 自定义资源(CR)来指定各个接口。各个 CR 中的 CNI 配置定义如何创建该接口。

21.1.2. OpenShift Container Platform 中的额外网络

OpenShift Container Platform 提供以下 CNI 插件,以便在集群中创建额外网络:

  • bridge配置基于网桥的额外网络,以允许同一主机上的 pod 相互通信,并与主机通信。
  • host-device配置 host-device 额外网络,以允许 pod 访问主机系统上的物理以太网网络设备。
  • ipvlan配置基于 ipvlan 的额外网络,以允许主机上的 Pod 与其他主机和那些主机上的 pod 通信,这类似于基于 macvlan 的额外网络。与基于 macvlan 的额外网络不同,每个 pod 共享与父级物理网络接口相同的 MAC 地址。
  • macvlan配置基于 macvlan 的额外网络,以允许主机上的 Pod 通过使用物理网络接口与其他主机和那些主机上的 Pod 通信。附加到基于 macvlan 的额外网络的每个 pod 都会获得一个唯一的 MAC 地址。
  • SR-IOV配置基于 SR-IOV 的额外网络,以允许 pod 附加到主机系统上支持 SR-IOV 的硬件的虚拟功能(VF)接口。

21.2. 配置额外网络

作为集群管理员,您可以为集群配置额外网络。支持以下网络类型:

21.2.1. 管理额外网络的方法

您可以使用两种方法之一管理 OpenShift Container Platform 中额外网络的生命周期:修改 Cluster Network Operator (CNO)配置或应用 YAML 清单。每种方法都是相互排斥的,您一次只能使用一种方法来管理额外网络。对于任一方法,额外网络由您配置的 Container Network Interface(CNI)插件管理。以下是两种不同方法:

  • 修改 Cluster Network Operator (CNO)配置:只有集群管理员只能使用 CNO 配置额外网络。CNO 会自动创建和管理 NetworkAttachmentDefinition 对象。通过使用这种方法,您可以在安装时通过配置 install-config 来定义 NetworkAttachmentDefinition 对象。
  • 应用 YAML 清单:您可以通过创建 NetworkAttachmentDefinition 对象直接管理额外网络。与修改 CNO 配置相比,这种方法为您提供了在涉及配置时更精细的控制和灵活性。
注意

当使用 OVN Kubernetes 在 Red Hat OpenStack Platform (RHOSP) 中使用多个网络接口部署 OpenShift Container Platform 节点时,二级接口的 DNS 配置可能会优先于主接口的 DNS 配置。在这种情况下,删除附加到二级接口的子网 ID 的 DNS 名称服务器:

Copy to Clipboard Toggle word wrap
$ openstack subnet set --dns-nameserver 0.0.0.0 <subnet_id>

21.2.2. 额外网络的 IP 地址分配

对于额外网络,可以使用 IP 地址管理(IPAM) CNI 插件来分配 IP 地址,该插件支持各种分配方法,包括动态主机配置协议(DHCP)和静态分配。

负责动态分配 IP 地址的 DHCP IPAM CNI 插件与两个不同的组件一起运行:

  • CNI 插件 :负责与 Kubernetes 网络堆栈集成,以请求和释放 IP 地址。
  • DHCP IPAM CNI 守护进程 :用于 DHCP 事件的监听程序,该事件与环境中的现有 DHCP 服务器协调,以处理 IP 地址分配请求。这个守护进程 不是 DHCP 服务器本身。

对于在 IPAM 配置中需要 type: dhcp 的网络,请确保以下内容:

  • DHCP 服务器可用并在环境中运行。DHCP 服务器是集群外部的,应该成为客户的现有网络基础架构的一部分。
  • DHCP 服务器被正确配置为为节点提供 IP 地址。

如果环境中 DHCP 服务器不可用,建议使用 Whereabouts IPAM CNI 插件。Whereabouts CNI 提供类似的 IP 地址管理功能,而无需外部 DHCP 服务器。

注意

当没有外部 DHCP 服务器或首选静态 IP 地址管理时,请使用 Whereabouts CNI 插件。Whereabouts 插件包含一个协调器守护进程来管理过时的 IP 地址分配。

在整个容器生命周期中,必须定期更新 DHCP 租期,因此需要单独的守护进程 DHCP IPAM CNI 守护进程。要部署 DHCP IPAM CNI 守护进程,请修改 Cluster Network Operator (CNO)配置,以触发此守护进程的部署,作为额外网络设置的一部分。

21.2.3. 配置额外网络附加

额外网络通过使用 k8s.cni.cncf.io API 组中的 NetworkAttachmentDefinition API 来配置。

重要

请勿将任何敏感信息或机密存储在 NetworkAttachmentDefinition 对象中,因为此类信息可由项目管理用户访问。

下表中描述了 API 的配置:

表 21.1. NetworkAttachmentDefinition API 字段
字段类型描述

metadata.name

string

额外网络的名称。

metadata.namespace

string

与对象关联的命名空间。

spec.config

string

JSON 格式的 CNI 插件配置。

21.2.3.1. 通过 Cluster Network Operator 配置额外网络

额外网络附加的配置作为 Cluster Network Operator(CNO)配置的一部分被指定。

以下 YAML 描述了使用 CNO 管理额外网络的配置参数:

Cluster Network Operator 配置

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  # ...
  additionalNetworks: 
1

  - name: <name> 
2

    namespace: <namespace> 
3

    rawCNIConfig: |- 
4

      {
        ...
      }
    type: Raw

1
由一个或多个附加网络配置组成的数组。
2
您要创建的额外网络附加的名称。该名称在指定的 namespace 中需要是唯一的。
3
在其中创建网络附加的命名空间。如果您未指定值,则使用 default 命名空间。
4
JSON 格式的 CNI 插件配置。
21.2.3.2. 从 YAML 清单配置额外网络

从 YAML 配置文件指定额外网络的配置,如下例所示:

Copy to Clipboard Toggle word wrap
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: <name> 
1

spec:
  config: |- 
2

    {
      ...
    }
1
您要创建的额外网络附加的名称。
2
JSON 格式的 CNI 插件配置。

21.2.4. 额外网络类型的配置

以下部分介绍了额外网络的具体配置字段。

21.2.4.1. 配置桥接额外网络

以下对象描述了 bridge CNI 插件的配置参数:

表 21.2. bridge CNI 插件 JSON 配置对象
字段类型描述

cniVersion

string

CNI 规格版本。需要 0.3.1 值。

名称

string

您之前为 CNO 配置提供的 name 参数的值。

type

string

用于配置的 CNI 插件的名称:bridge

ipam

object

IPAM CNI 插件的配置对象。该插件管理附加定义的 IP 地址分配。

bridge

string

可选:指定要使用的虚拟网桥名称。如果主机上不存在网桥接口,则进行创建。默认值为 cni0

ipMasq

布尔值

可选:设置为 true,为离开虚拟网络的流量启用 IP 伪装。所有流量的源 IP 地址都会改写为网桥 IP 地址。如果网桥没有 IP 地址,此设置无效。默认值为 false

isGateway

布尔值

可选:设置为 true,从而为网桥分配 IP 地址。默认值为 false

isDefaultGateway

布尔值

可选:设置为 true,将网桥配置为虚拟网络的默认网关。默认值为 false。如果 isDefaultGateway 设置为 true,则 isGateway 也会自动设置为 true

forceAddress

布尔值

可选:设置为 true,以允许将之前分配的 IP 地址分配给虚拟网桥。设置为 false 时,如果将来自于重叠子集的 IPv4 地址或者 IPv6 地址分配给虚拟网桥,则会发生错误。默认值为 false

hairpinMode

布尔值

可选:设置为 true,以允许虚拟网桥通过收到它的虚拟端口将其发回。这个模式也被称为反射中继。默认值为 false

promiscMode

布尔值

可选:设置为 true 以在网桥上启用混杂模式。默认值为 false

vlan

string

可选:指定一个虚拟 LAN (VLAN) 标签作为整数值。默认情况下不分配 VLAN 标签。

preserveDefaultVlan

string

可选:指示在连接到网桥的 veth 端是否保留默认 vlan。默认值为 true。

mtu

整数

可选:将最大传输单元 (MTU) 设置为指定的值。默认值由内核自动设置。

enabledad

布尔值

可选:为容器侧 veth 启用重复的地址检测。默认值为 false

macspoofchk

布尔值

可选:启用 mac spoof 检查,将来自容器的流量限制为接口的 mac 地址。默认值为 false

注意

VLAN 参数在 veth 的主机端配置 VLAN 标签,并在网桥接口上启用 vlan_filtering 功能。

注意

要为 L2 网络配置 uplink,您需要使用以下命令在 uplink 接口上允许 vlan :

Copy to Clipboard Toggle word wrap
$  bridge vlan add vid VLAN_ID dev DEV
21.2.4.1.1. 网桥配置示例

以下示例配置了名为 bridge-net 的额外网络:

Copy to Clipboard Toggle word wrap
{
  "cniVersion": "0.3.1",
  "name": "bridge-net",
  "type": "bridge",
  "isGateway": true,
  "vlan": 2,
  "ipam": {
    "type": "dhcp"
    }
}
21.2.4.2. 主机设备额外网络配置
注意

仅设置以下参数之一来指定您的网络设备:devicehwaddrkernelpathpciBusID

以下对象描述了 host-device CNI 插件的配置参数:

表 21.3. 主机 device CNI 插件 JSON 配置对象
字段类型描述

cniVersion

string

CNI 规格版本。需要 0.3.1 值。

名称

string

您之前为 CNO 配置提供的 name 参数的值。

type

string

用于配置的 CNI 插件的名称:host-device

device

string

可选:设备的名称,如 eth0

hwaddr

string

可选:设备硬件 MAC 地址。

kernelpath

string

可选:Linux 内核设备路径,如 /sys/devices/pci0000:00/0000:00:1f.6

pciBusID

string

可选:网络设备的 PCI 地址,如 0000:00:1f.6

21.2.4.2.1. host-device 配置示例

以下示例配置了名为 hostdev-net 的额外网络:

Copy to Clipboard Toggle word wrap
{
  "cniVersion": "0.3.1",
  "name": "hostdev-net",
  "type": "host-device",
  "device": "eth1"
}
21.2.4.3. 配置 IPVLAN 额外网络

以下对象描述了 IPVLAN CNI 插件的配置参数:

表 21.4. IPVLAN CNI 插件 JSON 配置对象
字段类型描述

cniVersion

string

CNI 规格版本。需要 0.3.1 值。

名称

string

您之前为 CNO 配置提供的 name 参数的值。

type

string

要配置的 CNI 插件的名称:ipvlan

ipam

object

IPAM CNI 插件的配置对象。该插件管理附加定义的 IP 地址分配。除非插件被串联,否则需要此项。

模式

string

可选:虚拟网络的操作模式。这个值必须是 l2l3l3s。默认值为 l2

master

string

可选:与网络附加关联的以太网接口。如果没有指定 master,则使用默认网络路由的接口。

mtu

整数

可选:将最大传输单元 (MTU) 设置为指定的值。默认值由内核自动设置。

注意
  • ipvlan 对象不允许虚拟接口与 master 接口通信。因此,容器无法使用 ipvlan 接口访问主机。确保容器加入提供主机连接的网络,如支持 Precision Time Protocol (PTP) 的网络。
  • 单个 master 接口无法同时配置为使用 macvlanipvlan
  • 对于不能与接口无关的 IP 分配方案,可以使用处理此逻辑的较早插件来串联 ipvlan 插件。如果省略 master,则前面的结果必须包含一个接口名称,以便 ipvlan 插件进行 enslave。如果省略 ipam,则使用前面的结果来配置 ipvlan 接口。
21.2.4.3.1. ipvlan 配置示例

以下示例配置了名为 ipvlan -net 的额外网络:

Copy to Clipboard Toggle word wrap
{
  "cniVersion": "0.3.1",
  "name": "ipvlan-net",
  "type": "ipvlan",
  "master": "eth1",
  "mode": "l3",
  "ipam": {
    "type": "static",
    "addresses": [
       {
         "address": "192.168.10.10/24"
       }
    ]
  }
}
21.2.4.4. 配置 MACVLAN 额外网络

以下对象描述了 MAC Virtual LAN (MACVLAN) Container Network Interface (CNI)插件的配置参数:

表 21.5. MACVLAN CNI 插件 JSON 配置对象
字段类型描述

cniVersion

string

CNI 规格版本。需要 0.3.1 值。

名称

string

您之前为 CNO 配置提供的 name 参数的值。

type

string

用于配置的 CNI 插件的名称:macvlan

ipam

object

IPAM CNI 插件的配置对象。该插件管理附加定义的 IP 地址分配。

模式

string

可选:配置虚拟网络上的流量可见性。必须是 bridgepassthruprivateVepa。如果没有提供值,则默认值为 bridge

master

string

可选:与新创建的 macvlan 接口关联的主机网络接口。如果没有指定值,则使用默认路由接口。

mtu

整数

可选:将最大传输单元 (MTU) 到指定的值。默认值由内核自动设置。

注意

如果您为插件配置指定 master key,请使用与主网络插件关联的物理网络接口,以避免可能冲突。

21.2.4.4.1. MACVLAN 配置示例

以下示例配置了名为 macvlan-net 的额外网络:

Copy to Clipboard Toggle word wrap
{
  "cniVersion": "0.3.1",
  "name": "macvlan-net",
  "type": "macvlan",
  "master": "eth1",
  "mode": "bridge",
  "ipam": {
    "type": "dhcp"
    }
}

21.2.5. 为额外网络配置 IP 地址分配

IP 地址管理 (IPAM) Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址。

您可以使用以下 IP 地址分配类型:

  • 静态分配。
  • 通过 DHCP 服务器进行动态分配。您指定的 DHCP 服务器必须可从额外网络访问。
  • 通过 Whereabouts IPAM CNI 插件进行动态分配。
21.2.5.1. 静态 IP 地址分配配置

下表描述了静态 IP 地址分配的配置:

表 21.6. ipam 静态配置对象
字段类型描述

type

string

IPAM 地址类型。值必须是 static

addresses

数组

指定分配给虚拟接口的 IP 地址的对象数组。支持 IPv4 和 IPv6 IP 地址。

Routes

数组

指定要在 pod 中配置的路由的一组对象。

dns

数组

可选:指定 DNS 配置的对象数组。

address 数组需要带有以下字段的对象:

表 21.7. ipam.addresses[] array
字段类型描述

address

string

您指定的 IP 地址和网络前缀。例如:如果您指定 10.10.21.10/24,那么会为额外网络分配 IP 地址 10.10.21.10,网掩码为 255.255.255.0

gateway

string

出口网络流量要路由到的默认网关。

表 21.8. ipam.routes[] array
字段类型描述

dst

string

CIDR 格式的 IP 地址范围,如 192.168.17.0/24 或默认路由 0.0.0.0/0

gw

string

网络流量路由的网关。

表 21.9. ipam.dns object
字段类型描述

nameservers

数组

用于发送 DNS 查询的一个或多个 IP 地址的数组。

domain

数组

要附加到主机名的默认域。例如,如果将域设置为 example.com,对 example-host 的 DNS 查找查询将被改写为 example-host.example.com

search

数组

在 DNS 查找查询过程中,附加到非限定主机名(如 example-host)的域名的数组。

静态 IP 地址分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "static",
      "addresses": [
        {
          "address": "191.168.1.7/24"
        }
      ]
  }
}

21.2.5.2. 动态 IP 地址(DHCP)分配配置

以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置。

DHCP 租期续订

pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。

要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:

shim 网络附加定义示例

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  additionalNetworks:
  - name: dhcp-shim
    namespace: default
    type: Raw
    rawCNIConfig: |-
      {
        "name": "dhcp-shim",
        "cniVersion": "0.3.1",
        "type": "bridge",
        "ipam": {
          "type": "dhcp"
        }
      }
  # ...

表 21.10. ipam DHCP 配置对象
字段类型描述

type

string

IPAM 地址类型。需要值 dhcp

动态 IP 地址(DHCP)分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "dhcp"
  }
}

21.2.5.3. 使用 Whereabouts 进行动态 IP 地址分配配置

Whereabouts CNI 插件允许在不使用 DHCP 服务器的情况下动态地将 IP 地址分配给额外网络。

下表描述了使用 Whereabouts 进行动态 IP 地址分配的配置:

表 21.11. ipam whereabouts 配置对象
字段类型描述

type

string

IPAM 地址类型。需要 abouts 的值。

range

string

CIDR 表示法中的 IP 地址和范围。IP 地址是通过这个地址范围来分配的。

exclude

数组

可选: CIDR 标记中零个或更多 IP 地址和范围的列表。包含在排除地址范围中的 IP 地址。

使用 Whereabouts 的动态 IP 地址分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "whereabouts",
    "range": "192.0.2.192/27",
    "exclude": [
       "192.0.2.192/30",
       "192.0.2.196/32"
    ]
  }
}

21.2.5.4. 创建 Whereabouts 协调器守护进程集

Whereabouts 协调器负责管理集群中 pod 的动态 IP 地址分配,使用 Whereabouts IP 地址管理 (IPAM) 解决方案。它确保每个 pod 从指定的 IP 地址范围中获取唯一的 IP 地址。它还会在 pod 删除或缩减时处理 IP 地址发行版本。

注意

您还可以使用 NetworkAttachmentDefinition 自定义资源进行动态 IP 地址分配。

通过 Cluster Network Operator 配置额外网络时,Whereabouts reconciler 守护进程集会被自动创建。从 YAML 清单配置额外网络时,它不会自动创建。

要触发 Whereabouts 协调器 daemonset 的部署,您必须通过编辑 Cluster Network Operator 自定义资源文件来手动创建 whereabouts-shim 网络附加。

使用以下步骤部署 Whereabouts 协调器 daemonset。

流程

  1. 运行以下命令来编辑 Network.operator.openshift.io 自定义资源(CR):

    Copy to Clipboard Toggle word wrap
    $ oc edit network.operator.openshift.io cluster
  2. 修改 CR 中的 additionalNetworks 参数,以添加 abouts-shim 网络附加定义。例如:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      additionalNetworks:
      - name: whereabouts-shim
        namespace: default
        rawCNIConfig: |-
          {
           "name": "whereabouts-shim",
           "cniVersion": "0.3.1",
           "type": "bridge",
           "ipam": {
             "type": "whereabouts"
           }
          }
        type: Raw
  3. 保存文件并退出文本编辑器。
  4. 运行以下命令,验证 whereabouts-reconciler 守护进程集是否已成功部署:

    Copy to Clipboard Toggle word wrap
    $ oc get all -n openshift-multus | grep whereabouts-reconciler

    输出示例

    Copy to Clipboard Toggle word wrap
    pod/whereabouts-reconciler-jnp6g 1/1 Running 0 6s
    pod/whereabouts-reconciler-k76gg 1/1 Running 0 6s
    pod/whereabouts-reconciler-k86t9 1/1 Running 0 6s
    pod/whereabouts-reconciler-p4sxw 1/1 Running 0 6s
    pod/whereabouts-reconciler-rvfdv 1/1 Running 0 6s
    pod/whereabouts-reconciler-svzw9 1/1 Running 0 6s
    daemonset.apps/whereabouts-reconciler 6 6 6 6 6 kubernetes.io/os=linux 6s

21.2.6. 使用 Cluster Network Operator 创建额外网络附加

Cluster Network Operator (CNO) 管理额外网络定义。当您指定要创建的额外网络时,CNO 会自动创建 NetworkAttachmentDefinition 对象。

重要

不要编辑 Cluster Network Operator 所管理的 NetworkAttachmentDefinition 对象。这样做可能会破坏额外网络上的网络流量。

先决条件

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

流程

  1. 可选:为额外网络创建命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace <namespace_name>
  2. 要编辑 CNO 配置,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc edit networks.operator.openshift.io cluster
  3. 通过为您要创建的额外网络添加配置来修改您要创建的 CR,如下例所示。

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      # ...
      additionalNetworks:
      - name: tertiary-net
        namespace: namespace2
        type: Raw
        rawCNIConfig: |-
          {
            "cniVersion": "0.3.1",
            "name": "tertiary-net",
            "type": "ipvlan",
            "master": "eth1",
            "mode": "l2",
            "ipam": {
              "type": "static",
              "addresses": [
                {
                  "address": "192.168.1.23/24"
                }
              ]
            }
          }
  4. 保存您的更改,再退出文本编辑器以提交更改。

验证

  • 通过运行以下命令确认 CNO 创建了 NetworkAttachmentDefinition 对象。CNO 创建对象之前可能会有延迟。

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions -n <namespace>

    其中:

    <namespace>
    指定添加到 CNO 配置中的网络附加的命名空间。

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                 AGE
    test-network-1       14m

21.2.7. 通过应用 YAML 清单来创建额外网络附加

先决条件

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

流程

  1. 使用额外网络配置创建 YAML 文件,如下例所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1
    kind: NetworkAttachmentDefinition
    metadata:
      name: next-net
    spec:
      config: |-
        {
          "cniVersion": "0.3.1",
          "name": "work-network",
          "type": "host-device",
          "device": "eth1",
          "ipam": {
            "type": "dhcp"
          }
        }
  2. 运行以下命令来创建额外网络:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f <file>.yaml

    其中:

    <file>
    指定包含 YAML 清单的文件名。

21.3. 关于虚拟路由和转发

21.3.1. 关于虚拟路由和转发

虚拟路由和转发(VRF)设备与 IP 规则相结合,提供了创建虚拟路由和转发域的能力。VRF 减少了 CNF 所需的权限数量,并可提高二级网络网络拓扑的可见性。VRF 用于提供多租户功能,例如,每个租户都有自己的唯一的路由表且需要不同的默认网关。

进程可将套接字绑定到 VRF 设备。通过绑定套接字的数据包使用与 VRF 设备关联的路由表。VRF 的一个重要特性是,它只影响 OSI 模型层 3 以上的流量,因此 L2 工具(如 LLDP)不会受到影响。这可让优先级更高的 IP 规则(如基于策略的路由)优先于针对特定流量的 VRF 设备规则。

21.3.1.1. 这对针对电信业使用的 pod 的从属网络提供了好处

在电信业,每个 CNF 都可连接到共享相同地址空间的多个不同的网络。这些从属网络可能会与集群的主网络 CIDR 冲突。使用 CNI VRF 插件,网络功能可使用相同的 IP 地址连接到不同的客户基础架构,使不同的客户保持隔离。IP 地址与 OpenShift Container Platform IP 空间重叠。CNI VRF 插件还可减少 CNF 所需的权限数量,并提高从属网络的网络拓扑的可见性。

21.4. 配置多网络策略

作为集群管理员,您可以为额外网络配置多网络。您可以为 SR-IOV 和 macvlan 额外网络指定多网络策略。macvlan 额外网络被完全支持。不支持其他类型的额外网络,如 ipvlan。

重要

支持为 SR-IOV 额外网络配置多网络策略是技术预览功能,且只支持内核网络接口卡 (NIC)。SR-IOV 不支持 Data Plane Development Kit (DPDK)应用程序。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

注意

在 IPv6 网络中会忽略配置的网络策略。

21.4.1. 多网络策略和网络策略之间的区别

虽然 MultiNetworkPolicy API 实现 NetworkPolicy API,但有几个重要的区别:

  • 您必须使用 MultiNetworkPolicy API:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1beta1
    kind: MultiNetworkPolicy
  • 当使用 CLI 与多网络策略交互时,您必须使用 multi-networkpolicy 资源名称。例如,您可以使用 oc get multi-networkpolicy <name> 命令来查看多网络策略对象,其中 <name> 是多网络策略的名称。
  • 您必须使用定义 macvlan 或 SR-IOV 额外网络的网络附加定义名称指定一个注解:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1beta1
    kind: MultiNetworkPolicy
    metadata:
      annotations:
        k8s.v1.cni.cncf.io/policy-for: <network_name>

    其中:

    <network_name>
    指定网络附加定义的名称。

21.4.2. 为集群启用多网络策略

作为集群管理员,您可以在集群中启用多网络策略支持。

先决条件

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

流程

  1. 使用以下 YAML 创建 multinetwork-enable-patch.yaml 文件:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      useMultiNetworkPolicy: true
  2. 配置集群以启用多网络策略:

    Copy to Clipboard Toggle word wrap
    $ oc patch network.operator.openshift.io cluster --type=merge --patch-file=multinetwork-enable-patch.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    network.operator.openshift.io/cluster patched

21.4.3. 使用多网络策略

作为集群管理员,您可以创建、编辑、查看和删除多网络策略。

21.4.3.1. 先决条件
  • 您已为集群启用了多网络策略支持。
21.4.3.2. 使用 CLI 创建多网络策略

要定义细致的规则来描述集群中命名空间允许的入口或出口网络流量,您可以创建一个多网络策略。

先决条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在多网络策略应用到的命名空间中工作。

流程

  1. 创建策略规则:

    1. 创建一个 <policy_name>.yaml 文件:

      Copy to Clipboard Toggle word wrap
      $ touch <policy_name>.yaml

      其中:

      <policy_name>
      指定多网络策略文件名。
    2. 在您刚才创建的文件中定义多网络策略,如下例所示:

      拒绝来自所有命名空间中的所有 pod 的入口流量

      这是一个基本的策略,阻止配置其他网络策略所允许的跨 pod 流量以外的所有跨 pod 网络。

      Copy to Clipboard Toggle word wrap
      apiVersion: k8s.cni.cncf.io/v1beta1
      kind: MultiNetworkPolicy
      metadata:
        name: deny-by-default
        annotations:
          k8s.v1.cni.cncf.io/policy-for: <network_name>
      spec:
        podSelector:
        ingress: []

      其中:

      <network_name>
      指定网络附加定义的名称。

      允许来自所有命名空间中的所有 pod 的入口流量

      Copy to Clipboard Toggle word wrap
      apiVersion: k8s.cni.cncf.io/v1beta1
      kind: MultiNetworkPolicy
      metadata:
        name: allow-same-namespace
        annotations:
          k8s.v1.cni.cncf.io/policy-for: <network_name>
      spec:
        podSelector:
        ingress:
        - from:
          - podSelector: {}

      其中:

      <network_name>
      指定网络附加定义的名称。

      允许从特定命名空间中到一个 pod 的入口流量

      此策略允许流量从在 namespace-y 中运行的容器集到标记 pod-a 的 pod。

      Copy to Clipboard Toggle word wrap
      apiVersion: k8s.cni.cncf.io/v1beta1
      kind: MultiNetworkPolicy
      metadata:
        name: allow-traffic-pod
        annotations:
          k8s.v1.cni.cncf.io/policy-for: <network_name>
      spec:
        podSelector:
         matchLabels:
            pod: pod-a
        policyTypes:
        - Ingress
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                 kubernetes.io/metadata.name: namespace-y

      其中:

      <network_name>
      指定网络附加定义的名称。

      限制到服务的流量

      应用此策略可确保每个带有标签 app=bookstore 和标签 role=api 的 pod 只能被带有标签 app=bookstore 的 pod 访问。在本例中,应用可以是 REST API 服务器,标记为标签 app=bookstorerole=api

      这个示例可以解决了以下用例:

      • 将到一个服务的流量限制为仅使用需要它的其他微服务。
      • 将连接限制为只允许使用它的应用程序。

        Copy to Clipboard Toggle word wrap
        apiVersion: k8s.cni.cncf.io/v1beta1
        kind: MultiNetworkPolicy
        metadata:
          name: api-allow
          annotations:
            k8s.v1.cni.cncf.io/policy-for: <network_name>
        spec:
          podSelector:
            matchLabels:
              app: bookstore
              role: api
          ingress:
          - from:
              - podSelector:
                  matchLabels:
                    app: bookstore

        其中:

        <network_name>
        指定网络附加定义的名称。
  2. 运行以下命令来创建多网络策略对象:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f <policy_name>.yaml -n <namespace>

    其中:

    <policy_name>
    指定多网络策略文件名。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

    输出示例

    Copy to Clipboard Toggle word wrap
    multinetworkpolicy.k8s.cni.cncf.io/deny-by-default created

注意

如果您使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群中的任何命名空间中以 YAML 或 web 控制台的形式创建网络策略。

21.4.3.3. 编辑多网络策略

您可以编辑命名空间中的多网络策略。

先决条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在存在多网络策略的命名空间中工作。

流程

  1. 可选: 要列出命名空间中的多网络策略对象,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get multi-networkpolicy

    其中:

    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
  2. 编辑多网络策略对象。

    • 如果您在文件中保存了多网络策略定义,请编辑该文件并进行必要的更改,然后输入以下命令。

      Copy to Clipboard Toggle word wrap
      $ oc apply -n <namespace> -f <policy_file>.yaml

      其中:

      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
      <policy_file>
      指定包含网络策略的文件的名称。
    • 如果您需要直接更新多网络策略对象,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc edit multi-networkpolicy <policy_name> -n <namespace>

      其中:

      <policy_name>
      指定网络策略的名称。
      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
  3. 确认已更新多网络策略对象。

    Copy to Clipboard Toggle word wrap
    $ oc describe multi-networkpolicy <policy_name> -n <namespace>

    其中:

    <policy_name>
    指定多网络策略的名称。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
注意

如果您使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群中的任何命名空间中以 YAML 或通过 Actions 菜单从 web 控制台中的策略编辑网络策略。

21.4.3.4. 使用 CLI 查看多网络策略

您可以检查命名空间中的多网络策略。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在存在多网络策略的命名空间中工作。

流程

  • 列出命名空间中的多网络策略:

    • 要查看命名空间中定义的多网络策略对象,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get multi-networkpolicy
    • 可选: 要检查特定的多网络策略,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc describe multi-networkpolicy <policy_name> -n <namespace>

      其中:

      <policy_name>
      指定要检查的多网络策略的名称。
      <namespace>
      可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。
注意

如果您使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群中的任何命名空间中以 YAML 或 web 控制台的形式查看网络策略。

21.4.3.5. 使用 CLI 删除多网络策略

您可以删除命名空间中的多网络策略。

先决条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在存在多网络策略的命名空间中工作。

流程

  • 要删除多网络策略对象,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc delete multi-networkpolicy <policy_name> -n <namespace>

    其中:

    <policy_name>
    指定多网络策略的名称。
    <namespace>
    可选: 如果对象在与当前命名空间不同的命名空间中定义,使用它来指定命名空间。

    输出示例

    Copy to Clipboard Toggle word wrap
    multinetworkpolicy.k8s.cni.cncf.io/default-deny deleted

注意

如果使用 cluster-admin 权限登录到 web 控制台,您可以选择在集群上以 YAML 或通过 Actions 菜单从 web 控制台中的策略删除网络策略。

21.4.3.6. 创建默认拒绝所有多网络策略

这是一个基本的策略,阻止其他部署网络策略允许的网络流量以外的所有跨 pod 网络。此流程强制使用默认 deny-by-default 策略。

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在多网络策略应用到的命名空间中工作。

流程

  1. 创建以下 YAML,以定义 deny-by-default 策略,以拒绝所有命名空间中的所有 pod 的入口流量。将 YAML 保存到 deny-by-default.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1beta1
    kind: MultiNetworkPolicy
    metadata:
      name: deny-by-default
      namespace: default 
    1
    
      annotations:
        k8s.v1.cni.cncf.io/policy-for: <network_name> 
    2
    
    spec:
      podSelector: {} 
    3
    
      ingress: [] 
    4
    1
    namespace:default 将此策略部署到 default 命名空间。
    2
    network_name :指定一个网络附加定义的名称。
    3
    podSelector: 为空,这意味着它与所有 pod 匹配。因此,该策略适用于 default 命名空间中的所有 pod。
    4
    没有指定 ingress 规则。这会导致传入的流量丢弃至所有 pod。
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f deny-by-default.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    multinetworkpolicy.k8s.cni.cncf.io/deny-by-default created

21.4.3.7. 创建多网络策略以允许来自外部客户端的流量

使用 deny-by-default 策略,您可以继续配置策略,允许从外部客户端到带有标签 app=web 的 pod 的流量。

注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

按照以下步骤配置策略,以直接从公共互联网允许外部服务,或使用 Load Balancer 访问 pod。只有具有标签 app=web 的 pod 才允许流量。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在多网络策略应用到的命名空间中工作。

流程

  1. 创建策略,以直接从公共互联网的流量或使用负载均衡器访问 pod。将 YAML 保存到 web-allow-external.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1beta1
    kind: MultiNetworkPolicy
    metadata:
      name: web-allow-external
      namespace: default
      annotations:
        k8s.v1.cni.cncf.io/policy-for: <network_name>
    spec:
      policyTypes:
      - Ingress
      podSelector:
        matchLabels:
          app: web
      ingress:
        - {}
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-external.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    multinetworkpolicy.k8s.cni.cncf.io/web-allow-external created

此策略允许来自所有资源的流量,包括下图所示的外部流量:

允许来自外部客户端的流量
21.4.3.8. 创建一个多网络策略,允许从所有命名空间中到应用程序的流量
注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

按照以下步骤配置允许从所有命名空间中的所有 pod 流量到特定应用程序的策略。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在多网络策略应用到的命名空间中工作。

流程

  1. 创建一个策略,允许从所有命名空间中的所有 pod 流量到特定应用。将 YAML 保存到 web-allow-all-namespaces.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1beta1
    kind: MultiNetworkPolicy
    metadata:
      name: web-allow-all-namespaces
      namespace: default
      annotations:
        k8s.v1.cni.cncf.io/policy-for: <network_name>
    spec:
      podSelector:
        matchLabels:
          app: web 
    1
    
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector: {} 
    2
    1
    仅将策略应用到 default 命名空间中的 app:web pod。
    2
    选择所有命名空间中的所有 pod。
    注意

    默认情况下,如果您省略了指定 namespaceSelector 而不是选择任何命名空间,这意味着策略只允许从网络策略部署到的命名空间的流量。

  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-all-namespaces.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    multinetworkpolicy.k8s.cni.cncf.io/web-allow-all-namespaces created

验证

  1. 输入以下命令在 default 命名空间中启动 web 服务:

    Copy to Clipboard Toggle word wrap
    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 运行以下命令在 secondary 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-$RANDOM --namespace=secondary --rm -i -t --image=alpine -- sh
  3. 在 shell 中运行以下命令,并观察是否允许请求:

    Copy to Clipboard Toggle word wrap
    # wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

21.4.3.9. 创建多网络策略允许从命名空间中到应用程序的流量
注意

如果使用具有 cluster-admin 角色的用户登录,则可以在集群中的任何命名空间中创建网络策略。

按照以下步骤配置允许从特定命名空间中到带有 app=web 标签的 pod 的策略。您可能需要进行以下操作:

  • 将流量限制为部署生产工作负载的命名空间。
  • 启用部署到特定命名空间的监控工具,以从当前命名空间中提取指标。

前提条件

  • 集群使用支持 NetworkPolicy 对象的网络插件,如设置了 mode: NetworkPolicy 的 OpenShift SDN 网络供应商。此模式是 OpenShift SDN 的默认模式。
  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您在多网络策略应用到的命名空间中工作。

流程

  1. 创建一个策略,允许来自特定命名空间中所有 pod 的流量,其标签为 purpose=production。将 YAML 保存到 web-allow-prod.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: k8s.cni.cncf.io/v1beta1
    kind: MultiNetworkPolicy
    metadata:
      name: web-allow-prod
      namespace: default
      annotations:
        k8s.v1.cni.cncf.io/policy-for: <network_name>
    spec:
      podSelector:
        matchLabels:
          app: web 
    1
    
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              purpose: production 
    2
    1
    仅将策略应用到 default 命名空间中的 app:web pod。
    2
    将流量仅限制为具有标签 purpose=production 的命名空间中的 pod。
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-prod.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    multinetworkpolicy.k8s.cni.cncf.io/web-allow-prod created

验证

  1. 输入以下命令在 default 命名空间中启动 web 服务:

    Copy to Clipboard Toggle word wrap
    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 运行以下命令来创建 prod 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace prod
  3. 运行以下命令来标记 prod 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc label namespace/prod purpose=production
  4. 运行以下命令来创建 dev 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace dev
  5. 运行以下命令来标记 dev 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc label namespace/dev purpose=testing
  6. 运行以下命令在 dev 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-$RANDOM --namespace=dev --rm -i -t --image=alpine -- sh
  7. 在 shell 中运行以下命令,并观察请求是否被阻止:

    Copy to Clipboard Toggle word wrap
    # wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    wget: download timed out

  8. 运行以下命令,在 prod 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-$RANDOM --namespace=prod --rm -i -t --image=alpine -- sh
  9. 在 shell 中运行以下命令,并观察是否允许请求:

    Copy to Clipboard Toggle word wrap
    # wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

21.4.4. 其他资源

21.5. 将 pod 附加到额外网络

作为集群用户,您可以将 pod 附加到额外网络。

21.5.1. 将 pod 添加到额外网络

您可以将 pod 添加到额外网络。pod 继续通过默认网络发送与集群相关的普通网络流量。

创建 pod 时会附加额外网络。但是,如果 pod 已存在,您无法为其附加额外网络。

pod 必须与额外网络处于相同的命名空间。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 登录到集群。

流程

  1. Pod 对象添加注解。只能使用以下注解格式之一:

    1. 要在没有自定义的情况下附加额外网络,请使用以下格式添加注解。将 <network> 替换为要与 pod 关联的额外网络的名称:

      Copy to Clipboard Toggle word wrap
      metadata:
        annotations:
          k8s.v1.cni.cncf.io/networks: <network>[,<network>,...] 
      1
      1
      要指定多个额外网络,请使用逗号分隔各个网络。逗号之间不可包括空格。如果您多次指定同一额外网络,则该 pod 会将多个网络接口附加到该网络。
    2. 要通过自定义来附加额外网络,请添加具有以下格式的注解:

      Copy to Clipboard Toggle word wrap
      metadata:
        annotations:
          k8s.v1.cni.cncf.io/networks: |-
            [
              {
                "name": "<network>", 
      1
      
                "namespace": "<namespace>", 
      2
      
                "default-route": ["<default-route>"] 
      3
      
              }
            ]
      1
      指定 NetworkAttachmentDefinition 对象定义的额外网络的名称。
      2
      指定定义 NetworkAttachmentDefinition 对象的命名空间。
      3
      可选:为默认路由指定覆盖,如 192.168.17.1
  2. 运行以下命令来创建 pod。将 <name> 替换为 pod 的名称。

    Copy to Clipboard Toggle word wrap
    $ oc create -f <name>.yaml
  3. 可选: 要确认 Pod CR 中是否存在注解,请输入以下命令将 <name> 替换为 pod 的名称。

    Copy to Clipboard Toggle word wrap
    $ oc get pod <name> -o yaml

    在以下示例中,example-pod pod 附加到 net1 额外网络:

    Copy to Clipboard Toggle word wrap
    $ oc get pod example-pod -o yaml
    apiVersion: v1
    kind: Pod
    metadata:
      annotations:
        k8s.v1.cni.cncf.io/networks: macvlan-bridge
        k8s.v1.cni.cncf.io/networks-status: |- 
    1
    
          [{
              "name": "openshift-sdn",
              "interface": "eth0",
              "ips": [
                  "10.128.2.14"
              ],
              "default": true,
              "dns": {}
          },{
              "name": "macvlan-bridge",
              "interface": "net1",
              "ips": [
                  "20.2.2.100"
              ],
              "mac": "22:2f:60:a5:f8:00",
              "dns": {}
          }]
      name: example-pod
      namespace: default
    spec:
      ...
    status:
      ...
    1
    k8s.v1.cni.cncf.io/networks-status 参数是对象的 JSON 数组。每个对象描述附加到 pod 的额外网络的状态。注解值保存为纯文本值。
21.5.1.1. 指定特定于 pod 的地址和路由选项

将 pod 附加到额外网络时,您可能需要在特定 pod 中指定有关该网络的其他属性。这可让您更改路由的某些方面,并指定静态 IP 地址和 MAC 地址。要达到此目的,您可以使用 JSON 格式的注解。

先决条件

  • pod 必须与额外网络处于相同的命名空间。
  • 安装 OpenShift CLI (oc) 。
  • 您必须登录集群。

流程

要在指定地址和/或路由选项的同时将 pod 添加到额外网络,请完成以下步骤:

  1. 编辑 Pod 资源定义。如果要编辑现有 Pod 资源,请运行以下命令在默认编辑器中编辑其定义。将 <name> 替换为要编辑的 Pod 资源的名称。

    Copy to Clipboard Toggle word wrap
    $ oc edit pod <name>
  2. Pod 资源定义中,将 k8s.v1.cni.cncf.io/networks 参数添加到 pod 元数据 映射中。k8s.v1.cni.cncf.io/networks 接受一个 JSON 字符串,该字符串除指定附加属性外,还引用 NetworkAttachmentDefinition 自定义资源(CR) 名称的对象。

    Copy to Clipboard Toggle word wrap
    metadata:
      annotations:
        k8s.v1.cni.cncf.io/networks: '[<network>[,<network>,...]]' 
    1
    1
    <network> 替换为 JSON 对象,如下例所示。单引号是必需的。
  3. 在以下示例中,通过 default-route 参数,注解指定了哪个网络附加将使用默认路由。

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: example-pod
      annotations:
        k8s.v1.cni.cncf.io/networks: '[
        {
          "name": "net1"
        },
        {
          "name": "net2", 
    1
    
          "default-route": ["192.0.2.1"] 
    2
    
        }]'
    spec:
      containers:
      - name: example-pod
        command: ["/bin/bash", "-c", "sleep 2000000000000"]
        image: centos/tools
    1
    name 是与 pod 关联的额外网络的名称。
    2
    default-route 指定了一个网关,当在路由表中没有其它路由条目时使用这个网关。如果指定了多个 default-route 键,这将导致 pod 无法成为活跃状态。

默认路由将导致任何没有在其它路由中指定的流量被路由到网关。

重要

将 OpenShift Container Platform 的默认路由设置为默认网络接口以外的接口时,可能会导致应该是 pod 和 pod 间的网络流量被路由到其他接口。

要验证 pod 的路由属性,可使用 oc 命令在 pod 中执行 ip 命令。

Copy to Clipboard Toggle word wrap
$ oc exec -it <pod_name> -- ip route
注意

您还可以引用 pod 的 k8s.v1.cni.cncf.io/networks-status 来查看哪个额外网络已经分配了默认路由,这可以通过 JSON 格式的对象列表中的 default-route 键实现。

要为 pod 设置静态 IP 地址或 MAC 地址,您可以使用 JSON 格式的注解。这要求您创建允许此功能的网络。这可以在 CNO 的 rawCNIConfig 中指定。

  1. 运行以下命令来编辑 CNO CR:

    Copy to Clipboard Toggle word wrap
    $ oc edit networks.operator.openshift.io cluster

以下 YAML 描述了 CNO 的配置参数:

Cluster Network Operator YAML 配置

Copy to Clipboard Toggle word wrap
name: <name> 
1

namespace: <namespace> 
2

rawCNIConfig: '{ 
3

  ...
}'
type: Raw

1
为您要创建的额外网络附加指定名称。名称在指定的命名空间中必须是唯一的。
2
指定要在其中创建网络附加的命名空间。如果您未指定值,则使用 default 命名空间。
3
基于以下模板,以 JSON 格式指定 CNI 插件配置。

以下对象描述了使用 macvlan CNI 插件的静态 MAC 地址和 IP 地址的配置参数:

使用静态 IP 和 MAC 地址的 macvlan CNI 插件 JSON 配置对象

Copy to Clipboard Toggle word wrap
{
  "cniVersion": "0.3.1",
  "name": "<name>", 
1

  "plugins": [{ 
2

      "type": "macvlan",
      "capabilities": { "ips": true }, 
3

      "master": "eth0", 
4

      "mode": "bridge",
      "ipam": {
        "type": "static"
      }
    }, {
      "capabilities": { "mac": true }, 
5

      "type": "tuning"
    }]
}

1
指定要创建的额外网络附加的名称。名称在指定的命名空间中必须是唯一的。
2
指定 CNI 插件配置的数组。第一个对象指定 macvlan 插件配置,第二个对象指定 tuning 插件配置。
3
指定一个请求启用 CNI 插件运行时配置功能的静态 IP 地址功能。
4
指定 macvlan 插件使用的接口。
5
指定一个请求启用 CNI 插件的静态 MAC 地址功能。

以上网络附加可能会以 JSON 格式的注解引用,同时使用相关的键来指定将哪些静态 IP 和 MAC 地址分配给指定 pod。

使用以下内容编辑 pod:

Copy to Clipboard Toggle word wrap
$ oc edit pod <name>

使用静态 IP 和 MAC 地址的 macvlan CNI 插件 JSON 配置对象

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  annotations:
    k8s.v1.cni.cncf.io/networks: '[
      {
        "name": "<name>", 
1

        "ips": [ "192.0.2.205/24" ], 
2

        "mac": "CA:FE:C0:FF:EE:00" 
3

      }
    ]'

1
使用在创建 rawCNIConfig 时提供的 <name>
2
提供包括子网掩码的 IP 地址。
3
提供 MAC 地址。
注意

静态 IP 地址和 MAC 地址不需要同时使用,您可以单独使用,也可以一起使用。

要验证一个带有额外网络的 pod 的 IP 地址和 MAC 属性,请使用 oc 命令在 pod 中执行 ip 命令。

Copy to Clipboard Toggle word wrap
$ oc exec -it <pod_name> -- ip a

21.6. 从额外网络中删除 pod

作为集群用户,您可以从额外网络中删除 pod。

21.6.1. 从额外网络中删除 pod

您只能通过删除 pod 来从额外网络中删除 pod。

先决条件

  • 一个额外网络被附加到 pod。
  • 安装 OpenShift CLI (oc) 。
  • 登录到集群。

流程

  • 要删除 pod,输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc delete pod <name> -n <namespace>
    • <name> 是 pod 的名称。
    • <namespace> 是包含 pod 的命名空间。

21.7. 编辑额外网络

作为集群管理员,您可以修改现有额外网络的配置。

21.7.1. 修改额外网络附加定义

作为集群管理员,您可以对现有额外网络进行更改。任何附加到额外网络的现有 pod 都不会被更新。

先决条件

  • 已为集群配置了额外网络。
  • 安装 OpenShift CLI (oc) 。
  • 以具有 cluster-admin 权限的用户身份登录。

流程

要为集群编辑额外网络,请完成以下步骤:

  1. 运行以下命令,在默认文本编辑器中编辑 Cluster Network Operator (CNO) CR:

    Copy to Clipboard Toggle word wrap
    $ oc edit networks.operator.openshift.io cluster
  2. additionalNetworks 集合中,用您的更改更新额外网络。
  3. 保存您的更改,再退出文本编辑器以提交更改。
  4. 可选:运行以下命令确认 CNO 更新了 NetworkAttachmentDefinition 对象。将 <network-name> 替换为要显示的额外网络名称。CNO 根据您的更改更新 NetworkAttachmentDefinition 对象前可能会有延迟。

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions <network-name> -o yaml

    例如,以下控制台输出显示名为 net1NetworkAttachmentDefinition 对象:

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions net1 -o go-template='{{printf "%s\n" .spec.config}}'
    { "cniVersion": "0.3.1", "type": "macvlan",
    "master": "ens5",
    "mode": "bridge",
    "ipam":       {"type":"static","routes":[{"dst":"0.0.0.0/0","gw":"10.128.2.1"}],"addresses":[{"address":"10.128.2.100/23","gateway":"10.128.2.1"}],"dns":{"nameservers":["172.30.0.10"],"domain":"us-west-2.compute.internal","search":["us-west-2.compute.internal"]}} }

21.8. 删除额外网络

作为集群管理员,您可以删除额外网络附加。

21.8.1. 删除额外网络附加定义

作为集群管理员,您可以从 OpenShift Container Platform 集群中删除额外网络。额外网络不会从它所附加的任何 pod 中删除。

先决条件

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

流程

要从集群中删除额外网络,请完成以下步骤:

  1. 运行以下命令,在默认文本编辑器中编辑 Cluster Network Operator (CNO):

    Copy to Clipboard Toggle word wrap
    $ oc edit networks.operator.openshift.io cluster
  2. 从您要删除的网络附加定义的 additionalNetworks 集合中删除配置,以此修改 CR。

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      additionalNetworks: [] 
    1
    1
    如果要删除 additionalNetworks 集合中唯一额外网络附加定义的配置映射,您必须指定一个空集合。
  3. 保存您的更改,再退出文本编辑器以提交更改。
  4. 可选:通过运行以下命令确认删除了额外网络 CR:

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definition --all-namespaces

21.9. 为 VRF 分配从属网络

作为集群管理员,您可以使用 CNI VRF 插件为虚拟路由和转发 (VRF) 域配置额外网络。此插件创建的虚拟网络与您指定的物理接口关联。

使用带有 VRF 实例的二级网络有以下优点:

工作负载隔离
通过为额外网络配置 VRF 实例来隔离工作负载流量。
提高了安全性
通过 VRF 域中的隔离网络路径启用更高的安全性。
多租户支持
通过网络分段支持每个租户的 VRF 域中唯一路由表的多租户。
注意

使用 VRF 的应用程序必须绑定到特定设备。通常的用法是在套接字中使用 SO_BINDTODEVICE 选项。SO_BINDTODEVICE 选项将套接字绑定到在传递接口名称中指定的设备,如 eth1。要使用 SO_BINDTODEVICE 选项,应用程序必须具有 CAP_NET_RAW 功能。

OpenShift Container Platform pod 不支持通过 ip vrf exec 命令使用 VRF。要使用 VRF,将应用程序直接绑定到 VRF 接口。

21.9.1. 使用 CNI VRF 插件创建额外网络附加

Cluster Network Operator (CNO) 管理额外网络定义。当您指定要创建的额外网络时,CNO 会自动创建 NetworkAttachmentDefinition 自定义资源(CR)。

注意

请勿编辑 Cluster Network Operator 所管理的 NetworkAttachmentDefinition CR。这样做可能会破坏额外网络上的网络流量。

要使用 CNI VRF 插件创建额外网络附加,请执行以下步骤。

先决条件

  • 安装 OpenShift Container Platform CLI(oc)。
  • 以具有 cluster-admin 权限的用户身份登录 OpenShift 集群。

流程

  1. 为额外网络附加创建 Network 自定义资源 (CR),并为额外网络插入 rawCNIConfig 配置,如下例所示。将 YAML 保存为文件 additional-network-attachment.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      additionalNetworks:
        - name: test-network-1
          namespace: additional-network-1
          type: Raw
          rawCNIConfig: '{
            "cniVersion": "0.3.1",
            "name": "macvlan-vrf",
            "plugins": [  
    1
    
            {
              "type": "macvlan",
              "master": "eth1",
              "ipam": {
                  "type": "static",
                  "addresses": [
                  {
                      "address": "191.168.1.23/24"
                  }
                  ]
              }
            },
            {
              "type": "vrf", 
    2
    
              "vrfname": "vrf-1",  
    3
    
              "table": 1001   
    4
    
            }]
          }'
    1
    plugins 必须是一个列表。列表中的第一个项必须是支持 VRF 网络的从属网络。列表中的第二个项目是 VRF 插件配置。
    2
    type 必须设为 vrf
    3
    vrfname 是接口分配的 VRF 的名称。如果 pod 中不存在,则创建它。
    4
    可选。table 是路由表 ID。默认情况下使用 tableid 参数。如果没有指定,CNI 会为 VRF 分配免费路由表 ID。
    注意

    只有在资源类型为 netdevice 时,VRF 才能正常工作。

  2. 创建 Network 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f additional-network-attachment.yaml
  3. 运行以下命令确认 CNO 创建了 NetworkAttachmentDefinition CR。将 <namespace> 替换为您在配置网络附加时指定的命名空间,如 additional-network-1

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions -n <namespace>

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                       AGE
    additional-network-1       14m

    注意

    CNO 创建 CR 之前可能会有延迟。

验证

  1. 创建 pod,并使用 VRF 实例将其分配给额外网络:

    1. 创建定义 Pod 资源的 YAML 文件:

      pod-additional-net.yaml 文件示例

      Copy to Clipboard Toggle word wrap
      apiVersion: v1
      kind: Pod
      metadata:
       name: pod-additional-net
       annotations:
         k8s.v1.cni.cncf.io/networks: '[
             {
                     "name": "test-network-1" 
      1
      
             }
       ]'
      spec:
       containers:
       - name: example-pod-1
         command: ["/bin/bash", "-c", "sleep 9000000"]
         image: centos:8

      1
      使用 VRF 实例指定额外网络的名称。
    2. 运行以下命令来创建 Pod 资源:

      Copy to Clipboard Toggle word wrap
      $ oc create -f pod-additional-net.yaml

      输出示例

      Copy to Clipboard Toggle word wrap
      pod/test-pod created

  2. 验证 Pod 网络附加是否已连接到 VRF 额外网络。使用 pod 启动远程会话并运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ ip vrf show

    输出示例

    Copy to Clipboard Toggle word wrap
    Name              Table
    -----------------------
    vrf-1             1001

  3. 确认 VRF 接口是额外接口的控制器:

    Copy to Clipboard Toggle word wrap
    $ ip link

    输出示例

    Copy to Clipboard Toggle word wrap
    5: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master red state UP mode

第 22 章 硬件网络

22.1. 关于单根 I/O 虚拟化(SR-IOV)硬件网络

Single Root I/O 虚拟化 (SR-IOV) 规范是针对一类 PCI 设备分配的标准,可与多个 pod 共享单个设备。

通过 SR-IOV,您可以将主机节点上识别为物理功能 (PF) 的兼容网络设备分段为多个虚拟功能 (VF)。VF 和其它网络设备一样使用。该设备的 SR-IOV 网络设备驱动程序决定了如何公开容器中的 VF:

  • netdevice 驱动程序: 容器 netns 中的常规内核网络设备
  • vfio-pci 驱动程序: 挂载到容器中的字符设备

对于需要高带宽或低延迟的应用程序,您可以在裸机或 Red Hat OpenStack Platform(RHOSP)基础架构上安装 OpenShift Container Platform 集群上的额外网络使用 SR-IOV 网络设备。

您可以为 SR-IOV 网络配置多网络策略。对这个功能的支持是技术预览,SR-IOV 额外网络只支持内核 NIC。它们不支持 Data Plane Development Kit (DPDK) 应用程序。

注意

与 SR-IOV 网络相比,在 SR-IOV 网络中创建多网络策略可能无法为应用程序提供相同的性能。

重要

SR-IOV 网络的多网络策略只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

您可以使用以下命令在节点上启用 SR-IOV:

Copy to Clipboard Toggle word wrap
$ oc label node <node_name> feature.node.kubernetes.io/network-sriov.capable="true"

22.1.1. 负责管理 SR-IOV 网络设备的组件

SR-IOV Network Operator 会创建和管理 SR-IOV 堆栈的组件。它执行以下功能:

  • 编配 SR-IOV 网络设备的发现和管理
  • 为 SR-IOV Container Network Interface(CNI)生成 NetworkAttachmentDefinition 自定义资源
  • 创建和更新 SR-IOV 网络设备插件的配置
  • 创建节点特定的 SriovNetworkNodeState 自定义资源
  • 更新每个 SriovNetworkNodeState 自定义资源中的 spec.interfaces 字段

Operator 置备以下组件:

SR-IOV 网络配置守护进程
SR-IOV Network Operator 启动时部署在 worker 节点上的守护进程集。守护进程负责在集群中发现和初始化 SR-IOV 网络设备。
SR-IOV Network Operator Webhook
这是动态准入控制器 Webhook,用于验证 Operator 自定义资源,并为未设置的字段设置适当的默认值。
SR-IOV Network Resources Injector(网络资源注入器)
这是一个动态准入控制器 Webhook,它提供通过请求和限制为自定义网络资源(如 SR-IOV VF)应用 Kubernetes pod 规格的功能。SR-IOV 网络资源注入器只会将 resource 字段添加到 pod 中的第一个容器。
网络SR-IOV 网络设备插件
这个设备插件用于发现、公告并分配 SR-IOV 网络虚拟功能 (VF) 资源。在 Kubernetes 中使用设备插件能够利用有限的资源,这些资源通常为于物理设备中。设备插件可以使 Kubernetes 调度程序了解资源可用性,因此调度程序可以在具有足够资源的节点上调度 pod。
SR-IOV CNI 插件
SR-IOV CNI 插件会附加从 SR-IOV 网络设备插件中直接分配给 pod 的 VF 接口。
SR-IOV InfiniBand CNI 插件
附加从 SR-IOV 网络设备插件中直接分配给 pod 的 InfiniBand(IB)VF 接口的 CNI 插件。
注意

SR-IOV Network resources injector 和 SR-IOV Operator Webhook 会被默认启用,可通过编辑 default SriovOperatorConfig CR 来禁用。禁用 SR-IOV Network Operator Admission Controller Webhook 时要小心。您可以在特定情况下禁用 webhook,如故障排除,或者想要使用不支持的设备。

22.1.1.1. 支持的平台

在以下平台上支持 SR-IOV Network Operator:

  • 裸机
  • Red Hat OpenStack Platform(RHOSP)
22.1.1.2. 支持的设备

OpenShift Container Platform 支持以下网络接口控制器:

表 22.1. 支持的网络接口控制器
制造商model供应商 ID设备 ID

Broadcom

BCM57414

14e4

16d7

Broadcom

BCM57508

14e4

1750

Broadcom

BCM57504

14e4

1751

Intel

X710

8086

1572

Intel

XL710

8086

1583

Intel

X710 基本 T

8086

15ff

Intel

XXV710

8086

158b

Intel

E810-CQDA2

8086

1592

Intel

E810-2CQDA2

8086

1592

Intel

E810-XXVDA2

8086

159b

Intel

E810-XXVDA4

8086

1593

Mellanox

MT27700 系列 [ConnectX-4]

15b3

1013

Mellanox

MT27710 系列 [ConnectX-4 Lx]

15b3

1015

Mellanox

MT27800 系列 [ConnectX-5]

15b3

1017

Mellanox

MT28880 系列 [ConnectX-5 Ex]

15b3

1019

Mellanox

MT28908 系列 [ConnectX-6]

15b3

101b

Mellanox

MT2892 Family [ConnectX‑6 Dx]

15b3

101d

Mellanox

MT2894 Family [ConnectX‑6 Lx]

15b3

101f

Mellanox

ConnectX-6 NIC 模式中的 MT42822 BlueField-2

15b3

a2d6

Pensando [1]

用于 ionic 驱动程序的 DSC-25 双端口 25G 分布式服务卡

0x1dd8

0x1002

Pensando [1]

用于 ionic 驱动程序的 DSC-100 双端口 100G 分布式服务卡

0x1dd8

0x1003

Silicom

STS 系列

8086

1591

  1. 支持 OpenShift SR-IOV,但在使用 SR-IOV 时,您必须使用 SR-IOV CNI 配置文件设置静态的虚拟功能(VF)介质访问控制(MAC)地址。
注意

有关支持的卡和兼容的 OpenShift Container Platform 版本的最新列表,请参阅 Openshift Single Root I/O Virtualization(SR-IOV)和 PTP 硬件网络支持列表

22.1.1.3. 自动发现 SR-IOV 网络设备

SR-IOV Network Operator 将搜索集群以获取 worker 节点上的 SR-IOV 功能网络设备。Operator 会为每个提供兼容 SR-IOV 网络设备的 worker 节点创建并更新一个 SriovNetworkNodeState 自定义资源 (CR) 。

为 CR 分配了与 worker 节点相同的名称。status.interfaces 列表提供有关节点上网络设备的信息。

重要

不要修改 SriovNetworkNodeState 对象。Operator 会自动创建和管理这些资源。

22.1.1.3.1. SriovNetworkNodeState 对象示例

以下 YAML 是 SR-IOV Network Operator 创建的 SriovNetworkNodeState 对象示例:

一 个 SriovNetworkNodeState 对象

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodeState
metadata:
  name: node-25 
1

  namespace: openshift-sriov-network-operator
  ownerReferences:
  - apiVersion: sriovnetwork.openshift.io/v1
    blockOwnerDeletion: true
    controller: true
    kind: SriovNetworkNodePolicy
    name: default
spec:
  dpConfigVersion: "39824"
status:
  interfaces: 
2

  - deviceID: "1017"
    driver: mlx5_core
    mtu: 1500
    name: ens785f0
    pciAddress: "0000:18:00.0"
    totalvfs: 8
    vendor: 15b3
  - deviceID: "1017"
    driver: mlx5_core
    mtu: 1500
    name: ens785f1
    pciAddress: "0000:18:00.1"
    totalvfs: 8
    vendor: 15b3
  - deviceID: 158b
    driver: i40e
    mtu: 1500
    name: ens817f0
    pciAddress: 0000:81:00.0
    totalvfs: 64
    vendor: "8086"
  - deviceID: 158b
    driver: i40e
    mtu: 1500
    name: ens817f1
    pciAddress: 0000:81:00.1
    totalvfs: 64
    vendor: "8086"
  - deviceID: 158b
    driver: i40e
    mtu: 1500
    name: ens803f0
    pciAddress: 0000:86:00.0
    totalvfs: 64
    vendor: "8086"
  syncStatus: Succeeded

1
name 字段的值与 worker 节点的名称相同。
2
interfaces 小节包括 Operator 在 worker 节点上发现的所有 SR-IOV 设备列表。
22.1.1.4. 在 pod 中使用虚拟功能的示例

您可以在附加了 SR-IOV VF 的 pod 中运行远程直接内存访问 (RDMA) 或 Data Plane Development Kit (DPDK) 应用程序。

本示例演示了在 RDMA 模式中使用虚拟功能 (VF) 的 pod:

使用 RDMA 模式的 Pod 规格

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: rdma-app
  annotations:
    k8s.v1.cni.cncf.io/networks: sriov-rdma-mlnx
spec:
  containers:
  - name: testpmd
    image: <RDMA_image>
    imagePullPolicy: IfNotPresent
    securityContext:
      runAsUser: 0
      capabilities:
        add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"]
    command: ["sleep", "infinity"]

以下示例演示了在 DPDK 模式中使用 VF 的 pod:

使用 DPDK 模式的 Pod 规格

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: dpdk-app
  annotations:
    k8s.v1.cni.cncf.io/networks: sriov-dpdk-net
spec:
  containers:
  - name: testpmd
    image: <DPDK_image>
    securityContext:
      runAsUser: 0
      capabilities:
        add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"]
    volumeMounts:
    - mountPath: /dev/hugepages
      name: hugepage
    resources:
      limits:
        memory: "1Gi"
        cpu: "2"
        hugepages-1Gi: "4Gi"
      requests:
        memory: "1Gi"
        cpu: "2"
        hugepages-1Gi: "4Gi"
    command: ["sleep", "infinity"]
  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages

22.1.1.5. 用于容器应用程序的 DPDK 库

一个可选的库 app-netutil 提供了几个 API 方法,用于从该 pod 中运行的容器内收集 pod 的网络信息。

此库可以将 SR-IOV 虚拟功能(VF)集成到 Data Plane Development Kit(DPDK)模式中。该程序库提供 Golang API 和 C API。

当前,采用三个 API 方法:

GetCPUInfo()
此函数决定了哪些 CPU 可供容器使用并返回相关列表。
GetHugepages()
此函数决定了每个容器在 Pod spec 中请求的巨页内存量并返回相应的值。
GetInterfaces()
此函数决定了容器中的一组接口,并返回相关的列表。返回值包括每个接口的接口类型和特定于类型的数据。

库的存储库包括用于构建容器镜像 dpdk-app-centos 的示例 Dockerfile。根据 pod 规格中的环境变量,容器镜像可以运行以下 DPDK 示例应用程序之一:l2fwd, l3wdtestpmd。容器镜像提供了一个将 app-netutil 库集成到容器镜像本身的示例。库也可以集成到 init 容器中。init 容器可以收集所需的数据,并将数据传递给现有的 DPDK 工作负载。

22.1.1.6. Downward API 的巨页资源注入

当 pod 规格包含巨页的资源请求或限制时,Network Resources Injector 会自动在 pod 规格中添加 Downward API 字段,以便为容器提供巨页信息。

Network Resources Injector 添加一个名为 podnetinfo 的卷,并挂载到 pod 中的每个容器的 /etc/podnetinfo。卷使用 Downward API,并包含一个用于大页面请求和限制的文件。文件命名规则如下:

  • /etc/podnetinfo/hugepages_1G_request_<container-name>
  • /etc/podnetinfo/hugepages_1G_limit_<container-name>
  • /etc/podnetinfo/hugepages_2M_request_<container-name>
  • /etc/podnetinfo/hugepages_2M_limit_<container-name>

上一个列表中指定的路径与 app-netutil 库兼容。默认情况下,库配置为搜索 /etc/podnetinfo 目录中的资源信息。如果您选择自己手动指定 Downward API 路径项目,app-netutil 库除上列表中的路径外还会搜索以下路径。

  • /etc/podnetinfo/hugepages_request
  • /etc/podnetinfo/hugepages_limit
  • /etc/podnetinfo/hugepages_1G_request
  • /etc/podnetinfo/hugepages_1G_limit
  • /etc/podnetinfo/hugepages_2M_request
  • /etc/podnetinfo/hugepages_2M_limit

与 Network Resources Injector 可以创建的路径一样,以上列表中的路径可以选择以一个 _<container-name> 后缀结尾。

22.1.2. 其他资源

22.1.3. 后续步骤

22.2. 安装 SR-IOV Network Operator

您可以在集群上安装单根 I/O 虚拟化(SR-IOV)网络 Operator,以管理 SR-IOV 网络设备和网络附加。

22.2.1. 安装 SR-IOV Network Operator

作为集群管理员,您可以使用 OpenShift Container Platform CLI 或 web 控制台安装 SR-IOV Network Operator。

22.2.1.1. CLI:安装 SR-IOV Network Operator

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

先决条件

  • 在裸机环境中安装的集群,其中的节点带有支持 SR-IOV 的硬件。
  • 安装 OpenShift CLI (oc) 。
  • 具有 cluster-admin 权限的帐户。

流程

  1. 运行以下命令来创建 openshift-sriov-network-operator 命名空间:

    Copy to Clipboard Toggle word wrap
    $ cat << EOF| oc create -f -
    apiVersion: v1
    kind: Namespace
    metadata:
      name: openshift-sriov-network-operator
      annotations:
        workload.openshift.io/allowed: management
    EOF
  2. 运行以下命令来创建 OperatorGroup CR:

    Copy to Clipboard Toggle word wrap
    $ cat << EOF| oc create -f -
    apiVersion: operators.coreos.com/v1
    kind: OperatorGroup
    metadata:
      name: sriov-network-operators
      namespace: openshift-sriov-network-operator
    spec:
      targetNamespaces:
      - openshift-sriov-network-operator
    EOF
  3. 订阅 SR-IOV Network Operator。

    1. 运行以下命令以获取 OpenShift Container Platform 的主版本和次版本。下一步中需要 channel 值。

      Copy to Clipboard Toggle word wrap
      $ OC_VERSION=$(oc version -o yaml | grep openshiftVersion | \
          grep -o '[0-9]*[.][0-9]*' | head -1)
    2. 要为 SR-IOV Network Operator 创建 Subscription CR,输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ cat << EOF| oc create -f -
      apiVersion: operators.coreos.com/v1alpha1
      kind: Subscription
      metadata:
        name: sriov-network-operator-subscription
        namespace: openshift-sriov-network-operator
      spec:
        channel: "${OC_VERSION}"
        name: sriov-network-operator
        source: redhat-operators
        sourceNamespace: openshift-marketplace
      EOF
  4. 要验证是否已安装 Operator,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get csv -n openshift-sriov-network-operator \
      -o custom-columns=Name:.metadata.name,Phase:.status.phase

    输出示例

    Copy to Clipboard Toggle word wrap
    Name                                         Phase
    sriov-network-operator.4.12.0-202310121402   Succeeded

22.2.1.2. web 控制台:安装 SR-IOV Network Operator

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

先决条件

  • 在裸机环境中安装的集群,其中的节点带有支持 SR-IOV 的硬件。
  • 安装 OpenShift CLI (oc) 。
  • 具有 cluster-admin 权限的帐户。

流程

  1. 安装 SR-IOV Network Operator:

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

    1. 进入到 OperatorsInstalled Operators 页面。
    2. 确保 SR-IOV Network Operatoropenshift-sriov-network-operator 项目中列出,StatusInstallSucceeded

      注意

      在安装过程中,Operator 可能会显示 Failed 状态。如果以后安装成功并显示 InstallSucceeded 信息,您可以忽略 Failed 信息。

      如果 Operator 没有被成功安装,请按照以下步骤进行故障排除:

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

        Copy to Clipboard Toggle word wrap
        $ oc annotate ns/openshift-sriov-network-operator workload.openshift.io/allowed=management
        注意

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

22.2.2. 后续步骤

22.3. 配置 SR-IOV Network Operator

Single Root I/O Virtualization(SR-IOV)Network Operator 管理集群中的 SR-IOV 网络设备和网络附加。

22.3.1. 配置 SR-IOV Network Operator

重要

通常不需要修改 SR-IOV Network Operator 配置。我们推荐在大多数用例中使用默认配置。只有 Operator 的默认行为与您的用例不兼容时,才需要按照以下步骤修改相关配置。

SR-IOV Network Operator 添加了 SriovOperatorConfig.sriovnetwork.openshift.io CustomResourceDefinition 资源。Operator 会在 openshift-sriov-network-operator 命名空间中自动创建一个名为 default 的 SriovOperatorConfig 自定义资源 (CR)。

注意

default CR 包含集群的 SR-IOV Network Operator 配置。要更改 Operator 配置,您必须修改此 CR。

22.3.1.1. SR-IOV Network Operator 配置自定义资源

sriovoperatorconfig 自定义资源的字段在下表中描述:

表 22.2. SR-IOV Network Operator 配置自定义资源
字段类型描述

metadata.name

string

指定 SR-IOV Network Operator 实例的名称。默认值为 default。不要设置不同的值。

metadata.namespace

string

指定 SR-IOV Network Operator 实例的命名空间。默认值为 openshift-sriov-network-operator。不要设置不同的值。

spec.configDaemonNodeSelector

string

指定在所选节点上调度 SR-IOV 网络配置守护进程的节点选择。默认情况下,此字段没有设置,Operator 会在 worker 节点上部署 SR-IOV 网络配置守护进程集。

spec.disableDrain

布尔值

指定是否禁用节点排空过程,或者在应用新策略在节点上配置 NIC 时启用节点排空过程。将此字段设置为 true 可促进软件开发,并在单一节点上安装 OpenShift Container Platform。默认情况下不设置此字段。

对于单节点集群,在安装 Operator 后将此字段设置为 true。此字段必须保持设为 true

spec.enableInjector

布尔值

指定是否启用或禁用 Network Resources Injector 守护进程集。默认情况下,此字段设置为 true

spec.enableOperatorWebhook

布尔值

指定是否启用或禁用 Operator Admission Controller webhook 守护进程集。

spec.logLevel

整数

指定 Operator 的日志详细程度。默认情况下,此字段设置为 0,它只显示基本日志。设置为 2,以显示所有可用的日志。

22.3.1.2. 关于 Network Resources Injector(网络资源注入器)

Network Resources Injector 是一个 Kubernetes Dynamic Admission Controller 应用。它提供以下功能:

  • 根据 SR-IOV 网络附加定义注解,对 Pod 规格中的资源请求和限值进行修改,以添加 SR-IOV 资源名称。
  • 使用 Downward API 卷修改 pod 规格,以公开 pod 注解、标签和巨页请求和限制。在 pod 中运行的容器可以作为 /etc/podnetinfo 路径下的文件来访问公开的信息。

默认情况下,Network Resources Injector 由 SR-IOV Network Operator 启用,并作为守护进程集在所有 control plane 节点上运行。以下是在具有三个 control plane 节点的集群中运行的 Network Resources Injector pod 示例:

Copy to Clipboard Toggle word wrap
$ oc get pods -n openshift-sriov-network-operator

输出示例

Copy to Clipboard Toggle word wrap
NAME                                      READY   STATUS    RESTARTS   AGE
network-resources-injector-5cz5p          1/1     Running   0          10m
network-resources-injector-dwqpx          1/1     Running   0          10m
network-resources-injector-lktz5          1/1     Running   0          10m

22.3.1.3. 关于 SR-IOV Network Operator 准入控制器 Webhook

SR-IOV Network Operator Admission Controller Webhook 是一个 Kubernetes Dynamic Admission Controller 应用程序。它提供以下功能:

  • 在创建或更新时,验证 SriovNetworkNodePolicy CR。
  • 修改 SriovNetworkNodePolicy CR,在创建或更新 CR 时为 prioritydeviceType 项设置默认值。

默认情况下,SR-IOV Network Operator Admission Controller Webhook 由 Operator 启用,并作为守护进程集在所有 control plane 节点上运行。

注意

禁用 SR-IOV Network Operator Admission Controller Webhook 时要小心。您可以在特定情况下禁用 webhook,如故障排除,或者想要使用不支持的设备。有关配置不支持的设备的详情,请参考将 SR-IOV Network Operator 配置为使用不支持的 NIC

以下是在具有三个 control plane 节点的集群中运行的 Operator Admission Controller webhook pod 的示例:

Copy to Clipboard Toggle word wrap
$ oc get pods -n openshift-sriov-network-operator

输出示例

Copy to Clipboard Toggle word wrap
NAME                                      READY   STATUS    RESTARTS   AGE
operator-webhook-9jkw6                    1/1     Running   0          16m
operator-webhook-kbr5p                    1/1     Running   0          16m
operator-webhook-rpfrl                    1/1     Running   0          16m

22.3.1.4. 关于自定义节点选择器

SR-IOV 网络配置守护进程在集群节点上发现并配置 SR-IOV 网络设备。默认情况下,它将部署到集群中的所有 worker 节点。您可以使用节点标签指定 SR-IOV 网络配置守护进程在哪些节点上运行。

22.3.1.5. 禁用或启用网络资源注入器

要禁用或启用默认启用的网络资源注入器,请完成以下步骤。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 以具有 cluster-admin 权限的用户身份登录。
  • 您必须已安装了 SR-IOV Network Operator。

流程

  • 设置 enableInjector 字段。将 <value> 替换为 false 来禁用这个功能,或替换为 true 来启用这个功能。

    Copy to Clipboard Toggle word wrap
    $ oc patch sriovoperatorconfig default \
      --type=merge -n openshift-sriov-network-operator \
      --patch '{ "spec": { "enableInjector": <value> } }'
    提示

    您还可以应用以下 YAML 来更新 Operator:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovOperatorConfig
    metadata:
      name: default
      namespace: openshift-sriov-network-operator
    spec:
      enableInjector: <value>
22.3.1.6. 禁用或启用 SR-IOV Network Operator 准入控制器 Webhook

要禁用或启用默认启用的准入控制器 Webhook,请完成以下步骤。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 以具有 cluster-admin 权限的用户身份登录。
  • 您必须已安装了 SR-IOV Network Operator。

流程

  • 设置 enableOperatorWebhook 字段。将 <value> 替换为 false 来禁用这个功能,或替换为 true 来启用它:

    Copy to Clipboard Toggle word wrap
    $ oc patch sriovoperatorconfig default --type=merge \
      -n openshift-sriov-network-operator \
      --patch '{ "spec": { "enableOperatorWebhook": <value> } }'
    提示

    您还可以应用以下 YAML 来更新 Operator:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovOperatorConfig
    metadata:
      name: default
      namespace: openshift-sriov-network-operator
    spec:
      enableOperatorWebhook: <value>
22.3.1.7. 为 SR-IOV 网络配置守护进程配置自定义 NodeSelector

SR-IOV 网络配置守护进程在集群节点上发现并配置 SR-IOV 网络设备。默认情况下,它将部署到集群中的所有 worker 节点。您可以使用节点标签指定 SR-IOV 网络配置守护进程在哪些节点上运行。

要指定部署了 SR-IOV 网络配置守护进程的节点,请完成以下步骤。

重要

当您更新 configDaemonNodeSelector 字段时,SR-IOV 网络配置守护进程会在所选节点上重新创建。在重新创建守护进程时,集群用户无法应用任何新的 SR-IOV 网络节点策略或创建新的 SR-IOV Pod。

流程

  • 要为 Operator 更新节点选择器,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc patch sriovoperatorconfig default --type=json \
      -n openshift-sriov-network-operator \
      --patch '[{
          "op": "replace",
          "path": "/spec/configDaemonNodeSelector",
          "value": {<node_label>}
        }]'

    <node_label> 替换为要应用的标签,如下例中:"node-role.kubernetes.io/worker": ""

    提示

    您还可以应用以下 YAML 来更新 Operator:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovOperatorConfig
    metadata:
      name: default
      namespace: openshift-sriov-network-operator
    spec:
      configDaemonNodeSelector:
        <node_label>
22.3.1.8. 为单一节点安装配置 SR-IOV Network Operator

默认情况下,SR-IOV Network Operator 会在每次策略更改前从节点排空工作负载。Operator 会执行这个操作,以确保在重新配置前没有使用虚拟功能的工作负载。

对于在单一节点上安装,没有其他节点来接收工作负载。因此,Operator 不得配置为从单一节点排空工作负载。

重要

执行以下步骤禁用排空工作负载后,您必须删除所有使用 SR-IOV 网络接口的工作负载,然后才能更改任何 SR-IOV 网络节点策略。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 以具有 cluster-admin 权限的用户身份登录。
  • 您必须已安装了 SR-IOV Network Operator。

流程

  • 要将 disableDrain 字段设置为 true,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc patch sriovoperatorconfig default --type=merge \
      -n openshift-sriov-network-operator \
      --patch '{ "spec": { "disableDrain": true } }'
    提示

    您还可以应用以下 YAML 来更新 Operator:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovOperatorConfig
    metadata:
      name: default
      namespace: openshift-sriov-network-operator
    spec:
      disableDrain: true
22.3.1.9. 为托管 control plane 部署 SR-IOV Operator
重要

托管的 control plane 只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

配置和部署托管服务集群后,您可以在托管集群中创建 SR-IOV Operator 订阅。SR-IOV pod 在 worker 机器上运行而不是在 control plane 上运行。

先决条件

您已配置并部署了托管集群。

流程

  1. 创建命名空间和 Operator 组:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Namespace
    metadata:
      name: openshift-sriov-network-operator
    ---
    apiVersion: operators.coreos.com/v1
    kind: OperatorGroup
    metadata:
      name: sriov-network-operators
      namespace: openshift-sriov-network-operator
    spec:
      targetNamespaces:
      - openshift-sriov-network-operator
  2. 创建 SR-IOV Operator 的订阅:

    Copy to Clipboard Toggle word wrap
    apiVersion: operators.coreos.com/v1alpha1
    kind: Subscription
    metadata:
      name: sriov-network-operator-subsription
      namespace: openshift-sriov-network-operator
    spec:
      channel: "4.12"
      name: sriov-network-operator
      config:
        nodeSelector:
          node-role.kubernetes.io/worker: ""
      source: s/qe-app-registry/redhat-operators
      sourceNamespace: openshift-marketplace

验证

  1. 要验证 SR-IOV Operator 是否已就绪,请运行以下命令并查看生成的输出:

    Copy to Clipboard Toggle word wrap
    $ oc get csv -n openshift-sriov-network-operator

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                         DISPLAY                   VERSION               REPLACES                                     PHASE
    sriov-network-operator.4.12.0-202211021237   SR-IOV Network Operator   4.12.0-202211021237   sriov-network-operator.4.12.0-202210290517   Succeeded

  2. 要验证 SR-IOV pod 是否已部署,请运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-sriov-network-operator

22.3.2. 后续步骤

22.4. 配置 SR-IOV 网络设备

您可以在集群中配置单一根 I/O 虚拟化(SR-IOV)设备。

22.4.1. SR-IOV 网络节点配置对象

您可以通过创建 SR-IOV 网络节点策略来为节点指定 SR-IOV 网络设备配置。策略的 API 对象是 sriovnetwork.openshift.io API 组的一部分。

以下 YAML 描述了 SR-IOV 网络节点策略:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: <name> 
1

  namespace: openshift-sriov-network-operator 
2

spec:
  resourceName: <sriov_resource_name> 
3

  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true" 
4

  priority: <priority> 
5

  mtu: <mtu> 
6

  needVhostNet: false 
7

  numVfs: <num> 
8

  nicSelector: 
9

    vendor: "<vendor_code>" 
10

    deviceID: "<device_id>" 
11

    pfNames: ["<pf_name>", ...] 
12

    rootDevices: ["<pci_bus_id>", ...] 
13

    netFilter: "<filter_string>" 
14

  deviceType: <device_type> 
15

  isRdma: false 
16

  linkType: <link_type> 
17

  eSwitchMode: <mode> 
18
1
自定义资源对象的名称。
2
安装 SR-IOV Network Operator 的命名空间。
3
SR-IOV 网络设备插件的资源名称。您可以为资源名称创建多个 SR-IOV 网络节点策略。

在指定名称时,请确保在 resourceName 中使用接受的语法表达式 ^[a-zA-Z0-9_]+$

4
节点选择器指定要配置的节点。只有所选节点上的 SR-IOV 网络设备才会被配置。SR-IOV Container Network Interface(CNI)插件和设备插件仅在所选节点上部署。
重要

SR-IOV Network Operator 按顺序将节点网络配置策略应用到节点。在应用节点网络配置策略前,SR-IOV Network Operator 会检查节点的机器配置池(MCP)是否处于不健康状态,如 DegradedUpdating。如果节点处于不健康的 MCP,将节点网络配置策略应用到集群中的所有目标节点的过程会被暂停,直到 MCP 返回健康状态。

为了避免处于不健康的 MCP 的节点阻止将节点网络配置策略应用到其他节点,包括处于其他 MCP 的节点,您必须为每个 MCP 创建单独的节点网络配置策略。

5
可选: priority(优先级)是 099 之间的整数。较小的值具有更高的优先级。例如,优先级 10 高于 99 的优先级。默认值为 99
6
可选:虚拟功能的最大传输单元(MTU)。最大 MTU 值可能因不同的网络接口控制器(NIC)型号而有所不同。
重要

如果要在默认网络接口上创建虚拟功能,请确保将 MTU 设置为与集群 MTU 匹配的值。

7
可选:将 needVhostNet 设置为 true,以在 pod 中挂载 /dev/vhost-net 设备。使用挂载的 /dev/vhost-net 设备及 Data Plane Development Kit (DPDK) 将流量转发到内核网络堆栈。
8
为 SR-IOV 物理网络设备创建的虚拟功能((VF)的数量。对于 Intel 网络接口控制器(NIC),VF 的数量不能超过该设备支持的 VF 总数。对于 Mellanox NIC,VF 的数量不能超过 127
9
NIC 选择器标识要配置的 Operator 的设备。您不必为所有参数指定值。建议您足够精确地识别网络设备以避免意外选择设备。

如果指定了rootDevices,则必须同时为 vendordeviceIDpfNames 指定一个值。如果您同时指定了 pfNamesrootDevices,请确保它们引用同一设备。如果您为 netFilter 指定一个值,则不需要指定任何其他参数,因为网络 ID 是唯一的。

10
可选: SR-IOV 网络设备的厂商十六进制代码。允许的值只能是 808615b3
11
可选: SR-IOV 网络设备的设备十六进制代码。例如: 101b 是 Mellanox ConnectX-6 设备的设备 ID。
12
可选:该设备的一个或多个物理功能(PF)名称的数组。
13
可选:用于该设备的 PF 的一个或多个 PCI 总线地址的数组。使用以下格式提供地址: 0000:02:00.1
14
可选:特定平台的网络过滤器。唯一支持的平台是 Red Hat OpenStack Platform(RHOSP)。可接受的值具有以下格式:openstack/NetworkID:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx。将 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx 替换为 /var/config/openstack/latest/network_data.json 元数据文件中的值。
15
可选:虚拟功能的驱动程序类型。允许的值只能是 netdevicevfio-pci。默认值为 netdevice

对于裸机节点上的 DPDK 模式的 Mellanox NIC,请使用 netdevice 驱动程序类型,并将 isRdma 设置为 true

16
可选:配置是否启用远程直接访问 (RDMA) 模式。默认值为 false

如果 isRdma 参数设为 true,您可以继续使用启用了 RDMA 的 VF 作为普通网络设备。设备可在其中的一个模式中使用。

isRdma 设置为 true,并将 needVhostNet 设置为 true 以配置 Mellanox NIC 以用于 Fast Datapath DPDK 应用程序。

注意

对于 intel NIC,您无法将 isRdma 参数设置为 true

17
可选:VF 的链接类型。默认值为 eth (以太网)。在 InfiniBand 中将这个值改为 'ib'。

当将 linkType 设置为 ib 时,SR-IOV Network Operator Webhook 会自动将 isRdma 设置为 true。当将 linkType 设置为 ib 时,deviceType 不应该设置为 vfio-pci

不要为 SriovNetworkNodePolicy 将 linkType 设置为 'eth',因为这可能会导致设备插件报告的可用设备数量不正确。

18
可选:NIC 设备模式。允许的值只能是 legacyswitchdev

当将 eSwitchMode 设置为 legacy 时,会启用默认的 SR-IOV 行为。

当将 eSwitchMode 设置为 switchdev 时,会启用硬件卸载。

22.4.1.1. SR-IOV 网络节点配置示例

以下示例描述了 InfiniBand 设备的配置:

InfiniBand 设备的配置示例

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-ib-net-1
  namespace: openshift-sriov-network-operator
spec:
  resourceName: ibnic1
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true"
  numVfs: 4
  nicSelector:
    vendor: "15b3"
    deviceID: "101b"
    rootDevices:
      - "0000:19:00.0"
  linkType: ib
  isRdma: true

以下示例描述了 RHOSP 虚拟机中的 SR-IOV 网络设备配置:

虚拟机中的 SR-IOV 设备配置示例

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-sriov-net-openstack-1
  namespace: openshift-sriov-network-operator
spec:
  resourceName: sriovnic1
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true"
  numVfs: 1 
1

  nicSelector:
    vendor: "15b3"
    deviceID: "101b"
    netFilter: "openstack/NetworkID:ea24bd04-8674-4f69-b0ee-fa0b3bd20509" 
2

1
在为虚拟机配置节点网络策略时,numVfs 字段始终设置为 1
2
当虚拟机在 RHOSP 上部署时,netFilter 字段必须引用网络 ID。netFilter 的有效值可从 SriovNetworkNodeState 对象获得。
22.4.1.2. SR-IOV 设备的虚拟功能 (VF) 分区

在某些情况下,您可能想要将同一个物理功能 (PF) 的虚拟功能 (VF) 分成多个资源池。例如,您可能希望某些 VF 使用默认驱动程序加载,剩余的 VF 负载使用 vfio-pci 驱动程序。在这种情况下,您的 SriovNetworkNodePolicy 自定义资源(CR) 中的 pfNames 选择器可以用来使用以下格式为池指定 VF 范围:<pfname>#<first_vf>-<last_vf>

例如,以下 YAML 显示名为 netpf0 的、带有 VF 27 的接口的选择器:

Copy to Clipboard Toggle word wrap
pfNames: ["netpf0#2-7"]
  • netpf0 是 PF 接口名称。
  • 2 是包含在范围内的第一个 VF 索引(基于 0)。
  • 7 是包含在范围内的最后一个 VF 索引(基于 0)。

如果满足以下要求,您可以使用不同的策略 CR 从同一 PF 中选择 VF:

  • 选择相同 PF 的不同策略的 numVfs 值必须相同。
  • VF 索引范围是从 0<numVfs>-1 之间。例如,如果您有一个策略,numVfs 设置为 8,则 <first_vf> 的值不能小于 0<last_vf> 不得大于 7
  • 不同策略中的 VF 范围不得互相重叠。
  • <first_vf> 不能大于 <last_vf>

以下示例演示了 SR-IOV 设备的 NIC 分区。

策略 policy-net-1 定义了一个资源池 net-1,其中包含带有默认 VF 驱动的 PF netpf0 的 VF 0 。策略 policy-net-1-dpdk 定义了一个资源池 net-1-dpdk,其中包含带有 vfio VF 驱动程序的 PF netpf0 的 VF 815

策略 policy-net-1

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-net-1
  namespace: openshift-sriov-network-operator
spec:
  resourceName: net1
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true"
  numVfs: 16
  nicSelector:
    pfNames: ["netpf0#0-0"]
  deviceType: netdevice

策略 policy-net-1-dpdk:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: policy-net-1-dpdk
  namespace: openshift-sriov-network-operator
spec:
  resourceName: net1dpdk
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: "true"
  numVfs: 16
  nicSelector:
    pfNames: ["netpf0#8-15"]
  deviceType: vfio-pci

验证接口是否已成功分区

运行以下命令,确认 SR-IOV 设备的接口分区到虚拟功能(VF)。

Copy to Clipboard Toggle word wrap
$ ip link show <interface> 
1
1
<interface> 替换为您在分区为 SR-IOV 设备的 VF 时指定的接口,如 ens3f1

输出示例

Copy to Clipboard Toggle word wrap
5: ens3f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 3c:fd:fe:d1:bc:01 brd ff:ff:ff:ff:ff:ff

vf 0     link/ether 5a:e7:88:25:ea:a0 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
vf 1     link/ether 3e:1d:36:d7:3d:49 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
vf 2     link/ether ce:09:56:97:df:f9 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
vf 3     link/ether 5e:91:cf:88:d1:38 brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off
vf 4     link/ether e6:06:a1:96:2f:de brd ff:ff:ff:ff:ff:ff, spoof checking on, link-state auto, trust off

22.4.2. 配置 SR-IOV 网络设备

SR-IOV Network Operator 把 SriovNetworkNodePolicy.sriovnetwork.openshift.io CRD 添加到 OpenShift Container Platform。您可以通过创建一个 SriovNetworkNodePolicy 自定义资源 (CR) 来配置 SR-IOV 网络设备。

注意

当应用由 SriovNetworkNodePolicy 对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。

它可能需要几分钟时间来应用配置更改。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 已安装 SR-IOV Network Operator。
  • 集群中有足够的可用节点,用于处理从排空节点中驱除的工作负载。
  • 您还没有为 SR-IOV 网络设备配置选择任何 control plane 节点。

流程

  1. 创建一个 SriovNetworkNodePolicy 对象,然后在 <name>-sriov-node-network.yaml 文件中保存 YAML。将 <name> 替换为此配置的名称。
  2. 可选:将 SR-IOV 功能的集群节点标记为 SriovNetworkNodePolicy.Spec.NodeSelector (如果它们还没有标记)。有关标记节点的更多信息,请参阅"了解如何更新节点上的标签"。
  3. 创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f <name>-sriov-node-network.yaml

    其中 <name> 指定此配置的名称。

    在应用配置更新后,sriov-network-operator 命名空间中的所有 Pod 都会变为 Running 状态。

  4. 要验证是否已配置了 SR-IOV 网络设备,请输入以下命令。将 <node_name> 替换为带有您刚才配置的 SR-IOV 网络设备的节点名称。

    Copy to Clipboard Toggle word wrap
    $ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name> -o jsonpath='{.status.syncStatus}'

22.4.3. SR-IOV 配置故障排除

在进行了配置 SR-IOV 网络设备的步骤后,以下部分会处理一些错误条件。

要显示节点状态,请运行以下命令:

Copy to Clipboard Toggle word wrap
$ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name>

其中: <node_name> 指定带有 SR-IOV 网络设备的节点名称。

错误输出: 无法分配内存

Copy to Clipboard Toggle word wrap
"lastSyncError": "write /sys/bus/pci/devices/0000:3b:00.1/sriov_numvfs: cannot allocate memory"

当节点表示无法分配内存时,检查以下项目:

  • 确认在 BIOS 中为节点启用了全局 SR-IOV 设置。
  • 确认在 BIOS 中为该节点启用了 VT-d。

22.4.4. 将 SR-IOV 网络分配给 VRF

作为集群管理员,您可以使用 CNI VRF 插件为 VRF 域分配 SR-IOV 网络接口。

要做到这一点,将 VRF 配置添加到 SriovNetwork 资源的可选 metaPlugins 参数中。

注意

使用 VRF 的应用程序需要绑定到特定设备。通常的用法是在套接字中使用 SO_BINDTODEVICE 选项。SO_BINDTODEVICE 将套接字绑定到在传递接口名称中指定的设备,如 eth1。要使用 SO_BINDTODEVICE,应用程序必须具有 CAP_NET_RAW 功能。

OpenShift Container Platform pod 不支持通过 ip vrf exec 命令使用 VRF。要使用 VRF,将应用程序直接绑定到 VRF 接口。

22.4.4.1. 使用 CNI VRF 插件创建额外的 SR-IOV 网络附加

SR-IOV Network Operator 管理额外网络定义。当您指定要创建的额外 SR-IOV 网络时,SR-IOV Network Operator 会自动创建 NetworkAttachmentDefinition 自定义资源(CR)。

注意

不要编辑 SR-IOV Network Operator 所管理的 NetworkAttachmentDefinition 自定义资源。这样做可能会破坏额外网络上的网络流量。

要使用 CNI VRF 插件创建额外的 SR-IOV 网络附加,请执行以下步骤。

先决条件

  • 安装 OpenShift Container Platform CLI(oc)。
  • 以具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform 集群。

流程

  1. 为额外 SR-IOV 网络附加创建 SriovNetwork 自定义资源 (CR) 并插入 metaPlugins 配置,如下例所示。将 YAML 保存为文件 sriov-network-attachment.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: example-network
      namespace: additional-sriov-network-1
    spec:
      ipam: |
        {
          "type": "host-local",
          "subnet": "10.56.217.0/24",
          "rangeStart": "10.56.217.171",
          "rangeEnd": "10.56.217.181",
          "routes": [{
            "dst": "0.0.0.0/0"
          }],
          "gateway": "10.56.217.1"
        }
      vlan: 0
      resourceName: intelnics
      metaPlugins : |
        {
          "type": "vrf", 
    1
    
          "vrfname": "example-vrf-name" 
    2
    
        }
    1
    type 必须设为 vrf
    2
    vrfname 是接口分配的 VRF 的名称。如果 pod 中不存在,则创建它。
  2. 创建 SriovNetwork 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sriov-network-attachment.yaml

验证 NetworkAttachmentDefinition CR 是否已成功创建

  • 运行以下命令,确认 SR-IOV Network Operator 创建了 NetworkAttachmentDefinition CR。

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions -n <namespace> 
    1
    1
    <namespace> 替换为您在配置网络附加时指定的命名空间,如 additional-sriov-network-1

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                            AGE
    additional-sriov-network-1      14m

    注意

    SR-IOV Network Operator 创建 CR 之前可能会有延迟。

验证额外 SR-IOV 网络附加是否成功

要验证 VRF CNI 是否已正确配置并附加额外的 SR-IOV 网络附加,请执行以下操作:

  1. 创建使用 VRF CNI 的 SR-IOV 网络。
  2. 将网络分配给 pod。
  3. 验证 pod 网络附加是否已连接到 SR-IOV 额外网络。远程 shell 到 pod 并运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ ip vrf show

    输出示例

    Copy to Clipboard Toggle word wrap
    Name              Table
    -----------------------
    red                 10

  4. 确认 VRF 接口是从属接口的主接口:

    Copy to Clipboard Toggle word wrap
    $ ip link

    输出示例

    Copy to Clipboard Toggle word wrap
    ...
    5: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master red state UP mode
    ...

22.4.5. 后续步骤

22.5. 配置 SR-IOV 以太网网络附加

您可以为集群中的单根 I/O 虚拟化(SR-IOV)设备配置以太网网络附加。

22.5.1. 以太网设备配置对象

您可以通过定义 SriovNetwork 对象来配置以太网网络设备。

以下 YAML 描述了 SriovNetwork 对象:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
  name: <name> 
1

  namespace: openshift-sriov-network-operator 
2

spec:
  resourceName: <sriov_resource_name> 
3

  networkNamespace: <target_namespace> 
4

  vlan: <vlan> 
5

  spoofChk: "<spoof_check>" 
6

  ipam: |- 
7

    {}
  linkState: <link_state> 
8

  maxTxRate: <max_tx_rate> 
9

  minTxRate: <min_tx_rate> 
10

  vlanQoS: <vlan_qos> 
11

  trust: "<trust_vf>" 
12

  capabilities: <capabilities> 
13
1
对象的名称。SR-IOV Network Operator 创建一个名称相同的 NetworkAttachmentDefinition 对象。
2
安装 SR-IOV Network Operator 的命名空间。
3
用于为这个额外网络定义 SR-IOV 硬件的 SriovNetworkNodePolicy 对象的 spec.resourceName 参数的值。
4
SriovNetwork 对象的目标命名空间。只有目标命名空间中的 pod 可以附加到额外网络。
5
可选:额外网络的虚拟 LAN(VLAN)ID。整数值必须从 04095。默认值为 0
6
可选:VF 的 spoof 检查模式。允许的值是字符串 "on""off"
重要

指定的值必须由引号包括,否则 SR-IOV Network Operator 将拒绝对象。

7
为 IPAM CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。
8
可选:虚拟功能(VF)的链接状态。允许的值是 enabledisableauto
9
可选:VF 的最大传输率(以 Mbps 为单位)。
10
可选:VF 的最低传输率(以 Mbps 为单位)。这个值必须小于或等于最大传输率。
注意

Intel NIC 不支持 minTxRate 参数。如需更多信息,请参阅 BZ#1772847

11
可选:VF 的 IEEE 802.1p 优先级级别。默认值为 0
12
可选:VF 的信任模式。允许的值是字符串 "on""off"
重要

您必须在引号中包含指定的值,或者 SR-IOV Network Operator 拒绝对象。

13
可选:为这个额外网络配置功能。您可以指定 "{ "ips": true }" 来启用 IP 地址支持,或指定 "{ "mac": true }" 来启用 MAC 地址支持。
22.5.1.1. 为额外网络配置 IP 地址分配

IP 地址管理 (IPAM) Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址。

您可以使用以下 IP 地址分配类型:

  • 静态分配。
  • 通过 DHCP 服务器进行动态分配。您指定的 DHCP 服务器必须可从额外网络访问。
  • 通过 Whereabouts IPAM CNI 插件进行动态分配。
22.5.1.1.1. 静态 IP 地址分配配置

下表描述了静态 IP 地址分配的配置:

表 22.3. ipam 静态配置对象
字段类型描述

type

string

IPAM 地址类型。值必须是 static

addresses

数组

指定分配给虚拟接口的 IP 地址的对象数组。支持 IPv4 和 IPv6 IP 地址。

Routes

数组

指定要在 pod 中配置的路由的一组对象。

dns

数组

可选:指定 DNS 配置的对象数组。

address 数组需要带有以下字段的对象:

表 22.4. ipam.addresses[] array
字段类型描述

address

string

您指定的 IP 地址和网络前缀。例如:如果您指定 10.10.21.10/24,那么会为额外网络分配 IP 地址 10.10.21.10,网掩码为 255.255.255.0

gateway

string

出口网络流量要路由到的默认网关。

表 22.5. ipam.routes[] array
字段类型描述

dst

string

CIDR 格式的 IP 地址范围,如 192.168.17.0/24 或默认路由 0.0.0.0/0

gw

string

网络流量路由的网关。

表 22.6. ipam.dns object
字段类型描述

nameservers

数组

用于发送 DNS 查询的一个或多个 IP 地址的数组。

domain

数组

要附加到主机名的默认域。例如,如果将域设置为 example.com,对 example-host 的 DNS 查找查询将被改写为 example-host.example.com

search

数组

在 DNS 查找查询过程中,附加到非限定主机名(如 example-host)的域名的数组。

静态 IP 地址分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "static",
      "addresses": [
        {
          "address": "191.168.1.7/24"
        }
      ]
  }
}

22.5.1.1.2. 动态 IP 地址(DHCP)分配配置

以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置。

DHCP 租期续订

pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。

SR-IOV Network Operator 不创建 DHCP 服务器部署。Cluster Network Operator 负责创建小型的 DHCP 服务器部署。

要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:

shim 网络附加定义示例

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  additionalNetworks:
  - name: dhcp-shim
    namespace: default
    type: Raw
    rawCNIConfig: |-
      {
        "name": "dhcp-shim",
        "cniVersion": "0.3.1",
        "type": "bridge",
        "ipam": {
          "type": "dhcp"
        }
      }
  # ...

表 22.7. ipam DHCP 配置对象
字段类型描述

type

string

IPAM 地址类型。需要值 dhcp

动态 IP 地址(DHCP)分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "dhcp"
  }
}

22.5.1.1.3. 使用 Whereabouts 进行动态 IP 地址分配配置

Whereabouts CNI 插件允许在不使用 DHCP 服务器的情况下动态地将 IP 地址分配给额外网络。

下表描述了使用 Whereabouts 进行动态 IP 地址分配的配置:

表 22.8. ipam whereabouts 配置对象
字段类型描述

type

string

IPAM 地址类型。需要 abouts 的值。

range

string

CIDR 表示法中的 IP 地址和范围。IP 地址是通过这个地址范围来分配的。

exclude

数组

可选: CIDR 标记中零个或更多 IP 地址和范围的列表。包含在排除地址范围中的 IP 地址。

使用 Whereabouts 的动态 IP 地址分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "whereabouts",
    "range": "192.0.2.192/27",
    "exclude": [
       "192.0.2.192/30",
       "192.0.2.196/32"
    ]
  }
}

22.5.1.1.4. 创建 Whereabouts 协调器守护进程集

Whereabouts 协调器负责管理集群中 pod 的动态 IP 地址分配,使用 Whereabouts IP 地址管理 (IPAM) 解决方案。它确保每个 pod 从指定的 IP 地址范围中获取唯一的 IP 地址。它还会在 pod 删除或缩减时处理 IP 地址发行版本。

注意

您还可以使用 NetworkAttachmentDefinition 自定义资源进行动态 IP 地址分配。

通过 Cluster Network Operator 配置额外网络时,Whereabouts reconciler 守护进程集会被自动创建。从 YAML 清单配置额外网络时,它不会自动创建。

要触发 Whereabouts 协调器 daemonset 的部署,您必须通过编辑 Cluster Network Operator 自定义资源文件来手动创建 whereabouts-shim 网络附加。

使用以下步骤部署 Whereabouts 协调器 daemonset。

流程

  1. 运行以下命令来编辑 Network.operator.openshift.io 自定义资源(CR):

    Copy to Clipboard Toggle word wrap
    $ oc edit network.operator.openshift.io cluster
  2. 修改 CR 中的 additionalNetworks 参数,以添加 abouts-shim 网络附加定义。例如:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      additionalNetworks:
      - name: whereabouts-shim
        namespace: default
        rawCNIConfig: |-
          {
           "name": "whereabouts-shim",
           "cniVersion": "0.3.1",
           "type": "bridge",
           "ipam": {
             "type": "whereabouts"
           }
          }
        type: Raw
  3. 保存文件并退出文本编辑器。
  4. 运行以下命令,验证 whereabouts-reconciler 守护进程集是否已成功部署:

    Copy to Clipboard Toggle word wrap
    $ oc get all -n openshift-multus | grep whereabouts-reconciler

    输出示例

    Copy to Clipboard Toggle word wrap
    pod/whereabouts-reconciler-jnp6g 1/1 Running 0 6s
    pod/whereabouts-reconciler-k76gg 1/1 Running 0 6s
    pod/whereabouts-reconciler-k86t9 1/1 Running 0 6s
    pod/whereabouts-reconciler-p4sxw 1/1 Running 0 6s
    pod/whereabouts-reconciler-rvfdv 1/1 Running 0 6s
    pod/whereabouts-reconciler-svzw9 1/1 Running 0 6s
    daemonset.apps/whereabouts-reconciler 6 6 6 6 6 kubernetes.io/os=linux 6s

22.5.2. 配置 SR-IOV 额外网络

您可以通过创建一个 SriovNetwork 对象来配置使用 SR-IOV 硬件的额外网络。创建 SriovNetwork 对象时,SR-IOV Network Operator 会自动创建一个 NetworkAttachmentDefinition 对象。

注意

如果一个 SriovNetwork 对象已被附加到状态为 running 的 pod,则不要修改或删除它。

先决条件

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

流程

  1. 创建一个 SriovNetwork 对象,然后在 <name>.yaml 文件中保存 YAML,其中 <name> 是这个额外网络的名称。对象规格可能类似以下示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: attach1
      namespace: openshift-sriov-network-operator
    spec:
      resourceName: net1
      networkNamespace: project2
      ipam: |-
        {
          "type": "host-local",
          "subnet": "10.56.217.0/24",
          "rangeStart": "10.56.217.171",
          "rangeEnd": "10.56.217.181",
          "gateway": "10.56.217.1"
        }
  2. 运行以下命令来创建对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f <name>.yaml

    这里的 <name> 指定额外网络的名称。

  3. 可选: 要确认与您在上一步中创建的 SriovNetwork 对象关联的 NetworkAttachmentDefinition 对象是否存在,请输入以下命令。将 <namespace> 替换为您在 SriovNetwork 对象中指定的 networkNamespace。

    Copy to Clipboard Toggle word wrap
    $ oc get net-attach-def -n <namespace>

22.5.3. 后续步骤

22.5.4. 其他资源

22.6. 配置 SR-IOV InfiniBand 网络附加

您可以为集群中的单根 I/O 虚拟化(SR-IOV)设备配置 InfiniBand(IB)网络附加。

22.6.1. Infiniband 设备配置对象

您可以通过定义 SriovIBNetwork 对象来配置 InfiniBand(IB)网络设备。

以下 YAML 描述了 SriovIBNetwork 对象:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovIBNetwork
metadata:
  name: <name> 
1

  namespace: openshift-sriov-network-operator 
2

spec:
  resourceName: <sriov_resource_name> 
3

  networkNamespace: <target_namespace> 
4

  ipam: |- 
5

    {}
  linkState: <link_state> 
6

  capabilities: <capabilities> 
7
1
对象的名称。SR-IOV Network Operator 创建一个名称相同的 NetworkAttachmentDefinition 对象。
2
安装 SR-IOV Operator 的命名空间。
3
用于为这个额外网络定义 SR-IOV 硬件的 SriovNetworkNodePolicy 对象的 spec.resourceName 参数的值。
4
SriovIBNetwork 对象的目标命名空间。只有目标命名空间中的 pod 可以附加到网络设备。
5
可选:将 IPAM CNI 插件配置为 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。
6
可选:虚拟功能(VF)的链接状态。允许的值是 enabledisableauto
7
可选:为此网络配置功能。您可以指定 "{ "ips": true }" 来启用 IP 地址支持,或者 "{ "infinibandGUID": true }" 启用 IB Global Unique Identifier(GUID)支持。
22.6.1.1. 为额外网络配置 IP 地址分配

IP 地址管理 (IPAM) Container Network Interface (CNI) 插件为其他 CNI 插件提供 IP 地址。

您可以使用以下 IP 地址分配类型:

  • 静态分配。
  • 通过 DHCP 服务器进行动态分配。您指定的 DHCP 服务器必须可从额外网络访问。
  • 通过 Whereabouts IPAM CNI 插件进行动态分配。
22.6.1.1.1. 静态 IP 地址分配配置

下表描述了静态 IP 地址分配的配置:

表 22.9. ipam 静态配置对象
字段类型描述

type

string

IPAM 地址类型。值必须是 static

addresses

数组

指定分配给虚拟接口的 IP 地址的对象数组。支持 IPv4 和 IPv6 IP 地址。

Routes

数组

指定要在 pod 中配置的路由的一组对象。

dns

数组

可选:指定 DNS 配置的对象数组。

address 数组需要带有以下字段的对象:

表 22.10. ipam.addresses[] array
字段类型描述

address

string

您指定的 IP 地址和网络前缀。例如:如果您指定 10.10.21.10/24,那么会为额外网络分配 IP 地址 10.10.21.10,网掩码为 255.255.255.0

gateway

string

出口网络流量要路由到的默认网关。

表 22.11. ipam.routes[] array
字段类型描述

dst

string

CIDR 格式的 IP 地址范围,如 192.168.17.0/24 或默认路由 0.0.0.0/0

gw

string

网络流量路由的网关。

表 22.12. ipam.dns object
字段类型描述

nameservers

数组

用于发送 DNS 查询的一个或多个 IP 地址的数组。

domain

数组

要附加到主机名的默认域。例如,如果将域设置为 example.com,对 example-host 的 DNS 查找查询将被改写为 example-host.example.com

search

数组

在 DNS 查找查询过程中,附加到非限定主机名(如 example-host)的域名的数组。

静态 IP 地址分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "static",
      "addresses": [
        {
          "address": "191.168.1.7/24"
        }
      ]
  }
}

22.6.1.1.2. 动态 IP 地址(DHCP)分配配置

以下 JSON 描述了使用 DHCP 进行动态 IP 地址地址分配的配置。

DHCP 租期续订

pod 在创建时获取其原始 DHCP 租期。该租期必须由集群中运行的一个小型的 DHCP 服务器部署定期续订。

要触发 DHCP 服务器的部署,您必须编辑 Cluster Network Operator 配置来创建 shim 网络附加,如下例所示:

shim 网络附加定义示例

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  additionalNetworks:
  - name: dhcp-shim
    namespace: default
    type: Raw
    rawCNIConfig: |-
      {
        "name": "dhcp-shim",
        "cniVersion": "0.3.1",
        "type": "bridge",
        "ipam": {
          "type": "dhcp"
        }
      }
  # ...

表 22.13. ipam DHCP 配置对象
字段类型描述

type

string

IPAM 地址类型。需要值 dhcp

动态 IP 地址(DHCP)分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "dhcp"
  }
}

22.6.1.1.3. 使用 Whereabouts 进行动态 IP 地址分配配置

Whereabouts CNI 插件允许在不使用 DHCP 服务器的情况下动态地将 IP 地址分配给额外网络。

下表描述了使用 Whereabouts 进行动态 IP 地址分配的配置:

表 22.14. ipam whereabouts 配置对象
字段类型描述

type

string

IPAM 地址类型。需要 abouts 的值。

range

string

CIDR 表示法中的 IP 地址和范围。IP 地址是通过这个地址范围来分配的。

exclude

数组

可选: CIDR 标记中零个或更多 IP 地址和范围的列表。包含在排除地址范围中的 IP 地址。

使用 Whereabouts 的动态 IP 地址分配配置示例

Copy to Clipboard Toggle word wrap
{
  "ipam": {
    "type": "whereabouts",
    "range": "192.0.2.192/27",
    "exclude": [
       "192.0.2.192/30",
       "192.0.2.196/32"
    ]
  }
}

22.6.1.1.4. 创建 Whereabouts 协调器守护进程集

Whereabouts 协调器负责管理集群中 pod 的动态 IP 地址分配,使用 Whereabouts IP 地址管理 (IPAM) 解决方案。它确保每个 pod 从指定的 IP 地址范围中获取唯一的 IP 地址。它还会在 pod 删除或缩减时处理 IP 地址发行版本。

注意

您还可以使用 NetworkAttachmentDefinition 自定义资源进行动态 IP 地址分配。

通过 Cluster Network Operator 配置额外网络时,Whereabouts reconciler 守护进程集会被自动创建。从 YAML 清单配置额外网络时,它不会自动创建。

要触发 Whereabouts 协调器 daemonset 的部署,您必须通过编辑 Cluster Network Operator 自定义资源文件来手动创建 whereabouts-shim 网络附加。

使用以下步骤部署 Whereabouts 协调器 daemonset。

流程

  1. 运行以下命令来编辑 Network.operator.openshift.io 自定义资源(CR):

    Copy to Clipboard Toggle word wrap
    $ oc edit network.operator.openshift.io cluster
  2. 修改 CR 中的 additionalNetworks 参数,以添加 abouts-shim 网络附加定义。例如:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      additionalNetworks:
      - name: whereabouts-shim
        namespace: default
        rawCNIConfig: |-
          {
           "name": "whereabouts-shim",
           "cniVersion": "0.3.1",
           "type": "bridge",
           "ipam": {
             "type": "whereabouts"
           }
          }
        type: Raw
  3. 保存文件并退出文本编辑器。
  4. 运行以下命令,验证 whereabouts-reconciler 守护进程集是否已成功部署:

    Copy to Clipboard Toggle word wrap
    $ oc get all -n openshift-multus | grep whereabouts-reconciler

    输出示例

    Copy to Clipboard Toggle word wrap
    pod/whereabouts-reconciler-jnp6g 1/1 Running 0 6s
    pod/whereabouts-reconciler-k76gg 1/1 Running 0 6s
    pod/whereabouts-reconciler-k86t9 1/1 Running 0 6s
    pod/whereabouts-reconciler-p4sxw 1/1 Running 0 6s
    pod/whereabouts-reconciler-rvfdv 1/1 Running 0 6s
    pod/whereabouts-reconciler-svzw9 1/1 Running 0 6s
    daemonset.apps/whereabouts-reconciler 6 6 6 6 6 kubernetes.io/os=linux 6s

22.6.2. 配置 SR-IOV 额外网络

您可以通过创建一个 SriovIBNetwork 对象来配置使用 SR-IOV 硬件的额外网络。创建 SriovIBNetwork 对象时,SR-IOV Network Operator 会自动创建一个 NetworkAttachmentDefinition 对象。

注意

如果一个 SriovIBNetwork 对象已被附加到状态为 running 的 pod,则不要修改或删除它。

先决条件

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

流程

  1. 创建一个 SriovIBNetwork 对象,然后在 <name>.yaml 文件中保存 YAML,其中 <name> 是这个额外网络的名称。对象规格可能类似以下示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovIBNetwork
    metadata:
      name: attach1
      namespace: openshift-sriov-network-operator
    spec:
      resourceName: net1
      networkNamespace: project2
      ipam: |-
        {
          "type": "host-local",
          "subnet": "10.56.217.0/24",
          "rangeStart": "10.56.217.171",
          "rangeEnd": "10.56.217.181",
          "gateway": "10.56.217.1"
        }
  2. 运行以下命令来创建对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f <name>.yaml

    这里的 <name> 指定额外网络的名称。

  3. 可选: 要确认与您在上一步中创建的 SriovIBNetwork 对象关联的 NetworkAttachmentDefinition 对象是否存在,请输入以下命令。将 <namespace> 替换为您在 SriovIBNetwork 对象中指定的 networkNamespace。

    Copy to Clipboard Toggle word wrap
    $ oc get net-attach-def -n <namespace>

22.6.3. 后续步骤

22.6.4. 其他资源

22.7. 将 pod 添加到额外网络

您可以将 pod 添加到现有的单根 I/O 虚拟化(SR-IOV)网络。

22.7.1. 网络附加的运行时配置

将 pod 附加到额外网络时,您可以指定运行时配置来为 pod 进行特定的自定义。例如,,您可以请求特定的 MAC 硬件地址。

您可以通过在 pod 规格中设置注解来指定运行时配置。注解键是 k8s.v1.cni.cncf.io/networks,它接受描述运行时配置的 JSON 对象。

22.7.1.1. 基于以太网的 SR-IOV 附加的运行时配置

以下 JSON 描述了基于以太网的 SR-IOV 网络附加的运行时配置选项。

Copy to Clipboard Toggle word wrap
[
  {
    "name": "<name>", 
1

    "mac": "<mac_address>", 
2

    "ips": ["<cidr_range>"] 
3

  }
]
1
SR-IOV 网络附加定义 CR 的名称。
2
可选:从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 MAC 地址。要使用这个功能,还必须在 SriovNetwork 对象中指定 { "mac": true }
3
可选:从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 IP 地址。支持 IPv4 和 IPv6 IP 地址。要使用这个功能,还必须在 SriovNetwork 对象中指定 { "ips": true }

运行时配置示例

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
  annotations:
    k8s.v1.cni.cncf.io/networks: |-
      [
        {
          "name": "net1",
          "mac": "20:04:0f:f1:88:01",
          "ips": ["192.168.10.1/24", "2001::1/64"]
        }
      ]
spec:
  containers:
  - name: sample-container
    image: <image>
    imagePullPolicy: IfNotPresent
    command: ["sleep", "infinity"]

22.7.1.2. 基于 InfiniBand 的 SR-IOV 附加的运行时配置

以下 JSON 描述了基于 InfiniBand 的 SR-IOV 网络附加的运行时配置选项。

Copy to Clipboard Toggle word wrap
[
  {
    "name": "<network_attachment>", 
1

    "infiniband-guid": "<guid>", 
2

    "ips": ["<cidr_range>"] 
3

  }
]
1
SR-IOV 网络附加定义 CR 的名称。
2
SR-IOV 设备的 InfiniBand GUID。要使用这个功能,还必须在 SriovIBNetwork 对象中指定 { "infinibandGUID": true }
3
从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 IP 地址。支持 IPv4 和 IPv6 IP 地址。要使用这个功能,你还必须在 SriovIBNetwork 对象中指定 { "ips": true }

运行时配置示例

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
  annotations:
    k8s.v1.cni.cncf.io/networks: |-
      [
        {
          "name": "ib1",
          "infiniband-guid": "c2:11:22:33:44:55:66:77",
          "ips": ["192.168.10.1/24", "2001::1/64"]
        }
      ]
spec:
  containers:
  - name: sample-container
    image: <image>
    imagePullPolicy: IfNotPresent
    command: ["sleep", "infinity"]

22.7.2. 将 pod 添加到额外网络

您可以将 pod 添加到额外网络。pod 继续通过默认网络发送与集群相关的普通网络流量。

创建 pod 时会附加额外网络。但是,如果 pod 已存在,您无法为其附加额外网络。

pod 必须与额外网络处于相同的命名空间。

注意

SR-IOV Network Resource Injector 会自动将 resource 字段添加到 pod 中的第一个容器中。

如果您在 Data Plane Development Kit(DPDK)模式下使用 Intel 网络接口控制器(NIC),则只有 pod 中的第一个容器被配置为访问 NIC。如果在 SriovNetworkNodePolicy 对象中将 deviceType 设置为 vfio-pci,则您的 SR-IOV 额外网络被配置为 DPDK 模式。

您可以通过确保需要访问 NIC 的容器是 Pod 对象定义的第一个容器,或者禁用 Network Resource Injector(Network Resource Injector)来解决此问题。如需更多信息,请参阅 BZ#1990953

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 登录到集群。
  • 安装 SR-IOV Operator。
  • 创建 SriovNetwork 对象或 SriovIBNetwork 对象以将 pod 附加到。

流程

  1. Pod 对象添加注解。只能使用以下注解格式之一:

    1. 要在没有自定义的情况下附加额外网络,请使用以下格式添加注解。将 <network> 替换为要与 pod 关联的额外网络的名称:

      Copy to Clipboard Toggle word wrap
      metadata:
        annotations:
          k8s.v1.cni.cncf.io/networks: <network>[,<network>,...] 
      1
      1
      要指定多个额外网络,请使用逗号分隔各个网络。逗号之间不可包括空格。如果您多次指定同一额外网络,则该 pod 会将多个网络接口附加到该网络。
    2. 要通过自定义来附加额外网络,请添加具有以下格式的注解:

      Copy to Clipboard Toggle word wrap
      metadata:
        annotations:
          k8s.v1.cni.cncf.io/networks: |-
            [
              {
                "name": "<network>", 
      1
      
                "namespace": "<namespace>", 
      2
      
                "default-route": ["<default-route>"] 
      3
      
              }
            ]
      1
      指定 NetworkAttachmentDefinition 对象定义的额外网络的名称。
      2
      指定定义 NetworkAttachmentDefinition 对象的命名空间。
      3
      可选:为默认路由指定覆盖,如 192.168.17.1
  2. 运行以下命令来创建 pod。将 <name> 替换为 pod 的名称。

    Copy to Clipboard Toggle word wrap
    $ oc create -f <name>.yaml
  3. 可选: 要确认 Pod CR 中是否存在注解,请输入以下命令将 <name> 替换为 pod 的名称。

    Copy to Clipboard Toggle word wrap
    $ oc get pod <name> -o yaml

    在以下示例中,example-pod pod 附加到 net1 额外网络:

    Copy to Clipboard Toggle word wrap
    $ oc get pod example-pod -o yaml
    apiVersion: v1
    kind: Pod
    metadata:
      annotations:
        k8s.v1.cni.cncf.io/networks: macvlan-bridge
        k8s.v1.cni.cncf.io/networks-status: |- 
    1
    
          [{
              "name": "openshift-sdn",
              "interface": "eth0",
              "ips": [
                  "10.128.2.14"
              ],
              "default": true,
              "dns": {}
          },{
              "name": "macvlan-bridge",
              "interface": "net1",
              "ips": [
                  "20.2.2.100"
              ],
              "mac": "22:2f:60:a5:f8:00",
              "dns": {}
          }]
      name: example-pod
      namespace: default
    spec:
      ...
    status:
      ...
    1
    k8s.v1.cni.cncf.io/networks-status 参数是对象的 JSON 数组。每个对象描述附加到 pod 的额外网络的状态。注解值保存为纯文本值。

22.7.3. 创建与 SR-IOV pod 兼容的非统一内存访问 (NUMA)

您可以通过限制 SR-IOV 和从相同 NUMA 节点分配的 CPU 资源,使用 restrictedsingle-numa-node Topology Manager 来创建与 SR-IOV pod 兼容的 NUMA。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您已将 CPU Manager 策略配置为 static。有关 CPU Manager 的详情请参考 "Additional resources" 部分。
  • 您已将 Topology Manager 策略配置为 single-numa-node

    注意

    single-numa-node 无法满足请求时,您可以将拓扑管理器策略配置为 restricted

流程

  1. 创建以下 SR-IOV pod 规格,然后在 <name>-sriov-pod.yaml 文件中保存 YAML。将 <name> 替换为这个 pod 的名称。

    以下示例显示了 SR-IOV pod 规格:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-pod
      annotations:
        k8s.v1.cni.cncf.io/networks: <name> 
    1
    
    spec:
      containers:
      - name: sample-container
        image: <image> 
    2
    
        command: ["sleep", "infinity"]
        resources:
          limits:
            memory: "1Gi" 
    3
    
            cpu: "2" 
    4
    
          requests:
            memory: "1Gi"
            cpu: "2"
    1
    <name> 替换为 SR-IOV 网络附加定义 CR 的名称。
    2
    <image> 替换为 sample-pod 镜像的名称。
    3
    要创建带有保证 QoS 的 SR-IOV pod,将 memory limits 设置为与 memory requests 相同的值。
    4
    要创建带有保证 QoS 的 SR-IOV pod,将 cpu limits 设置为与 cpu requests 相同。
  2. 运行以下命令来创建 SR-IOV pod 示例:

    Copy to Clipboard Toggle word wrap
    $ oc create -f <filename> 
    1
    1
    <filename> 替换为您在上一步中创建的文件的名称。
  3. 确认 sample-pod 配置为带有保证 QoS。

    Copy to Clipboard Toggle word wrap
    $ oc describe pod sample-pod
  4. 确认 sample-pod 被分配了独有的 CPU。

    Copy to Clipboard Toggle word wrap
    $ oc exec sample-pod -- cat /sys/fs/cgroup/cpuset/cpuset.cpus
  5. 确认为 sample-pod 分配的 SR-IOV 设备和 CPU 位于相同的 NUMA 节点上。

    Copy to Clipboard Toggle word wrap
    $ oc exec sample-pod -- cat /sys/fs/cgroup/cpuset/cpuset.cpus

22.7.4. 在 OpenStack 上使用 SR-IOV 的集群测试 pod 模板

以下 testpmd pod 演示了使用巨页、保留 CPU 和 SR-IOV 端口创建容器。

testpmd pod 示例

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: testpmd-sriov
  namespace: mynamespace
  annotations:
    cpu-load-balancing.crio.io: "disable"
    cpu-quota.crio.io: "disable"
# ...
spec:
  containers:
  - name: testpmd
    command: ["sleep", "99999"]
    image: registry.redhat.io/openshift4/dpdk-base-rhel8:v4.9
    securityContext:
      capabilities:
        add: ["IPC_LOCK","SYS_ADMIN"]
      privileged: true
      runAsUser: 0
    resources:
      requests:
        memory: 1000Mi
        hugepages-1Gi: 1Gi
        cpu: '2'
        openshift.io/sriov1: 1
      limits:
        hugepages-1Gi: 1Gi
        cpu: '2'
        memory: 1000Mi
        openshift.io/sriov1: 1
    volumeMounts:
      - mountPath: /dev/hugepages
        name: hugepage
        readOnly: False
  runtimeClassName: performance-cnf-performanceprofile 
1

  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages

1
本例假定性能配置集的名称为 cnf-performance profile

22.7.5. 其他资源

22.8. 为 SR-IOV 网络配置接口级别网络 sysctl 设置

作为集群管理员,您可以使用连接到 SR-IOV 网络设备的 pod 的 tuning Container Network Interface (CNI) meta 插件修改接口级网络 sysctl。

22.8.1. 为启用了 SR-IOV 的 NIC 标记节点

如果您只想在 SR-IOV 功能的节点上启用 SR-IOV,请执行几种方法:

  1. 安装 Node Feature Discovery (NFD) Operator。NFD 检测启用了 SR-IOV 的 NIC,并使用 node.alpha.kubernetes-incubator.io/nfd-network-sriov.enabled = true 标记节点。
  2. 检查每个节点的 SriovNetworkNodeState CR。interfaces 小节包括 worker 节点上 SR-IOV Network Operator 发现的所有 SR-IOV 设备列表。使用以下命令,为每个节点标记 feature.node.kubernetes.io/network-sriov.enabled: "true"

    Copy to Clipboard Toggle word wrap
    $ oc label node <node_name> feature.node.kubernetes.io/network-sriov.capable="true"
    注意

    您可以使用您需要的任何名称标记节点。

22.8.2. 设置一个 sysctl 标记

您可以为连接到 SR-IOV 网络设备的 pod 设置接口级网络 sysctl 设置。

在本例中,net.ipv4.conf.IFNAME.accept_redirects 在创建的虚拟接口上设置为 1

sysctl-tuning-test 是本例中使用的命名空间。

  • 使用以下命令来创建 sysctl-tuning-test 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace sysctl-tuning-test
22.8.2.1. 在使用 SR-IOV 网络设备的节点上设置一个 sysctl 标志

SR-IOV Network Operator 将 SriovNetworkNodePolicy.sriovnetwork.openshift.io 自定义资源定义(CRD) 添加到 OpenShift Container Platform。您可以通过创建一个 SriovNetworkNodePolicy 自定义资源 (CR) 来配置 SR-IOV 网络设备。

注意

当应用由 SriovNetworkNodePolicy 对象中指定的配置时,SR-IOV Operator 可能会排空并重启节点。

它可能需要几分钟时间来应用配置更改。

按照以下步骤创建一个 SriovNetworkNodePolicy 自定义资源 (CR)。

流程

  1. 创建一个 SriovNetworkNodePolicy 自定义资源 (CR)。例如,将以下 YAML 保存为文件 policyoneflag-sriov-node-network.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: policyoneflag 
    1
    
      namespace: openshift-sriov-network-operator 
    2
    
    spec:
      resourceName: policyoneflag 
    3
    
      nodeSelector: 
    4
    
        feature.node.kubernetes.io/network-sriov.capable="true"
      priority: 10 
    5
    
      numVfs: 5 
    6
    
      nicSelector: 
    7
    
        pfNames: ["ens5"] 
    8
    
      deviceType: "netdevice" 
    9
    
      isRdma: false 
    10
    1
    自定义资源对象的名称。
    2
    安装 SR-IOV Network Operator 的命名空间。
    3
    SR-IOV 网络设备插件的资源名称。您可以为资源名称创建多个 SR-IOV 网络节点策略。
    4
    节点选择器指定要配置的节点。只有所选节点上的 SR-IOV 网络设备才会被配置。SR-IOV Container Network Interface(CNI)插件和设备插件仅在所选节点上部署。
    5
    可选: priority(优先级)是 099 之间的整数。较小的值具有更高的优先级。例如,优先级 10 高于 99 的优先级。默认值为 99
    6
    为 SR-IOV 物理网络设备创建的虚拟功能(VF)的数量。对于 Intel 网络接口控制器(NIC),VF 的数量不能超过该设备支持的 VF 总数。对于 Mellanox NIC,VF 的数量不能超过 127
    7
    NIC 选择器标识要配置的 Operator 的设备。您不必为所有参数指定值。建议您足够精确地识别网络设备以避免意外选择设备。如果指定了rootDevices,则必须同时为 vendordeviceIDpfNames 指定一个值。如果您同时指定了 pfNamesrootDevices,请确保它们引用同一设备。如果您为 netFilter 指定一个值,则不需要指定任何其他参数,因为网络 ID 是唯一的。
    8
    可选:该设备的一个或多个物理功能(PF)名称的数组。
    9
    可选:虚拟功能的驱动程序类型。唯一允许的值是 netdevice。对于裸机节点上的 DPDK 模式的 Mellanox NIC,请将 isRdma 设置为 true
    10
    可选:配置是否启用远程直接访问 (RDMA) 模式。默认值为 false。如果 isRdma 参数设为 true,您可以继续使用启用了 RDMA 的 VF 作为普通网络设备。设备可在其中的一个模式中使用。将 isRdma 设置为 true,并将 needVhostNet 设置为 true 以配置 Mellanox NIC 以用于 Fast Datapath DPDK 应用程序。
    注意

    vfio-pci 驱动程序类型不被支持。

  2. 创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f policyoneflag-sriov-node-network.yaml

    应用配置更新后,sriov-network-operator 命名空间中的所有 pod 将变为 Running 状态。

  3. 要验证是否已配置了 SR-IOV 网络设备,请输入以下命令。将 <node_name> 替换为带有您刚才配置的 SR-IOV 网络设备的节点名称。

    Copy to Clipboard Toggle word wrap
    $ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name> -o jsonpath='{.status.syncStatus}'

    输出示例

    Copy to Clipboard Toggle word wrap
    Succeeded

22.8.2.2. 在 SR-IOV 网络中配置 sysctl

您可以通过将调优配置添加到 SriovNetwork 资源的可选 metaPlugins 参数,在 SR-IOV 创建的虚拟接口上设置特定于接口的 sysctl 设置。

SR-IOV Network Operator 管理额外网络定义。当您指定要创建的额外 SR-IOV 网络时,SR-IOV Network Operator 会自动创建 NetworkAttachmentDefinition 自定义资源(CR)。

注意

不要编辑 SR-IOV Network Operator 所管理的 NetworkAttachmentDefinition 自定义资源。这样做可能会破坏额外网络上的网络流量。

要更改接口级别网络 net.ipv4.conf.IFNAME.accept_redirects sysctl 设置,请使用 Container Network Interface (CNI) 调整插件创建额外的 SR-IOV 网络。

先决条件

  • 安装 OpenShift Container Platform CLI(oc)。
  • 以具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform 集群。

流程

  1. 为额外 SR-IOV 网络附加创建 SriovNetwork 自定义资源 (CR) 并插入 metaPlugins 配置,如下例所示。将 YAML 保存为文件 sriov-network-interface-sysctl.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: onevalidflag 
    1
    
      namespace: openshift-sriov-network-operator 
    2
    
    spec:
      resourceName: policyoneflag 
    3
    
      networkNamespace: sysctl-tuning-test 
    4
    
      ipam: '{ "type": "static" }' 
    5
    
      capabilities: '{ "mac": true, "ips": true }' 
    6
    
      metaPlugins : | 
    7
    
        {
          "type": "tuning",
          "capabilities":{
            "mac":true
          },
          "sysctl":{
             "net.ipv4.conf.IFNAME.accept_redirects": "1"
          }
        }
    1
    对象的名称。SR-IOV Network Operator 创建一个名称相同的 NetworkAttachmentDefinition 对象。
    2
    安装 SR-IOV Network Operator 的命名空间。
    3
    用于为这个额外网络定义 SR-IOV 硬件的 SriovNetworkNodePolicy 对象的 spec.resourceName 参数的值。
    4
    SriovNetwork 对象的目标命名空间。只有目标命名空间中的 pod 可以附加到额外网络。
    5
    为 IPAM CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。
    6
    可选:为额外网络设置功能。您可以指定 "{ "ips": true }" 来启用 IP 地址支持,或指定 "{ "mac": true }" 来启用 MAC 地址支持。
    7
    可选: metaPlugins 参数用于为该设备添加额外的功能。在这种情况下,将 type 字段设置为 tuning。指定在 sysctl 字段中设置的接口级网络 sysctl
  2. 创建 SriovNetwork 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sriov-network-interface-sysctl.yaml

验证 NetworkAttachmentDefinition CR 是否已成功创建

  • 运行以下命令,确认 SR-IOV Network Operator 创建了 NetworkAttachmentDefinition CR。

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions -n <namespace> 
    1
    1
    <namespace> 替换为您在 SriovNetwork 对象中指定的 networkNamespace 的值。例如:sysctl-tuning-test

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                  AGE
    onevalidflag                          14m

    注意

    SR-IOV Network Operator 创建 CR 之前可能会有延迟。

验证额外 SR-IOV 网络附加是否成功

要验证 tuning CNI 是否已正确配置并附加额外的 SR-IOV 网络附加,请执行以下操作:

  1. 创建 Pod CR。将以下 YAML 保存为文件 examplepod.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: tunepod
      namespace: sysctl-tuning-test
      annotations:
        k8s.v1.cni.cncf.io/networks: |-
          [
            {
              "name": "onevalidflag",  
    1
    
              "mac": "0a:56:0a:83:04:0c", 
    2
    
              "ips": ["10.100.100.200/24"] 
    3
    
           }
          ]
    spec:
      containers:
      - name: podexample
        image: centos
        command: ["/bin/bash", "-c", "sleep INF"]
        securityContext:
          runAsUser: 2000
          runAsGroup: 3000
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
    1
    SR-IOV 网络附加定义 CR 的名称。
    2
    可选:从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 MAC 地址。要使用这个功能,还必须在 SriovNetwork 对象中指定 { "mac": true }
    3
    可选:从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 IP 地址。支持 IPv4 和 IPv6 IP 地址。要使用这个功能,还必须在 SriovNetwork 对象中指定 { "ips": true }
  2. 创建 Pod CR:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f examplepod.yaml
  3. 运行以下命令验证 pod 是否已创建:

    Copy to Clipboard Toggle word wrap
    $ oc get pod -n sysctl-tuning-test

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME      READY   STATUS    RESTARTS   AGE
    tunepod   1/1     Running   0          47s

  4. 运行以下命令登录到 pod:

    Copy to Clipboard Toggle word wrap
    $ oc rsh -n sysctl-tuning-test tunepod
  5. 验证配置的 sysctl 标记的值。运行以下命令,查找 net.ipv4.conf.IFNAME.accept_redirects 的值:

    Copy to Clipboard Toggle word wrap
    $ sysctl net.ipv4.conf.net1.accept_redirects

    输出示例

    Copy to Clipboard Toggle word wrap
    net.ipv4.conf.net1.accept_redirects = 1

22.8.3. 为与绑定 SR-IOV 接口标记关联的 pod 配置 sysctl 设置

您可以为连接到绑定的 SR-IOV 网络设备的 pod 设置接口级网络 sysctl 设置。

在本例中,可以配置的特定网络接口级 sysctl 设置在绑定接口上设置。

sysctl-tuning-test 是本例中使用的命名空间。

  • 使用以下命令来创建 sysctl-tuning-test 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace sysctl-tuning-test
22.8.3.1. 在带有绑定的 SR-IOV 网络设备的节点上设置所有 sysctl 标志

SR-IOV Network Operator 将 SriovNetworkNodePolicy.sriovnetwork.openshift.io 自定义资源定义(CRD) 添加到 OpenShift Container Platform。您可以通过创建一个 SriovNetworkNodePolicy 自定义资源 (CR) 来配置 SR-IOV 网络设备。

注意

当应用由 SriovNetworkNodePolicy 对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。

它可能需要几分钟时间来应用配置更改。

按照以下步骤创建一个 SriovNetworkNodePolicy 自定义资源 (CR)。

流程

  1. 创建一个 SriovNetworkNodePolicy 自定义资源 (CR)。将以下 YAML 保存为文件 policyallflags-sriov-node-network.yaml。将 policyallflags 替换为配置的名称。

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: policyallflags 
    1
    
      namespace: openshift-sriov-network-operator 
    2
    
    spec:
      resourceName: policyallflags 
    3
    
      nodeSelector: 
    4
    
        node.alpha.kubernetes-incubator.io/nfd-network-sriov.capable = `true`
      priority: 10 
    5
    
      numVfs: 5 
    6
    
      nicSelector: 
    7
    
        pfNames: ["ens1f0"]  
    8
    
      deviceType: "netdevice" 
    9
    
      isRdma: false 
    10
    1
    自定义资源对象的名称。
    2
    安装 SR-IOV Network Operator 的命名空间。
    3
    SR-IOV 网络设备插件的资源名称。您可以为资源名称创建多个 SR-IOV 网络节点策略。
    4
    节点选择器指定要配置的节点。只有所选节点上的 SR-IOV 网络设备才会被配置。SR-IOV Container Network Interface(CNI)插件和设备插件仅在所选节点上部署。
    5
    可选: priority(优先级)是 099 之间的整数。较小的值具有更高的优先级。例如,优先级 10 高于 99 的优先级。默认值为 99
    6
    为 SR-IOV 物理网络设备创建的虚拟功能 (VF) 的数量。对于 Intel 网络接口控制器(NIC),VF 的数量不能超过该设备支持的 VF 总数。对于 Mellanox NIC,VF 的数量不能超过 127
    7
    NIC 选择器标识要配置的 Operator 的设备。您不必为所有参数指定值。建议您足够精确地识别网络设备以避免意外选择设备。如果指定了rootDevices,则必须同时为 vendordeviceIDpfNames 指定一个值。如果您同时指定了 pfNamesrootDevices,请确保它们引用同一设备。如果您为 netFilter 指定一个值,则不需要指定任何其他参数,因为网络 ID 是唯一的。
    8
    可选:该设备的一个或多个物理功能(PF)名称的数组。
    9
    可选:虚拟功能的驱动程序类型。唯一允许的值是 netdevice。对于裸机节点上的 DPDK 模式的 Mellanox NIC,请将 isRdma 设置为 true
    10
    可选:配置是否启用远程直接访问 (RDMA) 模式。默认值为 false。如果 isRdma 参数设为 true,您可以继续使用启用了 RDMA 的 VF 作为普通网络设备。设备可在其中的一个模式中使用。将 isRdma 设置为 true,并将 needVhostNet 设置为 true 以配置 Mellanox NIC 以用于 Fast Datapath DPDK 应用程序。
    注意

    vfio-pci 驱动程序类型不被支持。

  2. 创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f policyallflags-sriov-node-network.yaml

    应用配置更新后,sriov-network-operator 命名空间中的所有 pod 将变为 Running 状态。

  3. 要验证是否已配置了 SR-IOV 网络设备,请输入以下命令。将 <node_name> 替换为带有您刚才配置的 SR-IOV 网络设备的节点名称。

    Copy to Clipboard Toggle word wrap
    $ oc get sriovnetworknodestates -n openshift-sriov-network-operator <node_name> -o jsonpath='{.status.syncStatus}'

    输出示例

    Copy to Clipboard Toggle word wrap
    Succeeded

22.8.3.2. 在绑定的 SR-IOV 网络中配置 sysctl

您可以在从两个 SR-IOV 接口创建的绑定接口上设置特定于接口的 sysctl 设置。为此,可将调优配置添加到绑定网络附加定义的可选 Plugins 参数中。

注意

不要编辑 SR-IOV Network Operator 所管理的 NetworkAttachmentDefinition 自定义资源。这样做可能会破坏额外网络上的网络流量。

要更改特定的接口级网络 sysctl 设置,请按照以下流程使用 Container Network Interface (CNI) 调优插件创建 SriovNetwork 自定义资源 (CR)。

先决条件

  • 安装 OpenShift Container Platform CLI(oc)。
  • 以具有 cluster-admin 权限的用户身份登录 OpenShift Container Platform 集群。

流程

  1. 为绑定接口创建 SriovNetwork 自定义资源 (CR),如下例所示。将 YAML 保存为文件 sriov-network-attachment.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: allvalidflags 
    1
    
      namespace: openshift-sriov-network-operator 
    2
    
    spec:
      resourceName: policyallflags 
    3
    
      networkNamespace: sysctl-tuning-test 
    4
    
      capabilities: '{ "mac": true, "ips": true }' 
    5
    1
    对象的名称。SR-IOV Network Operator 创建一个名称相同的 NetworkAttachmentDefinition 对象。
    2
    安装 SR-IOV Network Operator 的命名空间。
    3
    用于为这个额外网络定义 SR-IOV 硬件的 SriovNetworkNodePolicy 对象的 spec.resourceName 参数的值。
    4
    SriovNetwork 对象的目标命名空间。只有目标命名空间中的 pod 可以附加到额外网络。
    5
    可选:为这个额外网络配置功能。您可以指定 "{ "ips": true }" 来启用 IP 地址支持,或指定 "{ "mac": true }" 来启用 MAC 地址支持。
  2. 创建 SriovNetwork 资源:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sriov-network-attachment.yaml
  3. 创建绑定网络附加定义,如下例所示。将 YAML 保存为文件 sriov-bond-network-interface.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: bond-sysctl-network
      namespace: sysctl-tuning-test
    spec:
      config: '{
      "cniVersion":"0.4.0",
      "name":"bound-net",
      "plugins":[
        {
          "type":"bond", 
    1
    
          "mode": "active-backup", 
    2
    
          "failOverMac": 1, 
    3
    
          "linksInContainer": true, 
    4
    
          "miimon": "100",
          "links": [ 
    5
    
            {"name": "net1"},
            {"name": "net2"}
          ],
          "ipam":{ 
    6
    
            "type":"static"
          }
        },
        {
          "type":"tuning", 
    7
    
          "capabilities":{
            "mac":true
          },
          "sysctl":{
            "net.ipv4.conf.IFNAME.accept_redirects": "0",
            "net.ipv4.conf.IFNAME.accept_source_route": "0",
            "net.ipv4.conf.IFNAME.disable_policy": "1",
            "net.ipv4.conf.IFNAME.secure_redirects": "0",
            "net.ipv4.conf.IFNAME.send_redirects": "0",
            "net.ipv6.conf.IFNAME.accept_redirects": "0",
            "net.ipv6.conf.IFNAME.accept_source_route": "1",
            "net.ipv6.neigh.IFNAME.base_reachable_time_ms": "20000",
            "net.ipv6.neigh.IFNAME.retrans_time_ms": "2000"
          }
        }
      ]
    }'
    1
    类型是 bond
    2
    mode 属性指定绑定模式。支持的绑定模式有:
    • balance-rr - 0
    • active-backup - 1
    • balance-xor - 2

      对于 balance-rrbalance-xor 模式,您必须为 SR-IOV 虚拟功能将 trust 模式设置为 on

    3
    对于 active-backup 模式,failover 属性是必需的。
    4
    linksInContainer=true 标志告知 Bond CNI 在容器内找到所需的接口。默认情况下,Bond CNI 会查找主机上的这些接口,该接口无法与 SRIOV 和 Multus 集成。
    5
    links 部分定义将用于创建绑定的接口。默认情况下,Multus 将附加的接口命名为 "net",再加上一个连续的数字。
    6
    为 IPAM CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。在这个 pod 示例 IP 地址中被手动配置,因此在本例中 ipam 被设置为 static。
    7
    为设备添加额外的功能。例如,将 type 字段设置为 tuning。指定在 sysctl 字段中设置的接口级网络 sysctl。这个示例设置可设置的所有接口级网络 sysctl 设置。
  4. 创建绑定网络附加定义:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sriov-bond-network-interface.yaml

验证 NetworkAttachmentDefinition CR 是否已成功创建

  • 运行以下命令,确认 SR-IOV Network Operator 创建了 NetworkAttachmentDefinition CR。

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definitions -n <namespace> 
    1
    1
    <namespace> 替换为您在配置网络附加时指定的 networkNamespace,如 sysctl-tuning-test

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                          AGE
    bond-sysctl-network           22m
    allvalidflags                 47m

    注意

    SR-IOV Network Operator 创建 CR 之前可能会有延迟。

验证额外的 SR-IOV 网络资源是否成功

要验证 tuning CNI 是否已正确配置并附加额外的 SR-IOV 网络附加,请执行以下操作:

  1. 创建 Pod CR。例如,将以下 YAML 保存为文件 examplepod.yaml

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: tunepod
      namespace: sysctl-tuning-test
      annotations:
        k8s.v1.cni.cncf.io/networks: |-
          [
            {"name": "allvalidflags"}, 
    1
    
            {"name": "allvalidflags"},
            {
              "name": "bond-sysctl-network",
              "interface": "bond0",
              "mac": "0a:56:0a:83:04:0c", 
    2
    
              "ips": ["10.100.100.200/24"] 
    3
    
           }
          ]
    spec:
      containers:
      - name: podexample
        image: centos
        command: ["/bin/bash", "-c", "sleep INF"]
        securityContext:
          runAsUser: 2000
          runAsGroup: 3000
          allowPrivilegeEscalation: false
          capabilities:
            drop: ["ALL"]
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
    1
    SR-IOV 网络附加定义 CR 的名称。
    2
    可选:从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 MAC 地址。要使用这个功能,还必须在 SriovNetwork 对象中指定 { "mac": true }
    3
    可选:从 SR-IOV 网络附加定义 CR 中定义的资源类型分配的 SR-IOV 设备的 IP 地址。支持 IPv4 和 IPv6 IP 地址。要使用这个功能,还必须在 SriovNetwork 对象中指定 { "ips": true }
  2. 应用 YAML:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f examplepod.yaml
  3. 运行以下命令验证 pod 是否已创建:

    Copy to Clipboard Toggle word wrap
    $ oc get pod -n sysctl-tuning-test

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME      READY   STATUS    RESTARTS   AGE
    tunepod   1/1     Running   0          47s

  4. 运行以下命令登录到 pod:

    Copy to Clipboard Toggle word wrap
    $ oc rsh -n sysctl-tuning-test tunepod
  5. 验证配置的 sysctl 标记的值。运行以下命令,查找 net.ipv6.neigh.IFNAME.base_reachable_time_ms 的值:

    Copy to Clipboard Toggle word wrap
    $ sysctl net.ipv6.neigh.bond0.base_reachable_time_ms

    输出示例

    Copy to Clipboard Toggle word wrap
    net.ipv6.neigh.bond0.base_reachable_time_ms = 20000

22.9. 配置高性能多播

您可以在您的单根 I/O 虚拟化(SR-IOV)硬件网络中使用多播。

22.9.1. 高性能多播

OpenShift SDN 网络插件支持默认网络上的 pod 间的多播。目前,多播最适用于低带宽协调或服务发现。它不适用于高带宽的应用程序。对于流传输介质应用程序,如 IPTV 和多方视频会议,可以使用 Single Root I/O Virtualization(SR-IOV)硬件来提供接近原生的性能。

使用额外的 SR-IOV 接口进行多播时:

  • pod 必须通过额外的 SR-IOV 接口发送或接收多播软件包。
  • 连接 SR-IOV 接口的物理网络决定了多播路由和拓扑结构,不受 OpenShift Container Platform 的控制。

22.9.2. 为多播配置 SR-IOV 接口

以下步骤为多播创建一个 SR-IOV 接口示例。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 您必须作为 cluster-admin 角色用户登录集群。

流程

  1. 创建一个 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: policy-example
      namespace: openshift-sriov-network-operator
    spec:
      resourceName: example
      nodeSelector:
        feature.node.kubernetes.io/network-sriov.capable: "true"
      numVfs: 4
      nicSelector:
        vendor: "8086"
        pfNames: ['ens803f0']
        rootDevices: ['0000:86:00.0']
  2. 创建一个 SriovNetwork 对象:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: net-example
      namespace: openshift-sriov-network-operator
    spec:
      networkNamespace: default
      ipam: | 
    1
    
        {
          "type": "host-local", 
    2
    
          "subnet": "10.56.217.0/24",
          "rangeStart": "10.56.217.171",
          "rangeEnd": "10.56.217.181",
          "routes": [
            {"dst": "224.0.0.0/5"},
            {"dst": "232.0.0.0/5"}
          ],
          "gateway": "10.56.217.1"
        }
      resourceName: example
    1 2
    如果选择将 DHCP 配置为 IPAM,请确保通过 DHCP 服务器提供了以下默认路由: 224.0.0.0/5232.0.0.0/5。这会覆盖由默认网络供应商设置的静态多播路由。
  3. 创建带有多播应用程序的 pod:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: testpmd
      namespace: default
      annotations:
        k8s.v1.cni.cncf.io/networks: nic1
    spec:
      containers:
      - name: example
        image: rhel7:latest
        securityContext:
          capabilities:
            add: ["NET_ADMIN"] 
    1
    
        command: [ "sleep", "infinity"]
    1
    只有在应用程序需要为 SR-IOV 接口分配多播 IP 地址时,才需要 NET_ADMIN 功能。否则,可以省略它。

22.10. 使用 DPDK 和 RDMA

OpenShift Container Platform 支持容器化 Data Plane Development Kit (DPDK) 应用程序。您可以使用单一根 I/O 虚拟化(SR-IOV)网络硬件和 Data Plane Development Kit (DPDK) 以及远程直接内存访问 (RDMA) 。

有关支持的设备的详情,请参考支持的设备

22.10.1. 在 DPDK 模式中使用 Intel NIC 的虚拟功能

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 安装 SR-IOV Network Operator。
  • 以具有 cluster-admin 权限的用户身份登录。

流程

  1. 创建以下 SriovNetworkNodePolicy 对象,然后在 intel-dpdk-node-policy.yaml 文件中保存 YAML。

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: intel-dpdk-node-policy
      namespace: openshift-sriov-network-operator
    spec:
      resourceName: intelnics
      nodeSelector:
        feature.node.kubernetes.io/network-sriov.capable: "true"
      priority: <priority>
      numVfs: <num>
      nicSelector:
        vendor: "8086"
        deviceID: "158b"
        pfNames: ["<pf_name>", ...]
        rootDevices: ["<pci_bus_id>", "..."]
      deviceType: vfio-pci 
    1
    1
    将虚拟功能(VF)的驱动器类型指定为 vfio-pci
    注意

    如需了解 inSriovNetworkNodePolicy 的每个选项的详情,请参阅 Configuring SR-IOV network devices 部分。

    当应用由 SriovNetworkNodePolicy 对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。

    应用配置更新后,openshift-sriov-network-operator 命名空间中的所有 pod 将变为 Running 状态。

  2. 运行以下命令来创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f intel-dpdk-node-policy.yaml
  3. 创建以下 SriovNetwork 对象,然后在 intel-dpdk-network.yaml 文件中保存 YAML。

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: intel-dpdk-network
      namespace: openshift-sriov-network-operator
    spec:
      networkNamespace: <target_namespace>
      ipam: |-
    # ... 
    1
    
      vlan: <vlan>
      resourceName: intelnics
    1
    为 ipam CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。
    注意

    如需 SriovNetwork 中的每个选项的详细说明,请参阅"Configuring SR-IOV additional network" 部分。

    一个可选的库 app-netutil 提供了多种 API 方法来收集有关容器父 pod 的网络信息。

  4. 运行以下命令来创建 SriovNetwork 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f intel-dpdk-network.yaml
  5. 创建以下 Pod spec,然后在 intel-dpdk-pod.yaml 文件中保存 YAML。

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: dpdk-app
      namespace: <target_namespace> 
    1
    
      annotations:
        k8s.v1.cni.cncf.io/networks: intel-dpdk-network
    spec:
      containers:
      - name: testpmd
        image: <DPDK_image> 
    2
    
        securityContext:
          runAsUser: 0
          capabilities:
            add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"] 
    3
    
        volumeMounts:
        - mountPath: /mnt/huge 
    4
    
          name: hugepage
        resources:
          limits:
            openshift.io/intelnics: "1" 
    5
    
            memory: "1Gi"
            cpu: "4" 
    6
    
            hugepages-1Gi: "4Gi" 
    7
    
          requests:
            openshift.io/intelnics: "1"
            memory: "1Gi"
            cpu: "4"
            hugepages-1Gi: "4Gi"
        command: ["sleep", "infinity"]
      volumes:
      - name: hugepage
        emptyDir:
          medium: HugePages
    1
    指定 target_namespace,它与 SriovNetwork 对象 intel-dpdk-network 创建于的命令空间相同。如果要在其他命名空间中创建 pod,在 Pod spec 和 SriovNetwork 对象中更改 target_namespace
    2
    指定包含应用程序和应用程序使用的 DPDK 库的 DPDK 镜像。
    3
    指定容器内的应用程序进行大页分配、系统资源分配和网络接口访问所需的额外功能。
    4
    /mnt/huge 下将巨页卷挂载到 DPDK pod。巨页卷由 emptyDir 卷类型支持,媒介是 Hugepages
    5
    可选:指定分配给 DPDK pod 的 DPDK 设备数。如果未明确指定,则此资源请求和限制将被 SR-IOV 网络资源注入程序自动添加。SR-IOV 网络资源注入程序是由 SR-IOV Operator 管理的准入控制器组件。它默认是启用的,可以通过把默认的 SriovOperatorConfig CR 中的 enableInjector 选项设置为 false 来禁用它。
    6
    指定 CPU 数量。DPDK pod 通常需要从 kubelet 分配专用 CPU。这可以通过将 CPU Manager 策略设置为 static,并创建带有有保障的 QoS 的 pod 来实现。
    7
    指定巨页大小 hugepages-1Gihugepages-2Mi 以及分配给 DPDK pod 的巨页数量。单独配置 2Mi1Gi 巨页。配置 1Gi 巨页需要在节点中添加内核参数。例如:添加内核参数 default_hugepagesz=1GB,hugepagesz=1Ghugepages=16 将导致系统引导过程中分配 16*1Gi 巨页。
  6. 运行以下命令来创建 DPDK pod:

    Copy to Clipboard Toggle word wrap
    $ oc create -f intel-dpdk-pod.yaml

22.10.2. 在带有 Mellanox NIC 的 DPDK 模式中使用虚拟功能

您可以创建一个网络节点策略,并在带有 Mellanox NIC 的 DPDK 模式中使用虚拟功能创建 Data Plane Development Kit (DPDK) pod。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 已安装 Single Root I/O Virtualization (SR-IOV) Network Operator。
  • 您已以具有 cluster-admin 权限的用户身份登录。

流程

  1. 将以下 SriovNetworkNodePolicy YAML 配置保存到 mlx-dpdk-node-policy.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: mlx-dpdk-node-policy
      namespace: openshift-sriov-network-operator
    spec:
      resourceName: mlxnics
      nodeSelector:
        feature.node.kubernetes.io/network-sriov.capable: "true"
      priority: <priority>
      numVfs: <num>
      nicSelector:
        vendor: "15b3"
        deviceID: "1015" 
    1
    
        pfNames: ["<pf_name>", ...]
        rootDevices: ["<pci_bus_id>", "..."]
      deviceType: netdevice 
    2
    
      isRdma: true 
    3
    1
    指定 SR-IOV 网络设备的设备十六进制代码。
    2
    指定到 netdevice 的虚拟功能 (VF) 的驱动程序类型。Mellanox SR-IOV 虚拟功能 (VF) 可以在 DPDK 模式下工作,而无需使用 vfio-pci 设备类型。VF 设备作为容器内的内核网络接口显示。
    3
    启用远程直接内存访问 (RDMA) 模式。Mellanox 卡需要在 DPDK 模式下工作。
    注意

    如需了解 SriovNetworkNodePolicy 对象中的每个选项的详细说明,请参阅配置 SR-IOV 网络设备

    当应用由 SriovNetworkNodePolicy 对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。

    应用配置更新后,openshift-sriov-network-operator 命名空间中的所有 pod 将变为 Running 状态。

  2. 运行以下命令来创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-dpdk-node-policy.yaml
  3. 将以下 SriovNetwork YAML 配置保存到 mlx-dpdk-network.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: mlx-dpdk-network
      namespace: openshift-sriov-network-operator
    spec:
      networkNamespace: <target_namespace>
      ipam: |- 
    1
    
    ...
      vlan: <vlan>
      resourceName: mlxnics
    1
    为 IP 地址管理 (IPAM) Container Network Interface (CNI) 插件指定一个配置对象作为 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。
    注意

    如需了解 SriovNetwork 对象中的每个选项的详细说明,请参阅配置 SR-IOV 网络设备

    app-netutil 选项库提供了几个 API 方法,用于收集有关容器父 pod 的网络信息。

  4. 运行以下命令来创建 SriovNetwork 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-dpdk-network.yaml
  5. 将以下 Pod YAML 配置保存到 mlx-dpdk-pod.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: dpdk-app
      namespace: <target_namespace> 
    1
    
      annotations:
        k8s.v1.cni.cncf.io/networks: mlx-dpdk-network
    spec:
      containers:
      - name: testpmd
        image: <DPDK_image> 
    2
    
        securityContext:
          runAsUser: 0
          capabilities:
            add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"] 
    3
    
        volumeMounts:
        - mountPath: /mnt/huge 
    4
    
          name: hugepage
        resources:
          limits:
            openshift.io/mlxnics: "1" 
    5
    
            memory: "1Gi"
            cpu: "4" 
    6
    
            hugepages-1Gi: "4Gi" 
    7
    
          requests:
            openshift.io/mlxnics: "1"
            memory: "1Gi"
            cpu: "4"
            hugepages-1Gi: "4Gi"
        command: ["sleep", "infinity"]
      volumes:
      - name: hugepage
        emptyDir:
          medium: HugePages
    1
    指定 target_namespace,它与 SriovNetwork 对象 mlx-dpdk-network 创建于的命令空间相同。要在不同命名空间中创建 pod,在 Pod spec 和 SriovNetwork 对象中更改 target_namespace
    2
    指定包含应用程序和应用程序使用的 DPDK 库的 DPDK 镜像。
    3
    指定容器内的应用程序进行大页分配、系统资源分配和网络接口访问所需的额外功能。
    4
    将巨页卷挂载到 /mnt/huge 下的 DPDK pod 中。巨页卷由 emptyDir 卷类型支持,介质是 Hugepages
    5
    可选:指定分配给 DPDK pod 的 DPDK 设备数。如果没有明确指定,则 SR-IOV 网络资源注入程序会自动添加此资源请求和限制。SR-IOV 网络资源注入程序是由 SR-IOV Operator 管理的准入控制器组件。它默认是启用的,可以通过把默认的 SriovOperatorConfig CR 中的 enableInjector 选项设置为 false 来禁用它。
    6
    指定 CPU 数量。DPDK pod 通常需要从 kubelet 分配专用 CPU。要做到这一点,将 CPU Manager 策略设置为 static,并创建带有 Guaranteed 服务质量 (QoS) 的 pod。
    7
    指定巨页大小 hugepages-1Gihugepages-2Mi 以及分配给 DPDK pod 的巨页数量。单独配置 2Mi1Gi 巨页。配置 1Gi 巨页需要在节点中添加内核参数。
  6. 运行以下命令来创建 DPDK pod:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-dpdk-pod.yaml

22.10.3. 实现特定 DPDK 行率概述

要实现特定的 Data Plane Development Kit (DPDK) 行率,部署 Node Tuning Operator 并配置单根 I/O 虚拟化 (SR-IOV)。您还必须为以下资源调整 DPDK 设置:

  • 隔离的 CPU
  • Hugepages
  • 拓扑调度程序
注意

在早期版本的 OpenShift Container Platform 中,Performance Addon Operator 用来实现自动性能优化,以便为 OpenShift Container Platform 应用程序实现低延迟性能。在 OpenShift Container Platform 4.11 及更新的版本中,这个功能是 Node Tuning Operator 的一部分。

DPDK 测试环境

下图显示了流量测试环境的组件:

DPDK 测试环境
  • 流量生成器:可以生成高容量数据包流量的应用。
  • SR-IOV 支持 NIC :与 SR-IOV 兼容的网络接口卡。该卡在物理接口上运行多个虚拟功能。
  • 物理功能 (PF) :支持 SR-IOV 接口的网络适配器的 PCI Express (PCIe) 功能。
  • 虚拟功能 (VF) :支持 SR-IOV 的网络适配器上的轻量级 PCIe 功能。VF 与网络适配器上的 PCIe PF 关联。VF 代表网络适配器的虚拟实例。
  • 交换机:网络交换机。节点也可以重新连接到回来。
  • testpmd: DPDK 中包含的示例应用程序。testpmd 应用可用于在数据包转发模式下测试 DPDK。testpmd 应用程序也是如何使用 DPDK 软件开发套件 (SDK) 构建功能全面的应用程序的示例。
  • worker 0worker 1:OpenShift Container Platform 节点。

22.10.4. 使用 SR-IOV 和 Node Tuning Operator 实现 DPDK 行率

您可以使用 Node Tuning Operator 配置隔离的 CPU、巨页和拓扑调度程序。然后,您可以使用 Node Tuning Operator 和单根 I/O 虚拟化 (SR-IOV) 来实现特定的 Data Plane Development Kit (DPDK) 行率。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 已安装 SR-IOV Network Operator。
  • 您已以具有 cluster-admin 权限的用户身份登录。
  • 您已部署了独立的 Node Tuning Operator。

    注意

    在以前版本的 OpenShift Container Platform 中,Performance Addon Operator 用来实现自动性能优化,以便为 OpenShift 应用程序实现低延迟性能。在 OpenShift Container Platform 4.11 及更新的版本中,这个功能是 Node Tuning Operator 的一部分。

流程

  1. 根据以下示例创建 PerformanceProfile 对象:

    Copy to Clipboard Toggle word wrap
    apiVersion: performance.openshift.io/v2
    kind: PerformanceProfile
    metadata:
      name: performance
    spec:
      globallyDisableIrqLoadBalancing: true
      cpu:
        isolated: 21-51,73-103 
    1
    
        reserved: 0-20,52-72 
    2
    
      hugepages:
        defaultHugepagesSize: 1G 
    3
    
        pages:
          - count: 32
            size: 1G
      net:
        userLevelNetworking: true
      numa:
        topologyPolicy: "single-numa-node"
      nodeSelector:
        node-role.kubernetes.io/worker-cnf: ""
    1
    如果系统上启用了超线程,请分配与 isolatedreserved CPU 组的相关符号链接。如果系统包含多个非统一内存访问节点 (NUMA),请将两个 NUMA 中的 CPU 分配给这两个组。您还可以将 Performance Profile Creator 用于此任务。如需更多信息,请参阅创建性能配置集
    2
    您还可以指定将队列设置为保留 CPU 数的设备列表。如需更多信息,请参阅使用 Node Tuning Operator 缩减 NIC 队列
    3
    分配所需的巨页的数量和大小。您可以为巨页指定 NUMA 配置。默认情况下,系统会为系统上的每个 NUMA 节点分配一个偶数数量。如果需要,您可以请求对节点使用实时内核。如需更多信息,请参阅置备具有实时功能的 worker
  2. yaml 文件保存为 mlx-dpdk-perfprofile-policy.yaml
  3. 使用以下命令应用性能配置集:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-dpdk-perfprofile-policy.yaml
22.10.4.1. 用于虚拟功能的 SR-IOV Network Operator 示例

您可以使用单根 I/O 虚拟化 (SR-IOV) Network Operator 从节点上分配和配置虚拟功能 (VF) 的虚拟功能(VF)。

如需有关部署 Operator 的更多信息,请参阅安装 SR-IOV Network Operator。有关配置 SR-IOV 网络设备的更多信息,请参阅配置 SR-IOV 网络设备

在 Intel VF 和 Mellanox VF 上运行 Data Plane Development Kit (DPDK) 工作负载之间存在一些区别。本节为这两个 VF 类型提供对象配置示例。以下是用于在 Intel NIC 上运行 DPDK 应用程序的 sriovNetworkNodePolicy 对象示例:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: dpdk-nic-1
  namespace: openshift-sriov-network-operator
spec:
  deviceType: vfio-pci 
1

  needVhostNet: true 
2

  nicSelector:
    pfNames: ["ens3f0"]
  nodeSelector:
    node-role.kubernetes.io/worker-cnf: ""
  numVfs: 10
  priority: 99
  resourceName: dpdk_nic_1
---
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: dpdk-nic-1
  namespace: openshift-sriov-network-operator
spec:
  deviceType: vfio-pci
  needVhostNet: true
  nicSelector:
    pfNames: ["ens3f1"]
  nodeSelector:
  node-role.kubernetes.io/worker-cnf: ""
  numVfs: 10
  priority: 99
  resourceName: dpdk_nic_2
1
对于 Intel NIC,deviceType 必须是 vfio-pci
2
如果需要内核与 DPDK 工作负载通信,请添加 needVhostNet: true。这会将 /dev/net/tun/dev/vhost-net 设备挂载到容器中,以便应用可以创建 tap 设备,并将 tap 设备连接到 DPDK 工作负载。

以下是 Mellanox NIC 的 sriovNetworkNodePolicy 对象示例:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: dpdk-nic-1
  namespace: openshift-sriov-network-operator
spec:
  deviceType: netdevice 
1

  isRdma: true 
2

  nicSelector:
    rootDevices:
      - "0000:5e:00.1"
  nodeSelector:
    node-role.kubernetes.io/worker-cnf: ""
  numVfs: 5
  priority: 99
  resourceName: dpdk_nic_1
---
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: dpdk-nic-2
  namespace: openshift-sriov-network-operator
spec:
  deviceType: netdevice
  isRdma: true
  nicSelector:
    rootDevices:
      - "0000:5e:00.0"
  nodeSelector:
    node-role.kubernetes.io/worker-cnf: ""
  numVfs: 5
  priority: 99
  resourceName: dpdk_nic_2
1
对于 Mellanox 设备,deviceType 必须是 netdevice
2
对于 Mellanox 设备,isRdma 必须为 true。Mellanox 卡使用流 Bifurcation 连接到 DPDK 应用程序。这种机制在 Linux 用户空间和内核空间之间分割流量,并增强了行速率处理能力。
22.10.4.2. SR-IOV 网络 Operator 示例

以下是 sriovNetwork 对象的示例定义。在这种情况下,Intel 和 Mellanox 配置是相同的:

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
  name: dpdk-network-1
  namespace: openshift-sriov-network-operator
spec:
  ipam: '{"type": "host-local","ranges": [[{"subnet": "10.0.1.0/24"}]],"dataDir":
   "/run/my-orchestrator/container-ipam-state-1"}' 
1

  networkNamespace: dpdk-test 
2

  spoofChk: "off"
  trust: "on"
  resourceName: dpdk_nic_1 
3

---
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetwork
metadata:
  name: dpdk-network-2
  namespace: openshift-sriov-network-operator
spec:
  ipam: '{"type": "host-local","ranges": [[{"subnet": "10.0.2.0/24"}]],"dataDir":
   "/run/my-orchestrator/container-ipam-state-1"}'
  networkNamespace: dpdk-test
  spoofChk: "off"
  trust: "on"
  resourceName: dpdk_nic_2
1
您可以使用不同的 IP 地址管理 (IPAM) 实现,如 Whereabouts。如需更多信息,请参阅使用 Whereabouts 进行动态 IP 地址分配配置
2
您必须请求创建网络附加定义的 networkNamespace。您必须在 openshift-sriov-network-operator 命名空间内创建 sriovNetwork CR。
3
resourceName 值必须与在 sriovNetworkNodePolicy 下创建的 resourceName 相匹配。
22.10.4.3. DPDK 基础工作负载示例

以下是数据平面开发套件 (DPDK) 容器的示例:

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Namespace
metadata:
  name: dpdk-test
---
apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/networks: '[ 
1

     {
      "name": "dpdk-network-1",
      "namespace": "dpdk-test"
     },
     {
      "name": "dpdk-network-2",
      "namespace": "dpdk-test"
     }
   ]'
    irq-load-balancing.crio.io: "disable" 
2

    cpu-load-balancing.crio.io: "disable"
    cpu-quota.crio.io: "disable"
  labels:
    app: dpdk
  name: testpmd
  namespace: dpdk-test
spec:
  runtimeClassName: performance-performance 
3

  containers:
    - command:
        - /bin/bash
        - -c
        - sleep INF
      image: registry.redhat.io/openshift4/dpdk-base-rhel8
      imagePullPolicy: Always
      name: dpdk
      resources: 
4

        limits:
          cpu: "16"
          hugepages-1Gi: 8Gi
          memory: 2Gi
        requests:
          cpu: "16"
          hugepages-1Gi: 8Gi
          memory: 2Gi
      securityContext:
        capabilities:
          add:
            - IPC_LOCK
            - SYS_RESOURCE
            - NET_RAW
            - NET_ADMIN
        runAsUser: 0
      volumeMounts:
        - mountPath: /mnt/huge
          name: hugepages
  terminationGracePeriodSeconds: 5
  volumes:
    - emptyDir:
        medium: HugePages
      name: hugepages
1
请求您需要的 SR-IOV 网络。设备的资源将自动注入。
2
禁用 CPU 和 IRQ 负载均衡基础。如需更多信息,请参阅禁用单个 pod 的中断处理
3
runtimeClass 设置为 performance-performance。不要将 runtimeClass 设置为 HostNetworkprivileged
4
为请求和限值请求相同数量的资源,以启动具有 Guaranteed 服务质量 (QoS) 的 pod。
注意

不要使用 SLEEP 启动容器集,然后执行到容器集以启动 testpmd 或 DPDK 工作负载。这可添加额外的中断,因为 exec 进程没有固定到任何 CPU。

22.10.4.4. testpmd 脚本示例

以下是运行 testpmd 的示例脚本:

Copy to Clipboard Toggle word wrap
#!/bin/bash
set -ex
export CPU=$(cat /sys/fs/cgroup/cpuset/cpuset.cpus)
echo ${CPU}

dpdk-testpmd -l ${CPU} -a ${PCIDEVICE_OPENSHIFT_IO_DPDK_NIC_1} -a ${PCIDEVICE_OPENSHIFT_IO_DPDK_NIC_2} -n 4 -- -i --nb-cores=15 --rxd=4096 --txd=4096 --rxq=7 --txq=7 --forward-mode=mac --eth-peer=0,50:00:00:00:00:01 --eth-peer=1,50:00:00:00:00:02

这个示例使用两个不同的 sriovNetwork CR。环境变量包含分配给 pod 的虚拟功能 (VF) PCI 地址。如果您在 pod 定义中使用相同的网络,您必须分割 pciAddress。配置流量生成器的正确 MAC 地址非常重要。这个示例使用自定义 MAC 地址。

22.10.5. 在带有 Mellanox NIC 的 RDMA 模式中使用虚拟功能

重要

RDMA over Converged Ethernet (RoCE) 只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

在 OpenShift Container Platform 上使用 RDMA 时,RDMA over Converged Ethernet (RoCE) 是唯一支持的模式。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 安装 SR-IOV Network Operator。
  • 以具有 cluster-admin 权限的用户身份登录。

流程

  1. 创建以下 SriovNetworkNodePolicy 对象,然后在 mlx-rdma-node-policy.yaml 文件中保存 YAML。

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: mlx-rdma-node-policy
      namespace: openshift-sriov-network-operator
    spec:
      resourceName: mlxnics
      nodeSelector:
        feature.node.kubernetes.io/network-sriov.capable: "true"
      priority: <priority>
      numVfs: <num>
      nicSelector:
        vendor: "15b3"
        deviceID: "1015" 
    1
    
        pfNames: ["<pf_name>", ...]
        rootDevices: ["<pci_bus_id>", "..."]
      deviceType: netdevice 
    2
    
      isRdma: true 
    3
    1
    指定 SR-IOV 网络设备的设备十六进制代码。
    2
    指定到 netdevice 的虚拟功能 (VF) 的驱动程序类型。
    3
    启用 RDMA 模式。
    注意

    如需了解 inSriovNetworkNodePolicy 的每个选项的详情,请参阅 Configuring SR-IOV network devices 部分。

    当应用由 SriovNetworkNodePolicy 对象中指定的配置时,SR-IOV Operator 可能会排空节点,并在某些情况下会重启节点。它可能需要几分钟时间来应用配置更改。确保集群中有足够的可用节点,用以预先处理被驱除的工作负载。

    应用配置更新后,openshift-sriov-network-operator 命名空间中的所有 pod 将变为 Running 状态。

  2. 运行以下命令来创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-rdma-node-policy.yaml
  3. 创建以下 SriovNetwork 对象,然后在 mlx-rdma-network.yaml 文件中保存 YAML。

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetwork
    metadata:
      name: mlx-rdma-network
      namespace: openshift-sriov-network-operator
    spec:
      networkNamespace: <target_namespace>
      ipam: |- 
    1
    
    # ...
      vlan: <vlan>
      resourceName: mlxnics
    1
    为 ipam CNI 插件指定一个配置对象做为一个 YAML 块 scalar。该插件管理附加定义的 IP 地址分配。
    注意

    如需 SriovNetwork 中的每个选项的详细说明,请参阅"Configuring SR-IOV additional network" 部分。

    一个可选的库 app-netutil 提供了多种 API 方法来收集有关容器父 pod 的网络信息。

  4. 运行以下命令来创建 SriovNetworkNodePolicy 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-rdma-network.yaml
  5. 创建以下 Pod spec,然后在 mlx-rdma-pod.yaml 文件中保存 YAML。

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Pod
    metadata:
      name: rdma-app
      namespace: <target_namespace> 
    1
    
      annotations:
        k8s.v1.cni.cncf.io/networks: mlx-rdma-network
    spec:
      containers:
      - name: testpmd
        image: <RDMA_image> 
    2
    
        securityContext:
          runAsUser: 0
          capabilities:
            add: ["IPC_LOCK","SYS_RESOURCE","NET_RAW"] 
    3
    
        volumeMounts:
        - mountPath: /mnt/huge 
    4
    
          name: hugepage
        resources:
          limits:
            memory: "1Gi"
            cpu: "4" 
    5
    
            hugepages-1Gi: "4Gi" 
    6
    
          requests:
            memory: "1Gi"
            cpu: "4"
            hugepages-1Gi: "4Gi"
        command: ["sleep", "infinity"]
      volumes:
      - name: hugepage
        emptyDir:
          medium: HugePages
    1
    指定 target_namespace,它与 SriovNetwork 对象 mlx-rdma-network 创建于的命令空间相同。如果要在其他命名空间中创建 pod,在 Pod spec 和 SriovNetwork 对象中更改 target_namespace
    2
    指定包含应用程序和应用程序使用的 RDMA 库的 RDMA 镜像。
    3
    指定容器内的应用程序进行大页分配、系统资源分配和网络接口访问所需的额外功能。
    4
    /mnt/huge 下将巨页卷挂载到 RDMA pod。巨页卷由 emptyDir 卷类型支持,媒介是 Hugepages
    5
    指定 CPU 数量。RDMA pod 通常需要从 kubelet 分配专用 CPU。这可以通过将 CPU Manager 策略设置为 static,并创建带有有保障的 QoS 的 pod 来实现。
    6
    指定巨页大小 hugepages-1Gihugepages-2Mi 以及分配给 RDMA pod 的巨页数量。单独配置 2Mi1Gi 巨页。配置 1Gi 巨页需要在节点中添加内核参数。
  6. 运行以下命令来创建 RDMA pod:

    Copy to Clipboard Toggle word wrap
    $ oc create -f mlx-rdma-pod.yaml

22.10.6. 在 OpenStack 上使用 OVS-DPDK 的集群测试 pod 模板

以下 testpmd pod 演示了使用巨页、保留 CPU 和 SR-IOV 端口创建容器。

testpmd pod 示例

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: testpmd-dpdk
  namespace: mynamespace
  annotations:
    cpu-load-balancing.crio.io: "disable"
    cpu-quota.crio.io: "disable"
# ...
spec:
  containers:
  - name: testpmd
    command: ["sleep", "99999"]
    image: registry.redhat.io/openshift4/dpdk-base-rhel8:v4.9
    securityContext:
      capabilities:
        add: ["IPC_LOCK","SYS_ADMIN"]
      privileged: true
      runAsUser: 0
    resources:
      requests:
        memory: 1000Mi
        hugepages-1Gi: 1Gi
        cpu: '2'
        openshift.io/dpdk1: 1 
1

      limits:
        hugepages-1Gi: 1Gi
        cpu: '2'
        memory: 1000Mi
        openshift.io/dpdk1: 1
    volumeMounts:
      - mountPath: /mnt/huge
        name: hugepage
        readOnly: False
  runtimeClassName: performance-cnf-performanceprofile 
2

  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages

1
本例中名为 dpdk1 是一个用户创建的 SriovNetworkNodePolicy 资源。您可以为您创建的资源替换此名称。
2
如果您的性能配置集没有命名为 cnf-performance profile,请将该字符串替换为正确的性能配置集名称。

22.10.7. 在 OpenStack 上使用 OVS 硬件卸载的集群测试 pod 模板

以下 testpmd pod 在 Red Hat OpenStack Platform (RHOSP) 上演示了 Open vSwitch (OVS) 硬件卸载。

testpmd pod 示例

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Pod
metadata:
  name: testpmd-sriov
  namespace: mynamespace
  annotations:
    k8s.v1.cni.cncf.io/networks: hwoffload1
spec:
  runtimeClassName: performance-cnf-performanceprofile 
1

  containers:
  - name: testpmd
    command: ["sleep", "99999"]
    image: registry.redhat.io/openshift4/dpdk-base-rhel8:v4.9
    securityContext:
      capabilities:
        add: ["IPC_LOCK","SYS_ADMIN"]
      privileged: true
      runAsUser: 0
    resources:
      requests:
        memory: 1000Mi
        hugepages-1Gi: 1Gi
        cpu: '2'
      limits:
        hugepages-1Gi: 1Gi
        cpu: '2'
        memory: 1000Mi
    volumeMounts:
      - mountPath: /mnt/huge
        name: hugepage
        readOnly: False
  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages

1
如果您的性能配置集没有命名为 cnf-performance profile,请将该字符串替换为正确的性能配置集名称。

22.10.8. 其他资源

22.11. 使用 pod 级别绑定

在 pod 级别的绑定对于启用需要高可用性和更多吞吐量的 pod 内的工作负载至关重要。使用 pod 级别绑定,您可以在内核模式接口上从多个根 I/O 虚拟化(SR-IOV)虚拟功能接口创建绑定接口。SR-IOV 虚拟功能传递到 pod,并附加到内核驱动程序中。

需要 pod 级别绑定的一个场景是从不同物理功能的多个 SR-IOV 虚拟功能创建绑定接口。可以利用主机上的两个不同物理功能创建绑定接口,以便在 pod 级别上实现高可用性。

有关创建 SR-IOV 网络、网络策略、网络附加定义和 pod 等任务的指导,请参阅配置 SR-IOV 网络设备

22.11.1. 从两个 SR-IOV 接口配置绑定接口

绑定可让多个网络接口聚合到一个逻辑 "bonded" 接口。绑定 Container Network Interface (Bond-CNI) 将绑定功能引入容器中。

Bond-CNI 可使用单根 I/O 虚拟化 (SR-IOV) 虚拟功能创建,并将它们放在容器网络命名空间中。

OpenShift Container Platform 仅支持使用 SR-IOV 虚拟功能的 Bond-CNI。SR-IOV Network Operator 提供了管理虚拟功能所需的 SR-IOV CNI 插件。不支持其他 CNI 或接口类型。

先决条件

  • 必须安装 SR-IOV Network Operator,并配置为获取容器中的虚拟功能。
  • 要配置 SR-IOV 接口,必须为每个接口创建一个 SR-IOV 网络和策略。
  • SR-IOV Network Operator 根据定义的 SR-IOV 网络和策略,为每个 SR-IOV 接口创建一个网络附加定义。
  • linkState 设置为 SR-IOV 虚拟功能的默认值 auto
22.11.1.1. 创建绑定网络附加定义

现在,SR-IOV 虚拟功能可用,您可以创建一个绑定网络附加定义。

Copy to Clipboard Toggle word wrap
apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: bond-net1
      namespace: demo
    spec:
      config: '{
      "type": "bond", 
1

      "cniVersion": "0.3.1",
      "name": "bond-net1",
      "mode": "active-backup", 
2

      "failOverMac": 1, 
3

      "linksInContainer": true, 
4

      "miimon": "100",
      "mtu": 1500,
      "links": [ 
5

            {"name": "net1"},
            {"name": "net2"}
        ],
      "ipam": {
            "type": "host-local",
            "subnet": "10.56.217.0/24",
            "routes": [{
            "dst": "0.0.0.0/0"
            }],
            "gateway": "10.56.217.1"
        }
      }'
1
cni-type 始终设置为 bond
2
mode 属性指定绑定模式。
注意

支持的绑定模式有:

  • balance-rr - 0
  • active-backup - 1
  • balance-xor - 2

对于 balance-rrbalance-xor 模式,您必须为 SR-IOV 虚拟功能将 trust 模式设置为 on

3
active-backup 模式的 failover 属性是必需的,必须设为 1。
4
linksInContainer=true 标志告知 Bond CNI 在容器内找到所需的接口。默认情况下,Bond CNI 会查找主机上的这些接口,该接口无法与 SRIOV 和 Multus 集成。
5
links 部分定义将用于创建绑定的接口。默认情况下,Multus 将附加的接口命名为 "net",再加上一个连续的数字。
22.11.1.2. 使用绑定接口创建 pod
  1. 使用名为 example podbonding.yaml 的 YAML 文件创建 pod 来测试设置,其内容类似以下示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
        kind: Pod
        metadata:
          name: bondpod1
          namespace: demo
          annotations:
            k8s.v1.cni.cncf.io/networks: demo/sriovnet1, demo/sriovnet2, demo/bond-net1 
    1
    
        spec:
          containers:
          - name: podexample
            image: quay.io/openshift/origin-network-interface-bond-cni:4.11.0
            command: ["/bin/bash", "-c", "sleep INF"]
    1
    注意网络注解:它包含两个 SR-IOV 网络附加,以及一个绑定网络附加。绑定附加使用两个 SR-IOV 接口作为绑定的端口接口。
  2. 运行以下命令来应用 yaml:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f podbonding.yaml
  3. 使用以下命令检查 pod 接口:

    Copy to Clipboard Toggle word wrap
    $ oc rsh -n demo bondpod1
    sh-4.4#
    sh-4.4# ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    valid_lft forever preferred_lft forever
    3: eth0@if150: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP
    link/ether 62:b1:b5:c8:fb:7a brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.122/24 brd 10.244.1.255 scope global eth0
    valid_lft forever preferred_lft forever
    4: net3: <BROADCAST,MULTICAST,UP,LOWER_UP400> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 9e:23:69:42:fb:8a brd ff:ff:ff:ff:ff:ff 
    1
    
    inet 10.56.217.66/24 scope global bond0
    valid_lft forever preferred_lft forever
    43: net1: <BROADCAST,MULTICAST,UP,LOWER_UP800> mtu 1500 qdisc mq master bond0 state UP qlen 1000
    link/ether 9e:23:69:42:fb:8a brd ff:ff:ff:ff:ff:ff 
    2
    
    44: net2: <BROADCAST,MULTICAST,UP,LOWER_UP800> mtu 1500 qdisc mq master bond0 state UP qlen 1000
    link/ether 9e:23:69:42:fb:8a brd ff:ff:ff:ff:ff:ff 
    3
    1
    绑定接口自动命名为 net3。要设置特定的接口名称,请将 @name 后缀添加到 pod 的 k8s.v1.cni.cncf.io/networks 注解。
    2
    net1 接口基于 SR-IOV 虚拟功能。
    3
    net2 接口基于 SR-IOV 虚拟功能。
    注意

    如果在 pod 注解中没有配置接口名称,接口名称会自动分配为 net<n>,其中 <n>1 开始。

  4. 可选: 如果要为 example bond0 设置一个特定的接口名称,请编辑 k8s.v1.cni.cncf.io/networks 注解,并将 bond0 设为接口名称,如下所示:

    Copy to Clipboard Toggle word wrap
    annotations:
            k8s.v1.cni.cncf.io/networks: demo/sriovnet1, demo/sriovnet2, demo/bond-net1@bond0

22.12. 配置硬件卸载 (offloading)

作为集群管理员,您可以在兼容节点上配置硬件卸载,以提高数据处理性能并减少主机 CPU 的负载。

22.12.1. 关于硬件卸载

Open vSwitch 硬件卸载是一种处理网络任务的方法,方法是将它们从 CPU 中分离出来,并将它们卸载到网络接口控制器上的专用处理器。因此,集群可从更快的数据传输速度、CPU 工作负载减少并降低计算成本中受益。

此功能的关键元素是网络接口控制器的现代类,称为 SmartNIC。SmartNIC 是一个网络接口控制器,它可以处理计算密集型网络处理任务。与专用图形卡可提高图形性能的方式相同,T SmartNIC 可改进网络性能。在各个情形中,专用处理器提高了特定类型的处理任务的性能。

在 OpenShift Container Platform 中,您可以为具有兼容 SmartNIC 的裸机节点配置硬件卸载。SR-IOV Network Operator 配置并启用硬件卸载。

硬件卸载并不适用于所有工作负载或应用程序类型。只支持以下两种通信类型:

  • pod 到 pod
  • Pod 到服务,其中服务是一个由常规 pod 支持的 ClusterIP 服务

在所有情况下,只有在将 pod 和服务分配给具有兼容 SmartNIC 的节点时,硬件卸载才会发生。假设节点上带有硬件卸载的 pod 会尝试与常规节点上的服务进行通信。常规节点上,所有处理都会在内核中进行,因此 pod 到服务通信的整体性能仅限于该常规节点的最大性能。硬件卸载与 DPDK 应用程序不兼容。

在节点上启用硬件卸载,但没有配置 pod 使用,可能会导致 pod 流量的吞吐量性能降低。您无法为 OpenShift Container Platform 管理的 pod 配置硬件卸载。

22.12.2. 支持的设备

在以下网络接口控制器上支持硬件卸载:

表 22.15. 支持的网络接口控制器
制造商model供应商 ID设备 ID

Mellanox

MT27800 系列 [ConnectX-5]

15b3

1017

Mellanox

MT28880 系列 [ConnectX-5 Ex]

15b3

1019

表 22.16. 技术预览网络接口控制器
制造商model供应商 ID设备 ID

Mellanox

MT2892 系列 [ConnectX-6 Dx]

15b3

101d

Mellanox

MT2894 系列 [ConnectX-6 Lx]

15b3

101f

Mellanox

ConnectX-6 NIC 模式中的 MT42822 BlueField-2

15b3

a2d6

重要

在 ConnectX-6 NIC 模式设备中使用 ConnectX-6 Lx 或 BlueField-2 只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

22.12.3. 先决条件

22.12.4. 将 SR-IOV Network Operator 设置为 systemd 模式

要支持硬件卸载,您必须首先将 SR-IOV Network Operator 设置为 systemd 模式。

先决条件

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

流程

  1. 创建一个 SriovOperatorConfig 自定义资源(CR)以部署所有 SR-IOV Operator 组件:

    1. 创建名为 sriovOperatorConfig.yaml 的文件,其中包含以下 YAML:

      Copy to Clipboard Toggle word wrap
      apiVersion: sriovnetwork.openshift.io/v1
      kind: SriovOperatorConfig
      metadata:
        name: default 
      1
      
        namespace: openshift-sriov-network-operator
      spec:
        enableInjector: true
        enableOperatorWebhook: true
        configurationMode: "systemd" 
      2
      
        logLevel: 2
      1
      SriovOperatorConfig 资源的唯一有效名称是 default,它必须位于部署 Operator 的命名空间中。
      2
      将 SR-IOV Network Operator 设置为 systemd 模式仅与 Open vSwitch 硬件卸载相关。
    2. 运行以下命令来创建资源:

      Copy to Clipboard Toggle word wrap
      $ oc apply -f sriovOperatorConfig.yaml

22.12.5. 为硬件卸载配置机器配置池

要启用硬件卸载,您可以创建一个专用的机器配置池,并将其配置为使用 SR-IOV Network Operator。

先决条件

  1. SR-IOV Network Operator 安装并设置为 systemd 模式。

流程

  1. 为您要使用硬件卸载的机器创建机器配置池。

    1. 创建一个文件,如 mcp-offloading.yaml,其内容类似以下示例:

      Copy to Clipboard Toggle word wrap
      apiVersion: machineconfiguration.openshift.io/v1
      kind: MachineConfigPool
      metadata:
        name: mcp-offloading 
      1
      
      spec:
        machineConfigSelector:
          matchExpressions:
            - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,mcp-offloading]} 
      2
      
        nodeSelector:
          matchLabels:
            node-role.kubernetes.io/mcp-offloading: "" 
      3
      1 2
      用于硬件卸载的机器配置池的名称。
      3
      此节点角色标签用于添加节点到机器配置池。
    2. 应用机器配置池的配置:

      Copy to Clipboard Toggle word wrap
      $ oc create -f mcp-offloading.yaml
  2. 将节点添加到机器配置池。使用池的节点角色标签标记每个节点:

    Copy to Clipboard Toggle word wrap
    $ oc label node worker-2 node-role.kubernetes.io/mcp-offloading=""
  3. 可选: 要验证是否创建了新池,请运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get nodes

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME       STATUS   ROLES                   AGE   VERSION
    master-0   Ready    master                  2d    v1.25.0
    master-1   Ready    master                  2d    v1.25.0
    master-2   Ready    master                  2d    v1.25.0
    worker-0   Ready    worker                  2d    v1.25.0
    worker-1   Ready    worker                  2d    v1.25.0
    worker-2   Ready    mcp-offloading,worker   47h   v1.25.0
    worker-3   Ready    mcp-offloading,worker   47h   v1.25.0

  4. 将此机器配置池添加到 SriovNetworkPoolConfig 自定义资源中:

    1. 创建一个文件,如 sriov-pool-config.yaml,其内容类似以下示例:

      Copy to Clipboard Toggle word wrap
      apiVersion: sriovnetwork.openshift.io/v1
      kind: SriovNetworkPoolConfig
      metadata:
        name: sriovnetworkpoolconfig-offload
        namespace: openshift-sriov-network-operator
      spec:
        ovsHardwareOffloadConfig:
          name: mcp-offloading 
      1
      1
      用于硬件卸载的机器配置池的名称。
    2. 应用配置:

      Copy to Clipboard Toggle word wrap
      $ oc create -f <SriovNetworkPoolConfig_name>.yaml
      注意

      当您应用由 SriovNetworkPoolConfig 对象中指定的配置时,SR-IOV Operator 会排空并重启机器配置池中的节点。

      它可能需要几分钟时间来应用配置更改。

22.12.6. 配置 SR-IOV 网络节点策略

您可以通过创建 SR-IOV 网络节点策略来为节点创建 SR-IOV 网络设备配置。要启用硬件卸载,您必须使用值 "switchdev" 定义 .spec.eSwitchMode 字段。

以下流程为带有硬件卸载的网络接口控制器创建 SR-IOV 接口。

先决条件

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

流程

  1. 创建一个文件,如 sriov-node-policy.yaml,其内容类似以下示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: sriovnetwork.openshift.io/v1
    kind: SriovNetworkNodePolicy
    metadata:
      name: sriov-node-policy <.>
      namespace: openshift-sriov-network-operator
    spec:
      deviceType: netdevice <.>
      eSwitchMode: "switchdev" <.>
      nicSelector:
        deviceID: "1019"
        rootDevices:
        - 0000:d8:00.0
        vendor: "15b3"
        pfNames:
        - ens8f0
      nodeSelector:
        feature.node.kubernetes.io/network-sriov.capable: "true"
      numVfs: 6
      priority: 5
      resourceName: mlxnics

    <.> 自定义资源对象的名称。<.> 必需。vfio-pci 不支持硬件卸载。<.> 必需。

  2. 应用策略的配置:

    Copy to Clipboard Toggle word wrap
    $ oc create -f sriov-node-policy.yaml
    注意

    当您应用由 SriovNetworkPoolConfig 对象中指定的配置时,SR-IOV Operator 会排空并重启机器配置池中的节点。

    它可能需要几分钟时间来应用配置更改。

22.12.6.1. OpenStack 的 SR-IOV 网络节点策略示例

以下示例描述了在 Red Hat OpenStack Platform (RHOSP) 上使用硬件卸载的网络接口控制器 (NIC) 的 SR-IOV 接口。

用于 RHOSP 上带有硬件卸载的 NIC 的 SR-IOV 接口

Copy to Clipboard Toggle word wrap
apiVersion: sriovnetwork.openshift.io/v1
kind: SriovNetworkNodePolicy
metadata:
  name: ${name}
  namespace: openshift-sriov-network-operator
spec:
  deviceType: switchdev
  isRdma: true
  nicSelector:
    netFilter: openstack/NetworkID:${net_id}
  nodeSelector:
    feature.node.kubernetes.io/network-sriov.capable: 'true'
  numVfs: 1
  priority: 99
  resourceName: ${name}

22.12.7. 创建网络附加定义

在定义机器配置池和 SR-IOV 网络节点策略后,您可以为您指定的网络接口卡创建网络附加定义。

先决条件

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

流程

  1. 创建一个文件,如 net-attach-def.yaml,其内容类似以下示例:

    Copy to Clipboard Toggle word wrap
    apiVersion: "k8s.cni.cncf.io/v1"
    kind: NetworkAttachmentDefinition
    metadata:
      name: net-attach-def <.>
      namespace: net-attach-def <.>
      annotations:
        k8s.v1.cni.cncf.io/resourceName: openshift.io/mlxnics <.>
    spec:
      config: '{"cniVersion":"0.3.1","name":"ovn-kubernetes","type":"ovn-k8s-cni-overlay","ipam":{},"dns":{}}'

    <.> 网络附加定义的名称。<.> 网络附加定义的命名空间。<.> 在 SriovNetworkNodePolicy 对象中指定的 spec.resourceName 字段的值。

  2. 应用网络附加定义的配置:

    Copy to Clipboard Toggle word wrap
    $ oc create -f net-attach-def.yaml

验证

  • 运行以下命令,以查看是否存在新定义:

    Copy to Clipboard Toggle word wrap
    $ oc get net-attach-def -A

    输出示例

    Copy to Clipboard Toggle word wrap
    NAMESPACE         NAME             AGE
    net-attach-def    net-attach-def   43h

22.12.8. 在 pod 中添加网络附加定义

创建机器配置池后,SriovNetworkPoolConfigSriovNetworkNodePolicy 自定义资源以及网络附加定义后,您可以通过在 pod 规格中添加网络附加定义来将这些配置应用到 pod。

流程

  • 在 pod 规格中,添加 .metadata.annotations.k8s.v1.cni.cncf.io/networks 字段,并为硬件卸载指定您创建的网络附加定义:

    Copy to Clipboard Toggle word wrap
    ....
    metadata:
      annotations:
        v1.multus-cni.io/default-network: net-attach-def/net-attach-def <.>

    <.> 该值必须是您为硬件卸载而创建的网络附加定义的名称和命名空间。

22.13. 将 Bluefield-2 从 DPU 切换到 NIC

您可以将 Bluefield-2 网络设备从数据处理单元 (DPU) 模式切换到网络接口控制器 (NIC) 模式。

重要

将 Bluefield-2 从数据处理单元 (DPU) 模式切换到网络接口控制器 (NIC) 模式只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围

22.13.1. 将 Bluefield-2 从 DPU 模式切换到 NIC 模式

使用以下步骤将 Bluefield-2 从数据处理单元 (DPU) 模式切换到网络接口控制器 (NIC) 模式。

重要

目前,只支持将 Bluefield-2 从 DPU 切换到 NIC 模式。不支持从 NIC 模式切换到 DPU 模式。

先决条件

  • 已安装 SR-IOV Network Operator。如需更多信息,请参阅"安装 SR-IOV Network Operator"。
  • 您已将 Bluefield-2 更新至最新的固件。如需更多信息,请参阅 NVIDIA BlueField-2 的固件

流程

  1. 输入以下命令为每个 worker 节点添加以下标签:

    Copy to Clipboard Toggle word wrap
    $ oc label node <example_node_name_one> node-role.kubernetes.io/sriov=
    Copy to Clipboard Toggle word wrap
    $ oc label node <example_node_name_two> node-role.kubernetes.io/sriov=
  2. 为 SR-IOV Operator 创建机器配置池,例如:

    Copy to Clipboard Toggle word wrap
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfigPool
    metadata:
      name: sriov
    spec:
      machineConfigSelector:
        matchExpressions:
          - {key: machineconfiguration.openshift.io/role, operator: In, values: [worker,sriov]}
      nodeSelector:
        matchLabels:
                node-role.kubernetes.io/sriov: ""
  3. 将以下 machineconfig.yaml 文件应用到 worker 节点:

    Copy to Clipboard Toggle word wrap
    apiVersion: machineconfiguration.openshift.io/v1
    kind: MachineConfig
    metadata:
      labels:
        machineconfiguration.openshift.io/role: sriov
      name: 99-bf2-dpu
    spec:
      config:
        ignition:
          version: 3.2.0
        storage:
          files:
          - contents:
              source: data:text/plain;charset=utf-8;base64,ZmluZF9jb250YWluZXIoKSB7CiAgY3JpY3RsIHBzIC1vIGpzb24gfCBqcSAtciAnLmNvbnRhaW5lcnNbXSB8IHNlbGVjdCgubWV0YWRhdGEubmFtZT09InNyaW92LW5ldHdvcmstY29uZmlnLWRhZW1vbiIpIHwgLmlkJwp9CnVudGlsIG91dHB1dD0kKGZpbmRfY29udGFpbmVyKTsgW1sgLW4gIiRvdXRwdXQiIF1dOyBkbwogIGVjaG8gIndhaXRpbmcgZm9yIGNvbnRhaW5lciB0byBjb21lIHVwIgogIHNsZWVwIDE7CmRvbmUKISBzdWRvIGNyaWN0bCBleGVjICRvdXRwdXQgL2JpbmRhdGEvc2NyaXB0cy9iZjItc3dpdGNoLW1vZGUuc2ggIiRAIgo=
            mode: 0755
            overwrite: true
            path: /etc/default/switch_in_sriov_config_daemon.sh
        systemd:
          units:
            - name: dpu-switch.service
              enabled: true
              contents: |
                [Unit]
                Description=Switch BlueField2 card to NIC/DPU mode
                RequiresMountsFor=%t/containers
                Wants=network.target
                After=network-online.target kubelet.service
                [Service]
                SuccessExitStatus=0 120
                RemainAfterExit=True
                ExecStart=/bin/bash -c '/etc/default/switch_in_sriov_config_daemon.sh nic || shutdown -r now' 
    1
    
                Type=oneshot
                [Install]
                WantedBy=multi-user.target
    1
    可选:可以选择性地指定特定卡的 PCI 地址,如 ExecStart=/bin/bash -c '/etc/default/switch_in_sriov_config_daemon.sh nic 0000:5e:00.0 || echo done'。默认情况下会选择第一个设备。如果有多个设备,您必须指定要使用的 PCI 地址。在将 Bluefield-2 从 DPU 模式切换到 NIC 模式的所有节点上,PCI 地址必须相同。
  4. 等待 worker 节点重启。重启后,worker 节点上的 Bluefield-2 网络设备切换到 NIC 模式。
  5. 可选:您可能需要重启主机硬件,因为最新的 Bluefield-2 固件版本需要硬件重启来切换到 NIC 模式。

22.14. 卸载 SR-IOV Network Operator

要卸载 SR-IOV Network Operator,您必须删除所有正在运行的 SR-IOV 工作负载,卸载 Operator,并删除 Operator 使用的 webhook。

22.14.1. 卸载 SR-IOV Network Operator

作为集群管理员,您可以卸载 SR-IOV Network Operator。

先决条件

  • 可以使用具有 cluster-admin 权限的账户访问 OpenShift Container Platform 集群。
  • 已安装 SR-IOV Network Operator。

流程

  1. 删除所有 SR-IOV 自定义资源(CR):

    Copy to Clipboard Toggle word wrap
    $ oc delete sriovnetwork -n openshift-sriov-network-operator --all
    Copy to Clipboard Toggle word wrap
    $ oc delete sriovnetworknodepolicy -n openshift-sriov-network-operator --all
    Copy to Clipboard Toggle word wrap
    $ oc delete sriovibnetwork -n openshift-sriov-network-operator --all
  2. 按照 "Deleting Operators from a cluster" 部分的说明从集群中移除 SR-IOV Network Operator。
  3. 卸载 SR-IOV Network Operator 后,删除在集群中保留的 SR-IOV 自定义资源定义:

    Copy to Clipboard Toggle word wrap
    $ oc delete crd sriovibnetworks.sriovnetwork.openshift.io
    Copy to Clipboard Toggle word wrap
    $ oc delete crd sriovnetworknodepolicies.sriovnetwork.openshift.io
    Copy to Clipboard Toggle word wrap
    $ oc delete crd sriovnetworknodestates.sriovnetwork.openshift.io
    Copy to Clipboard Toggle word wrap
    $ oc delete crd sriovnetworkpoolconfigs.sriovnetwork.openshift.io
    Copy to Clipboard Toggle word wrap
    $ oc delete crd sriovnetworks.sriovnetwork.openshift.io
    Copy to Clipboard Toggle word wrap
    $ oc delete crd sriovoperatorconfigs.sriovnetwork.openshift.io
  4. 删除 SR-IOV Webhook:

    Copy to Clipboard Toggle word wrap
    $ oc delete mutatingwebhookconfigurations network-resources-injector-config
    Copy to Clipboard Toggle word wrap
    $ oc delete MutatingWebhookConfiguration sriov-operator-webhook-config
    Copy to Clipboard Toggle word wrap
    $ oc delete ValidatingWebhookConfiguration sriov-operator-webhook-config
  5. 删除 SR-IOV Network Operator 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc delete namespace openshift-sriov-network-operator

第 23 章 OVN-Kubernetes 网络插件

23.1. 关于 OVN-Kubernetes 网络插件

OpenShift Container Platform 集群在 pod 和服务网络中使用虚拟网络。

Red Hat OpenShift Networking 的一部分,OVN-Kubernetes 网络插件是 OpenShift Container Platform 的默认网络供应商。OVN-Kubernetes 基于 Open Virtual Network(OVN),它提供了一个基于 overlay 的网络实现。使用 OVN-Kubernetes 插件的集群还在每个节点上运行 Open vSwitch (OVS)。OVN 在每个节点上配置 OVS 来实现声明的网络配置。

注意

OVN-Kubernetes 是 OpenShift Container Platform 和单节点 OpenShift 部署的默认网络解决方案。

OVN-Kubernetes (来自 OVS 项目)使用许多相同的结构,如开放流规则,以确定数据包通过网络传输的方式。如需更多信息,请参阅 Open Virtual Network 网站

OVN-Kubernetes 是 OVS 的一系列守护进程,用于将虚拟网络配置转换为 OpenFlow 规则。OpenFlow 是一种用于与网络交换机和路由器通信的协议,为远程控制网络设备上的网络流量流提供了方法,让网络管理员能够配置、管理和监控网络流量的流。

OVN-Kubernetes 提供了 OpenFlow 提供的更多高级功能。OVN 支持分布式虚拟路由、分布式逻辑交换机、访问控制、DHCP 和 DNS。OVN 在逻辑流中实施分布式虚拟路由,这些路由等同于开放流。例如,如果您有一个 pod 在网络上发送 DHCP 请求,它会发送出该广播查找 DHCP 地址的逻辑流规则,该逻辑流规则与该数据包匹配,并且响应了网关,DNS 服务器是 IP 地址等。

OVN-Kubernetes 在每个节点上运行一个守护进程。数据库和 OVN 控制器都有守护进程集,每个节点上运行的 OVN 控制器。OVN 控制器在节点上对 Open vSwitch 守护进程进行编程,以支持网络提供程序功能;出口 IP、防火墙、路由器、混合网络、IPSEC 加密、IPv6 加密、网络策略日志、网络策略日志、硬件卸载和多播。

23.1.1. OVN-Kubernetes 目的

OVN-Kubernetes 网络插件是一个开源、功能齐全的 Kubernetes CNI 插件,它使用 Open Virtual Network (OVN)来管理网络流量。OVN 是一个社区开发、与供应商无关的网络虚拟化解决方案。OVN-Kubernetes 网络插件:

  • 使用 OVN(开源虚拟网络)管理网络流量。OVN 是一个社区开发、与供应商无关的网络虚拟化解决方案。
  • 实现 Kubernetes 网络策略支持,包括入口和出口规则。
  • 使用 Geneve(通用网络虚拟化封装)协议而不是 VXLAN 在节点间创建覆盖网络。

OVN-Kubernetes 网络插件比 OpenShift SDN 提供以下优点。

  • 在支持的平台上完全支持 IPv6 单堆栈和 IPv4/IPv6 双栈网络
  • 支持 Linux 和 Microsoft Windows 工作负载中的混合集群
  • 可选的、集群内通信的 IPsec 加密
  • 将网络数据处理从主机 CPU 卸载到兼容的网卡和数据处理单元 (DPU)

23.1.2. 支持的网络插件功能列表

Red Hat OpenShift Networking 为网络插件(OpenShift SDN 和 OVN-Kubernetes)提供了两个选项,用于网络插件。下表总结了这两个网络插件的当前功能支持:

表 23.1. 默认 CNI 网络插件功能比较
功能OpenShift SDNOVN-Kubernetes

出口 IP

支持

支持

出口防火墙

支持

支持 [1]

出口路由器

支持

支持 [2]

混合网络

不支持

支持

集群内通信的 IPsec 加密

不支持

支持

IPv4 单栈

支持

支持

IPv6 单栈

不支持

支持 [3]

IPv4/IPv6 双栈

不支持

支持的 [4]

IPv6/IPv4 双栈

不支持

支持 [5]

Kubernetes 网络策略

支持

支持

Kubernetes 网络策略日志

不支持

支持

硬件卸载

不支持

支持

多播

支持

支持

  1. 在 OpenShift SDN 中,出口防火墙也称为出口网络策略。这和网络策略出口不同。
  2. OVN-Kubernetes 的出口路由器仅支持重定向模式。
  3. 裸机平台上的 IPv6 单堆栈网络。
  4. 裸机、IBM Power® 和 IBM Z® 平台上的 IPv4/IPv6 双栈网络。
  5. 裸机和 IBM Power® 平台上的 IPv6/IPv4 双栈网络。

23.1.3. OVN-Kubernetes IPv6 和双栈限制

OVN-Kubernetes 网络插件有以下限制:

  • 对于为双栈网络配置的集群,IPv4 和 IPv6 流量都必须使用与默认网关相同的网络接口。如果不满足此要求,则 ovnkube-node 守护进程集中的主机上的容器集进入 CrashLoopBackOff 状态。如果您使用 oc get pod -n openshift-ovn-kubernetes -l app=ovnkube-node -o yaml 等命令显示 pod,则 status 字段包含多个有关默认网关的消息,如以下输出所示:

    Copy to Clipboard Toggle word wrap
    I1006 16:09:50.985852   60651 helper_linux.go:73] Found default gateway interface br-ex 192.168.127.1
    I1006 16:09:50.985923   60651 helper_linux.go:73] Found default gateway interface ens4 fe80::5054:ff:febe:bcd4
    F1006 16:09:50.985939   60651 ovnkube.go:130] multiple gateway interfaces detected: br-ex ens4

    唯一的解析是重新配置主机网络,以便两个 IP 系列都针对默认网关使用相同的网络接口。

  • 对于为双栈网络配置的集群,IPv4 和 IPv6 路由表必须包含默认网关。如果不满足此要求,则 ovnkube-node 守护进程集中的主机上的容器集进入 CrashLoopBackOff 状态。如果您使用 oc get pod -n openshift-ovn-kubernetes -l app=ovnkube-node -o yaml 等命令显示 pod,则 status 字段包含多个有关默认网关的消息,如以下输出所示:

    Copy to Clipboard Toggle word wrap
    I0512 19:07:17.589083  108432 helper_linux.go:74] Found default gateway interface br-ex 192.168.123.1
    F0512 19:07:17.589141  108432 ovnkube.go:133] failed to get default gateway interface

    唯一的解析是重新配置主机网络,以便两个 IP 系列都包含默认网关。

23.1.4. 会话关联性

会话关联性是适用于 Kubernetes Service 对象的功能。如果要确保每次连接到 <service_VIP>:<Port> 时,您可以使用 会话关联性,流量始终被加载到同一后端。如需更多信息,包括如何根据客户端的 IP 地址设置会话关联性,请参阅会话关联性

会话关联性的粘性超时

OpenShift Container Platform 的 OVN-Kubernetes 网络插件根据最后一个数据包计算来自客户端的会话的粘性超时。例如,如果您运行 curl 命令 10 次,则粘性会话计时器从第十个数据包开始,而不是第一个数据包。因此,如果客户端不断联系该服务,则会话永远不会超时。当服务没有收到 timeoutSeconds 参数所设定的时间的数据包时,超时开始。

23.2. OVN-Kubernetes 架构

23.2.1. OVN-Kubernetes 架构简介

下图显示了 OVN-Kubernetes 架构。

图 23.1. OVK-Kubernetes 架构

OVN-Kubernetes 架构

主要组件是:

  • Cloud Management System (CMS) - OVN 的特定平台客户端,为 OVN 集成提供 CMS 特定的插件。该插件将云管理系统的逻辑网络配置概念转换为 OVN 理解的 CMS 配置数据库中。
  • OVN 北向数据库(nbdb) - 存储由 CMS 插件传递的逻辑网络配置。
  • OVN 南向数据库 (sbdb) - 存储每个节点上的 OpenVswitch (OVS)系统的物理和逻辑网络配置状态,包括绑定它们的表。
  • ovn-northd - 这是 nbdbsbdb 之间的中介客户端。它以传统网络概念的形式将逻辑网络配置(从 nbdb )转换为其下面的 sbdb 中的逻辑数据路径流。容器名称为 northd,它在 ovnkube-master 容器集内运行。
  • ovn-controller - 这是与 OVS 和 hypervisor 交互的 OVN 代理,适用于 sbdb 所需的任何信息或更新。ovn-controllersbdb 读取逻辑流,将它们转换为 OpenFlow 流,并将它们发送到节点的 OVS 守护进程。容器名称为 ovn-controller,它在 ovnkube-node pod 中运行。

OVN 北向数据库具有通过云管理系统(CMS)传递到它的逻辑网络配置。OVN 北向数据库包含网络的当前状态,以逻辑端口、逻辑交换机、逻辑路由器等形式显示。ovn-northd (northd 容器) 连接到 OVN 北向数据库和 OVN 南向数据库。它以传统网络概念的形式将逻辑网络配置转换为 OVN 北向数据库中的逻辑数据路径流。

OVN 南向数据库具有网络的物理和逻辑表示,并将它们连接在一起。集群中的每个节点都表示在南向数据库中,您可以看到连接到它的端口。它还包含所有逻辑流,逻辑流与在每个节点上运行的 ovn-controller 进程共享,ovn-controller 将它们转换为 OpenFlow 规则到程序 Open vSwitch

Kubernetes control plane 节点各自包含一个 ovnkube-master pod,用于为 OVN 北向和南向数据库托管容器。所有 OVN 北向数据库形成一个 Raft 集群,所有南向数据库组成一个单独的 Raft 集群。在任何给定时间,单个 ovnkube-master 是领导机,其他 ovnkube-master pod 都是 followers。

23.2.2. 列出 OVN-Kubernetes 项目中的所有资源

查找在 OVN-Kubernetes 项目中运行的资源和容器对于帮助您了解 OVN-Kubernetes 网络实施非常重要。

先决条件

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

流程

  1. 运行以下命令,以获取 OVN-Kubernetes 项目中的所有资源、端点和 ConfigMap

    Copy to Clipboard Toggle word wrap
    $ oc get all,ep,cm -n openshift-ovn-kubernetes

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                       READY   STATUS    RESTARTS      AGE
    pod/ovnkube-master-9g7zt   6/6     Running   1 (48m ago)   57m
    pod/ovnkube-master-lqs4v   6/6     Running   0             57m
    pod/ovnkube-master-vxhtq   6/6     Running   0             57m
    pod/ovnkube-node-9k9kc     5/5     Running   0             57m
    pod/ovnkube-node-jg52r     5/5     Running   0             51m
    pod/ovnkube-node-k8wf7     5/5     Running   0             57m
    pod/ovnkube-node-tlwk6     5/5     Running   0             47m
    pod/ovnkube-node-xsvnk     5/5     Running   0             57m
    
    NAME                            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)             AGE
    service/ovn-kubernetes-master   ClusterIP   None         <none>        9102/TCP            57m
    service/ovn-kubernetes-node     ClusterIP   None         <none>        9103/TCP,9105/TCP   57m
    service/ovnkube-db              ClusterIP   None         <none>        9641/TCP,9642/TCP   57m
    
    NAME                            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR                                                 AGE
    daemonset.apps/ovnkube-master   3         3         3       3            3           beta.kubernetes.io/os=linux,node-role.kubernetes.io/master=   57m
    daemonset.apps/ovnkube-node     5         5         5       5            5           beta.kubernetes.io/os=linux                                   57m
    
    NAME                              ENDPOINTS                                                        AGE
    endpoints/ovn-kubernetes-master   10.0.132.11:9102,10.0.151.18:9102,10.0.192.45:9102               57m
    endpoints/ovn-kubernetes-node     10.0.132.11:9105,10.0.143.72:9105,10.0.151.18:9105 + 7 more...   57m
    endpoints/ovnkube-db              10.0.132.11:9642,10.0.151.18:9642,10.0.192.45:9642 + 3 more...   57m
    
    NAME                                 DATA   AGE
    configmap/control-plane-status       1      55m
    configmap/kube-root-ca.crt           1      57m
    configmap/openshift-service-ca.crt   1      57m
    configmap/ovn-ca                     1      57m
    configmap/ovn-kubernetes-master      0      55m
    configmap/ovnkube-config             1      57m
    configmap/signer-ca                  1      57m

    在 control plane 节点上运行三个 ovnkube-masters,两个守护进程集用于部署 ovnkube-masterovnkube-node pod。集群中的每个节点都有一个 ovnkube-node pod。在本例中为 5 个,因为集群中的每个节点都有一个 ovnkube-node,因此集群中有五个节点。ovnkube-config ConfigMap 具有由 online-master 和 ovnkube-node 启动的 OpenShift Container Platform OVN-Kubernetes 配置。ovn-kubernetes-master ConfigMap 具有当前在线 master 领导的信息。

  2. 运行以下命令,列出 ovnkube-master pod 中的所有容器:

    Copy to Clipboard Toggle word wrap
    $ oc get pods ovnkube-master-9g7zt \
    -o jsonpath='{.spec.containers[*].name}' -n openshift-ovn-kubernetes

    预期输出

    Copy to Clipboard Toggle word wrap
    northd nbdb kube-rbac-proxy sbdb ovnkube-master ovn-dbchecker

    ovnkube-master pod 由几个容器组成。它负责托管北向数据库(nbdb 容器)、南向数据库(sbdb 容器),监视 pod、egressIP、命名空间、服务、端点、出口防火墙和网络策略并将其写入北向数据库(ovnkube-master pod),以及管理 pod 子网分配给节点。

  3. 运行以下命令,列出 ovnkube-node pod 中的所有容器:

    Copy to Clipboard Toggle word wrap
    $ oc get pods ovnkube-node-jg52r \
    -o jsonpath='{.spec.containers[*].name}' -n openshift-ovn-kubernetes

    预期输出

    Copy to Clipboard Toggle word wrap
    ovn-controller ovn-acl-logging kube-rbac-proxy kube-rbac-proxy-ovn-metrics ovnkube-node

    ovnkube-node pod 有一个容器 (ovn-controller),它驻留在每个 OpenShift Container Platform 节点上。每个节点的 ovn-controller 将 OVN 北向数据库连接到 OVN 南向数据库,以了解 OVN 配置。ovn-controller 将南向连接到 ovs-vswitchd 作为 OpenFlow 控制器,以控制网络流量,以及本地 ovsdb-server,以允许它监控和控制 Open vSwitch 配置。

23.2.3. 列出 OVN-Kubernetes 北向数据库内容

要理解逻辑流规则,您需要检查北向数据库,并了解哪些对象是如何转换为逻辑流规则。OVN Raft leader 上会显示最新信息,这个过程描述了如何找到 Raft 领导,然后查询它以列出 OVN 北向数据库内容。

先决条件

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

流程

  1. 查找北向数据库的 OVN Raft 领导。

    注意

    Raft 领导机存储最新信息。

    1. 运行以下命令列出 pod:

      Copy to Clipboard Toggle word wrap
      $ oc get po -n openshift-ovn-kubernetes

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                   READY   STATUS    RESTARTS       AGE
      ovnkube-master-7j97q   6/6     Running   2 (148m ago)   149m
      ovnkube-master-gt4ms   6/6     Running   1 (140m ago)   147m
      ovnkube-master-mk6p6   6/6     Running   0              148m
      ovnkube-node-8qvtr     5/5     Running   0              149m
      ovnkube-node-fqdc9     5/5     Running   0              149m
      ovnkube-node-tlfwv     5/5     Running   0              149m
      ovnkube-node-wlwkn     5/5     Running   0              142m

    2. 随机选择一个 master pod,并运行以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc exec -n openshift-ovn-kubernetes ovnkube-master-7j97q \
      -- /usr/bin/ovn-appctl -t /var/run/ovn/ovnnb_db.ctl \
      --timeout=3 cluster/status OVN_Northbound

      输出示例

      Copy to Clipboard Toggle word wrap
      Defaulted container "northd" out of: northd, nbdb, kube-rbac-proxy, sbdb, ovnkube-master, ovn-dbchecker
      1c57
      Name: OVN_Northbound
      Cluster ID: c48a (c48aa5c0-a704-4c77-a066-24fe99d9b338)
      Server ID: 1c57 (1c57b6fc-2849-49b7-8679-fbf18bafe339)
      Address: ssl:10.0.147.219:9643
      Status: cluster member
      Role: follower 
      1
      
      Term: 5
      Leader: 2b4f 
      2
      
      Vote: unknown
      
      Election timer: 10000
      Log: [2, 3018]
      Entries not yet committed: 0
      Entries not yet applied: 0
      Connections: ->0000 ->0000 <-8844 <-2b4f
      Disconnections: 0
      Servers:
          1c57 (1c57 at ssl:10.0.147.219:9643) (self)
          8844 (8844 at ssl:10.0.163.212:9643) last msg 8928047 ms ago
          2b4f (2b4f at ssl:10.0.242.240:9643) last msg 620 ms ago 
      3

      1
      此 pod 被识别为 follower
      2
      领导机被识别为 2b4f
      3
      2b4f 位于 IP 地址 10.0.242.240
    3. 使用以下命令,查找在 IP Address 10.0.242.240 上运行的 ovnkube-master pod:

      Copy to Clipboard Toggle word wrap
      $ oc get po -o wide -n openshift-ovn-kubernetes | grep 10.0.242.240 | grep -v ovnkube-node

      输出示例

      Copy to Clipboard Toggle word wrap
      ovnkube-master-gt4ms   6/6     Running             1 (143m ago)   150m   10.0.242.240   ip-10-0-242-240.ec2.internal   <none>           <none>

      ovnkube-master-gt4ms pod 在 IP Address 10.0.242.240 上运行。

  2. 运行以下命令以显示北向数据库中的所有对象:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-gt4ms \
    -c northd -- ovn-nbctl show

    此处列出输出太长。列表中包含 NAT 规则、逻辑交换机、负载均衡器等。

    运行以下命令,以显示可用于命令 ovn-nbctl 的选项:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-mk6p6 \
    -c northd ovn-nbctl --help

    您可以使用以下命令缩小并专注于特定组件:

  3. 运行以下命令以显示逻辑路由器列表:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-gt4ms \
    -c northd -- ovn-nbctl lr-list

    输出示例

    Copy to Clipboard Toggle word wrap
    f971f1f3-5112-402f-9d1e-48f1d091ff04 (GR_ip-10-0-145-205.ec2.internal)
    69c992d8-a4cf-429e-81a3-5361209ffe44 (GR_ip-10-0-147-219.ec2.internal)
    7d164271-af9e-4283-b84a-48f2a44851cd (GR_ip-10-0-163-212.ec2.internal)
    111052e3-c395-408b-97b2-8dd0a20a29a5 (GR_ip-10-0-165-9.ec2.internal)
    ed50ce33-df5d-48e8-8862-2df6a59169a0 (GR_ip-10-0-209-170.ec2.internal)
    f44e2a96-8d1e-4a4d-abae-ed8728ac6851 (GR_ip-10-0-242-240.ec2.internal)
    ef3d0057-e557-4b1a-b3c6-fcc3463790b0 (ovn_cluster_router)

    注意

    在这个输出中,您可以看到每个节点中存在路由器,再加上 ovn_cluster_router

  4. 运行以下命令以显示逻辑交换机列表:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-gt4ms \
    -c northd -- ovn-nbctl ls-list

    输出示例

    Copy to Clipboard Toggle word wrap
    82808c5c-b3bc-414a-bb59-8fec4b07eb14 (ext_ip-10-0-145-205.ec2.internal)
    3d22444f-0272-4c51-afc6-de9e03db3291 (ext_ip-10-0-147-219.ec2.internal)
    bf73b9df-59ab-4c58-a456-ce8205b34ac5 (ext_ip-10-0-163-212.ec2.internal)
    bee1e8d0-ec87-45eb-b98b-63f9ec213e5e (ext_ip-10-0-165-9.ec2.internal)
    812f08f2-6476-4abf-9a78-635f8516f95e (ext_ip-10-0-209-170.ec2.internal)
    f65e710b-32f9-482b-8eab-8d96a44799c1 (ext_ip-10-0-242-240.ec2.internal)
    84dad700-afb8-4129-86f9-923a1ddeace9 (ip-10-0-145-205.ec2.internal)
    1b7b448b-e36c-4ca3-9f38-4a2cf6814bfd (ip-10-0-147-219.ec2.internal)
    d92d1f56-2606-4f23-8b6a-4396a78951de (ip-10-0-163-212.ec2.internal)
    6864a6b2-de15-4de3-92d8-f95014b6f28f (ip-10-0-165-9.ec2.internal)
    c26bf618-4d7e-4afd-804f-1a2cbc96ec6d (ip-10-0-209-170.ec2.internal)
    ab9a4526-44ed-4f82-ae1c-e20da04947d9 (ip-10-0-242-240.ec2.internal)
    a8588aba-21da-4276-ba0f-9d68e88911f0 (join)

    注意

    在这个输出中,您可以看到每个节点的 ext 交换机以及节点名称本身和 join 开关。

  5. 运行以下命令以显示负载均衡器列表:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-gt4ms \
    -c northd -- ovn-nbctl lb-list

    输出示例

    Copy to Clipboard Toggle word wrap
    UUID                                    LB                  PROTO      VIP                     IPs
    f0fb50f9-4968-4b55-908c-616bae4db0a2    Service_default/    tcp        172.30.0.1:443          10.0.147.219:6443,10.0.163.212:6443,169.254.169.2:6443
    0dc42012-4f5b-432e-ae01-2cc4bfe81b00    Service_default/    tcp        172.30.0.1:443          10.0.147.219:6443,169.254.169.2:6443,10.0.242.240:6443
    f7fff5d5-5eff-4a40-98b1-3a4ba8f7f69c    Service_default/    tcp        172.30.0.1:443          169.254.169.2:6443,10.0.163.212:6443,10.0.242.240:6443
    12fe57a0-50a4-4a1b-ac10-5f288badee07    Service_default/    tcp        172.30.0.1:443          10.0.147.219:6443,10.0.163.212:6443,10.0.242.240:6443
    3f137fbf-0b78-4875-ba44-fbf89f254cf7    Service_openshif    tcp        172.30.23.153:443       10.130.0.14:8443
    174199fe-0562-4141-b410-12094db922a7    Service_openshif    tcp        172.30.69.51:50051      10.130.0.84:50051
    5ee2d4bd-c9e2-4d16-a6df-f54cd17c9ac3    Service_openshif    tcp        172.30.143.87:9001      10.0.145.205:9001,10.0.147.219:9001,10.0.163.212:9001,10.0.165.9:9001,10.0.209.170:9001,10.0.242.240:9001
    a056ae3d-83f8-45bc-9c80-ef89bce7b162    Service_openshif    tcp        172.30.164.74:443       10.0.147.219:6443,10.0.163.212:6443,10.0.242.240:6443
    bac51f3d-9a6f-4f5e-ac02-28fd343a332a    Service_openshif    tcp        172.30.0.10:53          10.131.0.6:5353
                                                                tcp        172.30.0.10:9154        10.131.0.6:9154
    48105bbc-51d7-4178-b975-417433f9c20a    Service_openshif    tcp        172.30.26.159:2379      10.0.147.219:2379,169.254.169.2:2379,10.0.242.240:2379
                                                                tcp        172.30.26.159:9979      10.0.147.219:9979,169.254.169.2:9979,10.0.242.240:9979
    7de2b8fc-342a-415f-ac13-1a493f4e39c0    Service_openshif    tcp        172.30.53.219:443       10.128.0.7:8443
                                                                tcp        172.30.53.219:9192      10.128.0.7:9192
    2cef36bc-d720-4afb-8d95-9350eff1d27a    Service_openshif    tcp        172.30.81.66:443        10.128.0.23:8443
    365cb6fb-e15e-45a4-a55b-21868b3cf513    Service_openshif    tcp        172.30.96.51:50051      10.130.0.19:50051
    41691cbb-ec55-4cdb-8431-afce679c5e8d    Service_openshif    tcp        172.30.98.218:9099      169.254.169.2:9099
    82df10ba-8143-400b-977a-8f5f416a4541    Service_openshif    tcp        172.30.26.159:2379      10.0.147.219:2379,10.0.163.212:2379,169.254.169.2:2379
                                                                tcp        172.30.26.159:9979      10.0.147.219:9979,10.0.163.212:9979,169.254.169.2:9979
    debe7f3a-39a8-490e-bc0a-ebbfafdffb16    Service_openshif    tcp        172.30.23.244:443       10.128.0.48:8443,10.129.0.27:8443,10.130.0.45:8443
    8a749239-02d9-4dc2-8737-716528e0da7b    Service_openshif    tcp        172.30.124.255:8443     10.128.0.14:8443
    880c7c78-c790-403d-a3cb-9f06592717a3    Service_openshif    tcp        172.30.0.10:53          10.130.0.20:5353
                                                                tcp        172.30.0.10:9154        10.130.0.20:9154
    d2f39078-6751-4311-a161-815bbaf7f9c7    Service_openshif    tcp        172.30.26.159:2379      169.254.169.2:2379,10.0.163.212:2379,10.0.242.240:2379
                                                                tcp        172.30.26.159:9979      169.254.169.2:9979,10.0.163.212:9979,10.0.242.240:9979
    30948278-602b-455c-934a-28e64c46de12    Service_openshif    tcp        172.30.157.35:9443      10.130.0.43:9443
    2cc7e376-7c02-4a82-89e8-dfa1e23fb003    Service_openshif    tcp        172.30.159.212:17698    10.128.0.48:17698,10.129.0.27:17698,10.130.0.45:17698
    e7d22d35-61c2-40c2-bc30-265cff8ed18d    Service_openshif    tcp        172.30.143.87:9001      10.0.145.205:9001,10.0.147.219:9001,10.0.163.212:9001,10.0.165.9:9001,10.0.209.170:9001,169.254.169.2:9001
    75164e75-e0c5-40fb-9636-bfdbf4223a02    Service_openshif    tcp        172.30.150.68:1936      10.129.4.8:1936,10.131.0.10:1936
                                                                tcp        172.30.150.68:443       10.129.4.8:443,10.131.0.10:443
                                                                tcp        172.30.150.68:80        10.129.4.8:80,10.131.0.10:80
    7bc4ee74-dccf-47e9-9149-b011f09aff39    Service_openshif    tcp        172.30.164.74:443       10.0.147.219:6443,10.0.163.212:6443,169.254.169.2:6443
    0db59e74-1cc6-470c-bf44-57c520e0aa8f    Service_openshif    tcp        10.0.163.212:31460
                                                                tcp        10.0.163.212:32361
    c300e134-018c-49af-9f84-9deb1d0715f8    Service_openshif    tcp        172.30.42.244:50051     10.130.0.47:50051
    5e352773-429b-4881-afb3-a13b7ba8b081    Service_openshif    tcp        172.30.244.66:443       10.129.0.8:8443,10.130.0.8:8443
    54b82d32-1939-4465-a87d-f26321442a7a    Service_openshif    tcp        172.30.12.9:8443        10.128.0.35:8443

    注意

    在这个截断的输出中,您可以看到有许多 OVN-Kubernetes 负载均衡器。OVN-Kubernetes 中的负载均衡器是服务的表示。

23.2.4. ovn-nbctl 的命令行参数检查北向数据库内容

下表描述了可用于 ovn-nbctl 的命令行参数,以检查北向数据库的内容。

表 23.2. 检查北向数据库内容的命令行参数
参数描述

ovn-nbctl show

北向数据库内容的概述。

ovn-nbctl show <switch_or_router>

显示与指定交换机或路由器关联的详细信息。

ovn-nbctl lr-list

显示逻辑路由器。

ovn-nbctl lrp-list <router>

使用 ovn-nbctl lr-list 中的路由器信息来显示路由器端口。

ovn-nbctl lr-nat-list <router>

显示指定路由器的网络地址转换详情。

ovn-nbctl ls-list

显示逻辑交换机

ovn-nbctl lsp-list <switch>

使用 ovn-nbctl ls-list 的交换机信息来显示交换机端口。

ovn-nbctl lsp-get-type <port>

获取逻辑端口的类型。

ovn-nbctl lb-list

显示负载平衡器。

23.2.5. 列出 OVN-Kubernetes 南向数据库内容

逻辑流规则存储在南向数据库中,后者是基础架构的一个表示形式。OVN Raft leader 上会显示最新信息,这个过程描述了如何找到 Raft 领导机并查询它以列出 OVN 南向数据库内容。

先决条件

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

流程

  1. 查找南向数据库的 OVN Raft 领导。

    注意

    Raft 领导机存储最新信息。

    1. 运行以下命令列出 pod:

      Copy to Clipboard Toggle word wrap
      $ oc get po -n openshift-ovn-kubernetes

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME                   READY   STATUS    RESTARTS       AGE
      ovnkube-master-7j97q   6/6     Running   2 (134m ago)   135m
      ovnkube-master-gt4ms   6/6     Running   1 (126m ago)   133m
      ovnkube-master-mk6p6   6/6     Running   0              134m
      ovnkube-node-8qvtr     5/5     Running   0              135m
      ovnkube-node-bqztb     5/5     Running   0              117m
      ovnkube-node-fqdc9     5/5     Running   0              135m
      ovnkube-node-tlfwv     5/5     Running   0              135m
      ovnkube-node-wlwkn     5/5     Running   0              128m

    2. 随机选择一个 master pod,并运行以下命令来查找 OVN 南向 Raft 领导:

      Copy to Clipboard Toggle word wrap
      $ oc exec -n openshift-ovn-kubernetes ovnkube-master-7j97q \
      -- /usr/bin/ovn-appctl -t /var/run/ovn/ovnsb_db.ctl \
      --timeout=3 cluster/status OVN_Southbound

      输出示例

      Copy to Clipboard Toggle word wrap
      Defaulted container "northd" out of: northd, nbdb, kube-rbac-proxy, sbdb, ovnkube-master, ovn-dbchecker
      1930
      Name: OVN_Southbound
      Cluster ID: f772 (f77273c0-7986-42dd-bd3c-a9f18e25701f)
      Server ID: 1930 (1930f4b7-314b-406f-9dcb-b81fe2729ae1)
      Address: ssl:10.0.147.219:9644
      Status: cluster member
      Role: follower 
      1
      
      Term: 3
      Leader: 7081 
      2
      
      Vote: unknown
      
      Election timer: 16000
      Log: [2, 2423]
      Entries not yet committed: 0
      Entries not yet applied: 0
      Connections: ->0000 ->7145 <-7081 <-7145
      Disconnections: 0
      Servers:
          7081 (7081 at ssl:10.0.163.212:9644) last msg 59 ms ago 
      3
      
          1930 (1930 at ssl:10.0.147.219:9644) (self)
          7145 (7145 at ssl:10.0.242.240:9644) last msg 7871735 ms ago

      1
      此 pod 被识别为 follower
      2
      领导机被识别为 7081
      3
      7081 为 IP 地址 10.0.163.212
    3. 使用以下命令,查找在 IP Address 10.0.163.212 上运行的 ovnkube-master pod:

      Copy to Clipboard Toggle word wrap
      $ oc get po -o wide -n openshift-ovn-kubernetes | grep 10.0.163.212 | grep -v ovnkube-node

      输出示例

      Copy to Clipboard Toggle word wrap
      ovnkube-master-mk6p6   6/6     Running   0              136m   10.0.163.212   ip-10-0-163-212.ec2.internal   <none>           <none>

      ovnkube-master-mk6p6 pod 在 IP Address 10.0.163.212 上运行。

  2. 运行以下命令,以显示存储在南向数据库中的所有信息:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-mk6p6 \
    -c northd -- ovn-sbctl show

    输出示例

    Copy to Clipboard Toggle word wrap
    Chassis "8ca57b28-9834-45f0-99b0-96486c22e1be"
        hostname: ip-10-0-156-16.ec2.internal
        Encap geneve
            ip: "10.0.156.16"
            options: {csum="true"}
        Port_Binding k8s-ip-10-0-156-16.ec2.internal
        Port_Binding etor-GR_ip-10-0-156-16.ec2.internal
        Port_Binding jtor-GR_ip-10-0-156-16.ec2.internal
        Port_Binding openshift-ingress-canary_ingress-canary-hsblx
        Port_Binding rtoj-GR_ip-10-0-156-16.ec2.internal
        Port_Binding openshift-monitoring_prometheus-adapter-658fc5967-9l46x
        Port_Binding rtoe-GR_ip-10-0-156-16.ec2.internal
        Port_Binding openshift-multus_network-metrics-daemon-77nvz
        Port_Binding openshift-ingress_router-default-64fd8c67c7-df598
        Port_Binding openshift-dns_dns-default-ttpcq
        Port_Binding openshift-monitoring_alertmanager-main-0
        Port_Binding openshift-e2e-loki_loki-promtail-g2pbh
        Port_Binding openshift-network-diagnostics_network-check-target-m6tn4
        Port_Binding openshift-monitoring_thanos-querier-75b5cf8dcb-qf8qj
        Port_Binding cr-rtos-ip-10-0-156-16.ec2.internal
        Port_Binding openshift-image-registry_image-registry-7b7bc44566-mp9b8

    此详细输出显示了附加到机箱的机箱和端口,本例中为所有路由器端口以及像主机网络一样运行的任何内容。任何 pod 使用源网络地址转换(SNAT)与更广泛的网络通信。其 IP 地址转换为运行 Pod 的节点的 IP 地址,然后发送到网络。

    除了机箱信息外,南向数据库还具有所有逻辑流,这些逻辑流随后发送到每个节点上运行的 ovn-controllerovn-controller 将逻辑流转换为开放流规则,最终程序 OpenvSwitch 以便您的 pod 可以遵循开放流规则并使它移出网络。

    运行以下命令以 ovn-sbctl 命令显示可用的选项:

    Copy to Clipboard Toggle word wrap
    $ oc exec -n openshift-ovn-kubernetes -it ovnkube-master-mk6p6 \
    -c northd -- ovn-sbctl --help

23.2.6. ovn-sbctl 的命令行参数检查南向数据库内容

下表描述了可用于 ovn-sbctl 的命令行参数,以检查南向数据库的内容。

表 23.3. 检查南向数据库内容的命令行参数
参数描述

ovn-sbctl show

南向数据库内容概述。

ovn-sbctl list Port_Binding <port>

列出特定端口的南向数据库的内容。

ovn-sbctl dump-flows

列出逻辑流。

23.2.7. OVN-Kubernetes 逻辑架构

OVN 是网络虚拟化解决方案。它创建逻辑交换机和路由器。这些交换机和路由器是互连的,以创建任何网络拓扑。当您运行 ovnkube-trace 时,日志级别设置为 2 或 5 时,OVN-Kubernetes 逻辑组件会被公开。下图显示了如何在 OpenShift Container Platform 中连接路由器和交换机。

图 23.2. OVN-Kubernetes 路由器和交换机组件

OVN-Kubernetes 逻辑架构

涉及数据包处理的关键组件有:

网关路由器
网关路由器有时称为 L3 网关路由器,通常在分布式路由器和物理网络之间使用。网关路由器(包括其逻辑补丁端口)绑定到物理位置(而非分布式)或机箱。此路由器上的跳接端口称为 ovn-southbound 数据库(ovn-sbdb)中的 l3gateway 端口。
分布式逻辑路由器
分布式逻辑路由器和其后面的逻辑交换机(虚拟机和容器附加)有效驻留在每个虚拟机监控程序上。
加入本地交换机
加入本地交换机用于连接分布式路由器和网关路由器。它可减少分布式路由器中所需的 IP 地址数量。
使用跳接端口的逻辑交换机
带有补丁端口的逻辑交换机用于虚拟化网络堆栈。它们通过隧道连接远程逻辑端口。
使用 localnet 端口的逻辑交换机
使用 localnet 端口的逻辑交换机用于将 OVN 连接到物理网络。它们通过将数据包桥接到使用 localnet 端口直接连接的物理 L2 片段来连接远程逻辑端口。
补丁端口
跳接端口代表逻辑交换机和逻辑路由器之间以及对等逻辑路由器之间的连接。单个连接在每个此类连接点上都有一对跳接端口。
l3gateway 端口
l3gateway 端口是 ovn-sbdb 中用于网关路由器中使用的逻辑补丁端口的端口绑定条目。它们称为 l3gateway 端口,而不是跳接端口,而只是这些端口绑定到机箱,就像网关路由器本身一样。
localnet 端口
桥接逻辑交换机上存在 localnet 端口,允许从每个 ovn-controller 实例连接到本地可访问的网络。这有助于从逻辑交换机对物理网络的直接连接建模。逻辑交换机只能附加一个 localnet 端口。
23.2.7.1. 在本地主机上安装 network-tools

在本地主机上安装 network-tools,以提供一组工具来调试 OpenShift Container Platform 集群网络问题。

流程

  1. 使用以下命令将 network-tools 存储库克隆到工作站:

    Copy to Clipboard Toggle word wrap
    $ git clone git@github.com:openshift/network-tools.git
  2. 更改到您刚才克隆的存储库的目录:

    Copy to Clipboard Toggle word wrap
    $ cd network-tools
  3. 可选:列出所有可用的命令:

    Copy to Clipboard Toggle word wrap
    $ ./debug-scripts/network-tools -h
23.2.7.2. 运行 network-tools

通过运行 network-tools 来获取逻辑交换机和路由器的信息。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 以具有 cluster-admin 权限的用户身份登录集群。
  • 您已在本地主机上安装了 network-tools

流程

  1. 运行以下命令列出路由器:

    Copy to Clipboard Toggle word wrap
    $ ./debug-scripts/network-tools ovn-db-run-command ovn-nbctl lr-list

    输出示例

    Copy to Clipboard Toggle word wrap
    Leader pod is ovnkube-master-vslqm
    5351ddd1-f181-4e77-afc6-b48b0a9df953 (GR_helix13.lab.eng.tlv2.redhat.com)
    ccf9349e-1948-4df8-954e-39fb0c2d4d06 (GR_helix14.lab.eng.tlv2.redhat.com)
    e426b918-75a8-4220-9e76-20b7758f92b7 (GR_hlxcl7-master-0.hlxcl7.lab.eng.tlv2.redhat.com)
    dded77c8-0cc3-4b99-8420-56cd2ae6a840 (GR_hlxcl7-master-1.hlxcl7.lab.eng.tlv2.redhat.com)
    4f6747e6-e7ba-4e0c-8dcd-94c8efa51798 (GR_hlxcl7-master-2.hlxcl7.lab.eng.tlv2.redhat.com)
    52232654-336e-4952-98b9-0b8601e370b4 (ovn_cluster_router)

  2. 运行以下命令列出 localnet 端口:

    Copy to Clipboard Toggle word wrap
    $ ./debug-scripts/network-tools ovn-db-run-command \
    ovn-sbctl find Port_Binding type=localnet

    输出示例

    Copy to Clipboard Toggle word wrap
    Leader pod is ovnkube-master-vslqm
    _uuid               : 3de79191-cca8-4c28-be5a-a228f0f9ebfc
    additional_chassis  : []
    additional_encap    : []
    chassis             : []
    datapath            : 3f1a4928-7ff5-471f-9092-fe5f5c67d15c
    encap               : []
    external_ids        : {}
    gateway_chassis     : []
    ha_chassis_group    : []
    logical_port        : br-ex_helix13.lab.eng.tlv2.redhat.com
    mac                 : [unknown]
    nat_addresses       : []
    options             : {network_name=physnet}
    parent_port         : []
    port_security       : []
    requested_additional_chassis: []
    requested_chassis   : []
    tag                 : []
    tunnel_key          : 2
    type                : localnet
    up                  : false
    virtual_parent      : []
    
    _uuid               : dbe21daf-9594-4849-b8f0-5efbfa09a455
    additional_chassis  : []
    additional_encap    : []
    chassis             : []
    datapath            : db2a6067-fe7c-4d11-95a7-ff2321329e11
    encap               : []
    external_ids        : {}
    gateway_chassis     : []
    ha_chassis_group    : []
    logical_port        : br-ex_hlxcl7-master-2.hlxcl7.lab.eng.tlv2.redhat.com
    mac                 : [unknown]
    nat_addresses       : []
    options             : {network_name=physnet}
    parent_port         : []
    port_security       : []
    requested_additional_chassis: []
    requested_chassis   : []
    tag                 : []
    tunnel_key          : 2
    type                : localnet
    up                  : false
    virtual_parent      : []
    
    [...]

  3. 运行以下命令列出 l3gateway 端口:

    Copy to Clipboard Toggle word wrap
    $ ./debug-scripts/network-tools ovn-db-run-command \
    ovn-sbctl find Port_Binding type=l3gateway

    输出示例

    Copy to Clipboard Toggle word wrap
    Leader pod is ovnkube-master-vslqm
    _uuid               : 9314dc80-39e1-4af7-9cc0-ae8a9708ed59
    additional_chassis  : []
    additional_encap    : []
    chassis             : 336a923d-99e8-4e71-89a6-12564fde5760
    datapath            : db2a6067-fe7c-4d11-95a7-ff2321329e11
    encap               : []
    external_ids        : {}
    gateway_chassis     : []
    ha_chassis_group    : []
    logical_port        : etor-GR_hlxcl7-master-2.hlxcl7.lab.eng.tlv2.redhat.com
    mac                 : ["52:54:00:3e:95:d3"]
    nat_addresses       : ["52:54:00:3e:95:d3 10.46.56.77"]
    options             : {l3gateway-chassis="7eb1f1c3-87c2-4f68-8e89-60f5ca810971", peer=rtoe-GR_hlxcl7-master-2.hlxcl7.lab.eng.tlv2.redhat.com}
    parent_port         : []
    port_security       : []
    requested_additional_chassis: []
    requested_chassis   : []
    tag                 : []
    tunnel_key          : 1
    type                : l3gateway
    up                  : true
    virtual_parent      : []
    
    _uuid               : ad7eb303-b411-4e9f-8d36-d07f1f268e27
    additional_chassis  : []
    additional_encap    : []
    chassis             : f41453b8-29c5-4f39-b86b-e82cf344bce4
    datapath            : 082e7a60-d9c7-464b-b6ec-117d3426645a
    encap               : []
    external_ids        : {}
    gateway_chassis     : []
    ha_chassis_group    : []
    logical_port        : etor-GR_helix14.lab.eng.tlv2.redhat.com
    mac                 : ["34:48:ed:f3:e2:2c"]
    nat_addresses       : ["34:48:ed:f3:e2:2c 10.46.56.14"]
    options             : {l3gateway-chassis="2e8abe3a-cb94-4593-9037-f5f9596325e2", peer=rtoe-GR_helix14.lab.eng.tlv2.redhat.com}
    parent_port         : []
    port_security       : []
    requested_additional_chassis: []
    requested_chassis   : []
    tag                 : []
    tunnel_key          : 1
    type                : l3gateway
    up                  : true
    virtual_parent      : []
    
    [...]

  4. 运行以下命令列出跳接端口:

    Copy to Clipboard Toggle word wrap
    $ ./debug-scripts/network-tools ovn-db-run-command \
    ovn-sbctl find Port_Binding type=patch

    输出示例

    Copy to Clipboard Toggle word wrap
    Leader pod is ovnkube-master-vslqm
    _uuid               : c48b1380-ff26-4965-a644-6bd5b5946c61
    additional_chassis  : []
    additional_encap    : []
    chassis             : []
    datapath            : 72734d65-fae1-4bd9-a1ee-1bf4e085a060
    encap               : []
    external_ids        : {}
    gateway_chassis     : []
    ha_chassis_group    : []
    logical_port        : jtor-ovn_cluster_router
    mac                 : [router]
    nat_addresses       : []
    options             : {peer=rtoj-ovn_cluster_router}
    parent_port         : []
    port_security       : []
    requested_additional_chassis: []
    requested_chassis   : []
    tag                 : []
    tunnel_key          : 4
    type                : patch
    up                  : false
    virtual_parent      : []
    
    _uuid               : 5df51302-f3cd-415b-a059-ac24389938f7
    additional_chassis  : []
    additional_encap    : []
    chassis             : []
    datapath            : 0551c90f-e891-4909-8e9e-acc7909e06d0
    encap               : []
    external_ids        : {}
    gateway_chassis     : []
    ha_chassis_group    : []
    logical_port        : rtos-hlxcl7-master-1.hlxcl7.lab.eng.tlv2.redhat.com
    mac                 : ["0a:58:0a:82:00:01 10.130.0.1/23"]
    nat_addresses       : []
    options             : {chassis-redirect-port=cr-rtos-hlxcl7-master-1.hlxcl7.lab.eng.tlv2.redhat.com, peer=stor-hlxcl7-master-1.hlxcl7.lab.eng.tlv2.redhat.com}
    parent_port         : []
    port_security       : []
    requested_additional_chassis: []
    requested_chassis   : []
    tag                 : []
    tunnel_key          : 4
    type                : patch
    up                  : false
    virtual_parent      : []
    
    [...]

23.2.8. 其他资源

23.3. OVN-Kubernetes 故障排除

OVN-Kubernetes 具有许多内置健康检查和日志来源。

23.3.1. 使用就绪度探测监控 OVN-Kubernetes 健康状况

ovnkube-masterovnkube-node pod 配置有就绪度探测的容器。

先决条件

  • 访问 OpenShift CLI (oc)。
  • 您可以使用 cluster-admin 权限访问集群。
  • 您已安装了 jq

流程

  1. 运行以下命令,查看 ovnkube-master 就绪度探测的详情:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-master \
    -o json | jq '.items[0].spec.containers[] | .name,.readinessProbe'

    ovnkube-master pod 中北向和南向数据库容器的就绪度探测会检查托管数据库的 Raft 集群的健康状态。

  2. 运行以下命令,查看 ovnkube-node 就绪度探测的详情:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-master \
    -o json | jq '.items[0].spec.containers[] | .name,.readinessProbe'

    ovnkube-node pod 中的 ovnkube-node 容器有一个就绪度探测来验证 ovn-kubernetes CNI 配置文件是否存在,而这代表 pod 没有运行,或者没有准备好接受配置 Pod 的请求。

  3. 使用以下命令,显示命名空间的所有事件,包括探测失败:

    Copy to Clipboard Toggle word wrap
    $ oc get events -n openshift-ovn-kubernetes
  4. 仅显示此 pod 的事件:

    Copy to Clipboard Toggle word wrap
    $ oc describe pod ovnkube-master-tp2z8 -n openshift-ovn-kubernetes
  5. 显示集群网络 Operator 的消息和状态:

    Copy to Clipboard Toggle word wrap
    $ oc get co/network -o json | jq '.status.conditions[]'
  6. 运行以下命令,显示 ovnkube-master pod 中每个容器的 就绪 状态 :

    Copy to Clipboard Toggle word wrap
    $ for p in $(oc get pods --selector app=ovnkube-master -n openshift-ovn-kubernetes \
    -o jsonpath='{range.items[*]}{" "}{.metadata.name}'); do echo === $p ===;  \
    oc get pods -n openshift-ovn-kubernetes $p -o json | jq '.status.containerStatuses[] | .name, .ready'; \
    done
    注意

    预期的是所有容器状态都报告为 true。就绪度探测失败,将状态设置为 false

23.3.2. 在控制台中查看 OVN-Kubernetes 警报

Alerting UI 提供有关警报及其相关警报规则和静默的详细信息。

先决条件

  • 对于您要查看指标的项目,您可以作为开发者或具有查看权限的用户访问集群。

流程 (UI)

  1. Administrator 视角中,选择 ObserveAlerting。在此视角中,Alerting UI 中的三个主要页面是 AlertsSilencesAlerting Rules 页面。
  2. 选择 ObserveAlertingAlerting Rules 来查看 OVN-Kubernetes 警报的规则。

23.3.3. 在 CLI 中查看 OVN-Kubernetes 警报

您可以从命令行获取有关警报及其监管警报规则和静默的信息。

先决条件

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

流程

  1. 运行以下命令,查看活动或触发警报:

    1. 运行以下命令设置警报管理器路由环境变量:

      Copy to Clipboard Toggle word wrap
      $ ALERT_MANAGER=$(oc get route alertmanager-main -n openshift-monitoring \
      -o jsonpath='{@.spec.host}')
    2. 运行以下命令,使用请求特定字段的正确授权详情向警报管理器路由 API 发出 curl 请求:

      Copy to Clipboard Toggle word wrap
      $ curl -s -k -H "Authorization: Bearer \
      $(oc create token prometheus-k8s -n openshift-monitoring)" \
      https://$ALERT_MANAGER/api/v1/alerts \
      | jq '.data[] | "\(.labels.severity) \(.labels.alertname) \(.labels.pod) \(.labels.container) \(.labels.endpoint) \(.labels.instance)"'
  2. 运行以下命令来查看警报规则:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-monitoring exec -c prometheus prometheus-k8s-0 -- curl -s 'http://localhost:9090/api/v1/rules' | jq '.data.groups[].rules[] | select(((.name|contains("ovn")) or (.name|contains("OVN")) or (.name|contains("Ovn")) or (.name|contains("North")) or (.name|contains("South"))) and .type=="alerting")'

23.3.4. 使用 CLI 查看 OVN-Kubernetes 日志

您可以使用 OpenShift CLI (oc)查看 ovnkube-masterovnkube-node pod 中各个 pod 的日志。

先决条件

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

流程

  1. 查看特定 pod 的日志:

    Copy to Clipboard Toggle word wrap
    $ oc logs -f <pod_name> -c <container_name> -n <namespace>

    其中:

    -f
    可选:指定输出是否遵循要写到日志中的内容。
    <pod_name>
    指定 pod 的名称。
    <container_name>
    可选:指定容器的名称。当 pod 具有多个容器时,您必须指定容器名称。
    <namespace>
    指定 pod 运行的命名空间。

    例如:

    Copy to Clipboard Toggle word wrap
    $ oc logs ovnkube-master-7h4q7 -n openshift-ovn-kubernetes
    Copy to Clipboard Toggle word wrap
    $ oc logs -f ovnkube-master-7h4q7 -n openshift-ovn-kubernetes -c ovn-dbchecker

    输出的日志文件内容。

  2. 检查 ovnkube-master pod 中所有容器的最新条目:

    Copy to Clipboard Toggle word wrap
    $ for p in $(oc get pods --selector app=ovnkube-master -n openshift-ovn-kubernetes \
    -o jsonpath='{range.items[*]}{" "}{.metadata.name}'); \
    do echo === $p ===; for container in $(oc get pods -n openshift-ovn-kubernetes $p \
    -o json | jq -r '.status.containerStatuses[] | .name');do echo ---$container---; \
    oc logs -c $container $p -n openshift-ovn-kubernetes --tail=5; done; done
  3. 使用以下命令,查看 ovnkube-master pod 中每个容器的最后 5 行:

    Copy to Clipboard Toggle word wrap
    $ oc logs -l app=ovnkube-master -n openshift-ovn-kubernetes --all-containers --tail 5

23.3.5. 使用 Web 控制台查看 OVN-Kubernetes 日志

您可以在 web 控制台中查看 ovnkube-masterovnkube-node pod 中的各个容器集的日志。

先决条件

  • 访问 OpenShift CLI (oc)。

流程

  1. 在 OpenShift Container Platform 控制台中,进入到 WorkloadsPods,或通过您要调查的资源进入到 pod。
  2. 从下拉菜单中选择 openshift-ovn-kubernetes 项目。
  3. 点您要调查的 pod 的名称。
  4. Logs。默认情况下,ovnkube-master 显示与 northd 容器关联的日志。
  5. 使用向下下拉菜单选择每个容器的日志。
23.3.5.1. 更改 OVN-Kubernetes 日志级别

OVN-Kubernetes 的默认日志级别为 2。要调试 OVN-Kubernetes 将日志级别设置为 5。按照以下步骤增加 OVN-Kubernetes 的日志级别,以帮助您调试问题。

先决条件

  • 您可以使用 cluster-admin 权限访问集群。
  • 访问 OpenShift Container Platform web 控制台。

流程

  1. 运行以下命令,以获取 OVN-Kubernetes 项目中所有 pod 的详细信息:

    Copy to Clipboard Toggle word wrap
    $ oc get po -o wide -n openshift-ovn-kubernetes

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                   READY   STATUS    RESTARTS      AGE   IP             NODE                           NOMINATED NODE   READINESS GATES
    ovnkube-master-84nc9   6/6     Running   0             50m   10.0.134.156   ip-10-0-134-156.ec2.internal   <none>           <none>
    ovnkube-master-gmlqv   6/6     Running   0             50m   10.0.209.180   ip-10-0-209-180.ec2.internal   <none>           <none>
    ovnkube-master-nhts2   6/6     Running   1 (48m ago)   50m   10.0.147.31    ip-10-0-147-31.ec2.internal    <none>           <none>
    ovnkube-node-2cbh8     5/5     Running   0             43m   10.0.217.114   ip-10-0-217-114.ec2.internal   <none>           <none>
    ovnkube-node-6fvzl     5/5     Running   0             50m   10.0.147.31    ip-10-0-147-31.ec2.internal    <none>           <none>
    ovnkube-node-f4lzz     5/5     Running   0             24m   10.0.146.76    ip-10-0-146-76.ec2.internal    <none>           <none>
    ovnkube-node-jf67d     5/5     Running   0             50m   10.0.209.180   ip-10-0-209-180.ec2.internal   <none>           <none>
    ovnkube-node-np9mf     5/5     Running   0             40m   10.0.165.191   ip-10-0-165-191.ec2.internal   <none>           <none>
    ovnkube-node-qjldg     5/5     Running   0             50m   10.0.134.156   ip-10-0-134-156.ec2.internal   <none>           <none>

  2. 创建类似以下示例的 ConfigMap 文件,并使用文件名,如 env-overrides.yaml

    ConfigMap 文件示例

    Copy to Clipboard Toggle word wrap
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: env-overrides
      namespace: openshift-ovn-kubernetes
    data:
      ip-10-0-217-114.ec2.internal: | 
    1
    
        # This sets the log level for the ovn-kubernetes node process:
        OVN_KUBE_LOG_LEVEL=5
        # You might also/instead want to enable debug logging for ovn-controller:
        OVN_LOG_LEVEL=dbg
      ip-10-0-209-180.ec2.internal: |
        # This sets the log level for the ovn-kubernetes node process:
        OVN_KUBE_LOG_LEVEL=5
        # You might also/instead want to enable debug logging for ovn-controller:
        OVN_LOG_LEVEL=dbg
      _master: | 
    2
    
        # This sets the log level for the ovn-kubernetes master process as well as the ovn-dbchecker:
        OVN_KUBE_LOG_LEVEL=5
        # You might also/instead want to enable debug logging for northd, nbdb and sbdb on all masters:
        OVN_LOG_LEVEL=dbg

    1
    指定要设置 debug 日志级别的节点名称。
    2
    指定 _master 来设置 ovnkube-master 组件的日志级别。
  3. 使用以下命令应用 ConfigMap 文件:

    Copy to Clipboard Toggle word wrap
    $ oc apply -n openshift-ovn-kubernetes -f env-overrides.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    configmap/env-overrides.yaml created

  4. 使用以下命令重启 ovnkube pod 以应用新的日志级别:

    Copy to Clipboard Toggle word wrap
    $ oc delete pod -n openshift-ovn-kubernetes \
    --field-selector spec.nodeName=ip-10-0-217-114.ec2.internal -l app=ovnkube-node
    Copy to Clipboard Toggle word wrap
    $ oc delete pod -n openshift-ovn-kubernetes \
    --field-selector spec.nodeName=ip-10-0-209-180.ec2.internal -l app=ovnkube-node
    Copy to Clipboard Toggle word wrap
    $ oc delete pod -n openshift-ovn-kubernetes -l app=ovnkube-master

23.3.6. 检查 OVN-Kubernetes pod 网络连接

在 OpenShift Container Platform 4.10 及更新的版本中,连接检查控制器会在集群中编配连接验证检查。这包括 Kubernetes API、OpenShift API 和单个节点。连接测试的结果存储在 openshift-network-diagnostics 命名空间中的 PodNetworkConnectivity 对象中。连接测试会每分钟以并行方式执行。

先决条件

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

流程

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

    Copy to Clipboard Toggle word wrap
    $ oc get podnetworkconnectivitychecks -n openshift-network-diagnostics
  2. 使用以下命令查看每个连接对象的最新成功:

    Copy to Clipboard Toggle word wrap
    $ oc get podnetworkconnectivitychecks -n openshift-network-diagnostics \
    -o json | jq '.items[]| .spec.targetEndpoint,.status.successes[0]'
  3. 使用以下命令查看每个连接对象的最新故障:

    Copy to Clipboard Toggle word wrap
    $ oc get podnetworkconnectivitychecks -n openshift-network-diagnostics \
    -o json | jq '.items[]| .spec.targetEndpoint,.status.failures[0]'
  4. 使用以下命令查看每个连接对象的最新中断:

    Copy to Clipboard Toggle word wrap
    $ oc get podnetworkconnectivitychecks -n openshift-network-diagnostics \
    -o json | jq '.items[]| .spec.targetEndpoint,.status.outages[0]'

    连接检查控制器也会将来自这些检查的指标记录到 Prometheus 中。

  5. 运行以下命令来查看所有指标:

    Copy to Clipboard Toggle word wrap
    $ oc exec prometheus-k8s-0 -n openshift-monitoring -- \
    promtool query instant  http://localhost:9090 \
    '{component="openshift-network-diagnostics"}'
  6. 查看源 pod 和 openshift api 服务之间的延迟,持续 5 分钟:

    Copy to Clipboard Toggle word wrap
    $ oc exec prometheus-k8s-0 -n openshift-monitoring -- \
    promtool query instant  http://localhost:9090 \
    '{component="openshift-network-diagnostics"}'

23.3.7. 其他资源

23.4. 使用 ovnkube-trace 追踪 Openflow

OVN 和 OVS 流量流可以在一个名为 ovnkube-trace 的单个实用程序中模拟。ovnkube-trace 实用程序运行 ovn-traceovs-appctl ofproto/traceovn-detrace,并在单个输出中关联这些信息。

您可以从专用容器执行 ovnkube-trace 二进制文件。对于 OpenShift Container Platform 4.7 后的版本,您还可以将该二进制文件复制到本地主机中,并从该主机执行它。

注意

Quay 镜像中的二进制文件目前不适用于 Dual IP 堆栈或 IPv6 环境。对于这些环境,您必须从源进行构建。

23.4.1. 在本地主机上安装 ovnkube-trace

ovnkube-trace 工具跟踪在 OVN-Kubernetes 驱动的 OpenShift Container Platform 集群中点之间的任意 UDP 或 TCP 流量的数据包模拟。将 ovnkube-trace 二进制文件复制到本地主机,使其可以针对集群运行。

先决条件

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

流程

  1. 使用以下命令创建 pod 变量:

    Copy to Clipboard Toggle word wrap
    $  POD=$(oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-master -o name | head -1 | awk -F '/' '{print $NF}')
  2. 在本地主机上运行以下命令从 ovnkube-master pod 中复制二进制文件:

    Copy to Clipboard Toggle word wrap
    $  oc cp -n openshift-ovn-kubernetes $POD:/usr/bin/ovnkube-trace ovnkube-trace
  3. 运行以下命令,使 ovnkube-trace 可执行:

    Copy to Clipboard Toggle word wrap
    $  chmod +x ovnkube-trace
  4. 运行以下命令,显示 ovnkube-trace 可用的选项:

    Copy to Clipboard Toggle word wrap
    $  ./ovnkube-trace -help

    预期输出

    Copy to Clipboard Toggle word wrap
    I0111 15:05:27.973305  204872 ovs.go:90] Maximum command line arguments set to: 191102
    Usage of ./ovnkube-trace:
      -dst string
        	dest: destination pod name
      -dst-ip string
        	destination IP address (meant for tests to external targets)
      -dst-namespace string
        	k8s namespace of dest pod (default "default")
      -dst-port string
        	dst-port: destination port (default "80")
      -kubeconfig string
        	absolute path to the kubeconfig file
      -loglevel string
        	loglevel: klog level (default "0")
      -ovn-config-namespace string
        	namespace used by ovn-config itself
      -service string
        	service: destination service name
      -skip-detrace
        	skip ovn-detrace command
      -src string
        	src: source pod name
      -src-namespace string
        	k8s namespace of source pod (default "default")
      -tcp
        	use tcp transport protocol
      -udp
        	use udp transport protocol

    支持的命令行参数是熟悉的 Kubernetes 构造,如命名空间、Pod、服务,因此您不需要查找 MAC 地址、目标节点的 IP 地址或 ICMP 类型。

    日志级别为:

    • 0 (最小输出)
    • 2 (显示 trace 命令结果的详细输出)
    • 5 (调试输出)

23.4.2. 运行 ovnkube-trace

运行 ovn-trace 以模拟 OVN 逻辑网络内的数据包转发。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您已在本地主机上安装了 ovnkube-trace

示例:测试 DNS 解析是否适用于部署的 pod

本例演示了如何从部署的 pod 测试 DNS 解析到集群中运行的核心 DNS pod。

流程

  1. 输入以下命令在 default 命名空间中启动 web 服务:

    Copy to Clipboard Toggle word wrap
    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  2. 列出在 openshift-dns 命名空间中运行的 pod:

    Copy to Clipboard Toggle word wrap
    oc get pods -n openshift-dns

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                  READY   STATUS    RESTARTS   AGE
    dns-default-467qw     2/2     Running   0          49m
    dns-default-6prvx     2/2     Running   0          53m
    dns-default-fkqr8     2/2     Running   0          53m
    dns-default-qv2rg     2/2     Running   0          49m
    dns-default-s29vr     2/2     Running   0          49m
    dns-default-vdsbn     2/2     Running   0          53m
    node-resolver-6thtt   1/1     Running   0          53m
    node-resolver-7ksdn   1/1     Running   0          49m
    node-resolver-8sthh   1/1     Running   0          53m
    node-resolver-c5ksw   1/1     Running   0          50m
    node-resolver-gbvdp   1/1     Running   0          53m
    node-resolver-sxhkd   1/1     Running   0          50m

  3. 运行以下 ovn-kube-trace 命令来验证 DNS 解析是否正常工作:

    Copy to Clipboard Toggle word wrap
    $ ./ovnkube-trace \
      -src-namespace default \ 
    1
    
      -src web \ 
    2
    
      -dst-namespace openshift-dns \ 
    3
    
      -dst dns-default-467qw \ 
    4
    
      -udp -dst-port 53 \ 
    5
    
      -loglevel 0 
    6
    1
    源 pod 的命名空间
    2
    源 pod 名称
    3
    目标 pod 的命名空间
    4
    目标 pod 名称
    5
    使用 udp 传输协议。端口 53 是 DNS 服务使用的端口。
    6
    将日志级别设置为 1 (0 为 minimal,5 为 debug)

    预期输出

    Copy to Clipboard Toggle word wrap
    I0116 10:19:35.601303   17900 ovs.go:90] Maximum command line arguments set to: 191102
    ovn-trace source pod to destination pod indicates success from web to dns-default-467qw
    ovn-trace destination pod to source pod indicates success from dns-default-467qw to web
    ovs-appctl ofproto/trace source pod to destination pod indicates success from web to dns-default-467qw
    ovs-appctl ofproto/trace destination pod to source pod indicates success from dns-default-467qw to web
    ovn-detrace source pod to destination pod indicates success from web to dns-default-467qw
    ovn-detrace destination pod to source pod indicates success from dns-default-467qw to web

    ouput 表示从部署的 pod 到 DNS 端口的成功,也表示它已成功返回其他方向。因此,如果我的 Web pod 想要从核心 DNS 进行 dns 解析,则 UDP 端口 53 上支持双向流量。

例如,如果 无法正常工作,并且您想要获取 ovn-traceovs-appctl ofproto/traceovn-detrace,更多调试类型信息会将日志级别增加到 2,然后再次运行命令,如下所示:

Copy to Clipboard Toggle word wrap
$ ./ovnkube-trace \
  -src-namespace default \
  -src web \
  -dst-namespace openshift-dns \
  -dst dns-default-467qw \
  -udp -dst-port 53 \
  -loglevel 2

这个日志级别的输出太大,无法在此处列出。在故障情况下,此命令的输出显示哪个流丢弃了该流量。例如,可以在不允许该流量的集群中配置 egress 或 ingress 网络策略。

示例:使用 debug 输出来验证配置的默认拒绝

本例演示了如何使用入口默认拒绝策略阻断流量的 debug 输出来识别。

流程

  1. 创建以下 YAML,以定义 deny-by-default 策略,以拒绝所有命名空间中的所有 pod 的入口流量。将 YAML 保存到 deny-by-default.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-by-default
      namespace: default
    spec:
      podSelector: {}
      ingress: []
  2. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f deny-by-default.yaml

    输出示例

    Copy to Clipboard Toggle word wrap
    networkpolicy.networking.k8s.io/deny-by-default created

  3. 输入以下命令在 default 命名空间中启动 web 服务:

    Copy to Clipboard Toggle word wrap
    $ oc run web --namespace=default --image=nginx --labels="app=web" --expose --port=80
  4. 运行以下命令来创建 prod 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc create namespace prod
  5. 运行以下命令来标记 prod 命名空间:

    Copy to Clipboard Toggle word wrap
    $ oc label namespace/prod purpose=production
  6. 运行以下命令,在 prod 命名空间中部署 alpine 镜像并启动 shell:

    Copy to Clipboard Toggle word wrap
    $ oc run test-6459 --namespace=prod --rm -i -t --image=alpine -- sh
  7. 打开另一个终端会话。
  8. 在这个新终端会话中,运行 ovn-trace 以验证在命名空间 prod 中运行的源 pod test-6459 与在 default 命名空间中的目标 pod 之间的通信失败:

    Copy to Clipboard Toggle word wrap
    $ ./ovnkube-trace \
     -src-namespace prod \
     -src test-6459 \
     -dst-namespace default \
     -dst web \
     -tcp -dst-port 80 \
     -loglevel 0

    预期输出

    Copy to Clipboard Toggle word wrap
    I0116 14:20:47.380775   50822 ovs.go:90] Maximum command line arguments set to: 191102
    ovn-trace source pod to destination pod indicates failure from test-6459 to web

  9. 运行以下命令,将日志级别增加到 2 以公开失败的原因:

    Copy to Clipboard Toggle word wrap
    $ ./ovnkube-trace \
     -src-namespace prod \
     -src test-6459 \
     -dst-namespace default \
     -dst web \
     -tcp -dst-port 80 \
     -loglevel 2

    预期输出

    Copy to Clipboard Toggle word wrap
    ct_lb_mark /* default (use --ct to customize) */
    ------------------------------------------------
     3. ls_out_acl_hint (northd.c:6092): !ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0, priority 4, uuid 32d45ad4
        reg0[8] = 1;
        reg0[10] = 1;
        next;
     4. ls_out_acl (northd.c:6435): reg0[10] == 1 && (outport == @a16982411286042166782_ingressDefaultDeny), priority 2000, uuid f730a887 
    1
    
        ct_commit { ct_mark.blocked = 1; };

    1
    因为默认的 deny 策略被到位,所以入口流量会被阻止
  10. 创建一个策略,允许来自特定命名空间中所有 pod 的流量,其标签为 purpose=production。将 YAML 保存到 web-allow-prod.yaml 文件中:

    Copy to Clipboard Toggle word wrap
    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: web-allow-prod
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: web
      policyTypes:
      - Ingress
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              purpose: production
  11. 输入以下命令应用策略:

    Copy to Clipboard Toggle word wrap
    $ oc apply -f web-allow-prod.yaml
  12. 输入以下命令运行 ovnkube-trace 来验证现在允许的流量:

    Copy to Clipboard Toggle word wrap
    $ ./ovnkube-trace \
     -src-namespace prod \
     -src test-6459 \
     -dst-namespace default \
     -dst web \
     -tcp -dst-port 80 \
     -loglevel 0

    预期输出

    Copy to Clipboard Toggle word wrap
    I0116 14:25:44.055207   51695 ovs.go:90] Maximum command line arguments set to: 191102
    ovn-trace source pod to destination pod indicates success from test-6459 to web
    ovn-trace destination pod to source pod indicates success from web to test-6459
    ovs-appctl ofproto/trace source pod to destination pod indicates success from test-6459 to web
    ovs-appctl ofproto/trace destination pod to source pod indicates success from web to test-6459
    ovn-detrace source pod to destination pod indicates success from test-6459 to web
    ovn-detrace destination pod to source pod indicates success from web to test-6459

  13. 在 open shell 中运行以下命令:

    Copy to Clipboard Toggle word wrap
     wget -qO- --timeout=2 http://web.default

    预期输出

    Copy to Clipboard Toggle word wrap
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>

23.4.3. 其他资源

23.5. 从 OpenShift SDN 网络插件迁移

作为集群管理员,您可以从 OpenShift SDN 网络插件迁移到 OVN-Kubernetes 网络插件。

您可以使用离线迁移方法从 OpenShift SDN 网络插件迁移到 OVN-Kubernetes 插件。离线迁移方法是包括一些停机时间的手动过程。

23.5.1. 迁移到 OVN-Kubernetes 网络插件

迁移到 OVN-Kubernetes 网络插件是一个手动的过程,其中会包括一些停机时间,在此期间集群无法被访问。

重要

在将 OpenShift Container Platform 集群迁移到使用 OVN-Kubernetes 网络插件前,将集群更新至最新的 z-stream 版本,以便所有最新的程序错误修复都应用到集群。

虽然提供了一个回滚过程,但迁移通常被认为是一个单向过程。

在以下平台上支持迁移到 OVN-Kubernetes 网络插件:

  • 裸机硬件
  • Amazon Web Services (AWS)
  • Google Cloud Platform (GCP)
  • IBM Cloud®
  • Microsoft Azure
  • Red Hat OpenStack Platform(RHOSP)
  • Red Hat Virtualization(RHV)
  • {vmw-first}
重要

Red Hat OpenShift Dedicated, Azure Red Hat OpenShift(ARO), 和 Red Hat OpenShift Service on AWS (ROSA) 上的受管 OpenShift 云服务不支持迁移到 OVN-Kubernetes 网络插件。

Nutanix 不支持从 OpenShift SDN 网络插件迁移到 OVN-Kubernetes 网络插件。

23.5.1.1. 迁移到 OVN-Kubernetes 网络插件的注意事项

如果您在 OpenShift Container Platform 集群中有超过 150 个节点,请创建一个支持问题单,供您迁移到 OVN-Kubernetes 网络插件。

迁移过程中不会保留分配给节点的子网以及分配给各个 pod 的 IP 地址。

虽然 OVN-Kubernetes 网络插件实现 OpenShift SDN 网络插件中存在的许多功能,但配置并不相同。

  • 如果您的集群使用以下 OpenShift SDN 网络插件功能,您必须在 OVN-Kubernetes 网络插件中手动配置相同的功能:

    • 命名空间隔离
    • 出口路由器 pod
  • 如果您的集群或周围的网络使用 100.64.0.0/16 地址范围中的任何部分,您必须在 spec.defaultNetwork.ovnKubernetesConfig 对象定义中指定 v4InternalSubnet spec 来选择另一个未使用的 IP 范围。OVN-Kubernetes 默认使用 IP 范围 100.64.0.0/16
  • 如果您的 openshift-sdn 集群具有 Precision Time Protocol (PTP),使用 User Datagram Protocol (UDP)进行硬件时间戳,并且您迁移到 OVN-Kubernetes 插件,则硬件时间戳无法应用到主接口设备,如 Open vSwitch (OVS)网桥。因此,UDP 版本 4 配置无法使用 br-ex 接口。

以下小节重点介绍了上述功能在 OVN-Kubernetes 和 OpenShift SDN 网络插件中的配置差异。

主网络接口

OpenShift SDN 插件允许 NodeNetworkConfigurationPolicy (NNCP)自定义资源(CR)的应用程序到节点上的主接口。OVN-Kubernetes 网络插件没有此功能。

如果您的 NNCP 应用到主接口,则必须在迁移到 OVN-Kubernetes 网络插件前删除 NNCP。删除 NNCP 不会从主接口中删除配置,但使用 OVN-Kubernetes,Kubernetes NMState 无法管理此配置。相反,configure-ovs.sh shell 脚本管理附加到这个接口的主接口和配置。

命名空间隔离

OVN-Kubernetes 仅支持网络策略隔离模式。

重要

对于使用在多租户或子网隔离模式下配置的 OpenShift SDN 的集群,您仍然可以迁移到 OVN-Kubernetes 网络插件。请注意,在迁移操作后,多租户隔离模式会被丢弃,因此您必须手动配置网络策略,以便为 Pod 和服务达到相同的项目级别的隔离。

出口 IP 地址

OpenShift SDN 支持两种不同的 Egress IP 模式:

  • 自动分配方法中,给节点分配一个出口 IP 地址范围。
  • 手动分配方法中,给节点分配包含一个或多个出口 IP 地址的列表。

迁移过程支持迁移使用自动分配模式的 Egress IP 配置。

下表中描述了在 OVN-Kubernetes 和 OpenShift SDN 配置出口 IP 地址的不同:

表 23.4. 出口 IP 地址配置的不同
OVN-KubernetesOpenShift SDN
  • 创建 EgressIPs 对象
  • 在一个 Node 对象上添加注解
  • NetNamespace 对象进行补丁
  • HostSubnet 对象进行补丁

有关在 OVN-Kubernetes 中使用出口 IP 地址的更多信息,请参阅"配置出口 IP 地址"。

出口网络策略

下表中描述在 OVN-Kubernetes 和 OpenShift SDN 间配置出口网络策略(也称为出口防火墙)的不同之处:

表 23.5. 出口网络策略配置的不同
OVN-KubernetesOpenShift SDN
  • 在命名空间中创建 EgressFirewall 对象
  • 在命名空间中创建一个 EgressNetworkPolicy 对象
注意

由于 EgressFirewall 对象的名称只能设置为 default,在迁移后,所有迁移的 EgressNetworkPolicy 对象都会命名为 default,而无论在 OpenShift SDN 下的名称是什么。

如果您随后回滚到 OpenShift SDN,则所有 EgressNetworkPolicy 对象都会命名为 default,因为之前的名称已丢失。

有关在 OVN-Kubernetes 中使用出口防火墙的更多信息,请参阅"配置项目出口防火墙"。

出口路由器 pod

OVN-Kubernetes 支持重定向模式的出口路由器 pod。OVN-Kubernetes 不支持 HTTP 代理模式或 DNS 代理模式的出口路由器 pod。

使用 Cluster Network Operator 部署出口路由器时,您无法指定节点选择器来控制用于托管出口路由器 pod 的节点。

多播

下表中描述了在 OVN-Kubernetes 和 OpenShift SDN 上启用多播流量的区别:

表 23.6. 多播配置的不同
OVN-KubernetesOpenShift SDN
  • Namespace 对象上添加注解
  • NetNamespace 对象中添加注解

有关在 OVN-Kubernetes 中使用多播的更多信息,请参阅"启用项目多播"。

网络策略

OVN-Kubernetes 在 networking.k8s.io/v1 API 组中完全支持 Kubernetes NetworkPolicy API。从 OpenShift SDN 进行迁移时,网络策略不需要更改。

23.5.1.2. 迁移过程如何工作

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

表 23.7. 从 OpenShift SDN 迁移到 OVN-Kubernetes
用户发起的步骤迁移操作

将名为 clusterNetwork.operator.openshift.io 自定义资源(CR)的 migration 字段设置为 OVNKubernetes。在设置值之前,请确保 migration 项为 null

Cluster Network Operator (CNO)
相应地更新名为 clusterNetwork.config.openshift.io CR 的状态。
Machine Config Operator(MCO)
将更新发布到 OVN-Kubernetes 所需的 systemd 配置 ; MCO 默认更新每个池的单一机器,从而导致迁移总时间随着集群大小而增加。

更新 Network.config.openshift.io CR 的 networkType 字段。

CNO

执行以下操作:

  • 销毁 OpenShift SDN control plane pod。
  • 部署 OVN-Kubernetes control plane pod。
  • 更新 Multus 对象以反映新的网络插件。

重新引导集群中的每个节点。

Cluster
当节点重启时,集群会为 OVN-Kubernetes 集群网络上的 pod 分配 IP 地址。

如果需要回滚到 OpenShift SDN,下表描述了这个过程。

重要

在启动回滚前,您必须等待 OpenShift SDN 到 OVN-Kubernetes 网络插件的迁移过程成功。

表 23.8. 执行到 OpenShift SDN 的回滚
用户发起的步骤迁移操作

挂起 MCO 以确保它不会中断迁移。

MCO 停止。

将名为 clusterNetwork.operator.openshift.io 自定义资源(CR)的 migration 字段设置为 OpenShiftSDN。在设置值之前,请确保 migration 项为 null

CNO
相应地更新名为 clusterNetwork.config.openshift.io CR 的状态。

更新 networkType 字段。

CNO

执行以下操作:

  • 销毁 OVN-Kubernetes control plane pod。
  • 部署 OpenShift SDN control plane pod。
  • 更新 Multus 对象以反映新的网络插件。

重新引导集群中的每个节点。

Cluster
当节点重启时,集群会为 OpenShift-SDN 网络上的 pod 分配 IP 地址。

在集群重启中的所有节点后启用 MCO。

MCO
将更新发布到 OpenShift SDN 所需的 systemd 配置 ; MCO 默认更新每个池的单一机器,因此迁移总时间随着集群的大小而增加。

23.5.2. 迁移到 OVN-Kubernetes 网络插件

作为集群管理员,您可以将集群的网络插件更改为 OVN-Kubernetes。在迁移过程中,您必须重新引导集群中的每个节点。

重要

在进行迁移时,集群不可用,工作负载可能会中断。仅在服务中断可以接受时才执行迁移。

先决条件

  • 您已在网络策略隔离模式下使用 OpenShift SDN CNI 网络插件配置集群。
  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 您有最新的 etcd 数据库备份。
  • 您可以手动重新引导每个节点。
  • 您检查集群是否处于已知良好状态,且没有任何错误。
  • 您创建了一条安全组规则,允许所有云平台上所有节点的端口 6081 上用户数据报协议(UDP)数据包。

流程

  1. 要备份集群网络的配置,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get Network.config.openshift.io cluster -o yaml > cluster-openshift-sdn.yaml
  2. 运行以下命令,验证 OVN_SDN_MIGRATION_TIMEOUT 环境变量是否已设置,并等于 0s

    Copy to Clipboard Toggle word wrap
    #!/bin/bash
    
    if [ -n "$OVN_SDN_MIGRATION_TIMEOUT" ] && [ "$OVN_SDN_MIGRATION_TIMEOUT" = "0s" ]; then
        unset OVN_SDN_MIGRATION_TIMEOUT
    fi
    
    #loops the timeout command of the script to repeatedly check the cluster Operators until all are available.
    
    co_timeout=${OVN_SDN_MIGRATION_TIMEOUT:-1200s}
    timeout "$co_timeout" bash <<EOT
    until
      oc wait co --all --for='condition=AVAILABLE=True' --timeout=10s && \
      oc wait co --all --for='condition=PROGRESSING=False' --timeout=10s && \
      oc wait co --all --for='condition=DEGRADED=False' --timeout=10s;
    do
      sleep 10
      echo "Some ClusterOperators Degraded=False,Progressing=True,or Available=False";
    done
    EOT
  3. 运行以下命令,从 Cluster Network Operator (CNO) 配置对象中删除配置:

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type='merge' \
    --patch '{"spec":{"migration":null}}'
  4. 通过完成以下步骤,删除 NodeNetworkConfigurationPolicy (NNCP)自定义资源(CR)定义 OpenShift SDN 网络插件的主网络接口:

    1. 输入以下命令检查现有 NNCP CR 是否将主接口绑定到集群:

      Copy to Clipboard Toggle word wrap
      $ oc get nncp

      输出示例

      Copy to Clipboard Toggle word wrap
      NAME          STATUS      REASON
      bondmaster0   Available   SuccessfullyConfigured

      Network Manager 将绑定的主接口的连接配置文件存储在 /etc/NetworkManager/system-connections 系统路径中。

    2. 从集群中删除 NNCP:

      Copy to Clipboard Toggle word wrap
      $ oc delete nncp <nncp_manifest_filename>
  5. 要为迁移准备所有节点,请运行以下命令在 CNO 配置对象上设置 migration 字段:

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type='merge' \
      --patch '{ "spec": { "migration": { "networkType": "OVNKubernetes" } } }'
    注意

    此步骤不会立即部署 OVN-Kubernetes。相反,指定 migration 字段会触发 Machine Config Operator(MCO)将新机器配置应用到集群中的所有节点,以准备 OVN-Kubernetes 部署。

    1. 运行以下命令检查重启是否已完成:

      Copy to Clipboard Toggle word wrap
      $ oc get mcp
    2. 运行以下命令,检查所有集群 Operator 是否可用:

      Copy to Clipboard Toggle word wrap
      $ oc get co
    3. 另外:您可以禁用将几个 OpenShift SDN 功能自动迁移到 OVN-Kubernetes 等效功能:

      • 出口 IP
      • 出口防火墙
      • 多播

      要为之前记录的 OpenShift SDN 功能禁用配置自动迁移,请指定以下键:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.operator.openshift.io cluster --type='merge' \
        --patch '{
          "spec": {
            "migration": {
              "networkType": "OVNKubernetes",
              "features": {
                "egressIP": <bool>,
                "egressFirewall": <bool>,
                "multicast": <bool>
              }
            }
          }
        }'

      其中:

      bool:指定是否启用功能的迁移。默认值是 true

  6. 可选: 您可以自定义 OVN-Kubernetes 的以下设置,以满足您的网络基础架构要求:

    • 最大传输单元 (MTU)。在为这个可选步骤自定义 MTU 前请考虑以下几点:

      • 如果您使用默认 MTU,并且要在迁移期间保留默认 MTU,则可以忽略这一步。
      • 如果您使用自定义 MTU,并且要在迁移过程中保留自定义 MTU,则必须在此步骤中声明自定义 MTU 值。
      • 如果要在迁移过程中更改 MTU 值,此步骤将无法正常工作。相反,您必须首先按照"选择集群 MTU"的说明进行操作。然后,您可以通过执行此步骤并声明自定义 MTU 值来保留自定义 MTU 值。

        注意

        OpenShift-SDN 和 OVN-Kubernetes 具有不同的覆盖(overlay)开销。MTU 值应遵循在 "MTU 值选择" 页面中找到的准则来选择。

    • Geneve(Generic Network Virtualization Encapsulation)覆盖网络端口
    • OVN-Kubernetes IPv4 内部子网

    要自定义之前记录的设置之一,请输入以下命令。如果您不需要更改默认值,请从补丁中省略该键。

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type=merge \
      --patch '{
        "spec":{
          "defaultNetwork":{
            "ovnKubernetesConfig":{
              "mtu":<mtu>,
              "genevePort":<port>,
              "v4InternalSubnet":"<ipv4_subnet>"
        }}}}'

    其中:

    mtu
    Geneve 覆盖网络的 MTU。这个值通常是自动配置的;但是,如果集群中的节点没有都使用相同的 MTU,那么您必须将此值明确设置为比最小节点 MTU 的值小 100
    port
    Geneve 覆盖网络的 UDP 端口。如果没有指定值,则默认为 6081。端口不能与 OpenShift SDN 使用的 VXLAN 端口相同。VXLAN 端口的默认值为 4789
    ipv4_subnet
    OVN-Kubernetes 内部使用的 IPv4 地址范围。您必须确保 IP 地址范围没有与 OpenShift Container Platform 安装使用的任何其他子网重叠。IP 地址范围必须大于可添加到集群的最大节点数。默认值为 100.64.0.0/16

    更新 mtu 字段的 patch 命令示例

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type=merge \
      --patch '{
        "spec":{
          "defaultNetwork":{
            "ovnKubernetesConfig":{
              "mtu":1200
        }}}}'

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

    Copy to Clipboard Toggle word wrap
    $ oc get mcp

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

    注意

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

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

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

      Copy to Clipboard Toggle word wrap
      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

      Copy to Clipboard Toggle word wrap
      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. 要确认机器配置正确,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get machineconfig <config_name> -o yaml | grep ExecStart

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

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

      Copy to Clipboard Toggle word wrap
      ExecStart=/usr/local/bin/configure-ovs.sh OVNKubernetes
    3. 如果节点一直处于 NotReady 状态,检查机器配置守护进程 pod 日志并解决所有错误。

      1. 运行以下命令列出 pod:

        Copy to Clipboard Toggle word wrap
        $ oc get pod -n openshift-machine-config-operator

        输出示例

        Copy to Clipboard Toggle word wrap
        NAME                                         READY   STATUS    RESTARTS   AGE
        machine-config-controller-75f756f89d-sjp8b   1/1     Running   0          37m
        machine-config-daemon-5cf4b                  2/2     Running   0          43h
        machine-config-daemon-7wzcd                  2/2     Running   0          43h
        machine-config-daemon-fc946                  2/2     Running   0          43h
        machine-config-daemon-g2v28                  2/2     Running   0          43h
        machine-config-daemon-gcl4f                  2/2     Running   0          43h
        machine-config-daemon-l5tnv                  2/2     Running   0          43h
        machine-config-operator-79d9c55d5-hth92      1/1     Running   0          37m
        machine-config-server-bsc8h                  1/1     Running   0          43h
        machine-config-server-hklrm                  1/1     Running   0          43h
        machine-config-server-k9rtx                  1/1     Running   0          43h

        配置守护进程 pod 的名称使用以下格式: machine-config-daemon-<seq><seq> 值是一个随机的五个字符的字母数字序列。

      2. 使用以下命令,输出在上一个输出中显示的第一个机器配置守护进程 pod 的 pod 日志:

        Copy to Clipboard Toggle word wrap
        $ oc logs <pod> -n openshift-machine-config-operator

        其中 pod 是机器配置守护进程 pod 的名称。

      3. 解决上一命令输出中显示的日志中的任何错误。
  9. 要启动迁移,请使用以下命令配置 OVN-Kubernetes 网络插件:

    • 要指定网络供应商而不更改集群网络 IP 地址块,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.config.openshift.io cluster \
        --type='merge' --patch '{ "spec": { "networkType": "OVNKubernetes" } }'
    • 要指定不同的集群网络 IP 地址块,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.config.openshift.io cluster \
        --type='merge' --patch '{
          "spec": {
            "clusterNetwork": [
              {
                "cidr": "<cidr>",
                "hostPrefix": <prefix>
              }
            ],
            "networkType": "OVNKubernetes"
          }
        }'

      其中 cidr 是 CIDR 块,prefix 是集群中每个节点的 CIDR 块的分片。您不能使用任何与 10064.0.0/16 CIDR 块重叠的 CIDR 块,因为 OVN-Kubernetes 网络供应商在内部使用此块。

      重要

      您无法在迁移过程中更改服务网络地址块。

  10. 在继续执行后续步骤前,验证 Multus 守护进程集的 rollout 是否已完成:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-multus rollout status daemonset/multus

    Multus pod 的名称采用 multus-<xxxxx> 的形式,其中 <xxxxx>是由字母组成的随机序列。pod 可能需要一些时间才能重启。

    输出示例

    Copy to Clipboard Toggle word wrap
    Waiting for daemon set "multus" rollout to finish: 1 out of 6 new pods have been updated...
    ...
    Waiting for daemon set "multus" rollout to finish: 5 of 6 updated pods are available...
    daemon set "multus" successfully rolled out

  11. 要完成更改网络插件,请重新引导集群中的每个节点。您可以使用以下方法之一重新引导集群中的节点:

    重要

    以下脚本同时重新引导集群中的所有节点。这可能导致集群不稳定。另一种选择是,每次只手动重新引导一个节点。逐一重新引导节点会导致,在具有多个节点的集群中出现大量停机时间。

    在重新引导节点前,集群 Operator 无法正常工作。

    • 使用 oc rsh 命令,您可以使用类似如下的 bash 脚本:

      Copy to Clipboard Toggle word wrap
      #!/bin/bash
      readarray -t POD_NODES <<< "$(oc get pod -n openshift-machine-config-operator -o wide| grep daemon|awk '{print $1" "$7}')"
      
      for i in "${POD_NODES[@]}"
      do
        read -r POD NODE <<< "$i"
        until oc rsh -n openshift-machine-config-operator "$POD" chroot /rootfs shutdown -r +1
          do
            echo "cannot reboot node $NODE, retry" && sleep 3
          done
      done
    • 使用 ssh 命令,您可以使用类似如下的 bash 脚本:该脚本假设您已将 sudo 配置为不提示输入密码。

      Copy to Clipboard Toggle word wrap
      #!/bin/bash
      
      for ip in $(oc get nodes  -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}')
      do
         echo "reboot node $ip"
         ssh -o StrictHostKeyChecking=no core@$ip sudo shutdown -r -t 3
      done
  12. 确认迁移成功完成:

    1. 要确认网络插件是 OVN-Kubernetes,请输入以下命令。status.networkType 的值必须是 OVNKubernetes

      Copy to Clipboard Toggle word wrap
      $ oc get network.config/cluster -o jsonpath='{.status.networkType}{"\n"}'
    2. 要确认集群节点处于 Ready 状态,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get nodes
    3. 要确认您的 pod 不在错误状态,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get pods --all-namespaces -o wide --sort-by='{.spec.nodeName}'

      如果节点上的 pod 处于错误状态,请重新引导该节点。

    4. 要确认所有集群 Operator 没有处于异常状态,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get co

      每个集群 Operator 的状态必须是: AVAILABLE="True"PROGRESSING="False"DEGRADED="False"。如果 Cluster Operator 不可用或降级,请检查集群 Operator 的日志以了解更多信息。

  13. 只有在迁移成功且集群处于良好状态时完成以下步骤:

    1. 要从 CNO 配置对象中删除迁移配置,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.operator.openshift.io cluster --type='merge' \
        --patch '{ "spec": { "migration": null } }'
    2. 要删除 OpenShift SDN 网络供应商的自定义配置,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.operator.openshift.io cluster --type='merge' \
        --patch '{ "spec": { "defaultNetwork": { "openshiftSDNConfig": null } } }'
    3. 要删除 OpenShift SDN 网络供应商命名空间,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc delete namespace openshift-sdn

后续步骤

  • 可选:在集群迁移后,您可以将 IPv4 单堆栈集群转换为支持 IPv4 和 IPv6 地址系列的双网络集群网络。如需更多信息,请参阅"协调 IPv4/IPv6 双栈网络"。

23.5.3. 其他资源

23.5.4. 了解 OVN-Kubernetes 中外部 IP 行为的更改

当从 OpenShift SDN 迁移到 OVN-Kubernetes (OVN-K)时,使用外部 IP 的服务可能会因为网络策略强制而在命名空间中无法访问。

在 OpenShift SDN 中,外部 IP 默认可在命名空间间访问。但是,在 OVN-K 中,网络策略严格强制执行多租户隔离,从而防止访问通过外部 IP 从其他命名空间公开的服务。

为确保访问,请考虑以下替代方案:

  • 使用入口或路由 :使用外部 IP 公开服务,在保持安全控制时配置入口或路由来允许外部访问。
  • 调整 NetworkPolicy 自定义资源(CR):修改 NetworkPolicy CR 以明确允许从所需命名空间中访问,并确保允许流量访问指定的服务端口。如果没有明确允许到所需端口的流量,访问可能仍然被阻止,即使允许命名空间。
  • 使用 LoadBalancer 服务:如果适用,部署 LoadBalancer 服务而不是依赖于外部 IP。有关配置 "NetworkPolicy 和 external IP in OVN-Kubernetes" 的更多信息。

23.6. 回滚到 OpenShift SDN 网络供应商

作为集群管理员,只有在迁移到 OVN-Kubernetes 网络插件后,才能从 OVN-Kubernetes 网络插件回滚到 OpenShift SDN。

23.6.1. 迁移到 OpenShift SDN 网络插件

集群管理员可以使用离线迁移方法回滚到 OpenShift SDN Container Network Interface (CNI) 网络插件。在迁移过程中,您必须手动重新引导集群中的每个节点。使用离线迁移方法时,集群会存在一些停机时间。

重要

在启动回滚前,您必须等待 OpenShift SDN 到 OVN-Kubernetes 网络插件的迁移过程成功。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 使用具有 cluster-admin 角色的用户访问集群。
  • 在使用 OVN-Kubernetes 网络插件配置的基础架构上安装集群。
  • etcd 数据库的最新备份可用。
  • 可根据每个节点手动触发重新引导。
  • 集群处于已知良好状态,没有任何错误。

流程

  1. 停止由 Machine Config Operator(MCO)管理的所有机器配置池:

    • 在 CLI 中输入以下命令来停止 master 配置池:

      Copy to Clipboard Toggle word wrap
      $ oc patch MachineConfigPool master --type='merge' --patch \
        '{ "spec": { "paused": true } }'
    • 在 CLI 中输入以下命令来停止 worker 机器配置池:

      Copy to Clipboard Toggle word wrap
      $ oc patch MachineConfigPool worker --type='merge' --patch \
        '{ "spec":{ "paused": true } }'
  2. 要准备迁移,请在 CLI 中输入以下命令将 migration 字段设置为 null

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type='merge' \
      --patch '{ "spec": { "migration": null } }'
  3. 在 CLI 中输入以下命令,检查 Network.config.openshift.io 对象的迁移状态是否为空。空命令输出表示对象不在迁移操作中。

    Copy to Clipboard Toggle word wrap
    $ oc get Network.config cluster -o jsonpath='{.status.migration}'
  4. 将补丁应用到 Network.operator.openshift.io 对象,通过在 CLI 中输入以下命令将网络插件设置为 OpenShift SDN:

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type='merge' \
      --patch '{ "spec": { "migration": { "networkType": "OpenShiftSDN" } } }'
    重要

    如果您在 Network.operator.openshift.io 对象上的补丁操作完成前将补丁应用到 Network.config.openshift.io 对象,Cluster Network Operator (CNO) 进入降级状态,这会导致 slight 延迟直到 CNO 从降级状态恢复。

  5. 在 CLI 中输入以下命令,确认 Network.config.openshift.io 集群对象的网络插件的迁移状态为 OpenShiftSDN

    Copy to Clipboard Toggle word wrap
    $ oc get Network.config cluster -o jsonpath='{.status.migration.networkType}'
  6. 将补丁应用到 Network.config.openshift.io 对象,通过在 CLI 中输入以下命令将网络插件设置为 OpenShift SDN:

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.config.openshift.io cluster --type='merge' \
      --patch '{ "spec": { "networkType": "OpenShiftSDN" } }'
  7. 可选:禁用将几个 OVN-Kubernetes 功能自动迁移到 OpenShift SDN 等效功能:

    • 出口 IP
    • 出口防火墙
    • 多播

    要为之前记录的 OpenShift SDN 功能禁用配置自动迁移,请指定以下键:

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type='merge' \
      --patch '{
        "spec": {
          "migration": {
            "networkType": "OpenShiftSDN",
            "features": {
              "egressIP": <bool>,
              "egressFirewall": <bool>,
              "multicast": <bool>
            }
          }
        }
      }'

    其中:

    bool:指定是否启用功能的迁移。默认值是 true

  8. 可选: 您可以自定义 OpenShift SDN 的以下设置,以满足您的网络基础架构的要求:

    • 最大传输单元(MTU)
    • VXLAN 端口

    要自定义之前记录的设置或两个设置,请在 CLI 中自定义并输入以下命令。如果您不需要更改默认值,请从补丁中省略该键。

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type=merge \
      --patch '{
        "spec":{
          "defaultNetwork":{
            "openshiftSDNConfig":{
              "mtu":<mtu>,
              "vxlanPort":<port>
        }}}}'
    mtu
    VXLAN 覆盖网络的 MTU。这个值通常是自动配置的;但是,如果集群中的节点没有都使用相同的 MTU,那么您必须将此值明确设置为比最小节点 MTU 的值小 50
    port
    VXLAN 覆盖网络的 UDP 端口。如果没有指定值,则默认为 4789。端口不能与 OVN-Kubernetes 使用的生成端口相同。Geneve 端口的默认值为 6081

    patch 命令示例

    Copy to Clipboard Toggle word wrap
    $ oc patch Network.operator.openshift.io cluster --type=merge \
      --patch '{
        "spec":{
          "defaultNetwork":{
            "openshiftSDNConfig":{
              "mtu":1200
        }}}}'

  9. 重新引导集群中的每个节点。您可以使用以下方法之一重新引导集群中的节点:

    • 使用 oc rsh 命令,您可以使用类似如下的 bash 脚本:

      Copy to Clipboard Toggle word wrap
      #!/bin/bash
      readarray -t POD_NODES <<< "$(oc get pod -n openshift-machine-config-operator -o wide| grep daemon|awk '{print $1" "$7}')"
      
      for i in "${POD_NODES[@]}"
      do
        read -r POD NODE <<< "$i"
        until oc rsh -n openshift-machine-config-operator "$POD" chroot /rootfs shutdown -r +1
          do
            echo "cannot reboot node $NODE, retry" && sleep 3
          done
      done
    • 使用 ssh 命令,您可以使用类似如下的 bash 脚本:该脚本假设您已将 sudo 配置为不提示输入密码。

      Copy to Clipboard Toggle word wrap
      #!/bin/bash
      
      for ip in $(oc get nodes  -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}')
      do
         echo "reboot node $ip"
         ssh -o StrictHostKeyChecking=no core@$ip sudo shutdown -r -t 3
      done
  10. 等待 Multus 守护进程集的 rollout 完成。运行以下命令查看您的 rollout 状态:

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-multus rollout status daemonset/multus

    Multus pod 的名称采用 multus-<xxxxx> 的形式,其中 <xxxxx>是由字母组成的随机序列。pod 可能需要一些时间才能重启。

    输出示例

    Copy to Clipboard Toggle word wrap
    Waiting for daemon set "multus" rollout to finish: 1 out of 6 new pods have been updated...
    ...
    Waiting for daemon set "multus" rollout to finish: 5 of 6 updated pods are available...
    daemon set "multus" successfully rolled out

  11. 重新引导集群中的节点并推出 multus pod 后,通过运行以下命令启动所有机器配置池:

    • 启动 master 配置池:

      Copy to Clipboard Toggle word wrap
      $ oc patch MachineConfigPool master --type='merge' --patch \
        '{ "spec": { "paused": false } }'
    • 启动 worker 配置池:

      Copy to Clipboard Toggle word wrap
      $ oc patch MachineConfigPool worker --type='merge' --patch \
        '{ "spec": { "paused": false } }'

    当 MCO 更新每个配置池中的机器时,它会重新引导每个节点。

    默认情况下,MCO 会在一个时间段内为每个池更新一台机器,因此迁移完成所需要的时间会随集群大小的增加而增加。

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

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

      Copy to Clipboard Toggle word wrap
      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

      Copy to Clipboard Toggle word wrap
      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. 要确认机器配置正确,在 CLI 中输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get machineconfig <config_name> -o yaml

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

  13. 确认迁移成功完成:

    1. 要确认网络插件是 OpenShift SDN,请在 CLI 中输入以下命令。status.networkType 的值必须是 OpenShiftSDN

      Copy to Clipboard Toggle word wrap
      $ oc get Network.config/cluster -o jsonpath='{.status.networkType}{"\n"}'
    2. 要确认集群节点处于 Ready 状态,请在 CLI 中输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get nodes
    3. 如果节点一直处于 NotReady 状态,检查机器配置守护进程 pod 日志并解决所有错误。

      1. 要列出 pod,在 CLI 中输入以下命令:

        Copy to Clipboard Toggle word wrap
        $ oc get pod -n openshift-machine-config-operator

        输出示例

        Copy to Clipboard Toggle word wrap
        NAME                                         READY   STATUS    RESTARTS   AGE
        machine-config-controller-75f756f89d-sjp8b   1/1     Running   0          37m
        machine-config-daemon-5cf4b                  2/2     Running   0          43h
        machine-config-daemon-7wzcd                  2/2     Running   0          43h
        machine-config-daemon-fc946                  2/2     Running   0          43h
        machine-config-daemon-g2v28                  2/2     Running   0          43h
        machine-config-daemon-gcl4f                  2/2     Running   0          43h
        machine-config-daemon-l5tnv                  2/2     Running   0          43h
        machine-config-operator-79d9c55d5-hth92      1/1     Running   0          37m
        machine-config-server-bsc8h                  1/1     Running   0          43h
        machine-config-server-hklrm                  1/1     Running   0          43h
        machine-config-server-k9rtx                  1/1     Running   0          43h

        配置守护进程 pod 的名称使用以下格式: machine-config-daemon-<seq><seq> 值是一个随机的五个字符的字母数字序列。

      2. 要显示以上输出中显示的每个机器配置守护进程 pod 的 pod 日志,请在 CLI 中输入以下命令:

        Copy to Clipboard Toggle word wrap
        $ oc logs <pod> -n openshift-machine-config-operator

        其中 pod 是机器配置守护进程 pod 的名称。

      3. 解决上一命令输出中显示的日志中的任何错误。
    4. 要确认您的 pod 不在错误状态,请在 CLI 中输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc get pods --all-namespaces -o wide --sort-by='{.spec.nodeName}'

      如果节点上的 pod 处于错误状态,请重新引导该节点。

  14. 只有在迁移成功且集群处于良好状态时完成以下步骤:

    1. 要从 Cluster Network Operator 配置对象中删除迁移配置,请在 CLI 中输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.operator.openshift.io cluster --type='merge' \
        --patch '{ "spec": { "migration": null } }'
    2. 要删除 OVN-Kubernetes 配置,请在 CLI 中输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc patch Network.operator.openshift.io cluster --type='merge' \
        --patch '{ "spec": { "defaultNetwork": { "ovnKubernetesConfig":null } } }'
    3. 要删除 OVN-Kubernetes 网络供应商命名空间,请在 CLI 中输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc delete namespace openshift-ovn-kubernetes

23.7. 转换为 IPv4/IPv6 双栈网络

作为集群管理员,您可以将 IPv4 单栈集群转换为支持 IPv4 和 IPv6 地址系列的双网络集群网络。转换为双栈后,所有新创建的 pod 都启用了双栈。

注意

在裸机、IBM Power、IBM Z 基础架构和单一节点 OpenShift 集群上置备的集群上支持双栈网络。

注意

在使用双栈网络时,您无法使用 IPv4 映射 IPv6 地址,如 ::FFFF:198.51.100.1,其中需要 IPv6。

23.7.1. 转换为双栈集群网络

作为集群管理员,您可以将单堆栈集群网络转换为双栈集群网络。

注意

转换为双栈网络后,只有新创建的 pod 会被分配 IPv6 地址。必须重新创建在转换前创建的所有 pod,才能接收 IPv6 地址。

重要

在继续操作前,请确保 OpenShift 集群使用版本 4.12.5 或更高版本。否则,转换可能会因为一个程序错误(ovnkube node pod crashed after converting to a dual-stack cluster network)而失败。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 集群使用 OVN-Kubernetes 网络插件。
  • 集群节点具有 IPv6 地址。
  • 您已根据基础架构配置了启用了 IPv6 的路由器。

流程

  1. 要为集群和服务网络指定 IPv6 地址块,请创建一个包含以下 YAML 的文件:

    Copy to Clipboard Toggle word wrap
    - op: add
      path: /spec/clusterNetwork/-
      value: 
    1
    
        cidr: fd01::/48
        hostPrefix: 64
    - op: add
      path: /spec/serviceNetwork/-
      value: fd02::/112 
    2
    1
    使用 cidrhostPrefix 字段指定对象。主机前缀必须为 64 或更高。IPv6 CIDR 前缀必须足够大,以容纳指定的主机前缀。
    2
    指定一个带有 112 前缀的 IPv6 CIDR。Kubernetes 仅使用最低 16 位。对于前缀 112,IP 地址从 112128 位进行分配。
  2. 要修补集群网络配置,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc patch network.config.openshift.io cluster \
      --type='json' --patch-file <file>.yaml

    其中:

    file

    指定您在上一步中创建的文件的名称。

    输出示例

    Copy to Clipboard Toggle word wrap
    network.config.openshift.io/cluster patched

验证

完成以下步骤以验证,集群网络是否可以识别您在上一步中指定的 IPv6 地址块。

  1. 显示网络配置:

    Copy to Clipboard Toggle word wrap
    $ oc describe network

    输出示例

    Copy to Clipboard Toggle word wrap
    Status:
      Cluster Network:
        Cidr:               10.128.0.0/14
        Host Prefix:        23
        Cidr:               fd01::/48
        Host Prefix:        64
      Cluster Network MTU:  1400
      Network Type:         OVNKubernetes
      Service Network:
        172.30.0.0/16
        fd02::/112

23.7.2. 转换为单堆栈集群网络

作为集群管理员,您可以将双栈集群网络转换为单堆栈集群网络。

重要

如果您最初将 IPv4 单堆栈集群网络转换为双栈集群,则只能转换为 IPv4 单堆栈集群,而不是 IPv6 单堆栈集群网络。相同的限制适用于转换为 IPv6 单堆栈集群网络。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 集群使用 OVN-Kubernetes 网络插件。
  • 集群节点具有 IPv6 地址。
  • 您已启用了双栈网络。

流程

  1. 运行以下命令来编辑 networks.config.openshift.io 自定义资源 (CR):

    Copy to Clipboard Toggle word wrap
    $ oc edit networks.config.openshift.io
  2. 从完成"Converting to a dual-stack 集群网络"步骤"步骤,删除添加到 cidr 中的 IPv4 或 IPv6 配置。

23.8. 出口防火墙和网络策略规则的日志记录

作为集群管理员,您可以为集群配置审计日志记录,并为一个或多个命名空间启用日志记录。OpenShift Container Platform 为出口防火墙和网络策略生成审计日志。

注意

审计日志记录仅适用于 OVN-Kubernetes 网络插件

23.8.1. 审计日志记录

OVN-Kubernetes 网络插件使用 Open Virtual Network (OVN) ACL 来管理出口防火墙和网络策略。审计日志记录会公开允许和拒绝 ACL 事件。

您可以为审计日志配置目的地,如 syslog 服务器或 UNIX 域套接字。无论任何其他配置如何,审计日志始终保存到集群中的每个 OVN-Kubernetes pod 上的 /var/log/ovn/acl-audit-log

您可以使用 k8s.ovn.org/acl-logging 部分为每个命名空间启用审计日志记录。在 k8s.ovn.org/acl-logging 部分中,您必须指定 allowdeny 或这两个值来为命名空间启用审计日志记录。

注意

网络策略不支持将 Pass 操作设置为规则。

ACL-logging 实现记录网络的访问控制列表 (ACL) 事件。您可以查看这些日志来分析任何潜在的安全问题。

命名空间注解示例

Copy to Clipboard Toggle word wrap
kind: Namespace
apiVersion: v1
metadata:
  name: example1
  annotations:
    k8s.ovn.org/acl-logging: |-
      {
        "deny": "info",
        "allow": "info"
      }

要查看默认的 ACL 日志记录配置值,请参阅 cluster-network-03-config.yml 文件中的 policyAuditConfig 对象。如果需要,您可以更改此文件中的日志文件参数的 ACL 日志记录配置值。

日志信息格式与 RFC5424 中定义的 syslog 兼容。syslog 工具可配置,默认为 local0。以下示例显示了日志消息中输出的关键参数及其值:

输出参数及其值的日志记录消息示例

Copy to Clipboard Toggle word wrap
<timestamp>|<message_serial>|acl_log(ovn_pinctrl0)|<severity>|name="<acl_name>", verdict="<verdict>", severity="<severity>", direction="<direction>": <flow>

其中:

  • <timestamp> 声明创建日志消息的时间和日期。
  • <message_serial> 列出日志消息的序列号。
  • acl_log (ovn_pinctrl0) 是一个字面字符串,它会在 OVN-Kubernetes 插件中输出日志消息的位置。
  • <severity> 为日志消息设置严重性级别。如果您启用支持 allowdeny 任务的审计日志记录,则日志消息输出中会显示两个严重性级别。
  • <name> 说明由网络策略创建的 OVN Network Bridging Database (nbdb) 中的 ACL-logging 实现的名称。
  • <verdict> 可以是 allowdrop
  • <direction> 可以是 to-lportfrom-lport,表示策略应用到 pod 的流量。
  • <flow> 显示与 OpenFlow 协议等效的格式的数据包信息。此参数包含 Open vSwitch (OVS) 字段。

以下示例显示了 flow 参数用来从系统内存提取数据包信息的 OVS 字段:

flow 参数用来提取数据包信息的 OVS 字段示例

Copy to Clipboard Toggle word wrap
<proto>,vlan_tci=0x0000,dl_src=<src_mac>,dl_dst=<source_mac>,nw_src=<source_ip>,nw_dst=<target_ip>,nw_tos=<tos_dscp>,nw_ecn=<tos_ecn>,nw_ttl=<ip_ttl>,nw_frag=<fragment>,tp_src=<tcp_src_port>,tp_dst=<tcp_dst_port>,tcp_flags=<tcp_flags>

其中:

  • <proto> 声明协议。有效值为 tcpudp
  • vlan_tci=0x0000 声明 VLAN 标头为 0,因为没有为内部 pod 网络流量设置 VLAN ID。
  • <src_mac> 指定 Media Access Control (MAC) 地址的源。
  • <source_mac> 指定 MAC 地址的目的地。
  • <source_ip> 列出源 IP 地址
  • <target_ip> 列出目标 IP 地址。
  • <tos_dscp> 声明 Differentiated Services Code Point (DSCP) 值,对网络流量进行分类并进行优先级排序。
  • <tos_ecn> 声明 Explicit Congestion Notification (ECN) 值,它表示您的网络中的阻塞网络流量。
  • <ip_ttl> 声明数据包的 Time To Live (TTP) 信息。
  • <fragment> 指定要匹配的 IP 片段或 IP 非碎片。
  • <tcp_src_port> 显示 TCP 和 UDP 协议的端口源。
  • <tcp_dst_port> 列出 TCP 和 UDP 协议的目的地端口。
  • <tcp_flags> 支持多个标示,如 SYN, ACK, PSH 等。如果您需要设置多个值,则不同的值由竖线 (|) 分隔。UDP 协议不支持此参数。
注意

有关前面的字段描述的更多信息,请转至 ovs-fields 的 OVS 手册页。

网络策略的 ACL 拒绝日志条目示例

Copy to Clipboard Toggle word wrap
2021-06-13T19:33:11.590Z|00005|acl_log(ovn_pinctrl0)|INFO|name="verify-audit-logging_deny-all", verdict=drop, severity=alert: icmp,vlan_tci=0x0000,dl_src=0a:58:0a:80:02:39,dl_dst=0a:58:0a:80:02:37,nw_src=10.128.2.57,nw_dst=10.128.2.55,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=8,icmp_code=0

下表描述了命名空间注解值:

表 23.9. k8s.ovn.org/acl-logging 的审计日志记录命名空间注解
字段描述

deny

阻止任何与 deny 操作匹配的 ACL 规则的流量的访问。字段支持的值包括:alert, warning, notice, info, 或 debug

allow

允许命名空间访问与 allow 操作匹配的 ACL 规则的任何流量。字段支持的值包括:alert, warning, notice, info, 或 debug

pass

pass 操作适用于管理员网络策略的 ACL 规则。pass 操作允许命名空间中的网络策略或基准 admin 网络策略规则来评估所有传入和传出流量。网络策略不支持 pass 操作。

23.8.2. 审计配置

审计日志记录的配置作为 OVN-Kubernetes 集群网络配置的一部分指定。以下 YAML 演示了审计日志的默认值:

审计日志记录配置

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  defaultNetwork:
    ovnKubernetesConfig:
      policyAuditConfig:
        destination: "null"
        maxFileSize: 50
        rateLimit: 20
        syslogFacility: local0

下表描述了审计日志的配置字段。

表 23.10. policyAuditConfig object
字段类型描述

rateLimit

整数

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

maxFileSize

整数

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

目的地

字符串

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

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

syslogFacility

字符串

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

23.8.3. 为集群配置出口防火墙和网络策略审计

作为集群管理员,您可以自定义集群的审计日志。

先决条件

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

流程

  • 要自定义审计日志配置,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc edit network.operator.openshift.io/cluster
    提示

    您还可以自定义并应用以下 YAML 来配置审计日志记录:

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      defaultNetwork:
        ovnKubernetesConfig:
          policyAuditConfig:
            destination: "null"
            maxFileSize: 50
            rateLimit: 20
            syslogFacility: local0

验证

  1. 要创建带有网络策略的命名空间,请完成以下步骤:

    1. 创建命名空间进行验证:

      Copy to Clipboard Toggle word wrap
      $ cat <<EOF| oc create -f -
      kind: Namespace
      apiVersion: v1
      metadata:
        name: verify-audit-logging
        annotations:
          k8s.ovn.org/acl-logging: '{ "deny": "alert", "allow": "alert" }'
      EOF

      输出示例

      Copy to Clipboard Toggle word wrap
      namespace/verify-audit-logging created

    2. 启用审计日志记录:

      Copy to Clipboard Toggle word wrap
      $ oc annotate namespace verify-audit-logging k8s.ovn.org/acl-logging='{ "deny": "alert", "allow": "alert" }'
      Copy to Clipboard Toggle word wrap
      namespace/verify-audit-logging annotated
    3. 为命名空间创建网络策略:

      Copy to Clipboard Toggle word wrap
      $ cat <<EOF| oc create -n verify-audit-logging -f -
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: deny-all
      spec:
        podSelector:
          matchLabels:
        policyTypes:
        - Ingress
        - Egress
      ---
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-same-namespace
      spec:
        podSelector: {}
        policyTypes:
         - Ingress
         - Egress
        ingress:
          - from:
              - podSelector: {}
        egress:
          - to:
             - namespaceSelector:
                matchLabels:
                  namespace: verify-audit-logging
      EOF

      输出示例

      Copy to Clipboard Toggle word wrap
      networkpolicy.networking.k8s.io/deny-all created
      networkpolicy.networking.k8s.io/allow-from-same-namespace created

  2. default 命名空间中的源流量创建 pod:

    Copy to Clipboard Toggle word wrap
    $ cat <<EOF| oc create -n default -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: client
    spec:
      containers:
        - name: client
          image: registry.access.redhat.com/rhel7/rhel-tools
          command: ["/bin/sh", "-c"]
          args:
            ["sleep inf"]
    EOF
  3. verify-audit-logging 命名空间中创建两个 pod:

    Copy to Clipboard Toggle word wrap
    $ for name in client server; do
    cat <<EOF| oc create -n verify-audit-logging -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: ${name}
    spec:
      containers:
        - name: ${name}
          image: registry.access.redhat.com/rhel7/rhel-tools
          command: ["/bin/sh", "-c"]
          args:
            ["sleep inf"]
    EOF
    done

    输出示例

    Copy to Clipboard Toggle word wrap
    pod/client created
    pod/server created

  4. 要生成流量并生成网络策略审计日志条目,请完成以下步骤:

    1. verify-audit-logging 命名空间中获取名为 server 的 pod 的 IP 地址:

      Copy to Clipboard Toggle word wrap
      $ POD_IP=$(oc get pods server -n verify-audit-logging -o jsonpath='{.status.podIP}')
    2. default 命名空间中名为 client 的 pod 中 ping 上一个命令的 IP 地址,并确认所有数据包都已丢弃:

      Copy to Clipboard Toggle word wrap
      $ oc exec -it client -n default -- /bin/ping -c 2 $POD_IP

      输出示例

      Copy to Clipboard Toggle word wrap
      PING 10.128.2.55 (10.128.2.55) 56(84) bytes of data.
      
      --- 10.128.2.55 ping statistics ---
      2 packets transmitted, 0 received, 100% packet loss, time 2041ms

    3. verify-audit-logging 命名空间中名为 client 的 pod 中 ping POD_IP shell 环境变量中保存的 IP 地址,并确认允许所有数据包:

      Copy to Clipboard Toggle word wrap
      $ oc exec -it client -n verify-audit-logging -- /bin/ping -c 2 $POD_IP

      输出示例

      Copy to Clipboard Toggle word wrap
      PING 10.128.0.86 (10.128.0.86) 56(84) bytes of data.
      64 bytes from 10.128.0.86: icmp_seq=1 ttl=64 time=2.21 ms
      64 bytes from 10.128.0.86: icmp_seq=2 ttl=64 time=0.440 ms
      
      --- 10.128.0.86 ping statistics ---
      2 packets transmitted, 2 received, 0% packet loss, time 1001ms
      rtt min/avg/max/mdev = 0.440/1.329/2.219/0.890 ms

  5. 显示网络策略审计日志中的最新条目:

    Copy to Clipboard Toggle word wrap
    $ for pod in $(oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-node --no-headers=true | awk '{ print $1 }') ; do
        oc exec -it $pod -n openshift-ovn-kubernetes -- tail -4 /var/log/ovn/acl-audit-log.log
      done

    输出示例

    Copy to Clipboard Toggle word wrap
    Defaulting container name to ovn-controller.
    Use 'oc describe pod/ovnkube-node-hdb8v -n openshift-ovn-kubernetes' to see all of the containers in this pod.
    2021-06-13T19:33:11.590Z|00005|acl_log(ovn_pinctrl0)|INFO|name="verify-audit-logging_deny-all", verdict=drop, severity=alert: icmp,vlan_tci=0x0000,dl_src=0a:58:0a:80:02:39,dl_dst=0a:58:0a:80:02:37,nw_src=10.128.2.57,nw_dst=10.128.2.55,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=8,icmp_code=0
    2021-06-13T19:33:12.614Z|00006|acl_log(ovn_pinctrl0)|INFO|name="verify-audit-logging_deny-all", verdict=drop, severity=alert: icmp,vlan_tci=0x0000,dl_src=0a:58:0a:80:02:39,dl_dst=0a:58:0a:80:02:37,nw_src=10.128.2.57,nw_dst=10.128.2.55,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=8,icmp_code=0
    2021-06-13T19:44:10.037Z|00007|acl_log(ovn_pinctrl0)|INFO|name="verify-audit-logging_allow-from-same-namespace_0", verdict=allow, severity=alert: icmp,vlan_tci=0x0000,dl_src=0a:58:0a:80:02:3b,dl_dst=0a:58:0a:80:02:3a,nw_src=10.128.2.59,nw_dst=10.128.2.58,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=8,icmp_code=0
    2021-06-13T19:44:11.037Z|00008|acl_log(ovn_pinctrl0)|INFO|name="verify-audit-logging_allow-from-same-namespace_0", verdict=allow, severity=alert: icmp,vlan_tci=0x0000,dl_src=0a:58:0a:80:02:3b,dl_dst=0a:58:0a:80:02:3a,nw_src=10.128.2.59,nw_dst=10.128.2.58,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=8,icmp_code=0

23.8.4. 为命名空间启用出口防火墙和网络策略审计日志

作为集群管理员,您可以为命名空间启用审计日志。

先决条件

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

流程

  • 要为命名空间启用审计日志,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc annotate namespace <namespace> \
      k8s.ovn.org/acl-logging='{ "deny": "alert", "allow": "notice" }'

    其中:

    <namespace>
    指定命名空间的名称。
    提示

    您还可以应用以下 YAML 来启用审计日志记录:

    Copy to Clipboard Toggle word wrap
    kind: Namespace
    apiVersion: v1
    metadata:
      name: <namespace>
      annotations:
        k8s.ovn.org/acl-logging: |-
          {
            "deny": "alert",
            "allow": "notice"
          }

    输出示例

    Copy to Clipboard Toggle word wrap
    namespace/verify-audit-logging annotated

验证

  • 显示审计日志中的最新条目:

    Copy to Clipboard Toggle word wrap
    $ for pod in $(oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-node --no-headers=true | awk '{ print $1 }') ; do
        oc exec -it $pod -n openshift-ovn-kubernetes -- tail -4 /var/log/ovn/acl-audit-log.log
      done

    输出示例

    Copy to Clipboard Toggle word wrap
    2021-06-13T19:33:11.590Z|00005|acl_log(ovn_pinctrl0)|INFO|name="verify-audit-logging_deny-all", verdict=drop, severity=alert: icmp,vlan_tci=0x0000,dl_src=0a:58:0a:80:02:39,dl_dst=0a:58:0a:80:02:37,nw_src=10.128.2.57,nw_dst=10.128.2.55,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=8,icmp_code=0

23.8.5. 为命名空间禁用出口防火墙和网络策略审计日志

作为集群管理员,您可以禁用命名空间的审计日志。

先决条件

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

流程

  • 要为命名空间禁用审计日志,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc annotate --overwrite namespace <namespace> k8s.ovn.org/acl-logging-

    其中:

    <namespace>
    指定命名空间的名称。
    提示

    您还可以应用以下 YAML 来禁用审计日志记录:

    Copy to Clipboard Toggle word wrap
    kind: Namespace
    apiVersion: v1
    metadata:
      name: <namespace>
      annotations:
        k8s.ovn.org/acl-logging: null

    输出示例

    Copy to Clipboard Toggle word wrap
    namespace/verify-audit-logging annotated

23.8.6. 其他资源

23.9. 配置 IPsec 加密

启用 IPsec 后,OVN-Kubernetes 集群网络上的节点之间所有 pod 到 pod 网络流量都使用 IPsec 传输模式加密。

默认禁用 IPsec。它可以在安装集群期间或之后启用。有关集群安装的详情,请参阅 OpenShift Container Platform 安装概述。如果您需要在集群安装后启用 IPsec,您必须首先将集群 MTU 大小调整为考虑 IPsec ESP IP 标头的开销。

OpenShift Container Platform 集群中 IPsec 存在以下支持限制:

  • 在升级到 OpenShift Container Platform 4.15 前,您必须禁用 IPsec。禁用 IPsec 后,还必须删除关联的 IPsec daemonset。如果您在没有禁用 IPsec 的情况下更新,存在一个已知问题可能会导致 pod 到 pod 的通信中断。(OCPBUGS-43323)

以下文档描述了如何在集群安装后启用和禁用 IPSec。

23.9.1. 先决条件

  • 您已将集群 MTU 的大小减少为 46 字节,以便增加 IPsec ESP 标头的开销。有关重新定义集群使用的 MTU 大小的更多信息,请参阅为集群网络更改 MTU

23.9.2. 使用 IPsec 加密的网络流量类型

启用 IPsec 后,只有 pod 间的以下网络流量会被加密:

  • 集群网络的不同节点上的 pod 间的流量
  • 从主机网络上的 pod 流量到集群网络上的 pod

以下流量流没有加密:

  • 集群网络上同一节点上的 pod 间的流量
  • 主机网络上的 pod 间的流量
  • 从集群网络上的 pod 流量到主机网络上的 pod

下图中显示了加密和未加密的流程:

IPsec 加密和未加密流量流
23.9.2.1. 启用 IPsec 时的网络连接要求

您必须配置机器之间的网络连接,以允许 OpenShift Container Platform 集群组件进行通信。每台机器都必须能够解析集群中所有其他机器的主机名。

表 23.11. 用于全机器到所有机器通信的端口
协议port描述

UDP

500

IPsec IKE 数据包

4500

IPsec NAT-T 数据包

ESP

N/A

IPsec Encapsulating Security Payload(ESP)

23.9.3. 加密协议和 IPsec 模式

使用的加密密码是 AES-GCM-16-256。完整性检查值 (ICV) 为 16 字节。密钥长度为 256 位。

使用的 IPsec 模式是 传输模式,这是通过向原始数据包的 IP 标头添加封装安全 Payload (ESP) 标头来加密端到端通信的模式。OpenShift Container Platform 目前不支持 pod 到 pod 通信的 IPsec Tunnel 模式

23.9.4. 安全证书生成和轮转

Cluster Network Operator(CNO)生成自签名 X.509 证书颁发机构(CA),该颁发机构(CA)用于加密。来自每个节点的证书签名请求(CSR)由 CNO 自动实现。

CA 的有效期为 10 年。独立节点证书的有效期为 5 年,并在 4 年半后自动轮转。

23.9.5. 启用 IPsec 加密

作为集群管理员,您可以在集群安装后启用 IPsec 加密。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 以具有 cluster-admin 权限的用户身份登录集群。
  • 您已将集群最大传输单元(MTU)的大小减少为 46 字节,以允许 IPsec ESP 标头的开销。

流程

  • 要启用 IPsec 加密,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc patch networks.operator.openshift.io cluster --type=merge \
    -p '{"spec":{"defaultNetwork":{"ovnKubernetesConfig":{"ipsecConfig":{ }}}}}'

验证

  1. 要查找 OVN-Kubernetes control plane pod 的名称,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -l app=ovnkube-master -n openshift-ovn-kubernetes

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                   READY   STATUS    RESTARTS   AGE
    ovnkube-master-fvtnh   6/6     Running   0          122m
    ovnkube-master-hsgmm   6/6     Running   0          122m
    ovnkube-master-qcmdc   6/6     Running   0          122m

  2. 输入以下命令验证集群中是否启用了 IPsec。命令输出必须 state true 来指示节点启用了 IPsec。

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ovn-kubernetes rsh ovnkube-master-<pod_number_sequence> \ 
    1
    
      ovn-nbctl --no-leader-only get nb_global . ipsec
    1
    将 < pod_number_sequence > 替换为上一步中的数据平面 pod 的随机序列( fvtnh )。

23.9.6. 禁用 IPsec 加密

作为集群管理员,只有在集群安装后启用了 IPsec 时,才能禁用 IPsec 加密。

重要

禁用 IPsec 后,您必须删除关联的 IPsec daemonsets pod。如果没有删除这些 pod,您可能会遇到集群中的问题。

先决条件

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

流程

  1. 要禁用 IPsec 加密,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc patch networks.operator.openshift.io/cluster --type=json \
      -p='[{"op":"remove", "path":"/spec/defaultNetwork/ovnKubernetesConfig/ipsecConfig"}]'
  2. 要查找集群中 master 节点上存在的 OVN-Kubernetes data plane pod 的名称,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ovn-kubernetes -l=app=ovnkube-master

    输出示例

    Copy to Clipboard Toggle word wrap
    ovnkube-master-5xqbf                      8/8     Running   0              28m
    ...

  3. 输入以下命令验证集群中的 master 节点是否已禁用 IPsec。命令输出必须处于 false 状态,以指示节点禁用了 IPsec。

    Copy to Clipboard Toggle word wrap
    $ oc -n openshift-ovn-kubernetes -c nbdb rsh ovnkube-master-<pod_number_sequence> \
    1
    
      ovn-nbctl --no-leader-only get nb_global . ipsec
    1
    将 < pod_number_sequence > 替换为上一步中的数据平面 pod 的随机字符序列,如 5xqbf
  4. 要从节点上的 openshift-ovn-kubernetes 命名空间中删除 IPsec ovn-ipsec daemonset pod,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc delete daemonset ovn-ipsec -n openshift-ovn-kubernetes 
    1
    1
    ovn-ipsec daemonset 为节点上的 east-west 流量配置 IPsec 连接。
  5. 输入以下命令验证 ovn-ipsec daemonset pod 是否已从集群中的所有节点中删除。如果命令输出没有列出 pod,则移除操作会成功。

    Copy to Clipboard Toggle word wrap
    $ oc get pods -n openshift-ovn-kubernetes -l=app=ovn-ipsec
    注意

    您可能需要重新运行 命令来删除 pod,因为有时初始命令尝试不会删除该 pod。

  6. 可选:您可以将集群 MTU 的大小增加 46 个字节,因为 IP 数据包中不再有 IPsec ESP 标头的开销。

23.9.7. 其他资源

23.10. 为项目配置出口防火墙

作为集群管理员,您可以为项目创建一个出口防火墙,用于限制离开 OpenShift Container Platform 集群的出口流量。

23.10.1. 出口防火墙在一个项目中的工作原理

作为集群管理员,您可以使用一个出口防火墙来限制集群内的一些 pod 或所有 pod 可以访问的外部主机。出口防火墙适用于以下情况:

  • pod 只能连接到内部主机,且无法启动到公共互联网的连接。
  • pod 只能连接到公共互联网,且无法启动到 OpenShift Container Platform 集群以外的内部主机的连接。
  • pod 无法访问 OpenShift Container Platform 集群外的特定内部子网或主机。
  • pod 只能连接到特定的外部主机。

例如,您可以允许某一个项目访问指定的 IP 范围,但拒绝其他项目对同一 IP 范围的访问。或者您可以限制应用程序开发人员从 Python pip 的镜像点进行更新,并强制要求更新只能来自于批准的源。

注意

出口防火墙不适用于主机网络命名空间。启用主机网络的 Pod 不受出口防火墙规则的影响。

您可以通过创建一个 EgressFirewall 自定义资源(CR)对象来配置出口防火墙策略。出口防火墙与满足以下任一条件的网络流量匹配:

  • CIDR 格式的 IP 地址范围
  • 解析为 IP 地址的 DNS 名称
  • 端口号
  • 协议是以下协议之一: TCP、UDP 和 SCTP
重要

如果您的出口防火墙包含 0.0.0.0/0 的拒绝规则,则阻止访问 OpenShift Container Platform API 服务器。您必须为每个 IP 地址添加允许规则。

以下示例演示了确保 API 服务器访问所需的出口防火墙规则的顺序:

Copy to Clipboard Toggle word wrap
apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
  namespace: <namespace> 
1

spec:
  egress:
  - to:
      cidrSelector: <api_server_address_range> 
2

    type: Allow
# ...
  - to:
      cidrSelector: 0.0.0.0/0 
3

    type: Deny
1
出口防火墙的命名空间。
2
包含 OpenShift Container Platform API 服务器的 IP 地址范围。
3
一个全局拒绝规则会阻止访问 OpenShift Container Platform API 服务器。

要查找 API 服务器的 IP 地址,请运行 oc get ep kubernetes -n default

如需更多信息,请参阅 BZ#1988324

警告

出口防火墙规则不适用于通过路由器的网络流量。任何有权创建 Route CR 对象的用户,都可以通过创建指向禁止的目的地的路由来绕过出口防火墙策略规则。

23.10.1.1. 出口防火墙的限制

出口防火墙有以下限制:

  • 项目不能有一个以上的 EgressFirewall 对象。
  • 每个项目最多可定义一个具有最多 8,000 个规则的 EgressFirewall 对象。
  • 如果您在 Red Hat OpenShift Networking 中使用带有共享网关模式的 OVN-Kubernetes 网络插件,则返回入口回复会受到出口防火墙规则的影响。如果出口防火墙规则丢弃入口回复目的地 IP,流量将被丢弃。

违反这些限制会导致项目的出口防火墙出现问题。因此,所有外部网络流量都会被丢弃,这可能会给您的组织造成安全风险。

可在 kube-node-leasekube-publickube-systemopenshiftopenshift- 项目中创建一个 Egress Firewall 资源。

23.10.1.2. 出口防火墙策略规则的匹配顺序

出口防火墙策略规则按照它们定义的顺序来评估,从第一个到最后一个的顺序。第一个与 pod 的出口连接匹配的规则会被应用。该连接会忽略后续的所有规则。

23.10.1.3. 域名服务器 (DNS) 解析如何工作

如果您在 egress 防火墙策略规则中使用 DNS 名称,则正确解析域名会受到以下限制:

  • 域名更新会根据生存时间(TTL)持续时间进行轮询。默认情况下,持续时间为 30 分钟。当出口防火墙控制器查询本地名称服务器以获取域名时,如果响应包含 TTL 且 TTL 小于 30 分钟,控制器会将该 DNS 名称的持续时间设置为返回的值。每个 DNS 名称都会在 DNS 记录的 TTL 过期后查询。
  • 在需要时,pod 必须通过相同的本地名称服务器解析域名。否则,egress 防火墙控制器和 pod 已知的域的 IP 地址可能会有所不同。如果主机名的 IP 地址不同,则出口防火墙的强制实施可能不一致。
  • 因为出口防火墙控制器和 pod 异步轮询相同的本地名称服务器,所以 pod 可能会在出口控制器执行前获取更新的 IP 地址,从而导致竞争条件。由于这个限制,仅建议在 EgressFirewall 对象中使用域名来更改 IP 地址的域。
注意

出口防火墙始终允许 pod 访问 pod 所在的用于 DNS 解析的节点的外部接口。

如果您在出口防火墙策略中使用域名,且您的 DNS 解析不是由本地节点上的 DNS 服务器处理,那么您必须添加出口防火墙规则,允许访问您的 DNS 服务器的 IP 地址。如果您在 pod 中使用域名。

23.10.2. EgressFirewall 自定义资源(CR)对象

您可以为出口防火墙定义一个或多个规则。规则是一个 Allow 规则,也可以是一个 Deny 规则,它包括规则适用的流量规格。

以下 YAML 描述了 EgressFirewall CR 对象:

EgressFirewall 对象

Copy to Clipboard Toggle word wrap
apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: <name> 
1

spec:
  egress: 
2

    ...

1
对象的名称必须是 default
2
以下部分所述,一个或多个出口网络策略规则的集合。
23.10.2.1. EgressFirewall 规则

以下 YAML 描述了一个出口防火墙规则对象。用户可以选择 CIDR 格式的 IP 地址范围或域名。egress 小节需要一个包括一个或多个对象的数组。

出口策略规则小节

Copy to Clipboard Toggle word wrap
egress:
- type: <type> 
1

  to: 
2

    cidrSelector: <cidr> 
3

    dnsName: <dns_name> 
4

  ports: 
5

      ...

1
规则类型。该值必须是 AllowDeny
2
描述出口流量匹配规则的小节,该规则指定 cidrSelector 字段或 dnsName 字段。您不能在同一规则中使用这两个字段。
3
CIDR 格式的 IP 地址范围。
4
DNS 域名。
5
可选:描述该规则的网络端口和协议集合的小节。

端口小节

Copy to Clipboard Toggle word wrap
ports:
- port: <port> 
1

  protocol: <protocol> 
2

1
网络端口,比如 80443。如果为这个字段指定值,还必须为 protocol 指定一个值。
2
网络协议。该值必须是 TCPUDPSCTP
23.10.2.2. EgressFirewall CR 对象示例

以下示例定义了几个出口防火墙策略规则:

Copy to Clipboard Toggle word wrap
apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
spec:
  egress: 
1

  - type: Allow
    to:
      cidrSelector: 1.2.3.0/24
  - type: Deny
    to:
      cidrSelector: 0.0.0.0/0
1
出口防火墙策略规则对象的集合。

以下示例定义了一个策略规则,如果流量使用 TCP 协议和目的地端口 80,则拒绝通过 172.16.1.1/32 IP 地址到主机的流量。

Copy to Clipboard Toggle word wrap
apiVersion: k8s.ovn.org/v1
kind: EgressFirewall
metadata:
  name: default
spec:
  egress:
  - type: Deny
    to:
      cidrSelector: 172.16.1.1/32
    ports:
    - port: 80
      protocol: TCP
    - port: 443

23.10.3. 创建出口防火墙策略对象

作为集群管理员,您可以为项目创建一个出口防火墙策略对象。

重要

如果项目已经定义了 EgressFirewall 对象,您必须编辑现有策略来更改出口防火墙规则。

先决条件

  • 使用 OVN-Kubernetes 网络插件的集群。
  • 安装 OpenShift CLI (oc) 。
  • 您需要使用集群管理员身份登陆到集群。

流程

  1. 创建策略规则:

    1. 创建一个 <policy_name>.yaml 文件,其中 <policy_name> 描述出口策略规则。
    2. 在您创建的文件中,定义出口策略对象。
  2. 运行以下命令来创建策略对象。将 <policy_name> 替换为策略的名称, <project> 替换为规则应用到的项目。

    Copy to Clipboard Toggle word wrap
    $ oc create -f <policy_name>.yaml -n <project>

    在以下示例中,在名为 project1 的项目中创建一个新的 EgressFirewall 对象:

    Copy to Clipboard Toggle word wrap
    $ oc create -f default.yaml -n project1

    输出示例

    Copy to Clipboard Toggle word wrap
    egressfirewall.k8s.ovn.org/v1 created

  3. 可选:保存 <policy_name>.yaml 文件,以便在以后进行修改。

23.11. 查看项目的出口防火墙

作为集群管理员,您可以列出任何现有出口防火墙的名称,并查看特定出口防火墙的流量规则。

23.11.1. 查看 EgressFirewall 对象

您可以查看集群中的 EgressFirewall 对象。

先决条件

  • 使用 OVN-Kubernetes 网络插件的集群。
  • 安装 OpenShift 命令行界面 (CLI),通常称为 oc
  • 您必须登录集群。

流程

  1. 可选: 要查看集群中定义的 EgressFirewall 对象的名称,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get egressfirewall --all-namespaces
  2. 要检查策略,请输入以下命令。将 <policy_name> 替换为要检查的策略名称。

    Copy to Clipboard Toggle word wrap
    $ oc describe egressfirewall <policy_name>

    输出示例

    Copy to Clipboard Toggle word wrap
    Name:		default
    Namespace:	project1
    Created:	20 minutes ago
    Labels:		<none>
    Annotations:	<none>
    Rule:		Allow to 1.2.3.0/24
    Rule:		Allow to www.example.com
    Rule:		Deny to 0.0.0.0/0

23.12. 为项目编辑出口防火墙

作为集群管理员,您可以修改现有出口防火墙的网络流量规则。

23.12.1. 编辑 EgressFirewall 对象

作为集群管理员,您可以更新一个项目的出口防火墙。

先决条件

  • 使用 OVN-Kubernetes 网络插件的集群。
  • 安装 OpenShift CLI (oc) 。
  • 您需要使用集群管理员身份登陆到集群。

流程

  1. 查找项目的 EgressFirewall 对象的名称。将 <project> 替换为项目的名称。

    Copy to Clipboard Toggle word wrap
    $ oc get -n <project> egressfirewall
  2. 可选:如果您在创建出口网络防火墙时没有保存 EgressFirewall 对象的副本,请输入以下命令来创建副本。

    Copy to Clipboard Toggle word wrap
    $ oc get -n <project> egressfirewall <name> -o yaml > <filename>.yaml

    <project> 替换为项目的名称。将 <name> 替换为 Pod 的名称。将 <filename> 替换为要将 YAML 保存到的文件的名称。

  3. 修改策略规则后,请输入以下命令替换 EgressFirewall 对象。将 <filename> 替换为包含更新的 EgressFirewall 对象的文件名称。

    Copy to Clipboard Toggle word wrap
    $ oc replace -f <filename>.yaml

23.13. 从项目中删除出口防火墙

作为集群管理员,您可以从项目中删除出口防火墙,从而删除对项目的离开 OpenShift Container Platform 集群的网络流量的限制。

23.13.1. 删除 EgressFirewall 对象

作为集群管理员,您可以从项目中删除出口防火墙。

先决条件

  • 使用 OVN-Kubernetes 网络插件的集群。
  • 安装 OpenShift CLI (oc) 。
  • 您需要使用集群管理员身份登陆到集群。

流程

  1. 查找项目的 EgressFirewall 对象的名称。将 <project> 替换为项目的名称。

    Copy to Clipboard Toggle word wrap
    $ oc get -n <project> egressfirewall
  2. 输入以下命令删除 EgressFirewall 对象。将 <project> 替换为项目名称,<name> 替换为对象名称。

    Copy to Clipboard Toggle word wrap
    $ oc delete -n <project> egressfirewall <name>

23.14. 配置出口 IP 地址

作为集群管理员,您可以配置 OVN-Kubernetes Container Network Interface (CNI) 网络插件,为命名空间分配一个或多个出口 IP 地址,或分配给命名空间中的特定 pod。

重要

在安装程序置备的基础架构集群中,不要将出口 IP 地址分配给已托管入口 VIP 的基础架构节点。如需更多信息,当出口 IP 分配给已托管入口 VIP 的 infra 节点时,红帽知识库解决方案 POD 来自启用了出口 IP 的命名空间中的 OCP 路由无法访问 IPI 集群中的 OCP 路由。

23.14.1. 出口 IP 地址架构设计和实施

OpenShift Container Platform 出口 IP 地址功能可确保来自一个或多个命名空间中的一个或多个 pod 的流量具有集群网络之外的服务具有一致的源 IP 地址。

例如,您可能有一个 pod 定期查询托管在集群外服务器上的数据库。要强制对服务器进行访问要求,将数据包过滤设备配置为只允许来自特定 IP 地址的流量。为确保您可以可靠地允许从该特定 pod 访问服务器,您可以为向服务器发出请求的 pod 配置特定的出口 IP 地址。

分配给命名空间的出口 IP 地址与用来向特定目的地发送流量的出口路由器不同。

在一些集群配置中,应用程序 Pod 和入口路由器 pod 在同一个节点上运行。如果您在这种情况下为应用程序项目配置出口 IP 地址,当您向应用程序项目发送请求时,不会使用 IP 地址。

重要

不能在任何 Linux 网络配置文件中配置出口 IP 地址,比如 ifcfg-eth0

23.14.1.1. 平台支持

下表概述了对不同平台中的出口 IP 地址功能的支持:

平台支持

裸机

VMware vSphere

Red Hat OpenStack Platform(RHOSP)

Amazon Web Services (AWS)

Google Cloud Platform (GCP)

Microsoft Azure

重要

在 Amazon Web Services(AWS)上置备的集群中不支持使用 EgressIP 功能将出口 IP 地址分配给 control plane 节点。(BZ#2039656)

23.14.1.2. 公共云平台注意事项

对于在公共云基础架构上置备的集群,每个节点绝对的 IP 地址会有一个约束。如下公式描述了每个节点的可分配 IP 地址或 IP 容量 上限:

Copy to Clipboard Toggle word wrap
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.12 中的 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 注解示例

Copy to Clipboard Toggle word wrap
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 注解示例

Copy to Clipboard Toggle word wrap
cloud.network.openshift.io/egress-ipconfig: [
  {
    "interface":"nic0",
    "ifaddr":{"ipv4":"10.0.128.0/18"},
    "capacity":{"ip":14}
  }
]

以下小节描述了支持公共云环境的 IP 地址容量,用于容量计算。

23.14.1.2.1. Amazon Web Services(AWS)IP 地址容量限制

在 AWS 上,IP 地址分配的限制取决于配置的实例类型。如需更多信息,请参阅 每个实例类型的每个网络接口的 IP 地址

23.14.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 范围概述

23.14.1.2.3. Microsoft Azure IP 地址容量限制

在 Azure 上,IP 地址分配有以下容量限制:

  • 对于每个 NIC,对于 IPv4 和 IPv6,可分配 IP 地址的最大数量为 256。
  • 对于每个虚拟网络,分配的 IP 地址的最大数量不能超过 65,536。

如需更多信息,请参阅网络限制

23.14.1.3. 将出口 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 地址的节点。

23.14.1.4. 将出口 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.110.10.20.2) 的 EgressIP 对象的选择器匹配,其中任何一个都可以用于每个 TCP 连接或 UDP 对话。

23.14.1.5. 出口 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.10192.168.126.102。这两个节点之间流量大致平衡。

图中的以下资源被详细描述:

Namespace 对象

命名空间在以下清单中定义:

命名空间对象

Copy to Clipboard Toggle word wrap
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.10192.168.126.102

EgressIP 对象

Copy to Clipboard Toggle word wrap
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 地址。

23.14.2. EgressIP 对象

以下 YAML 描述了 EgressIP 对象的 API。对象有效的范围为集群,它不是在命名空间中创建的。

Copy to Clipboard Toggle word wrap
apiVersion: k8s.ovn.org/v1
kind: EgressIP
metadata:
  name: <name> 
1

spec:
  egressIPs: 
2

  - <ip_address>
  namespaceSelector: 
3

    ...
  podSelector: 
4

    ...
1
EgressIPs 对象的名称。
2
包括一个或多个 IP 地址的数组。
3
出口 IP 地址与其关联的一个或多个命名空间选择器将。
4
可选:指定命名空间中的 pod 的一个或多个选择器,以将出口 IP 地址与其关联。通过使用这些选择器,可以选择命名空间中的 pod 子集。

以下 YAML 描述了命名空间选择器的小节:

命名空间选择器小节

Copy to Clipboard Toggle word wrap
namespaceSelector: 
1

  matchLabels:
    <label_name>: <label_value>

1
命名空间的一个或多个匹配规则。如果提供多个匹配规则,则会选择所有匹配的命名空间。

以下 YAML 描述了 pod 选择器的可选小节:

Pod 选择器片段

Copy to Clipboard Toggle word wrap
podSelector: 
1

  matchLabels:
    <label_name>: <label_value>

1
可选:与指定 namespaceSelector 规则匹配的命名空间中 pod 的一个或多个匹配规则。如果指定,则仅选择匹配的 pod。命名空间中的其他 Pod 不会被选择。

在以下示例中,EgressIP 对象将 192.168.126.11192.168.126.102 出口 IP 地址与将 app 标签设置为 web 的 pod 关联,并位于将 env 标签设置为 prod 的命名空间中:

EgressIP 对象示例

Copy to Clipboard Toggle word wrap
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.30192.168.127.40 出口 IP 地址与任何没有将 environment 标签设置为 development 的 pod 相关联:

EgressIP 对象示例

Copy to Clipboard Toggle word wrap
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

23.14.3. egressIPConfig 对象

作为出口 IP 的功能,reachabilityTotalTimeoutSeconds 参数配置 EgressIP 节点可访问性检查总超时时间(以秒为单位)。如果在这个超时时间内无法访问 EgressIP 节点,则会声明该节点。

您可以在配置文件中为 egressIPConfig 对象设置 reachabilityTotalTimeoutSeconds 的值。设置较大的值可能会导致 EgressIP 实现对节点更改做出反应的速度较慢。对于有问题的 EgressIP 节点,这个实现的反应会较慢。

如果您从 egressIPConfig 对象中省略了 reachabilityTotalTimeoutSeconds 参数,则平台会选择一个合理的默认值,这可能会随时间变化。当前的默认值为 1 秒。0 代表禁用 EgressIP 节点的访问性检查。

以下 egressIPConfig 对象描述了将 reachabilityTotalTimeoutSeconds 从默认的 1 秒探测改为 5 秒探测:

Copy to Clipboard Toggle word wrap
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
1
egressIPConfig 包含 EgressIP 对象选项的配置。通过更改这些配置,您可以扩展 EgressIP 对象。
2
reachabilityTotalTimeoutSeconds 的值接受从 060 的整数值。0 代表禁用 egressIP 节点的访问性检查。将 1 的值设置为 60 对应于探测向节点发送可达性检查的超时时间(以秒为单位)。

23.14.4. 标记节点以托管出口 IP 地址

您可以将 k8s.ovn.org/egress-assignable="" 标签应用到集群中的节点,以便 OpenShift Container Platform 可以为该节点分配一个或多个出口 IP 地址。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 以集群管理员身份登录集群。

流程

  • 要标记节点,使其可以托管一个或多个出口 IP 地址,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc label nodes <node_name> k8s.ovn.org/egress-assignable="" 
    1
    1
    要标记的节点的名称。
    提示

    您还可以应用以下 YAML 将标签添加到节点:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Node
    metadata:
      labels:
        k8s.ovn.org/egress-assignable: ""
      name: <node_name>

23.14.5. 后续步骤

23.14.6. 其他资源

23.15. 分配出口 IP 地址

作为集群管理员,您可以为从一个命名空间中,或从一个命名空间内的特定 pod 中离开集群的网络流量分配一个出口 IP 地址。

23.15.1. 为一个命名空间分配出口 IP 地址

您可以将一个或多个出口 IP 地址分配给一个命名空间,或分配给命名空间中的特定 pod。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 以集群管理员身份登录集群。
  • 至少配置一个节点来托管出口 IP 地址。

流程

  1. 创建 EgressIP 对象:

    1. 创建一个 <egressips_name>.yaml 文件,其中 <egressips_name> 是对象的名称。
    2. 在您创建的文件中,定义一个 EgressIP 对象,如下例所示:

      Copy to Clipboard Toggle word wrap
      apiVersion: k8s.ovn.org/v1
      kind: EgressIP
      metadata:
        name: egress-project1
      spec:
        egressIPs:
        - 192.168.127.10
        - 192.168.127.11
        namespaceSelector:
          matchLabels:
            env: qa
  2. 运行以下命令来创建对象。

    Copy to Clipboard Toggle word wrap
    $ oc apply -f <egressips_name>.yaml 
    1
    1
    <egressips_name> 替换为对象的名称。

    输出示例

    Copy to Clipboard Toggle word wrap
    egressips.k8s.ovn.org/<egressips_name> created

  3. 可选:保存 <egressips_name>.yaml 文件,以便稍后进行修改。
  4. 为需要出口 IP 地址的命名空间添加标签。要在第 1 步中定义的 EgressIP 对象的命名空间中添加标签,请运行以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc label ns <namespace> env=qa 
    1
    1
    <namespace> 替换为需要出口 IP 地址的命名空间。

验证

  • 要显示集群中所有正在使用的出口 IP,请输入以下命令:

    Copy to Clipboard Toggle word wrap
    $ oc get egressip -o yaml
    注意

    无论配置了多少个出口 IP 地址,oc get egressip 只返回一个出口 IP 地址。这并不是程序错误,它是 Kubernetes 的一个限制。作为临时解决方案,您可以传递 -o yaml-o json 标志来返回所有正在使用的出口 IP 地址。

    输出示例

    Copy to Clipboard Toggle word wrap
    # ...
    spec:
      egressIPs:
      - 192.168.127.10
      - 192.168.127.11
    # ...

23.15.2. 其他资源

23.16. 使用出口路由器 pod 的注意事项

23.16.1. 关于出口路由器 pod

OpenShift Container Platform 出口路由器(egress router ) pod 使用一个来自专用的私有源 IP 地址,将网络流量重定向到指定的远程服务器。出口路由器 pod 可以将网络流量发送到设置为仅允许从特定 IP 地址访问的服务器。

注意

出口路由器 pod 并不适用于所有外向的连接。创建大量出口路由器 pod 可能会超过您的网络硬件的限制。例如,为每个项目或应用程序创建出口路由器 pod 可能会导致,在转换为使用软件来进行 MAC 地址过滤前超过了网络接口可以处理的本地 MAC 地址的数量。

重要

出口路由器镜像与 Amazon AWS、Azure Cloud 或其他不支持第 2 层操作的云平台不兼容,因为它们与 macvlan 流量不兼容。

23.16.1.1. 出口路由器模式

重定向模式中,出口路由器 pod 配置 iptables 规则,将流量从其自身 IP 地址重定向到一个或多个目标 IP 地址。需要使用保留源 IP 地址的客户端 pod 必须配置为访问出口路由器的服务,而不是直接连接到目标 IP。您可以使用 curl 命令从应用程序 pod 访问目标服务和端口。例如:

Copy to Clipboard Toggle word wrap
$ curl <router_service_IP> <port>
注意

egress router CNI 插件只支持重定向模式。这与您可以使用 OpenShift SDN 部署的出口路由器实现不同。与 OpenShift SDN 的出口路由器不同,egress router CNI 插件不支持 HTTP 代理模式或 DNS 代理模式。

23.16.1.2. 出口路由器 pod 的实现

出口路由器实施使用出口路由器 Container Network Interface(CNI)插件。该插件将二级网络接口添加到 pod。

出口路由器是一个带有两个网络接口的 pod。例如,pod 可以具有 eth0net1 网络接口。eth0 接口位于集群网络中,pod 将继续将接口用于与集群相关的普通网络流量。net1 接口位于第二个网络中,并且具有该网络的 IP 地址和网关。OpenShift Container Platform 集群中的其他 pod 可以访问出口路由器服务,服务使 pod 可以访问外部服务。出口路由器作为 pod 和外部系统间的桥接。

离开出口路由器的流量会通过一个节点退出,但数据包带有来自路由器 pod 的 net1 接口的 MAC 地址。

添加出口路由器自定义资源时,Cluster Network Operator 会创建以下对象:

  • pod 的 net1 二级网络接口的网络附加定义。
  • 出口路由器的部署。

如果您删除了一个出口路由器自定义资源,Operator 会删除上列表中与出口路由器关联的两个对象。

23.16.1.3. 部署注意事项

出口路由器 pod 会为节点的主网络接口添加额外的 IP 地址和 MAC 地址。因此,您可能需要配置虚拟机监控程序或云供应商来允许额外的地址。

Red Hat OpenStack Platform (RHOSP)

如果在 RHOSP 上部署 OpenShift Container Platform,则必须允许来自 OpenStack 环境上的出口路由器 Pod 的 IP 和 MAC 地址的流量。如果您不允许流量,则通信会失败

Copy to Clipboard Toggle word wrap
$ openstack port set --allowed-address \
  ip_address=<ip_address>,mac_address=<mac_address> <neutron_port_uuid>
Red Hat Virtualization(RHV)
如果使用 RHV,必须为虚拟网络接口控制器 (vNIC) 选择 No Network Filter
VMware vSphere
如果您使用 VMware vSphere,请参阅 VMware 文档来保护 vSphere 标准交换机。通过从 vSphere Web 客户端中选择主机虚拟交换机来查看并更改 VMware vSphere 默认设置。

具体来说,请确保启用了以下功能:

23.16.1.4. 故障切换配置

为了避免停机,Cluster Network Operator 会将出口路由器 pod 部署为部署资源。部署名称为 egress-router-cni-deployment。与部署对应的 pod 具有 app=egress-router-cni 标签。

要为部署创建新服务,请使用 oc expose deployment/egress-router-cni-deployment --port <port_number> 命令或创建类似以下示例的文件:

Copy to Clipboard Toggle word wrap
apiVersion: v1
kind: Service
metadata:
  name: app-egress
spec:
  ports:
  - name: tcp-8080
    protocol: TCP
    port: 8080
  - name: tcp-8443
    protocol: TCP
    port: 8443
  - name: udp-80
    protocol: UDP
    port: 80
  type: ClusterIP
  selector:
    app: egress-router-cni

23.16.2. 其他资源

23.17. 以重定向模式部署出口路由器 pod

作为集群管理员,您可以部署出口路由器 Pod,将流量重新指向来自保留源 IP 地址的指定目标 IP 地址。

出口路由器实施使用出口路由器 Container Network Interface(CNI)插件。

23.17.1. 出口路由器自定义资源

在出口路由器自定义资源中定义出口路由器 pod 的配置。以下 YAML 描述了以重定向模式配置出口路由器的字段:

Copy to Clipboard Toggle word wrap
apiVersion: network.operator.openshift.io/v1
kind: EgressRouter
metadata:
  name: <egress_router_name>
  namespace: <namespace>  <.>
spec:
  addresses: [  <.>
    {
      ip: "<egress_router>",  <.>
      gateway: "<egress_gateway>"  <.>
    }
  ]
  mode: Redirect
  redirect: {
    redirectRules: [  <.>
      {
        destinationIP: "<egress_destination>",
        port: <egress_router_port>,
        targetPort: <target_port>,  <.>
        protocol: <network_protocol>  <.>
      },
      ...
    ],
    fallbackIP: "<egress_destination>" <.>
  }

<.> 可选:namespace 字段指定要在其中创建出口路由器的命名空间。如果您没有在文件或命令行中指定值,则会使用 default 命名空间。

<.> address 字段指定要在第二个网络接口上配置的 IP 地址。

<.> ip 字段指定节点用于出口路由器 pod 的物理网络中保留源 IP 地址和子网掩码。使用 CIDR 表示法指定 IP 地址和网络掩码。

<.> gateway 字段指定网络网关的 IP 地址。

<.> 可选: redirectRules 字段指定出口目的地 IP 地址、出口路由器端口和协议的组合。到指定端口和协议中的出口路由器的传入连接路由到目标 IP 地址。

<.> 可选: targetPort 字段指定目标 IP 地址上的网络端口。如果没有指定此字段,流量将路由到它到达的同一网络端口。

<.> protocol 字段支持 TCP、UDP 或 SCTP。

<.> 可选: fallbackIP 字段指定目标 IP 地址。如果没有指定任何重定向规则,出口路由器会将所有流量发送到这个回退 IP 地址。如果您指定了重定向规则,则出口路由器将任何与规则中定义的网络端口的连接发送到这个回退 IP 地址。如果没有指定此字段,出口路由器会拒绝与规则中没有定义的网络端口的连接。

出口路由器规格示例

Copy to Clipboard Toggle word wrap
apiVersion: network.operator.openshift.io/v1
kind: EgressRouter
metadata:
  name: egress-router-redirect
spec:
  networkInterface: {
    macvlan: {
      mode: "Bridge"
    }
  }
  addresses: [
    {
      ip: "192.168.12.99/24",
      gateway: "192.168.12.1"
    }
  ]
  mode: Redirect
  redirect: {
    redirectRules: [
      {
        destinationIP: "10.0.0.99",
        port: 80,
        protocol: UDP
      },
      {
        destinationIP: "203.0.113.26",
        port: 8080,
        targetPort: 80,
        protocol: TCP
      },
      {
        destinationIP: "203.0.113.27",
        port: 8443,
        targetPort: 443,
        protocol: TCP
      }
    ]
  }

23.17.2. 以重定向模式部署出口路由器

您可以部署出口路由器,将其自身保留源 IP 地址的流量重定向到一个或多个目标 IP 地址。

添加出口路由器后,需要使用保留源 IP 地址的客户端 pod 必须修改为连接到出口路由器,而不是直接连接到目标 IP。

先决条件

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

流程

  1. 创建出口路由器定义。
  2. 为确保其他 pod 可以找到出口路由器 pod 的 IP 地址,请创建一个使用出口路由器的服务,如下例所示:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Service
    metadata:
      name: egress-1
    spec:
      ports:
      - name: web-app
        protocol: TCP
        port: 8080
      type: ClusterIP
      selector:
        app: egress-router-cni <.>

    <.> 指定出口路由器的标签。显示的值由 Cluster Network Operator 添加,且不可配置。

    创建服务后,您的 Pod 可以连接到该服务。出口路由器 pod 将流量重定向到目标 IP 地址中对应的端口。连接来自保留的源 IP 地址。

验证

要验证 Cluster Network Operator 是否启动了出口路由器,请完成以下步骤:

  1. 查看 Operator 为出口路由器创建的网络附加定义:

    Copy to Clipboard Toggle word wrap
    $ oc get network-attachment-definition egress-router-cni-nad

    网络附加定义的名称不可配置。

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                    AGE
    egress-router-cni-nad   18m

  2. 查看出口路由器 pod 的部署:

    Copy to Clipboard Toggle word wrap
    $ oc get deployment egress-router-cni-deployment

    部署的名称不可配置。

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
    egress-router-cni-deployment   1/1     1            1           18m

  3. 查看出口路由器 pod 的状态:

    Copy to Clipboard Toggle word wrap
    $ oc get pods -l app=egress-router-cni

    输出示例

    Copy to Clipboard Toggle word wrap
    NAME                                            READY   STATUS    RESTARTS   AGE
    egress-router-cni-deployment-575465c75c-qkq6m   1/1     Running   0          18m

  4. 查看出口路由器 pod 的日志和路由表。
  1. 获取出口路由器 pod 的节点名称:

    Copy to Clipboard Toggle word wrap
    $ POD_NODENAME=$(oc get pod -l app=egress-router-cni -o jsonpath="{.items[0].spec.nodeName}")
  2. 在目标节点上进入一个 debug 会话。此步骤被实例化为一个名为 <node_name>-debug 的 debug pod:

    Copy to Clipboard Toggle word wrap
    $ oc debug node/$POD_NODENAME
  3. /host 设置为 debug shell 中的根目录。debug pod 在 pod 中的 /host 中挂载主机 的 root 文件系统。将根目录改为 /host,您可以从主机的可执行路径中运行二进制文件:

    Copy to Clipboard Toggle word wrap
    # chroot /host
  4. chroot 环境控制台中显示出口路由器日志:

    Copy to Clipboard Toggle word wrap
    # cat /tmp/egress-router-log

    输出示例

    Copy to Clipboard Toggle word wrap
    2021-04-26T12:27:20Z [debug] Called CNI ADD
    2021-04-26T12:27:20Z [debug] Gateway: 192.168.12.1
    2021-04-26T12:27:20Z [debug] IP Source Addresses: [192.168.12.99/24]
    2021-04-26T12:27:20Z [debug] IP Destinations: [80 UDP 10.0.0.99/30 8080 TCP 203.0.113.26/30 80 8443 TCP 203.0.113.27/30 443]
    2021-04-26T12:27:20Z [debug] Created macvlan interface
    2021-04-26T12:27:20Z [debug] Renamed macvlan to "net1"
    2021-04-26T12:27:20Z [debug] Adding route to gateway 192.168.12.1 on macvlan interface
    2021-04-26T12:27:20Z [debug] deleted default route {Ifindex: 3 Dst: <nil> Src: <nil> Gw: 10.128.10.1 Flags: [] Table: 254}
    2021-04-26T12:27:20Z [debug] Added new default route with gateway 192.168.12.1
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p UDP --dport 80 -j DNAT --to-destination 10.0.0.99
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p TCP --dport 8080 -j DNAT --to-destination 203.0.113.26:80
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p TCP --dport 8443 -j DNAT --to-destination 203.0.113.27:443
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat -o net1 -j SNAT --to-source 192.168.12.99

    当您启动出口路由器时,通过创建 EgressRouter 对象来启动出口路由器时,日志文件位置和日志记录级别不可配置,如下所述。

  5. chroot 环境控制台中获取容器 ID:

    Copy to Clipboard Toggle word wrap
    # crictl ps --name egress-router-cni-pod | awk '{print $1}'

    输出示例

    Copy to Clipboard Toggle word wrap
    CONTAINER
    bac9fae69ddb6

  6. 确定容器的进程 ID。在本例中,容器 ID 是 bac9fae69ddb6

    Copy to Clipboard Toggle word wrap
    # crictl inspect -o yaml bac9fae69ddb6 | grep 'pid:' | awk '{print $2}'

    输出示例

    Copy to Clipboard Toggle word wrap
    68857

  7. 输入容器的网络命名空间:

    Copy to Clipboard Toggle word wrap
    # nsenter -n -t 68857
  8. 显示路由表:

    Copy to Clipboard Toggle word wrap
    # ip route

    在以下示例输出中,net1 网络接口是默认路由。集群网络的流量使用 eth0 网络接口。192.168.12.0/24 网络的流量使用 net1 网络接口,并源自保留源 IP 地址 192.168.12.99。pod 将所有其他流量路由到网关,地址为 192.168.12.1。不显示服务网络的路由。

    输出示例

    Copy to Clipboard Toggle word wrap
    default via 192.168.12.1 dev net1
    10.128.10.0/23 dev eth0 proto kernel scope link src 10.128.10.18
    192.168.12.0/24 dev net1 proto kernel scope link src 192.168.12.99
    192.168.12.1 dev net1

23.18. 为项目启用多播

23.18.1. 关于多播

通过使用 IP 多播,数据可同时广播到许多 IP 地址。

重要
  • 目前,多播最适用于低带宽协调或服务发现。它不是一个高带宽解决方案。
  • 默认情况下,网络策略会影响命名空间中的所有连接。但是,多播不受网络策略的影响。如果在与网络策略相同的命名空间中启用了多播,则始终允许多播,即使有一个 deny-all 网络策略。在启用网络策略前,集群管理员应考虑对多播的影响。

默认情况下,OpenShift Container Platform pod 之间多播流量被禁用。如果使用 OVN-Kubernetes 网络插件,可以根据每个项目启用多播。

23.18.2. 启用 pod 间多播

您可以为项目启用 pod 间多播。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 您必须作为 cluster-admin 角色用户登录集群。

流程

  • 运行以下命令,为项目启用多播。使用您要启用多播的项目的名称替换 <namespace>

    Copy to Clipboard Toggle word wrap
    $ oc annotate namespace <namespace> \
        k8s.ovn.org/multicast-enabled=true
    提示

    您还可以应用以下 YAML 来添加注解:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Namespace
    metadata:
      name: <namespace>
      annotations:
        k8s.ovn.org/multicast-enabled: "true"

验证

要验证项目是否启用了多播,请完成以下步骤:

  1. 将您的当前项目更改为启用多播的项目。使用项目名替换 <project>

    Copy to Clipboard Toggle word wrap
    $ oc project <project>
  2. 创建 pod 以作为多播接收器:

    Copy to Clipboard Toggle word wrap
    $ cat <<EOF| oc create -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: mlistener
      labels:
        app: multicast-verify
    spec:
      containers:
        - name: mlistener
          image: registry.access.redhat.com/ubi8
          command: ["/bin/sh", "-c"]
          args:
            ["dnf -y install socat hostname && sleep inf"]
          ports:
            - containerPort: 30102
              name: mlistener
              protocol: UDP
    EOF
  3. 创建 pod 以作为多播发送器:

    Copy to Clipboard Toggle word wrap
    $ cat <<EOF| oc create -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: msender
      labels:
        app: multicast-verify
    spec:
      containers:
        - name: msender
          image: registry.access.redhat.com/ubi8
          command: ["/bin/sh", "-c"]
          args:
            ["dnf -y install socat && sleep inf"]
    EOF
  4. 在新的终端窗口或选项卡中,启动多播监听程序。

    1. 获得 Pod 的 IP 地址:

      Copy to Clipboard Toggle word wrap
      $ POD_IP=$(oc get pods mlistener -o jsonpath='{.status.podIP}')
    2. 输入以下命令启动多播监听程序:

      Copy to Clipboard Toggle word wrap
      $ oc exec mlistener -i -t -- \
          socat UDP4-RECVFROM:30102,ip-add-membership=224.1.0.1:$POD_IP,fork EXEC:hostname
  5. 启动多播传输。

    1. 获取 pod 网络 IP 地址范围:

      Copy to Clipboard Toggle word wrap
      $ CIDR=$(oc get Network.config.openshift.io cluster \
          -o jsonpath='{.status.clusterNetwork[0].cidr}')
    2. 要发送多播信息,请输入以下命令:

      Copy to Clipboard Toggle word wrap
      $ oc exec msender -i -t -- \
          /bin/bash -c "echo | socat STDIO UDP4-DATAGRAM:224.1.0.1:30102,range=$CIDR,ip-multicast-ttl=64"

      如果多播正在工作,则上一个命令会返回以下输出:

      Copy to Clipboard Toggle word wrap
      mlistener

23.19. 为项目禁用多播

23.19.1. 禁用 pod 间多播

您可以为项目禁用 pod 间多播。

先决条件

  • 安装 OpenShift CLI (oc) 。
  • 您必须作为 cluster-admin 角色用户登录集群。

流程

  • 运行以下命令来禁用多播:

    Copy to Clipboard Toggle word wrap
    $ oc annotate namespace <namespace> \ 
    1
    
        k8s.ovn.org/multicast-enabled-
    1
    您要禁用多播的项目的 namespace
    提示

    您还可以应用以下 YAML 来删除注解:

    Copy to Clipboard Toggle word wrap
    apiVersion: v1
    kind: Namespace
    metadata:
      name: <namespace>
      annotations:
        k8s.ovn.org/multicast-enabled: null

23.20. 跟踪网络流

作为集群管理员,您可以从集群中收集有关 pod 网络流的信息,以帮助以下区域:

  • 监控 pod 网络上的入口和出口流量。
  • 对性能问题进行故障排除。
  • 为容量规划和安全审计收集数据。

当您启用网络流的集合时,只会收集与流量相关的元数据。例如,不会收集实际的数据包数据,而是只收集协议、源地址、目标地址、端口号、字节数和其他数据包级别的信息。

数据采用以下一种或多种记录格式收集:

  • NetFlow
  • sFlow
  • IPFIX

当您使用一个或多个收集器 IP 地址和端口号配置 Cluster Network Operator(CNO)时,Operator 会在每个节点上配置 Open vSwitch(OVS),以将网络流记录发送到每个收集器。

您可以将 Operator 配置为将记录发送到多种类型的网络流收集器。例如,您可以将记录发送到 NetFlow 收集器,并将记录发送到 sFlow 收集器。

当 OVS 向收集器发送数据时,每种类型的收集器接收相同的记录。例如,如果您配置两个 NetFlow 收集器,节点上的 OVS 会将相同的记录发送到两个收集器。如果您还配置了两个 sFlow 收集器,则两个 sFlow 收集器将接收相同的记录。但是,每个收集器类型都具有唯一的记录格式。

收集网络流数据并将记录发送到收集器会影响性能。节点处理数据包的速度较慢。如果性能影响太大,您可以删除收集器的目的地,以禁用收集网络流数据并恢复性能。

注意

启用网络流收集器可能会影响集群网络的整体性能。

23.20.1. 用于跟踪网络流的网络对象配置

下表显示了在 Cluster Network Operator(CNO)中配置网络流收集器的字段:

表 23.12. 网络流配置
字段类型描述

metadata.name

字符串

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

spec.exportNetworkFlows

object

一个或多个 netFlowsFlowipfix.

spec.exportNetworkFlows.netFlow.collectors

数组

最多 10 个收集器的 IP 地址和网络端口对列表。

spec.exportNetworkFlows.sFlow.collectors

数组

最多 10 个收集器的 IP 地址和网络端口对列表。

spec.exportNetworkFlows.ipfix.collectors

数组

最多 10 个收集器的 IP 地址和网络端口对列表。

将以下清单应用到 CNO 后,Operator 会在集群中的每个节点上配置 Open vSwitch(OVS),将网络流记录发送到侦听 192.168.1.99:2056 的 NetFlow 收集器。

跟踪网络流的配置示例

Copy to Clipboard Toggle word wrap
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  name: cluster
spec:
  exportNetworkFlows:
    netFlow:
      collectors:
        - 192.168.1.99:2056

23.20.2. 为网络流收集器添加目的地

作为集群管理器,您可以将 Cluster Network Operator(CNO)配置为发送有关 pod 网络的网络流元数据到网络流收集器。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 使用具有 cluster-admin 权限的用户登陆到集群。
  • 您有一个网络流收集器,知道它所侦听的 IP 地址和端口。

流程

  1. 创建补丁文件,用于指定网络流收集器类型以及收集器的 IP 地址和端口信息:

    Copy to Clipboard Toggle word wrap
    spec:
      exportNetworkFlows:
        netFlow:
          collectors:
            - 192.168.1.99:2056
  2. 使用网络流收集器配置 CNO:

    Copy to Clipboard Toggle word wrap
    $ oc patch network.operator cluster --type merge -p "$(cat <file_name>.yaml)"

    输出示例

    Copy to Clipboard Toggle word wrap
    network.operator.openshift.io/cluster patched

验证

通常情况不需要进行验证。您可以运行以下命令,确认每个节点上的 Open vSwitch(OVS)已配置为将网络流记录发送到一个或多个收集器。

  1. 查看 Operator 配置,确认配置了 exportNetworkFlows 字段:

    Copy to Clipboard Toggle word wrap
    $ oc get network.operator cluster -o jsonpath="{.spec.exportNetworkFlows}"

    输出示例

    Copy to Clipboard Toggle word wrap
    {"netFlow":{"collectors":["192.168.1.99:2056"]}}

  2. 查看每个节点中的 OVS 网络流配置:

    Copy to Clipboard Toggle word wrap
    $ for pod in $(oc get pods -n openshift-ovn-kubernetes -l app=ovnkube-node -o jsonpath='{range@.items[*]}{.metadata.name}{"\n"}{end}');
      do ;
        echo;
        echo $pod;
        oc -n openshift-ovn-kubernetes exec -c ovnkube-node $pod \
          -- bash -c 'for type in ipfix sflow netflow ; do ovs-vsctl find $type ; done';
    done

    输出示例

    Copy to Clipboard Toggle word wrap
    ovnkube-node-xrn4p
    _uuid               : a4d2aaca-5023-4f3d-9400-7275f92611f9
    active_timeout      : 60
    add_id_to_interface : false
    engine_id           : []
    engine_type         : []
    external_ids        : {}
    targets             : ["192.168.1.99:2056"]
    
    ovnkube-node-z4vq9
    _uuid               : 61d02fdb-9228-4993-8ff5-b27f01a29bd6
    active_timeout      : 60
    add_id_to_interface : false
    engine_id           : []
    engine_type         : []
    external_ids        : {}
    targets             : ["192.168.1.99:2056"]-
    
    ...

23.20.3. 删除网络流收集器的所有目的地

作为集群管理员,您可以配置 Cluster Network Operator(CNO)来停止将网络流元数据发送到网络流收集器。

先决条件

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

流程

  1. 删除所有网络流收集器:

    Copy to Clipboard Toggle word wrap
    $ oc patch network.operator cluster --type='json' \
        -p='[{"op":"remove", "path":"/spec/exportNetworkFlows"}]'

    输出示例

    Copy to Clipboard Toggle word wrap
    network.operator.openshift.io/cluster patched

23.20.4. 其他资源

23.21. 配置混合联网

作为集群管理员,您可以配置 Red Hat OpenShift Networking OVN-Kubernetes 网络插件,以允许 Linux 和 Windows 节点分别托管 Linux 和 Windows 工作负载。

23.21.1. 使用 OVN-Kubernetes 配置混合网络

您可以将集群配置为使用 OVN-Kubernetes 的混合网络。这允许支持不同节点网络配置的混合集群。例如:集群中运行 Linux 和 Windows 节点时需要这样做。

重要

您必须在安装集群过程中使用 OVN-Kubernetes 配置混合网络。您不能在安装过程中切换到混合网络。

先决条件

  • 您在 install-config.yaml 文件中为 networking.networkType 参数定义了 OVNKubernetes。如需更多信息,请参阅有关在所选云供应商上配置 OpenShift Container Platform 网络自定义的安装文档。

流程

  1. 进入包含安装程序的目录并创建清单:

    Copy to Clipboard Toggle word wrap
    $ ./openshift-install create manifests --dir <installation_directory>

    其中:

    <installation_directory>
    指定包含集群的 install-config.yaml 文件的目录名称。
  2. <installation_directory>/manifests/ 目录中 为高级网络配置创建一个名为 cluster-network-03-config.yml 的 stub 清单文件:

    Copy to Clipboard Toggle word wrap
    $ cat <<EOF > <installation_directory>/manifests/cluster-network-03-config.yml
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
    EOF

    其中:

    <installation_directory>
    指定包含集群的 manifests/ 目录的目录名称。
  3. 在编辑器中打开 cluster-network-03-config.yml 文件,并使用混合网络配置 OVN-Kubernetes,如下例所示:

    指定混合网络配置

    Copy to Clipboard Toggle word wrap
    apiVersion: operator.openshift.io/v1
    kind: Network
    metadata:
      name: cluster
    spec:
      defaultNetwork:
        ovnKubernetesConfig:
          hybridOverlayConfig:
            hybridClusterNetwork: 
    1
    
            - cidr: 10.132.0.0/14
              hostPrefix: 23
            hybridOverlayVXLANPort: 9898 
    2

    1
    指定用于额外覆盖网络上节点的 CIDR 配置。hybridClusterNetwork CIDR 不得与 clusterNetwork CIDR 重叠。
    2
    为额外覆盖网络指定自定义 VXLAN 端口。这是在 vSphere 上安装的集群中运行 Windows 节点所需要的,且不得为任何其他云供应商配置。自定义端口可以是除默认 4789 端口外的任何打开的端口。有关此要求的更多信息,请参阅 Microsoft 文档中的 Pod 到主机间的 pod 连接性
    注意

    Windows Server Long-Term Servicing Channel(LTSC):Windows Server 2019 在带有自定义 hybridOverlayVXLANPort 值的集群中不被支持,因为这个 Windows server 版本不支持选择使用自定义的 VXLAN 端口。

  4. 保存 cluster-network-03-config.yml 文件,再退出文本编辑器。
  5. 可选:备份 manifests/cluster-network-03-config.yml 文件。创建集群时,安装程序会删除 manifests/ 目录。

完成所有进一步的安装配置,然后创建集群。安装过程完成后会启用 Hybrid 网络。

23.21.2. 其他资源

第 24 章 OpenShift SDN 网络插件

24.1. 关于 OpenShift SDN 网络插件

OpenShift SDN 的一部分,OpenShift SDN 是一个网络插件,它使用软件定义型网络 (SDN) 方法来提供一个统一的集群网络,它允许 OpenShift Container Platform 集群间 pod 间的通信。此 pod 网络由 OpenShift SDN 建立和维护,它使用 Open vSwitch (OVS) 配置覆盖网络。

24.1.1. OpenShift SDN 网络隔离模式

OpenShift SDN 提供三种 SDN 模式来配置 pod 网络:

  • 网络策略模式允许项目管理员使用 NetworkPolicy 对象配置自己的隔离策略。Network policy 是 OpenShift Container Platform 4.12 的默认模式。
  • 多租户模式为 Pod 和服务提供项目级别的隔离。来自不同项目的 Pod 不能与不同项目的 Pod 和服务互相发送或接收数据包。您可以针对项目禁用隔离,允许它将网络流量发送到整个集群中的所有 pod 和服务,并从那些 pod 和服务接收网络流量。
  • 子网模式提供一个扁平 pod 网络,每个 pod 都可以与所有其他 pod 和服务通信。网络策略模式提供与子网模式相同的功能。

24.1.2. 支持的网络插件功能列表

Red Hat OpenShift Networking 为网络插件(OpenShift SDN 和 OVN-Kubernetes)提供了两个选项,用于网络插件。下表总结了这两个网络插件的当前功能支持:

表 24.1. 默认 CNI 网络插件功能比较