搜索

24.8. 从 Kuryr 网络插件迁移到 OVN-Kubernetes 网络插件

download PDF

作为在 Red Hat OpenStack Platform (RHOSP) 上运行的集群的管理员,您可以从 Kuryr SDN 网络插件迁移到 OVN-Kubernetes 网络插件。

要了解更多有关 OVN-Kubernetes 的信息,请参阅关于 OVN-Kubernetes 网络插件

24.8.1. 迁移到 OVN-Kubernetes 网络供应商

您可以手动将 Red Hat OpenStack Platform (RHOSP) 上运行的集群迁移到 OVN-Kubernetes 网络供应商。

重要

迁移到 OVN-Kubernetes 是一个单向过程。在迁移过程中,集群将在短时间内无法访问。

24.8.1.1. 迁移到 OVN-Kubernetes 网络供应商时的注意事项

Kubernetes 命名空间由 Kuryr 在单独的 RHOSP 网络服务(Neutron) 子网中保留。在迁移过程中不会保留分配给单个 pod 的子网和 IP 地址。

24.8.1.2. 迁移过程如何工作

下表总结了迁移过程,介绍了与集群和 Operator 执行的操作相关的步骤。

表 24.9. Kuryr 到 OVN-Kubernetes 的迁移过程
用户发起的步骤迁移操作

将名为 clusterNetwork.operator.openshift.io 自定义资源(CR)的 migration 字段设置为 OVNKubernetes。在将 migration 字段的值设置为另一个值前,请验证 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

执行以下操作:

  • 销毁 Kuryr control plane pod: Kuryr CNIs 和 Kuryr 控制器。
  • 部署 OVN-Kubernetes control plane pod。
  • 更新 Multus 对象以反映新的网络插件。

重新引导集群中的每个节点。

Cluster
当节点重启时,集群会为 OVN-Kubernetes 集群网络上的 pod 分配 IP 地址。

清理剩余的资源 Kuryr。

Cluster
包含需要释放的 RHOSP 资源,以及要配置的 OpenShift Container Platform 资源。

24.8.2. 迁移到 OVN-Kubernetes 网络插件

作为集群管理员,您可以将集群的网络插件更改为 OVN-Kubernetes。

重要

在迁移过程中,您必须重新引导集群中的每个节点。在进行迁移时,集群不可用,工作负载可能会中断。仅在服务中断可以接受时才执行迁移。

先决条件

  • 已安装 OpenShift CLI(oc)。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。
  • 具有最新的 etcd 数据库的备份。
  • 您可以手动重新引导每个节点。
  • 要计划进行迁移的集群处于已知良好状态,没有任何错误。
  • 安装了 Python 解释器。
  • 安装了 openstacksdk python 软件包。
  • 安装了 openstack CLI 工具。
  • 您可以访问底层 RHOSP 云。

流程

  1. 运行以下命令备份集群网络的配置:

    $ oc get Network.config.openshift.io cluster -o yaml > cluster-kuryr.yaml
  2. 要设置 CLUSTERID 变量,请运行以下命令:

    $ CLUSTERID=$(oc get infrastructure.config.openshift.io cluster -o=jsonpath='{.status.infrastructureName}')
  3. 要为迁移准备所有节点,请输入以下命令在 Cluster Network Operator 配置对象上设置 migration 字段:

    $ oc patch Network.operator.openshift.io cluster --type=merge \
        --patch '{"spec": {"migration": {"networkType": "OVNKubernetes"}}}'
    注意

    此步骤不会立即部署 OVN-Kubernetes。指定 migration 字段会触发 Machine Config Operator(MCO)将新机器配置应用到集群中的所有节点。这会为 OVN-Kubernetes 部署准备集群。

  4. 可选: 您可以自定义 OVN-Kubernetes 的以下设置,以满足您的网络基础架构要求:

    • 最大传输单元(MTU)
    • Geneve(Generic Network Virtualization Encapsulation)覆盖网络端口
    • OVN-Kubernetes IPv4 内部子网
    • OVN-Kubernetes IPv6 内部子网

    要自定义这些设,请输入以下命令。

    $ oc patch Network.operator.openshift.io cluster --type=merge \
      --patch '{
        "spec":{
          "defaultNetwork":{
            "ovnKubernetesConfig":{
              "mtu":<mtu>,
              "genevePort":<port>,
              "v4InternalSubnet":"<ipv4_subnet>",
              "v6InternalSubnet":"<ipv6_subnet>"
        }}}}'

    其中:

    mtu
    为 Geneve 覆盖网络指定 MTU。这个值通常是自动配置的;但是,如果集群中的节点没有都使用相同的 MTU,那么您必须将此值明确设置为比最小节点 MTU 的值小 100
    port
    为 Geneve 覆盖网络指定 UDP 端口。如果没有指定值,则默认为 6081。端口不能与 Kuryr 使用的 VXLAN 端口相同。VXLAN 端口的默认值为 4789
    ipv4_subnet
    指定 OVN-Kubernetes 内部使用的 IPv4 地址范围。您必须确保 IP 地址范围没有与 OpenShift Container Platform 安装使用的任何其他子网重叠。IP 地址范围必须大于可添加到集群的最大节点数。默认值为 100.64.0.0/16
    ipv6_subnet
    指定 OVN-Kubernetes 内部使用的 IPv6 地址范围。您必须确保 IP 地址范围没有与 OpenShift Container Platform 安装使用的任何其他子网重叠。IP 地址范围必须大于可添加到集群的最大节点数。默认值为 fd98::/48

    如果您不需要更改默认值,请从补丁中省略该键。

    更新 mtu 字段的 patch 命令示例

    $ oc patch Network.operator.openshift.io cluster --type=merge \
      --patch '{
        "spec":{
          "defaultNetwork":{
            "ovnKubernetesConfig":{
              "mtu":1200
        }}}}'

  5. 输入以下命令检查机器配置池状态:

    $ oc get mcp

    当 MCO 更新每个机器配置池中的机器时,它会逐一重启每个节点。在继续前,必须等到所有节点都已更新。

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

    注意

    默认情况下,MCO 一次只更新每个池中的一个机器。与小集群相比,大型集群需要更长的时间进行迁移。

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

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

      $ oc describe node | egrep "hostname|machineconfig"

      输出示例

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

    2. 检查前一步中的输出。以下条件必须满足:

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

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

      其中:

      <config_name>

      指定来自 machineconfiguration.openshift.io/currentConfig 字段的机器配置名称。

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

      输出示例

      ExecStart=/usr/local/bin/configure-ovs.sh OVNKubernetes

    4. 如果节点一直处于 NotReady 状态,检查机器配置守护进程 pod 日志并解决所有错误:

      1. 运行以下命令列出 pod:

        $ oc get pod -n openshift-machine-config-operator

        输出示例

        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 日志:

        $ oc logs <pod> -n openshift-machine-config-operator

        其中:

        <pod>
        指定机器配置守护进程 pod 的名称。
      3. 解决上一命令输出中显示的日志中的任何错误。
  7. 要启动迁移,请使用以下命令配置 OVN-Kubernetes 网络插件:

    • 要指定网络供应商而不更改集群网络 IP 地址块,请输入以下命令:

      $ oc patch Network.config.openshift.io cluster --type=merge \
          --patch '{"spec": {"networkType": "OVNKubernetes"}}'
    • 要指定不同的集群网络 IP 地址块,请输入以下命令:

      $ 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 网络供应商在内部使用此块。

  8. 要完成迁移,请重新引导集群中的每个节点。例如,您可以使用类似以下示例的 bash 脚本。这个脚本假定您可以使用 ssh 连接到每个主机,并将 sudo 配置为不提示输入密码:

    #!/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
    注意

    如果无法使用 SSH,可以使用 openstack 命令:

    $ for name in $(openstack server list --name "${CLUSTERID}*" -f value -c Name); do openstack server reboot "${name}"; done

    或者,您可能通过基础架构供应商的管理门户重新引导每个节点。否则,请联系相关的部门来帮助通过 SSH 或管理门户和 OpenStack 客户端访问虚拟机。

验证

  1. 确认迁移成功,然后删除迁移资源:

    1. 要确认网络插件是 OVN-Kubernetes,请输入以下命令。

      $ oc get network.config/cluster -o jsonpath='{.status.networkType}{"\n"}'

      status.networkType 的值必须是 OVNKubernetes

    2. 要确认集群节点处于 Ready 状态,请输入以下命令:

      $ oc get nodes
    3. 要确认您的 pod 不在错误状态,请输入以下命令:

      $ oc get pods --all-namespaces -o wide --sort-by='{.spec.nodeName}'

      如果节点上的 pod 处于错误状态,请重新引导该节点。

    4. 要确认所有集群 Operator 没有处于异常状态,请输入以下命令:

      $ oc get co

      每个集群 Operator 的状态必须是: AVAILABLE="True"PROGRESSING="False"DEGRADED="False"。如果 Cluster Operator 不可用或降级,请检查集群 Operator 的日志以了解更多信息。

      重要

      如果以前任何一个验证步骤有错误,则不要继续。您可能会遇到因为清理过程中删除的终结器而处于 Terminating 状态的 pod。这并不代表错误。

  2. 如果迁移完成且集群处于良好状态,请输入以下命令从 CNO 配置对象中删除迁移配置:

    $ oc patch Network.operator.openshift.io cluster --type=merge \
        --patch '{"spec": {"migration": null}}'

24.8.3. 迁移后清理资源

从 Kuryr 网络插件迁移到 OVN-Kubernetes 网络插件后,您必须清理 Kuryr 之前创建的资源。

注意

清理过程依赖于 Python 虚拟环境,以确保您使用 Octavia 对象支持标签的软件包版本。如果您确定您的环境至少使用了以下组件,则不需要虚拟环境:

  • openstacksdk Python 软件包版本 0.54.0
  • python-openstackclient Python 软件包版本 5.5.0
  • python-octaviaclient Python 软件包版本 2.3.0

如果您决定使用这些特定版本,请务必在版本 9.0.0 之前拉取 python-neutronclient,因为它会阻止您访问中继。

先决条件

  • 已安装 OpenShift Container Platform CLI (oc)。
  • 安装了 Python 解释器。
  • 安装了 openstacksdk Python 软件包。
  • 安装了 openstack CLI。
  • 您可以访问底层 RHOSP 云。
  • 您可以使用具有 cluster-admin 角色的用户访问集群。

流程

  1. 创建一个干净的 Python 虚拟环境:

    1. 为您的环境创建一个临时目录。例如:

      $ python3 -m venv /tmp/venv

      所有清理示例都使用位于 /tmp/venv 目录中的虚拟环境。

    2. 进入虚拟环境例如:

      $ source /tmp/venv/bin/activate
    3. 运行以下命令,在虚拟环境中升级 pip 命令:

      (venv) $ pip install --upgrade pip
    4. 运行以下命令来安装所需的 Python 软件包:

      (venv) $ pip install openstacksdk==0.54.0 python-openstackclient==5.5.0 python-octaviaclient==2.3.0 'python-neutronclient<9.0.0'
  2. 在终端中,运行以下命令将变量设置为集群和 Kuryr 标识符:

    1. 设置集群 ID:

      (venv) $ CLUSTERID=$(oc get infrastructure.config.openshift.io cluster -o=jsonpath='{.status.infrastructureName}')
    2. 设置集群标签:

      (venv) $ CLUSTERTAG="openshiftClusterID=${CLUSTERID}"
    3. 设置路由器 ID:

      (venv) $ ROUTERID=$(oc get kuryrnetwork -A --no-headers -o custom-columns=":status.routerId"|uniq)
  3. 运行以下命令,创建一个从指定资源中删除终结器的 Bash 功能:

    (venv) $ function REMFIN {
        local resource=$1
        local finalizer=$2
        for res in $(oc get "${resource}" -A --template='{{range $i,$p := .items}}{{ $p.metadata.name }}|{{ $p.metadata.namespace }}{{"\n"}}{{end}}'); do
            name=${res%%|*}
            ns=${res##*|}
            yaml=$(oc get -n "${ns}" "${resource}" "${name}" -o yaml)
            if echo "${yaml}" | grep -q "${finalizer}"; then
                echo "${yaml}" | grep -v  "${finalizer}" | oc replace -n "${ns}" "${resource}" "${name}" -f -
            fi
        done
    }

    函数采用两个参数:第一个参数是资源名称,第二个参数是要删除的终结器。named 资源从集群中移除,其定义被复制的数据替代,不包括指定的终结器。

  4. 要从服务中删除 Kuryr 终结器,请输入以下命令:

    (venv) $ REMFIN services kuryr.openstack.org/service-finalizer
  5. 要删除 Kuryr service-subnet-gateway-ip 服务,请输入以下命令:

    (venv) $ if oc get -n openshift-kuryr service service-subnet-gateway-ip &>/dev/null; then
        oc -n openshift-kuryr delete service service-subnet-gateway-ip
    fi
  6. 要从 Octavia 中删除所有标记的 RHOSP 负载均衡器,请输入以下命令:

    (venv) $ for lb in $(openstack loadbalancer list --tags "${CLUSTERTAG}" -f value -c id); do
        openstack loadbalancer delete --cascade "${lb}"
    done
  7. 要从所有 KuryrLoadBalancer CR 中删除 Kuryr finalizers,请输入以下命令:

    (venv) $ REMFIN kuryrloadbalancers.openstack.org kuryr.openstack.org/kuryrloadbalancer-finalizers
  8. 要删除 openshift-kuryr 命名空间,请输入以下命令:

    (venv) $ oc delete namespace openshift-kuryr
  9. 要从路由器中删除 Kuryr 服务子网,请输入以下命令:

    (venv) $ openstack router remove subnet "${ROUTERID}" "${CLUSTERID}-kuryr-service-subnet"
  10. 要删除 Kuryr 服务网络,请输入以下命令:

    (venv) $ openstack network delete "${CLUSTERID}-kuryr-service-network"
  11. 要从所有 pod 中删除 Kuryr 终结器,请输入以下命令:

    (venv) $ REMFIN pods kuryr.openstack.org/pod-finalizer
  12. 要从所有 KuryrPort CR 中删除 Kuryr finalizers,请输入以下命令:

    (venv) $ REMFIN kuryrports.openstack.org kuryr.openstack.org/kuryrport-finalizer

    这个命令删除 KuryrPort CR。

  13. 要从网络策略中删除 Kuryr 终结器,请输入以下命令:

    (venv) $ REMFIN networkpolicy kuryr.openstack.org/networkpolicy-finalizer
  14. 要从剩余的网络策略中删除 Kuryr 终结器,请输入以下命令:

    (venv) $ REMFIN kuryrnetworkpolicies.openstack.org kuryr.openstack.org/networkpolicy-finalizer
  15. 要删除 Kuryr 从中继创建的子端口,请输入以下命令:

    (venv) $ mapfile trunks < <(python -c "import openstack; n = openstack.connect().network; print('\n'.join([x.id for x in n.trunks(any_tags='$CLUSTERTAG')]))") && \
    i=0 && \
    for trunk in "${trunks[@]}"; do
        trunk=$(echo "$trunk"|tr -d '\n')
        i=$((i+1))
        echo "Processing trunk $trunk, ${i}/${#trunks[@]}."
        subports=()
        for subport in $(python -c "import openstack; n = openstack.connect().network; print(' '.join([x['port_id'] for x in n.get_trunk('$trunk').sub_ports if '$CLUSTERTAG' in n.get_port(x['port_id']).tags]))"); do
            subports+=("$subport");
        done
        args=()
        for sub in "${subports[@]}" ; do
            args+=("--subport $sub")
        done
        if [ ${#args[@]} -gt 0 ]; then
            openstack network trunk unset ${args[*]} "${trunk}"
        fi
    done
  16. 要从 KuryrNetwork CR 检索所有网络和子网,并删除端口、路由器接口和网络本身,请输入以下命令:

    (venv) $ mapfile -t kuryrnetworks < <(oc get kuryrnetwork -A --template='{{range $i,$p := .items}}{{ $p.status.netId }}|{{ $p.status.subnetId }}{{"\n"}}{{end}}') && \
    i=0 && \
    for kn in "${kuryrnetworks[@]}"; do
        i=$((i+1))
        netID=${kn%%|*}
        subnetID=${kn##*|}
        echo "Processing network $netID, ${i}/${#kuryrnetworks[@]}"
        # Remove all ports from the network.
        for port in $(python -c "import openstack; n = openstack.connect().network; print(' '.join([x.id for x in n.ports(network_id='$netID') if x.device_owner != 'network:router_interface']))"); do
            ( openstack port delete "${port}" ) &
    
            # Only allow 20 jobs in parallel.
            if [[ $(jobs -r -p | wc -l) -ge 20 ]]; then
                wait -n
            fi
        done
        wait
    
        # Remove the subnet from the router.
        openstack router remove subnet "${ROUTERID}" "${subnetID}"
    
        # Remove the network.
        openstack network delete "${netID}"
    done
  17. 要删除 Kuryr 安全组,请输入以下命令:

    (venv) $ openstack security group delete "${CLUSTERID}-kuryr-pods-security-group"
  18. 要删除所有标记的子网池,请输入以下命令:

    (venv) $ for subnetpool in $(openstack subnet pool list --tags "${CLUSTERTAG}" -f value -c ID); do
        openstack subnet pool delete "${subnetpool}"
    done
  19. 要检查所有基于 KuryrNetwork CR 的网络是否已删除,请输入以下命令:

    (venv) $ networks=$(oc get kuryrnetwork -A --no-headers -o custom-columns=":status.netId") && \
    for existingNet in $(openstack network list --tags "${CLUSTERTAG}" -f value -c ID); do
        if [[ $networks =~ $existingNet ]]; then
            echo "Network still exists: $existingNet"
        fi
    done

    如果命令返回任何现有网络,在继续之前测试并删除它们。

  20. 要删除与网络策略相关的安全组,请输入以下命令:

    (venv) $ for sgid in $(openstack security group list -f value -c ID -c Description | grep 'Kuryr-Kubernetes Network Policy' | cut -f 1 -d ' '); do
        openstack security group delete "${sgid}"
    done
  21. 要从 KuryrNetwork CR 中删除终结器,请输入以下命令:

    (venv) $ REMFIN kuryrnetworks.openstack.org kuryrnetwork.finalizers.kuryr.openstack.org
  22. 要删除 Kuryr 路由器,请输入以下命令:

    (venv) $ if python3 -c "import sys; import openstack; n = openstack.connect().network; r = n.get_router('$ROUTERID'); sys.exit(0) if r.description != 'Created By OpenShift Installer' else sys.exit(1)"; then
        openstack router delete "${ROUTERID}"
    fi

24.8.4. 其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.