Recargar imagen en kubernets de nuevo push en bitbucket usando jenkins

by Josep Llauradó Selvas


Posted on 2020-11-24


En este artículo detallaremos los pasos para recargar una imagen docker en Kubernetes a partir de un push en un repositorio bitbucket usando Jenkins. Es un proceso completo que requiere un montón de pequeñas configuraciones que intentaré ir explicando poco a poco para que sea los más facil posible.

Para ello deberíamos contar con un clúster Kubernetes funcionando, así como un Jenkins configurado y enlazado con Bitbucket. Si necesitas información sobre cómo conseguir esta configuración base te recomiendo otros artículos, disponibles en el blog, y que te ayudaran en estos pasos.

 

Proceso actual

En nuestra organización trabajamos siempre con 3 entornos mínimo:  dev, test y producción. El proceso es desarrollar usando un Docker desktop para validar nuevos desarrollos. 

Si el código es correcto, lo pasamos a un entorno de test haciendo merge entre la rama de DEV con la de TEST. A continuación nos conectaremos a nuestra máquina de test y con un pull actualizaremos el código de la misma, validando que todo es correcto. Ahí podemos entrar en un ciclo de merges entre DEV y TEST hasta que todo el funcionamiento nos cuadra y las integraciones funcionan bien.

Si finalmente vemos que las pruebas en TEST han funcionado haremos el merge con producción y volveremos a realizar el proceso de pull: Nos conectaremos a la maquina de producción, nos bajaremos el código, y limpiaremos caches para finalizar el proceso validando que todo es correcto.

Los principales inconvenientes que tenemos ahora mismo con este proceso son los siguientes:

  • A veces el código no se comporta igual en test y en prod: Pequeñas diferencias en componentes, por ejemplo
  • El deployment a producción puede provocar paradas más largas de lo esperado
  • El proceso require múltiples pasos en diferentes maquinas: ssh, git pulls, …

Deployment usando Kubernetes-Jenkins-Bitbucket

Así pues nuestro proceso ideal sería el siguiente:

  1. Realizaremos un nuevo desarrollo, probándolo de forma local mediante Docker Desktop.
  2. Subiremos el código a Bitbucket, que desencadenará los siguientes pasos
  3. Jenkins recibirá el aviso de nuevo push en Bitbucket e iniciará la compilación de nueva imagen
  4. Si el proceso es correcto subirá la imagen a un repositorio local Docker local
  5. A continuación se dará la instruccion al cluster Kubernetes de que recargue los pods correspondientes

Ahora iremos explicando poco a poco los pasos…

Dockerfile

El primer punto importante es disponer de un dockerfile que sea capaz de generar una imagen ‘test’ valida sin intervención por nuestra parte. Os paso uno de nuestros ejemplos para que os hagais a la idea:

FROM php:7.3-apache

ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

RUN apt-get update && \
    apt-get install -y --no-install-recommends git zip unzip bzip2 coreutils mariadb-client vim iputils-ping libldap2-dev libxml2-dev
RUN docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \
    docker-php-ext-install pdo pdo_mysql mysqli ldap soap
RUN a2enmod rewrite

WORKDIR /
RUN curl --silent --show-error https://getcomposer.org/installer | php
RUN mv /composer.phar /usr/local/bin/composer

RUN ln -s /etc/apache2/mods-available/ssl.load  /etc/apache2/mods-enabled/ssl.load
COPY docker/web-default.conf /etc/apache2/sites-enabled/001-default.conf
COPY docker/test/_.domain.com.key /etc/apache2/ssl/ssl.key
COPY docker/test/_.domain.com.crt /etc/apache2/ssl/ssl.crt

#
#
# Symfony config
#
#
WORKDIR /var/www/html
RUN git clone http://jenkins:privatepass@jenkins.domain.com:7990/bitbucket/scm/wm/sapwm2.git origin && \
    mv origin/.git ./ && \
    git checkout test
COPY docker/test/init/.env docker/test/init/.env.test /var/www/html/
RUN yes | composer update && \
    chmod a+x bin/console 
COPY docker/test/init/.htaccess /var/www/html/public

En este caso partimos de una imagen PHP-7.3 con Apache para despues habilitar el SSL instalando los certificados de la maquina de test. Finalmente realizaremos el clone del código, copiaremos los ficheros de configuración (en este ejemplo para Symfony), y realizaremos la instalación desasistida.

Aquí fijaos 2 cosas relevantes:

  1. Hemos creado una carpeta docker con la configuración y dentro de ella una segunda llamada test para poder personalizar algunos ficheros para el entorno de test.
  2. Este Dockerfile es hermano de un segundo, mas simplificado, que usamos para nuestro Docker Desktop, y que usamos como nuestro entorno DEV.

Jenkins

Disponiendo ya de nuestro Jenkins, crearemos una tarea tipo ‘Freestyle’, en la que conectaremos con nuestro proyecto y repositorio Bitbucket. A continuación añadiremos una tarea en Build con el siguiente código:

docker build --no-cache -t sapwm2_web:1.${BUILD_NUMBER} -f docker/test/Dockerfile-web .

docker tag sapwm2_web:1.${BUILD_NUMBER} sapwm2_web:latest

docker tag sapwm2_web:1.${BUILD_NUMBER} "docker-repo.domain.com:5000/sapwm2_web":test
docker tag sapwm2_web:1.${BUILD_NUMBER} "docker-repo.domain.com:5000/sapwm2_web":1.${BUILD_NUMBER}

docker push "docker-repo.domain.com:5000/sapwm2_web":test
docker push "docker-repo.domain.com:5000/sapwm2_web":1.${BUILD_NUMBER}

docker images

El significado de cada paso es el siguiente:

  1. Compilaremos una nueva imagen usando como Dockerfile el que hemos preparado anteriormente
  2. Taguearemos la misma con el numero de versión de compilación de Jenkins, y también con el tag ‘test’
  3. También la taguearemos para nuestro servidor ‘Docker repository’, con el build de Jenkins y con test
  4. Finalmente mostraremos las imágenes para poderlo ver en los logs

Finalmente ejecutaremos un nuevo paso de build, tambien tipo shell, con el comando:

kubectl -n default rollout restart deployment sapwm2web --kubeconfig /var/lib/jenkins/.kube-admin.conf

Que se encargará de relanzar el deployment de nuestra parte web. 

Listos! solo tenemos que hacer un push a la rama test para que en un minuto aparezcan refrescados los servers de test!

 

homepage
Leave a Comment:


BeyondBlueSky - 2019

Website developed using Symfony 5, Bootstrap 4 and Open Iconic