This is an automated email from the ASF dual-hosted git repository.
czy006 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/amoro.git
The following commit(s) were added to refs/heads/master by this push:
new 04fef53e0 [AMORO-2979] Support K8S Pod Template From
KubernetesOptimizer (#3072)
04fef53e0 is described below
commit 04fef53e054cee488807a6f4b72fccf4e37996ab
Author: wyx <[email protected]>
AuthorDate: Thu Sep 5 09:53:19 2024 +0800
[AMORO-2979] Support K8S Pod Template From KubernetesOptimizer (#3072)
[AMORO-2979] Added podTemplate support and test unit(#2979)
---
.../manager/KubernetesOptimizerContainer.java | 180 +++++++++++++-
.../manager/TestKubernetesOptimizerContainer.java | 274 +++++++++++++++++++++
amoro-ams/src/test/resources/config.yaml | 35 ++-
docs/admin-guides/deployment-on-kubernetes.md | 50 ++++
pom.xml | 2 +-
5 files changed, 528 insertions(+), 13 deletions(-)
diff --git
a/amoro-ams/src/main/java/org/apache/amoro/server/manager/KubernetesOptimizerContainer.java
b/amoro-ams/src/main/java/org/apache/amoro/server/manager/KubernetesOptimizerContainer.java
index 1bd613408..3ccb0db3d 100644
---
a/amoro-ams/src/main/java/org/apache/amoro/server/manager/KubernetesOptimizerContainer.java
+++
b/amoro-ams/src/main/java/org/apache/amoro/server/manager/KubernetesOptimizerContainer.java
@@ -18,12 +18,18 @@
package org.apache.amoro.server.manager;
+import io.fabric8.kubernetes.api.model.Container;
+import io.fabric8.kubernetes.api.model.LabelSelector;
import io.fabric8.kubernetes.api.model.LocalObjectReference;
import io.fabric8.kubernetes.api.model.LocalObjectReferenceBuilder;
+import io.fabric8.kubernetes.api.model.ObjectMeta;
+import io.fabric8.kubernetes.api.model.PodTemplate;
import io.fabric8.kubernetes.api.model.Quantity;
+import io.fabric8.kubernetes.api.model.ResourceRequirements;
import io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
+import io.fabric8.kubernetes.api.model.apps.DeploymentSpec;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
@@ -34,12 +40,15 @@ import
org.apache.amoro.shade.guava32.com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -54,7 +63,7 @@ public class KubernetesOptimizerContainer extends
AbstractResourceContainer {
public static final String NAMESPACE = "namespace";
public static final String IMAGE = "image";
public static final String PULL_POLICY = "pullPolicy";
-
+ public static final String PODTEMPLATE = "podTemplate";
public static final String PULL_SECRETS = "imagePullSecrets";
public static final String KUBE_CONFIG_PATH = "kube-config-path";
@@ -79,9 +88,67 @@ public class KubernetesOptimizerContainer extends
AbstractResourceContainer {
groupProperties.putAll(getContainerProperties());
groupProperties.putAll(resource.getProperties());
- // generate pod start args
- long memoryPerThread = Long.parseLong(checkAndGetProperty(groupProperties,
MEMORY_PROPERTY));
- long memory = memoryPerThread * resource.getThreadCount();
+ Map<String, Object> argsList = generatePodStartArgs(resource,
groupProperties);
+ String image = argsList.get(IMAGE).toString();
+ String namespace = argsList.get(NAMESPACE).toString();
+ String pullPolicy = argsList.get(PULL_POLICY).toString();
+ List<LocalObjectReference> imagePullSecretsList =
+ (List<LocalObjectReference>) argsList.get(PULL_SECRETS);
+ int cpuLimit = (int) argsList.get("cpuLimit");
+ long memory = (long) argsList.get(MEMORY_PROPERTY);
+ String groupName = argsList.get("groupName").toString();
+ String resourceId = argsList.get("resourceId").toString();
+ String startUpArgs = argsList.get("startUpArgs").toString();
+
+ String kubernetesName = NAME_PREFIX + resourceId;
+ Deployment deployment;
+
+ if (null != groupProperties.get(PODTEMPLATE)) {
+ // configure the podTemplate read from config
+ PodTemplate podTemplate = initPodTemplateFromLocal(groupProperties);
+
+ deployment =
+ initPodTemplateFromFrontEnd(
+ podTemplate,
+ image,
+ pullPolicy,
+ cpuLimit,
+ groupName,
+ resourceId,
+ startUpArgs,
+ memory,
+ imagePullSecretsList);
+ } else {
+ deployment =
+ initPodTemplateWithoutConfig(
+ image,
+ pullPolicy,
+ cpuLimit,
+ groupName,
+ resourceId,
+ startUpArgs,
+ memory,
+ imagePullSecretsList);
+ }
+
+
client.apps().deployments().inNamespace(namespace).resource(deployment).create();
+ Map<String, String> startupProperties = Maps.newHashMap();
+ startupProperties.put(NAMESPACE, namespace);
+ startupProperties.put(KUBERNETES_NAME_PROPERTIES, kubernetesName);
+ return startupProperties;
+ }
+
+ public Map<String, Object> generatePodStartArgs(
+ Resource resource, Map<String, String> groupProperties) {
+ long memoryPerThread;
+ long memory;
+
+ if (resource.getMemoryMb() > 0) {
+ memory = resource.getMemoryMb();
+ } else {
+ memoryPerThread = Long.parseLong(checkAndGetProperty(groupProperties,
MEMORY_PROPERTY));
+ memory = memoryPerThread * resource.getThreadCount();
+ }
// point at amoro home in docker image
String startUpArgs =
String.format(
@@ -104,7 +171,31 @@ public class KubernetesOptimizerContainer extends
AbstractResourceContainer {
String resourceId = resource.getResourceId();
String groupName = resource.getGroupName();
- String kubernetesName = NAME_PREFIX + resourceId;
+
+ Map<String, Object> argsList = Maps.newHashMap();
+ argsList.put(NAMESPACE, namespace);
+ argsList.put(IMAGE, image);
+ argsList.put(PULL_POLICY, pullPolicy);
+ argsList.put(PULL_SECRETS, imagePullSecretsList);
+ argsList.put(MEMORY_PROPERTY, memory);
+ argsList.put("cpuLimit", cpuLimit);
+ argsList.put("resourceId", resourceId);
+ argsList.put("groupName", groupName);
+ argsList.put("startUpArgs", startUpArgs);
+
+ return argsList;
+ }
+
+ public Deployment initPodTemplateWithoutConfig(
+ String image,
+ String pullPolicy,
+ int cpuLimit,
+ String groupName,
+ String resourceId,
+ String startUpArgs,
+ long memory,
+ List<LocalObjectReference> imagePullSecretsList) {
+
DeploymentBuilder deploymentBuilder =
new DeploymentBuilder()
.withNewMetadata()
@@ -156,13 +247,80 @@ public class KubernetesOptimizerContainer extends
AbstractResourceContainer {
.endTemplate()
.endSpec();
}
- Deployment deployment = deploymentBuilder.build();
-
client.apps().deployments().inNamespace(namespace).resource(deployment).create();
- Map<String, String> startupProperties = Maps.newHashMap();
- startupProperties.put(NAMESPACE, namespace);
- startupProperties.put(KUBERNETES_NAME_PROPERTIES, kubernetesName);
- return startupProperties;
+ return deploymentBuilder.build();
+ }
+
+ public PodTemplate initPodTemplateFromLocal(Map<String, String>
groupProperties) {
+ return new Yaml().loadAs(groupProperties.get(PODTEMPLATE),
PodTemplate.class);
+ }
+
+ public Deployment initPodTemplateFromFrontEnd(
+ PodTemplate podTemplate,
+ String image,
+ String pullPolicy,
+ int cpuLimit,
+ String groupName,
+ String resourceId,
+ String startUpArgs,
+ long memory,
+ List<LocalObjectReference> imagePullSecretsList) {
+ podTemplate
+ .getTemplate()
+ .getMetadata()
+ .setLabels(
+ new HashMap<String, String>() {
+ {
+ put("app", NAME_PREFIX + resourceId);
+ put("AmoroOptimizerGroup", groupName);
+ put("AmoroResourceId", resourceId);
+ }
+ });
+
+ Container container = new Container();
+ container.setName("optimizer");
+ container.setImage(image);
+ container.setImagePullPolicy(pullPolicy);
+ container.setCommand(new ArrayList<>(Arrays.asList("sh", "-c",
startUpArgs)));
+
+ ResourceRequirements resourceRequirements = new ResourceRequirements();
+ resourceRequirements.setLimits(
+ ImmutableMap.of(
+ "memory", new Quantity(memory + "Mi"),
+ "cpu", new Quantity(cpuLimit + "")));
+ resourceRequirements.setRequests(
+ ImmutableMap.of(
+ "memory", new Quantity(memory + "Mi"),
+ "cpu", new Quantity(cpuLimit + "")));
+ container.setResources(resourceRequirements);
+
+ podTemplate.getTemplate().getSpec().getContainers().set(0, container);
+
+ if (!imagePullSecretsList.isEmpty()) {
+
podTemplate.getTemplate().getSpec().setImagePullSecrets(imagePullSecretsList);
+ }
+
+ DeploymentSpec deploymentSpec = new DeploymentSpec();
+ deploymentSpec.setTemplate(podTemplate.getTemplate());
+
+ LabelSelector labelSelector = new LabelSelector();
+ labelSelector.setMatchLabels(
+ new HashMap<String, String>() {
+ {
+ put("app", NAME_PREFIX + resourceId);
+ }
+ });
+
+ deploymentSpec.setSelector(labelSelector);
+ deploymentSpec.setReplicas(1);
+
+ Deployment deployment = new Deployment();
+ deployment.setSpec(deploymentSpec);
+ ObjectMeta deploymentMetadata = new ObjectMeta();
+ deploymentMetadata.setName(NAME_PREFIX + resourceId);
+ deployment.setMetadata(deploymentMetadata);
+
+ return deployment;
}
@Override
diff --git
a/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
b/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
new file mode 100644
index 000000000..fa44530b4
--- /dev/null
+++
b/amoro-ams/src/test/java/org/apache/amoro/server/manager/TestKubernetesOptimizerContainer.java
@@ -0,0 +1,274 @@
+/*
+ * 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.amoro.server.manager;
+
+import io.fabric8.kubernetes.api.model.LocalObjectReference;
+import io.fabric8.kubernetes.api.model.LocalObjectReferenceBuilder;
+import io.fabric8.kubernetes.api.model.PodTemplate;
+import io.fabric8.kubernetes.api.model.apps.Deployment;
+import org.apache.amoro.OptimizerProperties;
+import org.apache.amoro.resource.Resource;
+import org.apache.amoro.resource.ResourceType;
+import org.apache.amoro.server.AmoroManagementConf;
+import org.apache.amoro.shade.guava32.com.google.common.base.Preconditions;
+import org.apache.amoro.shade.guava32.com.google.common.collect.Maps;
+import org.apache.amoro.shade.jackson2.com.fasterxml.jackson.databind.JsonNode;
+import
org.apache.amoro.shade.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.amoro.utils.JacksonUtil;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.IOException;
+import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class TestKubernetesOptimizerContainer {
+ private KubernetesOptimizerContainer kubernetesOptimizerContainer;
+ private Map<String, String> containerProperties;
+ private Map<String, String> groupProperties;
+ public static final String MEMORY_PROPERTY = "memory";
+ public static final String CPU_FACTOR_PROPERTY = "cpu.factor";
+ public static final String IMAGE = "image";
+ public static final String PULL_POLICY = "pullPolicy";
+ public static final String PULL_SECRETS = "imagePullSecrets";
+
+ @Before
+ public void setup() throws IOException {
+ // generating configuration files
+ kubernetesOptimizerContainer = new KubernetesOptimizerContainer();
+ groupProperties = Maps.newHashMap();
+ containerProperties = Maps.newHashMap();
+
+ containerProperties.put(OptimizerProperties.AMS_HOME, "/home/ams");
+ containerProperties.put(OptimizerProperties.AMS_OPTIMIZER_URI,
"thrift://127.0.0.1:1261");
+
+ URL resource = getClass().getClassLoader().getResource("config.yaml");
+
+ JsonNode yamlConfig =
+ JacksonUtil.fromObjects(
+ new
Yaml().loadAs(Files.newInputStream(Paths.get(resource.getPath())), Map.class));
+ JsonNode containers = yamlConfig.get(AmoroManagementConf.CONTAINER_LIST);
+ for (JsonNode container : containers) {
+ if (container.get("name").asText().equals("KubernetesContainer")) {
+ ObjectMapper mapper = new ObjectMapper();
+
containerProperties.putAll(mapper.convertValue(container.get("properties"),
Map.class));
+ }
+ }
+ groupProperties.putAll(this.containerProperties);
+ }
+
+ private static String checkAndGetProperty(Map<String, String> properties,
String key) {
+ Preconditions.checkState(
+ properties != null && properties.containsKey(key), "Cannot find %s in
properties", key);
+ return properties.get(key);
+ }
+
+ @Test
+ public void testBuildPodTemplateFromLocal() {
+ PodTemplate podTemplate =
+ kubernetesOptimizerContainer.initPodTemplateFromLocal(groupProperties);
+
+ Assert.assertEquals(1,
podTemplate.getTemplate().getSpec().getContainers().size());
+ // read the image version from the podTemplate config and assert it
+ Assert.assertEquals(
+ "apache/amoro:0.6",
podTemplate.getTemplate().getSpec().getContainers().get(0).getImage());
+ }
+
+ @Test
+ public void testBuildPodTemplateWithResourceSetMemoryMb() {
+ PodTemplate podTemplate =
+ kubernetesOptimizerContainer.initPodTemplateFromLocal(groupProperties);
+
+ ResourceType resourceType = ResourceType.OPTIMIZER;
+ Map<String, String> properties = Maps.newHashMap();
+ properties.put("memory", "1024");
+ Resource resource =
+ new Resource.Builder("KubernetesContainer", "k8s", resourceType)
+ .setMemoryMb(1025) // It's not 0 here
+ .setThreadCount(1)
+ .setProperties(properties)
+ .build();
+ groupProperties.putAll(resource.getProperties());
+
+ Map<String, Object> argsList =
+ kubernetesOptimizerContainer.generatePodStartArgs(resource,
groupProperties);
+ String image = argsList.get(IMAGE).toString();
+ String pullPolicy = argsList.get(PULL_POLICY).toString();
+ List<LocalObjectReference> imagePullSecretsList =
+ (List<LocalObjectReference>) argsList.get(PULL_SECRETS);
+ int cpuLimit = (int) argsList.get("cpuLimit");
+ long memory = (long) argsList.get(MEMORY_PROPERTY);
+ String groupName = argsList.get("groupName").toString();
+ String resourceId = argsList.get("resourceId").toString();
+ String startUpArgs = argsList.get("startUpArgs").toString();
+
+ Deployment deployment =
+ kubernetesOptimizerContainer.initPodTemplateFromFrontEnd(
+ podTemplate,
+ image,
+ pullPolicy,
+ cpuLimit,
+ groupName,
+ resourceId,
+ startUpArgs,
+ memory,
+ imagePullSecretsList);
+
+ Assert.assertEquals(1, deployment.getSpec().getReplicas().intValue());
+ Assert.assertNotEquals(
+ "1024Mi",
+ deployment
+ .getSpec()
+ .getTemplate()
+ .getSpec()
+ .getContainers()
+ .get(0)
+ .getResources()
+ .getLimits()
+ .get("memory")
+ .toString());
+ Assert.assertEquals(
+ "1025Mi",
+ deployment
+ .getSpec()
+ .getTemplate()
+ .getSpec()
+ .getContainers()
+ .get(0)
+ .getResources()
+ .getLimits()
+ .get("memory")
+ .toString());
+ }
+
+ @Test
+ public void testBuildPodTemplateConfig() {
+ // before parameter merging
+ PodTemplate podTemplate =
+ kubernetesOptimizerContainer.initPodTemplateFromLocal(groupProperties);
+
+ // after parameter merging
+ ResourceType resourceType = ResourceType.OPTIMIZER;
+ Map<String, String> properties = Maps.newHashMap();
+ properties.put("memory", "1024");
+ Resource resource =
+ new Resource.Builder("KubernetesContainer", "k8s", resourceType)
+ .setMemoryMb(0)
+ .setThreadCount(1)
+ .setProperties(properties)
+ .build();
+ groupProperties.putAll(resource.getProperties());
+
+ // generate pod start args
+ long memoryPerThread;
+ long memory;
+
+ if (resource.getMemoryMb() > 0) {
+ memory = resource.getMemoryMb();
+ } else {
+ memoryPerThread = Long.parseLong(checkAndGetProperty(groupProperties,
MEMORY_PROPERTY));
+ memory = memoryPerThread * resource.getThreadCount();
+ }
+ String startUpArgs =
+ String.format(
+ "/entrypoint.sh optimizer %s %s",
+ memory,
kubernetesOptimizerContainer.buildOptimizerStartupArgsString(resource));
+ // read the image version from config and assert it , but not from
podTemplate
+ String image = checkAndGetProperty(groupProperties, IMAGE);
+ String pullPolicy = checkAndGetProperty(groupProperties, PULL_POLICY);
+ String pullSecrets = groupProperties.getOrDefault(PULL_SECRETS, "");
+ String cpuLimitFactorString =
groupProperties.getOrDefault(CPU_FACTOR_PROPERTY, "1.0");
+ double cpuLimitFactor = Double.parseDouble(cpuLimitFactorString);
+ int cpuLimit = (int) (Math.ceil(cpuLimitFactor *
resource.getThreadCount()));
+
+ List<LocalObjectReference> imagePullSecretsList =
+ Arrays.stream(pullSecrets.split(";"))
+ .map(secret -> new
LocalObjectReferenceBuilder().withName(secret).build())
+ .collect(Collectors.toList());
+
+ String resourceId = resource.getResourceId();
+ String groupName = resource.getGroupName();
+
+ Assert.assertEquals(1,
podTemplate.getTemplate().getSpec().getContainers().size());
+
+ // read the image version from the podTemplate config and assert it
+ Assert.assertEquals(
+ "apache/amoro:0.6",
podTemplate.getTemplate().getSpec().getContainers().get(0).getImage());
+
+ Deployment deployment =
+ kubernetesOptimizerContainer.initPodTemplateFromFrontEnd(
+ podTemplate,
+ image,
+ pullPolicy,
+ cpuLimit,
+ groupName,
+ resourceId,
+ startUpArgs,
+ memory,
+ imagePullSecretsList);
+
+ Assert.assertEquals("amoro-optimizer-" + resourceId,
deployment.getMetadata().getName());
+ Assert.assertEquals(
+ "k8s",
+
deployment.getSpec().getTemplate().getMetadata().getLabels().get("AmoroOptimizerGroup"));
+ Assert.assertEquals(1, deployment.getSpec().getReplicas().intValue());
+ Assert.assertEquals(
+ "IfNotPresent",
+
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImagePullPolicy());
+
+ Assert.assertEquals(1,
deployment.getSpec().getTemplate().getSpec().getContainers().size());
+
+ // read the image version from the podTemplate config and assert it
+ // the final version is still apache/amoro:0.7-SNAPSHOT
+ Assert.assertEquals(
+ "apache/amoro:0.7-SNAPSHOT",
+
deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage());
+ Assert.assertEquals(
+ String.valueOf(cpuLimit),
+ deployment
+ .getSpec()
+ .getTemplate()
+ .getSpec()
+ .getContainers()
+ .get(0)
+ .getResources()
+ .getLimits()
+ .get("cpu")
+ .toString());
+ Assert.assertEquals(
+ memory + "Mi",
+ deployment
+ .getSpec()
+ .getTemplate()
+ .getSpec()
+ .getContainers()
+ .get(0)
+ .getResources()
+ .getLimits()
+ .get("memory")
+ .toString());
+ }
+}
diff --git a/amoro-ams/src/test/resources/config.yaml
b/amoro-ams/src/test/resources/config.yaml
index 168046fda..4f1efa9c9 100644
--- a/amoro-ams/src/test/resources/config.yaml
+++ b/amoro-ams/src/test/resources/config.yaml
@@ -36,4 +36,37 @@ taskmanager:
size: 1728m
parallelism:
- default: 1
\ No newline at end of file
+ default: 1
+
+containers:
+ - name: KubernetesContainer
+ container-impl:
org.apache.amoro.server.manager.KubernetesOptimizerContainer
+ properties:
+ kube-config-path: "~/.kube/config"
+ image: apache/amoro:0.7-SNAPSHOT
+ namespace: default
+ pullPolicy: "IfNotPresent"
+ podTemplate: |
+ apiVersion: apps/v1
+ kind: PodTemplate
+ metadata:
+ name: <NAME_PREFIX><resourceId>
+ template:
+ metadata:
+ labels:
+ app: <NAME_PREFIX><resourceId>
+ AmoroOptimizerGroup: <groupName>
+ AmoroResourceId: <resourceId>
+ spec:
+ containers:
+ - name: optimizer
+ image: apache/amoro:0.6
+ imagePullPolicy: IfNotPresent
+ command: [ "sh", "-c", "echo 'Hello, World!'" ]
+ resources:
+ limits:
+ memory: 2048Mi
+ cpu: 2
+ requests:
+ memory: 2048Mi
+ cpu: 2
\ No newline at end of file
diff --git a/docs/admin-guides/deployment-on-kubernetes.md
b/docs/admin-guides/deployment-on-kubernetes.md
index 22ca2fe0d..b5d75ef08 100644
--- a/docs/admin-guides/deployment-on-kubernetes.md
+++ b/docs/admin-guides/deployment-on-kubernetes.md
@@ -209,6 +209,56 @@ optimizer:
"flink-conf.taskmanager.memory.network.min": "32mb"
}
```
+### Configure the Kubernetes Optimizer Container
+
+By default, the Kubernetes Optimizer Container is enabled.
+You can modify the container configuration by changing the
`optimizer.Kubernetes` section.
+
+```yaml
+optimizer:
+ kubernetes:
+ # enable the kubernetes optimizer container
+ enabled: true
+ properties:
+ namespace: "default"
+ kube-config-path: "~/.kube/config"
+ image: "apache/amoro:latest"
+ pullPolicy: "IfNotPresent"
+```
+
+To use PodTemplate, you need to copy and paste the following into the
`kubernetes.properties`.
+
+This is the default podTemplate, and when the user doesn't specify any
additional parameters, the default is to use the template's parameters
+
+Therefore, there will be a priority issue that needs to be elaborated:
_Resource(WebUi) > Independent User Profile Configuration > PodTemplate_
+
+```yaml
+podTemplate: |
+ apiVersion: apps/v1
+ kind: PodTemplate
+ metadata:
+ name: <NAME_PREFIX><resourceId>
+ template:
+ metadata:
+ labels:
+ app: <NAME_PREFIX><resourceId>
+ AmoroOptimizerGroup: <groupName>
+ AmoroResourceId: <resourceId>
+ spec:
+ containers:
+ - name: optimizer
+ image: apache/amoro:0.6
+ imagePullPolicy: IfNotPresent
+ command: [ "sh", "-c", "echo 'Hello, World!'" ]
+ resources:
+ limits:
+ memory: 2048Mi
+ cpu: 2
+ requests:
+ memory: 2048Mi
+ cpu: 2
+
+```
### Configure the RBAC
diff --git a/pom.xml b/pom.xml
index 20a5a0212..72d92a3ab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -140,7 +140,7 @@
<bitmap.version>1.0.1</bitmap.version>
<prometheus.version>0.16.0</prometheus.version>
<flink.version>1.20.0</flink.version>
-
<fabric8-kubernetes-client.version.version>6.12.1</fabric8-kubernetes-client.version.version>
+
<fabric8-kubernetes-client.version.version>6.13.3</fabric8-kubernetes-client.version.version>
<amoro-shade.version>0.7.0-incubating</amoro-shade.version>
<amoro-shade-guava.version>32.1.1-jre</amoro-shade-guava.version>
<amoro-shade-jackson.version>2.14.2</amoro-shade-jackson.version>