# k8s native java spring app <!-- Put the link to this slide here so people can follow --> slide: https://hackmd.io/@hmoniaga/k8s-native-spring --- ## Why? - JVM Apps consumes a lot of memory - Not cost effective (https://learnk8s.io/kubernetes-instance-calculator) - Not k8s native or container aware by default - Non-optimized memory management - Slow startup time --- ## Spring Native - AOT Framework - Compiled via GraalVM --- ### GraalVM - OpenJDK distribution with extra components - Native image builder - Does static analysis on compile time, and throw away anything not being used (JRE, other stuff not being used in classpath) - Other competing GraalVM based frameworks - micronaut - quarkus --- ### GraalVM Limitations - No more dynamic Java behavior - No reflection, serialization, proxies, JNI - Not recommended for large monolith or latency sensitive apps due to limited [Garbage collection](https://www.graalvm.org/reference-manual/native-image/MemoryManagement/) options - Serial GC - stop the world - G1 GC - concurrent, enterprise version - Epsilon GC - no op GC --- ### Spring JVM vs Spring Native Comparison - spring-petclinic - build size: 261MB vs 143MB - memory size: 508MB vs 57MB - startup time: 8s vs 0. - potential saving in AWS: - t4g.small 2CPU 2 GB 0,0168$/h = 147.168$/year - t4g.micro 2CPU 1 GB 0,0084$/h = 73.584$/year --- ### Spring Native Cons - Slow build time - May be mitigated by Spring JVM during development, and Spring Native in CI/CD - Still in beta (0.1 released in June 2021) - list of supported spring boot: https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/#support-spring-boot - May require some code change, e.g. additional annotations due AOT --- ### Recommended changes - Use [buildpacks](https://buildpacks.io/) to build container images - Use Spring Boot Actuator - Recommended server config: ```properties server.shutdown=graceful spring.lifecycle.timeout-per-shutdown-phase=30s ``` - k8s pod recommended properties ```yaml apiVersion: v1 kind: Pod spec: containers: - name: app image: app-image terminationGracePeriodSeconds: 60 ``` --- ### Health endpoint - By default, spring actuator's health endpoint includes DB or external components health check - The “liveness” Probe should not depend on health checks for external systems. Can cause service to trigger restart (and stuck in restart loop) if there is intermittent issues. - Recommended to turn off external components check - In newer spring actuator versions, liveness/readiness endpoints are provided by default ```yaml livenessProbe: httpGet: path: /actuator/health/liveness port: <actuator-port> failureThreshold: ... periodSeconds: ... readinessProbe: httpGet: path: /actuator/health/readiness port: <actuator-port> failureThreshold: ... periodSeconds: ... ``` --- ### Service Discovery - In traditional environment, you'd use Spring Discovery / Eureka - In k8s, it's provided out of the box via DNS --- ### Application configuration - Storing application.yaml in k8s - configmap to store configuration - secret to store sensitive information - Why not external config server? - Startup dependency and coupling - Auto reload provided via Spring Cloud Kubernetes Configuration --- ### Circuit breaking - Traditional approach would be to use Spring Cloud Hystrix on each service - If istio or service mesh is installed, this is no longer needed --- ### Thank you! :sheep:
{"metaMigratedAt":"2023-06-16T11:37:45.933Z","metaMigratedFrom":"YAML","title":"k8s native spring application","breaks":true,"description":"lightning talk","contributors":"[{\"id\":\"59159191-cc4b-4810-ac2d-1e3f4e92f52a\",\"add\":7402,\"del\":3750}]"}
    283 views