Gymterview
middle

Как выглядит YAML-манифест для деплоя Java/Spring Boot приложения?

Полный набор манифестов для развёртывания типичного Spring Boot приложения включает Deployment, Service, Ingress, ConfigMap, Secret и HPA.

Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-spring-app
  namespace: production
  labels:
    app: my-spring-app
    version: "1.0.0"
spec:
  replicas: 3
  revisionHistoryLimit: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: my-spring-app
  template:
    metadata:
      labels:
        app: my-spring-app
        version: "1.0.0"
    spec:
      terminationGracePeriodSeconds: 60
      containers:
        - name: app
          image: my-registry/my-spring-app:1.0.0
          imagePullPolicy: Always
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          env:
            - name: JAVA_OPTS
              value: >-
                -XX:MaxRAMPercentage=75.0
                -XX:+UseContainerSupport
                -Djava.security.egd=file:/dev/./urandom
            - name: SPRING_PROFILES_ACTIVE
              value: "kubernetes,production"
          envFrom:
            - configMapRef:
                name: spring-config
            - secretRef:
                name: spring-secret
          resources:
            requests:
              memory: "512Mi"
              cpu: "250m"
            limits:
              memory: "1Gi"
              cpu: "1000m"
          startupProbe:
            httpGet:
              path: /actuator/health/liveness
              port: http
            initialDelaySeconds: 15
            periodSeconds: 5
            failureThreshold: 30
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: http
            periodSeconds: 10
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: http
            periodSeconds: 5
            failureThreshold: 3
      imagePullSecrets:
        - name: registry-credentials
Service
apiVersion: v1
kind: Service
metadata:
  name: my-spring-app-service
  namespace: production
  labels:
    app: my-spring-app
spec:
  type: ClusterIP
  selector:
    app: my-spring-app
  ports:
    - name: http
      port: 80
      targetPort: http
      protocol: TCP
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-spring-app-ingress
  namespace: production
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - api.example.com
      secretName: api-tls-secret
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-spring-app-service
                port:
                  number: 80
ConfigMap + Secret + HPA
apiVersion: v1
kind: ConfigMap
metadata:
  name: spring-config
  namespace: production
data:
  SPRING_DATASOURCE_URL: "jdbc:postgresql://postgres-service:5432/mydb"
  SPRING_JPA_HIBERNATE_DDL_AUTO: "validate"
  SPRING_JPA_SHOW_SQL: "false"
  SERVER_SHUTDOWN: "graceful"
  SPRING_LIFECYCLE_TIMEOUT_PER_SHUTDOWN_PHASE: "30s"
---
apiVersion: v1
kind: Secret
metadata:
  name: spring-secret
  namespace: production
type: Opaque
stringData:
  SPRING_DATASOURCE_USERNAME: "app_user"
  SPRING_DATASOURCE_PASSWORD: "secure-password-here"
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-spring-app-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-spring-app
  minReplicas: 3
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

Все манифесты можно поместить в отдельные файлы в директории k8s/ и применить одной командой: kubectl apply -f ./k8s/ -n production.

На собеседовании: не нужно помнить YAML наизусть, но нужно знать структуру: какие ресурсы необходимы (Deployment, Service, ConfigMap, Secret, Probes) и ключевые поля (replicas, strategy, resources, probes). Частая ошибка — забыть про terminationGracePeriodSeconds или imagePullSecrets.