Kubernetes,  QNAP

Kubernetes. k0s – DRONE: Implementación de un sistema de integración continua

Uno más para la colección!

Vamos a ver que es esto de la integración continua y como siempre voy a evitar servicios externos. Vamos a instalar el Sistema de integración continua DRONE.

Drone es un sistema ci relativamente ligero. Se puede instalar en el cluster local k0s que está alojado en el NAS de QNAP. Tiene una gran comunidad que lo soporta y es posible utilizar multitud de gestores GIT, integrándose con ellos.

Voy a realizar la integración con github (sí lo se, no es local, esto para la próxima) tanto para los proyectos públicos como privados.

GitHub

La integración se describe en https://docs.drone.io/server/provider/github donde tras configurar una Aplicación OAuth2 se obtiene un:

Client ID

Secret

El servicio de DRONE se compone de un Servidor y uno o varios Runners.

Creación del servidor Drone

Para la instalación de Drone he utilizado HELM, aunque no lo he usado para la instalación como tal, sino para la creación de unos yaml de base que he ido personalizando. La creación de estas plantillas sería tal que así:

$ helm repo add community-charts https://community-charts.github.io/helm-charts
$ helm repo update
$ helm template drone community-charts/drone --output-dir .

Que genera los siguientes archivos:

Ahora bien, muchos archivos son y yo los he resumido en;

El contenido del yaml del servidor luce tal que así:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: drone-server
  labels:
    app.kubernetes.io/name: drone-server
  namespace: cicd
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: drone-server
  template:
    metadata:
      labels:
        app.kubernetes.io/name: drone-server
    spec:
      containers:
        - name: drone-server
          image: "drone/drone:2.16.0"
          ports:
            - containerPort: 3001
              protocol: TCP
          env:
            - name: DRONE_SERVER_PORT
              value: ":3001"
            - name: DRONE_GITHUB_CLIENT_ID
              value: obtenido_en_paso_anterior
            - name: DRONE_GITHUB_CLIENT_SECRET
              value: obtenido_en_paso_anterior
            - name: DRONE_RPC_SECRET
              value: obtenido a partir de $ openssl rand -hex 16
            - name: DRONE_SERVER_HOST
              value: fqdn_donde_publicas_el_servidor
            - name: DRONE_SERVER_PROTO
              value: https
            - name: DRONE_GIT_ALWAYS_AUTH
              value: "false"
          volumeMounts:
            - name: nfs-cicd-drone
              mountPath: /data
              subPath: ""

      volumes:
        - name: nfs-cicd-drone
          nfs:
            server: nfs-server
            path: /DPVs/cicd/drone
            readOnly: false

He detallado únicamente el Deploy, pero también hace falta un Servicio y un Ingress para publicarlo. Muchas de las variables no las puedo mostrar pero son fáciles de generar. Este Deploy además necesita persistencia y al igual que en otros proyectos he utilizado un Volumen configurado como nfs que tira de un recurso de la QNAP.

También de publicado sólo el Deploy para que no te valga con copiar, pegar y adaptar y te lo curres un poco más. El Servicio y el Ingress es igualito al que he publicado en otras entradas de Kubernetes.

Creación de un Drone-Runner

apiVersion: apps/v1
kind: Deployment
metadata:
  name: drone-runner
  namespace: cicd
  labels:
    app.kubernetes.io/name: drone-runner
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: drone-runner
  template:
    metadata:
      labels:
        app.kubernetes.io/name: drone-runner
    spec:
      containers:
        - name: drone-server
          image: "drone/drone-runner-kube:1.0.0-rc.2"
          ports:
            - containerPort: 3000
          env:
            - name: DRONE_RPC_SECRET
              value: el_que_has_definido_en_el_server
            - name: DRONE_RPC_HOST
              value: fqdn_donde_publicas_el_runner
            - name: DRONE_RPC_PROTO
              value: "https"

Probando el juguete

Como he creado un Namespace llamado cicd compruebo si los Pods se crean ok:

$ kubectl get all -n cicd
NAME                                READY   STATUS    RESTARTS   AGE
pod/drone-runner-75f599bfb4-8qwxv   1/1     Running   0          6m30s
pod/drone-server-55f7f88f45-ztnns   1/1     Running   0          4d15h

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/drone-runner   ClusterIP   10.96.227.111   <none>        3000/TCP   4d18h
service/drone-server   ClusterIP   10.101.96.100   <none>        3001/TCP   4d18h

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/drone-runner   1/1     1            1           4d18h
deployment.apps/drone-server   1/1     1            1           4d18h

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/drone-runner-75f599bfb4   1         1         1       6m30s
replicaset.apps/drone-server-55f7f88f45   1         1         1       4d15h


$ kubectl logs -n cicd pod/drone-server-55f7f88f45-ztnns

$ kubectl logs -n cicd pod/drone-runner-75f599bfb4-8qwxv

Parece que está todo OK, vamos entonces a entrar a la URL del server. Aparce una pantalla de bienvenida donde seleccionamos continuar y en este caso aparece el login de GitHub. El sistema de CI queda instalado en kubernetes (k0s).