Проектировал ли сущности под Kubernetes
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Kubernetes и архитектура приложений
Да, я проектировал приложения под Kubernetes. Это меняет подход к архитектуре.
Ключевые отличия при разработке для K8s
1. Stateless Design
Всё состояние должно быть вне приложения.
// ❌ Плохо для K8s
public class SessionManager {
private static Map<String, Session> sessions = new HashMap<>();
// Если pod перезагрузится, потеряем все сессии!
}
// ✅ Хорошо для K8s
public class SessionManager {
private final RedisTemplate<String, Session> redis;
public void saveSession(String id, Session session) {
redis.opsForValue().set("session:" + id, session);
}
}
2. Health Checks для K8s
K8s нужно знать, живо ли приложение.
@RestController @RequestMapping("/actuator")
public class HealthController {
@GetMapping("/health")
public ResponseEntity<HealthStatus> health() {
return ResponseEntity.ok(
new HealthStatus("UP")
);
}
@GetMapping("/health/live")
public ResponseEntity<String> liveness() {
// Это живо ли приложение?
return ResponseEntity.ok("alive");
}
@GetMapping("/health/ready")
public ResponseEntity<String> readiness() {
// Готово ли обрабатывать запросы?
if (databaseConnected()) {
return ResponseEntity.ok("ready");
}
return ResponseEntity.status(503).build();
}
}
3. Graceful Shutdown
При deployment новой версии K8s отправляет SIGTERM.
public class GracefulShutdown {
@PreDestroy
public void onShutdown() {
// Даём время завершить текущие requests
Thread.sleep(30_000);
// Закрываем пулы потоков
executorService.shutdown();
executorService.awaitTermination(30, TimeUnit.SECONDS);
}
}
4. Externalized Configuration
Всяконфигурация вне Dockerfile.
// application.yml
spring: datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USER}
password: ${DATABASE_PASSWORD}
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
K8s deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: my-app spec: replicas: 3 selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:1.0.0
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: app-config
key: database.url
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: password
livenessProbe:
httpGet:
path: /actuator/health/live
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
5. Service Discovery
В K8s нет IP адресов, есть DNS имена.
// Вместо:
String url = "http://192.168.1.100:8080/api";
// Используешь:
String url = "http://my-service:8080/api";
// K8s автоматически маршрутизирует на здоровый pod
6. Logging для K8s
Все логи должны идти в stdout/stderr.
// ❌ Не пиши в файлы
logger.info("message"); // в файл
// ✅ Пиши в stdout
System.out.println("message"); logger.info("message"); // в stdout (logback)
// K8s собирает через 'kubectl logs'
7. Database Migrations под K8s
Миграции должны быть idempotent и безопасны.
ApiVersion: batch/v1 kind: Job metadata: name: db-migration spec: template:
spec:
containers:
- name: migrate
image: my-app:1.0.0
command: ["java", "-jar", "app.jar", "migrate"]
restartPolicy: OnFailure
8. Service обнаружение зависимостей
В K8s используешь Service для зависимостей.
@Configuration
public class FeignClients {
@Bean
public UserServiceClient userServiceClient() {
// Вместо hardcoded http://192.168.1.50:8081
// Используешь K8s service name
return Feign.builder()
.target(UserServiceClient.class,
"http://user-service:8080");
}
}
K8s Service: apiVersion: v1 kind: Service metadata: name: user-service spec: selector:
app: user-service
ports:
- port: 8080
targetPort: 8080
9. Метрики для K8s Autoscaling
@Component
public class MetricsExporter {
private final MeterRegistry meterRegistry;
@Scheduled(fixedRate = 10000)
public void exportMetrics() {
// Prometheus metrics для K8s autoscaling
meterRegistry.gauge("app.queue.size", getQueueSize());
meterRegistry.gauge("app.processing.time", getAvgProcessingTime());
}
}
K8s Autoscaling: apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: my-app-hpa spec: scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2 maxReplicas: 10 metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
10. Volume и Persistent Storage
Для БД, кеша — используешь PersistentVolumeClaim.
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: db-pvc spec: accessModes:
- ReadWriteOnce resources:
requests:
storage: 10Gi
Главные principles для K8s
- Stateless — состояние вне приложения (Redis, БД)
- Health checks — /health/live и /health/ready
- Graceful shutdown — обрабатываем SIGTERM
- Externalized config — environment variables
- Logging to stdout — не в файлы
- Service discovery — DNS имена, не IP
- Resource requests/limits — K8s должен знать требования
- Idempotent migrations — безопасные обновления
- Metrics — для monitoring и autoscaling
- Small container images — fast deployments
Результат
Приложение, спроектированное для K8s:
- Быстро масштабируется
- Reliable при обновлениях
- Легко мониторится
- Self-healing при сбоях