Bagian ini membahas tentang tutorial Kubernetes.
Tutorial berfungsi untuk memperlihatkan bagaimana caranya mencapai suatu tujuan yang lebih dari sekedar task sederhana.
Biasanya, sebuah tutorial punya beberapa bagian, masing-masing bagian terdiri dari langkah-langkah yang berurutan.
Sebelum melangkah lebih lanjut ke tutorial, sebaiknya tandai dulu halaman Kamus Istilah untuk referensi nanti.
Prinsip Dasar
Prinsip Dasar Kubernetes merupakan tutorial yang sangat interaktif, membantu kamu mengerti apa itu sistem Kubernetes dan beberapa fitur Kubernetes yang umum digunakan.
Tertarik menulis tutorial? Lihat
Menggunakan Template Halaman
untuk info mengenai template dan ragam halaman tutorial.
1 - Halo Minikube
Tutorial ini menunjukkan bagaimana caranya menjalankan aplikasi sederhana Node.js Halo Dunia di Kubernetes, dengan minikube dan Katacoda.
Katacoda menyediakan environment Kubernetes secara gratis di dalam browser.
Catatan:
Kamupun bisa mengikuti tutorial ini kalau sudah instalasi minikube di lokal. Silakan lihat memulai minikube untuk instruksi instalasi.
Tujuan
Deploy aplikasi halo dunia pada minikube.
Jalankan aplikasinya.
Melihat log aplikasi.
Sebelum kamu memulai
Tutorial ini menyediakan image Kontainer yang dibuat melalui barisan kode berikut:
FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD node server.js
Untuk info lebih lanjut tentang perintah docker build, baca dokumentasi Docker.
Membuat sebuah klaster Minikube
Tekan Launch Terminal
Catatan:
Kalau kamu memilih instalasi minikube secara lokal, jalankan minikube start.
Buka dasbor Kubernetes di dalam browser:
minikube dashboard
Hanya untuk environment Katacoda: Di layar terminal paling atas, tekan tombol plus, lalu lanjut tekan Select port to view on Host 1.
Hanya untuk environment Katacoda: Ketik 30000, lalu lanjut tekan Display Port.
Membuat sebuah Deployment
Sebuah Kubernetes Pod adalah kumpulan dari satu atau banyak Kontainer,
saling terhubung untuk kebutuhan administrasi dan jaringan. Pod dalam tutorial ini hanya punya satu Kontainer. Sebuah Kubernetes
Deployment selalu memeriksa kesehatan
Pod kamu dan melakukan restart saat Kontainer di dalam Pod tersebut mati. Deployment adalah cara jitu untuk membuat dan mereplikasi Pod.
Gunakan perintah kubectl create untuk membuat Deployment yang dapat mengatur Pod.
Pod menjalankan Kontainer sesuai dengan image Docker yang telah diberikan.
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1111 1m
Lihat Pod:
kubectl get pods
Keluaran:
NAME READY STATUS RESTARTS AGE
hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m
Lihat event klaster:
kubectl get events
Lihat konfigurasi kubectl:
kubectl config view
Catatan:
Untuk info lebih lanjut tentang perintah kubectl, lihat ringkasan kubectl.
Membuat sebuah Servis
Secara default, Pod hanya bisa diakses melalui alamat IP internal di dalam klaster Kubernetes.
Supaya Kontainer hello-node bisa diakses dari luar jaringan virtual Kubernetes, kamu harus ekspos Pod sebagai Servis Kubernetes.
Ekspos Pod pada internet publik menggunakan perintah kubectl expose:
Tanda --type=LoadBalancer menunjukkan bahwa kamu ingin ekspos Servis keluar dari klaster.
Lihat Servis yang baru kamu buat:
kubectl get services
Keluaran:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
Untuk penyedia cloud yang memiliki load balancer, sebuah alamat IP eksternal akan disediakan untuk mengakses Servis tersebut.
Pada minikube, tipe LoadBalancer membuat Servis tersebut dapat diakses melalui perintah minikube service.
Jalankan perintah berikut:
minikube service hello-node
Hanya untuk environment Katacoda: Tekan tombol plus, lalu lanjut tekan Select port to view on Host 1.
Hanya untuk environment Katacoda: Ketik 30369 (lihat port di samping 8080 pada keluaran servis), lalu lanjut tekan
Ini akan membuka jendela browser yang menjalankan aplikasimu dan memperlihatkan pesan "Halo Dunia".
Aktifkan addons
Perangkat minikube meliputi sekumpulan addons bawaan yang bisa diaktifkan, dinonaktifkan, maupun dibuka di dalam environment Kubernetes lokal.
Tutorial ini menyediakan panduan dasar mekanisme orkestrasi klaster Kubernetes. Setiap modul memliki beberapa informasi mengenai latar belakang bagi konsep mendasar dan feature Kubernetes, termasuk mode interaktif yang dapat digunakan sebagai metode pembelajaran online. Mode tutorial interaktif ini memberikan kesempatan pengguna untuk melakukan manajemen klaster sederhana beserta aplikasi terkontainerisasi yang kamu miliki.
Dengan menggunakan mode tutorial interaktif ini, pengguna diharapkan dapat memahami:
Deploy sebuah aplikasi yang sudah dikontainerisasi pada klaster
Melakukan scaledeployment
Memperbarui aplikasi yang sudah dikontainerisasi dengan menggunakan versi aplikasi terbaru
Men-debug aplikasi yang sudah dikontainerisasi
Tutorial ini menggunakan Katakoda untuk menjalankan terminal virtual diatas Minikube pada web browser kamu. Dengan demikian, kamu tidak perlu melakukan instalasi perangkat lunak apa pun, segala modul yang ada dijalankan secara langsung melalui web browser yang kamu miliki.
Apa yang dapat dilakukan oleh Kubernetes untuk kamu?
Seiring berkembangnya web servis modern, pengguna memiliki ekspektasi agar aplikasi selalu dapat diakses 24/7, selain itu developers juga memiliki harapan agar mereka dapat melakukan deployment aplikasi dengan versi terbaru yang mereka miliki berulang per hari. Mekanisme kontainerisasi mengepak perangkat lunak agar memenuhi kebutuhan yang ada, memudahkan serta mempercepat proses rilis dan pembaharuan aplikasi tanpa adanya downtime proses ini dapat dilakukan berulang per hari. Kubernetes membantu kamu menjaga aplikasi yang kamu buat untuk dapat dijalankan dimana pun dan kapan pun kamu menginginkannya, serta menjamin segala kebutuhan dan peralatan yang dibutuhkan oleh aplikasi kamu tersedia. Kubernetes merupakan platform open source yang sudah matang yang didesain berdasarkan pengalaman Google serta ide yang brilian dari komunitas yang ada.
2.1.1 - Menggunakan Minikube Untuk Membuat Klaster
Objectives
Belajar apa itu klaster Kubernetes.
Belajar apa itu Minikube.
Memulai klaster Kubernetes menggunakan terminal _online_.
Klaster Kubernetes
Kubernetes mengoordinasikan klaster komputer ketersediaan tinggi (_highly available_) yang saling terhubung sebagai unit tunggal. Abstraksi pada Kubernetes mengizinkan kamu untuk men-_deploy_ aplikasi terkemas (_containerized_) ke sebuah klaster tanpa perlu membalutnya secara spesifik pada setiap mesin. Untuk menggunakan model baru _deployment_ ini, aplikasi perlu dikemas dengan cara memisahkan mereka dari hos individu: mereka perlu dikemas. Aplikasi terkemas lebih fleksibel dan tersedia dibanding model _deployment_ lama, dimana aplikasi dipasang secara langsung didalam mesin spesifik sebagai paket yang sangat terintegrasi dengan hos. Kubernetes mengotomasisasikan distribusi dan penjadwalan kontainer aplikasi sebuah klaster secara menyeluruh dengan cara yang lebih efisien. Kubernetes merupakan platform _open-source_ dan siap produksi.
Klaster Kubernetes terdiri dari 2 tipe sumber daya:
Master mengoordinasikan klaster
Node adalah pekerja (_worker_) yang menjalankan aplikasi
Summary:
Klaster Kubernetes
Minikube
Kubernetes merupakan platform _open-source_ tingkat produksi yang mengatur penjadwalan dan eksekusi kontainer aplikasi didalam dan keseluruhan klaster komputer.
Diagram Klaster
Master mempunyai kewajiban untuk mengelola klaster. Master mengoordinasikan semua aktifitas di klaster kamu, seperti penjadwalan aplikasi, pemeliharaan keadaan (_state_) aplikasi yang diinginkan, _scaling_ aplikasi, dan _roll-out_ pembaharuan.
Node merupakan VM atau komputer fisik yang berfungsi sebagai mesin pekerja dalam klaster Kubernetes. Setiap node mempunyai Kubelet, sebuah agen untuk mengatur Node dan komunikasi dengan Kubernetes master. Node juga harus mempunyai alat untuk menangani operasi kontainer, seperti Docker atau rkt. Sebuah klaster Kubernetes yang menangani trafik produksi harus mempunyai minimal 3 Node.
Master mengatur klaster dan Node yang digunakan sebagai hos dari aplikasi yang berjalan.
Ketika kamu men-_deploy_ aplikasi pada Kubernetes, kamu memberitahu master untuk memulai kontainer aplikasi. Master melakukan penjadwalan kontainer untuk berjalan diatas klaster Node. Node berkomunikasi dengan master menggunakan Kubernetes API, yang disediakan oleh master. Pengguna akhir juga dapat menggunakan Kubernetes API secara langsung untuk berinteraksi dengan klaster.
Klaster Kubernetes dapat di-_deploy_ ke mesik fisik maupun virtual. Untuk memulai pengembangan Kubernetes, kamu dapat menggunakan Minikube. Minikube merupakan implementasi Kubernetes ringan yang membuat VM padi mesin lokal kamu dan men-_deploy_ klaster sederhanya yang terdiri atas 1 Node. Minikube tersedia untuk Linux, macOS, dan sistem Windows. Minikube CLI menyediakan operasi _bootstraping_ dasar untuk bekerja dengan klaster kamu. Namun untuk tutorial ini, kamu akan menggunakan online terminal yang sudah disediakan dengan Minikube yang sudah diinstall sebelumnya.
Sekarang kamu telah mengetahui apa itu Kubernetes, mari kita pergi ke tutorial online dan memulai klaster pertama kita!
2.2.1 - Menggunakan kubectl untuk membuat Deployment
Tujuan
Belajar tentang menyebarkan (deploy) aplikasi.
Menyebarkan aplikasi pertama kamu di Kubernetes dengan kubectl.
Deployment Kubernetes
Ketika klaster Kubernetes kamu sudah berjalan, kamu dapat menyebarkan aplikasi terkontainerisasi di atasnya.
Untuk melakukannya, kamu perlu membuat konfigurasi Deployment. Deployment menginstruksikan Kubernetes
tentang bagaimana cara membuat dan memperbarui instance aplikasi kamu. Ketika kamu selesai membuat Deployment, Kubernetes control plane
melakukan penjadwalan instance aplikasi yang terlibat dalam Deployment untuk berjalan di Node individu pada klaster.
Setelah instance aplikasi telah dibuat, Kubernetes Deployment Controller akan melakukan monitoring instance tersebut secara kontinu. Jika instance pada hos Node mati atau terhapus, Deployment Controller akan mengganti instance tersebut dengan instance Node lain dalam klaster. Ia menyediakan mekanisme penyembuhan diri (self-healing) untuk mengatasi kegagalan mesin atau pemeliharaan (maintenance)
Pada masa pra-orkestrasi, instalasi script sering digunakan untuk memulai aplikasi, namun cara ini tidak memberikan mekanisme pemulihan ketika terjadi kegagalan mesin. Dengan kemampuan membuat instance aplikasi dan menjaganya tetap berjalan pada Node, Deployment Kubernetes menyediakan manajemen aplikasi dengan pendekatan fundamental yang berbeda.
Ringkasan:
Deployment
Kubectl
Sebuah Deployment bertanggung jawab untuk membuat dan memperbarui instance dari aplikasi kamu
Menyebarkan aplikasi pertama kamu dalam Kubernetes
Kamu dapat membuat dan mengatur Deployment dengan menggunakan antar muka baris perintah (CLI) Kubernetes, Kubectl. Kubectl menggunakan Kubernetes API untuk berinteraksi dengan klaster. Pada modul ini, kamu akan belajar perintah-perintah yang sering digunakan Kubectl untuk membuat Deployment untuk menjalankan aplikasi kamu pada klaster Kubernetes.
Ketika kamu membuat Deployment, kamu perlu mendefinisikan Container image untuk aplikasi kamu dan jumlah replika yang kamu inginkan. Kamu dapat mengganti informasi tersebut nanti dengan melakukan pembaharuan Deployment kamu; Modul 5 dan 6 pada bootcamp ini mendiskusikan bagaimana cara melakukan perluasan (scale) dan pembaruan Deployment kamu.
Aplikasi perlu dikemas menjadi satu dengan format Container yang didukung supaya tersebar pada Kubernetes
Pada Deployment pertama kamu, kamu akan menggunakan aplikasi Node.js yang terkemas dalam Container Docker. (Jika kamu belum pernah mencoba membuat aplikasi Node.js dan menyebarkannya dengan Container, kamu dapat melakukannya dengan mengikuti instruksi pada tutorial Hello Minikube).
Sekarang kamu tahu apa itu Deployment, mari kita ke tutorial online dan menyebarkan aplikasi pertama kita!
Pod merupakan unit eksekusi utama pada aplikasi Kubernetes. Setiap Pod mewakili sebagian dari beban kerja (workload) yang berjalan pada klaster kamu. Learn more about Pods.
Untuk berinteraksi dengan Terminal, silahkan gunakan desktop/tablet.
Mengatasi masalah pada aplikasi-aplikasi yang digelar.
Pod Kubernetes
Ketika kamu membuat sebuah Deployment pada Modul 2, Kubernetes membuatkan sebuah Pod untuk menempatkan instans aplikasimu. Pod merupakan sebuah abstraksi Kubernetes yang merepresentasikan sebuah grup yang terdiri dari satu atau lebih kontainer (seperti Docker), dan beberapa sumber daya bersama untuk kontainer-kontainer itu. Sumber daya tersebut termasuk:
Penyimpanan bersama, disebut Volume
Jaringan, sebagai satu alamat IP klaster unik
Informasi tentang bagaimana mejalankan tiap kontainer, seperti versi image atau porta spesifik yang digunakan oleh kontainer
Pod memodelkan sebuah "logical host" spesifik aplikasi dan dapat berisi beberapa kontainer aplikasi berbeda yang relatif terkait erat. Contohnya, sebuah Pod mungkin terdiri atas kontainer aplikasi Node.js dan juga kontainer berbeda yang bertugas menyediakan data untuk dipublikasikan ke server web Node.js. Kontainer-kontainer dalam sebuah Pod berbagi satu alamat IP dan ruang porta, selalu terletak bersama dan terjadwal bersama, dan berjalankan dalam satu konteks bersama (shared context) pada Node yang sama.
Pod merupakan unit terkecil dalam platform Kubernetes. Ketika kita membuat sebuat Deployment, Deployment tersebut membuat Pod dengan kontainer-kontainer di dalamnya (bukannya dengan membuat kontainer secara langsung). Tiap Pod terikat langsung dengan Node di mana dia dijadwalkan dan tetap di sana sampai diterminasi (berdasarkan restart policy) atau penghapusan. Jika terjadi kegagalan pada sebuah Node, Pod indentik akan dijadwalkan di Node lain dalam klaster.
Ringkasan:
Pod
Node
Perintah utama kubectl
Pod merupakan sebuah grup yang terdiri dari satu atau lebih kontainer aplikasi (seperti Docker) dan berisi penyimpanan bersama (volume), alamat IP dan informasi tentang bagaimana menjalankan mereka.
Ikhtisar Pod
Node
Sebuah Pod selalu berjalan dalam sebuah Node. Node merupakan sebuah mesin pekerja (worker) di Kubernetes dan mungkin merupakan mesin virtual ataupun fisik, tergantung dari klaster. Tiap Node dikelola oleh control plane. Satu Node dapat memiliki beberapa Pod, dan control plane Kubernetes yang otomatis menangani penjadwalan pod seluruh Node-Node dalam klaster. Penjadwalan otomatis oleh control plane memperhitungkan tersedianya sumber daya tiap Node.
Tiap Node Kubernetes menjalankan setidaknya:
Kubelet, satu proses yang bertanggung jawab untuk berkomunikasi antara control plane Kubernetes dan Node; ini juga mengelola Pod-Pod dan kontainer-kontainer yang berjalan di sebuah mesin.
Satu container runtime, seperti Docker, bertanggung jawab untuk menarik image kontainer dari register, membuka kontainer, dan menjalankan aplikasi.
Kontainer seharusnya hanya dijadwalkan bersama di satu Pod jika terkait erat dan membutuhkan sumber daya bersama seperti diska.
Ikhtisar Node
Mengatasi masalah dengan kubectl
Dalam Modul 2, kamu menggunakan antarmuka baris perintah kubectl. Kamu akan lanjut menggunakannya pada modul 3 untuk mendapatkan informasi tentang aplikasi-aplikasi yang digelar dan lingkungannya. Operasi yang paling umum dapat dilakukan dengan perintah kubectl berikut:
kubectl get - melihat daftar sumber daya
kubectl describe - menampilkan detil informasi tentang suatu sumber daya
kubectl logs - mencetak log-log dari satu kontainer dalam sebuah Pod
kubectl exec - eksekusi sebuah perintah pada satu kontainer dalam sebuah Pod
Kamu dapat menggunakan perintah ini kapan aplikasi-aplikasi digelar, apa status mereka saat ini, di mana mereka berjalan, dan apa konfigurasi mereka.
Sekarang karena kita lebih mengetahui tentang klaster kita dan baris perintahnya, mari kita menjelajah aplikasi kita.
Node merupakan mesin pekerja di Kubernetes dan bisa berupa VM ataupun mesin fisik, tergantung pada klaster. Beberapa Pod dapat berjalan dalam satu Node.
2.4.1 - Menggunakan Service untuk Mengekspos Aplikasimu
Tujuan
Belajar tentang Service di Kubernetes
Memahami bagaimana label dan objek LabelSelector berhubungan dengan sebuah Service
Mengekspos sebuah aplikasi keluar klaster Kubernetes menggunakan sebuah Service
Ikhtisar Service Kubernetes
Pod-Pod Kubernetes itu fana. Pod pada kenyataannya punya siklus hidup. Ketika sebuah Node pekerja mati, Pod yang berjalan dalam Node itu juga hilang. ReplicaSet mungkin kemudian secara dinamis mendorong klaster kembali ke keadaan yang diinginkan melalui penciptaan Pod baru untuk memastikan aplikasimu berjalan. Contoh lainnya, katakanlah ada backend pengolahan citra dengan 3 replika. Replika tersebut dapat ditukar; sistem front-end seharusnya tidak peduli tentang replika backend atau bahkan jika Pod hilang dan dibuat ulang. Walaupun demikian, tiap Pod dalam sebuah klaster Kubernetes memiliki alamat IP unik, meskipun Pod-Pod itu berada dalam satu Node yang sama, sehingga seharusnya ada jalan untuk mencocokan perubahan antara Pod-Pod itu sehingga aplikasimu tetap berfungsi.
Service di Kubernetes merupakan abstraksi yang mendefinisikan satu set Pod secara logis dan aturan untuk mengakses mereka. Service memungkinkan keterkaitan renggang antara Pod-Pod. Sebuah Service didefinisikan menggunakan YAML (lebih disukai) atau JSON, sebagaimana semua objek Kubernetes. Kumpulan Pod yang ditargetkan oleh Service biasanya ditentukan oleh LabelSelector (lihat di bawah mengapa kamu mungkin ingin Service tanpa selector dalam spec).
Meskipun tiap Pod memiliki alamat IP unik, IP tersebut tidak diekpos ke luar klaster tanpa sebuah Service. Service memperbolehkan aplikasimu untuk menerima kunjungan. Service dapat diekspos dengan cara yang berbeda menggunakan type di ServiceSpec:
ClusterIP (bawaan) - Mengekspos Service dengan internal IP dalam klaster. Type ini membuat Service hanya bisa diakses dalam klaster.
NodePort - Mengekspos Service dengan porta yang sama untuk tiap Node dalam klaster menggunakan NAT. Ini membuat Service dapat diakses dari luar dengan <NodeIP>:<NodePort>. Superset dari ClusterIP.
LoadBalancer - Membuat load balancer eksternal di cloud saat ini (jika didukung) dan memberikan IP eksternal tetap kepada Service. Superset dari NodePort.
ExternalName - Mengekpos Service menggunakan nama sesuai keinginan (ditentukan oleh externalName dalam spec) dengan mengembalikan catatan CNAME dengan nama tersebut. Tidak menggunakan proksi. Type ini membutuhkan kube-dns versi v1.7 atau lebih tinggi.
Selain itu, catat bahwa ada kasus penggunaan Service yang tidak mendefinisikan selector di spec. Sebuah Service yang dibuat tanpa selector juga tidak akan membuat objek Endpoint yang sesuai. Ini mengizinkan pengguna untuk memetakan Service secara manual ke endpoint spesifik. Kemungkinan lain kenapa dimungkinan tanpa selector adalah kamu dengan tegas menggunakan type: ExternalName.
Ringkasan
Mengekspos Pod ke kunjungan eksternal
Load balancing kunjungan melintasi beberapa Pod
Menggunakan label
Service Kubernetes adalah lapisan abstraksi yang mendefinisikan kumpulan Pod secara logis dan mengijinkan paparan kunjungan eksternal, load balancing, dan service discovery untuk Pod-Pod tersebut.
Service dan Label
Service mengarahkan kunjungan melintasi sekumpulan Pod. Service merupakan abstraksi yang mengizinkan Pod-Pod untuk mati dan replikasi dalam Kubernetes tanpa memengaruhi aplikasimu. Menemukan dan routing antara Pod dependen (seperti komponen frontend dan backend) yang ditangani oleh Service Kubernetes.
Service mencocokan satu set Pod menggunakan label dan selektor, mengelompokan primitif yang mengizinkan operasi logika pada objek-objek dalam Kubernetes. Label adalah pasangan key/value yang melekat pada objek-objek dan dapat digunakan untuk beberapa tujuan:
Menandai objek-objek untuk lingkungan development, test, dan production
Melekatkan label versi
Klasifikasi sebuah objek dengan label-label
Label-label dapat dilekatkan pada objek-objek pada waktu pembuatan ataupun setelahnya. Mereka dapat diubah kapanpun. Mari kita ekspos aplikasi kita sekarang dengan sebuah Service dan menerapkan beberapa label.
2.5.1 - Menjalankan Multipel Instans dari Aplikasimu
Tujuan
Penyekalaan aplikasi menggunakan kubectl.
Penyekalaan sebuah Aplikasi
Di modul-modul sebelumnya kita telah membuat Deployment, dan mengeksposnya secara publik via Service. Deployment tersebut hanya membuat satu Pod untuk menjalankan aplikasi kita. Ketika kunjungan meningkat, kita perlu melakukan penyekalaan (scale) aplikasi kita untuk mengikuti tingkat permintaan pengguna.
Penyekalaan dapat dicapai dengan mengubah nilai replicas dalam Deployment
Ringkasan:
Penyekalaan sebuah Deployment
Kamu dapat membuat Deployment dengan beberapa instans sekaligus dari awal dengan menggunakan parameter --replicas pada perintah kubectl create deployment
Perluasan skala Deployment akan memastikan Pod baru dibuat dan dijadwalkan ke Node-Node dengan sumber daya yang tersedia. Penyekalaan akan meningkatkan jumlah Pod ke keadaan yang diinginkan. Kubernetes juga mendukung autoscaling Pod, tetapi itu di luar cakupan tutorial ini. Penyekalaan ke nol juga dimungkinkan, dan tindakan ini akan mengakhiri semua Pod pada Deployment tersebut.
Menjalankan beberapa instans dari aplikasi akan membutuhkan cara untuk mendistribusikan trafik ke semuanya. Service memiliki penyeimbang beban terintegrasi yang akan mendistribusikan trafik jaringan ke semua Pod dari sebuah Deployment yang diekspos. Service akan terus memonitor Pod-Pod yang berjalan menggunakan Endpoints, untuk memastikan trafik hanya dikirim ke Pod yang tersedia.
Penyekalaan dapat dicapai dengan mengubah jumlah replicas pada sebuah Deployment.
Sewaktu kamu memiliki multipel instans dari aplikasi yang berjalan, kamu akan bisa melakukan pembaruan bertahap tanpa henti. Kita akan akan membahas hal tersebut pada modul selanjutnya. Sekarang, mari kita pergi ke terminal daring dan melakukan penyekalaan terhadap aplikasi kita.
Melakukan pembaruan bertahap (rolling update) menggunakan kubectl.
Memperbarui suatu aplikasi
Pengguna mengharapkan aplikasi tersedia sepanjang waktu dan pengembang bisa jadi diharapkan untuk men-deploy versi terbaru dari aplikasi tersebut beberapa kali dalam suatu waktu. Di Kubernetes hal ini dilakukan melalui pembaruan bertahap. Pembaruan bertahap memungkinkan pembaruan Deployment terjadi tanpa berhenti dengan memperbarui instans Pod secara bertahap dengan versi yang baru. Pod yang baru akan dijadwalkan pada Node dengan sumber daya yang tersedia.
Dalam modul sebelumnya kita telah melakukan penyekalaan aplikasi kita untuk menjalankan beberapa instans. Hal ini dibutuhkan untuk menjalankan pembaruan tanpa mempengaruhi ketersediaan aplikasi. Secara bawaan, jumlah maksimum dari Pod lama yang akan digantikan (menjadi tidak tersedia) selama pembaruan dan jumlah maksimum Pod baru yang dapat dibuat adalah satu. Kedua opsi ini dapat dikonfigurasi dengan angka atau persentase (dari Pod). Di Kubernetes, setiap pembaruan diberi versi masing-masing dan suatu pembaruan Deployment dapat dikembalikan ke versi sebelumnya (yang stabil).
Ringkasan:
Memperbarui aplikasi
Pembaruan bertahap memungkinkan pembaruan Deployment terjadi tanpa berhenti dengan memperbarui instans Pod secara bertahap dengan versi yang baru.
Seperti penyekalaan aplikasi, jika suatu Deployment terekspos secara publik, maka Service akan menyeimbangkan beban trafik hanya ke Pod yang tersedia saat pembaruan berlangsung. Pod yang tersedia adalah instans yang dapat diakses oleh pengguna aplikasi.
Gunakan sebuah penyedia layanan cloud seperti Google Kubernetes Engine atau Amazon Web Services
untuk membuat sebuah klaster Kubernetes. Tutorial ini membuat sebuah
load balancer eksternal,
yang membutuhkan sebuah penyedia layanan cloud.
Konfigurasi kubectl agar dapat berkomunikasi dengan Kubernetes API Server kamu.
Untuk informasi lebih lanjut, kamu dapat merujuk pada dokumentasi penyedia layanan cloud
yang kamu gunakan.
Tujuan
Jalankan lima buah instans dari aplikasi Hello World.
Buatlah sebuah objek Service yang mengekspos sebuah alamat IP eksternal.
Gunakan sebuah objek Service untuk mengakses aplikasi yang sedang dijalankan.
Membuat sebuah objek Service untuk sebuah aplikasi yang dijalankan pada lima buah Pod
Jalankan sebuah aplikasi Hello World pada klaster kamu:
Perintah di atas akan membuat sebuah
objek Deployment
dan sebuah objek
ReplicaSet
yang diasosiasikan dengan Deployment yang dibuat. ReplicaSet memiliki lima buah
Pod,
yang masing-masing dari Pod tersebut menjalankan aplikasi Hello World.
Tampilkan informasi mengenai Deployment:
kubectl get deployments hello-world
kubectl describe deployments hello-world
Tampilkan informasi mengenai objek ReplicaSet:
kubectl get replicasets
kubectl describe replicasets
Buatlah sebuah objek Service yang mengekspos deployment:
Keluaran dari perintah di atas akan menyerupai tampilan berikut:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.3.245.137 104.198.205.71 8080/TCP 54s
Catatan:
Service dengan `type=LoadBalancer` didukung oleh penyedia layanan cloud eksternal, yang tidak tercakup dalam contoh ini, silahkan merujuk pada [laman berikut](/id/docs/concepts/services-networking/service/#loadbalancer) untuk informasi lebih lanjut.
Catatan:
Jika sebuah alamat IP eksternal yang ditunjukkan dalam status \<pending\>, tunggulah hingga satu menit kemudian masukkan perintah yang sama lagi.
Tampilkan informasi detail mengenai Service:
kubectl describe services my-service
Perintah di atas akan menampilkan keluaran sebagai berikut:
Pastikan nilai dari alamat IP eksternal (LoadBalancer Ingress) diekspos
pada Service yang kamu buat. Pada contoh ini, alamat IP eksternal yang diberikan adalah 104.198.205.71.
Kemudian pastikan nilai dari Port dan NodePort. Pada contoh ini, Port
yang digunakan adalah 8080 dan NodePort adalah 32377.
Pada keluaran perintah sebelumnya, kamu dapat melihat beberapa Service dengan beberapa endpoint:
10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 lainnya. Berikut ini merupakan alamat IP dari Pod
dimana aplikasi tersebut dijalankan. Untuk melakukan verifikasi alamat-alamat IP yang digunakan oleh Pod,
masukkan perintah berikut:
Gunakan alamat IP eksternal (LoadBalancer Ingress) untuk mengakses aplikasi Hello World:
curl http://<external-ip>:<port>
dimana <external-ip> adalah alamat IP eksternal (LoadBalancer Ingress)
dari Service kamu, dan <port> adalah nilai dari Port dari deskripsi Service kamu.
Jika kamu menggunakan minikube, menuliskan perintah minikube service my-service akan
secara otomatis membuka aplikasi Hello World pada browser.
Respons yang diberikan apabila permintaan ini berhasil adalah sebuah pesan sapaan:
Hello Kubernetes!
Bersihkan
Untuk menghapus Service, kamu dapat menggunakan perintah ini:
kubectl delete services my-service
Untuk menghapus Deployment, ReplicaSet, dan Pod-Pod yang digunakan untuk
menjalankan aplikasi Hello World, kamu dapat memasukkan perintah berikut:
Tutorial ini memberikan pengantar untuk manajemen aplikasi dengan
StatefulSet.
Di sini dicontohkan bagaimana cara untuk membuat, menghapus, melakukan penyekalaan,
dan memperbarui Pod dari StatefulSet.
Sebelum kamu memulai
Sebelum memulai tutorial ini, kamu harus mengakrabkan dirimu dengan
konsep-konsep Kubernetes sebagai berikut:
Tutorial ini mengasumsikan bahwa klastermu telah dikonfigurasikan untuk
melakukan penyediaan PersistentVolume secara dinamis. Jika klastermu belum
dikonfigurasikan seperti itu, kamu harus menyediakan dua volume masing-masing dengan
ukuran 1 GiB sebelum memulai tutorial.
Tujuan
StatefulSet ditujukan untuk digunakan dengan aplikasi-aplikasi stateful
dan sistem terdistribusi. Akan tetapi, tata kelola aplikasi-aplikasi stateful
dan sistem terdistribusi pada Kubernetes merupakan topik yang luas dan kompleks.
Untuk menunjukkan fitur-fitur dasar dari StatefulSet dan tidak mencampuradukkan
topik sebelum dan terakhir, kamu akan menggelar sebuah aplikasi web sederhana
menggunakan StatefulSet.
Setelah tutorial ini, kamu akan akrab hal-hal berikut:
Bagaimana cara membuat sebuah StatefulSet
Bagaimana suatu StatefulSet mengelola Pod
Bagaimana cara menghapus StatefulSet
Bagaimana cara melakukan penyekalaan terhadap suatu StatefulSet
Bagaimana cara memperbarui Pod dari StatefulSet
Membuat Sebuah StatefulSet
Mulailah dengan membuat sebuah Statefulset dengan menggunakan contoh di bawah ini.
Hal ini mirip dengan contoh yang ditunjukkan di dalam konsep
StatefulSet.
Contoh ini menciptakan sebuah
Service headless,
nginx, untuk mempublikasikan alamat IP Pod di dalam StatefulSet, web.
Unduh contoh di atas, dan simpan ke dalam berkas dengan nama web.yaml.
Kamu perlu menggunakan dua jendela terminal. Pada terminal yang pertama, gunakan perintah
kubectl get untuk mengamati
pembuatan Pod dari StatefulSet.
kubectl get pods -w -l app=nginx
Pada terminal yang kedua, gunakan
kubectl apply untuk membuat
Service headless dan StatefulSet yang didefinisikan di dalam web.yaml.
kubectl apply -f web.yaml
service/nginx created
statefulset.apps/web created
Perintah di atas menciptakan dua Pod, masing-masing menjalankan server web
NGINX. Dapatkan Service nginx...
kubectl get service nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None <none> 80/TCP 12s
...kemudian dapatkan StatefulSet web, untuk memastikan keduanya berhasil dibuat:
kubectl get statefulset web
NAME DESIRED CURRENT AGE
web 2 1 20s
Pembuatan Pod Berurutan
Untuk StatefulSet dengan n replika, ketika Pod sedang digelar, kesemuanya
akan dibuat secara berurutan, terurut dari {0..n-1}. Periksa keluaran dari
perintah kubectl get pada terminal pertama. Pada akhirnya, keluaran yang dihasilkan
akan seperti contoh di bawah ini.
Perhatikan Pod web-1 tidak dijalankan hingga web-0 berganti status menjadi Running
(lihat Fase Pod) dan Ready
(lihat type di Kondisi Pod).
Pod pada StatefulSet
Pod pada StatefulSet memiliki satu indeks urutan unik dan satu identitas jaringan yang tetap.
Memeriksa Indeks Urutan Pod
Dapatkan Pod dari StatefulSet:
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 1m
web-1 1/1 Running 0 1m
Sebagaimana telah disebutkan di dalam konsep
StatefulSet,
Pod pada StatefulSet memiliki suatu identitas yang melekat (sticky) dan unik.
Identitas ini didasarkan pada sebuah indeks urutan yang unik yang di tetapkan
ke masing-masing Pod oleh pengontrol StatefulSet.
Nama Pod memiliki format <nama statefulset>-<indeks urutan>.
Karena StatefulSet web memiliki dua replika, maka ada dua Pod yang tercipta, web-0 dan web-1.
Menggunakan Identitas Jaringan yang Tetap
Setiap Pod memiliki nama hos yang tetep berdasarkan indeks urutannya. Gunakan perintah
kubectl exec untuk menjalankan
perintah hostname di tiap Pod:
for i in 0 1; do kubectl exec"web-$i" -- sh -c 'hostname'; done
web-0
web-1
Gunakan perintah kubectl run untuk
menjalankan sebuah Container yang menyediakan perintah nslookup dari paket dnsutils.
Dengan menjalankan perintah nslookup dengan nama hos dari Pod, kamu dapat memeriksa alamat
DNS mereka di dalam klaster:
kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm
perintah itu akan memulai sebuah shell baru. Pada shell tersebut, jalankan:
# Jalankan ini di dalam shell Container dns-testnslookup web-0.nginx
(dan selanjutnya keluarlah dari shell Container dengan menjalankan: exit)
CNAME dari headless service mengarah ke SRV record (satu untuk tiap Pod yang
Running dan Ready). SRC record mengarah ke entri A record yang memuat
alamat IP Pod.
Pada salah satu terminal, amati Pod dari StatefulSet:
kubectl get pod -w -l app=nginx
Pada terminal yang lain, gunakan perintah
kubectl delete untuk menghapus
semua Pod pada StatefulSet:
kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
Tunggu sampai StatefulSet menjalankan mereka kembali, dan untuk keduanya menjadi
Running dan Ready:
kubectl get pod -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 0/1 ContainerCreating 0 0s
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2s
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 34s
Gunakan perintah kubectl exec dan kubectl run untuk menampilkan nama hos Pod
dan entri DNS mereka dalam klaster. Pertama-tama, tampilkan nama hos Pod:
for i in 0 1; do kubectl exec web-$i -- sh -c 'hostname'; done
web-0
web-1
selanjutnya, jalankan:
kubectl run -i --tty --image busybox:1.28 dns-test --restart=Never --rm
perintah itu akan menjalankan shell baru.
Di dalam shell yang baru jalankan:
# Jalankan ini di dalam shell Container dns-testnslookup web-0.nginx
(dan selanjutnya keluarlah dari shell Container dengan menjalankan: exit)
Urutan, nama hos, SRV record, dan nama A record dari Pod tidak berubah,
akan tetapi alamat IP yang terkait dengan Pod bisa jadi mengalami perubahan. Pada klaster
yang digunakan dalam tutorial ini terjadi perubahan. Karena itulah mengapa sangat penting
untuk menghindari pengaturan terhadap aplikasi lain yang terhubung ke Pod di dalam
StatefulSet menggunakan alamat IP.
Jika kamu ingin mencari dan terhubung dengan anggota aktif dari StatefulSet, kamu
perlu melakukan kueri CNAME dari Service headless (nginx.default.svc.cluster.local).
SRV record yang terkait dengan CNAME hanya akan memuat Pod dari StatefulSet yang
Running dan Ready.
Jika aplikasimu telah menerapkan logika koneksi yang menguji keaktifan
(liveness) dan kesiapan (readiness), kamu dapat menggunakan SRV record dari Pod (
web-0.nginx.default.svc.cluster.local,
web-1.nginx.default.svc.cluster.local), karena mereka tidak akan berubah, dan
aplikasimu akan bisa menemukan alamat-alamat Pod ketika mereka mengalami peralihan
ke Running dan Ready.
Menulis ke Penyimpanan Tetap
Dapatkan PersistentVolumeClaim untuk web-0 dan web-1:
kubectl get pvc -l app=nginx
Keluarannya akan seperti:
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 48s
www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 48s
Karena klaster yang digunakan dalam tutorial ini dikonfigurasi untuk melakukan penyediaan
PersistentVolume secara dinamis, maka PersistentVolume dibuat dan terikat secara otomatis.
Server web NGINX, secara bawaan, menyajikan berkas indeks dari
/usr/share/nginx/html/index.html. FieldvolumeMounts pada spec StatefulSet
memastikan direktori /usr/share/nginx/html didukung oleh sebuah PersistentVolume.
Tulis nama hos Pod ke dalam berkas index.html mereka masing-masing dan periksa
apakah server web NGINX menyajikan nama hos tersebut:
for i in 0 1; do kubectl exec"web-$i" -- sh -c 'echo "$(hostname)" > /usr/share/nginx/html/index.html'; donefor i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
Catatan:
Jika kamu melihat respon 403 Forbidden untuk perintah curl di atas,
kamu perlu untuk memperbaiki izin (permission) dari direktori yang dipasang
oleh volumeMounts (disebabkan oleh sebuah
bug ketika menggunakan volume hostPath),
dengan menjalankan:
for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done
sebelum mencoba kembali perintah curl di atas.
Di salah satu terminal, amati Pod dari StatefulSet:
kubectl get pod -w -l app=nginx
Di terminal yang lain, hapus semua Pod dari StatefulSet:
kubectl delete pod -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
Periksa keluaran dari perintah kubectl get pada terminal yang pertama dan tunggu
semua Pod berubah menjadi Running dan Ready.
kubectl get pod -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 0/1 ContainerCreating 0 0s
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2s
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 1/1 Running 0 34s
Periksa apakah server web masih terus menyajikan nama hosnya:
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
Walaupun web-0 dan web-1 telah dijadwalkan ulang, mereka masih menyajikan
nama hos masing-masing karena PersistentVolume yang terkait dengan
PersistentVolumeClaim-nya dipasang kembali (remounted) ke setiap volumeMounts.
Di Node manapun web-0 dan web-1 dijadwalkan, PersistentVolume-nya akan
dipasangkan ke titik pasang (mount point) yang sesuai.
Penyekalaan StatefulSet
Melakukan penyekalaan pada StatefulSet berarti meningkatkan atau mengurangi jumlah
replika. Hal ini dicapai dengan memperbarui fieldreplicas. Kamu dapat menggunakan
kubectl scale atau
kubectl patch untuk
melakukan penyekalaan terhadap StatefulSet.
Penyekalaan Naik
Pada salah satu jendela terminal, amati Pod pada StatefulSet:
kubectl get pods -w -l app=nginx
Di jendela terminal yang lain gunakan perintah kubectl scale untuk melakukan
penyekalaan jumlah replika menjadi 5:
kubectl scale sts web --replicas=5
statefulset.apps/web scaled
Periksa keluaran dari perintah kubectl get pada terminal pertama dan tunggu
tambahan tiga Pod yang baru berubah menjadi Running dan Ready.
Pengontrol StatefulSet telah melakukan penyekalaan terhadap jumlah replika.
Sama seperti pembuatan StatefulSet, pengontrol
StatefulSet membuat tiap Pod berurutan sesuai dengan indeks urutan masing-masing
dan menunggu setiap Pod yang dibuat sebelumnya menjadi Running dan Ready sebelum
menjalankan Pod berikutnya.
Penyekalaan Turun
Di salah satu terminal, amati Pod pada StatefulSet:
kubectl get pods -w -l app=nginx
Di terminal yang lain, gunakan perintah kubectl patch untuk melakukan penyekalaan
StatefulSet turun menjadi tiga replika:
kubectl patch sts web -p '{"spec":{"replicas":3}}'
statefulset.apps/web patched
Tunggu hingga web-4 dan web-3 berubah menjadi Terminating.
kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 3h
web-1 1/1 Running 0 3h
web-2 1/1 Running 0 55s
web-3 1/1 Running 0 36s
web-4 0/1 ContainerCreating 0 18s
NAME READY STATUS RESTARTS AGE
web-4 1/1 Running 0 19s
web-4 1/1 Terminating 0 24s
web-4 1/1 Terminating 0 24s
web-3 1/1 Terminating 0 42s
web-3 1/1 Terminating 0 42s
Penghentian Pod Berurutan
Pengontrol menghapus satu Pod dalam satu waktu, dengan urutan terbalik dari indeks
urutannya, dan setiap Pod akan ditunggu sampai benar-benar mati terlebih dahulu
sebelum menghapus Pod berikutnya.
Di sana masih ada lima PersistentVolumeClaim dan lima PersistentVolume.
Ketika mengeksplorasi penyimpanan tetap pada Pod,
kita dapat melihat bahwa PersistentVolume yang terpasang pada Pod dari suatu StatefulSet
tidak terhapus ketika Pod-nya dihapus. Hal ini tetap berlaku ketika penghapusan Pod
terjadi karena penyekalaan turun pada suatu StatefulSet.
Memperbarui StatefulSet
Di Kubernetes 1.7 dan yang lebih baru, pengontrol StatefulSet mendukung
pembaruan otomatis. Strategi yang digunakan ditentukan oleh fieldspec.updateStrategy dari objek API StatefulSet. Fitur ini dapat digunakan untuk
memperbarui image Container, permintaan sumber daya dan/atau pembatasan, label,
dan anotasi Pod dalam suatu StatefulSet. Ada dua strategi pembaruan yang berlaku,
RollingUpdate dan OnDelete.
Pembaruan dengan RollingUpdate adalah strategi bawaan untuk StatefulSet.
Pembaruan Bertahap (RollingUpdate)
Pembaruan dengan strategi RollingUpdate akan memperbarui semua Pod di dalam
StatefulSet dalam urutan indeks terbalik, dengan tetap memperhatikan
jaminan dari StatefulSet.
Lakukan patch pada StatefulSet web dengan menerapkan RollingUpdate:
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate"}}}'
statefulset.apps/web patched
Pada salah satu jendela terminal, patch StatefulSet web untuk mengubah
image Container lagi:
kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"gcr.io/google_containers/nginx-slim:0.8"}]'
statefulset.apps/web patched
Pada terminal yang lain, amati Pod pada StatefulSet:
Pod dalam StatefulSet diperbarui dengan urutan indeks terbalik. Pengontrol
StatefulSet mengakhiri setiap Pod, dan menunggunya beralih menjadi Running dan Ready
sebelum melakukan pembaruan ke Pod berikutnya. Sebagai catatan, walaupun pengontrol
StatefulSet tidak akan melanjutkan pembaruan terhadap Pod berikutnya hingga penggantinya
Running dan Ready, pengontrol akan memulihkan Pod apa pun yang mengalami kegagalan selama
proses pembaruan berlangsung.
Pod yang telah menerima pembaruan akan dipulihkan ke versi yang diperbarui, sedangkan
Pod yang belum menerima pembaruan akan dipulihkan ke versi sebelumnya. Dengan cara inilah
pengontrol mencoba untuk terus mempertahankan kesehatan aplikasi dan
pembaruan tetap konsisten ditengah adanya kemungkinan kegagalan intermiten.
Dapatkan Pod untuk melihat image Container-nya:
for p in 01 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
Semua Pod pada StatefulSet saat ini sedang menjalankan image Container sebelumnya.
Catatan:
Kamu juga bisa menggunakan perintah kubectl rollout status sts/<name>
untuk menampilkan status pembaruan bertahap terhadap sebuah StatefulSet
Pembaruan dengan Staging
Kamu dapat melakukan staging terhadap suatu pembaruan StatefulSet dengan
menggunakan parameter partition dari strategi pembaruan RollingUpdate. Suatu
pembaruan yang di-staging akan akan mempertahankan semua Pod dalam StatefulSet
tersebut pada versi yang digunakan saat ini sembari mengizinkan terjadinya
perubahan pada .spec.template dari StatefulSet.
Lakukan patch terhadap StatefulSet web untuk menambahkan partisi pada
fieldupdateStrategy:
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":3}}}}'
statefulset.apps/web patched
Lakukan patch terhadap StatefulSet lagi, untuk mengubah image Container:
kubectl patch statefulset web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"registry.k8s.io/nginx-slim:0.7"}]'
statefulset.apps/web patched
Hapus sebuah Pod dari StatefulSet:
kubectl delete pod web-2
pod "web-2" deleted
Tunggu hingga Pod menjadi Running dan Ready.
kubectl get pod -l app=nginx -w
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 4m
web-1 1/1 Running 0 4m
web-2 0/1 ContainerCreating 0 11s
web-2 1/1 Running 0 18s
Dapatkan image Container Pod:
kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
registry.k8s.io/nginx-slim:0.8
Perhatikan, walaupun strategi pembaruan yang digunakan adalah RollingUpdate,
StatefulSet mengembalikan Pod dengan Container-nya yang semula. Hal ini karena
urutan Pod kurang dari nilai partition yang ditetapkan pada updateStrategy.
Meluncurkan Canary
Kamu dapat meluncurkan canary untuk mencoba suatu perubahan dengan mengurangi
partition yang kamu tentukan sebelumnya di atas.
Lakukan patch terhadap StatefulSet untuk mengurangi jumlah partisi:
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":2}}}}'
statefulset.apps/web patched
Tunggu hingga web-2 menjadi Running dan Ready.
kubectl get pod -l app=nginx -w
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 4m
web-1 1/1 Running 0 4m
web-2 0/1 ContainerCreating 0 11s
web-2 1/1 Running 0 18s
Dapatkan image Container Pod:
kubectl get pod web-2 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
registry.k8s.io/nginx-slim:0.7
Ketika kamu mengubah partition, pengontrol StatefulSet secara otomatis memperbarui Pod
web-2 karena urutan dari Pod tersebut lebih besar dari atau sama dengan
nilai partition.
Hapus Pod web-1:
kubectl delete pod web-1
pod "web-1" deleted
Tunggu sampai Pod web-1 menjadi Running dan Ready.
kubectl get pod web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
registry.k8s.io/nginx-slim:0.8
web-1 dikembalikan ke konfigurasinya yang semula karena urutan Pod lebih kecil
dari partisi. Ketika partisi ditentukan, semua Pod dengan urutan yang lebih besar
dari atau sama dengan jumlah partisi akan diperbarui ketika .spec.template dari
StatefulSet diubah. Jika suatu Pod yang memiliki urutan lebih kecil dari partisi
dihapus atau diakhiri, Pod tersebut akan dikembalikan ke konfigurasinya yang semula.
Peluncuran Bertahap
Kamu dapat melakukan peluncuran bertahap (misalkan peluncuran: linier, geometris, atau eksponensial)
dengan menggunakan pembaruan bertahap yang terpartisi dengan cara yang serupa
ketika kamu meluncurkan canary. Untuk melakukan peluncuran bertahap,
atur partition ke urutan di mana kamu menginginkan pengontrol untuk melakukan
pause terhadap pembaruan.
Saat ini partisi sedang di atur menjadi 2. Ganti partisi menjadi 0:
kubectl patch statefulset web -p '{"spec":{"updateStrategy":{"type":"RollingUpdate","rollingUpdate":{"partition":0}}}}'
statefulset.apps/web patched
Tunggu semua Pod pada StatefulSet menjadi Running dan Ready.
Dengan mengubah nilai partition menjadi 0, kamu mengizinkan StatefulSet
untuk melanjutkan proses pembaruan.
Pembaruan OnDelete
Strategi pembaruan OnDelete menerapkan mekanisme lama (versi 1.6 dan sebelumnya).
Ketika kamu memilih strategi pembaruan ini, pengontrol StatefulSet tidak akan secara
otomatis melakukan pembaruan terhadap Pod ketika suatu perubahan terjadi pada field.spec.template pada StatefulSet. Strategi ini dapat dipilih dengan mengatur
.spec.template.updateStrategy.type menjadi OnDelete.
Menghapus StatefulSet
StatefulSet mendukung penghapusan tidak berjenjang (non-cascading) dan berjenjang (cascading).
Dalam penghapusan tidak berjenjang (non-cascading delete), Pod pada StatefulSet
tidak dihapus ketika StatefulSet terhapus. Pada penghapusan berjenjang (Cascading Delete),
StatefulSet bersama Pod-nya dihapus semua.
Penghapusan Tidak Berjenjang (Non-Cascading)
Pada salah satu jendela terminal, amati Pod pada StatefulSet.
kubectl get pods -w -l app=nginx
Gunakan perintah kubectl delete
untuk menghapus StatefulSet. Pastikan kamu menambahkan parameter --cascade=orphan ke
perintah tersebut. Parameter ini memberitahukan Kubernetes untuk hanya menghapus StatefulSet
dan agar tidak menghapus Pod yang ada padanya.
kubectl delete statefulset web --cascade=orphan
statefulset.apps "web" deleted
Dapatkan Pod untuk melihat statusnya masing-masing:
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 6m
web-1 1/1 Running 0 7m
web-2 1/1 Running 0 5m
Walaupun web telah dihapus, semua Pod masih Running dan Ready.
Hapus web-0:
kubectl delete pod web-0
pod "web-0" deleted
Dapatkan Pod dari StatefulSet:
kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
web-1 1/1 Running 0 10m
web-2 1/1 Running 0 7m
Karena StatefulSet web telah dihapus, maka web-0 tidak dijalankan lagi.
Di salah satu terminal, amati Pod pada StatefulSet.
kubectl get pods -w -l app=nginx
Pada terminal yang lain, buat kembali StatefulSet. Perhatikan, terkecuali
jika kamu telah menghapus Service ngingx (yang seharusnya belum kamu lakukan),
kamu akan melihat sebuah galat yang mengindikasikan bahwa Service tersebut sudah ada.
kubectl apply -f web.yaml
statefulset.apps/web created
service/nginx unchanged
Abaikan galat yang terjadi. Hal itu hanya menunjukkan bahwa suatu upaya telah dilakukan
untuk membuat Service headlessnginx walaupun Service tersebut sebenarnya sudah ada.
Perhatikan keluaran dari perintah kubectl get yang dijalankan pada terminal
yang pertama.
kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-1 1/1 Running 0 16m
web-2 1/1 Running 0 2m
NAME READY STATUS RESTARTS AGE
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 18s
web-2 1/1 Terminating 0 3m
web-2 0/1 Terminating 0 3m
web-2 0/1 Terminating 0 3m
web-2 0/1 Terminating 0 3m
Ketika StatefulSet web dibuat ulang, yang dijalankan pertama kali adalah web-0.
Karena web-1 telah menjadi Running dan Ready, ketika web-0 berubah menjadi
Running dan Ready, web-0 mengadopsi Pod tersebut. Karena kamu membuat ulang
StatefulSet dengan replicas sama dengan 2, ketika web-0 selesai dibuat ulang, dan
ketika web-1 telah ditetapkan menjadi Running dan Ready, maka web-2 diakhiri.
Mari kita lihat kembali konten dari berkas index.html yang disajikan oleh server
web Pod:
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
Walaupun kamu sebelumnya pernah menghapus StatefulSet dan Pod web-0, server web
masih terus menyajikan nama hos sebelumnya yang dimasukkan ke dalam berkas
index.html. Hal ini terjadi karena StatefulSet tidak menghapus PersistentVolume
yang terkait dengan Pod. Ketika kamu membuat ulang StatefulSet dan menjalankan
kembali web-0, PersistentVolume yang digunakan sebelumnya akan dipasang kembali.
Penghapusan Berjenjang (Cascading)
Pada salah satu jendela terminal, amati Pod pada StatefulSet.
kubectl get pods -w -l app=nginx
Pada terminal yang lain, hapus StatefulSet lagi. Kali ini, hilangkan parameter
--cascade=orphan.
kubectl delete statefulset web
statefulset.apps "web" deleted
Perhatikan keluaran dari perintah kubectl get yang dijalankan di terminal
yang pertama, dan tunggu semua status Pod berubah menjadi Terminating.
kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 11m
web-1 1/1 Running 0 27m
NAME READY STATUS RESTARTS AGE
web-0 1/1 Terminating 0 12m
web-1 1/1 Terminating 0 29m
web-0 0/1 Terminating 0 12m
web-0 0/1 Terminating 0 12m
web-0 0/1 Terminating 0 12m
web-1 0/1 Terminating 0 29m
web-1 0/1 Terminating 0 29m
web-1 0/1 Terminating 0 29m
Seperti yang telah kamu saksikan pada bagian Penyekalaan Turun,
Pod diakhiri satu demi satu dengan urutan terbalik dari indeks urutan mereka. Sebelum
mengakhiri suatu Pod, pengontrol StatefulSet menunggu Pod pengganti hingga benar-benar
berakhir.
Catatan:
Walaupun penghapusan berjenjang menghapus suatu StatefulSet bersama Pod yang ada,
penghapusan ini tidak menghapus Service headless yang terkait dengan StatefulSet.
Kamu hapus menghapus Service nginx secara manual.
kubectl delete service nginx
service "nginx" deleted
Buat ulang StatefulSet dan Service headless sekali lagi:
kubectl apply -f web.yaml
service/nginx created
statefulset.apps/web created
Saat semua Pod StatefulSet mengalami transisi ke Running dan Ready, dapatkan
konten dari berkas index.html masing-masing:
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
Walaupun kamu telah menghapus StatefulSet dan semua Pod di dalamnya, Pod dibuat
lagi dengan PersistentVolume yang sama terpasang, dan web-0 dan web-1 masih
menyajikan nama hos masing-masing.
Akhirnya, hapus Service nginx...
kubectl delete service nginx
service "nginx" deleted
...dan StatefulSet web:
kubectl delete statefulset web
statefulset "web" deleted
Kebijakan Manajemen Pod
Untuk beberapa sistem terdistribusi, jaminan pengurutan StatefulSet tidak
penting dan/atau tidak diharapkan. Sistem-sistem tersebut hanya membutuhkan
keunikan dan identitas. Untuk mengatasi ini, pada Kubernetes 1.7, kami
memperkenalkan .spec.podManagementPolicy pada objek API StatefulSet.
Manajemen Pod OrderedReady
Manajemen Pod OrderedReady adalah bawaan dari StatefulSet. Manajemen
dengan cara ini memberitahukan pengontrol StatefulSet untuk menghormati
jaminan pengurutan yang sudah ditunjukkan sebelumnya.
Manajemen Pod Parallel
Manajemen Pod Parallel memberitahukan pengontrol StatefulSet untuk
menjalankan atau mengakhiri semua Pod secara bersamaan (paralel), dan tidak menunggu
suatu Pod menjadi Running dan Ready atau benar-benar berakhir sebelum menjalankan atau
mengakhiri Pod yang lain.
Selama penghapusan, StatefulSet menghapus semua Pod secara serentak; tidak menghentikan
Pod berdasarkan urutan indeksnya terlebih dahulu sebelum menghapus Pod tersebut.
Tutup terminal di mana perintah kubectl get dijalankan dan hapus Service nginx:
kubectl delete svc nginx
Catatan:
Kamu juga perlu menghapus media penyimpanan persisten untuk PersistentVolume
yang digunakan dalam tutorial ini.
Ikuti langkah-langkah yang dibutuhkan, berdasarkan lingkungan yang kamu gunakan,
konfigurasi penyimpanan, dan metode penyediaannya, untuk memastikan semua
penyimpanan dapat dimanfaatkan lagi.