Деплой Java приложений на Kubernetes: от Dockerfile до работающего сервиса
Современная Java-разработка немыслима без контейнеризации и оркестрации. Kubernetes (K8s) стал стандартом для управления микросервисами, и умение разворачивать Java-приложения в кластере — обязательный навык для backend-разработчика. В этой статье мы на практике разберем полный цикл деплоя: от сборки Docker-образа с Java-приложением до настройки балансировки нагрузки через Ingress.
1. Подготовка Java-приложения и Dockerfile
Прежде чем попасть в Kubernetes, ваше Java-приложение должно быть упаковано в Docker-образ. Рассмотрим классический случай — приложение на Spring Boot, собранное в JAR-файл.
Сборка проекта
Предположим, у нас есть проект, который собирается через Maven. Выполните команду в корне проекта:
mvn clean package -DskipTests
В результате в папке target/ появится файл my-app-1.0.0.jar.
Создание Dockerfile
Для минимизации размера образа и повышения безопасности используем многостадийную сборку (multi-stage build).
# Stage 1: сборка
FROM maven:3.8.6-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn package -DskipTests
# Stage 2: финальный образ
FROM openjdk:17-jdk-slim
WORKDIR /app
COPY --from=builder /app/target/my-app-1.0.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Сборка и публикация образа
docker build -t my-java-app:1.0.0 .
docker tag my-java-app:1.0.0 your-dockerhub/my-java-app:1.0.0
docker push your-dockerhub/my-java-app:1.0.0
2. Создание манифестов Kubernetes
Kubernetes использует декларативный подход. Мы опишем желаемое состояние системы в YAML-файлах.
Deployment — управление подам
Создайте файл deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: java-app-deployment
labels:
app: java-app
spec:
replicas: 3
selector:
matchLabels:
app: java-app
template:
metadata:
labels:
app: java-app
spec:
containers:
- name: java-app
image: your-dockerhub/my-java-app:1.0.0
ports:
- containerPort: 8080
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 5
Service — обеспечение доступа
Создайте файл service.yaml:
apiVersion: v1
kind: Service
metadata:
name: java-app-service
spec:
selector:
app: java-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
ConfigMap — вынесение конфигурации
Для хранения переменных окружения создайте configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
SPRING_PROFILES_ACTIVE: "prod"
DB_URL: "jdbc:postgresql://postgres-service:5432/mydb"
3. Деплой в кластер и проверка
Теперь применим все манифесты к кластеру. Убедитесь, что у вас настроен kubectl и вы подключены к нужному контексту.
Применение манифестов
kubectl apply -f configmap.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Проверка состояния
kubectl get pods
kubectl get deployments
kubectl get services
Вы должны увидеть три запущенных пода (replicas: 3) и сервис с ClusterIP.
Проброс портов для локальной проверки
kubectl port-forward service/java-app-service 8080:80
Теперь откройте браузер по адресу http://localhost:8080 — ваше Java-приложение должно отвечать.
4. Настройка Ingress и масштабирование
Для доступа из внешнего мира (например, по домену api.myapp.com) используем Ingress-контроллер.
Создание Ingress-ресурса
Файл ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: java-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: java-app-service
port:
number: 80
Горизонтальное масштабирование
Kubernetes позволяет легко изменять количество реплик:
kubectl scale deployment java-app-deployment --replicas=5
Для автоматического масштабирования на основе нагрузки используйте HorizontalPodAutoscaler (HPA):
kubectl autoscale deployment java-app-deployment --cpu-percent=70 --min=3 --max=10
Обновление приложения (Rolling Update)
Когда вы выпускаете новую версию образа, просто обновите образ в манифесте и повторно примените:
kubectl set image deployment/java-app-deployment java-app=your-dockerhub/my-java-app:1.0.1
kubectl rollout status deployment/java-app-deployment
Заключение
Мы прошли полный путь