//Module included in the following assemblies
//
//post_installation_configuration/multiarch-tuning-operator.adoc

:_mod-docs-content-type: CONCEPT
[id="multi-architecture-creating-podplacement-config_{context}"]
= Creating the ClusterPodPlacementConfig object

After installing the Multiarch Tuning Operator, you must create a `ClusterPodPlacementConfig` object. This object instructs the operator to deploy its operand, which enables architecture-aware workload scheduling across your cluster.

The `ClusterPodPlacementConfig` object supports two optional plugins:

* The **node affinity scoring** plugin patches pods to set soft preferences, using weighted affinities, for the architectures specified by the user. Pods are more likely to be scheduled on nodes running architectures with higher weights.
* The **exec format error monitor** plugin detects `ENOEXEC` errors, which occur when a pod attempts to execute a binary incompatible with the node's architecture. When enabled, this plugin generates events in the affected pod's event stream. It triggers a `ExecFormatErrorsDetected` Prometheus alert if one or more `ENOEXEC` errors are detected within the last six hours. These errors can result from incorrect architecture node selectors, invalid image metadata that affects architecture-aware workload scheduling, an incorrect binary in an image, or an incompatible binary injected at runtime.

[NOTE]
====
You can create only one instance of the `ClusterPodPlacementConfig` object.
====

.Example `ClusterPodPlacementConfig` object configuration
[source,yaml]
----
apiVersion: multiarch.openshift.io/v1beta1
kind: ClusterPodPlacementConfig
metadata:
  name: cluster <1>
spec:
  logVerbosityLevel: Normal <2>
  namespaceSelector: <3>
    matchExpressions:
      - key: multiarch.openshift.io/exclude-pod-placement
        operator: DoesNotExist
  plugins: <4>
    nodeAffinityScoring: <5>
      enabled: true <6>
      platforms: <7>
        - architecture: amd64 <8>
          weight: 100 <9>
        - architecture: arm64
          weight: 50
    execFormatErrorMonitor:
      enabled: true <10>
----
<1> You must set this field value to `cluster`.
<2> Optional: You can set the field value to `Normal`, `Debug`, `Trace`, or `TraceAll`. The value is set to `Normal` by default.
<3> Optional: You can configure the `namespaceSelector` to select the namespaces in which the Multiarch Tuning Operator's pod placement operand must process the `nodeAffinity` of the pods. All namespaces are considered by default.
<4> Optional: Includes a list of plugins for architecture-aware workload scheduling.
<5> Optional: You can use this plugin to set architecture preferences for pod placement. When enabled, the scheduler first filters out nodes that do not meet the pod's requirements. Then, it prioritizes the remaining nodes based on the architecture scores defined in the `nodeAffinityScoring.platforms` field.
<6> Optional: Set this field to `true` to enable the `nodeAffinityScoring` plugin. The default value is `false`.
<7> Optional: Defines a list of architectures and their corresponding scores.
<8> Specify the node architecture to score. The scheduler prioritizes nodes for pod placement based on the architecture scores that you set and the scheduling requirements defined in the pod specification. Accepted values are `arm64`, `amd64`, `ppc64le`, or `s390x`.
<9> Assign a score to the architecture. The value for this field must be configured in the range of `1` (lowest priority) to `100` (highest priority). The scheduler uses this score to prioritize nodes for pod placement, favoring nodes with architectures that have higher scores.
<10> Optional: Set this field to `true` to enable the `execFormatErrorMonitor` plugin. When enabled, the plugin detects `ENOEXEC` errors, caused when a pod executes a binary incompatible with the node's architecture. The plugin generates events in the affected pods, and triggers the `ExecFormatErrorsDetected` Prometheus alert if one or more errors are found in the last six hours.

In this example, the `operator` field value is set to `DoesNotExist`. Therefore, if the `key` field value (`multiarch.openshift.io/exclude-pod-placement`) is set as a label in a namespace, the operand does not process the `nodeAffinity` of the pods in that namespace. Instead, the operand processes the `nodeAffinity` of the pods in namespaces that do not contain the label.

If you want the operand to process the `nodeAffinity` of the pods only in specific namespaces, you can configure the `namespaceSelector` as follows:
[source,yaml]
----
namespaceSelector:
  matchExpressions:
    - key: multiarch.openshift.io/include-pod-placement
      operator: Exists
----

In this example, the `operator` field value is set to `Exists`. Therefore, the operand processes the `nodeAffinity` of the pods only in namespaces that contain the `multiarch.openshift.io/include-pod-placement` label.

[IMPORTANT]
====
This Operator excludes pods in namespaces starting with `kube-`. It also excludes pods that are expected to be scheduled on control plane nodes.
====