关于docker:Ceph实现DockerSwarm集群共享存储的尝试

5次阅读

共计 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 须要应用洁净的磁盘,要求如下:

  1. 设施没有分区
  2. 设施不得具备任何 LVM 状态
  3. 设施没有挂载
  4. 设施不蕴含任何文件系统
  5. 设施不蕴含 ceph bluestore osd
  6. 设施必须大于 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 应用当时创立好的数据卷即可实现存储共享。

正文完
 0