viernes, 4 de diciembre de 2020

Skopeo como Agente de Jenkins dentro de OpenShift 4.X

 

 
        En una cultura DevOps es normal desarrollar pipelines de Integración Continua o Despliegue Continuo, y sobre todo cuando esta actividad es llevada a cabo en un cluster OpenShift. En este escenario entren en juego varios componentes, siendo las imágenes docker una de las principales.
         Aqui surge, como en la mayoría de casos, realizar en una etapa del pipeline de CI/CD lo que se le conoce como Promover la Imágen. Que es guardar una copia de la misma en una registry (local o externa). Y para realizar esto de una manera sencilla y dinamica, podemos hacer uso de Skopeo. Una herramientaque ofrece un potencial increible para trabajar con imágenes docker.
  

Skopeo
  
        Skopeo es una utilidad de línea de comandos que puede realizar varias operaciones en imágenes de contenedores y en repositorios de imágenes (registry). No requiere que se ejecute como root (con permisos de administrador) para realizar la mayoría de sus operaciones. No requiere que se esté ejecutando un demonio para realizar sus operaciones. Y puede trabajar tanto con imágenes OCI así como con las imágenes originales de Docker v2.
   
Pueden encontrar más información en su repositorio en GitHub, donde podrán ver que comandos se pueden utilizar y que opciones admiten los mismos para acometer con nuestras necesidades:
  

¿Como generar el agente para Jenkins?
  
        Para utilizar skopeo en jenkins como agente dentro de OpenShift 4.X debemos llevar a cabo una serie de pasos. Lo cuales se desarrollan a continuación:
  
1. Buildear la Imagen
 
        Necesitamos construir una imagen que actúe como un esclavo de jenkins y que contenga la CLI de skopeo. Para ello, desde una consola de linea de comandos, iniciamos sesión en el cluster de OpenShift como system:admin y ejecutamos los siguientes comandos:
oc import-image ose-jenkins-agent-base --confirm --from=registry.redhat.io/openshift4/ose-jenkins-agent-base -n openshift

oc create is skopeo -n openshift

oc create -f ./skopeo-bc.yaml -n openshift

oc start-build skopeo -n openshift --wait

oc tag openshift/skopeo:latest skopeo:latest -n jenkins

oc label is skopeo role=jenkins-slave -n jenkins

 
  
        A continuación el contenido del archivo YAML para crear el BuildConfig de Skopeo:
apiVersion: v1
kind: BuildConfig
metadata:
  name: skopeo
spec:
  output:
    to:
      kind: ImageStreamTag
      name: skopeo:latest
  runPolicy: Serial
  type: Docker
  source:
    dockerfile: |-
      FROM registry.redhat.io/openshift4/ose-jenkins-agent-base

      USER root

      RUN export http_proxy=url.com:80 && \
          export https_proxy=url.com:80 && \ curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/CentOS_8/devel:kubic:libcontainers:stable.repo           dnf -y install skopeo USER 1001
strategy: dockerStrategy: from: kind: ImageStreamTag name: ose-jenkins-agent-base:latest
  
        Con estos pasos, ya tendremos una imagen armada de un slave de jenkins que cuenta con skopeo dentro.
 
 
Manejo de proxies
        Tenga en cuenta que el Dockerfile de Red Hat Enterprise Linux (RHEL) anula cualquier proxy que puedan estar configurados en los valores predeterminados de la build, ya que pueden interferir con las comunicaciones JNLP del servicio jnlp de jenkins.
   
ENV HTTP_PROXY='' http_proxy='' HTTPS_PROXY='' https_proxy='' NO_PROXY='' no_proxy=''
 
 
2. Usar el Agente dentro de Jenkins
    
        Para tener todo listo, es necesario indicarle a Jenkins como debe construirse el agente cuando sea llamado. Es decir, que imagen docker usará, labels, umbrales de timeout, entre otros.
 
        Para esto, desde la consola web de Jenkins debemos dirigirnos a la sección Cloud y configurar alli el agente. Entonces:
  
    1. Iniciar sesión en Jenkins
    2. Haga clic en Administrar Jenkins y luego en Configurar el sistema
    3. En la sección Cloud haga clic en enlace para abrir la pagina del plugin
    4. Configure el agende de skopeo con los siguientes valores:
  • Name: skopeo
  • Labels: skopeo
  • Usage: dejar este nodo para ejecutar sólamente tareas vinculadas a él
    Utilizando la herramienta de linea de comandos OC, ejecute el siguiente comando:
oc get is skopeo -n jenkins --template='{{ .status.dockerImageRepository }}'
     Arrojará un valor similar al usado en la propiedad Docker Image en el punto siguiente.
 
    5. Añadir un template de contenedor con los siguientes valores: 
  • Name: jnlp
  • Docker Image: image-registry.openshift-image-registry.svc:5000/jenkins/skopeo
  • Always pull image: [✓]
  • Working Directory: /tmp
  • Arguments to pass to the command: ${computer.jnlpmac} ${computer.name}
 
     6. Haga clic en Save para guardar los cambios.



        Con estos pasos ya tendremos configurado un agente de skopeo dentro de jenkins, que podremos utilizar para nuestros pipelines de integración continua.




Ejemplo de un pipeline

        Para usar entonces skopeo dentro de un pipeline, podremos hacerlo de la siguiente manera:
stage("Promote Image") {
    agent {
        label "skopeo"
    }
    steps {
        script {
            def srcToken = "ACCESSTOKEN000000000000000000001";
            def dstCreds = "USER:PASSWORD";

            def src = "docker://docker.io/user/testimage:latest";
            def dst = "docker://quay.io/organization1/my-prod-image:latest";

            sh """ skopeo copy --src-tls-verify=false \
                        --dest-tls-verify=false \
                        --src-registry-token=${
srcToken} \
                        --dest-creds=${dstCreds} \
                        ${src} ${dst}";
} } }
   
        De esta manera, cada vez que el pipeline de Jenkins se ejecute lo que ocurrirá es que gracias al agente que configuramos, se creará un nuevo pod utilziando la imagen que construimos con skopeo dentro y ejecutará el comando especificado (en este caso, para copiar una imagen de un registry a otro registry).

      Skopeo permite realizar multiples operaciones, como sincronizar un repositorio, o inspeccionar (ver la metadata) de una imagen, entre otras más. Y cada una de estas operaciones pueden personalizarse con opciones como utilizar credenciales de acceso (usuario y contraseña) o utilizar tokens, o deshabilitar que verifique TLS en la conexion que realiza, etc.
 
        Skopeo nos puede resultar una herramienta muy potente para obtener pipelines mas simples y robustos. Cualquier comentario o consulta puede debatirse libremente y con respeto en los comentarios de este articulo.



4 comentarios:

  1. Muy bueno, tienes alguna experiencia de crear un Agent con docker para construir imagenes docker desde Jenkins? o algun metodo para construir imagenes docker desde Jenkins que esta sobre OCP 4?

    ResponderEliminar
    Respuestas
    1. Hola si, es importante destacar en donde esta Jenkins instalado... Lo que te puedo comentar es que si Jenkins esta instalado dentro de OCP 4 simplemente con codigo groovy puedes lanzar la ejecución de BuildConfigs que construyan las imagenes por tí. De lo contrario, tengas jenkins afuera de OCP 4... ahi te toca instalar los plugins de openshift-sync, openshift-client y openshift-login para que tu jenkins tenga la habilidad de abrir agentes (en forma de pods) dentro de tu cluster OpenShift. Para esto accede a la configuración cloud dentro de tu Jenkins (la URL se vera algo asi: https://jenkins-url.com/configureClouds/) y aqui te tocará configurar un agente de la siguiente manera:
      Haces clic en "Agregar Pod Template" y lo llenas con la siguiente informacion:
      * Name: nombre-del-agente
      * Labels: label-del-agente
      * Usage: Dejar este nodo para tareas vinculadas a él
      * Containers.Name: jnlp
      * Containers.Docker image: image-registry.openshift-image-registry.svc:5000/tu-proyecto/imagen-docker-del-agente
      * Containers.Always pull image: true (marcar checkbox)
      * Containers.Working directory: /tmp
      * Containers.Arguments to pass to the command: ${computer.jnlpmac} ${computer.name}
      * Pod Retention: Default
      * Timeout in seconds for Jenkins connection: 100
      * Yaml merge strategy: Override
      * Show raw yaml in console: true
      * Service Account: jenkins
      * Workspace Volume: Empty Dir Workspace Volume

      Tambien aprovecho para dejarte un repo git que tengo donde puedes sacar ideas para contruir tus pipelines: https://github.com/lozanotux/openshift-cicd-pipelines

      Fijate en la carpeta /vars. Espero haberte ayudado, Saludos!

      Eliminar
    2. Gracias por tu respuesta, antes de leerla habia encontrado este repositorio donde tienen algo parecido a tu repo, pero esta se podia incluir en el Jenkinsfile o Jenkins de manera sencilla https://github.com/redhat-cop/pipeline-library. Tu repo esta muy bueno lo estare revisando para algunos casos de uso que tengo gracias.

      Eliminar