为什么需要存储类(storageclass)?
因为PV和PVC模式都是需要先创建好PV,然后定义好PVC和pv进行一对一的Bond,但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,Kubernetes提供一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板。k8s集群管理员通过创建storageclass可以动态生成一个存储卷pv供k8s pvc使用。
provisioner:供应商,storageclass需要有一个供应者,用来确定我们使用什么样的存储来创建pv。
以下是一些常见的供应商:
我们今天就以NFS为例,要想使用NFS,我们需要一个nfs-client的自动装载程序,称之为provisioner,这个程序会使用我们已经配置好的NFS服务器自动创建持久卷,也就是自动帮我们创建PV。
k8smaster | 192.168.8.128 |
k8snode1 | 192.168.8.129 |
k8snode2 | 192.168.8.130 |
一:配置NFS服务
1.1
[root@k8smaster1 ~]# yum install nfs-utils rpcbind -y
[root@k8snode1 ~]# yum install nfs-utils rpcbind -y
[root@k8snode2 ~]# yum install nfs-utils rpcbind -y
1.2
在master配置:
vim /etc/exports
/data/ 192.168.8.0/24(rw,no_root_squash)
#/data/
:表示挂载点
#192.168.8.0 表示允许8.0网段的主机挂载
rw
:表示挂载为可读写模式。no_root_squash
:表示不限制远程服务器的root用户权限。
保存退出
exportfs -arv
#执行exportfs -arv
命令,系统会按照 /etc/exports
文件中定义的配置,将所有文件系统重新导出,并显示详细的操作信息。
systemctl restart nfs-server nfs-utils rpcbind
systemctl status nfs-server nfs-utils rpcbind
1.3
在node1和node2配置:
showmount -e 192.168.8.128
#showmount
命令用于显示特定 NFS 服务器上所有允许客户端挂载的文件系统列表。这里的参数 -e
后面跟的是 NFS 服务器的 IP 地址。
可以看到已经成功查看到了
挂载nfs
[root@k8snode1 ~]# mount -t nfs 192.168.8.128:/data /data
[root@k8snode2 ~]# mount -t nfs 192.168.8.128:/data /data
写进/etc/fstab #写进/etc/fstab之后下次重启系统之后会自动挂载上
vim /etc/fstab
df -hT|grep nfs #确认一下是否挂载上
二:配置storageclass
在master配置
2.1 创建sa账户 #允许nfs供应商需要的sa账号
vim sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-provisioner
kubectl apply -f sa.yaml #创建yaml
kubectl get sa #查看yaml文件中创建的sa账户
2.2 给账号赋予权限 #clusterrolebinding绑定集群admin权限
kubectl create clusterrolebinding nfs-provisioner-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner
#这个绑定将 cluster-admin
集群角色授予默认命名空间(defaul)t
中的 nfs-provisioner
服务账户(ServiceAccount)。
2.3 安装nfs provisioner (供应商)
先拉取nfs供应商镜像,找一台有docker的主机,配置好阿里云的加速器
docker pull registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
将镜像打包成文件传到k8s 集群中
docker save -o nfs-subdir-external-provisioner.tar registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
#-o 后面跟的是打包后的文件名字 再后面是需要打包的镜像
将文件传到k8s nod1 和node2上面去
scp nfs-subdir-external-provisioner.tar.gz 192.168.8.129:/root/
scp nfs-subdir-external-provisioner.tar.gz 192.168.8.130:/root/
node1和node2都执行
ctr -n k8s.io image import nfs-subdir-external-provisioner.tar.gz #把镜像导入k8s集群中
vim nfs-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-provisioner
spec:
selector:
matchLabels:
app: nfs-provisioner
replicas: 2
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
spec:
serviceAccount: nfs-provisioner
containers:
- name: nfs-provisioner
image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
imagePullPolicy: IfNotPresent
volumeMounts:
- name: nfs-client-root #挂载到供应商里面指定的目录
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: example.com/nfs #供应商的名字
- name: NFS_SERVER
value: 192.168.8.128 #指定nfs服务器的ip地址 文章中是master的ip
- name: NFS_PATH
value: /data/ #nfs共享的目录
volumes:
- name: nfs-client-root #以nfs的type类型创建卷
nfs:
server: 192.168.8.128
path: /data/
kubectl apply -f nfs-provisioner.yaml
kubectl get pod -l app=nfs-provisioner #- l 指定yaml文件中定义的标签查看pod
2.4 创建storage class (存储类) 动态创建PV
vim storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: nfs
provisioner: example.com/nfs
example.com/nfs这个指定的就是创建nfs供应商的名字,yaml文件中的这个字段
kubectl apply -f storageclass.yaml
kubectl get storageclass
#可以看到已经成功创建了存储类,并且provisioner供应商这里指定的我们自己创建的nfs供应商
三:创建PVC测试
3.1 编写pvc yaml文件
vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim # 定义资源类型为 pvc
metadata:
name: test
spec:
accessModes: # 定义了卷的访问模式。
- ReadWriteMany # 允许多个节点以读写方式同时访问卷。
resources: # 定义了存储资源的请求。
requests:
storage: 1Gi # 请求的存储容量为 1GiB(Gibibyte)。
storageClassName: nfs # 指定存储类的名字
storageClassName: nfs 这个字段就指定的是2.4中创建的storageclass的名字
kubectl apply -f pvc.yaml
kubectl get pvc
kubectl get pv
可以看到已经成功自动绑定上了pv ,pv也自动创建出来了
3.2 创建pod测试一下
vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: nginx
image: docker.io/library/sjl-nginx:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts: #挂载到容器的/usr/share/nginx/html/目录
- name: html
mountPath: /usr/share/nginx/html/ #nginx的网页根目录
volumes: #以pvc类型创建卷,指定刚刚创建的pvc
- name: html
persistentVolumeClaim:
claimName: sjl-test
kubectl apply -f pod.yaml
kubectl get pod web -owide #-owide表示查看pod的详细信息
进入到nfs共享的data目录
这个就是挂载的pvc的目录
这个就是写了index网页,访问的是刚刚创建的pod ip地址
四:整体流程
1、创建一个nfs provisioner
2、创建storageclass(存储类),storageclass指定刚才创建的供应商
3、创建pvc,这个pvc指定storageclass的名字
4、创建pod或者deployment资源就可以指定pvc进行挂载
五:k8s 存储
k8s 的存储还有很多,只不过pvc这种是本人自认为最好用的一种
其他的存储方案:
emptydir:用于临时存储,当 Pod 被删除时,EmptyDir 中的数据也会被删除。
hostpath:宿主机挂载目录通常用于开发和测试环境,或者当某些应用需要访问宿主机上的特定文件或目录时。
nfs:网络共享挂载,可以在多个节点之间共享文件系统,适合于需要高可用性和共享存储的场景
还要其他很多存储方案可以访问官网进行查阅