System Design Problem

Design the Kubernetes Control Plane

Commonly Asked By:GoogleAmazonMicrosoftRed HatHashiCorp

Interview Setup

Interview Prompt

Design the Kubernetes control plane for a managed Kubernetes service (GKE/EKS/AKS style) operating 1,000 customer clusters, with individual clusters scaling to 10,000 nodes and 500,000 pods. Cover API server, etcd, scheduler, controller manager, kubelet, CNI networking, admission webhooks, RBAC, and multi tenant isolation. Address etcd performance limits, watch fan out, and list pagination at scale.

Clarifying Questions (ask before designing)

QuestionWhy it matters
Single mega cluster or fleet of clusters? Which scope?GKE style managed Kubernetes runs one control plane per cluster, with 1000 clusters plus a fleet layer. A single 500K Pod cluster stresses etcd and the API server differently from 1000 smaller clusters.
What is the consistency model for cluster state?etcd provides linearizable reads and writes via Raft. Kubernetes API object writes are persisted through the API server into etcd. Controllers and kubelets are eventually consistent watchers, allowing interviewers to probe whether you understand level triggered reconciliation.
Who are the tenants: namespaces in one cluster or separate clusters?SaaS platforms often use namespaces and quotas on shared clusters, whereas regulated enterprises get dedicated clusters. The isolation mechanisms therefore differ between namespace controls and full cluster boundaries.
Build vs operate: design upstream Kubernetes or the managed service layer?Staff interviews at cloud providers often expect both the core components, such as the scheduler and controllers, and the fleet layer for provisioning, upgrades, and multi cluster APIs.
What breaks first at 10x scale?etcd size and write throughput, unpaginated LIST calls, watch reconnect storms, scheduler bind QPS. Quantify before proposing fixes.

Scope

In scope

  • API server as gateway to etcd via REST, watch, and admission chain
  • etcd Raft cluster for strongly consistent cluster state
  • Scheduler: filtering predicates + scoring priorities + bind
  • Controller manager reconciliation loops (Deployment, ReplicaSet, Node)
  • Optional cloud controller manager integration for provider specific resources
  • kubelet pod lifecycle + CNI networking overview
  • Admission webhooks (mutating + validating) and RBAC
  • Multi-tenant: namespaces, ResourceQuota, LimitRange, NetworkPolicy
  • Scale: GKE style 1000 cluster fleet. Each large cluster has 10K nodes and 500K Pods
  • etcd performance limits, watch fan out, list pagination, and APF

Out of scope (state explicitly)

  • Implementing container runtime (containerd/CRI internals)
  • Full service mesh data plane (Service Discovery covers discovery while service mesh is separate)
  • Building CNI plugin from scratch (Calico/Cilium implementation)
  • Application CI/CD pipeline design (covered in CI/CD Platform)
  • Ingress controller and API gateway implementation (covered in API Gateway)

Functional Requirements

Start by asking your interviewer whether you are designing one mega cluster or a GKE style fleet of 1,000 clusters. Clarify admission webhooks, multi tenant namespace isolation, and whether the deep dive is API server and etcd or kubelet networking.

  • Declarative workload management: Users submit desired state through Deployments, StatefulSets, and DaemonSets. Controllers then converge actual state toward that desired state
  • API server: RESTful API for cluster objects, with authentication, authorization, admission, validation, and persistence to etcd
  • Scheduling: Assign pending pods to nodes based on resources, affinity, taints/tolerations, and topology constraints
  • Controller reconciliation: Deployment to ReplicaSet to Pod chain, Node health, and EndpointSlice for Services
  • Cloud integration: Optional cloud controller manager reconciles provider resources such as Node metadata, load balancers, routes, and persistent cloud identities
  • Node agent (kubelet): Pull images, run containers via CRI, mount volumes, execute probes, and report status
  • Networking: The container runtime invokes CNI to assign Pod IPs, kube-proxy or an eBPF based service proxy routes Service traffic, and CoreDNS provides cluster DNS (Service Discovery)
  • Admission control: Mutating and validating webhooks enforce policies before persistence
  • RBAC: Role based access scoped to the cluster or namespace
  • Multi tenancy: Namespaces, ResourceQuota, LimitRange, and NetworkPolicy for isolation
  • Fleet management: Provision, upgrade, and monitor 1,000 managed clusters using a GKE style control model

Non-Functional Requirements

Your interviewer will stress test etcd limits and unpaginated LIST operations. A single GET /api/v1/pods without limit can OOM the API server at 500K pods, while Raft quorum across AZs and API Priority and Fairness (APF) serve as staff-level follow-ups.

  • Consistency: Cluster state is strongly consistent through etcd Raft, and all writes go through the API server
  • Scale: 10K Nodes and 500K Pods per large cluster, with 1,000 clusters in the fleet
  • Availability: 99.95% control plane availability, with the scenario tolerating one AZ failure while quorum remains available
  • Performance: Support ~50K aggregate API read and watch demand through the watch cache and ~170 Pod binds/sec burst
  • Security: Use TLS and authenticated control plane communication, encryption at rest for Secrets, RBAC least privilege, and Pod Security Standards
  • Observability: Control plane metrics, audit logs, and distributed tracing (Observability and Distributed Tracing) for API requests
  • Upgrade safety: Perform rolling control plane upgrades without a fleet wide outage

Capacity Estimations

etcd represents the write bottleneck while watch fan out and large LIST responses represent the read and memory bottlenecks. Watch streams are long lived, so request QPS alone is not enough to size the API server. Size API server replicas, watch cache capacity, and concurrent request limits together. Never allow unpaginated LIST operations at 500K pods.

MetricCalculationValue
Managed clusters (fleet)Given: GKE style multi cluster1,000
Nodes per large clusterGiven: design worst case single cluster10K
Pods per large clusterGiven500K
API objects in etcd (large cluster)~500K Pods + 10K Nodes = 510K core objects, plus Services/ReplicaSets/Deployments and other overhead~1.1M objects
etcd size limit (practical)Default 2 GB. 8 GB is a suggested maximum for normal environments2-8 GB
etcd read throughputIllustrative planning range, depending on hardware and read mode~10K-40K reads/sec
etcd write throughputIllustrative planning assumption~8K sustained writes/sec
API server LIST rate (unpaginated risk)Controllers + kubectl. Platform policy requires pagination10K+ LIST calls/min at scale
Watch subscribers (large cluster)Scenario estimate: kubelet + controllers + operators per cluster~15K logical watch streams
Scheduling throughputBurst deploy: 50K pods in 5 min~170 binds/sec peak
Control plane request mix (large cluster)Scenario traffic mix. 80% watch, 15% get, 5% write~50K aggregate read/watch demand
Per-node kubelet sync500K pods ÷ 10K nodes~50 pods/node avg

etcd is the bottleneck for write heavy storms, while the API server watch cache plus large LIST responses are major read and memory bottlenecks for watch fan out. At 500K pods, never allow unpaginated LIST operations because a single GET /api/v1/pods can transfer gigabytes and destabilize the cluster. For this scenario, use 8 to 16 vCPU and 32 GB RAM as a starting point for each API server (3+ replicas), then benchmark and autosize from actual request and watch load. For etcd, use 8 vCPU, 32 GB RAM, and dedicated NVMe as an illustrative starting point, then size from fsync latency and workload measurements. The scheduler operates with a single active leader and can use parallel scheduling work to improve burst throughput.

Architecture Diagram

Walk control plane vs data plane first. Kubernetes separates decisions in the control plane from execution on kubelets and containers. Cluster state is stored in etcd, and the API server is the component through which cluster API writes are made.

Schedulers and controllers watch the API server and issue writes back through it using level triggered reconciliation rather than one shot event handlers. kubelets on each node pull desired pod state and run containers via CRI, while CNI assigns pod IPs and kube-proxy routes Service traffic.

For a managed service (GKE style), a fleet layer provisions and operates 1,000 such control planes, avoiding the anti-pattern of a single shared etcd for the entire fleet. The architectural layout places the API server and etcd in the center, the scheduler and controllers on the left, and kubelets on the right.

Loading...

In the room

Draw the API server connected to etcd first and state that Kubernetes control plane components persist cluster API state through the API server rather than writing to etcd directly. If asked what breaks at 10x scale, identify unpaginated LIST calls before scheduler throughput, because large object responses and controller concurrency can exhaust API server memory long before bind QPS saturates.

Reconciliation Loop

Loading...

Scheduler Pipeline

Loading...

Component Deep Dives

1. API Server + etcd ⭐

The API server, etcd, and scheduler pipeline form the interview core, while kubelet and CNI provide supporting operational depth unless the discussion focuses specifically on container networking.

Watch cache can serve cache eligible LIST and WATCH requests without reading etcd on the hot path, while APF prevents controller storms from starving kubelets.

  • API server: Validates requests against the OpenAPI schema, runs the admission chain, encodes objects to JSON or Protobuf, and reads or writes etcd. Optimistic concurrency for applicable updates uses resourceVersion
  • etcd: 5 member Raft cluster storing keys like /registry/pods/default/my-pod. Provides linearizable writes while watch streams propagate changes to the API server cache. Sensitive objects such as Secrets can be encrypted before persistence
  • Watch cache: In memory index per resource type that can serve cache eligible LIST and WATCH requests without hitting etcd on hot paths
  • List pagination: limit and continue token parameters are mandatory at scale by platform policy.resourceVersion=0 requests the "Any" consistency semantic for GET or LIST and can be served from the watch cache. A GET with no resourceVersion requests the most recent state, while LIST consistency depends on the resourceVersion and resourceVersionMatch combination. Clients must handle an expired continue token or stale watch resourceVersion by handling HTTP 410 Gone. For a stale watch, relist and then resume from the returned resourceVersion. For an expired paginated LIST token, follow the API server's 410 response semantics or restart the LIST when appropriate.
  • APF: Classifies requests into configured priority levels and flow schemas, with fair queuing preventing controller or batch traffic from starving latency sensitive requests

2. Scheduler (filter + score + bind)

Filter infeasible nodes, score the remainder, and bind with optimistic concurrency, recognizing that bin packing vs spread is an intentional tuning trade off.

  • Scheduling queue: ActiveQ for unscheduled pods, BackoffQ for failed attempts, and UnschedulableQ for pods that cannot currently be scheduled
  • Filtering plugins: NodeResourcesFit, NodeAffinity, TaintToleration, VolumeBinding, and InterPodAffinity to eliminate infeasible nodes
  • Scoring plugins: NodeResourcesBalancedAllocation, ImageLocality, and PodTopologySpread, where a weighted sum selects the best node
  • Bin packing vs utilization spreading: MostAllocated packs workloads tightly for cost savings, whereas LeastAllocated favors lower node utilization. High availability across failure domains comes from topology spread constraints and related placement rules, with scheduler plugin weights tuned per workload
  • Bind: Calls the Pod binding subresource to bind the Pod to the selected Node, with conflict handling when concurrent updates race with the decision

3. Controller Manager (reconciliation loops)

Deployment to ReplicaSet to Pod is the canonical reconciliation chain, driven by informers, workqueues, and rate limited backoff across every controller.

  • Deployment controller: Manages ReplicaSets, rolling updates (configured via maxSurge and maxUnavailable), and revision history
  • ReplicaSet controller: Maintains running pod counts matching the replicas specification
  • Node controller: Monitors node heartbeats and conditions. After the node monitor grace period it can mark an unreachable Node unhealthy and add taints. Taint based eviction and related controller behavior then determine when Pods are evicted according to tolerations, eviction settings, and rate controls
  • EndpointSlice controller: Maintains EndpointSlices from Service selectors and Pod state, including ready, serving, and terminating conditions
  • Reconciliation pattern: Informers maintain watch streams and local caches, queuing events into workqueues with rate limited backoff for level triggered reconciliation

4. kubelet + CNI Networking

The kubelet synchronizes desired and running state. During Pod sandbox creation, the container runtime invokes CNI ADD, and EndpointSlice conditions reflect Pod readiness, serving, and termination state.

  • Pod sync loop: Compares desired pods from the API server against running containers via CRI, creating, deleting, or updating state accordingly
  • CRI: containerd pulls images and instantiates container runtimes within pod cgroups
  • CNI: During Pod sandbox creation, the container runtime invokes CNI ADD so the plugin allocates an IP address and configures the network interfaces, with plugins such as Calico, Cilium, or AWS VPC CNI
  • Service proxying: kube-proxy programs Service ClusterIP routing rules using iptables, IPVS, or nftables. eBPF based service proxying can instead be provided by an alternative such as Cilium
  • DNS: CoreDNS uses Kubernetes Service and EndpointSlice state, plus related namespace and Pod state when configured for Pod records, to provide cluster DNS through the Service Discovery path
  • Probes: Evaluates liveness for container restarts, readiness for EndpointSlice membership, and startup probes for slow initializations

5. Admission Webhooks + RBAC

Mutating webhooks can inject defaults or sidecars, while validating webhooks and admission policies enforce security requirements. With failurePolicy set to Fail, a webhook communication error can reject matching API requests until the dependency recovers.

CREATE Pod request flow through admission:

1. Authentication (x509 client cert / OIDC bearer token)
2. Authorization (RBAC: can user create Pods in namespace?)
3. Mutating admission phase (matching mutating webhooks run serially):
   - inject sidecar (service mesh)
   - set default resources / labels
   - apply other configured mutations
4. API field and schema validation:
   - OpenAPI based field and schema validation
5. Validating admission phase (matching validating webhooks are called in parallel, where any rejection rejects the request):
   - PodSecurity admission for namespace security standards
   - OPA/Gatekeeper policy (no :latest tag, require limits)
   - image signature verification (cosign) as an example validating policy
   - other configured validating webhooks or admission policies
6. Persist through the API server into etcd
   - resourceVersion is used for optimistic concurrency on applicable updates, not for ordinary object creation
7. Return 201 to client

failurePolicy:
  - Fail: reject request on webhook error (secure, availability risk)
  - Ignore: proceed if webhook down (available, policy gap)

Timeout: Kubernetes allows 1 to 30 seconds. This scenario tunes webhooks to 2 to 5 seconds, with asynchronous audit for slow policy checks
YAML
# RBAC example: developer can deploy in namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: team-payments
  name: deployer
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "create", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: team-payments
subjects:
  - kind: User
    name: alice@corp.com
roleRef:
  kind: Role
  name: deployer
  apiGroup: rbac.authorization.k8s.io

6. Multi Tenant Isolation

Namespaces alone do not provide multi tenant isolation. ResourceQuota, LimitRange, NetworkPolicy, Pod Security Admission, and RBAC collectively define the tenant boundary.

Multi tenant isolation layers (shared cluster):

1. Namespace: logical boundary and name uniqueness per cluster
2. ResourceQuota: max pods, CPU, memory, PVCs per namespace
3. LimitRange: default, min, and max per-container resources
4. NetworkPolicy: L3/L4 rules. Create default deny ingress and egress policies, then add explicit allows
5. RBAC: Role and RoleBinding scoped to namespace
6. PodSecurityAdmission: restricted, baseline, and privileged levels
7. Node pools: dedicated nodes via taints (tenant=acme:NoSchedule). Admission policy should prevent tenants from selecting another tenant pool by granting arbitrary tolerations

Fleet level (1000 clusters):
  - One cluster per regulated tenant OR shared multi tenant with the controls above
  - Fleet RBAC maps each organization to its cluster list
  - Hub config sync for policy bundles across the fleet

7. Watch Fan Out at Scale

etcd delivers changes to the API server, which fans them out through its watch cache and watch path rather than sending updates directly to 15K clients. Bookmarks can reduce relist work on reconnect but are sent at server discretion.

Watch architecture at 500K pods / 15K subscribers:

API Server (per replica):
  - In memory watch cache (indexed by resource type + namespace)
  - Serves LIST from cache when resourceVersion within window
  - New watch: initialize from the API server watch cache when possible, then stream subsequent changes through the API server watch path

Subscriber breakdown (large cluster):
  - 10K kubelets (scenario count of logical watcher sources)
  - 2K controllers (Deployment, RS, Node, EndpointSlice, ...)
  - 2K operators (Prometheus, Istio, custom CRDs)
  - 1K kubectl and CI/CD platform long polls
  Note: one process can maintain multiple watch streams, so 15K is a scenario scale for logical watch streams, not a universal Kubernetes limit.

Reconnect storm mitigation:
  - Request resourceVersion bookmarks. A 5 min target is illustrative because bookmark delivery is not guaranteed at a fixed interval
  - APF: separate flow treatment for watch and mutating request traffic
  - Scenario quota: max 500 inflight watches per user identity

etcd does NOT fan out to 15K clients because the API server serves as the fan out hub

8. GKE Style Fleet Layer

One isolated control plane is dedicated to each customer cluster. The fleet Hub aggregates inventory and distributes policy bundles at scale.

  • Cluster provisioning: Cluster API or a proprietary operator provisions control plane and node pools per tenant
  • Fleet registration: Each cluster registers with the Hub, establishing a central inventory of 1,000 clusters
  • Policy at scale: Distributes Config Sync bundles (such as OPA and NetworkPolicy templates) across all clusters
  • Upgrades: Orchestrates surge upgrades while respecting the release-specific Kubernetes version skew policy. Control plane components normally match the kube-apiserver minor version and may be one minor version older. Kubelet and kube-proxy must not be newer than kube-apiserver and may be up to three minor versions older under the current policy. The exact supported range narrows when HA API servers themselves have version skew
  • Observability: Aggregates control plane SLIs across the fleet using Observability and Distributed Tracing, accompanied by per cluster etcd dashboards

API Design

Create Deployment

Kubernetes APIs are declarative. Clients submit desired state, and controllers converge actual state toward that specification. This section illustrates Deployment creation and paginated LIST requests using a continue token.

HTTP
POST /apis/apps/v1/namespaces/payments/deployments
Authorization: Bearer <oidc_token>
Content-Type: application/json

{
  "apiVersion": "apps/v1",
  "kind": "Deployment",
  "metadata": { "name": "checkout-api" },
  "spec": {
    "replicas": 50,
    "selector": { "matchLabels": { "app": "checkout" } },
    "template": {
      "metadata": { "labels": { "app": "checkout" } },
      "spec": {
        "containers": [{
          "name": "api",
          "image": "registry/checkout:v3.2.1",
          "resources": { "requests": { "cpu": "500m", "memory": "512Mi" } }
        }]
      }
    }
  }
}

Response: 201 Created
metadata.resourceVersion: "2847561"

List Pods (paginated)

HTTP
GET /api/v1/namespaces/payments/pods?limit=500&continue=<token>
Authorization: Bearer <token>

Response: 200 OK
{
  "items": [ ...500 pods... ],
  "metadata": {
    "resourceVersion": "2847561",
    "continue": "eyJ2IjoiMiIsImxhc3QiOi..."
  }
}

# Watch stream, starting from the LIST resourceVersion and requesting bookmarks:
GET /api/v1/namespaces/payments/pods?watch=true&resourceVersion=2847561&allowWatchBookmarks=true
-> stream of ADDED/MODIFIED/DELETED events with optional BOOKMARK progress events

# On supported releases, streaming lists can combine initial state and watch:
GET /api/v1/namespaces/payments/pods?watch=true&sendInitialEvents=true&allowWatchBookmarks=true&resourceVersion=&resourceVersionMatch=NotOlderThan
-> synthetic ADDED events, an initial BOOKMARK, then regular watch events

Admission Webhook Configuration

YAML
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: require-resource-limits
webhooks:
  - name: limits.policy.corp.com
    rules:
      - apiGroups: [""]
        apiVersions: ["v1"]
        operations: ["CREATE", "UPDATE"]
        resources: ["pods"]
    clientConfig:
      service:
        name: policy-webhook
        namespace: kube-system
        path: /validate
      caBundle: <BASE64_ENCODED_CA_BUNDLE>
    admissionReviewVersions: ["v1"]
    failurePolicy: Fail
    timeoutSeconds: 3
    sideEffects: None

ResourceQuota (multi tenant)

YAML
apiVersion: v1
kind: ResourceQuota
metadata:
  namespace: tenant-acme
spec:
  hard:
    pods: "200"
    requests.cpu: "100"
    requests.memory: 200Gi
    persistentvolumeclaims: "10"

Common Error Responses

400 Bad Request: invalid input, missing required fields, or malformed JSON payload
401 Unauthorized: missing or invalid authentication token or API key
403 Forbidden: authenticated caller lacks required permissions for this resource
404 Not Found: requested resource ID does not exist
409 Conflict: duplicate write or version conflict, retry with a unique idempotency key
422 Unprocessable Entity: syntactically valid request failed semantic business validation
429 Too Many Requests: rate limit quota exceeded, client should honor Retry-After header
500 Internal Error: unexpected server failure, retry safely with an idempotency key
503 Service Unavailable: downstream dependency is unavailable or overloaded, retry with exponential backoff
422 Unprocessable Entity: password does not meet security requirements or MFA verification is required
423 Locked: account temporarily locked after repeated failed login attempts

Data Model

etcd Key Layout (simplified)

/registry/pods/{namespace}/{name}           -> Pod spec + status
/registry/deployments/{namespace}/{name}    -> Deployment
/registry/nodes/{name}                      -> Node
/registry/rolebindings/{namespace}/{name}   -> RBAC bindings

Each value: serialized API object, typically using protobuf for storage
metadata.resourceVersion -> storage revision used for optimistic concurrency
metadata.uid            -> globally unique identifier

Core Object Relationships

Deployment (desired: replicas=50, template)
    └── ReplicaSet (hash abc123, replicas=50)
            └── Pod x 50 (nodeName, phase, conditions)
                    └── bound to Node (allocatable CPU/mem)
                            └── kubelet reports status

Service (selector: app=checkout)
    └── EndpointSlice (IP:port endpoints from ready pods)
            └── kube-proxy + CoreDNS (Service Discovery)

Lease Objects (coordination)

coordination.k8s.io/v1 Lease:
  - kube-scheduler leader election (Replication and Leader Election)
  - kube-controller manager leader election
  - Cloud controller manager HA
  - Custom operator leader election

Holder identity + renewTime + leaseDurationSeconds
Only leader runs active reconciliation to avoid duplicate work

Fleet Registry (managed service metadata)

SQL
CREATE TABLE clusters (
    cluster_id      UUID PRIMARY KEY,
    tenant_id       UUID NOT NULL,
    region          VARCHAR(32) NOT NULL,
    k8s_version     VARCHAR(16) NOT NULL,
    endpoint        VARCHAR(512) NOT NULL,   -- API server URL
    status          VARCHAR(16) NOT NULL,  -- provisioning, running, upgrading, failed
    node_count      INT DEFAULT 0,
    pod_count       INT DEFAULT 0,
    etcd_backup_ref VARCHAR(512),
    created_at      TIMESTAMPTZ NOT NULL,
    upgraded_at     TIMESTAMPTZ
);

CREATE INDEX idx_clusters_tenant ON clusters(tenant_id);
CREATE INDEX idx_clusters_region ON clusters(region, status);

Fault Tolerance

Fault Tolerance Scenarios

ConcernSolution
etcd quorum loss during AZ failureRun 5 member etcd across 3 AZs (2+2+1). Raft requires majority (3/5). Take automated snapshots every 15 min to object storage and target RPO < 15 min when snapshot upload completes within that interval. Use a restore runbook and verify recovered cluster state. Leader election ensures only one leader serves writes while followers catch up via the Raft log
API server overload from unpaginated LISTEnforce list pagination (limit=500 default, continue token). APF (API Priority and Fairness) queues requests by flow schema. The API server watch cache reduces etcd reads for cache eligible LIST and WATCH requests. Alert on unpaginated LIST requests or responses returning > 10K objects
Watch fan out storm after control plane restartRequest watch bookmarks and use the returned resourceVersion to reduce relist work on reconnect. A 5 min target is illustrative because bookmark delivery is not guaranteed at a fixed interval. Stagger controller resync with jitter when resync is configured. Limit concurrent watches per client identity. Horizontal API server replicas behind an L4 load balancer
Scheduler hotspot where all pods land on few nodesEnable PodTopologySpread + NodeResourcesFit. Balance MostAllocated (bin pack) vs LeastAllocated (spread) through scoring weights. Use Pod anti affinity for critical services. Monitor node utilization variance and alert if σ > 20%
Admission webhook timeout blocks all createsUse a 5s scenario timeout target. Kubernetes allows an admission webhook timeout from 1 to 30 seconds. Set failurePolicy=Ignore for non critical mutating hooks where policy risk is acceptable. Run webhooks HA with 3 replicas. Use asynchronous validation for expensive checks such as an OPA sidecar cache. If an external circuit breaker disables the webhook after a 50% failure rate, treat that as a platform runbook decision rather than native admission behavior
Tenant A Pod schedules on a tenant B NodeNamespace isolation + ResourceQuota + LimitRange. Use Node taints and tolerations for tenant pools, with admission policy restricting arbitrary tolerations. Create default deny NetworkPolicies and add explicit allows for required traffic. Use RBAC to grant tenant service accounts access only to intended namespaces. Optional: virtual clusters (vcluster) or dedicated node pools
Controller reconciliation storm after etcd restoreLevel triggered controllers re queue with rate limiting through the workqueue. Use exponential backoff on errors. Disable automatic synchronization during restore, then stage controllers according to the restore runbook, starting with foundational controllers before dependent controllers. Verify that watches can relist and controllers converge after restore

Additional Considerations

Cross Links

  • Service Discovery: Cluster DNS (CoreDNS) and EndpointSlices provide in cluster discovery, while kube-proxy routes Service VIPs. External discovery integrates via Ingress or an API Gateway.
  • CI/CD Platform: Deploy pipelines call the API server through kubectl apply, Helm, or GitOps controllers. The control plane must handle burst admission during rolling deployments, using ResourceQuota and APF to isolate CI tenants.
  • API Gateway: North-south traffic enters via Ingress and Gateway API, while the control plane manages GatewayClass and HTTPRoute CRDs, distinct from internal Service routing.
  • Replication, Failover, and Leader Election: Scheduler and controller manager use Lease-based leader election so that only one active instance mutates shared state.
  • Observability and Distributed Tracing: Export apiserver_request_duration, etcd_disk_wal_fsync_duration, and scheduler_scheduling_duration histograms, and trace admission webhook latency.

Custom Resources (CRDs) at Scale

Each CRD instance adds API objects to etcd and can increase memory pressure in informer caches. At 500K pods, adding 500K custom objects can substantially increase control plane memory, but the exact impact depends on object size, watch fan out, and cache scope. Guidelines include pruning status updates, using the status subresource intentionally, setting spec.versions[*].schema for validation, and avoiding high churn CRDs watched by multiple controllers.

Node Lifecycle: Cordon, Drain, Upgrade

kubectl cordon marks a node unschedulable, and drain evicts pods respecting PodDisruptionBudgets. Managed node pools roll OS and kubelet upgrades by replacing nodes as managed by the CI/CD Platform, requiring the control plane to handle burst rescheduling through adequate scheduler queue depth and pre scaled spare capacity.

Interview Walkthrough

  • 25-minute interview progression

    Skip deep fleet federation internals unless the interview is for a staff or principal role.

    • API server, etcd, controllers, scheduler, and kubelet architecture overview (5 min)
    • State etcd storage limits early, covering 2 GB default quota, pagination requirements, and watch cache caching (6 min)
    • Explain level triggered reconciliation with a step by step Deployment rollout example (5 min)
    • Scheduler pipeline: filter infeasible nodes, score remainder, and bind with bin packing vs spread trade offs (5 min)
    • Multi tenant isolation: namespace, ResourceQuota, NetworkPolicy, and RBAC governance (4 min)
  • Draw the core control plane pipeline first: API server and etcd at the center, controllers and scheduler on the left, and node kubelets on the right.
  • State etcd limits early, emphasizing the 2 GB default quota, mandatory list pagination with continue tokens, and the essential role of the API server watch cache.
  • Explain level triggered reconciliation using a Deployment to ReplicaSet to Pod rollout example.
  • Walk through the scheduler pipeline from filtering infeasible nodes to scoring and binding, highlighting the operational trade offs between bin packing and high availability spread.
  • Detail multi tenant isolation by combining namespaces, ResourceQuotas, NetworkPolicies, and RBAC rather than relying on namespaces alone.
  • Frame GKE style architecture as a fleet of 1,000 isolated per cluster control planes, avoiding a monolithic shared etcd across the fleet.
  • Avoid the common pitfall of treating the API server as stateless without understanding watch cache hydration and tight etcd coupling.

Engineering Trade-offs

Single Mega Cluster vs Multi Cluster Fleet

One 500K pod cluster maximizes resource utilization but concentrates blast radius, because etcd and API server limits cap scale. A GKE style fleet of 1,000 clusters isolates tenants and failure domains, though operational management scales with cluster count. Regulated tenants receive dedicated clusters, whereas cost-sensitive tenants share multi tenant clusters governed by namespace isolation.

Bin Packing vs Spread Scheduling

Bin packing (MostAllocated) reduces node count and cloud infrastructure costs but sacrifices burst headroom and increases noisy-neighbor risk. In contrast, PodTopologySpread improves placement across failure domains, while LeastAllocated favors lower node utilization. Together with other placement constraints, these choices can improve resilience while consuming more capacity. Production platforms typically adopt a hybrid approach where critical system daemons spread across failure domains and batch compute workloads bin pack tightly.

Admission webhook failurePolicy: Fail vs Ignore

The Fail policy enforces security and governance strictly, meaning a webhook outage can halt requests handled by that webhook and create an availability incident. Conversely, the Ignore policy keeps the cluster operating during webhook outages but risks admitting non compliant resources. The recommended practice sets Fail for security critical validating webhooks and Ignore for non essential mutating defaults, while deploying webhooks in high availability multi replica topologies with strict 2 to 5 second timeout targets.

etcd Strong Consistency vs Controller Eventual Consistency

etcd guarantees linearizable writes, but asynchronous controllers observe state changes via watch streams with minor latency skew. Designing control systems that assume instant global consistency leads to race conditions. Robust controllers rely on resourceVersion checks, optimistic concurrency, and level triggered reconciliation loops rather than one shot edge triggered event handlers, incorporating Saga and Outbox Patterns when coordinating operations across clusters.

Shared etcd vs etcd per Cluster (Fleet)

In this managed service design, keep etcd scoped to each customer cluster rather than sharing one etcd quorum across the fleet, because quorum degradation or a storage incident would otherwise expand the blast radius across tenants. Dedicated per cluster etcd instances are the standard topology for isolated Kubernetes control planes. While running five etcd nodes per cluster across 1,000 clusters incurs substantial infrastructure overhead, operators can right size smaller clusters to three member quorums when their failure domains and availability requirements permit it. The node count threshold is a scenario planning choice, not a Kubernetes requirement.

Host Project Network (VPC native) vs Overlay CNI

VPC native networking such as AWS VPC CNI or GCP alias IPs assigns pods directly routable VPC IP addresses, which can improve packet performance at the expense of IP address consumption within subnet pools. Conversely, overlay networks such as VXLAN or Geneve decouple pod addressing from VPC subnet capacity but introduce packet encapsulation overhead and possible latency. While the Kubernetes control plane remains agnostic to this distinction, the CNI selection heavily influences subnet capacity planning and NetworkPolicy enforcement efficiency.

💬Review

Help Us Improve

How helpful was this walkthrough?

Click a star to rate. We actively use this feedback to refine and update our system design content.

Placeholder
Optional but highly appreciated!

Discussion

Share your thoughts, ask questions, or help others.

Loading comments...