如合通過與Ceph的整合提升Docker存儲(chǔ)性能
【原文編者的話】
Ceph是開源社區(qū)深受歡迎的存儲(chǔ)方案,具有穩(wěn)定性高、性能好、可擴(kuò)展性強(qiáng)等特點(diǎn)。原作者的這篇文章展示并探討了如何將Ceph運(yùn)行在Docker上,無疑為Docker生態(tài)系統(tǒng)的完善邁出了重要一步。存儲(chǔ)問題是將Docker應(yīng)用于生產(chǎn)環(huán)境中的備受關(guān)注的話題之一,這篇文章拋磚引玉,必將激發(fā)廣大開源和Docker技術(shù)愛好者探究現(xiàn)有存儲(chǔ)方案與Docker相整合的熱情。
Ceph是一個(gè)完全開源的分布式存儲(chǔ)方案、網(wǎng)絡(luò)塊設(shè)備以及文件系統(tǒng),具有高穩(wěn)定性、高性能、高擴(kuò)展性等特點(diǎn),可應(yīng)對(duì)terabyte到exabyte級(jí)別的數(shù)據(jù)量。通過使用創(chuàng)新性的調(diào)度算法(CRUSH)、主動(dòng)存儲(chǔ)節(jié)點(diǎn)、以及peer-to-peer的gossip協(xié)議,Ceph規(guī)避了傳統(tǒng)集中控制和lookup table中的擴(kuò)展性和可靠性問題。Ceph目前在整個(gè)開源社區(qū)中極受推崇,已被廣泛應(yīng)用與虛擬化平臺(tái)(Proxmox)、云計(jì)算平臺(tái)(OpenStack、 CloudStack、OpenNebula)、容器技術(shù)(Docker)、以及大數(shù)據(jù)分析系統(tǒng)(Hadoop、作為HDFS的meted服務(wù)器)中。
我嘗試將Ceph運(yùn)行在Docker中已經(jīng)快兩年了。直到今天我依然在做這些工作。最近我更是在Docker中部署Ceph方面投入了不小的精力。
(在展開技術(shù)細(xì)節(jié)前,我要特別感謝Sean C McCord對(duì)此工作的大力支持,當(dāng)年的開源ceph-docker項(xiàng)目也的確是基于Sean的早期工作)
現(xiàn)在讓我們具體看看如何將Ceph運(yùn)行在Docker里!
原理
將Ceph運(yùn)行在Docker中是一個(gè)比較有爭議的話題,不少人質(zhì)疑這樣操作的意義。雖然將檢測模塊、metadata服務(wù)器、以及RADOS gateway容器化都沒有太大問題,但對(duì)于OSD(object storage daemon),事情會(huì)變得很棘手。Ceph的OSD專門針對(duì)物理機(jī)器進(jìn)行優(yōu)化,與底層硬件有很多關(guān)聯(lián)。如果物理硬盤失效,OSD也無法運(yùn)作,這給容器化的場景帶來了問題。
坦白地講,在過去某個(gè)時(shí)刻我也在想:
“我不知道自己為什么做這個(gè),我只知道有人需要這個(gè)功能(當(dāng)然,他們可能也不知道為什么想要)。我只是覺得想進(jìn)行技術(shù)嘗試,那就試試看!”
當(dāng)然上述想法聽起來并不樂觀,但這確實(shí)是我當(dāng)時(shí)真實(shí)的想法。我的觀點(diǎn)隨后有了一些變化,我來解釋下為什么是值得的。希望這個(gè)解釋也能改變你的看法(我的解釋不僅僅是“Docker很酷,所以我們要把所有東西都跑在Docker里!”)。
不少開發(fā)者已經(jīng)花了很多時(shí)間將他們的軟件容器化。在這個(gè)過程中,他們也用過多種不同的工具來構(gòu)建和管理他們的環(huán)境。如果我看到有人用Kubernetes來作為管理工具也一點(diǎn)都不會(huì)吃驚。有的人就喜歡將***潮的技術(shù)應(yīng)用到生產(chǎn)當(dāng)中,否則他們會(huì)覺得工作很無聊。所以當(dāng)他們看到自己最喜歡的開源存儲(chǔ)方案也正在被容器化時(shí),他們會(huì)因?yàn)檫@個(gè)順應(yīng)了“一切容器化”的方式而感到高興。
與傳統(tǒng)的yum或apt-get不同,容器使得軟件的升級(jí)和回卷變得容易:我們可以通過docker stop或者docker run來發(fā)布新的daemons版本。我們甚至可以在一臺(tái)物理機(jī)器上運(yùn)行多個(gè)相互隔離的集群。這些都為開發(fā)過程提供了極大的便利。
項(xiàng)目
如上所述,所有的工作都基于Sean C McCord的早期貢獻(xiàn),我們后來都在圍繞他的工作做完善。現(xiàn)在如果你用ceph-docker,你可以將每個(gè)單一的Ceph daemon運(yùn)行在Ubuntu或CentOS上。我們?cè)贒ocker Hub里有很多的鏡像,我們使用Ceph的命名空間,因此我們的鏡像前綴都是ceph/<daemon>。我們使用了自動(dòng)構(gòu)建,因此每次我們整合一個(gè)新的補(bǔ)丁就會(huì)觸發(fā)新的構(gòu)建,從而生成一個(gè)新的容器鏡像。由于我們現(xiàn)在在從事代碼重構(gòu),你會(huì)看到有很多的鏡像版本。一直以來我們對(duì)每一個(gè)daemon構(gòu)建一個(gè)單獨(dú)的鏡像(我們整合這些補(bǔ)丁的時(shí)候都會(huì)這樣做)。所以監(jiān)測、OSD、mds和radosgw各自都有獨(dú)立的鏡像。這個(gè)并不是最理想的方案,因此我們?cè)趪L試將所有組件都整合到一個(gè)叫做daemon的鏡像中。這個(gè)鏡像包含了所有的模塊,你可以在運(yùn)行docker run的時(shí)候通過命令行選擇性地激活不同模塊。如果你想試用我們的鏡像,我們推薦使用ceph/daemon鏡像。下面我就舉例說明如何運(yùn)行。
容器化Ceph
監(jiān)測
由于監(jiān)測模塊不能在NAT過的網(wǎng)絡(luò)中進(jìn)行通信,我們必須使用 --net=host來將主機(jī)的網(wǎng)絡(luò)層開放給容器:
- $ sudo docker run -d --net=host \
- -v /etc/ceph:/etc/ceph \
- -v /var/lib/ceph/:/var/lib/ceph \
- -e MON_IP=192.168.0.20 \
- -e CEPH_PUBLIC_NETWORK=192.168.0.0/24 \
- ceph/daemon mon
你可以配置如下選項(xiàng):
- MON_IP是運(yùn)行Docker的主機(jī)IP
- MON_NAME是你監(jiān)測模塊的名稱(默認(rèn)為$(hostname))
- CEPH_PUBLIC_NETWORK是運(yùn)行Docker的主機(jī)的CIDR。它和MON_IP必須是同一個(gè)網(wǎng)絡(luò)。
- CEPH_CLUSTER_NETWORK是運(yùn)行Docker的主機(jī)的備用網(wǎng)口的CIDR,為OSD的備份流量使用。
Object Storage Daemon
我們現(xiàn)在能實(shí)現(xiàn)允許每一個(gè)OSD進(jìn)程運(yùn)行在一個(gè)獨(dú)立的容器里。按照微服務(wù)的理念,一個(gè)容器里不應(yīng)該運(yùn)行超過一個(gè)服務(wù)。而在我們這里,在同一個(gè)容器里運(yùn)行多個(gè)OSD進(jìn)程,打破了這一理念,當(dāng)然這也會(huì)給系統(tǒng)的配置和維護(hù)帶來額外的復(fù)雜度。
在這樣的配置下,我們必須使用--privileged=true來使得容器中的進(jìn)程可以訪問/dev等其他內(nèi)核功能。然后,我們?cè)陂_放OSD的目錄的基礎(chǔ)上也支持其他配置,開放OSD的目錄可以讓operators來對(duì)設(shè)備做合適的準(zhǔn)備工作。這樣我們就可以簡單地開放OSD目錄,配置OSD(ceph-osd mkfs)的工作就會(huì)通過Entry Point來完成。我下面介紹的配置方法是最簡單的,因?yàn)樗恍枰阒付ㄒ粋€(gè)block device,剩下的事情都會(huì)由Entry Point完成。
如果不想用--privileged=true可以采用我的第二個(gè)例子。
- $ sudo docker run -d --net=host \
- --privileged=true \
- -v /etc/ceph:/etc/ceph \
- -v /var/lib/ceph/:/var/lib/ceph \
- -v /dev/:/dev/ \
- -e OSD_DEVICE=/dev/vdd \
- ceph-daemon osd_ceph_disk
如果你不想使用--privileged=true,你也可以使用你喜歡的配置管理工具來手動(dòng)配置OSD。
#p#
下面這個(gè)例子我假定你已經(jīng)實(shí)現(xiàn)分區(qū)并配置好文件系統(tǒng)。運(yùn)行下面的命令來生成你的OSD:
$ sudo docker exec <mon-container-id> ceph osd create.
然后運(yùn)行你的容器:
- docker run -v /osds/1:/var/lib/ceph/osd/ceph-1 -v /osds/2:/var/lib/ceph/osd/ceph-2
- $ sudo docker run -d --net=host \
- -v /etc/ceph:/etc/ceph \
- -v /var/lib/ceph/:/var/lib/ceph \
- -v /osds/1:/var/lib/ceph/osd/ceph-1 \
- ceph-daemon osd_disk_directory
可配置的選項(xiàng)如下:
- OSD_DEVICE i是OSD設(shè)備,例如:/dev/sdb
- OSD_JOURNAL使用來儲(chǔ)存OSD journal的設(shè)備,例如:/dev/sdz
- HOSTNAME是運(yùn)行OSD的主機(jī)(默認(rèn)為$(hostname)
- OSD_FORCE_ZAP會(huì)強(qiáng)制將制定的設(shè)備內(nèi)容zapping(默認(rèn)為 0,設(shè)為1去開啟)
- OSD_JOURNAL_SIZE是OSD journal的大小(默認(rèn)為 100)
Metadata 服務(wù)器
這個(gè)組件的設(shè)置較為直觀。唯一需要注意的地方是在Docker中我們可以訪問Ceph管理員密鑰。這個(gè)密鑰會(huì)用來生成CephFS pools和文件系統(tǒng)。
如果你運(yùn)行0.87以前的Ceph版本,你就不需要做此配置,然而我們***運(yùn)行***的版本!
- $ sudo docker run -d --net=host \
- -v /var/lib/ceph/:/var/lib/ceph \
- -v /etc/ceph:/etc/ceph \
- -e CEPHFS_CREATE=1 \
- ceph-daemon mds
可配置的選項(xiàng)如下:
- MDS_NAME是Metadata服務(wù)器的名字(默認(rèn)為mds-$(hostname))。
- CEPHFS_CREATE會(huì)為Metadata服務(wù)器生成文件系統(tǒng)(默認(rèn)為0,設(shè)為1 去開啟)。
- CEPHFS_NAME是Metadata文件系統(tǒng)的名字(默認(rèn)為cephfs)。
- CEPHFS_DATA_POOL是Metadata服務(wù)器data pool的名字(默認(rèn)為cephfs_data)。
- CEPHFS_DATA_POOL_PG是data pool的placement groups的數(shù)量 (默認(rèn)為8)。
- CEPHFS_DATA_POOL是Metadata服務(wù)器metadata pool的名字(默認(rèn)為cephfs_metadata)。
- CEPHFS_METADATA_POOL_PG是metadata pool的placement groups的數(shù)量(默認(rèn)為 8)。
RADOS gateway
我們部署RADOS gateway時(shí)默認(rèn)開啟civetweb。當(dāng)然,我們也可以通過指定地址和端口來使用不同的CGI前端:
- $ sudo docker run -d --net=host \
- -v /var/lib/ceph/:/var/lib/ceph \
- -v /etc/ceph:/etc/ceph \
- ceph-daemon rgw
可配置的選項(xiàng)如下:
- RGW_REMOTE_CGI指定是否使用嵌入的web服務(wù)器(默認(rèn)為0,設(shè)為1去關(guān)閉)。
- RGW_REMOTE_CGI_HOST指定運(yùn)行CGI進(jìn)程的遠(yuǎn)程主機(jī)。
- RGW_REMOTE_CGI_PORT是運(yùn)行CGI進(jìn)行的遠(yuǎn)程主機(jī)端口。
- RGW_CIVETWEB_PORT是civetweb的監(jiān)聽端口(默認(rèn)為80)。
- RGW_NAME是RADOS gateway實(shí)例的名字(默認(rèn)為$(hostname))。
后續(xù)工作
后端配置存儲(chǔ)
在默認(rèn)配置下,ceph.conf和所有的Ceph密鑰都會(huì)在監(jiān)測模塊啟動(dòng)階段生成。這個(gè)過程假定了你必須在將集群擴(kuò)展到多節(jié)點(diǎn)的時(shí)候去把這些配置傳送到所有節(jié)點(diǎn)上。這個(gè)操作并不靈活,我們希望去改善它。我馬上要提出的一個(gè)方案就是利用Ansible來生成這些配置文件和密碼,并將他們安裝到所有機(jī)器上。
另一種方法是將所有的配置信息存儲(chǔ)到不同的后端服務(wù)器上,例如etcd或consul。
部署管理
最直觀的方案是使用現(xiàn)成的ceph-ansible,雖然我還需要做一些變動(dòng),但主體工作已經(jīng)完成。另一種方案是使用Kubernetes,他們的預(yù)覽版本已經(jīng)發(fā)布。
支持Rocket等其他容器技術(shù)
也不需要做什么,因?yàn)槟憧梢灾苯訉⒛愕腄ocker鏡像運(yùn)送到Rocket里,然后運(yùn)行。