k8s之存储卷及pvc

本是古典 何须时尚 2021-11-13 16:56 367阅读 0赞

1.存储卷概述

因为pod是有生命周期的,pod一重启,里面的数据就没了,所以我们需要数据持久化存储,在k8s中,存储卷不属于容器,而是属于pod,也就是说同一个pod中的容器可以共享一个存储卷,存储卷可以是宿主机上的目录,也可以是挂载在宿主机上的外部设备.

存储卷类型:

emptyDIR存储卷:pod一重启,存储卷也删除,这叫emptyDir存储卷,一般用于当做临时空间或缓存关系;

hostPath存储卷:宿主机上目录作为存储卷,这种也不是真正意义实现了数据持久性;

SAN(iscsi)或NAS(nfs、cifs):网络存储设备;

分布式存储:ceph,glusterfs,cephfs,rbd

云存储:亚马逊的EBS,Azure Disk,阿里云,关键数据一定要有异地备份

a.emptyDIR存储卷

  1. vim podtest/pod-vol-demo.yaml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: pod-demo
  6. namespace: default
  7. labels:
  8. app: myapp
  9. tier: frontend
  10. spec:
  11. containers:
  12. - name: myapp
  13. image: ikubernetes/myapp:v2
  14. imagePullPolicy: IfNotPresent
  15. ports:
  16. - name: http
  17. containerPort: 80
  18. volumeMounts:
  19. - name: html
  20. mountPath: /usr/share/nginx/html
  21. - name: busybox
  22. image: busybox:latest
  23. imagePullPolicy: IfNotPresent
  24. volumeMounts:
  25. - name: html
  26. mountPath: /data/
  27. command: ["/bin/sh"]
  28. args: ["-c","while true;do echo $(date) >> /data/index.html; sleep 10;done"]
  29. volumes:
  30. - name: html
  31. emptyDir: {}
  32. volumeMounts:把哪个存储卷挂到pod中的哪个目录下
  33. emptyDir:不设置意味着对这个参数下的两个选项不做限制

b.hostPath:使用宿主机上目录作为存储卷

  1. kubectl explain pods.spec.volumes.hostPath.type
  2. DirectoryOrCreate:要挂载的路径是一个目录,不存在就创建目录;
  3. Directory:宿主机上必须实现存在目录,如果不存在就报错;
  4. FileOrCreate:表示挂载的是文件,如果不存在就创建;
  5. File:表示要挂载的文件必须事先存在,否则就报错.
  6. cat pod-hostpath-vol.yaml
  7. apiVersion: v1
  8. kind: Pod
  9. metadata:
  10. name: pod-vol-hostpath
  11. namespace: default
  12. spec:
  13. containers:
  14. - name: myapp
  15. image: ikubernetes/myapp:v2
  16. volumeMounts:
  17. - name: html
  18. mountPath: /usr/share/nginx/html/
  19. volumes:
  20. - name: html
  21. hostPath:
  22. path: /data/pod/volume1
  23. type: DirectoryOrCreate
  24. hostPath:宿主机上的目录.
  25. volumes的名字可以随便取,这是存储卷的名字,但是上面的volumeMounts指定时,
  26. name必须和存储卷的名字一致,这样两者才建立了联系.

c.nfs做共享存储

  1. 这里为了方便,把master节点当做nfs存储,三个节点均执行
  2. yum -y install nfs-utils # 然后在master上启动nfs
  3. mkdir /data/volumes
  4. cat /etc/exports
  5. /data/volumes 10.0.0.0/16(rw,no_root_squash)
  6. systemctl start nfs
  7. node1node2上试挂载
  8. mount -t nfs k8s-master:/data/volumes /mnt
  9. cat pod-vol-nfs.yaml
  10. apiVersion: v1
  11. kind: Pod
  12. metadata:
  13. name: pod-vol-nfs
  14. namespace: default
  15. spec:
  16. containers:
  17. - name: myapp
  18. image: ikubernetes/myapp:v2
  19. volumeMounts:
  20. - name: html
  21. mountPath: /usr/share/nginx/html/
  22. volumes:
  23. - name: html
  24. nfs:
  25. path: /data/volumes
  26. server: k8s-master
  27. kubectl apply -f pod-vol-nfs.yaml
  28. 此时不管pod被建立在哪个节点上,对应节点上是不存放数据的,数据都在nfs主机上

d.pvc和pv

用户只需要挂载pvc到容器中而不需要关注存储卷采用何种技术实现.pvc和pv的关系与pod和node关系类似,前者消耗后者的资源,pvc可以向pv申请指定大小的存储资源并设置访问模式.

1288851-20190616123023318-1738114863.png

在定义pod时,我们只需要说明我们要一个多大的存储卷就行了,pvc存储卷必须与当前namespace的pvc建立直接绑定关系,pvc必须与pv建立绑定关系,而pv是真正的某个存储设备上的空间.

一个pvc和pv是一一对应关系,一旦一个pv被一个pvc绑定了,那么这个pv就不能被其他pvc绑定了,一个pvc是可以被多个pod所访问的,pvc在名称空间中,pv是集群级别的.

1288851-20190616123126211-16822312.png

将master作为存储节点,创建挂载目录

  1. cd /data/volumes && mkdir v{1,2,3,4,5}
  2. cat /etc/exports
  3. /data/volumes/v1 10.0.0.0/16(rw,no_root_squash)
  4. /data/volumes/v2 10.0.0.0/16(rw,no_root_squash)
  5. /data/volumes/v3 10.0.0.0/16(rw,no_root_squash)
  6. exportfs -arv
  7. showmount -e
  8. kubectl explain pv.spec.nfs
  9. accessModes模式有:
  10. ReadWriteOnce:单路读写,可以简写为RWO;
  11. ReadOnlyMany:多路只读,可以简写为ROX;
  12. ReadWriteMany:多路读写,可以简写为RWX
  13. # 先将存储设备定义为pv
  14. cat pv-demo.yaml
  15. apiVersion: v1
  16. kind: PersistentVolume
  17. metadata:
  18. name: pv001 # 定义pv时不用加名称空间,因为pv是集群级别
  19. labels:
  20. name: pv001
  21. spec:
  22. nfs:
  23. path: /data/volumes/v1
  24. server: k8s-master
  25. accessModes: ["ReadWriteMany","ReadWriteOnce"]
  26. capacity: # 分配磁盘空间大小
  27. storage: 3Gi
  28. ---
  29. apiVersion: v1
  30. kind: PersistentVolume
  31. metadata:
  32. name: pv002
  33. labels:
  34. name: pv002
  35. spec:
  36. nfs:
  37. path: /data/volumes/v2
  38. server: k8s-master
  39. accessModes: ["ReadWriteOnce"]
  40. capacity:
  41. storage: 5Gi
  42. ---
  43. apiVersion: v1
  44. kind: PersistentVolume
  45. metadata:
  46. name: pv003
  47. labels:
  48. name: pv003
  49. spec:
  50. nfs:
  51. path: /data/volumes/v3
  52. server: k8s-master
  53. accessModes: ["ReadWriteMany","ReadWriteOnce"]
  54. capacity:
  55. storage: 8Gi
  56. kubectl apply -f pv-demo.yaml
  57. kubectl get pv
  58. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS
  59. pv001 3Gi RWO,RWX Retain Available
  60. pv002 5Gi RWO Retain Available
  61. pv003 8Gi RWO,RWX Retain Available

回收策略:

如果某个pvc在pv里面存数据了,后来pvc删了,那么pv里面的数据怎么处理

reclaim_policy:即pvc删了,但pv里面的数据不删除,还保留着;

recycle:即pvc删了,那么就把pv里面的数据也删了;

delete:即pvc删了,那么就把pv也删了.

  1. # 创建pvc的清单文件
  2. kubectl explain pods.spec.volumes.persistentVolumeClaim
  3. cat pod-vol-pvc.yaml
  4. apiVersion: v1
  5. kind: PersistentVolumeClaim # 简称pvc
  6. metadata:
  7. name: mypvc
  8. namespace: default # pvc和pod在同一个名称空间
  9. spec:
  10. accessModes: ["ReadWriteMany"] # 一定是pv策略的子集
  11. resources:
  12. requests:
  13. storage: 7Gi # 申请一个大小至少为7G的pv
  14. ---
  15. apiVersion: v1
  16. kind: Pod
  17. metadata:
  18. name: pod-vol-pvc
  19. namespace: default
  20. spec:
  21. containers:
  22. - name: myapp
  23. image: ikubernetes/myapp:v1
  24. volumeMounts:
  25. - name: html # 使用的存储卷的名字
  26. mountPath: /usr/share/nginx/html/ #挂载路径
  27. volumes:
  28. - name: html
  29. persistentVolumeClaim:
  30. claimName: mypvc # 表示要使用哪个pvc

所以pod的存储卷类型如果是pvc,则:pod指定的pvc需要先匹配一个pv,才能被pod所挂载,在k8s 1.10之后,不能手工从底层删除pv.

参考博客:http://blog.itpub.net/28916011/viewspace-2214804/

转载于:https://www.cnblogs.com/fawaikuangtu123/p/11031171.html

发表评论

表情:
评论列表 (有 0 条评论,367人围观)

还没有评论,来说两句吧...

相关阅读