use of io.fabric8.kubernetes.api.model.apps.StatefulSet in project kubernetes-client by fabric8io.
the class StatefulSetTest method testDeleteLoadedResource.
@Test
public void testDeleteLoadedResource() {
StatefulSet response = client.apps().statefulSets().load(getClass().getResourceAsStream("/test-statefulset.yml")).get();
server.expect().delete().withPath("/apis/apps/v1beta1/namespaces/test/statefulsets/example").andReturn(200, response).once();
Deletable items = client.load(getClass().getResourceAsStream("/test-statefulset.yml"));
assertTrue(items.delete());
}
use of io.fabric8.kubernetes.api.model.apps.StatefulSet in project quarkus by quarkusio.
the class OpenshiftWithStatefulSetResourceTest method assertGeneratedResources.
@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir).isDirectoryContaining(p -> p.getFileName().endsWith("openshift.json")).isDirectoryContaining(p -> p.getFileName().endsWith("openshift.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil.deserializeAsList(kubernetesDir.resolve("openshift.yml"));
assertThat(kubernetesList).filteredOn(i -> i instanceof StatefulSet).singleElement().satisfies(i -> {
assertThat(i).isInstanceOfSatisfying(StatefulSet.class, s -> {
assertThat(s.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo(APP_NAME);
});
assertThat(s.getSpec()).satisfies(statefulSetSpec -> {
assertThat(statefulSetSpec.getServiceName()).isEqualTo(APP_NAME);
assertThat(statefulSetSpec.getReplicas()).isEqualTo(5);
assertThat(statefulSetSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getTerminationGracePeriodSeconds()).isEqualTo(10);
assertThat(podSpec.getContainers()).allMatch(c -> APP_NAME.equals(c.getName()));
});
});
assertThat(statefulSetSpec.getSelector()).satisfies(ls -> {
assertThat(ls.getMatchLabels()).containsEntry("app.kubernetes.io/name", APP_NAME);
});
});
});
});
}
use of io.fabric8.kubernetes.api.model.apps.StatefulSet in project quarkus by quarkusio.
the class KubernetesWithStatefulSetResourceTest method assertGeneratedResources.
@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir).isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")).isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil.deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
assertThat(kubernetesList).filteredOn(i -> i instanceof StatefulSet).singleElement().satisfies(i -> {
assertThat(i).isInstanceOfSatisfying(StatefulSet.class, s -> {
assertThat(s.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo(APP_NAME);
});
assertThat(s.getSpec()).satisfies(statefulSetSpec -> {
assertThat(statefulSetSpec.getServiceName()).isEqualTo(APP_NAME);
assertThat(statefulSetSpec.getReplicas()).isEqualTo(42);
assertThat(statefulSetSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getTerminationGracePeriodSeconds()).isEqualTo(10);
assertThat(podSpec.getContainers()).allMatch(c -> APP_NAME.equals(c.getName()));
});
});
assertThat(statefulSetSpec.getSelector()).satisfies(ls -> {
assertThat(ls.getMatchLabels()).containsEntry("app.kubernetes.io/name", APP_NAME);
});
});
});
});
}
use of io.fabric8.kubernetes.api.model.apps.StatefulSet in project quarkus by quarkusio.
the class KubernetesWithInputStatefulSetResourcesTest method assertGeneratedResources.
@Test
public void assertGeneratedResources() throws IOException {
final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes");
assertThat(kubernetesDir).isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")).isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml"));
List<HasMetadata> kubernetesList = DeserializationUtil.deserializeAsList(kubernetesDir.resolve("kubernetes.yml"));
assertThat(kubernetesList).filteredOn(i -> i instanceof StatefulSet).singleElement().satisfies(i -> {
assertThat(i).isInstanceOfSatisfying(StatefulSet.class, s -> {
assertThat(s.getMetadata()).satisfies(m -> {
assertThat(m.getName()).isEqualTo(APP_NAME);
});
assertThat(s.getSpec()).satisfies(statefulSetSpec -> {
assertThat(statefulSetSpec.getServiceName()).isEqualTo(APP_NAME);
assertThat(statefulSetSpec.getReplicas()).isEqualTo(42);
assertThat(statefulSetSpec.getTemplate()).satisfies(t -> {
assertThat(t.getSpec()).satisfies(podSpec -> {
assertThat(podSpec.getTerminationGracePeriodSeconds()).isEqualTo(10);
assertThat(podSpec.getContainers()).allMatch(c -> APP_NAME.equals(c.getName()));
});
});
assertThat(statefulSetSpec.getSelector()).satisfies(ls -> {
assertThat(ls.getMatchLabels()).containsEntry("app.kubernetes.io/name", APP_NAME);
assertThat(ls.getMatchLabels()).containsEntry("custom-label", "my-label");
});
});
});
});
}
use of io.fabric8.kubernetes.api.model.apps.StatefulSet in project couchbase-elasticsearch-connector by couchbase.
the class ReplicaChangeWatcher method getReplicasAndPanicOnChange.
/**
* Starts watching the replica count and panics if the count changes
* or can't be determined.
*
* @return initial number of replicas
*/
public static int getReplicasAndPanicOnChange(KubernetesClient client, PanicButton panicButton) {
try {
StatefulSetInfo info = StatefulSetInfo.fromHostname();
String k8sName = info.name;
log.info("Kubernetes API version = {}", client.discovery().v1().getApiVersion());
String namespace = client.discovery().v1().getNamespace();
log.info("Kubernetes namespace = {}", namespace);
StatefulSet statefulSet = client.apps().statefulSets().inNamespace(namespace).withName(k8sName).get();
requireNonNull(statefulSet, "Failed to get StatefulSet in namespace '" + namespace + "' with name '" + k8sName + "'");
int initialReplicas = statefulSet.getSpec().getReplicas();
log.info("StatefulSet replicas = {}", initialReplicas);
log.info("Kubernetes API resync period = {} ; kill switch deadline = {}", resyncPeriod, killSwitchDeadline);
KillSwitch killSwitch = KillSwitch.start(killSwitchDeadline, () -> panicButton.panic("The connector contacts the Kubernetes API server every " + resyncPeriod + " to verify the StatefulSet's replica count has not changed," + " but " + killSwitchDeadline + " has elapsed without a successful response." + " Terminating to ensure multiple pods don't process the same Couchbase partitions."));
SharedIndexInformer<StatefulSet> informer = client.apps().statefulSets().inNamespace(namespace).withName(k8sName).inform(new ResourceEventHandler<>() {
// When the K8S API server is reachable, an update happens once per resync period
// and also immediately when the informer detects a change to the resource.
@Override
public void onUpdate(StatefulSet oldSet, StatefulSet newSet) {
killSwitch.reset();
int newReplicas = newSet.getSpec().getReplicas();
if (newReplicas != 0 && newReplicas != initialReplicas) {
// Panic to terminate the connector and let Kubernetes restart it.
// This is simpler than trying to stream from different vbuckets on the fly.
panicButton.mildPanic("The connector is automatically restarting because" + " it detected a change to the number of replicas in its StatefulSet." + " This is the intended behavior, and not a cause for alarm." + " Upon restart, the connector will wait for a quiet period to elapse, giving all pods" + " a chance to notice the change and shut down. This prevents multiple pods" + " from processing the same Couchbase partitions." + " There is a [very small] chance this strategy could fail, in which case" + " stale versions of some documents could be written to Elasticsearch and remain" + " until the documents are modified again in Couchbase." + " To be absolutely sure this never happens, we recommend first scaling" + " the StatefulSet down to zero (or deleting it) and waiting for pods" + " to terminate before scaling back up to the desired number of replicas.");
}
}
@Override
public void onAdd(StatefulSet it) {
}
@Override
public void onDelete(StatefulSet it, boolean deletedFinalStateUnknown) {
}
}, resyncPeriod.toMillis());
return initialReplicas;
} catch (Throwable t) {
panicButton.panic("Failed to get/watch StatefulSet replica count.", t);
// unreachable
throw t;
}
}
Aggregations