前言:最近在部署基于阿里云机器上的自建K8S集群,部署完成后因为一些成本原因,用不了云厂商的nfs存储。因为部署一些有状态的服务的需要,需要用到持久卷,想到有一台机器的存储空间比较大,所以把这台机器做一个nfs的本地服务,用于给K8S集群调度。
什么是StorageClass
Kubernetes提供了一套可以自动创建PV的机制,即:Dynamic Provisioning(动态配置)。而这个机制的核心在于StorageClass这个API对象。
StorageClass对象会定义下面两部分内容:
PV的属性。比如,存储类型,Volume的大小等。
- 创建这种PV需要用到的存储插件,即存储制备器。
- 有了这两个信息之后,Kubernetes就能够根据用户提交的PVC,找到一个对应的StorageClass,之后Kubernetes就会调用该StorageClass声明的存储插件,进而创建出需要的PV。
但是其实使用起来是一件很简单的事情,你只需要根据自己的需求,编写YAML文件即可,然后使用kubectl create命令执行即可。
部署
搭建StorageClass + NFS,大致有以下几个步骤:
- 创建一个可用的NFS Server
- 创建Service Account,这是用来管控NFS Provisioner 在k8s集群中运行的权限
- 创建StorageClass,负责建立PVC并调用NFS provisioner进行预定的工作,并让PV与PVC建立关联
- 创建NFS provisioner,有两个功能,一个是在NFS共享目录下创建挂载点(volume),另一个则是建了PV并将PV与NFS的挂载点建立关联
一:在指定服务器上创建NFS Server
#Centos系统安装部署
# 安装nfs-server(所有节点的操作)
yum install -y nfs-utils
# 授权存储目录(master)
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
# 执行以下命令,启动 nfs 服务;创建共享目录
mkdir -p /nfs/data
# 在master节点执行
systemctl enable rpcbind
systemctl enable nfs-server
systemctl start rpcbind
systemctl start nfs-server
# 使配置生效
exportfs -r
# 检查配置是否生效
exportfs
# 测试,在子节点 IP为master的ip
showmount -e 172.18.210.10
#在 Ubuntu 系统中,安装 NFS 服务的命令为:
sudo apt-get update
sudo apt-get install -y nfs-kernel-server
然后,您可以按照以下步骤授权存储目录和启动 NFS 服务:
1.授权存储目录
sudo echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
2.创建共享目录
sudo mkdir -p /nfs/data
3.启动 NFS 服务
sudo systemctl enable nfs-kernel-server
sudo systemctl start nfs-kernel-server
4.使配置生效
sudo exportfs -r
5.检查配置是否生效
sudo exportfs
6.测试,检查子节点是否可以访问共享目录(假设使用 IP 地址 192.168.0.1 作为 master 节点的 IP 地址)
showmount -e 172.18.210.10
二:创建Service Account
管控NFS Provisioner 在k8s集群中运行的权限
rbac.yaml: 唯一需要修改的地方只有namespace,根据实际情况定义(一般默认可以不用修改,就选default)
---
apiVersion: v1
kind: ServiceAccount #创建个SA账号主要用来管理NFS provisioner在k8s集群中运行的权限
metadata:
name: nfs-client-provisioner #和上面的SA账号保持一致
# replace with namespace where provisioner is deployed
namespace: default
---
#以下就是ClusterRole,ClusterRoleBinding,Role,RoleBinding都是权限绑定配置,不在解释。直接复制即可。
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: 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: 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: default
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
三:创建StorageClass 并指定 NFS provisioner
负责建立PVC并调用NFS provisioner进行预定的工作,并让PV与PVC建立关联
sc.yaml 需要把IP指定自己nfs服务器地址
## 创建NFS资源的StorageClass
apiVersion: storage.k8s.io/v1
#存储类的资源名称
kind: StorageClass
metadata:
#存储类的名称,自定义
name: nfs-storage
annotations:
#注解,是否是默认的存储,注意:KubeSphere默认就需要个默认存储,因此这里注解要设置为“默认”的存储系统,表示为"true",代表默认。
storageclass.kubernetes.io/is-default-class: "true"
#存储分配器的名字,自定义
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true" ## 删除pv的时候,pv的内容是否要备份
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: default
spec:
#只运行一个副本应用
replicas: 1
#描述了如何用新的POD替换现有的POD
strategy:
#Recreate表示重新创建Pod
type: Recreate
#选择后端Pod
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner #创建账户
containers:
- name: nfs-client-provisioner
image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nfs-subdir-external-provisioner:v4.0.2 #使用NFS存储分配器的镜像
# resources:
# limits:
# cpu: 10m
# requests:
# cpu: 10m
volumeMounts:
- name: nfs-client-root #定义个存储卷,
mountPath: /persistentvolumes #表示挂载容器内部的路径
env:
- name: PROVISIONER_NAME #定义存储分配器的名称
value: k8s-sigs.io/nfs-subdir-external-provisioner #需要和上面定义的保持名称一致
- name: NFS_SERVER #指定NFS服务器的地址,你需要改成你的NFS服务器的IP地址
value: 172.18.210.10 ## 指定自己nfs服务器地址
- name: NFS_PATH
value: /nfs/data ## nfs服务器共享的目录 #指定NFS服务器共享的目录
volumes:
- name: nfs-client-root #存储卷的名称,和前面定义的保持一致
nfs:
server: 172.18.210.10 #NFS服务器的地址,和上面保持一致,这里需要改为你的IP地址
path: /nfs/data #NFS共享的存储目录,和上面保持一致
# 保存上面文件到/usr/local/目录下
cd /usr/local/
sudo kubectl apply -f rbac.yaml
sudo kubectl apply -f sc.yaml
四:申明PVC进行测试
vi pvc.yaml
kind: PersistentVolumeClaim #创建PVC资源
apiVersion: v1
metadata:
name: nginx-pvc #PVC的名称
spec:
accessModes: #定义对PV的访问模式,代表PV可以被多个PVC以读写模式挂载
- ReadWriteMany
resources: #定义PVC资源的参数
requests: #设置具体资源需求
storage: 200Mi #表示申请200MI的空间资源
storageClassName: nfs-storage #指定存储类的名称,就指定上面创建的那个存储类。
# 测试自动创建PV
sudo kubectl apply -f pvc.yaml
# 获取pvc
kubectl get pvc
# kubectl delete -f pvc.yaml
评论区