<<< Chap 16 | Sommaire | >>>
Chap 18. Introduction aux Labels et NameSpaces
I. Labels et Sélecteurs
1.1 Exemple d’utilisation des labels (étiquettes)
Nous l’avons vu dans le chap 17, l’importance de l’utilisation des labels.
- Sans label, il nous a fallu créer un script pour supprimer tous les volumes persistants.
$ for n in {01..10};do kubectl delete pv nfs-sts-pv${n};done
- Avec un label prédéfini, tous les PVs portant l’étiquette
vol=sts-pv
, peuvent être détruits en une seule commande
$ kubectl get pv --show-labels
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE LABELS
nfs-pv-01 100Mi RWX Recycle Bound default/nfs-pvc-02 slow 16d
nfs-sts-pv01 1Gi RWO Recycle Available 9d vol=sts-pv
nfs-sts-pv02 1Gi RWO Recycle Available 9d vol=sts-pv
nfs-sts-pv03 1Gi RWO Recycle Available 9d vol=sts-pv
nfs-sts-pv04 1Gi RWO Recycle Available 9d vol=sts-pv
nfs-sts-pv05 1Gi RWO Recycle Available 9d vol=sts-pv
nfs-sts-pv06 1Gi RWO Recycle Bound default/nfs-pvc-sts-busybox-0 sts-disk 9d vol=sts-pv
nfs-sts-pv07 1Gi RWO Recycle Available sts-disk 9d vol=sts-pv
nfs-sts-pv08 1Gi RWO Recycle Bound default/nfs-pvc-sts-busybox-2 sts-disk 9d vol=sts-pv
nfs-sts-pv09 1Gi RWO Recycle Bound default/nfs-pvc-sts-busybox-1 sts-disk 9d vol=sts-pv
nfs-sts-pv10 1Gi RWO Recycle Available sts-disk 9d vol=sts-pv
$ kubectl delete pv -l vol=sts-pv
Aussi, les labels nous ont permis de ne sélectionner que certains nodes, y compris le Master, pour déployer les pods créés par Daemonsets. (voir chap 15)
- Etape 1:
- Appliquer un label
dsnode
avec comme valeur true
, aux nodes Master k8sn01
et Worker k8sn03
,
$ kubectl label node k8sn01 dsnode=true
$ kubectl label node k8sn03 dsnode=true
- Etape 2:
- Ajouter ensuite l’option de sélection de Nodes
nodeSelector
via les labels dans le fichier daemon.yaml
,
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: nginxds
name: nginx-daemonset
spec:
selector:
matchLabels:
app: nginxds
template:
metadata:
labels:
app: nginxds
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
nodeSelector:
dsnode: "true"
containers:
- image: nginx
name: nginx-daemonset
Pour rappel, l’option de tolerations
est ce qui nous a permis de déployer un Pod daemonset directement dans le node Master. Autre que pour cette utilisation bien précise, je ne vous conseille pas de le faire.
1.2 Syntaxe des labels
Une étiquette est un morceau de matière (tissu, papier, etc.) sur lequel des informations concernant l’objet auquel il est attaché sont écrites, telles que la marque, le prix, un code barre, des indications de lavage. (Wikipedia)
Avec kubernetes, une étiquette ou label (en anglais), est ce qui nous permet d’identifier un ou plusieurs objects (Pod, Volume Persistant, etc.) ayant les mêmes propriétes, pour ensuite les placer dans le même groupe.
Les labels, tout comme avec configmap et secret (chap 12), utilisent un système de « clé-valeur ».
- Clé d’étiquette (key)
- Préfixe d’étiquette (facultatif)
- Les préfixes d’étiquette ne peuvent pas dépasser 253 caractères
- Le préfixe d’étiquette doit être un sous-domaine DNS
- Le préfixe d’étiquette peut également être une série de sous-domaines DNS, séparés par « . »
- Les préfixes d’étiquette doivent se terminer par « / »
Exemple: app.kubernetes.io/
- Nom de l’étiquette
- Le nom de l’étiquette est requis
- Les noms d’étiquettes peuvent comporter jusqu’à 63 caractères
- Les caractères doivent être des caractères alphanumériques
- Les noms d’étiquettes peuvent également inclure » – » , » _ » et » . »
- Les noms d’étiquettes doivent commencer et se terminer par un caractère alphanumérique
Exemple: version
- Valeur de l’étiquette (label)
- Les valeurs d’étiquette peuvent comporter jusqu’à 63 caractères
- Les caractères doivent être des caractères alphanumériques
- Les valeurs d’étiquette peuvent également inclure » – » , » _ » et » . »
- Les valeurs des étiquettes doivent commencer et se terminer par un caractère alphanumérique
Exemple: "5.7.21"
Chaque clé doit être unique, et devraît apparaitre dans YAML avec les informations suivantes,
metadata:
labels:
clé-1 : valeur-1
clé-2 : valeur-2
1.3 Exemple d’utilisation des labels
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxzy
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
app.kubernetes.io/created-by: controller-manager
- Sans préfixes, je vais reprendre l’exemple du chap 15
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: deploy-busybox
Autres exemples couramment utilisés de labels sans préfixes,
"release"
release : "stable"
release : "canary"
"environment"
environment : "dev"
environment : "qa"
environment : "production"
"tier"
tier : "frontend"
tier : "backend"
tier : "cache"
"partition"
partition : "customerA"
partition : "customerB"
"track"
track : "daily"
track : "weekly"
1.4 Manipulation des labels
Les deux commandes à connaître pour manipuler les labels sont,
- kubectl get TYPE [NAME | -l label]
$ kubectl get --help | awk '/Usage/{getline; print}'
kubectl get
[(-o|--output=)json|yaml|wide|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=...]
(TYPE[.VERSION][.GROUP] [NAME | -l label] | TYPE[.VERSION][.GROUP]/NAME ...) [flags] [options]
$ kubectl label --help | awk '/Usage/{getline; print}'
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] [options]
Si je reprends l’exemple d’un déploiement de type ReplicaSet de la page de kubernetes.
$ wget https://kubernetes.io/examples/controllers/frontend.yaml
$ kubectl create -f frontend.yaml
$ kubectl get pod -o wide --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
frontend-b2c29 1/1 Running 0 16s 172.16.1.22 k8sn02 tier=frontend
frontend-jd4tt 1/1 Running 0 16s 172.16.2.150 k8sn03 tier=frontend
frontend-w4tw2 1/1 Running 0 16s 172.16.1.21 k8sn02 tier=frontend
- Y ajouter des labels supplémentaires aux Pods créés,
$ kubectl label pods --selector=tier=frontend release=canary
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-b2c29 1/1 Running 0 6m1s release=canary,tier=frontend
frontend-jd4tt 1/1 Running 0 6m1s release=canary,tier=frontend
frontend-w4tw2 1/1 Running 0 6m1s release=canary,tier=frontend
- Sinon, pour ajouter un label spécific par un pod,
$ kubectl label pods frontend-b2c29 environment=dev
$ kubectl label pods frontend-jd4tt environment=prod
$ kubectl label pods frontend-w4tw2 environment=prod
Je n’ai pas trouvé la méthode pour appliquer un label à plusieurs Pods à la fois. Si vous avez cette information, n’hésitez pas à la partager.
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-b2c29 1/1 Running 0 9m8s environment=dev,release=canary,tier=frontend
frontend-jd4tt 1/1 Running 0 9m8s environment=prod,release=canary,tier=frontend
frontend-w4tw2 1/1 Running 0 9m8s environment=prod,release=canary,tier=frontend
Par contre, rien à été modifié pour le réplicaset.
$ kubectl get rs --show-labels
NAME DESIRED CURRENT READY AGE LABELS
frontend 3 3 3 12m app=guestbook,tier=frontend
Pour supprimer un label, ajouter un signe négatif à la fin du nom du label à enlever.
$ kubectl label pods --selector=tier=frontend "release-"
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-b2c29 1/1 Running 0 42m environment=dev,tier=frontend
frontend-jd4tt 1/1 Running 0 42m environment=prod,tier=frontend
frontend-w4tw2 1/1 Running 0 42m environment=prod,tier=frontend
Créer ensuite un service, qui utilisera les labels proposés dans le fichier frontend.yaml
,
$ kubectl expose rs frontend --port 80
$ kubectl get svc --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
frontend ClusterIP 10.97.33.196 80/TCP 13s app=guestbook,tier=frontend
kubernetes ClusterIP 10.96.0.1 443/TCP 162d component=apiserver,provider=kubernetes
Supression des composants du lab en utilisant le label tier=frontend
, qui est commun a tous ces composants.
$ kubectl delete services,rs,deployments -l tier=frontend
J’utiliserai une méthode plus simplifié de cette commande à la fin du chapitre.
Il n’est pas nécessaire à ce niveau de supprimer l’ensemble du lab puisque vous en aurez besoin pour la suite. Sinon, vous pouvez toujours refaire le lab depuis le début.
1.5 Sélecteurs
Un sélecteur est utilisé pour sélectionner des resources kubernetes, basées sur la valeur de leurs labels.
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-8g474 1/1 Running 0 14m environment=dev,tier=frontend
frontend-bzfj2 1/1 Running 0 14m environment=prod,tier=frontend
frontend-fzfnd 1/1 Running 0 14m environment=prod,tier=frontend
La méthode de sélection peut être basée sur
- Comparaison entre valeurs et clés
Opération « = » (égalité):
$ kubectl get pod -l "environment=dev"
NAME READY STATUS RESTARTS AGE
frontend-8g474 1/1 Running 0 56m
Opération « != » (inégalité):
$ kubectl get pod -l "environment!=dev"
NAME READY STATUS RESTARTS AGE
frontend-bzfj2 1/1 Running 0 56m
frontend-fzfnd 1/1 Running 0 56m
Pour information, nous avons déjà eu recours à cette méthode pour retrouver tous les pods ayant pour label "tier=frontend"
et d’effectuer quelques modification comme,
=> Ajout (release=canary
) d’un label:
$ kubectl label pods -l "tier=frontend" release=canary
=> Suppression ("release-"
) d’un label:
$ kubectl label pods -l "tier=frontend" "release-"
Ajoutons un nouveau pod, auquel on associera le label environment=qa
,
$ kubectl run nginx --image=nginx -l environment=qa
$ kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-8g474 1/1 Running 0 90m environment=dev,tier=frontend
frontend-bzfj2 1/1 Running 0 90m environment=prod,tier=frontend
frontend-fzfnd 1/1 Running 0 90m environment=prod,tier=frontend
nginx 1/1 Running 0 8s environment=qa
- Filtrage des clés en fonction d’un ensemble de valeurs
$ kubectl get pod -l "environment in (dev,prod)" --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-8g474 1/1 Running 0 67m environment=dev,tier=frontend
frontend-bzfj2 1/1 Running 0 67m environment=prod,tier=frontend
frontend-fzfnd 1/1 Running 0 67m environment=prod,tier=frontend
$ kubectl get pod -l "environment notin (dev,prod)" --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx 1/1 Running 0 19m environment=qa
La première expression permet de lister tous les pods dont la valeur du label est égale à dev
ou prod
.
Par contre, la deuxième expression ne liste que les pods dont la valeur du label est différent de dev
et de prod
.
II. NameSpace
2.1 Introduction au NameSpace (espace de nom)
Je vous ai fait une petite introduction sur les NameSpace dans le chap 3, sans vraiment rentrer dans les détails.
Voici ce qui est dit sur la page officielle de kubernetes en ce qui concerne les namespaces.
Kubernetes prend en charge plusieurs clusters virtuels présents sur le même cluster physique. Ces clusters virtuels sont appelés namespaces (espaces de nommage en français).
(…)
Les namespaces sont des groupes de noms. Ils fournissent un modèle d’isolation de nommage des ressources.
(…)
Il n’est pas nécessaire d’utiliser plusieurs namespaces juste pour séparer des ressources légèrement différentes, telles que les versions du même logiciel: utiliser les labels pour distinguer les ressources dans le même namespace.
Cas d’utilisation des namespaces, cette liste n’est pas exhaustive et risque d’être modifiée (voir le blog de kubernetes)
- Séparer les différents espaces (Production, Développement, etc.)
- Gérer les contrôles d’accès via RBAC, afin de n’authoriser que les utilisateurs avec les certaines permissions[1] pour accéder aux resources du cluster (rôle d’administrateur, etc.)
- Assigner son propre cluster à chacun des client pour une demande bien précise. Par exemple,
- Quota sur les resources par cluster (CPU, RAM, etc.)
- Isolation[1] d’un projet
- etc.
Kubernetes démarre initiallement avec quatre namespaces (voir les infos de la documentation officielle):
$ kubectl get namespaces
NAME STATUS AGE
default Active 163d
kube-node-lease Active 163d
kube-public Active 163d
kube-system Active 163d
default
Le namespace par défaut
kube-system
Le namespace pour les objets créés par Kubernetes lui-même
kube-public
Ce namespace est créé automatiquement et est visible par tous les utilisateurs (y compris ceux qui ne sont pas authentifiés)
kube-node-lease
Ce namespace contient les objets de bail associés à chaque nœud, ce qui améliore les performances des pulsations du nœud à mesure que le cluster évolue
2.2 Création d’un nouveau namespace
Avant de penser à créer votre namespace, je tiens à ajouter l’information suivante, toujours tirée de la page officielle de kubernetes:
Note: Évitez de créer des namespaces avec le préfixe kube-
, car il est réservé aux namespaces système de Kubernetes.
Les namespaces peuvent être créés:
- En ligne de commande,
- Pour créer un namespace
alpha-namespace
avec pour label name=alpha
,
$ kubectl create namespace alpha-namespace
$ kubectl label namespace alpha-namespace name=alpha
- Avec un fichier YAML,
- Récupérer le fichier de configuration du namespace créé par défaut
$ kubectl get ns default -o yaml > beta-namespace.yaml
-
- Editer le contenu du fichier
namespace-dev.yaml
- Enfin, supprimer les informations inutiles, et n’oubliez pas d’ajouter un label pour ce namespace
$ vim beta-namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
name: beta-namespace
labels:
name: beta
$ kubectl apply -f beta-namespace.yaml
Vérifier ensuite que les nouveaux namespaces ont bien été créé sans problème.
$ kubectl get ns --show-labels
NAME STATUS AGE LABELS
alpha-namespace Active 16m name=alpha
beta-namespace Active 10s name=beta
default Active 175d <none>
kube-node-lease Active 175d <none>
kube-public Active 175d <none>
kube-system Active 175d <none>
2.3 Création de pods dans un namespace dédié
Par défaut, tous les nouveaux pods seront créés dans le namespace default
.
Dans cette partie, je vais explicitement choisir mon namespace à utiliser pour déployer mes Pods.
- Création d’un pods dans
alpha-namespace
$ kubectl run nginx --image=nginx -l environment=qa -n alpha-namespace
$ kubectl get pod -A -l environment --show-labels
NAMESPACE NAME READY STATUS RESTARTS AGE LABELS
alpha-namespace nginx 1/1 Running 0 5m50s environment=qa
default frontend-8g474 1/1 Running 0 167m environment=dev,tier=frontend
default frontend-bzfj2 1/1 Running 0 167m environment=prod,tier=frontend
default frontend-fzfnd 1/1 Running 0 167m environment=prod,tier=frontend
default nginx 1/1 Running 0 77m environment=qa
L’option -A
(–all-namespaces) nous permet d’afficher les pods de tous les namespaces, et qui ont pour label "environment=VALEUR"
.
- Application d’un fichier YAML pour la création de Pods dans
beta-namespace
Je vais réutiliser le fichier frontend.yaml
,
$ kubectl create -f frontend.yaml -n beta-namespace
Sinon, ajouter le nom du namespace dans le fichier yaml initial, dans la partie metatada.
metadata:
name: frontend
namespace: app
Puis lancer la commande
$ kubectl create -f frontend.yaml
Liste des pods dans beta-namespace
,
$ kubectl get pod -n beta-namespace --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-7nwkw 1/1 Running 0 105s tier=frontend
frontend-mzkqj 1/1 Running 0 105s tier=frontend
frontend-snkwb 1/1 Running 0 105s tier=frontend
2.4 Basculer entre les differents namespaces
Le basculement d’un namespace à un autre nous facilite l’utilisation de la commande kubectl
, puisqu’il n’est plus nécessaire de préciser le nom du namespace dans lequel nous souhaitons travailler.
Ainsi, une fois dans le namespace choisi, vous pouvez omettre l’option --namespace=NAMESPACE
à la fin de chaque commande.
La commande à utiliser quand le namespace est déjà créé, est la suivante:kubectl config set-context --current --namespace=NAMESPACE
.
Ici, l’option --current
fait référence au context courant, que vous pouvez afficher par,
$ kubectl config current-context
kubernetes-admin@kubernetes
Un context
kubernetes est décrit comme un ensemble de paramètres d’accès utilisé par un compte utilisateur pour accéder à un cluster ou à un namespace. Je ne vais pas rentrer dans les détails, puisque nous n’allons pas modifier cette option. Si vous souhaitez le faire, jettez un coup d’oeil à la page de kubernetes.
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* kubernetes-admin@kubernetes kubernetes kubernetes-admin
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.0.200:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
Passer maintenant d’un namespace à un autre, en activant ce dernier comme le namespace par défaut.
$ kubectl config set-context --current --namespace=beta-namespace
Context "kubernetes-admin@kubernetes" modified.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
frontend-7nwkw 1/1 Running 0 144m
frontend-mzkqj 1/1 Running 0 144m
frontend-snkwb 1/1 Running 0 144m
$ kubectl config set-context --current --namespace=alpha-namespace
Context "kubernetes-admin@kubernetes" modified.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 173m
Pour revenir au namespace initial, les deux options ci-dessous aboutissent au même résultat.
- Remplacez le nom du NAMESPACE par « default »
- Ne mettez rien après
--namespace=
$ kubectl config set-context --current --namespace=
Context "kubernetes-admin@kubernetes" modified.
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
frontend-8g474 1/1 Running 0 5h35m
frontend-bzfj2 1/1 Running 0 5h35m
frontend-fzfnd 1/1 Running 0 5h35m
nginx 1/1 Running 0 4h5m
2.5 Terminaison de pods
Appliqué à plusieurs namespaces, la terminaison de Pods et des différentes resources peut se faire, soit:
- En basculant de le namespace concerné, et y faire le ménage
- En ajoutant le nom du namspace à la fin de chaque commande
kubectl
- En supprimant le namespace
C’est cette dernière option que je vais choisir pour supprimer toutes les resources en dehors du namespace default
, y compris les namespaces nouvellement créés.
$ kubectl delete ns alpha-namespace
$ kubectl delete ns beta-namespace
Pour supprimer tous les Pods du namespace default
, qui est le dernier namespace actif du lab,
$ kubectl delete pod --all -n default
pod "frontend-8g474" deleted
pod "frontend-bzfj2" deleted
pod "frontend-fzfnd" deleted
pod "nginx" deleted
Sinon, vous pouvez utiliser les labels pour supprimer toutes les resources déployées dans ce lab.
$ kubectl apply -f frontend.yaml
$ kubectl get all -l tier=frontend
NAME READY STATUS RESTARTS AGE
pod/frontend-fc7p9 1/1 Running 0 35s
pod/frontend-gh9wr 1/1 Running 0 35s
pod/frontend-jnkqt 1/1 Running 0 35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/frontend ClusterIP 10.96.168.101 80/TCP 6h54m
NAME DESIRED CURRENT READY AGE
replicaset.apps/frontend 3 3 3 35s
$ kubectl delete all -l tier=frontend
pod "frontend-fc7p9" deleted
pod "frontend-gh9wr" deleted
pod "frontend-jnkqt" deleted
service "frontend" deleted
replicaset.apps "frontend" deleted
2.6 Network Namespace (netns)
Cette partie a déjà été traité dans le chap 9, dont je vais reprendre ici un extrait.
Chaque espace de nom, peut fournir à chacun des Pods toutes les resources liées au réseau.
Entre autre, chaque pod peut avoir,
- Une adresse IP privée
- Sa propre table de routage, avec ses règles de parefeux, etc.
Ce chapitre est maintenant terminé. J’espère vous avoir convaincu de l’utilité des labels!
Sources
9 Best Practices and Examples for Working with Kubernetes Labels
Labels and Selectors
Recommended Labels
Share a Cluster with Namespaces
Kubernetes Namespace
How to switch namespace in kubernetes