Implantação de Kotlin no Kubernetes: guia básico na prática
Kubernetes (K8s) tornou-se o padrão para orquestração de aplicações conteinerizadas. Se você desenvolve aplicações server-side em Kotlin (usando Ktor, Spring Boot ou http4k), mais cedo ou mais tarde surgirá a questão de implantá-las em um cluster. Neste guia, percorreremos o caminho desde o empacotamento da aplicação Kotlin em uma imagem Docker até sua execução no Kubernetes usando ConfigMap e Ingress. Todos os exemplos são funcionais e prontos para adaptação.
1. Preparação da aplicação Kotlin e da imagem Docker
Para o exemplo, usaremos uma aplicação simples em Ktor (pode ser substituída por qualquer outro framework). Nossa aplicação escutará na porta 8080 e retornará um JSON com a versão.
// 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)}Vamos compilar a aplicação em um fat JAR usando Gradle (plugin shadow). Após a compilação, criaremos um Dockerfile:
# DockerfileFROM openjdk:17-jdk-slimWORKDIR /appCOPY build/libs/app-all.jar app.jarEXPOSE 8080CMD ["java", "-jar", "app.jar"]Construímos a imagem e a enviamos para um registry (por exemplo, Docker Hub):
docker build -t youruser/kotlin-app:1.0.0 .docker push youruser/kotlin-app:1.0.02. Criação dos manifestos Kubernetes
Agora, descreveremos os recursos para implantação. Criaremos três arquivos: deployment.yaml, service.yaml e configmap.yaml.
2.1. ConfigMap para configuração
Vamos externalizar as configurações da aplicação (por exemplo, nível de log ou string de conexão) em um ConfigMap:
# configmap.yamlapiVersion: v1kind: ConfigMapmetadata: name: app-configdata: LOG_LEVEL: "DEBUG" APP_MODE: "production"2.2. Deployment
No manifesto Deployment, especificaremos a imagem, porta, réplicas e injetaremos as variáveis do 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
O Service balanceará o tráfego entre os pods:
# service.yamlapiVersion: v1kind: Servicemetadata: name: kotlin-app-servicespec: selector: app: kotlin-app ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP3. Implantação no cluster e configuração do Ingress
Aplicaremos os manifestos:
kubectl apply -f configmap.yamlkubectl apply -f deployment.yamlkubectl apply -f service.yamlVerificaremos se os pods estão em execução:
kubectl get podskubectl logs <pod-name>Agora, tornaremos a aplicação acessível externamente. Criaremos um Ingress (presume-se que um Ingress Controller, como NGINX, esteja instalado no cluster):
# ingress.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: kotlin-app-ingressspec: rules: - host: kotlin.example.com http: paths: