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使用事先建立好的数据卷便可实现存储共享。

相关文章
相关标签/搜索