k8s 1.28.2 集群部署 NFS server 和 NFS Subdir External Provisioner

文章目录

    • @[toc]
    • 前言
    • 部署 NFS server
      • 镜像准备
      • 节点打标签
      • 启动 NFS server
        • 创建 pv 验证
        • 创建 pvc
        • 创建 pod 挂载验证
    • 部署 NFS Subdir External Provisioner
      • 创建 pod 验证
        • 提前创建 pvc 的方式
        • 使用 volumeClaimTemplates 的方式

前言

NFS Subdir External Provisioner 可以使用现有的 NFS 服务器动态创建 pv 和 pvc

  • nfs-subdir-external-provisioner

部署 NFS server

镜像准备

这块可以看我之前的博客,这里就不啰嗦了

  • 使用 docker 的方式部署 NFS server 提供文件共享能力

节点打标签

采用 hostpath 的方式来持久化 NFS 的共享目录,需要绑定节点不让 NFS 飘移

k label node 192.168.22.124 nfs-server=true

启动 NFS server

  • 这里记录两个问题
    • NFS 的配置文件,根目录或者说第一个共享目录,需要加上 fsid=0 ,然后挂载的时候直接使用 / ,如果不加 fsid=0,挂载会报错找不到文件或目录,细节什么的,可以看一下官方的手册:exports
    • 因为需要本地宿主机挂载 NFS 共享目录到 kubelet 的目录下面,宿主机就没办法使用 svc 的方式来挂载,除非本地 DNS 服务器包含了 k8s 集群内的 DNS,我这边就暂时使用指定的 clusterIP 地址来创建 svc,集群内直接使用 svc 的 ip 地址来挂载 NFS
      • 关于 clusterip 的 ip 范围,需要看 apiserver 的 --service-cluster-ip-range 参数,一般都是 10.96.0.0/12,可用的范围在 10.96.0.010.111.255.255 之间,找一个集群内不存在的 ip 来用就行
      • Service ClusterIP 分配
      • exports 里面要把 node 节点的 ip 网段,svc 的网段和 pod 的网段都写进去,如果嫌烦,也可以直接写 * ,只要不是对外暴露的,问题不是很大
---
apiVersion: v1
data:exports: |/nfs-share-data 192.168.22.0/24(rw,fsid=0,sync,no_subtree_check,no_auth_nlm,insecure,no_root_squash)/nfs-share-data 10.96.0.0/12(rw,fsid=0,sync,no_subtree_check,no_auth_nlm,insecure,no_root_squash)/nfs-share-data 172.22.0.0/16(rw,fsid=0,sync,no_subtree_check,no_auth_nlm,insecure,no_root_squash)
kind: ConfigMap
metadata:name: nfs-server-cmnamespace: storage
---
apiVersion: v1
kind: Service
metadata:labels:app.kubernetes.io/name: nfs-servername: nfs-server-svcnamespace: storage
spec:clusterIP: 10.111.111.111ports:- name: tcpport: 2049targetPort: tcpselector:app.kubernetes.io/name: nfs-servertype: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app.kubernetes.io/name: nfs-servername: nfs-servernamespace: storage
spec:replicas: 1selector:matchLabels:app.kubernetes.io/name: nfs-serverstrategy:type: RollingUpdatetemplate:metadata:labels:app.kubernetes.io/name: nfs-serverspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: nfs-serveroperator: Invalues:- "true"containers:- env:- name: SHARED_DIRECTORYvalue: /nfs-share-dataimage: nfs-server-2.6.4:alpine-3.20imagePullPolicy: IfNotPresentname: nfs-serverports:- containerPort: 2049name: tcpprotocol: TCPresources:limits:cpu: 1000mmemory: 1024Mirequests:cpu: 100mmemory: 100MisecurityContext:capabilities:add:- SYS_ADMINvolumeMounts:- mountPath: /nfs-share-dataname: nfs-share-data- mountPath: /etc/exportsname: nfs-configsubPath: exportsvolumes:- hostPath:path: /approot/k8s_data/nfs-share-datatype: DirectoryOrCreatename: nfs-share-data- configMap:name: nfs-server-cmname: nfs-config
创建 pv 验证
---
apiVersion: v1
kind: PersistentVolume
metadata:name: nfs-pv
spec:capacity:storage: 1GiaccessModes:- ReadWriteManynfs:server: 10.111.111.111path: "/"
创建 pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: nfs-pvc
spec:accessModes:- ReadWriteManyresources:requests:storage: 1Gi
创建 pod 挂载验证
---
apiVersion: v1
kind: Pod
metadata:name: nfs-client
spec:containers:- name: appimage: m.daocloud.io/busybox:1.37command: ["sh", "-c", "while true; do sleep 3600; done"]volumeMounts:- name: nfs-storagemountPath: /mnt/nfsvolumes:- name: nfs-storagepersistentVolumeClaim:claimName: nfs-pvc

如果 pod 启动有类似如下的报错,可以在 k8s 节点上安装一下 nfs-utils

  Warning  FailedMount  1s (x7 over 33s)  kubelet            MountVolume.SetUp failed for volume "nfs-pv" : mount failed: exit status 32
Mounting command: mount
Mounting arguments: -t nfs nfs-server-svc.storage.svc.cluster.local:/nfs-share-data /var/lib/kubelet/pods/9e7abc6f-573c-4c3f-b023-cdceee95722a/volumes/kubernetes.io~nfs/nfs-pv
Output: mount: /var/lib/kubelet/pods/9e7abc6f-573c-4c3f-b023-cdceee95722a/volumes/kubernetes.io~nfs/nfs-pv: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program.

部署 NFS Subdir External Provisioner

官方也有 helm 的文档,需要用 helm 的,可以直接看官方的:NFS Subdirectory External Provisioner Helm Chart

我这边采用 yaml 编排来部署

---
apiVersion: v1
kind: ServiceAccount
metadata:labels:app: nfs-subdir-external-provisionername: nfs-subdir-external-provisioner-sanamespace: storage
---
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:labels:app: nfs-subdir-external-provisionername: nfs-client
parameters:archiveOnDelete: "true"pathPattern: /
provisioner: cluster.local/nfs-subdir-external-provisioner
reclaimPolicy: Retain
volumeBindingMode: Immediate
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:labels:app: nfs-subdir-external-provisionername: nfs-subdir-external-provisioner-runner
rules:
- apiGroups:- ""resources:- nodesverbs:- get- list- watch
- apiGroups:- ""resources:- persistentvolumesverbs:- get- list- watch- create- delete
- apiGroups:- ""resources:- persistentvolumeclaimsverbs:- get- list- watch- update
- apiGroups:- storage.k8s.ioresources:- storageclassesverbs:- get- list- watch
- apiGroups:- ""resources:- eventsverbs:- create- update- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:labels:app: nfs-subdir-external-provisionername: run-nfs-subdir-external-provisioner
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: nfs-subdir-external-provisioner-runner
subjects:
- kind: ServiceAccountname: nfs-subdir-external-provisioner-sanamespace: storage
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:labels:app: nfs-subdir-external-provisionername: leader-locking-nfs-subdir-external-provisionernamespace: storage
rules:
- apiGroups:- ""resources:- endpointsverbs:- get- list- watch- create- update- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:labels:app: nfs-subdir-external-provisionername: leader-locking-nfs-subdir-external-provisionernamespace: storage
roleRef:apiGroup: rbac.authorization.k8s.iokind: Rolename: leader-locking-nfs-subdir-external-provisioner
subjects:
- kind: ServiceAccountname: nfs-subdir-external-provisioner-sanamespace: storage
---
apiVersion: apps/v1
kind: Deployment
metadata:labels:app: nfs-subdir-external-provisionername: nfs-subdir-external-provisionernamespace: storage
spec:replicas: 1selector:matchLabels:app: nfs-subdir-external-provisionerstrategy:type: Recreatetemplate:metadata:labels:app: nfs-subdir-external-provisionerspec:containers:- env:- name: PROVISIONER_NAMEvalue: cluster.local/nfs-subdir-external-provisioner- name: NFS_SERVERvalue: 10.111.111.111- name: NFS_PATHvalue: /image: docker.m.daocloud.io/registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2imagePullPolicy: IfNotPresentname: nfs-subdir-external-provisionervolumeMounts:- mountPath: /persistentvolumesname: nfs-subdir-external-provisioner-rootserviceAccountName: nfs-subdir-external-provisioner-savolumes:- name: nfs-subdir-external-provisioner-rootnfs:path: /server: 10.111.111.111

创建 pod 验证

提前创建 pvc 的方式

创建 pvc

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-claim
spec:storageClassName: nfs-clientaccessModes:- ReadWriteManyresources:requests:storage: 1Mi

创建 pod

由于 NFS 这块是直接走的共享目录的根目录,会比较乱,因此 pod 增加了变量,再通过 volumeMounts.subPathExpr 将共享数据存到 pod 名字的目录下

---
kind: Pod
apiVersion: v1
metadata:name: test-pod
spec:containers:- name: test-podimage: m.daocloud.io/busybox:1.37command:- "/bin/sh"args:- "-c"- "touch /mnt/hello && exit 0 || exit 1"env:- name: POD_NAMEvalueFrom:fieldRef:apiVersion: v1fieldPath: metadata.namevolumeMounts:- name: nfs-pvcmountPath: "/mnt"subPathExpr: $(POD_NAME)restartPolicy: "Never"volumes:- name: nfs-pvcpersistentVolumeClaim:claimName: test-claim

可以通过之前创建的 nfs-client 来验证是否创建了 hello 这个文件

kubectl exec -it nfs-client -- ls /mnt/nfs/test-pod/
使用 volumeClaimTemplates 的方式
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: test-sts
spec:replicas: 1selector:matchLabels:app: test-ststemplate:metadata:labels:app: test-stsspec:containers:- name: test-stsimage: m.daocloud.io/busybox:1.37command:- "/bin/sh"args:- "-c"- "touch /mnt/SUCCESS && exit 0 || exit 1"env:- name: POD_NAMEvalueFrom:fieldRef:apiVersion: v1fieldPath: metadata.namevolumeMounts:- name: nfs-sts-pvcmountPath: "/mnt"subPathExpr: $(POD_NAME)restartPolicy: "Always"volumeClaimTemplates:- metadata:name: nfs-sts-pvcspec:storageClassName: nfs-clientaccessModes:- ReadWriteOnceresources:requests:storage: 10Gi

同样可以通过之前创建的 nfs-client 来验证是否创建了 SUCCESS 这个文件

kubectl exec -it nfs-client -- ls /mnt/nfs/test-sts-0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/459029.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF+MVVM案例实战(一)- 设备状态LED灯变化实现

文章目录 1、项目创建2、UI界面布局1. MainWindow.xaml2、颜色转换器实现2.MainViewModel.cs 代码实现 3、运行效果4.源代码下载 1、项目创建 打开 VS2022 &#xff0c;新建项目 Wpf_Examples&#xff0c;创建各层级文件夹&#xff0c;安装 CommunityToolkit.Mvvm 和 Microsof…

python实现投影仪自动对焦

这是一款投影仪,它带有对焦摄像头 它是如何自动对焦的呢? 我们先看一下对焦算法展示效果 说明:左侧是原视频,右侧是对调焦后的视频帧展示,如果下一帧视频比当前帧清晰就会显示下一帧,否则,还是显示当前帧,直至找到更清晰的帧 原理说明: 在投影仪上对焦摄像头就会实…

HelloCTF [RCE-labs] Level 4 - SHELL 运算符

开启靶场&#xff0c;打开链接&#xff1a; 源码很简单&#xff0c;system("ping -c 1 $ip"); GET传参ip 构造payload&#xff1a; /?ip127.0.0.1;ls / /?ip127.0.0.1;cat /flag 成功得到flag&#xff1a; NSSCTF{04ad1d48-4530-481d-aa5d-8a153b0ebf2c}

常见学习陷阱及解决方案

文章目录 1. 拖延2. 信息过载3. 缺乏计划4. 过度依赖记忆5. 缺乏反馈6. 学习环境不佳7. 不够自信8. 不适合的学习方法结论 在学习过程中&#xff0c;学生常常会遇到各种陷阱&#xff0c;这些陷阱可能会影响学习效果和动机。以下是一些常见的学习陷阱及其解决方案&#xff1a; 1…

软硬链接_动静态库

软硬链接 软链接创建 硬链接创建 软链接是独立文件&#xff08;独立inode号&#xff09; 硬链接不是独立文件&#xff08;inode和目标相同&#xff09; 如何理解软硬链接 软链接有独立inode&#xff0c;软链接内容上&#xff0c;保存的是文件路径 硬链接不是独立文件&#xf…

服务器虚拟化全面教程:从入门到实践

服务器虚拟化全面教程&#xff1a;从入门到实践 引言 在现代 IT 基础设施中&#xff0c;服务器虚拟化已成为一种不可或缺的技术。它不仅能够提高资源利用率&#xff0c;还能降低硬件成本&#xff0c;优化管理流程。本文将深入探讨服务器虚拟化的概念、技术、应用场景及其实现…

初始JavaEE篇——多线程(6):线程池

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 到现在为止&#xff0c;我们已经学习了两个经典的多线程案例了&#xff1a;饿汉模式与懒汉模式、阻塞队列与生产者—消费者模型。想要…

static、 静态导入、成员变量的初始化、单例模式、final 常量(Content)、嵌套类、局部类、抽象类、接口、Lambda、方法引用

static static 常用来修饰类的成员&#xff1a;成员变量、方法、嵌套类 成员变量 被static修饰&#xff1a;类变量、成员变量、静态字段 在程序中只占用一段固定的内存&#xff08;存储在方法区&#xff09;&#xff0c;所有对象共享可以通过实例、类访问 (一般用类名访问和修…

CI/CD 的原理

一、CI/CD 的概念 CI/CD是一种软件开发流程&#xff0c;旨在通过自动化和持续的集成、测试和交付实现高质量的软件产品。 CI(Continuous Integration)持续集成 目前主流的开发方式是协同开发&#xff0c;即多位开发人员同事处理同意应用不同模块或功能。 如果企业在同一时间将…

高效数据集成案例:从聚水潭·奇门到MySQL

聚水潭奇门数据集成到MySQL的技术案例分享 在企业信息化建设中&#xff0c;数据集成是实现业务流程自动化和数据统一管理的关键环节。本文将分享一个具体的系统对接集成案例&#xff1a;如何将聚水潭奇门平台上的销售出库单数据高效、可靠地集成到MySQL数据库中&#xff0c;以…

编译,链接,加载

编译、链接、加载 编译、链接、加载是基础&#xff0c;十几年前从《深入理解计算机系统》等相关书籍中获得了比较全面的理解&#xff0c;现在已经变得有些模糊了。当时没有做总结的习惯&#xff0c;现在零零散散的记一些吧&#xff0c;有时间还要重温书本。 Build time 编译器…

Python(pandas库3)

函数 随机抽样 语法&#xff1a; n&#xff1a;要抽取的行数 frac&#xff1a;抽取的比例&#xff0c;比如 frac0.5&#xff0c;代表抽取总体数据的50% axis&#xff1a;示在哪个方向上抽取数据(axis1 表示列/axis0 表示行) 案例&#xff1a; 输出结果都为随机抽取。 空…

YOLOv8实战野生动物识别

本文采用YOLOv8作为核心算法框架&#xff0c;结合PyQt5构建用户界面&#xff0c;使用Python3进行开发。YOLOv8以其高效的实时检测能力&#xff0c;在多个目标检测任务中展现出卓越性能。本研究针对野生动物数据集进行训练和优化&#xff0c;该数据集包含丰富的野生动物图像样本…

Semantic Kernel进阶:创建和管理聊天(ChatCompletion)历史记录对象(四)

一、引言 在构建基于Semantic Kernel的AI应用时&#xff0c;聊天历史记录对象&#xff08;Chat History&#xff09;是维护对话上下文和连续性的关键。本文将一步步指导你如何创建和管理聊天历史记录对象&#xff0c;从而为你的AI代理提供一个强大的对话管理工具。 二、聊天…

规划控制复现:Apollo LQR横向控制(C++/simulink实现)

本文在前文已经搭建好的ROS-C规划控制验证平台中进行LQR算法的复现&#xff0c;理论部分详见于&#xff1a; 规划控制复现&#xff1a;Apollo LQR横向控制&#xff08;算法原理推导与流程&#xff09;_apollo 规划控制-CSDN博客 Prescan-Carsim-ROS的仿真平台搭建详见于&…

ASO优化秘籍!

根据 App Annie 发布的报告显示&#xff0c;现全球移动设备使用时长达到新高&#xff0c;日均 4.2 小时。在这大环境下&#xff0c;App 的竞争也愈演愈烈&#xff0c;App 想让更多人看到&#xff0c;似乎越来越难。那么&#xff0c;App 可以通过哪些方式进行推广&#xff1f; …

面向对象编程中类与类之间的关系(一)

目录 1.引言 2."有一个"关系 3."是一个"关系(继承) 4.“有一个”与“是一个”的区别 5.not-a关系 6.层次结构 7.多重继承 8.混入类 1.引言 作为程序员&#xff0c;必然会遇到这样的情况&#xff1a;不同的类具有共同的特征&#xff0c;至少看起来彼…

React写关键字高亮的三个方案

1.js正则replaceAlldangerouslySetInnerHTML{{ __html: xxx }}危险属性 步骤最简单,但是是危险属性,不推荐使用,项目中实在没有头绪,可以使用它应急 通过useMemo计算得到新的状态值,赋值给dangerouslySetInnerHTML属性的__html 关键代码: const [state1, setState1] useSt…

Linux 生产者消费者模型

1. 背景概念 假设现在有多个线程&#xff0c;一部分线程负责生产任务&#xff0c;称为生产者productor&#xff0c;另一部线程负责执行任务&#xff0c;称为消费者consumer&#xff0c;他们之间是一对一一对一一对一的关系。 现在生产者productor-3有任务要派发&#xff0c;但…

PlantUML在IDEA中使用

1.打开settings,搜索PlantUML Integration并下载 2.安装并重启IDEA 3.学习相关的语法即可进行使用