Kembali ke layanan mikro dengan Istio. Bagian 2

Kembali ke layanan mikro dengan Istio. Bagian 2

Catatan. terjemahan: Bagian pertama Seri ini didedikasikan untuk memperkenalkan kemampuan Istio dan mendemonstrasikannya dalam tindakan. Sekarang kita akan berbicara tentang aspek yang lebih kompleks dari konfigurasi dan penggunaan mesh layanan ini, dan khususnya, tentang perutean yang disesuaikan dan manajemen lalu lintas jaringan.

Kami juga mengingatkan Anda bahwa artikel tersebut menggunakan konfigurasi (manifest untuk Kubernetes dan Istio) dari repositori penguasaan istio.

manajemen lalu lintas

Dengan Istio, kemampuan baru muncul di cluster untuk menyediakan:

  • Perutean permintaan dinamis: peluncuran canary, pengujian A/B;
  • Penyeimbang beban: sederhana dan konsisten, berdasarkan hash;
  • Pemulihan setelah jatuh: batas waktu, percobaan ulang, pemutus arus;
  • Memasukkan kesalahan: penundaan, permintaan dibatalkan, dll.

Seiring berlanjutnya artikel, kemampuan ini akan diilustrasikan menggunakan aplikasi yang dipilih sebagai contoh dan konsep baru akan diperkenalkan seiring berjalannya waktu. Konsep pertama adalah DestinationRules (yaitu aturan tentang penerima lalu lintas/permintaan - kira-kira terjemahan), yang dengannya kami mengaktifkan pengujian A/B.

Pengujian A/B: DestinationRules dalam praktiknya

Pengujian A/B digunakan jika terdapat dua versi aplikasi (biasanya keduanya berbeda secara visual) dan kami tidak 100% yakin versi mana yang akan meningkatkan pengalaman pengguna. Oleh karena itu, kami menjalankan kedua versi secara bersamaan dan mengumpulkan metrik.

Untuk menerapkan frontend versi kedua, 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 penerapan untuk versi hijau berbeda dalam dua hal:

  1. Gambar ini didasarkan pada tag yang berbeda - istio-green,
  2. Pod memiliki label version: green.

Karena kedua penerapan memiliki label app: sa-frontend,permintaan dirutekan oleh layanan virtual sa-external-services untuk layanan sa-frontend, akan dialihkan ke semua instance-nya dan beban akan didistribusikan algoritma round-robin, yang akan mengarah pada situasi berikut:

Kembali ke layanan mikro dengan Istio. Bagian 2
File yang diminta tidak ditemukan

File-file ini tidak ditemukan karena namanya 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, yang meminta satu versi file statis, dapat dikirim oleh penyeimbang beban ke pod yang memiliki versi berbeda, yang karena alasan yang jelas, file tersebut tidak ada. Oleh karena itu, agar aplikasi dapat berfungsi, kita perlu menetapkan batasan: “versi aplikasi yang sama yang melayani index.html harus melayani permintaan berikutnya'.

Kami akan mencapainya dengan penyeimbangan beban berbasis hash yang konsisten (Penyeimbangan Beban Hash yang Konsisten). Dalam hal ini permintaan dari klien yang sama dikirim ke instance backend yang sama, yang menggunakan properti yang telah ditentukan sebelumnya - misalnya, header HTTP. Diimplementasikan menggunakan DestinationRules.

Aturan Tujuan

Setelah Layanan Virtual mengirim permintaan ke layanan yang diinginkan, dengan menggunakan DestinationRules kita dapat menentukan kebijakan yang akan diterapkan pada lalu lintas yang ditujukan untuk contoh layanan ini:

Kembali ke layanan mikro dengan Istio. Bagian 2
Manajemen lalu lintas dengan sumber daya Istio

Catatan: Dampak sumber daya Istio terhadap lalu lintas jaringan disajikan di sini dengan cara yang mudah dipahami. Tepatnya, keputusan ke instance mana permintaan akan dikirim dibuat oleh Envoy di Ingress Gateway yang dikonfigurasi di CRD.

Dengan Aturan Tujuan, kita dapat mengonfigurasi penyeimbangan beban untuk menggunakan hash yang konsisten dan memastikan bahwa instance layanan yang sama merespons pengguna yang sama. Konfigurasi berikut memungkinkan Anda mencapai hal ini (aturan tujuan-sa-frontend.yaml):

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 konten header HTTP version.

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 tepat saat Anda menentukan header version:

$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep main

Catatan: Untuk menambahkan nilai berbeda di header dan menguji hasilnya langsung di browser, Anda dapat menggunakan ekstensi ini ke Chrome (Atau dengan ini untuk Firefox - kira-kira. terjemahan.).

Secara umum, DestinationRules memiliki lebih banyak kemampuan di bidang penyeimbangan beban - lihat detailnya di dokumentasi resmi.

Sebelum mempelajari VirtualService lebih lanjut, mari kita hapus “versi hijau” aplikasi dan aturan arah lalu lintas yang sesuai 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

Pembayangan (“perisai”) atau Pencerminan (“pencerminan”) digunakan ketika kami ingin menguji perubahan dalam produksi tanpa memengaruhi pengguna akhir: untuk melakukan ini, kami menduplikasi permintaan (“mirror”) ke instance kedua di mana perubahan yang diinginkan telah dilakukan, dan melihat konsekuensinya. Sederhananya, ini adalah saat kolega Anda memilih masalah yang paling kritis dan membuat permintaan penarikan dalam bentuk segumpal besar kotoran sehingga tidak ada yang bisa memeriksanya.

Untuk menguji skenario ini dalam tindakan, mari 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 mari kita jalankan perintah untuk memastikan semua instance dengan app=sa-logic Mereka juga 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, jadi semua permintaan akan didistribusikan ke semua instance:

Kembali ke layanan mikro dengan Istio. Bagian 2

... tapi kami ingin permintaan dikirim ke instance v1 dan dicerminkan ke instance v2:

Kembali ke layanan mikro dengan Istio. Bagian 2

Kami akan mencapai hal ini melalui VirtualService yang dikombinasikan dengan DestinationRule, di mana aturan akan menentukan subset dan rute VirtualService ke subset tertentu.

Mendefinisikan Subset dalam Aturan Tujuan

Subset (subset) ditentukan oleh konfigurasi berikut (sa-logika-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 rumah (host) mendefinisikan bahwa aturan ini hanya berlaku ketika rute menuju layanan sa-logic;
  2. Judul (name) subset digunakan saat merutekan ke subset instance;
  3. Label (label) mendefinisikan pasangan nilai kunci yang harus dicocokkan oleh instance agar 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 subset telah ditentukan, kita dapat melanjutkan dan mengonfigurasi VirtualService untuk menerapkan aturan pada permintaan ke sa-logic sehingga:

  1. Dirutekan ke subset v1,
  2. Dicerminkan ke subset v2.

Manifesto berikut memungkinkan Anda mencapai rencana Anda (sa-logika-subset-bayangan-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 diperlukan penjelasan di sini, jadi mari kita lihat aksinya:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created

Mari tambahkan beban dengan memanggil perintah berikut:

$ 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 Anda dapat melihat versinya yang memiliki bug (buggy) mengakibatkan kegagalan pada ~60% permintaan, namun tidak satu pun dari kegagalan ini memengaruhi pengguna akhir karena mereka ditanggapi oleh layanan yang sedang berjalan.

Kembali ke layanan mikro dengan Istio. Bagian 2
Respons yang berhasil dari berbagai versi layanan sa-logic

Di sini kita pertama kali melihat bagaimana VirtualService diterapkan pada Utusan layanan kami: kapan sa-web-app membuat permintaan ke sa-logic, ia melewati sespan Envoy, yang - melalui VirtualService - dikonfigurasi untuk merutekan permintaan ke subset v1 dan mencerminkan permintaan ke subset layanan v2 sa-logic.

Saya tahu, Anda mungkin berpikir bahwa Layanan Virtual itu sederhana. Di bagian berikutnya, kami akan memperluasnya dengan mengatakan bahwa mereka juga sangat hebat.

Peluncuran Canary

Canary Deployment adalah proses meluncurkan versi baru aplikasi ke sejumlah kecil pengguna. Ini digunakan untuk memastikan bahwa tidak ada masalah dalam rilis dan hanya setelah itu, karena sudah yakin dengan kualitas (rilis), mendistribusikannya ke pengguna lain.оaudiens yang lebih besar.

Untuk mendemonstrasikan peluncuran canary, kami akan terus bekerja dengan subset buggy у sa-logic.

Jangan buang waktu untuk hal-hal sepele dan segera kirim 20% pengguna ke versi yang memiliki bug (ini akan mewakili peluncuran canary kami), dan 80% sisanya ke layanan normal. Untuk melakukan ini, gunakan VirtualService berikut (sa-logika-subset-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 berat (weight), yang menentukan persentase permintaan yang akan diarahkan ke penerima atau sebagian penerima.

Mari perbarui konfigurasi VirtualService sebelumnya untuk sa-logic dengan perintah berikut:

$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured

... dan kita akan segera melihat bahwa beberapa permintaan menyebabkan kegagalan:

$ 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 memungkinkan peluncuran canary: Dalam kasus ini, kami telah mempersempit potensi dampak masalah ini menjadi 20% dari basis pengguna. Luar biasa! Sekarang, jika kita tidak yakin dengan kode kita (dengan kata lain - selalu...), kita dapat menggunakan mirroring dan canary rollout.

Batas waktu dan percobaan ulang

Namun bug tidak selalu berakhir pada kode. Dalam daftar dari "8 Kesalahpahaman tentang Komputasi Terdistribusi“Yang pertama adalah keyakinan yang salah bahwa “jaringan tersebut dapat diandalkan.” Pada kenyataannya jaringan tidak dapat diandalkan, dan karena alasan ini kita memerlukan waktu tunggu (batas waktu) dan percobaan ulang (mencoba lagi).

Untuk demonstrasi kami akan terus menggunakan versi masalah yang sama sa-logic (buggy), dan kami akan mensimulasikan tidak dapat diandalkannya jaringan dengan kegagalan acak.

Biarkan layanan kami yang memiliki bug memiliki peluang 1/3 untuk merespons terlalu lama, peluang 1/3 untuk berakhir dengan Kesalahan Server Internal, dan peluang 1/3 untuk berhasil mengembalikan halaman.

Untuk mengurangi dampak masalah tersebut dan menjadikan kehidupan pengguna lebih baik, kami dapat:

  1. tambahkan batas waktu jika layanan membutuhkan waktu lebih dari 8 detik untuk merespons,
  2. coba lagi jika permintaan gagal.

Untuk implementasi, kami akan menggunakan definisi sumber daya berikut (sa-logika-percobaan ulang-waktu tunggu-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. Permintaan dicoba ulang sebanyak 3 kali;
  3. Dan setiap upaya dianggap gagal jika waktu respons melebihi 3 detik.

Ini merupakan pengoptimalan karena pengguna tidak perlu menunggu lebih dari 8 detik dan kami akan melakukan tiga upaya baru untuk mendapatkan respons jika terjadi kegagalan, sehingga 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 di grafik Grafana bahwa jumlah respons yang berhasil meningkat di atas:

Kembali ke layanan mikro dengan Istio. Bagian 2
Peningkatan statistik keberhasilan respons setelah menambahkan batas waktu dan percobaan ulang

Sebelum melanjutkan ke bagian berikutnya (atau lebih tepatnya, ke bagian artikel selanjutnya, karena dalam hal ini tidak akan ada lagi eksperimen praktis - kira-kira terjemahan), menghapus 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

Pola Pemutus Arus dan Sekat

Kita berbicara tentang dua pola penting dalam arsitektur layanan mikro yang memungkinkan Anda mencapai pemulihan mandiri (penyembuhan diri sendiri) jasa.

Circuit Breaker ("pemutus arus") digunakan untuk menghentikan permintaan yang datang ke layanan yang dianggap tidak sehat dan memulihkannya sementara permintaan klien dialihkan ke layanan yang sehat (yang meningkatkan persentase respons yang berhasil). (Catatan: Penjelasan pola yang lebih rinci dapat ditemukan, misalnya, di sini.)

Sekat ("partisi") mengisolasi kegagalan layanan agar tidak mempengaruhi keseluruhan sistem. Misalnya, Layanan B rusak dan layanan lain (klien Layanan B) membuat permintaan ke Layanan B, menyebabkan kumpulan threadnya habis dan tidak dapat melayani permintaan lain (meskipun permintaan tersebut bukan dari Layanan B). (Catatan: Penjelasan pola yang lebih rinci dapat ditemukan, misalnya, di sini.)

Saya akan menghilangkan detail penerapan pola-pola ini karena mudah ditemukan dokumentasi resmi, dan saya juga sangat ingin menunjukkan otentikasi dan otorisasi, yang akan dibahas di bagian artikel selanjutnya.

PS dari penerjemah

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komentar