grafana / cloudcost-exporter

Prometheus Exporter for Cloud Provider agnostic cost metrics
Apache License 2.0
66 stars 4 forks source link

feat(gke): Implement basic GKE module #84

Closed Pokom closed 9 months ago

Pokom commented 10 months ago

Adds a new collector to the google family: gke_compute. It largely builds on top of the compute module but with one caveat: It is specifically searching for compute instances that belong to a GKE cluster. This took quite a bit of refactoring to mitigate the amount of code duplication.

High level refactors introduced:

There are two new metrics exported:

cloudcost_gcp_gke_node_cpu_usd_per_core_hour
cloudcost_gcp_gke_node_memory_usd_per_gib_hour

These share almost all of the same labels, with the addition of a cluster_name label which is set to the cluster the instance belongs to.

Pokom commented 10 months ago

You can run this PR with the following command:

go run cmd/exporter/exporter.go -provider=gcp -scrape-interval=1m -gcp.bucket-projects=grafanalabs-dev -gcp.services=gke 

Example metrics exporter are:

cloudcost_exporter_gke_node_info{cluster_name="dev-eu-west-3",instance_name="gke-dev-eu-west-3-main-n2s8-1-7127c190-1pjk",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-eu-west-3",instance_name="gke-dev-eu-west-3-main-n2s8-1-7127c190-4gfw",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-eu-west-3",instance_name="gke-dev-eu-west-3-main-n2s8-1-7127c190-m7lz",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-eu-west-3",instance_name="gke-dev-eu-west-3-main-n2s8-1-7127c190-p1hq",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-eu-west-3",instance_name="gke-dev-eu-west-3-main-n2s8-1-7127c190-r0xd",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-eu-west-3",instance_name="gke-dev-eu-west-3-main-n2s8-1-7127c190-wj13",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-cache-n2hc8-1-a0d9fa86-0n9p",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-cache-n2hc8-1-a0d9fa86-4v57",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-cache-n2hc8-1-a0d9fa86-dwdd",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-cache-n2hc8-1-a0d9fa86-sd2w",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-cache-n2hc8-1-a0d9fa86-sj4j",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-cache-n2hc8-1-a0d9fa86-zhzh",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-f8df2a60-znzh",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-fb691fe8-25gz",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-fb691fe8-4q57",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-fb691fe8-b260",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-fb691fe8-lp70",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-fb691fe8-x4dj",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-databenchloki-n2-fb691fe8-z111",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s4-7-497762a9-7dmb",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s4-7-497762a9-hc2x",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s4-7-497762a9-jgt7",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s4-7-497762a9-ttcw",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-2nd4",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-4rlh",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-5db5",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-7vdx",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-96m6",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-cc2g",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-jdvs",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-q9xs",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-r67w",project="grafanalabs-dev"} 1
cloudcost_exporter_gke_node_info{cluster_name="dev-us-central-0",instance_name="gke-dev-us-central-0-hg-n2s8-6-d8dc3ccc-vv2j",project="grafanalabs-dev"} 1

I'm going to collect some sample data into my grafana instance and then see if I can alter the kost queries and then compare the results between what we have in dev-cortex

Pokom commented 9 months ago

Like the implementation a lot. I think at this point we could just call the new package util ... as it also contains shared resources, which don't belong to billing.

@the-it I was a bit torn on that as well. In the latest commit though I've got it structured in such a way that we can have a dedicated billing module which is meant to have methods that call the billing provider(though technically I think this should be called cloudcatalog, but that's a different problem). I've left the pricing_map code within the compute module, as that's where it's most natural. There's no cyclical dependencies, code is shared pretty cleanly, and everything is looking good.