Kubernetes statefulset com volume NFS persistente
Eu tenho um kubernetescluster e tenho uma implantação simples mongodbcom NFSconjunto de volume persistente. Funciona bem, mas como recursos como bancos de dados stateful, pensei em usar Statefulsetpara o mongodb, mas agora o problema é que, quando analiso a documentação, o statefulset tem em volumeClaimTemplatesvez de volumes(em implantações).
Mas agora vem o problema.
em um deploymentfaça assim:
PersistentVolume-> PersistentVolumeClaim->Deployment
Mas como podemos fazer isso Statefulset?
É como:
volumeClaimTemplates -> StatefulSet
Como posso definir um PersistentVolumepara o volumeClaimTemplates. Se não usarmos PersistentVolumepara StatefulSet, como ele cria o volume e ONDE ele cria os volumes? Está em hostmáquinas (ou seja, nós de trabalho do Kubernetes)?
Como tenho um NFSprovisionador separado que estou usando para a mongodbimplantação (com replicasset = 1), como posso usar a mesma configuração StatefulSet?
Aqui está o my mongo-deployment.yaml-> que irei transformar em um statefulset, conforme mostrado no segundo trecho de código ( mongo-stateful.yaml)
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
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
Mas isso não está funcionando ( mongo-stateful.yaml) os pods estão no pendingestado quando eu os descrevo:
default-scheduler 0/3 nodes estão disponíveis: 1 node (s) tinha taint {node-role.kubernetes.io/master:}, que o pod não tolerou, 2 pod tem PersistentVolumeClaims imediatos não ligados
PS: A implantação funciona bem sem erros, o problema é com Statefulset
Alguém pode me ajudar, como escrever um statefulset com volumes?
Respostas
Se sua classe de armazenamento não suportar provisionamento de volume dinâmico, você terá que criar PVs e PVCs associados manualmente , usando arquivos yaml, então o volumeClaimTemplates permitirá vincular PVCs existentes com seus pods de statefulset.
Aqui está um exemplo prático: https://github.com/k8s-school/k8s-school/blob/master/examples/MONGODB-install.sh
Você deve:
- execute-o localmente em https://kind.sigs.k8s.io/, que suportam provisionamento de volume dinâmico, então aqui os PVCs e PVs serão criados automaticamente
- exportar arquivos yaml de PVs e PVCs
- use esses arquivos yaml como modelo para criar seus PVs e PVCs para seu back-end NFS.
Aqui está o que você obterá no 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
E um dump de um PVC (gerado aqui por volumeClaimTemplateporque odf kind dynamic volume provisionning):
$ 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
E o PV relacionado:
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