From bc859873d6cdc3ea662ef543139abc0873a20685 Mon Sep 17 00:00:00 2001 From: HermioneKT Date: Sun, 31 Mar 2024 20:07:12 +0800 Subject: [PATCH] add power manager Signed-off-by: HermioneKT --- CHANGELOG.md | 1 + docs/power_manager.md | 26 +++++++++++ go.work | 1 + go.work.sum | 1 + power_manager/go.mod | 3 ++ power_manager/util.go | 35 ++++++++++++++ scripts/power_manager/power_config.yaml | 12 +++++ scripts/power_manager/setup_power_manager.sh | 49 ++++++++++++++++++++ scripts/power_manager/shared-profile.yaml | 11 +++++ scripts/power_manager/shared-workload.yaml | 13 ++++++ 10 files changed, 152 insertions(+) create mode 100644 docs/power_manager.md create mode 100644 power_manager/go.mod create mode 100644 power_manager/util.go create mode 100644 scripts/power_manager/power_config.yaml create mode 100644 scripts/power_manager/setup_power_manager.sh create mode 100644 scripts/power_manager/shared-profile.yaml create mode 100644 scripts/power_manager/shared-workload.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a6bbb842..b1c363b37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added - Added support for [`OpenYurt`](https://openyurt.io/), an open platform that extends upstream Kubernetes to run on edge node pools. More details on how to the `Knative-atop-OpenYurt` mode are described [here](scripts/openyurt-deployer/README.md). +- Added support for [`K8 Power Manager`](https://networkbuilders.intel.com/solutionslibrary/power-manager-a-kubernetes-power-operator-technology-guide), a Kubernetes operator designed to manage and optimize power consumption in a Kubernetes cluster. More details are described [here](docs/power_manager.md). ### Changed diff --git a/docs/power_manager.md b/docs/power_manager.md new file mode 100644 index 000000000..7cd576334 --- /dev/null +++ b/docs/power_manager.md @@ -0,0 +1,26 @@ +# K8s Power Manager + +## Components +1. **Power Manager Controller**: ensures the actual state matches the desired state of the cluster. +2. **Power Config Controller**: sees the power config created by user and deploys Power Node Agents onto each node specified using a daemon set. + - power node selector: A key/value map used to define a list of node labels that a node must satisfy for the operator's node + agent to be deployed. + - power profiles: The list of power profiles that the user wants available on the nodes +3. **Power Node Agent**: containerized applications used to communicate with the node's Kubelet pod resources endpoint to discover the exact CPUs that + are allocated per container and tune frequency of the cores as requested + +4. **Power Profile**: predefined configuration that specifies how the system should manage power consumption for various components such as CPUs. It includes settings applied to host level such as CPU frequency, governor etc. + +4. **Power Workload**: the object used to define the lists of CPUs configured with a particular Power Profile. A power workload is created for each Power Profile on each Node with the Power Node Agent deployed. A power workload is represented in the Intel Power Optimization Library by a Pool. The Pools hold the values of the Power Profile used, their frequencies, and the CPUs that need to be configured. The creation of the Pool – and any additions to the Pool – then +carries out the changes. + +## Setup +Execute the following below **as a non-root user with sudo rights** using **bash**: +1. Follow [a quick-start guide](quickstart_guide.md) to set up a Knative cluster. +2. On master node, export NODE_NAME to your node name and run K8s power manager set up script: + ```bash + export NODE_NAME= *Name of the node you want to apply shared profile on* + ./scripts/power_manager/setup_power_manager.sh; + ``` + + This will install and configure the Kubernetes Power Manager for managing power consumption in a Kubernetes cluster. It clones the Power Manager repository, sets up the necessary namespace, service account, and Role-based Access Control rule, then generates and installs custom resource definitions, and deploys the Power Manager controller. It also applies a Power config to manage the power node agents, a shared profile for specifying CPU frequencies, and a shared workload for applying the CPU tuning settings. diff --git a/go.work b/go.work index ff129870a..cc41a9ca3 100644 --- a/go.work +++ b/go.work @@ -5,4 +5,5 @@ use ( ./scripts ./scripts/github_runner ./scripts/openyurt-deployer + ./power_manager ) diff --git a/go.work.sum b/go.work.sum index fc4d814c5..a3fb93b8c 100644 --- a/go.work.sum +++ b/go.work.sum @@ -76,6 +76,7 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= diff --git a/power_manager/go.mod b/power_manager/go.mod new file mode 100644 index 000000000..e7c1237ab --- /dev/null +++ b/power_manager/go.mod @@ -0,0 +1,3 @@ +module github.com/vhive-serverless/vhive/power_manager + +go 1.21 diff --git a/power_manager/util.go b/power_manager/util.go new file mode 100644 index 000000000..b4e803e44 --- /dev/null +++ b/power_manager/util.go @@ -0,0 +1,35 @@ +package power_manager + +import ( + "fmt" + "os/exec" +) + +func SetPowerProfileToNode(powerprofileName string, nodeName string, minFreq int64, maxFreq int64) error { + // powerConfig + command := fmt.Sprintf("kubectl apply -f - < create the power-node-agent DaemonSet that manages the Power Node Agent pods. +kubectl apply -f $HOME/vhive/scripts/power_manager/power_config.yaml + +# Apply Profile. U can modify the spec in the shared-profile.yaml file +kubectl apply -f $HOME/vhive/scripts/power_manager/shared-profile.yaml + +# Apply the shared PowerWorkload. All CPUs (except reservedCPUs specified in this yaml file) will be tuned to the specified frequency in shared-profile.yaml +envsubst < $HOME/vhive/scripts/power_manager/shared-workload.yaml | kubectl apply -f - + +kubectl get powerprofiles -n intel-power +kubectl get powerworkloads -n intel-power \ No newline at end of file diff --git a/scripts/power_manager/shared-profile.yaml b/scripts/power_manager/shared-profile.yaml new file mode 100644 index 000000000..8f161649a --- /dev/null +++ b/scripts/power_manager/shared-profile.yaml @@ -0,0 +1,11 @@ +apiVersion: power.intel.com/v1 +kind: PowerProfile +metadata: + name: performance + namespace: intel-power +spec: + name: "performance" + max: 1200 + min: 1200 + shared: true + governor: "performance" \ No newline at end of file diff --git a/scripts/power_manager/shared-workload.yaml b/scripts/power_manager/shared-workload.yaml new file mode 100644 index 000000000..a86d33576 --- /dev/null +++ b/scripts/power_manager/shared-workload.yaml @@ -0,0 +1,13 @@ +apiVersion: "power.intel.com/v1" +kind: PowerWorkload +metadata: + name: performance-$NODE_NAME-workload + namespace: intel-power +spec: + name: "performance-$NODE_NAME-workload" + allCores: true + powerNodeSelector: + # The label must be as below, as this workload will be specific to the Node + kubernetes.io/hostname: $NODE_NAME + # Replace this value with the intended shared PowerProfile + powerProfile: "performance" \ No newline at end of file