{"id":21126455,"url":"https://github.com/lreimer/green-kubernetes","last_synced_at":"2025-10-05T14:32:22.073Z","repository":{"id":178904523,"uuid":"662464850","full_name":"lreimer/green-kubernetes","owner":"lreimer","description":"Showcase repository to demonstrate sustainability projects for Kubernetes.","archived":false,"fork":false,"pushed_at":"2024-06-21T09:34:33.000Z","size":151,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-08T23:40:16.799Z","etag":null,"topics":["goldilocks","hpa","keda","kepler","kube-green","kubernetes","sustainability","vpa"],"latest_commit_sha":null,"homepage":"","language":"Makefile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lreimer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-07-05T07:39:28.000Z","updated_at":"2025-07-01T05:45:49.000Z","dependencies_parsed_at":"2024-01-12T04:43:43.933Z","dependency_job_id":"aae8b746-3a73-421a-bd30-60760ec0b76c","html_url":"https://github.com/lreimer/green-kubernetes","commit_stats":{"total_commits":58,"total_committers":3,"mean_commits":"19.333333333333332","dds":"0.18965517241379315","last_synced_commit":"d009ba1b781c6df8a76ec6db7988745af74631b9"},"previous_names":["lreimer/green-kubernetes"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/lreimer/green-kubernetes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lreimer%2Fgreen-kubernetes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lreimer%2Fgreen-kubernetes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lreimer%2Fgreen-kubernetes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lreimer%2Fgreen-kubernetes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lreimer","download_url":"https://codeload.github.com/lreimer/green-kubernetes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lreimer%2Fgreen-kubernetes/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267335102,"owners_count":24070704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["goldilocks","hpa","keda","kepler","kube-green","kubernetes","sustainability","vpa"],"created_at":"2024-11-20T04:41:56.335Z","updated_at":"2025-10-05T14:32:21.983Z","avatar_url":"https://github.com/lreimer.png","language":"Makefile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Green Kubernetes\n\nShowcase repository to demonstrate sustainability projects for Kubernetes.\n\n## Setup\n\n```bash\nexport GITHUB_USER=lreimer\nexport GITHUB_TOKEN=\n\n# for the GKE cluster setup\nmake create-gke-cluster\nmake bootstrap-gke-flux2\n\nkubectl edit service kube-prometheus-stack-grafana -n monitoring\nexport GRAFANA_IP=`kubectl get service kube-prometheus-stack-grafana -n monitoring -o jsonpath=\"{.status.loadBalancer.ingress[0].ip}\"`\n\nkubectl edit service goldilocks-dashboard -n goldilocks\nexport GOLDILOCKS_IP=`kubectl get service goldilocks-dashboard -n goldilocks -o jsonpath=\"{.status.loadBalancer.ingress[0].ip}\"`\n\n# for the EKS cluster setup\nmake create-eks-cluster\nmake bootstrap-eks-flux2\n\nkubectl edit service kube-prometheus-stack-grafana -n monitoring\nexport GRAFANA_HOSTNAME=`kubectl get service kube-prometheus-stack-grafana -n monitoring -o jsonpath=\"{.status.loadBalancer.ingress[0].hostname}\"`\n```\n\n## Cluster Planning\n\n```bash\nopen https://app.electricitymaps.com/map\nopen https://cloud.google.com/compute/docs/regions-zones?hl=de#available\n```\n\n## Cluster Rightsizing\n\nDepending on the Cloud provider there are different options to autoscale and thus rightsize the cluster itself, so that the number of nodes is sufficient to handle the current load but not more.\n\n```bash\n# add a deployment to demo cluster autoscaling\nkubectl apply -f karpenter/inflate.yaml\n\n# to trigger and watch a cluster ScaleUp\nkubectl scale deployment inflate --replicas 5\nkubectl get pods\nkubectl describe pod inflate-644ff677b7-jgw8r\nkubectl events\nkubectl get nodes -w\n\n# to trigger and watch a cluster ScaleDown\nkubectl scale deployment inflate --replicas 0\nkubectl get pods\nkubectl events\nkubectl get nodes -w\n```\n\n### Google GKE with Cluster Autoscaler\n\n```bash\n# create GKE cluster using gcloud CLI\ngcloud container clusters create green-gke-k8s ... \\\n    # enable GKE addons such as HPA support\n\t--addons HttpLoadBalancing,HorizontalPodAutoscaling \\\n    \n    # enable VPA support\n\t--enable-vertical-pod-autoscaling \\\n\n    # enable cluster autoscaling\n    # use profile for moderate (Balanced) or aggessive (Optimize-utilization) mode\n\t--enable-autoscaling \\\n\t--autoscaling-profile=optimize-utilization \\\n    \n    # specify initial node pool size and scaling limits\n\t--num-nodes=1 \\\n\t--min-nodes=1 --max-nodes=5 \\\n    \n  # Ampere Altra Arm-Prozessor\n  # currently only available in certain regions\n  # see https://cloud.google.com/compute/docs/regions-zones?hl=de#available\n  --machine-type=t2a-standard-4\n```\n\n### AWS EKS with Karpenter\n\nKarpenter automatically provisions new nodes in response to unschedulable pods. Karpenter does this by observing events within the Kubernetes cluster, and then sending commands to the underlying cloud provider. Currently, only EKS on AWS is supported. See https://karpenter.sh/docs/getting-started/getting-started-with-karpenter/\n\nTo easily install EKS with Karpenter, the `eksctl` tool can be used because it brings Karpenter support. See https://eksctl.io/usage/eksctl-karpenter/\n\n## Workload Rightsizing with VPA and Goldilocks\n\n```bash\n# explicitly enable goldilocks for the default namespace\nkubectl label ns default goldilocks.fairwinds.com/enabled=true\n\n# create resource and the VPA in recommender mode\nkubectl apply -f vpa/hamster.yaml\nkubectl apply -f vpa/vpa.yaml\n\n# display the container recommendations for CPU and memory\nkubectl describe vpa hamster-vpa\n\n# use Goldilocks dashboard to display recommendations\nkubectl get service goldilocks-dashboard -n goldilocks\nopen http://$GOLDILOCKS_IP:80\n```\n\n## kube-green\n\nDon't waste resources! Many workloads on dev/qa environments stay running during weekends,\nnon working hours or at night. _kube-green_ is a simple K8s addon to automatically shutdown\nand restart resources based on when they are needed (or not).\n\n```yaml\napiVersion: kube-green.com/v1alpha1\nkind: SleepInfo\nmetadata:\n  name: non-working-hours\nspec:\n  weekdays: \"1-5\"\n  sleepAt: \"18:00\"\n  wakeUpAt: \"08:00\"\n  timeZone: \"Europe/Rome\"\n  suspendCronJobs: true\n  excludeRef:\n    - apiVersion: \"apps/v1\"\n      kind:       Deployment\n      name:       no-sleep-deployment\n    - matchLabels: \n        kube-green.dev/exclude: \"true\"\n```\n\nTo see some details when the above `SleepInfo` resource will be schedules next, you can have a look at the log output from the _kube-green-controller-manager_ pod.\n```bash\nkubectl logs pod/kube-green-controller-manager-5855848d7f-dftxd -n kube-green\n```\n\n## Carbon Aware Scaling and Temporal Shifting with KEDA\n\n_KEDA is a Kubernetes-based Event Driven Autoscaler that allows granular scaling of workloads in Kubernetes, based on multiple defined parameters, leveraging the concept of built for purpose scalers. To build a Kubernetes application with carbon aware scaling, we need to implement demand shaping that scales workloads based on the current carbon intensity of the location where the Kubernetes cluster is deployed. To achieve this using KEDA, you can set up the newly introduced KEDA carbon-aware scaler for your Kubernetes workloads and define your carbon intensity scaling thresholds._  (https://www.tfir.io/carbon-aware-kubernetes-scaling-a-step-towards-greener-cloud-computing/)\n\n```bash\n# https://keda.sh/docs/2.12/scalers/metrics-api/\n# https://keda.sh/docs/2.12/scalers/loki/\n# https://keda.sh/docs/2.12/scalers/influxdb/\n\n# deploy the normal KEDA scaler\nkubectl apply -f keda/deploy-consumer.yaml\nkubectl apply -f keda/deploy-publisher-job.yaml\n\n# detailled installation instructions can be found in the Github repos\nopen https://github.com/Azure/carbon-aware-keda-operator\nopen https://github.com/Azure/kubernetes-carbon-intensity-exporter\n\n# you will also need the sources\n# install the intensity exporter\ngit clone https://github.com/Azure/kubernetes-carbon-intensity-exporter.git\ncd kubernetes-carbon-intensity-exporter\n\nexport WATTTIME_USERNAME=lreimer\nexport WATTTIME_PASSWORD=\nexport LOCATION=se\n# export LOCATION=westus\n\nhelm install carbon-intensity-exporter \\\n        --set carbonDataExporter.region=$LOCATION \\\n        --set wattTime.username=$WATTTIME_USERNAME \\\n        --set wattTime.password=$WATTTIME_PASSWORD \\\n        ./charts/carbon-intensity-exporter\n\n# check the carbon data\nkubectl get pod -n kube-system | grep carbon-intensity-exporter\nkubectl get cm -n kube-system carbon-intensity -o jsonpath='{.data}' | jq\nkubectl get cm -n kube-system carbon-intensity -o jsonpath='{.binaryData.data}' | base64 --decode | jq\n\n# install the carbon aware operator\ngit clone https://github.com/Azure/carbon-aware-keda-operator.git\ncd carbon-aware-keda-operator\nversion=$(git describe --abbrev=0 --tags)\nkubectl apply -f \"https://github.com/Azure/carbon-aware-keda-operator/releases/download/${version}/carbonawarekedascaler-${version}.yaml\"\n\n# deply the carbon aware scaler\nkubectl apply -f keda/deploy-consumer.yaml\nkubectl apply -f keda/deploy-publisher-job.yaml\nkubectl apply -f keda/carbon-aware-scaler.yaml\n```\n\n## Measure Power Usage with Kepler\n\nKepler (Kubernetes-based Efficient Power Level Exporter) uses eBPF to probe energy related system stats and exports as Prometheus metrics.\n\n```bash\n# the installation via Helm chart works, but is somewhat incomplete / outdated\n# instead, the installation from source via YAML is used\n# only working on AWS, on GKE instances some host volumes can't be mounted\n# using Ubuntu on AWS and GKE for now, this should solve the issue\n\ngit clone https://github.com/sustainable-computing-io/kepler.git\ncd kepler\nmake build-manifest OPTS=\"PROMETHEUS_DEPLOY\"\nkubectl apply -f _output/generated-manifest/deployment.yaml\n\nkubectl get all -n kepler\n```\n\n## Carbon aware Spatial Shifting with Karmada\n\nhttps://rossfairbanks.com/2023/07/12/carbon-aware-spatial-shifting-with-karmada/\n\n```bash\n# make sure you are running on a local K8s\nkubectl ctx rancher-desktop\nkubectl karmada init\nkubectl karmada init --karmada-data=$PWD/.karmada --karmada-pki=$PWD/.karmada/pki --karmada-apiserver-advertise-address=127.0.0.1 --etcd-storage-mode=emptyDir --cert-external-ip=127.0.0.1\n\n# next we join the GKE clusters\nkubectl karmada join eks-cluster --kubeconfig $PWD/.karmada/karmada-apiserver.config --cluster-kubeconfig=$HOME/.kube/config --cluster-context=mario-leander.reimer@green-eks-k8s.eu-north-1.eksctl.io --cluster-provider=aws --cluster-region=eu-north-1\nkubectl karmada join gke-cluster --kubeconfig $PWD/.karmada/karmada-apiserver.config --cluster-kubeconfig=$HOME/.kube/config --cluster-context=gke_cloud-native-experience-lab_europe-north1_green-gke-k8s --cluster-provider=gcp --cluster-region=europe-north1\n\n# see the cluster details\nkubectl --kubeconfig /Users/mario-leander.reimer/Projekte/green-kubernetes/.karmada/karmada-apiserver.config get clusters\nkubectl --kubeconfig /Users/mario-leander.reimer/Projekte/green-kubernetes/.karmada/karmada-apiserver.config describe cluster gke-cluster\n\n# deploy workload and propagation policy\nkubectl --kubeconfig /Users/mario-leander.reimer/Projekte/green-kubernetes/.karmada/karmada-apiserver.config apply -f karmada/nginx-deployment.yaml\nkubectl --kubeconfig /Users/mario-leander.reimer/Projekte/green-kubernetes/.karmada/karmada-apiserver.config apply -f karmada/propagationpolicy-region.yaml\n\nkubectl ctx mario-leander.reimer@green-eks-k8s.eu-north-1.eksctl.io\nkubectl get all\n\nkubectl ctx gke_cloud-native-experience-lab_europe-north1_green-gke-k8s\nkubectl get all\n```\n\n\n## Scaphandre\n\nhttps://github.com/hubblo-org/scaphandre\n\n## Prometheus Custom Metrics and HPA\n\nhttps://github.com/kubernetes-sigs/prometheus-adapter\n\n## References\n\n- Cloud Native Sustainabilty Roadmap\n- https://www.techtarget.com/searchitoperations/feature/How-to-approach-sustainability-in-IT-operations\n- https://www.redhat.com/en/blog/how-kepler-project-working-advance-environmentally-conscious-efforts\n\n## Maintainer\n\nM.-Leander Reimer (@lreimer), \u003cmario-leander.reimer@qaware.de\u003e\n\n## License\n\nThis software is provided under the MIT open source license, read the `LICENSE`\nfile for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flreimer%2Fgreen-kubernetes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flreimer%2Fgreen-kubernetes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flreimer%2Fgreen-kubernetes/lists"}