一、背景与论断
在一个四节点的Docker Swarm集群上,尝试应用Ceph作为Docker集群的共享存储,解决有状态服务在分布式环境下的数据存储问题。
通过尝试,胜利应用CephFS实现了多个Docker节点之间的存储共享。但同时留神到,对于小规模Docker集群并且运维老本无限的场景,Ceph这样的分布式对象存储系统依然显得有点重了,本文的4节点docker swarm集群上,在Ceph集群与Portainer-Agent(docker运维工具)部署之后,容器数量达到了30个。因而最终决定采纳其余计划实现小规模docker集群的共享存储,比方NFS。
但Ceph作为一个高可用高性能的分布式对象/块/文件存储系统,在其余场景还是有应用价值的。
本文次要记述Ceph的搭建过程以及如何用cephfs实现docker swarm集群的共享存储。其余诸如原理机制,运维材料等请参考社区文档。
Ceph对外提供了三种存储接口,别离是对象存储 RGW(rados gateway)、块存储 RBD(rados block device) 和文件存储 CephFS。RGW是RestAPI,docker的数据卷无奈间接应用。从性能角度思考,应该是RBD最快,但本文应用的Ceph版本与应用RBD做共享存储所须要的中间件RexRay貌似存在版本不兼容问题,最终没能胜利。。。
最终本文应用了CephFS来实现docker swarm集群的共享存储。
二、版本与相干材料
本文搭建Ceph应用了目前社区文档举荐的装置工具cephadm
,装置的版本为octopus
。四个节点的操作系统均为CentOS7
。
- 社区文档入口:
https://docs.ceph.com/docs/master/
- 中文社区文档入口:
http://docs.ceph.org.cn/
留神,编写本文时,中文社区文档并非最新版本,比方社区文档中目前倡议应用的装置工具cephadm
在中文社区文档中就没有相干材料。
三、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须要应用洁净的磁盘,要求如下:
- 设施没有分区
- 设施不得具备任何LVM状态
- 设施没有挂载
- 设施不蕴含任何文件系统
- 设施不蕴含ceph bluestore osd
- 设施必须大于5G
也就是给节点减少一块新磁盘之后,只有linux能辨认到即可,不要做分区/格式化/mount等操作。
四、各节点环境筹备工作
4.1 防火墙与Selinux
提前将Ceph相干防火墙规定设置好。或间接敞开防火墙。
firewall-cmd --permanent --zone=public --add-service=httpfirewall-cmd --permanent --zone=public --add-service=httpsfirewall-cmd --permanent --zone=public --add-service=cephfirewall-cmd --permanent --zone=public --add-service=ceph-monfirewall-cmd --reloadfirewall-cmd --zone=public --list-servicesfirewall-cmd --zone=public --add-port=3300/tcp --permanentfirewall-cmd --zone=public --add-port=3300/udp --permanentfirewall-cmd --zone=public --add-port=6789/tcp --permanentfirewall-cmd --zone=public --add-port=6800-7300/tcp --permanentfirewall-cmd --zone=public --add-port=8443/tcp --permanentfirewall-cmd --reloadfirewall-cmd --zone=public --list-ports
Ceph集群在应用中最好禁用Selinux。在各个节点上以root用户vi /etc/selinux/config
,批改:
#SELINUX=enforcingSELINUX=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-utilsyum install yum-plugin-priorities -yyum install gcc python-setuptools python-devel -yeasy_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-reloadsystemctl restart docker
而后提前为每个节点拉取Ceph相干镜像:
docker pull ceph/ceph:v15docker pull ceph/ceph-grafanadocker pull prom/prometheus:v2.18.1docker pull prom/alertmanager:v0.20.0docker 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 ::1restrict 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 iburstserver 127.127.1.0...
配置了NTP服务的治理节点须要防火墙配置端口:
firewall-cmd --zone=public --add-port=123/udp --permanentfirewall-cmd --reloadfirewall-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 ntpdsystemctl restart ntpdsystemctl 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 -yservice sshd status
4.7 确保短主机名能够ping通
在每个节点以root身份vi /etc/hosts
,增加:
172.17.13.1 manager01172.17.13.2 manager02172.17.13.3 worker01172.17.13.4 worker02
Ceph默认应用短域名,社区文档在环境查看中要求能以短域名ping通,但本文环境都是用的FQDN,这里即便设置短域名到hosts文件,后续仍然有些许小问题。
五、Ceph集群搭建
5.1 cephadm节点装置cephadm
以下操作均在cephadm节点上执行。(本文布局将worker02.xxx.com
作为cephadm节点)
cd ~mkdir cephadmincd cephadmincurl --silent --remote-name --location https://hub.fastgit.org/ceph/ceph/raw/octopus/src/cephadm/cephadmchmod +x cephadmll -h
官网地址https://github.com/ceph/ceph/raw/octopus/src/cephadm/cephadm
总是下载失败,因而应用了国内某镜像地址。
5.2 初始化Ceph集群
以下操作均在cephadm节点上执行。
生成ceph的yum源文件并将其替换为应用阿里云yum源:
./cephadm add-repo --release octopuscat /etc/yum.repos.d/ceph.reposed -i 's#download.ceph.com#mirrors.aliyun.com/ceph#' /etc/yum.repos.d/ceph.repocat /etc/yum.repos.d/ceph.repoyum list | grep ceph
留神版本是octopus
装置cephadm:
./cephadm installwhich cephadm
疏导ceph集群:
mkdir -p /etc/cephcephadm 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: 3y44vf60msINFO: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.keyringINFO:cephadm:Please consider enabling telemetry to help improve Ceph: ceph telemetry onFor 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.keyringINFO:cephadm:Using recent ceph image ceph/ceph:v15[ceph: root@worker02 /]# exitexit
在浏览器中拜访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 statusceph -s
5.4 向集群增加主机
将之前cephadm bootstrap初始化集群命令所生成的ceph密钥拷贝到其余节点root用户的"~/.ssh"目录。留神要输出其余节点root用户明码。
ssh-copy-id -f -i /etc/ceph/ceph.pub root@manager01.xxx.comssh-copy-id -f -i /etc/ceph/ceph.pub root@manager02.xxx.comssh-copy-id -f -i /etc/ceph/ceph.pub root@worker01.xxx.com
将其余节点退出集群
ceph orch host add manager01.xxx.comceph orch host add manager02.xxx.comceph orch host add worker01.xxx.comceph 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 MOUNTPOINTfd0 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/scanecho "- - -" > /sys/class/scsi_host/host1/scanecho "- - -" > /sys/class/scsi_host/host2/scan
将新磁盘设施退出集群
ceph orch daemon add osd manager01.xxx.com:/dev/sdbceph orch daemon add osd manager02.xxx.com:/dev/sdbceph orch daemon add osd worker01.xxx.com:/dev/sdbceph 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 ~/cephadminmkdir /etc/ceph
从cephadm节点以拷贝ceph.repo,cephadm,ceph集群配置文件,ceph客户端管理员密钥到其余节点:
scp /etc/yum.repos.d/ceph.repo root@manager01.xxx.com:/etc/yum.repos.dscp /etc/yum.repos.d/ceph.repo root@manager02.xxx.com:/etc/yum.repos.dscp /etc/yum.repos.d/ceph.repo root@worker01.xxx.com:/etc/yum.repos.dscp ~/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-commonceph -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.targetsystemctl stop ceph\*.service ceph\*.targetps -ef | grep cephdocker ps -asystemctl restart ceph.target# 重启后从新查看状态ceph -s
六、部署cephfs服务
6.1 创立cephfs
任意节点上执行:
# 创立一个用于cephfs数据存储的池,相干参数自行参阅社区文档,一言难尽。。。ceph osd pool create cephfs_data 64 64# 创立一个用于cephfs元数据存储的池ceph osd pool create cephfs_metadata 32 32# 创立一个新的fs服务,名为cephfsceph 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 mdsceph osd lspoolsceph 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。
七、部署RBD
Ceph的RBD对外提供的是块存储,但块存储间接作为磁盘挂载到各节点的话,并不能实现不同节点之间的数据共享。因而须要配合中间件Rexray
,以及docker插件rexray/rbd
来实现共享存储。
但本文并未胜利,起因后叙。
7.1 初始化rbd pool并创立RBD的image
在任意节点上执行:
ceph osd pool create rbd01 32rbd pool init rbd01# 在rbd01上创立一个300G的imagerbd create img01 --size 307200 --pool rbd01rbd ls rbd01rbd info --image img01 -p rbd01
此时能够在各个节点上挂载RBD的img01,然而并不能实现存储共享。
# 向linux零碎内核载入rbd模块modprobe rbd# 将img01映射到零碎内核rbd map img01 --pool rbd01 --id admin# 失败,须要禁用以后零碎内核不反对的featurerbd 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/rbd0meta-data=/dev/rbd0 isize=512 agcount=17, agsize=4914176 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0data = bsize=4096 blocks=78643200, imaxpct=25 = sunit=1024 swidth=1024 blksnaming =version 2 bsize=4096 ascii-ci=0 ftype=1log =internal log bsize=4096 blocks=38400, version=2 = sectsz=512 sunit=8 blks, lazy-count=1realtime =none extsz=4096 blocks=0, rtextents=0# mount到本地mkdir /mnt/data01mount /dev/rbd0 /mnt/data01# 查看本地磁盘信息df -hT# 卸除挂载并删除imageumount /mnt/data01rbd unmap img01 --pool rbd01 --id adminrbd 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: debuglibstorage: logging: level: debug httpRequests: true httpResponses: truelibstorage: service: rbdrbd: 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应用当时创立好的数据卷即可实现存储共享。