Ceph是一個徹底開源的分佈式存儲方案、網絡塊設備以及文件系統,具備高穩定性、高性能、高擴展性等特色,可應對terabyte到exabyte級別的數據量。前端
經過使用創新性的調度算法(CRUSH)、主動存儲節點、以及peer-to-peer的gossip協議,Ceph規避了傳統集中控制和lookup table中的擴展性和可靠性問題。web
Ceph目前在整個開源社區中極受推崇,已被普遍應用與虛擬化平臺(Proxmox)、雲計算平臺(OpenStack、 CloudStack、OpenNebula)、容器技術(Docker)、以及大數據分析系統(Hadoop、做爲HDFS的meted服務器)中。算法
我嘗試將Ceph運行在Docker中已經快兩年了。直到今天我依然在作這些工做。最近我更是在 Docker 中部署 Ceph方面投入了不小的精力。docker
在展開技術細節前,我要特別感謝Sean C McCord對此工做的大力支持,當年的開源ceph-docker項目也的確是基於Sean的早期工做。後端
如今讓咱們具體看看如何將Ceph運行在Docker裏!服務器
原理網絡
將Ceph運行在Docker中是一個比較有爭議的話題,很多人質疑這樣操做的意義。雖然將檢測模塊、metadata服務器、以及RADOS gateway容器化都沒有太大問題,但對於OSD(object storage daemon),事情會變得很棘手。Ceph的OSD專門針對物理機器進行優化,與底層硬件有不少關聯。若是物理硬盤失效,OSD也沒法運做,這給容器化的場景帶來了問題。app
坦白地講,在過去某個時刻我也在想:分佈式
「我不知道本身爲何作這個,我只知道有人須要這個功能(固然,他們可能也不知道爲何想要)。我只是以爲想進行技術嘗試,那就試試看!」微服務
固然上述想法聽起來並不樂觀,但這確實是我當時真實的想法。個人觀點隨後有了一些變化,我來解釋下爲何是值得的。但願這個解釋也能改變你的見解(個人解釋不只僅是「Docker很酷,因此咱們要把全部東西都跑在Docker裏!」)。
很多開發者已經花了不少時間將他們的軟件容器化。在這個過程當中,他們也用過多種不一樣的工具來構建和管理他們的環境。若是我看到有人用 Kubernetes 來做爲管理工具也一點都不會吃驚。
有的人就喜歡將最新潮的技術應用到生產當中,不然他們會以爲工做很無聊。因此當他們看到本身最喜歡的開源存儲方案也正在被容器化時,他們會由於這個順應了「一切容器化」的方式而感到高興。
與傳統的 yum 或 apt-get不一樣,容器使得軟件的升級和回捲變得容易:咱們能夠經過 docker stop或者docker run來發布新的daemons版本。咱們甚至能夠在一臺物理機器上運行多個相互隔離的集羣。這些都爲開發過程提供了極大的便利。
項目
如上所述,全部的工做都基於Sean C McCord的早期貢獻,咱們後來都在圍繞他的工做作完善。如今若是你用ceph-docker,你能夠將每一個單一的Ceph daemon運行在Ubuntu或CentOS上。
咱們在Docker Hub裏有不少的鏡像,咱們使用Ceph的命名空間,所以咱們的鏡像前綴都是ceph/<daemon>。咱們使用了自動構建,所以每次咱們整合一個新的補丁就會觸發新的構建,從而生成一個新的容器鏡像。
因爲咱們如今在從事代碼重構,你會看到有不少的鏡像版本。一直以來咱們對每個daemon構建一個單獨的鏡像(咱們整合這些補丁的時候都會這樣作)。因此監測、OSD、mds和radosgw各自都有獨立的鏡像。這個並非最理想的方案,所以咱們在嘗試將全部組件都整合到一個叫作 daemon的鏡像中。
這個鏡像包含了全部的模塊,你能夠在運行docker run的時候經過命令行選擇性地激活不一樣模塊。若是你想試用咱們的鏡像,咱們推薦使用ceph/daemon鏡像。下面我就舉例說明如何運行。
容器化Ceph
監測
因爲監測模塊不能在NAT過的網絡中進行通訊,咱們必須使用 --net=host來將主機的網絡層開放給容器:
$ 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
你能夠配置以下選項:
MON_IP是運行Docker的主機IP
MON_NAME是你監測模塊的名稱(默認爲$(hostname))
CEPH_PUBLIC_NETWORK是運行Docker的主機的CIDR。它和MON_IP必須是同一個網絡。
CEPH_CLUSTER_NETWORK是運行Docker的主機的備用網口的CIDR,爲OSD的備份流量使用。
Object Storage Daemon
咱們如今能實現容許每個OSD進程運行在一個獨立的容器裏。按照微服務的理念,一個容器裏不該該運行超過一個服務。而在咱們這裏,在同一個容器裏運行多個OSD進程,打破了這一理念,固然這也會給系統的配置和維護帶來額外的複雜度。
在這樣的配置下,咱們必須使用--privileged=true來使得容器中的進程能夠訪問/dev等其餘內核功能。而後,咱們在開放OSD的目錄的基礎上也支持其餘配置,開放OSD的目錄可讓operators來對設備作合適的準備工做。
這樣咱們就能夠簡單地開放OSD目錄,配置OSD(ceph-osd mkfs)的工做就會經過Entry Point來完成。我下面介紹的配置方法是最簡單的,由於它只須要你指定一個block device,剩下的事情都會由Entry Point完成。
若是不想用--privileged=true能夠採用個人第二個例子。
$ 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,你也可使用你喜歡的配置管理工具來手動配置OSD。
下面這個例子我假定你已經實現分區並配置好文件系統。運行下面的命令來生成你的OSD:
$ sudo docker exec <mon-container-id> ceph osd create.
而後運行你的容器:
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
可配置的選項以下:
OSD_DEVICE i是OSD設備,例如:/dev/sdb
OSD_JOURNAL使用來儲存OSD journal的設備,例如:/dev/sdz
HOSTNAME是運行OSD的主機(默認爲$(hostname)
OSD_FORCE_ZAP會強制將制定的設備內容zapping(默認爲 0,設爲1去開啓)
OSD_JOURNAL_SIZE是OSD journal的大小(默認爲 100)
Metadata 服務器
這個組件的設置較爲直觀。惟一須要注意的地方是在Docker中咱們能夠訪問Ceph管理員密鑰。這個密鑰會用來生成CephFS pools和文件系統。
若是你運行0.87之前的Ceph版本,你就不須要作此配置,然而咱們最好運行最新的版本!
$ 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
可配置的選項以下:
MDS_NAME是Metadata服務器的名字(默認爲mds-$(hostname))。
CEPHFS_CREATE會爲Metadata服務器生成文件系統(默認爲0,設爲1 去開啓)。
CEPHFS_NAME是Metadata文件系統的名字(默認爲cephfs)。
CEPHFS_DATA_POOL是Metadata服務器data pool的名字(默認爲cephfs_data)。
CEPHFS_DATA_POOL_PG是data pool的placement groups的數量 (默認爲8)。
CEPHFS_DATA_POOL是Metadata服務器metadata pool的名字(默認爲cephfs_metadata)。
CEPHFS_METADATA_POOL_PG是metadata pool的placement groups的數量(默認爲 8)。
RADOS gateway
咱們部署RADOS gateway時默認開啓civetweb。固然,咱們也能夠經過指定地址和端口來使用不一樣的CGI前端:
$ sudo docker run -d --net=host \
-v /var/lib/ceph/:/var/lib/ceph \
-v /etc/ceph:/etc/ceph \
ceph-daemon rgw
可配置的選項以下:
RGW_REMOTE_CGI指定是否使用嵌入的web服務器(默認爲0,設爲1去關閉)。
RGW_REMOTE_CGI_HOST指定運行CGI進程的遠程主機。
RGW_REMOTE_CGI_PORT是運行CGI進行的遠程主機端口。
RGW_CIVETWEB_PORT是civetweb的監聽端口(默認爲80)。
RGW_NAME是RADOS gateway實例的名字(默認爲$(hostname))。
後續工做
後端配置存儲
在默認配置下,ceph.conf和全部的Ceph密鑰都會在監測模塊啓動階段生成。這個過程假定了你必須在將集羣擴展到多節點的時候去把這些配置傳送到全部節點上。這個操做並不靈活,咱們但願去改善它。我立刻要提出的一個方案就是利用Ansible來生成這些配置文件和密碼,並將他們安裝到全部機器上。
另外一種方法是將全部的配置信息存儲到不一樣的後端服務器上,例如etcd或consul。
部署管理
最直觀的方案是使用現成的ceph-ansible,雖然我還須要作一些變更,但主體工做已經完成。另外一種方案是使用Kubernetes,他們的預覽版本已經發布。
支持Rocket等其餘容器技術
也不須要作什麼,由於你能夠直接將你的Docker鏡像運送到Rocket裏,而後運行。