Quickstart
This page is the fastest path to run Joulie. For conceptual context first, read Core Concepts.
Prerequisites
- Kubernetes cluster with worker nodes
- Node Feature Discovery (NFD) deployed
- Optional for real enforcement: nodes exposing writable power interfaces
- RAPL power limit files, or
- cpufreq sysfs interfaces
Install from release (recommended)
Install directly from OCI chart release:
helm upgrade --install joulie oci://registry.cern.ch/mbunino/joulie/joulie \
--version <version> \
-n joulie-system \
--create-namespace \
-f values/joulie.yaml
Label nodes managed by the operator
Important: Joulie will only target nodes with a specific label, and ignore all the others. By default, install does not auto-select nodes. Default expected selector value is:
joulie.io/managed=true(operator envNODE_SELECTOR)
So you must label target worker nodes, for example:
kubectl label node <node-a> joulie.io/managed=true --overwrite
kubectl label node <node-b> joulie.io/managed=true --overwrite
If this is missing, operator logs will show no eligible nodes matched selector.
By default, the agent DaemonSet uses the same selector scope (joulie.io/managed=true), so unlabeled nodes will not run agent pods.
Install from source (when developing)
If you changed source code, from repo root:
make build-push TAG=<tag>
make install TAG=<tag>
This pushes:
registry.cern.ch/mbunino/joulie/joulie-agent:<tag>registry.cern.ch/mbunino/joulie/joulie-operator:<tag>registry.cern.ch/mbunino/joulie/joulie-scheduler:<tag>
You can also do build+push+install in one command:
make build-push-install TAG=<tag>
Run make help to see all available targets (including rollout, uninstall, simulator-install, and more).
Install CRDs + components (source workflow)
If images for TAG are already in the registry (no source changes), run:
make install TAG=<tag>
This performs a Helm install/upgrade (charts/joulie) and sets both images to the requested tag.
Default values come from:
values/joulie.yaml
You can override with:
make install TAG=<tag> HELM_VALUES=<path-to-values.yaml>
Node selection behavior is the same as release install:
- operator expects
joulie.io/managed=trueby default - label target nodes before verifying reconciliation
Joulie will only target nodes with that specific label.
To remove Joulie components and CRD:
make uninstall
Update to a new image tag later
make rollout TAG=<new-tag>
Joulie operator and agents
Joulie control is a desired-state loop:
- agent discovers per-node hardware and publishes
NodeHardware, - operator resolves hardware/inventory and decides per-node target state,
- operator writes that desired state into
NodeTwin.spec, - node labels (
joulie.io/power-profile) expose current supply to the scheduler, - agent enforces node-local controls from desired state and telemetry/control profile.
Meaning of the key node labels:
joulie.io/managed=true- node is in Joulie operator scope (eligible for policy decisions)
joulie.io/power-profile=performance- node currently offers high-performance supply
joulie.io/power-profile=eco- node currently offers low-power supply (resources are throttled according to the selected policy)
Read the architecture path after this quickstart:
Architecture overview:

Central operator mode
The operator continuously writes NodeTwin.spec assignments from the active policy (for example static partition or queue-aware), mapping desired states to node profiles (performance/eco).
Configuration details:
- CRD and Policy Model
- Operator
- Optional runnable manifest walkthrough:
Verify:
kubectl get nodehardwares
kubectl get nodetwins
kubectl -n joulie-system logs deploy/joulie-operator --tail=100
kubectl -n joulie-system logs -l app.kubernetes.io/name=joulie-agent --tail=100
Look for:
NodeHardwareobjects appearing for managed nodes,- operator logs mentioning inventory-aware planning or desired-state assignment,
- agent logs containing desired-state source and enforcement/fallback actions.
Also verify installed images:
kubectl -n joulie-system get pods \
-o custom-columns=NAME:.metadata.name,IMAGE:.spec.containers[0].image,IMAGEID:.status.containerStatuses[0].imageID
If operator logs show no eligible nodes matched selector, verify node labels:
kubectl get nodes --show-labels | grep 'joulie.io/managed=true'
Workload and Power Simulator
The simulator has its own Helm chart, published alongside the main Joulie chart:
helm upgrade --install joulie-simulator oci://registry.cern.ch/mbunino/joulie/joulie-sim \
--version <version> \
-n joulie-sim-demo \
--create-namespace \
--set image.tag=<version>
Or from source: make simulator-install TAG=<version>
For fake-node workload + power simulation (real scheduler, fake KWOK nodes, real operator, agent pool mode), see:
- Simulator Overview
- Workload Simulator
- Power Simulator
- Hardware Modeling and Physical Power Model
- KWOK Simulator Example
kubectl plugin
The kubectl-joulie plugin adds kubectl joulie status for inspecting Joulie cluster energy state.
Install from release (Harbor/OCI)
Download the pre-built binary for your platform from the CERN OCI registry using ORAS:
# Pick your platform: linux-amd64, linux-arm64, darwin-amd64, darwin-arm64
PLATFORM="linux-amd64"
VERSION="<version>"
oras pull "registry.cern.ch/mbunino/joulie/kubectl-joulie:${VERSION}-${PLATFORM}"
chmod +x "kubectl-joulie-${PLATFORM}"
# User-local install (no sudo required, ensure ~/.local/bin is in your PATH)
install "kubectl-joulie-${PLATFORM}" ~/.local/bin/kubectl-joulie
# Or system-wide install (requires sudo)
sudo install "kubectl-joulie-${PLATFORM}" /usr/local/bin/kubectl-joulie
Alternatively, download from the GitHub release assets:
PLATFORM="linux-amd64"
VERSION="<version>"
curl -sLO "https://github.com/joulie-k8s/Joulie/releases/download/v${VERSION}/kubectl-joulie-${PLATFORM}"
chmod +x "kubectl-joulie-${PLATFORM}"
# User-local install (no sudo required, ensure ~/.local/bin is in your PATH)
install "kubectl-joulie-${PLATFORM}" ~/.local/bin/kubectl-joulie
# Or system-wide install (requires sudo)
sudo install "kubectl-joulie-${PLATFORM}" /usr/local/bin/kubectl-joulie
Install from source
make kubectl-plugin-install
Usage
kubectl joulie status # Show energy state of all Joulie-managed nodes
Next step
Continue with: