2

I am trying to run a Spring Batch application in kubernetes cluster. I am able to enforce resource limits to the main application pod by placing the following snippet in the deployment yaml:

resources:
  limits:
    cpu: 500m
    ephemeral-storage: 500Mi
    memory: 250Mi

These settings are getting applied and can be seen in the pod yaml (kubectl edit pod batch).

However, these limits are not propagated to the worker pods. I tried adding the following properties in configmap of batch to set the cpu and memory limits:

SPRING.CLOUD.DEPLOYER.KUBERNETES.CPU: 500m
SPRING.CLOUD.DEPLOYER.KUBERNETES.MEMORY: 250Mi

However, the worker pods are not getting these limits. I tried providing the following env variables too, but still the limits were not applied to the worker pod:

SPRING_CLOUD_DEPLOYER_KUBERNETES_CPU: 500m
SPRING_CLOUD_DEPLOYER_KUBERNETES_MEMORY: 250Mi

The versions involved are:

  • Spring Boot: 2.1.9.RELEASE
  • Spring Cloud: 2020.0.1
  • Spring Cloud Deployer: 2.5.0
  • Spring Cloud Task: 2.1.1.RELEASE
  • Kubernetes: 1.21

How can I set these limits?

EDIT: Adding code for DeployerPartitionerHandler:

public PartitionHandler partitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer) {

    Resource resource = this.resourceLoader.getResource(resourceSpec);

    DeployerPartitionHandler partitionHandler = new DeployerPartitionHandler(taskLauncher, jobExplorer, resource,
            "worker");

    commandLineArgs.add("--spring.profiles.active=worker");
    commandLineArgs.add("--spring.cloud.task.initialize.enable=false");
    commandLineArgs.add("--spring.batch.initializer.enabled=false");
    commandLineArgs.add("--spring.cloud.task.closecontext_enabled=true");
    commandLineArgs.add("--logging.level.root=DEBUG");

    partitionHandler.setCommandLineArgsProvider(new PassThroughCommandLineArgsProvider(commandLineArgs));
    partitionHandler.setEnvironmentVariablesProvider(environmentVariablesProvider());
    partitionHandler.setApplicationName(appName + "worker");
    partitionHandler.setMaxWorkers(maxWorkers);

    return partitionHandler;
}

@Bean
public EnvironmentVariablesProvider environmentVariablesProvider() {
    return new SimpleEnvironmentVariablesProvider(this.environment);
}
  • Are you using the `DeployerPartitionHandler` to create workers? Please share your code to be able to help you efficiently. – Mahmoud Ben Hassine Sep 02 '21 at 07:05
  • I don't have any specific implementation of TaskLauncher for kubernetes. It is picking up the default TaskLauncher bean provided by spring cloud deployer kubernetes – Abhinav Sharma Sep 02 '21 at 09:12

1 Answers1

2

Since the DeployerPartitionHandler is created using the new operator in the partitionHandler method, it is not aware of the values from the properties file. The DeployerPartitionHandler provides a setter for deploymentProperties. You should use this parameter to specify deployment properties for worker tasks.

EDIT: Based on comment by Glenn Renfro

The deployment property should be spring.cloud.deployer.kubernetes.limits.cpu and not spring.cloud.deployer.kubernetes.cpu.

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50
  • I am loading the environment though, from environmentVariablesProvider() bean. So would these environment variables not help? SPRING_CLOUD_DEPLOYER_KUBERNETES_CPU: 500m SPRING_CLOUD_DEPLOYER_KUBERNETES_MEMORY: 250Mi – Abhinav Sharma Sep 02 '21 at 12:55
  • I don't think so as those are different things: one is for environment variables to be set on each worker and the other is for deployment properties to be used by the TaskLauncher for each deployed app. – Mahmoud Ben Hassine Sep 02 '21 at 14:01
  • Is there anything missing to accept this answer? Have you tried to set deploymentProperties on the DeployerPartitionHandler? – Mahmoud Ben Hassine Sep 03 '21 at 07:04
  • Testing with changes, some issue came in my k8s setup, which is blocking me to test the solution. Will accept the answer soon, after resolving the k8s issue and testing. – Abhinav Sharma Sep 03 '21 at 07:39
  • I tried the recommended way. `@Value("#{${batch.deployer}}") private Map deployerProp;` `partitionHandler.setDeploymentProperties(deployerProp);` The deployerProperties are getting logged and printed on console, but the resource limits are not getting applied to the worker pod. – Abhinav Sharma Sep 03 '21 at 15:18
  • Any hints? Am I setting the properties correctly? I have given the following in batch.deployer: `batch.deployer={"spring.cloud.deployer.kubernetes.cpu":"100m","spring.cloud.deployer.kubernetes.memory":"500Mi"}` – Abhinav Sharma Sep 07 '21 at 05:57
  • Sorry for the delay in response. It should be `spring.cloud.deployer.kubernetes.limits.cpu` Hope this helps. – Glenn Renfro Sep 10 '21 at 14:37
  • Thanks, it worked now. limits, and requests was missing from the property name. – Abhinav Sharma Sep 13 '21 at 08:07
  • Good to hear that it solved your issue. I updated the answer accordingly. – Mahmoud Ben Hassine Sep 13 '21 at 08:39