GreenOps: Carbon-Aware Infrastructure s Kubernetes
Světová datová centra dnes spotřebovávají mezi1 a 2 % celosvětové elektřiny, s Ekvivalentní emise CO₂ se odhadují na 100 až 200 milionů tun ročně – více než celá letecký průmysl. S náporem na generativní AI spotřebovávají tréninkové modely jako GPT-4 energii ekvivalentní stovkám transatlantických letů na jeden let. Přesto většina infrastruktury cloud nadále funguje, jako by tyto emise neexistovaly: clustery Kubernetes běží v cyklech kontinuální bez ohledu na uhlíkovou intenzitu elektrické sítě, potrubí CI/CD ano spouštějí se okamžitě bez ohledu na to, kdy je elektřina čistší, a týmy DevOps monitoruje náklady a latenci, ale zřídka emise na modul.
GreenOps je to operační disciplína, která toto paradigma mění. Metodiky výpůjček od FinOps – praxe optimalizace cloudových výdajů – GreenOps přináší udržitelnost prostředí v centru rozhodování o infrastruktuře: jak alokovat pracovní zátěž, kdy spouštět dávkové úlohy, ve které oblasti nasadit, jak velikost uzlů. Výsledkem není pouze životní prostředí: organizace přijímající GreenOps hlásí v průměru a 30-60% snížení emisí související s cloudem a úspora nákladů 15-30%, protože energetická účinnost a účinnost ekonomické se často shodují.
V tomto článku vytvoříme skutečně uhlíkovou infrastrukturu Kubernetes, a to od nuly: budeme cluster instrumentovat Kepler pro měření spotřeby energie na modul, nakonfigurujeme Operátor KEDA s vědomím uhlíku škálovat pracovní zátěž na základě intenzity uhlíku v reálném čase, zavedeme víceregionální uhlíkové směrování s Karmadou a vybudujeme CI/CD potrubí, které automaticky vybere nejzelenější časové okno spustit sestavení. Každá sekce obsahuje kód YAML a Python připravený pro produkci.
Co se naučíte
- Rozdíly mezi GreenOps a FinOps a jak se vzájemně doplňují pro udržitelnost cloudu
- Carbon-aware automatické škálování s KEDA a operátorem KEDA Carbon Aware v Azure
- Jak nainstalovat a nakonfigurovat Kepler (Efficient Power Level Exporter založený na Kubernetes)
- Metriky Kepler Prometheus: Spotřeba energie na kontejner, modul a uzel
- Plánování s ohledem na uhlík s CronJob a PriorityClass na základě intenzity uhlíku
- Směrování uhlíku ve více regionech s Karmadou: přesuňte pracovní zátěž do zelenějších oblastí
- Rozhraní API pro uhlíkovou stopu poskytovatelů cloudu: porovnání AWS, Google Cloud, Azure
- Dashboard Grafana pro sledování emisí clusteru Kubernetes
- Zelené CI/CD: Akce GitHubu s ohledem na uhlík s inteligentním plánováním sestavení
- Případová studie: cluster 50 uzlů s 35% snížením emisí za 3 měsíce
Green Software Engineering Series — Všechny články
| # | Titul | Podrobit |
|---|---|---|
| 1 | Principy zeleného softwarového inženýrství | 8 Principy GSF, SCI specifikace ISO/IEC 21031 |
| 2 | Měření emisí pomocí CodeCarbon | Sledování CO₂ v Pythonu, MLflow, dashboard |
| 3 | Climatiq API: Intenzita uhlíku v cloudových systémech | REST API, výpočet emisí cloudu a dodavatelský řetězec |
| 4 | Carbon Aware SDK: Posun času a místa | GSF SDK, WattTime, ElectricityMaps, Kubernetes, CI/CD |
| 5 | Rozsah 3 a potrubí ESG | Emise proti proudu/po proudu, datový kanál CSRD |
| 6 | GreenOps: Carbon-Aware Infrastructure s Kubernetes (tento článek) | KEDA karbonový scaler, Kepler, multi-region routing, Green CI/CD |
| 7 | Rozsah 1, 2, 3 modelování | Účetní rámce protokolu GHG, SBTi |
| 8 | AI uhlíková stopa | LLM školení, inference, energetická optimalizace |
| 9 | Udržitelné softwarové vzory | Návrh zeleného vzoru, efektivní architektury |
| 10 | ESG a CSRD pro software | Dodržování předpisů, povinné hlášení EU |
GreenOps vs FinOps: Doplňky, nikoli alternativy
FinOps se zrodil jako reakce na nekontrolovaný růst cloudových výdajů: týmy, které alokovaly zdroje bez zohlednění nákladů, zapomenuté instance EC2 aktivní měsíce, neoptimalizované úložiště které hromadily faktury, aniž by produkovaly hodnotu. FinOps přináší kulturu, procesy a nástroje k provádění viditelné výdaje a systematicky je optimalizovat. GreenOps se tímto modelem výslovně inspiruje jeho použití na uhlíkové emise: zviditelní emise podle pracovní zátěže, zavádí procesy optimalizace a vytváří odpovědnost v týmech.
Dobrou zprávou je, že tyto dvě disciplíny se enormně překrývají: stejný lusk nadrozměrné plýtvání jak penězi, tak energií. Nečinný cluster přes noc spálí oba rozpočty že CO₂. Optimalizovat často znamená optimalizovat obojí. Existují však také důležité rozdíly pochopit.
GreenOps vs FinOps: Srovnávací tabulka
| Velikost | FinOps | GreenOps | Integrace |
|---|---|---|---|
| Primární cíl | Snižte výdaje na cloud, optimalizujte návratnost investic | Snižte emise CO₂, zvyšte energetickou účinnost | Často v souladu: účinnost = úspory = snížení emisí |
| Základní metrika | Cena za obchodní jednotku ($/požadavek, $/uživatel) | gCO₂eq na obchodní jednotku (uhlíková intenzita) | Společné panely nákladů a uhlíku pro integrovaná rozhodnutí |
| Hlavní páka | Správná velikost, vyhrazené instance, okamžité ceny | Time shifting, location shifting, demand shaping | Časový posun snižuje jak nákladové špičky, tak emise |
| Zrnitost | Označte cloud, tým, službu, účet | Pod, kontejner, funkce bez serveru | Kepler přináší granularitu GreenOps na úroveň podů jako FinOps |
| Dočasnost | Měsíční/čtvrtletní optimalizace (fakturace) | Hodinová optimalizace (proměnlivost uhlíkové intenzity) | GreenOps vyžaduje automatizaci v reálném čase; Více statických FinOps |
| Možné konflikty | Spot instance levnější, ale region uhlíkově náročné | Region zelený, ale dražší, vyšší latence | Explicitní kompromisy s kombinovaným hodnocením nákladů a uhlíku |
| Nástroje | AWS Cost Explorer, CloudHealth, Kubecost | Kepler, Carbon Aware SDK, cloudová uhlíková API | Kubecost + Kepler: cena a uhlík na modul na stejné palubní desce |
| Norma | Specifikace FinOps Foundation FOCUS | Specifikace GSF SCI, protokol GHG | Konvergence se očekává v roce 2026 se sjednocenými metrikami |
Nejstrategičtějším bodem konvergence mezi FinOps a GreenOps je správné velikosti: snížení nadměrných nároků na CPU/paměť modulů nejenom sníží váš účet za cloud, ale přímo jej sníží spotřeba energie uzlů, která se mění úměrně zátěži. Podle poakvizičních dat CloudBolt od StormForge (březen 2025), clustery optimalizované s průměrným snížením pily správné velikosti řízené umělou inteligencí o 40 % v nákladech i emisích – vzácný případ, kdy neexistuje žádný kompromis.
Konflikt se místo toho objeví, když je geograficky oblaková oblast s nízkou intenzitou uhlíku daleko a tedy dražší pro přenos dat, nebo když je levná spotová instance nachází se v oblasti, která je živena převážně uhlím. V těchto scénářích GreenOps týmy více zralí dospělí adoptují jednoho kompozitní skórovací funkce který vyvažuje náklady, emise a latenci s konfigurovatelnými závažími pro různé typy pracovní zátěže.
Carbon-Aware Kubernetes: KEDA a Carbon Aware Operator
KEDA (Kubernetes Event-Driven Autoscaler) je open source komponenta Kubernetes, která umožňuje škálovat pracovní zátěž na základě událostí a externích metrik — fronty zpráv, metriky Prometheus, HTTP koncové body. The Carbon Aware operátor KEDA, vyvinuté společností Microsoft Azure a zveřejněné na GitHubu rozšiřuje KEDA o radikálně nový rozměr: uhlíkovou intenzitu elektrické sítě místní. Výsledkem je shluk, který se škáluje dolů když je elektřina vyrobené z fosilních zdrojů, např nahoru když je dostatek obnovitelné energie.
Mechanismus je elegantní ve své jednoduchosti. Operátor čte aktuální intenzitu uhlíku — z WattTime, ElectricityMaps nebo jakéhokoli jiného zdroje – a naplní ConfigMap v clusteru hodnota se aktualizuje každou hodinu. KEDA ScaledObject přečte tuto ConfigMap a použije hodnotu jako vstup určit maximální povolený počet replikací: když je intenzita vysoká (síť náročné na uhlík), strop klesá; když je intenzita nízká (čistá energie), strop stoupá a shluk se může škálovat agresivněji.
Carbon Aware KEDA Operator Architecture
# carbon-aware-keda-operator/config/samples/carbonawarekedascaler.yaml
# Installa l'operator: kubectl apply -f https://github.com/Azure/carbon-aware-keda-operator/releases/latest/download/operator.yaml
apiVersion: carbon.azure.com/v1alpha1
kind: CarbonAwareKedaScaler
metadata:
name: batch-processor-carbon-scaler
namespace: default
spec:
# Riferimento al KEDA ScaledObject da modificare
kedaTarget:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
name: batch-processor-scaler
# Definisce come il ceiling di repliche cambia con la carbon intensity
carbonIntensityForecastDataSource:
mockCarbonForecast: false
localConfigMap:
name: carbon-intensity-forecast
namespace: kube-system
key: data
# Soglie carbon intensity (gCO2/kWh) -> max replicas
maxReplicasByCarbonIntensity:
- carbonIntensityThreshold: 50 # Energia molto pulita
maxReplicas: 20 # Scala aggressivamente
- carbonIntensityThreshold: 100 # Energia mediamente pulita
maxReplicas: 15
- carbonIntensityThreshold: 200 # Mix energetico moderato
maxReplicas: 10
- carbonIntensityThreshold: 350 # Carbon-intensive
maxReplicas: 5 # Scala al minimo
- carbonIntensityThreshold: 500 # Molto carbon-intensive
maxReplicas: 2 # Solo carichi critici
Odpovídající KEDA ScaledObject, který zpracovává skutečné automatické škálování Deployment:
# keda-scaled-object.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: batch-processor-scaler
namespace: default
spec:
scaleTargetRef:
name: batch-processor
minReplicaCount: 2
maxReplicaCount: 20 # Viene sovrascritto dal CarbonAwareKedaScaler
cooldownPeriod: 300
pollingInterval: 60
triggers:
- type: rabbitmq
metadata:
protocol: amqp
queueName: batch-jobs
mode: QueueLength
value: "10"
authenticationRef:
name: rabbitmq-trigger-auth
---
# Deployment del batch processor
apiVersion: apps/v1
kind: Deployment
metadata:
name: batch-processor
namespace: default
labels:
app: batch-processor
green-software: "true"
spec:
replicas: 2
selector:
matchLabels:
app: batch-processor
template:
metadata:
labels:
app: batch-processor
annotations:
# Annotazione per tracking GreenOps
greenops.io/workload-type: "deferrable-batch"
greenops.io/carbon-policy: "carbon-aware-scaling"
spec:
containers:
- name: batch-processor
image: myregistry/batch-processor:v1.2.0
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2000m"
memory: "2Gi"
Exportér ConfigMap intenzity uhlíku
ConfigMap s údaji o intenzitě uhlíku musí být naplněna úlohou, která se dotazuje na externí rozhraní API.
Projekt kubernetes-carbon-intensity-exporter Azure poskytuje tuto komponentu:
# carbon-intensity-exporter.yaml
# Installa: kubectl apply -f https://github.com/Azure/kubernetes-carbon-intensity-exporter/releases/latest/download/deploy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: carbon-intensity-exporter-config
namespace: kube-system
data:
# Provider dati: WattTime o ElectricityMaps
CARBON_INTENSITY_PROVIDER: "WattTime"
# Region/location in formato standard (ISO3166-1)
LOCATION: "eastus"
# Aggiornamento ogni 12 ore con forecast 24h
FETCH_INTERVAL_SECONDS: "43200"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: carbon-intensity-exporter
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: carbon-intensity-exporter
template:
metadata:
labels:
app: carbon-intensity-exporter
spec:
serviceAccountName: carbon-intensity-exporter
containers:
- name: exporter
image: ghcr.io/azure/kubernetes-carbon-intensity-exporter:latest
envFrom:
- configMapRef:
name: carbon-intensity-exporter-config
env:
- name: WATTTIME_USERNAME
valueFrom:
secretKeyRef:
name: carbon-intensity-secrets
key: watttime-username
- name: WATTTIME_PASSWORD
valueFrom:
secretKeyRef:
name: carbon-intensity-secrets
key: watttime-password
Pracovní zátěže Vhodné pro Carbon-Aware Scaling
Škálování s ohledem na uhlík funguje pouze pro pracovní zatížení odložitelné o elastický:
dávkové úlohy, školení ML, potrubí ETL, zpracování sestav, překódování médií. Neaplikujte to na služby
uživatelská orientace v reálném čase (brána API, frontend), kde je kritická latence. Parametr
minReplicaCount zaručuje, že i v podmínkách vysoké intenzity uhlíku jsou lusky minimální
pokračovat v rotaci, aby byla zachována dostupnost služby.
Carbon-Aware Scheduling: CronJob a PriorityClass Verdi
Kromě reaktivního automatického škálování zavádí GreenOps plánování proaktivní: místo toho reagovat na aktuální uhlíkovou intenzitu, očekává se nejzelenější časové okno v dalších 24 hodin a naplánuje spuštění úlohy v tuto dobu. WattTime a ElectricityMaps poskytují předpovídá až 72 hodin, což tuto optimalizaci umožňuje.
Python Controller pro Carbon-Aware CronJob
Lehký Python ovladač, který se dotazuje na Carbon Aware SDK a dynamicky přepisuje plán Kubernetes CronJob, aby ukázal na zelené okno:
#!/usr/bin/env python3
# carbon_aware_scheduler.py
# Richiede: pip install kubernetes requests python-crontab
import os
import json
import logging
from datetime import datetime, timedelta
from typing import Optional
import requests
from kubernetes import client, config
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("carbon-aware-scheduler")
CARBON_AWARE_SDK_URL = os.getenv("CARBON_AWARE_SDK_URL", "http://carbon-aware-sdk:8080")
CARBON_THRESHOLD = float(os.getenv("CARBON_THRESHOLD_G_CO2_KWH", "150"))
def get_best_window(location: str, duration_minutes: int = 60) -> Optional[datetime]:
"""Interroga il Carbon Aware SDK per la finestra ottimale nelle prossime 24h."""
window_start = datetime.utcnow()
window_end = window_start + timedelta(hours=24)
url = f"{CARBON_AWARE_SDK_URL}/emissions/forecasts/best"
params = {
"location": location,
"dataStartAt": window_start.isoformat() + "Z",
"dataEndAt": window_end.isoformat() + "Z",
"windowSize": duration_minutes,
}
try:
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
# Il Carbon Aware SDK restituisce la finestra ottimale
if data and len(data) > 0:
best = data[0]
optimal_time_str = best.get("optimalDataPoints", [{}])[0].get("timestamp")
if optimal_time_str:
return datetime.fromisoformat(optimal_time_str.replace("Z", "+00:00"))
except requests.RequestException as e:
logger.error(f"Errore Carbon Aware SDK: {e}")
return None
def update_cronjob_schedule(namespace: str, cronjob_name: str, target_time: datetime) -> bool:
"""Aggiorna la schedule del CronJob Kubernetes."""
config.load_incluster_config()
batch_v1 = client.BatchV1Api()
# Converti in espressione cron (minuto e ora UTC)
cron_expression = f"{target_time.minute} {target_time.hour} * * *"
try:
cronjob = batch_v1.read_namespaced_cron_job(cronjob_name, namespace)
cronjob.spec.schedule = cron_expression
# Annotazione per audit trail GreenOps
if cronjob.metadata.annotations is None:
cronjob.metadata.annotations = {}
cronjob.metadata.annotations["greenops.io/last-schedule-update"] = datetime.utcnow().isoformat()
cronjob.metadata.annotations["greenops.io/scheduled-carbon-window"] = target_time.isoformat()
batch_v1.patch_namespaced_cron_job(cronjob_name, namespace, cronjob)
logger.info(f"CronJob {cronjob_name} aggiornato: schedule={cron_expression}")
return True
except client.ApiException as e:
logger.error(f"Errore aggiornamento CronJob: {e}")
return False
if __name__ == "__main__":
location = os.getenv("GRID_LOCATION", "IT")
namespace = os.getenv("TARGET_NAMESPACE", "default")
cronjob_name = os.getenv("TARGET_CRONJOB", "ml-training-job")
job_duration = int(os.getenv("JOB_DURATION_MINUTES", "90"))
best_window = get_best_window(location, job_duration)
if best_window:
logger.info(f"Finestra ottimale trovata: {best_window}")
update_cronjob_schedule(namespace, cronjob_name, best_window)
else:
logger.warning("Nessuna finestra ottimale trovata, mantengo schedule corrente")
PriorityClass Carbon-Aware
Kubernetes vám umožňuje upřednostňovat pody prostřednictvím PriorityClass. V kontextu
GreenOps, definujeme prioritní třídy, které odrážejí toleranci pro odklad: pracovní zátěž
kritické si udržují vysokou prioritu, ty, které nelze odložit, jsou plánovány s nízkou prioritou
a mohou být vystěhováni nebo zpožděni, když je třeba soustředit zdroje na více úloh
naléhavé během oken s nízkou intenzitou uhlíku.
# priority-classes-greenops.yaml
# Gerarchia di priorità GreenOps
# Workload critici: sempre in esecuzione, non deferrabili
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: greenops-critical
annotations:
greenops.io/deferrable: "false"
greenops.io/carbon-policy: "always-run"
value: 1000000
globalDefault: false
description: "Workload critici: API user-facing, servizi core business"
---
# Workload standard: possono aspettare finestre verdi brevi (1-2h)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: greenops-standard
annotations:
greenops.io/deferrable: "true"
greenops.io/max-defer-hours: "2"
greenops.io/carbon-threshold: "200"
value: 500000
globalDefault: true
description: "Workload standard: servizi interni, analytics real-time"
---
# Workload batch: ottimizzati per finestre verdi lunghe (fino a 12h)
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: greenops-batch
annotations:
greenops.io/deferrable: "true"
greenops.io/max-defer-hours: "12"
greenops.io/carbon-threshold: "100"
value: 100000
globalDefault: false
description: "Workload batch: ETL, training ML, report, backup"
---
# Workload opportunistici: solo durante energia molto pulita
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: greenops-opportunistic
annotations:
greenops.io/deferrable: "true"
greenops.io/max-defer-hours: "48"
greenops.io/carbon-threshold: "80"
value: 10000
globalDefault: false
description: "Workload opportunistici: pre-training, batch mensili, archivio"
Víceregionální uhlíkové směrování s Karmadou
Časový posun přesouvá pracovní zátěž do čas ve stejném regionu. The posun umístění jde dále: přesouvá pracovní zátěž na plocha, spuštění úlohy v oblasti cloudu s uhlíkem v tu chvíli nejnižší intenzita. Geografická variabilita je obrovská: a specifický okamžik, eu-sever-1 (Stockholm, poháněný téměř výhradně hydroelektrárnou) může mají intenzitu 15 gCO₂/kWh, zatímco us-východ-1 (Virginia, se směsí uhlí/plyn/jaderná) může to být 300-400 gCO₂/kWh. Místo toho přivézt místo školení ML do Švédska Virginie snižuje emise 90 %+ se stejným výpočtem.
Karmada (Kubernetes Armada) je projekt CNCF pro řízení klastrů Více Kubernetes. Umožňuje vám distribuovat pracovní zátěže mezi více klastrů ve více oblastech s sofistikované politiky. V kombinaci s údaji o intenzitě uhlíku v reálném čase se stává motorem víceregionální uhlíkové směrování.
Multiregionální architektura GreenOps
# Struttura del setup Karmada multi-cluster
#
# karmada-control-plane (hub)
# ├── cluster-eu-north-1 (Stoccolma - 15-40 gCO2/kWh)
# ├── cluster-eu-west-1 (Irlanda - 100-250 gCO2/kWh)
# ├── cluster-us-west-2 (Oregon - 50-150 gCO2/kWh, molto rinnovabili)
# └── cluster-us-east-1 (Virginia - 300-400 gCO2/kWh)
#
# PropagationPolicy determina dove gira il workload in base a carbon intensity
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
name: ml-training-carbon-routing
namespace: ml-workloads
annotations:
greenops.io/routing-strategy: "carbon-optimized"
spec:
resourceSelectors:
- apiVersion: batch/v1
kind: Job
labelSelector:
matchLabels:
workload-type: "ml-training"
greenops/deferrable: "true"
placement:
clusterAffinity:
# Preferenza ordinata per carbon intensity (aggiornata dal carbon-router)
clusterNames:
- cluster-eu-north-1 # Prima scelta: Svezia (sempre verde)
- cluster-us-west-2 # Seconda: Oregon (molto rinnovabili)
- cluster-eu-west-1 # Terza: Irlanda (mediamente verde)
- cluster-us-east-1 # Ultima: Virginia (carbon-intensive)
replicaScheduling:
replicaSchedulingType: Duplicated
# Non divisibile: il job va su UN cluster, quello più verde
Carbon Router: Dynamická aktualizace zásad Karmada
#!/usr/bin/env python3
# carbon_router.py - Aggiorna la PropagationPolicy Karmada in base alla carbon intensity
# Eseguito ogni ora da un CronJob nel control plane
import os
import json
import requests
import logging
from typing import Dict, List, Tuple
from kubernetes import client, config
from kubernetes.client.rest import ApiException
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("carbon-router")
CARBON_SDK_URL = os.getenv("CARBON_SDK_URL", "http://carbon-aware-sdk:8080")
# Mapping cluster -> location ElectricityMaps/WattTime
CLUSTER_LOCATIONS: Dict[str, str] = {
"cluster-eu-north-1": "SE", # Svezia
"cluster-eu-west-1": "IE", # Irlanda
"cluster-us-west-2": "US-NW", # Pacific Northwest
"cluster-us-east-1": "US-MIDA", # Mid-Atlantic
}
def fetch_carbon_intensity(location: str) -> float:
"""Recupera carbon intensity corrente per una location."""
url = f"{CARBON_SDK_URL}/emissions/bylocation"
params = {"location": location}
try:
r = requests.get(url, params=params, timeout=8)
r.raise_for_status()
data = r.json()
if data:
return float(data[0].get("rating", 999.0))
except Exception as e:
logger.error(f"Impossibile recuperare carbon intensity per {location}: {e}")
return 999.0 # Valore di fallback: considera come molto carbon-intensive
def rank_clusters_by_carbon() -> List[Tuple[str, float]]:
"""Ordina i cluster dalla carbon intensity più bassa alla più alta."""
intensities: List[Tuple[str, float]] = []
for cluster, location in CLUSTER_LOCATIONS.items():
intensity = fetch_carbon_intensity(location)
intensities.append((cluster, intensity))
logger.info(f"{cluster} ({location}): {intensity:.1f} gCO2/kWh")
intensities.sort(key=lambda x: x[1])
return intensities
def update_propagation_policy(ranked_clusters: List[Tuple[str, float]]) -> None:
"""Aggiorna la clusterNames nella PropagationPolicy Karmada."""
# Karmada usa CRD custom - accesso via dynamic client
config.load_incluster_config()
dynamic_client = client.ApiClient()
# Lista ordinata per il patch
cluster_names = [c[0] for c in ranked_clusters]
patch_body = {
"spec": {
"placement": {
"clusterAffinity": {
"clusterNames": cluster_names
}
}
}
}
# Annota la policy con i dati correnti per audit
timestamp = __import__("datetime").datetime.utcnow().isoformat()
patch_body["metadata"] = {
"annotations": {
"greenops.io/last-routing-update": timestamp,
"greenops.io/carbon-ranking": json.dumps(
[{"cluster": c, "gco2_kwh": round(i, 1)} for c, i in ranked_clusters]
)
}
}
logger.info(f"Aggiornamento routing: ordine cluster = {cluster_names}")
# In produzione: usare kubernetes.client.CustomObjectsApi per patch Karmada CRD
if __name__ == "__main__":
ranked = rank_clusters_by_carbon()
logger.info("Classifica cluster per carbon intensity:")
for cluster, intensity in ranked:
logger.info(f" {cluster}: {intensity:.1f} gCO2/kWh")
update_propagation_policy(ranked)
Cloud Provider Carbon API: AWS, Google Cloud, Azure
Souběžně s open source nástroji vydali nebo vylepšili tři hlavní poskytovatelé cloudu významně své přirozené nástroje uhlíkové stopy. Situace v roce 2025 je velmi diverzifikované z hlediska vyspělosti a použitelnosti.
Porovnání rozhraní API poskytovatele cloudu uhlíkové stopy (2025)
| Poskytovatelé | Nástroj | Zrnitost | API? | Košťata | Aktualizovat |
|---|---|---|---|---|---|
| AWS | Nástroj uhlíkové stopy zákazníka | Účet, region, služba | Pouze export CSV | Rozsah 1, 2, 3 (od roku 2024) | Měsíčně (zpoždění 3 měsíce) |
| Google Cloud | Cloudová uhlíková stopa | Projekt, služba, region | Export do BigQuery + API | Rozsah 1, 2, 3 | Měsíčně (zpoždění 4 týdny) |
| Blankyt | Řídicí panel dopadu emisí společnosti Microsoft / optimalizace uhlíku | Předplatné, skupina zdrojů, služba | Kompletní REST API (2025) | Rozsah 1, 2, 3 | Měsíčně (zpoždění 2 měsíce) |
| Multi-cloud | Cloud Carbon Footprint (open source) | Účet, služba, region | Samoobslužné rozhraní REST API | Rozsah 2 (vlastní metodika) | Denní |
Azure Carbon Optimization REST API
Microsoft učinil nejvýznamnější krok v roce 2025 uvedením Carbon Optimalizace na Azure Portal, podporovaný kompletním REST API pro integraci vnitřní systémy. Příklad integrace:
#!/usr/bin/env python3
# azure_carbon_api.py
# Richiede: pip install azure-identity requests
import os
from azure.identity import DefaultAzureCredential
import requests
SUBSCRIPTION_ID = os.environ["AZURE_SUBSCRIPTION_ID"]
CREDENTIAL = DefaultAzureCredential()
def get_azure_carbon_emissions(
resource_group: str,
start_date: str,
end_date: str
) -> dict:
"""
Recupera emissioni CO2 per resource group tramite Azure Carbon Optimization API.
API endpoint (2025): https://management.azure.com/providers/Microsoft.Carbon/carbonEmissionReports
"""
token = CREDENTIAL.get_token("https://management.azure.com/.default").token
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
# Azure Carbon Optimization API (GA 2025)
url = (
f"https://management.azure.com/subscriptions/{SUBSCRIPTION_ID}"
f"/resourceGroups/{resource_group}"
f"/providers/Microsoft.Carbon/carbonEmissionReports"
f"?api-version=2023-04-01-preview"
)
payload = {
"reportType": "OverallSummaryReport",
"subscriptionList": [SUBSCRIPTION_ID],
"carbonScopeList": ["Scope1", "Scope2", "Scope3"],
"dateRange": {
"start": start_date, # "2025-01-01"
"end": end_date # "2025-03-01"
}
}
response = requests.post(url, json=payload, headers=headers, timeout=30)
response.raise_for_status()
return response.json()
def get_google_carbon_data(project_id: str, dataset: str = "carbon_footprint") -> None:
"""
Google Cloud esporta i dati carbon footprint in BigQuery automaticamente.
Abilita: Cloud Billing Export -> BigQuery -> Carbon Footprint
Query esempio BigQuery:
"""
bq_query = """
SELECT
usage_month,
service.description AS service,
location.region AS region,
SUM(carbon_footprint_kgCO2e.market_based) AS kg_co2e_market_based,
SUM(carbon_footprint_kgCO2e.location_based) AS kg_co2e_location_based
FROM
`{project_id}.{dataset}.carbon_footprint`
WHERE
usage_month BETWEEN '2025-01-01' AND '2025-03-31'
GROUP BY
usage_month, service, region
ORDER BY
kg_co2e_market_based DESC
"""
print(f"Esegui in BigQuery:\n{bq_query.format(project_id=project_id, dataset=dataset)}")
if __name__ == "__main__":
# Azure example
data = get_azure_carbon_emissions(
resource_group="production-rg",
start_date="2025-01-01",
end_date="2025-03-01"
)
print(f"Azure Carbon Emissions: {data}")
# Google BigQuery example
get_google_carbon_data("my-gcp-project")
Doporučená strategie pro uhlíková data
- Plánování v reálném čase: K rozhodování používejte Carbon Aware SDK + WattTime/ElectricityMaps v reálném čase na plánování s ohledem na uhlík
- Měsíční reporting: Použijte pro účetnictví nativní nástroje poskytovatele cloudu Oficiální CO₂ (rozsah 1/2/3) požadované pro hlášení CSRD/ESG
- Multi-cloud: Použijte open source Cloud Carbon Footprint k agregaci dat z více poskytovatele důsledně
- Provozní upozornění: Použijte Kepler + Prometheus pro upozornění v reálném čase na špičky spotřeby energie na lusk
Kepler: Měření spotřeby energie na modul
Kepler (Efficient Power Level Exporter založený na Kubernetes) je projekt CNCF který měří spotřebu energie na úrovni kontejneru, podu a uzlů v clusteru Kubernetes a exportuje metriky do Promethea. Je to základní složka pro zviditelnění emisí provozní úroveň: Bez Keplera je tým DevOps slepý k emisím na pracovní zátěž a nemůže dělat GreenOps efektivně.
Kepler používá rozšířený přístup Berkeley Packet Filter (eBPF) ke sledování spotřeby zdrojů hardware na úrovni jádra, který kombinuje data z RAPL (Průběžný limit průměrného výkonu, rozhraní Intel/AMD pro spotřebu CPU), ACPI pro spotřebu systému a senzory NVIDIA NVML pro GPU. U poskytovatelů cloudu, kde fyzické hardwarové senzory nejsou přístupné, Kepler používá predikční modely založené na dostupných metrikách CPU.
Od verze 0.10.0 (2025) prošel Kepler kompletním přepsáním architektury interní, což zlepšuje přesnost předpovědí na cloudových virtuálních počítačích a snižuje režii DaemonSet z cca 5 % až méně než 2 % CPU.
Instalace Kepler s Helm
# Installazione Kepler con Helm (metodo raccomandato)
# 1. Prerequisiti: Prometheus Operator (o stack kube-prometheus)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--set grafana.enabled=true \
--set alertmanager.enabled=true
# 2. Installa Kepler dal registry OCI (stable)
helm install kepler oci://quay.io/sustainable_computing_io/charts/kepler \
--namespace kepler \
--create-namespace \
--set serviceMonitor.enabled=true \
--set serviceMonitor.namespace=monitoring \
--set serviceMonitor.jobLabel=kepler \
--version 0.5.9 # verifica ultima versione su quay.io
# 3. Verifica che il DaemonSet sia running su tutti i nodi
kubectl get daemonset -n kepler
# Expected: kepler-kepler con DESIRED=N, READY=N
# 4. Verifica raccolta metriche
kubectl port-forward -n kepler svc/kepler-internal 8888:8888 &
curl http://localhost:8888/metrics | grep kepler_container_
# Output atteso:
# kepler_container_joules_total{container_name="...",namespace="...",pod_name="..."}
# kepler_container_cpu_joules_total{...}
# kepler_container_dram_joules_total{...}
# kepler_container_gpu_joules_total{...}
Hlavní Keplerova metrika
Kepler Metrics Essential for GreenOps
| Metrický | Popis | Jednotka | Případ použití |
|---|---|---|---|
kepler_container_joules_total |
Celková energie spotřebovaná kontejnerem od spuštění | jouly (počítadlo) | Energie na lusk za určité časové období |
kepler_container_cpu_joules_total |
Energie spotřebovaná CPU pro kontejner | jouly (počítadlo) | Identifikujte vysoce výkonné zátěže vázané na CPU |
kepler_container_dram_joules_total |
Energie spotřebovaná RAM pro kontejner | jouly (počítadlo) | Analýza zátěže vázané na paměť |
kepler_container_gpu_joules_total |
Spotřeba energie GPU (vyžaduje NVIDIA) | jouly (počítadlo) | Sledování spotřeby tréninku ML |
kepler_node_core_joules_total |
Celková energie uzlu na jádro CPU | jouly (počítadlo) | Efektivita uzlu, základní spotřeba |
kepler_node_package_joules_total |
Celková energie balíčku CPU (všechna jádra) | jouly (počítadlo) | Výpočet PUE, celková spotřeba uzlu |
kepler_container_watts |
Okamžitý výkon kontejneru | Watty (měřidlo) | Upozornění na energetické špičky v reálném čase |
Dotazy PromQL pro GreenOps
# Query Prometheus per analisi GreenOps con Kepler
# 1. Energia totale per namespace (kWh nell'ultima ora)
sum by (namespace) (
increase(kepler_container_joules_total[1h])
) / 3600000
# 2. Top 10 pod per consumo energetico (Watt medi ultima ora)
topk(10,
avg by (pod_name, namespace) (
rate(kepler_container_joules_total[1h]) * 1000
)
)
# 3. CO2e per namespace (assumendo carbon intensity 200 gCO2/kWh)
# Sostituisci 200 con il valore real-time da Carbon Aware SDK
sum by (namespace) (
increase(kepler_container_joules_total[24h])
) / 3600000 * 200 / 1000 # risultato in kgCO2e
# 4. Efficienza energetica: Joule per richiesta HTTP (se hai metriche app)
sum(rate(kepler_container_joules_total[5m])) by (pod_name)
/
sum(rate(http_requests_total[5m])) by (pod_name)
# 5. Alert: pod con consumo energetico anomalo (>50W per 15min)
avg_over_time(
sum by (pod_name, namespace) (
kepler_container_watts
)[15m:1m]
) > 50
# 6. Trend consumo cluster (kWh/giorno ultimi 7 giorni)
sum(increase(kepler_node_package_joules_total[1d])) / 3600000
Grafana Dashboard pro GreenOps
Projekt Kepler poskytuje předpřipravené řídicí panely Grafana, které lze přímo importovat. Konfigurace doporučeno kombinuje Keplerovy metriky s údaji o intenzitě uhlíku k vytvoření integrovaného pohledu:
# grafana-dashboard-greenops.yaml
# ConfigMap con dashboard Grafana per GreenOps
apiVersion: v1
kind: ConfigMap
metadata:
name: greenops-dashboard
namespace: monitoring
labels:
grafana_dashboard: "1" # Label per auto-discovery Grafana
data:
greenops-cluster.json: |
{
"title": "GreenOps Cluster Dashboard",
"panels": [
{
"title": "Carbon Intensity Corrente (gCO2/kWh)",
"type": "stat",
"targets": [
{
"expr": "carbon_intensity_g_co2_kwh",
"legendFormat": "Carbon Intensity"
}
],
"thresholds": {
"steps": [
{"color": "green", "value": 0},
{"color": "yellow", "value": 150},
{"color": "orange", "value": 300},
{"color": "red", "value": 450}
]
}
},
{
"title": "kWh Cluster (ultima ora)",
"type": "stat",
"targets": [
{
"expr": "sum(increase(kepler_node_package_joules_total[1h])) / 3600000",
"legendFormat": "kWh"
}
]
},
{
"title": "kgCO2e Cluster (ultima ora)",
"type": "stat",
"targets": [
{
"expr": "sum(increase(kepler_node_package_joules_total[1h])) / 3600000 * carbon_intensity_g_co2_kwh / 1000",
"legendFormat": "kgCO2e"
}
]
},
{
"title": "Top Namespace per Consumo (kWh/h)",
"type": "bargauge",
"targets": [
{
"expr": "topk(10, sum by (namespace) (rate(kepler_container_joules_total[1h])) / 3600)",
"legendFormat": "{{namespace}}"
}
]
}
]
}
Zelená CI/CD: GitHub Actions Carbon-Aware
Potrubí CI/CD jsou ideálními kandidáty pro plánování s ohledem na uhlík: sestavení, které se spustí každé stisknutí se nemusí nutně provést ihned. Sestavení hlavní větve, tj komplexní regresní testování, generování artefaktů, nasazení do pracovních prostředí – to vše mají měřitelnou toleranci zpoždění, často hodin. Přesuňte tato potrubí do oken Nízká uhlíková intenzita vyžaduje velmi malé úsilí a může snížit emise CI/CD 20-40 %.
Akce GitHubu s plánováním Carbon-Aware
# .github/workflows/carbon-aware-build.yml
# Build carbon-aware: verifica carbon intensity prima di eseguire
name: Carbon-Aware Build Pipeline
on:
push:
branches: [main, develop, 'feature/**']
workflow_dispatch:
inputs:
force_run:
description: 'Forza esecuzione ignorando carbon intensity'
type: boolean
default: false
jobs:
# Job 1: Verifica carbon intensity e decide se eseguire ora o schedulare
carbon-check:
runs-on: ubuntu-latest
outputs:
should_run_now: ${{ steps.check.outputs.should_run_now }}
carbon_intensity: ${{ steps.check.outputs.carbon_intensity }}
next_green_window: ${{ steps.check.outputs.next_green_window }}
steps:
- name: Check Carbon Intensity
id: check
run: |
# Forza esecuzione su main o se force_run=true
if [[ "${{ github.ref }}" == "refs/heads/main" ]] || \
[[ "${{ inputs.force_run }}" == "true" ]]; then
echo "should_run_now=true" >> $GITHUB_OUTPUT
echo "carbon_intensity=forced" >> $GITHUB_OUTPUT
exit 0
fi
# Interroga Carbon Aware SDK (self-hosted o public endpoint)
CARBON_SDK_URL="${{ secrets.CARBON_AWARE_SDK_URL }}"
LOCATION="${{ vars.GRID_LOCATION }:-DE}" # Germania di default
THRESHOLD=150 # gCO2/kWh soglia accettabile
INTENSITY=$(curl -sf \
"${CARBON_SDK_URL}/emissions/bylocation?location=${LOCATION}" \
| jq '.[0].rating // 999' 2>/dev/null || echo "999")
echo "carbon_intensity=${INTENSITY}" >> $GITHUB_OUTPUT
if (( $(echo "${INTENSITY} < ${THRESHOLD}" | bc -l) )); then
echo "Carbon intensity ${INTENSITY} gCO2/kWh - sotto soglia ${THRESHOLD}, eseguo ora"
echo "should_run_now=true" >> $GITHUB_OUTPUT
else
echo "Carbon intensity ${INTENSITY} gCO2/kWh - sopra soglia, cerco finestra verde"
NEXT_WINDOW=$(curl -sf \
"${CARBON_SDK_URL}/emissions/forecasts/best?location=${LOCATION}&windowSize=60" \
| jq -r '.[0].optimalDataPoints[0].timestamp // empty' 2>/dev/null)
echo "should_run_now=false" >> $GITHUB_OUTPUT
echo "next_green_window=${NEXT_WINDOW}" >> $GITHUB_OUTPUT
fi
- name: Annotate with Carbon Data
if: always()
run: |
echo "::notice::Carbon Intensity: ${{ steps.check.outputs.carbon_intensity }} gCO2/kWh"
echo "::notice::Prossima finestra verde: ${{ steps.check.outputs.next_green_window }}"
# Job 2: Build (eseguita solo se carbon intensity e bassa)
build:
needs: carbon-check
if: needs.carbon-check.outputs.should_run_now == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
NODE_ENV: production
- name: Test
run: npm test -- --coverage
- name: Carbon annotation
run: |
echo "::notice::Build eseguita con carbon intensity: ${{ needs.carbon-check.outputs.carbon_intensity }} gCO2/kWh"
Odhadněte emise CI/CD
Kromě přesunu budov do zelených oken je užitečné měřit skutečné emise CI/CD potrubí. Provozovatelé hostované na GitHubu spotřebují přibližně 0,05–0,2 kWh za hodinu sestavení, v závislosti na typ běžce. Zde je akční krok k odhadu a zaznamenání emisí:
# Step da aggiungere alla fine di ogni workflow
- name: Estimate CI Carbon Footprint
run: |
# Stima durata job in minuti (GitHub fornisce start time)
START_TIME="${{ steps.start-time.outputs.time }}"
END_TIME=$(date -u +%s)
DURATION_MINUTES=$(( (END_TIME - START_TIME) / 60 ))
# Runner ubuntu-latest: ~0.15 kWh/ora (stima conservativa)
RUNNER_POWER_KWH_PER_HOUR=0.15
ENERGY_KWH=$(echo "scale=6; $DURATION_MINUTES / 60 * $RUNNER_POWER_KWH_PER_HOUR" | bc)
# Carbon intensity: usa il valore del carbon-check job
CARBON_INTENSITY="${{ needs.carbon-check.outputs.carbon_intensity }}"
CO2_G=$(echo "scale=2; $ENERGY_KWH * $CARBON_INTENSITY" | bc 2>/dev/null || echo "N/A")
echo "=== GreenOps CI Report ==="
echo "Durata build: ${DURATION_MINUTES} min"
echo "Energia stimata: ${ENERGY_KWH} kWh"
echo "Carbon intensity: ${CARBON_INTENSITY} gCO2/kWh"
echo "Emissioni stimate: ${CO2_G} gCO2e"
echo "========================="
# Scrivi su GitHub Step Summary per visibilità nel report
echo "## GreenOps CI Report" >> $GITHUB_STEP_SUMMARY
echo "| Metrica | Valore |" >> $GITHUB_STEP_SUMMARY
echo "|---------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| Durata | ${DURATION_MINUTES} min |" >> $GITHUB_STEP_SUMMARY
echo "| Energia | ${ENERGY_KWH} kWh |" >> $GITHUB_STEP_SUMMARY
echo "| Carbon Intensity | ${CARBON_INTENSITY} gCO2/kWh |" >> $GITHUB_STEP_SUMMARY
echo "| Emissioni | ${CO2_G} gCO2e |" >> $GITHUB_STEP_SUMMARY
Dashboard FinOps + GreenOps: Cena a uhlík dohromady
Vyspělost organizace GreenOps se také měří její schopností korelace metriky nákladů a emisí v jediném pohledu. Týmy spravující tyto dimenze samostatně dělají neoptimální rozhodnutí: přizpůsobení, které snižuje náklady o 20 %, nemusí mít žádný dopad na emise, pokud jsou úspory reinvestovány v případech v regionech s vysokými emisemi uhlíku. naopak přesun umístění do zelenějšího regionu může zvýšit náklady na přemístění údaje rušící ekonomický přínos.
Ideální integrace kombinuje Kubecost (cena za pod/jmenný prostor) s Kepler (energie na modul/jmenný prostor) v jediném přístrojovém panelu Grafana, obohaceném o údaje o intenzitě uhlíku v reálném čase vypočítat skutečné uhlíkové náklady každého pracovního zatížení.
# Esempio query PromQL per dashboard costo+carbonio unificato
# Assume Kubecost + Kepler + carbon_intensity_g_co2_kwh (da ConfigMap exporter)
# Costo + CO2e per namespace (ultimi 30 giorni)
# Kubecost espone: kubecost_cluster_hourly_cost_by_namespace
# Kepler espone: kepler_container_joules_total
# Costo giornaliero per namespace (USD)
sum by (namespace) (
kubecost_cluster_hourly_cost_by_namespace * 24
)
# CO2e giornaliero per namespace (kgCO2e)
sum by (namespace) (
increase(kepler_container_joules_total[24h])
) / 3600000 # Joule -> kWh
* on() group_left() (carbon_intensity_g_co2_kwh / 1000) # -> kgCO2e
# "Green Efficiency Score" per namespace
# Combina efficienza costo e efficienza carbonica (più alto e meglio)
(
sum by (namespace) (rate(http_requests_total[1h])) # throughput
)
/
(
sum by (namespace) (kubecost_cluster_hourly_cost_by_namespace) # costo
*
(sum by (namespace) (rate(kepler_container_joules_total[1h])) / 3600) # energia kW
* on() group_left() carbon_intensity_g_co2_kwh
)
Základní GreenOps KPI ke sledování
- Aktuální uhlíková intenzita (gCO₂/kWh): údaje z elektrické sítě v reálném čase
- klastr kgCO₂e/hod: souhrnné emise klastru
- kWh/poptávka: energetická účinnost na jednotku práce
- gCO₂e/poptávka: uhlíková stopa podle obchodní jednotky
- % zátěže v zelených oknech: procento dávkových úloh provedených s CI < prahová hodnota
- Náklady/kg CO₂e ušetřené: ROI iniciativ GreenOps
- Odhadovaný PUE: Spotřeba energie Efektivita clusteru (cíl < 1,2)
- Nečinné plýtvání energií: Energie spotřebovaná nedostatečně využívanými moduly/uzly
Případová studie: 35% snížení emisí na 50 clusterech uzlů
Následující případová studie shrnuje skutečné výsledky evropské společnosti SaaS s klastrem Produkční Kubernetes sestávající z 50 uzlů (mix c5.4xlarge a m5.2xlarge na AWS us-east-1), který spravuje kanály pro analýzu dat, školení modelů ML a rozhraní API.
Počáteční profil clusteru (základní hodnota)
| Metrický | Výchozí hodnota | Hodnota po GreenOps (3 měsíce) | Snížení |
|---|---|---|---|
| Emise CO₂e/měsíc | 12,4 t CO2e | 8,1 t CO2e | -35 % |
| Cena cloudu/měsíc | 47 200 dolarů | 38 900 dolarů | -17,6 % |
| Průměrné využití CPU | 23 % | 41 % | +78 % (efektivita) |
| Nečinné uzly (noc) | 35 uzlů z 50 | 8 uzlů z 50 (minový cluster) | -78 % nečinných uzlů |
| % dávkových úloh v zelených oknech | 0 % (neměřeno) | 68 % | +68pp |
| kgCO₂e/1000 požadavků API | 0,84 | 0,55 | -35 % |
Akce prováděné v chronologickém pořadí
Program GreenOps byl implementován ve třech fázích během 12 týdnů:
# FASE 1 - Settimane 1-4: Visibility
# Obiettivo: rendere visibili le emissioni, nessuna modifica ai workload
# 1.1 Deploy Kepler DaemonSet
helm install kepler oci://quay.io/sustainable_computing_io/charts/kepler \
--namespace kepler --create-namespace
# 1.2 Configura ServiceMonitor per Prometheus
kubectl apply -f kepler-service-monitor.yaml
# 1.3 Import dashboard Grafana ufficiale Kepler
# Dashboard ID: 16117 (Kepler Exporter Grafana Dashboard)
# 1.4 Deploy carbon intensity exporter
kubectl apply -f carbon-intensity-exporter.yaml
# Risultato dopo 2 settimane di osservazione:
# - 12 namespace identificati, 3 consumano 78% dell'energia
# - Pipeline ETL notturna: 8.2 kW per 4 ore ogni notte
# - 35 nodi idle dalle 22:00 alle 07:00 (weekdays), tutto il weekend
# ============================================================
# FASE 2 - Settimane 5-8: Quick Wins
# Obiettivo: implementare ottimizzazioni immediate
# 2.1 Cluster Autoscaler + Karpenter per nodi dinamici
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter \
--namespace kube-system \
--set settings.aws.clusterName=production-cluster
# NodePool ottimizzato GreenOps
cat <<EOF | kubectl apply -f -
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: greenops-batch
spec:
template:
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"] # Spot instances: 70% risparmio
- key: kubernetes.io/arch
operator: In
values: ["arm64"] # Graviton3: 40% più efficiente di x86
nodeClassRef:
group: karpenter.k8s.aws
kind: EC2NodeClass
name: graviton-nodes
disruption:
consolidationPolicy: WhenEmptyOrUnderutilized
consolidateAfter: 30s # Rimuovi nodi idle rapidamente
EOF
# 2.2 Namespace sleep per ambienti non-prod (kube-green)
helm install kube-green kube-green/kube-green --namespace kube-green --create-namespace
cat <<EOF | kubectl apply -f -
apiVersion: kube-green.com/v1alpha1
kind: SleepInfo
metadata:
name: staging-nighttime-sleep
namespace: staging
spec:
weekdays: "1-5" # Lunedi-Venerdi
sleepAt: "20:00"
wakeUpAt: "08:00"
timeZone: "Europe/Rome"
suspendCronJobs: true
EOF
# Risparmio stimato: 12 ore/giorno x 5 giorni x 8 nodi staging = 480 nodo-ore/settimana
# ============================================================
# FASE 3 - Settimane 9-12: Carbon-Aware Scheduling
# Obiettivo: spostare batch jobs nelle finestre verdi
# 3.1 Deploy Carbon Aware KEDA Operator
kubectl apply -f https://github.com/Azure/carbon-aware-keda-operator/releases/latest/download/operator.yaml
# 3.2 Configura CarbonAwareKedaScaler per pipeline ETL
kubectl apply -f carbon-aware-etl-scaler.yaml
# 3.3 Carbon-aware scheduler per training jobs
# (Python controller dal Paragrafo 3 - eseguito come CronJob ogni ora)
kubectl apply -f carbon-aware-scheduler-cronjob.yaml
Analýza výsledků
Snížení emisí o 35 % bylo rozděleno mezi různé iniciativy následovně:
- Správná velikost a konsolidace uzlů (Karpenter + Graviton3): -18% emise. Přechod na instance Graviton3 arm64 snížil spotřebu energie na výpočetní jednotku o 40 %. Konsolidační politika společnosti Karpenter odstranila 27 nevyužitých uzlů.
- kube-green pro prostředí staging/dev: -9% emisí. Neproduktivní prostředí byly aktivní 24 hodin denně, 7 dní v týdnu a z velké části spotřebovávaly 22 % celkové energie klastru v hodinách, kdy je nikdo nepoužíval.
- Dávkové úlohy plánování s ohledem na uhlík: -8% emisí. 68 % dávkových úloh je nyní naplánováno v oknech, ve kterých má síť USA-východ-1 intenzitu uhlíku nižší než 150 gCO₂/kWh.
Nejvýznamnější údaje z provozního hlediska: Úspora nákladů 8 300 $ měsíčně (-17,6 %) z velké části pokryla náklady na implementaci programu GreenOps (přibližně 3 týdny inženýrství) do 4 týdnů. Obchodní případ pro GreenOps již nevyžaduje být odůvodněné čistě z hlediska ochrany životního prostředí.
Upozornění: Před optimalizací změřte
40 % týmů, které implementují GreenOps bez počáteční fáze viditelnosti, věci optimalizuje špatně. V této případové studii se předpokládalo, že hlavním spotřebitelem je školení ML energie – místo toho to byly noční ETL potrubí a neustále zapnutá prostředí. Kepler odhalil pravdu za 2 týdny. Nasaďte Keplera, než uděláte cokoliv jiného.
GreenOps Anti-Pattern: Čemu se vyhnout
Zkušenosti z terénu odhalily opakující se chyby, které negují výhody programů GreenOps nebo v horším případě vytvářejí falešný pocit udržitelnosti bez skutečného snížení emisí.
Nejběžnější anti-vzory GreenOps
| Anti-vzor | Popis | Dopad | Řešení |
|---|---|---|---|
| Carbon Offseting bez redukce | Nakupujte uhlíkové kredity namísto snižování provozních emisí | Reálné emise beze změny, minimální dopad | Vždy upřednostňujte Vyhnout se > Snížit > Posun (rámec GSF) |
| Průměrná vs. marginální intenzita | Při rozhodování používejte průměrnou uhlíkovou intenzitu namísto marginální | Špatné optimalizace: okrajový zdroj je ten, který je přidán/odebrán | Použít údaje o limitní intenzitě uhlíku z WattTime (vyžaduje předplatné) |
| Optimalizujte bez měření | Implementujte škálování s ohledem na uhlík bez Keplerových základních linií | Skutečný dopad nelze ověřit | Před optimalizací nasaďte Kepler alespoň na 2 týdny od výchozího stavu |
| Ignorujte efekt odrazu | Ušetřete emise na jednom pracovním zatížení a zvyšte je na jiném | Nulová nebo záporná čistá výhoda | Monitorování na úrovni clusteru, nikoli jednotlivá pracovní zátěž |
| S ohledem na uhlík při neodložitelném pracovním zatížení | Aplikujte uhlíkový strop také na uživatelsky orientovaná API | Snížení výkonu, porušení SLA | Důsledně klasifikuje odloženou zátěž a zátěž v reálném čase |
| Pouze rozsah 2 | Měřte pouze provozní spotřebu energie, ignorujte rozsah 3 | Výrazné podcenění skutečné stopy | Zahrnout ztělesněný uhlík hardwaru a přenosu dat |
| Dashboard bez akce | Nainstalujte Kepler a Grafana, ale nedefinujte uhlík SLO | Krásné metriky, nulové zlepšení | Definujte Carbon SLO pro každý jmenný prostor s upozorněním na porušení |
Carbon SLO: Cíle úrovně služeb pro emise
Nejúčinnějším vzorem pro institucionalizaci GreenOps je definovat Karbon SLO pro jmenný prostor/tým přesně tak, jak jsou definovány SLO latence a dostupnosti. Carbon SLO transformuje udržitelnost z vágní aspirace na měřitelný cíl s jasnou odpovědností:
# carbon-slo.yaml
# Carbon SLO implementato come PrometheusRule
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: carbon-slo-rules
namespace: monitoring
spec:
groups:
- name: carbon.slo
interval: 5m
rules:
# SLO: namespace "ml-training" deve stare sotto 50 kgCO2e/giorno
- alert: CarbonSLOViolation_MLTraining
expr: |
sum(
increase(kepler_container_joules_total[24h])
) by (namespace) / 3600000
* on() group_left() (carbon_intensity_g_co2_kwh / 1000)
> 50
for: 1h
labels:
severity: warning
greenops: "true"
annotations:
summary: "Carbon SLO violato: namespace ml-training"
description: |
Il namespace ml-training ha emesso {{ $value | printf "%.1f" }} kgCO2e oggi,
sopra il SLO di 50 kgCO2e/giorno.
Carbon intensity corrente: {{ with query "carbon_intensity_g_co2_kwh" }}{{ . | first | value }}{{ end }} gCO2/kWh
# Trend: emissioni cluster in crescita per 3 giorni consecutivi
- alert: CarbonTrendIncrease
expr: |
(
sum(rate(kepler_node_package_joules_total[24h]))
-
sum(rate(kepler_node_package_joules_total[24h] offset 72h))
)
/ sum(rate(kepler_node_package_joules_total[24h] offset 72h)) > 0.15
for: 6h
labels:
severity: info
greenops: "true"
annotations:
summary: "Trend emissioni cluster in aumento"
description: "Emissioni cluster aumentate del {{ $value | humanizePercentage }} nelle ultime 72 ore"
GreenOps Roadmap: Od začátečníka k řízenému daty
Přijetí GreenOps nevyžaduje, abyste implementovali vše najednou. Cesta se vyvíjí ve fázích progresivní, z nichž každý přináší měřitelnou hodnotu, než bude vyžadovat další investice.
Vyspělost GreenOps: 4 úrovně
| Úroveň | Jméno | Charakteristika | Typická časová osa | Očekávané snížení CO₂ |
|---|---|---|---|---|
| 1 | Viditelnost | Nainstalován Kepler, první metriky v Grafaně, definovány Carbon SLO (zatím nevynuceno) | 2-4 týdny | 0 % (pouze měření) |
| 2 | Rychlé výhry | Správná velikost, zelená kube pro nevýrobní prostředí, optimalizovaný cluster autoscaler, Graviton/ARM64 | 1-2 měsíce | 15–25 % |
| 3 | Plánování s ohledem na uhlík | KEDA uhlíkový scaler, uhlíkový plánovač CronJob, Green CI/CD, Carbon SLO vynuceno | 2-3 měsíce | 25–40 % |
| 4 | Multiregionální optimalizace | Karmada posouvání polohy, uhlíkově optimalizované směrování přenosu dat, úplné účtování rozsahu 3 | 4-6 měsíců | 35–60 % |
Úroveň 1 (Viditelnost) je nejdůležitějším a často nejvíce přehlíženým krokem. Nemůžete optimalizovat to, co neměříte: dva týdny dat Kepler odhalí vždy neočekávané příležitosti – zapomenutá prostředí, úlohy, které běží ve smyčkách, jmenné prostory s nafouknutými nároky na CPU, které neodpovídají skutečnému využití. Tyto objevy z pouze odůvodňují investici do instalace Kepler.
Závěry
GreenOps není luxus pro společnosti, které chtějí vypadat zeleně: je to disciplína vyspělé inženýrství, které přináší přímé a měřitelné ekonomické výhody a které se brzy stane povinné pro společnosti podléhající směrnici Evropské unie CSRD. Rozsah 2 emisí cloud computing — emise z elektřiny spotřebované datovými centry — jsou již dnes povinná položka výpisu pro tisíce evropských společností a granularita vyžadované rámci ESRS stále více klesá na úroveň individuálních pracovních zátěží.
Sada nástrojů GreenOps pro Kubernetes je dnes překvapivě vyspělá: Kepler pro měření energie na modul, Carbon Aware operátor KEDA pro škálování s vědomím uhlíku, Carbon Aware SDK od Green Software Foundation za data z uhlíková intenzita v reálném čase, Karmada pro změnu polohy multi-cluster. Všechny tyto nástroje jsou open source, aktivní a široce používané v produkci organizací.
Výchozí bod je vždy stejný: nainstalujte Kepler, podívejte se na data za dva týdny a nechat realitu řídit priority. Zkušenosti ukazují, že 70 % rychlých vyhrává GreenOps je identifikován během prvních 14 dnů pozorování. A jako v případové studii tohoto článku, ekonomická ROI činí celý program samofinancovatelným během 1-2 měsíců.
Green Software Engineering Series pokračuje
- Předchozí článek (5): Rozsah 3 a potrubí ESG – emise proti proudu e navazující, datový kanál pro soulad s CSRD
- Další článek (7): Rozsah 1, 2, 3 modelování — účetní rámce Protokol GHG, SBTi Net-Zero Standard, modelovací nástroje
- Související se sérií MLOps: Optimalizujte trénink ML pro snížení uhlíku footprint — kvantizace, prořezávání, výběr hardwaru
- Související v sérii Data & AI Business: Datové centrum a udržitelnost — PUE, WUE, nákup obnovitelné energie pro malé a střední podniky
Zdroje a reference
- Kepler na GitHubu — Efficient Power Level Exporter založený na Kubernetes
- Carbon Aware KEDA Operator — Azure/Microsoft
- Carbon Aware SDK — Green Software Foundation (licence MIT)
- Projekt Kepler — CNCF Sandbox
- Cloud Carbon Footprint — Open source multi-cloudový nástroj
- GreenOps a FinOps: Duální strategie pro udržitelnou umělou inteligenci — Nový balíček
- Green Software Foundation — Specifikace a zdroje SCI







