nitinjain999/platform-skills/karpenter
Claude Code and agent skill by nitinjain999/platform-skills
- community
Checking that the SKILL.md file is still in the repository.
Design, install, debug, review, plan capacity, audit scaling history, migrate from Cluster Autoscaler, and upgrade Karpenter v1.x on EKS. Covers NodePool, EC2NodeClass, NodeClaim, Spot diversity, disruption strategy, Pod Identity/IRSA, interruption queue, private clusters, AMI rotation, and GitOps integration. Use when asked to "set up Karpenter", "debug why nodes aren't provisioning", "review my NodePool", "what would Karpenter provision for this workload", "why did this node terminate", "migrate from CA", or "upgrade Karpenter".
Install
npx vskill@latest install nitinjain999/platform-skills/karpenterSKILL.md
Design, install, debug, review, plan capacity, audit, migrate, and upgrade Karpenter on EKS.
Verify current stable version before installing (Karpenter uses OCI, not a Helm repo):
crane ls public.ecr.aws/karpenter/karpenter | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -5
Pin to the version from that output, e.g.:
helm upgrade --install karpenter oci://public.ecr.aws/karpenter/karpenter --version x.y.z
All guidance targets the karpenter.sh/v1 API. The v0.x Provisioner/AWSNodeTemplate API was removed in v1.0 — if you are on v0.x, use migrate mode first.
Interactive Wizard (fires when no arguments are provided)
When invoked with no arguments, ask before proceeding:
Q1 — Mode?
Q2 — Environment context (ask after mode, one question at a time):
Use the answers to set defaults for every section below. If the user pastes a manifest or error, infer as much as possible and skip questions already answered.
Mode: generate
Design a production-ready NodePool and EC2NodeClass from requirements.
Steps:
- Collect (or infer from context):
- Workload profile: general-purpose / compute-optimised / memory-optimised / GPU / Spot-flex
- Instance family preferences (e.g.
m,c,r,g4dn) and architecture (amd64,arm64/Graviton, or both) - AMI family:
AL2023(default, recommended) |Bottlerocket|Windows2022 - Environment: dev/staging or production — this drives the AMI strategy
- Whether scale-to-zero is needed (requires
limitsplanning) - Disruption tolerance: can workloads survive consolidation? Are there PDBs?
- GitOps method: Flux / Argo CD / direct kubectl
- Generate
EC2NodeClasswith:
amiSelectorTerms: usealias: al2023@latestfor dev/staging; use a pinned AMI ID (id: ami-xxxx) for production. Floating@latestin production means an untested AMI can land on fleet nodes during any scheduled SSM parameter update. Ask the user which environment this is for before choosing.
> Ask user: "What is your EKS cluster name?" — substitute into karpenter.sh/discovery: <cluster-name> before applying.
subnetSelectorTermsandsecurityGroupSelectorTermsusingkarpenter.sh/discovery: <cluster-name>tagsinstanceProfileorrolematching the Karpenter node IAM roleblockDeviceMappingswith encrypted EBS and IMDSv2 enforced viametadataOptionstagsincluding at minimumkarpenter.sh/discovery,Environment, and billing tags
- Generate
NodePoolwith:
spec.template.spec.requirementscovering at least 3 instance families and bothOn-Demand/Spotcapacity types (or explicit single type)minValueson instance family or size requirements to guarantee Spot diversitylimitson CPU and memory — never omit, uncapped NodePools can runawayweightif this is one of multiple NodePools (higher weight = preferred)disruptionblock:consolidationPolicy,consolidateAfter,budgetsexpireAfterset to720h(30 days) unless the user has a reason to extend
- Generate companion resources:
- IRSA or Pod Identity IAM policy (minimum permissions — see references)
PodDisruptionBudgetfor stateful workloads that will land on Karpenter nodes- Flux
Kustomizationdependency or Argo CDsyncWaveannotation if GitOps is in use
- Show validation:
``bash kubectl apply --dry-run=server -f ec2nodeclass.yaml kubectl apply --dry-run=server -f nodepool.yaml kubectl describe nodepool <name> # check Conditions: Ready=True ``
Reference: references/karpenter.md → NodePool design, EC2NodeClass, IAM
Rollback: kubectl delete nodepool <name> && kubectl delete ec2nodeclass <name> — Karpenter immediately stops provisioning nodes from these templates. Existing nodes remain until drained by the scheduler or TTL.
Mode: debug
Diagnose why pods are stuck Pending or nodes are not provisioning.
Steps:
- Collect evidence first — do not suggest fixes before seeing output:
```bash # Pending pods and their scheduling failure reason kubectl get pods -A --field-selector=status.phase=Pending kubectl describe pod <name> -n <ns> # look for Events: FailedScheduling
# NodeClaim lifecycle kubectl get nodeclaim -A kubectl describe nodeclaim <name> # look for Conditions block
# NodePool status kubectl get nodepool -A kubectl describe nodepool <name> # look for: Ready condition, limits
# Karpenter controller logs (most diagnostic signal is here) kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter \ --since=30m --tail=200
# Node registration failures kubectl get nodes kubectl describe node <new-node-name> # look for NotReady or taint issues ```
- Work through this decision tree in order:
| Symptom | Most likely cause | Field to check | |
|---|---|---|---|
No NodePool found in pod events | No NodePool matches pod requirements | NodePool requirements vs pod nodeSelector/tolerations | |
NodePool at resource limit | NodePool limits exhausted | kubectl describe nodepool → Current Usage | |
NodeClaim stuck Pending | IAM error launching instance | Karpenter logs for EC2 error, UnauthorizedOperation | |
NodeClaim launched but node NotReady | Bootstrap failure, security group, subnet | kubectl describe node, user-data cloud-init logs | |
Spot capacity unavailable | Single AZ or narrow instance family | Add instance families, enable multi-AZ subnets | |
Node registers then terminates immediately | Drift triggered on launch | Check AMI selector — SSM alias resolved to drifted AMI | |
Pods evicted unexpectedly | Consolidation or expiration | Node annotation karpenter.sh/disruption-reason | |
Private cluster: node never registers | Karpenter cannot reach EC2/SQS APIs | VPC endpoints: EC2, SQS, ECR, SSM, S3 |
- For IAM errors — test the exact API calls Karpenter makes:
``bash # Test from a pod in the karpenter namespace using the controller SA kubectl run -it --rm debug --image=amazon/aws-cli \ --serviceaccount=karpenter -n karpenter -- \ aws ec2 describe-instance-types --region eu-north-1 ``
- State the most likely root cause with the exact field or annotation to fix. Show the corrected spec section. Show the command to verify the fix worked.
Reference: references/karpenter.md → Troubleshooting
Rollback: If you edited NodePool/EC2NodeClass during debug: kubectl apply -f <original-backup>.yaml to restore. Always take a backup before editing: kubectl get nodepool <name> -o yaml > nodepool-backup.yaml.
Mode: review
Production-readiness review of NodePool and EC2NodeClass manifests.
Review in this exact priority order:
Correctness
- Does
EC2NodeClass.spec.instanceProfileor.spec.rolereference a valid node IAM role? - Are
subnetSelectorTermsandsecurityGroupSelectorTermsusing stable selectors (tags, not names which can change)? - Does
NodePool.spec.template.spec.nodeClassRef.namematch theEC2NodeClassmetadata name? - Are
requirementssatisfiable — does the cluster have subnets in the selected AZs with enough IP space? - Is
limitsset? An uncapped NodePool will provision nodes without bound on runaway workloads.
Cost
- Are at least 3 instance families listed for Spot (narrow families = frequent
InsufficientCapacityError)? - Is
minValuesset on instance family or size requirements to enforce Spot diversity? - Is Graviton (
arm64) included where workloads support it (~20% cheaper on EC2)? - Is
consolidationPolicy: WhenEmptyOrUnderutilizedenabled? Idle nodes are silent cost leaks. - Is
expireAfterset? Nodes that run indefinitely accumulate AMI drift and resist consolidation.
Reliability
- Are PDBs in place for workloads that will land on these nodes?
- Does
disruption.budgetsprotect critical workloads from simultaneous eviction? - Is
terminationGracePeriodset on the NodePool (default 48h — may be too long or too short)? - Does
startupTaintsprevent workloads scheduling onto nodes before DaemonSets are ready?
Security
- Is
amiSelectorTermsusingalias: al2023@latestor a pinned, scanned AMI ID? (Floatinglatestin production means untested AMIs can land on nodes.) - Is EBS encrypted? (
blockDeviceMappings[].ebs.encrypted: true) - Is IMDSv2 enforced? (
metadataOptions.httpTokens: required,httpPutResponseHopLimit: 1) - Do EC2 instance tags include
karpenter.sh/discovery: <cluster-name>— and is this tag protected by an SCP/tag policy against modification? - Does the node IAM role follow least privilege? (No
ec2:*, noiam:*)
GitOps safety
- Does the Flux/Argo Kustomization
dependsOnthe Karpenter Helm release so CRDs exist before NodePool? - Is the IAM role ARN injected via
postBuild.substituteor Argo CDApplicationSetparameter, not hardcoded?
Separate findings into:
- Critical — must fix before deploying to production
- Improvement — should fix (cost, resilience)
- Note — informational (consider Graviton, document disruption tolerance)
Reference: references/karpenter.md → NodePool design, Security, Cost strategy
Mode: audit
Reconstruct what scaled out or in, when, and why — for post-incident analysis or cost review.
Steps:
- Collect the timeline from three layers:
```bash # Layer 1: NodeClaim lifecycle events (node creation and termination) kubectl get events -A \ --field-selector involvedObject.kind=NodeClaim \ --sort-by='.lastTimestamp' | tail -50
# Layer 2: Disruption reason on terminated nodes (if node still exists) kubectl get node <name> \ -o jsonpath='{.annotations.karpenter\.sh/disruption-reason}'
# Layer 3: Karpenter controller logs filtered to provisioning and disruption kubectl logs -n karpenter -l app.kubernetes.io/name=karpenter \ --since=3h | grep -E "provisioned|disrupted|consolidat|drift|interrupt|expir"
# Layer 4: EC2 instance history (for Spot interruptions, verify in CloudWatch) aws ec2 describe-spot-instance-requests \ --filters "Name=tag:karpenter.sh/nodepool,Values=<nodepool-name>" \ --query 'SpotInstanceRequests[*].{ID:InstanceId,State:State,Fault:Fault}' \ --region eu-north-1 ```
- Map each event to a cause:
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/karpenter/SKILL.md
Popularity
- 7-day trend score
- 0
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/nitinjain999/platform-skills/karpenter)