Belajar Kubernetes
Belajar kubernetes
Last updated
Belajar kubernetes
Last updated
Kubernetes adalah sebuah orkestrator open source untuk mendeploy aplikasi berbasis kontainer. Awalnya, Kubernetes dikembangkan oleh Google, terinspirasi dari pengalaman selama satu dekade dalam menerapkan sistem yang skalabel dan andal di dalam kontainer. Sejak diperkenalkan pada tahun 2014, Kubernetes telah berkembang menjadi salah satu open source project terbesar dan paling populer di dunia. Kubernetes kini menjadi standar API dalam membangun aplikasi cloud-native dan hadir di hampir semua penyedia layanan cloud publik.
Kubernetes merupakan infrastruktur yang telah terbukti dalam menangani sistem terdistribusi dan cocok untuk pengembang cloud-native dari berbagai skala, mulai dari cluster kecil berbasis Raspberry Pi hingga pusat data besar dengan mesin-mesin terbaru. Kubernetes menyediakan software yang dibutuhkan untuk membangun dan menerapkan sistem terdistribusi yang andal dan skalabel.
Saat ini, semakin banyak layanan yang dikirimkan melalui jaringan menggunakan API. API ini biasanya berjalan di atas sistem terdistribusi, di mana berbagai komponen yang menjalankan API tersebar di beberapa mesin, terhubung melalui jaringan, dan saling berkoordinasi untuk memberikan layanan.
Karena API semakin menjadi bagian penting dalam kehidupan sehari-hari—misalnya, untuk mencari rute tercepat ke rumah sakit terdekat—sistem yang menjalankannya harus sangat andal. Sistem tidak boleh gagal, bahkan jika ada bagian yang mengalami crash atau berhenti bekerja. Selain itu, ketersediaan layanan harus tetap terjaga, bahkan saat ada pembaruan perangkat lunak atau pemeliharaan.
Seiring dengan semakin banyaknya pengguna internet di seluruh dunia, layanan ini juga harus sangat skalabel, agar dapat menangani peningkatan jumlah pengguna tanpa perlu merombak arsitektur sistem terdistribusi secara menyeluruh. Dalam banyak kasus, ini berarti kapasitas sistem harus dapat ditingkatkan atau dikurangi secara otomatis agar aplikasi berjalan seefisien mungkin.
Tergantung pada latar belakang dan tujuan Anda dalam mempelajari Kubernetes, pengalaman Anda dengan kontainer, sistem terdistribusi, dan Kubernetes itu sendiri bisa sangat bervariasi. Anda mungkin berencana untuk membangun aplikasi di atas infrastruktur cloud publik, pusat data pribadi, atau lingkungan hybrid. Terlepas dari tingkat pengalaman Anda, Kubernetes dirancang untuk membantu Anda mengelola aplikasi dengan lebih efisien.
Ada banyak alasan mengapa orang menggunakan kontainer dan platform seperti Kubernetes, tetapi semuanya dapat dirangkum dalam beberapa manfaat utama:
Kecepatan Pengembangan (Development Velocity) – Mempermudah proses pengembangan dan penerapan aplikasi.
Skalabilitas (Scaling) – Baik dalam hal skala perangkat lunak maupun skala tim pengembang.
Abstraksi Infrastruktur (Abstracting Your Infrastructure) – Mengelola sumber daya tanpa harus menangani detail infrastruktur secara langsung.
Efisiensi (Efficiency) – Memanfaatkan sumber daya secara optimal, mengurangi biaya, dan meningkatkan kinerja.
Ekosistem Cloud-Native (Cloud Native Ecosystem) – Mendukung berbagai alat dan layanan dalam ekosistem cloud-native modern.
Kecepatan adalah komponen kunci dalam hampir semua pengembangan perangkat lunak modern. Industri perangkat lunak telah berkembang pesat, dari era pengiriman produk dalam bentuk CD atau DVD fisik menjadi layanan berbasis web yang dapat diperbarui setiap jam. Dalam lanskap yang terus berubah ini, keunggulan kompetitif sering kali bergantung pada seberapa cepat Anda dapat mengembangkan dan menerapkan fitur baru, atau seberapa cepat Anda dapat merespons inovasi yang dilakukan oleh pesaing.
Namun, penting untuk dipahami bahwa kecepatan bukan hanya tentang seberapa cepat sesuatu dapat dikembangkan dan dikirimkan. Meskipun pengguna selalu menginginkan peningkatan yang berkelanjutan, mereka lebih mengutamakan keandalan layanan. Dulu, wajar jika suatu layanan harus dihentikan untuk pemeliharaan setiap tengah malam. Tetapi saat ini, pengguna mengharapkan ketersediaan layanan yang konstan, bahkan jika perangkat lunak yang mereka gunakan terus mengalami perubahan.
Oleh karena itu, kecepatan tidak hanya diukur dari jumlah fitur yang dapat dirilis per jam atau hari, tetapi dari kemampuan untuk merilis fitur baru tanpa mengorbankan ketersediaan layanan.
Dalam hal ini, kontainer dan Kubernetes menyediakan alat yang memungkinkan pengembang untuk bergerak cepat tanpa mengorbankan stabilitas sistem. Konsep inti yang mendukung ini meliputi:
Immutability – Setiap perubahan dikemas dalam unit baru yang terisolasi, sehingga mengurangi risiko konflik.
Konfigurasi Deklaratif (Declarative Configuration) – Sistem dikonfigurasi menggunakan file deklaratif, yang membuat perubahan lebih terstruktur dan dapat direproduksi.
Sistem Pemulihan Diri (Online Self-Healing Systems) – Kubernetes dapat secara otomatis mendeteksi dan memperbaiki kegagalan tanpa campur tangan manusia.
Pustaka dan Alat yang Dapat Digunakan Kembali (Shared Reusable Libraries and Tools) – Memungkinkan pengembang untuk menggunakan kembali komponen yang telah teruji, mempercepat proses pengembangan dan penerapan.
Dengan menerapkan prinsip-prinsip ini, Kubernetes memungkinkan tim pengembang untuk menerapkan perubahan dengan lebih cepat dan andal, tanpa mengorbankan stabilitas dan ketersediaan layanan.
Kontainer dan Kubernetes mendorong pengembang untuk membangun sistem terdistribusi berdasarkan prinsip infrastruktur yang immutable (tidak berubah). Dalam pendekatan ini, setelah suatu artefak (seperti image kontainer) dibuat, ia tidak diubah melalui modifikasi langsung oleh pengguna.
Secara tradisional, sistem komputer dan perangkat lunak dikelola dengan infrastruktur yang mutable (dapat diubah). Dalam pendekatan ini, perubahan diterapkan sebagai pembaruan bertahap pada sistem yang sudah ada. Pembaruan ini bisa dilakukan sekaligus atau bertahap dalam jangka waktu tertentu. Contoh yang umum adalah pembaruan sistem dengan apt-get update
, di mana paket perangkat lunak yang diperbarui diunduh dan ditimpa ke versi lama secara bertahap.
Masalah utama dengan sistem yang mutable adalah bahwa status infrastruktur saat ini tidak pernah benar-benar tercatat sebagai satu artefak tunggal, melainkan merupakan hasil akumulasi perubahan bertahap dari waktu ke waktu. Lebih buruk lagi, dalam tim besar, pembaruan sistem sering kali dilakukan oleh banyak orang yang berbeda tanpa pencatatan yang jelas. Ini bisa menyebabkan inkonsistensi, kesulitan dalam troubleshooting, dan sulitnya rollback jika terjadi kesalahan.
Sebaliknya, dalam sistem yang immutable, setiap perubahan tidak diterapkan sebagai pembaruan bertahap, tetapi sebagai pembuatan ulang seluruh image sistem. Alih-alih mengubah konfigurasi atau memperbarui paket satu per satu, image baru dibuat dari awal dan menggantikan image lama dalam satu operasi tunggal.
Bayangkan ada dua cara untuk memperbarui perangkat lunak dalam sebuah kontainer:
Pendekatan Mutable:
Masuk ke dalam kontainer.
Menjalankan perintah untuk mengunduh perangkat lunak versi baru.
Menghentikan server lama dan memulai server baru dengan perangkat lunak yang diperbarui.
Pendekatan Immutable (Direkomendasikan oleh Kubernetes):
Membangun image kontainer baru dengan perangkat lunak versi terbaru.
Push image baru ke container registry.
Menghentikan kontainer lama dan menjalankan yang baru, menggunakan image yang diperbarui.
Sekilas, kedua metode ini tampak serupa. Namun, pendekatan immutable memberikan keuntungan utama dalam hal keandalan dan pencatatan perubahan.
✅ Rekaman Perubahan yang Jelas Setiap perubahan pada aplikasi dikemas dalam image baru yang terdokumentasi dengan baik. Ini memungkinkan pengembang untuk mengetahui dengan pasti apa yang telah berubah di setiap versi. Jika terjadi masalah, perbedaan antarversi dapat dianalisis dengan mudah untuk menemukan penyebabnya.
✅ Rollback yang Cepat dan Aman Karena pembaruan tidak dilakukan dengan menimpa file lama, versi sebelumnya dari image masih tersedia. Jika pembaruan baru menyebabkan masalah, rollback bisa dilakukan dengan cepat hanya dengan mengganti image baru dengan yang lama. Sebaliknya, jika kita langsung menimpa file biner dalam kontainer, rollback hampir mustahil dilakukan.
✅ Menghindari Konfigurasi yang Tidak Konsisten Dalam sistem mutable, ada risiko perbedaan konfigurasi antara satu server dengan server lainnya karena perubahan bertahap yang tidak selalu terdokumentasi dengan baik. Dengan pendekatan immutable, semua node dalam cluster menjalankan image yang identik, sehingga mengurangi risiko inkonsistensi.
✅ Sesuai dengan Prinsip Kubernetes Kubernetes didesain untuk bekerja dengan image kontainer yang immutable. Meskipun memungkinkan perubahan langsung pada kontainer yang sedang berjalan, ini dianggap antipattern, kecuali dalam keadaan darurat yang benar-benar tidak bisa dihindari. Bahkan dalam situasi seperti itu, perubahan harus tetap dicatat dan dimasukkan ke dalam pembaruan konfigurasi yang deklaratif sesegera mungkin setelah sistem kembali stabil.
Konsep immutability (ketidakberubahan) tidak hanya berlaku pada kontainer yang berjalan di dalam klaster Kubernetes, tetapi juga pada cara kita mendeskripsikan aplikasi dalam Kubernetes. Segala sesuatu di Kubernetes berbentuk objek konfigurasi deklaratif yang mewakili keadaan sistem yang diinginkan (desired state). Tugas Kubernetes adalah menyesuaikan keadaan aktual dengan keadaan yang diinginkan tersebut.
Seperti halnya perbedaan antara infrastruktur mutable dan immutable, konfigurasi deklaratif merupakan alternatif dari konfigurasi imperatif.
Pendekatan imperatif: Mendefinisikan serangkaian instruksi langkah demi langkah untuk mencapai suatu kondisi.
Pendekatan deklaratif: Mendefinisikan hasil akhir yang diinginkan, dan Kubernetes akan menangani bagaimana mencapainya.
Contoh sederhana: Jika kita ingin menjalankan tiga replika dari suatu aplikasi: ✅ Pendekatan imperatif:
“Jalankan instance A”
“Jalankan instance B”
“Jalankan instance C”
✅ Pendekatan deklaratif:
replicas: 3
(Hanya mendeklarasikan jumlah replika yang diinginkan, tanpa perlu menyebut langkah-langkahnya).
Karena konfigurasi deklaratif hanya mendeskripsikan keadaan akhir yang diinginkan, kita tidak perlu mengeksekusinya untuk memahami dampaknya. Hal ini membuat pendekatan deklaratif lebih minim kesalahan dibandingkan imperatif.
Selain itu, konfigurasi deklaratif memungkinkan penggunaan praktik pengembangan perangkat lunak yang lebih baik, seperti: ✅ Version control (Git) untuk menyimpan konfigurasi ✅ Code review sebelum perubahan diterapkan ✅ Unit testing untuk memverifikasi konfigurasi sebelum dideploy
Pendekatan deklaratif sangat erat kaitannya dengan konsep Infrastructure as Code (IaC), di mana konfigurasi infrastruktur disimpan dalam version control seperti Git. Salah satu implementasi populer dari IaC adalah GitOps, yaitu strategi di mana seluruh perubahan pada infrastruktur dilakukan melalui commit dan push ke repository Git.
Dalam GitOps, klaster Kubernetes dianggap sebagai lingkungan hanya-baca (read-only), artinya perubahan hanya bisa dilakukan dengan memodifikasi konfigurasi dalam repository Git, yang kemudian akan diterapkan secara otomatis ke klaster Kubernetes.
GitOps semakin banyak digunakan dalam layanan Kubernetes berbasis cloud karena memberikan cara yang lebih aman, terstruktur, dan otomatis untuk mengelola infrastruktur cloud-native.
Salah satu keuntungan terbesar dari konfigurasi deklaratif adalah rollback yang sangat mudah. Karena Kubernetes menyimpan keadaan sistem yang diinginkan dalam konfigurasi deklaratif, rollback hanya memerlukan pemulihan konfigurasi sebelumnya dalam version control.
Sebaliknya, dalam pendekatan imperatif, rollback sering kali sulit dilakukan karena: ❌ Instruksi imperatif hanya mendefinisikan cara berpindah dari A ke B, tetapi tidak menyimpan cara kembali dari B ke A. ❌ Tidak ada pencatatan otomatis tentang perubahan yang terjadi, sehingga sulit melacak apa yang harus dikembalikan.
Dengan konfigurasi deklaratif, cukup mengembalikan konfigurasi ke versi sebelumnya, lalu Kubernetes akan secara otomatis menyesuaikan sistem dengan konfigurasi tersebut.
Kubernetes adalah sistem online yang dapat menyembuhkan dirinya sendiri (self-healing system). Saat Kubernetes menerima konfigurasi keadaan yang diinginkan (desired state), ia tidak hanya menjalankan serangkaian tindakan satu kali untuk mencocokkan keadaan saat ini dengan keadaan yang diinginkan. Sebaliknya, Kubernetes secara terus-menerus mengambil tindakan untuk memastikan bahwa keadaan saat ini selalu sesuai dengan keadaan yang diinginkan.
Hal ini berarti bahwa Kubernetes tidak hanya menginisialisasi sistem, tetapi juga melindungi sistem dari kegagalan atau gangguan yang dapat mengganggu kestabilan dan keandalan sistem.
Dalam sistem tradisional, ketika terjadi gangguan atau kegagalan, operator sistem biasanya harus melakukan perbaikan secara manual dengan serangkaian langkah mitigasi berdasarkan notifikasi atau alarm. Pendekatan ini memiliki beberapa kelemahan:
❌ Mahal – Memerlukan tenaga operator yang selalu siaga untuk menangani masalah. ❌ Lambat – Operator mungkin harus bangun, masuk ke sistem, dan menganalisis masalah sebelum melakukan perbaikan. ❌ Kurang andal – Pendekatan imperatif (manual) sering kali menyebabkan ketidakkonsistenan dan berisiko terjadi kesalahan manusia.
Sebaliknya, sistem self-healing seperti Kubernetes mengurangi beban operator dan meningkatkan keandalan sistem dengan memperbaiki kegagalan secara otomatis dan cepat.
Sebagai ilustrasi, jika dalam konfigurasi Kubernetes Anda menyatakan bahwa harus ada tiga replika dari suatu aplikasi:
✅ Kubernetes akan menciptakan tiga replika. ✅ Jika seseorang secara manual menambahkan replika keempat, Kubernetes akan menghapus satu replika agar jumlahnya kembali ke tiga. ✅ Jika salah satu replika terhapus atau gagal, Kubernetes akan secara otomatis membuat replika baru untuk mengembalikan keadaan ke tiga replika yang diinginkan.
Pendekatan ini mengurangi pekerjaan manual, memastikan stabilitas sistem, dan meminimalkan downtime tanpa perlu intervensi operator.
Sistem self-healing dalam Kubernetes juga meningkatkan produktivitas developer karena:
✅ Mengurangi waktu dan tenaga yang dihabiskan untuk operasi dan pemeliharaan. ✅ Memungkinkan developer lebih fokus pada pengembangan fitur baru dan pengujian. ✅ Meningkatkan kecepatan inovasi dengan lingkungan yang lebih stabil dan otomatis.
Kubernetes juga memiliki Operator, yang merupakan mekanisme lanjutan untuk self-healing dengan logika yang lebih spesifik dan kompleks. Operator berjalan sebagai aplikasi dalam kontainer di dalam klaster Kubernetes dan bertanggung jawab untuk:
✅ Mendeteksi masalah secara lebih spesifik pada aplikasi tertentu (misalnya MySQL). ✅ Melakukan perbaikan otomatis yang lebih kompleks dibandingkan mekanisme self-healing standar Kubernetes. ✅ Mengelola scaling, konfigurasi, dan pemulihan untuk aplikasi tertentu.
Konsep Operator ini semakin berkembang dan memungkinkan otomatisasi lebih lanjut dalam pengelolaan aplikasi berbasis Kubernetes.
Dalam Kubernetes Master, terdapat beberapa komponen utama yang bertugas dalam mengelola dan mengontrol Kubernetes Cluster. Salah satu komponen terpenting adalah kube-apiserver, yang berfungsi sebagai API utama untuk berinteraksi dengan cluster Kubernetes. Semua komunikasi antara pengguna, sistem, maupun komponen internal Kubernetes melewati kube-apiserver, menjadikannya pusat dari seluruh operasi dalam cluster.
Selain itu, etcd berperan sebagai database terdistribusi yang menyimpan seluruh data konfigurasi dan status Kubernetes Cluster, termasuk informasi mengenai pod, service, hingga konfigurasi jaringan. Kemudian, ada kube-scheduler, yang bertugas memperhatikan aplikasi yang dijalankan dan menentukan Node yang paling sesuai untuk menjalankan aplikasi tersebut berdasarkan ketersediaan sumber daya dan kebijakan yang telah ditetapkan.
Selanjutnya, kube-controller-manager memiliki peran penting dalam mengelola berbagai kontrol loop di dalam Kubernetes Cluster, seperti memastikan jumlah replika pod sesuai dengan deklarasi, menangani node yang gagal, serta mengelola token akses dan akun service. Terakhir, terdapat cloud-controller-manager, yang berfungsi untuk mengontrol interaksi antara Kubernetes dengan cloud provider. Komponen ini memungkinkan Kubernetes untuk berintegrasi dengan layanan cloud seperti load balancer, penyimpanan, dan jaringan, sehingga dapat berjalan secara optimal dalam lingkungan public cloud, hybrid cloud, atau multi-cloud.
Dengan kombinasi semua komponen tersebut, Kubernetes dapat secara otomatis mengelola deployment, scaling, dan maintenance aplikasi berbasis container dengan efisien.
Dalam arsitektur Kubernetes Nodes, terdapat beberapa komponen penting yang memastikan aplikasi berjalan dengan baik di setiap Node. Salah satu komponen utama adalah kubelet, yang berjalan di setiap Node dan bertanggung jawab untuk memastikan bahwa aplikasi atau pod yang dijadwalkan oleh kube-scheduler benar-benar berjalan sesuai instruksi. Kubelet akan terus memantau status container dan berkomunikasi dengan kube-apiserver untuk melaporkan kondisi Node.
Selain itu, terdapat kube-proxy, yang juga berjalan di setiap Node dan berfungsi sebagai proxy jaringan. Komponen ini bertugas menangani lalu lintas jaringan yang masuk ke aplikasi, mengelola routing antar-pod, serta bertindak sebagai load balancer sederhana untuk mendistribusikan trafik ke container yang sesuai.
Komponen penting lainnya adalah container manager, yang bertanggung jawab dalam mengelola container yang berjalan di dalam Node. Kubernetes mendukung berbagai container runtime, seperti Docker, containerd, cri-o, rktlet, dan lainnya. Dengan fleksibilitas ini, Kubernetes dapat berjalan pada berbagai lingkungan dan tetap kompatibel dengan berbagai teknologi container yang tersedia.
Untuk menjalankan Kubernetes di lingkungan lokal, terdapat beberapa metode yang dapat digunakan sesuai dengan kebutuhan dan preferensi pengguna. Salah satu cara yang paling praktis adalah menggunakan Docker Desktop, yang sudah memiliki fitur bawaan untuk menjalankan Kubernetes tanpa konfigurasi tambahan. Metode ini cocok bagi pengembang yang ingin mengelola container dengan mudah dalam satu ekosistem.
Alternatif lain adalah menggunakan Minikube, yang memungkinkan pengguna untuk menjalankan Kubernetes Cluster secara lokal dalam satu Node. Minikube membutuhkan virtualisasi seperti VirtualBox atau Hyper-V untuk menjalankan mesin virtual yang mensimulasikan lingkungan Kubernetes. Dengan Minikube, pengguna dapat menguji dan mengembangkan aplikasi berbasis Kubernetes tanpa harus memiliki infrastruktur cloud yang sebenarnya.
Dengan berbagai pilihan ini, pengembang dapat dengan mudah menyiapkan Kubernetes Cluster di lingkungan lokal untuk keperluan pengembangan, pengujian, dan eksplorasi fitur Kubernetes sebelum menerapkannya di lingkungan produksi.
kubectl adalah command-line interface (CLI) utama yang digunakan untuk berinteraksi dengan Kubernetes Cluster. Dengan kubectl, pengguna dapat melakukan berbagai operasi seperti mendeploy aplikasi, mengelola resource, memantau status cluster, serta melakukan debugging pada pod dan service yang berjalan. Perintah kubectl berkomunikasi langsung dengan kube-apiserver, sehingga memungkinkan pengguna untuk mengontrol dan mengotomatisasi pengelolaan Kubernetes dari terminal. Beberapa perintah umum yang sering digunakan meliputi kubectl get pods
untuk melihat daftar pod yang berjalan, kubectl apply -f <file>.yaml
untuk menerapkan konfigurasi berbasis YAML, serta kubectl logs <pod>
untuk melihat log dari container dalam pod tertentu. Dengan fleksibilitas dan kemudahan penggunaannya, kubectl menjadi alat yang sangat penting bagi administrator dan developer dalam mengelola aplikasi berbasis Kubernetes secara efisien.
Dalam ekosistem Kubernetes, Node adalah komponen fundamental yang berfungsi sebagai worker machine tempat aplikasi berjalan. Dahulu, Node sempat disebut sebagai Minion, namun kini istilah tersebut tidak lagi digunakan. Sebuah Node dapat berupa mesin fisik (bare metal) atau virtual machine (VM), tergantung pada infrastruktur yang digunakan, baik di cloud, on-premise, maupun hybrid cloud.
Setiap Node dalam Kubernetes Cluster memiliki beberapa komponen utama yang memungkinkan operasional aplikasi berbasis container berjalan dengan baik. kubelet adalah agen yang berjalan di setiap Node dan bertanggung jawab untuk memastikan bahwa semua container yang dijadwalkan berjalan sesuai perintah dari kube-scheduler. kube-proxy berfungsi sebagai pengelola jaringan, menangani lalu lintas data antar-pod serta berperan sebagai load balancer sederhana yang mengarahkan request ke container yang tepat. Selain itu, setiap Node juga memiliki container manager, yang bertugas menjalankan dan mengelola container. Kubernetes mendukung berbagai container runtime seperti Docker, containerd, cri-o, dan rktlet, memberikan fleksibilitas dalam pengelolaan aplikasi berbasis container.
Dalam sebuah Kubernetes Cluster, bisa terdapat banyak Node, dan setiap Node dapat menjalankan beberapa pod secara bersamaan. Dengan desain ini, Kubernetes mampu mendistribusikan beban kerja secara otomatis, memastikan aplikasi berjalan dengan efisien, terisolasi, dan scalable, baik dalam skala kecil maupun besar.
Dalam Kubernetes, Pod adalah unit terkecil yang dapat dideploy dalam sebuah Kubernetes Cluster. Pod berfungsi sebagai wadah yang menampung satu atau lebih container, serta menyediakan lingkungan eksekusi yang dibutuhkan agar container dapat berjalan dengan optimal. Secara sederhana, Pod dapat dianggap sebagai aplikasi yang sedang berjalan di Kubernetes Cluster, di mana setiap Pod memiliki IP Address sendiri, serta berbagi jaringan dan penyimpanan antar-container dalam Pod yang sama.
Salah satu pertanyaan umum adalah mengapa Kubernetes tidak langsung menggunakan container, melainkan Pod? Alasannya adalah karena Kubernetes dirancang untuk mengelola aplikasi dalam skala besar, dan Pod memberikan fleksibilitas lebih dalam mengatur berbagai komponen aplikasi. Misalnya, dalam skenario sidecar pattern, sebuah Pod dapat menjalankan lebih dari satu container yang saling bekerja sama. Sebagai contoh, satu container bisa bertindak sebagai aplikasi utama, sementara container lainnya bisa digunakan untuk logging, monitoring, atau proxy untuk meningkatkan keamanan dan efisiensi komunikasi antar-komponen.
Dengan konsep ini, Pod memungkinkan isolasi yang lebih baik, mempermudah pengelolaan lifecycle aplikasi, serta mendukung berbagai pola arsitektur modern seperti microservices. Kubernetes juga mengelola Pod secara otomatis, menangani penjadwalan, scaling, serta self-healing ketika terjadi kegagalan, sehingga aplikasi dapat berjalan dengan stabil dan efisien.
Dalam Kubernetes, Pod adalah unit terkecil yang dapat dijalankan. Pod terdiri dari satu atau lebih container yang berbagi sumber daya dan jaringan, serta dijadwalkan bersama pada node yang sama. Pod memungkinkan kontainer yang saling bergantung untuk beroperasi sebagai satu kesatuan. Contoh klasik adalah Pod yang berisi web server dan sinkronisasi Git, yang berbagi sistem file.
Mengapa Memisahkan Kontainer ke dalam Pod?
Isolasi Sumber Daya: Kontainer dengan kebutuhan sumber daya berbeda (mis., memori) dipisahkan untuk mencegah konflik. Contoh: Web server membutuhkan prioritas tinggi, sedangkan Git synchronizer bersifat "best effort".
Keterikatan Lokasi: Kontainer yang saling bergantung (mis., berbagi filesystem) harus dijadwalkan pada node yang sama.
Manajemen Siklus Hidup: Pod memastikan kontainer di dalamnya dimulai, dijalankan, dan dihentikan bersama.
Struktur Pod
Setiap kontainer dalam Pod berjalan di cgroup terpisah tetapi berbagi namespace Linux (jaringan, UTS, IPC).
Pod memiliki alamat IP dan hostname yang sama.
Kontainer dalam Pod berbeda diisolasi sepenuhnya dari Pod lain, meski berada di node yang sama.
Pertimbangan Desain Pod
Jika kontainer tidak bisa berjalan di node yang berbeda, mereka harus berada dalam Pod yang sama.
Contoh antipattern: Menempatkan WordPress dan MySQL dalam satu Pod, karena keduanya bisa di-scale secara terpisah.
1. Cgroups (Control Groups)
Cgroups adalah fitur kernel Linux untuk mengontrol, membatasi, dan mengisolasi penggunaan sumber daya (CPU, memori, disk I/O, jaringan, dll.) oleh sekelompok proses. Cgroups memungkinkan administrator sistem atau aplikasi (seperti Kubernetes) mengatur alokasi sumber daya secara granular.
Fungsi Utama Cgroups:
Membatasi Sumber Daya: Misalnya, membatasi penggunaan CPU suatu container maksimal 50% dari total CPU host.
Prioritas Alokasi: Memberikan prioritas lebih tinggi pada proses tertentu (mis., aplikasi kritis).
Monitoring: Melacak konsumsi sumber daya (mis., memori yang digunakan oleh sebuah container).
Isolasi: Mencegah proses dalam satu grup memengaruhi proses lain di grup berbeda.
Subsistem Cgroups:
Setiap subsistem mengatur jenis sumber daya tertentu:
cpu
: Mengatur alokasi CPU.
memory
: Membatasi penggunaan memori.
blkio
: Mengontrol akses I/O ke block devices (disk).
devices
: Membatasi akses ke perangkat fisik (mis., USB).
net_cls
: Mengatur prioritas traffic jaringan.
Contoh Implementasi:
Di Kubernetes, resource limits
dan requests
pada Pod menggunakan cgroups untuk membatasi CPU/memori.
File konfigurasi cgroups biasanya terletak di /sys/fs/cgroup/
.
2. Namespaces
Namespaces adalah fitur kernel Linux untuk mengisolasi lingkungan sistem (filesystem, jaringan, proses, dll.) agar proses dalam namespace tidak dapat melihat atau mengakses proses di namespace lain. Ini adalah dasar dari teknologi containerisasi (seperti Docker).
Jenis-Jenis Namespaces:
PID (Process ID) Namespace:
Mengisolasi ID proses.
Proses dalam container memiliki PID sendiri (dimulai dari 1), tidak terlihat dari host.
Mount Namespace:
Mengisolasi filesystem.
Container memiliki direktori root (/
) sendiri, terpisah dari host.
UTS (Unix Timesharing System) Namespace:
Mengisolasi hostname dan domain.
Container bisa memiliki hostname berbeda dari host.
IPC (Inter-Process Communication) Namespace:
Mengisolasi komunikasi antar-proses (shared memory, semaphore).
Network Namespace:
Mengisolasi antarmuka jaringan, IP, port, dan routing table.
Container memiliki IP dan port sendiri.
User Namespace:
Mengisolasi ID pengguna (UID/GID).
Proses dalam container bisa memiliki ID pengguna berbeda dengan host.
Contoh Implementasi:
Saat membuat container Docker, setiap container memiliki namespace sendiri untuk PID, filesystem, jaringan, dll.
Dalam Pod Kubernetes, container dalam satu Pod berbagi beberapa namespace (mis., Network dan UTS), sehingga bisa berkomunikasi via localhost
dan berbagi hostname.
Perbedaan Cgroups vs. Namespaces
Aspek
Cgroups
Namespaces
Tujuan
Mengontrol sumber daya
Mengisolasi lingkungan sistem
Fokus
CPU, memori, I/O
Filesystem, jaringan, PID, dll.
Implementasi
Membatasi/memonitor penggunaan
Membuat "pandangan" sistem terpisah
Contoh Kasus
Membatasi memori container ke 1 GB
Container tidak melihat proses host
Kombinasi Cgroups dan Namespaces dalam Container
Keduanya bekerja sama untuk menciptakan lingkungan yang terisolasi dan terkontrol:
Namespaces mengisolasi proses, jaringan, dan filesystem container.
Cgroups membatasi sumber daya yang digunakan container (mis., CPU/memori).
Contoh:
Saat menjalankan Docker container:
Namespace membuat "dunia terpisah" untuk container.
Cgroups memastikan container tidak menggunakan sumber daya berlebihan.
Pentingnya dalam Kubernetes
Pod:
Container dalam Pod berbagi Network dan UTS namespace, sehingga bisa berkomunikasi via localhost
dan memiliki hostname yang sama.
Resource Management:
Kubernetes menggunakan cgroups untuk menerapkan resource limits
dan requests
pada container.
Isolasi: Namespaces memastikan Pod tidak saling mengganggu (mis., proses di Pod A tidak bisa melihat proses di Pod B).
Cgroups (Membatasi CPU):
bashCopy
Namespaces (Membuat PID namespace):
bashCopy
Cgroups = Kontrol sumber daya (seberapa banyak yang boleh digunakan).
Namespaces = Isolasi lingkungan (apa yang bisa dilihat/diakses).
Keduanya adalah fondasi containerisasi modern, memungkinkan aplikasi berjalan secara efisien, terisolasi, dan aman di lingkungan bersama seperti Kubernetes.
Cara termudah untuk membuat Pod adalah melalui perintah imperatif kubectl run. Misalnya, untuk menjalankan server kuard yang sama, gunakan:
Anda dapat melihat status Pod ini dengan menjalankan:
Pada awalnya, Anda mungkin melihat kontainer sebagai Pending, tetapi akhirnya Anda akan melihatnya beralih ke Running, yang berarti Pod dan kontainernya telah berhasil dibuat.
Untuk saat ini, Anda dapat menghapus Pod ini dengan menjalankan:
Kita sekarang akan melanjutkan untuk menulis manifes Pod lengkap secara manual.
1. Manifest Pod
Pod didefinisikan dalam manifest YAML/JSON yang mendeklarasikan konfigurasi desired state. Contoh manifest dasar:
2. Perintah Dasar
Membuat Pod
Melihat Status Pod
Detail Pod
Menghapus Pod Declarative Way
Menghapus Pod
Melihat log
Tambahkan flag -f
untuk menunggu stream dari log secara berkelanjutan.
Menjalankan Perintah linux di container menggunakan exec
Kubelet menggunakan liveness probe untuk mengecek kapan perlu me-restart Pod. Misal saat liveness probe pada Pod tidak merespon kubelet akan secara otomatis me-restart Pod. Kubelet menggunakan readiness probe untuk mengecek apakah Pod siap menerima traffic. Kubelet menggunakan startup probe untuk mengecek apakah Pod sudah berjalan, Jika belum berjalan, maka kubelet tidak akan melakukan pengecekan liveness dan readiness. Startup probe cocok untuk Pod yang membutuhkan proses startup lama, ini dapat digunakan untuk memastikan Pod tidak mati oleh kubelet sebelum selesai berjalan dengan sempurna.
Berikut konfigurasi probe:
initialDelaySeconds
, waktu setelah container jalan dan dilakukan pengecekan, default nya 0
periodSeconds
, seberapa sering pengecekan dilakukan, default nya 10
timeoutSeconds
, waktu timeout ketika pengecekan gagal, default 1
successThreshold
, minimum dianggap sukses setelah berstatus failure, default 1
failureThreshold
, minimum dianggap gagal, default 3
1. Liveness Probe
Memastikan aplikasi berjalan sehat. Jika gagal, kontainer di-restart. Contoh konfigurasi:
2. Readiness Probe
Memastikan Pod siap menerima traffic. Jika gagal, Pod dihapus dari load balancer.
3. Startup Probe
Digunakan untuk aplikasi yang lambat memulai. Probe ini berjalan sebelum liveness atau readiness.
Jenis Health Check Lainnya
TCP Socket: Membuka koneksi ke port tertentu.
Exec: Mengeksekusi perintah dalam kontainer (exit code 0 = sukses).
1. Permintaan Sumber Daya (Requests)
Menentukan minimum sumber daya yang dijamin untuk Pod. Contoh:
2. Batas Sumber Daya (Limits)
Membatasi penggunaan maksimum sumber daya.
CPU: Diatur menggunakan cpu-shares di Linux.
Memori: Jika melebihi batas, kontainer dihentikan dan di-restart.
Jenis Volume
emptyDir: Penyimpanan sementara yang terhapus saat Pod dihapus.
hostPath: Mengakses direktori pada host (mis., /var/lib/kuard
).
Persistent Volume (PV): Penyimpanan jaringan (NFS, cloud storage) yang bertahan meski Pod dihapus.
Contoh konfigurasi:
Pod adalah unit dasar di Kubernetes untuk menjalankan kontainer yang saling terkait.
Health checks (liveness, readiness, startup) memastikan aplikasi berjalan optimal.
Manajemen sumber daya (requests dan limits) mengoptimalkan penggunaan cluster.
Volume memungkinkan penyimpanan data persisten atau berbagi data antar kontainer.
Dalam Kubernetes, Label adalah mekanisme penting yang digunakan untuk menandai dan mengorganisir resource dalam cluster. Label berbentuk key-value pair yang dapat diterapkan pada Pod, Replication Controller, Replica Set, Service, serta berbagai resource lainnya. Dengan adanya label, pengguna dapat mengelompokkan dan mengidentifikasi resource berdasarkan kriteria tertentu, seperti nama aplikasi, lingkungan (development, staging, production), versi aplikasi, atau tim yang bertanggung jawab.
Label juga mempermudah pengelolaan dan pemilihan resource dalam Kubernetes. Misalnya, saat menerapkan Service atau Replica Set, Kubernetes dapat menggunakan Label Selector untuk secara otomatis menemukan dan mengatur resource yang memiliki label tertentu. Selain itu, label juga berguna dalam monitoring, logging, dan debugging, karena memungkinkan pengguna menambahkan informasi tambahan tanpa mengubah konfigurasi utama dari resource yang ada.
Dengan fleksibilitas dan kemudahan penggunaannya, Label menjadi elemen penting dalam mengelola arsitektur Kubernetes yang dinamis, membantu dalam deployment yang lebih terstruktur, pemeliharaan yang lebih mudah, serta pengelolaan aplikasi dalam skala besar dengan lebih efisien.
Production tidak menyukai singleton. Ketika pengguna pertama kali menerapkan perangkat lunak, mereka sering memulai dengan satu instance. Namun, seiring dengan perkembangan aplikasi, instance tersebut berkembang menjadi sekumpulan objek. Oleh karena itu, Kubernetes menggunakan label untuk menangani sekumpulan objek, bukan hanya satu instance.
Hierarki yang dipaksakan oleh sistem sering kali tidak cukup fleksibel. Selain itu, pengelompokan dan hierarki pengguna dapat berubah seiring waktu. Misalnya, seorang pengguna awalnya menganggap bahwa semua aplikasi terdiri dari berbagai layanan. Namun, dalam perkembangannya, layanan tertentu dapat digunakan bersama oleh beberapa aplikasi. Label Kubernetes cukup fleksibel untuk menyesuaikan dengan perubahan ini.
Untuk referensi lebih lanjut, buku Site Reliability Engineering oleh Betsy Beyer et al. (O’Reilly) membahas lebih dalam tentang pendekatan Google terhadap sistem produksi.
Label dalam Kubernetes memiliki sintaks sederhana berupa pasangan key/value, di mana baik key maupun value direpresentasikan sebagai string. Struktur label terdiri dari dua bagian: prefix opsional dan name wajib, yang dipisahkan oleh garis miring (/
).
Jika ada prefix, maka harus dalam format subdomain DNS dengan batasan maksimal 253 karakter.
Key wajib ada dan memiliki panjang maksimal 63 karakter.
Key harus diawali dan diakhiri dengan karakter alfanumerik serta dapat mengandung tanda hubung (-
), garis bawah (_
), dan titik (.
) di antara karakter.
Value label merupakan string dengan panjang maksimal 63 karakter dan mengikuti aturan yang sama seperti key.
Contoh key dan value label yang valid:
Key
Value
acme.com/app-version
1.0.0
appVersion
1.0.0
app.version
1.0.0
kubernetes.io/cluster-service
true
Ketika nama domain digunakan dalam label dan anotasi, domain tersebut seharusnya terkait dengan entitas tertentu. Misalnya, suatu proyek dapat mendefinisikan serangkaian label standar untuk mengidentifikasi tahap penerapan aplikasi seperti staging, canary, dan production. Atau, penyedia layanan cloud dapat mendefinisikan anotasi spesifik yang memperluas objek Kubernetes untuk mengaktifkan fitur tertentu dalam layanan mereka.
Dalam Kubernetes, Annotation adalah mekanisme yang mirip dengan Label, namun memiliki perbedaan utama dalam penggunaannya. Jika Label digunakan untuk mengorganisir dan melakukan filtering resource dalam cluster, Annotation lebih berfokus pada penyimpanan informasi tambahan yang tidak mempengaruhi seleksi atau pemilihan resource.
Annotation biasanya digunakan untuk menyimpan metadata dalam jumlah besar, seperti informasi versi build, sumber konfigurasi, checksum, atau catatan debugging yang mungkin dibutuhkan oleh alat eksternal atau sistem monitoring. Tidak seperti label yang terbatas dalam ukuran dan lebih bersifat struktural, annotation dapat menampung informasi hingga 256KB, memungkinkan penyimpanan detail yang lebih kaya tanpa membebani sistem inti Kubernetes.
Dengan adanya Annotation, Kubernetes memungkinkan penyimpanan informasi deskriptif yang dapat membantu dalam pemeliharaan, auditing, dan integrasi dengan sistem eksternal, tanpa mempengaruhi mekanisme penjadwalan atau seleksi resource di dalam cluster.
Kubernetes adalah sistem yang sangat dinamis. Sistem bertanggung jawab untuk menempatkan Pod pada node, memastikan bahwa Pod berjalan dengan baik, serta menjadwal ulang Pod jika diperlukan. Selain itu, Kubernetes menyediakan mekanisme untuk secara otomatis menyesuaikan jumlah Pod berdasarkan beban kerja, seperti yang dilakukan oleh Horizontal Pod Autoscaler.
Sifat Kubernetes yang berbasis API memungkinkan tingkat otomatisasi yang semakin tinggi. Namun, meskipun sifat dinamis ini memudahkan dalam menjalankan berbagai layanan, hal ini juga menimbulkan tantangan dalam menemukan dan mengakses layanan tersebut. Infrastruktur jaringan tradisional umumnya tidak dirancang untuk menangani tingkat dinamisme seperti yang ada di Kubernetes.
Istilah service discovery mengacu pada serangkaian masalah dan solusi terkait pencarian proses mana yang mendengarkan pada alamat tertentu untuk layanan tertentu. Alat service discovery membantu menyelesaikan masalah dalam menemukan layanan dengan memastikan informasi ini dapat diakses dengan cepat dan andal.
Sistem service discovery yang baik memiliki beberapa karakteristik utama:
Low-latency – Klien dapat segera mendapatkan pembaruan saat ada perubahan pada informasi layanan.
Penyimpanan informasi yang lebih kaya – Sistem dapat menyimpan lebih banyak detail tentang layanan, misalnya jika layanan tersebut menggunakan beberapa port sekaligus.
Secara tradisional, sistem yang digunakan untuk service discovery di internet adalah Domain Name System (DNS). DNS dirancang untuk resolusi nama yang stabil dengan caching yang luas dan efisien, menjadikannya sangat cocok untuk internet. Namun, DNS memiliki keterbatasan dalam lingkungan Kubernetes yang dinamis.
Beberapa tantangan dalam menggunakan DNS untuk service discovery di Kubernetes:
Banyak aplikasi (misalnya, Java secara default) hanya melakukan lookup nama di DNS sekali dan tidak memperbarui hasilnya. Ini bisa menyebabkan klien menyimpan alamat lama dan menghubungi IP yang salah.
Meskipun DNS memiliki TTL (time-to-live) pendek, tetap ada jeda alami antara perubahan alamat layanan dan waktu klien menyadarinya.
DNS memiliki keterbatasan dalam jumlah dan jenis informasi yang dapat dikembalikan dalam satu query. Jika terdapat lebih dari 20–30 A record untuk satu nama, sistem mulai mengalami kendala.
SRV record dapat menyelesaikan beberapa masalah ini, tetapi sering kali sulit digunakan.
Klien biasanya hanya mengambil IP pertama dari daftar hasil DNS, bergantung pada server DNS untuk merandomisasi atau melakukan round-robin. Pendekatan ini tidak sebaik metode load balancing yang lebih spesifik.
Karena tantangan ini, Kubernetes membutuhkan mekanisme service discovery yang lebih fleksibel dan dinamis dibandingkan dengan DNS tradisional.
Service discovery di Kubernetes dimulai dengan objek Service. Objek Service memungkinkan kita untuk membuat sebuah selector berbasis label yang memiliki nama unik. Selain itu, Service juga menyediakan fitur tambahan yang mempermudah komunikasi antar layanan dalam cluster.
kubectl expose
Sama seperti perintah kubectl run
yang memudahkan pembuatan Deployment, kita bisa menggunakan kubectl expose
untuk membuat Service dari suatu Deployment. Dalam konteks Kubernetes, Deployment adalah cara untuk menjalankan sebuah microservice dengan replikasi yang dapat diskalakan.
Mari kita coba membuat beberapa Deployment dan Service untuk memahami bagaimana ini bekerja:
Hasil dari perintah kubectl get services -o wide
menunjukkan tiga Service:
NAME
CLUSTER-IP
PORT(S)
SELECTOR
alpaca-prod
10.115.245.13
8080/TCP
app=alpaca
bandicoot-prod
10.115.242.3
8080/TCP
app=bandicoot
kubernetes
10.115.240.1
443/TCP
<none>
Dua Service yang baru kita buat adalah alpaca-prod
dan bandicoot-prod
, sementara Service bernama kubernetes
sudah ada secara otomatis untuk memungkinkan aplikasi berkomunikasi dengan Kubernetes API.
Pada kolom SELECTOR, kita bisa melihat bahwa alpaca-prod
menggunakan selector app=alpaca
, sementara bandicoot-prod
menggunakan selector app=bandicoot
. Dengan cara ini, Kubernetes bisa menghubungkan setiap Service dengan Pod yang memiliki label yang sesuai.
Setiap Service yang dibuat di Kubernetes mendapatkan Cluster IP, yaitu alamat IP virtual yang hanya dapat diakses di dalam cluster. Cluster IP ini digunakan untuk melakukan load balancing secara otomatis ke semua Pod yang cocok dengan selector yang diberikan.
Untuk mengakses salah satu Pod dari Service yang kita buat, kita bisa menggunakan port-forwarding. Berikut cara mengakses salah satu Pod dari alpaca-prod
:
Sekarang, kita bisa mengakses layanan alpaca-prod di browser atau menggunakan curl
melalui alamat:
Dengan konsep Service ini, Kubernetes memungkinkan layanan dalam cluster dapat ditemukan dan diakses secara dinamis tanpa perlu mengetahui alamat IP dari setiap Pod secara manual.
Karena Cluster IP bersifat virtual dan stabil, Kubernetes memberikan alamat DNS untuk setiap Service. Dengan adanya DNS, masalah terkait caching DNS pada klien tidak lagi menjadi kendala. Di dalam satu namespace, klien cukup menggunakan nama Service untuk terhubung ke salah satu Pod yang terdaftar dalam Service tersebut.
Kubernetes menyediakan DNS Service yang secara otomatis tersedia untuk semua Pod dalam cluster. DNS Service ini sudah di instal sebagai komponen sistem saat cluster pertama kali dibuat dan dikelola langsung oleh Kubernetes.
DNS ini memungkinkan Cluster IP memiliki nama DNS, sehingga Service dapat diakses menggunakan nama Service daripada harus menggunakan IP Address yang mungkin berubah.
Misalnya, jika kita memiliki Service bernama alpaca-prod
, kita bisa melakukan query terhadap DNS Record-nya. Hasilnya mungkin terlihat seperti ini:
Mari kita uraikan struktur dari nama DNS ini:
Bagian
Keterangan
alpaca-prod
Nama Service di Kubernetes
default
Namespace tempat Service berada
svc
Menunjukkan bahwa ini adalah Service
cluster.local.
Domain dasar dalam cluster (dapat diubah oleh administrator)
Ketika ingin mengakses Service dari dalam cluster, kita bisa menggunakan berbagai format nama DNS:
Nama pendek (dalam namespace yang sama):
Nama dengan namespace (dari namespace berbeda):
Nama lengkap (Fully Qualified Domain Name - FQDN):
Dengan DNS bawaan Kubernetes ini, setiap Service dapat ditemukan dan digunakan dengan cara yang lebih fleksibel tanpa perlu mengetahui IP statisnya. Materi tentang services lebih lanjut kita bahas pada section lain.
Dalam Kubernetes, Namespace adalah fitur yang digunakan untuk membagi cluster menjadi beberapa lingkungan yang terisolasi secara logis. Namespace memungkinkan pengelolaan resource dalam skala besar dengan lebih rapi dan terorganisir, terutama ketika jumlah resource semakin banyak atau ketika ada kebutuhan untuk mendukung multi-tenant, tim yang berbeda, atau berbagai lingkungan seperti development, staging, dan production dalam satu cluster.
Salah satu keuntungan utama Namespace adalah memungkinkan resource dengan nama yang sama untuk eksis secara bersamaan tanpa konflik, selama berada di Namespace yang berbeda. Misalnya, dua tim yang mengembangkan aplikasi yang berbeda dapat memiliki Pod, Service, atau Deployment dengan nama yang sama, tetapi tetap berjalan secara terpisah dalam Namespace masing-masing.
Untuk mengelola Namespace dalam Kubernetes, tersedia beberapa perintah kubectl seperti:
kubectl get namespaces
atau kubectl get ns
untuk melihat daftar Namespace yang ada.
kubectl get pod --namespace <nama_namespace>
atau kubectl get pod -n <nama_namespace>
untuk melihat daftar Pod dalam Namespace tertentu.
Namespace sangat berguna dalam isolasi resource, pengelolaan akses berbasis tim, serta optimasi penggunaan sumber daya dalam Kubernetes Cluster. Dengan memanfaatkan Namespace, tim dapat lebih mudah mengatur resource tanpa harus membangun cluster Kubernetes yang terpisah untuk setiap lingkungan atau tim.
Dalam Kubernetes, kita telah membahas bagaimana menjalankan container individu sebagai Pod, tetapi Pod ini pada dasarnya bersifat tunggal dan berdiri sendiri. Dalam banyak kasus, kita sering kali membutuhkan beberapa replika dari suatu container yang berjalan secara bersamaan karena berbagai alasan. Redundansi diperlukan agar aplikasi tetap berjalan meskipun ada kegagalan, dengan menjalankan beberapa instance. Skalabilitas memungkinkan peningkatan kapasitas pemrosesan permintaan dengan menambahkan lebih banyak instance. Sharding memungkinkan setiap replika menangani bagian tertentu dari sebuah perhitungan secara paralel untuk meningkatkan efisiensi.
Tentu saja, kita bisa secara manual membuat beberapa Pod dengan manifest yang hampir serupa, tetapi pendekatan ini melelahkan dan rentan terhadap kesalahan. Secara logis, seorang pengguna yang mengelola sekumpulan Pod yang direplikasi akan menganggapnya sebagai satu entitas yang perlu didefinisikan dan dikelola secara kolektif—dan di sinilah ReplicaSet berperan. ReplicaSet bertindak sebagai pengelola Pod di seluruh klaster, memastikan bahwa jumlah dan jenis Pod yang tepat selalu berjalan sebagaimana mestinya.
Karena ReplicaSet memudahkan proses pembuatan dan pengelolaan kumpulan Pod yang direplikasi, ia menjadi komponen dasar dalam pola penerapan aplikasi yang umum serta dalam pembuatan aplikasi yang dapat menyembuhkan dirinya sendiri pada tingkat infrastruktur. Pod yang dikelola oleh ReplicaSet secara otomatis dijadwalkan ulang jika terjadi kegagalan, seperti kegagalan node atau pemutusan jaringan.
Cara termudah untuk memahami ReplicaSet adalah dengan membayangkannya seperti kombinasi antara cetakan kue dan jumlah kue yang diinginkan dalam satu objek API. Saat kita mendefinisikan ReplicaSet, kita menentukan spesifikasi untuk Pod yang ingin kita buat (sebagai "cetakan kue") serta jumlah replika yang diinginkan. Selain itu, kita juga harus mendefinisikan metode untuk mengidentifikasi Pod yang akan dikelola oleh ReplicaSet. Proses pengelolaan Pod yang direplikasi ini merupakan contoh dari reconciliation loop, yaitu mekanisme dasar yang mendasari sebagian besar desain dan implementasi Kubernetes.
Konsep utama di balik reconciliation loop adalah perbedaan antara desired state (keadaan yang diinginkan) dan current state (keadaan saat ini). Desired state adalah kondisi yang ingin kita capai. Dalam konteks ReplicaSet, ini mencakup jumlah replika yang diharapkan serta definisi dari Pod yang akan direplikasi. Misalnya, "desired state" bisa berupa "memiliki tiga replika dari Pod yang menjalankan kuard server." Sementara itu, current state adalah kondisi sistem yang sedang diamati saat ini. Contohnya, "current state" bisa berupa "hanya ada dua Pod kuard yang sedang berjalan."
Reconciliation loop terus berjalan secara otomatis, mengamati keadaan saat ini, dan mengambil tindakan yang diperlukan untuk menyesuaikan current state agar sesuai dengan desired state. Dalam contoh sebelumnya, jika hanya ada dua Pod kuard yang berjalan, reconciliation loop akan membuat satu Pod tambahan untuk memenuhi jumlah yang diinginkan, yaitu tiga replika.
Pendekatan reconciliation loop dalam manajemen state memiliki banyak keuntungan. Sistem ini bersifat goal-driven dan self-healing, yang berarti Kubernetes secara otomatis akan mengoreksi ketidaksesuaian tanpa perlu intervensi manual. Selain itu, implementasi konsep ini bisa sangat sederhana, bahkan dapat diekspresikan hanya dalam beberapa baris kode. Sebagai contoh, reconciliation loop dalam ReplicaSet hanyalah satu loop, tetapi mampu menangani berbagai skenario, seperti peningkatan atau pengurangan jumlah replika berdasarkan perintah pengguna, serta pemulihan otomatis saat terjadi kegagalan node atau ketika sebuah node yang sempat offline kembali bergabung ke dalam klaster.
Konsep reconciliation loop ini menjadi dasar dari banyak mekanisme otomatisasi dalam Kubernetes, dan kita akan melihat berbagai contoh penerapannya di bagian-bagian selanjutnya.
Salah satu prinsip utama dalam Kubernetes adalah decoupling atau pemisahan antar komponen. Setiap konsep inti dalam Kubernetes dirancang agar bersifat modular, dapat diganti, dan tidak bergantung secara ketat satu sama lain. Dalam konteks ini, hubungan antara ReplicaSet dan Pod juga bersifat loosely coupled atau tidak terikat erat. Meskipun ReplicaSet bertanggung jawab untuk membuat dan mengelola Pod, ia tidak memiliki Pod yang dibuatnya secara langsung. Sebagai gantinya, ReplicaSet menggunakan label queries untuk mengidentifikasi kumpulan Pod yang harus dikelolanya.
Ketika ReplicaSet membuat Pod, ia menggunakan API yang sama dengan yang dapat digunakan secara langsung oleh pengguna. Pendekatan ini disebut "coming in the front door", yang merupakan salah satu konsep desain utama dalam Kubernetes. Selain itu, hubungan antara ReplicaSet yang membuat beberapa Pod dan Service yang mendistribusikan lalu lintas ke Pod tersebut juga sepenuhnya terpisah. Kedua komponen ini adalah objek API yang berdiri sendiri dan tidak saling bergantung.
Pemisahan ini bukan hanya untuk menjaga modularitas, tetapi juga memungkinkan beberapa perilaku penting yang akan dibahas lebih lanjut di bagian berikutnya.
Meskipun konfigurasi deklaratif sangat berguna, ada situasi di mana pendekatan imperatif lebih mudah diterapkan. Misalnya, pada tahap awal, Anda mungkin hanya menjalankan satu Pod dengan sebuah container image tanpa dikelola oleh ReplicaSet. Bahkan, Anda mungkin juga telah menetapkan load balancer untuk mengarahkan lalu lintas ke Pod tunggal tersebut.
Namun, seiring waktu, kebutuhan untuk mengubah container tunggal menjadi layanan yang terduplikasi bisa muncul, sehingga Anda perlu mengelola beberapa instance container yang serupa. Jika ReplicaSet memiliki kepemilikan penuh atas Pod yang dibuatnya, maka satu-satunya cara untuk mulai mereplikasi Pod adalah dengan menghapusnya dan menjalankannya kembali melalui ReplicaSet. Pendekatan ini bisa menyebabkan gangguan karena ada kemungkinan tidak ada instance yang berjalan selama transisi.
Untungnya, karena ReplicaSet tidak secara langsung memiliki Pod yang dikelolanya, Anda bisa cukup dengan membuat ReplicaSet baru yang akan mengadopsi Pod yang sudah ada dan secara otomatis menambahkan lebih banyak salinan container tersebut. Dengan cara ini, Anda dapat dengan mulus beralih dari Pod tunggal yang dibuat secara imperatif menjadi kumpulan Pod terduplikasi yang dikelola oleh ReplicaSet.
ReplicaSet dirancang untuk mewakili satu layanan mikro (microservice) yang dapat diskalakan dalam arsitektur aplikasi Anda. Ciri utama dari ReplicaSet adalah setiap Pod yang dibuat oleh kontrolernya bersifat homogen, artinya semua Pod yang dikelola memiliki konfigurasi yang sama. Biasanya, ReplicaSet digunakan bersama dengan service load balancer di Kubernetes, yang bertugas mendistribusikan lalu lintas ke semua Pod dalam layanan tersebut.
Secara umum, ReplicaSet lebih cocok digunakan untuk layanan stateless atau hampir stateless. Hal ini karena setiap Pod yang dibuatnya bersifat saling menggantikan. Saat ReplicaSet mengalami skala turun (scale down), pemilihan Pod yang akan dihapus dilakukan secara acak. Oleh karena itu, perilaku aplikasi tidak boleh bergantung pada keberadaan Pod tertentu agar tidak terpengaruh saat proses penskalaan terjadi.
Dalam praktiknya, sebagian besar aplikasi tidak menggunakan ReplicaSet secara langsung, melainkan menggunakan Deployment. Deployment menawarkan kontrol lebih lanjut, seperti kemampuan untuk mengelola perilisan versi baru dari aplikasi. Namun, di balik layar, Deployment menggunakan ReplicaSet untuk menjalankan dan mengelola Pod. Oleh karena itu, memahami cara kerja ReplicaSet sangat penting, terutama jika Anda perlu melakukan debugging atau troubleshooting dalam sistem Kubernetes Anda.
Seperti semua objek di Kubernetes, ReplicaSet didefinisikan menggunakan spesifikasi (spec). Setiap ReplicaSet harus memiliki nama unik, yang ditentukan dalam metadata.name. Selain itu, spesifikasi ReplicaSet mencakup jumlah Pod (replicas) yang harus berjalan dalam klaster, serta template Pod yang digunakan untuk membuat Pod baru jika jumlah yang diinginkan belum terpenuhi.
Berikut adalah contoh minimal dari definisi ReplicaSet dalam file YAML:
Dalam contoh di atas, terdapat tiga bagian utama yang penting untuk dipahami:
replicas – Menentukan jumlah Pod yang diinginkan dalam klaster, dalam hal ini 1.
selector – Mendefinisikan label yang digunakan untuk mencocokkan Pod yang dikelola oleh ReplicaSet ini.
template – Menentukan spesifikasi Pod, termasuk metadata dan konfigurasi kontainer yang akan dijalankan.
Setiap kali jumlah Pod dalam klaster berkurang dari jumlah yang ditentukan di dalam replicas, ReplicaSet akan secara otomatis membuat Pod baru menggunakan template yang telah ditetapkan.
Seperti yang telah disebutkan sebelumnya, jika jumlah Pod dalam keadaan saat ini lebih sedikit dari jumlah yang diinginkan, ReplicaSet controller akan membuat Pod baru menggunakan template yang terdapat dalam spesifikasi ReplicaSet.
Pod yang dibuat melalui ReplicaSet pada dasarnya sama seperti ketika kita membuat Pod secara manual dari file YAML. Namun, alih-alih mengajukan permintaan secara manual, Kubernetes ReplicaSet controller akan membuat dan mengirimkan manifest Pod berdasarkan template langsung ke API server.
Berikut adalah contoh template Pod dalam sebuah ReplicaSet:
Dalam template ini, terdapat beberapa elemen penting:
metadata.labels – Label digunakan untuk mencocokkan Pod yang dikelola oleh ReplicaSet.
spec.containers – Menentukan kontainer yang akan dijalankan dalam Pod, termasuk nama, image, dan port yang digunakan.
Setiap kali ReplicaSet perlu membuat Pod baru, ia akan menggunakan template ini untuk menghasilkan Pod yang identik dan mendaftarkannya ke dalam klaster Kubernetes.
Dalam sebuah klaster Kubernetes yang cukup besar, terdapat banyak Pod yang berjalan secara bersamaan. Lalu, bagaimana ReplicaSet mengetahui sekumpulan Pod yang harus dikelolanya?
ReplicaSet menggunakan label Pod untuk menyaring daftar Pod dalam klaster dan melacak Pod yang sedang berjalan. Ketika ReplicaSet pertama kali dibuat, ia akan mengambil daftar Pod dari Kubernetes API dan menyaringnya berdasarkan label. Berdasarkan jumlah Pod yang ditemukan, ReplicaSet akan menghapus atau membuat Pod baru agar jumlahnya sesuai dengan jumlah replica yang diinginkan.
Label yang digunakan untuk menyaring Pod ini didefinisikan dalam spesifikasi ReplicaSet dan merupakan kunci utama dalam cara kerja ReplicaSet.
Penting: Selector dalam spesifikasi ReplicaSet harus merupakan subset dari label yang terdapat dalam Pod template.
ReplicaSet dibuat dengan mengirimkan objek ReplicaSet ke API Kubernetes. Pada bagian ini, kita akan membuat ReplicaSet menggunakan file konfigurasi dan perintah kubectl apply
.
File konfigurasi ReplicaSet dibawah akan memastikan bahwa satu salinan dari kontainer gcr.io/kuar-demo/kuard-amd64:green
berjalan pada setiap waktu. Gunakan perintah kubectl apply
untuk mengirimkan ReplicaSet kuard ke API Kubernetes:
Setelah ReplicaSet kuard diterima, controller ReplicaSet akan mendeteksi bahwa tidak ada Pod kuard yang berjalan sesuai dengan keadaan yang diinginkan dan akan membuat Pod kuard baru berdasarkan isi template Pod:
Seperti halnya Pods dan objek API Kubernetes lainnya, jika Anda tertarik untuk melihat detail lebih lanjut tentang sebuah ReplicaSet, Anda dapat menggunakan perintah describe
untuk memberikan informasi lebih banyak tentang statusnya. Berikut adalah contoh penggunaan perintah describe
untuk mendapatkan detail dari ReplicaSet yang telah kita buat sebelumnya:
Anda dapat melihat label selector untuk ReplicaSet tersebut, serta status dari semua replica yang dikelola olehnya.
Terkadang Anda mungkin bertanya-tanya apakah sebuah Pod dikelola oleh ReplicaSet, dan jika iya, oleh ReplicaSet yang mana. Untuk memungkinkan penemuan seperti ini, controller ReplicaSet menambahkan bagian ownerReferences
pada setiap Pod yang dibuatnya. Jika Anda menjalankan perintah berikut, carilah bagian ownerReferences
:
Jika berlaku, perintah ini akan menampilkan nama ReplicaSet yang mengelola Pod tersebut.
Anda juga dapat menentukan sekelompok Pod yang dikelola oleh sebuah ReplicaSet. Pertama, ambil sekumpulan label menggunakan perintah kubectl describe
. Pada contoh sebelumnya, selector labelnya adalah app=kuard,version=2
. Untuk menemukan Pod yang cocok dengan selector ini, gunakan flag --selector
atau shorthand -l
:
Ini adalah kueri yang sama persis yang dijalankan oleh ReplicaSet untuk menentukan jumlah Pod yang sedang berjalan saat ini.
Secara umum, Replica Set memiliki fungsi yang hampir sama dengan Replication Controller, yaitu menjaga jumlah replika Pod agar tetap sesuai dengan yang diinginkan. Namun, perbedaan utama antara keduanya terletak pada mekanisme label selector yang digunakan. Replication Controller hanya mendukung match labels, yang berarti setiap Pod yang dikelola harus memiliki label yang sesuai secara langsung. Sementara itu, Replica Set memiliki label selector yang lebih ekspresif, yang memungkinkan penggunaan match expressions, sehingga memberikan fleksibilitas lebih dalam menentukan Pod yang akan dikelola. Dengan fitur ini, pengguna dapat membuat aturan seleksi yang lebih kompleks berdasarkan kondisi tertentu, menjadikan Replica Set sebagai pilihan yang lebih canggih dan fleksibel dalam mengelola replikasi Pod.
Sebelumnya, jika diperhatikan, untuk selector di Replication Set kita menggunakan matchLabels, yang artinya selector tersebut cara kerjanya match (sama seperti di ReplicationController). Selain menggunakan matchLabels, operasi lain yang bisa digunakan pada selector di Replication Set adalah menggunakan matchExpression.
In, value label harus ada di value in
NotIn, value label tidak boleh ada di value in
Exists, label harus ada
NotExists, label tidak boleh ada
Anda dapat menskalakan ReplicaSet ke atas atau ke bawah dengan memperbarui kunci spec.replicas
pada objek ReplicaSet yang disimpan di Kubernetes. Saat Anda menskalakan ReplicaSet ke atas, Kubernetes akan mengirimkan Pod baru menggunakan template Pod yang didefinisikan pada ReplicaSet.
Skalasi Imperatif dengan kubectl scale
Cara termudah untuk mencapai hal ini adalah dengan menggunakan perintah scale
pada kubectl. Misalnya, untuk menskalakan menjadi empat salinan, Anda dapat menjalankan:
Meskipun perintah imperatif seperti ini berguna untuk demonstrasi dan reaksi cepat dalam situasi darurat (misalnya, peningkatan beban secara mendadak), penting untuk juga memperbarui konfigurasi file teks agar sesuai dengan jumlah salinan yang Anda atur melalui perintah scale
imperatif. Alasan untuk ini menjadi jelas ketika Anda mempertimbangkan skenario berikut.
Alice sedang bertugas jaga, ketika tiba-tiba ada peningkatan beban yang besar pada layanan yang dia kelola. Alice menggunakan perintah scale
untuk meningkatkan jumlah server yang merespons permintaan menjadi 10, dan situasi pun terselesaikan. Namun, Alice lupa untuk memperbarui konfigurasi ReplicaSet yang tersimpan di kontrol sumber.
Beberapa hari kemudian, Bob sedang mempersiapkan rollout mingguan. Bob mengedit konfigurasi ReplicaSet yang disimpan di kontrol versi untuk menggunakan gambar kontainer baru, tetapi dia tidak menyadari bahwa jumlah salinan dalam file tersebut saat ini adalah 5, bukan 10 seperti yang diatur oleh Alice sebagai respons terhadap peningkatan beban. Bob melanjutkan rollout, yang memperbarui gambar kontainer dan mengurangi jumlah salinan menjadi setengah. Hal ini menyebabkan overload segera, yang berujung pada kegagalan layanan.
Studi kasus fiksi ini menggambarkan perlunya memastikan bahwa setiap perubahan imperatif segera diikuti dengan perubahan deklaratif di kontrol sumber. Sebenarnya, jika kebutuhannya tidak mendesak, kami umumnya menyarankan untuk hanya melakukan perubahan deklaratif seperti yang dijelaskan pada bagian berikut.
kubectl apply
Dalam dunia deklaratif, Anda melakukan perubahan dengan mengedit file konfigurasi di kontrol versi dan kemudian menerapkan perubahan tersebut ke cluster Anda. Untuk menskalakan ReplicaSet kuard, edit file konfigurasi kuard-rs.yaml
dan atur jumlah salinan menjadi 3:
Dalam pengaturan multiuser, Anda kemungkinan akan melakukan review kode yang terdokumentasi untuk perubahan ini dan akhirnya memeriksa perubahan ke dalam kontrol versi. Setelah itu, Anda bisa menggunakan perintah kubectl apply
untuk mengirimkan ReplicaSet kuard yang telah diperbarui ke server API:
Sekarang ReplicaSet kuard yang telah diperbarui sudah diterapkan, dan controller ReplicaSet akan mendeteksi bahwa jumlah Pod yang diinginkan telah berubah dan bahwa ia perlu mengambil tindakan untuk mencapai keadaan yang diinginkan tersebut. Jika Anda menggunakan perintah scale imperatif pada bagian sebelumnya, controller ReplicaSet akan menghancurkan satu Pod untuk menyesuaikan jumlah menjadi tiga. Sebaliknya, jika Anda melakukan perubahan deklaratif, controller akan mengirimkan dua Pod baru ke API Kubernetes menggunakan template Pod yang didefinisikan pada ReplicaSet kuard. Apapun caranya, Anda bisa menggunakan perintah kubectl get pods
untuk melihat daftar Pod kuard yang sedang berjalan. Anda seharusnya melihat output yang serupa dengan berikut, dengan tiga Pod dalam keadaan berjalan; dua di antaranya akan memiliki usia yang lebih kecil karena baru saja dimulai:
Meskipun ada kalanya Anda ingin memiliki kontrol eksplisit terhadap jumlah salinan dalam sebuah ReplicaSet, seringkali Anda hanya ingin memiliki salinan yang “cukup.” Definisi “cukup” bervariasi tergantung pada kebutuhan kontainer dalam ReplicaSet tersebut. Misalnya, dengan server web seperti NGINX, Anda mungkin ingin menskalakan berdasarkan penggunaan CPU. Untuk cache dalam memori, Anda mungkin ingin menskalakan berdasarkan konsumsi memori. Dalam beberapa kasus, Anda mungkin ingin menskalakan berdasarkan metrik aplikasi kustom.
Kubernetes dapat menangani semua skenario ini melalui Horizontal Pod Autoscaling (HPA). Istilah “Horizontal Pod Autoscaling” bisa terdengar panjang, dan Anda mungkin bertanya mengapa tidak cukup disebut sebagai “autoscaling.” Kubernetes membedakan antara skala horizontal, yang melibatkan pembuatan salinan tambahan dari sebuah Pod, dan skala vertikal, yang melibatkan peningkatan sumber daya yang dibutuhkan oleh Pod tertentu (seperti menambah CPU untuk Pod tersebut). Banyak solusi juga memungkinkan autoscaling cluster, di mana jumlah mesin dalam cluster disesuaikan berdasarkan kebutuhan sumber daya, tetapi solusi ini berada di luar cakupan bab ini.
Autoscaling memerlukan keberadaan metrics-server di cluster Anda. Metrics-server melacak metrik dan menyediakan API untuk mengonsumsi metrik yang digunakan HPA saat membuat keputusan skala. Sebagian besar instalasi Kubernetes menyertakan metrics-server secara default. Anda dapat memverifikasi keberadaannya dengan menampilkan Pod di namespace kube-system:
Anda seharusnya melihat Pod dengan nama yang dimulai dengan metrics-server dalam daftar tersebut. Jika tidak, autoscaling tidak akan berfungsi dengan benar.
Menskalakan berdasarkan penggunaan CPU adalah kasus penggunaan paling umum untuk autoscaling Pod. Anda juga bisa menskalakan berdasarkan penggunaan memori. Autoscaling berbasis CPU sangat berguna untuk sistem berbasis permintaan yang mengonsumsi CPU secara proporsional terhadap jumlah permintaan yang mereka terima, sementara menggunakan jumlah memori yang relatif statis.
Untuk menskalakan ReplicaSet, Anda bisa menjalankan perintah seperti berikut:
Perintah ini membuat autoscaler yang menskalakan antara dua hingga lima salinan dengan ambang batas CPU sebesar 80%. Untuk melihat, mengubah, atau menghapus sumber daya ini, Anda dapat menggunakan perintah kubectl standar dan sumber daya horizontalpodautoscalers
. Meskipun cukup panjang untuk mengetik horizontalpodautoscalers
, Anda dapat mempersingkatnya menjadi hpa
:
Karena sifat Kubernetes yang terpisah, tidak ada hubungan langsung antara HPA dan ReplicaSet. Meskipun hal ini bagus untuk modularitas dan komposisi, ini juga memungkinkan beberapa antipola. Secara khusus, menggabungkan autoscaling dengan manajemen jumlah salinan secara imperatif atau deklaratif adalah ide yang buruk. Jika baik Anda maupun autoscaler berusaha mengubah jumlah salinan, kemungkinan besar akan terjadi benturan yang mengakibatkan perilaku yang tidak terduga.
Ketika sebuah ReplicaSet tidak lagi dibutuhkan, ReplicaSet tersebut dapat dihapus menggunakan perintah kubectl delete
. Secara default, ini juga akan menghapus Pods yang dikelola oleh ReplicaSet tersebut:
Menjalankan perintah kubectl get pods
menunjukkan bahwa semua Pod kuard yang dibuat oleh ReplicaSet kuard juga telah dihapus:
Jika Anda tidak ingin menghapus Pods yang dikelola oleh ReplicaSet, Anda dapat menambahkan flag --cascade=false
untuk memastikan hanya objek ReplicaSet yang dihapus dan bukan Pods-nya:
Menggabungkan Pods dengan ReplicaSets memberikan dasar untuk membangun aplikasi yang tangguh dengan failover otomatis, serta memudahkan penerapan aplikasi tersebut dengan memungkinkan pola penerapan yang skalabel dan teratur. Gunakan ReplicaSets untuk setiap Pod yang Anda anggap penting, bahkan jika itu hanya satu Pod! Beberapa orang bahkan lebih memilih menggunakan ReplicaSets daripada Pods. Sebuah cluster yang khas akan memiliki banyak ReplicaSets, jadi terapkan secara luas di area yang relevan.
Deployment hadir untuk mengatur rilis versi terbaru dari aplikasi kita. Deployment memudahkan kita untuk berpindah dari satu versi ke versi lain, ini dinamakan proses "rollout" (peluncuran). Deployment memungkinkan kita untuk berganti versi aplikasi tanpa adanya downtime atau error. Di belakang layar, yang mengatur proses rollout ini ialah Deployment Controller yang berjalan di kubernetes cluster. Ini berarti kita dapat membiarkan Deployment berjalan tanpa pengawasan dan tetap beroperasi dengan benar dan aman.
Sama dengan kubernetes objek yang lainnya, sebuah deployment kita bisa representasikan secara deklaratif di dalam file YAML.
Simpan dan jalankan perintah kubectl apply -f deployment.yaml
Mari kita telusuri bagaimana sebenarnya Deployment itu bekerja. Sebelumnya kita sudah tau kalau ReplicaSets itu tugasnya mengatur Pods. Nah Deployment ini tugasnya mengatur ReplicaSets.
Kita bisa melihat label selector di dalam Deployment object
kubectl get deployments kuard -o jsonpath --template {.spec.selector.matchLabels}
Dengan menjalakan perintah diatas kamu akan melihat Deployment yang mengatur ReplicaSet menggunkan label run=kuard. Kita bisa menggunakan perintah kubectl get replicasets --selector=run=kuard
untuk melihat spesifik ReplicaSets.
1. Advanced Scheduling:
Taints and Tolerations: Mengatur penjadwalan pod ke node tertentu berdasarkan "taint".
Affinity/Anti-Affinity: Menentukan preferensi pod untuk berjalan di node atau pod tertentu (lebih fleksibel dari Node Selector).
Pod Topology Spread Constraints: Menyebarkan pod secara merata di seluruh zona/node.
2. Security:
RBAC (Role-Based Access Control): Mengelola izin akses ke sumber daya Kubernetes.
Pod Security Policies/Admission Controllers: Membatasi perilaku pod (misalnya, mencegah penggunaan privileged containers).
SecurityContext: Mengatur hak akses pod/container (e.g., user ID, filesystem permissions).
3. Networking:
Network Policies: Mengontrol lalu lintas jaringan antar pod (e.g., mengisolasi namespace).
CNI (Container Network Interface): Plugin jaringan Kubernetes (e.g., Calico, Flannel).
Service Mesh (Istio/Linkerd): Layer tambahan untuk observability, security, dan traffic management.
4. Storage:
StorageClass: Penyediaan volume persistent secara dinamis.
Volume Snapshots: Backup/restore data di PersistentVolume.
Ephemeral Volumes (e.g., emptyDir
): Volume sementara untuk pod.
5. Advanced Workloads:
Init Containers: Container yang dijalankan sebelum container utama dalam pod.
Pod Lifecycle Hooks (PostStart/PreStop): Menjalankan aksi sebelum/sesudah pod berjalan/berhenti.
Vertical Pod Autoscaler (VPA): Menyesuaikan resource requests/limits pod secara otomatis.
6. Observability:
Logging dengan EFK/ELK: Mengumpulkan dan menganalisis log aplikasi.
Monitoring dengan Prometheus/Grafana: Memantau kesehatan cluster dan aplikasi.
Kubernetes Events: Memahami event yang terjadi di cluster (e.g., pod gagal dijadwalkan).
7. Extending Kubernetes:
Custom Resource Definitions (CRD): Menambahkan sumber daya kustom ke Kubernetes.
Operator Pattern: Mengotomatiskan operasi aplikasi dengan CRD dan controller.
Helm: Package manager untuk aplikasi Kubernetes (charts, templating).
8. Best Practices:
Resource Quotas: Membatasi penggunaan resource di namespace.
Limit Ranges: Mengatur batasan resource untuk pod/container.
Immutable ConfigMaps/Secrets: Mencegah perubahan konfigurasi saat runtime.
9. Cloud-Specific Tools:
Kubernetes di Cloud (e.g., GKE, EKS, AKS): Manajemen cluster di lingkungan cloud.
Autoscaling Node di Cloud: Integrasi Cluster Autoscaler dengan cloud provider.
10. Debugging & Maintenance:
Troubleshooting Pod/Node: Teknik debugging (e.g., kubectl exec
, kubectl logs
).
Cordon/Drain Node: Memindahkan pod dari node yang bermasalah.
Backup/Restore Cluster: Menggunakan alat seperti Velero.
RBAC dan SecurityContext untuk keamanan dasar.
Network Policies jika memerlukan isolasi jaringan.
Helm untuk manajemen aplikasi yang kompleks.
Affinity/Anti-Affinity untuk penjadwalan lanjutan.
Operator Pattern jika menggunakan aplikasi stateful yang kompleks (e.g., database).
Labels menyediakan metadata identifikasi untuk objek dalam Kubernetes. Label merupakan atribut fundamental yang digunakan untuk pengelompokan, tampilan, dan operasi terhadap objek. Konsep label dalam Kubernetes terinspirasi dari pengalaman Google dalam mengelola aplikasi berskala besar dan kompleks. Beberapa hikmah yang diperoleh dari pengalaman ini antara lain: