Tools and Best Practices for Kubernetes Adoption: Lessons from Ray Tsang at SpringOne Platform 2019

Kubernetes

YOUR COSMETIC CARE STARTS HERE

Find the Best Cosmetic Hospitals

Trusted • Curated • Easy

Looking for the right place for a cosmetic procedure? Explore top cosmetic hospitals in one place and choose with confidence.

“Small steps lead to big changes — today is a perfect day to begin.”

Explore Cosmetic Hospitals Compare hospitals, services & options quickly.

✓ Shortlist providers • ✓ Review options • ✓ Take the next step with confidence

This article summarizes a talk by Ray Tsang, Developer Advocate at Google, delivered at SpringOne Platform 2019. The original coverage was published on InfoQ.

Overview

Adopting Kubernetes in an organization is rarely a straight line. At SpringOne Platform 2019, Ray Tsang — Developer Advocate at Google — walked developers through the practical challenges of containerization and shared a toolkit of projects, libraries, and operational patterns that can smooth the journey. The talk touched on image building, local testing, memory management, container security, and deployment best practices, with a particular focus on the Java and Spring ecosystem.

The Challenge of Containerizing Java Applications

Containerizing applications — especially Java applications — introduces friction at multiple levels. Writing and maintaining Dockerfiles is tedious and error-prone. IDE support for container-based workflows has historically lagged behind. These friction points slow down development cycles and create barriers to adoption for teams that are otherwise ready to move to Kubernetes.

The Spring Cloud Kubernetes project addresses part of this problem by providing common interfaces that allow Spring Cloud and Spring Boot applications to consume Kubernetes-native services directly, reducing the amount of Kubernetes-specific boilerplate developers need to write themselves.

Local Testing with TestContainers

One of the tools Tsang highlighted was TestContainers, a Java library that integrates with JUnit to spin up disposable Docker containers for common dependencies — databases, message brokers, Selenium browsers, and other services — during test execution. TestContainers is particularly useful for:

  • Data access layer tests: Run tests against a real database instance rather than an in-memory mock, without needing a persistent external database.
  • Integration tests: Compose multi-service environments locally that mirror production topology.
  • UI tests: Drive a containerized browser instance, removing the need for a locally installed browser.

The key benefit is that developers can run a representative test suite on a laptop without requiring a full Kubernetes cluster, reducing the feedback loop significantly.

Managing Java Memory Inside Kubernetes Containers

A common operational problem when running Java applications in Kubernetes is the OOMKilled state — where the container is terminated because it has exceeded its memory limit. This often happens because the JVM’s default memory settings are not aware of container resource limits.

Tsang pointed to the Cloud Foundry Java Buildpack Memory Calculator as one tool for computing a holistic JVM memory configuration. The calculator accounts for heap, metaspace, thread stacks, and other JVM memory regions to produce settings that keep total memory consumption within the container’s declared limit. Properly sizing JVM memory avoids both OOMKilled restarts and the opposite problem of under-allocating memory and hurting application performance.

Container Security: Don’t Run as Root

A recurring theme in Tsang’s container best practices discussion was privilege reduction. Most base Docker images default to running processes as the root user, which is a significant security risk in shared Kubernetes environments. The recommended practice is to explicitly set a non-root user in the Dockerfile or via Kubernetes security context settings.

Additional image hygiene best practices mentioned include:

  • Keeping image layers small to reduce attack surface and pull time.
  • Cleaning up unnecessary build artifacts and package manager caches within the image.
  • Avoiding storing sensitive data in image layers.

Fast Image Builds with Jib

Jib is a Google-developed open-source tool that builds optimized Docker and OCI-compliant container images for Java applications — without requiring a Docker daemon. Key characteristics:

  • No Docker required locally: Jib builds and pushes images directly to a registry, so developers don’t need Docker Desktop installed.
  • Automatic layering: Jib separates application code, resources, and dependencies into distinct image layers, meaning that a code change only invalidates the application layer rather than the entire image. This dramatically speeds up rebuilds and pushes.
  • Build tool integration: Available as a Maven plugin, a Gradle plugin, and a standalone Java library, so it fits into existing build pipelines with minimal configuration.
# Example: build and push with Jib via Maven
mvn compile jib:build -Dimage=gcr.io/my-project/my-appCode language: PHP (php)

Continuous Development with Skaffold

Skaffold is a command-line tool that automates the development workflow for Kubernetes applications. It watches source files, triggers a rebuild when changes are detected, and redeploys the updated image to a Kubernetes cluster — local or remote. Skaffold covers the full inner loop:

  • Build: Invoke Docker, Jib, Buildpacks, or other builders.
  • Push: Publish the image to a registry (or skip this step for local clusters).
  • Deploy: Apply Kubernetes manifests, Helm charts, or Kustomize configurations.

Skaffold also provides building blocks for CI/CD pipelines, allowing the same workflow definition used locally to be reused in automated pipelines, ensuring consistency between development and production deployments.

Operational Best Practices for Java on Kubernetes

Beyond tooling, Tsang covered several configuration and operational patterns that Java applications need to work reliably in Kubernetes:

  • Health checks: Configure liveness and readiness probes so Kubernetes knows when a pod is ready to receive traffic and when it needs to be restarted. Spring Boot Actuator exposes endpoints well-suited to this purpose.
  • Zero-downtime deployments: Use rolling update strategies and ensure readiness probes are correctly tuned so new pods only enter the load balancer rotation when they are genuinely ready.
  • Externalizing configuration: Store environment-specific configuration in Kubernetes ConfigMaps and Secrets rather than baking it into the image, keeping images portable across environments.
  • Structured logging: Output logs in a structured format (e.g., JSON) so they can be ingested efficiently by cluster-level logging infrastructure such as Fluentd or Stackdriver.

Summary

The tools and practices Ray Tsang outlined at SpringOne Platform 2019 remain highly relevant for teams adopting Kubernetes with Java and Spring workloads. Using Jib to simplify image builds, Skaffold to tighten the development feedback loop, TestContainers to enable realistic local testing, and pairing all of that with sound operational practices — proper memory sizing, non-root containers, health probes, and externalized config — gives teams a practical roadmap for a successful Kubernetes adoption.

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
0
Would love your thoughts, please comment.x