Aller au contenu principal

Utiliser un cluster kubernetes sur Gitlab CI/CD

· 6 minutes de lecture
Stéphane ROBERT
Consultant DevOps

Pour valider la faisabilité de mon projet de Home Lab Devops, j'ai testé la possibilité d'utiliser un cluster Kubernetes sur la version en ligne de Gitlab.com. Pour info, avant j'utilisais gitlab-runner avec du docker-machine pour instancier dynamiquement des runners sur de l'AWS, c'est donc plus moderne.

Pour rappel les objectifs que je me suis fixés pour ce Home La Devops :

  • Pouvoir faire tourner des jobs des pipelines CI/CD en local pour accéder à des ressources locales. Comme mon gestionnaire d'artefacts Nexus pour y déposer mes images de conteneurs, mes packages apt yum, mes librairies python,...
  • Pouvoir déployer des applications de type legacy avecAnsible AWX, terraform, ...
  • Pouvoir déployer des applications cloud native sur ce même cluster.

Installer un cluster kubernetes.

Pour rappel, mon Home Lab est composé de mini-pc et sur un de ceux-ci je vais instancier un cluster kubernetes avec k3s. J'aurais pu le faire aussi avec du minikube ou du kind, ...

Allez on se lance :

curl -sfL https://get.k3s.io | sh -

Patientez quelques minutes. Ensuite je vais copier la config de k3s sur la machine sur laquelle je bosse toujours.

mkdir ~/.kube
scp root@devbox1.robert.local:/etc/rancher/k3s/k3s.yaml ~/.kube/config-devbox1.yaml
export kubeconfig=~/.kube/config-devbox1.yaml
kubectl get nodes
NAME     STATUS   ROLES                  AGE     VERSION
devbox   Ready    control-plane,master   17m     v1.22.6+k3s1
kubectl get pod -A
NAMESPACE     NAME                                         READY   STATUS      RESTARTS   AGE
kube-system   local-path-provisioner-84bb864455-rjxh7      1/1     Running     0          17m
kube-system   coredns-96cc4f57d-bwzrd                      1/1     Running     0          17m
kube-system   helm-install-traefik-crd--1-b7m9d            0/1     Completed   0          17m
kube-system   metrics-server-ff9dbcb6c-rdgx4               1/1     Running     0          17m
kube-system   helm-install-traefik--1-bvbzk                0/1     Completed   2          17m
kube-system   svclb-traefik-chg9r                          2/2     Running     0          16m
kube-system   traefik-55fdc6d984-mnjdx                     1/1     Running     0          16m

Exposition du cluster sur internet

Maintenant, nous allons configurer les règles NAT de notre box internet pour exposer notre cluster Kubernetes. Je ne vais documenter que ma configuration actuelle, c'est-à-dire avec une box Orange :

  • Dans votre navigateur rendez sur l'ip de votre box http://192.168.1.1.
  • Identifiez-vous
  • Cliquez en bas de l'écran sur la roue dentée, puis sur réseau
  • Cliquez sur l'onglet NAT/PAT
  • Dans les règles personnalisées, cliquez sur nouveau
  • Saisissez Kubernetes, 6443, 6443, TCP, <l'ip de votre pc hébergeant k3s>, rien dans ip externe
  • Validez sur [Créer].

Pour valider que cela fonctionne :

curl -k https://<votre-ip-publique>:6443
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

Pour récupérer votre IP publique.

Les liens pour faire la même chose sur :

Intégration du cluster sur Gitlab

Notre cluster Kubernetes est désormais joignable depuis l'extérieur. Nous allons voir :

  • Comment installer et configurer des runners Gitlab
  • Comment l'ajouter à nos groupes/projets Gitlab pour déployer des environnements

Comme je vais tester le build d'une image Docker via un runner Gitlab tournant sur mon cluster, je crée un groupe docker-images.

Installation de Gitlab Runner sur le cluster Kubernetes

Dans les settings CI/CD du groupe cliquez [expand] de la partie Runners et copiez le token affiché.

Je vais utiliser le template Helm officiel pour l'installer. Ajoutons le repository Helm :

helm repo add gitlab https://charts.gitlab.io

Créons le fichier de valeurs :

helm show values gitlab/gitlab-runner >gitlab-runner-chart-values.yaml

Éditez-le et changez les valeurs suivantes :

image: gitlab/gitlab-runner:alpine-v14.7.0

gitlabUrl: https://gitlab.com/

runnerRegistrationToken: "<le token récupéré ci-dessus>"

rbac:
  create: true

metrics:
  enabled: false
  serviceMonitor:
    enabled: false

runners:
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{.Release.Namespace}}"
        image = "ubuntu:22.04"
  tags: "myrunner"
  name: "myrunner"
  privileged: true

On peut déployer le Runner Gitlab :

helm install -f gitlab-runner-chart-values.yaml gitlab-runner gitlab/gitlab-runner

kubectl get pod
NAMESPACE     NAME                                         READY   STATUS      RESTARTS   AGE
default       gitlab-runner-gitlab-runner-56c79b9c-wkjnv   1/1     Running     0          11m

Pour valider que Gitlab arrive bien à se connecter, retournez dans les paramètres ci/cd du groupe, ou rafraichissez la page, [expand] Runners et vous devriez voir apparaître votre runner :

Test du runner Gitlab

Pour tester notre runner :

  • Créez un projet git dans le groupe créé précédemment.
  • Cliquez ensuite sur [Setup CI/CD] + [Create new CI/CD Pipeline]
  • Ajoutez juste le tag que vous avez déclaré dans tous les stages. Exemple :

build-job:       # This job runs in the build stage, which runs first.
  stage: build
  tags:
    - myrunner
  script:
    - echo "Compiling the code..."
    - echo "Compile complete."

Commit et regardez ce qui se passe dans un des jobs du pipeline :

Running with gitlab-runner 14.7.0 (98daeee0)
  on myrunner 7onTfeUU
Preparing the "kubernetes" executor
00:00
Using Kubernetes namespace: default
Using Kubernetes executor with image ubuntu:22.04 ...
Using attach strategy to execute scripts...
Preparing environment
00:13
Waiting for pod default/runner-7ontfeuu-project-33781001-concurrent-07bqss to be running, status is Pending
Waiting for pod default/runner-7ontfeuu-project-33781001-concurrent-07bqss to be running, status is Pending
 ContainersNotReady: "containers with unready status: [build helper]"
 ContainersNotReady: "containers with unready status: [build helper]"
Waiting for pod default/runner-7ontfeuu-project-33781001-concurrent-07bqss to be running, status is Pending
 ContainersNotReady: "containers with unready status: [build helper]"
 ContainersNotReady: "containers with unready status: [build helper]"
Waiting for pod default/runner-7ontfeuu-project-33781001-concurrent-07bqss to be running, status is Pending
 ContainersNotReady: "containers with unready status: [build helper]"
 ContainersNotReady: "containers with unready status: [build helper]"
Running on runner-7ontfeuu-project-33781001-concurrent-07bqss via gitlab-runner-gitlab-runner-56c79b9c-wkjnv...

Oh kubernetes executor. Un petit tout sur le cluster :

default       runner-7ontfeuu-project-33781001-concurrent-1vjcbx   0/2     PodInitializing   0          2s
default       runner-7ontfeuu-project-33781001-concurrent-0qzpth   0/2     PodInitializing   0          3s

Magique.

Ajout du cluster Kubernetes au groupe Gitlab pour déployer dessus

On commence par préparer le terrain.

  • On crée un compte de service et on lui donne des droits d'admin. Pour cela créez un fichier gitlab-admin-service-account.yaml et mettez-y ce contenu :
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab
  namespace: kube-system
---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: gitlab-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin


- kind: ServiceAccount
    name: gitlab
    namespace: kube-system

Appliquez le tout :

export kubeconfig=~/.kube/config-devbox1.yaml
kubectl apply -f gitlab-admin-service-account.yaml
  • On récupère les informations nécessaires :

    • Le certificat du cluster :
    kubectl get secrets
    NAME                                      TYPE                                  DATA   AGE
    default-token-75fts                       kubernetes.io/service-account-token   3      4h41m
    
    kubectl get secret default-token-75fts -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
    -----BEGIN CERTIFICATE-----
    MIIBeDCCAR2gAwIBAgIBADAKBggqhkjOPQQDAjAjMSEwHwYDVQQDDBhrM3Mtc2Vy
    ...
    -----END CERTIFICATE-----
    
    • Le token :
    kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab | awk '{print $1}')
    
    ...
    
    token:      eyJhbGciOiJSUzI1NiIsImtpZCI6InlLQ3BIcFNMWGhOMl96eUJfX3pQTldBdWNWU2w2QjVjRlpWN1R5QnJqc3MifQ.....
    

Cette fois, on clique sur Kubernetes > [Connnect cluster with Certificate] > [Connect Existing cluster] :

  • Donnez un petit non à votre cluster : mon petit cluster
  • Dans API URL : https://<votre-ip-publique>:6443
  • Dans la zone CA Certificate le certificat récupéré ci-dessus
  • Dans la zone Service Token le token.
  • Le reste laissez par défaut.
  • Cliquez sur [Add Kubernetes cluster]

Vous devriez le voir apparaître comme ceci :

On peut déployer dessus ! Un grand pas pour mon Home Lab Devops.