use of io.fabric8.kubernetes.api.model.NodeSelectorRequirement in project strimzi by strimzi.
the class KafkaRollerIsolatedST method testKafkaPodPendingDueToRack.
@ParallelNamespaceTest
void testKafkaPodPendingDueToRack(ExtensionContext extensionContext) {
// Testing this scenario
// 1. deploy Kafka with wrong pod template (looking for nonexistent node) kafka pods should not exist
// 2. wait for Kafka not ready, kafka pods should be in the pending state
// 3. fix the Kafka CR, kafka pods should be in the pending state
// 4. wait for Kafka ready, kafka pods should NOT be in the pending state
final String namespaceName = StUtils.getNamespaceBasedOnRbac(INFRA_NAMESPACE, extensionContext);
final String clusterName = mapWithClusterNames.get(extensionContext.getDisplayName());
NodeSelectorRequirement nsr = new NodeSelectorRequirementBuilder().withKey("dedicated_test").withOperator("In").withValues("Kafka").build();
NodeSelectorTerm nst = new NodeSelectorTermBuilder().withMatchExpressions(nsr).build();
Affinity affinity = new AffinityBuilder().withNewNodeAffinity().withNewRequiredDuringSchedulingIgnoredDuringExecution().withNodeSelectorTerms(nst).endRequiredDuringSchedulingIgnoredDuringExecution().endNodeAffinity().build();
PodTemplate pt = new PodTemplate();
pt.setAffinity(affinity);
KafkaClusterTemplate kct = new KafkaClusterTemplateBuilder().withPod(pt).build();
resourceManager.createResource(extensionContext, false, KafkaTemplates.kafkaEphemeral(clusterName, 3, 3).editSpec().editKafka().withTemplate(kct).endKafka().endSpec().build());
// pods are stable in the Pending state
PodUtils.waitUntilPodStabilityReplicasCount(namespaceName, KafkaResources.kafkaStatefulSetName(clusterName), 3);
LOGGER.info("Removing requirement for the affinity");
KafkaResource.replaceKafkaResourceInSpecificNamespace(clusterName, kafka -> kafka.getSpec().getKafka().getTemplate().getPod().setAffinity(null), namespaceName);
// kafka should get back ready in some reasonable time frame
KafkaUtils.waitForKafkaReady(namespaceName, clusterName);
KafkaResource.kafkaClient().inNamespace(namespaceName).withName(clusterName).withPropagationPolicy(DeletionPropagation.FOREGROUND).delete();
KafkaUtils.waitForKafkaDeletion(namespaceName, clusterName);
}
use of io.fabric8.kubernetes.api.model.NodeSelectorRequirement in project strimzi by strimzi.
the class SpecificIsolatedST method testRackAware.
@IsolatedTest("UtestRackAwareConnectWrongDeploymentsing more tha one Kafka cluster in one namespace")
@Tag(REGRESSION)
@Tag(INTERNAL_CLIENTS_USED)
void testRackAware(ExtensionContext extensionContext) {
assumeFalse(Environment.isNamespaceRbacScope());
String clusterName = mapWithClusterNames.get(extensionContext.getDisplayName());
String producerName = "hello-world-producer";
String consumerName = "hello-world-consumer";
String rackKey = "rack-key";
resourceManager.createResource(extensionContext, KafkaTemplates.kafkaEphemeral(clusterName, 1, 1).editSpec().editKafka().withNewRack().withTopologyKey(rackKey).endRack().endKafka().endSpec().build());
Affinity kafkaPodSpecAffinity = StUtils.getStatefulSetOrStrimziPodSetAffinity(KafkaResources.kafkaStatefulSetName(clusterName));
NodeSelectorRequirement kafkaPodNodeSelectorRequirement = kafkaPodSpecAffinity.getNodeAffinity().getRequiredDuringSchedulingIgnoredDuringExecution().getNodeSelectorTerms().get(0).getMatchExpressions().get(0);
assertThat(kafkaPodNodeSelectorRequirement.getKey(), is(rackKey));
assertThat(kafkaPodNodeSelectorRequirement.getOperator(), is("Exists"));
PodAffinityTerm kafkaPodAffinityTerm = kafkaPodSpecAffinity.getPodAntiAffinity().getPreferredDuringSchedulingIgnoredDuringExecution().get(0).getPodAffinityTerm();
assertThat(kafkaPodAffinityTerm.getTopologyKey(), is(rackKey));
assertThat(kafkaPodAffinityTerm.getLabelSelector().getMatchLabels(), hasEntry("strimzi.io/cluster", clusterName));
assertThat(kafkaPodAffinityTerm.getLabelSelector().getMatchLabels(), hasEntry("strimzi.io/name", KafkaResources.kafkaStatefulSetName(clusterName)));
String rackId = cmdKubeClient().execInPod(KafkaResources.kafkaPodName(clusterName, 0), "/bin/bash", "-c", "cat /opt/kafka/init/rack.id").out();
assertThat(rackId.trim(), is("zone"));
String brokerRack = cmdKubeClient().execInPod(KafkaResources.kafkaPodName(clusterName, 0), "/bin/bash", "-c", "cat /tmp/strimzi.properties | grep broker.rack").out();
assertThat(brokerRack.contains("broker.rack=zone"), is(true));
String uid = kubeClient().getPodUid(KafkaResources.kafkaPodName(clusterName, 0));
List<Event> events = kubeClient().listEventsByResourceUid(uid);
assertThat(events, hasAllOfReasons(Scheduled, Pulled, Created, Started));
KafkaClients kafkaBasicClientJob = new KafkaClientsBuilder().withProducerName(producerName).withConsumerName(consumerName).withBootstrapAddress(KafkaResources.plainBootstrapAddress(clusterName)).withTopicName(TOPIC_NAME).withMessageCount(MESSAGE_COUNT).withDelayMs(0).build();
resourceManager.createResource(extensionContext, kafkaBasicClientJob.producerStrimzi());
resourceManager.createResource(extensionContext, kafkaBasicClientJob.consumerStrimzi());
}
use of io.fabric8.kubernetes.api.model.NodeSelectorRequirement in project strimzi by strimzi.
the class SpecificIsolatedST method testRackAwareConnectCorrectDeployment.
@IsolatedTest("Modification of shared Cluster Operator configuration")
@Tag(CONNECT)
@Tag(CONNECT_COMPONENTS)
@Tag(ACCEPTANCE)
@Tag(INTERNAL_CLIENTS_USED)
void testRackAwareConnectCorrectDeployment(ExtensionContext extensionContext) {
assumeFalse(Environment.isNamespaceRbacScope());
assumeTrue(!Environment.isHelmInstall() && !Environment.isOlmInstall());
String kafkaClientsName = mapWithKafkaClientNames.get(extensionContext.getDisplayName());
String clusterName = mapWithClusterNames.get(extensionContext.getDisplayName());
// We need to update CO configuration to set OPERATION_TIMEOUT to shorter value, because we expect timeout in that test
Map<String, String> coSnapshot = DeploymentUtils.depSnapshot(clusterOperator.getDeploymentNamespace(), ResourceManager.getCoDeploymentName());
// We have to install CO in class stack, otherwise it will be deleted at the end of test case and all following tests will fail
clusterOperator.unInstall();
clusterOperator = clusterOperator.defaultInstallation().withOperationTimeout(CO_OPERATION_TIMEOUT_SHORT).withReconciliationInterval(Constants.RECONCILIATION_INTERVAL).createInstallation().runBundleInstallation();
coSnapshot = DeploymentUtils.waitTillDepHasRolled(ResourceManager.getCoDeploymentName(), 1, coSnapshot);
String rackKey = "rack-key";
resourceManager.createResource(extensionContext, KafkaTemplates.kafkaEphemeral(clusterName, 3).editSpec().editKafka().withNewRack().withTopologyKey(rackKey).endRack().addToConfig("replica.selector.class", "org.apache.kafka.common.replica.RackAwareReplicaSelector").endKafka().endSpec().build());
// we should create topic before KafkaConnect - topic is recreated if we delete it before KafkaConnect
String topicName = "rw-" + KafkaTopicUtils.generateRandomNameOfTopic();
resourceManager.createResource(extensionContext, KafkaTopicTemplates.topic(clusterName, topicName).build());
resourceManager.createResource(extensionContext, KafkaClientsTemplates.kafkaClients(false, kafkaClientsName).build());
String kafkaClientsPodName = kubeClient().listPodsByPrefixInName(kafkaClientsName).get(0).getMetadata().getName();
LOGGER.info("Deploy KafkaConnect with correct rack-aware topology key: {}", rackKey);
KafkaConnect kc = KafkaConnectTemplates.kafkaConnect(extensionContext, clusterName, 1).editSpec().withNewRack().withTopologyKey(rackKey).endRack().addToConfig("key.converter.schemas.enable", false).addToConfig("value.converter.schemas.enable", false).addToConfig("key.converter", "org.apache.kafka.connect.storage.StringConverter").addToConfig("value.converter", "org.apache.kafka.connect.storage.StringConverter").endSpec().build();
resourceManager.createResource(extensionContext, kc);
NetworkPolicyResource.deployNetworkPolicyForResource(extensionContext, kc, KafkaConnectResources.deploymentName(clusterName));
String connectPodName = kubeClient().listPodNames(Labels.STRIMZI_KIND_LABEL, KafkaConnect.RESOURCE_KIND).get(0);
Affinity connectPodSpecAffinity = kubeClient().getDeployment(KafkaConnectResources.deploymentName(clusterName)).getSpec().getTemplate().getSpec().getAffinity();
NodeSelectorRequirement connectPodNodeSelectorRequirement = connectPodSpecAffinity.getNodeAffinity().getRequiredDuringSchedulingIgnoredDuringExecution().getNodeSelectorTerms().get(0).getMatchExpressions().get(0);
Pod connectPod = kubeClient().getPod(connectPodName);
NodeAffinity nodeAffinity = connectPod.getSpec().getAffinity().getNodeAffinity();
LOGGER.info("PodName: {}\nNodeAffinity: {}", connectPodName, nodeAffinity);
assertThat(connectPodNodeSelectorRequirement.getKey(), is(rackKey));
assertThat(connectPodNodeSelectorRequirement.getOperator(), is("Exists"));
KafkaConnectUtils.sendReceiveMessagesThroughConnect(connectPodName, topicName, kafkaClientsPodName, clusterOperator.getDeploymentNamespace(), clusterName);
// Revert changes for CO deployment
clusterOperator.unInstall();
clusterOperator = clusterOperator.defaultInstallation().createInstallation().runInstallation();
DeploymentUtils.waitTillDepHasRolled(ResourceManager.getCoDeploymentName(), 1, coSnapshot);
}
use of io.fabric8.kubernetes.api.model.NodeSelectorRequirement in project strimzi-kafka-operator by strimzi.
the class ModelUtils method populateAffinityBuilderWithRackLabelSelector.
/**
* @param builder the builder which is used to populate the node affinity
* @param userAffinity the userAffinity which is defined by the user
* @param topologyKey the topology key which is used to select the node
* @return the AffinityBuilder which has the node selector with topology key which is needed to make sure
* the pods are scheduled only on nodes with the rack label
*/
public static AffinityBuilder populateAffinityBuilderWithRackLabelSelector(AffinityBuilder builder, Affinity userAffinity, String topologyKey) {
// We need to add node affinity to make sure the pods are scheduled only on nodes with the rack label
NodeSelectorRequirement selector = new NodeSelectorRequirementBuilder().withOperator("Exists").withKey(topologyKey).build();
if (userAffinity != null && userAffinity.getNodeAffinity() != null && userAffinity.getNodeAffinity().getRequiredDuringSchedulingIgnoredDuringExecution() != null && userAffinity.getNodeAffinity().getRequiredDuringSchedulingIgnoredDuringExecution().getNodeSelectorTerms() != null) {
// User has specified some Node Selector Terms => we should enhance them
List<NodeSelectorTerm> oldTerms = userAffinity.getNodeAffinity().getRequiredDuringSchedulingIgnoredDuringExecution().getNodeSelectorTerms();
List<NodeSelectorTerm> enhancedTerms = new ArrayList<>(oldTerms.size());
for (NodeSelectorTerm term : oldTerms) {
NodeSelectorTerm enhancedTerm = new NodeSelectorTermBuilder(term).addToMatchExpressions(selector).build();
enhancedTerms.add(enhancedTerm);
}
builder = builder.editOrNewNodeAffinity().withNewRequiredDuringSchedulingIgnoredDuringExecution().withNodeSelectorTerms(enhancedTerms).endRequiredDuringSchedulingIgnoredDuringExecution().endNodeAffinity();
} else {
// User has not specified any selector terms => we add our own
builder = builder.editOrNewNodeAffinity().editOrNewRequiredDuringSchedulingIgnoredDuringExecution().addNewNodeSelectorTerm().withMatchExpressions(selector).endNodeSelectorTerm().endRequiredDuringSchedulingIgnoredDuringExecution().endNodeAffinity();
}
return builder;
}
use of io.fabric8.kubernetes.api.model.NodeSelectorRequirement in project strimzi-kafka-operator by strimzi.
the class SpecificIsolatedST method testRackAware.
@IsolatedTest("UtestRackAwareConnectWrongDeploymentsing more tha one Kafka cluster in one namespace")
@Tag(REGRESSION)
@Tag(INTERNAL_CLIENTS_USED)
void testRackAware(ExtensionContext extensionContext) {
assumeFalse(Environment.isNamespaceRbacScope());
String clusterName = mapWithClusterNames.get(extensionContext.getDisplayName());
String producerName = "hello-world-producer";
String consumerName = "hello-world-consumer";
String rackKey = "rack-key";
resourceManager.createResource(extensionContext, KafkaTemplates.kafkaEphemeral(clusterName, 1, 1).editSpec().editKafka().withNewRack().withTopologyKey(rackKey).endRack().endKafka().endSpec().build());
Affinity kafkaPodSpecAffinity = StUtils.getStatefulSetOrStrimziPodSetAffinity(KafkaResources.kafkaStatefulSetName(clusterName));
NodeSelectorRequirement kafkaPodNodeSelectorRequirement = kafkaPodSpecAffinity.getNodeAffinity().getRequiredDuringSchedulingIgnoredDuringExecution().getNodeSelectorTerms().get(0).getMatchExpressions().get(0);
assertThat(kafkaPodNodeSelectorRequirement.getKey(), is(rackKey));
assertThat(kafkaPodNodeSelectorRequirement.getOperator(), is("Exists"));
PodAffinityTerm kafkaPodAffinityTerm = kafkaPodSpecAffinity.getPodAntiAffinity().getPreferredDuringSchedulingIgnoredDuringExecution().get(0).getPodAffinityTerm();
assertThat(kafkaPodAffinityTerm.getTopologyKey(), is(rackKey));
assertThat(kafkaPodAffinityTerm.getLabelSelector().getMatchLabels(), hasEntry("strimzi.io/cluster", clusterName));
assertThat(kafkaPodAffinityTerm.getLabelSelector().getMatchLabels(), hasEntry("strimzi.io/name", KafkaResources.kafkaStatefulSetName(clusterName)));
String rackId = cmdKubeClient().execInPod(KafkaResources.kafkaPodName(clusterName, 0), "/bin/bash", "-c", "cat /opt/kafka/init/rack.id").out();
assertThat(rackId.trim(), is("zone"));
String brokerRack = cmdKubeClient().execInPod(KafkaResources.kafkaPodName(clusterName, 0), "/bin/bash", "-c", "cat /tmp/strimzi.properties | grep broker.rack").out();
assertThat(brokerRack.contains("broker.rack=zone"), is(true));
String uid = kubeClient().getPodUid(KafkaResources.kafkaPodName(clusterName, 0));
List<Event> events = kubeClient().listEventsByResourceUid(uid);
assertThat(events, hasAllOfReasons(Scheduled, Pulled, Created, Started));
KafkaClients kafkaBasicClientJob = new KafkaClientsBuilder().withProducerName(producerName).withConsumerName(consumerName).withBootstrapAddress(KafkaResources.plainBootstrapAddress(clusterName)).withTopicName(TOPIC_NAME).withMessageCount(MESSAGE_COUNT).withDelayMs(0).build();
resourceManager.createResource(extensionContext, kafkaBasicClientJob.producerStrimzi());
resourceManager.createResource(extensionContext, kafkaBasicClientJob.consumerStrimzi());
}
Aggregations