use of io.kubernetes.client.openapi.models.V1PodSpec in project heron by twitter.
the class V1Controller method configurePodSpec.
/**
* Configures the <code>Pod Spec</code> section of the <code>StatefulSet</code>. The <code>Heron</code> container
* will be configured to allow it to function but other supplied containers are loaded verbatim.
* @param podTemplateSpec The <code>Pod Template Spec</code> section to update.
* @param resource Passed down to configure the resource limits.
* @param numberOfInstances Passed down to configure the ports.
* @param isExecutor Flag used to configure components specific to <code>Executor</code> and <code>Manager</code>.
* @param volumes <code>Volumes</code> generated from configurations options.
* @param volumeMounts <code>Volume Mounts</code> generated from configurations options.
*/
private void configurePodSpec(final V1PodTemplateSpec podTemplateSpec, Resource resource, int numberOfInstances, boolean isExecutor, List<V1Volume> volumes, List<V1VolumeMount> volumeMounts) {
if (podTemplateSpec.getSpec() == null) {
podTemplateSpec.setSpec(new V1PodSpec());
}
final V1PodSpec podSpec = podTemplateSpec.getSpec();
// Set the termination period to 0 so pods can be deleted quickly
podSpec.setTerminationGracePeriodSeconds(0L);
// Set the pod tolerations so pods are rescheduled when nodes go down
// https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/#taint-based-evictions
configureTolerations(podSpec);
// Get <Heron> container and ignore all others.
final String containerName = isExecutor ? KubernetesConstants.EXECUTOR_NAME : KubernetesConstants.MANAGER_NAME;
V1Container heronContainer = null;
List<V1Container> containers = podSpec.getContainers();
if (containers != null) {
for (V1Container container : containers) {
final String name = container.getName();
if (name != null && name.equals(containerName)) {
if (heronContainer != null) {
throw new TopologySubmissionException(String.format("Multiple configurations found for '%s' container", containerName));
}
heronContainer = container;
}
}
} else {
containers = new LinkedList<>();
}
if (heronContainer == null) {
heronContainer = new V1Container().name(containerName);
containers.add(heronContainer);
}
if (!volumes.isEmpty() || !volumeMounts.isEmpty()) {
configurePodWithVolumesAndMountsFromCLI(podSpec, heronContainer, volumes, volumeMounts);
}
configureHeronContainer(resource, numberOfInstances, heronContainer, isExecutor);
podSpec.setContainers(containers);
addVolumesIfPresent(podSpec);
mountSecretsAsVolumes(podSpec);
}
use of io.kubernetes.client.openapi.models.V1PodSpec in project heron by twitter.
the class V1ControllerTest method testConfigureTolerations.
@Test
public void testConfigureTolerations() {
final V1Toleration keptToleration = new V1Toleration().key("kept toleration").operator("Some Operator").effect("Some Effect").tolerationSeconds(5L);
final List<V1Toleration> expectedTolerationBase = Collections.unmodifiableList(V1Controller.getTolerations());
final List<V1Toleration> inputTolerationsBase = Collections.unmodifiableList(Arrays.asList(new V1Toleration().key(KubernetesConstants.TOLERATIONS.get(0)).operator("replace").effect("replace"), new V1Toleration().key(KubernetesConstants.TOLERATIONS.get(1)).operator("replace").effect("replace"), keptToleration));
// Null Tolerations. This is the default case.
final V1PodSpec podSpecNullTolerations = new V1PodSpecBuilder().build();
v1ControllerWithPodTemplate.configureTolerations(podSpecNullTolerations);
Assert.assertTrue("Pod Spec has null TOLERATIONS and should be set to Heron's defaults", CollectionUtils.containsAll(podSpecNullTolerations.getTolerations(), expectedTolerationBase));
// Empty Tolerations.
final V1PodSpec podSpecWithEmptyTolerations = new V1PodSpecBuilder().withTolerations(new LinkedList<>()).build();
v1ControllerWithPodTemplate.configureTolerations(podSpecWithEmptyTolerations);
Assert.assertTrue("Pod Spec has empty TOLERATIONS and should be set to Heron's defaults", CollectionUtils.containsAll(podSpecWithEmptyTolerations.getTolerations(), expectedTolerationBase));
// Toleration overriding.
final V1PodSpec podSpecWithTolerations = new V1PodSpecBuilder().withTolerations(inputTolerationsBase).build();
final List<V1Toleration> expectedTolerationsOverriding = new LinkedList<>(expectedTolerationBase);
expectedTolerationsOverriding.add(keptToleration);
v1ControllerWithPodTemplate.configureTolerations(podSpecWithTolerations);
Assert.assertTrue("Pod Spec has TOLERATIONS and should be overridden with Heron's defaults", CollectionUtils.containsAll(podSpecWithTolerations.getTolerations(), expectedTolerationsOverriding));
}
use of io.kubernetes.client.openapi.models.V1PodSpec in project heron by twitter.
the class V1ControllerTest method testAddVolumesIfPresent.
@Test
public void testAddVolumesIfPresent() {
final String pathDefault = "config-host-volume-path";
final String pathNameDefault = "config-host-volume-name";
final Config configWithVolumes = Config.newBuilder().put(KubernetesContext.KUBERNETES_VOLUME_NAME, pathNameDefault).put(KubernetesContext.KUBERNETES_VOLUME_TYPE, Volumes.HOST_PATH).put(KubernetesContext.KUBERNETES_VOLUME_HOSTPATH_PATH, pathDefault).build();
final V1Controller controllerWithVol = new V1Controller(configWithVolumes, RUNTIME);
final V1Volume volumeDefault = new V1VolumeBuilder().withName(pathNameDefault).withNewHostPath().withNewPath(pathDefault).endHostPath().build();
final V1Volume volumeToBeKept = new V1VolumeBuilder().withName("volume-to-be-kept-name").withNewHostPath().withNewPath("volume-to-be-kept-path").endHostPath().build();
final List<V1Volume> customVolumeList = Arrays.asList(new V1VolumeBuilder().withName(pathNameDefault).withNewHostPath().withNewPath("this-path-must-be-replaced").endHostPath().build(), volumeToBeKept);
final List<V1Volume> expectedDefault = Collections.singletonList(volumeDefault);
final List<V1Volume> expectedCustom = Arrays.asList(volumeDefault, volumeToBeKept);
// No Volumes set.
V1Controller controllerDoNotSetVolumes = new V1Controller(Config.newBuilder().build(), RUNTIME);
V1PodSpec podSpecNoSetVolumes = new V1PodSpec();
controllerDoNotSetVolumes.addVolumesIfPresent(podSpecNoSetVolumes);
Assert.assertNull(podSpecNoSetVolumes.getVolumes());
// Default. Null Volumes.
V1PodSpec podSpecNull = new V1PodSpecBuilder().build();
controllerWithVol.addVolumesIfPresent(podSpecNull);
Assert.assertTrue("Default VOLUMES should be set in container with null VOLUMES", CollectionUtils.containsAll(expectedDefault, podSpecNull.getVolumes()));
// Empty Volumes list
V1PodSpec podSpecEmpty = new V1PodSpecBuilder().withVolumes(new LinkedList<>()).build();
controllerWithVol.addVolumesIfPresent(podSpecEmpty);
Assert.assertTrue("Default VOLUMES should be set in container with empty VOLUMES", CollectionUtils.containsAll(expectedDefault, podSpecEmpty.getVolumes()));
// Custom Volumes list
V1PodSpec podSpecCustom = new V1PodSpecBuilder().withVolumes(customVolumeList).build();
controllerWithVol.addVolumesIfPresent(podSpecCustom);
Assert.assertTrue("Default VOLUMES should be set in container with custom VOLUMES", CollectionUtils.containsAll(expectedCustom, podSpecCustom.getVolumes()));
}
use of io.kubernetes.client.openapi.models.V1PodSpec in project java by kubernetes-client.
the class DeployRolloutRestartExample method main.
public static void main(String[] args) throws IOException, ApiException {
ApiClient client = Config.defaultClient();
Configuration.setDefaultApiClient(client);
AppsV1Api appsV1Api = new AppsV1Api(client);
String deploymentName = "example-nginx";
String imageName = "nginx:1.21.6";
String namespace = "default";
// Create an example deployment
V1DeploymentBuilder deploymentBuilder = new V1DeploymentBuilder().withApiVersion("apps/v1").withKind("Deployment").withMetadata(new V1ObjectMeta().name(deploymentName).namespace(namespace)).withSpec(new V1DeploymentSpec().replicas(1).selector(new V1LabelSelector().putMatchLabelsItem("name", deploymentName)).template(new V1PodTemplateSpec().metadata(new V1ObjectMeta().putLabelsItem("name", deploymentName)).spec(new V1PodSpec().containers(Collections.singletonList(new V1Container().name(deploymentName).image(imageName))))));
appsV1Api.createNamespacedDeployment(namespace, deploymentBuilder.build(), null, null, null, null);
// Wait until example deployment is ready
Wait.poll(Duration.ofSeconds(3), Duration.ofSeconds(60), () -> {
try {
System.out.println("Waiting until example deployment is ready...");
return appsV1Api.readNamespacedDeployment(deploymentName, namespace, null).getStatus().getReadyReplicas() > 0;
} catch (ApiException e) {
e.printStackTrace();
return false;
}
});
System.out.println("Created example deployment!");
// Trigger a rollout restart of the example deployment
V1Deployment runningDeployment = appsV1Api.readNamespacedDeployment(deploymentName, namespace, null);
// Explicitly set "restartedAt" annotation with current date/time to trigger rollout when patch
// is applied
runningDeployment.getSpec().getTemplate().getMetadata().putAnnotationsItem("kubectl.kubernetes.io/restartedAt", LocalDateTime.now().toString());
try {
String deploymentJson = client.getJSON().serialize(runningDeployment);
PatchUtils.patch(V1Deployment.class, () -> appsV1Api.patchNamespacedDeploymentCall(deploymentName, namespace, new V1Patch(deploymentJson), null, null, "kubectl-rollout", null, null, null), V1Patch.PATCH_FORMAT_STRATEGIC_MERGE_PATCH, client);
// Wait until deployment has stabilized after rollout restart
Wait.poll(Duration.ofSeconds(3), Duration.ofSeconds(60), () -> {
try {
System.out.println("Waiting until example deployment restarted successfully...");
return appsV1Api.readNamespacedDeployment(deploymentName, namespace, null).getStatus().getReadyReplicas() > 0;
} catch (ApiException e) {
e.printStackTrace();
return false;
}
});
System.out.println("Example deployment restarted successfully!");
} catch (ApiException e) {
e.printStackTrace();
}
}
use of io.kubernetes.client.openapi.models.V1PodSpec in project java by kubernetes-client.
the class GenericClientExample method main.
public static void main(String[] args) throws Exception {
// The following codes demonstrates using generic client to manipulate pods
V1Pod pod = new V1Pod().metadata(new V1ObjectMeta().name("foo").namespace("default")).spec(new V1PodSpec().containers(Arrays.asList(new V1Container().name("c").image("test"))));
ApiClient apiClient = ClientBuilder.standard().build();
GenericKubernetesApi<V1Pod, V1PodList> podClient = new GenericKubernetesApi<>(V1Pod.class, V1PodList.class, "", "v1", "pods", apiClient);
V1Pod latestPod = podClient.create(pod).throwsApiException().getObject();
System.out.println("Created!");
V1Pod patchedPod = podClient.patch("default", "foo", V1Patch.PATCH_FORMAT_STRATEGIC_MERGE_PATCH, new V1Patch("{\"metadata\":{\"finalizers\":[\"example.io/foo\"]}}")).throwsApiException().getObject();
System.out.println("Patched!");
V1Pod deletedPod = podClient.delete("default", "foo").throwsApiException().getObject();
if (deletedPod != null) {
System.out.println("Received after-deletion status of the requested object, will be deleting in background!");
}
System.out.println("Deleted!");
}
Aggregations