Amazon EKS — Bottlerocket and AMI Types
The operating system running on your EKS nodes affects security, performance, and maintenance. AWS provides several AMI options purpose-built for EKS.
EKS AMI Options
| AMI | Description | Best For |
|---|---|---|
| Amazon Linux 2023 (AL2023) | Latest EKS-optimized AMI, default for new clusters | General production use |
| Amazon Linux 2 (AL2) | Previous generation, still supported | Legacy clusters |
| Bottlerocket | Minimal, immutable OS built for containers | Security-focused, hardened environments |
| Ubuntu | Canonical-maintained EKS AMI | Teams familiar with Ubuntu |
| Windows | Windows Server for .NET workloads | Windows containers |
| Custom AMI | Your own AMI based on any of the above | Special requirements |
Amazon Linux 2023 (AL2023)
AL2023 is the default and recommended AMI for new EKS clusters.
Key Features
- Based on Fedora, optimized for AWS
dnfpackage manager (replacesyum)- SELinux enabled by default
- Kernel 6.x with eBPF support
containerdas the container runtime- Faster boot times than AL2
Retrieving the Latest AL2023 AMI
aws ssm get-parameter \
--name /aws/service/eks/optimized-ami/1.29/amazon-linux-2023/x86_64/standard/recommended/image_id \
--query 'Parameter.Value' --output text
Using AL2023 with eksctl
managedNodeGroups:
- name: al2023-nodes
amiFamily: AmazonLinux2023
instanceType: m6i.xlarge
desiredCapacity: 3
Bottlerocket
Bottlerocket is a purpose-built, minimal, immutable OS designed specifically for running containers.
Why Bottlerocket?
| Feature | Bottlerocket | Standard Linux |
|---|---|---|
| Attack surface | Minimal — no shell, no package manager on host | Full OS with hundreds of packages |
| Updates | Atomic, image-based updates | Package-by-package updates |
| Rollback | Built-in A/B partition rollback | Manual/complex rollback |
| Configuration | API-driven (TOML) | SSH + scripts |
| Security | SELinux enforcing, dm-verity, read-only root | Varies by configuration |
| Compliance | CIS Benchmark hardened out of the box | Requires manual hardening |
How Bottlerocket Differs
Standard Linux:
┌──────────────────────────┐
│ Shell (bash) │
│ Package manager (yum) │
│ SSH server │
│ Hundreds of utilities │
│ Container runtime │
│ kubelet │
└──────────────────────────┘
Bottlerocket:
┌──────────────────────────┐
│ Container runtime │
│ kubelet │
│ API server (for config) │
│ (that's it) │
└──────────────────────────┘
Using Bottlerocket with EKS
managedNodeGroups:
- name: bottlerocket-nodes
amiFamily: Bottlerocket
instanceType: m6i.xlarge
desiredCapacity: 3
bottlerocket:
settings:
kubernetes:
maxPods: 58
Accessing Bottlerocket Nodes
There’s no SSH by default. For debugging, use the admin container:
# Enable admin container via user data
[settings.host-containers.admin]
enabled = true
Or use SSM Session Manager:
aws ssm start-session --target i-1234567890abcdef0
Bottlerocket Updates
Bottlerocket uses an image-based update model with A/B partitions:
# Check for updates (from the control container or API)
apiclient update check
# Apply update
apiclient update apply
# Reboot into the new partition
apiclient reboot
If the new version fails to boot, Bottlerocket automatically rolls back to the previous partition.
AL2023 vs Bottlerocket
| Feature | AL2023 | Bottlerocket |
|---|---|---|
| Package manager | dnf (can install packages) | None (immutable) |
| SSH access | Yes (with key) | No (admin container or SSM) |
| Security posture | Good (SELinux available) | Excellent (minimal surface, dm-verity) |
| Update model | Package updates (yum/dnf) | Image-based A/B updates |
| Rollback | Manual | Automatic A/B partition |
| Debugging | SSH, full toolset | Admin container, SSM |
| Learning curve | Familiar Linux | New paradigm |
| CIS hardened | Manual hardening needed | Out of the box |
| Best for | General workloads | Security-sensitive, compliance |
Custom AMI Considerations
When the default AMIs don’t meet your needs, build custom AMIs:
When to Build Custom AMIs
- Pre-install security agents (CrowdStrike, Datadog, etc.)
- Custom kernel modules or parameters
- Specific compliance requirements (FIPS, STIG)
- Pre-pulled container images for faster startup
- Custom monitoring agents
Building on Top of EKS AMIs
Always start from an EKS-optimized AMI — don’t build from scratch:
# Find the base AMI
BASE_AMI=$(aws ssm get-parameter \
--name /aws/service/eks/optimized-ami/1.29/amazon-linux-2023/x86_64/standard/recommended/image_id \
--query 'Parameter.Value' --output text)
echo "Base AMI: $BASE_AMI"
Then customize with Packer (see Self-Managed Nodes for the Packer template).
AMI Update Strategy
Custom AMIs need a rebuild pipeline:
- AWS releases a new EKS-optimized AMI (monthly-ish)
- Your pipeline rebuilds your custom AMI on top of the new base
- Update the launch template with the new AMI ID
- Trigger a rolling update on the node group
# Check latest AMI version
aws ssm get-parameter \
--name /aws/service/eks/optimized-ami/1.29/amazon-linux-2023/x86_64/standard/recommended/release_version \
--query 'Parameter.Value' --output text
Graviton (ARM) AMIs
All AMI types are available for Graviton (ARM) instances:
# AL2023 ARM AMI
aws ssm get-parameter \
--name /aws/service/eks/optimized-ami/1.29/amazon-linux-2023/arm64/standard/recommended/image_id \
--query 'Parameter.Value' --output text
managedNodeGroups:
- name: graviton-nodes
amiFamily: AmazonLinux2023
instanceType: m7g.xlarge # Graviton3
desiredCapacity: 3
Important: Your container images must be built for ARM (or multi-architecture). x86 images won’t run on Graviton nodes.
Best Practices
- Use AL2023 as the default — it’s the most supported and well-tested option
- Consider Bottlerocket for security-sensitive workloads — minimal attack surface, automatic rollback
- Avoid custom AMIs unless necessary — they add maintenance burden
- Automate custom AMI builds with a CI/CD pipeline that triggers on new base AMI releases
- Test Bottlerocket in a separate node group before migrating production workloads
- Use multi-arch images if mixing x86 and Graviton (ARM) nodes