Les images Docker avec la CI/CD

Mon premier build avec kaniko

Si vous souhaitez intégrer la construction de vos images Docker dans votre CI/CD, c'est bien évidemment possible! Il vous faudra utiliser une image "Kaniko". Vous pouvez en apprendre plus en vous rendant sur la page du projet.

Pour réaliser votre build, il faudra tout simplement modifier votre fichier .gitlab-ci.yaml de cette façon:

build:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:v1.20.0-debug
    entrypoint: [""]
  tags:
    - kaniko
  script:
    - /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
  

Qu'est-ce qui est important dans le code ci-dessus:

Dés que votre code sera push, l'image sera automatiquement build et envoyée dans le registry! Pour essayer de rendre la configuration la plus portable possible, vous pouvez utiliser ces différents tags pour obtenir un runner dédié:

Comment nommer mon image

Si vous avez l'habitude d'utiliser le Docker Hub, vous avez déjà vu que les images peuvent utiliser de nombreux noms, il est bien évidemment possible d'en exposer plusieurs notammment si votre projet fonctionne avec des microservices. Vous trouverez ci-dessous les différentes possibilités:

forge.univ-lyon1.fr:4567/namespace/project:tag # forge.univ-lyon1.fr:4567/doc-cicd/kaniko:latest
forge.univ-lyon1.fr:4567/namespace/project/image:tag # forge.univ-lyon1.fr:4567/doc-cicd/kaniko/nova-api:13.0
forge.univ-lyon1.fr:4567/namespace/project/dir/image:tag # forge.univ-lyon1.fr:4567/doc-cicd/kaniko/nova/nova-api:13.0

Utiliser mon image depuis le registry de la forge

Si vous avez utilisé le registry de la forge, vous pouvez consulter la bonne création de l'image en suivant le chemin suivant: Packages and registries (1) > Container Registry(2) > Copy Icon(3)

packages-and-registries-container-copy-icon
La suite va dépendre de la visibilité de votre dépôt. On va commencer avec le scénario où il est public. Dans cette situation après avoir réalisé l'étape 3, il suffit de taper la commande docker pull puis de coller le contenu du presse-papier:
# exemple d'un pull
docker pull forge.univ-lyon1.fr:4567/doc-cicd/kaniko

# exemple d'un run
docker run forge.univ-lyon1.fr:4567/doc-cicd/kaniko cat /root.conf
Si votre dépôt n'est pas public, vous allez problablement rencontrer l'erreur suivante:
Erreur possible:
Unable to find image 'forge.univ-lyon1.fr:4567/doc-cicd/kaniko:latest' locally
docker: Error response from daemon: Head "https://forge.univ-lyon1.fr:4567/v2/doc-cicd/kaniko/manifests/latest": denied: access forbidden.
See 'docker run --help'.
Il est donc nécessaire de réaliser une authentification auprès de la forge, il faudra utiliser la commande docker login:
docker login forge.univ-lyon1.fr:4567
Username: doc-demo
Password:
WARNING! Your password will be stored unencrypted in /home/doc-cicd/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
Et maintenant vous pouvez taper les commandes Docker suivantes:
# exemple d'un pull
docker pull forge.univ-lyon1.fr:4567/doc-cicd/kaniko

# exemple d'un run
docker run forge.univ-lyon1.fr:4567/doc-cicd/kaniko cat /root.conf

Utiliser mon image pendant mon pipeline de CI/CD

Pour utiliser votre image, il suffit de simplement utiliser le keyword image. Si votre dépôt est privé, il ne sera pas nécessaire de vous authentifier, la CI/CD le fera automatiquement. Ce qui donne l'exemple suivant:

build:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:v1.12.1-debug
    entrypoint: [""]
  tags:
    - kaniko
  script:
    - /kaniko/executor
      --context "${CI_PROJECT_DIR}"
      --dockerfile "${CI_PROJECT_DIR}/Dockerfile"
      --destination "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
  deploy:
  stage: deploy
  image:
    name: "${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}"
    # Il est bien évidemment possible de mettre un nom en dur
    # name: "${CI_REGISTRY_IMAGE}:latest"
    # name: "forge.univ-lyon1.fr:4567/namespace/project/
    # name: forge.univ-lyon1.fr:4567/doc-cicd/kaniko:latest
  script:
    - cat /root.conf

  

Sécuriser mon mot de passe "docker login"

# testé et validé sur Ubuntu 22.04
sudo apt install libsecret-1-dev make golang
git clone https://github.com/docker/docker-credential-helpers.git
cd docker-credential-helpers
make secretservice
sudo cp bin/build/docker-credential-secretservice /usr/local/bin
# testé et validé de Fedora 35 à 37
sudo dnf install libsecret-devel make golang
git clone https://github.com/docker/docker-credential-helpers.git
cd docker-credential-helpers
make secretservice
sudo cp bin/build/docker-credential-secretservice /usr/local/bin
# remerciement au CISR pour ces commandes!
xcode-select --install
brew install golang
make osxkeychain
cp bin/build/docker-credential-osxkeychain /usr/local/bin/

Pourquoi avoir fait le choix de Kaniko

Kaniko a été choisi car c'est la solution proposant le meilleur niveau de sécurité pour les utilisateurs. L'ancienne solution présentait des exploitations possibles.

Dois je vraiment saisir les tags de cette documentation?

Il est en effet pas obligatoire d'utiliser les tags mentionnés ci-dessous. Mais utiliser ces tags vous permettra de réaliser la construction de votre image sur des runners dédiés à cet usage, plus puissant et avec une file d'attente moins congestionnée que les autres runners!