Skip to content

Commit

Permalink
Add pre stop kubernetes support
Browse files Browse the repository at this point in the history
  • Loading branch information
DRSchlaubi committed Dec 7, 2024
1 parent 33b5410 commit a41dcbb
Show file tree
Hide file tree
Showing 12 changed files with 47 additions and 23 deletions.
14 changes: 10 additions & 4 deletions core/kubernetes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@ Plugin providing tools for running Mikbot within kubernetes

Also shouteout to @lucsoft, who helped me to set this up

## health endpoint
## kubernetes hooks

The plugin adds a HTTP endpoint, which you can use as a K8s probe, it will return 200 unless a shard or the DB connection
is down
is down.
It also adds a pre-stop hook, which will call hooks of the [redeploy-hook](../redeploy-hook) plugin

```yaml
livenessProbe:
httpGet:
path: /healthz
port: mikbot
port: mikbot-kubernetes # remember to specify this port somewhere, it defaults to 8081
startupProbe:
httpGet:
path: /healthz
port: mikbot # remember to specify that port name somewhere
port: mikbot-kubernetes
# let's give our shards time to connect
initialDelaySeconds: 15
lifecycle:
preStop:
httpGet:
port: mikbot-kubernetes
path: /kubernetes/pre-stop
```
### Own health checks
Expand Down
4 changes: 3 additions & 1 deletion core/kubernetes/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ repositories {
}

dependencies {
plugin(projects.core.ktor)
optionalPlugin(projects.core.redeployHook)
implementation(libs.ktor.server.netty)
implementation(libs.ktor.server.resources)

implementation(libs.kubernetes.client)
implementation(libs.kotlin.jsonpatch)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ object Config : EnvironmentConfig() {
val POD_ID by getEnv(transform = String::toInt)
val SHARDS_PER_POD by getEnv(2, String::toInt)
val TOTAL_SHARDS by getEnv(transform = String::toInt)
val PORT by getEnv(8081, String::toInt)
val STATEFUL_SET_NAME by this
val NAMESPACE by getEnv("default")
val CONTAINER_NAME by this
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
package dev.schlaubi.mikbot.core.health

import dev.kordex.core.koin.KordExKoinComponent
import dev.schlaubi.mikbot.core.health.check.HealthCheck
import dev.schlaubi.mikbot.core.health.routes.HealthRoutes
import dev.schlaubi.mikbot.util_plugins.ktor.api.KtorExtensionPoint
import dev.schlaubi.mikbot.core.redeploy_hook.api.RedeployExtensionPoint
import dev.schlaubi.mikbot.plugin.api.PluginContext
import dev.schlaubi.mikbot.plugin.api.getExtensions
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.resources.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import mu.KotlinLogging
import org.koin.core.component.inject
import org.pf4j.Extension

@Extension
class KubernetesAPIServer : KtorExtensionPoint, KordExKoinComponent {
private val checks by inject<List<HealthCheck>>()
fun startServer(checks: List<HealthCheck>, context: PluginContext) =
embeddedServer(Netty, Config.PORT) {
install(Resources)

override fun Application.apply() {
routing {
get<HealthRoutes.Health> {
if (checks.all { it.isSuccessful() }) {
Expand All @@ -26,9 +26,15 @@ class KubernetesAPIServer : KtorExtensionPoint, KordExKoinComponent {
call.respond(HttpStatusCode.InternalServerError)
}
}

if (context.pluginWrapper.pluginManager.getPlugin("redeploy-hook") != null) {
val redeployHooks = context.pluginSystem.getExtensions<RedeployExtensionPoint>()
get<HealthRoutes.PreStop> {
redeployHooks.forEach { it.beforeRedeploy() }
}
}
}
}
}
}.start(wait = false)

private val logger = KotlinLogging.logger {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import dev.kordex.core.builders.ExtensionsBuilder
import dev.kordex.core.utils.loadModule
import dev.schlaubi.mikbot.core.health.check.HealthCheck
import dev.schlaubi.mikbot.core.health.ratelimit.setupDistributedRateLimiter
import dev.schlaubi.mikbot.core.redeploy_hook.api.RedeployExtensionPoint
import dev.schlaubi.mikbot.plugin.api.Plugin
import dev.schlaubi.mikbot.plugin.api.PluginContext
import dev.schlaubi.mikbot.plugin.api.PluginMain
Expand All @@ -18,9 +19,12 @@ private val LOG = KotlinLogging.logger { }
@PluginMain
class KubernetesPlugin(context: PluginContext) : Plugin(context) {
private val healthChecks by lazy<List<HealthCheck>>(context.pluginSystem::getExtensions)

private val logger = KotlinLogging.logger(log)
override fun start() {
logger.info { "Registered ${healthChecks.size} health checks available at /healthz" }

startServer(healthChecks, contextSafe)
}

override fun ExtensionsBuilder.addExtensions() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package dev.schlaubi.mikbot.core.health.routes
import io.ktor.resources.*
import kotlinx.serialization.Serializable

@Serializable
@Resource("/")
class HealthRoutes {
@Serializable
@Resource("/healthz") // this is not a typo. See https://stackoverflow.com/questions/43380939/where-does-the-convention-of-using-healthz-for-application-health-checks-come-f
class Health(val health: HealthRoutes)

@Resource("/kubernetes/pre-stop")
@Serializable
class PreStop(val parent: HealthRoutes = HealthRoutes())
}
3 changes: 2 additions & 1 deletion music/api/server/src/main/kotlin/StateWatcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ class StateWatcher : Extension() {
val guild = kord.getGuild(guildId)
val player = musicModule.getCachedMusicPlayer(guildId) ?: return
val time = (this as? LavalinkPlayerUpdateEvent)?.state?.time ?: System.currentTimeMillis()
val channelId = player.lastChannelId ?: return

broadcastEvent(
Snowflake(player.lastChannelId!!),
Snowflake(channelId),
PlayerUpdateEvent(player.toPlayerState(guild), player.queuedTracks.mapToAPIQueuedTrack(guild), time, guildId),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package dev.schlaubi.mikmusic.commands

import dev.schlaubi.mikbot.plugin.api.util.translate
import dev.schlaubi.mikbot.translations.MusicTranslations
import dev.schlaubi.mikmusic.api.types.ChapterQueuedTrack
import dev.schlaubi.mikmusic.checks.anyMusicPlaying
import dev.schlaubi.mikmusic.core.MusicModule
import dev.schlaubi.mikmusic.core.musicControlContexts
import dev.schlaubi.mikmusic.player.ChapterQueuedTrack

suspend fun MusicModule.nextCommand() = ephemeralControlSlashCommand {
name = MusicTranslations.Commands.Next.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import dev.kord.rest.builder.message.embed
import dev.schlaubi.mikbot.plugin.api.util.forList
import dev.schlaubi.mikbot.plugin.api.util.translate
import dev.schlaubi.mikbot.translations.MusicTranslations
import dev.schlaubi.mikmusic.api.types.QueuedTrack
import dev.schlaubi.mikmusic.checks.anyMusicPlaying
import dev.schlaubi.mikmusic.core.MusicModule
import dev.schlaubi.mikmusic.core.musicControlContexts
import dev.schlaubi.mikmusic.player.QueuedTrack
import dev.schlaubi.mikmusic.player.addAutoPlaySongs
import dev.schlaubi.mikmusic.util.format
import kotlin.time.Duration.Companion.minutes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import dev.schlaubi.lavakord.rest.loadItem
import dev.schlaubi.mikbot.plugin.api.util.discordError
import dev.schlaubi.mikbot.plugin.api.util.translate
import dev.schlaubi.mikbot.translations.MusicTranslations
import dev.schlaubi.mikmusic.api.types.SimpleQueuedTrack
import dev.schlaubi.mikmusic.autocomplete.autoCompletedYouTubeQuery
import dev.schlaubi.mikmusic.checks.joinSameChannelCheck
import dev.schlaubi.mikmusic.core.MusicModule
import dev.schlaubi.mikmusic.player.SimpleQueuedTrack
import dev.schlaubi.mikmusic.player.enableAutoPlay
import dev.schlaubi.mikmusic.util.spotifyId

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import dev.kordex.core.commands.converters.impl.optionalString
import dev.kordex.core.commands.converters.impl.string
import dev.schlaubi.mikbot.plugin.api.util.translate
import dev.schlaubi.mikbot.translations.MusicTranslations
import dev.schlaubi.mikmusic.api.types.QueuedTrack
import dev.schlaubi.mikmusic.core.musicControlContexts
import dev.schlaubi.mikmusic.player.QueuedTrack
import dev.schlaubi.mikmusic.player.queue.QueueOptions
import dev.schlaubi.mikmusic.player.queue.findTracks
import dev.schlaubi.mikmusic.playlist.Playlist
Expand Down
4 changes: 3 additions & 1 deletion runtime/plugins.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
:core:ktor
:core:redeploy-hook
:core:kubernetes
:music:player
:music:api:server
:music:commands

0 comments on commit a41dcbb

Please sign in to comment.