Control Plane Components

The control plane is the “brain” of Kubernetes—it makes all the decisions about the cluster, maintains the desired state, and coordinates all activities. Understanding the control plane components is crucial because they determine how Kubernetes behaves, how it stores information, and how it responds to changes.

Think of the control plane like the management team of a company. The API server is like the front desk—everyone goes through it. etcd is like the filing cabinet—all important information is stored there. The scheduler is like HR—it decides who works where. The controller manager is like operations—it ensures everything runs according to plan.

Control Plane Overview

The Kubernetes control plane consists of four main components that work together:

graph TB User[Users/kubectl] --> API[API Server] API --> etcd[etcd] API --> Scheduler[Scheduler] API --> CM[Controller Manager] Scheduler --> API CM --> API etcd --> API API --> Kubelet[Kubelet<br/>on Nodes] style API fill:#e1f5ff style etcd fill:#fff4e1 style Scheduler fill:#fff4e1 style CM fill:#fff4e1

All components communicate through the API server. This design ensures:

  • Single source of truth - etcd is the only place state is stored
  • Centralized validation - All requests go through the API server
  • Loose coupling - Components don’t directly communicate with each other
  • Extensibility - New components can be added by watching the API

API Server

The API server (kube-apiserver) is the front end of the Kubernetes control plane. It’s the only component that directly communicates with etcd and is the central hub for all cluster communication.

Role and Responsibilities

The API server is responsible for:

  • Exposing the Kubernetes API - All interactions with Kubernetes go through the API server
  • Request validation - Ensures requests are valid before processing
  • Authentication - Verifies who is making the request
  • Authorization - Determines if the requester has permission
  • Admission control - Applies policies and defaults (mutating and validating webhooks)
  • API versioning - Handles different API versions and conversions
  • etcd interaction - All reads and writes to etcd go through the API server

How It Works

When you run kubectl get pods, here’s what happens:

  1. kubectl sends HTTP request to API server
  2. API server authenticates the request (checks certificates/tokens)
  3. API server authorizes the request (checks RBAC policies)
  4. API server reads from etcd
  5. API server returns the response to kubectl

The API server never directly exposes etcd—it’s the only component that talks to etcd, providing a layer of abstraction and security.

API Server Features

RESTful API - Kubernetes API is RESTful, meaning you can use standard HTTP methods:

  • GET - Retrieve resources
  • POST - Create resources
  • PUT - Update resources
  • DELETE - Delete resources
  • PATCH - Partial updates

Watch API - Components can watch for changes:

# Watch for pod changes
kubectl get pods --watch

API Versioning - Supports multiple API versions simultaneously:

  • /api/v1 - Core API group
  • /apis/apps/v1 - Apps API group
  • /apis/networking.k8s.io/v1 - Networking API group

OpenAPI Specification - Exposes OpenAPI schema for API discovery and client generation.

etcd

etcd is a distributed, consistent key-value store that serves as Kubernetes’ backing store. It’s the “memory” of Kubernetes—everything the cluster knows is stored here.

Role and Responsibilities

etcd stores:

  • All cluster state - Pods, services, deployments, nodes, etc.
  • Configuration - Cluster configuration, secrets, configmaps
  • Metadata - Labels, annotations, resource versions
  • Status - Current state of all resources

Why etcd?

Kubernetes chose etcd because it provides:

  • Consistency - Strong consistency guarantees (CAP theorem: CP system)
  • Reliability - Distributed and fault-tolerant
  • Watch support - Efficient change notifications
  • Performance - Fast reads and writes
  • Simplicity - Simple key-value interface

etcd in Kubernetes

etcd stores data in a hierarchical structure:

/registry/pods/default/my-pod
/registry/services/default/my-service
/registry/nodes/node-1

Each resource is stored as a JSON document with its complete specification and status.

etcd Operations

Reads - API server reads from etcd to serve GET requests Writes - API server writes to etcd when resources are created/updated Watches - Components watch etcd (through API server) for changes

etcd Clustering

For production, etcd runs as a cluster (typically 3 or 5 nodes) for:

  • High availability - Survives node failures
  • Consistency - Maintains quorum for writes
  • Performance - Distributes load

Scheduler

The scheduler (kube-scheduler) watches for newly created pods with no assigned node and selects a node for them to run on.

Role and Responsibilities

The scheduler is responsible for:

  • Pod placement - Deciding which node should run each pod
  • Resource evaluation - Checking node resources and capacity
  • Constraint checking - Evaluating affinity, anti-affinity, taints, tolerations
  • Policy enforcement - Applying scheduling policies and priorities

How Scheduling Works

The scheduler uses a two-phase approach:

Filtering - Filters out nodes that can’t run the pod:

  • Insufficient resources (CPU, memory)
  • Node selectors don’t match
  • Taints without matching tolerations
  • Pod anti-affinity rules violated

Scoring - Scores remaining nodes and selects the best one:

  • Resource availability (prefer nodes with more resources)
  • Affinity preferences (prefer nodes matching affinity rules)
  • Load balancing (spread pods across nodes)
  • Custom policies

Scheduler Example

When a pod is created:

  1. Pod is created with nodeName empty
  2. Scheduler watches for pods with empty nodeName
  3. Scheduler filters nodes (removes unsuitable ones)
  4. Scheduler scores remaining nodes
  5. Scheduler selects best node and updates pod with nodeName
  6. Kubelet on that node sees the assignment and creates the container

Scheduler Extensibility

The scheduler can be extended with:

  • Scheduler plugins - Custom filtering and scoring logic
  • Scheduler profiles - Different scheduling strategies
  • Custom schedulers - Alternative schedulers for specific use cases

Controller Manager

The controller manager (kube-controller-manager) runs controllers that watch the cluster state and make changes to move the current state toward the desired state.

Role and Responsibilities

The controller manager runs built-in controllers:

  • Deployment controller - Maintains desired number of replicas
  • ReplicaSet controller - Creates/deletes pods to match replica count
  • StatefulSet controller - Manages stateful workloads
  • DaemonSet controller - Ensures pods run on all/some nodes
  • Job controller - Manages job completion
  • Namespace controller - Handles namespace lifecycle
  • Node controller - Monitors node health
  • Service controller - Manages cloud load balancers
  • Endpoint controller - Populates Service endpoints
  • And more…

Controller Pattern

All controllers follow the same pattern:

graph LR A[Watch API] --> B[Compare State] B --> C{Match?} C -->|No| D[Take Action] C -->|Yes| A D --> A style A fill:#e1f5ff style B fill:#fff4e1 style C fill:#e8f5e9 style D fill:#ffe1e1
  1. Watch - Controller watches for changes to relevant resources
  2. Compare - Compares desired state (spec) with current state (status)
  3. Reconcile - Takes action to make current state match desired state
  4. Repeat - Continuously watches and reconciles

Example: Deployment Controller

When you create a Deployment:

  1. Deployment created with replicas: 3
  2. Deployment controller watches for Deployment changes
  3. Controller creates ReplicaSet with 3 replicas
  4. ReplicaSet controller watches for ReplicaSet changes
  5. Controller creates 3 Pods
  6. If a pod fails, controller creates a new one to maintain 3 replicas

This is the self-healing capability of Kubernetes—controllers continuously work to maintain desired state.

Leader Election

In high-availability setups, multiple controller managers run, but only one is active at a time (leader election). This ensures:

  • No duplicate actions
  • High availability (if leader fails, another takes over)
  • Consistent behavior

Component Interaction

Here’s how components work together to create a pod:

sequenceDiagram participant User participant API as API Server participant etcd participant Scheduler participant CM as Controller Manager participant Kubelet User->>API: Create Pod API->>etcd: Store Pod Spec API-->>Scheduler: Watch detects unscheduled pod Scheduler->>API: Bind Pod to Node API->>etcd: Update Pod with nodeName API-->>Kubelet: Watch detects pod assignment Kubelet->>API: Update Pod Status API->>etcd: Store Pod Status
  1. User creates pod - Sends request to API server
  2. API server validates - Checks request and stores in etcd
  3. Scheduler watches - Detects pod with no node assignment
  4. Scheduler assigns - Selects node and updates pod via API server
  5. API server updates etcd - Stores node assignment
  6. Kubelet watches - Detects pod assigned to its node
  7. Kubelet creates container - Starts the container
  8. Kubelet reports status - Updates pod status via API server
  9. API server updates etcd - Stores pod status

High Availability

For production clusters, control plane components should be highly available:

  • Multiple API servers - Behind a load balancer, all can serve requests
  • etcd cluster - Typically 3 or 5 nodes for quorum
  • Multiple schedulers - Leader election ensures only one active
  • Multiple controller managers - Leader election ensures only one active

This ensures the cluster continues operating even if individual components fail.

Key Takeaways

  • API server is the central hub—all communication goes through it
  • etcd is the single source of truth—all state is stored there
  • Scheduler assigns pods to nodes based on resources and constraints
  • Controller manager runs controllers that maintain desired state
  • Components use watch patterns for efficient change notification
  • All components communicate through the API server, not directly with each other
  • High availability requires multiple instances of each component

See Also