Simple PoC to give pods a CPU boost during startup (before pod is Ready).
- supports Kubernetes clusters starting from version 1.27 only with
InPlacePodVerticalScalingfeature gate enabled (for older versions, seev0.1.0) - requires container to boost to have:
- a
readinessProbeconfigured - a value for
resources.limits.cpu - a
resizePolicywithresourceName: cpuandrestartPolicy: NotRequire
- a
- works with pods with multiple containers, but can only boost a single container inside the pod
Between startup and Ready status, the container benefits from a CPU boost (x10).
It is deployed in two parts:
- a mutating webhook boosting the CPU of pods with
norbjd.github.io/k8s-pod-cpu-booster-enabled: "true"label, before they are submitted to k8s API - a controller listening for every update of pods with
norbjd.github.io/k8s-pod-cpu-booster-enabled: "true"label; when a pod is ready, it will reset its CPU limit
The CPU boost can be configured with norbjd.github.io/k8s-pod-cpu-booster-multiplier label:
- if specified, it will increase the CPU limit by
x, wherexis the value of the label (must be an unsigned integer) - if unspecified or invalid, it will increase the CPU limit by the default value (
10)
Use helm:
helm repo add k8s-pod-cpu-booster https://norbjd.github.io/k8s-pod-cpu-booster
helm repo update
helm install k8s-pod-cpu-booster k8s-pod-cpu-booster/k8s-pod-cpu-booster --devel \
--namespace pod-cpu-booster --create-namespaceCreate a kind cluster:
kind create cluster --config examples/kind-config.yamlLoad python:3.11-alpine image on the cluster (not mandatory):
docker pull python:3.11-alpine
kind load docker-image python:3.11-alpineInstall k8s-pod-cpu-booster:
helm repo add k8s-pod-cpu-booster https://norbjd.github.io/k8s-pod-cpu-booster
helm repo update
helm install k8s-pod-cpu-booster k8s-pod-cpu-booster/k8s-pod-cpu-booster --devel \
--namespace pod-cpu-booster --create-namespaceStart two similar pods with low CPU limits and running python -m http.server, with a readiness probe configured to check when the http server is started. The only differences are the name (obviously), and the label norbjd.github.io/k8s-pod-cpu-booster-enabled:
--- examples/pod-no-boost.yaml
+++ examples/pod-with-default-boost.yaml
@@ -4 +4,3 @@
- name: pod-no-boost
+ labels:
+ norbjd.github.io/k8s-pod-cpu-booster-enabled: "true"
+ name: pod-with-default-boostNote
The CPU boost multiplier can also be configured (see pod-with-small-boost.yaml) by using the norbjd.github.io/k8s-pod-cpu-booster-multiplier label.
As a result, the pod pod-with-default-boost (with the label) will benefit from a CPU boost, but pod-no-boost won't:
kubectl apply -f examples/pod-no-boost.yaml -f examples/pod-with-default-boost.yaml
# wait until pods are ready
kubectl wait --for=condition=Ready pod/pod-with-default-boost pod/pod-no-boostOnce both are ready, check how much time each took to be ready:
for pod_name in pod-with-default-boost pod-no-boost
do
kubectl get pods $pod_name -o go-template='{{ .metadata.name }}{{ " " }}{{ range .status.containerStatuses }}{{ if eq .name "python" }}{{ "started at: " }}{{ .state.running.startedAt }}{{ end }}{{ end }}{{ " / " }}{{ range .status.conditions }}{{ if (and (eq .type "Ready") (eq .status "True")) }}{{ "ready at: " }}{{ .lastTransitionTime }}{{ end }}{{ end }}{{ "\n" }}'
doneExample result:
pod-with-default-boost started at: 2023-10-28T14:00:46Z / ready at: 2023-10-28T14:00:49Z
pod-no-boost started at: 2023-10-28T14:00:46Z / ready at: 2023-10-28T14:01:04Z
Here, the pod with the CPU boost (pod-with-default-boost) took around 3 seconds to start, while the pod without CPU boost (pod-no-boost) took around 18 seconds.
Note
Even if boosts are made at Pod level and not at Deployment level, this works too with Deployments (and probably other resources managing pods under the hood). See examples/deployment-with-default-boost.yaml for example.
Cleanup:
kubectl delete -f examples/pod-no-boost.yaml -f examples/pod-with-default-boost.yaml
helm uninstall -n pod-cpu-booster k8s-pod-cpu-booster
kind delete cluster