Mengapa dan bagaimana Dropbox bermigrasi dari Nginx ke Envoy
(dropbox.tech)<p>Artikel yang menjelaskan dengan baik keunggulan Envoy dibandingkan Nginx oleh Dropbox, yang menangani puluhan juta koneksi simultan, ratusan juta request per detik, dan bandwidth berskala terabyte<br />
<br />
Sebelumnya: nginx (versi open source) + python2 + Jinja2 + YAML <br />
→ bahkan jika hanya satu hal berubah, seluruh sistem harus di-deploy ulang<br />
→ bagian dinamis dikembangkan dengan Lua<br />
→ logika kompleks ditangani di Bandaid, proxy berbasis Go<br />
<br />
Selama hampir 10 tahun ini berjalan dengan baik, tetapi tidak lagi cocok dengan lingkungan saat ini<br />
→ API internal dan eksternal (privat) secara bertahap beralih dari REST ke gRPC, sehingga membutuhkan kemampuan transcoding di proxy<br />
→ Protocol Buffers menjadi standar definisi layanan internal <br />
→ semua perangkat lunak dibangun dan diuji dengan Bazel tanpa memandang bahasa<br />
→ karyawan cukup aktif berkontribusi ke komunitas open source untuk proyek-proyek infrastruktur utama<br />
<br />
Nginx juga mahal untuk dipertahankan dari sisi operasional<br />
→ logika pembuatan config terlalu fleksibel dan tersebar di YAML, Jinja2, dan Python<br />
→ monitoring merupakan campuran Lua / parsing log / monitoring berbasis sistem<br />
→ ketergantungan pada modul pihak ketiga makin tinggi, memengaruhi stabilitas/performa dan menimbulkan biaya karena upgrade yang sering <br />
→ deployment dan manajemen proses nginx sendiri sangat berbeda dari layanan lain. Sangat bergantung pada hal-hal yang berbeda dari sistem dasar seperti syslog, logrotate, dan lainnya<br />
<br />
Karena itu, untuk pertama kalinya dalam 10 tahun mereka memutuskan mencari pengganti Nginx<br />
<br />
* Mengapa tidak beralih ke Bandaid (proxy berbasis Go buatan Dropbox sendiri)? * <br />
→ Go memakai sumber daya lebih banyak daripada C/C++. <br />
→ stack TLS Go tidak mendukung FIPS (Federal Information Processing Standards AS)<br />
→ karena merupakan alat internal, tidak bisa mengandalkan dukungan dari komunitas eksternal <br />
<br />
Saat ini: beralih ke infrastruktur trafik berbasis Envoy <br />
<br />
----- Hal-hal yang membuat Envoy lebih baik daripada Nginx ------<br />
<br />
* Performa *<br />
<br />
Arsitektur Nginx bersifat event-driven / multi-process. Mendukung SO_REUSEPORT & EPOLLEXCLUSIVE<br />
Berbasis event loop, tetapi tidak sepenuhnya non-blocking. Saat membuka file atau logging, event loop bisa terhenti. (bahkan jika `aio`, `aio_write`, dan threadpool diaktifkan)<br />
Akibatnya muncul tail latency dan kadang delay hingga hitungan detik<br />
<br />
Envoy juga memiliki arsitektur event-driven yang mirip, tetapi berbasis thread, bukan process <br />
Mendukung SO_REUSEPORT (dengan dukungan filter BPF), serta event loop melalui libevent <br />
Tidak ada blocking I/O di event loop. Logging event juga diimplementasikan secara non-blocking.<br />
<br />
Secara teori, keduanya tampak akan menunjukkan karakteristik performa yang mirip, dan memang pada sebagian besar pengujian workload hasilnya serupa.<br />
Namun, Nginx memiliki latensi yang lebih besar di long tail. Penyebabnya adalah event loop terhenti ketika I/O tinggi.<br />
<br />
Tanpa pengumpulan statistik, Nginx menunjukkan performa yang mirip dengan Envoy, tetapi alat pengumpulan statistik Lua internal yang digunakan membuat Nginx 3 kali lebih lambat pada pengujian high-RPS. (ini karena `lua_shared_dict` yang disinkronkan dengan mutex). Memang ada masalah pada cara Dropbox mengumpulkan statistik, tetapi mereka menyerah untuk menulis ulang ini secara efisien. (karena mereka memperkirakan instrumentasi di dalam Nginx akan menyulitkan upgrade di masa depan)<br />
<br />
Bagaimanapun, karena masalah seperti ini tidak ada di Envoy, setelah migrasi mereka dapat melepas hingga 60% server yang sebelumnya digunakan Nginx.<br />
<br />
* Observability *<br />
<br />
Nginx versi gratis hanya menyediakan 7 statistik melalui modul stub status <br />
Itu jelas tidak cukup, jadi mereka memasang handler `log_by_lua` untuk menyediakan lebih banyak statistik.<br />
Selain itu, ada parser `error.log` untuk mengekspor informasi error, dan exporter terpisah untuk mengekspor nilai status internal nginx.<br />
<br />
Setup dasar Envoy menyediakan ribuan metrik berbeda dalam format Prometheus <br />
Mulai dari informasi trafik proxy hingga status internal server,<br />
statistik per cluster/per upstream/per virtual host, serta statistik downstream TCP/HTTP/TLS per listener, dan lain-lain<br />
<br />
Dengan beragam statistik ini, Envoy juga memungkinkan Tracing Provider dipasang sebagai plugin.<br />
Ini bermanfaat bukan hanya untuk tim trafik, tetapi juga untuk developer aplikasi.<br />
<br />
Terakhir, Envoy dapat melakukan streaming access log melalui gRPC.<br />
Ini mengurangi beban pemeliharaan bridge syslog-to-hive milik tim trafik.<br />
Menjalankan layanan gRPC umum jauh lebih mudah dan aman dibanding memasang listener TCP/UDP kustom.<br />
<br />
* Integration *<br />
<br />
Integrasi Nginx sangat bergaya Unix. Configuration-nya sangat statis.<br />
Bergantung pada file untuk config, sertifikat TLS, allowlist/blocklist, dan sebagainya.<br />
Karena sederhana dan kompatibel ke belakang, otomatisasi dengan beberapa shell script memang memungkinkan,<br />
tetapi seiring sistem membesar, kemampuan untuk diuji dan standardisasi menjadi makin penting.<br />
<br />
Envoy punya pendekatannya sendiri untuk integrasi semacam ini.<br />
Ia menyediakan API bernama xDS yang mendorong penggunaan protobuf dan gRPC.<br />
Envoy menemukan resource dinamis melalui query ke xDS ini.<br />
<br />
- xDS ini kini berkembang melampaui Envoy dengan nama Universal Data Plane API (UDPA), dan sedang berevolusi menjadi standar de facto untuk load balancer L4/L7. Berdasarkan pengalaman kami, ini berjalan dengan baik. Kami juga sedang mencoba memakai UDPA untuk load balancer L4 Katran eBPF/XDP, bukan hanya untuk Envoy.<br />
<br />
Karena Dropbox secara internal menghubungkan layanan melalui gRPC, ini jauh lebih cocok.<br />
<br />
* Configuration *<br />
<br />
Nginx punya keunggulan besar berupa file konfigurasi yang mudah dibaca manusia. <br />
Namun keunggulan ini makin hilang ketika konfigurasi menjadi makin kompleks dan dihasilkan secara otomatis.<br />
Di Dropbox, konfigurasi dihasilkan melalui Python2, Jinja2, YAML, dan lain-lain, sehingga model datanya juga menjadi kusut dan rumit.<br />
<br />
Envoy memiliki model data terpadu untuk konfigurasi. Semua nilai konfigurasi didefinisikan dalam Protocol Buffer. Ini menyelesaikan masalah pemodelan data dan menambahkan informasi tipe ke nilai konfigurasi.<br />
Karena protobuf banyak digunakan di internal Dropbox, integrasinya menjadi mudah <br />
<br />
* Extensibility * <br />
<br />
Untuk memperluas Nginx, perlu menulis modul C. Untuk menulis modul yang aman, dibutuhkan developer senior. Antarmuka Perl / JS juga disediakan untuk pengembangan modul yang lebih ringan, tetapi sangat terbatas. Karena itu, cara yang paling umum dipakai adalah melalui `lua-nginx-module`. <br />
<br />
Mekanisme ekstensi utama Envoy adalah melalui plugin C++, dan walaupun dokumentasinya tidak sebaik nginx, pendekatannya sangat sederhana. Ini berkat antarmuka yang bersih dan diberi komentar dengan baik, bahasa C++14, serta standard library <br />
<br />
Perbedaan besar Envoy dibanding web server lain adalah dukungannya terhadap WebAssembly (WASM).<br />
Ini memungkinkan pengembangan ekstensi melalui berbagai bahasa seperti Rust. <br />
Dropbox belum memakai WASM, tetapi jika suatu saat dukungan Go SDK untuk proxy-wasm tersedia, ini bisa berubah<br />
<br />
* Building and Testing *<br />
<br />
Nginx pada dasarnya menggunakan konfigurasi kustom berbasis shell dan build berbasis make. Ini sederhana dan bagus, tetapi butuh cukup banyak usaha untuk mengintegrasikannya ke monorepo yang dibangun dengan Bazel <br />
Nginx memiliki integration test berbasis Perl, tetapi tidak punya unit test.<br />
<br />
Envoy sudah menggunakan sistem build berbasis Bazel, dan dengan mudah diintegrasikan ke monorepo mereka.<br />
Mendukung unit test berbasis gtest/gmock serta integration test framework<br />
<br />
* Security *<br />
<br />
Kode Nginx sangat kecil dan dependensi eksternalnya juga sedikit, sehingga tidak banyak titik kerentanan dari sisi keamanan.<br />
<br />
Envoy memiliki codebase yang lebih besar, sehingga terlihat punya lebih banyak permukaan serangan. Untuk mengatasinya, Envoy sangat mengandalkan praktik keamanan modern seperti AddressSanitizer, ThreadSanitizer, dan MemorySanitizer. <br />
<br />
* Features * <br />
<br />
Bagian ini cukup subjektif, jadi anggap sebagai referensi<br />
<br />
Nginx awalnya dimulai sebagai web server untuk melayani file statis dengan sumber daya yang sangat kecil. <br />
Artinya, fungsi utamanya adalah static serving, caching, dan range caching<br />
Dari sudut pandang proxy, Nginx kekurangan banyak fitur yang dibutuhkan infrastruktur modern. <br />
Tidak bisa koneksi HTTP/2 ke backend, tidak bisa menjadi proxy gRPC multi-koneksi, dan juga tidak mendukung gRPC transcoding.<br />
Model lisensinya berbasis open core, sehingga beberapa fitur penting tidak tersedia di "versi komunitas"<br />
<br />
Envoy sejak awal dibuat sebagai ingress/egress proxy, dan banyak digunakan di lingkungan dengan beban gRPC tinggi.<br />
Fitur web server-nya masih sangat dasar. Tidak bisa file serving, caching masih dalam pengembangan, dan belum mendukung brotli, dll. <br />
Untuk lingkungan seperti ini, mereka juga menggunakan setup Nginx yang memakai Envoy sebagai upstream cluster <br />
Mereka memperkirakan jika Envoy sudah mendukung HTTP cache, lingkungan static serving semacam ini juga bisa dipindahkan <br />
<br />
Envoy mendukung banyak fitur terkait gRPC<br />
- gRPC proxying<br />
- HTTP/2 ke backend<br />
- bridge gRPC → HTTP (+ reverse.) <br />
- gRPC-WEB <br />
- gRPC JSON transcoder<br />
<br />
Selain itu, Envoy juga bisa digunakan sebagai outbound proxy <br />
- Egress Proxy<br />
- service discovery perangkat lunak pihak ketiga dengan library gRPC Courier <br />
<br />
* Community *<br />
<br />
Pengembangan Nginx bersifat terpusat dan sebagian besar tertutup. <br />
Pengembangan Envoy terbuka dan terdesentralisasi. Prosesnya berjalan melalui issue/PR GitHub dan juga sangat aktif melalui mailing list/Slack, dan lainnya </p><p>----- Status migrasi Dropbox saat ini -----<br />
<br />
Nginx dan Envoy sudah dijalankan bersama selama setengah tahun, sambil memindahkan trafik secara bertahap melalui DNS <br />
Migrasi ini tentu tidak berjalan tanpa masalah sama sekali; ada isu-isu kecil, tetapi tidak ada gangguan serius.<br />
Mereka juga merangkum solusi untuk masalah yang muncul karena perilaku yang "unusual" atau "non-RFC" (lihat isi artikel untuk detailnya)<br />
<br />
** Hal-hal yang akan dilakukan berikutnya **<br />
<br />
- HTTP/3: Envoy juga mulai mendukungnya secara eksperimental. Mereka berencana mengujinya setelah meng-upgrade kernel Linux untuk akselerasi UDP<br />
- load balancer internal berbasis xDS dan Outlier Detection<br />
- ekstensi Envoy berbasis WASM <br />
- mengganti Bandaid (proxy berbasis Go) dengan Envoy <br />
- menerapkan Envoy Mobile ke aplikasi mobile</p>
3 komentar