<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Architecture on Joulie</title><link>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/</link><description>Recent content in Architecture on Joulie</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/index.xml" rel="self" type="application/rss+xml"/><item><title>CRD and Policy Model</title><link>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/policy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/policy/</guid><description>&lt;h2 id="crd"&gt;CRD&lt;/h2&gt;
&lt;p&gt;The implemented APIs are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Group: &lt;code&gt;joulie.io&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Version: &lt;code&gt;v1alpha1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NodePowerProfile&lt;/code&gt; (&lt;code&gt;nodepowerprofiles&lt;/code&gt;, cluster-scoped) for operator-assigned per-node desired state&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TelemetryProfile&lt;/code&gt; (&lt;code&gt;telemetryprofiles&lt;/code&gt;, cluster-scoped) for telemetry source configuration (node + cluster scope)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CRD files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;config/crd/bases/joulie.io_nodepowerprofiles.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config/crd/bases/joulie.io_telemetryprofiles.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="conceptual-model-next-step"&gt;Conceptual model (next step)&lt;/h2&gt;
&lt;p&gt;Policy should be modeled as a cluster-wide mapping:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;input: cluster context at time &lt;code&gt;t&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;output: &lt;code&gt;node -&amp;gt; power state&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Minimal states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ActivePerformance&lt;/code&gt; (mapped to profile &lt;code&gt;performance&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ActiveEco&lt;/code&gt; (mapped to profile &lt;code&gt;eco&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Initial implementation should remain rule-based and deterministic.
Future implementations can be telemetry-driven or model-driven.&lt;/p&gt;</description></item><item><title>Input Telemetry and Actuation Interfaces</title><link>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/telemetry/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/telemetry/</guid><description>&lt;p&gt;This document defines Joulie&amp;rsquo;s &lt;strong&gt;internal input interfaces&lt;/strong&gt; for telemetry and control.&lt;/p&gt;
&lt;p&gt;Important distinction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;this is &lt;strong&gt;not&lt;/strong&gt; about Prometheus metrics exposed by Joulie,&lt;/li&gt;
&lt;li&gt;this is about how Joulie components &lt;strong&gt;consume input data&lt;/strong&gt; and &lt;strong&gt;apply controls&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="goals"&gt;Goals&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Run against real hardware in bare metal clusters.&lt;/li&gt;
&lt;li&gt;Run in virtual/simulated clusters (kind/kwok) with the same control logic.&lt;/li&gt;
&lt;li&gt;Keep APIs generic enough for CPU + GPU + future signals.&lt;/li&gt;
&lt;li&gt;Avoid policy/API churn when moving from rule-based to data-driven policies.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="core-model-simple"&gt;Core model (simple)&lt;/h2&gt;
&lt;p&gt;Joulie uses:&lt;/p&gt;</description></item><item><title>Metrics Reference</title><link>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/metrics/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/metrics/</guid><description>&lt;p&gt;Joulie agent exposes Prometheus metrics on &lt;code&gt;/metrics&lt;/code&gt; (default &lt;code&gt;:8080&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;This document is only for &lt;strong&gt;exported observability metrics&lt;/strong&gt;.
For &lt;strong&gt;input telemetry and control interfaces&lt;/strong&gt; (real hardware vs simulated HTTP), see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/telemetry/"&gt;Input Telemetry and Actuation Interfaces&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="endpoint"&gt;Endpoint&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Path: &lt;code&gt;/metrics&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Address: &lt;code&gt;METRICS_ADDR&lt;/code&gt; env var (default &lt;code&gt;:8080&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="backendpolicy"&gt;Backend/Policy&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;joulie_backend_mode{node,mode}&lt;/code&gt; (gauge)
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mode&lt;/code&gt; values: &lt;code&gt;none&lt;/code&gt;, &lt;code&gt;rapl&lt;/code&gt;, &lt;code&gt;dvfs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Active mode has value &lt;code&gt;1&lt;/code&gt;, others &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;joulie_policy_cap_watts{node,policy}&lt;/code&gt; (gauge)
&lt;ul&gt;
&lt;li&gt;Current selected policy cap in watts&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This metric can also be used to derive policy states in Grafana:&lt;/p&gt;</description></item><item><title>Operator Notes</title><link>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/operator/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/operator/</guid><description>&lt;h2 id="target-concept"&gt;Target concept&lt;/h2&gt;
&lt;p&gt;Joulie should evolve into a centralized operator that owns the global optimization loop.&lt;/p&gt;
&lt;p&gt;At each control step (for example every minute), the operator:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Reads cluster-wide context.&lt;/li&gt;
&lt;li&gt;Decides node-to-power-profile assignments.&lt;/li&gt;
&lt;li&gt;Writes desired per-node state.&lt;/li&gt;
&lt;li&gt;Monitors outcomes and re-plans.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;States start simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ActivePerformance&lt;/code&gt; (mapped to profile &lt;code&gt;performance&lt;/code&gt;): unconstrained / HPC-oriented.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ActiveEco&lt;/code&gt; (mapped to profile &lt;code&gt;eco&lt;/code&gt;): constrained / energy-saving.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="control-responsibility-boundary"&gt;Control responsibility boundary&lt;/h2&gt;
&lt;p&gt;Operator is the control-plane brain.
Agent is an actuator/telemetry component.&lt;/p&gt;</description></item><item><title>Policy Algorithms</title><link>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/policies/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://joulie-k8s.github.io/Joulie/versions/v0.0.2/docs/architecture/policies/</guid><description>&lt;p&gt;This page documents the controller policy algorithms implemented in &lt;code&gt;cmd/operator/main.go&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="classification-input"&gt;Classification Input&lt;/h2&gt;
&lt;p&gt;Policy demand classification is derived from pod scheduling constraints on &lt;code&gt;joulie.io/power-profile&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;performance-only&lt;/code&gt;: pod can run only on &lt;code&gt;performance&lt;/code&gt;/&lt;code&gt;draining-performance&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eco-only&lt;/code&gt;: pod can run only on &lt;code&gt;eco&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;general&lt;/code&gt; (implicit unconstrained): no explicit power-profile constraint, or both profiles allowed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unknown&lt;/code&gt;: unsupported/ambiguous constraint shape.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For safety, &lt;code&gt;unknown&lt;/code&gt; is treated as performance-sensitive in downgrade guards.&lt;/p&gt;
&lt;h2 id="shared-reconcile-flow"&gt;Shared Reconcile Flow&lt;/h2&gt;
&lt;p&gt;Each reconcile tick:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Select eligible nodes from &lt;code&gt;NODE_SELECTOR&lt;/code&gt;, excluding reserved and unschedulable nodes.&lt;/li&gt;
&lt;li&gt;Build a desired plan with the selected policy.&lt;/li&gt;
&lt;li&gt;Apply downgrade guard (can convert planned &lt;code&gt;eco&lt;/code&gt; to &lt;code&gt;draining-performance&lt;/code&gt;/&lt;code&gt;performance&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Write &lt;code&gt;NodePowerProfile&lt;/code&gt; and update node label &lt;code&gt;joulie.io/power-profile&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="static_partition"&gt;&lt;code&gt;static_partition&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Goal: deterministic fixed HP/LP split.&lt;/p&gt;</description></item></channel></rss>