Jenkins 2 con Docker y GitLab

Anteriormente os hable de Docker, una solución increíble del mundillo de la virtualización, y muchos conoceran al famoso Señor Jenkins, o como yo lo veo de cierta forma la evolucion del siempre fiel CRON de Linux, pues bien! Jenkins cuenta con su imagen oficial basada en Docker que puedes poner en marcha de forma rápida y facilmente, no adentrare demasiado en las funcionalidades de Jenkins y pasare a comentaros como poner en marcha Jenkins desde un contenedor Docker y configurarlo con una cuenta de GitLab para la integración continua durante el proceso de desarrollo de un proyecto, basándonos en que habéis puesto en marcha ya Docker en vuestro servidor u ordenador y en que ya habéis probado un poco el entorno de Docker como os explique en mi post anterior Docker show time!.

1.- Desgarga de la imagen oficial de Jenkins desde los repositorios oficiales de Docker.

El repositorio oficial esta este link https://hub.docker.com/_/jenkins/ en vuestro caso podeis ejecutar simplemente desde la consola de vuestra preferencia el siguiente comando para la descarga de la imagen a vuestro repositorio local:

>_ docker pull jenkins

Luego pueden comprobar que la imagen ha quedado correctamente descargada verificando las imagenes que se encuentran descargadas en vuestro server Docker:

>_ docker images

Para desplegar la imagen de Jenkins asignando un nombre especifico y evitar que se le asigne de forma random ejecutar:

>_  docker run -p 8080:8080 -p 50000:50000 --name jenkins jenkins

Esto os creara el contenedor de Docker con el nombre jenkins en minusculas (importante!) y continuara monstrando el progreso durante la carga de Jenkins inicial, es importante que no salgais de la consola ni la canceleis o cerreis en ningun momento ya que esta primera fase genera un codigo de Unlock que luego necesitareis en el momento en que vayais a acceder a la administracion o gestion de Jenkins, una ves que os aparezca este codigo copiarlo en alguna parte segura para el paso que viene.

Sabiendo que el contenedor esta en marcha podemos acceder con nuestro navegador favorito a la dirección http://localhost:8080 donde lo primero que nos aparecerá sera una pantalla como esta:

Es en Administrator password donde tendreis que colocar el codigo que habeis copiado anteriormente y hacer click a siguiente!

En la proxima ventana se os pregunta si quereis seleccionar de la lista de Plugins disponibles para Jenkins o instalar los predeterminados, partiendo de la idea de que es primera ves que poneis en marcha Jenkins seleccionar los predeterminados.

Veran como comienzan a instalarse de forma automatica un listado de plugins preseleccionados.

Finalizada la instalacion de los plugins por defecto os dara la opcion de crear el usuario administrador, os recomiendo hacerlo de una ves estableciendo el nombre de usuario, contraseña e email que les venga bien, si se saltan este paso y reinician la instancia luego sera complicado recuperar la consola de administracion.

Y listo!, instalacion completada con exito, ahora pasaremos a la configuracion de las credenciales para que nuestro servidor Jenkins este vinculado a nuestra cuenta de GitLab.

Para trabajar con nuestro proyecto alojado en GitLab podemos hacerlo de varias formas, una de ellas seria acceder a nuestro proyecto de GitLab y en Settings / Integrations seleccionar la opción de Jenkins CI (An extendable open source continuous integration server) en este caso lo que haremos sera generar un Token desde nuestro GitLab profile que podremos usar para que Jenkins pueda acceder y comprobar el repositorio, con lo que accedemos a Profile / Settings / Access Tokens, aquí deberemos asignar un nombre al Token que queremos generar, pongamos por ejemplo Jenkins y en el campo Expires at lo dejamos en blanco para que dicho Token no tenga fecha de vencimiento por ahora, ya si deseamos revocarlo en algún momento podremos hacerlo sin problemas desde el botón rojo “Revoke“.

Teniendo esto hecho, ahora podemos volver a la consola de administración de nuestro Jenkins, y lo primero que haremos sera ir a la sección Administrar Jenkins, en el Filtro colocaremos la palabra clave git y buscaremos los plugins de GitLab y GitHub que no tengamos instalados y los seleccionaremos haciendo click al finalizar en Instalar sin reiniciar, después de esto podéis reiniciar el server de Jenkins desde el panel de administración.

Una ves finalizado podemos ir a la sección de configuración de las credenciales para añadir en las credenciales Globales el Token que hemos generado en GitLab que debemos haber apuntado previamente.

Haciendo click en Global nos pasara a la siguiente ventana en la que haciendo click en Add Credentials podremos añadir el Token.

Haciendo click en OK ya tendríamos creada nuestra credencial asociada a nuestro GitLab Token, ahora vamos a crear la tarea de Build automatico, lo haremos sobre un proyecto cualquiera que tengamos en GitLab y en el que cada ves que reciba un commit con un cambio aplicado al proyecto, Jenkins se percate de ello y realice la Build.

Hacemos click en Nueva Tarea añadimos un nombre al proyecto, en mi caso usare un repositorio de un blog hecho en Symfony 2.5.10, así que le pondré de nombre a la tarea symfony, en la sección Configurar el origen del código fuente selecciono la opción Git, añado el link del repositorio en cuestión en formato HTTP (https://jonas.marquez@gitlab.com/jonas.marquez/blog.git), en el campo Navegador del repositorio selecciono de la lista la opción de gitlab y añado la URL del proyecto (git@gitlab.com:jonas.marquez/blog.git), en Versión añado 1.0 ya que es la versión que de momento estoy probando.

Ahora en la sección Disparadores de ejecuciones seleccionamos la opción Build when a change is pushed to GitLab, con esto cada ves que se haga un push al repositorio Jenkins se encargara de descargarlo y hacer la respectiva Build del proyecto o lo que sea que definamos mas adelante.

Luego hacemos click en Apply y luego en Guardar, en principio con esto tendremos la tarea hecha y puesta en marcha, a partir de aquí solo tendremos que ir a nuestro proyecto en local y realizar alguna modificación en el README.md o a cualquier archivo en cuestión, hacer el respectivo commit y push del cambio e irnos a nuestro proyecto recientemente creado activando en la esquina superior derecha el “ACTIVAR AUTO REFRESCO“, a partir de aquí comenzaremos a ver como cada cierto tiempo pasados unos segundos luego de hacer un commit/push nuevo hacia GitLab se van generando Builds nuevas en nuestro proyecto en Jenkins de forma automática, si desean paralizar las Builds del proyecto en determinado momento lo pueden hacer sin problemas haciendo click en Desactivar el Proyecto (Botón Azul/Gris de la derecha).

Y eso es todo! ahora solo queda escribir código y hacer commits/push desde Git y Jenkins ira realizando las Builds y Pruebas por nosotros!

Espero que os sea de ayuda, hasta otra!

Docker show time!

Con los vientos que corren últimamente y todas las movidas de las nuevas tecnologías si hay algo que no se puede dejar pasar es el hecho de que al parecer el futuro es la virtualización!, no obstante con lo rápido que avanza todo estas tecnologías acotan mas y mas y es en este momento que tenemos que hablar de Docker!

Docker es un proyecto de código abierto que fue lanzado inicialmente el 13 de marzo de 2013 por Solomon Hykes, implementa una API de alto nivel y gestiona contenedores con recursos aislados, estamos acostumbrados a entornos basados en VMWare, VirtualBox, Hyper-V, etc, que no están mal y que para ser sinceros funcionan bastante bien pero no dejan de requerir que se ponga en marcha un OS y sobre el mismo el respectivo servicio que deseas poner en marcha, para que os hagáis una idea, si requieren en algún momento un servidor Web trabajando con VMWare requieren poner en marcha una VM, instalar un OS Base como Debian y luego instalar Apache, Nginex o lo que necesiten, con Docker al estar basado en las funcionalidades del kernel y utilizar aislamiento de recursos y namespaces separados puedes tener un Container exclusivamente con el Apache, otro container con MySQL en el cual gestiones las bases de datos, otro como Volumen de almacenamiento en el que guardes los archivos o ficheros de la Web y se guarden las bases de datos, es decir puedes tener los servicios separados, puedes crear clústers de estos servicios y mucho mas, ademas el despliegue se realiza con tan solo un comando, a continuación os explico un poco mas en detalle.

Lo primero que tienen que saber es que Docker es multi-plataforma, es decir que pueden ponerlo en marcha tanto en Windows, Linux como en Mac OS X, su gestión y administración es a través de su propia CLI que viene cargada de un montón de funcionalidades y opciones, la verdad es que es bastante extenso así que quien quiera ampliar aquí os dejo su documentación oficial.

En mi caso las pruebas las he estado haciendo en mi ordenador de sobre mesa basado en Windows 10, con lo que el terminal que he usado es el de PowerShell aunque para ser sincero he estado tirando mas de Cmder que me ha dejado muy buen sabor de boca por todas sus funcionalidades, aquí os dejo también su web oficial por si le quieren dar un vistazo!

Lo primero que tenemos que hacer es descargar he instalar Docker de su web oficial .

Ahora que ya lo tenemos instalado, imaginemos que queremos desplegar un contenedor con UBUNTU, podemos ubicar la información del contenedor oficial de UBUNTU desde los repositorios oficiales de Docker en este caso el enlace es https://hub.docker.com/_/ubuntu/.

Importante: los caracteres “>_” son para denotar que se trata de un comando, no debes ejecutar los comandos con estos caracteres solo a partir de la palabra docker incluyendo la palabra docker.

Para descargar el contenedor solo debemos ejecutar el siguiente comando en la consola:

>_ docker pull ubuntu

Iniciara una descarga de la imagen en cuestión, puede tardar mas o menos dependiendo de nuestra conexión a Internet.

Una ves finalizada podemos verificar que la imagen se encuentra en nuestro repositorio local con el siguiente comando:

>_  docker images

Ahora podemos desplegar un contenedor usando esa imagen como repositorio local simplemente con el comando:

>_ docker run -it ubuntu

Esto desplegara el contenedor y nos dejara dentro de la Shell del UBUNTU con el que podremos interactuar a plenitud, no obstante en cuanto hagamos un exit de la consola volveremos a nuestro entorno Shell o PowerShell o el que tengamos en uso en nuestro ordenador y el Container en cuestión se detendrá y con el cualquier servicio que este corriendo en dicho Container, pero no os preocupéis, a continuación detallo un montón de opciones con las cuales podrán lanzar Containers en modo dettached y así los contenedores quedaran en funcionamiento siempre, así como el comando para salir de la consola del contenedor actual sin que este se detenga que no es mas que Ctrl-P + Ctrl-Q.

Varios comandos importantes!

Crear un contenedor dettached y definiendo un nombre:

>_ docker run -d –name NOMRE

Si queremos mapear puertos hacia el contenedor:

>_ docker run -p in:out

ej: >_ docker run -p 8080:80 apache
Explicación: este comando inicia un contenedor llamado apache y definiendo la regla de que todo el trafico que entra al 8080 vaya al 80 del contenedor.
NOTA: los contenedores han de llamarse con nombres en minúsculas.

Si usas GIT y te conectas desde la consola de GIT a un contenedor Docker con attach no te dejara con los comandos básicos, así que tienes que añadir el prefijo “winpty“, imaginemos con el contenedor con ID ae143a78a8ba

ej: >_ winpty docker attach ae143a78a8ba

Distribuir imágenes

Descripción: no es mas que la publicación de las imágenes en tu repositorio de Docker como si de GIT se tratara.

>_ #docker login

>_ docker login hub.dondocker.com #DonDocker

>_ docker login [ hub.docker.com ] #Docker (no es necesario especificar)

Ahora etiquetamos la imagen con el nombre del servicio y el usuario:

>_ #docker tag //

>_ docker tag mi-apache hub.dondocker/canonale/mi-apache

>_ docker tag mi-apache [hub.docker.com/]canonale/mi-apache

Una vez etiquetado esta imagen solo falta subirla y, si se hace como con GIT: push.

>_ #docker push //

>_ docker push hub.dondocker/canonale/mi-apache

>_ docker push [hub.docker.com/]canonale/mi-apache

Ahora solo es necesario hacer un pull para disponer de esa imagen.

Salir de un contenedor sin que se detenga:

Para realizar el detach de la consola de un contenedor Docker evitando que este se detenga tenemos que ejecutar la secuencia de comando siguiente:

Ctrl-P + Ctrl-Q (Es decir, primero hacemos CONTROL+P y luego CONTROL+Q)

Crear un nuevo direccionamiento IP para Docker:

>_ docker network create –subnet=172.16.0.0/16 myNewLan

Con –subnet asignamos el tipo de red en este caso el direccionamiento sera clase C con mascara 255.255.0.0 y al final le asignamos el nombre “myNewLan”

Lanzar un container selecionando una red y asignando una IP especifica:

>_ docker run –net myNewLan –ip 172.16.26.10 -it debian bash

Luego de esto podemos hacer un docker ps o un docker ps -a y ver de esta forma el container lanzado, haciendo un attach a dicho container y ejecutando “ip addr” podemos ver que tiene asignada la IP 172.16.26.10.

Creacion de una imagen Docker a partir de un Docker file:

Crearemos una imagen de Docker basada en Debian en su ultima versión que contara con la instalación y puesta en marcha de OpenSSH-Server y habilitaremos la contraseña password para el usuario root, para conseguir que cuando lancemos la imagen en un contenedor podamos hacer login vía SSH con PuTTy por ejemplo hemos de crear un archivo (Bash Script) dentro de un directorio que llamaremos Debian_SSHD y lo llamaremos “entrypoint.sh” y dentro de este archivo el siguiente contenido:


#!/bin/sh

# Start the ssh server
/etc/init.d/ssh restart

# Execute the CMD
exec "$@"

Ahora crearemos el Dockerfile en  el mismo directorio del Script Bash anterior.

Dentro del directorio Docker_SSHd creamos el archivo Dockerfile escrito tal cual como lo he expuesto con la D mayúsculas, y dentro añadimos el siguiente contenido:

FROM debian:latest

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
CMD ["/etc/init.d/ssh restart"]

Luego debemos acceder vía consola al directorio Docker_SSHd donde tenemos nuestro Dockerfile y ejecutar el comando que hará el build de dicha imagen:

>_ docker build -t img_sshd .

Con el punto (.) del final le decimos que ubique el Dockerfile en el directorio en el que nos encontramos.

Luego solo hay que ver la imagen que se ha generado.

>_ docker images

Y luego lanzar la imagen

>_ docker run -d –name consola sshd_img bash

La verdad es que todo el tema de Docker es para continuar y continuar con varios posts y es lo que pienso hacer mas adelante, el tema es extenso y las funcionalidades y aplicaciones muchas, así que por el momento lo dejare hasta aquí y espero que os sirva de ayuda a todos!

Hasta otra!