Instalar cluster docker (swarm) + portainer.io

Ésta semana y la anterior estoy con un curso de DevOPs. En él estamos viendo principalmente docker y los orquestadores swarm y kubernetes.
En éste post nos vamos a centrar de momento con swarm.

Swarm viene “instalado” cuando instalamos docker y no tendremos que instalar nada addicional, simplemente configurarlo que lo veremos mas adelante.

Primero de todo pues tendremos que instalar docker, pero no usaremos los paquetes del repositorio, sino que vamos a seguir la instalación de la página web de docker para debian.

El entorno donde vamos a instalar docker van a ser 3 máquinas virtuales con KVM, docker-master (172.31.0.201), docker-worker1 (172.31.0.202) y docker-worker2 (172.31.0.203). La instalación la repetimos en las 3 máquinas.

Instalar docker

Comprobamos que docker no esté instalado y si lo está, lo desinstalamos

root@docker-master:~# apt update && apt -y upgrade && apt -y dist-upgrade
root@docker-master:~# apt-get remove docker docker-engine docker.io containerd runc

Instalamos las dependencias necesarias

root@docker-master:~# apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

Añadimos la clave GPG

root@docker-master:~# curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
root@docker-master:~# apt-key fingerprint 0EBFCD88

Configuramos el repositorio “stable”

root@docker-master:~#  add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"

Instalamos docker

root@docker-master:~# apt update
root@docker-master:~# apt-get install docker-ce docker-ce-cli containerd.io

A partir de aquí ya tenemos docker instalado y procederemos a montar el cluster swarm.

Activar cluster swarm

A continuación, montaremos 1 master y 2 workers. La recomendación es tener mínimo 3 master y 3 workers. En swarm, un master puede actuar como worker. De momento en el entorno que estamos …

La historia detrás de una simple transferencia de archivos

Ésta semana me he encargado de una tarea que muchos de nosotros hacemos diariamente, transferir ficheros por la red. Continuamente nos estamos pasando mensajes, fotografías, audios, vídeos, etc. por una red que nos interconecta a todos.

Al tratarse de un volumen considerable, la tarea requería un poco mas de dedicación y no era posible enviarse por los medios convencionales (telegram, mail), además el contenido de los ficheros era de importancia y era necesario comprobar que el contenido llegaba correctamente a su destino ya que el objetivo final era borrar los ficheros de origen.

Al igual que toda la historia que envuelve el contenido de éstos vídeos hay toda una historia detrás (y en la misma) del hito conseguido ésta tarde. Ésto hace apenas 30 años hubiese sido una utopía y denota una evolución tecnológica y también un cambio de paradigma en la forma que nos comunicamos los humanos.

Si nos remontamos unos años mas atrás, ésta necesidad de comunicación ya existía en los inicios de la especie humana. Una forma de comunicación serían lo que nos queda de aquellos inicios, las pinturas rupestres.
La comunicación la podemos usar para muchas cosas, para mostrar nuestros logros, para compartir nuestro conocimiento, para almacenar recuerdos e incluso mostrarnos a nosotros mismos. Ésta vorágine comunicativa se transmite mediante el arte: la pintura, la escultura, la escritura, la representación; la evolución del ser humano ha permitido la invención de cada vez mas complejos sistemas de comunicación que requieren una técnica mas avanzada, ésta técnica gracias …

Cómo gestionar las notificaciones?: mi caso

Hace unos días vi una persona que publicaba un vídeo sobre que se proponía desterrar los smartphones (teléfonos inteligentes) de su vida y pasar a un teléfono móvil sin internet. Me sorprendió por la persona de la que se trataba, @pauibars y como tal lo veo como un reto muy loable. Vídeo1: Viure sense smartphone al 2020 Vídeo2: Transició, reaccions i inici del repte de viure sense smartphone.

No es la primera vez que me encuentro con personas que renuncian a estar permanentemente conectadas y abrumadas de información.
Uno de los efectos secundarios de ésto es que cada vez pasamos menos tiempo leyendo o visionando, necesitamos consumir la información de forma mas voraz! en menos tiempo! cosa que nos convierte en personas mas ansiosas e individualistas, por otro lado nos convertimos en personas menos informadas, nos quedamos con los resúmenes y a veces aún peor sólo con el titular, nos quedamos sólo con la información de aquellos con los que estamos de acuerdo y perdemos la capacidad de investigar y cotejar por nosotros mismos la información. Ésto hace que nos convirtamos en personas fácilmente manipulables.
El año 2020 además del de la pandemia, lo etiquetaría como el año de las fake news (lacra existente desde el inicio de los tiempos y ahora magnificada con/por Internet).

Mi primer smartphone apareció en 2008 en la mano un nokia 95 8Gb y me he cuestionado varias veces sobre el uso que hago de mi teléfono móvil y he ido actuando en consecuencia. …

Seny i Rauxa

Pues hoy voy a poner un poco de “seny” (con un poco de “Rauxa” por la hora que es…) y me voy a ocupar de éste post que le había prometido a mi compañero de piso antes del 5 de Octubre, así que Luiz, aquí lo tienes. Que sepas que no dejo de pensar en ellas y ésto influye enormemente en mi vida! si analizas todo lo que te ocurre diariamente con éstas dos palabras, “seny” y “rauxa” todo toma un aire curioso :) cuando hago el check de mi día pienso en si lo que he hecho es “rauxa” o es “seny”.

Apreciados lectores y bots de internet, les pongo en situación. Luiz es, tal como he comentado en el párrafo anterior, mi actual compañero de piso. Brasileño, su última estancia fué Alemania, está aquí por un master de nosemuybienqué,peromolanlascosasquehace, que nos comunicamos en Inglés, que si alguna palabra no la sé la digo directamente en Castellano y si hace falta buscamos las palabras correctas para comunicar cosas (¡estoy aprendiendo mucho! ¡muchas gracias!). Parte de éste good feeling nos llevó una noche de verano entre una de muchas conversaciones a hablar sobre las palabras “Seny” y “Rauxa”.

Luiz tiene una asignatura que tienen que hacer los que hacen erasmus/master sobre algo sobre el sitio donde estás viviendo y decidió estudiar éstas dos palabras en un trabajo importante que tiene que hacer. Pero no eran dos palabras cualesquiera, eran de éstas palabras propias que tienen los idiomas, aquellas que definen …

Servidor y cliente REST: Django REST framework + requests

Muchos de los posts de éste blog son pequeñas píndolas y recordatorios que me dejo para facilitarme mi tarea diaria de administración de sistemas y últimamente de desarrollo, los comparto públicamente porque al servirme a mi, espero que sirvan a otros. Hoy os traigo un nuevo post de éstos últimos, precisamente de uno que ha sido durante varios años una espinita clavada, programar un servidor API. Hace 3 años hice un módulo de interacción con la API de un proveedor con uno de los programas que tengo en PHP, pero me quedaba lo que era realmente la espinita, la de crear yo el servidor API y permitir que otros programas interactuasen con el mío.

Hace alrededor de 5 años, un cliente que usaba un programa mío me pidió de la posibilidad de interactuar con el programa mediante una API. En aquel entonces traté de desarollarlo, pero con el lenguaje que estaba usando (PHP) y los conocimientos que tenía entonces me resultó tarea imposible, además de la actitud del desarrollador web del cliente. En fin. Así que haber superado éste hito es una inyección de felicidad, superación y autoconfianza.

Vamos a empezar.

Marco y necesidad
Me encuentro con dos aplicaciones que estoy desarrollando con django, voy a llamarlas por su nombre, colibrí y cóndor. Colibrí es un programa experto para hacer auditorías compliance y para cada empresa permite tener un inventario de máquinas. Por otro lado está Cóndor que es un programa de comunicación cliente-empresa. Lo que queremos hacer es que …

Múltiples idiomas en django

No hay momento mas dulce en el desarrollo de un programa el ver que va tomando solidez y que puedas implantar detallitos interesantes en la generación de pdf, navegar por el programa que va a los sitios que tiene que ir, etc. Hoy vamos a hablar de una de estas otras cosas que señalan el avanzado estado de nuestro programa, la internacionalización, el disponer la página en varios idiomas. Vamos a contarlo!

Primero de todo recomiendo tener a mano la documentación de django y éste otro artículo de Alex Dzul al que le he copiado el título y la metedología.

Para resumir, lo que tendremos que hacer será configurar el settings.py, preparar y traducir la interfaz y finalmente generar los ficheros .po. En la documentación te habla primero de la generación de los ficheros de traducción y después desarrollar la traducción en la interfaz (templates), luego contaré porqué es mejor hacerlo al revés.

Así que empezamos

Primero modificaremos el fichero settings.py de nuestro proyecto

(venv) laura@melatonina:~/dev/colibri$ vi colibri/settings.py 
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))

[...]

MIDDLEWARE_CLASSES = (
    # ...
    'django.middleware.locale.LocaleMiddleware',
    # ...
)

[...]

# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
# https://www.pythoniza.me/multiples-idiomas-en-django/

LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Madrid'
USE_I18N = True
USE_L10N = True
USE_TZ = True

from django.utils.translation import ugettext_lazy as _
LANGUAGES = (
    ('en', _('English')),
    ('es', _('Spanish')),
    ('ca', _('Catalan')),
)

# Definimos la ruta de los archivos de idiomas
LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)

# Definimos el procesador de contexto para i18n
#from django.conf.global_settings import TEMPLATE_CONTEXT_PROCESSORS 

Generar pdf con pie/cabecera con python, pdfkit y wkhtmltopdf

Ya llevo varios meses peleándome con pdfkit, al tener que atender otras partes de mi programa lo he ido dejando hasta que realmente he tenido la necesidad de ponerme a hacer funcionar correctamente pdfkit. La documentación que he encontrado por ahí ha sido un poco confusa, además de que estaba teniendo problemas con la versión del wkhtmltopdf y me estaba volviendo loca!

Ahora mismo tengo la necesidad de crear un pdf con sus márgenes, cabecera, pie y numero de página, además no quiero que salga la cabecera y pie de página en la primera página.

Primero de todo tendremos que tener en cuenta que pdfkit hace uso del programa wkhtmltopdf, que está en los repositorios de debian, pero me encuentro que éste no está compilado con qt, como tal al usar según que opciones de la configuración de wkhtmltopdf me soltaba un error similar a éste:

The switch --enable-internal-links, is not support using unpatched qt, and will be ignored.
The switch --footer-center, is not support using unpatched qt, and will be ignored.
The switch --header-html, is not support using unpatched qt, and will be ignored.
The switch --footer-html, is not support using unpatched qt, and will be ignored.

Para ello lo que haremos será primero de todo desinstalar wkhtmlpdf instalado en el sistema e instalar el .deb que nos ofrecen en la página del proyecto de wkhtmltopdf.

# apt remove --purge wkhtmltox
# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb
# dpkg -i wkhtmltox_0.12.6-1.buster_amd64.deb

UPDATE Para debian 12 bookworm mirar éste repositorio

# wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bookworm_amd64.deb

Instalar JDK Oracle en Debian + javaws

La receta de hoy pues sale tras la necesidad de acceder a la ILO/iDrac de un servidor Dell Poweredge R320. En varios sitios de internet te dicen que simplemente instalar el paquete icedtea-netx te vale, pero en mi caso no me termina de funcionar, así que he decidido probar un poco con el software privativo de oracle a ver qué tal respiraba la cosa, ya que en la máquina virtual windows que uso para acceder a otras ILO/iDrac en ésta versión de ILO/iDrac hay algún problema y no carga tampoco (quizás versiones de java demasiado viejas).

Así que primero iremos a la web de oracle y nos descargaremos el .tar.gz para linux de 64 bits.

A continuación lo descomprimimos en /usr/lib/jvm

# mkdir /usr/lib/jvm
# tar zxvf jdk-8u261-linux-x64.tar.gz -C /usr/lib/jvm

Y finalmente definimos los programas por defecto (update-alternatives crea un link simbólico en /etc/alternatives/ a la ubicación del binario y otro en /usr/bin/ a /etc/alternatives)

# update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_261/bin/java" 1
# update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.8.0_261/bin/javac 1
# update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.8.0_261/bin/javaws 1

Y luego para hacer funcionar el control remoto de la iDrac, entramos por http en ella y le indicamos “Launch Virtual Console”, nos descarga el fichero viewer.jnlp y lo ejecutamos así

$ javaws viewer.jnlp

Instalar asterisk con odbc + configurar odbc mariadb

Debido a una de las migraciones de servidores de un proxmox a otro, me he encontrado que la vieja debian 8 donde tenía instalado el servidor de telefonía, no arrancaba, así que he instalado asterisk en una debian 10, dentro de un contenedor lxc y con nesting activado.

Lo primero de todo será instalar asterisk

root@asterisk:~# cd /usr/src/
root@asterisk:/usr/src# wget http://downloads.asterisk.org/pub/telephony/certified-asterisk/asterisk-certified-16.8-current.tar.gz
root@asterisk:/usr/src# tar xvzf asterisk-certified-16.8-current.tar.gz
root@asterisk:/usr/src# cd asterisk-certified-16.8-cert3/contrib/scripts
root@asterisk:/usr/src/asterisk-certified-16.8-cert3/contrib/scripts# ./install_prereq
root@asterisk:/usr/src/asterisk-certified-16.8-cert3/contrib/scripts# ./get_mp3_source.sh
root@asterisk:/usr/src/asterisk-certified-16.8-cert3/contrib/scripts# cd ../../
root@asterisk:/usr/src/asterisk-certified-16.8-cert3# ./configure
root@asterisk:/usr/src/asterisk-certified-16.8-cert3# make menuselect
root@asterisk:/usr/src/asterisk-certified-16.8-cert3# make
root@asterisk:/usr/src/asterisk-certified-16.8-cert3# make install
root@asterisk:/usr/src/asterisk-certified-16.8-cert3# make config
root@asterisk:/usr/src/asterisk-certified-16.8-cert3# make samples

En el make menuselect activar chan_inunavailable, chan_sip, func_odbc

y con asterisk -vcccccccccccccc vemos como arranca asterisk y los errores

[Jul 21 00:14:03] WARNING[615]: res_odbc.c:1067 odbc_obj_connect: res_odbc: Error SQLConnect=-1 errno=0 [unixODBC][Driver Manager]Data source name not found, and no default driver specified

Para solucionar éste error, ahora configuraremos el odbc

root@asterisk:~# apt -y install unixodbc odbcinst

Ahora nos descargamos las librerías ya compiladas para debian buster

root@asterisk:~# wget https://downloads.mariadb.com/Connectors/odbc/connector-odbc-3.1.9/mariadb-connector-odbc-3.1.9-debian-buster-amd64.tar.gz
root@asterisk:~# tar xvzf mariadb-connector-odbc-3.1.9-debian-buster-amd64.tar.gz
root@asterisk:~# cd mariadb-connector-odbc-3.1.9-debian-buster-amd64
root@asterisk:~# cp lib/mariadb/lib*.so /usr/lib/x86_64-linux-gnu/odbc/

Ahora configuramos los ficheros odbc.ini y odbcinst.ini

root@asterisk:~# vi /etc/odbcinst.ini
[MySQL]
Description = ODBC para MySQL
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmaodbc.so
FileUsage = 1
root@asterisk:~# vi /etc/odbc.ini
[asterisk]
Description = MySQL Asterisk
Driver = MySQL
Database = asterisk
Server = localhost
User = xxxxx
Password = xxxxx
Port = 3306
Option = 3
Socket=/var/run/mysqld/mysqld.sock

[asterisk_users]
Description = MySQL Asterisk
Driver = MySQL
Database = users
Server = localhost
User = xxxxx
Password = xxxxx
Port = 3306
Option = 3
Socket=/var/run/mysqld/mysqld.sock

Es importante …

Proxmox: iptables nat vmbr0 y vmbr11

En éste caso la configuración que tenemos del servidor tenemos como siempre en vmbr0 una IP de guifi.net (que trato como ip local) y debido a que el numero de IPs públicas que tengo es limitada, tengo otro bridge vmbr11 con una red interna para comunicar las aplicaciones que sirven HTTP, luego tengo un contenedor con nginx y acceso a las 3 redes, la de guifi, la pública y la interna de las aplicaciones.

Para que las máquinas que están en la red de guifi y la de las aplicaciones puedan acceder a internet tendremos que configurar el NAT, para ello haremos lo siguiente:

En /etc/network/interfaces

root@wezen1A:~# cat /etc/network/interfaces
auto lo
iface lo inet loopback

iface eth0 inet manual

auto vmbr0
iface vmbr0 inet static
	address 10.90.234.166
	netmask 255.255.255.224
	gateway 10.90.234.161
	bridge_ports eth0
	bridge_stp off
	bridge_fd 0
	post-up echo 1 /proc/sys/net/ipv4/ip_forward

iface eth1 inet manual

auto vmbr1
iface vmbr1 inet static
        address 192.168.10.1
        netmask 255.255.255.0
        bridge_ports eth1     
        bridge_stp off
        bridge_fd 0

auto vmbr138
iface vmbr138 inet manual
        bridge_ports eth0.138
        bridge_stp off
        bridge_fd 0

auto vmbr11
iface vmbr11 inet static
        address 192.168.100.1
        netmask 255.255.255.0
        bridge_ports eth0.11
        bridge_stp off
        bridge_fd 0

La vmbr1 la tengo destinada a ceph, para que las maquinas compartan el disco ahí, además con su switch a parte! :) la vmbr138 es la que uso para las IPs públicas, en ésta red no vamos a aplicar NAT porqué las máquinas que estén en ésta red tendrán como gateway la IP del router. En vmbr0 ponemos en post-up el …