Aller au contenu principal

Déployer sur Kubernetes depuis GitLab CI

Vous avez une app, un cluster Kubernetes France Nuage, et vous voulez que git push déclenche un déploiement automatique. Ce tutoriel vous montre comment câbler tout ça en 15 minutes.

Ce qu'il vous faut

  • Un projet GitLab
  • Un namespace sur votre cluster Kubernetes France Nuage
  • Un kubeconfig (téléchargeable depuis la console France Nuage)

Étape 1 : stocker le kubeconfig dans GitLab

Allez dans votre projet : Settings > CI/CD > Variables.

VariableTypeProtected
KUBE_CONFIGFileoui

Collez le contenu de votre kubeconfig. Le type File est important : GitLab crée un fichier temporaire et met le chemin dans $KUBE_CONFIG. Si vous choisissez "Variable" par erreur, kubectl ne trouvera pas le fichier.

Étape 2 : le pipeline

Copiez ce .gitlab-ci.yml dans votre projet. On utilise BuildKit au lieu de Docker - si vous voulez savoir pourquoi, lisez le guide Runners GitLab CI.

# .gitlab-ci.yml
stages:
- build
- deploy

variables:
IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}

build:
stage: build
image:
name: moby/buildkit:rootless
entrypoint: [""]
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(echo -n $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD | base64)\"}}}" > ~/.docker/config.json
script:
- buildctl-daemonless.sh build
--frontend dockerfile.v0
--local context=.
--local dockerfile=.
--output type=image,name=${IMAGE},push=true

deploy:
stage: deploy
image: alpine/helm:latest
before_script:
- export KUBECONFIG=$KUBE_CONFIG
script:
- helm upgrade --install mon-app ./helm
--namespace mon-namespace
--set image.repository=${CI_REGISTRY_IMAGE}
--set image.tag=${CI_COMMIT_SHORT_SHA}
--wait
--timeout 5m
environment:
name: production

À chaque push, l'image est buildée et déployée. Pas plus compliqué que ça.

Étape 3 : staging + production (optionnel)

Si vous voulez déployer automatiquement en staging et garder un bouton manuel pour la prod :

stages:
- build
- deploy-staging
- deploy-production

variables:
IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}

build:
stage: build
image:
name: moby/buildkit:rootless
entrypoint: [""]
variables:
BUILDKITD_FLAGS: --oci-worker-no-process-sandbox
before_script:
- mkdir -p ~/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"auth\":\"$(echo -n $CI_REGISTRY_USER:$CI_REGISTRY_PASSWORD | base64)\"}}}" > ~/.docker/config.json
script:
- buildctl-daemonless.sh build
--frontend dockerfile.v0
--local context=.
--local dockerfile=.
--output type=image,name=${IMAGE},push=true
rules:
- if: '$CI_COMMIT_BRANCH == "main"'

.deploy: &deploy
image: alpine/helm:latest
before_script:
- export KUBECONFIG=$KUBE_CONFIG
script:
- helm upgrade --install $RELEASE ./helm
--namespace $NAMESPACE
--set image.repository=${CI_REGISTRY_IMAGE}
--set image.tag=${CI_COMMIT_SHORT_SHA}
--wait

deploy-staging:
<<: *deploy
stage: deploy-staging
variables:
RELEASE: mon-app-staging
NAMESPACE: staging
environment:
name: staging
url: https://staging.mon-app.fr
rules:
- if: '$CI_COMMIT_BRANCH == "main"'

deploy-production:
<<: *deploy
stage: deploy-production
variables:
RELEASE: mon-app-prod
NAMESPACE: production
environment:
name: production
url: https://mon-app.fr
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual

Étape 4 : promouvoir sans rebuild (optionnel)

Vous pouvez promouvoir l'image staging vers prod sans la reconstruire. Utile si le build prend du temps ou si vous voulez garantir que c'est exactement la même image :

promote-to-prod:
stage: deploy-production
image: quay.io/skopeo/stable:latest
script:
- skopeo copy
--src-creds=${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}
--dest-creds=${CI_REGISTRY_USER}:${CI_REGISTRY_PASSWORD}
docker://${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}
docker://${CI_REGISTRY_IMAGE}:production
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: manual

Dépannage

"Unable to connect to the server"

Vérifiez que KUBE_CONFIG est de type File, pas Variable. C'est l'erreur la plus fréquente.

"Forbidden"

Le kubeconfig n'a pas les droits sur le namespace. Vérifiez les RBAC ou demandez à votre admin cluster.

"ImagePullBackOff"

Kubernetes n'arrive pas à pull l'image depuis le registry GitLab. Il faut créer un secret :

kubectl create secret docker-registry gitlab-registry \
--docker-server=registry.gitlab.com \
--docker-username=deploy-token \
--docker-password=xxx \
-n mon-namespace

Puis référencez-le dans votre Deployment :

spec:
imagePullSecrets:
- name: gitlab-registry

Autres erreurs

Consultez les erreurs courantes du guide Runners.

Pour aller plus loin

Des questions ? support@france-nuage.fr