使用nfs-storageClass
-
storageClass
k8s持久化存储有多种方式,当我们没有条件使用ceph时候,NFS存储则成了我们的理想选择;通常的的作法有两种,这两种方法都有弊端和明显的弊端:
- 在每一台node上挂载主机nfs目录,然后在容器上映射到主机目录
-
由于对用到主机磁盘路径完全依靠手工填写,需要每个容器、至少是namespace级别统一规划好路径,否则很容易发生文件夹冲突
-
- 使用PV/PVC,先创建PV,映射到NFS,在创建PVC,绑定到PV
-
项目一多,创建起来非常麻烦
-
storageClass则是为了解决这个问题而诞生,他能够根据一组配置,自动生产PV/PVC
-
安装
- nfs-storage-rabc.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
# 替换为你的namespace
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- 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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
# 替换为你的namespace
namespace: default
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
# 替换为你的namespace
namespace: default
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
# replace with namespace where provisioner is deployed
# 替换为你的namespace
namespace: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
# 替换为你的namespace
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
- nfs-storage-provisioner
这其实是一个容器,他会进行一些列的API监视,然后根据给定的参数创建PV/PVC并进行绑定。
需要设置的参数:
# env:
# - PROVISIONER_NAME:名称,这个地方在后面创建storageClass时候回用到
# - NFS_SERVER:nfs服务器地址
# - NFS_PATH: nfs路径
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: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
image: k8s.dockerproxy.com/sig-storage/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
# value: <YOUR NFS SERVER HOSTNAME>
value: 192.168.5.10
- name: NFS_PATH
# value: /var/nfs
value: /data/share
volumes:
- name: nfs-client-root
nfs:
# server: <YOUR NFS SERVER HOSTNAME>
server: 192.168.5.10
path: /data/share
- nfs-storage-class
provisioner参数需要和PROVISIONER_NAME参数对应
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-client
# or choose another name, must match deployment's env PROVISIONER_NAME'
# 替换为 provisioner pod 的 环境变量 PROVISIONER_NAME
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
# 此处也可以使用 "${.PVC.namespace}/${.PVC.name}" 来使用pvc的名称作为nfs中真实目录名称
pathPattern: "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}"
# 删除PVC时候的策略,delete :删除目录,retain保留目录
onDelete: retain
# 删除PVC时候的策略,如果存在本项,且值为false,删除目录;如果存在 onDelete 设置,则以 onDelete 设置为准
archiveOnDelete: false
# 回收策略 Retain – 手动回收,Recycle – 需要擦除后才能再次使用,Delete – 当用户删除对应的 PersistentVolumeClaim 时,动态配置的 volume 将被自动删除。默认为 Delete
reclaimPolicy: Retain
- nfs-sotrage-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: pvc-default
annotations:
nfs.io/storage-path: "default-pvc" # not required, depending on whether this annotation was shown in the storage class description
spec:
storageClassName: nfs-client
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
- 执行安装
kubectl apply -f nfs-storage-rabc.yaml
kubectl apply -f nfs-storage-provisioner.yaml
kubectl apply -f nfs-storage-class.yaml
# 非必要
# 因为前文的storage-class路径规则为 "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}"
# 由于rancher界面使用快捷创建、预创建PVC,不支持增加注释,需要复制到导入YAML进行执行,如果你想指定到不同的路径下,可以执行这个
kubectl apply -f nfs-storage-pvc.yaml
-
使用
- 预创建PVC
-
快捷创建
也可以在创建POD的时候,在添加数据卷的时候直接使用或者新建PVC,存储类选择给定的storageClass,配置选项与预创建一致
-
最佳实现