Ansible Playbooks: Tutorial p2

Bienvenido a la segunda parte y final de este tutorial. En la primera parte hicimos una introducción a lo que eran los Playbooks, en este artículo veremos opciones más avanzadas para usar todo el poder de los Playbooks.

Escribiendo Playbooks

Variables

Hay varias formas en que se pueden definir variables en Ansible. La forma más simple es usar la sección vars de un playbook. El siguiente ejemplo define una variable llamada package que posteriormente usamos en una task:

1
2
3
4
5
6
7
8
---
- hosts: all
  become: true
  vars:
     package: vim
  tasks:
     - name: Install Package
       apt: name= state=latest

La variable package se puede usar en cualquier punto del provisionamiento, incluso en archivos y templates.

Loops

Loops se usan para ejecutar una tarea que se repite usando diferente valores de entrada. Por ejemplo en vez de crear 10 tasks para instalar 10 paquetes diferentes, puedes crear una sola task y luego usar un loop para repetir la tarea con todos los paquetes diferentes que necesitas instalar.

Para crear un loop en una tarea, se debe usar la opción with_items con un arreglo de valores. El contenido del arreglo se usa en el loop con la variable llamada item, como se muestra en el siguiente ejemplo:

1
2
3
4
5
6
- name: Install Packages
  apt: name= state=latest
  with_items:
     - vim
     - git
     - curl  

También puedes usar una variable para el array para definir los ítemes:

1
2
3
4
5
6
7
8
9
---
- hosts: all
  sudo: true
  vars:
     packages: [ 'vim', 'git', 'curl' ]
  tasks:
     - name: Install Package
       apt: name= state=latest
       with_items: packages

Condicionales

Los condicionales se pueden usar para decidir de forma dinámica si una tarea se debe ejecutar o no, basado en el valor de una variable o del resultado de un comando.

En el siguiente ejemplo se muestra una task que sólo se ejecutará en sistemas Debian:

1
2
3
- name: Shutdown Debian Based Systems
  command: /sbin/shutdown -t now
  when: ansible_os_family == "Debian"

El condicional when recibe un argumento o una expresión que se debe evaluar. La task solo se ejecuta en caso de que la expresión sea verdadera. En el ejemplo, nosotros revisamos el fact de que el sistema operativo fuera de la familia Debian.

Un uso común de los condicionales en automatización TI es cuando la ejecución de una task depende del resultado de un comando. Con Ansible, la forma de implementar esto es registrando una variable para contener el resultado de la ejecuión del comando, y luego revisar esta variable en las siguientes tasks. Se puede revisar el estado de salida del comando (si falló o se ejecutó bien). También podemos revisar por contenidos específicos del resultado del comando , lo cual puede necesitar que usemos regex.

El siguiente ejeplo muestra dos tareas condicionales que dependen del resultado del comando php -v. Comprobaremos el status de ejecución, ya que fallará si PHP no está instalado en el servidor. La opción ignore_errors se necesita para asegurarnos que el provisionamiento continue incluso cuando el comando falla su ejecución.

1
2
3
4
5
6
7
8
9
10
11
12
- name: Check if PHP is installed
  register: php_installed
  command: php -v
  ignore_errors: true

- name: This task is only executed if PHP is installed
  debug: var=php_install
  when: php_installed|success

- name: This task is only executed if PHP is NOT installed
  debug: msg='PHP is NOT installed'
  when: php_installed|failed

El módulo debug es útil para mostrar los contenidos de una variable o mensajes de depuración. Puede imprimir un texto (cuando se usa el argumento msg) o imprimir en contenido de una variable (cuando se usa el argumento var).

Templates

Los templates se usan típicamente para archivos de configuración, permitiendo el uso de variables y otras características que permiten hacer estos archivos más versátiles y re-utilizables. Ansible usa el motor Jinja2.

Abajo hay un ejemplo del uso de un template para configurar un host virtual en Apache, usando una variable para configurar el document root:

1
2
3
4
5
6
7
8
9
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot 

    <Directory >
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

El módulo template se usa para aplicar el template desde una task. Si llamamos el archivo de template vhost.tpl, y lo dejas en el mismo directorio del playbook, se aplica como se muestra a continuación:

1
2
- name: Change default Apache virtual host
  template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf

Triggers Handlers

Handlers se usan para ejecutar un cambio en el estado de un servicio, como iniciar o detener. Los Handlers funcionan de forma similar a las tasks, ejecutándose en el mismo orden en que se definieron, aunque sólo se ejecutan si y sólo si se gatillan usando la directiva notify en una task. Los Handlers generalmente se definen como un arreglo en la sección handlers de un playbook.

Vamos a usar el ejemplo anterior de templates, donde configuramos un hos virtual de Apache. Si te quieres asegurar de que Apache es re-iniciado cada vez que se cambia un host virtual, lo primero que necesitas es crear un handler para el servicio Apache. Así se definen los handlers en el playbook:

1
2
3
4
5
6
handlers:
    - name: restart apache
      service: name=apache2 state=restarted

    - name: other handler
      service: name=other state=restarted

La directiva name es importante porque es el único identificador de este handler. Para gatillar este handler desde una task, debes usar la opción notify:

1
2
3
- name: Change default Apache virtual host
  template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
  notify: restart apache

Playbook de ejemplo

Ahora vamos a revisar un playbook que automatizará la instalación del servidor web Apache en un sistema Ubuntu.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
- hosts: all
  become: true
  vars:
    doc_root: /var/www/example
  tasks:
    - name: Update apt
      apt: update_cache=yes

    - name: Install Apache
      apt: name=apache2 state=latest

    - name: Create custom document root
      file: path= state=directory owner=www-data group=www-data

    - name: Set up HTML file
      copy: src=index.html dest=/index.html owner=www-data group=www-data mode=0644

    - name: Set up Apache virtual host file
      template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
      notify: restart apache
  handlers:
    - name: restart apache
      service: name=apache2 state=restarted

Explicación del Playbook

hosts: all

El playbook comienza indicando que se debe ejecutar en todos (all) los hosts de tu inventario. Es posible segmentarlo a un grupo o host específico.

become: true

Esto le dice a Ansible que use sudo para ejecutar todas las tareas del playbook.to use privilege escalation (sudo) for executing all the tasks in this playbook.

vars

Define una variable, doc_root, que más tarde se usa en una tarea. Esta sección puede tener múltiples variables.

tasks

Esta sección es donde las tareas son definidas. La primera actualiza el caché de apt, y la segunda instala el paquete apache2.

La tercera tarea usa el módulo file para crear el directorio que se usará como document root. Este módulo se usa para administrar tanto archivos como directorios.

La cuarta tarea usa el módulo copy para copiar un archivo local al servidor remoto. Estamos copiando un simple archivo HTML.

handlers

Finalmente tenemos la sección handlers, donde se declaran los servicios. Aqui definimos un handler que reinicia apache cuando se notifica en la cuarta tarea, donde se aplica el template.

Conclusión

Ansible es una herramienta minimalista de automaticación que tiene una muy baja curva de aprendizaje y entrega muchos beneficios con un muy bajo costo.

En IT Linux usamos Ansible para todo, desde la administración de nuestros servidores, pasando por el soporte de nuestros clientes hasta la configuración de nuestros propios equipos.

Esperamos que le saques provecho ha estas guías.

Automatización y Por qué es tan Importante?

La mayoría de las personas que escucha el término DevOps piensa de forma automática en herramientas. DevOps es mucho más que herramientas. Es una forma de pensar. DevOps permite que tu empresa sea más ágil y apoya la creación de una cultura de innovación. En orden de alcanzar esta nueva forma de pensar, necesitas implementar algunas metodologías en tu organización. Estas metodologías contienen aspectos tales como continuous delivery.

También necesitaras una infrastructura sólida y bien definida, que permita construir ambientes que puedas ser clonados fácilmente y que puedan pasar a producción sin ningún riesgo. ¿Cómo podemos lograr esto?

La respuesta es Automatización. La Automatización permite construir ambientes idénticos una vez tras otras. Todos los paquetes necesarios, archivos de configuración, etc. se pueden definir de forma lógica y usarlos para construir plataformas de forma automática y libre de errores.

En los últimos años han nacido muchas herramientas para ayudar en la Automatización, siendo los principales Puppet de Puppetlabs, Chef y Ansible, reciéntemente adquirido por Red Hat.

Si bien todos ellos tienen un objetivo común: Automatizar la mantención de la infrastructura TI, todos operan de forma diferente, ya sea por el lenguage de configuración usado o porque algunos funcionan con un módelo Cliente <-> Servidor, siendo Ansible el único que no requiere un servidor o un agente para operar.

En ITLinux hace un tiempo ya decidimos quedarnos con Ansible. De todas las alternativas, es la solución que requiere menos inversión de tiempo y su curva de aprendizaje es baja, lo que permite alcanzar la promesa de la Automatización y no morir en el intento.

En nuestro Blog encontrarás varios artículos para comenzar tu uso de Ansible.

Primer Meetup: Virtualizando con Proxmox

El Viernes pasado, 6 de Mayo 2016, realizamos el primer Meetup del grupo Enterprise Open Source: Virtualizando con ProxmoxVE y Cloud con Open Source.

Agradecemos a todos los que participaron y les cuento que las Poleras ya están en producción, y que estamos organizando los próximos. Nuestra idea es realizar al menos dos por mes y que todos participemos con charlas.

Durante la próxima semana publicaremos el calendario de los primeros dos meses, por ahora los dejo con el material de la charla:

https://speakerdeck.com/pbruna/virtualizacion-con-proxmox

Ansible Playbooks: Tutorial p1

Como revisamos en un artículo anterior, Ansible se ha convertido en nuestra herramienta favorita. El Poder que entrega la Automatización es buena adicción, que lleva a contar con la seguridad de que tu plataforma siempre funcionará como corresponde.

En esta primera parte de dos artículos aprenderemos más sobre que son los Playbooks y su importancia al momento de automatizar el control de nuestras plataformas. Al final del segundo artículo ya tendremos los conocimientos necesarios para como ejemplo: Instalar un Servidor LAMP de forma autónoma.

Primero revisemos algunos términos importantes de Ansible:

  • Máquina de Administración, es la máquina donde tenemos instalado Ansible, puede ser nuestro laptop, y desde donde se ejecutaran las tareas. Recuerda que con ansible no necesitas servidores o agentes.

  • Inventory, es el archivo donde registramos los servidores sobre los cuales ejecutaremos las tareas,

  • Playbook, un archivo donde listamos las tareas que de deben ejecutar, es como una receta de concina. Se escribe en formato YAML

  • Task, un bloque dentro del Playbook que define una acción específica a realizar, pj: instalar un paquete.

  • Module, son como Plugins que permiten realizar tareas de forma más fácil. Muchos vienen, como yum para instalar software, y también nosotros podemos crear los nuestros.

  • Role, una forma de ordenar los diferentes Playbooks.

  • Play, se refiere a la ejecución de un Playbook.

  • Facts, variables dentro de Ansible que contienen información sobre los servidores. Ej: Sistema Operativo, Cantidad de Ram, Direcciones IP, etc.

  • Handlers, pequeño código que se usa cuando algo cambia. Por ej: si actualizas el archivo de configuración de Apache, un Handler re-iniciará el servicio httpd.

Tasks

Una Task (Tarea) define un sólo proceso que debe ser ejecutado durante el procedimiento. Generalmente se basa en el uso de algún módulo o la ejecución de un comando de shell (que en realidad es un módulo creado para ejecutar comandos). Este es un ejemplo de como se define una Task:

1
2
- name: Instalar nmap
  yum: name=nmap state=latest

La parte name es opcional, pero nosotros recomendamos su uso para describir que es lo que hará la tarea. yum es un módulo que viene incluído en Ansible y se encarga de todo lo que tiene que ver con la gestión de paquetes para distribuciones basadas den Red Hat. Esta Task le indica a Ansihle que el paquete nmap debe estar instalado en su última version, lo cual hará que yum lo instale si no está instalado, y que lo actualice si existe una versión más nueva.

Playbook

Los Playbooks son el punto de inicio al trabajar con Ansible. Ellos contienen información de en que máquinas se debe ejecutar el provisionamiento, como también las directivas y pasos que se deben realizar y el orden de su ejecución. A continuación un ejemplo de Playbook que primero crea un directorio y luego descarga un archivo en el:

1
2
3
4
5
6
7
8
---
- hosts: all
  tasks:
     - name: Crea directorio descargas
       file: path=/tmp/descargas state=directory mode=0755

     - name: Descarja Logo
       get_url: url=http://blog.itlinux.cl/images/logo_mini.png dest=/tmp/descargas/logo_mini.png

Como indicamos anteriormente, los Playbooks están escritos usando el formato YAML, el cual requiere que la identación sea perfecta para poder procesar el documento, por lo cual recomendamos que trabajes con un editor de texto que entienda el formato YAML, como puede ser ATOM.

Algunas cosas importantes del ejemplo:

  • hotst: all, indica este Playbook se ejecutará en todos los hosts definidos en el Inventory
  • tasks, es el conjunto de Tareas a ejecutar.

Ejecutando el Playbook

Una vez que tengas listo tu Playbook es momento de hacerlo funcionar, esto se realiza con el comando ansible-playbook, por ejemplo:

1
$ ansible-playbook -i hosts download_itlinux_logo.yml

Palabras al cierre

Esperamos que este artículo vaya aumentando tus ganas de Automatizar cuanto puedas en tu vida y veas lo simple que es hacerlo con Ansible.

Por ahora recomendamos que mientras esperan la segunda parte, jueguen con algunos ejemplos de Playbooks.

Introducción a Ansible

Ansible es una herramienta que permite Automatizar todas las tediosas y repetitivas tareas con que nos encontramos los administradores de sistema, como por ejemplo:

  • Configurar el computador para el nuevo
  • Instalar, configurar e ingresar los nuevos servidores al dominio
  • Administrar los usuarios de la VPN, y borrar los que ya no existen
  • Preparar las nuevas 38 VMs para el proyecto E-Commerce, las que deben estar creadas para mañana en Amazon AWS y RackSpace. Además de las de desarrollo en la plataforma Proxmox VE

Ufff, como que nos fuimos lejos con esa última. Pero , Ansible permite automatizar todo esto.

Como funciona Ansible

Una de las gracias de Ansible frente a la competencia es que no tienes que instalar ni Agentes ni Servidores. Sólo instalar ansible en tu máquina y estás listo para comenzar.

Ansible se conecta a los equipos que quieras configurar utilizando SSH y le envía las instrucciones que quieres ejecutar y las configuraciones que se deben aplicar.

Todo esto en paralelo, así que no importa si tienes 5 o 2 mil equipos que configurar.

Instalación de Ansible

La forma más fácil es utilizar el administrador de paquetes de tu sistema operativo.

1
2
3
4
5
6
7
8
 # RedHat y Clones
 $ yum install ansible

 # Debian y Clones
 $ apt-get install ansible

 # En Mac Os X con Homebrew
 $ brew install ansible

Trabajando con Ansible

El Inventario

Ansible trabaja con un Inventario de tu plataforma o servidores. Este Inventario es un archivo en el cual agrupas y listas los servidores según más te acomode:

1
2
3
4
5
 # Archivo hosts.cfg de inventario
 [dbs]
 db1.example.com
 db2.example.com
 db3.example.com

El archivo hosts.cfg contiene un grupo de servidores: dbs el cual tiene 3 servidores. Este es un Inventario sencillo, el de tu empresa puede ser mucho más complejo y también es posible hacer que se creen sólos.

Ejecutando comandos sencillos

El primer comando que vamos a usar, nos va a permitir comprobar que tenemos acceso a los clientes:

1
$ ansible -i hosts.cfg -m ping all

Otro ejemplo, para revisar la memoria disponibles en todos los servidores:

1
$ ansible -i hosts.cfg all -m shell -a 'free -m' -U root

Como vez en los dos ejemplos indicamos cual es el archivo Inventario que vamos a usar: -i hosts.cfg. Y en el último indicamos cual es el usuario con el que nos conectamos: -U root. Recuerda que la conexión se realiza con SSH.

Otro ejemplo que puede ser útil: Aplicar la actualización de Hora a todos los servidores, vamos a suponer que son del tipo Red Hat:

1
$ ansible -i hosts.cfg all -m yum -a "name=tzdata state=latest"

Del comando es importante notar lo siguiente:

  • -i hosts.cfg all, indica que se debe usar el inventario hosts.cfg y que se ejecutará en todos los servidores: all

  • -m yum, indica que módulo de ansible usaremos. Anteriormente ejecutamos comandos usando el módulo shell, ahora que queremos instalar un paquete, usamo yum.

  • -a "name=tzdata state=latest", son los parámetros que recibe el módulo. En este caso el nombre del paquete: name=tzdata, y el estado que debe tener: state=latest, en este caso que esté instalada la última versión.

En la documentación de Ansible puedes encontrar el listado completo de módules disponibles, y como se usan.

Donde vamos ahora

Continua con la Primera Parte del Tutorial de Playbooks.

Nuevamente se cambia la hora en Chile

SysAdmins de Chile preparen sus agendas y avisen en casa que nuevamente nos tocará estar en alerta por el cambio al horario de Invierno.

Está vez el cambio se realizará el día Domingo 15 de Mayo a las 00:00, según la información oficial de nuestro Gobierno. Ojo que en el sitio dice 14 de Mayo, 24:00 horas, pero esa fecha no existe. El reloj avanza de 00:00 a 23:59.

En el momento indicado los relojes deben retroceder una hora, lo cual nos dejará con la fecha 14 de Mayo, 23:00.

La mayoría de los fabricantes de software ya han sacado actualizaciones y recomendamos a todos aplicarlas lo antes posible. Estas actualizaciones no producen daño alguno:

Es importante hacer un alcance sobre las aplicaciones Java o J2EE, Java maneja una DB de zonas horarias independiente del sistema operativo, así que, sí o sí hay que actualizar la JVM.

¿Cómo actualizo el Sistema Operativo?

Para Red Hat y derivados

1
$ yum install tzdata tzdata-java -y

Para Debian y derivados

1
$ apt-get install tzdata tzdata-java -y

Para Microsoft

La verdad es que no sabemos :)

Feliz 15|14 de Mayo para Todos!!!

Publicar Tweets usando Cron

Como algunos ya sabrán estamos buscando gente que se integre a nuestro equipo, y encontrar buenos candidatos es casi tan difícil para la empresa, como para el que busca un buen trabajo, así que tienes que tratar de llegar a la mayor cantidad de personas: Las Redes Sociales.

Entonces como buen DevOps decides que tienes que automatizar este proceso, nos vas a gastar tu tiempo posteando, y para ello vamos a ocupar Twitter CLI, una herramienta de consola que permite postear en Twitter.

Su instalación, configuración y demás está muy bien explicada en el Readme, así que no lo vamos a repetir aquí. Una vez instalada sólo debes configurar crontab con las publicaciones que quieras, en el caso nuestro lo configuramos así:

1
2
3
4
5
06 17 * * * /usr/local/bin/t update "En @ITLinux buscamos Ingeniero de Soporte Linux para nuestro equipo http://bit.ly/21hlwgy"
06 21 * * * /usr/local/bin/t update "Si amas crear soluciones con OpenSource, unete al equipo de @ITLinux http://bit.ly/21hlwgy"
06 8 * * * /usr/local/bin/t update "En @ITLinux buscamos Ingeniero de Soporte http://bit.ly/21hlwgy"
06 11 * * * /usr/local/bin/t update "Ven y pon a pruebas tus conocimientos #DevOps, en @ITLinux tenemos un puesto para ti http://bit.ly/21hlwgy"
30 14 * * * /usr/local/bin/t update "Quieres trabajar en una empresa donde importa la creatividad mas que los productos? Ven y unete a nuestro equipo http://bit.ly/21hlwgy"

Y eso es. Espero que a más de uno le sirva.

Buscamos Ingenierio DevOps

En IT Linux llevamos vamos a cumplir 10 años ayudando a empresas nacionales e internacionales con sus necesidades de soluciones tecnológicas escalables y seguras a través del Software Libre, y cada vez más empresas quieren contar con nuestro apoyo. Pero para para poder entregarles la misma calidad de servicio que nos ha hecho conocidos, necesitamos de tu ayuda.

Por qué Ingenierio DevOps

Porque necesitamos un Ingeniero Sysadmin que se maneja con algún lenguaje de programación como: Perl, Python, Ruby, Go, etc. Y que lo use para que el computador trabaje por él y no al revés.

Descripción del Cargo

Tu responsabilidad será el ayudar a nuestros clientes con sus consultas y tareas en el menor tiempo posible, para lo cual debes mantener o mejorar nuestro record de 27 minutos de tiempo de respuesta. Tu trabajo comienza con la evaluación de la solicitud y termina con el correo de gracias por parte del cliente.

Junto con lo anterior debes tener una pasión por Automatizar cosas y Analizar Métricas. Tu tiempo debe estar destinado a ayudarnos a construir y mejorar la experiencia de nuestros clientes y no haciendo tareas tediosas que los computadores deben realizar por si sólos.

Algunas de los tecnologías con que deberás trabajar son:

  • Plataformas de Virtualización: KVM, Xen, Docker,
  • Soluciones de Correo y Colaboración, mayormente Zimbra CS
  • Herramientas de Automatización como Puppet, Ansible, Chef
  • Monitoreo y Análisis como Nagios, ELK Stack (Elasticsearch, Logstash, Kibana)

Finalmente debes estar disponible para trabajar fuera de horario cuando lo amerite.

Habilidades y Requisitos

Lo primero que debes tener para trabajar con nosotros es la dispocisión de estar enfrentado continuamente a nuevos desafíos y muchas ganar de aprender, y ser capaz de llegar a soluciones por ti mismo y documentar estas soluciones para compartirlas con el equipo.

Es obligatorio que tengas experiencia avanzada en:

  • Linux
  • Protocolos de Red: SMTP, HTTP, SNMP, DNS, etc.
  • Redes en Linux: iptables, ip, arptables, vlan, bonding, etc.
  • Configuración de Servidores de Correo (Postfix)

Es necesario que hayas usado y tengas experiencia con:

  • Virtualización, de preferencia KVM,
  • Programación en (perl || python || ruby || Go || node.js),
  • Herramientas de automatización como: Ansible, Puppet, Chef
  • Sistemas de Monitoreo como Nagios o Sensu

Beneficios

IT Linux es un lugar entretenido y desafiante para trabajar, ofrecemos un sueldo competitivo y puedes trabajar de forma remota (de donde tu quieras). Además siempre podrás participar de:

  • Capacitaciones,
  • Exámenes de Certificación,
  • Bonos por desempeño,
  • Tour gastronómicos,
  • Debates de actualidad

El mejor equipo del mercado con nuestra configuración especial.

Como Postular

Mediante GETONBOARD

Zimbra Authentication with Multiples LDAP Backends

So here we are again with another Zimbra Migration Challenge, this time the customer’s requirement was to enable External Authentication for a Domain, the catch: it had to be done in group of users. This way the IT Department could minimize the support calls when the user’s were facing with de Enter Password dialog.

The External Authentication Directory is a Samba 4 (Active Directory) LDAP, that has been working for almost a year now, so it was time to consolidate the users and password.

The approach we took was to deploy a LDAP Proxy using OpenLDAP Meta Backend and LDAP SASL Authentication. The following diagram shows the setup.

As you can see in the diagram, the flow of the authentication is:

  1. Zimbra was configured to authenticate against the LDAP Proxy.
  2. The LDAP Proxy pass the authentication request to the local saslauthd daemon.
  3. saslauthd ask the LDAP Proxy to do a Pass-Trough authentication to the corresponding Backend
  4. The Samba4 or the internal Zimbra LDAP validate the user.

So how did we do this? Glad you ask ;)

Zimbra: Debugging un servidor mailbox con mal desempeño

Hace unos días comenzamos a recibir alertas de alta carga de uno de los servidores Mailbox de ZBox, lo cual resultaba extraño ya que todos comparten la misma configuración, toda nuestra plataforma está definida con Ansible.

Como buenos sysadmins que somos tenemos monitoreado cada uno de los componentes de la plataforma ZBox, así que lo primero que hicimos fue mirar que decían las gráficas. Lo que más resaltaba era que el proceso de MySQL de este Mailbox estaba siempre al 100% de CPU, mientras que todos los demás estaban muy por debajo. A mirar que pasaba con MySQL.

Gracias al detalle que nos permite Hyperic identificamos que la cantidad de consultas SELECT por minuto eran 100 veces más que en el resto de los mailboxes. Algo extraño pasa aquí.

Qué son estas consultas?

Ya sabíamos que algo extraño pasaba con las consultas SELECT, pero lo que no sabíamos era que consultas eran. Para poder ver esto hay que habilitar el log de todas las consultas en MySQL. Entonces como usuario zimbra ejecutamos:

1
2
3
[zimbra@mailbox-03 ~]$ mysql
MariaDB [(none)]> SET GLOBAL general_log = 'ON';
MariaDB [(none)]> exit

Lo anterior habilita el registro de todas las consultas en el archivo /opt/zimbra/log/mysql-mailboxd.log. Hay que tener cuidado que este archivo crece mucho, muy rápido. Luego de un par de minutos desactive el registro con:

1
2
3
[zimbra@mailbox-03 ~]$ mysql
MariaDB [(none)]> SET GLOBAL general_log = 'OFF';
MariaDB [(none)]> exit

Nuetra intuición nos decía que algún usuario estaba provocando este comportamiento del servidor, así que lo que nos interesaba saber era que usuario. Para ello sacamos la información de las casillas con el siguiente comando:

1
$ grep SELECT /opt/zimbra/log/mysql-mailboxd.log|perl -ne 'chomp; @a=split(/\s+/,$_);print "$a[-7]$a[-6]$a[-5]\n"' > /tmp/mbxs

El contenido del archivo /tmp/mbxs son varias líneas del tipo:

1
2
3
4
5
6
7
8
9
10
...
mailbox_id=922
mailbox_id=922
mailbox_id=909
mailbox_id=922
mailbox_id=909
mailbox_id=909
mailbox_id=922
mailbox_id=922
...

Inmediatemente vimos un patrón, algo raro hay con las casillas 922 y 909. Contemos para ver si hay algo verdaderamente extraño:

1
2
3
4
5
6
7
$ cat /tmp/mbxs | cut -d= -f2 | sort | uniq --count
      1 500
      5 520
      1 536
      1 859
  65234 909
  32430 922

Definitivamente algo raro hay con esas casillas. Pero ¿a qué usuario corresponden?. Para saber esto ejecutamos el siguiente comando:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[zimbra@mailbox-03 ~]$  mysql -e 'SELECT * FROM zimbra.mailbox WHERE id=909 OR id=922\G'
*************************** 1. row ***************************
                  id: 909
            group_id: 9
          account_id: dc0b1ca1-2764-4494-a654-56a1f3d6c5c7
     index_volume_id: 2
  item_id_checkpoint: 338657
       contact_count: 4562
     size_checkpoint: 43794615187
   change_checkpoint: 561405
       tracking_sync: 122119
       tracking_imap: 0
      last_backup_at: 1434698066
             comment: usuario_problema_1@example.com
    last_soap_access: 1434976906
        new_messages: 364
  idx_deferred_count: 0
     highest_indexed: NULL
             version: 2.7
       last_purge_at: 1435196438
itemcache_checkpoint: 0
*************************** 2. row ***************************
                  id: 922
            group_id: 22
          account_id: 191bd27e-b87e-4cb3-828c-31da1a01b642
     index_volume_id: 2
  item_id_checkpoint: 313381
       contact_count: 5510
     size_checkpoint: 43947359451
   change_checkpoint: 859858
       tracking_sync: 198
       tracking_imap: 0
      last_backup_at: 1434704383
             comment: usuario_problema_2@example.com
    last_soap_access: 1435192996
        new_messages: 26
  idx_deferred_count: 0
     highest_indexed: NULL
             version: 2.7
       last_purge_at: 1435197163
itemcache_checkpoint: 0

[zimbra@mailbox-03 ~]$

Como puedes ver en el resultado, comment indica cual es el usuario. Una vez identificados, los bloqueamos y el servidor volvió a su comportamiento normal, lo que nos permitió examinar con más calma cual es la causa del problema.

Después de unos minutos nos dimos cuentas que ambos usuarios, con más de 40GB de correos, habían configurados sus iPads para descargar todo el correo. Si, así mismo.