+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
張賀,多年互聯網行業工作經驗,擔任過網絡工程師、系統集成工程師、LINUX系統運維工程師
個人網站:www.zhanghehe.cn
筆者微信:zhanghe15069028807,現居濟南歷下區
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
一、概念
1、為什么用存儲?
當我們訪問WEB服務的時候,比如淘寶,淘寶的后台肯定不只有一台服務器,我們無論在什么地方登錄,看到的界面都是一樣的,雖然我們在不同的地區登錄,訪問的服務器也不是一個,但是這些服務器用的存儲都是一個。
一致性,當賣家刪除了一件商品時,所有的買家都不應該再看到這個商品,不能山東的用戶不能看到這個商品,但是山西的用戶卻能看到,而存儲服務器必須通過共享才能實現數據的一致性。
成本,一台WEB服務器,其實不需要太大的硬件空間,為什么?WEB服務器存的是代碼,而代碼是文本文本,文本文件占用的空間比較小,像淘寶的WEB前端的代碼也不會超過100M,阿里雲默認的WEB服務器自帶也就40G硬盤,這完全足夠使用了,我們不需要再另行增加,我們只需要做存儲的那一台服務器有大硬盤空間就可以了,其余的WEB前端服務器都是讀取的存儲服務器。
2、最重要的是什么?
對於一個大型網站,存儲的作用是共享,而不是加速,那么網站的加速靠什么?靠CDN
CDN的全稱是Content Delivery Network,即內容分發網絡,CDN是構建在現有網絡基礎之上的智能虛擬網絡,依靠部署在各地的邊緣服務器,通過中心平台的負載均衡、內容分發、調度等功能模塊,使用戶就近獲取所需內容,降低網絡擁塞,提高用戶訪問響應速度和命中率。CDN的關鍵技術主要有內容存儲和分發技術
對於一個網站頁面來說,存儲的最大作用是用來共享的,對速度的增加實有限,速度問題最終要靠CDN解決,通常是這樣的,前面WEB服務器將共享存儲掛載到本地,存儲又通過rsync的同步功能將數據推送到備份服務器,然后備份服務器再將內容推送到CDN。
CDN上存儲的是靜態的內容,比如電視劇、電影、圖片這些,一般不會輕易更改的,當用戶向網站寫入內容的時候,訪問的是真實提供服務的服務器, 寫入的數據會先寫到存儲上,然后存儲再推到CDN上;當用戶讀取網站的圖片、文字的時候,其實讀取的並不是提供服務的服務器上面的內容,而是CDN上面的內容,這樣減少了服務器的壓力。稍有規模的網站一般都使用了CDN加速。
3、專業存儲服務器
什么時候使用專業的存儲服務器取決於數據量的多少和數據的重要性。
假設說你公司有1T的的數據,有沒有必要使用專業的存儲呢?沒有必要,我們只需要買一台服務器充當存儲服務器即可。
專業的存儲與服務器充當的存儲有什么區別?
專業的存儲服務器就是在服務器充當的存儲之上再次改進的產物,這個改進包括和硬件和軟件兩個方面。比如專業的存儲比服務器充當的存儲能掛更多的硬盤,有一些新的技術,操作上更為簡單,服務上更加周到,任意的存儲廠商無論他們的宣傳手冊、營銷手段好花里胡哨,其實這些設備的本質都是一樣的,LINUX系統+開源軟件+前端WEB界面+號稱自研的軟件。
二、NFS
1、NFS原理
NFS是什么?是網絡文件系統,好吧,說白了,他就是一個基礎網絡的軟件,用來共享的。
為什么用NFS?因為方便,具體原因請看上文。
怎么用?這一章節就是講這玩意兒怎么用。
本地文件操作-本地系統調用:
當我們在系統之上創建一個文件夾的時候,其實硬件是無法識別這樣的操作,是shell將這樣的操作翻譯成系統能理解的二進制,然后告訴內核,內核通過驅動程序才能驅動硬盤,在硬盤上創建一個文件夾,然后由內核再返回結果,這里面涉及到用戶空間轉換到內核空間的過程。
NFS訪問流程:
-
當我們在NFS客戶端上執行一個操作時,請求先交給NFS客戶端。
-
NFS客戶端會將這些操作封裝成一個函數(通過上圖,我們看到這個函數包括讀、寫、創建、移動、改名)
-
再然后交給內核,但內核這時不會直接驅動硬盤了,而是會驅動tcp/ip協議棧,將封裝好函數通過網絡交給NFS服務端。
-
函數到達NFS服務器的內核時,首先到達的還是TCP/IP協議線,然后內核再交給服務端的BASH執行,進行本地系統調用 。
主機與主機之間是通過tcp/ip協議、NFS協議、rpc協議三者結合進行的跨主機遠程過程調用,這就要求rpc協議必須先運行起來,然后NFS協議才能和PRC結合起來,至於tcp/ip協議就不用我們操作了,它會一直運行在內核當中,它是內核的一部分。
NFS的原理:
NFS服務端並不會直接對外提供服務,默認不會偵聽任何固定的套接字,那它是怎樣給用戶提供服務的呢?它需要RPC程序的配合,RPC服務偵聽固定的套接字:111端口,客戶端訪問服務端的時候,目的端口剛開始是111,連接的RPC進程,RPC進程收到用戶的請求之后,會“告訴”NFS服務,有人來連接了,這個時候NFS服務才會臨時生成一個進程,讓這個進程偵聽在2049這個端口上,RPC服務會把NFS進程偵聽在2049這個消息告訴客戶端,客戶端會重新發起連接,這時的目的端口就是2049了,如果再有客戶端再連接NFS服務商,它還是會臨時再生成一個進程,再偵聽在2050端口上,RPC再告訴客戶端連接2050.
上述只是連接的部分,還沒有結束呢?連接完成之后,服務端還有兩個進程需要對客戶端的請求做檢查,rpc-mount進程和rpc-nfsd進程,nfsd進程檢查用戶的IP是否允許連接NFS服務,mount進程檢查用戶連接了NFS服務之后可以對目錄做什么權限,也就是說mount進程會根據/etc/exports文件對客戶端的請求做檢查。
2、 項目案例
NFS客戶端 | 192.168.80.166 |
---|---|
NFS服務器 | 192.168.80.200 |
需求:
將NFS服務端的/data目錄共享給192.168.80.0網段內的所有主機
在將數據寫入到NFS服務器的硬盤中后才會結合操作,最大限度保證數據的不丟失
將所有用戶映射為本地的匿名用戶(nfsnoby)
服務端
NFS要依賴於rpc協議進行函數的封裝和數據的傳輸,所以在安裝NFS包之前要先安裝RPC包,RPC相當於中介,NFS相當於房子,要先有中介,然后房源才能找到中介進行登記注冊。在centos6的時候,確實是這樣,要一起安裝兩個包,但是在centos7這里,我們就可以只安裝NFS,RPC做為NFS的依賴自動安裝,並自動啟動,自動加入開機啟動,也就是說,我們在centos7系統上面,完全不用理會RPC,它一切都是自動的,我們要需要安裝NFS,啟動,加入到開機啟動即可。
[root@NFS-SERVER ~]# yum erase nfs-utils
root@NFS-SERVER ~]# rpm -q nfs-utils
package nfs-utils is not installed
[root@NFS-SERVER ~]# yum list | grep '^nfs'
nfs-utils.x86_64 1:1.3.0-0.65.el7 base
nfs4-acl-tools.x86_64 0.3.3-20.el7 base
nfsometer.noarch 1.7-1.el7 base
nfstest.noarch 2.1.5-1.el7 base
[root@NFS-SERVER ~]# yum -y install nfs-utils
[root@NFS-SERVER ~]# systemctl is-active nfs-server
active
[root@NFS-SERVER ~]# systemctl status nfs-server
● nfs-server.service - NFS server and services
Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled)
Active: active (exited) since Thu 2019-10-31 09:53:29 CST; 20s ago
Main PID: 20402 (code=exited, status=0/SUCCESS)
CGroup: /system.slice/nfs-server.service
[root@NFS-SERVER ~]# systemctl status rpcbind #自動就運行了,不用我們管。
● rpcbind.service - RPC bind service
Loaded: loaded (/usr/lib/systemd/system/rpcbind.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-10-31 08:23:27 CST; 1h 31min ago
Main PID: 8350 (rpcbind)
CGroup: /system.slice/rpcbind.service
└─8350 /sbin/rpcbind -w
[root@NFS-SERVER ~]# rpm -qc nfs-utils #NFS的配置文件在這里並不會顯示,/etc/expors才是NFS的配置文件。
/etc/gssproxy/24-nfs-server.conf
/etc/modprobe.d/lockd.conf
/etc/nfs.conf
/etc/nfsmount.conf
/etc/request-key.d/id_resolver.conf
/etc/sysconfig/nfs
/var/lib/nfs/etab
/var/lib/nfs/rmtab
/var/lib/nfs/state
/var/lib/nfs/xtab
[root@NFS-SERVER ~]# cat /etc/exports
#語法相當簡單,共享哪個目錄?data,共享給誰?192.168.80.0這上網段,權限是啥(rw,rsync,all_squash)
/data 192.168.80.0/24(rw,rsync,all_squash)
[root@NFS-SERVER ~]# systemctl restart nfs-server
[root@NFS-SERVER ~]# rpm -ql nfs-utils | grep "etab"
/var/lib/nfs/etab
[root@NFS-SERVER ~]# cat /var/lib/nfs/etab
#如果/var/lib/nfs/etab這個文件里面有內容說明配置正確了,如果不正常說明不正確,現在沒有內容,那錯在哪里了呢?
#/data文件還沒有創建呢?創建一下
[root@NFS-SERVER ~]# mkdir /data
[root@NFS-SERVER ~]# systemctl restart nfs-server
[root@NFS-SERVER ~]# cat /var/lib/nfs/etab #創建了之后還是沒有內容
#這里面有一個坑,注意啊,我們在學rsync的時候,rsync這個單詞已經寫習慣了,配置文件里面是sync,而不是rsync!
[root@NFS-SERVER ~]# cat /etc/exports
/data 192.168.80.0/24(rw,sync,all_squash)
[root@NFS-SERVER ~]# systemctl restart nfs-server
[root@NFS-SERVER ~]# cat /var/lib/nfs/etab #再次查看,里面就有內容了。
/data 192.168.80.0/24
(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,
no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,root_squash,all_squash)
請注意/var/lib/nfs/etab這個文件,這個文件里面是啥呢?就是NFS啟動的時候對外輸出的內容,通過上面的內容我們可以看到當前NFS服務是以65534這個用戶來來運行的,那么這個用戶是誰呢?
[root@NFS-SERVER ~]# cat /etc/passwd | grep 65534
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
通過上面的內容,我們知道了,NFS服務是nfsnobody這個用戶運行的。
解釋一下all_squash這個參數的作用,我們看一下NFS這個服務當前是誰在運行?如下所示:
[root@NFS-SERVER ~]# ps aux | grep nfs
root 21380 0.0 0.0 0 0 ? S< 10:25 0:00 [nfsd4_callbacks]
root 21386 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21387 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21388 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21389 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21390 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21391 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21392 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21393 0.0 0.0 0 0 ? S 10:25 0:00 [nfsd]
root 21560 0.0 0.0 112708 976 pts/1 S+ 10:38 0:00 grep --color=auto nfs
當前正是root在運行,我們在參數里面加了all_aquash之后,NFS的運行者實際上還是root,但是當NFS向/data目錄里面寫入東西的時候,用的則是nfsnobody用戶,但是你看一看當前/data目錄的權限是啥?如下所示:
[root@NFS-SERVER ~]# ll -d /data
drwxr-xr-x 2 root root 6 Oct 31 10:05 /data
data目錄的所有人和所屬組都是root,所以等會客戶端掛載完成之后是無法寫入的,但這里面我們先不改,等到報了錯,我們看一下是什么錯誤,然后再回來更改。
客戶端
客戶端必須RPC服務,才能發起連接,干脆,我們也安裝nfs服務。
[root@NFS-client ~]# yum -y install nfs-utils
[root@NFS-client ~]# mkdir /nfs
[root@NFS-client ~]# showmount -e 192.168.80.200 #查看服務提供了哪些共享目錄
Export list for 192.168.80.200:
/data 192.168.80.0/24
[root@NFS-client ~]# mount -t nfs 192.168.80.200:/data /nfs
root@NFS-client nfs]# touch client.txt #寫入一個文件卻報錯,怎么回事?
touch: cannot touch ‘client.txt’: Permission denied
[root@NFS-SERVER ~]# chown nfsnobody:nfsnobody /data
[root@NFS-client nfs]# touch client.txt #成功寫入,無報錯
[root@NFS-client nfs]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos_centos7-root 50G 4.1G 46G 9% /
devtmpfs 1.6G 4.0K 1.6G 1% /dev
tmpfs 1.6G 0 1.6G 0% /dev/shm
tmpfs 1.6G 12M 1.6G 1% /run
tmpfs 1.6G 0 1.6G 0% /sys/fs/cgroup
/dev/sda1 1014M 179M 836M 18% /boot
/dev/mapper/centos_centos7-home 446G 39M 446G 1% /home
tmpfs 325M 0 325M 0% /run/user/0
192.168.80.200:/data 50G 4.1G 46G 9% /nfs #在這里
[root@NFS-client nfs]# nfsiostat #查看NFS的IO占用,不使用時為空
mount -t nfs 172.16.1.31:/data /data
指定類型 掛載什么 掛在什么地方
三、問題
1、自動掛載
客戶端寫入/etc/fstab文件即可,格式如下:
172.16.1.31:data /opt nfs default 0 0
2、客戶端掛載失敗,無法重啟
rd.break
ctrl+x進入救援模式
mount -o remount.rw /sysroot/
chroot /sysroot
編輯fstab,刪除一行
退出去
reboot
不重啟客戶端如何驗證客戶端的永久掛載是否正確呢?
mount -a
a是aoto是自動掛載的意思測試一下,不報錯就不會出問題,卡住了就是錯了,不要等着重啟才發現出錯,那就太晚了。
mount等於cat /proc/mounts這個文件
mount -a等於執行一下/etc/fstab這個文件
無需重啟NFS,平滑加載配置文件exports -rv
3、強制卸載
如果NFS服務端掛了,在客戶端正常卸載不掉的情況下,可以使用強制卸載。
umount -lf /nfsddir
4、安全性
通常NFS服務共享的只是普通的靜態數據:圖片、附件、視頻,不需要執行suid、exec等權限,掛載的這個文件系統只能作為數據存取之用,無法執行程序,對於客戶端來講增加了安全性,例如很多木馬篡改站點都是用上傳入口上傳的程序到存儲目錄,然后執行的。
//通過mount -o 指定掛載參數,禁止使用suid和exec,增加安全指數
mount -t nfs -oo nosuid,noexec,nodev 172.16.1.31/data /opt
5、性能
//通過mount -o指定掛載參數,禁止更新目錄及文件時間戳
mount -t nfs -o noatime,nodiratime 172.16.1.31:data /opt
通過mount -lf 可以進行強制卸載
6、建議
為了NFS存儲與前端的WEB程序統一用戶,通常NFS的寫入權限應當於nginx的運行用戶保持一致。也就是說當我們在exports文件里面要進行權限的壓縮,把寫入的權限壓縮成運行nginx的用戶。
groupadd -g 666 www
useradd -g 666 -u 666 -M -s /sbin/nologin www
vim /etc/exports
/data 192.168.80.0/24(rw,all_squash,anonuid=666,anongid=666)
四、小結
NFS存儲優點
-
NFS文件系統簡單易用、方便部署,數據可靠,服務穩定,滿足中小企業需求
-
NFS文件系統內存放的數據都在文件系統之上,所有數據都是可見的。
NFS存儲局限
-
存在單點故障,構建高可用維護麻煩web---nfs---backup
-
NFS數據明文,沒有校驗
-
客戶端掛載沒有密碼,安全性一般(也就內網使用)
NFS應用建議
-
生產場景應用將靜態數據盡可能向前推送,減少后端存儲的壓力
-
必須將存儲的靜態資源通過CDN緩存jpg/png/mp4/avi/css/js
-
如果沒有緩存,存儲再多對網站的速度也沒有太大幫助
大小問題
當我們在WEB上掛載了NFS共享的/data目錄之后,查看一下,我們發現/data的大小是50G,為什么是50G,我們難道共享了一個目錄就一下子共享了50G嗎?其實就是這樣的,你想呀,我們在/data的根下創建了目錄,那這個目錄是多大?我們在創建目錄的時候也不能指定這個目錄最大能到多少G,這就是和我們在windows上創建一個文件夾一樣,這個文件夾最終能變大取決於該文件夾所在的分區有多大,在NFS上/data是在根所有的分區上創建的,理論上NFS的根最大能變多大,/data目錄就能變多大。
[root@Web01 html]# df -h
Filesystem Size Used Avail Use% Mounted on
192.168.80.221:/data 50G 4.0G 47G 8% /var/www/html
我們在NFS上查看一下根的大小,發現根就是50G,這下你明白了吧!
[root@Nfs ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 50G 4.0G 47G 8% /