Mengamankan Karpenter dari dua sisi: kebijakan IAM minimal untuk controller dan instance profile, IRSA dan Pod Identity untuk workload, lalu pengamanan node dengan AMI hardened, kontrol SSH, userData, dan isolasi NodePool dengan taints.

Di episode 13 kalian sudah memahami bagaimana Karpenter memilih subnet, security group, dan terhubung dengan VPC CNI. Namun node yang tersambung ke jaringan tanpa kredensial yang tepat adalah lubang keamanan yang menunggu dieksploitasi. Autoscaler node memiliki akses luas ke AWS: ia bisa meluncurkan, menghapus, dan menandai instance. Jika kredensial controller bocor, dampaknya bukan hanya satu pod, melainkan seluruh infrastruktur.
Episode ini membahas security dan IAM dari dua sisi. Pertama, sisi kontrol: kebijakan IAM minimal untuk controller, instance profile yang dipasang ke node, serta IRSA dan EKS Pod Identity untuk workload. Kedua, sisi node: AMI hardened, kontrol akses SSH, userData di NodeClass, dan isolasi antar NodePool dengan taints dan tolerations.
Karpenter butuh izin untuk membuat instance, memasang security group, dan mengelola sumber daya EKS. Izin ini harus dibatasi seketat mungkin — bukan AdministratorAccess. Pendekatan yang benar adalah memberi akses ke resource spesifik lewat condition, misalnya membatasi peluncuran instance hanya pada AMI yang disetujui.
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"StringEquals": {
"ec2:InstanceType": "m5.large"
}
}
}Kebijakan yang direkomendasikan Karpenter mencakup aksi ec2:RunInstances, ec2:TerminateInstances, ec2:CreateTags, iam:PassRole, dan eks:DescribeCluster. Hindari menyalin kebijakan dari versi lama tanpa meninjau, karena set izin berubah antar rilis.
Setiap node yang diluncurkan Karpenter diberi instance profile lewat field role di NodeClass. Profile ini menentukan siapa node tersebut ketika berbicara dengan AWS: menarik image, melaporkan health, dan mengambil metadata. Node seharusnya tidak memiliki izin ekstra yang tidak dibutuhkan kubelet.
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
role: "karpenter-node-role"
subnetSelectorTerms:
- tags:
karpenter.sh/discovery: my-clusterGunakan satu role untuk semua node Karpenter, dan pisahkan dari role control plane. Jika workload membutuhkan akses AWS, jangan menambahkannya ke instance profile node — gunakan IRSA atau Pod Identity (lihat bagian berikut), sehingga izin melekat pada pod, bukan pada semua node.
IAM Roles for Service Accounts (IRSA) memetakan service account Kubernetes ke peran IAM. Karpenter sendiri dijalankan dengan IRSA, dan pola yang sama dipakai untuk workload biasa. Token JWT yang ditandatangani OIDC cluster ditukar menjadi kredensial AWS sementara, sehingga tidak ada key statis yang disimpan.
eksctl create iamserviceaccount \
--cluster my-cluster \
--namespace production \
--name my-workload \
--attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
--approveSetelah service account dibuat, pod cukup menambahkan serviceAccountName di spec-nya. Kredensial hanya valid selama pod berjalan dan terbatas pada izin peran tersebut.
EKS Pod Identity adalah mekanisme yang lebih baru dan lebih sederhana daripada IRSA. Alih-alih membuat peran IAM untuk tiap service account, kalian membuat asosiasi peran IAM ke service account langsung di EKS. Ini menghilangkan pengelolaan OIDC provider dan trust policy yang rumit.
Tip
Mulai dari versi terbaru Karpenter, instalasi resmi merekomendasikan EKS Pod Identity dibanding IRSA karena alur trust-nya lebih sederhana dan tidak bergantung pada konfigurasi OIDC. Pilih IRSA hanya jika kalian sudah terlanjur memakai ekosistemnya dan tidak bisa migrasi.
Satu aturan emas: kredensial AWS untuk workload tidak boleh diletakkan di instance profile node. Dengan IRSA atau Pod Identity, tiap deployment hanya memiliki akses ke layanan yang dibutuhkannya, dan rotasi kredensial terjadi otomatis tanpa intervensi manusia.
Node yang diluncurkan Karpenter memakai AMI keluarga tertentu. Untuk lingkungan dengan tuntutan keamanan tinggi, gunakan AMI yang sudah di-hardening — misalnya melalui EC2 Image Builder atau Amazon Linux yang diperkuat dengan CIS benchmark. Tentukan lewat amiFamily dan jika perlu amiSelectorTerms di NodeClass.
| amiFamily | Karakteristik |
|---|---|
| AL2 | Default, familiar, dukungan luas |
| AL2023 | Lebih baru, sertifikat dan tooling diperbarui |
| Bottlerocket | Minimal, read-only root, cocok untuk hardening |
| Ubuntu | Paket luas, umum di banyak tim |
Warning
Jika menggunakan amiSelectorTerms untuk memilih AMI kustom, pastikan drift detection tetap aktif (episode 11). AMI yang di-hardening usang adalah ilusi keamanan — patch keamanan tidak berguna jika Karpenter tidak mengganti node saat AMI baru tersedia.
Jangan biarkan SSH terbuka ke internet. Akses node seharusnya lewat session manager (SSM) atau bastion dengan kunci yang dikelola. Security group yang dipilih NodeClass (episode 13) harus membatasi port 22 hanya dari jaringan tepercaya, atau lebih baik menutupnya sama sekali.
apiVersion: karpenter.k8s.aws/v1
kind: EC2NodeClass
metadata:
name: default
spec:
amiFamily: AL2
userData: |
#!/bin/bash
systemctl enable amazon-ssm-agent
systemctl start amazon-ssm-agentDengan SSM, kalian masuk ke node lewat AWS console atau CLI tanpa perlu port terbuka. Semua sesi tercatat di CloudTrail, sehingga ada jejak audit untuk tiap akses.
Tidak semua node boleh dipakai semua workload. Node untuk PCI, untuk GPU, atau untuk tenancy khusus seharusnya diisolasi. Karpenter mendukung isolasi lewat taints di NodePool dan tolerations di pod, ditambah requirement di kedua sisi sebagai pengaman ganda.
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
name: gpu
spec:
template:
spec:
taints:
- key: workload-type
value: gpu
effect: NoSchedule
requirements:
- key: karpenter.k8s.aws/instance-category
operator: In
values: ["g"]Pod yang ingin duduk di node GPU harus memiliki toleration yang cocok dan biasanya juga meminta resource nvidia.com/gpu. Kombinasi taint dan toleration memastikan pod CPU tidak pernah ditempatkan ke node GPU yang mahal, dan pod GPU tidak sembarangan ditempatkan ke node general.
Caution
Taint hanya mencegah scheduling pod tanpa toleration — ia tidak menolak pod yang sudah ada. Jika kalian butuh isolasi keras untuk tenancy, kombinasikan taint dengan security group berbeda dan NodeClass terpisah, bukan hanya mengandalkan taint.
Keamanan Karpenter bukan satu pengaturan, melainkan rangkaian keputusan yang saling melengkapi dari IAM sampai isolasi workload.
Inti yang harus dibawa pulang:
Keamanan sudah kokoh, namun biaya infrastruktur bisa membengkak tanpa strategi. Di episode 15 kita membahas Best Practice & FinOps — penyebaran workload multi-AZ, kombinasi Spot dan On-Demand, alignment dengan Reserved dan Savings Plans, hingga alokasi biaya per workload berbasis tag. Sampai jumpa!