-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for node unregistration in KRaft mode (#10442)
Signed-off-by: Jakub Scholz <[email protected]>
- Loading branch information
Showing
13 changed files
with
750 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
.../src/main/java/io/strimzi/operator/cluster/operator/assembly/KafkaNodeUnregistration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/* | ||
* Copyright Strimzi authors. | ||
* License: Apache License 2.0 (see the file LICENSE or http://apache.org/licenses/LICENSE-2.0.html). | ||
*/ | ||
package io.strimzi.operator.cluster.operator.assembly; | ||
|
||
import io.strimzi.api.kafka.model.kafka.KafkaResources; | ||
import io.strimzi.operator.cluster.model.KafkaCluster; | ||
import io.strimzi.operator.cluster.operator.VertxUtil; | ||
import io.strimzi.operator.common.AdminClientProvider; | ||
import io.strimzi.operator.common.Reconciliation; | ||
import io.strimzi.operator.common.ReconciliationLogger; | ||
import io.strimzi.operator.common.auth.PemAuthIdentity; | ||
import io.strimzi.operator.common.auth.PemTrustSet; | ||
import io.vertx.core.Future; | ||
import io.vertx.core.Vertx; | ||
import org.apache.kafka.clients.admin.Admin; | ||
import org.apache.kafka.common.KafkaException; | ||
import org.apache.kafka.common.errors.BrokerIdNotRegisteredException; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* Contains utility methods for unregistering KRaft nodes from a Kafka cluster after scale-down | ||
*/ | ||
public class KafkaNodeUnregistration { | ||
private static final ReconciliationLogger LOGGER = ReconciliationLogger.create(KafkaNodeUnregistration.class.getName()); | ||
|
||
/** | ||
* Unregisters Kafka nodes from a KRaft-based Kafka cluster | ||
* | ||
* @param reconciliation Reconciliation marker | ||
* @param vertx Vert.x instance | ||
* @param adminClientProvider Kafka Admin API client provider | ||
* @param pemTrustSet Trust set for the admin client to connect to the Kafka cluster | ||
* @param pemAuthIdentity Key set for the admin client to connect to the Kafka cluster | ||
* @param nodeIdsToUnregister List of node IDs that should be unregistered | ||
* | ||
* @return Future that completes when all nodes are unregistered | ||
*/ | ||
public static Future<Void> unregisterNodes( | ||
Reconciliation reconciliation, | ||
Vertx vertx, | ||
AdminClientProvider adminClientProvider, | ||
PemTrustSet pemTrustSet, | ||
PemAuthIdentity pemAuthIdentity, | ||
List<Integer> nodeIdsToUnregister | ||
) { | ||
try { | ||
String bootstrapHostname = KafkaResources.bootstrapServiceName(reconciliation.name()) + "." + reconciliation.namespace() + ".svc:" + KafkaCluster.REPLICATION_PORT; | ||
Admin adminClient = adminClientProvider.createAdminClient(bootstrapHostname, pemTrustSet, pemAuthIdentity); | ||
|
||
List<Future<Void>> futures = new ArrayList<>(); | ||
for (Integer nodeId : nodeIdsToUnregister) { | ||
futures.add(unregisterNode(reconciliation, vertx, adminClient, nodeId)); | ||
} | ||
|
||
return Future.all(futures) | ||
.eventually(() -> { | ||
adminClient.close(); | ||
return Future.succeededFuture(); | ||
}) | ||
.map((Void) null); | ||
} catch (KafkaException e) { | ||
LOGGER.warnCr(reconciliation, "Failed to unregister nodes", e); | ||
return Future.failedFuture(e); | ||
} | ||
} | ||
|
||
/** | ||
* Unregisters a single Kafka node using the Kafka Admin API. In case the failure is caused by the node not being | ||
* registered, the error will be ignored. | ||
* | ||
* @param reconciliation Reconciliation marker | ||
* @param vertx Vert.x instance | ||
* @param adminClient Kafka Admin API client instance | ||
* @param nodeIdToUnregister ID of the node that should be unregistered | ||
* | ||
* @return Future that completes when the node is unregistered | ||
*/ | ||
private static Future<Void> unregisterNode(Reconciliation reconciliation, Vertx vertx, Admin adminClient, Integer nodeIdToUnregister) { | ||
LOGGER.debugCr(reconciliation, "Unregistering node {} from the Kafka cluster", nodeIdToUnregister); | ||
|
||
return VertxUtil | ||
.kafkaFutureToVertxFuture(reconciliation, vertx, adminClient.unregisterBroker(nodeIdToUnregister).all()) | ||
.recover(t -> { | ||
if (t instanceof BrokerIdNotRegisteredException) { | ||
// The broker is not registered anymore, so it does not need to be unregistered anymore and we | ||
// report success. Situation like this might happen when the operator fails before updating the | ||
// status, when the Kafka API call fails (e.g. due to network connection) but the unregistration | ||
// was done on the Kafka cluster and similar. | ||
LOGGER.warnCr(reconciliation, "Node {} is not registered and cannot be unregistered from the Kafka cluster", nodeIdToUnregister, t); | ||
return Future.succeededFuture(); | ||
} else { | ||
LOGGER.warnCr(reconciliation, "Failed to unregister node {} from the Kafka cluster", nodeIdToUnregister, t); | ||
return Future.failedFuture(t); | ||
} | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.