25.7. 从 Kuryr 网络插件迁移到 OVN-Kubernetes 网络插件
从 Kuryr 迁移到 OVN-Kubernetes 只是一个技术预览功能。技术预览功能不受红帽产品服务等级协议(SLA)支持,且功能可能并不完整。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的更多信息,请参阅技术预览功能支持范围。
作为在 Red Hat OpenStack Platform (RHOSP) 上运行的集群的管理员,您可以从 Kuryr SDN 网络插件迁移到 OVN-Kubernetes 网络插件。
要了解更多有关 OVN-Kubernetes 的信息,请参阅关于 OVN-Kubernetes 网络插件。
25.7.1. 迁移到 OVN-Kubernetes 网络供应商
您可以手动将 Red Hat OpenStack Platform (RHOSP) 上运行的集群迁移到 OVN-Kubernetes 网络供应商。
迁移到 OVN-Kubernetes 是一个单向过程。在迁移过程中,集群将在短时间内无法访问。
25.7.1.1. 迁移到 OVN-Kubernetes 网络供应商时的注意事项
Kubernetes 命名空间由 Kuryr 在单独的 RHOSP 网络服务(Neutron) 子网中保留。在迁移过程中不会保留分配给单个 pod 的子网和 IP 地址。
25.7.1.2. 迁移过程如何工作
下表总结了迁移过程,介绍了与集群和 Operator 执行的操作相关的步骤。
用户发起的步骤 | 迁移操作 |
---|---|
将名为 |
|
更新 |
|
重新引导集群中的每个节点。 |
|
清理剩余的资源 Kuryr。 |
|
25.7.2. 迁移到 OVN-Kubernetes 网络插件
作为集群管理员,您可以将集群的网络插件更改为 OVN-Kubernetes。
在迁移过程中,您必须重新引导集群中的每个节点。在进行迁移时,集群不可用,工作负载可能会中断。仅在服务中断可以接受时才执行迁移。
先决条件
-
已安装 OpenShift CLI(
oc
)。 -
您可以使用具有
cluster-admin
角色的用户访问集群。 - 具有最新的 etcd 数据库的备份。
- 您可以手动重新引导每个节点。
- 要计划进行迁移的集群处于已知良好状态,没有任何错误。
- 安装了 Python 解释器。
-
安装了
openstacksdk
python 软件包。 -
安装了
openstack
CLI 工具。 - 您可以访问底层 RHOSP 云。
流程
运行以下命令备份集群网络的配置:
$ oc get Network.config.openshift.io cluster -o yaml > cluster-kuryr.yaml
要设置
CLUSTERID
变量,请运行以下命令:$ CLUSTERID=$(oc get infrastructure.config.openshift.io cluster -o=jsonpath='{.status.infrastructureName}')
要为迁移准备所有节点,请输入以下命令在 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 部署准备集群。可选: 您可以自定义 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 }}}}'
输入以下命令检查机器配置池状态:
$ oc get mcp
当 MCO 更新每个机器配置池中的机器时,它会逐一重启每个节点。在继续前,必须等到所有节点都已更新。
成功更新的节点具有以下状态:
UPDATED=true
、UPDATING=false
、DEGRADED=false
。注意默认情况下,MCO 一次只更新每个池中的一个机器。与小集群相比,大型集群需要更长的时间进行迁移。
确认主机上新机器配置的状态:
要列出机器配置状态和应用的机器配置名称,请输入以下命令:
$ 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
检查前一步中的输出。以下条件必须满足:
-
machineconfiguration.openshift.io/state
字段的值为Done
。 -
machineconfiguration.openshift.io/currentConfig
字段的值等于machineconfiguration.openshift.io/desiredConfig
字段的值。
-
要确认机器配置正确,请输入以下命令:
$ oc get machineconfig <config_name> -o yaml | grep ExecStart
其中:
- <config_name>
指定来自
machineconfiguration.openshift.io/currentConfig
字段的机器配置名称。机器配置必须包括以下对 systemd 配置的更新:
输出示例
ExecStart=/usr/local/bin/configure-ovs.sh OVNKubernetes
如果节点一直处于
NotReady
状态,检查机器配置守护进程 pod 日志并解决所有错误:运行以下命令列出 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>
值是一个随机的五个字符的字母数字序列。使用以下命令,输出在上一个输出中显示的第一个机器配置守护进程 pod 的 pod 日志:
$ oc logs <pod> -n openshift-machine-config-operator
其中:
- <pod>
- 指定机器配置守护进程 pod 的名称。
- 解决上一命令输出中显示的日志中的任何错误。
要启动迁移,请使用以下命令配置 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 网络供应商在内部使用此块。
输入以下命令验证 Multus 守护进程集推出部署是否已完成:
$ oc -n openshift-multus rollout status daemonset/multus
Multus pod 的名称采用
multus-<xxxxx>
的形式,其中<xxxxx>
是由字母组成的随机序列。pod 可能需要一些时间才能重启。输出示例
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
要完成迁移,请重新引导集群中的每个节点。例如,您可以使用类似以下示例的 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 客户端访问虚拟机。
验证
确认迁移成功,然后删除迁移资源:
要确认网络插件是 OVN-Kubernetes,请输入以下命令。
$ oc get network.config/cluster -o jsonpath='{.status.networkType}{"\n"}'
status.networkType
的值必须是OVNKubernetes
。要确认集群节点处于
Ready
状态,请输入以下命令:$ oc get nodes
要确认您的 pod 不在错误状态,请输入以下命令:
$ oc get pods --all-namespaces -o wide --sort-by='{.spec.nodeName}'
如果节点上的 pod 处于错误状态,请重新引导该节点。
要确认所有集群 Operator 没有处于异常状态,请输入以下命令:
$ oc get co
每个集群 Operator 的状态必须是:
AVAILABLE="True"
、PROGRESSING="False"
和DEGRADED="False"
。如果 Cluster Operator 不可用或降级,请检查集群 Operator 的日志以了解更多信息。重要如果以前任何一个验证步骤有错误,则不要继续。您可能会遇到因为清理过程中删除的终结器而处于
Terminating
状态的 pod。这并不代表错误。
如果迁移完成且集群处于良好状态,请输入以下命令从 CNO 配置对象中删除迁移配置:
$ oc patch Network.operator.openshift.io cluster --type='merge' \ --patch '{ "spec": { "migration": null } }'
25.7.3. 迁移后清理资源
从 Kuryr 网络插件迁移到 OVN-Kubernetes 网络插件后,您必须清理 Kuryr 之前创建的资源。
清理过程依赖于 Python 虚拟环境,以确保您使用 Octavia 对象支持标签的软件包版本。如果您可以确定您的环境最少满足以下情况,则不需要虚拟环境:* openstacksdk
版本 0.54.0 * python-openstackclient
版本 5.5.0 * python-octaviaclient
版本 2.3.0
先决条件
-
已安装 OpenShift Container Platform CLI (
oc
)。 - 安装了 Python 解释器。
-
安装了
openstacksdk
Python 软件包。 -
安装了
openstack
CLI。 - 您可以访问底层 RHOSP 云。
-
您可以使用具有
cluster-admin
角色的用户访问集群。
流程
创建一个干净的 Python 虚拟环境:
为您的环境创建一个临时目录。例如:
$ python3 -m venv /tmp/venv
所有清理示例都使用位于
/tmp/venv
目录中的虚拟环境。进入虚拟环境例如:
$ source /tmp/venv/bin/activate
运行以下命令,在虚拟环境中升级
pip
命令:(venv) $ pip install pip --upgrade
运行以下命令来安装所需的 Python 软件包:
(venv) $ pip install openstacksdk==0.54.0 python-openstackclient==5.5.0 python-octaviaclient==2.3.0
在终端中,运行以下命令将变量设置为集群和 Kuryr 标识符:
设置集群 ID:
(venv) $ CLUSTERID=$(oc get infrastructure.config.openshift.io cluster -o=jsonpath='{.status.infrastructureName}')
设置集群标签:
(venv) $ CLUSTERTAG="openshiftClusterID=${CLUSTERID}"
设置路由器 ID:
(venv) $ ROUTERID=$(oc get kuryrnetwork -A --no-headers -o custom-columns=":status.routerId"|head -n 1)
运行以下命令,创建一个从指定资源中删除终结器的 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 资源从集群中移除,其定义被复制的数据替代,不包括指定的终结器。
要从服务中删除 Kuryr 终结器,请输入以下命令:
(venv) $ REMFIN services kuryr.openstack.org/service-finalizer
要删除 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
要从 Octavia 中删除所有标记的 RHOSP 负载均衡器,请输入以下命令:
(venv) $ for lb in $(openstack loadbalancer list --tags $CLUSTERTAG -f value -c id); do openstack loadbalancer delete --cascade $lb done
要从所有
KuryrLoadBalancer
CR 中删除 Kuryr finalizers,请输入以下命令:(venv) $ REMFIN kuryrloadbalancers.openstack.org kuryr.openstack.org/kuryrloadbalancer-finalizers
要删除
openshift-kuryr
命名空间,请输入以下命令:(venv) $ oc delete namespace openshift-kuryr
要从路由器中删除 Kuryr 服务子网,请输入以下命令:
(venv) $ openstack router remove subnet $ROUTERID ${CLUSTERID}-kuryr-service-subnet
要删除 Kuryr 服务网络,请输入以下命令:
(venv) $ openstack network delete ${CLUSTERID}-kuryr-service-network
要从所有 pod 中删除 Kuryr 终结器,请输入以下命令:
(venv) $ REMFIN pods kuryr.openstack.org/pod-finalizer
要从所有
KuryrPort
CR 中删除 Kuryr finalizers,请输入以下命令:(venv) $ REMFIN kuryrports.openstack.org kuryr.openstack.org/kuryrport-finalizer
这个命令删除
KuryrPort
CR。要从网络策略中删除 Kuryr 终结器,请输入以下命令:
(venv) $ REMFIN networkpolicy kuryr.openstack.org/networkpolicy-finalizer
要从剩余的网络策略中删除 Kuryr 终结器,请输入以下命令:
(venv) $ REMFIN kuryrnetworkpolicies.openstack.org kuryr.openstack.org/networkpolicy-finalizer
要删除 Kuryr 从中继创建的子端口,请输入以下命令:
(venv) $ read -ra trunks <<< $(python -c "import openstack; n = openstack.connect().network; print(' '.join([x.id for x in n.trunks(any_tags='$CLUSTERTAG')]))") && \ i=0 && \ for trunk in "${trunks[@]}"; do 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
要从
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
要删除 Kuryr 安全组,请输入以下命令:
(venv) $ openstack security group delete ${CLUSTERID}-kuryr-pods-security-group
要删除所有标记的子网池,请输入以下命令:
(venv) $ for subnetpool in $(openstack subnet pool list --tags $CLUSTERTAG -f value -c ID); do openstack subnet pool delete $subnetpool done
要检查所有基于
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
如果命令返回任何现有网络,在继续之前测试并删除它们。
要删除与网络策略相关的安全组,请输入以下命令:
(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
要从
KuryrNetwork
CR 中删除终结器,请输入以下命令:(venv) $ REMFIN kuryrnetworks.openstack.org kuryrnetwork.finalizers.kuryr.openstack.org
要删除 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
25.7.4. 其他资源
- OVN-Kubernetes 网络插件的配置参数
- 备份 etcd
- 关于网络策略
要了解更多有关 OVN-Kubernetes 功能的信息,请参阅: