Implantação Automatizada de Cluster Kubernetes com Ansible
1.1 Introdução ao Ansible
Ansible é uma ferramenta de automação de TI. Ela pode configurar sistemas, implantar software e coordenar tarefas de TI mais avançadas, como implantação contínua e atualizações contínuas. Ansible é adequado para gerenciamento de infraestrutura de TI empresarial, desde pequenas escalas com poucos hosts até ambientse empresariais com milhares de instâncias. Ansible também é uma linguagem de automação simples que pode descrever perfeitamente a infraestrutura de aplicativos de TI.
Características principais:
- Simplicidade: Reduz o custo de aprendizado
- Potência: Coordena o ciclo de vida de aplicativos
- Sem agente: Previsível, confiável e seguro
Documentação: https://docs.ansible.com/
Instalação do Ansible: yum install ansible -y
- Inventory: Informações dos hosts gerenciados pelo Ansible, incluindo endereços IP, portas SSH, contas, senhas, etc.
- Modules: As tarefas são executadas por módulos, que também podem ser personalizados, como scripts frequentemente utilizados.
- Plugins: Usados para aumentar as funcionalidades do Ansible, com muitos plugins fornecidos e possibilidade de criação de plugins personalizados. Por exemplo, plugins de conexão para conectar aos hosts de destino.
- Playbooks: "Peças de teatro", definem modularmente uma série de tarefas para serem chamadas externamente. Funcionalidade central do Ansible.
1.2 Lista de Hosts
[servidores_web]
servidor_alpha.exemplo.org
servidor_beta.exemplo.org
192.168.1.100
www[001:006].exemplo.com
[servidores_banco]
banco01.intranet.meudominio.net
banco02.intranet.meudominio.net
10.25.1.56
10.25.1.57
banco-[99:101]-no.exemplo.com
1.3 Uso via Linha de Comando
Comandos ad-hoc podem ser usados para executar rapidamente operações específicas sem a necessidade de manter registros.
Comandos ad-hoc são fundamentais para entender o Ansible e antes de aprender playbooks.
Em geral, o verdadeiro poder do Ansible reside nos playbooks.
1. Autenticação para Conexão com Hosts Remotos
Autenticação por senha SSH:
[servidores_web]
192.168.1.100:22 ansible_ssh_usuario=root ansible_ssh_senha='123456'
192.168.1.101:22 ansible_ssh_usuario=root ansible_ssh_senha='123456'
Autenticação por par de chaves SSH:
[servidores_web]
10.206.240.111:22 ansible_ssh_usuario=root ansible_ssh_chave=/root/.ssh/id_rsa
10.206.240.112:22 ansible_ssh_usuario=root
Também pode ser especificado no arquivo de configuração ansible.cfg:
[defaults]
private_key_file = /root/.ssh/id_rsa # caminho padrão
2. Opções Comuns
| Opção | Descrição |
|---|---|
| -C, --check | Executa verificação sem realizar operações |
| -e VARIAVEIS_EXTRAS,--extra-vars=VARIAVEIS_EXTRAS | Define variáveis adicionais chave=valor |
| -u USUARIO_REMOTO, --user=USUARIO_REMOTO | Usuário para conexão SSH, padrão None |
| -k, --ask-pass | Solicita senha do usuário SSH |
| -b, --become | Eleva privilégios, padrão root |
| -K, --ask-become-pass | Solicita senha de elevação de privilégios |
3. Exemplos de Comandos
ansible all -m ping
ansible all -m shell -a "ls /home" -u root -k
ansible servidores_web -m copy –a "origem=/etc/hosts destino=/tmp/hosts"
1.4 Módulos Comuns
ansible-doc –l para listar todos os módulos
ansible-doc –s copy para ver documentação do módulo
Documentação de módulos: https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
1. shell
Executa comandos shell no host de destino.
- name: Redirecionar resultado do comando para arquivo
shell: algum_script.sh >> algum_log.txt
- name: Mudar diretório e executar comando
shell:
cmd: ls -l | grep log
chdir: algum_diretorio/
- name: Criar script
shell: |
if [ 0 -eq 0 ]; then
echo sim > /tmp/resultado
else
echo nao > /tmp/resultado
fi
args:
executable: /bin/bash
2. copy
Copia arquivos para hosts remotos.
- name: Copiar arquivo
copy:
src: /srv/meus_arquivos/config.conf
dest: /etc/config.conf
owner: usuario
group: grupo
mode: u=rw,g=r,o=r
backup: yes
3. file
Gerencia arquivos e seus atributos.
- name: Criar diretório
file:
path: /etc/algum_diretorio
state: directory
mode: '0755'
- name: Remover arquivo
file:
path: /config.txt
state: absent
- name: Remover diretório recursivamente
file:
path: /diretorio
state: absent
present, latest: indica instalação
absent: indica desinstalação
4. yum
Gerenciamento de pacotes.
- name: Instalar versão mais recente do apache
yum:
name: httpd
state: latest
- name: Instalar todos os pacotes da lista
yum:
name:
- nginx
- postgresql
- postgresql-server
state: present
- name: Desinstalar pacote apache
yum:
name: httpd
state: absent
- name: Atualizar todos os pacotes
yum:
name: '*'
state: latest
- name: Instalar nginx de repositório remoto
yum:
name: http://nginx.org/packages/rhel/7/x86_64/RPMS/nginx-1.14.0-1.el7_4.ngx.x86_64.rpm
state: present
5. service/systemd
Gerenciamento de serviços.
- name: Gerenciar serviço
service:
name: etcd
state: started
#state: stopped
#state: restarted
#state: reloaded
- name: Habilitar inicialização automática
service:
name: httpd
enabled: yes
- name: Gerenciar serviço
systemd:
nome=etcd
estado=reiniciado
habilitado=sim
recarregar_servico=sim
6. unarchive
- name: Descompactar arquivo
unarchive:
origem=arquivo_teste.tar.gz
destino=/tmp
7. debug
Imprime mensagens durante a execução.
- debug:
msg: Sistema {{ inventory_hostname }} tem uuid {{ ansible_product_uuid }}
- name: Exibir todas as variáveis do host
debug:
var: hostvars[inventory_hostname]
verbosity: 4
1.5 Playbook
Playbooks são a linguagem de configuração, implantação e orquestração do Ansible. Eles descrevem o que você deseja que aconteça nas máquinas remotas ou uma série de etapas em um processo de TI. Os arquivos de Playbook são organizados no formato YAML legível.
Se os módulos do Ansible são suas ferramentas de trabalho, então os Playbooks são seus manuais de instruções, e o arquivo de ativos de hosts é sua matéria-prima.
Em comparação com o modo de execução de tarefas ad-hoc, usar Playbooks com Ansible é uma abordagem completamente diferente e extremamente poderosa.
https://docs.ansible.com/ansible/latest/user_guide/playbooks.html
---
- hosts: servidores_web
vars:
porta_http: 80
nome_servidor: www.exemplo.com
remote_user: root
gather_facts: false
tasks:
- name: Instalar nginx mais recente
yum: pkg=nginx state=latest
- name: Escrever arquivo de configuração nginx
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
notify:
- reiniciar nginx
- name: Garantir que nginx esteja rodando
service: name=httpd state=started
handlers:
- name: reiniciar nginx
service: name=nginx state=reloaded
1. Hosts e Usuários
- hosts: servidores_web
remote_user: usuario
become: yes
become_user: root
ansible-playbook nginx.yaml -u usuario -k -b -K
2. Definindo Variáveis
Variáveis são uma conveniente forma de aplicar configurações a múltiplos hosts; na prática, as variáveis são adicionadas a cada host antes da execução e então referenciadas durante a execução.
- Passagem via linha de comando
-e VAR=VALOR
- Variáveis de host e grupo
Definidas no Inventory.
[servidores_web]
192.168.1.100 ansible_ssh_user=root hostname=web1
192.168.1.100 ansible_ssh_user=root hostname=web2
[servidores_web:vars]
ansible_ssh_user=root hostname=web1
- Armazenamento em arquivo único
A prática recomendada no Ansible é não armazenar variáveis no Inventory.
Além de armazenar variáveis diretamente no arquivo Inventory, variáveis de host e grupo também podem ser armazenadas em arquivos individuais relativos ao arquivo Inventory.
Variáveis de grupo:
group_vars armazena variáveis de grupo
group_vars/all.yml é válido para todos os hosts, equivalente a [all:vars]
group_vars/etcd.yml é válido para hosts do grupo etcd, equivalente a [etcd:vars]
# vi /etc/ansible/group_vars/all.yml
dir_trabalho: /dados
# vi /etc/ansible/host_vars/servidores_web.yml
porta_nginx: 80
- Definindo no Playbook
- hosts: servidores_web
vars:
porta_http: 80
nome_servidor: www.exemplo.com
- Variáveis Register
- shell: /usr/bin/uptime
register: resultado
- debug:
var: resultado
3. Lista de Tarefas
Cada play contém uma série de tarefas. Essas tarefas são executadas em sequência, e em um play, todos os hosts executam as mesmas instruções. O objetivo de um play é mapear hosts selecionados para tarefas.
tasks:
- name: Instalar nginx mais recente
yum: pkg=nginx state=latest
4. Verificação de Sintaxe e Depuração
Verificação de sintaxe: ansible-playbook --check /caminho/para/playbook.yaml
Execução de teste, sem operações reais: ansible-playbook -C /caminho/para/playbook.yaml
O módulo debug imprime mensagens durante a execução, útil para depurar variáveis ou expressões sem interromper o play. Funciona melhor com a instrução 'when:'.
- debug: msg={{grupos_nomes}}
- name: Nome do host
debug:
msg: "{{inventory_hostname}}"
5. Controle de Tarefas
Se você tem um playbook grande, pode ser útil executar partes específicas sem rodar o playbook inteiro.
tasks:
- name: Instalar nginx mais recente
yum: pkg=nginx state=latest
tags: instalacao
- name: Escrever arquivo de configuração nginx
template: src=/srv/httpd.j2 dest=/etc/nginx/nginx.conf
tags: configuracao
Uso:
ansible-playbook exemplo.yml --tags "instalacao"
ansible-playbook exemplo.yml --tags "instalacao,configuracao"
ansible-playbook exemplo.yml --skip-tags "instalacao"
6. Controle de Fluxo
Condições:
tasks:
- name: Executar tarefa apenas no 192.168.1.100
debug: msg="{{ansible_default_ipv4.address}}"
when: ansible_default_ipv4.address == '192.168.1.100'
Laços:
tasks:
- name: Criar usuários em lote
user: name={{ item }} state=present groups=wheel
with_items:
- usuario_teste1
- usuario_teste2
- name: Copiar arquivos
copy: src={{ item }} dest=/tmp
with_fileglob:
- "*.txt"
Instruções de laço comuns:
| Instrução | Descrição |
|---|---|
| with_items | Laço padrão |
| with_fileglob | Percorrer arquivos de diretório |
| with_dict | Percorrer dicionário |
7. Modelos (Templates)
vars:
dominio: "www.exemplo.com"
tasks:
- name: Escrever arquivo de configuração nginx
template: src=/srv/servidor.j2 dest=/etc/nginx/conf.d/servidor.conf
# servidor.j2
{% set nome_dominio = dominio %}
server {
listen 80;
server_name {{ nome_dominio }};
location / {
root /usr/share/html;
}
}
No Jinja, variáveis do Ansible são referenciadas diretamente com {{ }}. Para atribuir variáveis do Ansible a variáveis do Jinja, não use {{ }}.
Definindo variáveis:
{% set ip_local = inventory_hostname %}
Condições e laços:
{% set lista=['um', 'dois', 'tres'] %}
{% for i in lista %}
{% if i == 'dois' %}
-> dois
{% elif loop.index == 3 %}
-> 3
{% else %}
{{i}}
{% endif %}
{% endfor %}
Exemplo: Gerar string de conexão etcd
{% for host in grupos['etcd'] %}
https://{{ hostvars[host].inventory_hostname }}:2379
{% if not loop.last %},{% endif %}
{% endfor %}
Também é possível usar variáveis do Ansible dentro.
1.6 Funções (Roles)
Roles são um método para carregar automaticamente certos arquivos de variáveis, tarefas e manipuladores com base em uma estrutura de arquivos conhecida. Elas agrupam conteúdo por função, sendo adequadas para construir ambientes de implantação complexos.
1. Definindo Roles
Estrutura de diretórios de Roles:
site.yml
servidores_web.yml
servidores_foo.yml
roles/
comum/
tasks/
handlers/
files/
templates/
vars/
defaults/
meta/
servidores_web/
tasks/
defaults/
meta/
tasks- Contém a lista principal de tarefas que a função deve executar.handlers- Contém manipuladores que podem ser usados por esta função ou em qualquer outro lugar.defaults- Variáveis padrão da funçãovars- Outras variáveis da funçãofiles- Contém arquivos que podem ser implantados por esta função.templates- Contém modelos que podem ser implantados por esta função.meta- Define alguns metadados para esta função.
A prática comum é incluir tarefas específicas da plataforma a partir do arquivo tasks/main.yml:
# roles/servidores_web/tasks/main.yml
- name: Adicionado na 2.4, anteriormente você usava 'include'
import_tasks: redhat.yml
when: ansible_facts['os_family']|lower == 'redhat'
- import_tasks: debian.yml
when: ansible_facts['os_family']|lower == 'debian'
# roles/servidores_web/tasks/redhat.yml
- yum:
name: "httpd"
state: present
# roles/servidores_web/tasks/debian.yml
- apt:
name: "apache2"
state: present
2. Usando Funções
# site.yml
- hosts: servidores_web
roles:
- comum
- servidores_web
Definindo múltiplas funções:
- name: 0
gather_facts: false
hosts: all
roles:
- comum
- name: 1
gather_facts: false
hosts: all
roles:
- servidores_web
3. Controle de Funções
- name: 0. Inicialização do sistema
gather_facts: false
hosts: all
roles:
- comum
tags: inicializacao
1.7 Implantação Automatizada do Kubernetes (Versão Offline)
1. Familiarizando-se com os passos de implantação binária do Kubernetes
- Planejamento de servidores
- Inicialização do sistema
- Desativar selinux e firewalld
- Desativar swap
- Sincronização de tempo
- Configurar hosts
- Implantação do cluster Etcd
- Gerar certificados etcd
- Implantar três nós etcd
- Verificar estado do cluster
- Implantação do Master
- Gerar certificados do apiserver
- Implantar componentes apiserver, controller-manager e scheduler
- Iniciar TLS Bootstrapping
- Implantação do Node
- Instalar Docker
- Implantar kubelet e kube-proxy
- Permitir que o Master emita certificados para novos Nodes
- Autorizar o apiserver a acessar o kubelet
- Implantação de plugins (com imagens preparadas)
- Flannel
- Web UI
- CoreDNS
- Ingress Controller
- Alta disponibilidade do Master
- Adicionar nó Master (idêntico ao Master1)
- Implantar balanceador de carga Nginx
- Alta disponibilidade Nginx+Keepalived
- Modificar Node para conectar ao VIP
2. Análise da organização de componentes do K8S com Roles
Sugestões de desenvolvimento:
- Mapear fluxos e estrutura de Roles
- Se arquivos de configuração tiverem conteúdo variável, usar Jinja para renderizar
- Conteúdo que requer intervenção manual deve ser centralizado em um único arquivo
3. Download dos arquivos necessários
Garanta que todos os nós tenham horários de sistema consistentes
Baixar arquivos de implantação do Ansible:
git clone https://github.com/usuario/ansible-instalacao-k8s
cd ansible-instalacao-k8s
Baixar pacotes de software e extrair:
Link da nuvem: https://cloud.com/link/arquivos_binariosCódigo de extração: 1234
tar zxf pacotes_binarios.tar.gz
4. Modificar arquivos do Ansible
Modificar o arquivo hosts, ajustando IPs e nomes conforme o planejamento.
vi hosts
Modificar o arquivo group_vars/all.yml, ajustando o diretório de software e IPs confiáveis para certificados.
vim group_vars/all.yml
diretorio_software: '/root/pacotes_binarios'
...
hosts_certificado:
k8s:
etcd:
5. Implantação com um único comando
Diagrama de arquitetura
Arquitetura de único Master
Arquitetura multi-Master
Comando de implantaçãoVersão de único Master:
ansible-playbook -i hosts implantacao-unico-master.yml -uroot -k
Versão multi-Master:
ansible-playbook -i hosts implantacao-multi-master.yml -uroot -k
6. Controle de implantação
Se uma fase de instalação falhar, pode-se testar especificamenet.
Por exemplo: executar apenas a implantação de plugins
ansible-playbook -i hosts implantacao-unico-master.yml -uroot -k --tags plugins