Desplegar app en Okteto con Gitlab CI II

Desplegar app en Okteto con Gitlab CI II

En este tutorial nos enfocaremos en realizar un pequeño refactor y añadir unos nuevos jobs de cara al siguiente tutorial.

Aquí os dejo los objetivos que abordaremos:

  • Buildear con Kaniko y subir la imagen a Docker Hub.
  • Agregar GitGuardian para detectar contraseñas y token.
  • Analizar imagen con Trivy.
  • Analizaremos con Kube-linter los manifiestos de kubernetes.
  • Integrar Sonar para buscar vulnerabilidades.
  • Redefinir flujo de CI.

Como siempre aquí os dejo el repositorio que usaremos.

Daniel J. Saldaña / app-okteto · GitLab

Recordamos que el tutorial lo podrá encontrar en la rama main, ya que verá que actualmente existen más ramas, las cuales están enfocadas en los siguientes labs.

gitlab-ci.yml
stages:
- test
- scanning
- review
- build
- production
variables:
IMAGE_GITGUARDIAN: gitguardian/ggshield:latest
IMAGE_DOCKER: docker:stable
IMAGE_KANIKO: gcr.io/kaniko-project/executor:v1.9.0-debug
IMAGE_SONAR: sonarsource/sonar-scanner-cli:latest
IMAGE_OKTETO: okteto/okteto:1.13.4
IMAGE_HELM: alpine/helm
kubelinter:
stage: test
image: $IMAGE_DOCKER
services:
- docker:dind
script:
- docker run -v $PWD/charts:/dir -v $PWD/lint/config.yaml:/etc/config.yaml stackrox/kube-linter lint /dir --config /etc/config.yaml
only:
- branches
except:
- main
sonarcloud-check:
stage: test
image:
name: $IMAGE_SONAR
variables:
SONAR_USER_HOME: '${CI_PROJECT_DIR}/.sonar'
GIT_DEPTH: '0'
cache:
key: '${CI_JOB_NAME}'
paths:
- .sonar/cache
script:
- sonar-scanner
only:
- branches
except:
- main
gitguardian:
stage: scanning
needs:
- kubelinter
- sonarcloud-check
image:
name: $IMAGE_GITGUARDIAN
script:
- ggshield secret scan ci
only:
- branches
except:
- main
deploy-review:
stage: review
image: $IMAGE_OKTETO
needs: ['gitguardian']
variables:
APP: $CI_COMMIT_REF_SLUG
VA_ENV: review
script:
- okteto preview deploy $VA_ENV-$CI_COMMIT_REF_SLUG-$OKTETO_USERNAME --scope personal --branch $CI_COMMIT_REF_NAME --repository $CI_REPOSITORY_URL --wait
environment:
name: review/$CI_COMMIT_REF_SLUG
url: https://${CI_PROJECT_TITLE}-${VA_ENV}-${CI_COMMIT_REF_SLUG}-${OKTETO_USERNAME}.cloud.okteto.net
on_stop: stop-review
only:
- branches
except:
- main
stop-review:
stage: review
needs: ['deploy-review']
image: $IMAGE_OKTETO
when: delayed
start_in: 30 minutes
variables:
APP: $CI_COMMIT_REF_SLUG
VA_ENV: review
environment:
name: review/$CI_COMMIT_REF_SLUG
action: stop
script:
- okteto preview destroy $VA_ENV-$CI_COMMIT_REF_SLUG-$OKTETO_USERNAME
only:
- branches
except:
- main
build-docker:
stage: build
image: $IMAGE_DOCKER
services:
- docker:dind
variables:
REGISTRY_HOST: docker.io
DOCKER_HUB_IMAGE: app-okteto
REGISTRY_IMAGE: index.docker.io/danieljesussp/app-okteto
script:
- docker login -u "$DOCKER_HUB_USER" -p "$DOCKER_HUB_PASSWORD" $REGISTRY_HOST
- >
docker build
--no-cache
--tag $REGISTRY_IMAGE:$CI_COMMIT_SHA
.
- docker push $REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
refs:
- main
build-kaniko:
stage: build
image:
name: $IMAGE_KANIKO
entrypoint: ['']
variables:
DOCKER_HUB_REGISTRY: registry.gitlab.com
script:
- /kaniko/executor
--context ${CI_PROJECT_DIR}
--dockerfile ${CI_PROJECT_DIR}/Dockerfile
--destination $DOCKER_HUB_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA
only:
refs:
- main
container_scanning:
image:
name: docker.io/aquasec/trivy:latest
entrypoint: ['']
needs: ['build-kaniko']
stage: build
variables:
FULL_IMAGE_NAME: $DOCKER_HUB_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA
script:
- trivy --version
- trivy image --clear-cache
- trivy image --exit-code 0 --cache-dir .trivycache/ --no-progress --security-checks vuln "$FULL_IMAGE_NAME"
- trivy image --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress --security-checks vuln "$FULL_IMAGE_NAME"
cache:
paths:
- .trivycache/
only:
refs:
- main
deploy-production:
stage: production
image:
name: $IMAGE_HELM
entrypoint: ['']
needs: ['container_scanning']
variables:
VA_ENV: production
environment:
name: production
url: https://${CI_PROJECT_TITLE}-${OKTETO_USERNAME}.cloud.okteto.net
script:
- export KUBECONFIG=${ENV_KUBECONFIG}:${KUBECONFIG:-$HOME/.kube/config}
# "Simple" hack to dynamically set
- sed -i 's/_CI_PROJECT_TITLE/'"${CI_PROJECT_TITLE}"'/' "charts/templates/NOTES.txt"
- sed -i 's/_VA_ENV/'""'/' "charts/templates/NOTES.txt"
- sed -i 's/_CI_COMMIT_REF_SLUG/'""'/' "charts/templates/NOTES.txt"
- sed -i 's/_OKTETO_USERNAME/'"-${OKTETO_USERNAME}"'/' "charts/templates/NOTES.txt"
- helm upgrade $CI_PROJECT_NAME ./charts
--values=./charts/values.yaml
--install --atomic
only:
refs:
- main
uninstall-production:
stage: production
needs: ['deploy-production']
image:
name: $IMAGE_HELM
entrypoint: ['']
when: delayed
start_in: 30 minutes
environment:
name: production
url: https://${CI_PROJECT_TITLE}-production-$CI_COMMIT_REF_SLUG-$OKTETO_USERNAME.cloud.okteto.net
script:
- export KUBECONFIG=${ENV_KUBECONFIG}:${KUBECONFIG:-$HOME/.kube/config}
- helm uninstall $CI_PROJECT_NAME
only:
refs:
- main

Vamos a explicar brevemente los cambios más relevantes que tendremos.

En primera instancia agregaremos a nuestro CI la herramienta KubeLinter. Esta solución me encanta y siempre que puedo trato de recomendarla a los distintos clientes con los que trabajo. Ya que nos permite analizar nuestros manifiestos de Kubernetes. Nos ofrece reglas de seguridad y es capaz que identifica los errores de configuración y programación en las implementaciones de Kubernetes.

gitlab-ci.yml
kubelinter:
stage: test
image: $IMAGE_DOCKER
services:
- docker:dind
script:
- docker run -v $PWD/charts:/dir -v $PWD/lint/config.yaml:/etc/config.yaml stackrox/kube-linter lint /dir --config /etc/config.yaml
only:
- branches
except:
- main

En el siguiente paso agregaremos SonarSource para analizar la calidad de nuestro código. Esta herramienta es totalmente gratuita si nuestro repositorio es gratuito, por lo que solo tendremos que crear nuestro proyecto en ella.

gitlab-ci.yml
sonarcloud-check:
stage: test
image:
name: $IMAGE_SONAR
variables:
SONAR_USER_HOME: '${CI_PROJECT_DIR}/.sonar'
GIT_DEPTH: '0'
cache:
key: '${CI_JOB_NAME}'
paths:
- .sonar/cache
script:
- sonar-scanner
only:
- branches
except:
- main

Ahora ha llegado el momento de GitGuardian. Esta herramienta nos permitirá analizar nuestros commit en busca de contraseñas o token que puedan ocasionar una falla de seguridad. Si no conocéis os la recomiendo sin ninguna duda, incluye un plan gratuito.

gitlab-ci.yml
gitguardian:
stage: scanning
needs:
- kubelinter
- sonarcloud-check
image:
name: $IMAGE_GITGUARDIAN
script:
- ggshield secret scan ci
only:
- branches
except:
- main

En el siguiente paso, emplearemos Kaniko para buildear nuestra imagen y subirla a Docker Hub. Kaniko construye imágenes sin necesidad de un demonio Docker, haciendo el proceso de construcción más seguro. Cada capa de la imagen se construye en el espacio de usuario, así que no hay necesidad de disponer de privilegios de acceso para generar una imagen.

gitlab-ci.yml
build-kaniko:
stage: build
image:
name: $IMAGE_KANIKO
entrypoint: ['']
variables:
DOCKER_HUB_REGISTRY: registry.gitlab.com
script:
- /kaniko/executor
--context ${CI_PROJECT_DIR}
--dockerfile ${CI_PROJECT_DIR}/Dockerfile
--destination $DOCKER_HUB_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA
only:
refs:
- main

Como último paso, agregaremos Trivy es una herramienta Open Source para escanear imágenes de contenedores en busca de vulnerabilidades en los paquetes del sistema operativo y las dependencias de las aplicaciones.

gitlab-ci.yml
container_scanning:
image:
name: docker.io/aquasec/trivy:latest
entrypoint: ['']
needs: ['build-kaniko']
stage: build
variables:
FULL_IMAGE_NAME: $DOCKER_HUB_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_SHA
script:
- trivy --version
- trivy image --clear-cache
- trivy image --exit-code 0 --cache-dir .trivycache/ --no-progress --security-checks vuln "$FULL_IMAGE_NAME"
- trivy image --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress --security-checks vuln "$FULL_IMAGE_NAME"
cache:
paths:
- .trivycache/
only:
refs:
- main

¡Nos vemos en la tercera parte de este bloque de tutoriales!

次回まで

0
0