Déploiement de Kotlin sur Kubernetes : guide pratique de base
Kubernetes (K8s) est devenu la norme pour l'orchestration d'applications conteneurisées. Si vous développez des applications serveur en Kotlin (avec Ktor, Spring Boot ou http4k), tôt ou tard se posera la question de leur déploiement dans un cluster. Dans ce guide, nous parcourrons le chemin depuis l'empaquetage d'une application Kotlin dans une image Docker jusqu'à son exécution dans Kubernetes en utilisant ConfigMap et Ingress. Tous les exemples sont fonctionnels et prêts à être adaptés.
1. Préparation de l'application Kotlin et de l'image Docker
Pour l'exemple, prenons une application simple sur Ktor (peut être remplacée par n'importe quel autre framework). Notre application écoutera sur le port 8080 et renverra un JSON avec la 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)}Compilons l'application en un fat JAR avec Gradle (plugin shadow). Après la compilation, créons un Dockerfile :
# DockerfileFROM openjdk:17-jdk-slimWORKDIR /appCOPY build/libs/app-all.jar app.jarEXPOSE 8080CMD ["java", "-jar", "app.jar"]Construisons l'image et poussons-la dans un registre (par exemple, Docker Hub) :
docker build -t youruser/kotlin-app:1.0.0 .docker push youruser/kotlin-app:1.0.02. Création des manifestes Kubernetes
Décrivons maintenant les ressources pour le déploiement. Créons trois fichiers : deployment.yaml, service.yaml et configmap.yaml.
2.1. ConfigMap pour la configuration
Externalisons les paramètres de l'application (par exemple, le niveau de journalisation ou la chaîne de connexion) dans un ConfigMap :
# configmap.yamlapiVersion: v1kind: ConfigMapmetadata: name: app-configdata: LOG_LEVEL: "DEBUG" APP_MODE: "production"2.2. Deployment
Dans le manifeste Deployment, indiquons l'image, le port, les réplicas et injectons les variables depuis le 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: 52.3. Service
Le Service équilibrera le trafic entre les pods :
# service.yamlapiVersion: v1kind: Servicemetadata: name: kotlin-app-servicespec: selector: app: kotlin-app ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP3. Déploiement dans le cluster et configuration d'Ingress
Appliquons les manifestes :
kubectl apply -f configmap.yamlkubectl apply -f deployment.yamlkubectl apply -f service.yamlVérifions que les pods sont lancés :
kubectl get podskubectl logs <pod-name>Maintenant, rendons l'application accessible depuis l'extérieur. Créons un Ingress (en supposant qu'un Ingress Controller est installé dans le cluster, par exemple NGINX) :
# ingress.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: kotlin-app-ingressspec: rules: - host: kotlin.example.com http: paths: