Деплой Kotlin на Kubernetes: базовое руководство для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Деплой Kotlin на Kubernetes: базовое руководство для начинающих

Kubernetes (K8s) стал стандартом де-факто для оркестрации контейнеров в современной разработке. Если вы пишете на Kotlin, будь то бэкенд на Spring Boot, микросервис на Ktor или консольное приложение, умение разворачивать его в кластере Kubernetes — критически важный навык. В этом руководстве мы пройдем путь от простого Kotlin-приложения до работающего пода в кластере. Материал рассчитан на начинающих: никаких сложных тем вроде Service Mesh или Helm — только база.

1. Подготовка Kotlin-приложения к контейнеризации

Прежде чем думать о Kubernetes, нужно упаковать наше приложение в Docker-образ. Рассмотрим пример простого REST API на Ktor — легковесного фреймворка, идеально подходящего для микросервисов.

Создадим файл build.gradle.kts с минимальными зависимостями:

plugins {
    kotlin("jvm") version "1.9.0"
    application
}

application {
    mainClass.set("com.example.AppKt")
}

dependencies {
    implementation("io.ktor:ktor-server-netty:2.3.0")
    implementation("io.ktor:ktor-server-content-negotiation:2.3.0")
    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.0")
}

Напишем простое приложение, которое отвечает на GET-запросы:

// src/main/kotlin/com/example/App.kt
package com.example

import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.routing.*
import io.ktor.server.response.*
import io.ktor.http.*

fun main() {
    embeddedServer(Netty, port = 8080) {
        routing {
            get("/") {
                call.respondText("Hello from Kotlin on Kubernetes!", ContentType.Text.Plain)
            }
        }
    }.start(wait = true)
}

Приложение слушает порт 8080. Это важно запомнить — мы будем использовать этот порт в Dockerfile и манифестах.

2. Создание Docker-образа

Для сборки образа нам понадобится Dockerfile. Лучшая практика — использовать multi-stage сборку, чтобы итоговый образ был минимальным по размеру.

FROM gradle:7.6-jdk17 AS build
WORKDIR /app
COPY build.gradle.kts settings.gradle.kts ./
COPY src ./src
RUN gradle build --no-daemon

FROM openjdk:17-jre-slim
WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Соберем образ и загрузим его в реестр (например, Docker Hub):

docker build -t yourusername/kotlin-k8s-demo:v1 .
docker push yourusername/kotlin-k8s-demo:v1

Если у вас нет доступа к реестру, можно использовать minikube и загрузить образ локально командой minikube image load.

3. Основные манифесты Kubernetes

Теперь перейдем к самому интересному — написанию YAML-манифестов для развертывания приложения в кластере. Нам понадобятся два базовых объекта: Deployment (управляет репликами подов) и Service (обеспечивает доступ к подам).

3.1 Deployment

Deployment описывает желаемое состояние подов: какой образ использовать, сколько реплик, какие порты открывать.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kotlin-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: kotlin-app
  template:
    metadata:
      labels:
        app: kotlin-app
    spec:
      containers:
      - name: kotlin-app
        image: yourusername/kotlin-k8s-demo:v1
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 3

Обратите внимание на два важных блока:

  • Resources — запросы и лимиты по CPU и памяти. Без них Kubernetes может «переполнить» ноду.
  • Probes — проверки здоровья. livenessProbe перезапускает под, если приложение зависло, а readinessProbe отключает трафик от неподготовленного пода.

3.2 Service

Чтобы к нашему приложению можно было обратиться изнутри кластера или извне, создадим Service типа LoadBalancer (для облачных провайдеров) или NodePort (для локального тестирования).

apiVersion: v1
kind: Service
metadata:
  name: kotlin-service
spec:
  selector:
    app: kotlin-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: LoadBalancer

Service перенаправляет трафик с порта 80 (внешний) на порт 8080 (внутренний порт пода).

4. Запуск и проверка

Применим оба манифеста к кластеру:

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

Проверим статус подов:

kubectl get pods

Если все хорошо, вы увидите два пода в статусе Running. Проверим сервис:

kubectl get svc kotlin-service

Для локального кластера (Minikube) получите доступ к приложению:

minikube service kotlin-service

Откроется браузер, и вы увидите наше приветствие: Hello from Kotlin on Kubernetes!.

Попробуйте изменить количество реплик в манифесте (replicas: 3) и повторно применить kubectl apply -f deployment.yaml. Kubernetes автоматически создаст новый под — это и есть масштабирование на практике.

5. Полезные советы для начинающих

  • Используйте Namespace: для изоляции разных сред (dev,

Блоги

Рекомендаций по книгам