实战:用“廉价”的NFS作为K8S后端存储

简介: 实战:用“廉价”的NFS作为K8S后端存储

K8S后端存储:NFS

大家都知道,NFS是一种基于网络的文件系统协议,允许在不同的机器之间共享文件系统资源。在K8S中,可以使用NFS作为后端存储,以提供持久化存储和共享存储卷。但是否适合在生产环境使用NFS作为后端存储,这取决于具体的应用程序和使用场景。如果应用程序对性能和可靠性要求比较高,可能需要选择其他更适合的存储方案,比如ceph。如果只是在测试或者开发环境中,我觉得使用NFS可以更方便地实现共享存储卷,提高测试或者开发的效率。

搭建NFS

# step1 安装yum install nfs-utils -y
yum install nfs-utils -y
# step2 创建NFS共享目录
mkdir /data/nfs_k8s_storage_share
# step3 配置NFS共享,编辑/etc/exports文件,将要共享的目录添加到文件中
/data/nfs_k8s_storage_share *(rw,sync,no_root_squash) # 这将允许任何客户端以读写模式访问共享目录。
# step4 重新加载NFS配置
exportfs -r
# step5 启动NFS服务
systemctl start nfs-server
systemctl enable nfs-server
# step6 确认NFS服务正在运行
systemctl status nfs-server
# step7 注意防火墙,可以关闭或添加允许策略
firewall-cmd --permanent --zone=public --add-service=nfs
firewall-cmd --reload
# step8 验证是否共享成功
showmount -e 192.168.11.254

k8s工作节点安装nfs-utils

安装完即可,无需做任何配置

yum install nfs-utils -y

具体在哪个工作节点安装得看在下面的deployment.yaml中拉起的NFS客户端配置程序pod跑在哪个节点上,可以让该pod调度到指定的节点,那么该节点就要安装好nfs-utils。如果不干涉调度行为,或者考虑到后续要跑多个副本就可以将全部工作节点都安装好nfs-utils。

在k8s master节点上安装nfs动态供给插件

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

相关yaml下载链接: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/blob/master/deploy/rbac.yamlhttps://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/blob/master/deploy/deployment.yamlhttps://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/blob/master/deploy/class.yaml

  • rbac.yaml:授权访问ApiServer
  • deployment.yaml:部署插件,部署之前要修改里面的指向的nfs服务器地址和共享目录
  • class.yaml:创建存储类
开始部署插件
  1. 部署rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
---
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: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
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
  # replace with namespace where provisioner is deployed
  namespace: default
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 deployed
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
kubectl create -f rbac.yaml
  1. 部署deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
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: tantianran/nfs-subdir-external-provisioner:v4.0.1 # 使用到镜像已经转存到我的仓库
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.11.254 #此处修改成nfs服务器的ip地址
            - name: NFS_PATH
              value: /data/nfs_k8s_storage_share # 此处修改成nfs的共享目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.11.254 #此处修改成nfs服务器的ip地址
            path: /data/nfs_k8s_storage_share # 此处修改成nfs的共享目录
kubectl create -f deployment.yaml
  1. 创建存储类class.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"
kubectl create -f class.yaml
  1. 查看
# 查看授权
kubectl get sa
# 查看存储类
kubectl get sc

使用

  1. 创建一个PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: nfs-client

在这里,PVC名称为my-pvc,请求5GB的存储空间,并将存储类设置为nfs-client

  1. 查看pvc
# pvc已创建
[root@k8s-a-master nfs-storage-yaml]# kubectl get pvc
NAME     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
my-pvc   Bound    pvc-ce18ae0a-d4b4-4fa9-8241-b8b9551baa61   5Gi        RWO            nfs-client     2m6s
# 对应的pv已经自动创建
[root@k8s-a-master nfs-storage-yaml]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
pvc-ce18ae0a-d4b4-4fa9-8241-b8b9551baa61   5Gi        RWO            Delete           Bound    default/my-pvc   nfs-client              2m7s
[root@k8s-a-master nfs-storage-yaml]#
  1. 创建一个应用pod
apiVersion: v1
kind: Pod
metadata:
  name: test-nginx-pod
spec:
  containers:
  - name: test-nginx-container
    image: nginx
    volumeMounts:
    - name: storage
      mountPath: /data
  volumes:
  - name: storage
    persistentVolumeClaim:
      claimName: my-pvc
  1. 查看pod是否挂载成功
[root@k8s-a-master nfs-storage-yaml]# kubectl exec -it test-nginx-pod -- df -h
...                                                                                            3.9G     0  3.9G   0% /sys/fs/cgroup
192.168.11.254:/data/nfs_k8s_storage_share/default-my-pvc-pvc-ce18ae0a-d4b4-4fa9-8241-b8b9551baa61  500G  1.8G  499G   1% /data
...
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
2月前
|
缓存 安全 前端开发
构建高效后端服务:从理论到实战
在数字化浪潮的推动下,后端服务成为了支撑现代互联网应用的核心。本文旨在揭示如何打造一个既可靠又高效的后端系统,从基础架构设计、代码组织、性能优化到安全防护,全方位解析后端开发的艺术。通过实际代码示例和深入浅出的解释,引导读者理解并掌握后端开发的关键技术点。
|
2月前
|
存储 SQL 数据库
深入浅出后端开发之数据库优化实战
【10月更文挑战第35天】在软件开发的世界里,数据库性能直接关系到应用的响应速度和用户体验。本文将带你了解如何通过合理的索引设计、查询优化以及恰当的数据存储策略来提升数据库性能。我们将一起探索这些技巧背后的原理,并通过实际案例感受优化带来的显著效果。
56 4
|
2月前
|
运维 NoSQL Java
后端架构演进:微服务架构的优缺点与实战案例分析
【10月更文挑战第28天】本文探讨了微服务架构与单体架构的优缺点,并通过实战案例分析了微服务架构在实际应用中的表现。微服务架构具有高内聚、低耦合、独立部署等优势,但也面临分布式系统的复杂性和较高的运维成本。通过某电商平台的实际案例,展示了微服务架构在提升系统性能和团队协作效率方面的显著效果,同时也指出了其带来的挑战。
87 4
|
2月前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
131 1
|
2月前
|
JSON Dart 数据格式
<大厂实战场景> ~ flutter&鸿蒙next处理后端返回来的数据的转义问题
在 Flutter 应用开发中,处理后端返回的数据是常见任务,尤其涉及转义字符时。本文详细探讨了如何使用 Dart 的 `dart:convert` 库解析包含转义字符的 JSON 数据,并提供了示例代码和常见问题的解决方案,帮助开发者有效处理数据转义问题。
146 0
|
2月前
|
前端开发 JavaScript NoSQL
探索后端开发之旅:从基础到高级实战
【10月更文挑战第24天】在这个数字时代的浪潮中,后端开发如同一座巨大的宝藏岛,等待着勇敢的探险者去发掘。本文将作为你的藏宝图,引领你从浅滩走向深海,探索后端开发的广阔天地。无论你是初心者还是资深开发者,这篇文章都将为你提供价值连城的知识和技能。准备好了吗?让我们启航,一起构建强大、高效、安全的后端系统!
|
4月前
|
网络协议
keepalived对后端服务器的监测方式实战案例
关于使用keepalived进行后端服务器TCP监测的实战案例,包括配置文件的编辑和keepalived服务的重启,以确保配置生效。
92 1
|
5月前
|
大数据 数据处理 分布式计算
JSF 逆袭大数据江湖!看前端框架如何挑战数据处理极限?揭秘这场技术与勇气的较量!
【8月更文挑战第31天】在信息爆炸时代,大数据已成为企业和政府决策的关键。JavaServer Faces(JSF)作为标准的 Java Web 框架,如何与大数据技术结合,高效处理大规模数据集?本文探讨大数据的挑战与机遇,介绍 JSF 与 Hadoop、Apache Spark 等技术的融合,展示其实现高效数据存储和处理的潜力,并提供示例代码,助您构建强大的大数据系统。
63 0
|
5月前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
122 0
|
5月前
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
529 0