Juju does support both node and pod affinity - k8s constraint tags have been extended to support pod affinity as well as node affinity
Use the “pod.” or “anti-pod.” prefix for pod affinity and pod anti affinity. As with space constraints, use the “^” syntax for anti-affinity.
No prefix or “node.” is for node affinity
eg
juju deploy somecharm --constraints="tags=node.foo=a|b|c,^bar=d|e|f,^foo=g|h,pod.foo=1|2|3,^pod.bar=4|5|6,anti-pod.afoo=x|y|z,^anti-pod.abar=7|8|9"
kubectl get -o json statefulset.apps/somecharm | jq .spec.template.spec.affinity
{
"nodeAffinity": {
"requiredDuringSchedulingIgnoredDuringExecution": {
"nodeSelectorTerms": [
{
"matchExpressions": [
{
"key": "bar",
"operator": "NotIn",
"values": [
"d",
"e",
"f"
]
},
{
"key": "foo",
"operator": "NotIn",
"values": [
"g",
"h"
]
},
{
"key": "foo",
"operator": "In",
"values": [
"a",
"b",
"c"
]
}
]
}
]
}
},
"podAffinity": {
"requiredDuringSchedulingIgnoredDuringExecution": [
{
"labelSelector": {
"matchExpressions": [
{
"key": "bar",
"operator": "NotIn",
"values": [
"4",
"5",
"6"
]
},
{
"key": "foo",
"operator": "In",
"values": [
"1",
"2",
"3"
]
}
]
},
"topologyKey": ""
}
]
},
"podAntiAffinity": {
"requiredDuringSchedulingIgnoredDuringExecution": [
{
"labelSelector": {
"matchExpressions": [
{
"key": "abar",
"operator": "NotIn",
"values": [
"7",
"8",
"9"
]
},
{
"key": "afoo",
"operator": "In",
"values": [
"x",
"y",
"z"
]
}
]
},
"topologyKey": ""
}
]
}
}