Containers are a good way to bundle and run your applications. In a production environment, you need to manage the containers that run the applications and ensure that there is no downtime.
Kubernetes provides you with a framework to run distributed systems resiliently. It takes care of scaling and failover for your application, provides deployment patterns, and more.
NOTE: Kubernetes operates at the container level rather than at the hardware level.
Core Features
Kubernetes provides you with:
-
Service discovery and load balancing: Kubernetes can expose a container using a DNS name or its own IP address. If traffic to a container is high, Kubernetes is able to load balance and distribute the network traffic so that the deployment is stable.
-
Automated rollouts and rollbacks: You can describe the desired state for your deployed containers using Kubernetes, and it can change the actual state to the desired state at a controlled rate. For example, you can automate Kubernetes to create new containers for your deployment, remove existing containers and adopt all their resources to the new container.
-
Self-healing: Kubernetes restarts containers that fail, replaces containers, kills containers that don't respond to your user-defined health check, and doesn't advertise them to clients until they are ready to serve.
-
Horizontal scaling: Scale your application up and down with a simple command, with a UI, or automatically based on CPU usage.
-
Application-centric management: Raises the level of abstraction from running an OS on virtual hardware to running an application on an OS using logical resources.
Architecture
A Kubernetes cluster consists of a control plane plus a set of worker machines, called nodes, that run containerized applications. In production environments, the control plane usually runs across multiple computers and a cluster usually runs multiple nodes, providing fault-tolerance and high availability.
Low Level Design
-
API Layer (Spring Boot REST Controller): Instead of Node.js with Express, you would use a Spring Boot REST Controller to accept incoming container deployment requests. You can use Spring Data JPA or MyBatis with a database like PostgreSQL to store your job states.
-
Job Dispatcher (Spring Scheduling): Rather than BullMQ, you can use Spring's native Scheduling capabilities (
@Scheduled) to create a background task that polls your database for "submitted" jobs. You could also use an enterprise-grade job scheduling library likeJobRunrif you require distributed job processing across multiple nodes. -
CRI / Scheduler (Docker Java API): To interact with Docker, use the docker-java library, which provides a native Java SDK for the Docker Remote API. This allows your service to perform the same operations shown in the video—pulling images, creating containers, and monitoring their lifecycle.
Core Components Structure:
Repository Layer: Define a JobEntity to track image, command, status (PENDING, RUNNING, SUCCEEDED), and containerId.
Scheduler Service: Create a @Service class annotated with @EnableScheduling to handle the logic of polling the database and triggering the Docker interaction.
Docker Client Bean: Configure a @Configuration class to initialize the DockerClient object, allowing you to inject it into your services.
This approach gives you a robust foundation in Java for managing containerized workloads. Remember to handle thread safety (e.g., using AtomicLong or database locking) if you plan to run multiple scheduler instances to avoid race conditions when picking up jobs.