3.2 Time-slice a node¶
Time-slicing is configured in two places: a ConfigMap that describes the sharing policy, and a node label that opts a node into it. The ClusterPolicy connects the two. Nothing changes on a node until it's labelled — which is exactly the control you want in a mixed fleet.
Step 1 — The sharing config¶
apiVersion: v1
kind: ConfigMap
metadata:
name: time-slicing-config
namespace: gpu-operator
data:
# The key name is what you reference from a node label:
# kubectl label node <node> nvidia.com/device-plugin.config=four-way
#
# Two keys on purpose. The device plugin's config manager has a "single"
# fallback: a ConfigMap with exactly ONE key is applied to every node,
# label or not. An explicit no-sharing config keeps unlabelled nodes
# exclusive and gives you a value to label them with if you want to be
# explicit.
exclusive: |-
version: v1
flags:
migStrategy: none
four-way: |-
version: v1
flags:
migStrategy: none
sharing:
timeSlicing:
# Keep the resource name nvidia.com/gpu. With true, the shared
# resource is advertised as nvidia.com/gpu.shared instead, which is
# a good production pattern (workloads opt in explicitly).
renameByDefault: false
# A pod asking for 2 "GPUs" on a time-sliced node would get 2 slices
# of the same GPU and think it has two devices. Fail loudly instead.
failRequestsGreaterThanOne: true
resources:
- name: nvidia.com/gpu
replicas: 4
replicas: 4 means the device plugin advertises four nvidia.com/gpu for every physical GPU. failRequestsGreaterThanOne: true rejects any pod asking for 2 on a sliced node — two slices of the same card is not two GPUs, and the pod would find that out the hard way.
Why two keys?
The device plugin's config manager has a single fallback: if the ConfigMap has exactly one key, it applies it to every node whether labelled or not. A ConfigMap with only four-way would slice your whole fleet the moment the Operator picked it up. The exclusive key exists so that unlabelled nodes stay exclusive.
Step 2 — Tell the Operator about it¶
kubectl patch clusterpolicies.nvidia.com/cluster-policy -n gpu-operator --type merge \
-p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config", "default": ""}}}}'
name points at the ConfigMap; default: "" plus the two-key ConfigMap means no sharing applies unless a node asks for it by label. (Setting default: four-way would slice every GPU node in the cluster — sometimes what you want, never by accident.)
The Operator now re-renders the device-plugin DaemonSet with a config-manager sidecar that watches node labels. You'll see the plugin pod restart once on your GPU node:
2/2 — the second container is the config manager. Press Ctrl+C.
The Operator does not watch the ConfigMap
Edit the ConfigMap later (say, replicas: 8) and nothing happens. The device plugin only re-reads its config when the label changes or the pod restarts. NVIDIA's docs say so explicitly. Treat sharing configs as immutable: make a new key (eight-way), then relabel.
Step 3 — Opt your node in¶
export NODE_A=$(kubectl get nodes -l karpenter.sh/nodepool=gpu -o jsonpath='{.items[0].metadata.name}')
echo "$NODE_A"
kubectl label node "$NODE_A" nvidia.com/device-plugin.config=four-way
The config manager sees the label, writes the four-way config into place and restarts the plugin container. Ten seconds later:
kubectl get node "$NODE_A" -o custom-columns='NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu,REPLICAS:.metadata.labels.nvidia\.com/gpu\.replicas,PRODUCT:.metadata.labels.nvidia\.com/gpu\.product,STRATEGY:.metadata.labels.nvidia\.com/gpu\.sharing-strategy'
Three things changed and all three are visible to the scheduler and to anyone reading labels:
nvidia.com/gpu: 4— one physical L4, four schedulable units.nvidia.com/gpu.product: NVIDIA-L4-SHARED— GFD appends-SHAREDso anodeSelectoron the unsliced product name will not match this node. That's your safety rail for latency-sensitive workloads: selectNVIDIA-L4and you can never land on a shared card by accident.nvidia.com/gpu.sharing-strategy: time-slicing— the explicit label if you'd rather select on that.
If the numbers didn't change after 30 seconds, kubectl -n gpu-operator logs -l app=nvidia-device-plugin-daemonset -c config-manager tells you why (usually a typo in the label value vs. the ConfigMap key).