k8s通过nfs-provisioner配置持久化存储

news/2024/11/8 15:05:38/

一、nfs-client-provisioner简介

Kubernetes集群中NFS类型的存储没有内置 Provisioner。但是你可以在集群中为NFS配置外部Provisioner。

Nfs-client-provisioner是一个开源的NFS 外部Provisioner,利用NFS Server为Kubernetes集群提供持久化存储,并且支持动态购买PV。但是nfs-client-provisioner本身不提供NFS,需要现有的NFS服务器提供存储。持久卷目录的命名规则为: n a m e s p a c e − {namespace}- namespace{pvcName}-${pvName}。

K8S的外部NFS驱动可以按照其工作方式(是作为NFS server还是NFS client)分为两类:

nfs-client:

它通过K8S内置的NFS驱动挂载远端的NFS服务器到本地目录;然后将自身作为storage provider关联storage class。当用户创建对应的PVC来申请PV时,该provider就将PVC的要求与自身的属性比较,一旦满足就在本地挂载好的NFS目录中创建PV所属的子目录,为Pod提供动态的存储服务。

nfs-server:

与nfs-client不同,该驱动并不使用k8s的NFS驱动来挂载远端的NFS到本地再分配,而是直接将本地文件映射到容器内部,然后在容器内使用ganesha.nfsd来对外提供NFS服务;在每次创建PV的时候,直接在本地的NFS根目录中创建对应文件夹,并export出该子目录。

本文将介绍使用nfs-client-provisioner这个应用,利用NFS Server给Kubernetes作为持久存储的后端,并且动态提供PV。前提条件是有已经安装好的NFS服务器,并且NFS服务器与Kubernetes的Slave节点网络能够连通。将nfs-client驱动做为一个deployment部署到K8S集群中,然后对外提供存储服务

二、准备NFS服务端

2.0 当前环境信息
[root@master1 ~]# kubectl get nodes -owide
NAME               STATUS   ROLES    AGE     VERSION    INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                KERNEL-VERSION              CONTAINER-RUNTIME
master1.k8s.test   Ready    <none>   5d21h   v1.22.17   10.140.20.141   <none>        CentOS Linux 7 (Core)   6.3.2-1.el7.elrepo.x86_64   docker://19.3.15
master2.k8s.test   Ready    <none>   5d21h   v1.22.17   10.140.20.142   <none>        CentOS Linux 7 (Core)   6.3.2-1.el7.elrepo.x86_64   docker://19.3.15
master3.k8s.test   Ready    <none>   5d21h   v1.22.17   10.140.20.143   <none>        CentOS Linux 7 (Core)   6.3.2-1.el7.elrepo.x86_64   docker://19.3.15
node1.k8s.test     Ready    <none>   5d21h   v1.22.17   10.140.20.156   <none>        CentOS Linux 7 (Core)   6.3.2-1.el7.elrepo.x86_64   docker://19.3.15
2.1 通过yum安装nfs server端
[root@master1 ~]# rpm -qa|egrep "nfs|rpc"
[root@master1 ~]# yum -y install nfs-utils rpcbind
2.2 启动服务和设置开机启动
#启动nfs-server,并加入开机启动
[root@master1 ~]# systemctl start rpcbind.service
[root@master1 ~]# systemctl enable rpcbind.service
[root@master1 ~]# systemctl start nfs
[root@master1 ~]# systemctl enable nfs-server --now
#查看nfs server是否已经正常启动
[root@master1 ~]# systemctl status nfs-server
2.3 编辑配置文件,设置共享目录
[root@master1 ~]# mkdir /data/nfs-provisioner -p
[root@master1 ~]# cat > /etc/exports <<EOF
/data/nfs_provisioner   10.140.20.0/24(rw,no_root_squash)
EOF
#不用重启nfs服务,配置文件就会生效
[root@master1 ~]# exportfs -arv 
exporting 10.140.20.0/24:/data/nfs_provisioner
用于配置NFS服务程序配置文件的参数:
参数含义
ro只读
rw读写
root_squash当NFS客户端以root管理员访问时,映射未NFS服务器的匿名用户
no_root_squash当NFS客户端以root管理员访问时,映射未NFS服务器的root管理员
all_suash无论NFS客户端使用什么账户访问,均映射未NFS服务器的匿名用户
sync同时将数据写入到内存与硬盘中,保证不丢失数据
async优先将数据保存到内存,然后再写入硬盘。效率高但易丢失数据
2.4 客户端测试
客户端需要安装nfs-utils
[root@master1 ~]# yum -y install nfs-utils
[root@master1 ~]# systemctl enable nfs --now
[root@master1 ~]# systemctl status nfs
客户端验证
[root@master2 ~]# showmount -e 10.140.20.141
Export list for 10.140.20.141:
/data/nfs_provisioner 10.140.20.0/24

三、部署nfs-provisioner

3.1.0 创建namespace、工作目录
[root@master1 ~]# kubectl create namespace test
[root@master1 ~]# mkdir  nfs-provisioner
[root@master1 ~]# cd  nfs-provisioner
3.1 创建ServiceAccount
[root@master1 ~]# cat > nfs-sa.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: test
---
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: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: test
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: 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 deployednamespace: test
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 deployednamespace: test
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: test
roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io
EOF
应用生效
[root@master1 nfs-provisioner]# kubectl apply -f nfs-sa.yaml
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
3.2 创建Deployment
[root@master1 ~]# cat > nfs-deployment.yaml << EOF
kind: Deployment
apiVersion: apps/v1
metadata:name: nfs-client-provisionernamespace: test
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0volumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: nfs-provisioner # 和3.Storage中provisioner保持一致便可- name: NFS_SERVERvalue: 10.140.20.141- name: NFS_PATHvalue: /data/nfs_provisionervolumes:- name: nfs-client-rootnfs:server: 10.140.20.141path: /data/nfs_provisioner
EOF
应用生效
[root@master1 nfs-provisioner]# kubectl apply -f nfs-deployment.yaml
deployment.apps/nfs-client-provisioner created
3.3 创建storageclass
[root@master1 ~]# cat > nfs-sc.yaml << EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:annotations:storageclass.kubernetes.io/is-test-class: "true"name: nfs-storagenamespace: test
provisioner: nfs-provisioner
volumeBindingMode: Immediate
reclaimPolicy: Delete
EOF
应用生效
[root@master1 nfs-provisioner]# kubectl apply -f nfs-sc.yaml
storageclass.storage.k8s.io/nfs-storage created
3.4 创建pvc
[root@master yaml]# cat > nfs-pvc.yaml << EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nfs-pvcnamespace: testlabels:app: nfs-pvc
spec:accessModes: #指定访问类型- ReadWriteOncevolumeMode: Filesystem #指定卷类型resources:requests:storage: 2GistorageClassName: nfs-storage #指定创建的存储类的名字
EOF#创建pvc
[root@master1 nfs-provisioner]# kubectl apply -n test -f nfs-pvc.yaml 
persistentvolumeclaim/nfs-pvc created
#查看pvc
[root@master1 nfs-provisioner]# kubectl get pvc -n test
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nfs-pvc     Bound    pvc-791dc175-c068-4977-a14b-02f8cb153bc3   2Gi        RWO            nfs-storage    8s
www-web-0   Bound    pvc-b666f81e-9723-4e88-8e81-157b9e081577   10Mi       RWO            nfs-storage    17m
www-web-1   Bound    pvc-a900806b-47e0-432e-81fd-865c5ff6e3ba   10Mi       RWO            nfs-storage    16m
#查看nfs共享目录
[root@master1 nfs-provisioner]# ls /data/nfs_provisioner/
test-nfs-pvc-pvc-791dc175-c068-4977-a14b-02f8cb153bc3
test-www-web-0-pvc-b666f81e-9723-4e88-8e81-157b9e081577
test-www-web-1-pvc-a900806b-47e0-432e-81fd-865c5ff6e3ba#总结:创建pvc使使用storageclass,那么将会自动创建pv并进行绑定

四、创建应用测试动态添加PV

4.1 创建一个nginx应用
cat > nginx_sts_pvc.yaml << EOF
apiVersion: v1
kind: Service
metadata:name: nginxnamespace: testlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: webnamespace: test
spec:serviceName: "nginx"replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginxports:- containerPort: 80name: webvolumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates:- metadata:name: wwwspec:accessModes: [ "ReadWriteOnce" ]storageClassName: "nfs-storage"  #使用新建的scresources:requests:storage: 10Mi
EOF
应用生效
[root@master1 nfs-provisioner]# kubectl apply -f nginx_sts_pvc.yaml
service/nginx created
statefulset.apps/web created
4.2 检查结果
检查deployment、statefulset状态
[root@master1 nfs-provisioner]# kubectl get sts,deploy -n test
NAME                   READY   AGE
statefulset.apps/web   2/2     4m49sNAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nfs-client-provisioner   1/1     1            1           15m
检查pod状态
[root@master1 nfs-provisioner]# kubectl get pods -n test
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-fb55999fb-pcrqt   1/1     Running   0          9m30s
web-0                                    1/1     Running   0          3m40s
web-1                                    1/1     Running   0          3m15s
检查nfs-server服务器是否创建pv持久卷:
[root@master1 nfs-provisioner]# kubectl get pvc,pv -n test
NAME                              STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/nfs-pvc     Bound    pvc-791dc175-c068-4977-a14b-02f8cb153bc3   2Gi        RWO            nfs-storage    2m45s
persistentvolumeclaim/www-web-0   Bound    pvc-b666f81e-9723-4e88-8e81-157b9e081577   10Mi       RWO            nfs-storage    19m
persistentvolumeclaim/www-web-1   Bound    pvc-a900806b-47e0-432e-81fd-865c5ff6e3ba   10Mi       RWO            nfs-storage    19mNAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
persistentvolume/pvc-791dc175-c068-4977-a14b-02f8cb153bc3   2Gi        RWO            Delete           Bound    test/nfs-pvc     nfs-storage             2m45s
persistentvolume/pvc-a900806b-47e0-432e-81fd-865c5ff6e3ba   10Mi       RWO            Delete           Bound    test/www-web-1   nfs-storage             19m
persistentvolume/pvc-b666f81e-9723-4e88-8e81-157b9e081577   10Mi       RWO            Delete           Bound    test/www-web-0   nfs-storage             19m[root@master1 nfs-provisioner]# kubectl exec -it -n test web-0 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@web-0:/# echo 1 >  /usr/share/nginx/html/1.txt
root@web-0:/# exit
[root@master1 nfs-provisioner]# ls /data/nfs_provisioner/
test-nfs-pvc-pvc-791dc175-c068-4977-a14b-02f8cb153bc3
test-www-web-0-pvc-b666f81e-9723-4e88-8e81-157b9e081577
test-www-web-1-pvc-a900806b-47e0-432e-81fd-865c5ff6e3ba
[root@master1 nfs-provisioner]# cat  /data/nfs_provisioner/test-www-web-0-pvc-b666f81e-9723-4e88-8e81-157b9e081577/1.txt 
1

http://www.ppmy.cn/news/77138.html

相关文章

ChatGPT 的 AskYourPDF 插件所需链接如何获取?

一、背景 目前 ChatGPT 主要有两款 PDF 对话插件&#xff0c;一个是 AskYourPDF 一个是 ChatWithPDF&#xff08;需 ChatGPT Plus&#xff09;&#xff0c;他们都可以实现给一个公共的PDF 链接&#xff0c;然后进行持续对话&#xff0c;对读论文&#xff0c;阅读 PDF 格式的文…

【Python零基础学习入门篇⑤】——第五节:Python中的函数

⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello&#xff0c;大家好呀我是陈童学哦&#xff0c;一个普通大一在校生&#xff0c;请大家多多关照呀嘿嘿&#x1f601;&#x1f60a;&#x1f618; &#x1f31f;&#x1f31f;&#x1f31f;技术这条路固然很艰辛&#xff0c;但既已选择&…

【JS】1691- 重学 JavaScript API - Performance API

❝ 前期回顾&#xff1a; 1. Page Visibility API 2. Broadcast Channel API 3. Beacon API 4. Resize Observer API 5. Clipboard API 6. Fetch API ❞ &#x1f3dd; 1. 什么是 Performance API 1.1 概念介绍 Performance API 提供了「访问和测量浏览器性能相关信息」的方法。…

mmdetection3d框架安装与Demo模型运行--基于Ubuntu18.04+Cuda10.1

1.NVIDIA Driver和Cuda安装 在Ubuntu18.04机器上安装好NVIDIA Driver4.18和CUDA10.1&#xff0c;版本号分别为4.18和10.1 查看NVIDIA Driver版本号&#xff1a;nvidia-smi 查看CUDA版本号&#xff1a;nvcc -V 2.安装MiniConda&#xff0c;并创建和管理虚拟环境 2.1 安装Min…

从零实现一个数据库(DataBase) Go语言实现版 5.B树实现(Part2))

英文源地址 紧接着上一篇进行b树的实现. b树中删除操作 删除叶子节点 从叶子节点中删除一个key的代码很像其他nodeReplace*函数 func leafDelete(new BNode, old BNode, idx uint16) {new.setHeader(BNODE_LEAF, old.nkeys() - 1)nodeAppendRange(new, old, 0, 0, idx)node…

2023年25个Java8面试问题和答案

Java是一种非常流行的编程语言&#xff0c;从Android应用程序到物联网&#xff08;IoT&#xff09;无处不在。事实上&#xff0c;根据Codeplatoon的数据&#xff0c;Java在1年的招聘信息中排名#2022。考虑到它的普遍存在&#xff0c;对精通Java的专业人员的需求仍然很高也就不足…

【投毒情报】PyPI中 colorara 等组件包泄漏主机截屏等敏感信息

漏洞描述 PyPI仓库中受影响版本的 colorara 和 libida组件在安装过程中会根据不同操作系统分别执行恶意逻辑&#xff0c;针对Windows执行White Snake远控木马&#xff0c;针对Linux收集系统截屏、主机名、用户名、IP等主机敏感信息发送至telegram。 漏洞名称PyPI中 colorara …

Vue 中动态引入图片为什么要是 require

在vue中动态的引入图片为什么要使用require&#xff1f; 因为动态添加src被当做静态资源处理了&#xff0c;没有进行编译&#xff0c;所以要加上require&#xff0c; 我倒着都能背出来...... emmm... 乍一看好像说的很有道理啊&#xff0c;但是仔细一看&#xff0c;这句话说…