Kubernetes - Démarrage rapide
Prérequis pour suivre ce tutoriel
Afin d'utiliser le service de cluster Kubernetes managés Numspot, les prérequis sont:
- Avoir un compte utilisateur NumSpot détenant le rôle
Kubernetes Admin
. - Avoir un espace NumSpot auquel est rattaché l'utilisateur.
- Avoir un compte de service et le jeton utilisateur correspondant (voir comment générer un token).
Les interactions avec l'API HTTP de NumSpot nécessitent d'être authentifiées par un jeton d'accès (Access Token) dans une région et un espace donné. Il est donc nécessaire de préparer un environnement d'exécution en conséquence. Cet environnement sera utilisé par les commandes fournies dans ce document.
Générer un Token pour un Service Account donné
Afin d'utiliser l'API, il est nécessaire de créer au préalable un Service Account avec les autorisations "Kubernetes Admin" sur le Space ID à opérer.
Une fois le Service Account créé, vous devez [générer le token d'accès]](/docs/iam/concepts/api.mdx) correspondant, valable pour la durée indiquée lors de la création du Service Account.
curl "https://api.$REGION.numspot.com/iam/token" \
-u "${NUMSPOT_SA_AK}":"${NUMSPOT_SA_SK}" \
-d 'grant_type=client_credentials&scope=openid+offline_access'
Où NUMSPOT_SA_AK est la clé d'accès du compte de service, et NUMSPOT_SA_SK la clé secrète récupérée à la création du compte de service.
Exporter les variables nécessaires à l'utilisation de l'API
export REGION="eu-west-2"
export SPACE_ID="myspaceid"
export ACCESS_TOKEN="myaccesstoken"
Il est nécessaire de conserver la même session du terminal tout au long de ce tutoriel. Les données exportées sont disponibles uniquement dans la session dans laquelle elles ont été initialisées, à savoir REGION
, SPACE_ID
, et ACCESS_TOKEN
.
Certaines des commandes fournies à titre d'exemple dans ce document utilisent l'application jq
. Il est donc nécessaire que cet outil soit disponible dans l'environnement d'exécution.
Créer un premier cluster
Pour commencer, nous allons créer un cluster Kubernetes en utilisant l'API HTTP de NumSpot depuis la région standard (eu-west-2
), ceci afin de limiter les coûts engendrés par les ressources déployées.
Notre premier cluster contiendra deux nodes de type VERY_SMALL
(disposant de caractéristiques spécifiques).
Pour plus de facilité, nous choisirons la dernière version disponible de l'offre Kubernetes de NumSpot. Celle-ci peut être récupérée en se référant à la documentation sur les versions disponibles.
Enfin, nous utiliserons le CIDR 10.1.0.0/16
pour adresser nos machines virtuelles. Il est possible de choisir un CIDR sous la forme 10.X.0.0/16
, pour plus de détails se référer à l'article sur le choix du CIDR.
curl -X POST https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"name": "my-first-cluster",
"cidr": "10.1.0.0/16",
"version": "1.29.5",
"nodeProfile": "VERY_SMALL",
"nodeCount": 3
}' \
| export CLUSTER_ID=$(jq -r .clusterid)
Dans la commande précédente, nous avons utilisé la commande jq
pour récupérer le CLUSTER_ID
: identifiant du cluster en cours de création, qui nous servira pour opérer différentes actions une fois le cluster créé.
Suivre le status pendant la création
La création d'un cluster complet peut durer environ 15 minutes (ordre de grandeur indicatif). Pour suivre l'état du cluster et savoir quand il est prêt à être utilisé, le status est disponible via la route de GET Cluster, comme suit:
curl -X GET https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json'
{
"availabilityZone": "eu-west-2a",
"cidr": "10.1.0.0/16",
"createdAt": "2025-04-16T16:11:02.151115712Z",
"id": "8b06aa15-b28c-415c-bf7a-4ecc1353b4f1",
"name": "my-first-cluster",
"nodePools": [
...
],
"status": "CREATING",
"version": "1.31.6"
...
}
La propriété status
indique l'état d'avancement de celle-ci. Les différentes valeurs possibles sont :
CREATING
: le cluster est en cours de créationACTIVE
: le cluster est en état stable, toutes les opérations (création, modification, suppression de worker) sont terminées.DELETING
: le cluster est en cours de suppressionPENDING
: une opération de mise à jour est en cours, comme l'ajout de workersREPAIRING
: une erreur interne a eu lieu lors d'une opération sur le cluster, il n'est pas en état stable.
Tant que l'opération n'est pas terminée, continuez à la surveiller avec cette même requête. Quand la propriété status
devient ACTIVE
, le cluster est prêt à être utilisé.
Accéder au cluster
Pour utiliser le cluster au travers de l'invite de commande kubectl
, il est nécessaire de se munir des éléments suivants:
- URL de l'API Kubernetes
- fichier kubeconfig d'accès au cluster
- IP du bastion SSH et sa clé privée autorisant l'accès au réseau du cluster
Récupérer l'URL de l'API Kubernetes et l'IP du bastion
L'URL de l'API Kubernetes ainsi que l'IP du bastion SSH sont exposées dans les informations du cluster.
curl -X GET https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json'
La propriété urls.[0].api
contient l'URL de l'API Kubernetes. La propriété clientBastionPublicIP
contient l'adresse IP du bastion SSH.
{
"id": "8b06aa15-b28c-415c-bf7a-4ecc1353b4f1",
"version": "1.31.6",
"clientBastionPublicIP": "80.247.12.243",
...
"ingressUrl": "lbi-XXXXXXXXXXXX-XXXXXXXXX.myregion.lbu.outscale.com",
"apiUrl": "internal-lbm-XXXXXXXXXXXX-XXXXXXXXX.myregion.lbu.outscale.com",
}
Pour simplifier les exemples suivants, stockez ces deux informations respectivement dans les variables d'environnement NS_KUBEAPI_URL
et NS_KUBE_BASTION_IP
.
export NS_KUBEAPI_URL="url-kubernetes-api"
export NS_KUBE_BASTION_IP="ip-du-bastion"
Récupérer les fichiers
Dans cette étape, nous allons récupérer deux fichiers, la clé privée SSH (ns-my-first-cluster.key) autorisant l'accès au réseau du cluster, ainsi que le fichier kubeconfig contenant les informations d'authentification à l'API Kubernetes.
Nous allons d'abord récupérer la clé privée SSH du bastion.
curl -X GET https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID/ns-my-first-cluster.key \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/octet-stream'
Le contenu devra être stocké dans un fichier que l'on nommera de manière arbitraire ns-my-first-cluster.key
.
Le fichier de clé privée doit avoir un accès limité pour pouvoir être utilisé par ssh, à effectuer avec la commande suivante:
chmod 0600 ns-my-first-cluster.key
Nous allons ensuite, avec le même processus, récupérer le fichier kubeconfig:
curl -X GET https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID/kubeconfig \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/octet-stream'
Le contenu devra être stocké dans un fichier que l'on nommera de manière arbitraire ns-kubeconfig.yaml
.
Préparer le fichier kubeconfig
Dans le fichier ns-kubeconfig.yaml
, remplacer la propriété server
par https://127.0.0.1:6443
.
sed -ri "s/( +server:) (.*)$/\1 https:\/\/127.0.0.1:6443/" ns-kubeconfig.yaml
Connexion avec le bastion du cluster
Afin d'atteindre l'API du cluster, il est nécessaire d'avoir un accès au réseau des machines du cluster. Pour ce faire, nous allons initier une connexion vers le bastion SSH afin de rediriger les commandes kubectl
vers le cluster.
ssh-keyscan $NS_KUBE_BASTION_IP >> ~/.ssh/known_hosts
ssh -i ns-my-first-cluster.key -o IdentitiesOnly=yes -l client-tunnel -L 127.0.0.1:6443:$NS_KUBEAPI_URL:6443 -N $NS_KUBE_BASTION_IP &
Tester la connexion
Une fois la connexion établie, définir la variable d'environnement KUBECONFIG
en utilisant le chemin de kubeconfig
:
export KUBECONFIG=$PWD/ns-kubeconfig.yaml
Vérifiez que le cluster est accessible avec kubectl
en utilisant la commande suivante:
kubectl version
Vérifiez que les noeuds de travail sont bien provisionnés et que leur status est bien "Ready"
kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-1-3-4 Ready <none> 52m v1.31.6
Créer un premier déploiement
Une fois la connexion avec le cluster fonctionnelle, nous allons pouvoir déployer notre première application.
Créez un fichier deployments.yaml
avec le contenu suivant.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27.0
ports:
- containerPort: 80
Pour déployer cette ressource, il suffit d’exécuter:
kubectl create deployment -f deployments.yaml
La demande de création de déploiement a été validée et est en train d'être exécutée par Kubernetes.
Nous allons vérifier que le pod correspondant au déploiement est fonctionnel. Pour cela, il est nécessaire de connaître l'état du pod (readinessProbe
et livenessProbe
) depuis la ligne de commande suivante:
kubectl get pods -l app=nginx
Vérifions que le pod du déploiement est correctement déployé et fonctionnel en nous référant à la valeur présente sous la colonne READY
. Si 1/1
est rapporté, le pod est fonctionnel. Si une autre valeur est rapportée, vérifiez la valeur de la colonne STATUS
.
NAME READY STATUS RESTARTS AGE
nginx-deployment-5654578ff8-8s7qh 1/1 Running 0 9s
...
Le déploiement du service ci-dessus basé sur Nginx est issue de la classe d'Ingress par défaut fournit nativement par Kubernetes vanilla (voir l'IngressClass par défaut de Kubernetes).
Créer un volume persistant et l'attacher à votre application
Une fois votre application crée, il est possible de lui attacher un volume, en suivant la procédure suivante:
Créer un PersistentVolumeClaim
créer un fichier pvc.yaml
avec le contenu suivant:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: outscale-bsu-standard
Pour le champ storageClassName
, utilisez les storageClasses mise à disposition dans votre cluster.
Vous pouvez les lister via la commande kubectl get storageclasses
Une storage class est défini pour chaque type de volume.
Pour déployer cette ressource, il suffit d'exécuter:
kubectl apply -f pvc.yaml
La demande de création de la ressource PersistentVolumeClaim (PVC) a été validée et créée. En revanche, le volume en mode bloc correspondant (PersistentVolume) n'a pas encore été créé. En effet, nos storageClasses sont configurées pour attendre le premier consommateur avant de créer le volume associé au PVC.
Utiliser le PersistentVolumeClaim dans un déploiement
Ainsi, il faut configurer votre application pour utiliser le PVC. Cela se fait dans le déploiement de l'application, en éditant le fichier deployments.yaml
de la manière suivante:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27.0
ports:
- containerPort: 80
volumes:
- name: storage
persistentVolumeClaim:
claimName: my-pvc
On ajoute au déploiement une partie "volume" dans le yaml, et on y retrouve la référence au PVC défini plus haut my-pvc
.
Ensuite pour appliquer cette modification sur la ressource Deployment
, il suffit d’exécuter:
oc apply -f deployments.yaml
un PersistentVolume sera créé.
Pour vérifier, lancer la commande kubectl get pv
et vous devriez voir votre PersistentVolume, celui-ci correspond à un volume en mode bloc créé à la demande par le CSI.
Ajouter des workers au cluster
Conformément aux paramètres fournis lors de notre demande de création de cluster, le cluster contient actuellement 2 workers. Nous allons en ajouter 2 afin d'en avoir 4 au total.
Rappelons-nous que nous avons demandé des profils de workers VERY_SMALL
.
curl -X POST https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID/workers/add \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"nodeCount": 2,
"nodeProfile": "VERY_SMALL",
"version": "1.31.6"
}'
La requête renvoie les informations de l'opération lancée.
Supprimer un worker du cluster
La suppression de workers se fait de manière unitaire: la requête d'API de suppression permet de supprimer 1 worker à la fois.
Le paramètre principal est le type de worker à supprimer. Dans le cas de notre exemple, il s'agit d'un worker VERY_SMALL
curl -X POST https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID/workers/remove \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"nodeProfile": "VERY_SMALL"
}'
Vérification du nombre de workers
Pour vérifier que les opérations d'ajout et suppression ont bien abouti, un GET cluster permet de lister les workers du cluster.
curl https://api.$REGION.numspot.com/kubernetes/spaces/$SPACE_ID/clusters/$CLUSTER_ID \
--header "Authorization: Bearer $ACCESS_TOKEN"
Alternativement, kubectl peut être utilisé pour s'assurer que l'état du cluster est celui attendu:
kubectl get nodes
# Pour avoir plus de détails sur les nodes
kubectl describe nodes