Example 6-4. Pod with node affinity apiVersion : v1 kind : Pod metadata : name : random-generator spec : affinity : nodeAffinity : requiredDuringSchedulingIgnoredDuringExecution : nodeSelectorTerms : -  matchExpressions : -  key : numberCores operator : Gt values : [ "3" ] preferredDuringSchedulingIgnoredDuringExecution : -  weight : 1 preference : matchFields : -  key : metadata.name operator : NotIn values : [ "master" ] containers : -  image : k8spatterns/random-generator:1.0 name : random-generator Hard requirement that the node must have more than three cores (indicated by a node label) to be considered in the scheduling process. The rule is not reevalu‐ ated during execution if the conditions on the node change. Match on labels. Soft requirements, which is a list of selectors with weights. For every node, the sum of all weights for matching selectors is calculated, and the highest-valued node is chosen, as long as it matches the hard requirement. Match on a field (specified as jsonpath). Note that only  In  and  NotIn  are allowed as operators, and only one value is allowed to be given in the list of values. Node affinity is a more powerful way of scheduling and should be preferred when nodeSelector  is not enough. This mechanism allows constraining which nodes a Pod can run based on label or field matching. It doesn’t allow expressing dependencies among Pods to dictate where a Pod should be placed relative to other Pods. To express how Pods should be spread to achieve high availability, or be packed and co- located together to improve latency, Pod affinity and antiaffinity can be used. 52  |  Chapter 6: Automated Placement Pod Affinity and Antiaffinity