../_images/kup6s-icon-howto.svg

Schedule pods to specific nodes

This guide shows you how to control where Plone backend, frontend, and Varnish pods run. Use nodeSelector to require specific node labels and tolerations to schedule onto tainted nodes.

Prerequisites

  • A working Plone deployment using cdk8s-plone.

  • Cluster labels and taints already configured on the target nodes.

    kubectl get nodes --show-labels
    kubectl describe node <node> | grep Taints
    

Constrain pods to labeled nodes

Add nodeSelector to backend, frontend, or both. Every label in the selector must match for a node to be considered.

import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';

new Plone(chart, 'plone', {
  variant: PloneVariant.VOLTO,
  backend: {
    image: 'plone/plone-backend:6.1.3',
    nodeSelector: {
      'topology.kubernetes.io/region': 'fsn1',
      'workload': 'plone',
    },
  },
  frontend: {
    image: 'plone/plone-frontend:16.0.0',
    nodeSelector: {
      'workload': 'plone',
    },
  },
});

Schedule the cache onto the same nodes

PloneVinylCache exposes the same nodeSelector option.

import { PloneVinylCache } from '@bluedynamics/cdk8s-plone';

new PloneVinylCache(chart, 'cache', {
  plone: ploneInstance,
  nodeSelector: {
    'workload': 'plone',
  },
});

PloneHttpcache schedules through the underlying mittwald Helm chart and does not expose a nodeSelector option directly. Use cluster-level affinity rules or taints when you need to constrain those pods.

Tolerate tainted nodes

When nodes carry a taint, pods must declare a matching toleration before the scheduler places them there. Both cache constructs accept a tolerations list.

new PloneHttpcache(chart, 'cache', {
  plone: ploneInstance,
  tolerations: [
    {
      key: 'workload',
      operator: 'Equal',
      value: 'plone',
      effect: 'NoSchedule',
    },
  ],
});
new PloneVinylCache(chart, 'cache', {
  plone: ploneInstance,
  tolerations: [
    {
      key: 'workload',
      operator: 'Equal',
      value: 'plone',
      effect: 'NoSchedule',
    },
  ],
});

operator: 'Exists' matches any value for that key. Omit effect to tolerate every effect for the matching taint.

Combine selector and toleration

Selectors and tolerations work together: the selector narrows the candidate nodes, and the toleration unblocks the scheduler when those nodes are tainted.

new PloneVinylCache(chart, 'cache', {
  plone: ploneInstance,
  nodeSelector: {
    'workload': 'plone',
  },
  tolerations: [
    { key: 'workload', operator: 'Equal', value: 'plone', effect: 'NoSchedule' },
  ],
});

Verify the rollout

cdk8s synth
kubectl apply -f dist/

# Confirm pods landed on the expected nodes
kubectl get pods -n <namespace> -o wide

A pod stuck in Pending with 0/N nodes are available: ... node(s) had untolerated taint means a taint is not tolerated. 0/N nodes are available: ... node(s) didn't match Pod's node affinity/selector means the nodeSelector does not match any node.

See also