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