文章转载自:http://www.mydlq.club/article/109/

系统环境:

  • 操作系统: CentOS 7.9
  • Docker 版本: 19.03.13
  • Kubernetes 版本: 1.20.2
  • NFS Subdir External Provisioner 版本: v4.0.0

示例地址:Kubernetes 部署 NFS Subdir External Provisioner 的示例文件

一、什么是 NFS-Subdir-External-Provisioner

存储组件 NFS subdir external provisioner 是一个存储资源自动调配器,它可用将现有的 NFS 服务器通过持久卷声明来支持 Kubernetes 持久卷的动态分配。自动新建的文件夹将被命名为 ${namespace}-${pvcName}-${pvName} ,由三个资源名称拼合而成。

此组件是对 nfs-client-provisioner 的扩展,nfs-client-provisioner 已经不提供更新,且 nfs-client-provisioner 的 Github 仓库已经迁移到 NFS-Subdir-External-Provisioner 的仓库。

二、创建 NFS Server 端

我们先创建 NFS Server 端才能够正常使用 NFS 文件系统,下面介绍下如何在 CentOS 7 系统中安装 NFS Server 的过程。

关闭防火墙

为了方便部署,我们直接将防火墙关闭,可以执行下面命令:

$ systemctl stop firewalld && systemctl disable firewalld

安装 nfs-utils 和 rpcbind

为了能够正常使用 NFS,我们需要在使用 Kubernetes 集群中的所有服务器上安装以下依赖,命令如下:

$ yum install -y nfs-utils rpcbind

创建存储数据的文件夹

创建用于共享数据的文件夹,命令如下:

# 创建文件夹
$ mkdir /nfs # 更改归属组与用户
$ chown -R nfsnobody:nfsnobody /nfs

配置 NFS Server

配置 NFS Server,指定共享文件夹目录以及能够使用共享文件夹的 IP 段,命令如下:

# 编辑exports
$ vi /etc/exports # 输入以下内容(格式:FS共享的目录 NFS客户端地址1(参数1,参数2,...) 客户端地址2(参数1,参数2,...))
$ /nfs 192.168.2.0/24(rw,async,no_root_squash)

如果设置为 /nfs *(rw,async,no_root_squash) 则对所以的 IP 都有效

常用选项:

  • ro:客户端挂载后,其权限为只读,默认选项;
  • rw:读写权限;
  • sync:同时将数据写入到内存与硬盘中;
  • async:异步,优先将数据保存到内存,然后再写入硬盘;
  • Secure:要求请求源的端口小于1024

用户映射:

  • root_squash:当NFS客户端使用root用户访问时,映射到NFS服务器的匿名用户;
  • no_root_squash:当NFS客户端使用root用户访问时,映射到NFS服务器的root用户;
  • all_squash:全部用户都映射为服务器端的匿名用户;
  • anonuid=UID:将客户端登录用户映射为此处指定的用户uid;
  • anongid=GID:将客户端登录用户映射为此处指定的用户gid

启动 NFS Server

可与执行下面命令启动且开机就启动 NFS Server:

## 重启 rpcbind
$ systemctl restart rpcbind ## 重启 NFS Server 并设置开机就启动
$ systemctl enable nfs && systemctl restart nfs

到此我们就成功启动 NFS Server,这里服务器 IP 为 192.168.2.11,NFS 目录为 /nfs。

三、创建 ServiceAccount

现在的 Kubernetes 集群大部分是基于 RBAC 的权限控制,所以我们需要创建一个拥有一定权限的 ServiceAccount 与后面要部署的 NFS Subdir Externa Provisioner 组件绑定。

创建 RBAC 资源文件

创建 RBAC 资源文件 nfs-rbac.yaml,文件内容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
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
namespace: kube-system
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
namespace: kube-system
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io

注意: 请提前修改里面的 Namespace 名称为你要想部署 Namespace 空间。

部署 RBAC 资源

执行 kubectl 命令将 RBAC 文件部署到 Kubernetes 集群,命令如下:

  • -f: 指定资源文件名称。
$ kubectl apply -f nfs-rbac.yaml

四、部署 NFS-Subdir-External-Provisioner

设置 NFS-Subdir-External-Provisioner 部署文件,这里将其部署到 kube-system 命令空间中。

创建 NFS-Subdir-External-Provisioner 部署文件

创建一个用于部署的 Deployment 资源文件 nfs-provisioner-deploy.yaml,文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate ## 设置升级策略为删除再创建(默认为滚动更新)
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
#image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME ## Provisioner的名称,以后设置的storageclass要和这个保持一致
value: nfs-client
- name: NFS_SERVER ## NFS服务器地址,需和valumes参数中配置的保持一致
value: 192.168.2.11
- name: NFS_PATH ## NFS服务器数据存储目录,需和valumes参数中配置的保持一致
value: /nfs/data
volumes:
- name: nfs-client-root
nfs:
server: 192.168.2.11 ## NFS服务器地址
path: /nfs/data ## NFS服务器数据存储目录

由于官方镜像存储在 gcr.io 仓库中,国内无法拉取,所以本人将其拉下并存储在阿里云仓库中。

部署 NFS-Subdir-External-Provisioner

将组件 NFS-Subdir-External-Provisioner 部署到 Kubernetes 的 kube-system 命名空间下,命令如下:

  • -f: 指定资源文件名称。
$ kubectl apply -f nfs-provisioner-deploy.yaml -n kube-system

五、创建 NFS SotageClass

我们在创建 PVC 时经常需要指定 storageClassName 名称,这个参数配置的就是一个 StorageClass 资源名称,PVC 通过指定该参数来选择使用哪个 StorageClass,并与其关联的 Provisioner 组件来动态创建 PV 资源。所以,这里我们需要提前创建一个 Storagelcass 资源。

创建 StorageClass 资源文件

创建一个 StoageClass 资源文件 nfs-storageclass.yaml,文件内容如下:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-storage
annotations:
storageclass.kubernetes.io/is-default-class: "false" ## 是否设置为默认的storageclass
provisioner: nfs-client ## 动态卷分配者名称,必须和上面创建的"provisioner"变量中设置的Name一致
parameters:
archiveOnDelete: "true" ## 设置为"false"时删除PVC不会保留数据,"true"则保留数据
mountOptions:
- hard ## 指定为硬挂载方式
- nfsvers=4 ## 指定NFS版本,这个需要根据NFS Server版本号设置

上面配置中 Provisioner 参数用于声明 NFS 动态卷提供者的名称,该参数值要和上面部署 NFS-Subdir-External-Provisioner 部署文件中指定的 PROVISIONER_NAME 参数保持一致,即设置为 nfs-storage。

部署 StorageClass 资源

将 StorageClass 资源部署到 Kubernetes 集群,命令如下:

  • -f: 指定资源文件名称。
$ kubectl apply -f nfs-storageclass.yaml

六、创建用于测试的 PVC 资源

创建一个用于测试的 PVC 资源部署到 Kubernetes 中,这样可以测试 NFS-Subdir-External-Provisioner 是否能够自动创建 PV 与该 PVC 进行绑定。

创建用于测试的 PVC 资源文件

创建一个用于测试的 PVC 资源文件 test-pvc.yaml,文件内容如下:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-pvc
spec:
storageClassName: nfs-storage ## 需要与上面创建的storageclass的名称一致
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Mi

部署用于测试的 PVC 资源

将上面创建的用于测试的 PVC 资源部署到 Kubernetes 集群,命令如下:

  • -f: 指定资源文件名称。
$ kubectl apply -f test-pvc.yaml

观察是否自动创建 PV 并与 PVC 绑定

等待创建完成后观察 NFS-Subdir-External-Provisioner 是否会自动创建 PV 与该 PVC 进行绑定,可以执行下面命令:

  • -o: 指定输出的资源内容的格式,一般会设置为为 yaml 格式。
$ kubectl get pvc test-pvc -o yaml | grep phase

可以看到显示如下状态:

phase: Bound

如果显示 phase 为 Bound,则说明已经创建 PV 且与 PVC 进行了绑定

七、创建测试的 Pod 资源

创建一个测试的 Pod 资源部署到 Kubernetes 中,这样就可以测试上面创建的 PVC 是否能够正常使用。

创建测试的 Pod 资源文件

创建一个用于测试的 Pod 资源文件 test-pod.yaml,文件内容如下:

kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: busybox:latest
command:
- "/bin/sh"
args:
- "-c"
- "touch /mnt/SUCCESS && exit 0 || exit 1" ## 创建一个名称为"SUCCESS"的文件
volumeMounts:
- name: nfs-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-pvc

部署用于测试的 Pod 资源

将上面创建的用于测试的 Pod 资源部署到 Kubernetes 集群,命令如下:

  • -f: 指定资源文件名称。
$ kubectl apply -f test-pod.yaml

进入 NFS Server 服务器验证是否存在测试文件

进入 NFS Server 服务器的 NFS 挂载目录,检查在 Pod 中创建的文件 SUCCESS 是否存在:

$ cd /nfs/data && ls -l | grep test-pvc
drwxrwxrwx 2 root root default-test-pvc-pvc-aa2a0b72-8320-40d2-a5ab-9209f0dfee45 $ cd default-test-pvc-pvc-aa2a0b72-8320-40d2-a5ab-9209f0dfee45 && ls -l
-rw-r--r-- 1 root root SUCCESS

可以看到已经生成 SUCCESS 该文件,并且可知通过 NFS-Subdir-External-Provisioner 创建的目录命名方式为 namespace名称-pvc名称-pv名称,PV 名称是随机字符串,所以每次只要不删除 PVC,那么 Kubernetes 中的与存储绑定将不会丢失,要是删除 PVC 也就意味着删除了绑定的文件夹,下次就算重新创建相同名称的 PVC,生成的文件夹名称也不会一致,因为 PV 名是随机生成的字符串,而文件夹命名又跟 PV 有关,所以删除 PVC 需谨慎。

八、清理用于测试的资源

在测试组件是否能正常使用后,我们需要将上面的测试资源文件进行清理,可以执行下面命令:

## 删除测试的 Pod 资源文件
$ kubectl delete -f test-pod.yaml ## 删除测试的 PVC 资源文件
$ kubectl delete -f test-pvc.yaml

Kubernetes 中部署 NFS-Subdir-External-Provisioner 为 NFS 提供动态分配卷的更多相关文章

  1. 概念验证:在Kubernetes中部署ABAP

    对于将SAP ABAP应用服务器组件容器化和在Kubernetes中部署它们,我们在SPA LinuxLab中做了概念验证(PoC),本文将介绍一些我们的发现和经验.本文会也会指出这项工作的一些潜在的 ...

  2. Kubernetes入门(四)——如何在Kubernetes中部署一个可对外服务的Tensorflow机器学习模型

    机器学习模型常用Docker部署,而如何对Docker部署的模型进行管理呢?工业界的解决方案是使用Kubernetes来管理.编排容器.Kubernetes的理论知识不是本文讨论的重点,这里不再赘述, ...

  3. 在 Kubernetes 中部署 Redis 集群

    在 Kubernetes 中部署 Redis 集群 在Kubernetes中部署Redis集群面临挑战,因为每个 Redis 实例都依赖于一个配置文件,该文件可以跟踪其他集群实例及其角色.为此,我们需 ...

  4. 在Kubernetes中部署GlusterFS+Heketi

    目录 简介 Gluster-Kubernetes 部署 环境准备 下载相关文件 部署glusterfs 部署heketi server端 配置heketi client 简介 在上一篇<独立部署 ...

  5. Helm, 在Kubernetes中部署应用的利器

    一.背景 Kubernetes(k8s)是一个基于容器技术的分布式架构领先方案.它在Docker技术的基础上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整功能,提高了大规模容器 ...

  6. Kubernetes 中部署 MySQL 集群

    文章转载自:https://www.cnblogs.com/ludongguoa/p/15319861.html 一般情况下 Kubernetes 可以通过 ReplicaSet 以一个 Pod 模板 ...

  7. 在虚拟机环境(CentOS7系统)下将kubernetes中部署服务成功,但在虚拟机外部无法访问到服务

    在CentOS7环境下,kubernetes单机版环境,成功部署一个服务,在虚拟机中访问服务没问题,下面这样: curl http://172.27.73.26:8888/eureka-server/ ...

  8. kubernetes中部署kube-prometheus项目解决ControllerManager与Scheduler无法监控问题

    文章转载自:https://www.kococ.cn/20210302/cid=697.html 一.问题描述 在部署 kube-prometheus 到 kubernetes 集群中总会遇到一个问题 ...

  9. Kubernetes中部署wordpress+mysql(六)

    经过前面的内容其实对k8s已经有了服务迁移的能力了,下面这篇文章主要是用来搭建一些后面要用的组件 一.创建wordpress命名空间 kubectl create namespace wordpres ...

随机推荐

  1. Tapdata x 轻流,为用户打造实时接入轻流的数据高速通道

      在全行业加速布局数字化的当口,如何善用工具,也是为转型升级添薪助力的关键一步.   那么当轻量的异构数据实时同步工具,遇上轻量的数字化管理工具,将会收获什么样的新体验?此番 Tapdata 与轻流 ...

  2. DENIED Redis is running in protected mode because protected mode is enabled

    DENIED Redis is running in protected mode because protected mode is enabled redisson连接错误 Unable to i ...

  3. idea插件和springboot镜像

    主题 https://blog.csdn.net/zyx1260168395/article/details/102928172 springboot镜像 http://start.springboo ...

  4. Codeforces Round #792 (Div. 1 + Div. 2) // C ~ E

    比赛链接:Dashboard - Codeforces Round #792 (Div. 1 + Div. 2) - Codeforces C. Column Swapping 题意: 给定一个n*m ...

  5. javascript打印对象函数

    //js对象打印函数 function writeObj(obj) { var description = ""; for (var i in obj) { var propert ...

  6. 后端Python3+Flask结合Socket.io配合前端Vue2.0实现简单全双工在线客服系统

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_158 在之前的一篇文章中:为美多商城(Django2.0.4)添加基于websocket的实时通信,主动推送,聊天室及客服系统,详 ...

  7. MYSQL的Java操作器——JDBC

    MYSQL的Java操作器--JDBC 在学习了Mysql之后,我们就要把Mysql和我们之前所学习的Java所结合起来 而JDBC就是这样一种工具:帮助我们使用Java语言来操作Mysql数据库 J ...

  8. 搭建 Webpack + TypeScript + Babel 的项目

    安装依赖包 安装 webpack 相关的依赖: npm i -D webpack webpack-cli 安装 ts.babel.source-map 的 loader: npm i -D ts-lo ...

  9. 解决:Uncaught TypeError: $ is not a function

    本来好好的,突然就出现的错误,不过这并不是什么难解决的错误: 我的问题是:在js文件里我定义了一个var $;变量,只要把这个去掉就没问题了. 出现这种错误的解决方法: 1,先看看你的jq文件是否已经 ...

  10. C++ 对于函数名的操作,函数名本身和取*以及取&的区别

    void TestFunc() { } int _tmain(int argc, _TCHAR* argv[]) { cout<<TestFunc<<endl; cout< ...