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#


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
11天前
|
存储 监控 对象存储
ACK 容器监控存储全面更新:让您的应用运行更稳定、更透明
针对本地存储和 PVC 这两种容器存储使用方式,我们对 ACK 的容器存储监控功能进行了全新升级。此次更新完善了对集群中不同存储类型的监控能力,不仅对之前已有的监控大盘进行了优化,还针对不同的云存储类型,上线了全新的监控大盘,确保用户能够更好地理解和管理容器业务应用的存储资源。
|
8天前
|
存储 Kubernetes 安全
k8s存储类型:emptyDir、hostPath、nfs、pvc及存储类storageclass的静态/动态创建pv
Kubernetes提供了多种存储类型,满足不同的应用需求。`emptyDir`和 `hostPath`适用于临时和宿主机存储需求,`nfs`适用于共享存储,`PersistentVolumeClaim`和 `StorageClass`实现了持久存储的灵活管理。通过理解和配置这些存储类型,可以有效提升Kubernetes集群的存储管理能力。
30 13
|
16天前
|
存储 监控 对象存储
ACK容器监控存储全面更新:让您的应用运行更稳定、更透明
介绍升级之后的ACK容器监控体系,包括各大盘界面展示和概要介绍。
|
6月前
|
存储 Kubernetes 容器
Kubernetes 存储选项:持久化卷与存储类
【8月更文第29天】随着容器化的普及,越来越多的应用程序需要持久化数据以保持状态信息。Kubernetes 提供了一套完整的解决方案来管理和配置持久化存储,包括持久卷 (Persistent Volume, PV)、持久卷声明 (Persistent Volume Claim, PVC) 和存储类 (StorageClass)。本文将详细介绍这些概念,并通过实际示例来演示如何在 Kubernetes 中配置存储。
479 1
|
6月前
|
存储 Kubernetes 容器
k8s创建NFS动态存储
k8s创建NFS动态存储
|
6月前
|
存储 Kubernetes 数据安全/隐私保护
在K8S中,如果后端nfs存储的ip发生变化如何解决?
在K8S中,如果后端nfs存储的ip发生变化如何解决?
|
24天前
|
缓存 容灾 网络协议
ACK One多集群网关:实现高效容灾方案
ACK One多集群网关可以帮助您快速构建同城跨AZ多活容灾系统、混合云同城跨AZ多活容灾系统,以及异地容灾系统。
|
2月前
|
Kubernetes Ubuntu 网络安全
ubuntu使用kubeadm搭建k8s集群
通过以上步骤,您可以在 Ubuntu 系统上使用 kubeadm 成功搭建一个 Kubernetes 集群。本文详细介绍了从环境准备、安装 Kubernetes 组件、初始化集群到管理和使用集群的完整过程,希望对您有所帮助。在实际应用中,您可以根据具体需求调整配置,进一步优化集群性能和安全性。
115 12
|
2月前
|
Prometheus Kubernetes 监控
OpenAI故障复盘 - 阿里云容器服务与可观测产品如何保障大规模K8s集群稳定性
聚焦近日OpenAI的大规模K8s集群故障,介绍阿里云容器服务与可观测团队在大规模K8s场景下我们的建设与沉淀。以及分享对类似故障问题的应对方案:包括在K8s和Prometheus的高可用架构设计方面、事前事后的稳定性保障体系方面。
|
2月前
|
Kubernetes 网络协议 应用服务中间件
Kubernetes Ingress:灵活的集群外部网络访问的利器
《Kubernetes Ingress:集群外部访问的利器-打造灵活的集群网络》介绍了如何通过Ingress实现Kubernetes集群的外部访问。前提条件是已拥有Kubernetes集群并安装了kubectl工具。文章详细讲解了Ingress的基本组成(Ingress Controller和资源对象),选择合适的版本,以及具体的安装步骤,如下载配置文件、部署Nginx Ingress Controller等。此外,还提供了常见问题的解决方案,例如镜像下载失败的应对措施。最后,通过部署示例应用展示了Ingress的实际使用方法。
77 2

热门文章

最新文章