Statefulset Kubernetes avec volume persistant NFS

Oct 16 2020

J'ai un kubernetescluster et j'ai un déploiement simple mongodbavec NFSun ensemble de volumes persistants. Cela fonctionne bien, mais comme des ressources telles que des bases de données sont statefulenvisagées Statefulsetpour le mongodb, mais maintenant, le problème est que lorsque je parcoure la documentation, statefulset a volumeClaimTemplatesau lieu de volumes(dans les déploiements).

Mais maintenant, le problème vient.

dans un deploymentfaire comme ça:

PersistentVolume-> PersistentVolumeClaim->Deployment

Mais comment pouvons-nous faire cela Statefulset?

Est-ce comme:

volumeClaimTemplates -> StatefulSet

Comment puis-je définir un PersistentVolumepour le volumeClaimTemplates. Si nous ne l' utilisons pas PersistentVolumepour StatefulSet, comment fonctionne- t - il créer du volume et il ne crée WHERE les volumes? Est-ce dans les hostmachines (c'est-à-dire les nœuds de travail Kubernetes)?

Étant donné que j'utilise un NFSapprovisionneur distinct pour le mongodbdéploiement (avec replicasset = 1), comment puis-je utiliser la même configuration avec StatefulSet?

Voici le my mongo-deployment.yaml-> que je vais transformer en un statefulset comme indiqué dans le deuxième extrait de code ( mongo-stateful.yaml)

  1. mongo-deployment.yaml
<omitted>
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    name: mynfs # name can be anything
spec:
  storageClassName: manual # same storage class as pvc
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: <nfs-server-ip>
    path: "/srv/nfs/mydata" 
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany #  must be the same as PersistentVolume
  resources:
    requests:
      storage: 1Gi          
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment    
  labels:
    name: mongodb
spec:
  selector:
    matchLabels:
      app: mongodb
  replicas: 1
  template:
    metadata:
      labels: 
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo
        ports:
        -  containerPort: 27017
        ... # omitted some parts for easy reading
        volumeMounts:
        - name: data  
          mountPath: /data/db
      volumes: 
        - name: data
          persistentVolumeClaim: 
            claimName: task-pv-claim    
  1. mongo-stateful.yaml
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    name: mynfs # name can be anything
spec:
  storageClassName: manual # same storage class as pvc
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  nfs:
    server: <nfs-server-ip>
    path: "/srv/nfs/mydata" 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb-statefulset
spec:
  selector:
    matchLabels:
      name: mongodb-statefulset
  serviceName: mongodb-statefulset
  replicas: 2
  template:
    metadata:
      labels:
        name: mongodb-statefulset
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: mongodb
        image: mongo:3.6.4
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: db-data
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: db-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "manual"
      resources:
        requests:
          storage: 2Gi

Mais cela ne fonctionne pas ( mongo-stateful.yaml) les pods sont dans l' pendingétat comme quand je le décris le montre:

default-scheduler 0/3 nœuds sont disponibles: 1 nœud (s) avait un taint {node-role.kubernetes.io/master:}, que le pod n'a pas toléré, 2 pod a un PersistentVolumeClaims immédiat non lié

PS: le déploiement fonctionne correctement sans aucune erreur, le problème est avec Statefulset

Quelqu'un peut-il s'il vous plaît m'aider, comment écrire un statefulset avec des volumes?

Réponses

1 fjammes Oct 16 2020 at 14:50

Si votre classe de stockage ne prend pas en charge le provisionnement de volume dynamique, vous devez créer manuellement des PV et des PVC associés , en utilisant des fichiers yaml, puis les volumesClaimTemplates permettront de lier les PVC existants aux pods de votre statefulset.

Voici un exemple de travail: https://github.com/k8s-school/k8s-school/blob/master/examples/MONGODB-install.sh

Vous devriez:

  • exécutez-le localement sur https://kind.sigs.k8s.io/, qui prennent en charge l'approvisionnement dynamique en volume, donc ici les PVC et les PV seront créés automatiquement
  • exporter des fichiers yaml PV et PVC
  • utilisez ces fichiers yaml comme modèle pour créer vos PV et PVC pour votre backend NFS.

Voici ce que vous obtiendrez sur Kind:

$ ./MONGODB-install.sh + kubectl apply -f 13-12-mongo-configmap.yaml configmap/mongo-init created + kubectl apply -f 13-11-mongo-service.yaml service/mongo created + kubectl apply -f 13-14-mongo-pvc.yaml statefulset.apps/mongo created $ kubectl get pods
NAME      READY   STATUS    RESTARTS   AGE
mongo-0   2/2     Running   0          8m38s
mongo-1   2/2     Running   0          5m58s
mongo-2   2/2     Running   0          5m45s
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE database-mongo-0 Bound pvc-05247511-096e-4af5-8944-17e0d8222512 1Gi RWO standard 8m42s database-mongo-1 Bound pvc-f53c35a4-6fc0-4b18-b5fc-d7646815c0dd 1Gi RWO standard 6m2s database-mongo-2 Bound pvc-2a711892-eeee-4481-94b7-6b46bf5b76a7 1Gi RWO standard 5m49s $ kubectl get pv 
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                      STORAGECLASS   REASON   AGE
pvc-05247511-096e-4af5-8944-17e0d8222512   1Gi        RWO            Delete           Bound    default/database-mongo-0   standard                8m40s
pvc-2a711892-eeee-4481-94b7-6b46bf5b76a7   1Gi        RWO            Delete           Bound    default/database-mongo-2   standard                5m47s
pvc-f53c35a4-6fc0-4b18-b5fc-d7646815c0dd   1Gi        RWO            Delete           Bound    default/database-mongo-1   standard                6m1s

Et un dump d'un PVC (généré ici par volumeClaimTemplateprovisionnement de volume dynamique de type odf):

$ kubectl get pvc database-mongo-0 -o yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    pv.kubernetes.io/bind-completed: "yes"
    pv.kubernetes.io/bound-by-controller: "yes"
    volume.beta.kubernetes.io/storage-provisioner: rancher.io/local-path
    volume.kubernetes.io/selected-node: kind-worker2
  creationTimestamp: "2020-10-16T15:05:20Z"
  finalizers:
  - kubernetes.io/pvc-protection
  labels:
    app: mongo
  managedFields:
    ...
  name: database-mongo-0
  namespace: default
  resourceVersion: "2259"
  selfLink: /api/v1/namespaces/default/persistentvolumeclaims/database-mongo-0
  uid: 05247511-096e-4af5-8944-17e0d8222512
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard
  volumeMode: Filesystem
  volumeName: pvc-05247511-096e-4af5-8944-17e0d8222512
status:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  phase: Bound

Et le PV associé:

kubectl get pv pvc-05247511-096e-4af5-8944-17e0d8222512 -o yaml     
apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/provisioned-by: rancher.io/local-path
  creationTimestamp: "2020-10-16T15:05:23Z"
  finalizers:
  - kubernetes.io/pv-protection
  managedFields:
    ...
  name: pvc-05247511-096e-4af5-8944-17e0d8222512
  resourceVersion: "2256"
  selfLink: /api/v1/persistentvolumes/pvc-05247511-096e-4af5-8944-17e0d8222512
  uid: 3d1e894e-0924-411a-8378-338e48ba4a28
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 1Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: database-mongo-0
    namespace: default
    resourceVersion: "2238"
    uid: 05247511-096e-4af5-8944-17e0d8222512
  hostPath:
    path: /var/local-path-provisioner/pvc-05247511-096e-4af5-8944-17e0d8222512_default_database-mongo-0
    type: DirectoryOrCreate
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - kind-worker2
  persistentVolumeReclaimPolicy: Delete
  storageClassName: standard
  volumeMode: Filesystem
status:
  phase: Bound