Deploying Kotlin Application on Kubernetes: Basic Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Deploying Kotlin on Kubernetes: A Practical Basic Guide



Kubernetes (K8s) has become the standard for orchestrating containerized applications. If you develop server-side applications in Kotlin (using Ktor, Spring Boot, or http4k), sooner or later you will face the question of deploying them in a cluster. In this guide, we will walk through the process from packaging a Kotlin application into a Docker image to running it in Kubernetes using ConfigMap and Ingress. All examples are working and ready for adaptation.



1. Preparing the Kotlin Application and Docker Image



For the example, let's take a simple application on Ktor (can be replaced with any other framework). Our application will listen on port 8080 and return a JSON with the version.



// src/main/kotlin/com/example/Application.ktimport io.ktor.server.engine.*import io.ktor.server.netty.*import io.ktor.server.routing.*import io.ktor.server.response.*

fun main() { embeddedServer(Netty, port = 8080) { routing { get("/") { call.respond(mapOf("app" to "kotlin-on-k8s", "version" to "1.0.0")) } } }.start(wait = true)}


Let's build the application into a fat JAR using Gradle (the shadow plugin). After the build, create a Dockerfile:



# DockerfileFROM openjdk:17-jdk-slimWORKDIR /appCOPY build/libs/app-all.jar app.jarEXPOSE 8080CMD ["java", "-jar", "app.jar"]


Build the image and push it to a registry (e.g., Docker Hub):



docker build -t youruser/kotlin-app:1.0.0 .docker push youruser/kotlin-app:1.0.0


2. Creating Kubernetes Manifests



Now let's describe the resources for deployment. Create three files: deployment.yaml, service.yaml, and configmap.yaml.



2.1. ConfigMap for Configuration



Let's externalize application settings (e.g., logging level or connection string) into a ConfigMap:



# configmap.yamlapiVersion: v1kind: ConfigMapmetadata:  name: app-configdata:  LOG_LEVEL: "DEBUG"  APP_MODE: "production"


2.2. Deployment



In the Deployment manifest, specify the image, port, replicas, and inject variables from the ConfigMap:



# deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata:  name: kotlin-appspec:  replicas: 2  selector:    matchLabels:      app: kotlin-app  template:    metadata:      labels:        app: kotlin-app    spec:      containers:        - name: app          image: youruser/kotlin-app:1.0.0          ports:            - containerPort: 8080          envFrom:            - configMapRef:                name: app-config          livenessProbe:            httpGet:              path: /              port: 8080            initialDelaySeconds: 10            periodSeconds: 5


2.3. Service



The Service will balance traffic between pods:



# service.yamlapiVersion: v1kind: Servicemetadata:  name: kotlin-app-servicespec:  selector:    app: kotlin-app  ports:    - protocol: TCP      port: 80      targetPort: 8080  type: ClusterIP


3. Deploying to the Cluster and Configuring Ingress



Apply the manifests:



kubectl apply -f configmap.yamlkubectl apply -f deployment.yamlkubectl apply -f service.yaml


Check that the pods are running:



kubectl get podskubectl logs <pod-name>


Now make the application accessible from outside. Create an Ingress (assuming an Ingress Controller, e.g., NGINX, is installed in the cluster):



# ingress.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:  name: kotlin-app-ingressspec:  rules:    - host: kotlin.example.com      http:        paths:                

Blogs

Book Recommendations