Kubernetes: 利用NFS动态提供后端存储

简介: Kubernetes: 利用NFS动态提供后端存储

目录

Kubernetes: 利用NFS动态提供后端存储

pv, pvc和storageclass关系

前提条件

nfs-client-provisioner

安装部署

方式1: 使用Helm

配置

方式2: 不使用Helm

授权

如果启用了RBAC

修改deployment文件并部署 deploy/deployment.yaml

修改StorageClass文件并部署 deploy/class.yaml

测试

最新版本nfs-subdir-external-provisioner

参考链接:



Kubernetes: 利用NFS动态提供后端存储


pv, pvc和storageclass关系

一幅示意图描述:

从图中我们可以看到,在这个体系中:

  • PVC 描述的,是 Pod 想要使用的持久化存储的属性,比如存储的大小、读写权限等。
  • PV 描述的,则是一个具体的 Volume 的属性,比如 Volume 的类型、挂载目录、远程存储服务器地址等。
  • 而 StorageClass 的作用,则是充当 PV 的模板。并且,只有同属于一个 StorageClass 的 PV 和 PVC,才可以绑定在一起。

当然,StorageClass 的另一个重要作用,是指定 PV 的 Provisioner(存储插件)。这时候,如果你的存储插件支持 Dynamic Provisioning 的话,Kubernetes 就可以自动为你创建 PV 了。

  • Kubernetes 为我们提供了一套可以自动创建 PV 的机制,即:Dynamic Provisioning。相比之下,人工管理 PV 的方式就叫作 Static Provisioning。Dynamic Provisioning 机制工作的核心,在于一个名叫 StorageClass 的 API 对象。

容器持久化存储涉及的概念比较多,试着总结一下整体流程。

用户提交请求创建pod,Kubernetes发现这个pod声明使用了PVC,那就靠PersistentVolumeController帮它找一个PV配对。

没有现成的PV,就去找对应的StorageClass,帮它新创建一个PV,然后和PVC完成绑定。

新创建的PV,还只是一个API 对象,需要经过“两阶段处理”变成宿主机上的“持久化 Volume”才真正有用:

  1. 第一阶段由运行在master上的AttachDetachController负责,为这个PV完成 Attach 操作,为宿主机挂载远程磁盘;
  2. 第二阶段是运行在每个节点上kubelet组件的内部,把第一步attach的远程磁盘 mount 到宿主机目录。这个控制循环叫VolumeManagerReconciler,运行在独立的Goroutine,不会阻塞kubelet主循环。

完成这两步,PV对应的“持久化 Volume”就准备好了,POD可以正常启动,将“持久化 Volume”挂载在容器内指定的路径。

PV 描述的,是持久化存储数据卷。这个 API 对象主要定义的是一个持久化存储在宿主机上的目录,比如一个 NFS 的挂载目录。通常情况下,PV 对象是由运维人员事先创建在 Kubernetes 集群里待用的。

PVC 描述的,则是 Pod 所希望使用的持久化存储的属性。比如,Volume 存储的大小、可读写权限等等。

PVC 对象通常由开发人员创建;或者以 PVC 模板的方式成为 StatefulSet 的一部分,然后由 StatefulSet 控制器负责创建带编号的 PVC。

本文翻译自nfs-client-provisioner的说明文档,本文将介绍使用nfs-client-provisioner这个应用,利用NFS Server给Kubernetes作为持久存储的后端,并且动态提供PV


前提条件

  1. 是有已经安装好的NFS服务器,并且NFS服务器与Kubernetes的Slave节点都能网络连通。
  2. 所有下文用到的文件来自于git clone https://github.com/kubernetes-incubator/external-storage.git的nfs-client目录。


nfs-client-provisioner

nfs-client-provisioner 是一个Kubernetes的简易NFS的外部provisioner,本身不提供NFS,需要现有的NFS服务器提供存储

  • PV以 ${namespace}-${pvcName}-${pvName}的命名格式提供(在NFS服务器上)
  • PV回收的时候以 archieved-${namespace}-${pvcName}-${pvName} 的命名格式(在NFS服务器上)


安装部署


方式1: 使用Helm

按照https://github.com/helm/charts/tree/master/stable/nfs-client-provisioner维护的helm chart的说明进行操作

helm install stable/nfs-client-provisioner --set nfs.server=xxxx --set nfs.path=/exported/path


配置

下表列出了此图表的可配置参数及其默认值。

范围 描述 默认
replicaCount 要部署的 Provisioner 实例数 1
strategyType 指定用于用新 Pod 替换旧 Pod 的策略 Recreate
image.repository 供应商仓库 quay.io/external_storage/nfs-client-provisioner
image.tag 供应商镜像的版本 v3.1.0-k8s1.11
image.pullPolicy 镜像拉取策略 IfNotPresent
storageClass.name 存储类名称 nfs-client
storageClass.defaultClass 设置为默认 StorageClass false
storageClass.allowVolumeExpansion 允许扩大存储量 true
storageClass.reclaimPolicy 用于回收废弃卷的方法 Delete
storageClass.provisionerName 供应商名称名称 空值
storageClass.archiveOnDelete 删除时归档 pvc true
storageClass.accessModes 设置 PV 访问模式 ReadWriteOnce
nfs.server NFS 服务器的主机名 null(IP 或主机名)
nfs.path 要使用的挂载点的基本路径 /ifs/kubernetes
nfs.mountOptions 挂载选项(例如’nfsvers=3’) 空值
resources 所需资源(例如 CPU、内存) {}
rbac.create 使用基于角色的访问控制 true
podSecurityPolicy.enabled 创建和使用 Pod 安全策略资源 false
priorityClassName 设置 pod priorityClassName 空值
serviceAccount.create 我们应该创建一个 ServiceAccount true
serviceAccount.name 要使用的 ServiceAccount 的名称 空值
nodeSelector Pod 分配的节点标签 {}
affinity 亲和度设置 {}
tolerations 要容忍的节点污点列表 []

其中使用https://github.com/helm/charts/tree/master/stable/nfs-server-provisioner包括一个内置的 NFS 服务器,并不用于连接到预先存在的 NFS 服务器。


方式2: 不使用Helm


授权

如果你的集群启用了RBAC,或者你正在运行OpenShift,则必须授权provisioner。

如果你在非默认的default名称空间/项目之外部署,可以编辑deploy/auth/clusterrolebinding.yaml或编辑oadm policy指令。


如果启用了RBAC

需要执行如下的命令来授权。

kubectl create -f deploy/auth/serviceaccount.yaml
serviceaccount "nfs-client-provisioner" created
kubectl create -f deploy/auth/clusterrole.yaml
clusterrole "nfs-client-provisioner-runner" created
kubectl create -f deploy/auth/clusterrolebinding.yaml
clusterrolebinding "run-nfs-client-provisioner" created
kubectl patch deployment nfs-client-provisioner -p '{"spec":{"template":{"spec":{"serviceAccount":"nfs-client-provisioner"}}}}'


修改deployment文件并部署 deploy/deployment.yaml

需要修改的地方只有NFS服务器所在的IP地址(10.0.0.200),以及NFS服务器共享的路径(/nfs,两处都需要修改为你实际的NFS服务器和共享目录

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              # 必须与class.yaml中的provisioner的名称一致
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              # NFS服务器的ip地址
              value: 10.0.0.200
            - name: NFS_PATH
              # 修改为实际创建的共享挂载目录
              value: /nfs
      volumes:
        - name: nfs-client-root
          nfs:
            # NFS服务器的ip地址
            server: 10.0.0.200
            # 修改为实际创建的共享挂载目录
            path: /nfs


修改StorageClass文件并部署 deploy/class.yaml

此处可以不修改,或者修改provisioner的名字,需要与上面的deployment的PROVISIONER_NAME名字一致。

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              # 必须与class.yaml中的provisioner的名称一致
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              # NFS服务器的ip地址
              value: 10.0.0.200
            - name: NFS_PATH
              # 修改为实际创建的共享挂载目录
              value: /nfs
      volumes:
        - name: nfs-client-root
          nfs:
            # NFS服务器的ip地址
            server: 10.0.0.200
            # 修改为实际创建的共享挂载目录
            path: /nfs


测试

测试创建PVC

  • kubectl create -f deploy/test-claim.yaml

测试创建POD

  • kubectl create -f deploy/test-pod.yaml

在NFS服务器上的共享目录下的卷子目录中检查创建的NFS PV卷下是否有"SUCCESS" 文件。

[root@node2 ~]# cd /nfs/
[root@node2 nfs]# ll
total 4
drwxrwxrwx 2 root root  6 Oct 27 14:15 default-test-claim-pvc-f37dbcf5-bf9d-402c-9350-0b3b2efd9979
-rw-r--r-- 1 root root 19 Oct 26 10:49 index.txt
[root@node2 nfs]# cd default-test-claim-pvc-f37dbcf5-bf9d-402c-9350-0b3b2efd9979/
[root@node2 default-test-claim-pvc-f37dbcf5-bf9d-402c-9350-0b3b2efd9979]# ll
total 0
-rw-r--r-- 1 root root 0 Oct 27 14:19 SUCCESS


删除测试POD

  • kubectl delete -f deploy/test-pod.yaml

删除测试PVC

  • kubectl delete -f deploy/test-claim.yaml

在NFS服务器上的共享目录下查看NFS的PV卷回收以后是否名字以archived开头。


[root@node2 nfs]# ll
total 4
drwxrwxrwx 2 root root 21 Oct 27 14:19 archived-default-test-claim-pvc-f37dbcf5-bf9d-402c-9350-0b3b2efd9979
-rw-r--r-- 1 root root 19 Oct 26 10:49 index.txt


最新版本nfs-subdir-external-provisioner

这个仓库是从https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client迁移过来的。作为迁移的一部分:

  • 容器镜像名称和存储库已分别更改为k8s.gcr.io/sig-storagenfs-subdir-external-provisioner
  • 为了保持与早期部署文件的向后兼容性,NFS Client Provisioner 的命名保留nfs-client-provisioner在部署 YAML 中。
#
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
# 
helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
    --set nfs.server=x.x.x.x \
    --set nfs.path=/exported/path

我的命令

# 安装
helm install /usr/local/jt/nfs-subdir-external-provisioner \
    --name nfs-storage \
    --namespace=big-data \
    --set nfs.server=10.0.0.200 \
    --set nfs.path=/nfs \
    --set storageClass.name=managed-nfs-storage
# 安装    
helm delete my-release    

https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner


参考链接:

https://github.com/kubernetes-retired/external-storage/tree/master/nfs-client

https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

https://jimmysong.io/kubernetes-handbook/practice/using-nfs-for-persistent-storage.html#


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
3天前
|
存储 Kubernetes 安全
云上攻防-云原生篇&K8s安全&Config泄漏&Etcd存储&Dashboard鉴权&Proxy暴露
云上攻防-云原生篇&K8s安全&Config泄漏&Etcd存储&Dashboard鉴权&Proxy暴露
|
1月前
|
存储 Kubernetes Docker
k8s-配置与存储-配置管理
k8s-配置与存储-配置管理
|
1月前
|
存储 Kubernetes 调度
K8S常见的持久化(存储)方案用法详解
K8S常见的持久化(存储)方案用法详解
150 3
|
1月前
|
存储 Kubernetes 应用服务中间件
k8s-配置与存储-持久化存储-NFS 挂载、StorageClass 存储类 动态创建NFS-PV案例
k8s-配置与存储-持久化存储-NFS 挂载、StorageClass 存储类 动态创建NFS-PV案例
212 0
|
1月前
|
存储 Kubernetes 数据安全/隐私保护
|
21天前
|
Kubernetes 微服务 容器
Aspire项目发布到远程k8s集群
Aspire项目发布到远程k8s集群
370 2
Aspire项目发布到远程k8s集群
|
10天前
|
Kubernetes Cloud Native 微服务
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
微服务实践之使用 kube-vip 搭建高可用 Kubernetes 集群
185 3
|
1天前
|
Kubernetes 算法 API
K8S 集群认证管理
【6月更文挑战第22天】Kubernetes API Server通过REST API管理集群资源,关键在于客户端身份认证和授权。
|
12天前
|
Kubernetes 数据处理 调度
天呐!部署 Kubernetes 模式的 Havenask 集群太震撼了!
【6月更文挑战第11天】Kubernetes 与 Havenask 集群结合,打造高效智能的数据处理解决方案。Kubernetes 如指挥家精准调度资源,Havenask 快速响应查询,简化复杂任务,优化资源管理。通过搭建 Kubernetes 环境并配置 Havenask,实现高可扩展性和容错性,保障服务连续性。开发者因此能专注业务逻辑,享受自动化基础设施管理带来的便利。这项创新技术组合引领未来,开启数据处理新篇章。拥抱技术新时代!
|
12天前
|
Kubernetes 前端开发 Serverless
Serverless 应用引擎产品使用合集之如何调用Kubernetes集群内服务
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。