Logo K8S

Kubernetes : Les bases

1 – Les PODs :

Dans un cluster Kubernetes un Pod est un groupe d’un ou plusieurs conteneurs qui partage la même couche réseau et le même stockage.

Depuis un manisfest :

apiVersion: v1
kind: Pod
metadata:
  name: monpodnginx
spec:
  containers:
  - name: monnginx
    image: nginx
    ports:
    - containerPort: 80

Puis on applique la configuration en appelant le fichier depuis Kubernetes

kubectl apply -f monpodnginx.yml

Nous pouvons aussi le faire directement en ligne de commande :

kubectl run monpodnginx --image=nginx --port=80

Nous vérifions que notre nouveau POD est bien créer et démarrer

kubectl get pod

NAME           READY   STATUS    RESTARTS   AGE
monpodnginx    1/1     Running   0          4h16m

Notre pod va se voir attribuer une IP au sein du cluster Kubernetes que nous allons pouvoir interroger seulement depuis celui-ci :

kubectl get pod -o wide

NAME          READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES

monpodnginx   1/1     Running   0          24s   10.244.3.10   ks8-node-2   none           none

Depuis le master nous pouvons effectuer un curl pour valider la réponse du serveur web :

curl 10.244.3.10 80

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

On peut se connecter au pod pour modifier la page html de cette manière :

kubectl exec monpodnginx -it sh

Pour supprimer le pod :

kubectl delete pod monpodnginx

ou

kubectl delete pod --all

2 – Déploiements et services

Un déploiement est une représentation logique d’un ou plusieurs pod (configuration).

Un service est un moyen d’accéder à nos pods

A – Création d’un déploiement

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

ou directement en commandes :

kubectl create deployment monpodnginx --image=nginx

Nous pouvons afficher notre déploiement avec cette commande :

kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   1/1     1            1           24s

Notre déploiement contient un pod :

kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-d46f5678b-ltrmk   1/1     Running   0          92s

B – Création du service :

Pour que notre POD soit accessible depuis une machine extérieur à notre cluster K8S nous allons créer un service :

kubectl create service nodeport monpodnginx --tcp=8080:80

Le port 8080 correspond au port qui pourra être utilisé par un autre pod pour communiquer avec notre pod nginx (ClusterPort).

Le port 80 correspond au port en écoute du serveur nginx (TargetPort).

Le port qui sera joignable depuis l’extérieur sera généré automatiquement dans le range de port suivant 30000-32767 (NodePort).

kubectl get service
NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
monpodnginx   NodePort    10.102.58.21   none>        8080:31618/TCP   5s

Nodeport = Expose le service pour qu’il soit joignable depuis l’extérieur du cluster K8S via un port dans le range suivant : 30000-32767
Clusterip = Expose le service sur une IP interne au cluster. Il sera seulement accessible depuis un autre POD du cluster

Pour y accéder depuis notre navigateur il suffit d’indiquer l’ip de notre master et le port générer automatiquement lors de la création du service ici : 31618

Welcome to nginx - page par défaut de nginx

Il est aussi possible de passer par la commande ci-dessous qui permet d’exposer une ressource :

kubectl expose deployment monpodnginx --type NodePort --port 80

ou par le biais d’un manisfest :

apiVersion: v1
kind: Service
metadata:
  name: monpodnginx
spec:
  selector:
    app: monpodnginx
  type: NodePort
  ports:
    - protocol: TCP
      port: 8080
      nodePort: 31618
      targetPort: 80

3 – Les volumes persistants :

Nous allons maintenant associer un volume à notre pod. Ici j’ai monté un partage nfs sur mon master. Le stockage sera donc accessible depuis n’importe quelle nœud de notre cluster k8s.

A – Création du serveur nfs

apt-get install nfs-kernel-server
vi /etc/export
/share/nfs 192.168.4.0/24(rw,sync,no_root_squash)
exportfs -a
/etc/init.d/nfs-kernel-server start

Depuis un nœud K8S nous pouvons essayer de monter le partage de cette manière :

root@k8s-node-1:~# mount -t nfs k8s-master.ophyde.tech:/share/nfs /tmp
root@k8s-node-1:~# umount /tmp

B – Persistant Volume :

Nous allons commencer par créer un « Persistant Volume ».

Le Persistant Volume (PV) correspond à un élément de stockage qui a été provisionné par l’administrateur. Il s’agit d’une ressource de stockage dans le cluster au même titre qu’un nœud du cluster. Il comporte les détails techniques d’accès au stockage (NFS, ISCSI etc)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001-nfs
spec:
  storageClassName: nfs-nas
  capacity: 
    storage: 2Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: k8s-master.ophyde.tech
    path: /share/nfs

Les modes d’accès sont suivants :

  • ReadWriteOnce — le volume peut être monté en lecture-écriture par un seul nœud
  • ReadOnlyMany — le volume peut être monté en lecture seule par plusieurs nœuds
  • ReadWriteMany — le volume peut être monté en lecture-écriture par de nombreux nœuds
kubectl apply -f pvnas.yaml

On affiche notre Persistant Volume :

kubectl get pv

NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001-nfs   2Gi        RWX            Retain           Available           nfs-nas                 19s

C – Persistant Volume Claim :

Le Persistant Volume Claim (PVC) correspond à un élément de stockage qui a été provisionné par l’utilisateur. Il s’agit d’une ressource de stockage dans le cluster au même titre qu’un POD. Cela permet à l’utilisateur de consommer des ressources de stockage abstraites sans avoir connaissance du type de stockage. L’utilisateur ne connait donc pas les détails technique de mise en œuvre du stockage.

Nous allons maintenant créer un Persistant Volume Claim qui pourra être utiliser par un conteneur appartenant à un de nos POD.

apiVersion: v1
kind: PersistentVolumeClaim
metadata: 
  name: pvc001-nfs
spec:
  storageClassName: nfs-nas
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

kubectl apply -f pvnas.yaml

La liaison entre le PV et le PVC se fait par le biais du storageClassName ici il correspond à nfs-nas

kubectl get pv,pvc
NAME                         CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
persistentvolume/pv001-nfs   2Gi        RWX            Retain           Bound    default/pvc001-nfs   nfs-nas                 14s

NAME                               STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc001-nfs   Bound    pv001-nfs   2Gi        RWX            nfs-nas        10s

D – Utilisation du stockage par notre pod

Nous souhaitons déporter le répertoire /usr/share/nginx/html qui contient nos pages web de notre conteneur nginx sur notre stockage persistant.

Les pods accèdent au stockage en utilisant le PVC comme volume.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx

    spec:
      containers:
      - name: monnginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
          - name: www
            mountPath: /usr/share/nginx/html
      
      volumes:
      - name: www
        persistentVolumeClaim:
          claimName: pvc001-nfs

On lance la création de notre POD :

kubectl apply -f monpodnginx.yaml

kubectl get pod -o wide

NAME          READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES
monpodnginx   1/1     Running   0          4m    10.244.3.11   k8s-node-2   none           none

kubectl describe pod

Name:         monpodnginx
Namespace:    default
Priority:     0
--- Ignored line ---
Volumes:
  www:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  pvc001-nfs
    ReadOnly:   false
--- Ignored line ---

Et nous exposons notre pod pour qu’il soit joignable de l’extérieur :

kubectl create service nodeport nginx-deployment --tcp=8080:80

kubectl get service -o wide
NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE     SELECTOR
nginx-deployment   NodePort    10.104.18.232   none>        8080:31832/TCP   4m44s   app=nginx-deployment

Le POD me retourne un 403 Forbiden car il ne dispose pas d’un index.html (rappelez-vous nous avons monté notre pvc directement dans le dossier contenant nos pages web)

403 Forbidden - Page afficher par le serveur nginx

Pour remédiez à cela il suffit de rajouter sur notre stockage persistant une page html.

root@k8s-master-1:/#   echo "Mon pod nginx 1" >> /share/nfs/index.html

Mon pod nginx 1 - Page afficher par nginx après modification de l'index.html

Si vous souhaitez installer votre propre cluster vous pouvez vous reporter à cet article

Source :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.