Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ protected String buildOptimizerStartupArgsString(Resource resource) {
.append(" -hb ")
.append(resource.getProperties().get(OptimizerProperties.OPTIMIZER_HEART_BEAT_INTERVAL));
}
if (resource.getProperties().containsKey(OptimizerProperties.OPTIMIZER_SHUTDOWN_TIMEOUT_MS)) {
stringBuilder
.append(" -st ")
.append(resource.getProperties().get(OptimizerProperties.OPTIMIZER_SHUTDOWN_TIMEOUT_MS));
}
if (PropertyUtil.propertyAsBoolean(
resource.getProperties(),
OptimizerProperties.OPTIMIZER_EXTEND_DISK_STORAGE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import org.apache.amoro.OptimizerProperties;
import org.apache.amoro.resource.Resource;
import org.apache.amoro.shade.guava32.com.google.common.base.Preconditions;
import org.apache.amoro.shade.guava32.com.google.common.collect.ImmutableMap;
import org.apache.amoro.shade.guava32.com.google.common.collect.Maps;
import org.apache.amoro.utils.PropertyUtil;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -75,6 +77,13 @@ public class KubernetesOptimizerContainer extends AbstractOptimizerContainer {

private static final String EXTRA_PROPERTY_PREFIX = "extra.";

/**
* Buffer added on top of optimizer's shutdown-timeout when deriving K8s
* terminationGracePeriodSeconds, to leave room for thread join, best-effort task result
* reporting, and log flush before SIGKILL.
*/
static final long TERMINATION_GRACE_BUFFER_SECONDS = 30L;

private static final Map<String, String> EXTRA_PROPERTY_DEFAULTS = new HashMap<>();

static {
Expand All @@ -86,6 +95,16 @@ private String getExtraProperty(Map<String, String> properties, String key) {
EXTRA_PROPERTY_PREFIX + key, EXTRA_PROPERTY_DEFAULTS.getOrDefault(key, null));
}

static long resolveTerminationGracePeriodSeconds(Map<String, String> properties) {
long shutdownTimeoutMs =
PropertyUtil.propertyAsLong(
properties,
OptimizerProperties.OPTIMIZER_SHUTDOWN_TIMEOUT_MS,
OptimizerProperties.OPTIMIZER_SHUTDOWN_TIMEOUT_MS_DEFAULT);
long shutdownTimeoutSeconds = (shutdownTimeoutMs + 999L) / 1000L;
return shutdownTimeoutSeconds + TERMINATION_GRACE_BUFFER_SECONDS;
}

private KubernetesClient client;

@Override
Expand Down Expand Up @@ -118,6 +137,7 @@ protected Map<String, String> doScaleOut(Resource resource) {
String groupName = argsList.get("groupName").toString();
String resourceId = argsList.get("resourceId").toString();
String startUpArgs = argsList.get("startUpArgs").toString();
long terminationGraceSeconds = (long) argsList.get("terminationGraceSeconds");

String kubernetesName = NAME_PREFIX + resourceId;
Deployment deployment;
Expand All @@ -136,7 +156,8 @@ protected Map<String, String> doScaleOut(Resource resource) {
resourceId,
startUpArgs,
memory,
imagePullSecretsList);
imagePullSecretsList,
terminationGraceSeconds);
} else {
deployment =
initPodTemplateWithoutConfig(
Expand All @@ -147,7 +168,8 @@ protected Map<String, String> doScaleOut(Resource resource) {
resourceId,
startUpArgs,
memory,
imagePullSecretsList);
imagePullSecretsList,
terminationGraceSeconds);
}

client.apps().deployments().inNamespace(namespace).resource(deployment).create();
Expand Down Expand Up @@ -206,6 +228,11 @@ public Map<String, Object> generatePodStartArgs(
argsList.put("resourceId", resourceId);
argsList.put("groupName", groupName);
argsList.put("startUpArgs", startUpArgs);
// Derive the grace period from the same resource properties that drive the -st startup arg
// (buildOptimizerStartupArgsString), so the pod's SIGKILL deadline can never fall below the
// shutdown timeout the optimizer JVM actually honors.
argsList.put(
"terminationGraceSeconds", resolveTerminationGracePeriodSeconds(resource.getProperties()));

return argsList;
}
Expand All @@ -218,7 +245,8 @@ public Deployment initPodTemplateWithoutConfig(
String resourceId,
String startUpArgs,
long memory,
List<LocalObjectReference> imagePullSecretsList) {
List<LocalObjectReference> imagePullSecretsList,
long terminationGraceSeconds) {

DeploymentBuilder deploymentBuilder =
new DeploymentBuilder()
Expand All @@ -234,11 +262,12 @@ public Deployment initPodTemplateWithoutConfig(
.addToLabels("AmoroResourceId", resourceId)
.endMetadata()
.withNewSpec()
.withTerminationGracePeriodSeconds(terminationGraceSeconds)
.addNewContainer()
.withName("optimizer")
.withImage(image)
.withImagePullPolicy(pullPolicy)
.withCommand("sh", "-c", startUpArgs)
.withCommand("sh", "-c", "exec " + startUpArgs)
.withResources(
new ResourceRequirementsBuilder()
.withLimits(
Expand Down Expand Up @@ -288,7 +317,8 @@ public Deployment initPodTemplateFromFrontEnd(
String resourceId,
String startUpArgs,
long memory,
List<LocalObjectReference> imagePullSecretsList) {
List<LocalObjectReference> imagePullSecretsList,
long terminationGraceSeconds) {
podTemplate
.getTemplate()
.getMetadata()
Expand All @@ -305,7 +335,7 @@ public Deployment initPodTemplateFromFrontEnd(
container.setName("optimizer");
container.setImage(image);
container.setImagePullPolicy(pullPolicy);
container.setCommand(new ArrayList<>(Arrays.asList("sh", "-c", startUpArgs)));
container.setCommand(new ArrayList<>(Arrays.asList("sh", "-c", "exec " + startUpArgs)));

ResourceRequirements resourceRequirements = new ResourceRequirements();
resourceRequirements.setLimits(
Expand All @@ -324,6 +354,10 @@ public Deployment initPodTemplateFromFrontEnd(
podTemplate.getTemplate().getSpec().setImagePullSecrets(imagePullSecretsList);
}

if (podTemplate.getTemplate().getSpec().getTerminationGracePeriodSeconds() == null) {
podTemplate.getTemplate().getSpec().setTerminationGracePeriodSeconds(terminationGraceSeconds);
}

DeploymentSpec deploymentSpec = new DeploymentSpec();
deploymentSpec.setTemplate(podTemplate.getTemplate());

Expand Down
Loading
Loading