Autor:
En primer lugar, quiero dejar claro que no soy un experto en DevOps. Aún así, espero que esto les sea útil. Esta guía se basa principalmente en el curso Implementing a Full CI/CD Pipeline dictado por William Boyd en Linux Academy.
La idea general de este procedimiento es mostrar cómo configurar un canal de CI / CD que conecte su código fuente con su respectivo deployment, lo que significa que cada vez que haga push del código en un repositorio de GitHub, se iniciará una nueva compilación con la última versión de su código y se desplegará en un cluster de Kubernetes. Si ha usado Heroku, el resultado final le podrá resultar bastante familiar. Como es de esperarse, no tendremos un deployment actualizado en “tiempo real”, de hecho, todo el proceso de build y deployment puede demorar unos 4 minutos o más desde el momento en que se envía el código a github, lo cual puede variar según tamaño de su aplicación node.js.
Si bien hay servicios administrados como Google App Engine que facilitan las implementaciones (deployments), nunca está de más expandir su campo de visión e incluir tecnologías modernas como la containerizacion y la orquestación de contenedores.
Por cierto, usaré Google Cloud Platform (GCP), pero este procedimiento definitivamente debería funcionar con el proveedor que cada quien prefiera, así que siéntase libre de desviarse y explorar, y sí, la prueba gratuita de GCP es suficiente para lo que haremos en esta guía.
Para este tutorial necesitará.
Es deseable tener comprensión básica de sistemas Kubernetes y Linux, pero no es indispensable. Para seguir este tutorial es necesario activar la prueba gratuita de GCP, o tener una tarjeta de crédito asociada a su cuenta de GCP para cubrir los gastos de las VM que ejecutaremos.
Empezaremos por crear y configurar las máquinas virtuales VM que alojarán nuestro cluster de Kubernetes y servidor de Jenkins.
1. Una vez que estés en Google Cloud Console, pasa el cursor sobre el ícono del triple igual en la esquina superior izquierda y vaya a Compute Engine > VM instances
Aquí necesitamos crear.
1 cluster de Kubernetes
1 VM con Jenkins, Docker y GIT.
Nota: un clúster GKE no funcionará ya que no podemos comunicarnos directamente con API server de kubernetes.
Sin embargo, podemos implementar un clúster Kubernetes fácilmente mediante la creación de una máquina virtual llamada Bitnami’s Certified Kubernetes Sandbox .
En el menú principal de Google Compute Engine, haga clic en Create VM, vaya a la opción Marketplace y busque “Kubernetes”, la imagen de Bitnami debería aparecer dentro de los resultados de la búsqueda.
Haga clic en ella y luego en el botón Launch on Compute Engine.
En la descripción general de esta máquina virtual, puede ver que contiene Kubectl, Kubeadm y Kubelet, así como cri-contenererd.
Desplácese hacia abajo y haga clic en deploy para implementar esta máquina virtual en su proyecto GCP. Después de que su VM se haya creado con éxito, espere 5 minutos más, mientras que los scripts de Bitnami inician el Cluster de Kubernetes, en el panel de información general de la VM puede ver el progreso de estas tareas.
Una vez completadas esas tareas, vuelva a la página principal de Google Compute Engine y entre a su nueva VM por medio de SSH.
Ahora debería poder comunicarse con su clúster Kubernetes mediante el comando Kubectl.
Ejecute
Kubectl get nodes
El resultado es una lista de los nodos conforman este clúster y su estado; en este caso, solo tengo un nodo que funciona como Master y worker, lo cual es suficiente para el propósito de esta guia.
Ahora vamos a enfocarnos en la implementación continua (CD) del proyecto. Vamos a necesitar otra máquina virtual con Jenkins, Dockerb y Git.
Para eso, solo voy a crear una nueva instancia en GCE, si está siguiendo este procedimiento puede usar su distro de linux favorita, yo usaré CentOS 7, al momento de crear esta VM asegúrese de habilitar el tráfico mediante HTTP y HTTPS.
En primer lugar, es necesario tener java instalado en la máquina virtual, pero esta distribución específica de CentOS no tiene java preinstalado, así que instalaré java 1.8.0 OpenJDK y el paquete wget que necesitaremos más adelante. Lo anterior usando los comandos.
sudo yum install -y java-1.8.0-openjdksudo yum install -y wget
Y ahora Jenkins:
curl --silent --location http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo | sudo tee /etc/yum.repos.d/jenkins.reposudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.keysudo yum install -y jenkinssudo systemctl enable jenkinssudo systemctl start jenkins
Con esos comandos, agregamos el repositorio de Jenkins e importamos la key necesaria para al mismo, lo instalamos jenkins, habilitamos el servicio de Jenkins para asegurarnos de que se ejecutará cada vez que iniciemos esta VM, y finalmente inicializamos dicho servicio.
El servicio Jenkins ya debería estar funcionando.
Ejecuta este comando para verificar:
sudo tail -f /var/log/jenkins/jenkins.log
Ahora instalaremos Docker:
sudo yum update && sudo yum -y install yum-utils device-mapper-persistent-data lvm2sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.reposudo yum install -y docker-cesudo systemctl start dockersudo systemctl enable docker
Con docker instalado y funcionando podemos usar este Comando para verificar su correcto funcionamiento:
sudo docker run hello-world
Más adelante necesitaremos que jenkins pueda ejecutar comandos de docker, por lo que necesitamos agregar el usuario jenkins al grupo docker ejecutando:
sudo gpasswd -a jenkins docker
En caso de que el grupo docker no exista todavía podemos agregarlo escuchando este comando:
sudo groupadd docker
Ahora instalaremos git:
sudo yum install -y git
Con Jenkins corriendo necesitamos Ingresar a su interfaz web, la cual se encuentra en el puerto 8080. Para eso tenemos dos opciones. La primera es habilitar un cortafuegos de Google Cloud platform que nos permita Ingresar a dicho puerto. La segunda es redireccionar el tráfico entrante y saliente del puerto 80 hacia el puerto 8080. En mi caso usaré la segunda opción ejecutando el siguiente comando:
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp — dport 80 -j REDIRECT — to-port 8080
Ahora si navegamos desde nuestro navegador a la dirección IP externa de la máquina virtual de Jenkins, veremos una pantalla de bienvenida similar a esta:
2. Nuevamente en la sesión ssh de la máquina virtual de Jenkins ejecutamos:
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Esto nos devolverá el password temporal de acceso de administrador, lo copiamos y pegamos en la interfaz web de jenkins:
Click en continuar
Una vez hayamos ingresado se nos preguntará si deseamos instalar varias extensiones, aceptamos y luego podremos crear una cuenta de administrador de jenkins.
Al finalizar, vará una pantalla similar a la siguiente.
¡Felicitaciones, ya tiene Jenkins instalado y configurado!
Lo primero será instalar el plugin de integración continua de kubernetes para eso vamos al panel que hay a mano izquierda y seleccionamos la opción que dice manage Jenkins y luego a manage plugins allí iremos a la pestaña que dice available y buscamos Kubernetes.
Entre los resultados de búsqueda aparecerá un plugin llamado kubernetes continuous deployment.
Lo instalamos y reiniciamos jenkins.
Una vez que Jenkins reiniciado y hemos iniciado sesión nuevamente iremos al panel izquierdo y seleccionaremos credentials > global > add credentials
Primero ingresaremos las credenciales de docker hub para eso seleccionamos usuario y contraseña en el campo kind y llenamos los campos correspondientes. En el campo ID es muy importante ingresar, docker_hub_login , y que luego nos referiremos a estas credenciales por medio de ése ID.
Para finalizar, hacer click en save.
Hacemos click nuevamente en add credentials.
Para github es un poco diferente ya que necesitaremos un Access token. En github.com vamos al avatar arriba en la derecha y seleccionamos select settings> developer settings y generamos un nuevo token con cualquier nombre y habilitamos admin:repo_hook.
Al hacer clic en generar podemos ver el token lo copiamos y pegamos en el campo de contraseña en el formulario de credenciales de jenkins, necesitaremos el token más adelante. El nombre de usuario será nuestro usuario de github. En el campo ID digitamos github_key y guardamos
Haremos click en add credentials una vez más y en kind seleccionamos kubernetes configuration el ID que asignaremos es kubeconfig y seleccionamos la opción enter directly aparecerá un campo de texto donde debemos ingresar el archivo kubeconfig de nuestro cluster de kubernetes.
Para obtener este archivo nuevamente a Google compute engine ingresamos mediante ssh a la máquina virtual donde tenemos el cluster de kubernetes.
Ingresaremos uno de estos dos comandos para obtener el archivo kubeconfig:
sudo cat ~/.kube/config
O en su defecto:
sudo cat /etc/kubernetes/admin.conf En caso de que el primer Comando no funcione
Una vez veamos el contenido del archivo en la terminal lo copiamos todo asegurándonos de no es por fuera ningún carácter ya que hacerlo invalidaría totalmente el archivo kubeconfig. Y lo pegamos en la caja de texto de las credenciales de kubernetes.
Guardamos.
Finalmente vamos a la pantalla principal de jenkins y seleccionamos las opciones manage Jenkins y luego configure system
Bajamos hasta ver la sección github server, haga clic add github server > github server.
Le asignamos un nombre cualquiera y en el campo API URL escribimos https://api.github.com
Secret text aparecerá un campo llamado secret donde debemos ingresar el token de acceso de github. Le asignamos un ID de github_secret y terminamos haciendo click en Add
Ahora github_secret aparecerá entre las opciones del menú desplegable de credenciales de github, lo seleccionamos y activamos la casilla manage webhooks
De esta forma todo estará listo para iniciar un pipeline de jenkins.
3. Si desea seguir este procedimiento primero será necesario crear un fork de este proyecto de github https://github.com/FelipeLujan/gradle-test. Una vez tenga su fork propio, verá que en la raíz del proyecto hay un archivo llamado Jenkinsfile, modifique la linea 5 de este archivo y cambie “felipelujan” por su usuario de dockerhub. Este archivo es sumamente importante, más adelante explicaremos su función.
También mientras se encuentra en su fork de github.
Vaya a la opcion settings:
En el panel del lado izquierdo será una opción que dice webhooks selecciónela y luego seleccione add webhook:
En el campo payload URL ingrese la dirección ip externa de su servidor de jenkins seguido de /github-webhook/, también modifique el campo content type tal como aparece en la imagen:
De esta manera github podrá comunicarse con jenkins cuando haya nuevo código en el repositorio.
Finalmente podremos configurar el pipeline que se encargará de obtener compilar y desplegar el proyecto de github de manera automática, para ello vamos a la pantalla principal de jenkins y seleccionamos new item.
Ingrese un nombre cualquiera y seleccione multibranch pipeline, haga clic en ok.
En branch sources haga click en add source > GitHub. Aparecerá el siguiente formulario.
En credentials seleccione github_key.
En owner, ingrese su nombre de usuario de github.
El menú desplegable siguiente se llenará automáticamente con los proyectos que tenga en su cuenta de github, allí seleccione el fork del proyecto que estamos usando.
Y en el campo behaviors, seleccione exclude branches with PRs.
Haga clic en guardar.
4. Con esto el pipeline de jenkins ya estará completo.
Para ver las tareas que se están ejecutando haga clic en el nombre del pipeline que se encuentra en la parte superior izquierda de la pantalla.
al hacerlo aparecerá una tabla con las ramas presentes en el repositorio al que ha hecho fork recientemente.
Si no ha creado ninguna otra rama solamente estará la rama Master haga allí aquí para ver los procesos descritos en el Jenkinsfile.