Skip to main content

Cluster K8s en AWS usando Ansible

Este proyecto consiste en utilizar solamente Ansible para crear un cluster Kubernetes en AWS y utilizar durante el proyecto recursos que son esenciales saber para quien trabaja directamente con Ansible. A pesar de que Terraform en mi opinión es la mejor herramienta para provisionamiento de cloud también podemos hacer esto vía Ansible. Claro que podríamos sumar lo mejor de las dos herramientas aliado aún con Packer, pero vamos a mantenernos solamente con Ansible para ganar más conocimiento.

Para este proyecto vamos a aprender cómo crear una buena estructura de directorios para sus playbooks y cómo separar los archivos a fin de que quede muy práctico de gerenciar y dar mantenimiento. Para esto Ansible fornece un comando llamado ansible-galaxy que ayuda a crear una estructura de directorio muy buena. Además de esto ansible-galaxy es utilizado para instalar collections de módulos desarrollados por la comunidad.

Requisitos

Fases del proyecto

  • 1 Provisionamiento => En esta fase precisamos montar la infraestructura en AWS
  • 2 Setup => Precisamos instalar y configurar el cluster
  • 3 Deploy => Vamos a deployar una aplicación ejemplo en el cluster
  • 4 Monitoreo => Vamos a instalar Prometheus y Grafana para monitorear nuestro cluster

Estructura de directorios

Dentro de la carpeta ./src/ será de facto donde el proyecto acontecerá. Este directorio contendrá el directorio de las fases

Dentro de cada fase tendremos los siguientes archivos.

  • El hosts, nuestro inventario para cada fase
  • El ansible.cfg para tener las configuraciones de nuestro Ansible para cada fase.
  • El directorio roles que de facto tendrá nuestros playbooks
  • Un README.md explicando cada fase del proyecto.
~/projects/ansible/study-ansible/Projeto K8S Cluster main !5 ?2                                                                                                                    1.1.7 11:51:00
touch ansible.cfg hosts main.yml

Vamos a crear una carpeta llamada roles que dentro de ella tendrán nuestros playbooks, nuestras tasks. Para esto vamos a utilizar el binario llamado ansible-galaxy. Junto con Ansible vienen varios binarios que nos ayudan además del galaxy, vale la pena conferir.

![Binarios Ansible](./docs/iac/ansible/Projeto K8S Cluster/pics/binarios%20ansibles.jpg)

Vamos a montar los directorios referentes a las fases.

~/projects/ansible/study-ansible/Projeto K8S Cluster main !5 ?2                                                                                                                    1.1.7 11:41:43
cd roles

~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:41:48
❯ ansible-galaxy init provisioning
- Role provisioning was created successfully

~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:41:59
❯ ansible-galaxy init setup
- Role setup was created successfully

~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:42:05
❯ ansible-galaxy init deploy_app
- Role deploy_app was created successfully

~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:42:21
❯ ansible-galaxy init deploy_monitoring
- Role deploy_monitoring was created successfully

~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:42:28

Dentro de cada una de nuestras tasks pueden existir sub-tasks, o hasta mismo sub-sub-tasks. Luego será necesario crear una carpeta roles dentro de cada una de nuestras roles iniciales, pero vamos haciendo esto a lo largo del camino de acuerdo a lo necesario.

~/projects/ansible/study-ansible/Projeto K8S Cluster main !5 ?2                                                                                                                    1.1.7 11:51:11
❯ tree
.
├── ansible.cfg
├── hosts
├── main.yml
├── pics
│ └── binarios ansibles.jpg
├── README.md
└── roles
├── deploy_app
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ ├── tests
│ │ ├── inventory
│ │ └── test.yml
│ └── vars
│ └── main.yml
├── deploy_monitoring
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ ├── tests
│ │ ├── inventory
│ │ └── test.yml
│ └── vars
│ └── main.yml
├── provisioning
│ ├── defaults
│ │ └── main.yml
│ ├── files
│ ├── handlers
│ │ └── main.yml
│ ├── meta
│ │ └── main.yml
│ ├── README.md
│ ├── tasks
│ │ └── main.yml
│ ├── templates
│ ├── tests
│ │ ├── inventory
│ │ └── test.yml
│ └── vars
│ └── main.yml
└── setup
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml

38 directories, 37 files

Hosts - detalles

Sobre hosts vale la pena aprender algunas cosas https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

Si ves la documentación vas a observar que es posible pasar variables para todos los hosts o hosts específicos.

Definir cual es el camino del intérprete Python, esto evita que salga procurando y caso no esté en el path dar algún tipo de error para esto definimos el ansible_python_interpreter

vamos a comenzar con un hosts así:

# variables globales
[all:vars]
ansible_python_interpreter=/usr/bin/python
ntp_server=br.pool.ntp.org

[local]
localhost

# variables del grupo local
[local:vars]
ansible_connection=local
gather_facts=false

# será rellenado después automáticamente
[kubernetes]

Main.yml - detalles

Este solamente servirá para hacer includes (llamar otro archivo) de nuestras fases de acuerdo con lo que vamos haciendo, entonces será rellenado de acuerdo con nuestro desarrollo, pero vamos a dejar el primer llamado como ejemplo.

---
# Solamente includes aquí de las tasks
- include: provisioning

Aprendizajes durante el proyecto

El uso de tags es interesante pues puedes ejecutar solamente un playbook específico utilizando, o hasta mismo negar algunos.

solamente ejecutará las tagsA y tagB

ansible-playbook -i hosts main.yml --tags "tagA,tagB"

no va a ejecutar la tagA y tagB

ansible-playbook -i hosts main.yml --skip-tags "tagA,tagB"