共计 12736 个字符,预计需要花费 32 分钟才能阅读完成。
一、背景与论断
在一个四节点的 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=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 文件,后续仍然有些许小问题。
五、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 |
六、部署 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。
七、部署 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 应用当时创立好的数据卷即可实现存储共享。