Deploying Kotlin on Kubernetes: A Practical Basic Guide
\n\nModern development increasingly requires not only writing quality code but also its competent deployment. Kubernetes has become the de facto standard for container orchestration. In this guide, we will walk through how to package a Kotlin application into a Docker container and deploy it in a Kubernetes cluster. You will get ready-made manifests and practical examples in Kotlin (using the Ktor framework).
\n\n1. Preparing the Kotlin Application
\n\nFor demonstration, we'll take a simple REST API on Ktor. Make sure you have Gradle (or Maven) configured with the application plugin.
Example build.gradle.kts:
plugins {\n kotlin("jvm") version "1.9.22"\n application\n id("com.github.johnrengelman.shadow") version "8.1.1"\n}\n\napplication {\n mainClass.set("com.example.ApplicationKt")\n}\n\ndependencies {\n implementation("io.ktor:ktor-server-netty:2.3.7")\n implementation("io.ktor:ktor-server-content-negotiation:2.3.7")\n implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")\n}\n\nThe simplest endpoint (src/main/kotlin/com/example/Application.kt):
package com.example\n\nimport io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.routing.*\nimport io.ktor.server.response.*\nimport io.ktor.serialization.kotlinx.json.*\nimport io.ktor.server.plugins.contentnegotiation.*\n\nfun main() {\n embeddedServer(Netty, port = 8080) {\n install(ContentNegotiation) {\n json()\n }\n routing {\n get("/") {\n call.respond(mapOf("message" to "Hello from Kotlin on K8s!"))\n }\n get("/health") {\n call.respond(mapOf("status" to "UP"))\n }\n }\n }.start(wait = true)\n}\n\nBuild the fat JAR with the command:
\n./gradlew shadowJar\n\nThe ready JAR will appear in build/libs/.
2. Creating the Docker Image
\n\nCreate a Dockerfile in the project root:
FROM openjdk:17-jdk-slim\n\nWORKDIR /app\n\nCOPY build/libs/*-all.jar app.jar\n\nEXPOSE 8080\n\nENTRYPOINT ["java", "-jar", "app.jar"]\n\nBuild the image and push it to a registry (e.g., Docker Hub):
\ndocker build -t yourusername/kotlin-k8s-demo:v1 .\ndocker push yourusername/kotlin-k8s-demo:v1\n\nBe sure to replace yourusername with your Docker Hub login or specify the address of a private registry.
3. Kubernetes Manifests
\n\nFor deployment, we will need two YAML files: Deployment (manages pods) and Service (provides access).
\n\n3.1. Deployment (deployment.yaml)
\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: kotlin-app\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: kotlin-app\n template:\n metadata:\n labels:\n app: kotlin-app\n spec:\n containers:\n - name: kotlin-app\n image: yourusername/kotlin-k8s-demo:v1\n ports:\n - containerPort: 8080\n livenessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 5\n periodSeconds: 10\n readinessProbe:\n httpGet:\n path: /health\n port: 8080\n initialDelaySeconds: 3\n periodSeconds: 5\n\n3.2. Service (service.yaml)
\napiVersion: v1\nkind: Service\nmetadata:\n name: kotlin-app-service\nspec:\n selector:\n app: kotlin-app\n ports:\n - port: 80\n targetPort: 8080\n type: LoadBalancer\n\nApply the manifests:
\nkubectl apply -f deployment.yaml\nkubectl apply -f service.yaml\n\nCheck the status:
\nkubectl get pods\nkubectl