By Vicente Málaga, Tue 07 July 2015, in category Infrastructure
Mi nombre es Vicente Málaga, Responsable de operaciones online en Qdqmedia y voy a comenzar con una serie de artículos relacionados con la base tecnológica que usamos en nuestra empresa.
Con una amplia experiencia en entornos de producción, primero en entornos unix y después con linux, he visto una transformación en la forma que se gestionan los CPD's y también como, desde los departamentos de producción se implementan las aplicaciones.
En la era pre-virtualización, la mayoría de las aplicaciones se implementaban de tal manera que cada aplicación tenia un asignación económica para tener su propio servidor. Esto hizo que los Cpd's crecieran de manera exponencial al crecimiento de las aplicaciones informáticas que se introducían en las empresas, algo poco sostenible ya que el coste e infra-utilizacion de los servidores era muy alto. El mantenimiento era muy costoso e incluso implementar soluciones de alta disponibilidad requería a veces duplicar o triplicar el numero de servidores necesarios para una aplicación.
Después llego la era de la virtualización, en la que el coste por servidor se redujo drásticamente ya que la utilización de los recursos de los servidores era optima, pudiendo alojar tantas maquinas virtuales en la maquina como permitieran los recursos de cpu y memoria. Además el nivel de aislamiento dentro del huésped de las VM esta muy conseguido. Pero esto también tiene sus desventajas, ya que para alojar en una maquina virtual un LAMP con su apache-php-mysql, necesitamos también toda la parte del sistema operativo, con su kernel, libc, etc ... , consumiendo memoria y mas recursos. KVM intenta mitigar este problema con el uso de KSM ( Kernel Samepage Merging ) haciendo que las paginas de memoria compartidas entre maquinas virtuales sean mezcladas para optimizar el uso de memoria en el huésped.
En Qdqmedia apostamos firmemente desde hace años por el Software libre algo que nos ha permitido cambios muy rápidos en la infraestructura sin los costes en licencias que tienes con los sistemas propietarios. Esto requiere que la plantilla del departamento de IT crezca rápidamente con técnicos y desarrolladores linux, que también necesitan crear sus aplicaciones rápidamente y aunque existe soluciones IaaS ( Infrastructure as a Service ) con portales de autoservicio como por ejemplo el famoso OpenStack, esto requiere que o bien el administrador instale todo el stack para que funcione la aplicación o el desarrollador sepa instalarlo y se encargue el de hacerlo, algo que no siempre tiene por que saber hacerlo, ademas de que tendría que conocer muy bien toda la estructura de red y almacenamiento para poder poner su aplicación en producción. Esto ademas de complicado, puede restar tiempo al desarrollador para cumplir sus objetivos.
Hace ya unos años aparecieron los primeros platform as a service como Heroku, que permitían al desarrollador desplegar su aplicación sin necesidad de conocer nada sobre la infraestructura que hay detras. Que necesita una base de datos o una queue de rabbit-mq, pues el sistema se lo expone como un servicio para que lo use dentro de la app sin necesidad de saber donde están esos servicios. De la misma manera el sistema ofrece una serie de lenguajes o frameworks para que el desarrollador pueda elejir el que mas le guste o el que mas le convenga en ese momento, python, nodejs o java.
En Qdqmedia después de evaluar diferentes opciones para montar un Paas privado hemos optado por TSURU https://tsuru.io por las siguente razones:
La documentación completa del producto la podeis encontrar en la web de tsuru http://tsuru.readthedocs.org y para no repetir lo mismo que hay en la documentación, os voy a enseñar como desplegar una aplicación hecha en nodejs bajada desde github, se llama mongo-express y es un frontend hecho en nodejs para mongodb. Para poder realizar la instalación necesitamos un entorno completo de tsuru, ademas de los clientes tsuru-client y tsuru-admin
$ git clone https://github.com/andzdroid/mongo-express.git && cd mongo-express
$ tsuru app-create mongo-express nodejs
tsuru app-info
Application: mongo-express
Repository: git@tsrmgr.example.com:mongo-express.git
Platform: nodejs
Teams: admin
Address: mongo-express.tsuru.example.com
Owner: admin@example.com
Team owner: admin
Deploys: 0
Pool: prod
App Plan:
+---------------+--------+------+-----------+--------+---------+
| Name | Memory | Swap | Cpu Share | Router | Default |
+---------------+--------+------+-----------+--------+---------+
| autogenerated | 0 MB | 0 MB | 100 | | false |
+---------------+--------+------+-----------+--------+---------+
echo "web: node app" > Procfile
cp config.default.js config.js
git add Procfile
gtt add -f config.js
git commit -am "add Procfile and config.js"
git remote add tsuru git@tsrmgr.example.com:mongo-express.git
root@tsrmgr:~/mongo-express# git push tsuru master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (22/22), 9.60 KiB | 0 bytes/s, done.
Total 22 (delta 10), reused 0 (delta 0)
remote: tar: Removing leading `/' from member names
remote:
remote: ---- Building application image ----
remote: ---> Sending image to repository (0.05MB)
remote: ---> Cleaning up
remote:
remote: ---- Starting 1 new unit ----
remote: ---> Started unit 7d60e37be6...
remote:
remote: ---- Binding and checking 1 new units ----
remote: ---> Bound and checked unit 7d60e37be6
remote:
remote: ---- Adding routes to 1 new units ----
remote: ---> Added route to unit 7d60e37be6
remote:
remote: OK
To git@tsrmgr.example.com:mongo-express.git
* [new branch] master -> master
Ahora si volvemos a ejecutar tsuru app-info -a mongo-express veremos nuestra aplicacion levantada en alguno de los nodos de docker
root@tsrmgr:~/mongo-express# tsuru app-info
Application: mongo-express
Repository: git@tsrmgr.example.com:mongo-express.git
Platform: nodejs
Teams: admin
Address: mongo-express.tsuru.example.com
Owner: admin@example.com
Team owner: admin
Deploys: 4
Pool: prod
Units: 1
+------------+---------+--------------------+-------+-------------+
| Unit | State | Host | Port | IP |
+------------+---------+--------------------+-------+-------------+
| 15f823cf0b | started | tsurunode01 | 32829 | 172.17.0.84 |
+------------+---------+--------------------+-------+-------------+
App Plan:
+---------------+--------+------+-----------+--------+---------+
| Name | Memory | Swap | Cpu Share | Router | Default |
+---------------+--------+------+-----------+--------+---------+
| autogenerated | 0 MB | 0 MB | 100 | | false |
+---------------+--------+------+-----------+--------+---------+
Ahora puedes acceder a la url que aparece en el Address para ver la aplicacion corriendo
http://mongo-express.tsuru.example.com
Con tsuru podemos aprovechar al máximo el hardware ya que cada app solo tiene los procesos justos para funcionar dentro del container de docker
root@tsrmgr:~/mongo-express# tsuru app-shell
root@43cc63f1d59e:/# ps -ef
UID PID PPID C STIME TTY TIME CMD
ubuntu 1 0 0 jul09 ? 00:00:00 /usr/bin/python /usr/local/bin/tsuru_unit_agent http://tsrmgr.example.com:8080 e9b847909a51f4e0b79382ecac672efd46cc0beb mongo-express /var/li
ubuntu 9 1 0 jul09 ? 00:00:58 /home/application/.circus_env/bin/python /home/application/.circus_env/bin/circusd /etc/circus/circus.ini --log-output /var/log/circus/circus.
ubuntu 23 9 0 jul09 ? 00:00:00 /home/application/.circus_env/bin/python -c from circus import plugins;plugins.main() --endpoint tcp://127.0.0.1:5555 --pubsub tcp://127.0.0.1
ubuntu 24 9 0 jul09 ? 00:00:00 /home/application/.circus_env/bin/python -c from circus import plugins;plugins.main() --endpoint tcp://127.0.0.1:5555 --pubsub tcp://127.0.0.1
ubuntu 27 9 0 jul09 ? 00:00:32 /home/application/.circus_env/bin/python -c from circus import plugins;plugins.main() --endpoint tcp://127.0.0.1:5555 --pubsub tcp://127.0.0.1
ubuntu 28 9 0 jul09 ? 00:00:09 /home/application/.circus_env/bin/python -c from circus import plugins;plugins.main() --endpoint tcp://127.0.0.1:5555 --pubsub tcp://127.0.0.1
ubuntu 31 9 0 jul09 ? 00:00:00 node app
root 54 0 1 22:13 ? 00:00:00 bash -l
root 68 54 0 22:13 ? 00:00:00 ps -ef