Skip to content
Snippets Groups Projects
Commit cb553aef authored by Benedikt Wetzel's avatar Benedikt Wetzel
Browse files

add leader election in operator mode

parent 0df1afb0
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!143Introduce Leader Election,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus
package theodolite.execution.operator
import io.fabric8.kubernetes.client.DefaultKubernetesClient
import io.fabric8.kubernetes.client.NamespacedKubernetesClient
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderCallbacks
import io.fabric8.kubernetes.client.extended.leaderelection.LeaderElectionConfigBuilder
import io.fabric8.kubernetes.client.extended.leaderelection.resourcelock.LeaseLock
import mu.KotlinLogging
import java.time.Duration
import java.util.*
import kotlin.reflect.KFunction0
private val logger = KotlinLogging.logger {}
class LeaderElector(
val client: NamespacedKubernetesClient,
val name: String
) {
fun getLeadership(leader: KFunction0<Unit>) {
val lockIdentity: String = UUID.randomUUID().toString()
DefaultKubernetesClient().use { kc ->
kc.leaderElector()
.withConfig(
LeaderElectionConfigBuilder()
.withName("Theodolite")
.withLeaseDuration(Duration.ofSeconds(15L))
.withLock(LeaseLock(client.namespace, name, lockIdentity))
.withRenewDeadline(Duration.ofSeconds(10L))
.withRetryPeriod(Duration.ofSeconds(2L))
.withLeaderCallbacks(LeaderCallbacks(
{ Thread{leader()}.start() },
{ logger.info { "STOPPED LEADERSHIP" } }
) { newLeader: String? ->
logger.info { "New leader elected $newLeader" }
})
.build()
)
.build().run()
}
}
}
\ No newline at end of file
...@@ -28,13 +28,22 @@ private val logger = KotlinLogging.logger {} ...@@ -28,13 +28,22 @@ private val logger = KotlinLogging.logger {}
*/ */
class TheodoliteOperator { class TheodoliteOperator {
private val namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE private val namespace = System.getenv("NAMESPACE") ?: DEFAULT_NAMESPACE
val client = DefaultKubernetesClient().inNamespace(namespace)
fun start() {
LeaderElector(
client = client,
name = "theodolite-operator"
)
.getLeadership(::startOperator)
}
/** /**
* Start the operator. * Start the operator.
*/ */
fun start() { private fun startOperator() {
logger.info { "Using $namespace as namespace." } logger.info { "Using $namespace as namespace." }
val client = DefaultKubernetesClient().inNamespace(namespace)
KubernetesDeserializer.registerCustomKind( KubernetesDeserializer.registerCustomKind(
"$GROUP/$API_VERSION", "$GROUP/$API_VERSION",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment