Deep, field-by-field explanation of a Spring Boot UI+API Deployment and a ClusterIP Service, including selectors, ports, probes, and resource requests/limits.
Deployment + Service
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-ui-api
labels:
app: spring-ui-api
spec:
replicas: 2
selector:
matchLabels:
app: spring-ui-api
template:
metadata:
labels:
app: spring-ui-api
spec:
containers:
- name: app
image: REPLACEME_ACR_LOGIN/spring-ui-api:1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 9087
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 9087
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 6
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 9087
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 3
startupProbe:
httpGet:
path: /actuator/health
port: 9087
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 30
resources:
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
---
apiVersion: v1
kind: Service
metadata:
name: spring-ui-api-svc
labels:
app: spring-ui-api
spec:
selector:
app: spring-ui-api
ports:
- name: http
port: 80
targetPort: 9087
type: ClusterIP
apiVersion: apps/v1 selects the stable API group for workloads like Deployments.kind: Deployment declares a higher-level controller for rolling updates and replicas.kubectl get deploy spring-ui-api).
Requests two Pod replicas. The Deployment controller continuously reconciles reality to match this desired state.
This is one of the most important concepts in Kubernetes: the Deployment’s selector decides which Pods it owns and manages.
app: spring-ui-api
REPLACEME_ACR_LOGIN/spring-ui-api:1.0 is a placeholder for your ACR login server,
for example: myregistry.azurecr.io/spring-ui-api:1.0.
:1.0 is the immutable version you’re deploying. Updating the tag changes what AKS pulls.
Always for dev).
containerPort: 9087 documents the port the process listens on inside the container.
This is the same port your Dockerfile exposes and your Spring Boot app runs on.
periodSeconds.
Each call must respond within timeoutSeconds.
After failureThreshold consecutive failures, Kubernetes takes action
(ready=false, restart, or “still starting”).
GET /actuator/health on port 9087
initialDelaySeconds: 5 → wait 5 seconds before first checkperiodSeconds: 5 → check every 5 secondstimeoutSeconds: 2 → each call must complete within 2 secondsfailureThreshold: 30 → allow 30 failures before declaring startup failedGET /actuator/health/readiness on port 9087
initialDelaySeconds: 5 → begin checks shortly after container startsperiodSeconds: 5 → check frequently (fast cutover)timeoutSeconds: 2 → keep probe calls tightfailureThreshold: 6 → after 6 failures → Pod becomes NotReadyGET /actuator/health/liveness on port 9087
initialDelaySeconds: 15 → allow more time before first liveness checkperiodSeconds: 10 → check every 10 secondstimeoutSeconds: 2 → each call must complete within 2 secondsfailureThreshold: 3 → after 3 failures → container restart/actuator/health is exposed, readiness/liveness URLs will 404 and probes will fail.
The minimum resources Kubernetes uses for scheduling decisions. A node must have at least these available for the Pod to be placed.
cpu: 100m → 0.1 CPU core requestedmemory: 256Mi → 256 MiB requestedThe upper bounds enforced at runtime (especially for memory). Exceeding memory limit typically leads to OOM kill. CPU limits throttle.
cpu: 500m → up to 0.5 CPU corememory: 512Mi → up to 512 MiB512Mi, the Pod may be OOM-killed. If this happens, increase the limit or set JVM flags
(not shown here) to cap heap appropriately.
selector.app = spring-ui-api.
port: 80 → Service listens on 80 (cluster-internal)targetPort: 9087 → forwards to container’s 9087