Skip to main content

EKS Control Plane Deep Dive — Comprehensive Guide to CRD at Scale

📅 Created: 2026-03-24 | ⏱️ Reading time: ~25 min

When operating CRD (Custom Resource Definition) based platforms on EKS, the Control Plane becomes the first bottleneck. This guide provides practical strategies for understanding how the Control Plane operates, identifying the specific impact of CRDs, and proactively responding through Provisioned Control Plane (PCP) and monitoring.


Table of Contents

  1. EKS Control Plane Internal Architecture
  2. Automatic Scaling — VAS
  3. EKS Provisioned Control Plane (PCP)
  4. Impact of CRDs on Control Plane
  5. EKS Control Plane Monitoring
  6. CRD Design Best Practices
  7. Comprehensive Recommendations & Adoption Roadmap

1. EKS Control Plane Internal Architecture

1.1 Physical Infrastructure Structure

The EKS Control Plane runs in a dedicated VPC managed by AWS. It is independent infrastructure separated from customer worker nodes.

EKS Control Plane (AWS Managed)
├── Control Plane Instances (CPI): 2~6 instances (distributed across AZs)
│ ├── kube-apiserver
│ ├── kube-controller-manager
│ ├── kube-scheduler
│ └── etcd (runs on same instance as API Server)
├── Network Load Balancer: 1 instance (API Server endpoint)
└── Route53 Records

Key points:

  • Control Plane instances are distributed across 3 AZs to ensure high availability
  • etcd runs colocated on the same instance as the API Server
  • A single API Server endpoint is exposed to customers through an NLB

1.2 etcd — The Heart of the Control Plane

etcd is a distributed key-value store that stores all Kubernetes state (Pods, Services, CRD objects, etc.). Why it becomes the critical bottleneck for Control Plane performance:

CharacteristicDescriptionCRD Impact
DB Size LimitStandard tier 10GB, XL and above 20GBMore CRD objects increase DB size
Request Size LimitMax 1.5MB per single objectLarge specs in CRs can approach the limit
Watch StreamReal-time propagation of changesMore CRD controllers adding Watches increase load
RAFT ConsensusMajority consensus required for writesLatency occurs with write-heavy CRD patterns
etcd Architecture Evolution

AWS is working on replacing etcd's consensus layer with an internal service called Journal. This is expected to deliver predictable performance (consistent latency), zero data loss guarantee, and enhanced availability.


2. Automatic Scaling — VAS

2.1 VAS Operation Principles

EKS automatically vertically scales Control Plane instances through VAS (Vertical Autoscaling Service). VAS evaluates the following metrics in 3-minute cycles:

Signal SourceMetricDescription
EC2 InternalCPU UtilizationControl Plane instance CPU
EC2 InternalMemory UtilizationControl Plane instance memory
K8s MetricsInflight RequestsAPI Server concurrent request count
K8s MetricsScheduler QPSPod scheduling throughput
K8s Metricsetcd DB Sizeetcd database size
Data PlaneWorker Node CountProactive scale-up based on node count

2.2 Scaling Policies

  • Scale Up: Immediate scale-up when CPU/Memory exceeds 80% or K8s metric watermarks are exceeded
  • Scale Down: CPU/Memory below 30% → 1-hour cooldown before scale-down in Standard mode (conservative)

2.3 Instance Bundle Ladder

VAS scales instances following this ladder:

2 vCPU → 4 vCPU → 8 vCPU → 16 vCPU → 32 vCPU → 64 vCPU → 96 vCPU

Standard tier maximum

Most clusters start at 2 vCPU and automatically scale up based on load.

2.4 Detailed Parameters by Bundle

BundleMax ObjectsInflight/MutatingWatch Cacheetcd DB
2cpu x 21,20050/10020/3010GB
4cpu x 21,60054-65/10040/4010GB
8cpu x 22,00062-79/10060/6010GB
16cpu x 22,40078-108/108100/10010GB
32cpu x 23,100100-167/167180/18010GB
64cpu x 23,800100-283/283340/34010GB
96cpu x 24,500100-400/400500/50010GB
96cpu x 36,750400/400500/50010GB
96cpu x 613,500400/400500/50010GB

VAS automatically adjusts --max-requests-inflight, --max-mutating-requests-inflight, --default-watch-cache-size, --kube-api-qps/burst etc. per bundle.

Key Insight

In Standard tier, etcd DB Size is always fixed at 10GB. In platforms with many CRD objects, this limit becomes the first bottleneck. No matter how much VAS scales up CPU/Memory, etcd capacity does not increase.


3. EKS Provisioned Control Plane (PCP)

3.1 Overview

EKS Provisioned Control Plane (PCP) was released as GA at re:Invent 2025. It allows customers to directly select the Control Plane scaling tier (T-Shirt Size) to set a performance floor.

Previously, you could only rely on VAS automatic scaling, but with PCP you can proactively secure a minimum guaranteed performance level.

3.2 Two Operating Modes

ModeDescription
Standard (Dynamic mode)Same as before. VAS automatically scales within 2 vCPU ~ 32 vCPU range. 1-hour scale-down cooldown
Provisioned (Provisioning mode)Customer selects desired tier among XL/2XL/4XL/8XL. VAS never scales down below that tier. Can automatically scale up above tier if needed

3.3 Tier Specifications and Pricing

TierMax ObjectsInflightWatch Cacheetcd DBSLAHourly PriceCPI Configuration
Standard1,200 ~ 3,10050 ~ 10020 ~ 18010GB99.95%$0.102 x 2~32 vCPU
XL~3,800~283~34020GB99.99%$1.752 x 64 vCPU
2XL~4,500~400~50020GB99.99%$3.502 x 96 vCPU
4XL~6,750~400~50020GB99.99%$7.003 x 96 vCPU
8XL~13,500~400~50020GB99.99%$14.006 x 96 vCPU

3.4 PCP Core Design Principles

  1. Avoid scale-ups caused by internal resources (CPU/Memory) invisible to customers — Scaling should first be triggered by K8s metrics (inflight requests, scheduler QPS, etcd DB size) that are billing criteria
  2. Availability > Price — Both customers and EKS prioritize availability over cost
  3. Standard tier guarantees at least upstream K8s default values

3.5 Features Available Only in XL and Above Tiers

FeatureStandardXL and Above
API Server horizontal scaling (2+ instances)2 instance limitPossible (4XL: 3 instances, 8XL: 6 instances)
etcd DB Size 20GB10GB fixed20GB
etcd Event ShardingNot availableAvailable (separates event objects into separate etcd partition)
99.99% SLA99.95%99.99%
Why XL and Above is Recommended for CRD Platforms

The first limit reached in CRD-based platforms is etcd DB Size. The 10GB limit in Standard tier is quickly exhausted in environments with many CRD objects. XL and above expand to 20GB (2x), and can also separate event object load through Event Sharding.

3.6 CLI/API Usage

Specify tier when creating cluster:

aws eks create-cluster --name prod \
--role-arn arn:aws:iam::012345678910:role/eks-service-role \
--resources-vpc-config subnetIds=subnet-xxx,securityGroupIds=sg-xxx \
--control-plane-scaling-config tier=XL

Change tier for existing cluster:

aws eks update-cluster-config --name example \
--control-plane-scaling-config tier=XL

Check update progress:

aws eks describe-update --name example --update-id <update-id>
# Response: { "update": { "type": "ScalingTierConfigUpdate", "status": "Successful" } }

Check cluster information:

aws eks describe-cluster --name example
# Response includes controlPlaneScalingConfig.tier field
AttributeDescription
controlPlaneScalingConfig.tierCurrently provisioned tier (Standard/XL/2XL/4XL/8XL)
Control Plane Scaling Tier - Provisioned (CPSTP)Tier provisioned by customer through PCP feature
Control Plane Scaling Tier - Consumed (CPSTC)Current actual Control Plane tier (reached by automatic scaling or PCP)

4. Impact of CRDs on Control Plane

When operating CRD-based platforms, you must accurately understand the impact on the Control Plane. The impact is divided into two main axes: etcd and API Server.

4.1 Impact on etcd (Most Important)

Impact FactorMechanismImpact Level
DB Size GrowthCRD objects occupy etcd storageHigh
Watch Stream LoadCRD controllers create Watch streams increasing etcd gRPC loadHigh
Request SizeIndividual CRD objects can approach 1.5MB limitMedium
List Call CostCRDs use JSON encoding (not protobuf) → performance bottleneckHigh

etcd DB Size Limits (by PCP tier):

TierDB Size LimitSingle Object Limit
Standard10GB (20GB EBS)1.5MB (unchangeable)
XL and Above20GB1.5MB (unchangeable)

4.2 Impact on API Server

CRD-related API Server performance issues:

  1. JSON vs Protobuf: CRDs use JSON serialization, so List/Watch performance is significantly degraded compared to built-in resources
  2. APF (API Priority and Fairness): List requests can occupy up to 10 seats by the Work Estimator, quickly reaching inflight request limits
  3. Watch Cache: CRD Watch Cache capacity defaults to 100, same as built-in resources

4.3 Symptom-to-Cause Mapping

Mapping symptoms and their causes in actual production environments:

CRD Load Formula

Control Plane Load = Number of CRD Types x Object Size x Controller Pattern (List/Watch frequency)

You must manage all three factors. Even with few CRD types, the same problem occurs if objects are large or controllers are inefficient.


5. EKS Control Plane Monitoring

EKS provides 4 dimensions of Observability for the Control Plane:

┌─────────────────────────────────────────────────────────────────────┐
│ EKS Control Plane Observability │
├──────────────────┬──────────────────┬────────────────┬──────────────┤
│ ① CloudWatch │ ② Prometheus │ ③ Control │ ④ Cluster │
│ Vended Metrics│ Metrics │ Plane │ Insights │
│ │ Endpoint │ Logging │ │
├──────────────────┼──────────────────┼────────────────┼──────────────┤
│ AWS/EKS namespace│ KCM/KSH/etcd │ API/Audit/ │ Upgrade │
│ (automatic, free)│ (Prometheus │ Auth/CM/Sched │ Readiness │
│ │ compatible │ (CloudWatch │ Health Issues│
│ │ K8s API) │ Logs) │ Addon Compat │
├──────────────────┼──────────────────┼────────────────┼──────────────┤
│ v1.28+ automatic │ v1.28+ manual │ All versions │ All versions │
│ │ configuration │ │ automatic │
└──────────────────┴──────────────────┴────────────────┴──────────────┘

5.1 CloudWatch Vended Metrics (Automatic, Free)

For K8s 1.28+ clusters, core Control Plane metrics are automatically published to the CloudWatch AWS/EKS namespace at no additional cost.

Key Vended Metrics:

ComponentMetricDescriptionPriority
API Serverapiserver_request_totalTotal API requestsRequired
API Serverapiserver_request_total_4xx4xx error requestsRequired
API Serverapiserver_request_total_5xx5xx error requestsRequired
API Serverapiserver_request_total_429429 Throttling requestsRequired
API Serverapiserver_request_duration_secondsAPI request latencyRecommended
API Serverapiserver_storage_size_bytesetcd storage size (before defrag)Required
Schedulerscheduler_schedule_attempts_totalTotal scheduling attemptsRecommended
Schedulerscheduler_schedule_attempts_SCHEDULEDSuccessful scheduling countRequired
Schedulerscheduler_schedule_attempts_UNSCHEDULABLEUnschedulable countRecommended

PCP-Exclusive Additional Metrics:

MetricDescriptionUsage
apiserver_flowcontrol_current_executing_seats_totalAPI Server current concurrent execution seatsMonitor API Request Concurrency against tier limit
etcd_mvcc_db_total_size_in_use_in_bytesetcd DB actual usage sizeMonitor Cluster Database Size against tier limit
apiserver_storage_size_bytesStorage size before defragAlternative etcd DB size metric

5.2 Prometheus-Compatible Metrics Endpoint

You can scrape not only API Server metrics but also KCM (Kube-Controller-Manager), KSH (Kube-Scheduler), and etcd metrics.

Metrics Endpoint Paths:

# API Server metrics (existing)
kubectl get --raw=/metrics

# Kube-Controller-Manager metrics
kubectl get --raw=/apis/metrics.eks.amazonaws.com/v1/kcm/container/metrics

# Kube-Scheduler metrics
kubectl get --raw=/apis/metrics.eks.amazonaws.com/v1/ksh/container/metrics

# etcd metrics
kubectl get --raw=/apis/metrics.eks.amazonaws.com/v1/etcd/container/metrics

Prometheus Scraping Configuration Example:

scrape_configs:
- job_name: 'kcm-metrics'
honor_labels: true
kubernetes_sd_configs:
- role: endpoints
scheme: https
metrics_path: /apis/metrics.eks.amazonaws.com/v1/kcm/container/metrics
tls_config:
ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
relabel_configs:
- source_labels:
[__meta_kubernetes_namespace, __meta_kubernetes_service_name,
__meta_kubernetes_endpoint_port_name]
action: keep
regex: default;kubernetes;https

Required RBAC Permissions:

rules:
- apiGroups: ["metrics.eks.amazonaws.com"]
resources: ["kcm/metrics", "ksh/metrics", "etcd/metrics"]
verbs: ["get"]

KCM/KSH Metrics Particularly Useful for CRD Operations:

MetricSourceDescription
workqueue_depthKCMWork queue depth per controller — check CRD controller load
workqueue_adds_totalKCMTotal items added to queue
workqueue_retries_totalKCMRetry count — identify CRD controller error rate
scheduler_pending_podsKSHNumber of pending Pods
scheduler_scheduling_duration_secondsKSHScheduling latency
apiserver_flowcontrol_current_executing_seatsAPI ServerCurrent execution seats per APF — check CRD List request impact

Amazon Managed Prometheus (AMP) Integration:

Using EKS's Agentless Collector (Poseidon), you can automatically collect Control Plane metrics to an AMP workspace without installing Prometheus in the cluster.

EKS Console → Observability tab → Add scraper → Select AMP Workspace

5.3 Control Plane Logging

EKS can export 5 types of Control Plane logs to CloudWatch Logs:

Log TypeDescriptionCRD Use Case
API Server (api)API request/response logsAnalyze CRD API call patterns
Audit (audit)Audit logs of who did whatTrack CRD changes, security audit
AuthenticatorIAM authentication logsDebug authentication issues
Controller ManagerKCM diagnostic logsAnalyze CRD controller errors
SchedulerScheduler decision logsAnalyze Pod scheduling issues

Activation Method:

aws eks update-cluster-config --name my-cluster \
--logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'

CloudWatch Logs Insights Query Example — Analyze CRD-related API Call Patterns:

-- Analyze CRD-related API call patterns
fields @timestamp, userAgent, verb, requestURI
| filter requestURI like /customresourcedefinitions/
| stats count(*) by verb, userAgent
| sort count(*) desc
| limit 20

5.4 Cluster Insights

EKS Cluster Insights automatically scans clusters to detect potential issues and provide recommendations:

CategoryDescriptionFrequency
Upgrade InsightsDetect items that may cause issues during K8s version upgrade24 hours + manual
Configuration InsightsDetect cluster configuration errors24 hours + manual
Addon CompatibilityCheck if EKS Addons are compatible with next K8s version24 hours
Cluster Health IssuesCurrent cluster health status issues24 hours
aws eks list-insights --cluster-name my-cluster
aws eks describe-insight --cluster-name my-cluster --id <insight-id>

5.5 EKS Console Observability Dashboard

The EKS Console includes an integrated Observability Dashboard:

EKS Console → Select Cluster → Observability tab
├── Health and Performance Summary (summary cards)
├── Cluster Health Issues (health issue list)
├── Control Plane Monitoring
│ ├── Metrics (CloudWatch-based graphs)
│ │ ├── API Server Request Types (Total, 4XX, 5XX, 429)
│ │ ├── etcd Database Size
│ │ └── Kube-Scheduler Scheduling Attempts
│ ├── CloudWatch Log Insights (predefined queries)
│ └── Control Plane Logs (CloudWatch links)
└── Upgrade Insights (upgrade readiness status)

5.6 Monitoring Channel Comparison Table

ChannelCostSetupData TypePCP Support
CloudWatch Vended MetricsFree (AWS/EKS)Automatic (v1.28+)Core K8s metrics (time series)Includes tier usage metrics
Prometheus EndpointFree (scraping)Manual configuration requiredDetailed KCM/KSH/etcd metricsExtensible
Control Plane LoggingCloudWatch standard pricingManual activationLogs (API/Audit/Auth/CM/Sched)
Cluster InsightsFreeAutomaticCluster health/upgrade recommendationsPCP tier recommendations (future)
EKS Console DashboardFreeAutomaticVisualized metrics + log queriesDisplays tier information

6. CRD Design Best Practices

6.1 Minimize Object Size

  • Keep each CR instance's spec size as small as possible (etcd 1.5MB request limit)
  • Separate large data into ConfigMap or external storage references
  • Include only necessary information in status field — move history or log-type data externally

6.2 Manage Number of CRDs

  • More CRD types proportionally increase API Server Watch Cache and etcd Watch Stream
  • When possible, consolidate similar resources into a single CRD (leverage subresource patterns)
  • Always clean up unused CRDs

6.3 Controller Optimization

PatternCorrect UsageUsage to Avoid
Watch resourceVersionUse resourceVersion correctlyProhibit resourceVersion="" usage (refetches entire list)
List CallsAlways use paginationRetrieve entire List at once
InformerUse client-go's SharedInformer patternEach controller creating independent Watches
ReconnectionApply Exponential Backoff when Watch disconnectsImmediately retry connection (thundering herd)

6.4 Keep K8s Version Up-to-Date

  • K8s 1.33+ supports Streaming List, greatly improving large-scale List performance
  • Use the latest K8s version when possible to benefit from Control Plane performance improvements

6.5 Cluster Architecture Recommendations

Separate Clusters by Workload:

  • When there are many CRDs: Separate Core CRD cluster / Workload execution cluster
  • Platform CRDs and tenant workloads in the same cluster affect each other

Namespace-Based Isolation:

  • Limit object count per namespace through Kubernetes ResourceQuota
  • Prevent "object explosion" due to incorrect automation or bugs

7. Comprehensive Recommendations & Adoption Roadmap

7.1 PCP Tier Selection Guide by CRD Scale

Workload ProfileRecommended TierKey ReasonMonthly Cost (Estimate)
Less than 10 CRDs, small-scale operationsStandardBasic automatic scaling is sufficient~$73
10~30 CRDs, medium-scale operationsXLSecure etcd 20GB, 99.99% SLA~$1,277
30+ CRDs + multiple controllers2XLinflight 4,500+, KCM QPS 500~$2,555
Large-scale AI/ML pipelines + CRDs4XLHorizontal scaling of 3+ API Servers~$5,110

7.2 Core Alert Configuration

Alert NameMetricThresholdSeverityResponse Action
API Throttlingapiserver_request_total_429> 10/min for 5 minCriticalReview PCP tier upgrade
API Server Errorsapiserver_request_total_5xx> 5/min for 3 minCriticalCheck Control Plane logs
etcd DB Usageapiserver_storage_size_bytes> 8GB (Standard) / > 16GB (XL+)WarningClean up unnecessary CRD resources
Scheduling Failuresscheduler_schedule_attempts_UNSCHEDULABLE> 0 for 10 minWarningCheck node resources
API Concurrencyapiserver_flowcontrol_current_executing_seats_total> 80% of tier limitWarningReview higher tier provisioning
Integrated Monitoring Architecture

[1] CloudWatch Vended Metrics (automatic)
│ → Set up AWS/EKS namespace alarms
│ → Utilize Console Observability Dashboard

[2] Prometheus Endpoint (manual configuration)
│ → AMP Agentless Scraper or Self-hosted Prometheus
│ → Monitor CRD controllers with KCM workqueue metrics
│ → Configure Grafana dashboards

[3] Control Plane Logging (manual activation)
│ → Must activate audit + controllerManager logs
│ → Analyze CRD-related API call patterns

[4] Cluster Insights (automatic)
→ Always check before upgrades
→ PCP tier recommendations (future)

7.4 Phased Adoption Roadmap

PhaseDurationKey Activities
Phase 1: Basic Setup1 weekSet up CloudWatch alarms, activate Control Plane Logging (audit + controllerManager)
Phase 2: Prometheus Integration2 weeksConfigure AMP Scraper, collect KCM/KSH metrics, Grafana dashboards
Phase 3: Apply PCP1 weekSelect appropriate PCP tier after analyzing workload profile (XL and above recommended)
Phase 4: OptimizationOngoingUtilize Cluster Insights, adjust tier based on monitoring data, tune CRD controllers

7.5 Final Summary — Response Strategies by Key Challenge

ChallengeLeverage EKS FeaturesCRD Design Response
etcd Overload from CRDsXL and above: etcd 20GB + Event Sharding + VAS automatic scalingApply XL+ tier, minimize CR object size
API Server Performance DegradationGuaranteed inflight requests per PCP tier + APF priority managementOptimize controller List/Watch patterns, use latest K8s version
Scheduling LimitsAPI Server horizontal scaling in 4XL/8XL (up to 6 instances)Proactively provision higher tier when workload growth predicted
Control Plane StabilityMulti-AZ, 99.99% SLA (XL+)XL and above recommended for production clusters
Cost PredictabilityFixed price per PCP tier ($0.10 ~ $14.00/hr)Select appropriate tier matching workload profile
Lack of Visibility4 monitoring channels (Vended Metrics, Prometheus, Logging, Insights)Phased monitoring adoption Phase 1~4