背景
服務(wù)端:centos 7.6。ip:47.96.156.20。
客戶端:centos 7.6烂琴。ip:
服務(wù)端不在同一vpc下赊琳。
nfs簡(jiǎn)介
NFS是Network File System的簡(jiǎn)寫,即網(wǎng)絡(luò)文件系統(tǒng),NFS是FreeBSD支持的文件系統(tǒng)中的一種。NFS基于RPC(Remote Procedure Call)遠(yuǎn)程過(guò)程調(diào)用實(shí)現(xiàn),其允許一個(gè)系統(tǒng)在網(wǎng)絡(luò)上與它人共享目錄和文件题翰。通過(guò)使用NFS,用戶和程序就可以像訪問(wèn)本地文件一樣訪問(wèn)遠(yuǎn)端系統(tǒng)上的文件。NFS是一個(gè)非常穩(wěn)定的豹障,可移植的網(wǎng)絡(luò)文件系統(tǒng)冯事。具備可擴(kuò)展和高性能等特性,達(dá)到了企業(yè)級(jí)應(yīng)用質(zhì)量標(biāo)準(zhǔn)血公。由于網(wǎng)絡(luò)速度的增加和延遲的降低昵仅,NFS系統(tǒng)一直是通過(guò)網(wǎng)絡(luò)提供文件系統(tǒng)服務(wù)的有競(jìng)爭(zhēng)力的選擇 。
NFS與Samba服務(wù)類似累魔,但一般Samba服務(wù)常用于辦公局域網(wǎng)共享摔笤,而NFS常用于互聯(lián)網(wǎng)中小型網(wǎng)站集群架構(gòu)后端的數(shù)據(jù)共享。
NFS客戶端將NFS服務(wù)端設(shè)置好的共享目錄掛載到本地某個(gè)掛載點(diǎn)垦写,對(duì)于客戶端來(lái)說(shuō)吕世,共享的資源就相當(dāng)于在本地的目錄下。
rpc簡(jiǎn)介
RPC(Remote Procedure Call Protocol)遠(yuǎn)程過(guò)程調(diào)用協(xié)議梯投。它是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù)命辖,而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。
在NFS服務(wù)端和NFS客戶端之間分蓖,RPC服務(wù)扮演一個(gè)中介角色尔艇,NFS客戶端通過(guò)RPC服務(wù)得知NFS服務(wù)端使用的端口,從而雙方可以進(jìn)行數(shù)據(jù)通信么鹤。
rpc和nfs通訊
當(dāng)NFS服務(wù)端啟動(dòng)服務(wù)時(shí)會(huì)隨機(jī)取用若干端口漓帚,并主動(dòng)向RPC服務(wù)注冊(cè)取用相關(guān)端口及功能信息,這樣午磁,RPC服務(wù)就知道NFS每個(gè)端口對(duì)應(yīng)的的NFS功能了,然后RPC服務(wù)使用固定的111端口來(lái)監(jiān)聽(tīng)NFS客戶端提交的請(qǐng)求毡们,并將正確的NFS端口信息回復(fù)給請(qǐng)求的NFS客戶端迅皇。這樣,NFS客戶就可以與NFS服務(wù)端進(jìn)行數(shù)據(jù)傳輸了
nfs服務(wù)端
- 通過(guò)yum目錄安裝nfs服務(wù)和rpcbind服務(wù)
yum -y install nfs-utils rpcbind
- 啟動(dòng)服務(wù)
systemctl start rpcbind
systemctl enable rpcbind
systemctl start nfs(或者systemctl start nfs-server)
sytemctl enable nfs
- 查看nfs服務(wù)是否安裝正常
rpcinfo -p localhost
或者是通過(guò)公網(wǎng)測(cè)試服務(wù)端的nfs服務(wù)是否可用衙熔。
rpcinfo -p 47.96.156.20
顯示如下即正常
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 45993 status
100024 1 tcp 39431 status
100005 1 udp 20048 mountd
100005 1 tcp 20048 mountd
100005 2 udp 20048 mountd
100005 2 tcp 20048 mountd
100005 3 udp 20048 mountd
100005 3 tcp 20048 mountd
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 3 tcp 2049 nfs_acl
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 3 udp 2049 nfs_acl
100021 1 udp 43258 nlockmgr
100021 3 udp 43258 nlockmgr
100021 4 udp 43258 nlockmgr
100021 1 tcp 33941 nlockmgr
100021 3 tcp 33941 nlockmgr
100021 4 tcp 33941 nlockmgr
可以看到如上有3個(gè)主要進(jìn)程
- portmap:主要功能是進(jìn)行端口映射工作登颓。當(dāng)客戶端嘗試連接并使用RPC服務(wù)器提供的服務(wù)(如NFS服務(wù))時(shí),portmap會(huì)將所管理的與服務(wù)對(duì)應(yīng)的端口提供給客戶端红氯,從而使客戶可以通過(guò)該端口向服務(wù)器請(qǐng)求服務(wù)框咙。該進(jìn)程就是rpc服務(wù)的進(jìn)程,該服務(wù)使用111端口來(lái)件套nfs客戶端提交的請(qǐng)求痢甘,并將正確的nfs端口信息回復(fù)給請(qǐng)求的nfs客戶端喇嘱。
- mountd:它是RPC安裝守護(hù)進(jìn)程,主要功能是管理NFS的文件系統(tǒng)塞栅。當(dāng)客戶端順利通過(guò)nfsd登錄NFS服務(wù)器后者铜,在使用NFS服務(wù)所提供的文件前,還必須通過(guò)文件使用權(quán)限的驗(yàn)證。它會(huì)讀取NFS的配置文件/etc/exports來(lái)對(duì)比客戶端權(quán)限作烟。
- nfs:它是基本的NFS守護(hù)進(jìn)程愉粤,主要功能是管理客戶端是否能夠登錄服務(wù)器;nfs服務(wù)的端口默認(rèn)是2049拿撩,客戶端使用mount命令掛載報(bào)time out時(shí)衣厘,可能原因就是該進(jìn)程的端口未暴露。
- nfs 服務(wù)端共享配置
在NFS服務(wù)器端的主要配置文件為/etc/exports压恒,通過(guò)此配置文件可以設(shè)置服務(wù)端的共享文件目錄影暴。每條配置記錄由NFS共享目錄、NFS客戶端地址和參數(shù)這3部分組成涎显,格式如下
[NFS共享目錄](méi) [NFS客戶端地址1(參數(shù)1,參數(shù)2,參數(shù)3……)] [客戶端地址2(參數(shù)1,參數(shù)2,參數(shù)3……)]
- NFS共享目錄:nfs服務(wù)端上共享出去的文件目錄坤检;
- NFS客戶端地址:允許其訪問(wèn)的NFS服務(wù)端的客戶端地址,可以是客戶端IP地址期吓,也可以是一個(gè)網(wǎng)段(192.168.64.0/24)早歇,或者是*表示所有客戶端IP都可以訪問(wèn);
- 訪問(wèn)參數(shù):括號(hào)中逗號(hào)分隔項(xiàng)讨勤,主要是一些權(quán)限選項(xiàng)箭跳。
序號(hào) | 選項(xiàng) | 描述 |
---|---|---|
1 | ro | 客戶端對(duì)于共享文件目錄為只讀權(quán)限。(默認(rèn)設(shè)置) |
2 | rw | 客戶端對(duì)共享文件目錄具有讀寫權(quán)限 |
3 | root_squash | 使客戶端使用root賬戶訪問(wèn)時(shí)潭千,服務(wù)器映射為服務(wù)器本地的匿名賬號(hào)谱姓。 |
4 | no_root_squash | 客戶端連接服務(wù)端時(shí)如果使用的是root的話,那么也擁有對(duì)服務(wù)端分享的目錄的root權(quán)限 |
5 | all_squash | 將所有客戶端用戶請(qǐng)求映射到匿名用戶或用戶組(nfsnobody) |
6 | no_all_squash | 與上相反(默認(rèn)設(shè)置) |
7 | anonuid=xxx | 將遠(yuǎn)程訪問(wèn)的所有用戶都映射為匿名用戶刨晴,并指定該用戶為本地用戶(UID=xxx) |
8 | anongid=xxx | 將遠(yuǎn)程訪問(wèn)的所有用戶組都映射為匿名用戶組賬戶屉来,并指定該匿名用戶組賬戶為本地用戶組賬戶(GID=xxx) |
9 | sync | 同步寫操作,數(shù)據(jù)寫入存儲(chǔ)設(shè)備后返回成功信息狈癞。(默認(rèn)設(shè)置) |
10 | async | 異步寫操作茄靠,數(shù)據(jù)在未完全寫入存儲(chǔ)設(shè)備前就返回成功信息,實(shí)際還在內(nèi)存蝶桶。 |
11 | wdelay | 延遲寫入選項(xiàng)慨绳,將多個(gè)寫操請(qǐng)求合并后寫入硬盤,減少I/O次數(shù)真竖,NFS非正常關(guān)閉數(shù)據(jù)可能丟失(默認(rèn)設(shè)置) |
12 | no_wdelay | 與上相反脐雪,不與async同時(shí)生效,如果NFS服務(wù)器主要收到小且不相關(guān)的請(qǐng)求恢共,該選項(xiàng)實(shí)際會(huì)降低性能 |
13 | subtree | 若輸出目錄是一個(gè)子目錄战秋,則nfs服務(wù)器將檢查其父目錄的權(quán)限(默認(rèn)設(shè)置) |
14 | no_subtree | 即使輸出目錄是一個(gè)子目錄,nfs服務(wù)器也不檢查其父目錄的權(quán)限旁振,這樣可以提高效率 |
15 | secure | 限制客戶端只能從小于1024的tcp/ip端口連接nfs服務(wù)器(默認(rèn)設(shè)置) |
16 | insecure | 允許客戶端從大于1024的tcp/ip端口連接服務(wù)器 |
比如我們?cè)诜?wù)端的共享目錄為/nfs-share获询,接著輸入以下命令配置共享目錄
echo "/nfs-share *(rw,async,no_root_squash)" >> /etc/exports
要保證/nfs-share目錄已經(jīng)存在節(jié)點(diǎn)上涨岁,然后輸入以下命令使共享目錄生效。
exportfs -r
- 重新啟動(dòng)服務(wù)
systemctl restart rpcbind
systemctl restart nfs(或者systemctl restart nfs-server)
- 測(cè)試
showmount -e localhost
或者
showmount -e 公網(wǎng)ip
showmount命令查詢“mountd”守護(hù)進(jìn)程吉嚣,以顯示NFS服務(wù)器加載的信息梢薪。
-d:僅顯示已被NFS客戶端加載的目錄
-e:顯示NFS服務(wù)器上所有的共享目錄
- 問(wèn)題
一般showmount -e localhost命令都是好使的,在使用showmount -e 公網(wǎng)ip時(shí)會(huì)顯示如下問(wèn)題
showmount -e 47.96.156.205
clnt_create: RPC: Port mapper failure - Timed out
解決:
很明顯報(bào)的是portmapper進(jìn)程連接超時(shí)尝哆,很大可能是端口111沒(méi)有放行秉撇。我們使用telnet命令測(cè)試顯示,111端口確實(shí)沒(méi)有放開(kāi)。
[root@s1 ~]# telnet 47.96.156.205 111
Trying 47.96.156.205...
所有我們需要在安全組中放行TCP類型的端口111秋泄,放行之后再次測(cè)試發(fā)現(xiàn)還是連接超時(shí)琐馆。。
接著我們繼續(xù)放行mountd進(jìn)程的TCP端口20048恒序,瘦麸,放行之后再次測(cè)試發(fā)現(xiàn)仍然是連接超時(shí)。歧胁。滋饲。。
經(jīng)過(guò)一番排查喊巍,細(xì)心的朋友會(huì)發(fā)現(xiàn)portmapper進(jìn)程有TCP的111端口屠缭,也有UDP的111端口,mountd進(jìn)程有TCP的20048端口崭参,也有UDP的20048端口(rpcinfo -p 命令)呵曹。
接著放行UDP的111端口和UDP的20048端口后果然顯示成功了
[root@s1 ~]# showmount -e 47.96.156.205
Export list for 47.96.156.205:
/k8s *
至此,nfs的服務(wù)端就安裝成功了何暮。
nfs客戶端
服務(wù)端安裝完后奄喂,我們需要安裝NFS客戶端。
由于此實(shí)驗(yàn)條件不足海洼,導(dǎo)致nfs客戶端與nfs的服務(wù)端不是同一vpc下砍聊,所以我們需要使用nfs服務(wù)端的公網(wǎng)掛載,但是我們?cè)谏a(chǎn)環(huán)境中要保證在nfs服務(wù)端與客戶端都在同一個(gè)vpc下贰军,可以有效避免網(wǎng)絡(luò)之間的延遲。
- 安裝nfs-utils
yum install nfs-utils rpcbind -y
- 啟動(dòng)服務(wù)
systemctl start rpcbind
systemctl enable rpcbind
systemctl start nfs(或者使systemctl start nfs-server)
sytemctl enable nfs
- 客戶端講掛載點(diǎn)掛載到服務(wù)端的共享目錄
執(zhí)行如下命令掛載
[root@002 home]# mount -t nfs -o 47.96.156.205:/k8s /home/k8s/
mount: can't find /home/k8s/ in /etc/fstab
發(fā)現(xiàn)報(bào)如上問(wèn)題
首先解釋下命令含義蟹肘,mount常用來(lái)掛載文件系統(tǒng)词疼,本質(zhì)nfs就是一個(gè)文件系統(tǒng)。上面命令就是將客戶端目錄/home/k8s做為掛載點(diǎn)帘腹,掛載到nfs服務(wù)端的共享目錄/k8s下贰盗,nfs服務(wù)端的ip是47.96.156.205。通俗講就是將客戶端目錄/home/k8s與服務(wù)端的共享目錄/k8s實(shí)現(xiàn)共享阳欲。
執(zhí)行此命令之前必須保證nfs服務(wù)端的export文件內(nèi)已經(jīng)配置/k8s為共享目錄了舵盈。
接著繼續(xù)看我們的問(wèn)題陋率,/etc/fstab文件是配置nfs掛載點(diǎn)的文件,問(wèn)題也就很明顯了秽晚,我們需要在該文件的末尾新增一行配置一個(gè)掛載點(diǎn)瓦糟,配置如下。
47.96.156.205:/k8s /home/k8s nfs default 0 0
第一列是需要掛載的文件系統(tǒng)或者是存儲(chǔ)設(shè)備或者是需要掛載的目錄赴蝇。
第二列是掛載點(diǎn)菩浙,掛載點(diǎn)就是客戶端掛載的目錄。
第三列是文件系統(tǒng)或者是分區(qū)的類型(其實(shí)分區(qū)類型就是中文件系統(tǒng))
第四列是以何種形式掛載句伶,比如rw讀寫, auto自動(dòng)掛載,ro只讀等等參數(shù)劲蜻。不過(guò)最常用的是default。default是rw考余,suid先嬉,dev,exec楚堤,auto疫蔓,nouser,async等的組合钾军。
第五列為dump選項(xiàng)鳄袍,設(shè)置是否讓備份程序dump備份文件系統(tǒng),0為忽略吏恭,1為備份拗小。
第六列為fsck選項(xiàng),告訴fsck程序以什么順序檢查文件系統(tǒng)樱哼,0為忽略哀九。
此時(shí)繼續(xù)執(zhí)行上個(gè)命令
[root@002 home]# mount -t nfs -o 47.96.156.205:/k8s /home/k8s/
mount.nfs: Connection timed out
第一反應(yīng)是我們NFS服務(wù)的mountd進(jìn)程端口沒(méi)有放行,但是我們已經(jīng)放行了搅幅。經(jīng)發(fā)現(xiàn)阅束,nfs服務(wù)的端口2049的端口沒(méi)有放行,而nfs進(jìn)程的主要功能是管理客戶端是否能夠登錄服務(wù)器茄唐,所有問(wèn)題確認(rèn)了息裸,我們只需要放行NFS服務(wù)端TCP端口的2049即可,不用放行UDP端口為2049沪编。
此時(shí)我們執(zhí)行如下命令,此命令和上述命令相比沒(méi)有參數(shù)-o,發(fā)現(xiàn)掛載成功呼盆。
mount -t nfs 47.96.156.205:/k8s /home/k8s/
具體參數(shù)可以使用help命令查看
mount -help
- 測(cè)試
執(zhí)行如下命令
[root@002 home]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 909M 0 909M 0% /dev
tmpfs 919M 0 919M 0% /dev/shm
tmpfs 919M 90M 830M 10% /run
tmpfs 919M 0 919M 0% /sys/fs/cgroup
/dev/vda1 40G 18G 21G 47% /
tmpfs 184M 0 184M 0% /run/user/0
shm 64M 0 64M 0%
shm 64M 0 64M 0%
47.96.156.205:/k8s 40G 1.8G 36G 5% /home/k8s
在下面最后一行我們看到已經(jīng)掛載成功了。
此時(shí)我們?cè)诳蛻舳说?home/k8s目錄下新增或刪除內(nèi)容后蚁廓,服務(wù)端的/k8s目錄下也會(huì)立即發(fā)生相應(yīng)的內(nèi)容的改變访圃。
服務(wù)端的/k8s目錄下新增或刪除內(nèi)容后,會(huì)發(fā)現(xiàn)客戶端的/home/k8s目錄會(huì)立即發(fā)生相應(yīng)的內(nèi)容的改變
總結(jié):說(shuō)明服務(wù)端的共享目錄和客戶端的掛載點(diǎn)是雙向共享的相嵌。
k8s中volume使用nfs類型
k8s就相當(dāng)于是一個(gè)nfs的客戶端腿时。如果上述的客戶端掛載成功了况脆,k8s的掛載也一定能掛載成功。
最好k8s集群和nfs服務(wù)端在一個(gè)vpc下(同一局域網(wǎng)內(nèi))批糟。
deployment的yaml文件大致如下
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: nginx-php7
namespace: laravel
labels:
name: nginx-php7
annotations:
reloader.stakater.com/auto: "true"
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
name: nginx-php7
template:
metadata:
labels:
name: nginx-php7
spec:
containers:
- name: nginx-php7
image: harbor.maigengduo.com/laravel/nginx-php7:latest
ports:
- name: http
containerPort: 80
protocol: TCP
imagePullPolicy: Always
volumeMounts:
- name: nfs-share
mountPath: "/data"
restartPolicy: Always
volumes:
- name: nfs-share
nfs:
server: 47.96.156.20
path: "/k8s"
執(zhí)行kubectl apply -f deployment.yaml命令后發(fā)現(xiàn)格了,pod并沒(méi)有running狀態(tài)。kubeclt describe pod pod-id發(fā)現(xiàn)報(bào)如下錯(cuò)誤
mount: wrong fs type, bad option, bad superblock on 39.105.232.173:/first-k8s,
missing codepage or helper program, or other error
(for several filesystems (e.g. nfs, cifs) you might
need a /sbin/mount.<type> helper program)
In some cases useful info is found in syslog - try
dmesg | tail or so
經(jīng)查閱資料發(fā)現(xiàn)跃赚,我們沒(méi)有安裝nfs客戶端笆搓,我們?cè)疽詾閗8s會(huì)自動(dòng)安裝呢,其實(shí)并沒(méi)有纬傲。
那么現(xiàn)有有倆種選擇满败,nfs客戶端是在pod內(nèi)安裝還是在node內(nèi)安裝呢?
我們的第一反應(yīng)肯定是pod內(nèi)安裝叹括,因?yàn)樗械膱?zhí)行程序都在pod內(nèi)嘛算墨。但是了解k8s的volume原理的或者docker的volume原理的會(huì)知道,volume的本質(zhì)是將pod內(nèi)的文件映射到宿主機(jī)內(nèi)的一個(gè)目錄的汁雷。所有我們只需要在k8s集群內(nèi)所有的node節(jié)點(diǎn)上都安裝nfs集群即可净嘀,和上述的客戶端安裝方式相同。
但是發(fā)現(xiàn)不需要在node節(jié)點(diǎn)的/etc/fstab文件寫入掛載點(diǎn)侠讯。
在node節(jié)點(diǎn)上執(zhí)行df -h命令
[root@s1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 858M 0 858M 0% /dev
tmpfs 868M 0 868M 0% /dev/shm
tmpfs 868M 2.6M 865M 1% /run
tmpfs 868M 0 868M 0% /sys/fs/cgroup
47.96.156.205:/k8s 40G 1.9G 36G 5% /var/lib/kubelet/pods/5784ab85-bf51-11ea-b509-00163e0e21a6/volumes/kubernetes.io~nfs/nfs-share
可以看到pod的文件映射在主機(jī)的/var/lib/kubelet/pods/5784ab85-bf51-11ea-b509-00163e0e21a6/volumes/kubernetes.io~nfs/nfs-share目錄下挖藏。
多pod間共享存儲(chǔ)
該deployment中replicas(副本集)為2,也就是會(huì)有2個(gè)pod厢漩。
在第一個(gè)pod內(nèi)的/data目錄寫入數(shù)據(jù)時(shí)膜眠,在第二個(gè)pod內(nèi)的/data目錄下也會(huì)立即生成數(shù)據(jù),pod1和pod2內(nèi)/data目錄下的數(shù)據(jù)永遠(yuǎn)是相同溜嗜,倆個(gè)pod內(nèi)的數(shù)據(jù)是共享的宵膨。