Skip to content

Commit

Permalink
Carbon phase1 (#117)
Browse files Browse the repository at this point in the history
* static carbon intensity starting point

Signed-off-by: Scott Trent <[email protected]>

* base for carbon phase 1

Signed-off-by: Scott Trent <[email protected]>

* clean up. add carbon metric

Signed-off-by: Scott Trent <[email protected]>

* clean up phase 1

Signed-off-by: Scott Trent <[email protected]>

---------

Signed-off-by: Scott Trent <[email protected]>
  • Loading branch information
trent-s authored Aug 22, 2024
1 parent d60183f commit 1b94f07
Show file tree
Hide file tree
Showing 22 changed files with 265 additions and 95 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# SusQL Operator

SusQL is a Kubernetes operator that aggregates energy data from pods tagged with SusQL specific labels. The energy measurements are taken from [Kepler](https://sustainable-computing.io/) which should be installed/deployed in the cluster before using SusQL. Watch a video with a demonstration by clicking on the image bellow.
SusQL is a Kubernetes operator that aggregates energy and estimated carbon dioxide emission data for pods tagged with SusQL specific labels. The energy measurements are taken from [Kepler](https://sustainable-computing.io/) which should be installed/deployed in the cluster before using SusQL. Watch a video with a demonstration by clicking on the image bellow.

[![Watch the video](https://img.youtube.com/vi/NRVD7gJECfA/maxresdefault.jpg)](https://youtu.be/NRVD7gJECfA)

## Getting Started

SusQL is an operator that can be deployed in a Kubernetes/OpenShift cluster. You can use [kind](https://sigs.k8s.io/kind) or [minikube](https://minikube.sigs.k8s.io/) to get a local cluster for testing, or run against a remote cluster.

## Carbon Dioxide Emission Calculation

CO2 emission calculation is currently a work in progress. At the moment we use
a static conversion factor based on
[US EPA](https://www.epa.gov/energy/greenhouse-gases-equivalencies-calculator-calculations-and-references)
data. Although users can configure this value to match their runtime environment, we are working on providing
automatic up to date conversion functionality.

### Prerequisites

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.22
0.0.23
3 changes: 3 additions & 0 deletions api/v1/labelgroup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ type LabelGroupStatus struct {
// TotalEnergy keeps track of the accumulated energy over time
TotalEnergy string `json:"totalEnergy,omitempty"`

// TotalCarbon keeps track of the accumulated grams of carbon dioxide emission over time
TotalCarbon string `json:"totalCarbon,omitempty"`

// Prometheus query to get the total energy for this label group
SusQLPrometheusQuery string `json:"susqlPrometheusQuery,omitempty"`

Expand Down
2 changes: 1 addition & 1 deletion bundle.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/
LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/
LABEL operators.operatorframework.io.bundle.package.v1=susql-operator
LABEL operators.operatorframework.io.bundle.channels.v1=alpha
LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.34.1
LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.36.1
LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1
LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v4

Expand Down
94 changes: 65 additions & 29 deletions bundle/manifests/susql-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ metadata:
]
capabilities: Basic Install
categories: Monitoring
containerImage: quay.io/sustainable_computing_io/susql_operator:0.0.22
createdAt: "2024-07-09T05:01:04Z"
description: 'Aggregates energy data from pods tagged with SusQL labels '
operators.operatorframework.io/builder: operator-sdk-v1.34.1
containerImage: quay.io/sustainable_computing_io/susql_operator:0.0.23
createdAt: "2024-08-22T02:22:46Z"
description: 'Aggregates energy and CO2 emission data for pods tagged with SusQL
labels '
operators.operatorframework.io/builder: operator-sdk-v1.36.1
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
repository: https://github.com/sustainable-computing-io/susql-operator
support: https://github.com/sustainable-computing-io/susql-operator/issues
name: susql-operator.v0.0.22
name: susql-operator.v0.0.23
namespace: placeholder
spec:
apiservicedefinitions: {}
Expand All @@ -43,10 +44,10 @@ spec:
description: |-
### About this Operator
SusQL is a Kubernetes operator that aggregates energy data from pods
tagged with SusQL specific labels. The energy measurements are taken
from Kepler which should be deployed in the cluster before
using SusQL.
SusQL is a Kubernetes operator that aggregates energy and estimated
carbon dioxide emission data for pods tagged with SusQL specific
labels. The energy measurements are taken from Kepler which should
be deployed in the cluster before using SusQL.
### Prerequisites
Expand Down Expand Up @@ -196,35 +197,70 @@ spec:
capabilities:
drop:
- ALL
- args:
- --leader-elect=$(LEADER-ELECT)
- --kepler-prometheus-url=$(KEPLER-PROMETHEUS-URL)
- --kepler-metric-name=$(KEPLER-METRIC-NAME)
- --susql-prometheus-database-url=$(SUSQL-PROMETHEUS-DATABASE-URL)
- --susql-prometheus-metrics-url=$(SUSQL-PROMETHEUS-METRICS-URL)
- --sampling-rate=$(SAMPLING-RATE)
- --health-probe-bind-address=$(HEALTH-PROBE-BIND-ADDRESS)
- --metrics-bind-address=$(METRICS-BIND-ADDRESS)
command:
- command:
- /manager
env:
- name: KEPLER-PROMETHEUS-URL
value: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091
valueFrom:
configMapKeyRef:
key: KEPLER-PROMETHEUS-URL
name: susql-config
optional: true
- name: KEPLER-METRIC-NAME
value: kepler_container_joules_total
valueFrom:
configMapKeyRef:
key: KEPLER-METRIC-NAME
name: susql-config
optional: true
- name: SUSQL-PROMETHEUS-DATABASE-URL
value: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091
valueFrom:
configMapKeyRef:
key: SUSQL-PROMETHEUS-DATABASE-URL
name: susql-config
optional: true
- name: SUSQL-PROMETHEUS-METRICS-URL
value: http://0.0.0.0:8082
valueFrom:
configMapKeyRef:
key: SUSQL-PROMETHEUS-METRICS-URL
name: susql-config
optional: true
- name: SAMPLING-RATE
value: "2"
valueFrom:
configMapKeyRef:
key: SAMPLING-RATE
name: susql-config
optional: true
- name: LEADER-ELECT
value: "true"
valueFrom:
configMapKeyRef:
key: LEADER-ELECT
name: susql-config
optional: true
- name: HEALTH-PROBE-BIND-ADDRESS
value: :8081
valueFrom:
configMapKeyRef:
key: HEALTH-PROBE-BIND-ADDRESS
name: susql-config
optional: true
- name: METRICS-BIND-ADDRESS
value: 127.0.0.1:9999
image: quay.io/sustainable_computing_io/susql_operator:0.0.22
valueFrom:
configMapKeyRef:
key: METRICS-BIND-ADDRESS
name: susql-config
optional: true
- name: SUSQL-LOG-LEVEL
valueFrom:
configMapKeyRef:
key: SUSQL-LOG-LEVEL
name: susql-config
optional: true
- name: STATIC-CARBON-INTENSITY
valueFrom:
configMapKeyRef:
key: STATIC-CARBON-INTENSITY
name: susql-config
optional: true
image: quay.io/sustainable_computing_io/susql_operator:0.0.23
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
Expand Down Expand Up @@ -328,4 +364,4 @@ spec:
provider:
name: SusQL Operator Contributors
url: https://github.com/sustainable-computing-io/susql-operator
version: 0.0.22
version: 0.0.23
4 changes: 4 additions & 0 deletions bundle/manifests/susql.ibm.com_labelgroups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ spec:
description: Prometheus query to get the total energy for this label
group
type: string
totalCarbon:
description: TotalCarbon keeps track of the accumulated grams of carbon
dioxide emission over time
type: string
totalEnergy:
description: TotalEnergy keeps track of the accumulated energy over
time
Expand Down
2 changes: 1 addition & 1 deletion bundle/metadata/annotations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ annotations:
operators.operatorframework.io.bundle.metadata.v1: metadata/
operators.operatorframework.io.bundle.package.v1: susql-operator
operators.operatorframework.io.bundle.channels.v1: alpha
operators.operatorframework.io.metrics.builder: operator-sdk-v1.34.1
operators.operatorframework.io.metrics.builder: operator-sdk-v1.36.1
operators.operatorframework.io.metrics.mediatype.v1: metrics+v1
operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v4

Expand Down
62 changes: 45 additions & 17 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,37 @@ func init() {
//+kubebuilder:scaffold:scheme
}

func getEnv(key, defval string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return defval
}

func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
var keplerPrometheusUrl string
var keplerMetricName string
var susqlPrometheusMetricsUrl string
var susqlPrometheusDatabaseUrl string
var samplingRate string
var metricsAddr string = "127.0.0.1:9999"
var enableLeaderElection bool = true
var probeAddr string = ":8081"
var keplerPrometheusUrl string = "https://thanos-querier.openshift-monitoring.svc.cluster.local:9091"
var keplerMetricName string = "kepler_container_joules_total"
var susqlPrometheusMetricsUrl string = "http://0.0.0.0:8082"
var susqlPrometheusDatabaseUrl string = "https://thanos-querier.openshift-monitoring.svc.cluster.local:9091"
var samplingRate string = "2"
var susqlLogLevel string = "-5"
// Static Carbon Intensity Factor in grams CO2 / Joule
var staticCarbonIntensity string = "0.00000000011583333"

// NOTE: these can be set as env or flag, flag takes precedence over env
keplerPrometheusUrlEnv := os.Getenv("KEPLER-PROMETHEUS-URL")
keplerMetricNameEnv := os.Getenv("KEPLER-METRIC-NAME")
susqlPrometheusDatabaseUrlEnv := os.Getenv("SUSQL-PROMETHEUS-DATABASE-URL")
susqlPrometheusMetricsUrlEnv := os.Getenv("SUSQL-PROMETHEUS-METRICS-URL")
samplingRateEnv := os.Getenv("SAMPLING-RATE")
metricsAddrEnv := os.Getenv("METRICS-BIND-ADDRESS")
probeAddrEnv := os.Getenv("HEALTH-PROBE-BIND-ADDRESS")
enableLeaderElectionEnv, err := strconv.ParseBool(os.Getenv("LEADER-ELECT"))
keplerPrometheusUrlEnv := getEnv("KEPLER-PROMETHEUS-URL", keplerPrometheusUrl)
keplerMetricNameEnv := getEnv("KEPLER-METRIC-NAME", keplerMetricName)
susqlPrometheusDatabaseUrlEnv := getEnv("SUSQL-PROMETHEUS-DATABASE-URL", susqlPrometheusDatabaseUrl)
susqlPrometheusMetricsUrlEnv := getEnv("SUSQL-PROMETHEUS-METRICS-URL", susqlPrometheusMetricsUrl)
samplingRateEnv := getEnv("SAMPLING-RATE", samplingRate)
metricsAddrEnv := getEnv("METRICS-BIND-ADDRESS", metricsAddr)
probeAddrEnv := getEnv("HEALTH-PROBE-BIND-ADDRESS", probeAddr)
susqlLogLevelEnv := getEnv("SUSQL-LOG-LEVEL", susqlLogLevel)
staticCarbonIntensityEnv := getEnv("STATIC-CARBON-INTENSITY", staticCarbonIntensity)
enableLeaderElectionEnv, err := strconv.ParseBool(getEnv("LEADER-ELECT", strconv.FormatBool(enableLeaderElection)))
if err != nil {
enableLeaderElectionEnv = false
}
Expand All @@ -81,13 +93,20 @@ func main() {
flag.StringVar(&samplingRate, "sampling-rate", samplingRateEnv, "Sampling rate in seconds")
flag.StringVar(&metricsAddr, "metrics-bind-address", metricsAddrEnv, "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", probeAddrEnv, "The address the probe endpoint binds to.")
flag.StringVar(&susqlLogLevel, "susql-log-level", susqlLogLevelEnv, "SusQL log level")
flag.StringVar(&staticCarbonIntensity, "static-carbon-intensity", staticCarbonIntensityEnv, "Static Carbon Intensity Factor in grams CO2 / Joule")
flag.BoolVar(&enableLeaderElection, "leader-elect", enableLeaderElectionEnv,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")

susqlLogLevelInt, err := strconv.Atoi(susqlLogLevel)
if err != nil {
susqlLogLevelInt = -5
}

opts := zap.Options{
Development: true,
Level: zapcore.Level(-5),
Level: zapcore.Level(susqlLogLevelInt),
}
opts.BindFlags(flag.CommandLine)
flag.Parse()
Expand All @@ -103,6 +122,8 @@ func main() {
susqlLog.Info("susqlPrometheusMetricsUrl=" + susqlPrometheusMetricsUrl)
susqlLog.Info("susqlPrometheusDatabaseUrl=" + susqlPrometheusDatabaseUrl)
susqlLog.Info("samplingRate=" + samplingRate)
susqlLog.Info("susqlLogLevel=" + susqlLogLevel)
susqlLog.Info("staticCarbonIntensity=" + staticCarbonIntensity)

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Expand Down Expand Up @@ -134,6 +155,12 @@ func main() {
samplingRateInteger = 2
}

staticCarbonIntensityFloat, err := strconv.ParseFloat(staticCarbonIntensity, 64)
if err != nil {
susqlLog.Error(err, "Unable to obtain static carbon intensity value. Using 0.0.")
staticCarbonIntensityFloat = 0.0
}

susqlLog.Info("Setting up labelGroupReconciler.")

if err = (&controller.LabelGroupReconciler{
Expand All @@ -144,6 +171,7 @@ func main() {
SusQLPrometheusDatabaseUrl: susqlPrometheusDatabaseUrl,
SusQLPrometheusMetricsUrl: susqlPrometheusMetricsUrl,
SamplingRate: time.Duration(samplingRateInteger) * time.Second,
StaticCarbonIntensity: staticCarbonIntensityFloat,
Logger: susqlLog,
}).SetupWithManager(mgr); err != nil {
susqlLog.Error(err, "unable to create controller", "controller", "LabelGroup")
Expand Down
4 changes: 4 additions & 0 deletions config/crd/bases/susql.ibm.com_labelgroups.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ spec:
description: Prometheus query to get the total energy for this label
group
type: string
totalCarbon:
description: TotalCarbon keeps track of the accumulated grams of carbon
dioxide emission over time
type: string
totalEnergy:
description: TotalEnergy keeps track of the accumulated energy over
time
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ kind: Kustomization
images:
- name: controller
newName: quay.io/sustainable_computing_io/susql_operator
newTag: 0.0.22
newTag: 0.0.23
Loading

0 comments on commit 1b94f07

Please sign in to comment.