Ceph實現DockerSwarm集羣共享存儲的嘗試

1、背景與結論

在一個四節點的Docker Swarm集羣上,嘗試使用Ceph做爲Docker集羣的共享存儲,解決有狀態服務在分佈式環境下的數據存儲問題。html

通過嘗試,成功使用CephFS實現了多個Docker節點之間的存儲共享。但同時注意到,對於小規模Docker集羣而且運維成本有限的場景,Ceph這樣的分佈式對象存儲系統仍然顯得有點重了,本文的4節點docker swarm集羣上,在Ceph集羣與Portainer-Agent(docker運維工具)部署以後,容器數量達到了30個。所以最終決定採用其餘方案實現小規模docker集羣的共享存儲,好比NFS。node

但Ceph做爲一個高可用高性能的分佈式對象/塊/文件存儲系統,在其餘場景仍是有使用價值的。python

本文主要記述Ceph的搭建過程以及如何用cephfs實現docker swarm集羣的共享存儲。其餘諸如原理機制,運維資料等請參考社區文檔。linux

Ceph對外提供了三種存儲接口,分別是對象存儲 RGW(rados gateway)、塊存儲 RBD(rados block device) 和文件存儲 CephFS。

RGW是RestAPI,docker的數據卷沒法直接使用。從性能角度考慮,應該是RBD最快,但本文使用的Ceph版本與使用RBD作共享存儲所須要的中間件RexRay貌似存在版本不兼容問題,最終沒能成功。。。git

最終本文使用了CephFS來實現docker swarm集羣的共享存儲。github

2、版本與相關資料

本文搭建Ceph使用了目前社區文檔推薦的安裝工具cephadm,安裝的版本爲octopus。四個節點的操做系統均爲CentOS7docker

  • 社區文檔入口:https://docs.ceph.com/docs/master/
  • 中文社區文檔入口:http://docs.ceph.org.cn/
注意,編寫本文時,中文社區文檔並不是最新版本,好比社區文檔中目前建議使用的安裝工具 cephadm在中文社區文檔中就沒有相關資料。

3、Ceph角色規劃

No ip hostname OSD盤 Ceph角色
1 172.17.13.1 manager01.xxx.com /dev/sdb mon,osd,ceph-mds,mgr
2 172.17.13.2 manager02.xxx.com /dev/sdb mon,osd,ceph-mds
3 172.17.13.3 worker01.xxx.com /dev/sdb mon,osd,ceph-mds
4 172.17.13.4 worker02.xxx.com /dev/sdb mon,osd,ceph-mds,mgr,cephadm,NTP服務器

Ceph用於存儲數據的服務OSD須要使用乾淨的磁盤,要求以下:shell

  1. 設備沒有分區
  2. 設備不得具備任何LVM狀態
  3. 設備沒有掛載
  4. 設備不包含任何文件系統
  5. 設備不包含ceph bluestore osd
  6. 設備必須大於5G

也就是給節點增長一塊新磁盤以後,只要linux能識別到便可,不要作分區/格式化/mount等操做。json

4、各節點環境準備工做

4.1 防火牆與Selinux

提早將Ceph相關防火牆規則設置好。或直接關閉防火牆。bootstrap

firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --permanent --zone=public --add-service=ceph
firewall-cmd --permanent --zone=public --add-service=ceph-mon
firewall-cmd --reload
firewall-cmd --zone=public --list-services

firewall-cmd --zone=public --add-port=3300/tcp --permanent
firewall-cmd --zone=public --add-port=3300/udp --permanent
firewall-cmd --zone=public --add-port=6789/tcp --permanent
firewall-cmd --zone=public --add-port=6800-7300/tcp --permanent
firewall-cmd --zone=public --add-port=8443/tcp --permanent
firewall-cmd --reload
firewall-cmd --zone=public --list-ports

Ceph集羣在使用中最好禁用Selinux。在各個節點上以root用戶vi /etc/selinux/config,修改:

#SELINUX=enforcing
SELINUX=disabled

而後執行setenforce 0

4.2 各節點添加epel-release資源包

從阿里雲鏡像獲取/etc/yum.repos.d/epel.repo,以下:

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

4.3 各節點安裝依賴庫

填坑的過程當中嘗試過不一樣的搭建方案,這裏有些依賴庫可能不是必須的。。。

yum -y install python3 yum-utils
yum install yum-plugin-priorities -y
yum install gcc python-setuptools python-devel -y
easy_install pip

4.4 安裝Docker CE

本文的環境已經提早安裝了docker ce,docker compose,並建立了docker swarm集羣。

每一個節點都須要先安裝好Docker,具體方法參考官方文檔:https://docs.docker.com/engine/install/centos/
注意最好使用國內的dokcer安裝yum鏡像。

yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安裝完成以後,添加docker鏡像倉庫地址,vi /etc/docker/daemon.json,添加:

"registry-mirrors": [
          "https://docker.mirrors.ustc.edu.cn",
          "https://dockerhub.azk8s.cn",
          "https://reg-mirror.qiniu.com",
          "https://hub-mirror.c.163.com",
          "https://mirror.ccs.tencentyun.com",
          "https://registry.docker-cn.com"
  ],

而後重啓docker服務:

systemctl daemon-reload
systemctl restart docker

而後提早爲每一個節點拉取Ceph相關鏡像:

docker pull ceph/ceph:v15
docker pull ceph/ceph-grafana
docker pull prom/prometheus:v2.18.1
docker pull prom/alertmanager:v0.20.0
docker pull prom/node-exporter:v0.18.1

4.5 安裝NTP並同步各節點時間

各節點安裝ntp服務

yum install ntp ntpdate ntp-doc -y

在管理節點worker02.xxx.com上安裝ntp服務,vi /etc/ntp.conf:

...
restrict 127.0.0.1 
restrict ::1
restrict 172.17.13.0 mask 255.255.255.0

# Hosts on local network are less restricted.
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
server 127.127.1.0
...

配置了NTP服務的管理節點須要防火牆配置端口:

firewall-cmd --zone=public --add-port=123/udp --permanent
firewall-cmd --reload
firewall-cmd --zone=public --list-ports

在其餘節點設置ntp服務器爲剛剛設定的ntp服務器,vi /etc/ntp.conf:

…
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
server worker02.xxx.com
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
…

重啓各個節點的ntp服務,並設置開機啓動:

systemctl enable ntpd
systemctl restart ntpd
systemctl status ntpd

# Centos7默認安裝了chronyd而且默認enable,這裏須要關閉,不然重啓之後會致使ntpd不能啓動
systemctl disable chronyd

管理節點從外網同步時間,其餘節點從管理節點同步時間:

# 管理節點
ntpdate -u ntp1.aliyun.com

# 其餘節點
ntpdate -u worker02.xxx.com

4.6 更新SSH服務

各節點默認已安裝,能夠更新最新版本,並確認服務狀態

yum install openssh-server -y
service sshd status

4.7 確保短主機名能夠ping通

在每一個節點以root身份vi /etc/hosts,添加:

172.17.13.1  manager01
172.17.13.2  manager02
172.17.13.3  worker01
172.17.13.4  worker02
Ceph默認使用短域名,社區文檔在環境檢查中要求能以短域名ping通,但本文環境都是用的FQDN,這裏即便設置短域名到hosts文件,後續依然有些許小問題。

5、Ceph集羣搭建

5.1 cephadm節點安裝cephadm

如下操做均在cephadm節點上執行。(本文規劃將worker02.xxx.com做爲cephadm節點)

cd ~
mkdir cephadmin
cd cephadmin
curl --silent --remote-name --location https://hub.fastgit.org/ceph/ceph/raw/octopus/src/cephadm/cephadm
chmod +x cephadm
ll -h
官方地址 https://github.com/ceph/ceph/raw/octopus/src/cephadm/cephadm老是下載失敗,所以使用了國內某鏡像地址。

5.2 初始化Ceph集羣

如下操做均在cephadm節點上執行。

生成ceph的yum源文件並將其替換爲使用阿里雲yum源:

./cephadm add-repo --release octopus
cat /etc/yum.repos.d/ceph.repo

sed -i 's#download.ceph.com#mirrors.aliyun.com/ceph#' /etc/yum.repos.d/ceph.repo
cat /etc/yum.repos.d/ceph.repo
yum list | grep ceph
注意版本是 octopus

安裝cephadm:

./cephadm install
which cephadm

引導ceph集羣:

mkdir -p /etc/ceph
cephadm bootstrap --mon-ip 172.17.13.4 --allow-fqdn-hostname

成功後會出現以下信息:

...
INFO:cephadm:Ceph Dashboard is now available at:

         URL: https://worker02.xxx.com:8443/
        User: admin
    Password: 3y44vf60ms

INFO:cephadm:You can access the Ceph CLI with:

    sudo /usr/sbin/cephadm shell --fsid fbd10774-c8cf-11ea-8bcc-00505683571d -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring

INFO:cephadm:Please consider enabling telemetry to help improve Ceph:

    ceph telemetry on

For more information see:

    https://docs.ceph.com/docs/master/mgr/telemetry/

INFO:cephadm:Bootstrap complete.

嘗試登陸Ceph CLI:

[root@worker02 ~]# cephadm shell --fsid fbd10774-c8cf-11ea-8bcc-00505683571d -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring
INFO:cephadm:Using recent ceph image ceph/ceph:v15
[ceph: root@worker02 /]# exit
exit

在瀏覽器中訪問https://worker02.xxx.com:8443/,打開 ceph ui, 第一次登錄要求更改默認密碼

域名訪問前先配置瀏覽器所在節點的hosts文件

5.3 安裝ceph-common並驗證集羣

如下操做均在cephadm節點上執行。

安裝 ceph 工具包, 其中包括 ceph, rbd, mount.ceph 等命令:

cephadm install ceph-common

驗證集羣狀態:

# 查看 ceph 集羣全部組件運行狀態
ceph orch ps

# 查看指定組件運行狀態
ceph orch ps --daemon-type mon

# 查看集羣當前狀態
ceph status
ceph -s

5.4 向集羣添加主機

將以前cephadm bootstrap初始化集羣命令所生成的ceph密鑰拷貝到其餘節點root用戶的"~/.ssh"目錄。注意要輸入其餘節點root用戶密碼。

ssh-copy-id -f -i /etc/ceph/ceph.pub root@manager01.xxx.com
ssh-copy-id -f -i /etc/ceph/ceph.pub root@manager02.xxx.com
ssh-copy-id -f -i /etc/ceph/ceph.pub root@worker01.xxx.com

將其餘節點加入集羣

ceph orch host add manager01.xxx.com
ceph orch host add manager02.xxx.com
ceph orch host add worker01.xxx.com

ceph orch host ls

查看集羣當前服務分佈(此時應該有4個crash,4個mon,兩個mgr)

ceph orch ps

5.5 部署OSD

檢查每一個節點是否有一塊還沒有分區的新磁盤,例如這裏的sdb:

[root@worker01 ~]# lsblk 
NAME            MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
fd0               2:0    1     4K  0 disk 
sda               8:0    0   300G  0 disk 
├─sda1            8:1    0   500M  0 part /boot
└─sda2            8:2    0 299.5G  0 part 
  ├─centos-root 253:0    0 295.5G  0 lvm  /
  └─centos-swap 253:1    0     4G  0 lvm  [SWAP]
sdb               8:16   0   300G  0 disk 
sr0              11:0    1  1024M  0 rom
對於虛擬機,在虛擬機控制檯直接給運行中的虛擬機添加新磁盤以後,每一個節點執行如下命令就能夠刷出磁盤信息,不用重啓:
echo "- - -" > /sys/class/scsi_host/host0/scan
echo "- - -" > /sys/class/scsi_host/host1/scan
echo "- - -" > /sys/class/scsi_host/host2/scan

將新磁盤設備加入集羣

ceph orch daemon add osd manager01.xxx.com:/dev/sdb
ceph orch daemon add osd manager02.xxx.com:/dev/sdb
ceph orch daemon add osd worker01.xxx.com:/dev/sdb
ceph orch daemon add osd worker02.xxx.com:/dev/sdb

# 查看設備信息
ceph orch device ls
# 查看掛載好的osd信息
ceph osd df

5.6 其餘節點安裝ceph-common

爲了在其餘節點也可以直接訪問Ceph集羣,咱們須要在其餘節點上也安裝ceph-common。

cephadm之外的其餘節點執行:

mkdir ~/cephadmin
mkdir /etc/ceph

從cephadm節點以拷貝ceph.repo,cephadm,ceph集羣配置文件,ceph客戶端管理員密鑰到其餘節點:

scp /etc/yum.repos.d/ceph.repo root@manager01.xxx.com:/etc/yum.repos.d
scp /etc/yum.repos.d/ceph.repo root@manager02.xxx.com:/etc/yum.repos.d
scp /etc/yum.repos.d/ceph.repo root@worker01.xxx.com:/etc/yum.repos.d

scp ~/cephadmin/cephadm root@manager01.xxx.com:~/cephadmin/
scp ~/cephadmin/cephadm root@manager02.xxx.com:~/cephadmin/
scp ~/cephadmin/cephadm root@worker01.xxx.com:~/cephadmin/

scp /etc/ceph/ceph.conf root@manager01.xxx.com:/etc/ceph/
scp /etc/ceph/ceph.conf root@manager02.xxx.com:/etc/ceph/
scp /etc/ceph/ceph.conf root@worker01.xxx.com:/etc/ceph/

scp /etc/ceph/ceph.client.admin.keyring root@manager01.xxx.com:/etc/ceph/
scp /etc/ceph/ceph.client.admin.keyring root@manager02.xxx.com:/etc/ceph/
scp /etc/ceph/ceph.client.admin.keyring root@worker01.xxx.com:/etc/ceph/

其餘節點執行:

cd ~/cephadmin
./cephadm install ceph-common

ceph -s

5.7 健康檢查的錯誤

在執行ceph -s或者ceph health時,可能會發現以下的錯誤:

Module 'cephadm' has failed: auth get failed: failed to find client.crash.worker02 in keyring retval: -2

推測是Ceph對長域名支持不足的緣由。經過ceph auth ls命令能夠查看ceph集羣全部的用戶的密鑰,能查到對應的長域名client.crash.worker02.xxx.com用戶但沒有短域名用戶。經過如下命令建立對應的短域名用戶:

# 手動添加用戶client.crash.xxx,任意節點執行
ceph auth add client.crash.worker02 mgr 'profile crash' mon 'profile crash'
ceph auth add client.crash.manager01 mgr 'profile crash' mon 'profile crash'
ceph auth add client.crash.manager02 mgr 'profile crash' mon 'profile crash'
ceph auth add client.crash.worker01 mgr 'profile crash' mon 'profile crash'

# 查看新增用戶是否成功
ceph auth ls

# 重啓ceph集羣,各個節點上都須要執行
systemctl restart ceph.target

# 也能夠用下面的命令中止再重啓ceph集羣,各個節點上都須要執行
systemctl stop ceph.target
systemctl stop ceph\*.service ceph\*.target
ps -ef | grep ceph
docker ps -a
systemctl restart ceph.target

# 重啓後從新檢查狀態
ceph -s

6、部署cephfs服務

6.1 建立cephfs

任意節點上執行:

# 建立一個用於cephfs數據存儲的池,相關參數自行參閱社區文檔,一言難盡。。。
ceph osd pool create cephfs_data 64 64
# 建立一個用於cephfs元數據存儲的池
ceph osd pool create cephfs_metadata 32 32
# 建立一個新的fs服務,名爲cephfs
ceph fs new cephfs cephfs_metadata cephfs_data
# 查看集羣當前的fs服務
ceph fs ls
# 設置cephfs最大mds服務數量
ceph fs set cephfs max_mds 4
# 部署4個mds服務
ceph orch apply mds cephfs --placement="4 manager01.xxx.com manager02.xxx.com worker01.xxx.com worker02.xxx.com"
# 查看mds服務是否部署成功
ceph orch ps --daemon-type mds
本文在這裏遇到一個問題,mds服務一直不能啓動,查看 ceph health發現一個 1 filesystem is online with fewer MDS than max_mds的警告,應該是 ceph fs set cephfs max_mds 4沒有生效。後來重啓了整個集羣就行了。
# 在全部節點上執行
systemctl restart ceph.target

# 重啓以後檢查相關服務
ceph orch ps --daemon-type mds
ceph osd lspools
ceph fs ls

6.2 建立cephfs訪問用戶

建立用戶,用於客戶端訪問CephFs

ceph auth get-or-create client.cephfs mon 'allow r' mds 'allow r, allow rw path=/' osd 'allow rw pool=cephfs_data' -o ceph.client.cephfs.keyring

查看輸出的ceph.client.cephfs.keyring密鑰文件,或使用下面的命令查看密鑰:

ceph auth get-key client.cephfs

6.3 掛載cephfs到各節點本地目錄

在各個節點執行:

mkdir /mnt/cephfs/
mount -t ceph manager01.xxx.com:6789,manager02.xxx.com:6789,worker01.xxx.com:6789,worker02.xxx.com:6789:/ /mnt/cephfs/ -o name=cephfs,secret=<cephfs訪問用戶的密鑰>
manager01.xxx.com:6789,manager02.xxx.com:6789,worker01.xxx.com:6789,worker02.xxx.com:6789 是全部mon服務

編輯各個節點的/etc/fstab文件,實現開機自動掛載,添加如下內容:

manager01.xxx.com:6789,manager02.xxx.com:6789,worker01.xxx.com:6789,worker02.xxx.com:6789:/     /mnt/cephfs    ceph    name=cephfs,secretfile=<cephfs訪問用戶的密鑰>,noatime,_netdev    0       2
相關參數請自行查閱linux下fstab的配置資料。

6.4 使用cephfs實現docker共享存儲

將掛載到本地的cephfs做爲本地磁盤使用便可。例如本文中,能夠在docker run命令中,或者docker compose編排文件中,使用volume本地掛載到/mnt/cephfs下。

示例,注意volumes:

...
  portainer:
    image: portainer/portainer
    ...
    volumes:
      - /mnt/cephfs/docker/portainer:/data
    ...
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints: [node.role == manager]
...
至此,使用cephfs實現docker共享存儲的嘗試已經OK。

7、部署RBD

Ceph的RBD對外提供的是塊存儲,但塊存儲直接做爲磁盤掛載到各節點的話,並不能實現不一樣節點之間的數據共享。所以須要配合中間件Rexray,以及docker插件rexray/rbd來實現共享存儲。

但本文並未成功,緣由後敘。

7.1 初始化rbd pool並建立RBD的image

在任意節點上執行:

ceph osd pool create rbd01 32
rbd pool init rbd01

# 在rbd01上建立一個300G的image
rbd create img01 --size 307200 --pool rbd01
rbd ls rbd01
rbd info --image img01 -p rbd01

此時能夠在各個節點上掛載RBD的img01,可是並不能實現存儲共享。

# 向linux系統內核載入rbd模塊
modprobe rbd

# 將img01映射到系統內核
rbd map img01 --pool rbd01 --id admin
# 失敗,須要禁用當前系統內核不支持的feature
rbd feature disable img01 --pool rbd01 exclusive-lock, object-map, fast-diff, deep-flatten
# 從新映射
rbd map img01 --pool rbd01 --id admin

# 映射成功後,會返回映射目錄"/dev/rbd0",對該目錄進行格式化:
[root@worker01 ~]# mkfs.xfs /dev/rbd0
meta-data=/dev/rbd0              isize=512    agcount=17, agsize=4914176 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=78643200, imaxpct=25
         =                       sunit=1024   swidth=1024 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=38400, version=2
         =                       sectsz=512   sunit=8 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

# mount到本地
mkdir /mnt/data01
mount /dev/rbd0 /mnt/data01

# 查看本地磁盤信息
df -hT

# 卸除掛載並刪除image
umount /mnt/data01
rbd unmap img01 --pool rbd01 --id admin
rbd rm --image img01 -p rbd01

7.2 安裝rexray與rexray/rbd

任意某個節點下載rexray:

curl -sSL https://rexray.io/install | sh

編輯配置文件vi /etc/rexray/config.yml,內容以下:

rexray:
  logLevel:        debug
libstorage:
  logging:
    level:         debug
    httpRequests:  true
    httpResponses: true
libstorage:
  service: rbd
rbd:
  defaultPool: rbd01

嘗試啓動Rexray服務,這裏一直失敗:

[root@manager01 rexray]# rexray start
...
error: service startup failed: agent: mod init failed: error initializing instance ID cache
日誌中除了最後的錯誤,並沒有其餘有用的信息。在github對應項目的issue中有相似問題,解決方法是ceph配置文件 /etc/ceph/ceph.conf中添加 mon_host配置。但本文使用的ceph版本 octopus的配置文件中已經明確配置了 mon_host,且格式與issue所述不一樣。

最終也沒有找到緣由,懷疑是Ceph版本太新,與rexray不兼容所致。因此這裏的嘗試到此爲止,後續安裝docker插件與建立rbd數據卷並未進行。

若是Rexray服務能成功啓動,那麼後續還須要在每一個節點安裝docker插件rexray/rbd:

docker plugin install rexray/rbd RBD_DEFAULTPOOL=rbd01 LINUX_VOLUME_FILEMODE=0777

最後在docker swarm上建立rbd驅動的數據卷:

docker volume create -d <rexrayHost>:5011/rexray/rbd <數據卷名稱>

若是成功,docker run或編排文件中的volume使用事先建立好的數據卷便可實現存儲共享。

相關文章
相關標籤/搜索