Open deepu105 opened 3 years ago
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.
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.
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
It's also possible that we can simplify how we implement
Resource
so that you can useApi<MyMetricType>
as long as we canimpl 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
There is a related (closed) issue in k8s-openapi: https://github.com/Arnavion/k8s-openapi/issues/76
Seems like they don't want to support this.
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.
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
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
May be we can just document the solution from @theduke and close the ticket
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.
Ya documentation sounds like a good solution as the current solutions mentioned here are good enough
On Mon, 21 Jun 2021, 8:24 pm Eirik A, @.***> wrote:
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.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/clux/kube-rs/issues/492#issuecomment-865249846, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIOKF5FFZAAQ5L2HZ5POYDTT57VDANCNFSM4274AIQQ .
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.
Is there swagger.json
for metrics? It has // +k8s:openapi-gen=true
, but I don't know where the output is.
Only reference to it i see was removed from the repo. Following the trail:
Not sure if that's even relevant.
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.
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.
Fro the sake of reference while this is being sorted out - k8s-metrics crate
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/