Post-Image

Automatiza el despliegue de tu web con Jenkins, Github y Kubernetes

Actualmente el proceso de creación y mantenimiento de un proyecto web puede ser una tarea tediosa, sin embargo, si pensamos como vamos a mantener un proyecto sin necesidad de grandes esfuerzos nos viene a la menta la automatización de las partes que no requieran de supervisión, es decir, todo lo relativo a la creación y publicación de la web del proyecto de Github.

En primer lugar tener claro como queremos publicar nuestra web, el proyecto que vamos a utilizar para este ejemplo es https://github.com/alefnode/jenkins-themes como veis he separado la web al directorio webpage que es donde tendremos toda la web a excepción de aquellas que se generan en el job de Jenkins.

Por otro lado he definido la carpeta container que es donde vamos a agregar todos los ficheros que conforman el container y el despliegue en kubernetes.

Para entender que es lo que vamos a hacer debemos entender que es lo que hace el Containerfile en este caso este es un sencillo fichero que instala Nginx y copia los ficheros necesarios para la web, de tal forma que si destruimos, o por un momento falla, la web es tan sencillo como destruirlo y recrearlo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
FROM registry.alefnode.com/centos:8
MAINTAINER Alenode <adriancampos@teachelp.com>

RUN yum -y install nginx && \
    yum clean all && \
    mkdir -p /var/www/html

RUN mkdir -p /var/www/html/images && \
    mkdir -p /var/www/html/dist

COPY ./container/nginx.conf /etc/nginx/nginx.conf
COPY ./images/* /var/www/html/images/
COPY ./webpage/* /var/www/html/
COPY ./dist/* /var/www/html/dist/

EXPOSE 80

CMD ["nginx","-g","daemon off;"]

Este es la imagen que va a desplegar el despliegue sobre Kubernetes, pero para entender esta parte revisemos el fichero que ejecuta esta acción:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins-themes-alefnode-deployment
  labels:
    app: jenkins-themes-alefnode
spec:
  replicas: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 25%
  selector:
    matchLabels:
      app: jenkins-themes-alefnode
  template:
    metadata:
      labels:
        app: jenkins-themes-alefnode
    spec:
      containers:
      - name: jenkins-themes-alefnode
        image: registry.alefnode.com/jenkins-themes-alefnode:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
          successThreshold: 1
      imagePullSecrets:
      - name: regcred

---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-themes-alefnode-service
spec:
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30194
  selector:
    app: jenkins-themes-alefnode

Este fichero realiza dos acciones, por un lado, define y despliega la imagen que creamos anteriormente, y por otro, crea el servicio a través del cual vamos a poder ver nuestra web. Una parte importante a revisar es la estrategia rollingupdate ya que es la que nos permite tener zero-downtime a la hora de realizar una actualización.

Ahora vamos a configurar nuestro ejecutor y la integración automática con Github. Creamos en Jenkins nuestro job que configuramos de tal forma que use nuestro proyecto. jenkins-themes configuración 001

Y lo configuramos con los siguientes steps: jenkins-themes configuración 002

1
2
3
4
5
6
npm install
node_modules/grunt/bin/grunt --force
for i in $(docker image ls -qa); do docker rmi -f "$i"; done
docker build -t jenkins-themes-alefnode -f ./container/Containerfile . && docker tag jenkins-themes-alefnode:latest registry.alefnode.com/jenkins-themes-alefnode:latest && docker push registry.alefnode.com/jenkins-themes-alefnode:latest
kubectl apply -f ./container/kube-jenkins-themes-alefnode.yml
kubectl rollout restart deployment/jenkins-themes-alefnode-deployment

Como se puede observar los dos primeros pasos hacen referencia directamente a la compilación del código de nuestro proyecto y luego lo que hacemos es crear el contenedor y desplegarlo, se puede observar que antes de la creación del contenedor lo que hacemos es limpiar todo nuestro nodo, esto lo hacemos para no dejar lleno de imágenes nuestro esclavo de Jenkins (probablemente esto no es lo mejor ya que ralentiza bastante la operación, pero prefiero mantenerlo lo más limpio posible)

Para conectar nuestro proyecto de Github con nuestro Jenkins vamos a utlizar el plugin llamado generic-webhook-trigger una vez instalado necesitamos realizar la configuración. Nos vamos a la configuración de nuestro job y procedemos con la configuración. jenkins-themes configuración 003

Mientras que en nuestro proyecto de Github debemos configurarlo tal y como os muestro en la imagen. jenkins-themes configuración 004

Una parte muy importante es definir un token seguro para evitar que alguien ajeno realice ejecuciones sin permiso.

El resultado final de este proyecto lo podéis ver en https://jenkins-themes.alefnode.com y cualquier sugerencia o mejora es bien recibida.