Présentation

local-path-provisioner est un opĂ©rateur Kubernetes permettant d’utiliser les disques locaux (comprendre un disque dur ou disque SSD ou disque NVME, etc.) comme support pour provisionner des volumes persistants.

En somme vous transformer un espace disque en volume persistant sous Kubernetes. Pratique, non ?

Fichiers YAML d’exemples

Le code YAML prĂ©sentĂ© ici se retrouve dans l’ historique du fichier local-path-provisioner.yaml de mon infra sur Gitlab .

Et le fichier storage_class.yaml de mon infra sur Gitlab .

Tout est basé sur le fichier README.md du dépôt Github du projet local-path-provisioner .

local-path-provisioner.yaml

---
apiVersion: v1
kind: Namespace
metadata:
  name: local-path-storage
  labels:
    pod-security.kubernetes.io/enforce: privileged
    pod-security.kubernetes.io/enforce-version: latest
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: local-path-provisioner-service-account
  namespace: local-path-storage
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: local-path-provisioner-role
rules:
  - apiGroups: [""]
    resources: ["nodes", "persistentvolumeclaims", "configmaps"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes", "endpoints", "pods"]
    verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: local-path-provisioner-bind
subjects:
  - kind: ServiceAccount
    name: local-path-provisioner-service-account
    namespace: local-path-storage
roleRef:
  kind: ClusterRole
  name: local-path-provisioner-role
  apiGroup: rbac.authorization.k8s.io
---
kind: ConfigMap
apiVersion: v1
metadata:
  name: local-path-config
  namespace: local-path-storage
data:
  config.json: |-
    {
            "nodePathMap":[
            {
                    "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
                    "paths":["/var/mnt/local-storage"]
            }
            ]
    }    
  setup: |-
    #!/bin/sh
    set -eu
    mkdir -m 0777 -p "$VOL_DIR"    
  teardown: |-
    #!/bin/sh
    set -eu
    rm -rf "$VOL_DIR"    
  helperPod.yaml: |-
    apiVersion: v1
    kind: Pod
    metadata:
      name: helper-pod
    spec:
      priorityClassName: system-node-critical
      tolerations:
        - key: node.kubernetes.io/disk-pressure
          operator: Exists
          effect: NoSchedule
      containers:
      - name: helper-pod
        image: busybox
        imagePullPolicy: IfNotPresent    
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: local-path-provisioner
  namespace: local-path-storage
  labels:
    app: local-path-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: local-path-provisioner
  template:
    metadata:
      labels:
        app: local-path-provisioner
    spec:
      serviceAccountName: local-path-provisioner-service-account
      containers:
        - name: provisioner
          image: rancher/local-path-provisioner:v0.0.31
          imagePullPolicy: IfNotPresent
          command:
            - local-path-provisioner
            - --debug
            - start
            - --config
            - /etc/config/config.json
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config/
      volumes:
        - name: config-volume
          configMap:
            name: local-path-config

storage_class.yaml

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-path
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer

Explications

Tout va se jouer dans l’Ă©lĂ©ment suivant :

kind: ConfigMap
apiVersion: v1
metadata:
  name: local-path-config
  namespace: local-path-storage
data:
  config.json: |-
    {
            "nodePathMap":[
            {
                    "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
                    "paths":[
                        "/var/mnt/local-storage",
                        "/mon/second/chemin"
                    ]
            }
            ]
    }    
  setup: |-

SpĂ©cifiquement le paths qui, dans l’exemple ci-dessus, pointe sur /var/mnt/local-storage.

Il s’agit donc de modifier ce chemin pour utiliser une destination qu’on souhaite utiliser pour nos volumes persistants dans Kubernetes. Voire plusieurs paths.

Ensuite il va falloir créer un storage class qui fait le lien avec notre ConfigMap. Par exemple :

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: rancher.io/local-path
parameters:
  configMapName: local-path-config
  configMapNamespace: local-path-storage
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain # conserve les données

Si, en revanche, on a plusieurs chemins disponibles, alors le storageclass ressemblera à :

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: bulk-local-storage
provisioner: rancher.io/local-path
parameters:
  nodePath: /mnt/hdd-storage
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain

Liens utiles