O requisito foi satisfeito da seguinte forma:
Instalei uma versão mais recente do ipvsadm (e seus módulos do kernel), a que suporta o --ops
flag (1.26). Como o keepalived não expõe esse sinalizador em seu arquivo de configuração, você deve aplicá-lo manualmente. Felizmente, você pode fazer isso depois que o "serviço virtual" for criado (em termos de ipvsadm simples, você pode primeiro ipvsam -A
um serviço virtual sem --ops
e ipvsadm -E
para adicionar um agendamento de pacotes).
Como o keepalived cria o serviço virtual para você, tudo o que você precisa fazer é editá-lo depois de criado, o que acontece quando o quorum é obtido para esse servidor virtual (basicamente, há um número suficiente de servidores reais em funcionamento). Veja como fica no arquivo keepalived.conf
:
virtual_server <VIP> <VPORT> {
lb_algo rr
lb_kind NAT
protocol UDP
...
# Enable one-packet scheduling when quorum is gained
quorum_up "ipvsadm -E -u <VIP>:<VPORT> --ops -s rr"
... realserver definitions, etc ...
}
Isso funciona, mas eu encontrei vários problemas (tipo de) com essa configuração:
- Há um pequeno intervalo de tempo (menos de um segundo, mais como 1/10), entre o quorum subindo e o script em
quorum_up
sendo executado. Quaisquer datagramas que consigam passar pelo diretor durante esse tempo criarão uma entrada de conexão no ipvsadm e os datagramas adicionais desse host / porta de origem ficarão presos no mesmo servidor real mesmo depois que o sinalizador--ops
for adicionado . Você pode minimizar a chance de isso acontecer, certificando-se de que o serviço virtual nunca seja excluído depois de criado. Você faz isso especificandoinhibit_on_failure
flag em suas definições de servidor real para que elas não sejam excluídas quando o servidor real correspondente estiver inativo (quando todos os servidores reais forem excluídos, o serviço virtual também será excluído), mas seu peso será definido como zero (eles parar de receber tráfego então). Como resultado, o único tempo que os datagramas podem passar é durante a inicialização do keepalive (supondo que você tenha pelo menos um servidor real ativo naquele momento para que o quorum seja obtido imediatamente). - Quando
--ops
está ativo, o diretor não reescreve o host / porta de origem dos datagramas, que os servidores reais enviam aos clientes para que o host / porta de origem sejam os do servidor real, que enviou esse datagrama específico. Isso pode ser um problema (era para os clientes meus ). Você pode alterar isso porSNAT
'desses datagramas com iptables. - Eu notei uma carga significativa na CPU do sistema quando o diretor está sob carga. Acontece que a CPU está sobrecarregada pelo ksoftirqd. Isso não acontece se você desativar
--ops
. Presumivelmente, o problema é que o algoritmo de despacho de pacotes é acionado em cada datagrama, em vez de apenas o primeiro datagrama na "conexão" (se isso se aplica ao UDP ...). Eu realmente não encontrei o caminho para "consertar" isso, mas talvez eu não tenha tentado o suficiente. O sistema tem alguns requisitos de carga específicos e, sob essa carga, o uso do processador não atinge o máximo, nem há datagramas perdidos, portanto, esse problema não é considerado um show-stopper. Ainda é bastante alarmante embora.
Resumo: a configuração definitivamente funciona (também sob carga), mas os aros que se tem que pular e os problemas que eu encontrei (especialmente №3 .. talvez alguém sabe a solução?) significa que, dado o tempo, Eu teria usado um programa de espaço do usuário (escrito em C, provavelmente) para escutar em um soquete UDP e distribuir os datagramas recebidos entre servidores reais em conjunto com algo, que verificaria a integridade dos servidores reais para mim, SNAT
in iptables para reescrever o host / porta de origem e keepalived no modo VRRP para HA.