Keamanan Kubernetes untuk Pemula — Jangan Sampai Cluster Kamu Jadi Pintu Masuk Hacker
Kamu deploy aplikasi pake Kubernetes? Udah yakin cluster kamu aman? Coba deh cek — dashboard Kubernetes kamu kebuka di internet gak? RBAC udah di-configure? Atau kamu kayak gue dulu: install Kubernetes, deploy aplikasi, seneng karena berhasil, terus tutup laptop dan tidur nyenyak… sementara cluster kamu jadi playground hacker crypto miner dari belahan dunia lain? Nah, keamanan Kubernetes pemula itu sering banget diabaikan — dan akibatnya bisa fatal.
Gue ngomong ini dari pengalaman. Bukan karangan. Tahun 2022, gue lagi belajar Kubernetes buat proyek side hustle. Udah berhasil deploy cluster pake k3s. Udah berhasil running aplikasi Node.js di atas 3 pod. Bangga banget. Saking bangganya, gue lupa nutup Kubernetes Dashboard. Default. Tanpa autentikasi. Exposed ke internet.
Dua hari kemudian gue buka dashboard — dan lo tau apa yang gue liat? Di namespace “default” ada 14 pod yang gue gak kenal. Semuanya jalanin container mining crypto. CPU server gue 98%. Memory full. IP-nya dari Rusia. Gue panik. Langsung hapus pod, tutup dashboard. Tapi besokannya pod itu balik lagi. Karena mereka udah bikin CronJob. Gila.
Keamanan Kubernetes pemula itu emang kayak gitu — hal-hal basic yang kelupaan. Bukan karena Kubernetes gak aman. Tapi karena konfigurasi default seringkali gak cukup buat production. Dan banyak yang belajar Kubernetes fokus ke deployment, scaling, microservices — lupa sama aspek keamanannya.
Di sini gue mau cerita apa aja yang gue pelajari dari insiden memalukan itu. Step-by-step. Dari RBAC, Network Policies, Pod Security, Secret Management, sampe Image Scanning. Gue usahain jelasin pake bahasa yang gak bikin lo pusing — karena jujur, dokumentasi resmi Kubernetes itu… ya gitulah. Tebal. Berat. Kayak baca kitab suci.
RBAC Itu Bukan Opsional — Itu Wajib
Pernah gak sih lo bikin service account, kasih role “cluster-admin” karena males mikirin permission-nya? Gue sering. Dulu. Itu bad practice. Banget.
RBAC (Role-Based Access Control) di Kubernetes itu kayak sistem izin masuk. Lo gak mungkin kasih kunci rumah ke semua tamu kan? Nah ini konsepnya sama. Jangan semua pod, semua service account, semua user — punya akses penuh ke cluster lo.
Gimana RBAC Bekerja?
Singkatnya, ada empat komponen utama:
- ServiceAccount: Identitas buat pod atau aplikasi yang jalan di dalam cluster. Bukan buat manusia — buat proses.
- Role/ClusterRole: Ini isinya permission — apa yang boleh dilakukan (get, list, create, delete pod, dan sebagainya). Role berlaku di satu namespace. ClusterRole berlaku di seluruh cluster.
- RoleBinding/ClusterRoleBinding: Ini yang ngehubungin ServiceAccount ke Role. Jadi si ServiceAccount A di-binding ke Role B, jadinya dia cuma bisa ngelakuin yang diizinin Role B.
Simpel kan? Tapi implementasinya di lapangan sering berantakan.
Kesalahan Fatal yang Sering Terjadi
Satu: bikin ServiceAccount terus di-binding ke ClusterRole “cluster-admin”. Karena males mikir permission. Walhasil, pod kamu bisa ngapa-ngapain. Termasuk bikin pod baru — persis kayak yang terjadi sama gue dulu.
Dua: gak bikin RBAC sama sekali. Ini terjadi di banyak cluster development. Semua pod pake ServiceAccount default — yang di beberapa setup, bisa punya akses luas ke API server. Lo kira aman? Gak.
Tiga: ServiceAccount token di-mount ke pod yang gak butuh akses ke Kubernetes API. Ini boros dan ningkatin attack surface. Kenapa pod frontend perlu token buat ngomong ke API server? Gak perlu.
Mulai Dari Mana?
Cek dulu ServiceAccount yang ada di cluster lo:
kubectl get serviceaccounts --all-namespaces
Terus cek RoleBinding dan ClusterRoleBinding:
kubectl get rolebindings,clusterrolebindings --all-namespaces
Kalo lo nemu binding yang pake “cluster-admin” padahal gak perlu — itu alarm merah. Delete atau ganti. Jangan ditunda nanti-nanti. Keamanan Kubernetes pemula dimulai dari membersihkan RBAC yang berantakan.
Prinsip dasarnya: least privilege. Kasih izin seminimal mungkin. Pod yang cuma perlu baca ConfigMap? Bikin Role yang cuma bisa “get” dan “list” ConfigMap di namespace tertentu. Jangan lebih. Kalo ada pod yang komplain karena permission-nya kurang? Tinggal ditambahin. It’s easier to grant than to revoke.
Network Policies — Jangan Biarin Pod Lo Ngobrol Bebas
Nah ini juga. Default Kubernetes itu semua pod bisa komunikasi sama semua pod. Flat network. Lo punya pod database dan pod frontend? Mereka otomatis bisa saling ngobrol. Bagus sih, praktis. Tapi dari sisi keamanan… nightmare.
Bayangin lo punya 50 pod jalan. Salah satu pod — entah itu vulnerable library, atau container image yang udah kena backdoor — berhasil di-compromise. Karena network-nya flat, attacker bisa langsung scanning semua pod lain dari situ. Tanpa hambatan. Dari pod yang kena, mereka bisa ping ke database, ke Redis, ke internal API — semuanya terbuka.
Network Policies itu kayak firewall antara pod. Lo bisa atur: pod A boleh ngomong ke pod B di port 5432 (PostgreSQL) — tapi gak boleh ngomong ke internet. Atau pod frontend boleh nerima traffic dari ingress controller aja, bukan dari pod lain.
Gimana Network Policy Bekerja?
Network Policy pake label selector buat nentuin pod mana yang di-apply, dan ingress/egress rules buat nentuin traffic mana yang diizinin. Konsepnya:
- podSelector: Pod mana yang kena policy ini.
- Ingress rules: Traffic masuk dari mana ke pod target.
- Egress rules: Traffic keluar dari pod target ke mana.
Yang penting: Network Policy adalah whitelist model. Begitu ada Network Policy yang match pod, traffic yang gak di-allow otomatis di-deny. Kalo gak ada Network Policy sama sekali — semua traffic diizinkan.
Contoh Praktis Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
Itu nge-blokir SEMUA traffic masuk ke pod di namespace “production”. Lalu lo bikin allow rules:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Kebayang kan power-nya? Lo bisa bikin mikro-segmentasi yang sangat granular.
MASALAHNYA: Network Policy butuh CNI plugin yang support — kayak Calico, Cilium, atau Weave Net. Kalo lo pake Flannel (yang umum dipake pemula karena gampang), Network Policy gak jalan. Jadi lo harus cek dulu CNI lo apa.
Pertanyaan Buat Lo
Coba lo jawab jujur: lo tau semua jalur komunikasi antar pod di cluster lo? Dari pod A ke pod B lewat port berapa? Ke database lewat mana? Ke service eksternal? Kalo lo gak bisa jawab, lo belum siap bikin Network Policy. Mulai dari mapping traffic dulu. Tools kayak Hubble (dari Cilium) bisa bantu visualisasi.
Pod Security — Pod Lo Jalan Sebagai Root?
Ini klasik dan masih sering kejadian di 2026. Container image yang lo tarik dari Docker Hub — dia jalan sebagai user apa? Root? Yup, banyak banget image default yang jalan sebagai root. Dan kalo container itu di-compromise, attacker langsung dapet akses root di host node. Game over.
Pod Security Standards (PSS) di Kubernetes ngebantu lo enforce aturan. Ada tiga level:
- Privileged: Bebas. Bisa apa aja. Ini buat workload yang emang perlu akses spesial — kayak monitoring agent atau CNI plugin.
- Baseline: Minimal. Nge-blokir hal-hal yang obvious bahaya — kayak privilege escalation, hostPath volume, run as root, hostNetwork, hostPID.
- Restricted: Ketat. Pod harus non-root, gak boleh pake host namespace, filesystem harus read-only, volume types dibatasin.
Cara Implementasi PSS
Lo bisa ngelabelin namespace pake label khusus:
kubectl label namespace production \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
Keterangan:
- enforce: Pod yang gak comply bakal ditolak.
- warn: Pod yang gak comply bakal tetep jalan tapi muncul warning.
- audit: Dicatat di audit log aja, gak ada enforcement.
Buat production, minimal enforce=baseline. Idealnya enforce=restricted.
Security Context di Pod Spec
Kalo lo pake Helm chart atau nulis pod spec manual, pastiin ada:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Ini bukan cuma checklist. Ini habit. Setiap kali lo bikin pod baru, tanya: “ini perlu jalan sebagai root? Kalo enggak, non-root.” Dan 95% kasus, jawabannya enggak.
Secret Management — Jangan Simpen Password di ConfigMap
Pernah nemu ConfigMap yang isinya password database? Atau Secret yang isinya cuma Base64 encoding, terus lo mikir “ah Base64 itu enkripsi”? Base64 itu encoding. BUKAN enkripsi. Semua orang bisa decode. Itu cuma buat ngindarin karakter spesial yang bikin YAML rusak.
Masalah secret management di Kubernetes:
- Secret default cuma di-encode Base64. Gak di-enkripsi.
- Etcd (database-nya Kubernetes) nyimpen secret sebagai plaintext — kecuali lo enable encryption at rest.
- Secret bisa diakses siapa aja yang punya akses ke namespace itu — via
kubectl get secret -o yaml.
Solusi: External Secrets Management
Ada beberapa opsi, dari yang simpel sampe enterprise:
- Sealed Secrets (Bitnami): Secret dienkripsi pake public key. Bisa di-commit ke Git dengan aman. Controller di cluster yang decrypt. Simpel dan powerful.
- External Secrets Operator: Nge-sync secret dari AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, atau HashiCorp Vault ke Kubernetes Secret object. Source of truth tetap di external vault.
- HashiCorp Vault + Vault Sidecar Injector: Paling mature. Vault inject secret langsung ke pod via sidecar atau init container. Secret gak pernah nyentuh Kubernetes API.
Buat small to medium setup, Sealed Secrets adalah sweet spot. Simpel, aman, dan lo bisa commit ke Git tanpa parno.
Encryption at Rest di Etcd
Kubernetes support encryption at rest buat Secret di etcd. Caranya:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}
Ini penting. Walaupun etcd harusnya gak bisa diakses dari luar, defense in depth: kalaupun etcd bocor, Secret tetap terenkripsi.
Image Scanning — Container Lo Ada Vulnerabilitasnya?
Lo tarik image dari Docker Hub, jalanin, selesai. Tapi pernah gak lo cek: image itu ada CVE-nya? Ada library lawas yang vulnerable? Ada embedded malware? Ada misconfig yang bikin container jalan sebagai root padahal gak perlu?
Gue dulu gak pernah. Jujur. Sampe akhirnya gue nyobain Trivy dari Aqua Security. Gue scan image PostgreSQL official. Hasilnya: 27 vulnerability. Beberapa HIGH severity. Satu CRITICAL. Image resmi lho. Bukan dari repo shady.
Sejak itu, image scanning jadi mandatory di pipeline gue.
Tools Image Scanning
- Trivy: Open source. Ringan. Support Docker image, filesystem, Git repo, dan Kubernetes cluster scan. Bisa dijalanin sebagai CLI atau Helm chart.
- Clair: Dari Red Hat. Mature, banyak integrasi dengan registry.
- Grype: Dari Anchore. Cepet, simple CLI. Bagus buat local dev.
- Snyk: Commercial tapi ada free tier. Cover library dependency juga.
Integrasi ke CI/CD
Scan image setiap build. Kalo ada vulnerability CRITICAL — gagalkan pipeline. Contoh .github/workflows/scan.yml:
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: 'my-app:${{ github.sha }}'
format: 'table'
exit-code: '1'
severity: 'CRITICAL,HIGH'
Ini nge-block image yang punya vulnerability HIGH/CRITICAL dari production.
Scheduled Scanning
Image yang udah di-deploy bisa jadi vulnerable kemudian hari. CVE baru muncul tiap hari. Jadi setup scheduled scan — misalnya tiap minggu pake CronJob atau Trivy Operator. Kalo nemu CVE baru di image yang udah running, patch dan redeploy.
Audit Logging — Mata-Mata Internal Cluster Lo
Gue nyesel banget gak enable audit logging dari awal. Waktu cluster kena crypto miner, gue gak tau siapa yang bikin pod itu, dari IP mana, pake credential apa. Kalo aja ada audit log, gue bisa trace attacker dan nutup celahnya.
Kubernetes punya audit logging built-in di kube-apiserver. Lo tinggal bikin audit policy:
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
omitStages:
- RequestReceived
Level yang tersedia:
- None: Gak log apa-apa.
- Metadata: Log metadata request (user, timestamp, resource, verb) — tanpa body.
- Request: Metadata + request body.
- RequestResponse: Metadata + request body + response body.
Production: minimal Metadata. Kalo lagi debugging insiden, naikin ke Request. Tapi hati-hati: RequestResponse bisa generate log gede banget dan mungkin mengandung data sensitif.
Forward ke SIEM
Audit log jangan cuma disimpen di file di master node. Forward ke SIEM — kayak Elasticsearch, Splunk, atau Grafana Loki. Bikin alert kalo ada request yang suspicious:
- ServiceAccount tiba-tiba bikin ClusterRoleBinding (eskalasi privilege).
- Request ke
/secretsdari IP yang gak dikenal. - Exec ke dalam pod (
kubectl exec) di luar jam kerja.
Falco — Runtime Security Buat Kubernetes
Ini bonus. Falco adalah runtime security tool dari Sysdig. Dia mantau system call di level kernel dan alert kalo ada behavior mencurigakan di dalam container.
Contoh alert yang bisa Falco deteksi:
- Shell di-spawn di dalam container (padahal harusnya gak ada shell di production).
- File yang gak seharusnya diedit (kayak
/etc/shadow). - Koneksi network ke IP yang suspicious.
- Process yang tiba-tiba berubah (container image immutable tapi tiba-tiba ada binary baru).
Falco terintegrasi sama Kubernetes via daemonset. Install-nya gampang pake Helm. Rules-nya udah ada bawaan dan bisa lo custom.
Checklist: Udah Aman Belum Cluster Lo?
Gue ringkasin jadi checklist biar lo bisa audit sendiri:
- RBAC: Audit semua ClusterRoleBinding. Hapus yang pake cluster-admin gak perlu. Terapin least privilege.
- Network Policy: Implementasi deny-all dulu di namespace production, terus bikin allow rules spesifik.
- Pod Security: Enforce baseline minimal. Target restricted. Cek securityContext di semua pod.
- Secret Management: Enable encryption at rest. Pake Sealed Secrets atau External Secrets Operator.
- Image Scanning: Scan setiap build. Gagalkan kalo ada CRITICAL. Scan ulang scheduled.
- Audit Logging: Enable minimal Metadata. Forward ke SIEM. Bikin alert rules.
- Dashboard: JANGAN expose ke internet. Pake kubectl proxy atau ingress dengan OAuth2/OIDC.
Keamanan Kubernetes pemula emang keliatannya overwhelming. Banyak banget yang harus dipelajari. Tapi lo gak harus implementasiin semuanya sekaligus. Mulai dari dua yang paling kritikal: RBAC dan Pod Security. Dua ini aja udah ngeblokir mayoritas insiden keamanan Kubernetes yang terjadi di real world.
Dan plis: jangan expose dashboard tanpa autentikasi ke internet. Gue udah jadi korban. Jangan lo juga. Keamanan Kubernetes pemula dimulai dari hal-hal basic yang kadang justru paling sering dilupain.
