一、前言:
NFS 是一款老牌的基于网络共享文件的存储解决方案,即网络文件系统。NFS 允许在一个系统网络上与它人共享目录和文件。通过使用 NFS,用户和程序可以像访问本地文件一样访问远端系统上的文件。
- nfs: 是我们最终的存储;
- nfs-client: 是用来动态创建 pv 和 pvc 的,我们称为 provisioner;
- StorageClass: 关联到对应的 provisioner 就可以使用;
- statefulset/deployment/daemonset:(或别的资源)需要配置 storageClassName 进行使用;
优点:
- 部署快速,维护简单方便;
- 集中存放在一台机器上,网络内部所有计算机可以通过网络访问,不必单独存储。;
- 从软件层面上来看,数据可靠性高,经久耐用,服务稳定;
缺点:
- 存在单点故障,如果nfs server宕机了,所有的客户都不能访问共享目录;
- 大数据高并发的场景,nfs效率低(网络/磁盘IO);
二、编写nfs-client的rbac角色授权yaml文件
# vim nfs-client-rbac.yaml
#定义账号
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
---
#定义账号拥有哪些资源的哪些权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nfs-client-provisioner-cr
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get","list","watch","create","delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get","list","watch","update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get","list","watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["list","watch","create","update","patch"]
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create","delete","get","list","watch","patch","update"]
---
#将角色与账号进行绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: nfs-client-provisioner-crb
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-cr
apiGroup: rbac.authorization.k8s.io
三、编写nfs-client-provisioner资源yaml文件
nfs-client-provisioner相当于一个nfs 客户端程序,用于声明nfs服务端的服务器地址、路径
创建storageclass资源时需要指定使用某个nfs-client-provisioner来提供数据存储
# vim nfs-client-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: nfs-client-provisioner
spec:
replicas: 1
selector:
matchLabels:
app: nfs-client-provisioner
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
image: quay.io/external_storage/nfs-client-provisioner:latest
env:
- name: PROVISIONER_NAME #给nfs-client-provisioner起个名字
value: nfs-storage
- name: NFS_SERVER
value: 192.168.171.200 #nfs server地址
- name: NFS_PATH
value: /opt/sharedata #nfs共享路径
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes #具体挂载路径
volumes: #定义一个nfs类型的volume,将nfs挂载到容器中
- name: nfs-client-root
nfs:
server: 192.168.171.200
path: /opt/sharedata
四、编写storageclass资源yaml文件
创建一个storageclass资源,storageclass资源需要指定使用哪个nfs-client-provisioner
# vim nfs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storageclass #重点:后续需要引用的名字
provisioner: nfs-storage #指定使用哪个nfs-client-provisioner
reclaimPolicy: Retain #回收策略
ReclaimPolicy 回收策略:
- Delete(删除):当 PVC 被删除时,PV 同样会被删除。
- Retain(保留):当 PVC 被删除时,PV 并不会被删除,需要手动进行删除。
- Recycle(回收):当 PVC 被删除时,PV 上的数据也会随之删除,以便和新的 PVC 进行绑定(已被遗弃)
五、存储提供
我们在服务端创建一个共享目录 /opt/sharedata ,作为客户端挂载的远端入口,然后设置权限。
$ mkdir -p /opt/sharedata/
$ chmod 666 /opt/sharedata/
然后,修改 NFS 配置文件 /etc/exports
# cat /etc/exports
/opt/sharedata 192.168.171.0/24(rw,sync,insecure,no_subtree_check,no_root_squash)
说明一下,这里配置后边有很多参数,每个参数有不同的含义,具体可以参考下边。此处,我配置了将 /opt/sharedata 文件目录设置为允许 IP 为该 192.168.171.0/24 区间的客户端挂载,当然,如果客户端 IP 不在该区间也想要挂载的话,可以设置 IP 区间更大或者设置为 * 即允许所有客户端挂载,例如:/home *(ro,sync,insecure,no_root_squash) 设置 /home 目录允许所有客户端只读挂载。
# showmount -e localhost
Export list for localhost:
/opt/sharedata 192.168.171.0/24
示例:
挂载远端目录到本地 /share 目录。
$ mount 192.168.171.200:/opt/sharedata /share
$ df -h | grep 192.168.171.11
Filesystem Size Used Avail Use% Mounted on
192.168.171.200:/opt/sharedata 27G 11G 17G 40% /share
客户端要卸载 NFS 挂载的话,使用如下命令即可。
$ umount /share
六、客户端安装(所有node上操作)
# yum -y install rpcbind nfs-utils
# 启动服务
systemctl enable rpcbind && systemctl start rpcbind
systemctl enable nfs-server && systemctl start nfs-server
七、创建所有资源
1.创建资源
# kubectl apply -f ./
deployment.apps/nfs-client-provisioner created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-cr created
clusterrolebinding.rbac.authorization.k8s.io/nfs-client-provisioner-crb created
storageclass.storage.k8s.io/nfs-storageclass created
2.查看nfs-client-provisioner资源的状态
# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-554cc7d84d-j4966 1/1 Running 0 35m
3.查看nfs-client-provisioner资源的详细信息
# kubectl describe pod nfs-client-provisioner-554cc7d84d-j4966
4.查看storageclass资源的状态
# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-storageclass nfs-storage Retain Immediate false 7s
5.查看storageclass资源的详细信息
# kubectl describe sc
Name: nfs-storageclass
IsDefaultClass: No
Annotations:
Provisioner: nfs-storage
Parameters:
AllowVolumeExpansion:
MountOptions:
ReclaimPolicy: Retain
VolumeBindingMode: Immediate
Events:
八、NFS实现总结
九、NFS在K8S中的应用场景
1.1、在PVC中调用StorageClass
apiVersion: v1kind: PersistentVolumeClaimmetadata:name: test-pvcspec:storageClassName: nfs-storageclass //指定通过哪个StorageClass创建pvaccessModes: - ReadWriteMany resources: requests: storage: 500Mi
1.2、在Statefulset控制器中使用StorageClass
apiVersion: apps/v1kind: StatefulSetmetadata: name: storage-statspec:·········· volumeClaimTemplates: //定义pvc模板,这个配置项只有statfulset资源有,因此需要配置在spec下,里面的自配置项和pvc调用StorageClass配置一致 - metadata: //定义元数据 name: nginx-storage-test-pvc //pvc的名称 spec: storageClassName: nfs-storageclass //指定通过哪个StorageClass创建pv accessModes: //访问模式 - ReadWriteMany //多主机读写 resources: //资源分配 requests: storage: 1Gi
1.3、应用建议:
大中小型网站(2000万/日pv以下)线上应用,门户网站也可以使用;
对于大型网站且可靠性要求较高的企业,nfs网络文件系统的替代软件为分布式文件系统ceph,fastDFS;
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它通过将请求的发送者和接收者解耦,使多个对象都有机会处理请求。在这个模式中,请求沿着一个处理链依次传递,直到有一个对象能够处理它为止。 本文将详细介绍责任链模式的…