Eu tenho um programa, que não pode ser usado no modo multiprocess \ multithread, então ele usa um núcleo de CPU, outros núcleos são gratuitos, mas RAM e uso de largura de banda de rede perto de 10% do max.
O servidor para a finalidade determinada tem 8 núcleos de CPU, 16GB de RAM, uma sub-rede / 20 para atender a pedidos de 4094 endereços IP externos.
A idéia principal era: basta executar 8 instâncias, cada uma com uma porta tcp separada, e criar uma regra de redirecionamento usando algum software de firewall.
No linux (ubuntu 14.04 LTS amd64) foi feito usando o iptables:
/etc/iptables/rules.v4
(apenas parte de redirecionamento)
-A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 8 --packet 0 -j DNAT --to-destination :4001 -A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 7 --packet 0 -j DNAT --to-destination :4002 -A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 6 --packet 0 -j DNAT --to-destination :4003 -A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 5 --packet 0 -j DNAT --to-destination :4004 -A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 4 --packet 0 -j DNAT --to-destination :4005 -A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination :4006 -A PREROUTING -p tcp -m tcp --dport 4000 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination :4007 -A PREROUTING -p tcp -m tcp --dport 4000 -j DNAT --to-destination :4008
Mas o programa se torna instável, e então eu tentei compilá-lo para o freebsd (releng 11 amd64), e use o pf para redirecionar a porta 4000:
/etc/pf.conf
table <mainips> { a.a.a.a/32 } ext_if="lagg0" set state-policy if-bound set optimization aggressive set skip on { lo0 } set limit states 150000 scrub in inet all fragment reassemble random-id scrub inet all reassemble tcp scrub in inet6 all rdr pass log on $ext_if inet proto tcp from any to x.x.240.0/20 port 4000 -> x.x.240.0/20 port 4001:4008 round-robin pass in on $ext_if inet proto tcp to x.x.240.0/20 port 4000 pass on $ext_if inet proto icmp pass on $ext_if inet6 proto icmp6 pass in on $ext_if inet proto tcp to <mainips> port { 22 } pass out on { $ext_if } inet proto tcp all flags S/SA modulate state pass out on { $ext_if } inet proto udp all #block all
Mas o ciclo de balanceamento de carga só pensava em endereços IP, não em portas, então tentei usar ipfilter \ ipnat:
/etc/ipf.rules:
pass in quick on lo0 all pass out quick on lo0 all pass out quick on lagg0 proto tcp from any to any port = 22 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4000 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4001 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4002 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4003 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4004 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4005 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4006 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4007 flags S keep state pass out quick on lagg0 proto tcp from any to any port = 4008 flags S keep state
/etc/ipnat.rules:
rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4001 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4002 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4003 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4004 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4005 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4006 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4007 tcp round-robin rdr lagg0 x.x.240.1/20 port 4000 -> x.x.240.1-x.x.255.254 port 4008 tcp round-robin
Esta configuração permite obter portas de destino de pensamento de ciclo, mas redireciona todas elas apenas para o endereço x.x.240.1.
A questão principal: como obter o comportamento de redirecionamento do FreeBSD da mesma maneira que no linux?
Tags iptables linux load-balancing freebsd pf