How to Mock Kubernetes Services with a ClusterIP Registry in Python

Simulate Kubernetes service discovery by assigning ClusterIP addresses to dataclass-defined services, with JSON export for inspection or testing.

Medium Python 3.9+ Aug 9, 2026 Production deployment patterns 13 views 0 copies

Python code

72 lines
Python 3.9+
import json
from dataclasses import dataclass, asdict
from typing import Dict, Optional


@dataclass
class Service:
    name: str
    namespace: str
    cluster_ip: str
    selector: Dict[str, str]
    port: int
    target_port: Optional[int] = None


class ClusterIPServiceRegistry:
    _ip_counter = 0

    def __init__(self) -> None:
        self._services: Dict[str, Service] = {}

    def _next_cluster_ip(self) -> str:
        self._ip_counter += 1
        return f"10.96.{self._ip_counter // 256}.{self._ip_counter % 256}"

    def create_service(self, name: str, namespace: str, selector: Dict[str, str], port: int, target_port: Optional[int] = None) -> Service:
        key = f"{namespace}/{name}"
        if key in self._services:
            raise ValueError(f"Service {key} already exists")

        service = Service(
            name=name,
            namespace=namespace,
            cluster_ip=self._next_cluster_ip(),
            selector=selector,
            port=port,
            target_port=target_port or port,
        )
        self._services[key] = service
        return service

    def get_service(self, name: str, namespace: str = "default") -> Optional[Service]:
        return self._services.get(f"{namespace}/{name}")

    def list_services(self) -> list[Service]:
        return list(self._services.values())

    def to_json(self) -> str:
        return json.dumps([asdict(s) for s in self.list_services()], indent=2)


if __name__ == "__main__":
    registry = ClusterIPServiceRegistry()

    web_service = registry.create_service(
        name="web",
        namespace="default",
        selector={"app": "web"},
        port=80,
        target_port=8080,
    )
    api_service = registry.create_service(
        name="api",
        namespace="prod",
        selector={"app": "api"},
        port=443,
    )

    print(registry.to_json())

    found = registry.get_service("web")
    print(f"\nFound: {found.cluster_ip} -> {found.target_port}")

Output

stdout
[
  {
    "name": "web",
    "namespace": "default",
    "cluster_ip": "10.96.0.1",
    "selector": {
      "app": "web"
    },
    "port": 80,
    "target_port": 8080
  },
  {
    "name": "api",
    "namespace": "prod",
    "cluster_ip": "10.96.0.2",
    "selector": {
      "app": "api"
    },
    "port": 443,
    "target_port": 443
  }
]

Found: 10.96.0.1 -> 8080

How it works

The ClusterIPServiceRegistry auto-generates ClusterIP addresses using a monotonically increasing counter, mapping it into a 10.96.x.x /16 range like real Kubernetes. The Service dataclass stores the essential metadata — name, namespace, selector, ports — and asdict converts it to a dict for clean JSON output. Namespace/name keying mirrors Kubernetes' unique resource identifier, preventing duplicate services. The to_json method lets you export the registry state, which is handy for mocking service discovery in tests or local dev setups. Using an optional target_port defaults it to the service port, matching K8s behavior when not explicitly set.

Common mistakes

  • Forgetting that ClusterIP allocation starts at .1, not .0, which skews IP expectations in tests
  • Not keying services by namespace — this allows duplicate names across namespaces and breaks lookups
  • Using mutable class-level `_ip_counter` across registries, causing shared state and unexpected IPs

Variations

  1. Use a fixed range like 10.43.0.0/16 to match k3s or a provider-specific CIDR
  2. Back the registry with a `dict` plus a `threading.Lock` to make it concurrency-safe

Real-world use cases

  • Local development shim that mimics Kubernetes service discovery without a real cluster.
  • Integration tests for microservices that depend on stable ClusterIP endpoints and DNS-like lookups.
  • Sandboxed demo environments where users create services and inspect JSON output for validation.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Production deployment patterns

Related tutorials and quizzes for this topic.