【智簡聯接,萬物互聯】華為云·云享專家董昕:Serverless和微服務下, IoT的變革蓄勢待發
1380
2022-05-29
搭建 NFS 服務器
背景介紹
Kubernetes 對 Pod 進行調度時,以當時集群中各節點的可用資源作為主要依據,自動選擇某一個可用的節點,并將 Pod 分配到該節點上。在這種情況下,Pod 中容器數據的持久化如果存儲在所在節點的磁盤上,就會產生不可預知的問題,例如,當 Pod 出現故障,Kubernetes 重新調度之后,Pod 所在的新節點上,并不存在上一次 Pod 運行時所在節點上的數據。
為了使 Pod 在任何節點上都能夠使用同一份持久化存儲數據,我們需要使用網絡存儲的解決方案為 Pod 提供數據卷。常用的網絡存儲方案有:NFS/cephfs/glusterfs。
本文介紹一種使用 centos 搭建 nfs 服務器的方法。此方法僅用于測試目的,請根據您生產環境的實際情況,選擇合適的 NFS 服務。
配置要求
本文以手動模式部署一個開發測試用集群為例,如果使用通過 Rook 支持 Ceph 存儲方案,則不需要準備存儲主機。每個主機的用途和需求是:
配置NFS服務器
配置環境
本文中所有命令都以 root 身份執行
關閉防火墻服務
# 停止并禁用防火墻 systemctl stop firewalld systemctl disable firewalld
關閉并禁用SELinux
setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
安裝nfs-utils和rpcbind
yum install -y nfs-utils rpcbind
創建存儲的文件夾
# 創建文件夾 mkdir /nfs # 更改歸屬組與用戶 chown -R nfsnobody:nfsnobody /nfs
配置NFS
執行命令vim /etc/exports,創建 exports 文件,文件內容如下:
# 編輯exports vi /etc/exports # 輸入以下內容(格式:FS共享的目錄 NFS客戶端地址1(參數1,參數2,...) 客戶端地址2(參數1,參數2,...)) /nfs 172.16.106.215/24(rw,async,no_root_squash)
如果設置為 /nfs *(rw,async,no_root_squash) 則對所以的IP都有效
常用選項:
ro:客戶端掛載后,其權限為只讀,默認選項;
rw:讀寫權限;
sync:同時將數據寫入到內存與硬盤中;
async:異步,優先將數據保存到內存,然后再寫入硬盤;
Secure:要求請求源的端口小于1024
用戶映射:
root_squash:當NFS客戶端使用root用戶訪問時,映射到NFS服務器的匿名用戶;
no_root_squash:當NFS客戶端使用root用戶訪問時,映射到NFS服務器的root用戶;
all_squash:全部用戶都映射為服務器端的匿名用戶;
anonuid=UID:將客戶端登錄用戶映射為此處指定的用戶uid;
anongid=GID:將客戶端登錄用戶映射為此處指定的用戶gi
3.5、設置開機啟動并啟動
執行以下命令,啟動 nfs 服務:
rpcbind:
systemctl restart rpcbind
nfs:
systemctl enable nfs && systemctl restart nfs
查看是否有可用的NFS地址
檢查配置是否生效:
showmount -e 127.0.0.1
客戶端配置
本章節中所有命令都以 root 身份執行
服務器端防火墻開放111、662、875、892、2049的 tcp / udp 允許,否則遠端客戶無法連接。
安裝nfs-utils和rpcbind
執行以下命令安裝 nfs 客戶端所需的軟件包
yum install -y nfs-utils rpcbind
創建掛載的文件夾
mkdir -p /nfs-data
掛載nfs
執行以下命令掛載 nfs 服務器上的共享目錄到本機路徑/nfs-data
mount -t nfs -o nolock,vers=4 172.16.106.205:/nfs /nfs-data
參數解釋:
mount:掛載命令
o:掛載選項
nfs :使用的協議
nolock :不阻塞
vers : 使用的NFS版本號
IP : NFS服務器的IP(NFS服務器運行在哪個系統上,就是哪個系統的IP)
/nfs: 要掛載的目錄(Ubuntu的目錄)
/nfs-data : 要掛載到的目錄(開發板上的目錄,注意掛載成功后,/mnt下原有數據將會被隱藏,無法找到)
查看掛載:
df -h
卸載掛載:
umount /nfs-data
檢查 nfs 服務器端是否有設置共享目錄
# showmount -e $(nfs服務器的IP) showmount -e 172.16.106.205 # 輸出結果如下所示 Export list for 172.16.106.205: /nfs *
查看nfs版本
# 查看nfs服務端信息(服務端執行) nfsstat -s # 查看nfs客戶端信息(客戶端執行) nfsstat -c
寫入一個測試文件
echo "hello nfs server" > /nfs-data/test.txt
在 nfs 服務器上執行以下命令,驗證文件寫入成功:
cat /nfs/test.txt
部署 NFS-Subdir-External-Provisioner 提供動態分配卷
NFS-Subdir-External-Provisioner 簡介
NFS-Subdir-External-Provisioner是一個自動配置卷程序,它使用現有的和已配置的 NFS 服務器來支持通過持久卷聲明動態配置 Kubernetes 持久卷。
持久卷被配置為:${namespace}-${pvcName}-${pvName}。
此組件是對 nfs-client-provisioner 的擴展,nfs-client-provisioner 已經不提供更新,且 nfs-client-provisioner 的 Github 倉庫已經遷移到 NFS-Subdir-External-Provisioner 的倉庫。
GitHub 地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
創建 NFS 服務端
本文是具體介紹如何部署 NFS 動態卷分配應用 “NFS-Subdir-External-Provisioner”,所以部署前請確認已經存在 NFS 服務端,,如果非 Centos 系統,請先自行查找 NFS Server 安裝方法。
這里 NFS 服務端環境為:
IP地址:172.16.106.205
存儲目錄:/nfs/data
存儲目錄:/nfs/helm_data
部署 NFS Provisioner
創建 ServiceAccount
現在的 Kubernetes 集群大部分是基于 RBAC 的權限控制,所以創建一個一定權限的 ServiceAccount 與后面要創建的 “NFS Provisioner” 綁定,賦予一定的權限。
apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner namespace: default # 替換成你要部署的 Namespace --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nfs-client-provisioner-runner rules: - 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 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 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 namespace: default subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
創建 RBAC:
kubectl apply -f nfs-rbac.yaml
部署 NFS-Subdir-External-Provisioner
創建 NFS Provisioner 部署文件,這里將其部署到 “default” Namespace 中。
nfs-provisioner-deploy.yaml:
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner 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: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0 image: registry.cn-beijing.aliyuncs.com/xngczl/nfs-subdir-external-provisione:v4.0.0 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME ## Provisioner的名稱,以后設置的storageclass要和這個保持一致 value: nfs-client - name: NFS_SERVER ## NFS服務器地址,需和valumes參數中配置的保持一致 value: 172.16.106.205 - name: NFS_PATH ## NFS服務器數據存儲目錄,需和valumes參數中配置的保持一致 value: /nfs/data volumes: - name: nfs-client-root nfs: server: 172.16.106.205 ## NFS服務器地址 path: /nfs/data ## NFS服務器數據存儲目錄
創建 NFS Provisioner:
# -n: 指定應用部署的 Namespace kubectl apply -f nfs-provisioner-deploy.yaml
創建 NFS SotageClass
創建一個 StoageClass,聲明 NFS 動態卷提供者名稱為 “nfs-storage”。
nfs-storage.yaml:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "false" ## 是否設置為默認的storageclass provisioner: nfs-client ## 動態卷分配者名稱,必須和上面創建的"provisioner"變量中設置的Name一致 parameters: archiveOnDelete: "true" ## 設置為"false"時刪除PVC不會保留數據,"true"則保留數據 mountOptions: - hard ## 指定為硬掛載方式 - nfsvers=4 ## 指定NFS版本,這個需要根據NFS Server版本號設置
創建 StorageClass:
kubectl apply -f nfs-storage.yaml
創建 PVC 和 Pod 進行測試
在 Namespace 下創建一個測試用的 PVC 并觀察是否自動創建是 PV 與其綁定。
test-pvc.yaml:
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-pvc spec: storageClassName: nfs-storage #---需要與上面創建的storageclass的名稱一致 accessModes: - ReadWriteOnce resources: requests: storage: 1Mi
創建 PVC:
kubectl apply -f test-pvc.yaml
查看 PVC 狀態是否與 PV 綁定
利用 Kubectl 命令獲取 pvc 資源,查看 STATUS 狀態是否為 “Bound”。
$ kubectl get pvc test-pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test-pvc Bound pvc-105a5f32-e4dd-4b1d-943b-c4f2ca498f60 1Mi RWO nfs-storage-new 45m
創建一個測試用的 Pod,指定存儲為上面創建的 PVC,然后創建一個文件在掛載的 PVC 目錄中,然后進入 NFS 服務器下查看該文件是否存入其中。
test-pod.yaml:
kind: Pod apiVersion: v1 metadata: name: test-pod spec: containers: - name: test-pod image: busybox:latest command: - "/bin/sh" args: - "-c" - "touch /mnt/SUCCESS && exit 0 || exit 1" #創建一個名稱為"SUCCESS"的文件 volumeMounts: - name: nfs-pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-pvc
創建 Pod:
# -n:指定創建 Pod 的 Namespace kubectl apply -f test-pod.yaml
進入 NFS 服務器驗證是否創建對應文件
進入 NFS 服務器的 NFS 掛載目錄,查看是否存在 Pod 中創建的文件:
[root@nfs ~]# cd /nfs/data/ [root@nfs data]# ll 總用量 4 drwxrwxrwx 2 root root 4096 10月 17 12:29 default-test-pvc-pvc-e85690ac-311f-46fa-af88-9501e35f8582 [root@nfs data]# cd default-test-pvc-pvc-e85690ac-311f-46fa-af88-9501e35f8582/ [root@nfs default-test-pvc-pvc-e85690ac-311f-46fa-af88-9501e35f8582]# ll 總用量 0 -rw-r--r-- 1 root root 0 10月 17 12:29 SUCCESS [root@nfs default-test-pvc-pvc-e85690ac-311f-46fa-af88-9501e35f8582]#
可以看到已經生成 SUCCESS 該文件,并且可知通過 NFS Provisioner 創建的目錄命名方式為“namespace名稱-pvc名稱-pv名稱”,pv 名稱是隨機字符串,所以每次只要不刪除 PVC,那么 Kubernetes 中的與存儲綁定將不會丟失,要是刪除 PVC 也就意味著刪除了綁定的文件夾,下次就算重新創建相同名稱的 PVC,生成的文件夾名稱也不會一致,因為 PV 名是隨機生成的字符串,而文件夾命名又跟 PV 有關,所以刪除 PVC 需謹慎。
示例源碼:
https://github.com/zuozewei/blog-example/tree/master/Kubernetes/k8s-nfs-subdir-external-provisioner
Kubernetes
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。