Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for metrics API #492

Open
deepu105 opened this issue Apr 15, 2021 · 17 comments
Open

Add support for metrics API #492

deepu105 opened this issue Apr 15, 2021 · 17 comments
Labels
api Api abstraction related blocked awaiting upstream work docs unclear documentation

Comments

@deepu105
Copy link

Is there a way to use the metrics API for Kubernetes? In Go it is a separate package and I believe there is no Rust craete equivalent for that yet

https://kubernetes.io/docs/tasks/debug-application-cluster/resource-metrics-pipeline/

@MikailBag
Copy link
Contributor

kube::Client and kube::Api can work with metrics API (as with any other API). If you are ready to work with untyped JSON, than you can use e.g.:

let gvk = GroupVersionKind::gvk("metrics.k8s.io", "v1beta1" /*IIRC*/, "nodemetrics");
let node_metrics: Api<DynamicObject> = Api::all_with(client.clone(), &gvk);
let metrics_list = node_metrics.list(...).await?;
// now metrics_list is essentially Vec<Json>
...

You may also want typed API (like the one you have for core or apps). But in fact, Kubernetes API typings are provided not by kube itself, but by the k8s-openapi crate.

That's why i think that k8s-openapi repository can be a better place for this issue.

@clux clux added the api Api abstraction related label Apr 15, 2021
@clux
Copy link
Member

clux commented Apr 15, 2021

It's also possible that we can simplify how we implement Resource so that you can use Api<MyMetricType> as long as we can impl Resource for MyMetricType where DynamicType = GroupVersionKind in an easy way.

I think we could have a middle ground between completely untyped, and k8s-openapi.

@deepu105
Copy link
Author

Btw for context. I'm building a Kubernetes terminal dashboard and was trying to use this. Btw if any of you are interested, please consider contributing. I'm quite new to rust and this lib so any help is appreciated

https://github.com/kdash-rs/kdash

@deepu105
Copy link
Author

It's also possible that we can simplify how we implement Resource so that you can use Api<MyMetricType> as long as we can impl Resource for MyMetricType where DynamicType = GroupVersionKind in an easy way.

I think we could have a middle ground between completely untyped, and k8s-openapi.

That would be nice

@theduke
Copy link

theduke commented Apr 23, 2021

There is a related (closed) issue in k8s-openapi: Arnavion/k8s-openapi#76

Seems like they don't want to support this.

@MikailBag
Copy link
Contributor

MikailBag commented Apr 23, 2021

Seems like they don't want to support this.

K8s-openapi maintainer has recently merged my PR which adds support for taking spec from arbitrary URL.
So ideally you should be able to take spec from a cluster with metrics-server enabled and get typings for metrics.k8s.io group.

The problem is, k8s-openapi seems to make many assumptions about REST operations, so code generation fails for aggregated apis.

As a next step, I'd try adding a parameter to k8s-openapi which completely skips client generation. I hope this will be enough to support non-builtin API groups.

@theduke
Copy link

theduke commented Apr 24, 2021

FWIW, here is an implementation for pod metrics that works for me with Api:

#[derive(serde::Deserialize, Clone, Debug)]
pub struct PodMetricsContainer {
    pub name: String,
    pub usage: PodMetricsContainerUsage,
}

#[derive(serde::Deserialize, Clone, Debug)]
pub struct PodMetricsContainerUsage {
    pub cpu: Quantity,
    pub memory: Quantity,
}

#[derive(serde::Deserialize, Clone, Debug)]
pub struct PodMetrics {
    pub metadata: ObjectMeta,
    pub timestamp: String,
    pub window: String,
    pub containers: Vec<PodMetricsContainer>,
}

impl k8s_openapi::Resource for PodMetrics {
    const GROUP: &'static str = "metrics.k8s.io";
    const KIND: &'static str = "pod";
    const VERSION: &'static str = "v1beta1";
    const API_VERSION: &'static str = "metrics.k8s.io/v1beta1";
}

impl k8s_openapi::Metadata for PodMetrics {
    type Ty = ObjectMeta;

    fn metadata(&self) -> &Self::Ty {
        &self.metadata
    }

    fn metadata_mut(&mut self) -> &mut Self::Ty {
        &mut self.metadata
    }
}
Api::<PodMetrics>::namespaces(client.clone(), "default").get("test-pod").await

@deepu105
Copy link
Author

deepu105 commented Jun 8, 2021

I ended up doing the below for Node metrics

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Usage {
    pub cpu: String,
    pub memory: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeMetrics {
  metadata: kube::api::ObjectMeta,
  usage: Usage,
  timestamp: String,
  window: String,
}

    let request = Request::new("/apis/metrics.k8s.io/v1beta1/nodes");
    client
      .clone()
      .request::<ObjectList<NodeMetrics>>(request.list(&ListParams::default()).unwrap())
      .await

@deepu105
Copy link
Author

deepu105 commented Jun 8, 2021

May be we can just document the solution from @theduke and close the ticket

@clux
Copy link
Member

clux commented Jun 21, 2021

Yeah, I think there are sufficiently short workarounds at the moment; create structs as above, impl kube::Resource in your source, or use it dynamically with an ApiResource.

Going to mark this as a wontfix for now. I think it would set a difficult precedent for us by trying to do every little peripheral thing in kubernetes ecosystems. I would rather encourage separate packages to help us with code-gen for non-core apis, and have us focus on as much of the generic/apimachinery-esque stuff as possible.

People should be able to find this solution/guidance by searching issues, but I think some kind of document classifying things you can do with kubernetes (in go world) and what the rust-counterparts require, would make sense as a follow-up action here.

@clux clux added docs unclear documentation wontfix This will not be worked on labels Jun 21, 2021
@deepu105
Copy link
Author

deepu105 commented Jun 21, 2021 via email

@clux clux added blocked awaiting upstream work and removed wontfix This will not be worked on labels Nov 3, 2021
@clux
Copy link
Member

clux commented Nov 3, 2021

We do actually grab the metrics structs in the new prototype k8s-pb repo. So we will have support for this once we get the protobuf issue #371 resolved. Absolutely no ETA on that though. It's a pretty big project.

@kazk
Copy link
Member

kazk commented Nov 3, 2021

Is there swagger.json for metrics? It has // +k8s:openapi-gen=true, but I don't know where the output is.

@clux
Copy link
Member

clux commented Nov 3, 2021

Only reference to it i see was removed from the repo. Following the trail:

Not sure if that's even relevant.

@clux
Copy link
Member

clux commented Nov 3, 2021

Maybe it's one of those structs that are only ever generated by the metrics-server and so we don't have it on disk. Maybe it needs to be run through https://github.com/kubernetes/kube-openapi ?

I have no idea here. There's very little documentation on this repo. But we might be able to get an answer in #sig-api-machinery or similar channel on the kubernetes slack.

@goenning
Copy link
Contributor

I'm on version 0.15 of the k8s-openapi and there are a few new required properties on the Resource trait, this is what worked for me:

impl k8s_openapi::Resource for PodMetrics {
    const GROUP: &'static str = "metrics.k8s.io";
    const KIND: &'static str = "PodMetrics";
    const VERSION: &'static str = "v1beta1";
    const API_VERSION: &'static str = "metrics.k8s.io/v1beta1";
    const URL_PATH_SEGMENT: &'static str = "pods";

    type Scope = k8s_openapi::NamespaceResourceScope;
}

The rest is just like as mentioned by @theduke above.

@imp
Copy link
Contributor

imp commented Jan 16, 2023

Fro the sake of reference while this is being sorted out - k8s-metrics crate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Api abstraction related blocked awaiting upstream work docs unclear documentation
Projects
None yet
Development

No branches or pull requests

7 participants