// Module included in the following assemblies:
//
// * virt/post_installation_configuration/virt-node-placement-virt-components.adoc

:_mod-docs-content-type: REFERENCE
[id="virt-node-placement-rule-examples_{context}"]
= Node placement rule examples

ifndef::openshift-rosa,openshift-dedicated[]
You can specify node placement rules for a {VirtProductName} component by editing a `Subscription`, `HyperConverged`, or `HostPathProvisioner` object.
endif::openshift-rosa,openshift-dedicated[]
ifdef::openshift-rosa,openshift-dedicated[]
You can specify node placement rules for a {VirtProductName} component by editing a `HyperConverged` or `HostPathProvisioner` object.
endif::openshift-rosa,openshift-dedicated[]

ifndef::openshift-rosa,openshift-dedicated[]
[id="subscription-object-node-placement-rules_{context}"]
== Subscription object node placement rule examples

To specify the nodes where OLM deploys the {VirtProductName} Operators, edit the `Subscription` object during {VirtProductName} installation.

Currently, you cannot configure node placement rules for the `Subscription` object by using the web console.

The `Subscription` object does not support the `affinity` node pplacement rule.

.Example `Subscription` object with `nodeSelector` rule
[source,yaml,subs="attributes+"]
----
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: hco-operatorhub
  namespace: {CNVNamespace}
spec:
  source: {CNVSubscriptionSpecSource}
  sourceNamespace: openshift-marketplace
  name: {CNVSubscriptionSpecName}
  startingCSV: kubevirt-hyperconverged-operator.v{HCOVersion}
  channel: "stable"
  config:
    nodeSelector:
      example.io/example-infra-key: example-infra-value <1>
----
<1> OLM deploys the {VirtProductName} Operators on nodes labeled `example.io/example-infra-key = example-infra-value`.

.Example `Subscription` object with `tolerations` rule
[source,yaml,subs="attributes+"]
----
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: hco-operatorhub
  namespace: {CNVNamespace}
spec:
  source:  {CNVSubscriptionSpecSource}
  sourceNamespace: openshift-marketplace
  name: {CNVSubscriptionSpecName}
  startingCSV: kubevirt-hyperconverged-operator.v{HCOVersion}
  channel: "stable"
  config:
    tolerations:
    - key: "key"
      operator: "Equal"
      value: "virtualization" <1>
      effect: "NoSchedule"
----
<1> OLM deploys {VirtProductName} Operators on nodes labeled `key = virtualization:NoSchedule` taint. Only pods with the matching tolerations are scheduled on these nodes.
endif::openshift-rosa,openshift-dedicated[]

[id="hyperconverged-object-node-placement-rules_{context}"]
== HyperConverged object node placement rule example

To specify the nodes where {VirtProductName} deploys its components, you can edit the `nodePlacement` object in the HyperConverged custom resource (CR) file that you create during {VirtProductName} installation.

.Example `HyperConverged` object with `nodeSelector` rule
[source,yaml,subs="attributes+"]
----
apiVersion: hco.kubevirt.io/v1beta1
kind: HyperConverged
metadata:
  name: kubevirt-hyperconverged
  namespace: {CNVNamespace}
spec:
  infra:
    nodePlacement:
      nodeSelector:
        example.io/example-infra-key: example-infra-value <1>
  workloads:
    nodePlacement:
      nodeSelector:
        example.io/example-workloads-key: example-workloads-value <2>
----
<1> Infrastructure resources are placed on nodes labeled `example.io/example-infra-key = example-infra-value`.
<2> workloads are placed on nodes labeled `example.io/example-workloads-key = example-workloads-value`.

.Example `HyperConverged` object with `affinity` rule
[source,yaml,subs="attributes+"]
----
apiVersion: hco.kubevirt.io/v1beta1
kind: HyperConverged
metadata:
  name: kubevirt-hyperconverged
  namespace: {CNVNamespace}
spec:
  infra:
    nodePlacement:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: example.io/example-infra-key
                operator: In
                values:
                - example-infra-value <1>
  workloads:
    nodePlacement:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: example.io/example-workloads-key <2>
                operator: In
                values:
                - example-workloads-value
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: example.io/num-cpus
                operator: Gt
                values:
                - 8 <3>
----
<1> Infrastructure resources are placed on nodes labeled `example.io/example-infra-key = example-value`.
<2> workloads are placed on nodes labeled `example.io/example-workloads-key = example-workloads-value`.
<3> Nodes that have more than eight CPUs are preferred for workloads, but if they are not available, pods are still scheduled.

.Example `HyperConverged` object with `tolerations` rule
[source,yaml,subs="attributes+"]
----
apiVersion: hco.kubevirt.io/v1beta1
kind: HyperConverged
metadata:
  name: kubevirt-hyperconverged
  namespace: {CNVNamespace}
spec:
  workloads:
    nodePlacement:
      tolerations: <1>
      - key: "key"
        operator: "Equal"
        value: "virtualization"
        effect: "NoSchedule"
----
<1> Nodes reserved for {VirtProductName} components are labeled with the `key = virtualization:NoSchedule` taint. Only pods with matching tolerations are scheduled on reserved nodes.

[id="hostpathprovisioner-object-node-placement-rules_{context}"]
== HostPathProvisioner object node placement rule example

You can edit the `HostPathProvisioner` object directly or by using the web console.

[WARNING]
====
You must schedule the hostpath provisioner and the {VirtProductName} components on the same nodes. Otherwise, virtualization pods that use the hostpath provisioner cannot run. You cannot run virtual machines.
====

After you deploy a virtual machine (VM) with the hostpath provisioner (HPP) storage class, you can remove the hostpath provisioner pod from the same node by using the node selector. However, you must first revert that change, at least for that specific node, and wait for the pod to run before trying to delete the VM.

You can configure node placement rules by specifying `nodeSelector`, `affinity`, or `tolerations` for the `spec.workload` field of the `HostPathProvisioner` object that you create when you install the hostpath provisioner.

.Example `HostPathProvisioner` object with `nodeSelector` rule
[source,yaml]
----
apiVersion: hostpathprovisioner.kubevirt.io/v1beta1
kind: HostPathProvisioner
metadata:
  name: hostpath-provisioner
spec:
  imagePullPolicy: IfNotPresent
  pathConfig:
    path: "</path/to/backing/directory>"
    useNamingPrefix: false
  workload:
    nodeSelector:
      example.io/example-workloads-key: example-workloads-value <1>
----
<1> Workloads are placed on nodes labeled `example.io/example-workloads-key = example-workloads-value`.
