Dalam kasus saya, ternyata menjadi kasus sederhana spasi .
Ternyata, saya memiliki ruang yang dimasukkan setelah yang terakhir; dan sebelum "" C:\Program Files\MySQL\MySQL Server 5.7 " Untuk alasan yang sangat sederhana ini, apa pun yang saya lakukan, MySql masih belum dikenali.
Setelah saya menghilangkan spasi sebelum dan sesudah jalur, itu bekerja dengan sempurna.
Dalam retrospeksi, sepertinya jawaban yang sangat jelas, tetapi tidak ada yang
menyebutkannya di mana saja.
Juga, saya baru mengenal semua jendela ini, jadi tolong permisi jika kedengarannya sangat sederhana.
What you need its #1 communication from App1-x to Mysql router and #2 a VIP/LB from MysqlRoutere to external mysql instances.
Table of Contents
- 1 - Halo Minikube
- Sebelum kamu memulai
- Membuat sebuah klaster Minikube
- Membuat sebuah Deployment
- Membuat sebuah Servis
- Aktifkan addons
- Bersih-bersih
- Selanjutnya
- 3.1 - Mengekspos Alamat IP Eksternal untuk Mengakses Aplikasi di dalam Klaster
- Sebelum kamu memulai
- Membuat sebuah objek Service untuk sebuah aplikasi yang dijalankan pada lima buah Pod
- Selanjutnya
- 4.1 - Dasar-dasar StatefulSet
- Sebelum kamu memulai
- Membuat Sebuah StatefulSet
- Pembuatan Pod Berurutan
- Pod pada StatefulSet
- Memeriksa Indeks Urutan Pod
- Menggunakan Identitas Jaringan yang Tetap
- Penyekalaan StatefulSet
- Penyekalaan Naik
- Penyekalaan Turun
- Penghentian Pod Berurutan
- Memperbarui StatefulSet
- Pembaruan Bertahap (RollingUpdate)
- Pembaruan OnDelete
- Menghapus StatefulSet
- Penghapusan Tidak Berjenjang (Non-Cascading)
- Penghapusan Berjenjang (Cascading)
- Kebijakan Manajemen
Pod
- Manajemen Pod OrderedReady
- Manajemen Pod Parallel
Well start with #2 configuration of Mysql instances VIP. You will need a service without selector.
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
ports:
- name: mysql
port: 3306
protocol: TCP
targetPort: 3306
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
name: mysql-service
subsets:
- addresses:
- ip: 192.168.123.130
- ip: 192.168.123.131
- ip: 192.168.123.132
ports:
- name: mysql
port: 3306
protocol: TCP
You don't need LoadBalancer
cuz you will connect only inside
cluster. So, use ClusterIp
instead.
#1 Create MysqlRouter deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-router
namespace: mysql-router
spec:
replicas: 1
selector:
matchLabels:
app: mysql-router
template:
metadata:
labels:
app: mysql-router
version: v1
spec:
containers:
- name: mysql-router
image: mysql/mysql-router
env:
- name: MYSQL_HOST
value: "mysql-service"
- name: MYSQL_PORT
value: "3306"
- name: MYSQL_USER
value: "root"
- name: MYSQL_PASSWORD
value: "[email protected]"
imagePullPolicy: Always
ports:
- containerPort: 6446
To connect to external MySQL instances trough VIP/ClusterIP use mysql-service
service and if deployment and service is in same namespace use mysql-service
as hostname or put there a CLusterIP
from kubectl get service mysql-service
apiVersion: v1
kind: Service
metadata:
name: mysql-router-service
namespace: mysql-router
labels:
app: mysql-router
spec:
selector:
app: mysql-router
ports:
- name: mysql
port: 6446
protocol: TCP
targetPort: 6446
type: ClusterIP
You can connect within kubernetes cluster to mysql-router-service
hostname in same namespace and outside namespace to mysql-router-service.namespace.svc
or outside kubernetes cluster use NodePort
or LoadBalancer
.
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.
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:
var http = require('http');
var handleRequest = function(request, response) {
console.log('Received request for URL: ' + request.url);
response.writeHead(200);
response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);
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
Buka dasbor Kubernetes di dalam browser:
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.
kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4
Lihat Deployment:
Keluaran:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 1m
Lihat Pod:
Keluaran:
NAME READY STATUS RESTARTS AGE
hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m
Lihat event klaster:
Lihat konfigurasi 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
:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
Tanda --type=LoadBalancer
menunjukkan bahwa kamu ingin ekspos Servis keluar dari klaster.
Lihat Servis yang baru kamu buat:
Keluaran:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 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.
Daftar addons yang ada saat ini:
Keluaran:
addon-manager: enabled
coredns: disabled
dashboard: enabled
default-storageclass: enabled
efk: disabled
freshpod: disabled
heapster: disabled
ingress: disabled
kube-dns: enabled
metrics-server: disabled
nvidia-driver-installer: disabled
nvidia-gpu-device-plugin: disabled
registry: disabled
registry-creds: disabled
storage-provisioner: enabled
Aktifkan sebuah addon, misalnya heapster
:
minikube addons enable heapster
Keluaran:
heapster was successfully enabled
Lihat Pod dan Servis yang baru
saja kamu buat:
kubectl get pod,svc -n kube-system
Keluaran:
NAME READY STATUS RESTARTS AGE
pod/heapster-9jttx 1/1 Running 0 26s
pod/influxdb-grafana-b29w8 2/2 Running 0 26s
pod/kube-addon-manager-minikube 1/1 Running 0 34m
pod/kube-dns-6dcb57bcc8-gv7mw 3/3 Running 0 34m
pod/kubernetes-dashboard-5498ccf677-cgspw 1/1 Running 0 34m
pod/storage-provisioner 1/1 Running 0 34m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/heapster ClusterIP 10.96.241.45 80/TCP 26s
service/kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP 34m
service/kubernetes-dashboard NodePort 10.109.29.1 80:30000/TCP 34m
service/monitoring-grafana NodePort 10.99.24.54 80:30002/TCP 26s
service/monitoring-influxdb ClusterIP 10.111.169.94 8083/TCP,8086/TCP 26s
Non-aktifkan heapster
:
minikube addons disable heapster
Keluaran:
heapster was successfully disabled
Bersih-bersih
Sekarang, mari kita bersihkan semua resource yang kamu buat di klaster:
kubectl delete service hello-node
kubectl delete deployment hello-node
Kamu juga boleh mematikan mesin virtual atau virtual machine (VM) untuk minikube:
Kamu juga boleh menghapus minikube VM:
Selanjutnya
- Pelajari lebih lanjut tentang Deployment.
- Pelajari lebih
lanjut tentang Deploy aplikasi.
- Pelajari lebih lanjut tentang Servis.
3.1 - Mengekspos Alamat IP Eksternal untuk Mengakses Aplikasi di dalam Klaster
Dokumen ini menjelaskan bagaimana cara membuat objek Service Kubernetes yang mengekspos alamat IP eksternal.
Sebelum kamu memulai
Instal kubectl.
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:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: load-balancer-example
name: hello-world
spec:
replicas: 5
selector:
matchLabels:
app.kubernetes.io/name: load-balancer-example
template:
metadata:
labels:
app.kubernetes.io/name: load-balancer-example
spec:
containers:
- image: gcr.io/google-samples/node-hello:1.0
name: hello-world
ports:
- containerPort: 8080
kubectl apply -f https://k8s.io/examples/service/load-balancer-example.yaml
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:
kubectl expose deployment hello-world --type=LoadBalancer --name=my-service
Tampilkan informasi mengenai Service:
kubectl get services my-service
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
Tampilkan informasi detail mengenai Service:
kubectl describe services my-service
Perintah di atas akan menampilkan keluaran sebagai berikut:
Name: my-service
Namespace: default
Labels: app.kubernetes.io/name=load-balancer-example
Annotations:
Selector: app.kubernetes.io/name=load-balancer-example
Type: LoadBalancer
IP: 10.3.245.137
LoadBalancer Ingress: 104.198.205.71
Port: 8080/TCP
NodePort: 32377/TCP
Endpoints: 10.0.0.6:8080,10.0.1.6:8080,10.0.1.7:8080 + 2 more...
Session Affinity: None
Events:
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:
kubectl get pods --output=wide
Keluaran yang diberikan akan menyerupai:
NAME ... IP NODE
hello-world-2895499144-1jaz9 ... 10.0.1.6 gke-cluster-1-default-pool-e0b8d269-1afc
hello-world-2895499144-2e5uh ... 10.0.1.8 gke-cluster-1-default-pool-e0b8d269-1afc
hello-world-2895499144-9m4h2 ... 10.0.0.6 gke-cluster-1-default-pool-e0b8d269-5v7a
hello-world-2895499144-o4z13 ... 10.0.1.7 gke-cluster-1-default-pool-e0b8d269-1afc
hello-world-2895499144-segjf ... 10.0.2.5 gke-cluster-1-default-pool-e0b8d269-cpuc
Gunakan alamat IP eksternal (LoadBalancer Ingress
) untuk mengakses aplikasi Hello World:
curl http://:
dimana
adalah alamat IP eksternal (LoadBalancer Ingress
) dari Service kamu, dan
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:
kubectl delete deployment hello-world
Selanjutnya
Pelajari lebih lanjut cara untuk menghubungkan aplikasi dengan berbagai Service.
4.1 - Dasar-dasar StatefulSet
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:
- Pod
- DNS klaster
- Service headless
- PersistentVolume
- Penyediaan PersistentVolume
- StatefulSet
- Alat baris perintah (command line tool) kubectl
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
.
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
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 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.
kubectl get pods -w -l app=nginx
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 19s
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 18s
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 -
. 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-test
nslookup web-0.nginx
Keluarannya
akan seperti:
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.244.1.6
nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.244.2.6
(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 /bin/sh
perintah itu akan menjalankan shell baru. Di dalam shell yang baru jalankan:
# Jalankan ini di dalam shell Container dns-test
nslookup web-0.nginx
Keluarannya akan seperti:
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.244.1.7
nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.244.2.8
(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.
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
Pengontrol StatefulSet membuat dua PersistentVolumeClaim yang terikat ke dua PersistentVolume.
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
. Field volumeMounts
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'; done
for i in 0 1; do kubectl exec -i -t "web-$i" -- curl http://localhost/; done
web-0
web-1
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 field replicas
. 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.
kubectl get pods -w -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 2h
web-1 1/1 Running 0 2h
NAME READY STATUS RESTARTS AGE
web-2 0/1 Pending 0 0s
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 19s
web-3 0/1 Pending 0 0s
web-3 0/1 Pending 0 0s
web-3 0/1 ContainerCreating 0 0s
web-3 1/1 Running 0 18s
web-4 0/1 Pending 0 0s
web-4 0/1 Pending 0 0s
web-4 0/1 ContainerCreating 0 0s
web-4 1/1 Running 0 19s
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.
Dapatkan PersistentVolumeClaim dari StatefulSet:
kubectl get pvc -l app=nginx
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-15c268c7-b507-11e6-932f-42010a800002 1Gi RWO 13h
www-web-1 Bound pvc-15c79307-b507-11e6-932f-42010a800002 1Gi RWO 13h
www-web-2 Bound pvc-e1125b27-b508-11e6-932f-42010a800002 1Gi RWO 13h
www-web-3 Bound pvc-e1176df6-b508-11e6-932f-42010a800002 1Gi RWO 13h
www-web-4 Bound pvc-e11bb5f8-b508-11e6-932f-42010a800002 1Gi RWO 13h
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 field spec.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:
kubectl get pod -l app=nginx -w
Keluarannya akan seperti:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 7m
web-1 1/1 Running 0 7m
web-2 1/1 Running 0 8m
web-2 1/1 Terminating 0 8m
web-2 1/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Terminating 0 8m
web-2 0/1 Pending 0 0s
web-2 0/1 Pending 0 0s
web-2 0/1 ContainerCreating 0 0s
web-2 1/1 Running 0 19s
web-1 1/1 Terminating 0 8m
web-1 0/1 Terminating 0 8m
web-1 0/1 Terminating 0 8m
web-1 0/1 Terminating 0 8m
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 6s
web-0 1/1 Terminating 0 7m
web-0 1/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
web-0 0/1 Terminating 0 7m
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 10s
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 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
k8s.gcr.io/nginx-slim:0.8
k8s.gcr.io/nginx-slim:0.8
k8s.gcr.io/nginx-slim:0.8
Semua Pod pada
StatefulSet saat ini sedang menjalankan image Container sebelumnya.
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 field updateStrategy
:
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":"k8s.gcr.io/nginx-slim:0.7"}]'
statefulset.apps/web patched
Hapus sebuah Pod dari StatefulSet:
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}}'
k8s.gcr.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}}'
k8s.gcr.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
:
pod "web-1" deleted
Tunggu sampai Pod web-1
menjadi Running dan Ready.
kubectl get pod -l app=nginx -w
Keluarannya akan seperti:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 6m
web-1 0/1 Terminating 0 6m
web-2 1/1 Running 0 2m
web-1 0/1 Terminating 0 6m
web-1 0/1 Terminating 0 6m
web-1 0/1 Terminating 0 6m
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 18s
Dapatkan image Container dari Pod web-1
:
kubectl get pod web-1 --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'
k8s.gcr.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.
kubectl get pod -l app=nginx -w
Keluarannya akan seperti:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 3m
web-1 0/1 ContainerCreating 0 11s
web-2 1/1 Running 0 2m
web-1 1/1 Running 0 18s
web-0 1/1 Terminating 0 3m
web-0 1/1 Terminating 0 3m
web-0 0/1 Terminating 0 3m
web-0 0/1 Terminating 0 3m
web-0 0/1 Terminating 0 3m
web-0 0/1 Terminating 0 3m
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 3s
Dapatkan detail image Container dari Pod pada StatefulSet:
for p in 0 1 2; do kubectl get pod "web-$p" --template '{{range $i, $c := .spec.containers}}{{$c.image}}{{end}}'; echo; done
k8s.gcr.io/nginx-slim:0.7
k8s.gcr.io/nginx-slim:0.7
k8s.gcr.io/nginx-slim:0.7
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
:
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 headless nginx
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.
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.
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
podManagementPolicy: "Parallel"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
Unduh contoh di atas, dan simpan ke sebuah berkas dengan nama web-parallel.yaml
.
Manifes ini serupa dengan yang telah kamu unduh sebelumnya kecuali .spec.podManagementPolicy
dari
StatefulSet web
diatur ke Parallel
.
Di salah satu terminal, amati Pod pada StatefulSet.
kubectl get pod -l app=nginx -w
Pada terminal yang lain, buat StatefulSet dan Service dari manifes tadi:
kubectl apply -f web-parallel.yaml
service/nginx created
statefulset.apps/web created
Perhatikan keluaran dari perintah kubectl get
yang kamu jalankan pada terminal yang pertama.
kubectl get pod -l app=nginx -w
NAME READY STATUS RESTARTS AGE
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-1 0/1 ContainerCreating 0 0s
web-0 1/1 Running 0 10s
web-1 1/1 Running 0 10s
Pengontrol StatefulSet menjalankan web-0
dan web-
berbarengan.
Biarkan terminal kedua tetap terbuka, kemudian, di jendela terminal yang lain lakukan penyekalaan terhadap
StatefulSet:
kubectl scale statefulset/web --replicas=4
statefulset.apps/web scaled
Perhatikan keluaran terminal di mana perintah kubectl get
dijalankan.
web-3 0/1 Pending 0 0s
web-3 0/1 Pending 0 0s
web-3 0/1 Pending 0 7s
web-3 0/1 ContainerCreating 0 7s
web-2 1/1 Running 0 10s
web-3 1/1 Running 0 26s
StatefulSet menjalankan dua Pod baru dan tidak menunggu Pod pertama menjadi Running dan Ready terlebih dahulu sebelum menjalankan Pod yang kedua.
Bersihkan
Kamu harus membuka dua terminal yang siap untuk menjalankan perintah kubectl
sebagai bagian dari pembersihan.
kubectl delete sts web
# sts adalah singkatan dari statefulset
Kamu dapat mengamati kubectl get
untuk melihat semua Pod yang sedang dihapus.
kubectl get pod -l app=nginx -w
web-3 1/1 Terminating 0 9m
web-2 1/1 Terminating 0 9m
web-3 1/1 Terminating 0 9m
web-2 1/1 Terminating 0 9m
web-1 1/1 Terminating 0 44m
web-0 1/1 Terminating 0 44m
web-0 0/1 Terminating 0 44m
web-3 0/1 Terminating 0 9m
web-2 0/1 Terminating 0 9m
web-1 0/1 Terminating 0 44m
web-0 0/1 Terminating 0 44m
web-2 0/1 Terminating 0 9m
web-2 0/1 Terminating 0 9m
web-2 0/1 Terminating 0 9m
web-1 0/1 Terminating 0 44m
web-1 0/1 Terminating 0 44m
web-1 0/1 Terminating 0 44m
web-0 0/1 Terminating 0 44m
web-0 0/1 Terminating 0 44m
web-0 0/1 Terminating 0 44m
web-3 0/1 Terminating 0 9m
web-3 0/1 Terminating 0 9m
web-3 0/1 Terminating 0 9m
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
: