Skip to content

Creación de pipeline de Desarrollo

Laboratorio: Creación de pipeline de Desarrollo

Descripción

La presente guía enseña al estudiante el proceso de creación de pipelines como código para Gitlab CI.

Objetivos

  • Crear un pipeline que corra a través de Gitlab CI.

Antes de comenzar

  • Contar con el acceso al ambiente del laboratorio

Inicio de laboratorio

  1. Acceda a la carpeta angular-demo

    cd angular-demo
    

  2. Cree una nueva rama llamada dev

    git checkout -b dev
    

  3. Borre el contenido del archivo .gitlab-ci.yml

  4. Agregue los siguientes stages al archivo .gitlab-ci.yml

    1
    2
    3
    4
    5
    stages:
      - package
      - analyze
      - build
      - deploy
    

  5. Agregue la tarea package

     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
    stages:
      - package
      - analyze
      - build
      - deploy
    
    package:
      stage: package
      image: node:14.15.5
      artifacts:
        expire_in: 2 hrs
        paths:
          - dist
      tags:
        - dev
      script:
        - |
          echo "[INFO] Verificando e instalando librerias"
          npm install
    
          echo "[INFO] Empaquetando en archivos web"
          npm run build
    
          echo "[INFO] Package Exitoso!"
          ls -l dist
    

  6. Guarde y suba los cambios

    git add .
    git commit -m "Upd ci"
    git push --set-upstream origin dev
    

  7. Revise en el portal de gitlab la ejecución del pipeline

  8. Observe los logs del Job package

  9. Agregue el Job sonar

     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
    stages:
      - package
      - analyze
      - build
      - deploy
    
    package:
      stage: package
      image: node:14.15.5
      artifacts:
        expire_in: 2 hrs
        paths:
          - dist
      tags:
        - dev
      script:
        - |
          echo "[INFO] Verificando e instalando librerias"
          npm install
    
          echo "[INFO] Empaquetando en archivos web"
          npm run build
    
          echo "[INFO] Package Exitoso!"
          ls -l dist
    
    sonar:
      stage: analyze
      image: sonarsource/sonar-scanner-cli:11.4
      tags:
        - dev
      script:
        - sonar-scanner $SONAR_ARGS
    

  10. Agregue el bloque de variables al principio del archivo

     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
    variables:
      SONAR_ARGS: "-Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectKey=some.org:${PROJECT_NAME} -Dsonar.host.url=$SONAR_URL -Dsonar.sources=. -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.exclusions=node_modules/*"
      PROJECT_NAME: "angular-demo"
      SONAR_URL: "http://sonarqube.x-x-x-x.nip.io/"
    
    stages:
      - package
      - analyze
      - build
      - deploy
    
    package:
      stage: package
      image: node:14.15.5
      artifacts:
        expire_in: 2 hrs
        paths:
          - dist
      tags:
        - dev
      script:
        - |
          echo "[INFO] Verificando e instalando librerias"
          npm install
    
          echo "[INFO] Empaquetando en archivos web"
          npm run build
    
          echo "[INFO] Package Exitoso!"
          ls -l dist
    
    sonar:
      stage: analyze
      image: sonarsource/sonar-scanner-cli:4.7
      tags:
        - dev
      script:
        - sonar-scanner $SONAR_ARGS
    

  11. En el portal de Gitlab, en su repositorio seleccione del menú izquierdo Settings > CI/CD

  12. Expanda Variables

  13. Cree una nueva variable de key SONAR_TOKEN y de valor el token generado a traves de Sonarqube, desmarcar la opción Protect variable y marque la opción Mask variable

  14. Guarde y suba los cambios locales

    git add .
    git commit -m "Add analyze jobs"
    git push
    

  15. Revise en el portal de gitlab la ejecución del pipeline

  16. Observe los logs del Job package

  17. Observe los logs del Job sonar

  18. Agregue el Job build-image

     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
    variables:
      SONAR_ARGS: "-Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectKey=some.org:${PROJECT_NAME} -Dsonar.host.url=$SONAR_URL -Dsonar.sources=. -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.exclusions=node_modules/*"
      PROJECT_NAME: "angular-demo"
      SONAR_URL: "http://sonarqube.x-x-x-x.nip.io/"
    
    stages:
      - package
      - analyze
      - build
      - deploy
    
    package:
      stage: package
      image: node:14.15.5
      artifacts:
        expire_in: 2 hrs
        paths:
          - dist
      tags:
        - dev
      script:
        - |
          echo "[INFO] Verificando e instalando librerias"
          npm install
    
          echo "[INFO] Empaquetando en archivos web"
          npm run build
    
          echo "[INFO] Package Exitoso!"
          ls -l dist
    
    sonar:
      stage: analyze
      image: sonarsource/sonar-scanner-cli:4.7
      tags:
        - dev
      script:
        - sonar-scanner $SONAR_ARGS
    
    build-image:
      stage: build
      image:
        name: gcr.io/kaniko-project/executor:debug
        entrypoint: [""]
      tags:
        - dev
      script:
        - mkdir -p /kaniko/.docker
        - echo "{\"auths\":{\"$REGISTRY_URL\":{\"username\":\"$REGISTRY_USER\",\"password\":\"$TOKEN\"}}}" > /kaniko/.docker/config.json
        - /kaniko/executor --context . --dockerfile docker/Dockerfile --destination ${REGISTRY_URL}/${REGISTRY_PROJECT}/${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA} --skip-tls-verify $KANIKO_ARGS --image-fs-extract-retry 5
        - echo ${CI_COMMIT_SHORT_SHA} > .sha-image
    

  19. En el portal de Gitlab, en su repositorio seleccione del menú izquierdo Settings > CI/CD

  20. Expanda Variables

  21. Cree las siguientes variables

    Variable Valor Mask
    REGISTRY_URL harbor.x-x-x-x.nip.io
    REGISTRY_USER pull-image
    TOKEN Pull1234
  22. Agregue las siguientes variables al archivo .gitlab-ci.yml

    1
    2
    3
    4
    5
    6
    variables:
      SONAR_ARGS: "-Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectKey=some.org:${PROJECT_NAME} -Dsonar.host.url=$SONAR_URL -Dsonar.sources=. -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.exclusions=node_modules/*"
      PROJECT_NAME: "angular-demo"
      SONAR_URL: "http://sonarqube.x-x-x-x.nip.io/"
      REGISTRY_PROJECT: "api-test"
      IMAGE_NAME: "angular-demo"
    

  23. Cree la carpeta docker

    mkdir docker
    

  24. Cree el archivo Dockerfile en la carpeta docker con el siguiente contenido

    FROM nginx:alpine
    
    COPY dist/sample-angular-app /usr/share/nginx/html
    EXPOSE 80
    
    ENTRYPOINT ["nginx", "-g", "daemon off;"]
    

  25. Guarde y suba los cambios locales

    git add .
    git commit -m "Add build jobs"
    git push
    

  26. Revise en el portal de gitlab la ejecución del pipeline

  27. Observe los logs del Job package

  28. Observe los logs del Job sonar

  29. Observe los logs del Job build-image

  30. Revise las imagenes en el proyecto de Harbor

  31. Agregue el Job apply al archivo .gitlab-ci.yml

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    apply:
      stage: deploy
      image: quay.io/itmlabs/kubectl-tools:v0.0.1
      tags:
        - dev
      script:
        - |
    
          echo "[INFO] Reemplazando variables en archivo template"
          envsubst < manifests/k8s-template.yaml > k8s-resources.yaml
    
          echo "[INFO] Recursos creados con valores substituidos"
          cat k8s-resources.yaml
    
          echo "[INFO] Desplegando aplicación"
          kubectl apply -f k8s-resources.yaml
    

  32. Cree la carpeta manifests y la subcarpeta dev

    mkdir -p manifests/dev
    

  33. Cree el archivo k8s-template.yaml en la carpeta manifests con el siguiente contenido

     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
    52
    53
    54
    55
    56
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: ${DEPLOYMENT_NAME}
      namespace: ${NAMESPACE}
      labels:
        app: ${DEPLOYMENT_NAME}
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ${DEPLOYMENT_NAME}
      template:
        metadata:
          labels:
            app: ${DEPLOYMENT_NAME}
        spec:
          imagePullSecrets:
            - name: regcred
          containers:
            - name: ${DEPLOYMENT_NAME}
              image: ${REGISTRY_URL}/${REGISTRY_PROJECT}/${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}
              ports:
                - containerPort: ${SERVICE_PORT}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ${DEPLOYMENT_NAME}-service
      namespace: ${NAMESPACE}
    spec:
      selector:
        app: ${DEPLOYMENT_NAME}
      ports:
        - name: http
          protocol: TCP
          port: ${SERVICE_PORT}
          targetPort: ${SERVICE_PORT}
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ${DEPLOYMENT_NAME}-ingress
      namespace: ${NAMESPACE}
    spec:
      rules:
      - host: "${INGRESS_HOST}"
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: ${DEPLOYMENT_NAME}-service
                port:
                  number: ${SERVICE_PORT}
    

  34. Agregue las variables al archivo .gitlab-ci.yml

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    variables:
      SONAR_ARGS: "-Dsonar.projectName=${PROJECT_NAME} -Dsonar.projectKey=some.org:${PROJECT_NAME} -Dsonar.host.url=$SONAR_URL -Dsonar.sources=. -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.exclusions=node_modules/*"
      PROJECT_NAME: "angular-demo"
      SONAR_URL: "http://sonarqube.x-x-x-x.nip.io/"
      REGISTRY_PROJECT: "apis"
      IMAGE_NAME: "angular-demo"
      DEPLOYMENT_NAME: "angular-demo"
      NAMESPACE: "userx"
      SERVICE_PORT: "80"
      INGRESS_HOST: "angular-demo.x-x-x-x.nip.io"
    

  35. En el portal de Gitlab, en su repositorio seleccione del menú izquierdo Settings > CI/CD

  36. Expanda Variables

  37. Cree la siguiente variable de tipo File

    Variable Tipo Valor Mask
    KUBECONFIG File contenido del archivo config del cluster

El contenido de esta variable lo debe de tomar del siguiente archivo que se encuentra en su laboratorio /etc/rancher/rke2/rke2.yaml El contenido deberia ser parecido al siguiente

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJlVENDQVIrZ0F3SUJBZ0lCQURBS0JnZ3Foa2pPUFFRREFqQWtNU0l3SUFZRFZRUUREQmx5YTJVeUxYTmwKY25abGNpMWpZVUF4TnpVMk1USTJNakUxTUI0WERUSTFNRGd5TlRFeU5UQXhOVm9YRFRNMU1EZ3lNekV5TlRBeApOVm93SkRFaU1DQUdBMVVFQXd3WmNtdGxNaTF6WlhKMlpYSXRZMkZBTVRjMU5qRXlOakl4TlRCWk1CTUdCeXFHClNNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJJL09FQVEwdHZWWWhMSGRnV0hxY2dzV0lNSTNONHptMFVPandtbzEKWi9NTmh4MW53RVhYa1JtTlNQVWVxMkprRS9LS1NMeTBVcmd0QmU2QTFNN2NwTDZqUWpCQU1BNEdBMVVkRHdFQgovd1FFQXdJQ3BEQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01CMEdBMVVkRGdRV0JCUkFnUjJKTVVPbUwrR2M2ckIwCnNzdzhFRHV5dnpBS0JnZ3Foa2pPUFFRREFnTklBREJGQWlCTi9zTE8ySGsrT1U5MXhHbEZUNFRWU01iZWpEOEIKUGhIKzRUUmQ0WlA0UFFJaEFQa1BxendqUTIwckxJYXk1RktHQ1hWR2VHMHhMUXl5SnVGY1ZGK1lONE5NCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://127.0.0.1:6443
  name: default
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrekNDQVRpZ0F3SUJBZ0lJZm82b2NIN2tabUl3Q2dZSUtvWkl6ajBFQXdJd0pERWlNQ0FHQTFVRUF3d1oKY210bE1pMWpiR2xsYm5RdFkyRkFNVGMxTmpFeU5qSXhOVEFlRncweU5UQTRNalV4TWpVd01UVmFGdzB5TmpBNApNalV4TWpVd01UVmFNREF4RnpBVkJnTlZCQW9URG5ONWMzUmxiVHB0WVhOMFpYSnpNUlV3RXdZRFZRUURFd3h6CmVYTjBaVzA2WVdSdGFXNHdXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBVE4wTE1tL1ozN3VPRzQKbTdwM0pqVDYwZUFZSjRheWYrQm5keU9vUms3SlFRaVFZYWpJVktSWFdXVmdMWnMybTlCV1N2UDc3bDVldFhWcwpCRUkwbHFjQW8wZ3dSakFPQmdOVkhROEJBZjhFQkFNQ0JhQXdFd1lEVlIwbEJBd3dDZ1lJS3dZQkJRVUhBd0l3Ckh3WURWUjBqQkJnd0ZvQVVrRWpEbE5lbDE4QVp0WVY2bnZRKzZVVEM3OVV3Q2dZSUtvWkl6ajBFQXdJRFNRQXcKUmdJaEFKN0FNNVQrWjd5T1Y3bzd6czBBclNmS1NNeFN3ZzhHd2Y0NEtneXFhZFZJQWlFQS9nbUhkcGVGK0tSNwovQmovT3ArVG5WUjdRZlcvR056VW5lYVBBL1IyT3ZJPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlCZVRDQ0FSK2dBd0lCQWdJQkFEQUtCZ2dxaGtqT1BRUURBakFrTVNJd0lBWURWUVFEREJseWEyVXlMV05zCmFXVnVkQzFqWVVBeE56VTJNVEkyTWpFMU1CNFhEVEkxTURneU5URXlOVEF4TlZvWERUTTFNRGd5TXpFeU5UQXgKTlZvd0pERWlNQ0FHQTFVRUF3d1pjbXRsTWkxamJHbGxiblF0WTJGQU1UYzFOakV5TmpJeE5UQlpNQk1HQnlxRwpTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCRFMyRHB1eDFYRWM1R2Rna2xSZkIwWTNvRlIrN3VlZDgyRFN5L3g3Cno2MVVpWDF6MmIzTmd4d2E2SFV4UmRNN21JV1BKMGhzWGw3TDFwKzUwTkptTlhDalFqQkFNQTRHQTFVZER3RUIKL3dRRUF3SUNwREFQQmdOVkhSTUJBZjhFQlRBREFRSC9NQjBHQTFVZERnUVdCQlNRU01PVTE2WFh3Qm0xaFhxZQo5RDdwUk1MdjFUQUtCZ2dxaGtqT1BRUURBZ05JQURCRkFpQkErU0xneHFqUXN2K0I0VE5QaHNtdlBCa3ZyM21PCnJkSVdLdjVPR2xTUXRRSWhBSnNMVnVPd3B1MUdTT3EzVGcrMS9PK3g0Q0JpRzUvbWZ3WFplWTNuVVd4QQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
    client-key-data: LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSU8yYm94RG9GM2lleDY3WnpWK2FMQTUwWFpudGt1WDJDL3kyREtUdnRZTW9vQW9HQ0NxR1NNNDkKQXdFSG9VUURRZ0FFemRDekp2MmQrN2podUp1NmR5WTArdEhnR0NlR3NuL2daM2NqcUVaT3lVRUlrR0dveUZTawpWMWxsWUMyYk5wdlFWa3J6Kys1ZVhyVjFiQVJDTkphbkFBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=
Asegurese de cambiar la parte de server que apunta a 127.0.0.1:6443 a la ip de su maquina de laboratorio siempre en el puerto 6443

  1. Guarde y suba los cambios locales

    git add .
    git commit -m "Add deploy jobs"
    git push
    

  2. Revise en el portal de gitlab la ejecución del pipeline

  3. Observe los logs del Job package

  4. Observe los logs del Job sonar

  5. Observe los logs del Job build-image

  6. Revise las imagenes en el proyecto de Harbor

  7. Revise los logs del Job apply

  8. Revise los recursos creados en el cluster

    kubectl get deploy,pods,svc,ingress -n userx
    

  9. Cree un nuevo pull secret en su namespace de userx

    kubectl create secret docker-registry regcred \
      --docker-server=harbor.xx-xx-xx.nip.io \
      --docker-username=pull-image \
      --docker-password=Pull1234 \
      --docker-email=micorreo@example.com \
      -n userx