-
-
Notifications
You must be signed in to change notification settings - Fork 357
add resize subresource for Pods #1794
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
use k8s_openapi::api::core::v1::Pod; | ||
use kube::{ | ||
Client, Result, | ||
api::{Api, PostParams, ResourceExt}, | ||
}; | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
unsafe { | ||
std::env::set_var("RUST_LOG", "info,kube=debug"); | ||
} | ||
tracing_subscriber::fmt::init(); | ||
let client = Client::try_default().await?; | ||
|
||
let name = std::env::args() | ||
.nth(1) | ||
.expect("Usage: cargo run --bin pod_resize <pod-name>"); | ||
|
||
let pods: Api<Pod> = Api::default_namespaced(client); | ||
|
||
// Resize is only available in Kubernetes 1.33+ | ||
k8s_openapi::k8s_if_ge_1_33! { | ||
tracing::info!("Resizing pod {}", name); | ||
|
||
// Get the current pod | ||
let mut pod = pods.get(&name).await?; | ||
tracing::info!("Current pod: {}", pod.name_any()); | ||
|
||
// Modify the pod's resource requirements | ||
if let Some(ref mut spec) = pod.spec { | ||
if let Some(container) = spec.containers.get_mut(0) { | ||
// Example: Update CPU and memory limits | ||
if container.resources.is_none() { | ||
container.resources = Some(Default::default()); | ||
} | ||
if let Some(ref mut resources) = container.resources { | ||
use k8s_openapi::apimachinery::pkg::api::resource::Quantity; | ||
use std::collections::BTreeMap; | ||
|
||
// Set new resource limits | ||
let mut limits = BTreeMap::new(); | ||
limits.insert("cpu".to_string(), Quantity("500m".to_string())); | ||
limits.insert("memory".to_string(), Quantity("256Mi".to_string())); | ||
resources.limits = Some(limits); | ||
|
||
// Set new resource requests | ||
let mut requests = BTreeMap::new(); | ||
requests.insert("cpu".to_string(), Quantity("250m".to_string())); | ||
requests.insert("memory".to_string(), Quantity("128Mi".to_string())); | ||
resources.requests = Some(requests); | ||
} | ||
} | ||
} | ||
|
||
// Apply the resize | ||
let pp = PostParams::default(); | ||
let updated_pod = pods.resize(&name, &pp, &pod).await?; | ||
tracing::info!("Pod resized successfully: {}", updated_pod.name_any()); | ||
|
||
if let Some(ref spec) = updated_pod.spec { | ||
if let Some(container) = spec.containers.get(0) { | ||
if let Some(ref resources) = container.resources { | ||
tracing::info!("New limits: {:?}", resources.limits); | ||
tracing::info!("New requests: {:?}", resources.requests); | ||
} | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -610,3 +610,78 @@ where | |
Ok(Portforwarder::new(connection.into_stream(), ports)) | ||
} | ||
} | ||
|
||
// ---------------------------------------------------------------------------- | ||
// Resize subresource | ||
// ---------------------------------------------------------------------------- | ||
|
||
#[test] | ||
fn resize_path() { | ||
k8s_openapi::k8s_if_ge_1_33! { | ||
use kube_core::{request::Request, Resource, params::PostParams}; | ||
use k8s_openapi::api::core::v1 as corev1; | ||
let pp = PostParams::default(); | ||
let url = corev1::Pod::url_path(&(), Some("ns")); | ||
let req = Request::new(url).resize("foo", vec![], &pp).unwrap(); | ||
assert_eq!(req.uri(), "/api/v1/namespaces/ns/pods/foo/resize?"); | ||
} | ||
} | ||
|
||
/// Marker trait for objects that can be resized | ||
/// | ||
/// See [`Api::resize`] for usage | ||
pub trait Resize {} | ||
|
||
k8s_openapi::k8s_if_ge_1_33! { | ||
impl Resize for k8s_openapi::api::core::v1::Pod {} | ||
} | ||
|
||
impl<K> Api<K> | ||
where | ||
K: DeserializeOwned + Resize, | ||
{ | ||
/// Resize a resource | ||
/// | ||
/// This works similarly to [`Api::replace`] but uses the resize subresource. | ||
/// Takes a full Pod object to specify the new resource requirements. | ||
Comment on lines
+645
to
+646
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should link to limitations |
||
/// | ||
/// ```no_run | ||
/// use kube::api::{Api, PostParams}; | ||
/// use k8s_openapi::api::core::v1::Pod; | ||
/// # async fn wrapper() -> Result<(), Box<dyn std::error::Error>> { | ||
/// # let client = kube::Client::try_default().await?; | ||
/// let pods: Api<Pod> = Api::namespaced(client, "apps"); | ||
/// let mut pod = pods.get("mypod").await?; | ||
/// | ||
/// // Modify the pod's resource requirements | ||
/// if let Some(ref mut spec) = pod.spec { | ||
/// if let Some(ref mut containers) = spec.containers.first_mut() { | ||
/// if let Some(ref mut resources) = containers.resources { | ||
/// // Update CPU/memory limits | ||
/// } | ||
/// } | ||
/// } | ||
/// | ||
/// let pp = PostParams::default(); | ||
/// let resized_pod = pods.resize("mypod", &pp, &pod).await?; | ||
/// # Ok(()) | ||
/// # } | ||
/// ``` | ||
pub async fn resize(&self, name: &str, pp: &PostParams, data: &K) -> Result<K> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. misses support for the other verbs get/patch. need to rename this to |
||
where | ||
K: serde::Serialize, | ||
{ | ||
let mut req = self | ||
.request | ||
.resize( | ||
name, | ||
serde_json::to_vec(data).map_err(Error::SerdeError)?, | ||
pp, | ||
) | ||
.map_err(Error::BuildRequest)?; | ||
req.extensions_mut().insert("resize"); | ||
self.client.request::<K>(req).await | ||
} | ||
} | ||
|
||
// ---------------------------------------------------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't need to gate the example on 1_33 because the we have
latest
as a required feature