| Field | Value |
|---|---|
| Cluster | ex-karpenter-test |
| Region | us-west-2 |
| Account | 123456789012 |
| Current Version | 1.32 (Extended Support) |
| Target Version | 1.33 |
| Assessment Date | 2026-05-25 |
Karpenter 1.0.2 is incompatible with Kubernetes 1.33 (requires >= 1.5). This is a hard blocker — node provisioning will break after the control plane upgrade. You must upgrade Karpenter to >= 1.5 before upgrading the control plane. All other checks pass cleanly; once Karpenter is resolved, this cluster is in good shape.
| Category | Status | Deduction | Details |
|---|---|---|---|
| Breaking Changes | ✅ | -0 pts | None detected for 1.33 target |
| Deprecated APIs | ✅ | -0 pts | All resources on current API versions |
| Node Readiness | ✅ | -0 pts | All nodes on 1.32, subnets have 4000+ IPs |
| Add-on Compatibility | ✅ | -0 pts | vpc-cni, kube-proxy, pod-identity-agent all healthy |
| Karpenter | ❌ | -10 pts | v1.0.2 installed, requires >= 1.5 for K8s 1.33 |
| Workload Risks | ⚠️ | -7 pts | 1 single-replica, missing probes, missing PDB |
| AWS Upgrade Insights | ✅ | -0 pts | All 5 insights PASSING |
| AL2 / AMI | ✅ | -0 pts | No AL2 nodes (Fargate + Bottlerocket) |
| Behavioral Changes | ✅ | -0 pts | Endpoints deprecation is informational only |
| Total | -17 pts | Arithmetic: 83%, capped to 59% (hard blocker) |
Hard Blocker: Karpenter 1.0.2 incompatible with target → score capped at 59%
karpenter namespace. The official compatibility matrix requires Karpenter >= 1.5 for Kubernetes 1.33.Upgrade Karpenter before the control plane upgrade. The 1.0.x → 1.5+ jump crosses the v1 API boundary — verify your NodePool and EC2NodeClass CRDs are on v1 APIs (not v1beta1):
# 1. Check current Karpenter version
kubectl get deployment karpenter -n karpenter -o jsonpath='{.spec.template.spec.containers[0].image}'
# 2. Verify NodePool CRDs are v1 (not v1beta1)
kubectl get nodepools.karpenter.sh -o yaml | grep apiVersion
# 3. Upgrade Karpenter via Helm (adjust version to latest >= 1.5)
helm upgrade karpenter oci://public.ecr.aws/karpenter/karpenter \
--namespace karpenter \
--version 1.5.0 \
--set clusterName=ex-karpenter-test \
--set clusterEndpoint=$(aws eks describe-cluster --name ex-karpenter-test --query cluster.endpoint --output text --region us-west-2) \
--wait
# 4. Verify Karpenter is healthy after upgrade
kubectl get pods -n karpenter
kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter --tail=20
default/singleton-app runs with 1 replica. During node drain (Karpenter consolidation or upgrade), this workload will experience downtime.default/inflate (3 replicas)default/singleton-app (1 replica)default/inflate has 3 replicas but no PodDisruptionBudget. During node drain, all 3 pods could be evicted simultaneously. kubectl create pdb inflate-pdb --namespace default \
--selector app=inflate --min-available 2
inflate container in default/inflate has a CPU request but no memory request. Without memory requests, the scheduler cannot make optimal placement decisions during rescheduling.resources.requests.memory to the container spec.discovery.k8s.io/v1). The 3 endpoints found (karpenter/karpenter, kube-system/eks-extension-metrics-api, kube-system/kube-dns) are auto-managed by their Services — no user action needed.ip-10-0-x-x runs containerd 1.7.31. This is fine for 1.33 but containerd 1.x support ends in Kubernetes 1.35. Plan to update before targeting 1.35.| Add-on | Type | Version | Status | Verdict | Source |
|---|---|---|---|---|---|
| vpc-cni | Managed | v1.20.5-eksbuild.1 | ACTIVE | COMPATIBLE | EKS managed |
| kube-proxy | Managed | v1.32.13-eksbuild.5 | ACTIVE | COMPATIBLE | EKS managed |
| eks-pod-identity-agent | Managed | v1.3.10-eksbuild.3 | ACTIVE | COMPATIBLE | EKS managed |
| Karpenter | OSS (Helm) | 1.0.2 | Running | INCOMPATIBLE | karpenter.sh/docs/upgrading/compatibility |
| Node | Type | Version | OS | Runtime | Skew vs 1.33 | Status |
|---|---|---|---|---|---|---|
| fargate-ip-10-0-x-x | Fargate | v1.32.13 | Minimal | containerd 2.2.3 | 1 | ✅ |
| fargate-ip-10-0-x-x | Fargate | v1.32.13 | Minimal | containerd 2.2.3 | 1 | ✅ |
| ip-10-0-x-x | Karpenter (c8g.xlarge) | v1.32.12 | Bottlerocket 1.61.0 | containerd 1.7.31 | 1 | ✅ |
Karpenter NodePools:
| NodePool | CPU Limit | Disruption | NodeClass |
|---|---|---|---|
| default | 1000 | WhenEmpty, 30s | EC2NodeClass/default |
| graviton-nodepool | 1000 | WhenEmptyOrUnderutilized, 60s | NodeClass/graviton-nodeclass |
| spot-nodepool | 1000 | WhenEmptyOrUnderutilized, 60s | NodeClass/spot-nodeclass |
Subnet Capacity:
| Subnet | AZ | CIDR | Available IPs | Status |
|---|---|---|---|---|
| subnet-0aaaaaaaaaaaaaaaa | us-west-2a | 10.0.0.0/20 | 4090 | ✅ |
| subnet-0bbbbbbbbbbbbbbbb | us-west-2c | 10.0.32.0/20 | 4089 | ✅ |
| subnet-0cccccccccccccccc | us-west-2b | 10.0.16.0/20 | 4060 | ✅ |
Master Workload Table (non-system namespaces):
| # | Name | Kind | NS | Replicas | Strategy | Probes | Requests | Findings |
|---|---|---|---|---|---|---|---|---|
| 1 | inflate | Deployment | default | 3 | RollingUpdate | ❌ none | cpu only | Missing probes, missing memory request, no PDB |
| 2 | singleton-app | Deployment | default | 1 | RollingUpdate | ❌ none | ✅ cpu+mem | Single replica, missing probes |
Risk Findings:
| Finding | Severity | Workloads (by row #) | Count | Pts |
|---|---|---|---|---|
| Single replica | HIGH | #2 | 1 | 3 |
| Missing readiness probes | MEDIUM | #1, #2 | 2 | 1 |
| Missing memory request | MEDIUM | #1 | 1 | 1 |
| Missing PDB (multi-replica) | MEDIUM | #1 | 1 | 1 |
| Drain-blocking PDB (singleton-pdb) | MEDIUM | #2 | 1 | 2 |
| HIGH sub-total | 3 (cap 8) | |||
| MEDIUM sub-total | 6 → capped 4 | |||
| Category total | 7 (cap 10) |
| Insight | Status | Description |
|---|---|---|
| EKS add-on version compatibility | ✅ PASSING | All add-on versions compatible with 1.33 |
| Cluster health issues | ✅ PASSING | No cluster health issues detected |
| Amazon Linux 2 compatibility | ✅ PASSING | No AL2 nodes detected |
| kube-proxy version skew | ✅ PASSING | kube-proxy versions match control plane |
| Kubelet version skew | ✅ PASSING | Node kubelet versions match control plane |
Do NOT proceed until the Karpenter blocker is resolved.
# Check current CRD API versions
kubectl get nodepools.karpenter.sh -o yaml | grep apiVersion
kubectl get ec2nodeclasses.karpenter.k8s.aws -o yaml | grep apiVersion
# Upgrade Karpenter (adjust to latest stable >= 1.5)
helm upgrade karpenter oci://public.ecr.aws/karpenter/karpenter \
--namespace karpenter \
--version 1.5.0 \
--set clusterName=ex-karpenter-test \
--set clusterEndpoint=$(aws eks describe-cluster --name ex-karpenter-test --query cluster.endpoint --output text --region us-west-2) \
--wait
# Verify Karpenter is healthy
kubectl get pods -n karpenter
kubectl get nodepools.karpenter.sh
# Check for latest compatible versions
aws eks describe-addon-versions --addon-name vpc-cni --kubernetes-version 1.33 --query 'addons[0].addonVersions[0].addonVersion' --region us-west-2
aws eks describe-addon-versions --addon-name kube-proxy --kubernetes-version 1.33 --query 'addons[0].addonVersions[0].addonVersion' --region us-west-2
aws eks describe-addon-versions --addon-name eks-pod-identity-agent --kubernetes-version 1.33 --query 'addons[0].addonVersions[0].addonVersion' --region us-west-2
aws eks update-cluster-version \
--name ex-karpenter-test \
--kubernetes-version 1.33 \
--region us-west-2
# Get the update ID from the output of Step 3, then:
aws eks describe-update \
--name ex-karpenter-test \
--update-id <UPDATE_ID> \
--region us-west-2
# Or watch cluster status
watch -n 30 'aws eks describe-cluster --name ex-karpenter-test --query "cluster.{status:status,version:version}" --output table --region us-west-2'
Karpenter nodes will be replaced automatically based on your NodePool expireAfter (720h) and disruption settings. To force immediate rotation:
# Option A: Trigger drift detection (Karpenter detects version mismatch and replaces nodes)
# This happens automatically after control plane upgrade
# Option B: Force immediate replacement
kubectl delete node <node-name>
Fargate pods must be recycled to pick up the new platform version:
# Delete and let the controller recreate them
kubectl rollout restart deployment -n <namespace> <deployment-name>
kubectl get nodes -o wide
kubectl get pods -A | grep -v Running | grep -v Completed
aws eks describe-cluster --name ex-karpenter-test --query "cluster.version" --region us-west-2