Kubernetes for Java Developers: Best Practices (2025)


Kubernetes for Java Developers

Kubernetes has become the de facto standard for container orchestration, and Java applications are no exception. This comprehensive guide explores best practices for deploying and managing Java applications in Kubernetes, from containerization to operational excellence.

Pro Tip: Understanding Kubernetes best practices helps Java developers build scalable, maintainable, and resilient applications.

Containerization Best Practices

Note: Proper containerization is crucial for successful Kubernetes deployment of Java applications.

Optimized Dockerfile Example


# Build stage
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN ./mvnw clean package -DskipTests

# Run stage
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app

# Add curl for healthcheck
RUN apk add --no-cache curl

# Copy only necessary files
COPY --from=builder /app/target/*.jar app.jar

# Add non-root user
RUN addgroup -S spring && adduser -S spring -G spring
USER spring

# Set JVM options
ENV JAVA_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError"

# Health check
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

Resource Management

Pro Tip: Proper resource management ensures optimal performance and cost efficiency in Kubernetes.

Resource Configuration Example


apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: java-app
  template:
    metadata:
      labels:
        app: java-app
    spec:
      containers:
      - name: java-app
        image: myapp:latest
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
        env:
        - name: JAVA_OPTS
          value: "-XX:+UseG1GC -XX:MaxGCPauseMillis=200"
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10

Deployment Strategies

Note: Choosing the right deployment strategy is crucial for maintaining application availability during updates.

Rolling Update Strategy


apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      containers:
      - name: java-app
        image: myapp:latest
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10

Configuration Management

Pro Tip: Proper configuration management ensures flexibility and maintainability of Java applications in Kubernetes.

ConfigMap and Secret Example


apiVersion: v1
kind: ConfigMap
metadata:
  name: java-app-config
data:
  application.properties: |
    server.port=8080
    spring.profiles.active=prod
    logging.level.root=INFO
---
apiVersion: v1
kind: Secret
metadata:
  name: java-app-secrets
type: Opaque
data:
  DB_PASSWORD: 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
spec:
  template:
    spec:
      containers:
      - name: java-app
        image: myapp:latest
        envFrom:
        - configMapRef:
            name: java-app-config
        - secretRef:
            name: java-app-secrets
        volumeMounts:
        - name: config-volume
          mountPath: /config
      volumes:
      - name: config-volume
        configMap:
          name: java-app-config

Monitoring and Observability

Note: Comprehensive monitoring is essential for maintaining application health and performance.

Prometheus Integration Example


apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: java-app-monitor
spec:
  selector:
    matchLabels:
      app: java-app
  endpoints:
  - port: http
    path: /actuator/prometheus
    interval: 15s
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
spec:
  template:
    metadata:
      labels:
        app: java-app
    spec:
      containers:
      - name: java-app
        image: myapp:latest
        ports:
        - name: http
          containerPort: 8080
        env:
        - name: MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE
          value: "prometheus,health,info"

Security Considerations

Pro Tip: Security should be a top priority when deploying Java applications in Kubernetes.

Security Context Example


apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
      containers:
      - name: java-app
        image: myapp:latest
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
          capabilities:
            drop:
            - ALL
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      volumes:
      - name: tmp
        emptyDir: {}

Operational Excellence

Note: Following operational best practices ensures smooth application management in Kubernetes.

Horizontal Pod Autoscaling


apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: java-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: java-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80

Best Practices Summary

  • Use multi-stage builds for smaller container images
  • Implement proper health checks and probes
  • Set appropriate resource limits and requests
  • Use ConfigMaps and Secrets for configuration
  • Implement proper monitoring and logging
  • Follow security best practices
  • Use appropriate deployment strategies
  • Implement proper scaling policies

Conclusion

Successfully deploying Java applications in Kubernetes requires a comprehensive understanding of containerization, resource management, and operational best practices. By following these guidelines, developers can build scalable, maintainable, and secure applications that thrive in a Kubernetes environment.