Kubernetes
Service Dependencies
Container Orchestration
DevOps
Microservices

How can we create service dependencies using kubernetes

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Kubernetes does not have a built-in "service dependency" feature in the way some older application servers do. That is intentional. In a distributed system, startup order is a weak guarantee, so the usual Kubernetes answer is to design services that tolerate dependencies being unavailable for a while and become ready only when they can actually serve traffic.

Start with the Right Mental Model

A Kubernetes Service is a stable network endpoint, not a process supervisor for other services. Creating a Service for api and another Service for database does not mean Kubernetes will automatically start one before the other or delay traffic until every dependency is healthy.

Instead, dependency handling is usually built from these pieces:

  • readiness probes
  • startup probes
  • init containers
  • retry logic inside the application
  • one-time Jobs for migrations or setup work

That is a better match for real distributed systems than strict startup ordering.

Use Readiness Probes to Control Traffic

The most important mechanism is usually a readiness probe. It does not force another service to start first, but it prevents traffic from reaching a Pod until that Pod is genuinely ready.

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: api
5spec:
6  replicas: 2
7  selector:
8    matchLabels:
9      app: api
10  template:
11    metadata:
12      labels:
13        app: api
14    spec:
15      containers:
16        - name: api
17          image: myorg/api:1.0.0
18          ports:
19            - containerPort: 8080
20          readinessProbe:
21            httpGet:
22              path: /ready
23              port: 8080
24            initialDelaySeconds: 5
25            periodSeconds: 5

The application behind /ready should check the dependencies it truly needs. If the database connection is mandatory, the endpoint should fail until the database is usable. That way the Pod can start, retry, and eventually become ready without serving broken traffic.

Use Init Containers for Hard Preconditions

If a container truly must wait before its main process starts, an init container is the right tool. Init containers run to completion before the main container starts.

yaml
1apiVersion: apps/v1
2kind: Deployment
3metadata:
4  name: worker
5spec:
6  replicas: 1
7  selector:
8    matchLabels:
9      app: worker
10  template:
11    metadata:
12      labels:
13        app: worker
14    spec:
15      initContainers:
16        - name: wait-for-db
17          image: busybox:1.36
18          command:
19            - sh
20            - -c
21            - until nc -z database 5432; do echo waiting for database; sleep 2; done
22      containers:
23        - name: worker
24          image: myorg/worker:1.0.0

This is useful for simple cases, but do not overuse it. Waiting for a TCP port is weaker than waiting for application-level readiness. A database might accept a socket connection while still replaying logs or applying migrations.

Use Jobs for Setup Tasks

Some dependencies are not runtime relationships at all. Schema migrations, seed data, or queue creation are one-time setup tasks. Model those as Kubernetes Job resources instead of baking them into startup order.

That separation is cleaner:

  • Job handles setup work
  • application Deployments handle long-running services
  • readiness probes decide when traffic is safe

This keeps startup logic explicit and easier to observe.

Retry in the Application

Even with init containers and probes, dependencies can still disappear later due to restarts, node failures, or network partitions. That is why application-level retry and backoff matter more than startup sequencing.

An application that exits permanently because Redis was unavailable for ten seconds is fragile in Kubernetes. A better service logs the problem, retries with backoff, and reports not-ready until it recovers.

Common Pitfalls

  • Expecting Kubernetes Services to express startup order by themselves.
  • Using init containers as a substitute for proper readiness checks and retry logic.
  • Waiting only for an open port instead of real application-level readiness.
  • Coupling unrelated setup work to every container startup instead of using a Job.
  • Assuming dependencies only matter at startup and never fail later.

Summary

  • Kubernetes does not provide strict service dependency management as a first-class feature.
  • Readiness probes are the main tool for preventing traffic to unready Pods.
  • Init containers are useful for hard startup prerequisites, but they should be used carefully.
  • One-time setup work belongs in Jobs, not in every container boot path.
  • Real resilience comes from application retries and recovery, not from startup ordering alone.

Course illustration
Course illustration

All Rights Reserved.