<?xml version="1.0" encoding="UTF-8" ?><oembed><version>1.0</version><provider_name>Jui-Nan Lin&#039;s Blog</provider_name><provider_url>https://jnlin.org</provider_url><author_name>jnlin</author_name><author_url>https://jnlin.org/author/jnlin/</author_url><title>用 pf + relayd 架設 Layer 4 Switch (Server Load Balancer)</title><html>源於 OpenBSD，port 到 FreeBSD 的 &lt;a href=&quot;http://www.freebsd.org/cgi/man.cgi?query=pf&amp;apropos=0&amp;sektion=0&amp;manpath=FreeBSD+7.0-RELEASE&amp;format=html&quot;&gt;pf&lt;/a&gt; 本身就可以作 load balancer，但是不能作 healthy check。要作 healthy check 的話，必須加上 &lt;a href=&quot;http://www.freshports.org/net/relayd&quot;&gt;relayd&lt;/a&gt;。另外用 &lt;a href=&quot;http://www.freebsd.org/cgi/man.cgi?query=carp&amp;apropos=0&amp;sektion=0&amp;manpath=FreeBSD+7.0-RELEASE&amp;format=html&quot;&gt;CARP(4)&lt;/a&gt; 與 &lt;a href=&quot;http://www.freebsd.org/cgi/man.cgi?query=pfsync&amp;apropos=0&amp;sektion=0&amp;manpath=FreeBSD+7.0-RELEASE&amp;format=html&quot;&gt;PFSYNC(4)&lt;/a&gt; 可以做到 Active-Standby 的 Redundancy HA，也就是當一台 SLB (Server Load Balancer) 死掉的時候，另一台會自動起來提供服務。詳細的作法在參考資料有，因此這裡不贅述。基本的想法為：  &lt;ol&gt;   &lt;li&gt;用 pf 設定防火牆與 NAT，把 incoming port 80 的 destination 換成 server pool 內的任一台。&lt;/li&gt;    &lt;li&gt;用 carp 來保證 HA。&lt;/li&gt;    &lt;li&gt;用 pfsync 來 sync 兩台 SLB 之間的 pf firewall state。&lt;/li&gt;    &lt;li&gt;用 relayd 來檢查 server 的狀態，如果不能連線的時候，把 server 從 pool 內拿掉。&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;這樣就可以達到 Layer 4 Switch 的功能，在 relayd 裡面稱為 REDIRECT 模式，缺點是 pool 內所有的 server 都必須把 default gateway 設為 SLB。   &lt;br /&gt;另外 relayd 也可以採用類似 &lt;a href=&quot;http://www.freshports.org/net/haproxy&quot;&gt;haproxy&lt;/a&gt; 的方式，由 relayd 跟 client 與 server 各建立一個連線，作 Layer 7 的 forwarding。這在 relayd 裡面稱為 RELAY 模式。    &lt;br /&gt;設定 relay 模式的時候，可以對 HTTP Header 作修改，例如加上 X-Forwarded-For Header，或是根據 Host Header 或者 URI 來決定要分配到的 Pool。另外 healthy check 也可以由管理者自行撰寫 script，因此可以作比較複雜的檢查。設定方式可以參考 &lt;a href=&quot;http://www.openbsd.org/cgi-bin/man.cgi?query=relayd.conf&amp;apropos=0&amp;sektion=0&amp;manpath=OpenBSD+Current&amp;arch=i386&amp;format=html&quot;&gt;RELAYD.CONF(5)&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;比起 haproxy 來說，relayd 可以輕易的達到 Full Transparent Proxy （後端的 Server 看到的 source ip 是真正的 ip）的功能而不需要 patch kernel，而且也可以作 graceful restart（ haproxy 在 restart 的時候服務會中斷）；不過 haproxy 有許多的實例已經驗證過它的效能，可以吃滿 10Gbps 網路，但 relayd 在 RELAY 模式的 效能還是未知數。另外，由於 relayd 與 pf 綁的很緊，因此目前只有 OpenBSD 與 FreeBSD 版，不能在 Linux 上執行。&lt;/p&gt;  &lt;p&gt;參考資料：&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;     &lt;a href=&quot;http://blog.sysv.cn/?action=show&amp;id=14&quot;&gt;7.0下通过CARP+PF+relayd+PFSYNC实现健康检查等功能群集&lt;/a&gt;   &lt;/li&gt;    &lt;li&gt;     &lt;a href=&quot;http://www.openbsd.org/cgi-bin/man.cgi?query=relayctl&amp;sektion=8&amp;format=html&quot;&gt;RELAYCTL(8)&lt;/a&gt;   &lt;/li&gt; &lt;/ul&gt;</html><type>rich</type></oembed>