Benchmarking y tunning de servidores para ceph

Una vez tenemos una infraestructura de servidores funcionando bajo ceph, nos podemos preguntar ¿Cómo compruebo que mi cluster está funcionando a máximo rendimiento? En este post vamos a ver algunas herramientas para comprobar el rendimiento y tunning que podemos realizar en nuestros servidores para sacarle mas partido a Ceph.

Comprobar la escritura de disco
La forma mas sencilla para hacer un benchmark del disco es usando el comando dd. Para ello vamos a usar el siguiente comando, añadiendo la etiqueta oflag para bypassear la cache del disco:

# dd if=/dev/zero of=here bs=1G count=1 oflag=direct

Esta es la salida de uno de mis servidores, la primera sobre /root y la otra sobre /mnt/pve/ceph_data que es donde está montado un pool de ceph

root@wezen3D:~# dd if=/dev/zero of=here bs=1G count=1 oflag=direct
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 11.1835 s, 96.0 MB/s

root@wezen3D:/mnt/pve/ceph_data# dd if=/dev/zero of=here bs=1G count=1 oflag=direct
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 46.5157 s, 23.1 MB/s

Comprobar la velocidad de la red
Cuando estamos usando ceph, la red es un factor muy importante. En mi actual infraestructura estoy usando puertos ethernet a 1Gbps. En los foros de proxmox muchos de los administradores usan varios puertos ethernet en bonding o incluso puertos de fibra de 10Gbps. Espero que en unas semanas pueda tener funcionando la segunda opción, de mientras todo el tunning que puedo hacer es tocar parámetros y configuración (ahora entraremos en ello).

La herramienta por excelencia …

Ceph: El maldito deep scrubbing

Si has llegado aquí es que estás buscando ¿qué coño es esto del deep scrubbing? y es que no hay sólo deep scrubbing, sino que ¡hay también otro! el scrubbing a secas. Si aún no has llegado aquí te lo cuento.

En ceph hay los pg, que vendrían a ser las unidades de datos dentro de ceph. En estas unidades de dados es realmente donde se almacena la información y una forma de verlos sería como ficheros o volúmenes de datos.
Para que los datos sean coherentes entre los distintos servidores, ceph hace scrubbing y deep scrubbing. Aquí lo explican muy bien.

En resumen sería

  • scrubbing (a secas). captura los errores del OSD o del sistema de ficheros. Este proceso suele ser ligero y no generar un gran impacto en la lectura y escritura de disco (iout o io)
  • deep scrubbing, compara los datos de los objetos PG, bit a bit. Busca sectores defectuosos en los discos. Este proceso genera un I/O alto.

Una cosa que ya he identificado es que un I/O alto afecta al rendimiento de todo el sistema. Hace que todo vaya leeeeentooooo, que mover ficheros de un lugar a otro sea un supliciooooo….

Desde que actualicé de proxmox 6 a proxmox 7 y actualizando la versión del ceph, todo ha ido empeorando con el paso de los días. He comprado un switch mikrotik con 8 puertos de fibra de 10G y a ver si con las tarjetas de red de 10Gb de fibra y los …

Convertir una web con wordpress a estática con httrack

Hace unos días llegó a mí una de aquellas tareas que en teoría tenía que ser poquitas horas, las poquitas horas han terminado siendo casi un mes entero de trabajo.

La tarea encomendada era la de arreglar la portada de la página web del periódico digital de contrainformación kaosenlared.net.

La web estaba usando el tema publisher y la portada estaba construida con gutenberg, además para cachear la web se estaba usando el plugin W3 total cache. Una combinación del tema y los dos plugins mencionados hacían que se descuadrase toda la página. Por suerte se disponía de una copia de seguridad de un día anterior a que se rompiese la portada. Mi tarea fue pues reestablecer la configuración del tema desde las opciones de exportación y cargar el contenido de la página de la portada. Al arreglarlo y volver a poner la página en producción, a las pocas horas, la portada se volvía a descuadrar. El cliente pidió simplemente dar de baja esta web, hacer algo con los archivos y aprovechar para crear otra nueva que ya estaban usando como web de emergencia.

Así que mi propuesta fue arreglar de nuevo el wordpress y convertir la página web a estática, ya que la página web tenía un pequeño detallito de nada, la friolera de 407.000 entradas, cosa que hacía que el consumo de recursos de la web fuese espectacular, por la gran cantidad de páginas y usuarios que visitaban diariamente el sitio.

Lo primero pues fue copiar todo el …

Proxmox: Ceph y error SECURITY information

Olrait! otro problemilla de estos tontos que tenía pendientes de solucionar, resuelto!

La cosa es que hace un par de meses actualicé un proxmox 6.4 a 7.0, con major upgrade del sistema operativo (debian 10 a debian 11) incluso antes que saliese liberada la propia debian 11! Al hacerlo también tuve que subir la versión de ceph de nautilus (14.x) a octopus (15.x).

Al terminar, aquella misma noche recibo un mensaje de todos y cada uno de los servidores que había actualizado el ceph

Asunto: *** SECURITY information for planet1A.lamardebits.org ***

Cuerpo:
planet1A.lamardebits.org : Sep 9 00:08:13 : ceph : a password is required ; PWD=/ ; USER=root ; COMMAND=nvme wdc_wd4003ffbx-68mu3n0 smart-log-add –json /dev/sdb

La solución viene hoy pues tras encontrar éste mail en las listas de proxmox. Hay que entender el problema, falta algo en sudo o algo otro en otro programa para que suelte esto:

Primero será mirar qué hay en sudoers

root@planet1A:/etc/sudoers.d# cat ceph-osd-smartctl 
## allow ceph-osd (which runs as user ceph) to collect device health metrics

ceph ALL=NOPASSWD: /usr/sbin/smartctl -a --json=o /dev/*
ceph ALL=NOPASSWD: /usr/sbin/nvme * smart-log-add --json /dev/*

Después será mirar si existe el keyring de ceph para conectar con los otros ceph:

root@planet1A:~# cat /var/lib/ceph/bootstrap-osd/ceph.keyring
[client.bootstrap-osd]
	key = *****************************

Finalmente y lo que ha sido creo la solución, porque al mirar ambas cosas estaban correctas, ha sido instalar el paquete nvme-cli y listos, sin reiniciar ni nada.

root@planet1A:~# apt -y install nvme-cli

Cada día, al ejecutarse la copia de seguridad salía el …

Actualitzar gitlab 10.7.3 con debian 8 a gitlab 14.1.0 con debian 10

Hoy os traigo una migración que me ha llevado 4 días largos y el motivo es el de dejar sin actualizar demasiado tiempo un sistema. Con el tiempo lo he ido poniendo todo al día pero siempre había éste (y otro) servicio que se me resistía. Hablamos de gitlab instalado usando los repositorios de gitlab y cabe decir que aunque haya sido una actualización larga y puñetera me ha obligado a mirarme como funcionaba a nivel de sistemas gitlab y telita la de cosas que tiene!

El gitlab que tengo instalado, la curiosidad es que “trae los programas dentro”, es decir, en lugar de estar instalados por apt con los repositorios de debian están ahí metidos en una carpeta.

Otra cosa que tendremos que tener en cuenta es que para hacer una migración a una nueva versión se recomienda hacerlo desde otras versiones tal como explica en la documentación.

En mi caso por las versiones que debería pasar son las:

11.11.8 -12.0.12 -12.1.17 -12.10.14 -13.0.14 -13.1.11 -latest 13.12.Z -latest 14.0.Z -14.1.Z -latest 14.Y.Z

Así que vamos a empezar.

Actualizar de debian 8 a debian 10
En esta migración me ha tocado sacarme el miedo con los upgrades de versiones major de debian. Siempre he tenido la costumbre cada vez que ha habido una release de debian nueva ir migrando los servicios en un sistema nuevo. Por la complejidad de la instalación y porqué al principio no me enteraba muy bien …

Cambiar valor de option al seleccionar un campo select con jquery

Pequeño tip para hacer que al seleccionar un valor de un select se cambien las opciones de otro select.

Partimos de los dos select:

<select class="form-control rounded-0" name="sanctioningprocedure" onchange="update_reasons()">
    <option value="">{% trans "Select Sanctioning Procedure" %}</option>
    {% for sc in box.multiple_sanctioning_procedure_group.all %}
        <option value="{{ sc.pk }}">{{ sc|object_name:request.language }}</option>
    {% endfor %}
</select>

<select class="form-control rounded-0" name="complaint_reason">
    <option value="">{% trans "Select Reason" %}</option>
</select>

La parte de javascript:

<script>
function update_reasons(){
    var group = document.getElementById("sanctioningprocedure").value;

    $("#complaint_reason").empty();
    option = '';
    {% for r in all_reasons %}
        if (group == {{ r.group.pk }}) {
            option = option + '<option value="{{ r.pk }}">{{ r|object_name:request.language }}</option>';
        }
     {% endfor %}

     $("#complaint_reason").html(option);
}
</script>

 

 …

Proxmox migrar máquinas con mountpoints locales

Tengo 2 contenedores LXC que comparten un directorio con ficheros de configuración que está sobre glusterfs y está montado en local a todos los nodos. El otro día al tratar de migrar las máquinas me decía que no podía migrar las máquinas porque algo no le gustaba del mountpoint. Es una puñeta porque si se para el nodo en el que se encuentra el contenedor por algún motivo, el HA fallará por no poder migrar el contenedor a otro nodo.
El otro día traté de añadir el mountpoint local desde la interfaz de proxmox y no daba la opción. Hoy tonteando en los foros de proxmox he encontrado la solución.

En los contenedores, había configurado a mano el mountpoint. Para ello, paramos el contenedor y nos vamos al nodo en el que se encuentra en aquel momento cada uno de los contenedores y editamos el fichero de configuración que se encuentra en /etc/pve/lxc/

root@planet1B:/etc/pve/lxc# vi 106.conf
mp0: /mnt/gluster/gvol1/nginx,mp=/mnt/conf-nginx,shared=1

El secreto para poder migrar los contenedores con el mountpoint, es añadirle “shared=1” y el directorio tiene que estar en todos los nodos.

Aquí una capturilla de pantalla de como queda en proxmox

ip real con frontal proxy nginx, backend apache y wordpress

Por fin he encontrado la solución! otra de estas tareas pendientes que hacía que una instalación no funcionase como era esperado! en este caso me encuentro con dos frontales de nginx que actúan como proxy http y detrás de ellos está un wordpress sobre apache. Hace un tiempo, hice un post similar a éste, pero detrás estaba otro nginx.

Así que aquí dejo la solución.

Frontal nginx
En este caso tengo 2 ficheros, el de la configuración del dominio y otro con la configuración específica para los wordpress almacenado en el directorio snippets

# vi /etc/nginx/sites-available/lamardebits.org
server {
    listen 80;
    listen [::]:80;

    server_name lamardebits.org
                www.lamardebits.org;
    return 301 https://lamardebits.org$request_uri;

    #root /var/www/html/;
    include snippets/certbot.conf;
}


server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name lamardebits.org;

    include snippets/certbot.conf;

    # Aquí s'inclou el servidor intern i la protecció específica de WP
    include snippets/wordpress10.conf;

    ssl_certificate /etc/letsencrypt/live/lamardebits.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lamardebits.org/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_trusted_certificate /etc/letsencrypt/live/lamardebits.org/chain.pem;
}

Y la configuración específica para los wordpress

# vi /etc/nginx/snippets/wordpress10.conf
include conf.d/external-log.conf;
location / {
    proxy_pass http://172.31.0.145:6081;
    include proxy_params;

    location ~ \.php$ {
        proxy_pass http://172.31.0.145:6081;
        include proxy_params;

        location ~* wp\-login\.php {
            client_max_body_size 40M;
            proxy_pass http://172.31.0.145:6081;
            include proxy_params;
            include snippets/lmdb-protected.conf;
        }
    }

    proxy_headers_hash_max_size 512;
    proxy_headers_hash_bucket_size 128;

    fastcgi_read_timeout 300;
    proxy_read_timeout 300;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP       $remote_addr;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  X-Forwarded-Host $remote_addr;

    add_header X-Frame-Options SAMEORIGIN;

}

La configuración de proxy de nginx la tengo así

# vi /etc/nginx/conf.d/proxy.conf
proxy_buffer_size         128k;
proxy_buffers           4 256k;
proxy_busy_buffers_size   256k;
client_max_body_size      32M;

proxy_read_timeout 1800;
proxy_connect_timeout 1800;
proxy_send_timeout 1800;
send_timeout 1800;             

Backend apache + wordpress

A …

Instalación y configuración de Apache Guacamole en Debian 10

Hola, hoy veremos cómo instalar, configurar y usar Apache Guacamole, una herramienta que nos permite conectarnos remotamente por web mediante protocolos cómo SSH, RDP, VNC.

¿Qué es Apache Guacamole?
Apache Guacamole es una herramienta libre y Open-Source que nos permite conectarnos remotamente a un servidor mediante el navegador web sin necesidad de usar un cliente.

Gracias a HTML5, una vez tengamos instalado y configurado Apache Guacamole, tan solo tenemos que conectarnos mediante el navegador web para empezar a trabajar remotamente.

¿Qué es Tomcat?
Apache Guacamole no es una aplicación web autónoma y está compuesta de muchas partes. La aplicación web en realidad está diseñada para ser simple y mínima.

Una de esas partes, y esencial, es Tomcat. Tomcat es una especie de contenedor de ServLets que nos permite ejecutar herramientas desarrolladas con Java Server Page (JSP).

Para poder usar aplicaciones con Tomcat, este las “comprime” en ficheros .war.

¿Qué es un fichero .war?
Un fichero .war es una Aplicación Web que permite a Tomcat acceder a su utilización. El fichero .war en sí no es legible sino que tiene que ser expandido/descomprimido para ser leído.

Instalación de Guacamole-server
Comezamos con la instalación de Apache Guacamole-Server. Primero debemos instalar los paquetes mínimos necesarios, después podrémos elegir qué protocolos usar según nuestras necesidades.

Instalamos los paquetes principales necesarios:

root@guacamole:~# apt install libcairo2-dev libjpeg62-turbo-dev libpng-dev libossp-uuid-dev gcc make tomcat9 tomcat9-admin tomcat9-user

Ahora podemos elegir, según nuestras necesidades, qué paquetes instalar:

Usar Guacenc:

apt install libavcodec-dev libavutil-dev libswscale-dev

Usar el soporte para RDP:

apt 

Cambiar la red de ceph

El sábado hice un taller en vivo sobre proxmox en el que enseñé a configurar tanto ceph como glusterfs.

Aquí el vídeo sólo de la parte de la entrevista:

Instalar proxmox es super fácil, pero preparar bien el entorno ya es otra cosa. Al prepararlo cometí un fallo de diseño al reutilitzar configuración antigua.

Tal como dije, se recomienda destinar una red específicamente para la comunicación de los ceph. Así que vamos a ello.

El contenido de mi fichero de configuración de red es el siguiente

# vi /etc/network/interfaces
auto lo
iface lo inet loopback

iface eth0 inet manual

auto vmbr0
iface vmbr0 inet static
        address 10.139.39.166/27
        gateway 10.139.39.161
        bridge_ports eth0.10
        bridge_stp off
        bridge_fd 0

auto vmbr1
iface vmbr1 inet static
        address 172.31.0.11
        netmask 255.255.0.0
        bridge_ports eth0.1000
        bridge_stp off
        bridge_fd 0
        post-up echo 1 /proc/sys/net/ipv4/ip_forward

auto vmbr2
iface vmbr2 inet manual
        bridge_ports eth0.1001
        bridge_stp off
        bridge_fd 0


# ceph - glusterfs # dades
iface eth1 inet manual

auto vmbr11
iface vmbr11 inet static
        address 192.168.10.1/24
        bridge-ports eth1
        bridge-stp off
        bridge-fd 0

He cambiado los bridge_ports tanto de vmbr1 como de vmbr2 y añadido el bridge vmbr11 sin vlans y con la red 192.168.10.0/24.

He aplicado la configuración correspondiente a cada nodo del cluster y los he reiniciado.

Una vez iniciados de nuevo y comprobado que lleguen los servidores entre ellos por la red 192.168.10.0/24, he ido al fichero de configuración del ceph (/etc/pve/ceph.conf) y he cambiado el parámetro cluster_network

# vi /etc/pve/ceph.conf
[global]
         auth_client_required = cephx
         auth_cluster_required = cephx
         auth_service_required