Kunci untuk menskalakan lapisan penyeimbang beban HTTP adalah dengan menambahkan lapisan penyeimbangan beban level rendah (IP atau TCP) lainnya terlebih dahulu. Lapisan ini dapat dibangun sepenuhnya dengan perangkat lunak sumber terbuka, meskipun Anda akan mendapatkan hasil yang lebih baik jika Anda memiliki perute modern.
Aliran (sesi TCP) harus di hash menggunakan header seperti IP sumber / tujuan dan port TCP, untuk memutuskan frontend yang dituju. Anda juga membutuhkan mekanisme untuk memastikan bahwa ketika sebuah frontend mati, ia akan berhenti digunakan.
Ada berbagai strategi, saya akan menguraikan pasangan yang telah saya gunakan dalam produksi di situs yang melayani jutaan pengguna, sehingga Anda bisa mendapatkan idenya. Akan terlalu lama untuk menjelaskan semuanya secara terperinci tetapi saya harap jawaban ini akan memberi Anda cukup informasi / petunjuk untuk memulai. Untuk menerapkan solusi ini, Anda akan membutuhkan seseorang yang benar-benar berpengetahuan tentang jaringan.
Memang apa yang saya jelaskan di sini jauh lebih sulit diimplementasikan daripada apa yang dijelaskan dalam jawaban lain, tetapi ini benar-benar canggih jika Anda memiliki situs web yang diperdagangkan tinggi dengan masalah skalabilitas besar dan persyaratan ketersediaan lebih dari 99,9% . Asalkan Anda sudah memiliki insinyur jaringan yang lebih baik, ongkosnya lebih murah untuk pemasangan dan pengaturan (baik dalam capex dan opex) daripada peralatan penyeimbang beban, dan dapat ditingkatkan lebih lanjut dengan hampir tanpa biaya tambahan (vs. membeli yang baru, bahkan lebih alat mahal ketika Anda melebihi model Anda saat ini).
Strategi pertama: dengan firewall
Mungkin Anda memiliki beberapa router yang terhubung dengan ISP uplink Anda. ISP Anda menyediakan 2 tautan (aktif / pasif, menggunakan VRRP). Di router Anda, Anda juga menggunakan VRRP, dan Anda merutekan lalu lintas yang menuju jaringan publik Anda ke firewall. Firewall ( FW 1
dan di FW 2
bawah) juga aktif / pasif dan akan menyaring lalu lintas dan mengirim setiap aliran ke server frontend yang sehat (penyeimbang beban HTTP Anda, FE 1
dan di FE 2
bawah).
+ -------------- + + -------------- +
| Router ISP A | | Router ISP B |
+ -------------- + + -------------- +
| |
== # ====================== # == (jaringan publik)
| |
+ --------------- + + --------------- +
| Router Anda A | | Router Anda B |
+ --------------- + + --------------- +
| |
== # ===== # ========== # ===== # == (jaringan pribadi RFC 1918)
| | | |
+ ------ + + ------ + + ------ + + ------ +
| FW 1 | | FE 1 | | FE 2 | | FW 2 |
+ ------ + + ------ + + ------ + + ------ +
Tujuannya agar tampilan menjadi seperti ini:
- ISP merutekan lalu lintas ke IP Anda ke router aktif Anda.
- Router Anda merutekan traffic ke VIP yang menggunakan alamat RFC 1918 . VIP ini dimiliki oleh firewall aktif, mirip seperti VRRP. Jika Anda menggunakan OpenBSD untuk kebutuhan firewall Anda, maka Anda dapat menggunakan CARP , alternatif bebas paten untuk VRRP / HSRP.
- Firewall Anda menerapkan filter (misalnya "hanya izinkan 80 / tcp dan 443 / tcp pergi ke alamat IP khusus ini").
- Firewall Anda juga bertindak sebagai router dan meneruskan paket ke frontend yang sehat.
- Frontend Anda mengakhiri koneksi TCP.
Sekarang keajaiban terjadi di langkah 4 dan 5, jadi mari kita lihat lebih detail apa yang mereka lakukan.
Firewall Anda mengetahui daftar frontend ( FE 1
dan FE 2
), dan ia akan memilih salah satu dari mereka berdasarkan aspek aliran tertentu (misalnya dengan hashing IP sumber dan port, di antara header lainnya). Tetapi juga perlu memastikan bahwa itu meneruskan lalu lintas ke frontend yang sehat, jika tidak Anda akan blackhole lalu lintas. Jika Anda menggunakan OpenBSD, misalnya, Anda dapat menggunakan relayd
. Aparelayd
memang sederhana: memeriksa kesehatan semua frontend Anda (misalnya dengan mengirimkan mereka permintaan HTTP probe), dan setiap kali frontend sehat, ia menambahkannya ke tabel yang digunakan firewall untuk memilih paket paket berikutnya dari aliran yang diberikan . Jika frontend gagal pemeriksaan kesehatan, itu dihapus dari tabel dan tidak ada paket yang dikirim lagi. Saat meneruskan paket ke frontend, yang dilakukan firewall hanyalah menukar alamat tujuan MAC paket tersebut dengan yang ada di frontend yang dipilih.
Pada langkah 5, paket dari pengguna diterima oleh penyeimbang beban Anda (baik itu Varnish, nginx, atau apa pun). Pada titik ini, paket tersebut masih diperuntukkan bagi alamat IP publik Anda sehingga Anda perlu menambahkan VIP pada antarmuka loopback. Ini disebut DSR (Direct Server Return), karena frontend Anda mengakhiri koneksi TCP dan firewall di antara hanya melihat lalu lintas simpleks (hanya paket yang masuk). Router Anda akan merutekan paket keluar langsung kembali ke router ISP. Ini sangat baik untuk lalu lintas HTTP karena permintaan cenderung lebih kecil dari respons, kadang-kadang secara signifikan. Untuk lebih jelasnya: ini bukan hal khusus OpenBSD dan banyak digunakan di situs web yang diperdagangkan tinggi.
Gotchas:
- Pengguna akhir akan langsung terhubung ke server frontend Anda karena Anda menggunakan DSR. Mungkin memang sudah demikian, tetapi jika tidak, Anda harus memastikan semuanya sudah diamankan.
- Jika Anda menggunakan OpenBSD, berhati-hatilah karena kernel berulir tunggal sehingga kinerja inti CPU tunggal akan membatasi throughput firewall. Ini mungkin masalah tergantung pada jenis NIC Anda dan tingkat paket yang Anda lihat. Ada cara untuk mengatasi masalah ini (lebih lanjut tentang ini di bawah).
Strategi kedua: tanpa firewall
Strategi ini lebih efisien tetapi lebih sulit untuk diatur karena lebih tergantung pada spesifikasi router yang Anda miliki. Idenya adalah untuk mem-bypass firewall di atas dan membuat router melakukan semua pekerjaan yang dilakukan firewall.
Anda akan memerlukan router yang mendukung per-port L3 / L4 ACL, BGP dan ECMP , dan Policy Based Routing (PBR). Hanya router kelas atas yang mendukung fitur-fitur ini, dan mereka seringkali memiliki biaya lisensi tambahan untuk menggunakan BGP. Ini biasanya masih lebih murah daripada penyeimbang beban perangkat keras, dan juga jauh lebih mudah untuk diukur. Hal yang baik tentang router kelas atas ini adalah bahwa mereka cenderung menjadi line-rate (misalnya mereka selalu dapat memaksimalkan tautan, bahkan pada antarmuka 10GbE, karena semua keputusan yang mereka buat dilakukan dalam perangkat keras oleh ASIC).
Pada port yang memiliki ISP uplink Anda, terapkan ACL yang dulu ada di firewall (mis. "Hanya izinkan 80 / tcp dan 443 / tcp pergi ke alamat IP khusus ini"). Kemudian mintalah masing-masing frontend Anda mempertahankan sesi BGP dengan router Anda. Anda dapat menggunakan OpenBGPD yang sangat baik (jika frontend Anda menggunakan OpenBSD) atau Quagga . Router Anda akan ECMP lalu lintas ke frontend yang sehat (karena mereka mempertahankan sesi BGP mereka). Router juga akan merutekan traffic keluar dengan menggunakan PBR.
Perbaikan
- Dengan solusi pasangan firewall, alangkah baiknya jika Anda dapat menyinkronkan status TCP di seluruh firewall, sehingga ketika satu firewall gagal, semuanya gagal dengan lancar ke yang lainnya. Anda dapat mencapai ini dengan
pfsync
.
- Ingatlah bahwa
pfsync
biasanya akan menggandakan laju paket pada firewall Anda.
- HTTP adalah protokol tanpa kewarganegaraan, jadi ini bukan akhir dunia jika Anda mengatur ulang semua koneksi selama firewall gagal karena Anda tidak menggunakannya
pfsync
.
- Jika Anda melebihi firewall tunggal, Anda dapat menggunakan ECMP pada router Anda untuk merutekan lalu lintas ke lebih dari satu pasang firewall.
- Jika Anda menggunakan lebih dari satu pasang firewall, Anda mungkin membuatnya semuanya aktif / aktif. Anda dapat mencapai ini dengan meminta firewall mempertahankan sesi BGP dengan router, seperti halnya frontend perlu mempertahankannya dalam desain ke-2 tanpa firewall.
Contoh relayd
konfigurasi
Lihat juga HOWTO di https://calomel.org/relayd.html
vip = "1.2.3.4" # Alamat IP publik Anda
# (Anda dapat memiliki lebih dari satu, tetapi tidak perlu)
fe1 = "10.1.2.101"
fe2 = "10.1.2.102"
fe3 = "10.1.2.103"
fe4 = "10.1.2.104" # Anda dapat memiliki sejumlah frontend.
int_if = "em0"
tabel <fe> {$ fe1 coba lagi 2, $ fe2 coba lagi 2, $ fe3 coba lagi 2, $ fe4 coba lagi 2}
tabel <fallback> {127.0.0.1}
redirect webtraffic {
dengarkan pada $ vip port 80
batas waktu sesi 60
rute ke <fe> periksa http "/healthcheck.html" digest "(sha1sum of healthcheck.html)" interface $ int_if
}