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-cm
  namespace: storage
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: nfs-server
  name: nfs-server-svc
  namespace: storage
spec:
  clusterIP: 10.111.111.111
  ports:
  - name: tcp
    port: 2049
    targetPort: tcp
  selector:
    app.kubernetes.io/name: nfs-server
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: nfs-server
  name: nfs-server
  namespace: storage
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: nfs-server
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app.kubernetes.io/name: nfs-server
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nfs-server
                operator: In
                values:
                - "true"
      containers:
      - env:
        - name: SHARED_DIRECTORY
          value: /nfs-share-data
        image: nfs-server-2.6.4:alpine-3.20
        imagePullPolicy: IfNotPresent
        name: nfs-server
        ports:
        - containerPort: 2049
          name: tcp
          protocol: TCP
        resources:
          limits:
            cpu: 1000m
            memory: 1024Mi
          requests:
            cpu: 100m
            memory: 100Mi
        securityContext:
          capabilities:
            add:
            - SYS_ADMIN
        volumeMounts:
        - mountPath: /nfs-share-data
          name: nfs-share-data
        - mountPath: /etc/exports
          name: nfs-config
          subPath: exports
      volumes:
      - hostPath:
          path: /approot/k8s_data/nfs-share-data
          type: DirectoryOrCreate
        name: nfs-share-data
      - configMap:
          name: nfs-server-cm
        name: nfs-config
创建 pv 验证
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 10.111.111.111
    path: "/"
创建 pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
创建 pod 挂载验证
---
apiVersion: v1
kind: Pod
metadata:
  name: nfs-client
spec:
  containers:
  - name: app
    image: m.daocloud.io/busybox:1.37
    command: ["sh", "-c", "while true; do sleep 3600; done"]
    volumeMounts:
    - name: nfs-storage
      mountPath: /mnt/nfs
  volumes:
  - name: nfs-storage
    persistentVolumeClaim:
      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-provisioner
  name: nfs-subdir-external-provisioner-sa
  namespace: storage
---
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  labels:
    app: nfs-subdir-external-provisioner
  name: 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-provisioner
  name: nfs-subdir-external-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
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  labels:
    app: nfs-subdir-external-provisioner
  name: run-nfs-subdir-external-provisioner
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: nfs-subdir-external-provisioner-runner
subjects:
- kind: ServiceAccount
  name: nfs-subdir-external-provisioner-sa
  namespace: storage
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  labels:
    app: nfs-subdir-external-provisioner
  name: leader-locking-nfs-subdir-external-provisioner
  namespace: storage
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  verbs:
  - get
  - list
  - watch
  - create
  - update
  - patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    app: nfs-subdir-external-provisioner
  name: leader-locking-nfs-subdir-external-provisioner
  namespace: storage
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: leader-locking-nfs-subdir-external-provisioner
subjects:
- kind: ServiceAccount
  name: nfs-subdir-external-provisioner-sa
  namespace: storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nfs-subdir-external-provisioner
  name: nfs-subdir-external-provisioner
  namespace: storage
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-subdir-external-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-subdir-external-provisioner
    spec:
      containers:
      - env:
        - name: PROVISIONER_NAME
          value: cluster.local/nfs-subdir-external-provisioner
        - name: NFS_SERVER
          value: 10.111.111.111
        - name: NFS_PATH
          value: /
        image: docker.m.daocloud.io/registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
        imagePullPolicy: IfNotPresent
        name: nfs-subdir-external-provisioner
        volumeMounts:
        - mountPath: /persistentvolumes
          name: nfs-subdir-external-provisioner-root
      serviceAccountName: nfs-subdir-external-provisioner-sa
      volumes:
      - name: nfs-subdir-external-provisioner-root
        nfs:
          path: /
          server: 10.111.111.111

创建 pod 验证

提前创建 pvc 的方式

创建 pvc

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

创建 pod

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

---
kind: Pod
apiVersion: v1
metadata:
  name: test-pod
spec:
  containers:
  - name: test-pod
    image: m.daocloud.io/busybox:1.37
    command:
      - "/bin/sh"
    args:
      - "-c"
      - "touch /mnt/hello && exit 0 || exit 1"
    env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    volumeMounts:
      - name: nfs-pvc
        mountPath: "/mnt"
        subPathExpr: $(POD_NAME)
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        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: 1
  selector:
    matchLabels:
      app: test-sts
  template:
    metadata:
      labels:
        app: test-sts
    spec:
      containers:
      - name: test-sts
        image: m.daocloud.io/busybox:1.37
        command:
          - "/bin/sh"
        args:
          - "-c"
          - "touch /mnt/SUCCESS && exit 0 || exit 1"
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        volumeMounts:
          - name: nfs-sts-pvc
            mountPath: "/mnt"
            subPathExpr: $(POD_NAME)
      restartPolicy: "Always"
  volumeClaimTemplates:
  - metadata:
      name: nfs-sts-pvc
    spec:
      storageClassName: nfs-client
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL 干货 | SQL 半连接

大多数数据库开发人员和管理员都熟悉标准的内、外、左和右连接类型。虽然可以使用 ANSI SQL 编写这些连接类型&#xff0c;但还有一些连接类型是基于关系代数运算符的&#xff0c;在 SQL 中没有语法表示。今天我们将学习一种这样的连接类型&#xff1a;半连接&#xff08;Semi …

内网穿透:如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)

内网穿透&#xff1a;如何借助Cloudflare连接没有公网的电脑的远程桌面(RDP)-含详细原理配置说明介绍 前言 远程桌面协议(RDP, Remote Desktop Protocol)可用于远程桌面连接&#xff0c;Windows系统&#xff08;家庭版除外&#xff09;也是支持这种协议的&#xff0c;无需安装…

[RK3566-Android11] 使用SPI方式点LED灯带-JE2815/WS2812,实现呼吸/渐变/随音量变化等效果

问题描述 之前写了一篇使用GPIO方式点亮LED灯带的文章 https://blog.csdn.net/jay547063443/article/details/134688745?fromshareblogdetail&sharetypeblogdetail&sharerId134688745&sharereferPC&sharesourcejay547063443&sharefromfrom_link 使用GPIO…

C++20中头文件ranges的使用

<ranges>是C20中新增加的头文件&#xff0c;提供了一组与范围(ranges)相关的功能&#xff0c;此头文件是ranges库的一部分。包括&#xff1a; 1.concepts: (1).std::ranges::range:指定类型为range&#xff0c;即它提供开始迭代器和结束标记(it provides a begin iterato…

博弈论 C++

前置知识 若一个游戏满足&#xff1a; 由两名玩家交替行动在游戏进行的任意时刻&#xff0c;可以执行的合法行动与轮到哪位玩家无关不能行动的玩家判负 则称该游戏为一个公平组合游戏。 尼姆游戏&#xff08;NIM&#xff09;属于公平组合游戏&#xff0c;但常见的棋类游戏&…

idea(2017版)创建项目的搭建方式

目录 一、普通Java项目 二、普通JavaWeb项目 三、maven的Java项目 四、maven的JavaWeb项目 一、普通Java项目 1.创建新项目 2.因为是普通的java项目&#xff0c;所以先点最上面的Java&#xff0c;然后确定jdk&#xff0c;然后next 3.这里直接点next 4.写好项目名称和路径…

互联网系统的微观与宏观架构

互联网系统的架构设计&#xff0c;通常会根据项目的体量、业务场景以及技术需求被划分为微观架构&#xff08;Micro-Architecture&#xff09;和宏观架构&#xff08;Macro-Architecture&#xff09;。这两者的概念与职责既独立又相互关联。本文将通过一些系统案例&#xff0c;…

Vue3 学习笔记(五)Vue3 模板语法详解

在 Vue3 的世界里&#xff0c;模板语法是我们构建用户界面的基石。今天&#xff0c;让我们一起深入了解 Vue3 的模板语法&#xff0c;我将用通俗易懂的语言和实用的例子&#xff0c;带你掌握这项必备技能。 1、文本插值&#xff1a;最基础的开始 想在页面上显示数据&#xff1f…

《探索 HarmonyOS NEXT(5.0):开启构建模块化项目架构奇幻之旅 —— 模块化基础篇》

从无到有&#xff0c;打造模块化项目。构建一个开箱即用的项目&#xff0c;从 Git 上拉取下来即可直接进行开发&#xff0c;其中涵盖路由通信、上下拉刷新、网络请求、事件通知、顶部tab封装等功能&#xff0c;项目里调用API为鸿洋大佬的wanAndroidAPI。后期将持续完善&#xf…

【C】数组(array)

数组(array) 数组的概念 数组是一组相同类型元素的集合 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0数组中存放的多个数据&#xff0c;类型是相同的 数组分为一维数组和多维数组&#xff0c;多维数组一般比较多见的是二维数组 一维数组的创建和初始…

JAVA面试八股文(五)

#1024程序员节&#xff5c;征文# 在1024程序员节这个特别的日子里&#xff0c;首先&#xff0c;我想对每一位程序员表示最诚挚的祝贺&#xff01;祝愿大家在未来的日子里&#xff0c;能够继续热爱编程、追求卓越&#xff0c;携手共创更美好的科技未来&#xff01;让我们共同庆祝…

Redis Search系列 - 第六讲 基准测试 - Redis Search VS. MongoDB VS. ElasticSearch

目录 一、引言二、Redis Search 2.x版本的性能提升三、Redis Search VS. MongoDB VS. ElasticSearch3.1 测试环境3.2 100%写 - 基准测试3.3 100%读 - 基准测试3.4 混合读/写/搜索 - 基准测试2.5 搜索延迟分析3.6 读延迟分析3.7 写延迟分析3.8 Redis Search VS. ElasticSearch3.…

混个1024勋章

一眨眼毕业工作已经一年了&#xff0c;偶然进了游戏公司成了一名初级游戏服务器开发。前两天总结的时候&#xff0c;本来以为自己这一年没学到多少东西&#xff0c;但是看看自己的博客其实也有在进步&#xff0c;虽然比不上博客里的众多大佬&#xff0c;但是回头看也算是自己的…

micro-app【微前端实战】主应用 vue3 + vite 子应用 vue3+vite

micro-app 官方文档为 https://micro-zoe.github.io/micro-app/docs.html#/zh-cn/framework/vite 子应用 无需任何修改&#xff0c;直接启动子应用即可。 主应用 1. 安装微前端框架 microApp npm i micro-zoe/micro-app --save2. 导入并启用微前端框架 microApp src/main.ts …

手机摄影入门

感觉会摄影的人是能够从生活中发现美的人。 我不太会拍照&#xff0c;觉得拍好的照片比较浪费时间&#xff0c;而且缺乏审美也缺乏技巧&#xff0c;所以拍照的时候总是拍不好。但有时候还是需要拍一些好看的照片的。 心态和审美可能需要比较长时间提升&#xff0c;但一些基础…

Apple Vision Pro市场表现分析:IDC最新数据揭示的真相

随着AR/VR技术逐渐成熟并被更多消费者接受,2024年第二季度(Q2)成为这一领域的一个重要转折点。根据国际数据公司(IDC)发布的最新报告,整个AR/VR市场在本季度经历了显著的增长。接下来,我们将深入探讨Apple Vision Pro在这股增长浪潮中的具体表现。 市场背景 2024年Q2,…

中航资本:股票支撑位和压力位什么意思?股票如何找支撑与压力?

股票支撑位和压力位什么意思&#xff1f; 支撑位是指股票价格在下跌过程中遇到的一个或多个价格方位&#xff0c;这些价位上存在着较强的买盘力气&#xff0c;可以提供满足的支撑&#xff0c;阻止股价继续下跌。 而股票压力位是指股票价格在上涨过程中遇到的一个或多个价格方…

docker部署rustdesk

文章目录 一.ubuntu修改ssh端口二.开放端口三.安装rustDesk四.连接验证 一.ubuntu修改ssh端口 借鉴乌班图Ubuntu 24.04 SSH Server 修改默认端口重启无效 https://bugs.launchpad.net/ubuntu/source/openssh/bug/2069041 sudo vim /etc/ssh/sshd_config sudo systemctl daem…

在windows下利用安装docker加vscode调试OceanBase,

文章目录 一、安装WSL二、安装docker三、 OceanBase安装 -- 运行镜像&#xff0c;配置VScode四、 OceanBase安装 -- 将获取到的文件与docker容器 映射连接 – 参考官方文档 docker安装 在windows上通过docker配置环境并利用vscode调试代码 一、安装WSL 1.可以在任务管理器中&…

⌈ 传知代码 ⌋ 农作物病害分类(Web端实现)

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…