一、数据持久化的类型:
1.emptyDir:只能作为临时存储使用。如果容器被删除,数据仍然存在,如果Pod被删除,数据也会被删除。
2.HostPath:使用场景不多,会增加Pod与节点之间的耦合性。
3.PV、PVC:基于NFS服务。PV状态必须为Available,访问模式必须相同及存储类的名称必须相同。
出错:Pod不断的重启:
1.swap没有关闭,导致集群运行不正常。
2.内存不足,运行服务也会重启。
注意:基于NFs创建PV,与PVC。
并且需要创建PV所需的宿主机目录。
二、做实验类比,如果集群中存在两个空间大小不同的PV,PVC如何跟PV关联。
1.创建PV(创建两个空间大小不同的PV,web-pv1和web-pv2)
1.[root@master yaml]# vim web1.yaml
2.
3.kind: PersistentVolume
4.apiVersion: v1
5.metadata:
6. name: web-pv1
7.spec:
8. accessModes:
9. - ReadWriteOnce
10. capacity:
11. storage: 1Gi
12. persistentVolumeReclaimPolicy: Recycle
13. storageClassName: nfs
14. nfs:
15. path: /nfsdata/web1
16. server: 192.168.1.1
17.
18.[root@master yaml]# mkdir /nfsdata/web1
19.[root@master yaml]# kubectl apply -f web1.yaml
20.persistentvolume/web-pv1 created
21.[root@master yaml]# kubectl get pv
22.NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
23.web-pv1 1Gi RWO Recycle Available nfs 7s
2.创建第二个Pv
1.[root@master yaml]# vim web2.yaml
2.kind: PersistentVolume
3.apiVersion: v1
4.metadata:
5. name: web-pv2
6.spec:
7. accessModes:
8. - ReadWriteOnce
9. capacity:
10. storage: 2Gi
11. persistentVolumeReclaimPolicy: Recycle
12. storageClassName: nfs
13. nfs:
14. path: /nfsdata/web2
15. server: 192.168.1.1
16.
17.[root@master yaml]# kubectl apply -f web2.yaml
18.persistentvolume/web-pv2 created
19.
20.[root@master yaml]# kubectl get pv
21.NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
22.web-pv1 1Gi RWO Recycle Available nfs 103s
23.web-pv2 2Gi RWO Recycle Available nfs 14s
3.创建PVCbr/>1.[root@master yaml]# vim web-pvc.yaml
2.kind: PersistentVolumeClaim br/>3.apiVersion: v1
4.metadata:
5. name: web-pvc
6.spec:
7. accessModes:
8. - ReadWriteOnce
9. resources:
10. requests:
11. storage: 1Gi
12. storageClassName: nfs
13.[root@master yaml]# kubectl apply -f web-pvc.yaml
14.persistentvolumeclaim/web-pvc created br/>15.[root@master yaml]# kubectl get pvc
16.NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE br/>17.web-pvc Bound web-pv1 1Gi RWO nfs 5s
18.[root@master yaml]# kubectl get pv
19.NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
20.web-pv1 1Gi RWO Recycle Bound default/web-pvc nfs 8m59s
21.web-pv2 2Gi RWO Recycle Available nfs 7m30s
通过上面的实验得出:
如果,K8s集群中,有很多类似的PV,PVC在去向PV申请空间的时候,不仅会考虑名称以及访问控制模式,还会考虑PVC申请空间的大小,会分配最合适大小的PV。
三、分析storageclass 资源对象的作用及优点。
1.使用PV和PVC可以实现数据持久化,假如我们的PV容量为10G,定义访问模式为RWO,而我们PVC申请的存储空间为5G,那么被申请的PV就有容量被浪费掉了,因为访问模式只能被单个节点挂载。还有,我们每次去创建PV也是比较麻烦的,所以这时候就有了动态的自动的创建所需要的PV了(Storage Class)。
Storage Class:即存储类,是K8s资源类型的一种,它是有管理员为管理PV更加方便创建的一个逻辑组,可以按照存储系统的性能高低,或者综合服务质量,备份策略等分类。不过k8s本身不知道类别到底是什么,它这是作为一个描述。
优点:支持PV的动态创建,当用户用到持久性存储时,不必再去提前创建PV,而是直接创建PVC就可以了,非常的方便。
存储类对象的名称很重要,并且除了名称之外,还有三个关键字段:
Provisioner(供给方、提供者):即提供了存储资源的存储系统。k8s内建有多重供给方,这些供给方的名字都以“kubernetes.io”为前缀。并且还可以自定义。
Parameters(参数):存储类使用参数描述要关联到的存储卷,注意不同的供给方参数也不同。
ReclaimPlicy:PV的回收策略。
关于Storage Class的详情介绍:
https://www.kubernetes.org.cn/pvpvcstorageclass
2.做一个自动创建PV的实验:
基于nginx运行一个web服务,使用Deployment资源对象,replicas=3.持久化存储目录为默认主目录,使用storageclass自动创建PV。
基于NFS:
1)首先NFS服务的开启:
1.[root@master yaml]# yum install -y nfs-utils rpcbind #这里注意三台都要安装NFS服务。
2.[root@master yaml]# vim /etc/exports
3./nfsdata *(rw,sync,no_root_squash)
4.[root@master yaml]# mkdir /nfsdata
5.[root@master yaml]# systemctl start rpcbind
6.[root@master yaml]# systemctl start nfs-server.service
7.[root@master yaml]# showmount -e
8.Export list for master:
9./nfsdata *
2)创建RBAC授权:
1.[root@master yaml]# vim rbac-rolebind.yaml #为了给SC资源操作K8s集群的权限。
2.
3.kind: Namespace
4.apiVersion: v1
5.metadata:
6. name: lbs-test
7.---
8.apiVersion: v1
9.kind: ServiceAccount #创建Rbac授权用户。及定义权限。
10.metadata:
11. name: nfs-provisioner
12. namespace: lbs-test
13.---
14.apiVersion: rbac.authorization.k8s.io/v1
15.kind: ClusterRole
16.metadata:
17. name: nfs-provisioner-runner
18. namespace: lbs-test
19.rules:
20. - apiGroups: [""]
21. resources: ["persistentvolumes"]
22. verbs: ["get", "list", "watch", "create", "delete"]
23. - apiGroups: [""]
24. resources: ["persistentvolumeclaims"]
25. verbs: ["get", "list", "watch", "update"]
26. - apiGroups: ["storage.k8s.io"]
27. resources: ["storageclasses"]
28. verbs: ["get", "list", "watch"]
29. - apiGroups: [""]
30. resources: ["events"]
31. verbs: ["watch", "create", "update", "patch"]
32. - apiGroups: [""]
33. resources: ["services", "endpoints"]
34. verbs: ["get","create","list", "watch","update"]
35. - apiGroups: ["extensions"]
36. resources: ["podsecuritypolicies"]
37. resourceNames: ["nfs-provisioner"]
38. verbs: ["use"]
39.---
40.kind: ClusterRoleBinding
41.apiVersion: rbac.authorization.k8s.io/v1
42.metadata:
43. name: run-nfs-provisioner
44.subjects:
45. - kind: ServiceAccount
46. name: nfs-provisioner
47. namespace: lbs-test
48.roleRef:
49. kind: ClusterRole
50. name: nfs-provisioner-runner
51. apiGroup: rbac.authorization.k8s.io
执行yaml文件:
1.[root@master yaml]# kubectl apply -f rbac-rolebind.yaml
namespace/lbh-test created
serviceaccount/nfs-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-provisioner created
3)创建nfs-client-provisioner容器:
1.[root@master yaml]# vim nfs-deployment.yaml
2.
3.apiVersion: extensions/v1beta1
4.kind: Deployment
5.metadata:
6. name: nfs-client-provisioner
7. namespace: lbs-test
8.spec:
9. replicas: 1 #副本数量为1
10. strategy:
11. type: Recreate
12. template:
13. metadata:
14. labels:
15. app: nfs-client-provisioner
16. spec:
17. serviceAccount: nfs-provisioner #指定账户
18. containers:
19. - name: nfs-client-provisioner
20. image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner #使用的镜像。
21. volumeMounts:
22. - name: nfs-client-root
23. mountPath: /persistentvolumes #指定容器内的挂载目录
24. env:
25. - name: PROVISIONER_NAME #这是这个容器内置的变量
26. value: lbs-test #这是上面变量的值(名字)
27. - name: NFS_SERVER #内置变量,用于指定nfs服务的IP
28. value: 192.168.2.50
29. - name: NFS_PATH #内置变量,指定的是nfs共享的目录
30. value: /nfsdata
31. volumes: #这下面是指定上面挂载到容器内的nfs的路径及IP
32. - name: nfs-client-root
33. nfs:
34. server: 192.168.2.50
35. path: /nfsdata
NFS-deployment:
作用:其实它是一个NFS客户端。它通过K8S的内置的NFS驱动挂载远端的NFS服务器到本地目录;然后将自身作为storage provider,关联storage class。
执行yaml文件:br/>1.[root@master yaml]# kubectl apply -f nfs-deployment.yaml
deployment.extensions/nfs-client-provisioner created
4)创建SC(Storage Class)自动创建pv
1.[root@master yaml]# vim test-storageclass.yaml
2.apiVersion: storage.k8s.io/v1
3.kind: StorageClass
4.metadata:
5. name: sc-nfs
6. namespace: lbs-test #名称空间
7.provisioner: lbs-test #这里要与deployment的env环境变量中的value值对应。
8.reclaimPolicy: Retain #回收策略为:retain。
执行yaml文件:
1.[root@master yaml]# kubectl apply -f test-storageclass.yaml
storageclass.storage.k8s.io/sc-nfs created
5)创建PVC
1.[root@master yaml]# vim test-pvc.yaml
2.
3.apiVersion: v1
4.kind: PersistentVolumeClaim
5.metadata:
6. name: lbs-claim
7. namespace: lbs-test
8.
9.spec:
10. storageClassName: sc-nfs 需要与storageclass的名字一致
11. accessModes:
12. - ReadWriteMany
13. resources:
14. requests:
15. storage: 500Mi
当我们创建完PVC后,会自动创建一个PV,其目录在NFS共享目录下:
1.[root@master yaml]# ls /nfsdata/
lbs-test-lbs-claim-pvc-71262c5a-f866-4bc6-a22f-cd49daf13edf
2.[root@master yaml]# kubectl get pv -n lbs-test
3.NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-71262c5a-f866-4bc6-a22f-cd49daf13edf 500Mi RWX Delete Bound lbs-test/lbs-claim sc-nfs 26m
6)**基于nginx运行web服务,使用Deployment资源对象,副本数量三个,持久化存储目录为默认主目录。将默认主目录内容,更改为自己的名称,并验证数据自动创建的PV目录下是否有数据。**
创建Deployment资源:
1.[root@master yaml]# vim nginx.yaml
2.
3.apiVersion: extensions/v1beta1
4.kind: Deployment
5.metadata:
6. name: lbs-web
7. namespace: lbs-test
8.spec:
9. replicas: 3
10. template:
11. metadata:
12. labels:
13. app: web
14. spec:
15. containers:
16. - name: nginx
17. image: nginx
18. volumeMounts:
19. - name: lbs-web
20. mountPath: /usr/share/nginx/html/
21. volumes:
22. - name: lbs-web
23. persistentVolumeClaim:
24. claimName: lbs-claim
执行yaml文件,并查看Pod:
1.[root@master yaml]# kubectl apply -f nginx.yaml
2.deployment.extensions/lbh-web created
3.
4.[root@master yaml]# kubectl get pod -n lbs-test
5.NAME READY STATUS RESTARTS AGE
6.lbs-web-6d596b6666-68wls 1/1 Running 0 2m29s
7.lbs-web-6d596b6666-k8vz2 1/1 Running 0 2m29s
8.lbs-web-6d596b6666-pvppq 1/1 Running 0 2m29s
分别进入容器,配置网页根目录:
1.[root@master yaml]# kubectl exec -it -n lbs-test lbs-web-6d596b6666-68wls /bin/bash
2.root@lbs-web-6d596b6666-68wls:/# cd /usr/share/nginx/html/
3.root@lbs-web-6d596b6666-68wls:/usr/share/nginx/html# echo 123 > index.html
4.root@lbs-web-6d596b6666-68wls:/usr/share/nginx/html# ls
5.index.html
6.root@lbs-web-6d596b6666-68wls:/usr/share/nginx/html# exit
其他两台步骤一样。
查看自动创建得分PV目录下是否有数据:
1.[root@master yaml]# cat /nfsdata/lbs-test-lbs-claim-pvc-71262c5a-f866-4bc6-a22f-cd49daf13edf/index.html
2.123
访问网页测试:
1.[root@master yaml]# kubectl get pod -o wide -n lbs-test
2.NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
3.lbs-web-6d596b6666-68wls 1/1 Running 0 11m 10.244.2.7 node02
4.lbs-web-6d596b6666-k8vz2 1/1 Running 0 11m 10.244.2.9 node02
5.lbs-web-6d596b6666-pvppq 1/1 Running 0 11m 10.244.2.8 node02
6.[root@master yaml]# curl 10.244.2.7
7.123
nginx容器内的网页根目录和本地的nfs共享目录关联。
数据不会因容器,pod被删除,而丢失。