
Isstio service mesh
Kami di Yaitu telah menggunakan Istio selama setahun sekarang. Dia kemudian pergi begitu saja. Kami mengalami penurunan kinerja yang luar biasa di kluster Kubernetes, kami ingin distribusi tracing dan membawa Istio untuk menjalankan Jaeger dan mencari tahu. Service mesh sangat cocok dengan infrastruktur kami sehingga kami memutuskan untuk berinvestasi dalam alat ini.
Saya harus menderita, tetapi kami mempelajarinya jauh dan luas. Ini adalah posting pertama dalam seri di mana saya akan menjelaskan bagaimana Istio terintegrasi dengan Kubernetes dan apa yang kami pelajari tentang kerjanya. Kadang-kadang kita akan berkeliaran di belantara teknis, tetapi tidak terlalu jauh. Selanjutnya akan ada lebih banyak posting.
Apa itu Istio?
Istio adalah alat konfigurasi layanan mesh. Bunyinya status cluster Kubernetes dan upgrade ke proxy L7 (HTTP dan gRPC), yang diimplementasikan sebagai sespan di pod Kubernetes. Sespan ini adalah wadah Utusan yang membaca konfigurasi dari Istio Pilot API (dan layanan gRPC) dan rute lalu lintas melaluinya. Dengan proxy L7 yang kuat di bawah kap, kita bisa menggunakan metrik, jejak, coba lagi logika, pemutus sirkuit, penyeimbangan muatan, dan penyebaran kenari.
Mari kita mulai dari awal: Kubernetes
Di Kubernetes, kami membuat di bawah menggunakan penyebaran atau StatefulSet. Atau itu bisa saja "vanilla" di bawah tanpa pengontrol tingkat tinggi. Kemudian Kubernetes melakukan yang terbaik untuk mempertahankan status yang diinginkan - ia membuat pod di cluster pada node, memastikan bahwa mereka memulai dan memulai kembali. Ketika sebuah under dibuat, Kubernet melewati siklus hidup API, memastikan bahwa setiap langkah berhasil, dan baru kemudian akhirnya menciptakan under di cluster.
Tahapan Siklus Hidup API:

Terima kasih kepada Banzai Cloud untuk gambar kerennya.
Salah satu langkah adalah memodifikasi webhook masuk. Ini adalah bagian terpisah dari siklus hidup di Kubernetes, di mana sumber daya dikustomisasi sebelum melakukan ke repositori etcd, sumber kebenaran untuk konfigurasi Kubernetes. Dan di sini Istio melakukan sihirnya.
Memodifikasi webhook masuk
Ketika sub dibuat (melalui kubectl
atau Deployment
), ia melewati siklus hidup ini, dan akses memodifikasi webhook mengubahnya sebelum melepaskannya ke dunia besar.
Selama instalasi Istio, istio-sidecar-injector ditambahkan sebagai sumber konfigurasi untuk memodifikasi webhooks:
$ kubectl get mutatingwebhookconfiguration NAME AGE istio-sidecar-injector 87d
Dan konfigurasinya:
apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: labels: app: istio-sidecar-injector chart: sidecarInjectorWebhook-1.0.4 heritage: Tiller name: istio-sidecar-injector webhooks: - clientConfig: caBundle: redacted service: name: istio-sidecar-injector namespace: istio-system path: /inject failurePolicy: Fail name: sidecar-injector.istio.io namespaceSelector: matchLabels: istio-injection: enabled rules: - apiGroups: - "" apiVersions: - v1 operations: - CREATE resources: - pods
Dikatakan di sini bahwa Kubernetes harus mengirim semua acara pembuatan perapian ke layanan istio-sidecar-injector
di ruang istio-system
namespace istio-system
jika namespace memiliki istio-injection=enabled
. Injektor mencakup dua wadah lagi di PodSpec: satu sementara untuk menetapkan aturan proxy dan satu untuk proxy itu sendiri. Injector sespan memasukkan wadah ini sesuai dengan templat dari peta konfigurasi istio-sidecar-injector
. Proses ini juga disebut sidecaring.
Pod sespan
Sidecar adalah trik dari pesulap Istio kita. Istio menjejalkan semuanya dengan sangat cerdik sehingga dari luar itu hanya keajaiban, jika Anda tidak tahu detailnya. Dan itu berguna untuk mengetahuinya jika Anda tiba-tiba perlu men-debug permintaan jaringan.
Wadah init dan proxy
Kubernetes memiliki wadah init satu kali sementara yang dapat dijalankan sebelum yang utama. Mereka mengumpulkan sumber daya, memigrasi basis data, atau, seperti halnya dengan Istio, mengkonfigurasi aturan jaringan.
Istio menggunakan Utusan untuk mem-proxy semua permintaan untuk pengiriman di sepanjang rute yang diinginkan. Untuk melakukan ini, Istio membuat aturan iptables
, dan mereka mengirim lalu lintas masuk dan keluar langsung ke Utusan, dan itu dengan rapi proksi lalu lintas ke tujuannya. Lalu lintas membuat jalan memutar kecil, tetapi Anda telah mendistribusikan penelusuran, metrik kueri, dan penegakan kebijakan. Dalam file ini, dari repositori Istio Anda dapat melihat bagaimana Istio membuat aturan iptables.
@jimmysongio membuat diagram koneksi yang sangat baik antara aturan iptables dan proxy Utusan:

Utusan - Utusan Lalu Lintas
Utusan menerima semua lalu lintas masuk dan keluar, sehingga semua lalu lintas umumnya bergerak di dalam Utusan, seperti pada diagram. Proxy Istio adalah wadah lain yang ditambahkan ke semua pod yang dimodifikasi oleh injektor sespan Istio. Dalam wadah ini, proses Utusan dimulai, yang menerima semua lalu lintas dari perapian (dengan beberapa pengecualian, seperti lalu lintas dari kluster Kubernetes Anda).
Proses Utusan menemukan semua rute melalui API Utusan v2, yang mengimplementasikan Istio.
Utusan dan Pilot
Utusan itu sendiri tidak memiliki logika untuk mendeteksi pod dan layanan dalam sebuah cluster. Ini adalah bidang data dan membutuhkan bidang kontrol untuk memandu. Parameter konfigurasi Utusan meminta host atau port layanan untuk menerima konfigurasi ini melalui API gRPC. Istio, melalui layanan Pilot-nya, memenuhi persyaratan untuk API gRPC. Utusan terhubung ke API ini berdasarkan konfigurasi sespan diimplementasikan melalui webhook memodifikasi. API memiliki semua aturan lalu lintas yang perlu ditemukan Utusan dan rute untuk cluster. Ini adalah service mesh.

Pertukaran data "di bawah Pilot <->
Pilot terhubung ke kluster Kubernetes, membaca status kluster dan menunggu pembaruan. Ini memantau perapian, layanan, dan titik akhir di cluster Kubernetes, untuk kemudian memberikan konfigurasi yang tepat untuk semua sespan utusan yang terhubung ke Pilot. Ini adalah jembatan antara Kubernetes dan Utusan.

Dari Pilot ke Kubernetes
Ketika pod, layanan, atau titik akhir dibuat atau diperbarui di Kubernetes, Pilot mempelajarinya dan mengirimkan konfigurasi yang diperlukan untuk semua instance Utusan yang terhubung.
Konfigurasi apa yang sedang dikirim?
Konfigurasi apa yang didapatkan Utusan dari Istio Pilot?
Secara default, Kubernetes memecahkan masalah jaringan Anda dengan layanan (layanan) yang mengelola endpoint
. Daftar titik akhir dapat dibuka dengan perintah:
kubectl get endpoints
Ini adalah daftar semua IP dan porta di cluster dan alamatnya (biasanya ini adalah pod yang dibuat dari penyebaran). Istio penting untuk diketahui untuk mengkonfigurasi dan mengirim data rute ke Utusan.
Layanan, pendengar, dan rute
Saat Anda membuat layanan di kluster Kubernetes, Anda menyertakan pintasan yang dengannya semua pod yang sesuai akan dipilih. Saat Anda mengirim lalu lintas ke IP layanan, Kubernetes memilih lalu lintas untuk lalu lintas ini. Misalnya, perintahnya
curl my-service.default.svc.cluster.local:3000
Pertama, ia akan menemukan IP virtual yang ditetapkan untuk my-service
di namespace default
, dan IP ini akan meneruskan lalu lintas ke sub yang cocok dengan label layanan.
Istio dan Utusan sedikit mengubah logika ini. Istio mengkonfigurasi Utusan berdasarkan layanan dan titik akhir di kluster Kubernetes dan menggunakan fitur perutean cerdas dan penyeimbangan muatan Envoy untuk mem-bypass layanan Kubernetes. Alih-alih proksi lebih dari satu IP, Utusan terhubung langsung ke perapian IP. Untuk melakukan ini, Istio memetakan konfigurasi Kubernetes ke konfigurasi Utusan .
Istilah Kubernetes, Istio dan Utusan sedikit berbeda, dan tidak jelas apa yang mereka makan.
Layanan
Layanan di Kubernetes memetakan ke sebuah cluster di Utusan. Cluster Utusan berisi daftar titik akhir , yaitu IP (atau nama host) dari instance untuk memproses permintaan. Untuk melihat daftar cluster yang dikonfigurasi di Istio sidecar-pod, jalankan istioctl proxy-config cluster < >
. Perintah ini menunjukkan keadaan saat ini dalam hal perapian. Berikut adalah contoh dari salah satu lingkungan kami:
$ istioctl proxy-config cluster taxparams-6777cf899c-wwhr7 -n applications SERVICE FQDN PORT SUBSET DIRECTION TYPE BlackHoleCluster - - - STATIC accounts-grpc-gw.applications.svc.cluster.local 80 - outbound EDS accounts-grpc-public.applications.svc.cluster.local 50051 - outbound EDS addressvalidator.applications.svc.cluster.local 50051 - outbound EDS
Semua layanan yang sama berada di namespace ini:
$ kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) accounts-grpc-gw ClusterIP 10.3.0.91 <none> 80/TCP accounts-grpc-public ClusterIP 10.3.0.202 <none> 50051/TCP addressvalidator ClusterIP 10.3.0.56 <none> 50051/TCP
Bagaimana Istio tahu protokol mana yang menggunakan layanan ini? Mengkonfigurasi protokol untuk manifes layanan oleh bidang name
di entri port.
$ kubectl get service accounts-grpc-public -o yaml apiVersion: v1 kind: Service metadata: name: accounts-grpc-public spec: ports: - name: grpc port: 50051 protocol: TCP targetPort: 50051
Jika ada grpc
atau awalan grpc-, Istio akan mengkonfigurasi protokol HTTP2 untuk layanan ini. Kami belajar melalui pengalaman pahit bagaimana Istio menggunakan nama port ketika konfigurasi proxy rusak karena mereka tidak menentukan awalan http atau grpc ...
Jika Anda menggunakan kubectl dan halaman penerusan port admin di Utusan, Anda dapat melihat bahwa titik akhir akun-grpc-publik diimplementasikan oleh Pilot sebagai cluster di Utusan dengan protokol HTTP2. Ini menegaskan asumsi kami:
$ kubectl -n applications port-forward otherpod-dc56885ff-dqc6t 15000:15000 & $ curl http://localhost:15000/config_dump | yq r - ... - cluster: circuit_breakers: thresholds: - {} connect_timeout: 1s eds_cluster_config: eds_config: ads: {} service_name: outbound|50051||accounts-grpc-public.applications.svc.cluster.local http2_protocol_options: max_concurrent_streams: 1073741824 name: outbound|50051||accounts-grpc-public.applications.svc.cluster.local type: EDS ...
Port 15000 adalah halaman admin Utusan , tersedia di setiap sespan.
Pendengar
Pendengar mengenali titik akhir Kubernetes untuk meneruskan lalu lintas ke perapian. Layanan verifikasi alamat memiliki satu titik akhir di sini:
$ kubectl get ep addressvalidator -o yaml apiVersion: v1 kind: Endpoints metadata: name: addressvalidator subsets: - addresses: - ip: 10.2.26.243 nodeName: ip-10-205-35-230.ec2.internal targetRef: kind: Pod name: addressvalidator-64885ccb76-87l4d namespace: applications ports: - name: grpc port: 50051 protocol: TCP
Oleh karena itu, perapian verifikasi alamat memiliki satu pendengar di port 50051:
$ kubectl -n applications port-forward addressvalidator-64885ccb76-87l4d 15000:15000 & $ curl http://localhost:15000/config_dump | yq r - ... dynamic_active_listeners: - version_info: 2019-01-13T18:39:43Z/651 listener: name: 10.2.26.243_50051 address: socket_address: address: 10.2.26.243 port_value: 50051 filter_chains: - filter_chain_match: transport_protocol: raw_buffer ...
Rute
Di Istio, alih-alih objek Kubernetes Ingress standar, sumber daya kustom lebih abstrak dan efisien VirtualService
- VirtualService
. VirtualService memetakan rute ke cluster hulu dengan mengikatnya ke gateway. Ini adalah cara menggunakan Kubernetes Ingress dengan pengontrol Ingress.
Di Yaitu, kami menggunakan Istio Ingress-Gateway untuk semua lalu lintas GRPC internal:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: grpc-gateway spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: http2 number: 80 protocol: HTTP2 --- apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: grpc-gateway spec: gateways: - grpc-gateway hosts: - '*' http: - match: - uri: prefix: /namely.address_validator.AddressValidator retries: attempts: 3 perTryTimeout: 2s route: - destination: host: addressvalidator port: number: 50051
Sekilas, Anda tidak akan mengerti apa pun dalam contoh ini. Tidak terlihat di sini, tetapi penyebaran Istio-IngressGateway mencatat titik akhir yang diperlukan berdasarkan pada istio: ingressgateway
. Dalam contoh ini, IngressGateway merutekan lalu lintas untuk semua domain melalui port 80 melalui HTTP2. VirtualService mengimplementasikan rute untuk gateway ini, cocok dengan awalan /namely.address_validator.AddressValidator
dan meneruskan addressvalidator
melalui port 50051 ke layanan upstream addressvalidator
aturan coba lagi dalam dua detik.
Jika kita mengarahkan ulang port pod dari Istio-IngressGateway dan melihat konfigurasi Utusan, kita akan melihat apa yang VirtualService lakukan:
$ kubectl -n istio-system port-forward istio-ingressgateway-7477597868-rldb5 15000 ... - match: prefix: /namely.address_validator.AddressValidator route: cluster: outbound|50051||addressvalidator.applications.svc.cluster.local timeout: 0s retry_policy: retry_on: 5xx,connect-failure,refused-stream num_retries: 3 per_try_timeout: 2s max_grpc_timeout: 0s decorator: operation: addressvalidator.applications.svc.cluster.local:50051/namely.address_validator.AddressValidator* ...
Apa yang kami googled saat menggali di Istio
Kesalahan 503 atau 404 terjadi
Alasannya berbeda, tetapi biasanya ini adalah:
- Aplikasi sespan tidak dapat menghubungi Pilot (periksa apakah Pilot sedang berjalan).
- Manifes layanan Kubernetes memiliki protokol yang tidak valid.
- Konfigurasi VirtualService / Utusan menulis rute ke cluster hulu yang salah. Mulai dengan layanan tepi, tempat Anda mengharapkan lalu lintas masuk, dan periksa log Utusan. Atau gunakan sesuatu seperti Jaeger untuk menemukan kesalahan.
Apa arti NR / UH / UF dalam log proxy Istio?
- NR - Tanpa Rute.
- UH - Hulu Tidak Sehat (hulu yang tidak bisa dioperasi).
- UF - Kegagalan Hulu (kegagalan hulu).
Baca lebih lanjut di situs web Utusan .
Mengenai Ketersediaan Tinggi dengan Istio
- Tambahkan NodeAffinity ke komponen Istio untuk mendistribusikan perapian secara merata di berbagai zona ketersediaan dan meningkatkan jumlah replika minimum.
- Luncurkan versi baru Kubernetes dengan fitur Horizontal Pod Autoscaling. Tungku perapian yang paling penting akan diukur berdasarkan bebannya.
Mengapa cronjob tidak berakhir?
Ketika beban kerja utama selesai, wadah sespan terus bekerja. Untuk mengatasi masalah ini, nonaktifkan sidecar di cronjobs dengan menambahkan sidecar.istio.io/inject: “false”
annotation.istio.io/inject sidecar.istio.io/inject: “false”
ke PodSpec.
Bagaimana cara menginstal Istio?
Kami menggunakan Spinnaker untuk penerapan, tetapi kami biasanya mengambil grafik Helm terbaru, menyulapnya, menggunakan helm template -f values.yml
dan mengkomit file pada Github untuk melihat perubahan sebelum menerapkannya melalui kubectl apply -f -
. Ini agar tidak secara tidak sengaja mengubah CRD atau API di versi yang berbeda.
Terima kasih kepada Bobby Tables dan Michael Hamrah karena telah membantu menulis posting ini.