26.8. Kuryr 네트워크 플러그인에서 OVN-Kubernetes 네트워크 플러그인으로 마이그레이션
RHOSP(Red Hat OpenStack Platform)에서 실행되는 클러스터의 관리자는 Kuryr SDN 네트워크 플러그인에서 OVN-Kubernetes 네트워크 플러그인으로 마이그레이션할 수 있습니다.
OVN-Kubernetes에 대한 자세한 내용은 OVN-Kubernetes 네트워크 플러그인 정보를 참조하십시오.
26.8.1. OVN-Kubernetes 네트워크 공급자로 마이그레이션
RHOSP(Red Hat OpenStack Platform)에서 실행되는 클러스터를 OVN-Kubernetes 네트워크 공급자로 수동으로 마이그레이션할 수 있습니다.
OVN-Kubernetes로의 마이그레이션은 단방향 프로세스입니다. 마이그레이션하는 동안 짧은 시간 동안 클러스터에 연결할 수 없습니다.
26.8.1.1. OVN-Kubernetes 네트워크 공급자로 마이그레이션할 때 고려 사항
Kubernetes 네임스페이스는 Kuryr에 의해 별도의 RHOSP 네트워킹 서비스(Neutron) 서브넷에 보관됩니다. 개별 포드에 할당된 서브넷 및 IP 주소는 마이그레이션 중에 보존되지 않습니다.
26.8.1.2. 마이그레이션 프로세스의 작동 방식
다음 표에는 클러스터 및 Operator에서 수행하는 작업과 관련된 마이그레이션 프로세스가 요약되어 있습니다.
사용자 시작 단계 | 마이그레이션 활동 |
---|---|
|
|
|
|
클러스터의 각 노드를 재부팅합니다. |
|
Kuryr가 제어하는 나머지 리소스를 정리합니다. |
|
26.8.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
필드를 지정하면 MCO(Machine Config Operator)가 클러스터의 모든 노드에 새 머신 구성을 적용합니다. 이렇게 하면 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를 사용하지 않을 때는 최소 노드 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
필드를 업데이트하는 패치 명령 예$ 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
이전 단계의 출력을 검토합니다. 다음 설명은 true여야 합니다.
-
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 로그를 조사하고 오류를 해결합니다.포드를 나열하려면 다음 명령을 입력합니다.
$ 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
구성 데몬 포드의 이름은 다음 형식입니다.
machine-config-daemon-<seq>
.<seq>
값은 임의 5자 영숫자 순서입니다.다음 명령을 입력하여 이전 출력에 표시된 첫 번째 머신 구성 데몬 포드에 대한 포드 로그를 표시합니다.
$ 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 블록의 슬라이스를 지정합니다.
중요마이그레이션 중에 서비스 네트워크 주소 블록을 변경할 수 없습니다.
OVN-Kubernetes 네트워크 공급자가 이 블록을 내부에서 사용하므로
100.64.0.0/16
CIDR 블록과 겹치는 CIDR 블록을 사용할 수 없습니다.
마이그레이션을 완료하려면 클러스터의 각 노드를 재부팅합니다. 예를 들어 다음 예와 유사한 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
이어야 합니다.클러스터 노드가
준비
상태에 있는지 확인하려면 다음 명령을 입력합니다.$ 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"
여야 합니다. 클러스터 Operator를 사용할 수 없거나 성능이 저하된 경우 자세한 내용은 클러스터 Operator의 로그를 확인합니다.중요이전 확인 단계에서 오류가 표시되면 진행하지 마십시오. 정리 중에 제거된 종료자로 인해
Terminating
상태가 있는 Pod가 표시될 수 있습니다. 오류 표시가 아닙니다.
마이그레이션이 완료되고 클러스터가 정상 상태인 경우 다음 명령을 입력하여 CNO 구성 오브젝트에서 마이그레이션 구성을 제거합니다.
$ oc patch Network.operator.openshift.io cluster --type=merge \ --patch '{"spec": {"migration": null}}'
26.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
역할의 사용자로 클러스터에 액세스할 수 있습니다.
프로세스
정리 Python 가상 환경을 생성합니다.
환경에 사용할 임시 디렉터리를 생성합니다. 예를 들면 다음과 같습니다.
$ python3 -m venv /tmp/venv
/tmp/venv
디렉터리에 있는 가상 환경은 모든 정리 예제에 사용됩니다.가상 환경을 입력합니다. 예를 들면 다음과 같습니다.
$ source /tmp/venv/bin/activate
다음 명령을 실행하여 가상 환경에서
pip
명령을 업그레이드합니다.(venv) $ pip install --upgrade pip
다음 명령을 실행하여 필요한 Python 패키지를 설치합니다.
(venv) $ pip install openstacksdk==0.54.0 python-openstackclient==5.5.0 python-octaviaclient==2.3.0 'python-neutronclient<9.0.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"|uniq)
다음 명령을 실행하여 지정된 리소스에서 종료자를 제거하는 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 }
이 함수는 두 매개 변수를 사용합니다. 첫 번째 매개 변수는 리소스의 이름이며 두 번째 매개 변수는 제거할 종료자입니다. 이름이 지정된 리소스는 클러스터에서 제거되고 해당 정의는 지정된 종료자를 제외하고 복사된 데이터로 교체됩니다.
서비스에서 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 종료자를 제거하려면 다음 명령을 입력합니다.(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 종료자를 제거하려면 다음 명령을 입력합니다.(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) $ 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
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
26.8.4. 추가 리소스
- OVN-Kubernetes 네트워크 플러그인의 구성 매개변수
- etcd 백업
- 네트워크 정책 정의
OVN-Kubernetes 기능에 대한 자세한 내용은 다음을 참조하십시오.