7.2. Validation 서비스에 대한 사용자 지정 규칙 생성


유효성 검사 서비스는 OCI(Open Policy Agent) 정책 규칙을 사용하여 마이그레이션을 위한 각 VM(가상 머신)의 적합성을 확인합니다. 유효성 검사 서비스는 공급자 인벤토리 서비스에 VM 속성으로 저장되는 각 VM에 대한 우려 목록을 생성합니다. 웹 콘솔에는 공급자 인벤토리의 각 VM에 대한 문제가 표시됩니다.

사용자 지정 규칙을 만들어 Validation 서비스의 기본 규칙 집합을 확장할 수 있습니다. 예를 들어 VM에 여러 디스크가 있는지 확인하는 규칙을 생성할 수 있습니다.

7.2.1. Rego 파일 정보

검증 규칙은 OCI(Open Policy Agent) 기본 쿼리 언어인 Rego 로 작성됩니다. 규칙은 Validation Pod의 /usr/share/opa/policies/io/konveyor/forklift/<provider > 디렉터리에 .rego 파일로 저장됩니다.

각 검증 규칙은 별도의 .rego 파일에 정의되고 특정 조건에 대한 테스트입니다. 조건이 true 로 평가되면 규칙은 {"category", "label", "assessment"} 해시를 문제에 추가합니다. 문제가 있는 콘텐츠는 VM의 인벤토리 레코드에 있는 concerns 키에 추가됩니다. 웹 콘솔에는 공급자 인벤토리의 각 VM에 대한 concerns 키 내용이 표시됩니다.

다음 .rego 파일 예제에서는 VMware VM 클러스터에서 활성화된 분산 리소스 스케줄링을 확인합니다.

drs_enabled.rego example

package io.konveyor.forklift.vmware 
1


has_drs_enabled {
    input.host.cluster.drsEnabled 
2

}

concerns[flag] {
    has_drs_enabled
    flag := {
        "category": "Information",
        "label": "VM running in a DRS-enabled cluster",
        "assessment": "Distributed resource scheduling is not currently supported by OpenShift Virtualization. The VM can be migrated but it will not have this feature in the target environment."
    }
}
Copy to Clipboard Toggle word wrap

1
각 검증 규칙은 패키지 내에 정의됩니다. 패키지 네임스페이스는 VMware용 io.konveyor.forklift.vmware 및 Red Hat Virtualization의 경우 io.konveyor.forklift.ovirt 입니다.
2
쿼리 매개변수는 Validation 서비스 JSON의 입력 키를 기반으로 합니다.

7.2.2. 기본 검증 규칙 확인

사용자 지정 규칙을 만들기 전에 Validation 서비스의 기본 규칙을 확인하여 기존 기본값을 설명하는 규칙을 만들지 않아야 합니다.

예: 기본 규칙에 default valid_input = false 행이 포함되어 있고 default valid_input = true 줄이 포함된 사용자 정의 규칙을 생성하면 검증 서비스가 시작되지 않습니다.

프로세스

  1. Validation Pod의 터미널에 연결합니다.

    $ oc rsh <validation_pod>
    Copy to Clipboard Toggle word wrap
  2. 공급자의 OPA 정책 디렉터리로 이동합니다.

    $ cd /usr/share/opa/policies/io/konveyor/forklift/<provider> 
    1
    Copy to Clipboard Toggle word wrap
    1
    vmware 또는 ovirt 를 지정합니다.
  3. 기본 정책을 검색합니다.

    $ grep -R "default" *
    Copy to Clipboard Toggle word wrap

7.2.3. 검증 규칙 생성

검증 서비스에 규칙이 포함된 구성 맵 CR(사용자 정의 리소스)을 적용하여 검증 규칙을 생성합니다.

중요
  • 기존 규칙과 동일한 이름으로 규칙을 만드는 경우 유효성 검사 서비스는 규칙을 사용하여 OR 작업을 수행합니다.
  • 기본 규칙과 일치하지 않는 규칙을 생성하면 검증 서비스가 시작되지 않습니다.

검증 규칙 예

검증 규칙은 공급자 인벤토리 서비스에서 수집한 VM(가상 머신) 속성을 기반으로 합니다.

예를 들어 VMware API는 이 경로를 사용하여 VMware VM에 NUMA 노드 유사성이 MOR: Cryostat.config.extraConfig["numa.nodeAffinity"] 가 구성되어 있는지 확인합니다.

공급자 인벤토리 서비스는 이 구성을 단순화하고 목록 값을 사용하여 테스트 가능한 속성을 반환합니다.

"numaNodeAffinity": [
    "0",
    "1"
],
Copy to Clipboard Toggle word wrap

이 속성을 기반으로 Rego 쿼리를 생성하고 forklift-validation-config 구성 맵에 추가합니다.

`count(input.numaNodeAffinity) != 0`
Copy to Clipboard Toggle word wrap

프로세스

  1. 다음 예에 따라 구성 맵 CR을 생성합니다.

    $ cat << EOF | oc apply -f -
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: <forklift-validation-config>
      namespace: openshift-mtv
    data:
      vmware_multiple_disks.rego: |-
        package <provider_package> 
    1
    
    
        has_multiple_disks { 
    2
    
          count(input.disks) > 1
        }
    
        concerns[flag] {
          has_multiple_disks 
    3
    
            flag := {
              "category": "<Information>", 
    4
    
              "label": "Multiple disks detected",
              "assessment": "Multiple disks detected on this VM."
            }
        }
    EOF
    Copy to Clipboard Toggle word wrap
    1
    공급자 패키지 이름을 지정합니다. 허용되는 값은 VMware의 경우 io.konveyor.forklift.vmware 및 Red Hat Virtualization의 경우 io.konveyor.forklift.ovirt 입니다.
    2
    concerns 이름 및 Rego 쿼리를 지정합니다.
    3
    concerns name 및 flag 매개변수 값을 지정합니다.
    4
    허용되는 값은 Critical,WarningInformation 입니다.
  2. forklift-controller 배포를 0 으로 스케일링하여 Validation Pod를 중지합니다.

    $ oc scale -n openshift-mtv --replicas=0 deployment/forklift-controller
    Copy to Clipboard Toggle word wrap
  3. forklift-controller 배포를 1 로 확장하여 Validation Pod를 시작합니다.

    $ oc scale -n openshift-mtv --replicas=1 deployment/forklift-controller
    Copy to Clipboard Toggle word wrap
  4. Validation Pod 로그를 확인하여 Pod가 시작되었는지 확인합니다.

    $ oc logs -f <validation_pod>
    Copy to Clipboard Toggle word wrap

    사용자 정의 규칙이 기본 규칙과 충돌하면 Validation Pod가 시작되지 않습니다.

  5. 소스 공급자를 제거합니다.

    $ oc delete provider <provider> -n openshift-mtv
    Copy to Clipboard Toggle word wrap
  6. 소스 공급자를 추가하여 새 규칙을 적용합니다.

    $ cat << EOF | oc apply -f -
    apiVersion: forklift.konveyor.io/v1beta1
    kind: Provider
    metadata:
      name: <provider>
      namespace: openshift-mtv
    spec:
      type: <provider_type> 
    1
    
      url: <api_end_point> 
    2
    
      secret:
        name: <secret> 
    3
    
        namespace: openshift-mtv
    EOF
    Copy to Clipboard Toggle word wrap
    1
    허용되는 값은 ovirt,vsphere, openstack 입니다.
    2
    API 엔드포인트 URL을 지정합니다(예: vSphere의 경우 https://<vCenter_host>/sdk, RHV의 경우 https://<engine_host>/ovirt-engine/api 또는 OpenStack의 경우 https://<identity_service>/v 3).
    3
    공급자 Secret CR의 이름을 지정합니다.

인벤토리 서비스에서 변경 사항을 감지하고 VM의 유효성을 검사하도록 사용자 지정 규칙을 생성한 후 규칙 버전을 업데이트해야 합니다.

7.2.4. 인벤토리 규칙 버전 업데이트

공급자 인벤토리 서비스에서 변경 사항을 감지하고 검증 서비스를 트리거하도록 규칙을 업데이트할 때마다 인벤토리 규칙 버전을 업데이트해야 합니다.

규칙 버전은 각 공급자에 대한 rules_version.rego 파일에 기록됩니다.

프로세스

  1. 현재 규칙 버전을 검색합니다.

    $ GET https://forklift-validation/v1/data/io/konveyor/forklift/<provider>/rules_version 
    1
    Copy to Clipboard Toggle word wrap

    출력 예

    {
       "result": {
           "rules_version": 5
       }
    }
    Copy to Clipboard Toggle word wrap

  2. Validation Pod의 터미널에 연결합니다.

    $ oc rsh <validation_pod>
    Copy to Clipboard Toggle word wrap
  3. /usr/share/opa/policies/io/konveyor/forklift/<provider>/rules_version.rego 파일에서 규칙 버전을 업데이트합니다.
  4. Validation Pod 터미널에서 로그아웃합니다.
  5. 업데이트된 규칙 버전을 확인합니다.

    $ GET https://forklift-validation/v1/data/io/konveyor/forklift/<provider>/rules_version 
    1
    Copy to Clipboard Toggle word wrap

    출력 예

    {
       "result": {
           "rules_version": 6
       }
    }
    Copy to Clipboard Toggle word wrap

7.2.5. 인벤토리 서비스 JSON 검색

인벤토리 서비스 쿼리를 VM(가상 머신 )으로 전송하여 인벤토리 서비스 JSON을 검색합니다. 출력에는 유효성 검사 서비스 규칙에 의해 쿼리되는 인벤토리 속성이 포함된 "입력" 키가 포함되어 있습니다.

"입력" 키의 모든 속성을 기반으로 검증 규칙을 생성할 수 있습니다(예: input.snapshot.kind ).

프로세스

  1. 프로젝트의 경로를 검색합니다.

    oc get route -n openshift-mtv
    Copy to Clipboard Toggle word wrap
  2. 인벤토리 서비스 경로를 검색합니다.

    $ oc get route <inventory_service> -n openshift-mtv
    Copy to Clipboard Toggle word wrap
  3. 액세스 토큰을 검색합니다.

    $ TOKEN=$(oc whoami -t)
    Copy to Clipboard Toggle word wrap
  4. HTTP GET 요청을 트리거합니다(예: Curl 사용).

    $ curl -H "Authorization: Bearer $TOKEN" https://<inventory_service_route>/providers -k
    Copy to Clipboard Toggle word wrap
  5. 공급자의 UUID 를 검색합니다.

    $ curl -H "Authorization: Bearer $TOKEN"  https://<inventory_service_route>/providers/<provider> -k 
    1
    Copy to Clipboard Toggle word wrap
    1 1 1
    공급자에 허용되는 값은 vsphere,ovirt, openstack 입니다.
  6. 공급자의 VM을 검색합니다.

    $ curl -H "Authorization: Bearer $TOKEN"  https://<inventory_service_route>/providers/<provider>/<UUID>/vms -k
    Copy to Clipboard Toggle word wrap
  7. VM의 세부 정보를 검색합니다.

    $ curl -H "Authorization: Bearer $TOKEN"  https://<inventory_service_route>/providers/<provider>/<UUID>/workloads/<vm> -k
    Copy to Clipboard Toggle word wrap

    출력 예

    {
        "input": {
            "selfLink": "providers/vsphere/c872d364-d62b-46f0-bd42-16799f40324e/workloads/vm-431",
            "id": "vm-431",
            "parent": {
                "kind": "Folder",
                "id": "group-v22"
            },
            "revision": 1,
            "name": "iscsi-target",
            "revisionValidated": 1,
            "isTemplate": false,
            "networks": [
                {
                    "kind": "Network",
                    "id": "network-31"
                },
                {
                    "kind": "Network",
                    "id": "network-33"
                }
            ],
            "disks": [
                {
                    "key": 2000,
                    "file": "[iSCSI_Datastore] iscsi-target/iscsi-target-000001.vmdk",
                    "datastore": {
                        "kind": "Datastore",
                        "id": "datastore-63"
                    },
                    "capacity": 17179869184,
                    "shared": false,
                    "rdm": false
                },
                {
                    "key": 2001,
                    "file": "[iSCSI_Datastore] iscsi-target/iscsi-target_1-000001.vmdk",
                    "datastore": {
                        "kind": "Datastore",
                        "id": "datastore-63"
                    },
                    "capacity": 10737418240,
                    "shared": false,
                    "rdm": false
                }
            ],
            "concerns": [],
            "policyVersion": 5,
            "uuid": "42256329-8c3a-2a82-54fd-01d845a8bf49",
            "firmware": "bios",
            "powerState": "poweredOn",
            "connectionState": "connected",
            "snapshot": {
                "kind": "VirtualMachineSnapshot",
                "id": "snapshot-3034"
            },
            "changeTrackingEnabled": false,
            "cpuAffinity": [
                0,
                2
            ],
            "cpuHotAddEnabled": true,
            "cpuHotRemoveEnabled": false,
            "memoryHotAddEnabled": false,
            "faultToleranceEnabled": false,
            "cpuCount": 2,
            "coresPerSocket": 1,
            "memoryMB": 2048,
            "guestName": "Red Hat Enterprise Linux 7 (64-bit)",
            "balloonedMemory": 0,
            "ipAddress": "10.19.2.96",
            "storageUsed": 30436770129,
            "numaNodeAffinity": [
                "0",
                "1"
            ],
            "devices": [
                {
                    "kind": "RealUSBController"
                }
            ],
            "host": {
                "id": "host-29",
                "parent": {
                    "kind": "Cluster",
                    "id": "domain-c26"
                },
                "revision": 1,
                "name": "IP address or host name of the vCenter host or RHV Engine host",
                "selfLink": "providers/vsphere/c872d364-d62b-46f0-bd42-16799f40324e/hosts/host-29",
                "status": "green",
                "inMaintenance": false,
                "managementServerIp": "10.19.2.96",
                "thumbprint": <thumbprint>,
                "timezone": "UTC",
                "cpuSockets": 2,
                "cpuCores": 16,
                "productName": "VMware ESXi",
                "productVersion": "6.5.0",
                "networking": {
                    "pNICs": [
                        {
                            "key": "key-vim.host.PhysicalNic-vmnic0",
                            "linkSpeed": 10000
                        },
                        {
                            "key": "key-vim.host.PhysicalNic-vmnic1",
                            "linkSpeed": 10000
                        },
                        {
                            "key": "key-vim.host.PhysicalNic-vmnic2",
                            "linkSpeed": 10000
                        },
                        {
                            "key": "key-vim.host.PhysicalNic-vmnic3",
                            "linkSpeed": 10000
                        }
                    ],
                    "vNICs": [
                        {
                            "key": "key-vim.host.VirtualNic-vmk2",
                            "portGroup": "VM_Migration",
                            "dPortGroup": "",
                            "ipAddress": "192.168.79.13",
                            "subnetMask": "255.255.255.0",
                            "mtu": 9000
                        },
                        {
                            "key": "key-vim.host.VirtualNic-vmk0",
                            "portGroup": "Management Network",
                            "dPortGroup": "",
                            "ipAddress": "10.19.2.13",
                            "subnetMask": "255.255.255.128",
                            "mtu": 1500
                        },
                        {
                            "key": "key-vim.host.VirtualNic-vmk1",
                            "portGroup": "Storage Network",
                            "dPortGroup": "",
                            "ipAddress": "172.31.2.13",
                            "subnetMask": "255.255.0.0",
                            "mtu": 1500
                        },
                        {
                            "key": "key-vim.host.VirtualNic-vmk3",
                            "portGroup": "",
                            "dPortGroup": "dvportgroup-48",
                            "ipAddress": "192.168.61.13",
                            "subnetMask": "255.255.255.0",
                            "mtu": 1500
                        },
                        {
                            "key": "key-vim.host.VirtualNic-vmk4",
                            "portGroup": "VM_DHCP_Network",
                            "dPortGroup": "",
                            "ipAddress": "10.19.2.231",
                            "subnetMask": "255.255.255.128",
                            "mtu": 1500
                        }
                    ],
                    "portGroups": [
                        {
                            "key": "key-vim.host.PortGroup-VM Network",
                            "name": "VM Network",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch0"
                        },
                        {
                            "key": "key-vim.host.PortGroup-Management Network",
                            "name": "Management Network",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch0"
                        },
                        {
                            "key": "key-vim.host.PortGroup-VM_10G_Network",
                            "name": "VM_10G_Network",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch1"
                        },
                        {
                            "key": "key-vim.host.PortGroup-VM_Storage",
                            "name": "VM_Storage",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch1"
                        },
                        {
                            "key": "key-vim.host.PortGroup-VM_DHCP_Network",
                            "name": "VM_DHCP_Network",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch1"
                        },
                        {
                            "key": "key-vim.host.PortGroup-Storage Network",
                            "name": "Storage Network",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch1"
                        },
                        {
                            "key": "key-vim.host.PortGroup-VM_Isolated_67",
                            "name": "VM_Isolated_67",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch2"
                        },
                        {
                            "key": "key-vim.host.PortGroup-VM_Migration",
                            "name": "VM_Migration",
                            "vSwitch": "key-vim.host.VirtualSwitch-vSwitch2"
                        }
                    ],
                    "switches": [
                        {
                            "key": "key-vim.host.VirtualSwitch-vSwitch0",
                            "name": "vSwitch0",
                            "portGroups": [
                                "key-vim.host.PortGroup-VM Network",
                                "key-vim.host.PortGroup-Management Network"
                            ],
                            "pNICs": [
                                "key-vim.host.PhysicalNic-vmnic4"
                            ]
                        },
                        {
                            "key": "key-vim.host.VirtualSwitch-vSwitch1",
                            "name": "vSwitch1",
                            "portGroups": [
                                "key-vim.host.PortGroup-VM_10G_Network",
                                "key-vim.host.PortGroup-VM_Storage",
                                "key-vim.host.PortGroup-VM_DHCP_Network",
                                "key-vim.host.PortGroup-Storage Network"
                            ],
                            "pNICs": [
                                "key-vim.host.PhysicalNic-vmnic2",
                                "key-vim.host.PhysicalNic-vmnic0"
                            ]
                        },
                        {
                            "key": "key-vim.host.VirtualSwitch-vSwitch2",
                            "name": "vSwitch2",
                            "portGroups": [
                                "key-vim.host.PortGroup-VM_Isolated_67",
                                "key-vim.host.PortGroup-VM_Migration"
                            ],
                            "pNICs": [
                                "key-vim.host.PhysicalNic-vmnic3",
                                "key-vim.host.PhysicalNic-vmnic1"
                            ]
                        }
                    ]
                },
                "networks": [
                    {
                        "kind": "Network",
                        "id": "network-31"
                    },
                    {
                        "kind": "Network",
                        "id": "network-34"
                    },
                    {
                        "kind": "Network",
                        "id": "network-57"
                    },
                    {
                        "kind": "Network",
                        "id": "network-33"
                    },
                    {
                        "kind": "Network",
                        "id": "dvportgroup-47"
                    }
                ],
                "datastores": [
                    {
                        "kind": "Datastore",
                        "id": "datastore-35"
                    },
                    {
                        "kind": "Datastore",
                        "id": "datastore-63"
                    }
                ],
                "vms": null,
                "networkAdapters": [],
                "cluster": {
                    "id": "domain-c26",
                    "parent": {
                        "kind": "Folder",
                        "id": "group-h23"
                    },
                    "revision": 1,
                    "name": "mycluster",
                    "selfLink": "providers/vsphere/c872d364-d62b-46f0-bd42-16799f40324e/clusters/domain-c26",
                    "folder": "group-h23",
                    "networks": [
                        {
                            "kind": "Network",
                            "id": "network-31"
                        },
                        {
                            "kind": "Network",
                            "id": "network-34"
                        },
                        {
                            "kind": "Network",
                            "id": "network-57"
                        },
                        {
                            "kind": "Network",
                            "id": "network-33"
                        },
                        {
                            "kind": "Network",
                            "id": "dvportgroup-47"
                        }
                    ],
                    "datastores": [
                        {
                            "kind": "Datastore",
                            "id": "datastore-35"
                        },
                        {
                            "kind": "Datastore",
                            "id": "datastore-63"
                        }
                    ],
                    "hosts": [
                        {
                            "kind": "Host",
                            "id": "host-44"
                        },
                        {
                            "kind": "Host",
                            "id": "host-29"
                        }
                    ],
                    "dasEnabled": false,
                    "dasVms": [],
                    "drsEnabled": true,
                    "drsBehavior": "fullyAutomated",
                    "drsVms": [],
                    "datacenter": null
                }
            }
        }
    }
    Copy to Clipboard Toggle word wrap

맨 위로 이동
Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다. 최신 업데이트를 확인하세요.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

Theme

© 2026 Red Hat