Catatan perev. : Bagian pertama dari seri ini dikhususkan untuk memperkenalkan Istio dan menunjukkannya dalam aksi. Sekarang kita akan berbicara tentang aspek-aspek yang lebih kompleks dari konfigurasi dan penggunaan mesh layanan ini, dan khususnya, tentang perutean yang diatur secara halus dan manajemen lalu lintas jaringan.
Kami juga mengingatkan Anda bahwa artikel tersebut menggunakan konfigurasi (manifes untuk Kubernetes dan Istio) dari repositori istio-mastery . Manajemen lalu lintas
Dengan Istio, fitur baru muncul di kluster untuk menyediakan:
- Routing query dinamis : peluncuran canary, pengujian A / B;
- Penyeimbangan beban : sederhana dan konsisten, berdasarkan hash;
- Fall recovery : timeout, retries, pemutus sirkuit;
- Input kesalahan : keterlambatan, gangguan permintaan, dll.
Dalam kelanjutan artikel, fitur-fitur ini akan ditampilkan sebagai contoh aplikasi yang dipilih dan konsep-konsep baru akan diperkenalkan di sepanjang jalan. Konsep tersebut pertama adalah
DestinationRules
(yaitu aturan tentang penerima lalu lintas / permintaan - kira-kira. Terjemahan) , Dengan mana kami mengaktifkan pengujian A / B.
Pengujian A / B: DestinationRules in Practice
Pengujian A / B digunakan dalam kasus di mana ada dua versi aplikasi (biasanya mereka berbeda secara visual) dan kami tidak 100% yakin mana yang akan meningkatkan interaksi pengguna. Karenanya, kami secara bersamaan meluncurkan kedua versi dan mengumpulkan metrik.
Untuk menggunakan versi kedua frontend yang diperlukan untuk mendemonstrasikan pengujian A / B, jalankan perintah berikut:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml deployment.extensions/sa-frontend-green created
Manifes penyebaran untuk "versi hijau" berbeda di dua tempat:
- Gambar didasarkan pada tag lain -
istio-green
, - Pod memiliki
version: green
label version: green
.
Karena kedua penyebaran memiliki
app: sa-frontend
label, permintaan yang dialihkan oleh
sa-external-services
virtual
sa-external-services
ke layanan
sa-frontend
akan dialihkan ke semua instance dan beban akan didistribusikan menggunakan
algoritma round-robin , yang akan mengarah pada situasi berikut:
File yang diminta tidak ditemukanFile-file ini tidak ditemukan karena mereka dipanggil secara berbeda di versi aplikasi yang berbeda. Mari kita pastikan ini:
$ curl --silent http://$EXTERNAL_IP/ | tr '"' '\n' | grep main /static/css/main.c7071b22.css /static/js/main.059f8e9c.js $ curl --silent http://$EXTERNAL_IP/ | tr '"' '\n' | grep main /static/css/main.f87cd8c9.css /static/js/main.f7659dbb.js
Ini berarti bahwa
index.html
, meminta satu versi file statis, dapat dikirim oleh load balancer ke pod yang memiliki versi berbeda, di mana, untuk alasan yang jelas, file seperti itu tidak ada. Oleh karena itu, agar aplikasi berfungsi, kita perlu memberi batasan: "
versi aplikasi yang sama yang memberikan index.html juga harus melayani permintaan berikutnya ."
Kami akan mencapai tujuan tersebut dengan penyeimbangan beban berbasis hash yang konsisten
(Consistent Hash Loadbalancing) . Dalam hal ini,
permintaan dari satu klien dikirim ke instance backend yang sama , yang digunakan properti yang telah ditentukan sebelumnya - misalnya, header HTTP. Diimplementasikan menggunakan DestinationRules.
Aturan Aturan
Setelah
VirtualService telah mengirim permintaan ke layanan yang diinginkan, menggunakan DestinationRules kita dapat menentukan kebijakan yang akan diterapkan pada lalu lintas yang ditujukan untuk instance layanan ini:
Manajemen Lalu Lintas Sumber Daya IstioCatatan : Efek sumber daya Istio pada lalu lintas jaringan disajikan di sini dengan cara yang disederhanakan. Lebih tepatnya, keputusan untuk mengirim contoh permintaan dibuat oleh Utusan di Ingress Gateway dikonfigurasi dalam CRD.
Dengan menggunakan Aturan Tujuan, kami dapat mengonfigurasi penyeimbangan muatan sehingga hash yang konsisten digunakan dan respons dari layanan yang sama dijamin untuk pengguna yang sama. Konfigurasi berikut memungkinkan ini (
destinationrule-sa-frontend.yaml ) untuk mencapai ini:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: sa-frontend spec: host: sa-frontend trafficPolicy: loadBalancer: consistentHash: httpHeaderName: version # 1
1 - hash akan dihasilkan berdasarkan pada isi header
version
HTTP.
Terapkan konfigurasi dengan perintah berikut:
$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml destinationrule.networking.istio.io/sa-frontend created
Sekarang jalankan perintah di bawah ini dan pastikan Anda mendapatkan file yang Anda butuhkan saat menentukan
version
header:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' '\n' | grep main
Catatan : Untuk menambahkan nilai yang berbeda dalam judul dan menguji hasilnya langsung di browser, Anda dapat menggunakan
ekstensi ini untuk Chrome
(atau yang ini untuk Firefox - kira-kira Terjemahkan.) .
Secara umum, DestinationRules memiliki lebih banyak opsi di bidang penyeimbangan beban - periksa
dokumentasi resmi untuk detailnya.
Sebelum mempelajari VirtualService lebih lanjut, kami akan menghapus "versi hijau" dari aplikasi dan aturan yang sesuai dalam arah lalu lintas dengan menjalankan perintah berikut:
$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml deployment.extensions “sa-frontend-green” deleted $ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml destinationrule.networking.istio.io “sa-frontend” deleted
Mirroring: Layanan Virtual dalam Praktek
Shadowing
("shielding") atau Mirroring
("mirroring") digunakan dalam kasus-kasus ketika kami ingin menguji perubahan dalam produksi tanpa mempengaruhi pengguna akhir: untuk ini kami menduplikasi ("mirror") permintaan untuk instance kedua, di mana perubahan yang diperlukan dibuat, dan lihat konsekuensinya.
Sederhananya, ini adalah saat (a) kolega Anda memilih masalah yang paling kritis dan mengajukan permintaan dalam bentuk gumpalan tanah yang sangat besar sehingga tidak ada yang bisa benar-benar membuat ulasan untuknya.Untuk menguji skenario ini dalam tindakan, buat instance SA-Logic kedua dengan bug (
buggy
) dengan menjalankan perintah berikut:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml deployment.extensions/sa-logic-buggy created
Dan sekarang kita menjalankan perintah untuk memastikan bahwa semua instance dengan
app=sa-logic
memiliki label dengan versi yang sesuai:
$ kubectl get pods -l app=sa-logic --show-labels NAME READY LABELS sa-logic-568498cb4d-2sjwj 2/2 app=sa-logic,version=v1 sa-logic-568498cb4d-p4f8c 2/2 app=sa-logic,version=v1 sa-logic-buggy-76dff55847-2fl66 2/2 app=sa-logic,version=v2 sa-logic-buggy-76dff55847-kx8zz 2/2 app=sa-logic,version=v2
Layanan
sa-logic
menargetkan pod dengan label
app=sa-logic
, sehingga semua permintaan akan didistribusikan di antara semua instance:

... tapi kami ingin permintaan diarahkan ke instance dengan versi v1 dan dicerminkan ke instance dengan versi v2:

Kami akan mencapai ini melalui VirtualService dalam kombinasi dengan DestinationRule, di mana aturan akan menentukan himpunan bagian dan rute dari VirtualService ke subset tertentu.
Mendefinisikan Subset dalam Aturan Tujuan
Subset didefinisikan oleh konfigurasi berikut (
sa-logic-subset-destinationrule.yaml ):
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: sa-logic spec: host: sa-logic # 1 subsets: - name: v1 # 2 labels: version: v1 # 3 - name: v2 labels: version: v2
- Tuan
host
menentukan bahwa aturan ini hanya berlaku untuk kasus-kasus ketika rute menuju sa-logic
; - Nama-nama himpunan bagian digunakan saat routing ke instance dari subset;
- Label menentukan pasangan nilai kunci yang harus dicocokkan oleh instance untuk menjadi bagian dari subset.
Terapkan konfigurasi dengan perintah berikut:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml destinationrule.networking.istio.io/sa-logic created
Sekarang setelah himpunan bagian didefinisikan, Anda bisa melanjutkan dan mengkonfigurasi VirtualService untuk menerapkan aturan untuk permintaan ke s-logika sehingga mereka:
- Diarahkan ke subset dari
v1
, - Dicerminkan ke subset dari
v2
.
Manifes berikut memungkinkan Anda untuk mencapai rencana Anda (
sa-logic-subsets-shadowing-vs. Yaml ):
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: sa-logic spec: hosts: - sa-logic http: - route: - destination: host: sa-logic subset: v1 mirror: host: sa-logic subset: v2
Tidak ada penjelasan yang diperlukan di sini, jadi lihat saja tindakannya:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml virtualservice.networking.istio.io/sa-logic created
Tambahkan beban dengan memanggil perintah ini:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment \ -H "Content-type: application/json" \ -d '{"sentence": "I love yogobella"}'; \ sleep .8; done
Mari kita lihat hasilnya di Grafana, di mana kita dapat melihat bahwa versi
buggy
macet untuk ~ 60% dari permintaan, tetapi tidak satu pun dari crash ini mempengaruhi pengguna akhir karena mereka memiliki layanan yang berfungsi.
Keberhasilan tanggapan dari berbagai versi layanan sa-logicDi sini kita melihat untuk pertama kalinya bagaimana VirtualService diterapkan ke Utusan layanan kami: ketika
sa-web-app
membuat permintaan untuk
sa-logic
, ia melewati Utusan sespan, yang - melalui VirtualService - dikonfigurasi untuk merutekan permintaan ke subset v1 dan mirror permintaan ke subset dari v2 dari layanan
sa-logic
.
Saya tahu: Anda sudah punya waktu untuk berpikir bahwa Layanan Virtual itu sederhana. Pada bagian selanjutnya, kami memperluas pandangan ini dengan fakta bahwa mereka juga benar-benar luar biasa.
Gulungan kenari
Canary Deployment adalah proses meluncurkan versi baru aplikasi untuk sejumlah kecil pengguna. Ini digunakan untuk memastikan bahwa tidak ada masalah dalam rilis dan hanya setelah itu, sudah yakin dengan kualitas (rilis) yang cukup, untuk menyebar ke audiens yang lebih besar.
Untuk mendemonstrasikan peluncuran kenari, kami akan terus bekerja dengan sub-bagian dari
buggy
dalam
sa-logic
.
Jangan buang waktu dan segera kirim 20% pengguna ke versi dengan bug (itu akan mewakili peluncuran kenari kami), dan sisanya 80% untuk layanan normal. Untuk melakukan ini, terapkan VirtualService berikut (
sa-logic-subsets-canary-vs.yaml ):
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: sa-logic spec: hosts: - sa-logic http: - route: - destination: host: sa-logic subset: v1 weight: 80 # 1 - destination: host: sa-logic subset: v2 weight: 20 # 1
1 adalah bobot, yang menentukan persentase permintaan yang akan dikirim ke penerima atau sebagian dari penerima.
Perbarui konfigurasi VirtualService sebelumnya untuk
sa-logic
perintah berikut:
$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml virtualservice.networking.istio.io/sa-logic configured
... dan segera lihat bahwa bagian dari permintaan macet:
$ while true; do \ curl -i http://$EXTERNAL_IP/sentiment \ -H "Content-type: application/json" \ -d '{"sentence": "I love yogobella"}' \ --silent -w "Time: %{time_total}s \t Status: %{http_code}\n" \ -o /dev/null; sleep .1; done Time: 0.153075s Status: 200 Time: 0.137581s Status: 200 Time: 0.139345s Status: 200 Time: 30.291806s Status: 500
Layanan Virtual mengaktifkan peluncuran kenari: dalam hal ini, kami mempersempit konsekuensi potensial dari masalah menjadi 20% dari basis pengguna. Hebat! Sekarang, dalam setiap kasus, ketika kita tidak yakin dengan kode kita (dengan kata lain, selalu ...), kita bisa menggunakan mirroring dan canary rollouts.
Timeout dan Retries
Tetapi tidak selalu bug ada dalam kode. Dalam daftar "
8 kesalahan dalam komputasi terdistribusi " di tempat pertama muncul pendapat keliru bahwa "jaringan dapat diandalkan." Pada kenyataannya, jaringan
tidak dapat diandalkan, dan untuk alasan ini kita perlu waktu tunggu dan
coba lagi .
Untuk demonstrasi, kami akan terus menggunakan versi
sa-logic
(
buggy
), dan kami akan mensimulasikan jaringan yang tidak dapat diandalkan dengan kegagalan acak.
Biarkan layanan kami dengan bug memiliki 1/3 peluang untuk tanggapan yang terlalu lama, 1/3 untuk penyelesaian dengan Kesalahan Server Internal, dan 1/3 untuk pengembalian halaman yang berhasil.
Untuk mengurangi konsekuensi dari masalah tersebut dan menjadikan hidup lebih baik bagi pengguna, kami dapat:
- tambahkan batas waktu jika layanan merespons lebih dari 8 detik,
- coba lagi jika permintaan gagal.
Untuk implementasi, kami akan menggunakan definisi sumber daya berikut (
sa-logic-retries-timeout-vs.yaml ):
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: sa-logic spec: hosts: - sa-logic http: - route: - destination: host: sa-logic subset: v1 weight: 50 - destination: host: sa-logic subset: v2 weight: 50 timeout: 8s # 1 retries: attempts: 3 # 2 perTryTimeout: 3s # 3
- Batas waktu permintaan diatur ke 8 detik;
- Upaya permintaan berulang dilakukan 3 kali;
- Dan setiap upaya dianggap tidak berhasil jika waktu respons melebihi 3 detik.
Jadi kami telah mencapai optimasi, karena pengguna tidak perlu menunggu lebih dari 8 detik dan kami akan melakukan tiga upaya baru untuk mendapatkan jawaban jika terjadi kegagalan, meningkatkan peluang respons yang berhasil.
Terapkan konfigurasi yang diperbarui dengan perintah berikut:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml virtualservice.networking.istio.io/sa-logic configured
Dan periksa dalam grafik Grafana bahwa jumlah jawaban yang sukses sudah berakhir:
Perbaikan dalam statistik respons yang berhasil setelah menambahkan batas waktu dan coba lagiSebelum melanjutkan ke bagian berikutnya
(atau lebih tepatnya, ke bagian selanjutnya dari artikel ini, karena tidak akan ada lagi percobaan dalam praktik ini - sekitar Terjemahan.) , Hapus
sa-logic-buggy
dan VirtualService dengan menjalankan perintah berikut:
$ kubectl delete deployment sa-logic-buggy deployment.extensions “sa-logic-buggy” deleted $ kubectl delete virtualservice sa-logic virtualservice.networking.istio.io “sa-logic” deleted
Pemutus Sirkuit dan Pola Sekat
Kita berbicara tentang dua pola penting dalam arsitektur layanan mikro yang memungkinkan Anda untuk mencapai layanan
penyembuhan diri .
Circuit Breaker ("circuit breaker") digunakan untuk menghentikan permintaan yang datang ke layanan yang dianggap tidak sehat dan memulihkannya sementara permintaan klien dialihkan ke contoh layanan yang sehat (yang meningkatkan persentase respons yang berhasil).
(Catatan: Deskripsi pola yang lebih rinci dapat ditemukan, misalnya, di sini .)Bulkhead ("partisi") mengisolasi kegagalan layanan dari kekalahan seluruh sistem. Misalnya, layanan B rusak, dan layanan lain (klien layanan B) membuat permintaan untuk layanan B, sebagai akibatnya ia akan menggunakan kumpulan utangnya dan tidak akan dapat melayani permintaan lain (bahkan jika mereka tidak terkait dengan layanan B).
(Catatan: Deskripsi pola yang lebih rinci dapat ditemukan, misalnya, di sini .)Saya akan menghilangkan detail penerapan pola-pola ini, karena mudah ditemukan di
dokumentasi resmi , dan saya benar-benar ingin menunjukkan otentikasi dan otorisasi, yang akan dibahas pada bagian selanjutnya dari artikel ini.
PS dari penerjemah
Baca juga di blog kami: