You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by "GabrielCWT (via GitHub)" <gi...@apache.org> on 2025/10/01 09:51:14 UTC
[PR] Implement dynamic capacity for kubernetes task runner (druid)
GabrielCWT opened a new pull request, #18591:
URL: https://github.com/apache/druid/pull/18591
### Description
The aim of the PR is to enable changing `capacity` for the `KubernetesTaskRunner`. This would be done through the existing POST API `/druid/indexer/v1/k8s/taskrunner/executionconfig`.
#### K8 configuration changes
In order to do this, I have added a new interface `KubernetesTaskRunnerConfig` and renamed the existing config to `KubernetesTaskRunnerStaticConfig`. The interface will be implemented by the existing static config and a new `KubernetesTaskRunnerEffectiveConfig` which will be a wrapper class to encapsulate both the dynamic and static configs.
The effective config will fall back to the static config's capacity if the dynamic config has not been set.
#### Changes to `/druid/indexer/v1/k8s/taskrunner/executionconfig` behaviour
The API will now take a new `capacity` field. On top of this, the fields will now be optional. If any field is `null` or not passed, we will use the existing dynamic config values.
#### Release note
New `capacity` field for `/druid/indexer/v1/k8s/taskrunner/executionconfig` POST API. It will change the capacity for `KubernetesTaskRunner`.
### Challenges
In order to update the capacity for the task runner, I am calling a new function `syncCapacityWithDynamicConfig` before every task is run in order to update the thread pool to the newest config.
The issue with this is that any changes by the user will not be immediately reflected on the web console's homepage under the "Tasks" widget. The "task slots" would only be updated after a new task has been run.
I could not find a way to add a callback to the updating of dynamic configurations and felt that having a check every few seconds to see if the dynamic configuration had been updated was unnecessarily complex. I am open to suggestions if there are better ways to update the task runner.
<img width="342" height="202" alt="Screenshot 2025-10-01 at 5 47 05 PM" src="https://github.com/user-attachments/assets/1476d5a0-ccae-4813-ac69-24244cf29737" />
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GWphua (via GitHub)" <gi...@apache.org>.
GWphua commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2401129522
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerEffectiveConfig.java:
##########
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.google.common.base.Supplier;
+import org.apache.druid.k8s.overlord.execution.KubernetesTaskRunnerDynamicConfig;
+import org.apache.druid.k8s.overlord.execution.PodTemplateSelectStrategy;
+import org.joda.time.Period;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Effective config object that combines static {@link KubernetesTaskRunnerConfig}
+ * with dynamic overrides from {@link KubernetesTaskRunnerDynamicConfig}.
Review Comment:
```suggestion
* Provides a flexible mechanism to configure Kubernetes task pods,
* by merging the static base settings from {@link KubernetesTaskRunnerConfig}
* with dynamic overrides from {@link KubernetesTaskRunnerDynamicConfig}.
* <p>
* Kubernetes will always use this effective config to run new tasks.
```
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
Review Comment:
Would be great to have Javadocs to say how this config is used.
##########
docs/development/extensions-core/k8s-jobs.md:
##########
@@ -48,9 +48,9 @@ Other configurations required are:
Druid operators can dynamically tune certain features within this extension. You don't need to restart the Overlord
service for these changes to take effect.
-Druid can dynamically tune [pod template selection](#pod-template-selection), which allows you to configure the pod
-template based on the task to be run. To enable dynamic pod template selection, first configure the
-[custom template pod adapter](#custom-template-pod-adapter).
+Druid can dynamically tune [pod template selection](#pod-template-selection) and [capacity](#properties).
Review Comment:
Would be clearer, IMO, to add a sentence to state 'capacity' refers to 'the maximum number of pods that can run at any time, or u can write it as `druid.indexer.runner.capacity`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3380126203
Thanks for the clarification, @FrankChen021 !
I am just a little apprehensive since the K8s task runner is already pretty buggy.
Also, it feels weird to have a config be specified by both static and dynamic means.
But I suppose the static config can be thought of as the default value.
I haven't gone through the whole PR yet. Will try to do a thorough review today.
@GabrielCWT , it would be nice if you could hold off on merging this PR until then.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3388601005
> Hi @kfaraz are u reviewing this PR? I hope we can merge it into druid 35.
Yes, @FrankChen021 , I will go through the changes either today or tomorrow.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3433202633
> @kfaraz any comments?
Hey @FrankChen021 , yeah, still planning on going through this PR. Will try to prioritize it for later this week.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "cryptoe (via GitHub)" <gi...@apache.org>.
cryptoe commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3624834030
+1 thanks @FrankChen021 for merging this.
The new code structure seems much better.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3365393934
> too?
In a k8s deployment, after increasing the task capability, increasing the overlord resources may not be always needed. For example, we generally set the cpu limit to a higher value while keeping the cpu request relatively low at the initial deployment, when capacity is increased, no need to increase the cpu resource. I mean risky because overlord needs to restore all tasks, previously we had some problems (maybe bug) that after switching leaders, overlord failed to elect a new leader. We try our best not to restart coordinator/overlord in production.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3365370572
Thanks for the responses, @FrankChen021 , @GabrielCWT .
Even though with the K8s task runner, the task pods are not technically a part of the Druid cluster, the Overlord still has to manage those tasks. The KubernetesTaskRunner itself keeps separate threads for each running task to track their status (this PR also updates that thread count, if I am not mistaken).
So I should imagine that a major change in task capacity would also require some kind of scaling of the Overlord itself.
Also, why is the Overlord restart "risky" or even "slow"? Doesn't a version upgrade require an Overlord restart too?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2418642914
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -179,6 +189,24 @@ protected KubernetesWorkItem joinAsync(Task task)
}
}
+ private void syncCapacityWithDynamicConfig()
Review Comment:
It is possible to make `currentCapacity` to be thread safe.
> Can we do this in a seperate thread instead of calling sync everywhere.
This was an alternative solution though I am not sure if we are thinking of the same implementation. My solution was to have a thread which periodically checks whether there has been any changes to the capacity and update `currentCapacity` accordingly. However, I wasn't sure if it was a waste of resources as there would need to be a trade off between responsiveness (how quick will the changes be visible) and resources (since we need to wake the thread up every X seconds).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3372021229
> I mean risky because overlord needs to restore all tasks, previously we had some problems (maybe bug) that after switching leaders, overlord failed to elect a new leader.
Yes, there might be some bugs around that. Also, the K8s task runner makes certain list pod calls, which are pretty heavy
and needs to be addressed. I think @capistrant is doing some work to improve that code flow.
> We try our best not to restart coordinator/overlord in production.
Oh, how frequently do you upgrade your cluster?
Is changing the task capacity going to be much more frequent than that.
I agree that K8s task runner is buggy and we should improve upon it.
But making the task capacity dynamic doesn't seem like the best solution.
It will open a whole another can of worms and make this piece only more complicated.
Instead, we should trying to fix up the actual problems in the task runner which make Overlord leader switch erroneous.
What are your thoughts, @FrankChen021 ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "cryptoe (via GitHub)" <gi...@apache.org>.
cryptoe commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2465582946
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerEffectiveConfig.java:
##########
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.google.common.base.Supplier;
+import org.apache.druid.k8s.overlord.execution.KubernetesTaskRunnerDynamicConfig;
+import org.apache.druid.k8s.overlord.execution.PodTemplateSelectStrategy;
+import org.joda.time.Period;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides a flexible mechanism to configure Kubernetes task pods,
+ * by merging the static base settings from {@link KubernetesTaskRunnerConfig}
+ * with dynamic overrides from {@link KubernetesTaskRunnerDynamicConfig}.
+ * <p>
+ * Kubernetes will always use this effective config to run new tasks.
+ */
+public class KubernetesTaskRunnerEffectiveConfig implements KubernetesTaskRunnerConfig
+{
+ private final KubernetesTaskRunnerStaticConfig staticConfig;
+ private final Supplier<KubernetesTaskRunnerDynamicConfig> dynamicConfigSupplier;
+
+ public KubernetesTaskRunnerEffectiveConfig(
+ KubernetesTaskRunnerStaticConfig staticConfig,
+ Supplier<KubernetesTaskRunnerDynamicConfig> dynamicConfigSupplier
+ )
+ {
+ this.staticConfig = staticConfig;
+ this.dynamicConfigSupplier = dynamicConfigSupplier;
+ }
+
+ @Override
+ public String getNamespace()
+ {
+ return staticConfig.getNamespace();
+ }
+
+ @Override
+ public String getOverlordNamespace()
+ {
+ return staticConfig.getOverlordNamespace();
+ }
+
+ @Override
+ public String getK8sTaskPodNamePrefix()
+ {
+ return staticConfig.getK8sTaskPodNamePrefix();
+ }
+
+ @Override
+ public boolean isDebugJobs()
+ {
+ return staticConfig.isDebugJobs();
+ }
+
+ @Override
+ public boolean isSidecarSupport()
+ {
+ return staticConfig.isSidecarSupport();
+ }
+
+ @Override
+ public String getPrimaryContainerName()
+ {
+ return staticConfig.getPrimaryContainerName();
+ }
+
+ @Override
+ public String getKubexitImage()
+ {
+ return staticConfig.getKubexitImage();
+ }
+
+ @Override
+ public Long getGraceTerminationPeriodSeconds()
+ {
+ return staticConfig.getGraceTerminationPeriodSeconds();
+ }
+
+ @Override
+ public boolean isDisableClientProxy()
+ {
+ return staticConfig.isDisableClientProxy();
+ }
+
+ @Override
+ public Period getTaskTimeout()
+ {
+ return staticConfig.getTaskTimeout();
+ }
+
+ @Override
+ public Period getTaskJoinTimeout()
+ {
+ return staticConfig.getTaskJoinTimeout();
+ }
+
+ @Override
+ public Period getTaskCleanupDelay()
+ {
+ return staticConfig.getTaskCleanupDelay();
+ }
+
+ @Override
+ public Period getTaskCleanupInterval()
+ {
+ return staticConfig.getTaskCleanupInterval();
+ }
+
+ @Override
+ public Period getTaskLaunchTimeout()
+ {
+ return staticConfig.getTaskLaunchTimeout();
+ }
+
+ @Override
+ public Period getLogSaveTimeout()
+ {
+ return staticConfig.getLogSaveTimeout();
+ }
+
+ @Override
+ public List<String> getPeonMonitors()
+ {
+ return staticConfig.getPeonMonitors();
+ }
+
+ @Override
+ public List<String> getJavaOptsArray()
+ {
+ return staticConfig.getJavaOptsArray();
+ }
+
+ @Override
+ public int getCpuCoreInMicro()
+ {
+ return staticConfig.getCpuCoreInMicro();
+ }
+
+ @Override
+ public Map<String, String> getLabels()
+ {
+ return staticConfig.getLabels();
+ }
+
+ @Override
+ public Map<String, String> getAnnotations()
+ {
+ return staticConfig.getAnnotations();
+ }
+
+ @Override
+ public Integer getCapacity()
+ {
+ if (dynamicConfigSupplier == null || dynamicConfigSupplier.get() == null || dynamicConfigSupplier.get().getCapacity() == null) {
+ return staticConfig.getCapacity();
+ }
+ return dynamicConfigSupplier.get().getCapacity();
Review Comment:
Wont this be bit weird for the cluster admin.
In the static configs, we supply lets say 10, but in the dynamic config we supply 20. How would the cluster admin reason about this ?
How are these configs reconciled ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3494498851
Hi @cryptoe Looks like all comments have been addressed. if no further comments, I will merge this
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2467735906
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -132,10 +142,12 @@ public KubernetesTaskRunner(
this.httpClient = httpClient;
this.peonLifecycleFactory = peonLifecycleFactory;
this.cleanupExecutor = Executors.newScheduledThreadPool(1);
- this.exec = MoreExecutors.listeningDecorator(
- Execs.multiThreaded(config.getCapacity(), "k8s-task-runner-%d")
- );
this.emitter = emitter;
+
+ this.currentCapacity = config.getCapacity();
+ this.tpe = new ThreadPoolExecutor(currentCapacity, currentCapacity, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Execs.makeThreadFactory("k8s-task-runner-%d", null));
+ this.exec = MoreExecutors.listeningDecorator(this.tpe);
+ configManager.addListener(KubernetesTaskRunnerDynamicConfig.CONFIG_KEY, StringUtils.format(OBSERVER_KEY, Thread.currentThread().getId()), this::syncCapacityWithDynamicConfig);
Review Comment:
Yes it will run in the same thread as the one handling the API call. Would your concern be that if more listeners were to be added in the future, the updating of dynamic configs would be a long blocking call?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2401297575
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
Review Comment:
Added the docs below.
```
/**
* Static configuration for the Kubernetes-based task runner used by the Overlord.
* <p>
* This configuration is populated from runtime properties with the prefix
* {@code druid.indexer.runner}.
*/
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GWphua (via GitHub)" <gi...@apache.org>.
GWphua commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2401333736
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
Review Comment:
Thanks for the change!
> Static configuration for the Kubernetes-based task runner used by the Overlord.
I think this is redundant -- already self-explanatory in the class name. Code readers who come to this class are probably more interested in how and when this class is used, instead of what this class is.
e.g. Used as the starting config, and then will be gradually updated by dynamic configs if applicable.
Capturing this idea is probably more crucial.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3365175240
> @GabrielCWT , thanks for putting this together.
>
> I might be mistaken but I am not entirely sure if the task capacity of a cluster should be a dynamic config. For any cluster admin, this can have large cost implications. It seems odd to be able to override the capacity of the cluster defined in the Overlord runtime property simply by calling an API.
>
> Changing the task capacity should not be a very frequent requirement for any cluster. And when needed, it should be fairly reasonable to require an Overlord restart.
>
> Could you please elaborate on why you feel the current setup is not adequate?
I think it's true that changing the task slot for middle manager requires the restart as we might need a redeployment of middelmanager to some servers with bigger resources. but for K8S-based task scheduling, the resources is allocated at K8S side which is out of druid, restarting of the overlord does not make any sense, we should have the ablity to reload the capacity dynamically. As @GabrielCWT has stated above, restarting overlord is a heavy and risky operation in production.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2401040516
##########
extensions-core/kubernetes-overlord-extensions/src/test/java/org/apache/druid/k8s/overlord/taskadapter/K8sTaskAdapterTest.java:
##########
@@ -138,12 +138,12 @@ public PodSpec getSpec()
}
};
- KubernetesTaskRunnerConfig config = KubernetesTaskRunnerConfig.builder()
- .withNamespace("test")
- .withOverlordNamespace("test_different")
- .withAnnotations(ImmutableMap.of("annotation_key", "annotation_value"))
- .withLabels(ImmutableMap.of("label_key", "label_value"))
- .build();
+ KubernetesTaskRunnerStaticConfig config = KubernetesTaskRunnerStaticConfig.builder()
Review Comment:
I think we can still keep the builder method in the interface, so that there will not be any changes in the test cases
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -109,17 +111,20 @@ public class KubernetesTaskRunner implements TaskLogStreamer, TaskRunner
protected final TaskAdapter adapter;
private final KubernetesPeonClient client;
- private final KubernetesTaskRunnerConfig config;
+ private final KubernetesTaskRunnerEffectiveConfig config;
Review Comment:
I think we can still keep using the interface declaration
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2401297575
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
Review Comment:
Added the docs below.
```
/**
* Static configuration for the Kubernetes-based task runner used by the Overlord.
* <p>
* This configuration is populated from runtime properties with the prefix
* {@code druid.indexer.runner}.
*/
public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3388108009
Hi @kfaraz are u reviewing this PR? I hope we can merge it into druid 35.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2467716608
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerEffectiveConfig.java:
##########
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.google.common.base.Supplier;
+import org.apache.druid.k8s.overlord.execution.KubernetesTaskRunnerDynamicConfig;
+import org.apache.druid.k8s.overlord.execution.PodTemplateSelectStrategy;
+import org.joda.time.Period;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides a flexible mechanism to configure Kubernetes task pods,
+ * by merging the static base settings from {@link KubernetesTaskRunnerConfig}
+ * with dynamic overrides from {@link KubernetesTaskRunnerDynamicConfig}.
+ * <p>
+ * Kubernetes will always use this effective config to run new tasks.
+ */
+public class KubernetesTaskRunnerEffectiveConfig implements KubernetesTaskRunnerConfig
+{
+ private final KubernetesTaskRunnerStaticConfig staticConfig;
+ private final Supplier<KubernetesTaskRunnerDynamicConfig> dynamicConfigSupplier;
+
+ public KubernetesTaskRunnerEffectiveConfig(
+ KubernetesTaskRunnerStaticConfig staticConfig,
+ Supplier<KubernetesTaskRunnerDynamicConfig> dynamicConfigSupplier
+ )
+ {
+ this.staticConfig = staticConfig;
+ this.dynamicConfigSupplier = dynamicConfigSupplier;
+ }
+
+ @Override
+ public String getNamespace()
+ {
+ return staticConfig.getNamespace();
+ }
+
+ @Override
+ public String getOverlordNamespace()
+ {
+ return staticConfig.getOverlordNamespace();
+ }
+
+ @Override
+ public String getK8sTaskPodNamePrefix()
+ {
+ return staticConfig.getK8sTaskPodNamePrefix();
+ }
+
+ @Override
+ public boolean isDebugJobs()
+ {
+ return staticConfig.isDebugJobs();
+ }
+
+ @Override
+ public boolean isSidecarSupport()
+ {
+ return staticConfig.isSidecarSupport();
+ }
+
+ @Override
+ public String getPrimaryContainerName()
+ {
+ return staticConfig.getPrimaryContainerName();
+ }
+
+ @Override
+ public String getKubexitImage()
+ {
+ return staticConfig.getKubexitImage();
+ }
+
+ @Override
+ public Long getGraceTerminationPeriodSeconds()
+ {
+ return staticConfig.getGraceTerminationPeriodSeconds();
+ }
+
+ @Override
+ public boolean isDisableClientProxy()
+ {
+ return staticConfig.isDisableClientProxy();
+ }
+
+ @Override
+ public Period getTaskTimeout()
+ {
+ return staticConfig.getTaskTimeout();
+ }
+
+ @Override
+ public Period getTaskJoinTimeout()
+ {
+ return staticConfig.getTaskJoinTimeout();
+ }
+
+ @Override
+ public Period getTaskCleanupDelay()
+ {
+ return staticConfig.getTaskCleanupDelay();
+ }
+
+ @Override
+ public Period getTaskCleanupInterval()
+ {
+ return staticConfig.getTaskCleanupInterval();
+ }
+
+ @Override
+ public Period getTaskLaunchTimeout()
+ {
+ return staticConfig.getTaskLaunchTimeout();
+ }
+
+ @Override
+ public Period getLogSaveTimeout()
+ {
+ return staticConfig.getLogSaveTimeout();
+ }
+
+ @Override
+ public List<String> getPeonMonitors()
+ {
+ return staticConfig.getPeonMonitors();
+ }
+
+ @Override
+ public List<String> getJavaOptsArray()
+ {
+ return staticConfig.getJavaOptsArray();
+ }
+
+ @Override
+ public int getCpuCoreInMicro()
+ {
+ return staticConfig.getCpuCoreInMicro();
+ }
+
+ @Override
+ public Map<String, String> getLabels()
+ {
+ return staticConfig.getLabels();
+ }
+
+ @Override
+ public Map<String, String> getAnnotations()
+ {
+ return staticConfig.getAnnotations();
+ }
+
+ @Override
+ public Integer getCapacity()
+ {
+ if (dynamicConfigSupplier == null || dynamicConfigSupplier.get() == null || dynamicConfigSupplier.get().getCapacity() == null) {
+ return staticConfig.getCapacity();
+ }
+ return dynamicConfigSupplier.get().getCapacity();
Review Comment:
You raise a good point. I don't think there is any way around this issue. I have updated the docs to state that the static config value will be overridden in the event that a dynamic config has been set. Hopefully this would add a little more clarity for users.
I am open to suggestions to make this even clearer.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 merged PR #18591:
URL: https://github.com/apache/druid/pull/18591
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3430259041
@kfaraz any comments?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "cecemei (via GitHub)" <gi...@apache.org>.
cecemei commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3433197650
This pull request hasn’t been merged into the master branch yet, which means it won’t be included in the upcoming Druid 35 release. It will most likely be part of Druid 36 once it’s reviewed and merged.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3374918699
> > I mean risky because overlord needs to restore all tasks, previously we had some problems (maybe bug) that after switching leaders, overlord failed to elect a new leader.
>
> Yes, there might be some bugs around that. Also, the K8s task runner makes certain list pod calls, which are pretty heavy and needs to be addressed. I think @capistrant is doing some work to improve that code flow.
>
> > We try our best not to restart coordinator/overlord in production.
>
> Oh, how frequently do you upgrade your cluster? Is changing the task capacity going to be much more frequent than that.
>
We don't upgrade clusters very frequently, may be once a year or more than 1 year. We do adjust the capacity (upsize or downsize) regularly based on load/requirement.
> I agree that K8s task runner is buggy and we should improve upon it. But making the task capacity dynamic doesn't seem like the best solution. It will open a whole another can of worms and make this piece only more complicated.
>
> Instead, we should trying to fix up the actual problems in the task runner which make Overlord leader switch erroneous.
>
> What are your thoughts, @FrankChen021 ?
The main idea of dynamic configuration is not to circumvent problems at restarting phase, it's about reducing the operation complexity and saving time. even restarting overlord is smooth, I don't think changing such configuration requires a restart from users/operators' view. for static configurations, operators have to change configuration files, sync files to kubenetes, restarting components, it's a heavy work flow.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3494656823
Apologies! I have been bogged down with a bunch of other stuff, some to do with the D35 release as well.
@FrankChen021 , I would really appreciate it if you could hold off on merging this at least until Friday (tomorrow).
If I have not found some time to leave any feedback by then, and @cryptoe has approved, you can merge off this PR.
@cryptoe and I have discussed this briefly. For the most part, the capabilities added here make sense.
But I just want to take a quick pass through the code flow and structure since this is a critical piece of the task management system.
We could always merge off this PR and address my comments in a follow up PR but that would only make the changes more difficult to track.
I hope that makes sense.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "github-advanced-security[bot] (via GitHub)" <gi...@apache.org>.
github-advanced-security[bot] commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2394090355
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10466)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerEffectiveConfig.java:
##########
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.google.common.base.Supplier;
+import org.apache.druid.k8s.overlord.execution.KubernetesTaskRunnerDynamicConfig;
+import org.apache.druid.k8s.overlord.execution.PodTemplateSelectStrategy;
+import org.joda.time.Period;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Effective config object that combines static {@link KubernetesTaskRunnerConfig}
+ * with dynamic overrides from {@link KubernetesTaskRunnerDynamicConfig}.
+ */
+public class KubernetesTaskRunnerEffectiveConfig implements KubernetesTaskRunnerConfig
+{
+ private final KubernetesTaskRunnerStaticConfig staticConfig;
+ private final Supplier<KubernetesTaskRunnerDynamicConfig> dynamicConfigSupplier;
+
+ public KubernetesTaskRunnerEffectiveConfig(
+ KubernetesTaskRunnerStaticConfig staticConfig,
+ Supplier<KubernetesTaskRunnerDynamicConfig> dynamicConfigSupplier
+ )
+ {
+ this.staticConfig = staticConfig;
+ this.dynamicConfigSupplier = dynamicConfigSupplier;
+ }
+
+ @Override
+ public String getNamespace()
+ {
+ return staticConfig.getNamespace();
+ }
+
+ @Override
+ public String getOverlordNamespace()
+ {
+ return staticConfig.getOverlordNamespace();
+ }
+
+ @Override
+ public String getK8sTaskPodNamePrefix()
+ {
+ return staticConfig.getK8sTaskPodNamePrefix();
+ }
+
+ @Override
+ public boolean isDebugJobs()
+ {
+ return staticConfig.isDebugJobs();
+ }
+
+ @Override
+ public boolean isSidecarSupport()
+ {
+ return staticConfig.isSidecarSupport();
Review Comment:
## Deprecated method or constructor invocation
Invoking [KubernetesTaskRunnerStaticConfig.isSidecarSupport](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10464)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10468)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10469)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10475)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
+ this.peonMonitors = ObjectUtils.defaultIfNull(
+ peonMonitors,
+ this.peonMonitors
+ );
+ this.javaOptsArray = ObjectUtils.defaultIfNull(
+ javaOptsArray,
+ this.javaOptsArray
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10478)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
+ this.peonMonitors = ObjectUtils.defaultIfNull(
+ peonMonitors,
+ this.peonMonitors
+ );
+ this.javaOptsArray = ObjectUtils.defaultIfNull(
+ javaOptsArray,
+ this.javaOptsArray
+ );
+ this.cpuCoreInMicro = ObjectUtils.defaultIfNull(
+ cpuCoreInMicro,
+ this.cpuCoreInMicro
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10479)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
+ this.peonMonitors = ObjectUtils.defaultIfNull(
+ peonMonitors,
+ this.peonMonitors
+ );
+ this.javaOptsArray = ObjectUtils.defaultIfNull(
+ javaOptsArray,
+ this.javaOptsArray
+ );
+ this.cpuCoreInMicro = ObjectUtils.defaultIfNull(
+ cpuCoreInMicro,
+ this.cpuCoreInMicro
+ );
+ this.labels = ObjectUtils.defaultIfNull(
+ labels,
+ this.labels
+ );
+ this.annotations = ObjectUtils.defaultIfNull(
+ annotations,
+ this.annotations
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10481)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10467)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10470)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10474)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10476)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10465)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10471)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10472)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10473)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
+ this.peonMonitors = ObjectUtils.defaultIfNull(
+ peonMonitors,
+ this.peonMonitors
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10477)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
+ this.peonMonitors = ObjectUtils.defaultIfNull(
+ peonMonitors,
+ this.peonMonitors
+ );
+ this.javaOptsArray = ObjectUtils.defaultIfNull(
+ javaOptsArray,
+ this.javaOptsArray
+ );
+ this.cpuCoreInMicro = ObjectUtils.defaultIfNull(
+ cpuCoreInMicro,
+ this.cpuCoreInMicro
+ );
+ this.labels = ObjectUtils.defaultIfNull(
+ labels,
+ this.labels
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10480)
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunnerStaticConfig.java:
##########
@@ -0,0 +1,562 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.druid.k8s.overlord;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.lang3.ObjectUtils;
+import org.joda.time.Period;
+
+import javax.annotation.Nonnull;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+
+public class KubernetesTaskRunnerStaticConfig implements KubernetesTaskRunnerConfig
+{
+ @JsonProperty
+ @NotNull
+ private String namespace;
+
+ @JsonProperty
+ private String k8sTaskPodNamePrefix = "";
+
+ // This property is the namespace that the Overlord is running in.
+ // For cases where we want task pods to run on different namespace from the overlord, we need to specify the namespace of the overlord here.
+ // Else, we can simply leave this field alone.
+ @JsonProperty
+ private String overlordNamespace = "";
+
+ @JsonProperty
+ private boolean debugJobs = false;
+
+ /**
+ * Deprecated, please specify adapter type runtime property instead
+ * <p>
+ * I.E `druid.indexer.runner.k8s.adapter.type: overlordMultiContainer`
+ */
+ @Deprecated
+ @JsonProperty
+ private boolean sidecarSupport = false;
+
+ @JsonProperty
+ // if this is not set, then the first container in your pod spec is assumed to be the overlord container.
+ // usually this is fine, but when you are dynamically adding sidecars like istio, the service mesh could
+ // in fact place the istio-proxy container as the first container. Thus, you would specify this value to
+ // the name of your primary container. e.g. druid-overlord
+ private String primaryContainerName = null;
+
+ @JsonProperty
+ // for multi-container jobs, we need this image to shut down sidecars after the main container
+ // has completed
+ private String kubexitImage = "karlkfi/kubexit:v0.3.2";
+
+ // how much time to wait for preStop hooks to execute
+ // lower number speeds up pod termination time to release locks
+ // faster, defaults to your k8s setup, usually 30 seconds.
+ private Long graceTerminationPeriodSeconds = null;
+
+ @JsonProperty
+ // disable using http / https proxy environment variables
+ private boolean disableClientProxy;
+
+ @JsonProperty
+ @NotNull
+ private Period maxTaskDuration = new Period("PT4H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the jobs to be cleaned up.
+ private Period taskCleanupDelay = new Period("P2D");
+
+ @JsonProperty
+ @NotNull
+ // interval for k8s job cleanup to run
+ private Period taskCleanupInterval = new Period("PT10m");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait to join peon k8s jobs on startup
+ private Period taskJoinTimeout = new Period("PT1M");
+
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for the peon k8s job to launch
+ private Period k8sjobLaunchTimeout = new Period("PT1H");
+
+ @JsonProperty
+ @NotNull
+ // how long to wait for log saving operations to complete
+ private Period logSaveTimeout = new Period("PT300S");
+
+ @JsonProperty
+ // ForkingTaskRunner inherits the monitors from the MM, in k8s mode
+ // the peon inherits the monitors from the overlord, so if someone specifies
+ // a TaskCountStatsMonitor in the overlord for example, the peon process
+ // fails because it can not inject this monitor in the peon process.
+ private List<String> peonMonitors = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private List<String> javaOptsArray = ImmutableList.of();
+
+ @JsonProperty
+ @NotNull
+ private int cpuCoreInMicro = 0;
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> labels = ImmutableMap.of();
+
+ @JsonProperty
+ @NotNull
+ private Map<String, String> annotations = ImmutableMap.of();
+
+ @JsonProperty
+ @Min(1)
+ @Max(Integer.MAX_VALUE)
+ @NotNull
+ private Integer capacity = Integer.MAX_VALUE;
+
+ public KubernetesTaskRunnerStaticConfig()
+ {
+ }
+
+ private KubernetesTaskRunnerStaticConfig(
+ @Nonnull String namespace,
+ String overlordNamespace,
+ String k8sTaskPodNamePrefix,
+ boolean debugJobs,
+ boolean sidecarSupport,
+ String primaryContainerName,
+ String kubexitImage,
+ Long graceTerminationPeriodSeconds,
+ boolean disableClientProxy,
+ Period maxTaskDuration,
+ Period taskCleanupDelay,
+ Period taskCleanupInterval,
+ Period k8sjobLaunchTimeout,
+ Period logSaveTimeout,
+ List<String> peonMonitors,
+ List<String> javaOptsArray,
+ int cpuCoreInMicro,
+ Map<String, String> labels,
+ Map<String, String> annotations,
+ Integer capacity,
+ Period taskJoinTimeout
+ )
+ {
+ this.namespace = namespace;
+ this.overlordNamespace = ObjectUtils.defaultIfNull(
+ overlordNamespace,
+ this.overlordNamespace
+ );
+ this.k8sTaskPodNamePrefix = k8sTaskPodNamePrefix;
+ this.debugJobs = ObjectUtils.defaultIfNull(
+ debugJobs,
+ this.debugJobs
+ );
+ this.sidecarSupport = ObjectUtils.defaultIfNull(
+ sidecarSupport,
+ this.sidecarSupport
+ );
+ this.primaryContainerName = ObjectUtils.defaultIfNull(
+ primaryContainerName,
+ this.primaryContainerName
+ );
+ this.kubexitImage = ObjectUtils.defaultIfNull(
+ kubexitImage,
+ this.kubexitImage
+ );
+ this.graceTerminationPeriodSeconds = ObjectUtils.defaultIfNull(
+ graceTerminationPeriodSeconds,
+ this.graceTerminationPeriodSeconds
+ );
+ this.disableClientProxy = disableClientProxy;
+ this.maxTaskDuration = ObjectUtils.defaultIfNull(
+ maxTaskDuration,
+ this.maxTaskDuration
+ );
+ this.taskCleanupDelay = ObjectUtils.defaultIfNull(
+ taskCleanupDelay,
+ this.taskCleanupDelay
+ );
+ this.taskCleanupInterval = ObjectUtils.defaultIfNull(
+ taskCleanupInterval,
+ this.taskCleanupInterval
+ );
+ this.k8sjobLaunchTimeout = ObjectUtils.defaultIfNull(
+ k8sjobLaunchTimeout,
+ this.k8sjobLaunchTimeout
+ );
+ this.taskJoinTimeout = ObjectUtils.defaultIfNull(
+ taskJoinTimeout,
+ this.taskJoinTimeout
+ );
+ this.logSaveTimeout = ObjectUtils.defaultIfNull(
+ logSaveTimeout,
+ this.logSaveTimeout
+ );
+ this.peonMonitors = ObjectUtils.defaultIfNull(
+ peonMonitors,
+ this.peonMonitors
+ );
+ this.javaOptsArray = ObjectUtils.defaultIfNull(
+ javaOptsArray,
+ this.javaOptsArray
+ );
+ this.cpuCoreInMicro = ObjectUtils.defaultIfNull(
+ cpuCoreInMicro,
+ this.cpuCoreInMicro
+ );
+ this.labels = ObjectUtils.defaultIfNull(
+ labels,
+ this.labels
+ );
+ this.annotations = ObjectUtils.defaultIfNull(
+ annotations,
+ this.annotations
+ );
+ this.capacity = ObjectUtils.defaultIfNull(
+ capacity,
+ this.capacity
+ );
Review Comment:
## Deprecated method or constructor invocation
Invoking [ObjectUtils.defaultIfNull](1) should be avoided because it has been deprecated.
[Show more details](https://github.com/apache/druid/security/code-scanning/10482)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3365136456
> @GabrielCWT , thanks for putting this together.
>
> I might be mistaken but I am not entirely sure if the task capacity of a cluster should be a dynamic config. For any cluster admin, this can have large cost implications. It seems odd to be able to override the capacity of the cluster defined in the Overlord runtime property simply by calling an API.
>
> Changing the task capacity should not be a very frequent requirement for any cluster. And when needed, it should be fairly reasonable to require an Overlord restart.
>
> Could you please elaborate on why you feel the current setup is not adequate?
Restarting the Overlord can be time-consuming and potentially risky as we could face issues when trying to redeploy the Overlord instance. Updating the task capacity dynamically allows admins to adjust the cluster safely, reducing operational downtime and complexity. While changes to task capacity are infrequent, I feel that providing a safer runtime option would help to minimize disruptions.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3546921496
@kfaraz can we merge this now? because I'm going to add a new kubernetes runner, and we hope this PR can be merged first otherwise there will be conflicts.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3624245498
@kfaraz I merged this. if there's any concerns, let's resolve it in a new pr.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3365100320
@GabrielCWT , thanks for putting this together.
I might be mistaken but I am not entirely sure if the task capacity of a cluster should be a dynamic config.
For any cluster admin, this can have large cost implications.
It seems odd to be able to override the capacity of the cluster defined in the Overlord runtime property
simply by calling an API.
Changing the task capacity should not be a very frequent requirement for any cluster.
And when needed, it should be fairly reasonable to require an Overlord restart.
Could you please elaborate on why you feel the current setup is not adequate?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "cryptoe (via GitHub)" <gi...@apache.org>.
cryptoe commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2465602586
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -179,6 +191,24 @@ protected KubernetesWorkItem joinAsync(Task task)
}
}
+ private void syncCapacityWithDynamicConfig(KubernetesTaskRunnerDynamicConfig config)
Review Comment:
This looks much cleaner. Thanks @FrankChen021 for the suggestion and @GabrielCWT for the impl.
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -132,10 +142,12 @@ public KubernetesTaskRunner(
this.httpClient = httpClient;
this.peonLifecycleFactory = peonLifecycleFactory;
this.cleanupExecutor = Executors.newScheduledThreadPool(1);
- this.exec = MoreExecutors.listeningDecorator(
- Execs.multiThreaded(config.getCapacity(), "k8s-task-runner-%d")
- );
this.emitter = emitter;
+
+ this.currentCapacity = config.getCapacity();
+ this.tpe = new ThreadPoolExecutor(currentCapacity, currentCapacity, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Execs.makeThreadFactory("k8s-task-runner-%d", null));
+ this.exec = MoreExecutors.listeningDecorator(this.tpe);
+ configManager.addListener(KubernetesTaskRunnerDynamicConfig.CONFIG_KEY, StringUtils.format(OBSERVER_KEY, Thread.currentThread().getId()), this::syncCapacityWithDynamicConfig);
Review Comment:
Would this run in the jetty thread?
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -111,19 +117,23 @@ public class KubernetesTaskRunner implements TaskLogStreamer, TaskRunner
private final KubernetesPeonClient client;
private final KubernetesTaskRunnerConfig config;
private final ListeningExecutorService exec;
+ private final ThreadPoolExecutor tpe;
private final HttpClient httpClient;
private final PeonLifecycleFactory peonLifecycleFactory;
private final ServiceEmitter emitter;
// currently worker categories aren't supported, so it's hardcoded.
protected static final String WORKER_CATEGORY = "_k8s_worker_category";
+ private int currentCapacity;
Review Comment:
This should be made thread safe. Use Atomic int.
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -179,6 +189,24 @@ protected KubernetesWorkItem joinAsync(Task task)
}
}
+ private void syncCapacityWithDynamicConfig()
Review Comment:
Thank you the watcher based approach looks much more cleaner.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "GabrielCWT (via GitHub)" <gi...@apache.org>.
GabrielCWT commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2446965554
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -179,6 +189,24 @@ protected KubernetesWorkItem joinAsync(Task task)
}
}
+ private void syncCapacityWithDynamicConfig()
Review Comment:
I've added observer support for ConfigHolders
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "kfaraz (via GitHub)" <gi...@apache.org>.
kfaraz commented on PR #18591:
URL: https://github.com/apache/druid/pull/18591#issuecomment-3624383909
Thanks for the update, @FrankChen021 !
My concern was mostly the code structure, the fact that we have to pass around an "effective" config and the merging of static and dynamic configs (even though most of the configs seem to be always static), but we can always address it later if needed.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "FrankChen021 (via GitHub)" <gi...@apache.org>.
FrankChen021 commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2425110452
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -179,6 +189,24 @@ protected KubernetesWorkItem joinAsync(Task task)
}
}
+ private void syncCapacityWithDynamicConfig()
Review Comment:
using a separate thread to check is also a bad idea , it does not solve the real problem here but increase the complexity.
the real problem here is that the config manager does not provide a notification mechanism when it detects configuration changes.
If we look at the config manager implementation, it provides a method `swapIfNew` to check and set new values. This is a place where we can add notification.
I think we can add a new overridden `watch` method which accepts a `Runnable` as callback.
This callback is kept in the internal `ConfigHolder`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org
Re: [PR] Implement dynamic capacity for kubernetes task runner (druid)
Posted by "cryptoe (via GitHub)" <gi...@apache.org>.
cryptoe commented on code in PR #18591:
URL: https://github.com/apache/druid/pull/18591#discussion_r2418558386
##########
extensions-core/kubernetes-overlord-extensions/src/main/java/org/apache/druid/k8s/overlord/KubernetesTaskRunner.java:
##########
@@ -179,6 +189,24 @@ protected KubernetesWorkItem joinAsync(Task task)
}
}
+ private void syncCapacityWithDynamicConfig()
Review Comment:
This code is not maintainable.
Can we do this in a seperate thread instead of calling sync everywhere.
Is the currentCapacity thread safe ?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org