k8s1.27使用NFS作為StorageClass

1. 概述

在日常學(xué)習(xí)與企業(yè)內(nèi)網(wǎng)環(huán)境中,可能并沒有條件使用Ceph等分布式存儲艘希,這時可以使用NFS作為StorageClass侠坎。

NFS代表網(wǎng)絡(luò)文件系統(tǒng)(Network File System)庄新,它是一種允許計算機(jī)通過網(wǎng)絡(luò)共享文件和存儲設(shè)備的協(xié)議偿短。

2. 環(huán)境說明

本文nfs server所在服務(wù)器的操作系統(tǒng)為Ubuntu 22.04.2, IP為192.168.3.10

kubernetes版本為1.27.2
kubernetes節(jié)點(diǎn)的操作系統(tǒng)為RockyLinux 9.2 x64

3. k8s集群外部署NFS server

  1. 安裝nfs server
apt install -y nfs-kernel-server 
  1. 配置nfs server
mkdir /data/nfs
chmod a+rw /data/nfs/
echo '/data/nfs *(rw,sync,no_subtree_check,no_root_squash,insecure)' >> /etc/exports
# 使配置生效
exportfs -r
# 查看當(dāng)前配置
exportfs

systemctl restart rpcbind
systemctl enable rpcbind
systemctl restart nfs-server
systemctl enable nfs-server

# 查看rpc服務(wù)的注冊情況
rpcinfo -p localhost |grep nfs
showmount -e 192.168.3.10

4. k8s集群內(nèi)創(chuàng)建Storage class

官方文檔: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner


4.1 所有k8s節(jié)點(diǎn)安裝nfs client

# centos/rockylinux
yum install -y nfs-utils

4.2 為NFS設(shè)置rbac

創(chuàng)建文件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 apply -f rbac.yaml

輸出

serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

4.3 創(chuàng)建nfs subdir external provisioner

創(chuàng)建文件nfs-subdir-external-provisioner.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          # image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          image: k8s.dockerproxy.com/sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              # value: <YOUR NFS SERVER HOSTNAME>
              value: 192.168.3.10
            - name: NFS_PATH
              # value: /var/nfs
              value: /data/nfs
      volumes:
        - name: nfs-client-root
          nfs:
            # server: <YOUR NFS SERVER HOSTNAME>
            server: 192.168.3.10
            path: /data/nfs
kubectl apply -f nfs-subdir-external-provisioner.yaml

4.4 部署storage class

創(chuàng)建文件nfs-storage-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:
  pathPattern: "${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}" # 此處也可以使用 "${.PVC.namespace}/${.PVC.name}" 來使用pvc的名稱作為nfs中真實目錄名稱
  onDelete: delete
kubectl apply -f nfs-storage-class.yaml

5. 測試nfs storage class

5.1 創(chuàng)建一個PVC

創(chuàng)建文件nfs-pvc.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  annotations:
    nfs.io/storage-path: "test-path" # not required, depending on whether this annotation was shown in the storage class description
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 50Mi
kubectl apply -f nfs-pvc.yaml

查看pvc

kubectl get pvc

輸出

NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim   Bound    pvc-e9a9f6ad-45f8-4e3f-9b1e-abdc5f59c7ef   50Mi       RWX            nfs-client     11s

5.2 在NFS server查看

登錄服務(wù)器192.168.3.10

可以看到在/data/nfs/目錄下有一個default目錄,這表示default命名空間

default目錄下有一個test-path目錄,這個就是創(chuàng)建pvc時在annotations指定的 nfs.io/storage-path: "test-path"凯旋;

tree /data/nfs/
/data/nfs/
├── default
│   └── test-path
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末呀潭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子至非,更是在濱河造成了極大的恐慌钠署,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荒椭,死亡現(xiàn)場離奇詭異谐鼎,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)趣惠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門狸棍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人味悄,你說我怎么就攤上這事草戈。” “怎么了傍菇?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長界赔。 經(jīng)常有香客問我丢习,道長,這世上最難降的妖魔是什么淮悼? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任咐低,我火速辦了婚禮,結(jié)果婚禮上袜腥,老公的妹妹穿的比我還像新娘见擦。我一直安慰自己,他們只是感情好羹令,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布鲤屡。 她就那樣靜靜地躺著,像睡著了一般福侈。 火紅的嫁衣襯著肌膚如雪酒来。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天肪凛,我揣著相機(jī)與錄音堰汉,去河邊找鬼辽社。 笑死,一個胖子當(dāng)著我的面吹牛翘鸭,可吹牛的內(nèi)容都是我干的滴铅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼就乓,長吁一口氣:“原來是場噩夢啊……” “哼汉匙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起档址,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤盹兢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后守伸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绎秒,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年尼摹,在試婚紗的時候發(fā)現(xiàn)自己被綠了见芹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蠢涝,死狀恐怖玄呛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情和二,我是刑警寧澤徘铝,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站惯吕,受9級特大地震影響惕它,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜废登,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一淹魄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧堡距,春花似錦甲锡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至易稠,卻和暖如春疚俱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缩多。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工呆奕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留养晋,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓梁钾,卻偏偏與公主長得像绳泉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子姆泻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容