Kembali ke layanan microser dengan Istio. Bagian 2



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:

  1. Gambar didasarkan pada tag lain - istio-green ,
  2. 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 ditemukan

File-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 Istio

Catatan : 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 

  1. Tuan host menentukan bahwa aturan ini hanya berlaku untuk kasus-kasus ketika rute menuju sa-logic ;
  2. Nama-nama himpunan bagian digunakan saat routing ke instance dari subset;
  3. 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:

  1. Diarahkan ke subset dari v1 ,
  2. 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-logic

Di 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:

  1. tambahkan batas waktu jika layanan merespons lebih dari 8 detik,
  2. 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 

  1. Batas waktu permintaan diatur ke 8 detik;
  2. Upaya permintaan berulang dilakukan 3 kali;
  3. 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 lagi

Sebelum 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:

Source: https://habr.com/ru/post/id440378/


All Articles