Bekas, perkhidmatan mikro dan jaringan perkhidmatan

Di Internet sekumpulan Perkara ΠΎ jaringan perkhidmatan (jaringan perkhidmatan), dan ini satu lagi. Hooray! Tapi kenapa? Kemudian, saya ingin menyatakan pendapat saya bahawa adalah lebih baik jika jaringan perkhidmatan muncul 10 tahun yang lalu, sebelum kemunculan platform kontena seperti Docker dan Kubernetes. Saya tidak mengatakan bahawa pandangan saya lebih baik atau lebih teruk daripada yang lain, tetapi memandangkan jaringan perkhidmatan adalah haiwan yang agak kompleks, pelbagai sudut pandangan akan membantu untuk memahaminya dengan lebih baik.

Saya akan bercakap tentang platform dotCloud, yang dibina pada lebih seratus perkhidmatan mikro dan menyokong beribu-ribu aplikasi kontena. Saya akan menerangkan cabaran yang kami hadapi dalam membangunkan dan melancarkannya, dan cara jaringan perkhidmatan boleh (atau tidak dapat) membantu.

Sejarah dotCloud

Saya telah menulis tentang sejarah dotCloud dan pilihan seni bina untuk platform ini, tetapi saya tidak banyak bercakap tentang lapisan rangkaian. Jika anda tidak mahu menyelami membaca artikel terakhir mengenai dotCloud, berikut ialah intipati ringkasnya: ia ialah platform-sebagai-perkhidmatan PaaS yang membolehkan pelanggan menjalankan pelbagai aplikasi (Java, PHP, Python...), dengan sokongan untuk pelbagai data perkhidmatan (MongoDB, MySQL, Redis...) dan aliran kerja seperti Heroku: Anda memuat naik kod anda ke platform, ia membina imej kontena dan menggunakannya.

Saya akan memberitahu anda bagaimana trafik diarahkan ke platform dotCloud. Bukan kerana ia sangat keren (walaupun sistem berfungsi dengan baik pada zamannya!), tetapi terutamanya kerana dengan alatan moden reka bentuk sedemikian boleh dilaksanakan dengan mudah dalam masa yang singkat oleh pasukan sederhana jika mereka memerlukan cara untuk mengarahkan lalu lintas antara kumpulan perkhidmatan mikro atau sekumpulan aplikasi. Dengan cara ini, anda boleh membandingkan pilihan: apa yang berlaku jika anda membangunkan semuanya sendiri atau menggunakan jaringan perkhidmatan sedia ada. Pilihan standard adalah untuk membuatnya sendiri atau membelinya.

Penghalaan trafik untuk aplikasi yang dihoskan

Aplikasi pada dotCloud boleh mendedahkan titik akhir HTTP dan TCP.

Titik akhir HTTP ditambah secara dinamik pada konfigurasi kluster pengimbang beban Sakit kepala. Ini serupa dengan apa yang dilakukan oleh sumber hari ini Ingress dalam Kubernetes dan pengimbang beban seperti Traefik.

Pelanggan menyambung ke titik akhir HTTP melalui domain yang sesuai, dengan syarat nama domain itu menghala ke pengimbang beban dotCloud. Tiada apa yang istimewa.

Titik akhir TCP dikaitkan dengan nombor port, yang kemudiannya dihantar ke semua bekas dalam tindanan itu melalui pembolehubah persekitaran.

Pelanggan boleh menyambung ke titik akhir TCP menggunakan nama hos yang sesuai (sesuatu seperti gateway-X.dotcloud.com) dan nombor port.

Nama hos ini diselesaikan kepada kluster pelayan "nats" (tidak berkaitan dengan SIFAT), yang akan menghalakan sambungan TCP masuk ke bekas yang betul (atau, dalam kes perkhidmatan seimbang beban, ke bekas yang betul).

Jika anda biasa dengan Kubernetes, ini mungkin akan mengingatkan anda tentang Perkhidmatan NodePort.

Tiada perkhidmatan yang setara pada platform dotCloud KlusterIP: Untuk kesederhanaan, perkhidmatan telah diakses dengan cara yang sama dari dalam dan luar platform.

Segala-galanya disusun dengan agak ringkas: pelaksanaan awal rangkaian penghalaan HTTP dan TCP mungkin hanya beberapa ratus baris Python setiap satu. Algoritma mudah (saya katakan naif) yang telah diperhalusi apabila platform berkembang dan keperluan tambahan muncul.

Pemfaktoran semula yang meluas bagi kod sedia ada tidak diperlukan. khususnya, 12 aplikasi faktor boleh terus menggunakan alamat yang diperoleh melalui pembolehubah persekitaran.

Bagaimanakah ini berbeza daripada jaringan perkhidmatan moden?

Terhad penglihatan. Kami tidak mempunyai sebarang metrik untuk jaringan penghalaan TCP sama sekali. Apabila ia berkaitan dengan penghalaan HTTP, versi kemudiannya memperkenalkan metrik HTTP terperinci dengan kod ralat dan masa tindak balas, tetapi jaringan perkhidmatan moden pergi lebih jauh, menyediakan penyepaduan dengan sistem pengumpulan metrik seperti Prometheus, sebagai contoh.

Keterlihatan adalah penting bukan sahaja dari perspektif operasi (untuk membantu menyelesaikan masalah), tetapi juga apabila mengeluarkan ciri baharu. Ini tentang selamat penempatan biru-hijau ΠΈ penyebaran kenari.

Kecekapan penghalaan juga terhad. Dalam jaringan penghalaan dotCloud, semua trafik perlu melalui sekumpulan nod penghalaan khusus. Ini bermakna berpotensi melepasi beberapa sempadan AZ (Zon Ketersediaan) dan meningkatkan kependaman dengan ketara. Saya masih ingat kod penyelesaian masalah yang membuat lebih seratus pertanyaan SQL setiap halaman dan membuka sambungan baharu ke pelayan SQL untuk setiap pertanyaan. Apabila berjalan secara setempat, halaman dimuatkan serta-merta, tetapi dalam dotCloud ia mengambil masa beberapa saat untuk dimuatkan kerana setiap sambungan TCP (dan pertanyaan SQL seterusnya) mengambil masa berpuluh-puluh milisaat. Dalam kes khusus ini, sambungan berterusan menyelesaikan masalah.

Mesh perkhidmatan moden lebih baik dalam menangani masalah sedemikian. Pertama sekali, mereka menyemak bahawa sambungan dihalakan dalam sumber. Aliran logik adalah sama: ΠΊΠ»ΠΈΠ΅Π½Ρ‚ β†’ мСш β†’ сСрвис, tetapi kini mesh berfungsi secara tempatan dan bukan pada nod jauh, jadi sambungan ΠΊΠ»ΠΈΠ΅Π½Ρ‚ β†’ мСш adalah setempat dan sangat pantas (mikrosaat dan bukannya milisaat).

Jerat perkhidmatan moden juga melaksanakan algoritma pengimbangan beban yang lebih bijak. Dengan memantau kesihatan bahagian belakang, mereka boleh menghantar lebih banyak trafik ke bahagian belakang yang lebih pantas, menghasilkan prestasi keseluruhan yang lebih baik.

keselamatan lebih baik juga. Jaringan penghalaan dotCloud berjalan sepenuhnya pada EC2 Classic dan tidak menyulitkan trafik (berdasarkan andaian bahawa jika seseorang berjaya meletakkan penghidu pada trafik rangkaian EC2, anda sudah menghadapi masalah besar). Jaringan perkhidmatan moden secara telus melindungi semua trafik kami, contohnya, dengan pengesahan TLS bersama dan penyulitan seterusnya.

Menghalakan trafik untuk perkhidmatan platform

Okay, kami telah membincangkan trafik antara aplikasi, tetapi bagaimana pula dengan platform dotCloud itu sendiri?

Platform itu sendiri terdiri daripada kira-kira seratus perkhidmatan mikro yang bertanggungjawab untuk pelbagai fungsi. Ada yang menerima permintaan daripada orang lain, dan ada yang merupakan pekerja latar belakang yang menyambung kepada perkhidmatan lain tetapi tidak menerima sambungan itu sendiri. Walau apa pun, setiap perkhidmatan mesti mengetahui titik akhir alamat yang perlu disambungkan.

Banyak perkhidmatan peringkat tinggi boleh menggunakan jaringan penghalaan yang diterangkan di atas. Malah, banyak daripada lebih seratus perkhidmatan mikro dotCloud telah digunakan sebagai aplikasi biasa pada platform dotCloud itu sendiri. Tetapi sebilangan kecil perkhidmatan peringkat rendah (terutamanya yang melaksanakan rangkaian penghalaan ini) memerlukan sesuatu yang lebih mudah, dengan kebergantungan yang lebih sedikit (kerana mereka tidak boleh bergantung pada diri mereka sendiri untuk bekerja - masalah ayam dan telur tua yang baik).

Perkhidmatan peringkat rendah dan kritikal misi ini digunakan dengan menjalankan kontena secara langsung pada beberapa nod utama. Dalam kes ini, perkhidmatan platform standard tidak digunakan: penyambung, penjadual dan pelari. Jika anda ingin dibandingkan dengan platform kontena moden, ia seperti menjalankan pesawat kawalan dengan docker run terus pada nod, bukannya mewakilkan tugas kepada Kubernetes. Ia agak serupa dalam konsep modul statik (pod), yang digunakannya kubeadm atau bootkube apabila boot kelompok kendiri.

Perkhidmatan ini didedahkan dengan cara yang mudah dan kasar: fail YAML menyenaraikan nama dan alamat mereka; dan setiap pelanggan perlu mengambil salinan fail YAML ini untuk digunakan.

Di satu pihak, ia amat boleh dipercayai kerana ia tidak memerlukan sokongan stor kunci/nilai luaran seperti Zookeeper (ingat, etcd atau Konsul tidak wujud pada masa itu). Sebaliknya, ia menyukarkan pemindahan perkhidmatan. Setiap kali langkah dibuat, semua pelanggan akan menerima fail YAML yang dikemas kini (dan berkemungkinan but semula). Tak selesa sangat!

Selepas itu, kami mula melaksanakan skim baharu, di mana setiap pelanggan disambungkan ke pelayan proksi tempatan. Daripada alamat dan port, ia hanya perlu mengetahui nombor port perkhidmatan dan menyambung melalui localhost. Proksi tempatan mengendalikan sambungan ini dan memajukannya ke pelayan sebenar. Kini, apabila mengalihkan bahagian belakang ke mesin lain atau penskalaan, bukannya mengemas kini semua pelanggan, anda hanya perlu mengemas kini semua proksi setempat ini; dan but semula tidak lagi diperlukan.

(Ia juga dirancang untuk merangkum trafik dalam sambungan TLS dan meletakkan pelayan proksi lain pada bahagian penerima, serta mengesahkan sijil TLS tanpa penyertaan perkhidmatan penerima, yang dikonfigurasikan untuk menerima sambungan hanya pada localhost. Lebih lanjut mengenai ini kemudian).

Ini sangat serupa dengan SmartStack daripada Airbnb, tetapi perbezaan ketara ialah SmartStack dilaksanakan dan digunakan untuk pengeluaran, manakala sistem penghalaan dalaman dotCloud telah ditangguhkan apabila dotCloud menjadi Docker.

Saya secara peribadi menganggap SmartStack sebagai salah satu pendahulu kepada sistem seperti Istio, Linkerd dan Consul Connect kerana mereka semua mengikuti corak yang sama:

  • Jalankan proksi pada setiap nod.
  • Pelanggan menyambung kepada proksi.
  • Pesawat kawalan mengemas kini konfigurasi proksi apabila hujung belakang berubah.
  • ... Untung!

Pelaksanaan moden jaringan perkhidmatan

Jika kita perlu melaksanakan grid yang sama hari ini, kita boleh menggunakan prinsip yang sama. Sebagai contoh, konfigurasi zon DNS dalaman dengan memetakan nama perkhidmatan kepada alamat dalam ruang 127.0.0.0/8. Kemudian jalankan HAProxy pada setiap nod dalam kelompok, menerima sambungan pada setiap alamat perkhidmatan (dalam subnet 127.0.0.0/8) dan mengubah hala/mengimbangkan beban ke hujung belakang yang sesuai. Konfigurasi HAProxy boleh dikawal confd, membolehkan anda menyimpan maklumat bahagian belakang dalam etcd atau Consul dan secara automatik menolak konfigurasi yang dikemas kini ke HAProxy apabila diperlukan.

Beginilah cara Istio berfungsi! Tetapi dengan beberapa perbezaan:

  • Kegunaan Proksi Utusan bukannya HAProxy.
  • Menyimpan konfigurasi bahagian belakang melalui API Kubernetes dan bukannya etcd atau Consul.
  • Perkhidmatan adalah alamat yang diperuntukkan pada subnet dalaman (alamat Kubernetes ClusterIP) dan bukannya 127.0.0.0/8.
  • Mempunyai komponen tambahan (Citadel) untuk menambah pengesahan TLS bersama antara klien dan pelayan.
  • Menyokong ciri baharu seperti pemutus litar, pengesanan teragih, penggunaan kenari, dsb.

Mari kita lihat beberapa perbezaan.

Proksi Utusan

Proksi Utusan telah ditulis oleh Lyft [pesaing Uber dalam pasaran teksi - lebih kurang. lorong]. Ia serupa dalam banyak cara dengan proksi lain (cth. HAProxy, Nginx, Traefik...), tetapi Lyft menulis proksi mereka kerana mereka memerlukan ciri yang kekurangan proksi lain, dan nampaknya lebih bijak untuk membuat yang baharu daripada melanjutkan yang sedia ada.

Utusan boleh digunakan sendiri. Jika saya mempunyai perkhidmatan khusus yang perlu disambungkan kepada perkhidmatan lain, saya boleh mengkonfigurasinya untuk menyambung kepada Utusan, dan kemudian mengkonfigurasi dan mengkonfigurasi semula Utusan secara dinamik dengan lokasi perkhidmatan lain, sambil mendapat banyak fungsi tambahan yang hebat, seperti keterlihatan. Daripada pustaka pelanggan tersuai atau menyuntik jejak panggilan ke dalam kod, kami menghantar trafik kepada Utusan dan ia mengumpul metrik untuk kami.

Tetapi Utusan juga mampu bekerja sebagai satah data (satah data) untuk jaringan perkhidmatan. Ini bermakna bahawa Utusan kini dikonfigurasikan untuk mesh perkhidmatan ini pesawat kawalan (satah kawalan).

Pesawat kawalan

Untuk satah kawalan, Istio bergantung pada API Kubernetes. Ini tidak jauh berbeza dengan menggunakan confd, yang bergantung pada etcd atau Konsul untuk melihat set kunci dalam stor data. Istio menggunakan API Kubernetes untuk melihat set sumber Kubernetes.

Antara ini dan kemudian: Saya secara peribadi mendapati ini berguna Penerangan API Kubernetesyang berbunyi:

Pelayan API Kubernetes ialah "pelayan bodoh" yang menawarkan storan, versi, pengesahan, pengemaskinian dan semantik untuk sumber API.

Istio direka untuk bekerja dengan Kubernetes; dan jika anda ingin menggunakannya di luar Kubernetes, maka anda perlu menjalankan contoh pelayan API Kubernetes (dan perkhidmatan pembantu etcd).

Alamat perkhidmatan

Istio bergantung pada alamat ClusterIP yang Kubernetes peruntukkan, jadi perkhidmatan Istio menerima alamat dalaman (bukan dalam julat 127.0.0.0/8).

Trafik ke alamat ClusterIP untuk perkhidmatan tertentu dalam kelompok Kubernetes tanpa Istio dipintas oleh kube-proxy dan dihantar ke backend proksi tersebut. Jika anda berminat dengan butiran teknikal, kube-proxy menyediakan peraturan iptables (atau pengimbang beban IPVS, bergantung pada cara ia dikonfigurasikan) untuk menulis semula alamat IP destinasi sambungan yang pergi ke alamat ClusterIP.

Sebaik sahaja Istio dipasang pada gugusan Kubernetes, tiada apa-apa perubahan sehingga ia didayakan secara eksplisit untuk pengguna tertentu, malah seluruh ruang nama, dengan memperkenalkan bekas sidecar ke dalam pod tersuai. Bekas ini akan memutarkan contoh Envoy dan menyediakan satu set peraturan iptables untuk memintas trafik yang pergi ke perkhidmatan lain dan mengubah hala trafik tersebut kepada Utusan.

Apabila disepadukan dengan DNS Kubernetes, ini bermakna kod kami boleh disambungkan mengikut nama perkhidmatan dan semuanya "hanya berfungsi." Dalam erti kata lain, kod kami mengeluarkan pertanyaan seperti http://api/v1/users/4242kemudian api menyelesaikan permintaan untuk 10.97.105.48, peraturan iptables akan memintas sambungan dari 10.97.105.48 dan memajukannya kepada proksi Utusan tempatan dan proksi tempatan itu akan memajukan permintaan ke API bahagian belakang yang sebenar. Fuh!

Embel-embel tambahan

Istio juga menyediakan penyulitan dan pengesahan hujung ke hujung melalui mTLS (TLS bersama). Satu komponen dipanggil Citadel.

Terdapat juga komponen Mixer, yang Utusan boleh minta masing-masing meminta untuk membuat keputusan khas tentang permintaan itu bergantung pada pelbagai faktor seperti pengepala, beban hujung belakang, dll... (jangan risau: terdapat banyak cara untuk memastikan Mixer berjalan, dan walaupun ia ranap, Envoy akan terus berfungsi baik sebagai proksi).

Dan, sudah tentu, kami menyebut keterlihatan: Utusan mengumpul sejumlah besar metrik sambil menyediakan pengesanan teragih. Dalam seni bina perkhidmatan mikro, jika permintaan API tunggal mesti melalui perkhidmatan mikro A, B, C dan D, maka selepas log masuk, pengesanan teragih akan menambah pengecam unik pada permintaan dan menyimpan pengecam ini melalui subpermintaan kepada semua perkhidmatan mikro ini, membenarkan semua panggilan berkaitan untuk ditangkap. kelewatan, dsb.

Membangunkan atau membeli

Istio mempunyai reputasi sebagai kompleks. Sebaliknya, membina jaringan penghalaan yang saya terangkan pada permulaan siaran ini agak mudah menggunakan alat sedia ada. Jadi, adakah masuk akal untuk membuat jaringan perkhidmatan anda sendiri?

Jika kita mempunyai keperluan yang sederhana (kita tidak memerlukan keterlihatan, pemutus litar dan kehalusan lain), maka terfikir untuk membangunkan alat kita sendiri. Tetapi jika kita menggunakan Kubernetes, ia mungkin tidak diperlukan kerana Kubernetes sudah menyediakan alat asas untuk penemuan perkhidmatan dan pengimbangan beban.

Tetapi jika kami mempunyai keperluan lanjutan, maka "membeli" rangkaian perkhidmatan nampaknya merupakan pilihan yang lebih baik. (Ini bukan selalunya "beli" kerana Istio ialah sumber terbuka, tetapi kami masih perlu melaburkan masa kejuruteraan untuk memahami, menggunakan dan mengurusnya.)

Patutkah saya memilih Istio, Linkerd atau Consul Connect?

Setakat ini kita hanya bercakap tentang Istio, tetapi ini bukan satu-satunya jaringan perkhidmatan. Alternatif popular - Linkerd, dan ada lagi Consul Connect.

Apa yang perlu memilih?

Sejujurnya, saya tidak tahu. Pada masa ini saya tidak menganggap diri saya cukup cekap untuk menjawab soalan ini. Terdapat beberapa menarik Perkara dengan perbandingan alat ini dan juga tanda aras.

Satu pendekatan yang menjanjikan ialah menggunakan alat seperti SuperGloo. Ia melaksanakan lapisan abstraksi untuk memudahkan dan menyatukan API yang terdedah oleh jejaring perkhidmatan. Daripada mempelajari API khusus (dan, pada pendapat saya, agak kompleks) bagi jejaring perkhidmatan yang berbeza, kami boleh menggunakan binaan SuperGloo yang lebih mudah - dan dengan mudah bertukar dari satu kepada yang lain, seolah-olah kami mempunyai format konfigurasi perantaraan yang menerangkan antara muka HTTP dan hujung belakang yang mampu. menjana konfigurasi sebenar untuk Nginx, HAProxy, Traefik, Apache...

Saya telah mencuba sedikit dengan Istio dan SuperGloo, dan dalam artikel seterusnya saya ingin menunjukkan cara menambah Istio atau Linkerd pada kluster sedia ada menggunakan SuperGloo, dan cara yang terakhir menyelesaikan kerja, iaitu, membolehkan anda beralih daripada satu jaringan perkhidmatan kepada yang lain tanpa menulis ganti konfigurasi.

Sumber: www.habr.com

Tambah komen