6.2. 유효성 검사 서비스에 대한 사용자 정의 규칙 생성


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

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

6.2.1. Rego 파일 정보

검증 규칙은 Rego,OPA(Open Policy Agent) 네이티브 쿼리 언어로 작성됩니다. 규칙은 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

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

6.2.2. 기본 검증 규칙 확인

사용자 지정 규칙을 만들기 전에 유효성 검사 서비스의 기본 규칙을 확인하여 기존 기본값을 재정의하는 규칙을 만들지 않도록 해야 합니다.Before you create a custom rule, you must check the default rules of the Validation service to ensure that you do not create a rule that overriddens an existing default value.

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

절차

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

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

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

    $ grep -R "default" *
    Copy to Clipboard

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

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

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

절차

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

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

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

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

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

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

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

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

    출력 예

    {
        "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

6.2.4. 검증 규칙 생성

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

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

검증 규칙 예

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

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

Provider Inventory 서비스는 이 구성을 단순화하고 목록 값이 있는 테스트 가능한 특성을 반환합니다.

"numaNodeAffinity": [
    "0",
    "1"
],
Copy to Clipboard

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

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

절차

  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
    1
    공급자 패키지 이름을 지정합니다. Red Hat Virtualization의 경우 허용되는 값은 VMware의 경우 io.konveyor.forklift.vmwareio.konveyor.forklift.ovirt 입니다.
    2
    concerns name 및 Rego 쿼리를 지정합니다.
    3
    concerns 이름 및 플래그 매개변수 값을 지정합니다.
    4
    허용되는 값은 Critical,WarningInformation 입니다.
  2. forklift-controller 배포를 0 으로 스케일링하여 유효성 검사 Pod를 중지합니다.

    $ oc scale -n openshift-mtv --replicas=0 deployment/forklift-controller
    Copy to Clipboard
  3. forklift-controller 배포를 1 로 확장하여 유효성 검사 Pod를 시작합니다.

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

    $ oc logs -f <validation_pod>
    Copy to Clipboard

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

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

    $ oc delete provider <provider> -n openshift-mtv
    Copy to Clipboard
  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
    1
    허용되는 값은 ovirt,vsphere, openstack 입니다.
    2
    API 엔드 포인트 URL을 지정합니다(예: vSphere의 경우 https://<vCenter_host>/sdk, https://<engine_host>/ovirt-engine/api/api/ for RHV, 또는 OpenStack의 경우 https://<identity_service>/v3).
    3
    공급자 Secret CR의 이름을 지정합니다.

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

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

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

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

절차

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

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

    출력 예

    {
       "result": {
           "rules_version": 5
       }
    }
    Copy to Clipboard

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

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

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

    출력 예

    {
       "result": {
           "rules_version": 6
       }
    }
    Copy to Clipboard

맨 위로 이동
Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

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

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

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

Red Hat 소개

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

Theme

© 2025 Red Hat