HAProxy ile SMTP Load Balancing
Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYuIYmJG' (Errcode: 28 - No space left on device) in /usr/share/nginx/html/syslogs/wp-includes/class-wpdb.php on line 2349
Bildiğiniz gibi HAProxy isimli küçük ve kullanışlı bir load balancer uygulaması bulunuyor. Hemen her *nix sistemde çalışan bu balancer HTTP'nin yanı sıra TCP üzerinde çalışan diğer servisler için de kullanılabildiğinden ötürü sadece web servislerini değil tcp üzerinde çalışan hemen her türlü uygulama için yük dengelemesi yapabiliyorsunuz. |
Kolay kurulumu ve yapılandırılması, yüksek load değerlerinde stabil olarak çalışabilmesi, web tabanlı durum ve istatistik raporu sunması, Access Contol List ve Pattern extraction desteği sayesinde detaylı koşullar belirlemeye olanak sağlaması gibi güzel özellikleri bulunuyor. Üstelik Haproxy'nin, Fedora, Twitter, Reddit, GitHub gibi kullanıcıları da bulunuyor.
Ben Haproxy'yi, giden mailleri birden fazla smtp sunucuya eşit olarak dağıtmak, böylece outbound smtp trafiği için dağıtık bir yapı oluşturmak üzere kullanıyorum. Sizin de buna benzer bir ihtiyacınız yazının devamında HAProxy kurulumu ve 4 smtp sunucusu için round-robin load balance servisi verecek şekilde yapılandırılmasından bahsedeceğim. İşinize yarayabilir.
İçerik İndexi
Kurulum
HAProxy, bir çok sistemin kendi paket yöneticisinden kurulabiliyor. Ben FreeBSD kullanıyor olsam da kurulum işleminin CentOS sistemlerde de nasıl olduğundan bahsedeceğim. (Yapılandırma ise tüm sistemler için aynıdır.)
FreeBSD
FreeBSD sistemlerde, haproxy paketi port ağacında/usr/ports/net/haproxy dizininde bulunmaktadır. Dolayısı ile kurulum ports üzerinden aşağıdaki gibi kolayca yapılabilmektedir.
Not: Eğer port ağacınızı uzun zamandır güncellemediyseniz, kuruluma başlamadan önce portsnap ile güncellemenizi öneririm.
# cd /usr/ports/net/haproxy # make install clean
FreeBSD sistemlerde ana yapılandırma dosyasının haproxy.conf ismi ile /usr/local/etc/ dizini altında bulunması gerekiyor ancak öntanımlı olarak gelmediğinden dolayı (yazının yapılandırma bölümünde editlemek üzere) boş bir tane oluşturalım.
# touch /usr/local/etc/haproxy.conf
(Örnek bir yapılandırma dosyası /usr/local/share/examples/haproxy/ dizini altında haproxy.cfg ismi ile bulunuyor. İncelemek üzere göz atmak isteyebilirsiniz.)
Ayrıca haproxy için herhangi home dizini ya da login yetkisi olmayan bir kullanıcı oluşturuyoruz. (Bu kullanıcıyı yapılandırma dosyası içerisinde belirteceğiz ve servisin bu kullanıcı ile çalıştırılmasını söyleyeceğiz. Aksi taktirde haproxy root yetkileri ile çalışır.)
# pw useradd -n haproxy -d /nonexistent -s /usr/sbin/nologin
Son olarak da açılışlarda start edilmesi için rc.conf dosyasına haproxy_enable ibaresini ekliyoruz.
# echo 'haproxy_enable="YES"' >> /etc/rc.conf
FreeBSD sistemler için kurulum bu kadar. Bu aşamadan sonra bir sonrakı ana başlık olan “Yapılandırma” kısmına geçebilirsiniz.
RHEL/CentOS/Fedora
RHEL,CentOS ya da Fedora sistemler için haproxy paketi epel yum deposunda bulunuyor, ilgili depo'yu (32bit CentOS 5.6 bir sistem için) aşağıdaki şekilde sisteminize ekleyebilirsiniz.
# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
Bundan sonra haproxy paketini yum kullanarak aşağıdaki şekilde kurabilirsiniz:
# yum install haproxy
CentOS sistemlerde, haproxy ana yapılandırma dosyası /etc/haproxy/ dizini altında haproxy.cfg ismi ile oluşturulmaktadır. Yazının yapılandırma başlıklı bölümünde bu dosyayı editleyeceğiz.
Şimdi açılışlarda çalıştırılması için haproxy'yi startup'a ekleyelim:
# chkconfig haproxy on
RHEL tabanlı sistemler için kurulum bu kadar.
Yapılandırma
Bu bölümde anlatılacak işlemler tüm sistemler için aynıdır. Tek fark editlenecek yapılandırma dosyasının yerinin farklı olmasıdır. Kurulum bölümünde de bahsedildiği üzere yapılandırma dosyası FreeBSD sistemelerde /usr/local/etc/haproxt.cfg , RHEL tabanlı dağıtımlarda ise /etc/haproxy/haproxt.cfg ‘dir.
Örnek Senaryo
Yazının başında belirttiğim gibi yapılandırma işleminde, 4 adet smtp sunucu arasında roundrobin (sıralı) yük dengelemesinin nasıl yapılabileceğinden bahsedeceğim. Daha açıklayıcı olması için durumu senaryolaştırmak iyi olacak sanırım.
Elimizde 4 adet smtp sunucu olduğunu ve hostname/ip adreslerinin aşağıdaki gibi olduğunu düşünelim:
smtp-01 — 192.168.0.11
smtp-02 — 192.168.0.12
smtp-03 — 192.168.0.13
smtp-04 — 192.168.0.14
ve üzerine haproxy kurduğumuz sistemin 192.168.0.10 ip adresine sahip olduğunu varsayalım.
Örnek Yapılandırma Dosyası
Bu senaryoya göre, haproxy'nin 25. porta ulaşan tüm istekleri sırayla smtp-01, 02, 03 ve 04 isimli sunuculara yönlendirmesi için haproxy.cfg dosyasına aşağıdaki tanımlamalar girilmelidir:
global log 127.0.0.1 local0 notice maxconn 2048 user haproxy group haproxy daemon defaults log global mode tcp option dontlognull retries 3 option redispatch maxconn 2048 timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen stats :8080 mode http stats enable stats uri /stats stats auth admin:1234 listen smtp :25 mode tcp option tcplog balance roundrobin acl izinli src 192.168.0.0/24 tcp-request content accept if izinli tcp-request content reject server smtp-01 192.168.0.11:25 server smtp-02 192.168.0.12:25 server smtp-03 192.168.0.13:25 server smtp-04 192.168.0.14:25
Gördüğünüz gibi yapılandırma dosyasına girilen tanımlar bir kaç bölümden oluşmaktadır.
Sırası ile bu satırların anlamları şöyledir:
Tanımlamalar ve Açıklamalar
Yapılandırma dosyasına girilen tanımlamalar kendi içlerinde bölümlere ayrılmaktadır. Temel bölümler global ve defaults olmak üzere genel geçer kuralların düzenlendiği kısımlardır.
Global Bölümü
Global section'ı altında belirtilen herşey “process-wide” tanımlamaları içerir ve haproxy sürecinin hangi koşullarla çalışması gerektiğinin belirlenmesine yarar. Bizim örneğimizde global kısmına girilen değerler ve anlamları şu şekilde:
log 127.0.0.1 local0 notice:
Loglama'nın nasıl yapılacağı bildirir. Bu örnekte loglar, localhost üzerinde çalışan syslog'un local0 fasilitesine, notice seviyesinde gönderilmektedir.
Log parametresi maksimum iki kez girilebilir. Örneğin birinci satır ile localhost'taki syslog' üzerinden loglama yapılırken, ikinci bir satır ile aynı ya da daha spesifik kriterlere göre uzaktaki bir syslog sunucusuna log gönderebilirsiniz.
maxconn 2048:
Her bir süreç için eş zamanlı olarak kaç adet bağlantı açılabileceği maxconn paramtresi ile belirlenir. Örnekte bu değer 2048'dir. Bu değerin üzerine çıkılığı zaman proxy yeni bağlantı kabul etmez.
maxconn değerini kendi ihtiyaçlarınız doğrultusunda belirleyebilirsiniz. Ancak bu değerin sisteminizde tanımlı max file descriptor (fd) değerinden yüksek olmamasına dikkat ediniz (bkz: ulimit -n)
user haproxy:
Haproxy sürecinin hangi kullanıcının yetkileri ile çalıştırılacağını belirler. Bu bölümde herhangi bir değer girmezseniz, haproxy root yetkileri ile çalışır. linux sistemlerde haproxy kurulumu sırasında haproxy isimli user otomatik olarak oluşturulur. FreeBSD kullanıyorsanız, bu kullanıcıyı kurulum bölümünde yaptığımız gibi manuel oluşturmak gerekir.
group haproxy:
user parametresine benzer şekilde haproxy süreci için tanımlanan grubu belirtir.
daemon:
Sürecin arka planda (daemon mode'da) çalışması gerektiğini belirtir.
Global bölümü ile ilgili örnekte yer verdiğimiz tanımlamalar bu kadar. Ancak bu bölümde tanımlanabilecek daha bir çok parametre bulunuyor. Bunların neler olduğu ve açıklamaları için http://haproxy.1wt.eu/download/1.4/doc/configuration.txt adresindeki dökümanın “3. Global parameters” bölümüne bakabilirsiniz.
Defaults Bölümü
Bu section ise öntanımlı parametrelerin belirtildiği bölümdür. Burada girilen tüm bilgiler, load balance için tanımlanan bölümler için öntanımlı olarak devreye alınırlar. Örnekte tanımladığımız parametreler ve anlamları şu şekilde:
log global:
Log parametresi loglama işlemleri için tanımlamaları belirlemektedir. Örnekte lb işlemleri için loglamaların global bölümünde tanımlandığı şekilde yapılması için global ibaresini kullandık.
mode tcp
Mode bölümü, haproxy'nin handi modda çalışacağını belirlemektedir. Biz smtp (tcp 25) için load balance işlemi yapacağımız için haproxy'yi ön tanımlı olarak tcp modda çalıştırıyoruz. tcp'nin yanı dışında http mode'da da çalıştırmak mümkün.
option dontlognull
Bu parametre null connections olarak nitelendirilen ve üzerinden herhangi data transferi yapılmayan bağlantılar için loglama yapılmamasını söyler.
retries 3
Başarısız olan bağlantı istekleri için arka tarafa kaç kez daha bağlantı denemesinde bulunacağını belirler.
option redispatch
Başarısız bağlantı denemeleri için oturumun bir sonraki çalışan sunucuya yönlendirilmesini belirtir.
maxconn 2048
Maxconn değeri global section'da da tanımlandığı gibi kabul edilebilecek eş zamanlı bağlandı adedini tanımlar ve örnekte bu rakam 2048'dir.
timeout connect 5000ms
Arkadaki sunucuya bağlantı teşebbüsleri için milisaniye cinsinden timeout değerini belirler. Örneğe göre arkadaki sunucuya bağlantı için 5 saniye beklenecektir. 5 saniye içerisinde bağlantı kurulamazsa sunucuya erişilemediği varsayılacaktır.
timeout client 5000ms
İstemci tarafı için maximum inactivity time'ı belirler. Örnek olarak haproxy'ye bağlı bulunan istemci 5 saniye boyunce herhangi transferde bulunmazsa timeout'a düşecektir.
timeout server 5000ms
Bu parametre, bir önceki parametrenin sunucu tarafı için olan versiyonudur. Haproxy ile arka taraftaki sunucu arasındaki bağlantıda 5 sn boyunca herhangi inactivity durumu oluşursa bağlantı timeout olacaktır.
Listen Stats Bölümü
Bu bölümde web tabanlı istatistik ekranı için gerekli olan tanımlamalar yapılmaktadır.
listen stats :8080
stats web arayüzünün 8080. porttan yayınlanmasını söylüyoruz.
mode http
Bu listen bölümününi http modda çalışacağını belirtiyoruz.
stats enable
İstatistiklerin tutulması için stats özelliğinin devreye alınmasını söylüyoruz.
stats uri /stats
İstatistik web sayfasına erişmek için uri'nin ne olacağını belirliyoruz. Bu örneğe göre adres http://haproxy.ip.adresi:8080/haproxy?stats olacaktır.
stats auth admin:12345
İstatistik sayfasına giriş için bir kullanıcı adı ve şifre belirliyoruz.
Listen Smtp Bölümü
Bu bölüm smtp load balancing işlemlerinin nasıl olması gerektiğini belirleyen section'dır.
listen smtp :25
Bu kısımda, haproxy'ye 25. portu dinlemesini ve section'a smtp ismini vermesini söylüyoruz. Bu noktada hatırlatmak isterim ki sunucunuzda 25. portu dinleyen başka bir servis olmamalıdır. Aksi halde haproxy servisi başlatılamaz. Böyle bir durum söz konusu ise diğer servisi stop etmeniz ya da bu satırda port olarak kullanımda olmayan bir port belirtmeniz (örnek: 2525) gerekir. Ancak bu durumda da sitemciler haproxy'nin burada belirttiğiniz portuna erişmeleri gerekir ki bu yaklaşım duruma göre mantıklı bir kullanım şekli olmayabilir.
mode tcp
Bu section için mode'un tcp olacağını belirtiyoruz.
option tcplog
tcplog parametresi tcp bağlantıları için oturum durumu ve zamanlarla ilgili olarak gelişmiş loglamayı etkinleştirir.
balance roundrobin
Bu tanımlamada, yük dengeleme işleminin hangi algoritma ile yapılacağını belirler. Biz, istemcilerden gelen bağlantıların arkadaki sunuculara sırayla iletilmesini istediğimiz için balance algoritması olarak roundrobin kullanıyoruz.
acl izinli src 192.168.0.0/24
Haproxy'nin sadece 192.168.0.0/24 networkünden gelen isteklere cevap vermesi amacıyla “izinli” isiminde bir access control list oluşturup networkümüzü bu acl'e tanımlıyoruz.
tcp-request content accept if izinli
izinili ismindeki access list'te bulunan networkten gelen bağlantı isteklerine izin verilmesini söylüyoruz.
tcp-request content reject
Geri kalan tüm bağlantı isteklerinin geri çevrilmesini belirtiyoruz.
server smtp-01 192.168.0.11:25 check
server smtp-02 192.168.0.12:25 check
server smtp-03 192.168.0.13:25 check
server smtp-04 192.168.0.14:25 check
Son olarak bu bölümde de sırayla (backend) smtp sunucularımızı tanımlıyoruz. Satır sonlarında bulunan check ibaresi, smtp sunucularında periyodik olarak health check yapılmasını söylüyor. Eğer bu parametreyi vermezseniz arkadaki tüm sunucular öntanımlı olarak çalışıyor olarak varsayılırlar. Smtp sunucularınızla, haproxy aynı network üzerinde bulunuyorsa check işlemi yapmanıza çok da gerek olmayabilir.
Genel olarak yapılandırma işlemleri bu kadar. Ancak elbette Haproxy'nin bir çok başka özelliği ve parametresi bulunuyor. Bunları haproxy dökümanında bulabilirsiniz.
Servisin Başlatılması
Yapılandırma işlemlerinden sonra geriye Haproxy'nin start edilmesi kalıyor.
NOT: Yapılandırma dosyasında 25. portun dinlenmesini söylemiştik ancak haproxy'yi kurduğunuz sistemde halihazırda 25. portu dinlemekte olan herhangi bir servis (örnek sendmail) bulunuyorsa haproxy bu ayarlarla çalışamaz. Bu nedenle ilgili servisi durdurmanız gerekir. |
FreeBSD
FreeBSD sistemlerde rc scripti klasik olarak /usr/local/etc/rc.d/ dizininde duruyor. Servisi şu şekilde başlatabilirsiniz:
# /usr/local/etc/rc.d/haproxy start
RHEL/CentOS
linux sistemlerde ise init scripti /etc/init.d altında bulunmaktadır.
# /etc/init.d/haproxy start
Herşey yolunda gittiyse haproxy belirlenen koşulara göre load balance işlemini gerçekleştirmeye başlamış olmalıdır.
Test İşlemleri
HAProxy'nin sorunsuz çalıştığından emin olmak üzere öncelikle haproxy sürecinin düzgün çalışıp çalışmadığını kontrol edebilirsiniz.
# ps aux |grep haproxy
komutunun çıktısı aşağıdakine olacaktır:
haproxy 32650 0.0 0.3 2604 908 ? Ss Jun13 0:13 /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid
Ayrıca, netstat ile haproxy'nin dinlediği portları gözlemleyebilirsiniz.
# netstat -ant |grep LISTEN
komutunu verdiğinizde bizim örneğimize göre aşağa görüldüğü gibi 8080 (listen stats) ve 25 (listen smtp) portları dinlemede olacaklardır.
tcp4 0 0 *.25 *.* LISTEN tcp4 0 0 *.8080 *.* LISTEN
Ayrıca, test için haproxy'ye 25. porttan telnet ile bağlanmayı deneyebilirsiniz. Her bağlantınız arkadaki sunuculara sırası ile yönlendirileceklerdir.
Son olarak durum kontrolü için haproxy'nin web tabanlı stat arayüzüne de göz atabilirsiniz.
Stats Arayüzü
Yapılandırma sırasında, stats arayüzünün 8080. port üzerinde yayınlanması üzere tanımlamalar girdik. Bu durumda herhangi bir web browser üzerinden http://haproxy.ip.adresi:8080/stats adresini çağırabilir ve admin/12345 kullanıcı adı şifre bilgileri ile arayüze login olabilirsiniz.
Örnek bir sayfa aşağıdaki gibi olacaktır.
Resmin büyük halini görmek için tıklayınız.
Haproxy ile smtp load balancing yapmak için kurulum ve yapılandırma işlemleri bu kadardı.
Detaylı bilgi için haproxy dökümünana göz atmanızı öneririm.
Kaynaklar:
http://haproxy.1wt.eu/
http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
tcp-request content accept if izinli1
tcp-request content reject
Bu yazılar da ilginizi çekebilir:
- FreeBSD – Sendmail Smart Host Configuration
- qmail Smtproute Auth Patch
- Rblsmtpd – Custom Whitelist ve Blacklist Tanımlamaları
- FreeBSD üzerine Rsyslog Kurulumu ve Yapılandırması
- qmail Kurulum Scripti – FreeBSD 9.x
Yorumlar
Trackbacks
Yorumda bulunun.
Anlatım için teşekkürler, peki Çağrı bu sistem açık kaynak mı?
[Cevapla]
Evet, GPL v2.
[Cevapla]
Anladım, teşekkür ederim kolay gelsin.
[Cevapla]
Çağrı tekrar merhaba, bir şey daha sormak istiyorum. Böyle bana açık kaynaklı bir smtp gateway gerekli gelen mailleri hem dağıtacak hemde istediğimiz yerleri değiştirmemiz gerekiyor. Örnek from adresi ve headerler gibi. Bildiğin böyle alıp geliştirebileceğimiz açık kaynak centos üzerinde çalışabilecek bir program falan biliyor musun önereceğin, iyi çalışmalar.
[Cevapla]
anlatım için teşekkürler
haproxy + ngnix için yapılandırma ne gibi değişiklikler olucaktır. kısaca değinebilirmisiniz yada bunun için ayrı bir yazı yayınlarsanız sevinirim.
teşekkürler
[Cevapla]