目錄
前言
為什么要搭建一個NAS
因?yàn)榇鎯臻g不夠了浪耘。本人有保留文檔的習(xí)慣乱灵,自己經(jīng)手過的東西,寫的代碼七冲、自己做的視頻痛倚、看過的書、看過的電影我都希望一直保留下來澜躺。所以數(shù)據(jù)越來越多蝉稳,而一個移動硬盤只有4TB的空間,存不下掘鄙。所以需要搭建一個NAS來擴(kuò)大存儲空間耘戚。
而且用移動硬盤還有一個風(fēng)險,萬一哪天這個盤壞掉了操漠,我的數(shù)據(jù)就全部丟失了收津。所以除了擴(kuò)大空間之外,需要做數(shù)據(jù)冗余浊伙。
因此這就引出了我的兩大需求:擴(kuò)大存儲空間撞秋、數(shù)據(jù)冗余。那么我如何來滿足這兩大需求嚣鄙?
Ceph是什么
Ceph是一種為優(yōu)秀的性能吻贿、可靠性和可擴(kuò)展性而設(shè)計的統(tǒng)一的、分布式文件系統(tǒng)哑子。
- 可靠性是指Ceph本身支持容錯舅列,數(shù)據(jù)存儲在Ceph系統(tǒng)中可以設(shè)置存儲副本肌割,當(dāng)其中一個副本因?yàn)橛脖P損壞不可訪問時,Ceph會通過副本還原出數(shù)據(jù)帐要。
- 分布式是指Ceph可以部署在多臺機(jī)器上把敞,并組合成為一個整體。當(dāng)一臺機(jī)器的存儲空間不夠時宠叼,可以將多臺機(jī)器的存儲合并到一起先巴。在大型企業(yè)中其爵,Ceph可以將成百上千臺機(jī)器冒冬,上萬個硬盤的存儲空間合并成一個整體的文件系統(tǒng)。
Ceph的這兩大特性恰好滿足了我的兩大需求摩渺。
為什么用Ceph
能滿足我兩大需求的方案很多简烤,比如RAID也可以滿足,為什么要用Ceph摇幻?
隨著硬盤容量逐年上升横侦,數(shù)據(jù)量越來越大,硬盤變得越來越脆弱容易出現(xiàn)故障導(dǎo)致數(shù)據(jù)丟失找不回來绰姻。因此需要想辦法避免數(shù)據(jù)丟失枉侧。
常見的NAS通過RAID或者ZFS實(shí)現(xiàn)數(shù)據(jù)冗余,當(dāng)其中一份數(shù)據(jù)丟失之后狂芋,冗余的數(shù)據(jù)能把數(shù)據(jù)恢復(fù)出來榨馁。RAID和ZFS在擴(kuò)容時都不方便,操作不慎容易導(dǎo)致數(shù)據(jù)丟失帜矾。比如RAID1升級到RAID5要做數(shù)據(jù)重構(gòu)翼虫,重構(gòu)期間就有數(shù)據(jù)丟失的風(fēng)險,一旦丟失就丟掉了所有的數(shù)據(jù)屡萤。ZFS從2盤升級到4盤時珍剑,總共需要用到6個硬盤,其中兩個盤用于存放中間過程數(shù)據(jù)死陆,很不方便招拙。
因此為了讓擴(kuò)容更簡單,我們通過Ceph實(shí)現(xiàn)數(shù)據(jù)的冗余措译。在確保數(shù)據(jù)安全不丟失的前提下實(shí)現(xiàn)了擴(kuò)展的方便性别凤。Ceph的基本原理是把所有數(shù)據(jù)拆分成4MB的數(shù)據(jù)塊,每個數(shù)據(jù)塊構(gòu)建冗余瞳遍,并平均分散到各個硬盤上闻妓。并且確保同一份數(shù)據(jù)在多個硬盤同時保存,避免一個硬盤壞掉之后導(dǎo)致數(shù)據(jù)丟失掠械。
如何搭建一個基于Ceph的個人NAS
界面效果展示
NAS的核心是文件存儲:
后臺管理界面:
功能很豐富由缆,沒有一個個全部截圖注祖。
硬件裝機(jī)
硬件配置
- 主板: 微星Z370M-S01。268元均唉。
- 內(nèi)存:16Gx2金士頓 2666MHz是晨。 463元。
- CPU:i9-9900T舔箭。1620元罩缴。
- 系統(tǒng)盤:三星SSD 970 EVO Plus 500G。449元层扶。
- 數(shù)據(jù)盤:希捷酷狼Pro 16TB x2箫章。 2720元。
- 電源:益衡 7660B镜会。 749元檬寂。
- 機(jī)箱:拓普龍8盤位。520元戳表。
- 其它雜七雜八配件:
- CPU散熱: 雜牌超薄型桶至。70元。
- 網(wǎng)卡:PCIx1接口匾旭,2.5Gbps镣屹。49元。
- 網(wǎng)卡:USB接口价涝,2.5Gbps女蜈。67元。
- 網(wǎng)線:8類萬兆線飒泻。11元鞭光。
- DVI轉(zhuǎn)HDMI: 11元。
費(fèi)用:
- 總計費(fèi)用: 6997元泞遗。
- 目前裝了2盤位平均每TB費(fèi)用: 218元/TB惰许。
- 將來8盤位全部裝滿后平均每TB費(fèi)用: 118元/TB。其中85元是硬盤的費(fèi)用史辙。
搭建完之后的效果:
能耗測試
使用小米智能插座測試功率汹买,不是很準(zhǔn)但是可以參考量級。
- 基礎(chǔ)(電源+主板+CPU+內(nèi)存+SSD+網(wǎng)卡):21瓦
- 基礎(chǔ)+內(nèi)存測試:73瓦
- 基礎(chǔ)+1個系統(tǒng)盤空閑狀態(tài):26瓦
- 基礎(chǔ)+2個系統(tǒng)盤空閑狀態(tài):32瓦
- 基礎(chǔ)+2個系統(tǒng)盤+1個盤壞道檢測:43瓦
全年365x24小時開機(jī)大約耗電350度聊倔,不是很多晦毙。
內(nèi)存測試
通過MemTest86+,測了半小時耙蔑,沒遇到問題见妒。
硬盤測試
首先看Smart信息:都是全新的硬盤,沒有發(fā)現(xiàn)問題甸陌。
再掃描壞道须揣,掃描了兩個小時盐股,沒發(fā)現(xiàn)問題。
操作系統(tǒng)安裝
官方推薦使用22.04版本的Ubuntu耻卡。安裝之前把網(wǎng)線都拔掉疯汁,不然裝完之后會自動升級,導(dǎo)致功能不正常卵酪。
- 用戶名: cpc
- 計算機(jī)名稱: cpc (不要設(shè)置成node0幌蚊,不然后面安裝的時候會出現(xiàn)無法解析node0 IP的錯誤)
安裝完成后重啟。關(guān)掉cloud-init后門溃卡。因?yàn)橄到y(tǒng)每次啟動都會連接Ubuntu的服務(wù)器溢豆,存在后門風(fēng)險,因此干掉:
apt-get purge cloud-init -y
systemctl disable systemd-networkd-wait-online.service
本教程所有操作都以root身份運(yùn)行塑煎。
為了方便后續(xù)管理沫换,我們需要將節(jié)點(diǎn)的IP固定下來,不然每次IP不確定都要修改配置文件最铁。在路由器上設(shè)置DHCP:
- 設(shè)置DHCP動態(tài)IP的范圍192.168.31.100~199。
- 設(shè)置DHPC靜態(tài)IP規(guī)則垮兑,將這次新增的節(jié)點(diǎn)設(shè)置成192.168.31.10冷尉。后面192.168.31.11~19是將來擴(kuò)展節(jié)點(diǎn)。
配置hosts文件:
vi /etc/hosts
192.168.31.10 node0 testnode
192.168.31.11 node1
192.168.31.12 node2
192.168.31.13 node3
192.168.31.14 node4
192.168.31.15 node5
192.168.31.16 node6
192.168.31.17 node7
192.168.31.18 node8
192.168.31.19 node9
并且以上hosts配置要放到所有其它電腦上系枪。這樣其它電腦就能通過節(jié)點(diǎn)名稱來訪問雀哨,不需要指定IP。Ceph提供的Dashboard默認(rèn)只會通過節(jié)點(diǎn)名稱來訪問私爷。
Ceph的安裝
參考文檔: https://ceph.com/en/users/getting-started/
內(nèi)存至少8G雾棺。最少要求如下圖:
安裝cephadm并下載鏡像:
# 安裝cephadm
hostnamectl set-hostname node1
apt update
apt install -y docker.io uuid cephadm ceph-common
# docker翻墻
mkdir -p /etc/systemd/system/docker.service.d
cat <<EOF > /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://192.168.31.223:8001"
Environment="HTTPS_PROXY=http://192.168.31.223:8001"
EOF
systemctl daemon-reload
systemctl restart docker
systemctl show --property=Environment docker
# 下載Docker鏡像
docker pull quay.io/ceph/ceph:v17
設(shè)置環(huán)境變量:
uuid
vi /root/.bashrc
export fsid=???
alias cephadm='/usr/sbin/cephadm --image quay.io/ceph/ceph:v17'
mon_ip=192.168.31.11
node=node1
source /root/.bashrc
安裝集群:
# 安裝新集群
password=123456
cephadm bootstrap --mon-ip $mon_ip --skip-pull --dashboard-password-noupdate --initial-dashboard-password $password --fsid $fsid
# 刪除之前的集群
cephadm rm-cluster --fsid $fsid --force
# 設(shè)置UID的目的是為了和容器內(nèi)的uid保持一致。不然后面會遇到莫名其妙的錯誤衬浑。
# 由于uid發(fā)生變化捌浩。刪掉集群再重新安裝。
usermod -u 167 ceph
groupmod -g 167 ceph
usermod -u 997 cephadm
cephadm bootstrap --mon-ip $mon_ip --skip-pull --dashboard-password-noupdate --initial-dashboard-password $password --fsid $fsid
查看集群狀態(tài):
ceph -s
# 或者瀏覽器訪問 https://192.168.31.150:8443/
添加硬盤:
# 格式化所有硬盤
for i in sdb sdc sdd sde sdf sdg ; do
ceph orch device zap node1 /dev/$i --force
done
通過GUI添加OSD
設(shè)置集群參數(shù)(假設(shè)只有一個節(jié)點(diǎn)工秩,因此設(shè)置了允許數(shù)據(jù)在同一臺機(jī)器上的不同硬盤中):
ceph config set global mon_allow_pool_delete true
ceph osd crush rule create-replicated osd-replicate default osd #1
ceph osd erasure-code-profile set ec-22 plugin=jerasure k=2 m=2 technique=reed_sol_van crush-failure-domain=osd
ceph osd crush rule create-erasure ec-22-rule ec-22 #2
ceph osd erasure-code-profile set ec-42 plugin=jerasure k=4 m=2 technique=reed_sol_van crush-failure-domain=osd
ceph osd crush rule create-erasure ec-42-rule ec-42 #3
ceph config set global osd_pool_default_crush_rule 1
ceph config set global osd_pool_default_min_size 2
ceph config set global osd_pool_default_size 2
通過RBD構(gòu)建文件系統(tǒng)
創(chuàng)建image:
# 創(chuàng)建image
ceph osd pool create rbd
ceph osd pool application enable rbd rbd # 第一個rbd表示poolname
rbd create --size 14TB rbd/myimage --stripe-unit 32M --stripe-count 1 --object-size 32M
# 格式化分區(qū)
rbd device map rbd/myimage --id admin
gdisk /dev/rbd0
mkfs -t xfs /dev/rbd0p1
# 掛載
mkdir /mnt/rbd
mount -t xfs -o wsync /dev/rbd0p1 /mnt/rbd
# 退出掛載
#rbd device list
#rbd device unmap /dev/rbd0
初始化文件系統(tǒng)的內(nèi)容尸饺,避免文件系統(tǒng)還沒掛上就開始往里寫東西了
cd /mnt/rbd
mkdir mounted
chown cpc:cpc -R mounted
cd ..
ln -s /mnt/rbd/mounted samba
開機(jī)自啟:
touch onstartup.sh
chmod +x onstartup.sh
vi ~/onstartup.sh
while [ 1 ] ; do
sleep 1
echo mapping
device=$(rbd device map rbd/myimage --id admin) || continue
break
done
while [ 1 ] ; do
sleep 1
echo mounting
mount -t xfs -o wsync "${device}p1" /mnt/rbd || continue
break
done
安裝cron腳本:
crontab -e
@reboot /usr/bin/bash /root/onstartup.sh 1 > /root/onstartup.log 2>&1
安裝Samba服務(wù): 通過Samba提供服務(wù)
通過Filesystem構(gòu)建文件系統(tǒng)(不推薦)
不推薦的理由是性能太差。對于家用小集群助币,硬盤不多浪听。而Filesystem至少兩個Pool,一個Pool負(fù)責(zé)元數(shù)據(jù)的保存眉菱,一個Pool負(fù)責(zé)數(shù)據(jù)的保存迹栓。這兩個Pool在硬盤上的物理地址相距甚遠(yuǎn),當(dāng)數(shù)據(jù)寫入時克伊,需要同時將元數(shù)據(jù)和內(nèi)容數(shù)據(jù)記錄到這兩個Pool中叉抡,導(dǎo)致磁頭在兩個Pool之間來回擺動,花費(fèi)了大量的時間在尋道答毫,所以性能差褥民。
當(dāng)集群很小,硬盤數(shù)量是2時洗搂,設(shè)置以下參數(shù)創(chuàng)建文件系統(tǒng):
ceph fs volume create myfs
由于客戶端和服務(wù)端在同一臺機(jī)器會引發(fā)bug消返,因此要掛載到虛擬機(jī)里。
由于服務(wù)端和客戶端在同一臺機(jī)器上耘拇,掛載的時候服務(wù)端還沒啟動撵颊。因此要放到crontab中:
# 設(shè)置權(quán)限
ceph auth rm client.localmount
secret=$(ceph fs authorize myfs client.localmount / rwp | fgrep key | awk -F ' = ' '{print $2}')
# crontab腳本設(shè)置
cat <<EOF > /root/mount-cephfs.sh
mkdir -p /mnt/cephfs
while [ 1 ] ; do
sleep 1
mount -t ceph 192.168.31.10:6789:/ /mnt/cephfs -o name=localmount,secret=$secret || continue
break
done
EOF
chmod +x /root/mount-cephfs.sh
# 安裝crontab任務(wù)
cd
echo @reboot /root/mount-cephfs.sh > mycron
crontab mycron
rm mycron
./mount-cephfs.sh
為了方便后續(xù)遷移,在文件系統(tǒng)里面設(shè)置子文件夾:
mkdir /mnt/cephfs/replicated
rm -f /mnt/cephfs/current
ln -sf replicated /mnt/cephfs/current
chown -R cpc:cpc /mnt/cephfs
chmod -R 700 /mnt/cephfs
添加開啟自動啟動命令VirtualBox:
vboxmanage startvm xxxxx --type headless
通過Samba將分區(qū)掛載到Windows上
安裝samba并配置:
apt install -y samba
ufw allow samba
smbpasswd -a cpc
vi /etc/samba/smb.conf
[global]
client min protocol = NT1
server min protocol = NT1
……后面內(nèi)容省略
[root]
comment = cpc
path = /mnt/samba
read only = no
browsable = yes
recycle:repository = .recycle/%T/
vfs objects = recycle
recycle:keeptree = yes
recycle:versions = yes
valid users = cpc
[監(jiān)控中心]
comment = monitor
valid users = guest
path = /mnt/samba/監(jiān)控中心
read only = no
browsable = yes
recycle:repository = .recycle/%T/
vfs objects = recycle
recycle:keeptree = yes
recycle:versions = yes
force user = cpc
[下載]
comment = download
valid users = guest
path = /mnt/samba/下載
read only = no
browsable = yes
strict sync = no
recycle:repository = .recycle/%T/
vfs objects = recycle
recycle:keeptree = yes
recycle:versions = yes
force user = cpc
service smbd restart
Windows上映射網(wǎng)絡(luò)驅(qū)動器惫叛。\\192.168.31.11\CephFS
倡勇。 用戶名是cpc。
為了數(shù)據(jù)安全嘉涌,監(jiān)控中心的數(shù)據(jù)不能隨意讓外部讀取妻熊,每分鐘轉(zhuǎn)移:
vi /root/onminute.sh
cd /mnt/samba/監(jiān)控中心/xiaomi_camera_videos/607ea442c3a3 || exit 1
DST=/mnt/samba/個人文件/監(jiān)控錄像
#cd /root/test
#DST=/root/test2
find -type d -exec mkdir -vp "$DST"/{} \; -or -exec mv -fv {} "$DST"/{} \; || exit 1
#find -type d | tail -n +2 | while read line ; do rmdir -v --ignore-fail-on-non-empty "$line" ; done || exit 1
crontab -e
30 * * * * /usr/bin/bash
后期運(yùn)維操作
如果斷電重啟會怎樣?
重啟后所有的掛載仑最、Samba服務(wù)都恢復(fù)扔役。讀寫都正常。
如果硬盤接口順序插錯了警医?
調(diào)整SATA接口的順序亿胸,模擬硬盤維護(hù)過程中重新插拔順序錯亂≡せ剩看看ceph集群能否正吵扌恢復(fù)。試了吟温,可以正承蛳桑恢復(fù),并且文件正常讀寫溯街。
因?yàn)槊總€硬盤上記錄了OSD編號诱桂,系統(tǒng)會根據(jù)OSD編號找到自己的數(shù)據(jù)盤。
如果一個硬盤壞了會怎樣呈昔?
硬盤損壞后Ceph不會自動踢掉挥等。而是要人工干預(yù):
i=0
ceph osd crush rm osd.$i
systemctl |fgrep osd.$i
systemctl stop xxx
ceph osd rm osd.$i
rm -R /var/lib/ceph/$fsid/osd.$i
ceph auth rm osd.$i
# 格式化新盤: ceph orch device zap node150 /dev/比如sdb --force
這樣才會觸發(fā)數(shù)據(jù)重新平衡。等數(shù)據(jù)全部恢復(fù)完成后堤尾,才能讀取文件菩收。如果EC分區(qū)其中一個OSD由于硬盤數(shù)量太少無法恢復(fù)损搬,也會導(dǎo)致文件無法讀取檀何。
重啟之后,讀寫都正常掷漱。
替換新的盤之后,新的盤馬上有數(shù)據(jù)寫入進(jìn)去了榄檬。
min_size如果=1卜范,那么一個盤壞掉之后仍然可以寫入。
壞了一個盤之后鹿榜,如果min_size=2海雪,那么數(shù)據(jù)寫入不會報錯,因?yàn)閄FS文件系統(tǒng)有寫緩存舱殿,緩存無法更新到硬盤奥裸,此時如果斷電重啟數(shù)據(jù)會丟失。為了優(yōu)化這個問題需要:
ceph osd pool set rbd min_size 2
mount參數(shù)要加上-o wsync沪袭,保證元數(shù)據(jù)的一致性
這樣設(shè)置完之后湾宙,當(dāng)壞掉了一個盤,所有的數(shù)據(jù)讀寫操作都會被禁止冈绊。哪天硬盤有損壞侠鳄,馬上就知道了。
更進(jìn)一步可以通過定時任務(wù)焚碌,再加一層自動降級:
degrades=$(ceph -s|fgrep degrade|wc -l)
if [ "$degrades" != "0" ] ; then
service smbd stop
fi
如果容量不夠了要怎么辦畦攘?
先備份數(shù)據(jù),做快照
通過GUI生成image快照
加硬盤:
# ceph orch device zap node0 /dev/$i --force
ceph orch daemon add osd node150:/dev/sdd
ceph orch daemon add osd node150:/dev/sde
Image的擴(kuò)容:
rbd resize --image rbd/myimage --size 20GB
文件系統(tǒng)擴(kuò)容:
# 先解除掛載
service smbd stop
umount /mnt/rbd
# 修復(fù)文件系統(tǒng)
xfs_repair -n /dev/rbd0p1
# 分區(qū)擴(kuò)容
parted /dev/rbd0
# print
# Fix
# resizepart 1 21.5GB
reboot
# 重新掛載
#mount -t xfs /dev/rbd0p1 /mnt/rbd
#service smbd start
重啟之后十电,文件能正常讀寫。
如果大小填錯了叹螟,往小了寫鹃骂。需要加上--allow-shrink防呆。
如何修改副本數(shù)量罢绽?
當(dāng)后面擴(kuò)容增加硬盤畏线,需要修改副本數(shù)量,至少3副本才能保證數(shù)據(jù)安全:
ceph osd pool set cephfs.myfs.meta size 3
ceph osd pool set cephfs.myfs.data size 3
ceph osd pool set .mgr size 3
ceph config set global osd_pool_default_size 3
如果通過EC冗余碼提供更多空間良价?
通過副本實(shí)現(xiàn)冗余會導(dǎo)致一份數(shù)據(jù)占用兩份空間寝殴,存在較多空間浪費(fèi)。因此需要想辦法節(jié)約空間明垢。
EC冗余碼是指Erasure Code蚣常,中文名是糾刪碼。比如RAID5利用了EC碼實(shí)現(xiàn)了1.5倍冗余痊银。也就是說一份數(shù)據(jù)占用1.5份數(shù)據(jù)的空間抵蚊,比副本模式節(jié)約空間。而EC碼則能夠更進(jìn)一步節(jié)約空間,根據(jù)需要可以調(diào)整參數(shù)節(jié)約更多空間贞绳。核心兩大參數(shù)M+K谷醉。M代表數(shù)據(jù)的拆分的數(shù)量,K代表冗余碼的份數(shù)冈闭。每一份數(shù)據(jù)都要放到不同的硬盤上俱尼。比如RAID5是M=2,K=1實(shí)現(xiàn)了2+1的數(shù)據(jù)模式萎攒,至少需要3個硬盤遇八,最多能壞掉M個硬盤,也就是最多壞掉1個硬盤而不影響數(shù)據(jù)恢復(fù)躺酒。而RAID6則是6+2押蚤,至少需要8個硬盤,最多能壞掉2個硬盤而不影響數(shù)據(jù)恢復(fù)羹应。
方法1: 復(fù)制Image(推薦)
# 解除掛載
service smbd stop
umount /mnt/rbd
rbd device unmap /dev/rbd0
# 復(fù)制image
ceph osd pool create rbd-ec-22 erasure ec-22 ec-22-rule
ceph osd pool application enable rbd-ec-22 rbd
ceph osd pool set rbd-ec-22 allow_ec_overwrites true
rbd cp rbd/myimage rbd/myimage2-ec-22 --data-pool rbd-ec-22
# 放到回收站
rbd trash rbd/myimage
# 重新掛載
vi /root/onstartup.sh
reboot
# 測試沒問題后揽碘,刪除舊數(shù)據(jù)
rbd rm rbd/myimage
重啟之后可以正常讀寫文件。
方法2:復(fù)制data pool(不可行)
這個方法執(zhí)行完后會造成數(shù)據(jù)無法讀取园匹、無法寫入雳刺。因?yàn)樵獢?shù)據(jù)中記錄了數(shù)據(jù)放在那個pool_id。這種方式執(zhí)行完之后pool_id發(fā)生了變化裸违,導(dǎo)致數(shù)據(jù)內(nèi)容無法讀取掖桦。最終現(xiàn)象是元數(shù)據(jù)能看到,但是無法讀取無法寫入供汛。
# 刪掉文件系統(tǒng)
ceph fs fail myfs
ceph fs rm myfs --yes-i-really-mean-it
# 將data數(shù)據(jù)復(fù)制一份
ceph osd pool create cephfs.myfs.ec-42 erasure ec-42 ec-42-rule
ceph osd pool set cephfs.myfs.ec-42 allow_ec_overwrites true
rados cppool cephfs.myfs.data cephfs.myfs.ec-42
# 創(chuàng)建新的文件系統(tǒng)
ceph fs new myfs cephfs.myfs.meta cephfs.myfs.ec-42 --force --recover
ceph fs set myfs joinable true
# 刪除舊的數(shù)據(jù)
ceph osd pool rm cephfs.myfs.data cephfs.myfs.data --yes-i-really-really-mean-it
方法3:通過setfattr將數(shù)據(jù)復(fù)制到新的pool
# 停掉SMB服務(wù)
service smbd stop
# 創(chuàng)建新的data pool
ceph osd pool create cephfs.myfs.ec-42 erasure ec-42 ec-42-rule
ceph osd pool set cephfs.myfs.ec-42 allow_ec_overwrites true
# 在fs中添加data pool
ceph fs add_data_pool myfs cephfs.myfs.ec-42
mkdir -p /mnt/cephfs/ec-42
chown cpc:cpc -R /mnt/cephfs/ec-42
setfattr -n ceph.dir.layout.pool -v cephfs.myfs.ec-42 /mnt/cephfs/ec-42
# 將文件復(fù)制過去
cp -RvP --preserve=mode,ownership,timestamps,links,xattr,all /mnt/cephfs/replicated/* /mnt/cephfs/ec-42/
rm -f /mnt/cephfs/current
ln -sf ec-42 /mnt/cephfs/current
# 重建文件系統(tǒng)
ceph fs fail myfs
ceph fs rm myfs --yes-i-really-mean-it
ceph fs new myfs cephfs.myfs.meta cephfs.myfs.ec-42 --force --recover
ceph fs set myfs joinable true
# 重新開啟SMB服務(wù)
service smbd start
# 刪除舊的數(shù)據(jù)
rm -R /mnt/cephfs/replicated
ceph osd pool rm cephfs.myfs.data cephfs.myfs.data --yes-i-really-really-mean-it
系統(tǒng)盤壞了怎么辦枪汪?
如果系統(tǒng)盤發(fā)生了故障,只剩下數(shù)據(jù)盤怔昨,而數(shù)據(jù)盤的分區(qū)格式是Ceph定制的BluestoreFS雀久,里面的內(nèi)容無法直接獲取,此時要如何恢復(fù)數(shù)據(jù)趁舀?
系統(tǒng)盤里裝了什么重要的東西赖捌?
集群的元數(shù)據(jù)都在系統(tǒng)盤上。元數(shù)據(jù)包括了集群的UUID矮烹、集群中包含的節(jié)點(diǎn)越庇,集群和OSD的關(guān)系、OSD和PG的對應(yīng)關(guān)系奉狈、PG和Pool的關(guān)系卤唉。而我們所有的應(yīng)用層RBD、Filesystem都是建立在Pool基礎(chǔ)上嘹吨,如果Pool的元數(shù)據(jù)信息丟失搬味,那么系統(tǒng)就不知道某個Pool的數(shù)據(jù)在哪境氢,這些應(yīng)用層都無法使用。
恢復(fù)工具制作
目前使用Ceph v17版本搭建了NAS碰纬,并且版本在不斷更新萍聊。等到過了幾年到了2025年之后,如果系統(tǒng)盤發(fā)生了損壞悦析,那么還能不能找到v17版本是個問題寿桨。因此需要把當(dāng)前的軟件版本做個備份,構(gòu)建一個虛擬機(jī)能完整運(yùn)行Ceph v17系統(tǒng)强戴,在虛擬機(jī)里做了一次故障演練亭螟,能演練成功。然后將這臺虛擬機(jī)備份到阿里云上骑歹,這樣恢復(fù)工具就制作完成了预烙。
恢復(fù)步驟
參考資料: https://docs.ceph.com/en/quincy/rados/troubleshooting/troubleshooting-mon/#recovery-using-osds
系統(tǒng)盤壞掉之后,先恢復(fù)Pool道媚。
首先從阿里云上下載到備份文件: https://caipeichao-doc-backup.oss-cn-hangzhou.aliyuncs.com/-recover/ceph-recover-disk2.part01.rar 總共5個分卷
安裝必要工具:
apt install -y jq ceph-osd ceph-mon
找到集群ID:
# 查看虛擬卷關(guān)聯(lián)的硬件設(shè)備
lsblk
ls -l /dev/mapper
# 找出集群ID
fsid=$(ceph-bluestore-tool show-label --dev /dev/dm-0 | jq -r '.[].ceph_fsid')
安裝集群扁掸,fsid和上面獲取的集群ID保持一致。然后停掉集群:
systemctl stop ceph.target
復(fù)原osd配置:
# 配置
node=node150
mon_ip=192.168.31.150
# alias
alias cephadm='/usr/sbin/cephadm --image quay.io/ceph/ceph:v17'
function recover {
dev=$1
fsid=$(ceph-bluestore-tool show-label --dev $dev | jq -r '.[].ceph_fsid')
cd /var/lib/ceph/$fsid
# 創(chuàng)建文件夾
osd_id=$(ceph-bluestore-tool show-label --dev $dev | jq -r '.[].whoami')
rm -Rf osd.$osd_id
mkdir osd.$osd_id
cd osd.$osd_id
# 創(chuàng)建文件
ln -s /dev/$(dmsetup info $dev|fgrep Name:|egrep -o 'ceph.*'|sed -e 's/--/-/g' -e 's/-osd-block/\/osd-block/g') block
echo $fsid > ceph_fsid
echo [global] > config
echo fsid = $fsid >> config
echo "mon_host = [v2:$mon_ip:3300/0,v1:$mon_ip:6789/0]" >> config
ceph-bluestore-tool show-label --dev $dev | jq -r '.[].osd_uuid' > fsid
key="$(ceph-bluestore-tool show-label --dev $dev | jq -r '.[].osd_key' )"
echo "[osd.$osd_id]" > keyring
echo "key = $key" >> keyring
ceph-bluestore-tool show-label --dev $dev | jq -r '.[].ready' > ready
ceph-bluestore-tool show-label --dev $dev | jq -r '.[].require_osd_release' > require_osd_release
echo bluestore > type
echo $osd_id > whoami
# 將bluestore導(dǎo)出到rocksdb中:
ceph-objectstore-tool --data-path . --no-mon-config --op update-mon-db --mon-store-path /var/lib/ceph/$fsid/mon.$node
}
ls -l /dev/mapper | fgrep ceph-- | egrep -o 'dm-[0-9]+$' | while read line ; do
recover /dev/$line
done
樣例輸出:
osd.0 : 0 osdmaps trimmed, 837 osdmaps added.
osd.4 : 0 osdmaps trimmed, 0 osdmaps added.
osd.5 : 0 osdmaps trimmed, 0 osdmaps added.
osd.3 : 0 osdmaps trimmed, 0 osdmaps added.
osd.2 : 0 osdmaps trimmed, 0 osdmaps added.
osd.1 : 0 osdmaps trimmed, 0 osdmaps added.
復(fù)原認(rèn)證信息:
cd /var/lib/ceph/$fsid
cat /etc/ceph/ceph.client.admin.keyring mon.$node/keyring mgr.$node.*/keyring > admin.keyring
ceph-authtool admin.keyring -n client.admin \
--cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow *' --cap mgr 'allow *'
ceph-authtool admin.keyring -n mgr.* \
--cap mon 'allow profile mgr' --cap osd 'allow *' --cap mds 'allow *'
ceph-monstore-tool ./mon.$node$ rebuild -- --keyring admin.keyring --mon-ids $mon_ip --mon-nodes $node
修復(fù)權(quán)限問題:
chown -R 167:167 /var/lib/ceph/$fsid/mon.*
chown -R 167:167 /var/lib/ceph/$fsid/osd.*
構(gòu)建osd daemon:
systemctl start ceph.target
#ceph mgr module enable cephadm
#ceph mgr module enable dashboard
#ceph mgr module enable alerts
#ceph dashboard create-self-signed-cert
for i in 0 1 2 3 ; do
cd /var/lib/ceph/$fsid/osd.$i
cephadm deploy --name osd.$i --fsid $fsid --osd-fsid $(cat fsid)
done
# 有時候osd.1不能正常啟動最域。需要重試一下谴分。
然后Image不用恢復(fù)。因?yàn)槟J(rèn)從rbd的pool中獲取元數(shù)據(jù)镀脂。直接就可以用了牺蹄,我們掛載上去看看,步驟參見 通過RBD掛載到Linux文件夾下
重新掛載之后文件讀寫正常薄翅。
幕后:失敗的嘗試
找到辦法可以僅從OSD復(fù)原出整個集群: https://docs.ceph.com/en/quincy/rados/troubleshooting/troubleshooting-mon/#recovery-using-osds
但是要求osd的rocksdb數(shù)據(jù)要有沙兰。怎么辦呢?定時同步翘魄?不知道多久更新一次啊僧凰。看了一下里面的內(nèi)容熟丸,通常不會變化。所以一種辦法是定期備份這些元數(shù)據(jù)伪节。另一種辦法是構(gòu)建多個mon節(jié)點(diǎn)光羞。
ms=/root/mon-store
mkdir $ms
從元數(shù)據(jù)備份中恢復(fù)出集群。步驟和搭建新集群相同怀大,區(qū)別在于新建集群時指定集群ID:
sudo cephadm bootstrap --mon-ip 192.168.31.10 --fsid 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 --mgr-id qwohcg
執(zhí)行恢復(fù):
#關(guān)掉系統(tǒng)
systemctl stop ceph.target
#將備份文件復(fù)制來
cd /var/lib/ceph
mv 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71.bak
cp -Rd /mnt/old2/var/lib/ceph/43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 ./
#啟動系統(tǒng)
systemctl start ceph.target
系統(tǒng)起不來纱兑,秒退』瑁可能是keyring不對:
cp /mnt/old2/etc/ceph/* /etc/ceph/
還是秒退潜慎。貌似mgrID不對。重建集群:
#重建集群
sudo cephadm rm-cluster --fsid 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 --force
sudo cephadm bootstrap --mon-ip 192.168.31.10 --fsid 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 --mgr-id qwohcg
#關(guān)掉系統(tǒng)
systemctl stop ceph.target
#將備份文件復(fù)制來
cd /var/lib/ceph
mv 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71.bak
cp -Rdv /mnt/old2/var/lib/ceph/43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 ./
cp -v /mnt/old2/etc/ceph/* /etc/ceph/
chown -R cpc:cpc /var/lib/ceph
#啟動系統(tǒng)
systemctl start ceph.target
健康狀態(tài)是mgr沒有啟動。數(shù)據(jù)狀態(tài)都健康:
root@node0:/home/cpc# ceph -s
cluster:
id: 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71
health: HEALTH_WARN
no active mgr
mon node0 is low on available space
22 daemons have recently crashed
services:
mon: 1 daemons, quorum node0 (age 6m)
mgr: no daemons active (since 6m)
mds: myfs:1 {0=myfs.node0.gxjtfo=up:active(laggy or crashed)}
osd: 6 osds: 6 up (since 5h), 6 in (since 5h)
data:
pools: 4 pools, 97 pgs
objects: 197 objects, 695 MiB
usage: 7.2 GiB used, 12 TiB / 12 TiB avail
pgs: 97 active+clean
應(yīng)該是mgr名字弄錯了铐炫,正確的應(yīng)該是 node0.qwohcg垒手。
重新試一下:
#重建集群
sudo cephadm rm-cluster --fsid 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 --force
sudo cephadm bootstrap --mon-ip 192.168.31.10 --fsid 43cdbb7a-3bac-11ed-91d4-834ed8ea0c71 --mgr-id node0.qwohcg
#關(guān)掉系統(tǒng)
systemctl stop ceph.target
docker ps
#將備份文件復(fù)制來
cd /var/lib
mv ceph ceph.bak.$(date +%s)
cp -Rdvp /mnt/old2/var/lib/ceph ./
cp -Rdvp /mnt/old2/etc/ceph/* /etc/ceph/
cp -Rdvp /mnt/old2/root/.ssh /root
#啟動系統(tǒng)
systemctl start ceph.target
osd沒權(quán)限,手動添加權(quán)限:
ceph auth rm osd.0
ceph auth get-or-create osd.0 mon 'allow profile osd' mgr 'allow profile osd' osd 'allow *'
加了也不行倒信。給osd加上名字科贬,可以了,應(yīng)該是用戶身份的問題:
cephadm shell --name osd.0 <<EOF
cd /var/lib/ceph/osd/ceph-0
ceph-osd --osd-data . --name osd.0
EOF
手動啟動雖然可以鳖悠,但是機(jī)器重啟之后osd就找不到了榜掌。所以需要想辦法修復(fù)daemon的問題。
問題根源似乎找到了乘综,是因?yàn)閏eph用了ssh-key憎账,在/etc/ceph/ceph.pub。而ssh-key在系統(tǒng)重裝之后發(fā)生了變化卡辰。因此把之前的key復(fù)制來試一下:
cp -Rdvp /mnt/old2/root/.ssh /root
還是不行胞皱。研究一下daemon為什么不起來:
不知道從哪里開始研究。日志也沒有看政。先手動起來吧:
for i in 2 3 4 ; do
cephadm shell --name osd.$i ceph-osd -d --osd-data /var/lib/ceph/osd/ceph-$i --name osd.$i &
sleep 1
done
掛載文件系統(tǒng):
sudo su
#啟動MDS
ceph orch reconfig mds.myfs.node0.gxjtfo
cephadm shell --name mds.myfs.node0.gxjtfo ceph-mds --name mds.myfs.node0.gxjtfo -d &
#掛載
#安裝samba
apt update
apt install samba
vi /etc/samba/smb.conf
cat <<EOF
#修改內(nèi)容
usershare allow guests = no
[CephFS]
comment = Samba over CephFS
path = /mnt/samba
read only = no
browsable = yes
EOF
service smbd restart
ufw allow samba
smbpasswd -a cpc
檢查文件是否正確:
最后一次MD5計算結(jié)果和之前一致朴恳,說明數(shù)據(jù)成功恢復(fù)了。
但是現(xiàn)在集群管理有點(diǎn)問題允蚣。服務(wù)不會自動啟動于颖。需要排查原因。雖然數(shù)據(jù)有了嚷兔,但是這個集群不能用森渐。
如何通過快照進(jìn)一步確保數(shù)據(jù)不丟?
為了讓數(shù)據(jù)更好的保留冒晰,我們每天自動進(jìn)行快照同衣,保留最近30天快照:
vi /root/ondaily.sh
# 每天生成快照
image=rbd/myimage
rbd snap create ${image}@auto-`date +%Y%m%d`
# 每天自動清理,保留30天快照
rbd snap list ${image}|awk '{print $2}'|egrep -o '^auto-[0-9]{8}$' | sort | head -n -30 | while read line ; do
sleep 60 # 休息一下壶运,防止遇到race condition BUG
rbd snap remove ${image}@${line}
done
crontab -e
30 4 * * * /usr/bin/bash /root/ondaily.sh
下面測試一下快照是否能達(dá)到預(yù)期效果耐齐。我們假設(shè)某一天誤操作格式化了磁盤:
通過GUI創(chuàng)建快照
service smbd stop
umount /mnt/rbd
mkfs -t ext4 /dev/rbd0p1
mount -t ext4 /dev/rbd0p1 /mnt/rbd
可以看到文件全沒了。然后通過快照恢復(fù)數(shù)據(jù):
umount /mnt/rbd
rbd unmap /dev/rbd0
通過GUI將快照rollback
重新掛載:
rbd map rbd/myimage
mount -t xfs /dev/rbd0p1 /mnt/rbd
系統(tǒng)重啟之后文件也都能正常讀寫蒋情,說明通過快照徹底恢復(fù)了數(shù)據(jù)埠况。
如果硬盤損壞過多出現(xiàn)unfound object之后如何處理?
強(qiáng)制創(chuàng)建PG:
ceph osd force-create-pg 3.11 --yes-i-really-mean-it
創(chuàng)建完成之后pool恢復(fù)正常了,但是文件系統(tǒng)無法恢復(fù)棵癣。不展開研究辕翰。
Ceph的相關(guān)測試
支持文件隨機(jī)讀寫
結(jié)論優(yōu)先:兼容所有POSIX文件操作。
Ceph作為一款存儲引擎狈谊,要確毕裁基本的文件操作都能支持沟沙。比如文件的讀寫、移動壁榕、隨機(jī)讀寫矛紫。
之所以做這個測試是因?yàn)橐恍┐鎯σ姹热鏗DFS、Ceph Ganesha不支持隨機(jī)寫护桦。
- 在這個文件夾里編譯一個軟件
- tar打包
- 中文文件名
- 中文文件夾
- 移動文件夾
- 移動文件
- 隨機(jī)寫入
- 隨機(jī)讀取
import java.io.RandomAccessFile;
import java.util.Random;
public class Main {
public static void main(String[] argv) throws Exception {
RandomAccessFile f = new RandomAccessFile("test.txt", "rws");
f.seek(16);
f.writeLong(new Random().nextLong());
f.close();
f = new RandomAccessFile("test.txt", "r");
f.seek(16);
System.out.println(f.readLong());
f.close();
}
}
Ceph內(nèi)部原理
整體架構(gòu)
ceph-mon
元數(shù)據(jù)內(nèi)容分析含衔。先看一下一個普通的集群里面有什么。執(zhí)行以下命令:
alias kv='ceph-kvstore-tool rocksdb store.db'
kv list | awk '{print $1}' | uniq -c
可以看到整體有以下內(nèi)容:
19 auth
2 config
12 health
145 kv
2107 logm
4 mds_health
1 mds_metadata
32 mdsmap
24 mgr
1 mgr_command_descs
1 mgr_metadata
102 mgrstat
98 mon_config_key
7 monitor
1 monitor_store
3 monmap
6 osd_metadata
1 osd_pg_creating
397 osdmap
678 paxos
那么每個key代表什么含義呢二庵?
kv get auth 1
(auth, 3)
00000000 01 02 02 0c 00 00 00 00 00 00 00 20 5e 00 00 00 |........... ^...|
00000010 00 00 00 |...|
00000013
value被編碼過了贪染。編碼格式參見: https://docs.ceph.com/en/latest/dev/encoding/ 。通過工具ceph-dencoder
可以破譯這些編碼:
# 先修復(fù)dencoder的BUG
cd /usr/bin
gzip -d ceph-dencoder.gz
# 先看有哪些類型
ceph-dencoder list_types
# 提取二進(jìn)制文件
kv get auth 14 out test
# 解碼
ceph-dencoder type MonitorDBStore::Transaction import test decode dump_json
Ceph二進(jìn)制編碼系統(tǒng)
Ceph系統(tǒng)在組件之間通信催享、數(shù)據(jù)存儲時會將數(shù)據(jù)結(jié)構(gòu)編碼成二進(jìn)制形式再進(jìn)行傳輸或者存儲杭隙。Ceph是如何將一個內(nèi)存中的struct數(shù)據(jù)結(jié)構(gòu)序列化成二進(jìn)制數(shù)據(jù)流?又是如何將二進(jìn)制數(shù)據(jù)流反序列化成內(nèi)存中的struct數(shù)據(jù)結(jié)構(gòu)因妙?本小節(jié)將會詳細(xì)介紹痰憎。
Ceph元數(shù)據(jù)編碼的基本規(guī)則
根據(jù)官方的文檔 https://docs.ceph.com/en/latest/dev/encoding/ ,標(biāo)準(zhǔn)的序列化攀涵、反序列化寫法如下:
class AcmeClass
{
int member1 = 0xC0;
std::string member2 = "admin";
void encode(bufferlist &bl)
{
ENCODE_START(1, 1, bl); // 步驟1
::encode(member1, bl); // 步驟2
::encode(member2, bl); // 步驟3
ENCODE_FINISH(bl); // 步驟4
}
void decode(bufferlist::iterator &bl)
{
DECODE_START(1, bl);
::decode(member1, bl);
::decode(member2, bl);
DECODE_FINISH(bl);
}
};
先說結(jié)論铣耘。encode最終會輸出:
步驟1和4輸出: 01 01 0D 00 00 00
步驟2輸出: C0 00 00 00
步驟3輸出: 05 00 00 00 61 64 6D 69 6E
步驟1ENCODE_START(1, 1, bl);
,會在bl中預(yù)留一段空白以故,用于編碼結(jié)束時回填蜗细。第一個參數(shù)1表示數(shù)據(jù)結(jié)構(gòu)的版本號,第二個參數(shù)2表示此結(jié)構(gòu)在反序列化時最低能兼容版本號怒详,第三個參數(shù)bl用于存放編碼的結(jié)果炉媒。
步驟2encode(member1, bl);
,假設(shè)此時member1=0xC0昆烁,那么這行語句會把C0 00 00 00
追加到bl吊骤。因?yàn)閙ember1是int類型,占用4個字節(jié)静尼,并且在intel平臺上將會按little-endian順序輸出白粉。
步驟3encode(member2, bl);
,假設(shè)此時member2="admin"鼠渺,那么這樣語句會把05 00 00 00 61 64 6D 69 6E
追加到bl蜗元。其中前四個字節(jié)05 00 00 00
表示字符串的長度。后面5個字節(jié)是字符串的ASCII編碼結(jié)果系冗。
步驟4ENCODE_FINISH(bl);
不增加額外內(nèi)容,但會把ENCODE_START預(yù)留的空白處填上01 01 0D 00 00 00
追加到bl
薪鹦。下面是這段二進(jìn)制數(shù)據(jù)的解讀:
01 表示數(shù)據(jù)結(jié)構(gòu)的版本號
01 表示此結(jié)構(gòu)在反序列化時最低能兼容版本號
0D 00 00 00 表示此結(jié)構(gòu)的長度掌敬,(不包含ENCODE_FINISH時回填的長度)惯豆。
具體每個基本類型的編碼方式在源代碼encoding.h中可以找到。源代碼地址: https://github.com/ceph/ceph/blob/6fee777d603aebce492c57b41f3b5760d50ddb07/src/include/encoding.h
通過以上過程就把內(nèi)存里的一段struct數(shù)據(jù)結(jié)構(gòu)序列化成了一段二進(jìn)制數(shù)據(jù)流奔害。我們知道了序列化的過程之后楷兽,反序列化原理大體相同。就不贅述了华临。
具體例子
我們從ceph-mon的rocksdb中提取出二進(jìn)制數(shù)據(jù)芯杀,并分析其中包含的內(nèi)容。首先獲取二進(jìn)制數(shù)據(jù)雅潭,命令如下:
# 先進(jìn)入ceph環(huán)境
cephadm shell
# 先修復(fù)dencoder的BUG
cd /usr/bin
gzip -d ceph-dencoder.gz
alias kv='ceph-kvstore-tool rocksdb store.db'
# 先看有哪些類型
ceph-dencoder list_types
# 提取二進(jìn)制內(nèi)容
cd /var/lib/ceph/*/mon.*
kv get auth 13 out test
得到了如下內(nèi)容:
00000000 01 02 02 a7 00 00 00 01 00 00 00 02 00 00 00 9b
00000010 00 00 00 01 01 00 00 00 02 00 00 00 11 00 00 00
00000020 6d 79 66 73 2e 6e 6f 64 65 30 2e 64 64 6c 6f 65
00000030 63 02 ff ff ff ff ff ff ff ff 01 00 9f c7 31 63
00000040 6e a4 22 08 10 00 19 b7 f5 51 33 ed 0c 6a f2 c1
00000050 cf 93 f7 9d 56 84 03 00 00 00 03 00 00 00 6d 64
00000060 73 09 00 00 00 05 00 00 00 61 6c 6c 6f 77 03 00
00000070 00 00 6d 6f 6e 0f 00 00 00 0b 00 00 00 70 72 6f
00000080 66 69 6c 65 20 6d 64 73 03 00 00 00 6f 73 64 1b
00000090 00 00 00 17 00 00 00 61 6c 6c 6f 77 20 72 77 20
000000a0 74 61 67 20 63 65 70 68 66 73 20 2a 3d 2a
000000ae
沒有研究下去了揭厚。
Ceph 17.2.5 源碼編譯
為了深入研究ceph,需要下載源碼并編譯研究扶供。
操作系統(tǒng): Ubuntu 22.04
下載源碼
源代碼地址: https://github.com/ceph/ceph/ 通過以下命令下載源碼:
git clone https://github.com/ceph/ceph
依賴組件安裝
進(jìn)入代碼目錄筛圆,然后執(zhí)行以下代碼:
./install-deps.sh
如果在國內(nèi),由于國情的特殊性椿浓,在安裝過程中可能會出現(xiàn)網(wǎng)絡(luò)連接錯誤太援。因此需要設(shè)置國內(nèi)apt鏡像。具體方法是將/etc/apt/source.list
中的cn.archive.ubuntu.com
全部替換成mirrors.aliyun.com
扳碍。
下載submodule的代碼
代碼庫中包含了一堆submodule提岔,需要初始化。進(jìn)入代碼目錄笋敞,執(zhí)行以下命令:
git submodule update --init --recursive --progress -j1
由于國情的特殊性碱蒙,會出現(xiàn)網(wǎng)絡(luò)連接錯誤。需要你自己想辦法液样。
通過CLion閱讀代碼
可以正常閱讀振亮。
編譯安裝
尚未研究。
如何搭建軟路由
我們要在軟路由上實(shí)現(xiàn)網(wǎng)卡1和網(wǎng)卡2的橋接鞭莽。
第一步配置網(wǎng)橋:
vi /etc/netplan/00-installer-config.yaml
network:
version: 2
renderer: networkd
ethernets:
eno1:
dhcp4: no
enp2s0:
dhcp4: no
bridges:
br0:
dhcp4: yes
interfaces:
- eno1
- enp2s0
其中eno1就是圖中的網(wǎng)卡1坊秸。enp2s0就是圖中的網(wǎng)卡2。這樣設(shè)置完之后電腦發(fā)出去的數(shù)據(jù)包在軟路由接收到只有不會做轉(zhuǎn)發(fā)澎怒。因此要配上轉(zhuǎn)發(fā)規(guī)則:
iptables -A FORWARD -i br0 -j ACCEPT
這個配置在下次重啟后會失效褒搔,因此通過如下方法持久化配置:
iptables-save > /etc/iptables/rules.v4
apt install iptables-persistent
更多功能,比如流量轉(zhuǎn)發(fā)喷面,DNS代理星瘾,尚未完成。