此为南京大学 2024 年春季学期云计算课程的第二次实践内容。
实践原始要求:采用成熟、简单的 ceph-deploy 实现 Ceph 集群(nautilus版本)的部署。
在实践课开始之前,我就想动手开始做,奈何没有文档,所以提前琢磨了一下。
本文的内容主要参考了 Ceph 官方文档、只讲了一半的知乎专栏、TinyChen 的博客与 GPT4。
关于 Ceph 集群的介绍,本文不再赘述,有兴趣的读者可以参考 Ceph 官方文档。
本文记录了 Sakiyary 在 Docker 的容器内(赛博洁癖,没事找事)使用 ceph-deploy 部署 Ceph 集群的过程。实现了 Ceph 的节点(MON x1、MGR x1、OSD x3)与 Dashboard 的部署。
环境说明
- 计算机属性:
软院云塑料云上的某一台服务器
- 操作系统:Ubuntu 18.04
- 假物理内存大小:16 GB
- 假硬盘大小:145 GB
- Docker 版本:20.10.21
- 用户:root
所以本文所有命令中均没有 sudo
前缀。
可自行替换本文中的 /root/
路径为 /home/<用户名>/
,并添加 sudo
前缀。
经完整部署后预估 Ceph 集群(Docker部署 3 个节点)所需占用的最小硬盘空间为 10 GB 左右(不含 Docker 本体,仅估计 OSD 大小与镜像大小)。
准备工作
Docker 的安装、科学网络的配置等工作不在本文的讨论范围内,这里只讨论 Ceph 部署的过程。
若干参考文档中均指出了 Ceph 不同节点间需要同步时钟,但由于本人这次是在 Docker 容器内部署,每个容器均调用了宿主机的时间,所以这里不需要再进行时钟同步。
创建虚拟逻辑卷
由于服务器仅有一块物理硬盘,但是部署 1 个 Ceph 集群就至少应该有 3 个 OSD 节点,也就是 3 个硬盘设备(逻辑卷),所以这里需要先创建三个逻辑卷。(仅创建物理卷是不够的,Ceph 只认逻辑卷,血的教训,被网爆了很久……)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
mkdir -p /root/ceph touch /root/ceph/osd1.img touch /root/ceph/osd2.img touch /root/ceph/osd3.img
dd if=/dev/zero of=/root/ceph/osd1.img bs=1G count=3 dd if=/dev/zero of=/root/ceph/osd2.img bs=1G count=3 dd if=/dev/zero of=/root/ceph/osd3.img bs=1G count=3
losetup /dev/loop11 /root/ceph/osd1.img losetup /dev/loop12 /root/ceph/osd2.img losetup /dev/loop13 /root/ceph/osd3.img pvcreate /dev/loop11 pvcreate /dev/loop12 pvcreate /dev/loop13
vgcreate ceph-vg-1 /dev/loop11 vgcreate ceph-vg-2 /dev/loop12 vgcreate ceph-vg-3 /dev/loop13
lvcreate -l 100%FREE -n osd-lv-1 ceph-vg-1 lvcreate -l 100%FREE -n osd-lv-2 ceph-vg-2 lvcreate -l 100%FREE -n osd-lv-3 ceph-vg-3
|
配置宿主机自交的 SSH 免密登录
Ceph 集群中的节点之间需要 SSH 免密登录,这里提前配置好可以省去非常多的重复操作(血的教训)。
思路是让三个容器都使用同一个 .ssh
目录,这样就不用在每个容器中都配置一遍 SSH 了,实现全联通。
1 2 3 4 5 6 7 8 9 10 11
|
mkdir -p /root/.ssh
ssh-keygen -t rsa -f /root/.ssh/id_rsa -C "root@se-cloud" cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
chmod 700 /root/.ssh chmod 600 /root/.ssh/authorized_keys
|
创建 Docker 网络
这里创建一个 Docker 网络,方便容器之间的通信。
1 2 3
|
docker network create --subnet 192.168.102.0/24 ceph-network
|
如果不指定 --subnet
,Docker 会自动分配一个子网,但这个默认的子网很大概率会与南大鼓楼二舍有线网网段冲突(172.17.0.0/16
),导致服务器失联,故建议手动指定一个不冲突的子网。
部署 Ceph 集群
经过 Sakiyary 的反复试错,反复调整,反复查资料,将几乎所有的重复步骤都整合进了 Dockerfile
中,这里只需要构建一个专属镜像就可以避免很多重复操作。(都是血的教训……)
注:这里并未使用 Ceph 官方的镜像,而是使用 CentOS 7 作为基础镜像,再在其基础上使用 ceph-deploy 安装 Ceph,这样可以更好地控制 Ceph 的版本,也可以更好地理解 Ceph 的安装过程,最为重要的是满足实践原始要求。
构建带有 Systemd + Ceph 的 CentOS 镜像
1 2 3 4 5
|
docker pull centos:7
vim /root/ceph/Dockerfile
|
这里给出我的 Dockerfile,部分内容需要自行填写,可以根据自己的需求进行修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| FROM centos:7 ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ rm -f /lib/systemd/system/multi-user.target.wants/*;\ rm -f /etc/systemd/system/*.wants/*;\ rm -f /lib/systemd/system/local-fs.target.wants/*; \ rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ rm -f /lib/systemd.system/basic.target.wants/*;\ rm -f /lib/systemd.system/anaconda.target.wants/*;
ENV HTTP_PROXY="http://你自己的地址:端口" \ HTTPS_PROXY="http://你自己的地址:端口" \ http_proxy="http://你自己的地址:端口" \ https_proxy="http://你自己的地址:端口"
RUN echo "192.168.102.2 centos-1" >> /etc/hosts && \ echo "192.168.102.3 centos-2" >> /etc/hosts && \ echo "192.168.102.4 centos-3" >> /etc/hosts
RUN echo -e "[Ceph]\nname=Ceph Nautilus\nbaseurl=http://download.ceph.com/rpm-nautilus/el7/\$basearch\nenabled=1\ngpgcheck=0\npriority=1" > /etc/yum.repos.d/ceph-nautilus.repo && \ echo -e "[Ceph-noarch]\nname=Ceph Noarch\nbaseurl=http://download.ceph.com/rpm-nautilus/el7/noarch\nenabled=1\ngpgcheck=0\npriority=1" >> /etc/yum.repos.d/ceph-nautilus.repo && \ echo -e "[Ceph-source]\nname=Ceph Source\nbaseurl=http://download.ceph.com/rpm-nautilus/el7/SRPMS\nenabled=0\ngpgcheck=0\npriority=1" >> /etc/yum.repos.d/ceph-nautilus.repo
RUN yum update -y && \ yum install -y vim wget openssh-clients openssh-server net-tools chrony conntrack ipset jq iptables curl sysstat libseccomp socat git python-setuptools epel-release ceph-deploy && \ yum install -y ceph-mon ceph-radosgw ceph-mds ceph-mgr ceph-osd ceph-common
RUN mkdir -p /root/ceph-admin
RUN mkdir -p /root/.ssh && \ chmod 700 /root/.ssh && \ ssh-keygen -A
RUN systemctl enable sshd
CMD ["/usr/sbin/init"]
|
编写完 Dockerfile
后,构建镜像。
1 2 3
|
docker build -t centos-ceph:7 /root/ceph
|
若出现 `/etc/hosts`: Read-only file system 报错
此为 Docker 的安全机制导致的。在 Docker 中,某些文件和目录(如 /etc/hosts
、/etc/resolv.conf
和 /etc/hostname
)是自动管理的,通常不允许在构建过程中直接修改。
请将 Dockerfile
中 22~24 行与 /etc/hosts
相关的 RUN
命令删除,改为在容器启动时执行。
请用新增参数后的 `docker run` 指令替换下一节的指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| docker run \ -d \ --privileged \ --name centos-1 \ --hostname centos-1 \ --network ceph-network \ -p 8011:8011 \ --device /dev/ceph-vg-1/osd-lv-1:/dev/ceph-vg-1/osd-lv-1 \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /dev:/dev \ -v /root/.ssh:/root/.ssh \ --add-host centos-1:192.168.102.2 \ --add-host centos-2:192.168.102.3 \ --add-host centos-3:192.168.102.4 \ centos-ceph:7
|
等待漫长的构建过程结束后,我们就可以使用这个镜像来创建容器了。如果你的网络不好的话,很可能会在构建时卡死在更新软件源/安装软件那几步。
构建完的镜像可以通过 docker images
查看,大小约为 1.01 GB。
创建 Ceph 容器
这里使用 docker-compose
来运行容器会更加好。我这里就偷懒了,复制了三条 docker run
命令完事,不过记得要按顺序输入,也不建议更改容器的主机名称 hostname
,Ceph 要求主机名与域名相同,域名已在 Dockerfile
中设置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| docker run \ -d \ --privileged \ --name centos-1 \ --hostname centos-1 \ --network ceph-network \ -p 8011:8011 \ --device /dev/ceph-vg-1/osd-lv-1:/dev/ceph-vg-1/osd-lv-1 \ -v /sys/fs/cgroup:/sys/fs/cgroup:ro \ -v /dev:/dev \ -v /root/.ssh:/root/.ssh \ centos-ceph:7
docker run -d --privileged --name centos-2 --hostname centos-2 --network ceph-network -p 8012:8012 --device /dev/ceph-vg-2/osd-lv-2:/dev/ceph-vg-2/osd-lv-2 -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /dev:/dev -v /root/.ssh:/root/.ssh centos-ceph:7 docker run -d --privileged --name centos-3 --hostname centos-3 --network ceph-network -p 8013:8013 --device /dev/ceph-vg-3/osd-lv-3:/dev/ceph-vg-3/osd-lv-3 -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /dev:/dev -v /root/.ssh:/root/.ssh centos-ceph:7
|
如果读不懂这几行运行容器的命令也很正常,因为这里的所有参数都是我每摔倒一次、去问一下 GPT4、再加上去的,诸如端口映射、设备映射、挂载目录、Systemd 的启动等等,读不懂但是好奇的也可以去问问 GPT。
进入容器
在创建完三个容器之后,最简单的就是开三个终端,分屏操作,Windows 11 的三页分屏就很爽。
在三个终端分别输入下面三条命令进入容器内。
1 2 3 4 5 6 7
|
docker exec -it centos-1 /bin/bash
docker exec -it centos-2 /bin/bash
docker exec -it centos-3 /bin/bash
|
测试容器网络与 SSH
分别进入容器后,可以先测试一下Docker 内部网络与 SSH 互联是否正常。
1 2 3 4 5 6 7
| ping centos-2 ping centos-3 ssh root@centos-2
ssh root@centos-3
|
部署 MON 与 MGR 节点
接下来就是部署 Ceph 集群了,这里只需要在一个容器内执行即可。我选择在 centos-1
容器内执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
cd ~/ceph-admin
ceph-deploy new --cluster-network 192.168.102.0/24 --public-network 192.168.102.0/24 centos-1
ceph-deploy mon create-initial
ceph-deploy admin centos-1 centos-2 centos-3
ceph-deploy --overwrite-conf admin centos-1 centos-2 centos-3
ceph-deploy mgr create centos-1
|
成功创建完 MON 节点与 MGR 节点后,就可以在另外两个容器中查看 Ceph 集群的状态了。
若显示如下,则说明 Ceph 集群的 MON 节点与 MGR 节点部署成功。打码部分为下一小节的内容。
HEALTH_WARN
不影响正常使用,可以忽略,也可在 centos-1
容器内执行如下命令解决。
1 2 3
|
ceph config set mon auth_allow_insecure_global_id_reclaim false
|
部署 OSD 节点
接下来就是部署 OSD 了,这里也只需要在一个容器内执行即可。我选择在 centos-1
容器内执行。这一步折磨了我非常久,最终在 GPT4 的指导下将准备工作中的物理卷转为逻辑卷后才成功。
1 2 3 4 5 6 7 8
|
ceph-deploy osd create --data /dev/ceph-vg-1/osd-lv-1 centos-1 ceph-deploy osd create --data /dev/ceph-vg-2/osd-lv-2 centos-2 ceph-deploy osd create --data /dev/ceph-vg-3/osd-lv-3 centos-3
ceph osd tree
|
同理,成功创建完 OSD 后,就可以在另外两个容器中查看 Ceph 集群的完整状态了。
注意到,仅搭建 Ceph 集群而不使用的话,每个 OSD 的大小可以适当缩小,这里我每个 OSD 都是 10 GB,实际上只需要 2 GB 就够了,3 GB 较为保险,故 OSD 总共只需要 9 GB 的硬盘空间来保证实践的顺利进行。
部署 Ceph Dashboard
Ceph Dashboard 是 Ceph 集群的 Web 管理界面,可以通过浏览器访问,方便地查看集群的状态、监控集群的运行情况、管理集群的配置等。
Dashboard 只需要在一个节点上部署即可,这里我选择在 centos-1
容器内部署。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
yum install -y ceph-mgr-dashboard
ceph mgr module enable dashboard
ceph config set mgr mgr/dashboard/ssl false ceph config set mgr mgr/dashboard/server_addr 0.0.0.0
ceph config set mgr mgr/dashboard/server_port 8011 ceph config set mgr mgr/dashboard/ssl_server_port 8011
ceph mgr module disable dashboard ceph mgr module enable dashboard
echo "admin" > /tmp/pwd.txt
ceph dashboard ac-user-create admin -i /tmp/pwd.txt administrator rm /tmp/pwd.txt
ceph dashboard ac-user-show admin
|
运行完上述命令后,如果容器、Docker、宿主机(服务器)的网络配置均没有问题,防火墙均开放 8011 端口的话,就可以在浏览器中输入 http://<服务器 IP>:8011
访问 Ceph 的 Dashboard 了。
总结
本来以为 Docker 完成这种部署任务可以轻而易举的(就像隔壁 Flink 一样),结果一来是官方文档没有 Docker 相关,二来是互联网上经验教程屈指可数,同样没有同时与 Docker / ceph-deploy 相关的内容,三来是本人的赛博洁癖越发严重,不想为这个小任务去装庞大的 VMWare,所以就坚定地磕磕绊绊地用 Docker 和 ceph-deploy 把 Ceph 成果部署完了。感谢 GPT4 的指导,让我少走了很多弯路!
也是因为在实践的过程中,记录下了很多重复性的命令(用来复制的,虽然后来抽象成了 Dockerfile
),所以才突发奇想,马上建个博客,把这个过程记录下来,也算是对自己通了个宵的一个总结。
后日谈
要开始做清理啦!这里提供了一些清理的命令,以免在实验结束后占用服务器资源。
停止与删除容器
1 2 3
| docker stop centos-1 centos-2 centos-3 docker rm centos-1 centos-2 centos-3
|
删除 Docker 网络
1 2
| docker network rm ceph-network
|
删除 Docker 镜像
1 2
| docker rmi centos-ceph:7 centos:7
|
删除逻辑卷
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| lvremove /dev/ceph-vg-1/osd-lv-1 lvremove /dev/ceph-vg-2/osd-lv-2 lvremove /dev/ceph-vg-3/osd-lv-3 vgremove ceph-vg-1 vgremove ceph-vg-2 vgremove ceph-vg-3 pvremove /dev/loop11 pvremove /dev/loop12 pvremove /dev/loop13 losetup -d /dev/loop11 losetup -d /dev/loop12 losetup -d /dev/loop13 rm -f /root/ceph/osd*.img
dmsetup ls
dmsetup remove ceph--vg--1-osd--lv--1 dmsetup remove ceph--vg--2-osd--lv--2 dmsetup remove ceph--vg--3-osd--lv--3
|
删除 SSH 密钥
这个好像也不用删。