You are looking for taints, and tolerations. In addition to a nodeSelector.
A taint is a way to mark a node. Such marks may be used to prevent workloads from being scheduled on your nodes. While tolerations may be defined on your workloads, to allow for exceptions.
You could taint your node with something like:
kubectl taint nodes worker1.example.com workload=reserved:NoSchedule
kubectl taint nodes workerN.example.com workload=reserved:NoSchedule
And have your special applications set the following, in their pod spec, which would bypass that taint:
spec:
containers:
- [...]
tolerations:
- key: workload
operator: Equal
value: reserved
effect: NoSchedule
And while this would ensure that no pod would get scheduled over there unless they have that taint: you would probably want to add some label to your nodes, and use a nodeSelector, ensuring your special pods may only start on your reserved nodes.
You would add a label with:
kubectl label node worker1.example.com workload=reserved
kubectl label node workerN.example.com workload=reserved
And add a nodeSelector to your pod definition:
spec:
containers:
- [...]
nodeSelector:
workload: reserved