Search code examples
spring-bootbuildpack

When running spring-boot container on kubernetes active processor count is set with host CPU, not k8s cpu limit for container


We run spring-boot containers created using bootBuildImage gradle task on kubernetes. We provide both CPU limits and memory limits to the pods at startup in k8s. We use:

  • spring-boot version 2.6.2
  • docker image built with gradle spring-boot plugin bootBuildImage task
  • spring-boot-admin to administrate our spring-boot based deployments
  • JDK 11 (to enable blockhound)
  • 32 CPUs hosts in GCP GKE
  • In dev we limit our container to 1 CPU and 1Gig of memory

We noticed that all our spring-boot based containers are provisioned (ie nb of threads) as if running on 32 CPUs instances.

Docker startup logs show

Setting Active Processor Count to 32

[...]

Picked up JAVA_TOOL_OPTIONS: [...] -XX:ActiveProcessorCount=32

In spring-boot-admin with see web servers (netty for reactive, undertow for servlet) are provisioned with thread pools as if the application was running on 32 CPUs allocated container even if the container was limited with 1 CPU by k8s. OTH the allocated memory to the JVM is correct.

How can we make sure the active CPU count reflects the k8s CPU limitation ?

Thanks in advance


Solution

  • Based on the output you included, it looks like you're using buildpacks (i.e. ./mvnw spring-boot:build-image or ./gradlew bootBuildImage or pack build).

    In that case, you can set the env variable JAVA_TOOL_OPTIONS with -XX:ActiveProcessorCount=x to override the default calculation. The default calculation will pull the total number of processors (as reported by Go's runtime.NumCPU() function).

    Side note. What you are asking seems reasonable, so I opened an issue to see if we can enable it to detect the limited CPU count.