Maximizando o Desempenho do Ansible com ControlPersist e Pipelining
Ansible é uma ferramenta poderosa para automatizar a infraestrutura de TI, permitindo o gerenciamento de configurações e a implantação de aplicações em escala. No entanto, em ambientes de alto volume ou ao gerenciar um grande número de nós, a sobrecarga inerente ao estabelecimento de conexões SSH para cada tarefa pode se tornar um gargalo significativo. Isso pode levar a tempos de execução de playbooks dolorosamente lentos. Felizmente, o Ansible oferece duas funcionalidades poderosas, ControlPersist e Pipelining, que podem melhorar drasticamente o desempenho otimizando a forma como o Ansible se comunica com os nós gerenciados.
Este guia o conduzirá pelo entendimento e implementação de ControlPersist e Pipelining. Ao aproveitar essas técnicas, você pode reduzir significativamente os tempos de execução, tornando sua automação Ansible mais eficiente e responsiva, especialmente em ambientes com centenas ou milhares de hosts. Dominar essas otimizações é crucial para qualquer pessoa que busca escalar suas implantações de Ansible de forma eficaz.
Entendendo o Comportamento de Conexão Padrão do Ansible
Por padrão, o Ansible estabelece uma nova conexão SSH para cada host gerenciado a cada tarefa executada dentro de um playbook. Para cada conexão, ele executa várias etapas:
- Iniciar conexão SSH: Uma nova conexão SSH é estabelecida.
- Transferir módulos: O Ansible transfere os módulos Python necessários (ou outros arquivos relevantes) para o host remoto.
- Executar módulo: O módulo é executado no host remoto.
- Receber saída: O Ansible recupera os resultados da execução.
- Fechar conexão: A conexão SSH é encerrada.
Embora essa abordagem seja robusta e garanta um estado limpo para cada tarefa, o processo repetido de conexão e transferência de módulos consome um tempo considerável, especialmente ao lidar com inúmeras tarefas ou um grande inventário.
Otimizando Conexões com ControlPersist
ControlPersist é um recurso SSH que permite manter as conexões SSH abertas por um período especificado, mesmo após o comando inicial ter terminado. Isso significa que tarefas Ansible subsequentes que visam o mesmo host podem reutilizar a conexão existente e aberta em vez de estabelecer uma nova. Isso reduz significativamente a latência associada à configuração de sessões SSH.
Como o ControlPersist Funciona
Quando ativado, ControlPersist instrui o cliente SSH a manter uma conexão mestre de controle. Conexões SSH subsequentes para o mesmo host usando as mesmas credenciais e opções podem então ser multiplexadas sobre esta conexão mestre. O Ansible aproveita isso definindo as opções ControlPath e ControlPersist em sua configuração SSH.
Habilitando o ControlPersist no Ansible
Você pode habilitar o ControlPersist de várias maneiras:
-
Via
ansible.cfg(Recomendado para configurações globais ou específicas do projeto):
Edite ou crie seu arquivoansible.cfg(localizado no diretório do seu projeto Ansible,~/.ansible.cfg, ou/etc/ansible/ansible.cfg). Adicione a seguinte configuração à seção[ssh_connection]:ini [ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p-o ControlMaster=auto: Habilita o compartilhamento de conexão. Se uma conexão mestre existir, use-a; caso contrário, crie uma.-o ControlPersist=600: Mantém a conexão de controle aberta por 600 segundos (10 minutos). Ajuste este valor com base no seu fluxo de trabalho e políticas de segurança. Uma duração maior significa mais potencial de reutilização, mas também mais recursos mantidos abertos.-o ControlPath=~/.ssh/ansible_control_%r@%h:%p: Define o caminho para o socket de controle.%ré o nome de usuário remoto,%hé o nome do host e%pé a porta. Isso garante sockets únicos para diferentes conexões.
-
Via Variável de Ambiente:
Você pode definir os argumentos SSH diretamente usando uma variável de ambiente:bash export ANSIBLE_SSH_ARGS='-o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p' ansible-playbook your_playbook.yml -
Via Playbook (menos comum para esta configuração):
Embora seja possível, geralmente não é recomendado definir opções SSH persistentes dentro de um playbook em si, pois é uma configuração de nível de conexão. No entanto, para fins de completude, você poderia usaransible.builtin.set_factou similar para influenciá-lo, masansible.cfgé preferido.
Considerações para ControlPersist
- Segurança: Garanta que o
ControlPathesteja seguro para que apenas usuários autorizados possam acessar os sockets de controle. O caminho padrão no exemplo é geralmente seguro para configurações de nível de usuário. - Uso de Recursos: Manter as conexões abertas consome recursos tanto no nó de controle quanto nos nós gerenciados. Monitore o uso de recursos se você tiver um grande número de conexões persistentes.
- Redefinição de Conexão: Se um dispositivo de rede intermediário ou o servidor SSH remoto impuser tempos limite de conexão menores que
ControlPersist, a conexão ainda poderá cair. OControlPersistfunciona melhor em ambientes de rede estáveis.
Otimizando a Execução de Módulos com Pipelining
Pipelining é outra poderosa otimização do Ansible que reduz ainda mais a sobrecarga da execução de tarefas. Em vez de transferir módulos para o host remoto, executá-los e, em seguida, recuperar a saída, o pipelining transmite comandos diretamente pela conexão SSH. Isso significa que o Ansible não precisa colocar módulos no sistema de arquivos remoto ou criar arquivos temporários para a saída.
Como o Pipelining Funciona
Quando o pipelining está ativado, o Ansible executa módulos diretamente via ssh no host remoto. A saída padrão e o erro padrão do módulo são transmitidos de volta ao Ansible pela mesma conexão SSH. Isso elimina a necessidade de o Ansible gravar arquivos no sistema de arquivos remoto (como /usr/bin/ansible_module_name ou arquivos temporários) e depois executá-los. Isso é particularmente eficaz para módulos que não exigem escalonamento de privilégios ou interação significativa com o sistema de arquivos remoto.
Habilitando o Pipelining no Ansible
O pipelining é habilitado via arquivo ansible.cfg ou variáveis de ambiente.
-
Via
ansible.cfg:
Adicione ou modifique a seção[ssh_connection]:ini [ssh_connection] pipelining = True -
Via Variável de Ambiente:
bash export ANSIBLE_PIPELINING=True ansible-playbook your_playbook.yml
Considerações para Pipelining
- Escalonamento de Privilégios: O pipelining funciona melhor com módulos que não exigem escalonamento de privilégios (por exemplo, usando
become: yesousudo). Quandobecomeé usado, o Ansible geralmente precisa copiar arquivos para o sistema remoto. Se você usabecomecom frequência, o pipelining pode não oferecer tantos benefícios ou pode até causar problemas com certos tipos de módulos. - Compatibilidade de Módulos: A maioria dos módulos Ansible incorporados funciona bem com pipelining. No entanto, módulos personalizados ou aqueles que dependem fortemente de operações no sistema de arquivos remoto podem se comportar de forma diferente. Teste exaustivamente.
- Estabilidade da Conexão: Uma conexão SSH estável é crucial para que o pipelining funcione corretamente.
- Configuração SSH
requiretty: O pipelining é incompatível com a opção SSHrequirettyno servidor remoto. Se o seu servidor SSH tiverDefaults requirettyem/etc/sudoers, pode ser necessário desativá-lo ou usar!requirettypara o usuário específico com o qual o Ansible se conecta.
Combinando ControlPersist e Pipelining para Máximo Desempenho
Para os ganhos de desempenho mais significativos, é altamente recomendável habilitar tanto o ControlPersist quanto o Pipelining. Essa combinação aborda as duas principais sobrecargas: estabelecimento de conexão e execução de módulos.
Veja como seu ansible.cfg pode parecer com ambos habilitados:
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p
pipelining = True
Quando ambos estão ativos:
- O Ansible inicia uma conexão SSH e estabelece um ControlMaster se um não existir (ControlPersist).
- Para tarefas subsequentes, a conexão existente e aberta é reutilizada.
- Os módulos são executados diretamente sobre o fluxo sem serem copiados para o sistema de arquivos (Pipelining).
Essa sinergia reduz drasticamente o tempo que o Ansible gasta se comunicando com cada nó gerenciado, resultando em execuções de playbooks muito mais rápidas.
Cenário de Exemplo Prático
Vamos imaginar um playbook que precisa executar 10 tarefas simples em 100 hosts.
Sem otimizações:
Cada tarefa requer uma nova conexão SSH, transferência de módulo, execução e fechamento da conexão. Isso totaliza 100 hosts * 10 tarefas * (tempo_de_conexão + tempo_de_transferência_de_módulo). Se o tempo_de_conexão for 0,5 segundos e o tempo_de_transferência_de_módulo for 0,2 segundos, isso significa 100 * 10 * 0,7 = 700 segundos de sobrecarga apenas para comunicação e transferências, sem incluir a execução real do módulo.
Com ControlPersist e Pipelining habilitados:
- A primeira tarefa em cada host estabelece a conexão inicial e configura o ControlMaster.
- Todas as 9 tarefas subsequentes nesse host reutilizam a conexão aberta e transmitem a execução do módulo.
A sobrecarga por host se aproxima de tempo_de_conexão + (9 * sobrecarga_mínima_de_streaming). O tempo total é significativamente reduzido, com a maior parte do tempo de execução do playbook dedicada ao trabalho real que os módulos realizam, em vez da mecânica de comunicação.
Quando Ser Cauteloso
Embora essas otimizações sejam poderosas, elas não são universalmente aplicáveis sem consideração:
- Ambientes com Firewalls Rígidos ou Restrições de Rede: Quedas frequentes de conexão ou inspeção de estado podem interferir no ControlPersist.
- Ambientes de Alta Segurança: Conexões SSH de vida útil mais longa podem ser uma preocupação de segurança em ambientes altamente regulamentados. Ajuste a duração do
ControlPersistde acordo. - Playbooks que dependem fortemente de
becomee operações de arquivo: A eficácia do Pipelining é reduzida quandobecomeé usado consistentemente, pois muitas vezes isso exige operações de arquivo. Teste o impacto no desempenho.
Conclusão
Otimizar a comunicação do Ansible com os nós gerenciados é um passo fundamental para uma automação eficiente e escalável. Ao entender e implementar ControlPersist e Pipelining, você pode reduzir drasticamente os tempos de execução do playbook. O ControlPersist mantém as conexões SSH ativas, reduzindo a sobrecarga de conexão, enquanto o Pipelining transmite a execução do módulo, eliminando a necessidade de transferências de arquivos. A combinação dessas duas configurações, principalmente através do ansible.cfg, é uma prática recomendada para qualquer usuário Ansible que gerencia um número significativo de hosts ou executa playbooks complexos. Sempre teste essas configurações em seu ambiente específico para otimizar o desempenho e garantir a compatibilidade.