Acelere o Ansible

Turbocompressor seccional


Não é segredo que, com as configurações padrão, o Ansible pode não fazer seu trabalho muito rapidamente. No artigo irei apontar várias razões para isso e oferecer um mínimo de configurações úteis que, muito possivelmente, irão realmente aumentar a velocidade do seu projeto.



Discutiremos aqui e mais adiante o Ansible 2.9.x, que foi instalado no virtualenv recém-criado da sua maneira favorita.



Após a instalação, criamos um arquivo "ansible.cfg" ao lado do seu manual - este local permitirá que você transfira essas configurações junto com o projeto, além disso, elas serão carregadas de forma totalmente automática.



Pipelining



Alguém já pôde ouvir sobre a necessidade de usar pipelining, ou seja, não copiar módulos para o FS do sistema de destino, mas transferir um arquivo zip empacotado em Base64 diretamente para o stdin do interpretador Python, mas o fato permanece : Esta configuração ainda está subestimada. Infelizmente, algumas das distribuições populares do Linux usadas para configurar o sudo não muito bem por padrão - de modo que este comando exigia um tty (terminal), então Ansible deixou esta configuração muito útil desabilitada por padrão.



pipelining = True


Coletando fatos



Você sabia que com as configurações padrão, o Ansible para cada jogada iniciará uma coleção de fatos de todos os hosts que participam dela? Em geral, se você não sabia, agora você sabe. Para evitar que isso aconteça, você precisa habilitar o modo de solicitação explícita para coletar fatos (explícito) ou o modo inteligente. Nele, os fatos serão coletados apenas daqueles hosts que não foram encontrados em jogos anteriores.

UPD. Ao copiar, você terá que escolher uma dessas configurações.



gathering = smart|explicit


Reutilizando conexões ssh



Se você já iniciou o Ansible no modo de depuração (opção "v" repetida de uma a nove vezes), deve ter notado que as conexões ssh estão sendo estabelecidas e abandonadas constantemente. Portanto, também há algumas sutilezas aqui.



Você pode evitar o estágio de restabelecimento de uma conexão ssh em dois níveis ao mesmo tempo: ambos diretamente no cliente ssh e ao transferir arquivos para um host gerenciado de um gerenciador.

Para reutilizar uma conexão ssh aberta, simplesmente passe as chaves necessárias para o cliente ssh. Então ele começará a fazer o seguinte: ao estabelecer uma conexão ssh pela primeira vez, crie adicionalmente um chamado soquete de controle, nos subseqüentes - verifique a existência deste mesmo soquete e, se for bem sucedido, reutilize a conexão ssh existente. E para que tudo isso faça sentido, vamos acertar o horário para salvar a conexão quando inativa. Mais detalhes podem ser encontrados na documentação do ssh , e no contexto do Ansible, simplesmente usamos o "encaminhamento" das opções necessárias para o cliente ssh.



ssh_args = "-o ControlMaster=auto -o ControlPersist=15m"


Para reutilizar uma conexão ssh já aberta ao transferir arquivos para um host gerenciado, você só precisa especificar mais uma configuração desconhecida ssh_tranfer_method. A documentação sobre este assunto é extremamente esparsa e enganosa, porque esta opção funciona sozinha! Mas a leitura do código-fonte permite que você entenda o que exatamente vai acontecer: o comando dd será lançado no host gerenciado, trabalhando diretamente com o arquivo necessário.



transfer_method = piped


A propósito, no ramo "desenvolver" essa configuração também existe e não foi a lugar nenhum .



Não tenha medo da faca, tenha medo do garfo



Outra configuração útil são os garfos. Ele determina o número de processos de trabalho que se conectarão simultaneamente aos hosts e realizarão tarefas. Devido às peculiaridades do Python como um PL, são os processos, não os threads, que são usados, porque o Ansible ainda oferece suporte ao Python 2.7 - nenhum assíncio para você, não há nada para gerar assincronia aqui! Por padrão, o Ansible inicia cinco trabalhos, mas se solicitado corretamente, ele executará mais:



forks = 20


Eu acabei de avisar que pode haver algumas dificuldades associadas à quantidade de memória disponível na máquina de controle. Em outras palavras, você pode, é claro, colocar garfos = 100500, mas quem disse que vai funcionar?



Juntando tudo



Como resultado, para ansible.cfg (formato ini), as configurações necessárias podem ser semelhantes a estas:



[defaults]
gathering = smart|explicit
forks = 20
[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=15m
transfer_method = piped


E se você quiser ocultar tudo no inventário normal do YaML de uma pessoa saudável, pode ser algo assim:



---
all:
  vars:
    ansible_ssh_pipelining: true
    ansible_ssh_transfer_method: piped
    ansible_ssh_args: -o ControlMaster=auto -o ControlPersist=15m


Infelizmente, isso não funcionará com as configurações "meeting = smart / explicit" e "forks = 20": não existem equivalentes YaML. Ou os definimos em ansible.cfg, ou os passamos pelas variáveis ​​de ambiente ANSIBLE_GATHERING e ANSIBLE_FORKS.



Sobre Mitogen
— Mitogen? — , . — . , Mitogen, Ansible , , — , Mitogen . , , — .



Mitogen? , . — , : , « , ». , « ».



Algumas dessas configurações foram descobertas durante a leitura do código-fonte do plugin de conexão com o nome autoexplicativo "ssh.py". Compartilho os resultados da leitura na esperança de que inspire alguém a olhar a fonte, lê-la, verificar a implementação, comparar com a documentação - afinal, mais cedo ou mais tarde, tudo isso trará resultados positivos. Boa sorte!



All Articles