0%

问题描述

42Team社团上线下载站,使用Nginx反向代理为用户提供服务。问题的现象是当用户下载文件超过1G大小时出现断开下载连接的情况导致下载失败。

问题分析

一开始以为是Flask的流传输出了问题,调试并跟踪代码后并没有发现问题,而且直接在本地代码调试下载大文件不会出现断开情况。那么开发环境与生产环境中只相差了中间有一层Nginx反向代理,那么初步问题定位到Nginx的反向代理配置上。

经过在网上进行搜索“反向代理下载大文件失败断开连接”等关键字后找到了一篇其他人写的博文,遇到过类似的问题。

发现可能是因为超时的原因导致,因为反向代理服务器和部署下载站服务的服务器之间的网络传输速度和磁盘性能非常好,所以他们之间传递1G以上的大文件仅仅有几秒的时间,而Nginx反向代理服务器将文件传输到用户端可能需要数分钟或数十分钟,由于这之间的时间差非常大,所以超过了Nginx的默认连接超时时间,导致此问题发生

问题解决

禁用缓存

禁用缓存,客户端的每次清求都转发到被代理服务器,做法是在代理服务器的Nginx配置里面添加:

1
2
3
proxy_pass http://172.17.8.88:5050/;
proxy_redirect default;
proxy_buffering off;

加大Nginx服务器与另一服务器之间的超时等待时间

1
2
keepalive_timeout 15;
send_timeout 3600;

Nginx反向代理导致大文件下载失败

基操

修改IE浏览器安全策略

默认的IE浏览器安全策略不允许访问任何不受信任的域,这让我打开百毒-下载Chrome浏览器的过程变得无比艰难。

关闭限制的方法是在服务器管理器中选择本地服务器。

Snipaste_2020-08-31_21-42-28-2020-08-31

打开一些功能

在Windows Server中为了保障系统运行的稳定性最大限度的关闭了不需要的功能。但是要把它作为一台使用的系统最好将他的实用性更改得好一些。

在服务器管理器中选择选择添加角色和功能,手动打开一些常见功能,比如WIFI、游戏图形API支持等。

功能名 描述
Direct Play 游戏图形支持API
Windows Search服务 Windows搜索索引
Windows Server备份 备份服务
媒体基础 包含Windows媒体文件格式之间转换
适用于 Linux 的 Windows 子系统 提供环境和服务在Windows中运行Linux shell及程序
无线LAN服务 开启对WLAN的支持

开启一些服务

声音服务:Windows AudioWindows Audio Endpoint Builder设置为自动。

Windows移动热点服务,如果需要开热点可以开启。

无线电管理服务

组策略设置

WIN键+R键,输入gpedit.msc,进入组策略设置。

1、计算机配置,Windows设置,安全设置,帐户策略,密码策略:“密码必须符合复杂性要求”,设置为”已禁用”。
解决问题:设置帐号密码,默认必须是字母、数字、特殊字符都必须有,否则会提示不符合条件。

2、计算机配置,Windows设置,安全设置,帐户策略,密码策略:“密码最短使用期限”,设置为”0”(无期限)。
解决问题:密码有有效期,快到期会提示修改密码。修改后密码永久有效。

3、计算机配置,Windows设置,安全设置,本地策略,安全选项,“无需按 Ctrl+Alt+Del”,设置为”已启用”。
解决问题:登录系统,需要先按Ctrl+Alt+Del,才能显示登录界面。修改后不再需要。

4、计算机配置,管理模板,系统,显示”关闭事件跟踪程序”,设置为”已禁用”。
解决问题:关机时,需要输入关机原因。设置后不再需要。

5、计算机配置,管理模板,系统,登录时不显示”管理你的服务器”页,设置为”已启用”。
解决问题:Administrators组下的用户每次登录,会自动启动server manager,设置该策略后,会不再自动启动。
另外一种设置方式:通过设置server manager,下次启动时不再自动启动。

6、最好是新建一个用户。也可以使用Administrator(内置管理员),但要启用批准模式,组策略,计算机配置,Windows设置,安全设置,本地策略,安全选项,“用于内置管理员帐户的管理员批准模式”,设置为”已启用”,重启后生效。
解决问题:Administrator也使用UAC,如果想要超级权限,该策略可不设置。

7、标准帐户类型的用户允许关机,重启
解决问题:标准帐户类型的用户,默认无法关机、重启,是没有这些按钮的,按如下设置可以解决该问题。
Computer Configuration > Windows Settings > Security Settings > Local Policies > User Rights Assignment > Shutdown the system
添加Users组即可。
工作站默认的组(指windows 10):Administrators, Backup Operators, Users.
服务器默认的组(指windows server 2019): Administrators, Backup Operators.

以上参考自互联网,由于找不到谁是第一个撰写该博文的网友,所以此处不添加引用来源,请谅解。

开启备份

默认情况下,Windows Server不启动系统备份,也不会创建系统还原点。如果像我一样Windows绝缘体经常遇到“蓝屏”的话导致系统无法启动等问题还真是很让人崩溃。所以很有必要开启Windows备份,在先前已经安装了Windows Server备份功能,所以搜索 Windows Server 备份应用,即可配置备份设置。

驱动问题

先用联想官方驱动助手过一边,之后会发现有两个驱动打不上,一个还是非常重要的板载驱动。(4网口千兆网卡可以免驱直接被识别,所以一开始的时候我将网线插到了这张卡上来上网23333)

板载有线网卡

正常情况下板载有线网卡并不能被驱动,在官网下载对应的驱动也无法进行安装,所以只能手动修改inf驱动信息来安装。
参考Windows Server 2019安装Intel I219-V I211网卡驱动

蓝牙驱动异常

在任务管理器中,可见一个未知设备。点击详情后提示与蓝牙有关。查看设备硬件ID为:BTH \ MS_BTHPAN,在Intel官网支持找到一篇文章,解决了此问题。

在英特尔® NUC8i3PN、NUC8v5PN、NUC8v7PN 上安装 Windows * Server 2019 时,使用硬件 ID BTH \ MS_BTHPAN 解决未知设备

Ceph块设备

块是一个字节序列(例如,一个512字节的一块数据),基于块的存储接口是最常见的存储数据方法,他们基于旋转媒体,类似于硬盘、CD、软盘、甚至传统的磁带。无处不在的块设备接口使得虚拟块设备成为与Ceph这样海量存储系统交互的理想之选。

Ceph块设备是瘦接口、大小可以调整且数据被条带化存储在Ceph集群内的多个OSD上。Ceph块设备均衡多个RADOS的能力,快照、复制和一致性,Ceph的RADOS块设备用内核模块或librbd库与各个OSD交互。

ceph-block-rados-2020-08-03

Ceph 块设备靠无限伸缩性提供了高性能,如向内核模块、或向 abbr:KVM (kernel virtual machines) (如 QEMU 、依赖 libvirt 和 QEMU 的 OpenStack 和 CloudStack 云计算系统都可与 Ceph 块设备集成)。可以用同一个集群同时运营 Ceph RADOS 网关、 CephFS 文件系统、和 Ceph 块设备。

块设备的基本操作

rbd命令可以用于创建、罗列、自检和删除块设备的映像。当然也可以对映像进行克隆、创建快照并支持回滚等。

创建一个块设备存储池

在管理节点上,用ceph命令创建一个Pool池。了解更多关于Pool池可以访问OSD与Pool池的常见操作及管理

ceph osd pool create rbd 64 64

成功创建一个Pool后使用rbd工具再对这个Pool池进行初始化用于RBD。

rbd pool init <pool-name>

此处将新创建的rbdPool池进行初始化

注意:在接下来使用rbd的命令时如果需要填写<pool-name>参数的地方为空没有填写,那么默认会查找Pool池名为rbd并使用它。

创建块设备用户(非必须)

如果不指定用户的话,使用rbd命令会默认使用admin管理员访问Ceph集群,admin的用户权限最大,不应该分配给其他机器。所以最好创建一个权限尽可能小的用户访问块设备池。

1
2
3
osd 'allow {access-spec} [{match-spec}] [network {network/prefix}]'

osd 'profile {name} [pool={pool-name} [namespace={namespace-name}]] [network {network/prefix}]'

如果要了解更多Ceph用户有关信息,可以访问阅读Ceph用户管理

创建块设备映像

如果想要将块设备添加到某一节点,你需要先在Pool中创建一个映像文件。

rbd create --size {megabytes} {pool-name}/{image-name}

例如,在rbd这个Pool池中创建一个名为42team-webnode.img,大小为20G的一个映像:

rbd create --size 20G --pool rbd --image 42team-webnode.img

罗列磁盘映像

要罗列rbdPool存储池中的全部映像,使用下面的命令:

rbd ls {poolname}

{poolname}如果不填写,则默认使用rbd存储池。

检索映像信息

使用下面的命令来检索某一个映像的信息:

rbd info {pool-name}/{image-name}

{poolname}如果不填写,则默认使用rbd存储池。

rbd info rbd/42team-webnode.img

返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@vm1 ~]# rbd info rbd/42team-webnode.img
rbd image '42team-webnode.img':
size 20 GiB in 5120 objects
order 22 (4 MiB objects)
snapshot_count: 0
id: 17382bc345839
block_name_prefix: rbd_data.17382bc345839
format: 2
features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
op_features:
flags:
create_timestamp: Mon Aug 3 11:03:56 2020
access_timestamp: Mon Aug 3 11:03:56 2020
modify_timestamp: Mon Aug 3 11:03:56 2020

调整块设备映像大小

Ceph块设备是瘦接口设备,只有真正写入了数据后才开始占据物理空间,直到限制到它最大的存储大小,他们的最大存储容量就是设置的--size选项的值。如果需要增加或减少Ceph块设备的存储最大尺寸,使用下面的命令:

缩小映像最大尺寸

如果要缩小块设备的映像最大存储尺寸,需要添加--allow-shrink选项,才允许缩小映像尺寸。

rbd resize -p rbd --image 42team-webnode.img -s 5G --allow-shrink

如果已使用的存储尺寸大于要缩减之后的尺寸,强行缩减块设备映像尺寸会导致数据丢失!

扩大映像最大尺寸

rbd resize -p rbd --image 42team-webnode.img -s 25G

删除块设备映像

你可以直接将块设备中的映像删除,或者先将他们移动到垃圾桶中,等待一段时间删除或者手动进行清理。

直接删除块设备映像

rbd rm {pool-name}/{image-name}

rbd rm 42team-webnode.img

{poolname}如果不填写,则默认使用rbd存储池。

延期删除映像

延期删除可以现将要删除的映像存放到垃圾池中,即便他有快照或者正被克隆的镜像引用者也可以被放入到垃圾桶池中,但是不能将他们从垃圾池中删掉。

你可以用 –expires-at 设置延期时间(默认为 now ),并且,它的延期时间没到的话是不能删除的,除非你用 –force 选项。

rbd trash mv {pool-name}/{image-name}

rbd trash mv rbd/42team-webnode.img

rbd trash mv restore-42team-webnode.img --expires-at "20200805"

之后可以通过rbd trash ls --long查看放入到垃圾池的映像有哪些,如果设立日期保护的话还可以看到保护到期的时间。

还原块设备映像

当你突然醒悟不该放弃某个映像时,你当然可以从垃圾池中将映像还原!但是前提时你将它放入到了垃圾池而不是直接删除掉他们。

rbd trash restore {pool-name}/{image-id}

在还原映像时需要使用image-id进行还原。可以使用rbd trash ls查看image映像id。

1
2
3
[root@vm1 ~]# rbd trash ls
17382bc345839 42team-webnode.img
[root@vm1 ~]#

rbd trash restore 17382bc345839 --image restore-42team-webnode.img

在还原的同时,还可以指定--image选项对垃圾池内的映像重命名。

彻底删除在垃圾池中的映像

rbd trash rm {pool-name}/{image-id}

使用rbd trash rm命令可以将在垃圾池中的映像彻底删除,如果你设置了延期时间–expires-at ,那么没到延期时间内直接删除是不可以的,除非使用 –force 选项强制删除。

拍摄镜像快照

快照是某映像在一个特定时间点的一份只读副本。Ceph块设备的一个高级功能是可以为映像创建快照来保留历史。Ceph也支持分层快照,这样可以更快速的的克隆一个映像(如VM映像)。Ceph的快照功能还支持rbd命令和多种高级接口,包括 QEMU 、 libvirt 、 OpenStack 和 CloudStack

因为RBD不关心文件系统,如果没有与map挂载着的计算机协调的话,快照就是crash-consistent的。所以,在拍摄快照前应该将这个映像的I/O操作暂停,如果这个映像还包含文件系统,在拍摄这个包含文件系统的映像前系统还必须处于一致性状态,否则就要用fsck来修复它了…

可以使用fsfreeze命令冻结I/O。对于虚拟机来说,qemu-guest-agent 可在创建快照时自动冻结文件系统。

ceph-snap-ins-2020-08-06

快速操作快照

接下来的过程演示了如何用 rbd 命令创建、罗列、和删除快照。

创建快照

rbd snap create命令创建快照,需要声明存储池名和映像名。

rbd snap create {pool-name}/{image-name}@{snap-name}

如为rbd/5G.img拍摄快照:

rbd snap create 5G.img@2008050810

罗列快照

要列出某一个映像的快照,需要指定存储池名和映像名。

rbd snap ls {pool-name}/{image-name}

例如:

rbd snap ls 5G.img

1
2
3
[root@vm1 ~]# rbd snap ls 5G.img
SNAPID NAME SIZE PROTECTED TIMESTAMP
4 2008050810 5 GiB Wed Aug 5 08:10:55 2020

回滚快照

要用rbd回滚到某一快照,使用rbd snap rollback命令。回滚快照时要求该映像不能处于map状态!不应该有任何资源占用这个映像。

rbd snap rollback {pool-name}/{image-name}@{snap-name}

例如:

rbd snap rollback 5G.img@2008050810

把映像回滚到一快照的意思是,用快照中的数据覆盖映像的当前版本,此过程花费的时间随映像尺寸增长。从快照克隆要快于回滚到某快照。这也是回到先前状态的首选方法。

删除快照

删除某映像的一个快照

使用rbd snap rm命令删除某一映像的快照:

rbd snap rm rbd/5G.img@2008050810

删除后可以再查看一下当前快照,检查是否成功删除:

rbd snap ls rbd/5G.img

删除某映像的全部快照

当你要删除一个映像的全部快照时,使用rbd snap purge命令:

rbd snap purge {pool-name}/{image-name}

rbd snap purge rbd/5G.img

克隆快照映像

可以克隆一个映像,在原有映像基础之上建立新的分支。不过需要了解分层的概念,想要克隆一个快照必须先创建快照,并且将其保护,之后才能克隆快照。

了解分层

ceph-clone-2020-08-06

Ceph 块设备的分层是个简单的过程。你必须有个映像、必须为它创建快照、必须保护快照,执行过这些步骤后,你才能克隆快照。

克隆出的映像包含到父快照的饮用、存储池ID、映像ID和快照ID。包含存储池ID意味着你可以把存储池内的快照克隆到别的存储池中。

分层可以应用于以下方面:

  • 映像模版:块设备分层的一个常见用法是创建一个主映像及其快照,并作为模版以供克隆。例如管理员会创建一个Linux发行版的映像,之后周期性的升级维护(比如执行了dnf update操作之后等)。等映像文件稳定可用后,用户可以克隆任意快照。
  • 拓展模板:更高级的用法包括拓展映像模板,让它包含比基础映像更多的信息。例如,首先可以克隆一个基础映像,然后再此基础之上安装新的软件包(如数据库、博客平台、内容管理系统等),之后在此拓展上再次创建快照,拍下的快照可以像基础映像一样更新。
  • 模版存储池:块设备分层的一种用法是创建一个存储池,其中包含作为模版的主映像和那些模版快照。然后把只读权限分给用户,这样他们就可以克隆快照了,而无需分配此存储池内的写和执行权限。
  • 映像迁移/恢复:块设备分层的一种用法是把以存储池内的数据迁移或恢复到另一个存储池。

保护快照

克隆的映像要访问父快照。如果那个用户不小心删除掉了父快照,那么所有依赖这个父快照的克隆映像都会损坏。为了防止数据丢失,必须先保护快照,然后再当作父快照进行克隆。

rbd snap protect {pool-name}/{image-name}@{snapshot-name}

如下:

rbd snap protect 5G.img@202008051308

之后查看该映像的所有快照:

rbd snap ls 5G.img

1
2
3
4
5
[root@vm1 ~]# rbd snap ls 5G.img
SNAPID NAME SIZE PROTECTED TIMESTAMP
10 202008051308 5 GiB yes Wed Aug 5 13:08:03 2020
11 202008051309 5 GiB Wed Aug 5 13:08:05 2020
12 2020080513010 5 GiB Wed Aug 5 13:08:10 2020

可以看到刚刚被保护的快照,在此处有了标记,接下来尝试能否删除这个快照:

rbd snap rm 5G.img@202008051308

ceph-snap-protect-rm-2020-08-06

结果显而易见,当快照被保护的情况下是不允许被删除的。这样我们就可以在这个快照的基础上进行克隆全新的映像!

克隆映像快照

要克隆快照,你得指定父存储池、映像、和快照,还有子存储池和映像名。克隆前必须先保护快照,否则不允许克隆。

rbd clone {pool-name}/{parent-image}@{snap-name} {pool-name}/{child-image-name}

例如克隆我们刚刚保护的那个快照,并且把克隆后的映像叫做5G_new.img:

rbd clone 5G.img@202008051308 rbd/5G_new.img

你可以把一存储池中的映像的快照克隆到另一个存储池。例如,你可以把一存储池中的只读映像及快照当作模版进行维护,之后(比如映像调试完毕后)可以将其克隆到另一个存储池中进行发布使用。

现在,可以查看以下刚刚克隆的新映像的信息:

rbd ls --long

rbd info 5G_new.img

ceph-clone-ls-2020-08-06
ceph-clone-rbd-info-2020-08-06

罗列快照的后代

rbd children {pool-name}/{image-name}[@{snapshot-name}]

例如:

rbd children rbd/5G.img

取消快照保护

删除快照前,必须先需要快照保护。另外如果有其他的子映像使用着这个快照,那么你不能删除这个快照。除非你将引用这个快照的子映像执行拍平的操作。

rbd snap unprotect {pool-name}/{image-name}@{snapshot-name}

无法取消保护一个被克隆的子映像使用的快照,除非你将克隆后的映像拍平。
ceph-snap-unprotect-1-2020-08-06

拍平克隆的映像

克隆的映像一直保留着对父快照的引用,所以你无法取消保护一个被引用的父快照。如果你要从子克隆删除到父快照的这些引用,你可以把引用的父快照信息完整的复制到子克隆中,也就是拍平它。拍平克隆品的时间因快照尺寸而不同,要删除快照或者取消保护快照,必须将子映像拍平。

rbd flatten {pool-name}/{image-name}

例如:

rbd flatten rbd/5G_new.img

拍平子映像后,就不会再引用父快照的信息了。此时,你可以将父快照解除保护并删除。

从集群中删除OSD节点

使用cephadm部署的Ceph集群,再尝试从集群中删除OSD节点的时候遇到了各种问题……

既然自动化工具目前不太完善(或者说在文档里目前还没看到使用cephadm删除OSD节点的方法),那么就手动删除吧!记录一次使用cephadm搭建的集群如何删除OSD节点。当然使用其他方式部署的OSD要删除的话也是大同小异的。

ceph版本:ceph version 15.2.4 (7447c15c6ff58d7fce91843b705a268a1917325c) octopus (stable)

查看集群OSD状态

先查看集群内OSD的状态,并找到要删除的OSD节点。现在准备删除osd.4osd.5这两个节点,他们都在vm2这台主机上。

ceph osd tree

ceph-rm-osd-tree-2020-07-31

ceph osd dump

ceph-rm-osd-dump-2020-07-31

可以留意一下ID,之后便于确认ID所对应的块设备名(如:/dev/sdx或/dev/nvmex)

删除OSD节点节点

使用cephadm删除OSD节点

目前使用cephadm删除OSD节点后也需要手动的释放磁盘占用

ceph orch osd rm <svc_id>... [--replace] [--force]

要删除osd.4osd.5节点则执行:ceph orch osd rm 4 5

删除的过程需要一段时间,会重新分配集群内的PG,删除CRUSH图节点信息,删除这两个OSD所对应的用户和密钥环。

查看自动删除状态进度ceph orch osd rm status,如果长时间无响应或者依旧没有删除,可以开始尝试手动删除OSD节点

手动删除OSD节点

移除daemon守护进程

接下来的操作请确保你对整个集群拥有admin权限并且对要删除OSD节点的主机有root权限。

登录到拥有Ceph集群admin权限的主机,执行如下命令:

ceph orch daemon rm osd.4 osd.5 --force

返回结果如下,已经移除他们容器的守护进程:

1
2
Removed osd.4 from host 'vm2'
Removed osd.5 from host 'vm2'

此时查看集群中这两个OSD的状态:

要删除osd.4osd.5这两个节点的状态变成了DOWN。接下来就可以从crush表中将他们移除。

ceph-rm-osd-tree-2-2020-07-31

如果还没有使用cephadm管理集群,此处你可以登录到vm2这台主机中手动的将他们的systemd守护进程disable

1
2
systemctl disable --now  ceph-osd@4
systemctl disable --now ceph-osd@5

删除CRUSH图中所对应的OSD节点

删除CRUSH图中的OSD节点信息

ceph osd crush remove osd.4

ceph osd crush remove osd.5

执行成功返回结果:

1
2
removed item id 4 name 'osd.4' from crush map
removed item id 5 name 'osd.5' from crush map

此时再次手动检查集群内的OSD节点中是否还包含osd.4osd.5

已经从CRUSH图标中删除,此处已经看不到这两个OSD节点。

ceph-rm-osd-tree-3-2020-07-31

删除osd节点

ceph osd rm osd.4 osd.5

返回执行成功结果:removed osd.4, osd.5

ceph-osd-rm-2020-07-31

删除osd用户

ceph auth ls | grep ^osd -A4

ceph-auth-ls-2020-07-31

发现Ceph的OSD用户未被删除,残留在此处(会影响下一次添加OSD时,导致密钥环不匹配的错误)。执行如下命令删除:

ceph auth rm osd.4

ceph auth rm osd.5

删除OSD配置(如果有的话)

如果额外对OSD进行了额外配置的话需要手动删除当时的配置信息。登录到这台被删除OSD节点的主机上,修改配置文件:vim /etc/ceph/ceph.conf,将对该OSD节点额外配置的信息删除。

之后把更新过的ceph.conf文件要拷贝到其他集群主机的/etc/ceph/目录下。

解除Ceph对磁盘的占用

之后的操作都需要在移除OSD节点的主机(vm2)上通过root用户特权执行操作。

当删除了OSD之后,由于先前的配置,Ceph仍然对磁盘进行占用。需要移除这块OSD磁盘的DM状态,并之后对其格式化,这样才完整的手动移除一个OSD节点(磁盘)。

查询磁盘DM状态并移除编码

dmsetup status

dmset-status-2020-07-31

注意在一开始要留意的哪个ID,在这里用来识别要删除哪个磁盘的DM标记。

dmsetup remove ceph--14c75e65--a33e--459a--8bc7--c95add15d8a3-osd--block--d2af5a38--54b9--4112--9bbf--8ea313c673f1

dmsetup remove ceph--6ceb7c60--8b90--44fc--b159--34bd3d8c8e0f-osd--block--5f1d52fa--e50c--4915--b059--f672684ce571

执行完上面的命令后,再检查一下DM状态,发现已经成功被删除DM标记:

dmset-status-2-2020-07-31

wipefs格式化文件系统

在使用wipefs工具清除文件系统前,要找到所对应的块设备名称。

执行lsblk -f命令:

下面的图片中可以看到,nvme0n2nvme0n3这两个块设备已经没有了像nvme0n4下方的ID标记,所以可以判定nvme0n2nvme0n3和两块磁盘是我们移除的OSD节点所使用的磁盘。

fdisk-f-2020-07-31

接下来对nvme0n2nvme0n3两个块设备格式他们的文件系统,执行命令:

wipefs -a /dev/nvme0n2 /dev/nvme0n3

wipefs-2020-07-31

到此,完成的将OSD节点从集群中移除。你可以使用lsblk工具或稍后一段时间后在拥有集群admin权限的主机上执行ceph orch device ls命令查看这两个OSD节点所使用的磁盘是否是可以用的状态了。现在你可以将这两个磁盘取出或者在这两块磁盘上重新部署OSD节点…

fdisk-f-clean-2020-07-31

ceph-orch-device-ls-2020-07-31

现在有一台服务器想作为NTP服务器,3台客户端想作为NTP服务器的客户端,保证客户端机器上的时间与服务器端保持同步。清单如下:

类型 IP地址
server 192.168.1.30
client 192.168.1.[31:33]

部署服务端chrony

ssh登录到server机器后放行防火墙、安装chrony服务、配置chrony服务器端。

放行防火墙端口

Centos8使用firewalld服务对防火墙进行管理。放行ntp服务(123/udp)

firewall-cmd --add-service=ntp --permanent && firewall-cmd --reload

安装chrony服务

默认情况下Centos8中已经安装好chrony的软件包。如果发现没有安装,使用下面的命令安装即可:

sudo dnf install chrony -y

配置chrony服务端

sudo vim /etc/chrony.conf

不习惯vi/vim编辑器的小伙伴可以替换为自己喜爱的编辑器如nano

把原有自带的上游NTP服务器地址删除。之后手动配置国内阿里云的NTP服务器地址。

1
2
3
4
5
server time1.aliyun.com iburst     #添加上游NTP服务器
server time2.aliyun.com iburst
server time3.aliyun.com iburst

allow 192.168.1.0/24 #允许IP端内的客户端通过这台服务器获取时间

配置无误后,重启chrony服务,并配置开机自启动:

systemctl restart chronyd.service && systemctl enable chronyd.service --now

使用ss -tlunp | grep chrony命令检查,发现chrony服务已经在监听123/udp端口,服务端配置成功。

配置chrony客户端

配置chrony客户端需要将三台客户端都安装chrony并且配置好他们的配置文件。如果说客户端数量较少可以手动配置,当数量为成百上千台机器时使用Ansible自动化配置是一个不错的选择。所以在这里有两种配置方法供大家参考,一种是普通手动配置,一种是使用Ansible-Galaxy角色配置。

手动配置chrony客户端

配置客户端同样的需要放行防火墙、安装chrony软件包、配置chrony客户端。

安装chrony软件包

dnf install chrony -y

修改客户端chrony配置文件

sudo vim /etc/chrony.conf

不习惯vi/vim编辑器的小伙伴可以替换为自己喜爱的编辑器如nano

1
2
3
4
5
6
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
# pool 2.centos.pool.ntp.org iburst

# 把原有的NTP服务器地址注释掉或者直接删除。添加下面刚刚搭建好的NTP服务器地址。
server 192.168.1.30 iburst

注释默认的NTP服务器地址,之后添加上我们自己刚刚搭建好的NTP服务器地址即可完成chrony客户端的手动配置。

重启chrony客户端服务

重启chrony服务,并配置开机自启动:

systemctl restart chronyd.service && systemctl enable chronyd.service --now

查看同步状态

chronyc sources -v

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@vm1 ~]# chronyc sources -v
210 Number of sources = 1

.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current synced, '+' = combined , '-' = not combined,
| / '?' = unreachable, 'x' = time may be in error, '~' = time too variable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) -. | xxxx = adjusted offset,
|| Log2(Polling interval) --. | | yyyy = measured offset,
|| \ | | zzzz = estimated error.
|| | | \
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 192.168.1.30 3 6 17 16 +3424ns[ +110us] +/- 31ms

可以看到,输出结果里已经有我们搭建好的NTP服务器了。并且在服务器地址前有^*标记,证明已经正确同步时间。

至此一台客户端的chrony已经搭建完毕。剩下的两台同理部署即可。

使用Ansible自动化配置chrony客户端

相关Ansible基础默认你已经了解,不再赘述。如果你不了解Ansible请从Ansible文档入门学习。

mkdir Chrony && cd Chrony

配置ansible.cfg

vim ansible.cfg

1
2
3
4
5
6
7
8
9
10
[defaults]
inventory = inventory
remote_user = root
roles_path=./roles:/usr/share/ansible/roles:/etc/ansible/roles

[privilege_escalation]
become=True
become_method=sudo
beome_user=root
become_ask_pass=False

配置主机清单

vim inventory

1
2
[client]
192.168.1.3[1:3]

配置ssh免密登陆客户端

配置SSH免密登录

下载chrony角色

ansible-galaxy install ericsysmin.chrony

编写Playbok

vim playbook.yml

1
2
3
4
5
6
7
8
---
- name: Config Chrony Client
hosts: client
roles:
- role: ericsysmin.chrony
chrony_config_server:
- 192.168.1.30
...

执行结果如下,全部OK即为成功:

1
2
3
4
PLAY RECAP **************************
192.168.1.31 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.1.32 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
192.168.1.33 : ok=7 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

之后可以登录几台机器进行手动验证,查看是否已经以NTP服务器保持同步。

搭建Ceph集群

部署前准备

机器清单

host ip地址 描述
centos8 192.168.1.30(外网)/10.10.1.10(内网) 为其他机器运行Ansible脚本(部署)、Ceph客户端
vm1 192.168.1.31/10.10.1.11 Ceph OSD节点
vm2 192.168.1.32/10.10.1.12 Ceph OSD节点
vm3 192.168.1.33/10.10.1.13 Ceph OSD节点

hosts文件

把机器清单编写为hosts文件。

vim /etc/hosts

1
2
3
4
192.168.1.30    centos8
192.168.1.31 vm1
192.168.1.32 vm2
192.168.1.33 vm3

防火墙放行

服务名 端口号 描述
Monitor监视器 6789/tcp 与Ceph集群通信
Manager 7000/tcp Ceph管理面板
8003/tcp Ceph Restful API管理 with HTTPS
9283/tcp Prometheus插件通信接口
OSD 6800-7300/tcp 每个OSD在这个范围内使用3个端口,一个用来与客户端和监视器进行通信,一个用来与集群中其他的OSD进行通信或者在公网上传输数据,最后一个用来在集群中发送心跳包
RADOS 网关 7480/tcp 默认RADOS网管端口为7480,你可以修改为80/443(如果使用TLS)

如果你使用firewalld来管理你的防火墙,可以执行下面的命令放行端口:

firewall-cmd --add-service=ceph --add-service=ceph-mon --permanent && firewall-cmd --reload

创建部署Ceph的用户

ceph-deploy 工具必须以普通用户登录,且此用户拥有无密码使用 sudo 的权限,因为它需要安装软件及配置文件,中途不能输入密码。

较新版的 ceph-deploy 支持用 --username 选项提供可无密码使用 sudo 的用户名(包括 root ,虽然不建议这样做)。要用 ceph-deploy --username {username} 命令,指定的用户必须能够通过无密码 SSH 连接到 Ceph 节点,因为 ceph-deploy 不支持中途输入密码。

从 Infernalis 版起,用户名 “ceph” 保留给了 Ceph 守护进程。如果 Ceph 节点上已经有了 “ceph” 用户,升级前必须先删掉这个用户。

在各个Ceph节点创建新用户

1
2
3
ssh username@ceph-server
sudo useradd -d /home/{username} -m {username}
echo "password" | passwd {username} --stdin

配置sudo权限

1
2
echo "{username} ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/{username}
sudo chmod 0440 /etc/sudoers.d/{username}

配置ssh-key免密登录

在centos8机器中创建密钥对,但是不要用sudo或root用户。口令为空。

ssh-keygen

全部默认配置,直接回车生成key。

现在将centos8机器的ssh公钥发送到vm[1:3]的机器上。

把公钥拷贝到各 Ceph 节点,把下列命令中的 {username} 替换成前面创建部署 Ceph 的用户里的用户名。

1
2
3
4
for i in 1 2 3
do
ssh-copy-id {username}@vm$i
done

如果使用ceph-deploy工具部署集群推荐使用以下方式配置免密登录

修改 ceph-deploy 管理节点上的 ~/.ssh/config 文件,这样 ceph-deploy 就能用你所建的用户名登录 Ceph 节点了,无需每次执行 ceph-deploy 都指定 --username {username} 。这样做同时也简化了 ssh 和 scp 的用法。把 {username} 替换成你创建的用户名。注意要将~/.ssh/config 文件权限修改为0600。

1
2
3
4
5
6
7
8
9
Host node1
Hostname node1
User {username}
Host node2
Hostname node2
User {username}
Host node3
Hostname node3
User {username}

配置NTP

集群之间机器的时间应该保持同步,需要使用NTP服务同步时间。

如果不了解NTP服务及搭建,请参考搭建NTP服务和配置客户端

配置SELinux

在 CentOS 和 RHEL 上, SELinux 默认开启为 Enforcing 。为简化安装,我们建议把 SELinux 设置为 Permissive 或者完全禁用,也就是在加固系统配置前先确保集群的安装、配置没问题。用下列命令把 SELinux 设置为 Permissive

sudo setenforce 0

要使 SELinux 配置永久生效,需修改其配置文件/etc/selinux/config

使用Ansible部署Ceph集群

使用centos8作为Ansible部署节点,为其他机器安装服务。

使用ceph-ansible来部署集群

在centos8机器上执行 yum install ceph-ansible -y

复制ceph-ansible目录到家目录下 cp -r /usr/share/ceph-ansible /home/student/ && cd /home/student/ceph-ansible

配置ansible.cfg vim ansible.cfg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[defaults]
inventory = ./inventory
# 因为该Ansible脚本目前比较老,脚本中使用的语法在新版本的Ansible上运行会有警告提示,提示部分语法即将被弃用。但是目前还可以继续使用,暂时忽略警告即可
deprecation_warnings = false
ansible_managed = Please do not change this file directly since it is managed by Ansible and will be overwritten
action_plugins = plugins/actions
roles_path = ./roles
log_path = /tmp/ansible.log

# Disable them in the context of https://review.openstack.org/#/c/469644
retry_files_enabled = False

# This is the default SSH timeout to use on connection attempts
# CI slaves are slow so by setting a higher value we can avoid the following error:
# Timeout (12s) waiting for privilege escalation prompt:
timeout = 30

[ssh_connection]
# see: https://github.com/ansible/ansible/issues/11536
control_path = %(directory)s/%%h-%%r-%%p

配置inventory vim inventory

1
2
3
4
5
6
7
8
[mons]
server[c:e]

[mgrs]
server[c:e]

[osds]
server[c:e]

测试一下连通性 ansible all -m ping,返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
vm3 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
vm2 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}
vm1 | SUCCESS => {
"changed": false,
"failed": false,
"ping": "pong"
}

配置group_vars变量:

配置 all.yml group_vars变量:

拷贝all.yml变量 cp group_vars/all.yml.sample group_vars/all.yml

编辑变量文件 vim group_vars/all.yml

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
fetch_directory: ~/ceph-ansible-keys

ntp_service_enabled: true
ceph_origin: repository

ceph_repository: rhcs

ceph_rhcs_version: "3"
ceph_repository_type: "cdn"

rbd_cache: "true"
rbd_cache_writethrough_until_flush: "false"

rbd_client_directories: false # this will create rbd_client_log_path and rbd_client_admin_socket_path directories with proper permissions

monitor_interface: eth0

journal_size: 1024 # OSD journal size in MB
public_network: 172.25.250.0/24
cluster_network: "{{ public_network }}"

ceph_conf_overrides:
global:
mon_osd_allow_primary_affinity: 1
mon_clock_drift_allowed: 0.5
osd_pool_default_size: 2
osd_pool_default_min_size: 1
mon_pg_warn_min_per_osd: 0
mon_pg_warn_max_per_osd: 0
mon_pg_warn_max_object_skew: 0
client:
rbd_default_features: 1
配置 osds.yml group_vars变量:

在这里配置OSD存储相关设置

cp group_vars/osds.yml.sample group_vars/osds.yml

先来查看server[c:e]中空闲磁盘的名称,发现在这三台机器中都有/dev/vd[b:d]三块21.5G空闲磁盘未被使用。所以在配置OSD时使用这三台机器的/dev/vd[b:d]空闲磁盘作为OSD存储空间。

ssh ceph@vm1

sudo fdisk -l

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Disk /dev/vdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/vdc: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/vdd: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

vim group_vars/osds.yml

1
2
3
4
5
6
7
8
copy_admin_key: true

devices:
- /dev/vdb
- /dev/vdc
- /dev/vdd

osd_scenario: "collocated"

配置site.yml Playbook

cp site.yml.sample site.yml

运行Playbook开始部署

请确保当前目录在ceph-ansible目录下。

执行 ansible-playbook site.yml 开始部署Ceph基础集群。

等待一段时间后Ansible返回执行结束结果,没有机器存在failed则表明配置成功。

1
2
3
4
PLAY RECAP ******************************
vm1 : ok=203 changed=32 unreachable=0 failed=0
vm2 : ok=185 changed=26 unreachable=0 failed=0
vm3 : ok=187 changed=27 unreachable=0 failed=0

之后可以验证部署结果

部署Ceph客户端

如果要控制Ceph集群,现在只能通过在部署了Ceph集群节点上区管理集群。注意,我们最开始是从centos8上搭建的,那么现在也想要在centos8上部署Ceph客户端以此能够在centos8上就可以控制整个Ceph集群。

复制group_vars变量 cp group_vars/clients.yml.sample group_vars/clients.yml

编辑复制好的clients.yml变量,开启copy_admin_key即可:

1
2
---
copy_admin_key: true

编辑inventory主机清单文件,在其中加入clients项。

vim inventory

1
2
3
4
5
6
7
8
9
10
server[c:e]

[mgrs]
server[c:e]

[osds]
server[c:e]

[clients]
centos8

运行Playbook:

ansible-playbook site.yml --limit=clients

仅限制运行主机清单中clients组即可!节省时间。

如果一切部署顺利,Playbook执行结束后会在结果处返回failed=0。

现在切换到centos8上的ceph用户,尝试执行ceph -s命令,没有异常的情况下可以正常读取到Ceph集群的信息了。我们没有在centos8上配置OSD或者MON,仅仅是把它作为控制Ceph的客户端,目前centos8具有admin的权限。

验证部署结果

现在ssh登陆vm1这台机器上,接下来执行ceph的相关命令来检测刚刚的配置详情。

ssh ceph@vm1

ceph -s查看集群概况及状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ceph@vm1 ~]$ ceph -s
cluster:
id: ca5c8e66-e427-4adb-86c1-83b0eb5983cb
health: HEALTH_OK

services:
mon: 3 daemons, quorum vm1,vm2,vm3
mgr: vm2(active), standbys: vm1, vm3
osd: 9 osds: 9 up, 9 in

data:
pools: 0 pools, 0 pgs
objects: 0 objects, 0 bytes
usage: 966 MB used, 169 GB / 170 GB avail
pgs:

如果配置成功,此时执行 ceph -s 命令后。可以看到health: HEALTH_OK字样,这表明集群现在是健康的状态。

输出结果的services中可以看到osd: 9 osds: 9 up, 9 in,表明这三台机器一共9个OSD都在正常的运行着。

输出结果data中包含usage: 966 MB used, 169 GB / 170 GB avail,可以看得到我们一共有170G的存储空间,目前剩余169GB空间可用,已经使用966MB空间。

如果此时停止vm1这台机器上的ceph-mon.target服务,会发现集群状态变成了HEALTH_WARN状态。重启ceph-mon.target服务后不久集群状态又会恢复。

刚刚搭建好了Ceph OSD集群,如果停止掉一个OSD进程看看有什么效果?

在vm1上使用ceph osd tree查看vm1上osd信息

ceph-osd-tree-1

发现在vm1上运行3个osd进程,分别是osd.0,osd.3,osd.8 。现在我们人为干预宕掉vm1上的osd.3之后看看集群有什么反应。

sudo systemctl stop ceph-osd@8.service

ceph-osd-tree-down-2020-07-26

ceph-s-osd-down-1-2020-07-26

恢复osd.8运行 sudo systemctl start ceph-osd@8.service

使用ceph-deploy搭建集群

使用ceph-deploy搭建集群前,请确保已经完成准备工作,并且创建了一个Ceph集群用户

安装ceph-deploy

注意:如果是在Centos8上,要开启epel源。这里是用阿里的镜像源加速。

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

yum install ceph-deploy

配置Ceph国内源

vim /etc/yum.repos.d/ceph.repo

1
2
3
4
5
6
7
[ceph]
name=Ceph packages for $basearch
baseurl=http://mirrors.aliyun.com/ceph/rpm-octopus/el8/$basearch
enabled=1
gpgcheck=1
type=rpm-md
gpgkey=https://download.ceph.com/keys/release.asc

注意:当使用ceph-deploy install的时候,务必这样用:ceph-deploy install –repo-url http://mirrors.aliyun.com/ceph/rpm-octopus/el8/ ceph-deploy install centos8 vm1 vm2 vm3(官方的方法是:ceph-deploy install admin-node node1 node2 node3)因为这个ceph-deploy在安装过程中会自动帮你修改repo,所以需要用–repo-url来拒绝这个改动,我安装的是jewel发行版,可根据实际需要修改为最新的

查看安装的Ceph版本

ceph -v

1
2
[ceph@vm1 ~]$ ceph -v
ceph version 12.2.1-40.el7cp (c6d85fd953226c9e8168c9abe81f499d66cc2716) luminous (stable)

使用Cephadm部署集群

Cephadm通过在单个主机上的引导,再拓展其他的主机加入集群,部署所欲要的服务来达到创建一个新的Ceph集群。

cephadm使用容器的方式部署Ceph集群,所以需要额外准备以下要求与环境:

  • systemd
  • Podman或Docker容器支持
  • 时间同步(NTP)
  • 用于供应存储设备的LVM2

安装Cephadm

cephadm可以引导一个全新的集群,控制容器化下的Ceph集群,以及调试Ceph守护程序。

如果是RHEL系系统使用yum或dnf即可安装cephadm:

dnf install -y cephadm

引导部署一个全新的集群

此时,需要知道Ceph集群中提供第一个监视器mon的服务器IP地址。通常来说这是第一台的主机IP,如果有多个网络和接口,应该选择一个确保能连接到所有集群内主机的一个网络接口。

引导集群

mkdir -p /etc/ceph

cephadm bootstrap --mon-ip *<mon-ip>*

执行这条命令后会执行如下操作:

  1. 为本地集群创建监视器和管理器的守护进程
  2. 为集群生成一个新的SSH Key文件并且在/root/.ssh/authorized_keys文件中添加一个root认证用户
  3. 生成一个与新集群通信的最小化配置文件/etc/ceph/ceph.conf
  4. 写入Ceph用户认证用户client.admin的密钥环到/etc/ceph/ceph.client.admin.keyring
  5. 将公钥副本写入/etc/ceph/ceph.pub

如上,执行引导命令:

cephadm bootstrap --mon-ip 192.168.1.30

完成部署Ceph容器后,会生成如下信息。其中包括了Dashboard的登录地址以及随机生成的用户信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
INFO:cephadm:Ceph Dashboard is now available at:

URL: https://centos8:8443/
User: admin
Password: g1ohoef3t9

INFO:cephadm:You can access the Ceph CLI with:

sudo /usr/sbin/cephadm shell --fsid c50990c4-d1b9-11ea-9884-000c29c91658 -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集群建立完成,接下来会添加其他机器节点并分别部署Ceph任务 。

使用 Ceph 命令行

Cephadm并不会在主机上安装任何Ceph软件包,因为它会使用容器管理工具创建容器,将Ceph部署在容器中。那么如果在机器上想要访问Ceph容器并执行Ceph命令的话有如下几种方式可以实现:

  • cephadm shell命令可以在安装了Ceph的容器中启动一个shell。默认情况下,如果在/etc/ceph目录下找到配置文件和密钥环文件,他们就会被传入到Ceph容器环境中,这样可以使用Ceph shell的功能。注意:如果在cephadm shell在部署了MON节点的机器上安装,那么它会使用Ceph MON容器内的配置文件来代替默认默认配置文件。
    cephadm shell

  • 创建alias别名:alias ceph='cephadm shell -- ceph'
    echo "alias ceph='cephadm shell -- ceph'" >> /etc/profile.d/colorls.sh

    source /etc/profile.d/colorls.sh

现在可以直接使用ceph命令进行操作:

ceph -v

1
2
3
4
INFO:cephadm:Inferring fsid c50990c4-d1b9-11ea-9884-000c29c91658
INFO:cephadm:Inferring config /var/lib/ceph/c50990c4-d1b9-11ea-9884-000c29c91658/mon.centos8/config
INFO:cephadm:Using recent ceph image docker.io/ceph/ceph:v15
ceph version 15.2.4 (7447c15c6ff58d7fce91843b705a268a1917325c) octopus (stable)

确认ceph命令可以连接到集群并且可以查看他们的状态:

ceph status

将主机添加到集群

添加主机到集群中需要两步:

  1. 在新主机的root用户的authorized_keys文件中添加添加SSH公钥。

    ssh-copy-id -f -i /etc/ceph/ceph.pub root@vm1

    ssh-copy-id -f -i /etc/ceph/ceph.pub root@vm2

    ssh-copy-id -f -i /etc/ceph/ceph.pub root@vm3

  2. 告知Ceph集群添加新节点主机:

    ceph orch host add vm1

    ceph orch host add vm2

    ceph orch host add vm3

1
2
3
4
5
[root@centos8 ~]# ceph orch host add vm3
INFO:cephadm:Inferring fsid c50990c4-d1b9-11ea-9884-000c29c91658
INFO:cephadm:Inferring config /var/lib/ceph/c50990c4-d1b9-11ea-9884-000c29c91658/mon.centos8/config
INFO:cephadm:Using recent ceph image docker.io/ceph/ceph:v15
Added host 'vm3'

添加MON监控节点

一个Ceph集群应该有1、3、5奇数个MON监控节点(投票选举)分布在不同的主机上。如果集群中有5个或以上的主机节点,推荐部署5个MON监控节点。

当指定给Ceph告知MON监视器使用哪个IP子网时,那么在添加新的集群MON节点时会自动使用该子网自动部署。在默认情况下,Ceph假定其他监视器的子网与集群内第一台监视器MON节点的IP在同一个子网下。

如果Ceph的mon监视器在单个子网中,cephadm会在添加节点时默认自动的在集群中最多部署5个MON节点,不需要人工干预。

  • 如果你指定MON监视器使用的子网,那么可以执行下面的命令配置:

    ceph config set mon public_network 192.168.1.0/24

    之后添加的MON节点会自动的在该子网内工作。

  • 调整默认的MON监视器数量(默认为5个):

    ceph orch apply mon 3

  • 指定在一组主机桑拿部署Ceph的mon监视器:

    ceph orch apply mon *<host1,host2,host3,...>*

    ceph orch apply mon vm1,vm2,vm3

    确保此处mon部署节点中包括了引导节点(本机节点)

  • 罗列当前集群内的全部主机

    ceph orch host ls

    1
    2
    3
    4
    HOST  ADDR  LABELS  STATUS
    vm1 vm1
    vm2 vm2
    vm3 vm3
  • 你可以为某个主机这只标签进行标记,比如在此处就可以编辑合适的标签给刚刚添加的那三台主机。

    1
    2
    orch host label add <hostname> <label>
    orch host label rm <hostname> <label>

    ceph orch host label add vm1 mon

    ceph orch host label add vm1 cephadm

    添加标签后再重新罗列集群内主机节点:

    ceph orch host ls

    1
    2
    3
    4
    HOST  ADDR  LABELS       STATUS
    vm1 vm1 mon cephadm
    vm2 vm2 mon
    vm3 vm3 mon

添加OSD节点

显示当前主机集群内主机可用的存储设备列表,添加主机到节点中请参考将主机添加到集群

ceph orch device ls

在我当亲添加的三台主机中,存储设备列表如下,其中包含了可以用作OSD部署的设备以及他们的容量等基本信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
HOST  PATH          TYPE   SIZE  DEVICE                                     AVAIL  REJECT REASONS
vm1 /dev/nvme0n2 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm1 /dev/nvme0n3 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm1 /dev/nvme0n4 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm1 /dev/nvme0n5 ssd 10.0G VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm1 /dev/nvme0n1 ssd 20.0G VMware Virtual NVMe Disk_VMWare NVME_0000 False LVM detected, Insufficient space (<5GB) on vgs, locked
vm2 /dev/nvme0n2 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm2 /dev/nvme0n3 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm2 /dev/nvme0n4 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm2 /dev/nvme0n1 ssd 20.0G VMware Virtual NVMe Disk_VMWare NVME_0000 False Insufficient space (<5GB) on vgs, locked, LVM detected
vm3 /dev/nvme0n2 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm3 /dev/nvme0n3 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm3 /dev/nvme0n4 ssd 5120M VMware Virtual NVMe Disk_VMWare NVME_0000 True
vm3 /dev/nvme0n1 ssd 20.0G VMware Virtual NVMe Disk_VMWare NVME_0000 False Insufficient space (<5GB) on vgs, locked, LVM detected

如果满足以下所有条件,则认为存储设备可以部署OSD:

  • 设备必须没有分区。
  • 设备不得具有任何LVM状态。
  • 不得安装设备。
  • 该设备不得包含文件系统。
  • 该设备不得包含Ceph BlueStore OSD。
  • 设备必须大于5GB

部署OSD节点

  • 自动发现可用的存储设备:

    ceph orch apply osd --all-available-devices

    不过我自己在使用上面这个命令时并没有得到任何输出…

  • 在特定主机上创建OSD:

    ceph orch daemon add osd *<host>*:*<device-path>*

    ceph orch daemon add osd vm2:/dev/nvme0n2,/dev/nvme0n2

    或者写一个脚本批量添加某一节点上的OSD节点:

    1
    2
    3
    4
    for i in 2 3 4
    > do
    > ceph orch daemon add osd vm3:/dev/nvme0n$i
    > done

查看已添加的Ceph的OSD节点:

ceph osd tree

删除OSD节点

ceph orch osd rm <svc_id>... [--replace] [--force]

如果要删除1234这四个OSD节点则执行下面的命令:

ceph orch osd rm 1 2 3 4

之后可以执行ceph orch osd rm status查询删除状态。当被移除的OSD中没有PG时,则会将它正式的下架。

Ceph硬件准备

大部分的推荐配置来源于http://docs.ceph.org.cn/

Ceph为普通硬件设计,这可以让维护构建PB级别的数据集群的费用相对来说更低廉。在搭建集群前最初的硬件架构设计极为重要。你需要均衡几个方面的因素,包括区域实效和潜在的性能问题。硬件规划包含要把使用Ceph集群的Ceph守护进程和其他进程所需要的资源恰当合理分布。

通常只推荐在一台机器上运行一种类型的守护进程。我们推荐把使用数据集群的进程(如 Openstack、CloudStack等)安装在别的机器上。

CPU

Ceph元数据服务器对CPU敏感,他会动态地重分布他们的负载,所以你的元数据服务器应该有足够的处理能力(如4核或更强悍的CPU)。Ceph的OSD运行着RADOS服务,用CRUSH算法计算着数据存放位置、复制数据、维护它自己的集群运行图副本,因此OSD需要一定的处理能力(如双核心CPU)。Ceph监视器只简单地维护者集群运行图的副本,因此对CPU不敏感。

但是需要考虑是否未来会在Ceph监视器的机器会运行其他的CPU密集型任务。比如运行用于计算的虚拟机(Openstack NOVA),你就要确保给Ceph进程保留足够的处理能力,所以推荐在其他机器上运行CPU密集型任务。

内存

元数据服务器和监视器必须尽可能快的提供他们的数据,所以元数据服务器与监视器至少每个进程分配1G内存。

OSD的日常运行不需要那么多的内存,但是也要确保每个进程能分配到500M的内存,通常来说在进行数据恢复的期间他们占用的内存比较大,每TB级数据需要1GB的内存。

通常内存越多越好。

数据存储

谨慎的规划数据和数据存储架构,因为期间涉及明显的成本和性能折衷。

来自操作系统的并行操作和到单个硬盘的多个守护进程的并发读写会极大的降低性能。同时文件系统局限性也要考虑,btrfs尚未稳定到可以用于生产环境的程度,但它可以同时记录日志并写入数据,而xfs和ext4不能。

Ceph发送ACK前必须把所有数据写入日志(至少对xfs和ext4来说是),因此均衡日志和OSD性能相当重要。

磁盘驱动器

OSD应该有足够的空间用于存储对象数据。考虑到大硬盘的没GB成本,建议使用容量大于1TB的硬盘。建议用GB数除以硬盘价格来计算每GB的成本,因为较大的硬盘通常会对每GB成本有较大影响。

值得注意的是,单个驱动器的容量越大,其对应的OSD进程所需要的内存就越大,特别是在重均衡、回填、恢复期间。1TB的存储空间大约需要1GB内存。

在单个硬盘上运行多个OSD,这样不太妙!
在运行了OSD的磁盘上又同时运行着监视器或者云数据服务器这样也不太妙!

磁盘驱动器受限于寻道时间、访问时间、读写时间、还有吞吐量这些磁盘的物理局限影响着整体系统的性能,特别是在出现故障系统恢复期间。因此推荐独立的磁盘用于安装操作系统和软件,避免增加OSD存储磁盘的负担以提升性能。

Ceph可以在每块硬盘上运行多个OSD,但这会导致资源竞争并降低总体吞吐量;Ceph也允许把日志和对象数据存储在相同的磁盘驱动器上,但这会增加记录写日志并回应客户端的延迟,因为Ceph必须先写入日志才会回应确认了写动作。btrfs文件胸能同时写入日志数据和对象数据,而xfs、etx4不能。

Ceph最佳实践指示,应该分别在单独的硬盘运行操作系统、OSD和OSD日志。

固态硬盘

一种提升性能的方法是使用固态硬盘SSD来降低随机访问时间和读延时,同时增加吞吐量。SSD和硬盘相比每GB的成本通常要高出10倍以上,但访问时间至少比硬盘快100倍!

SSD没有可移动机械部件,所以不存在和硬盘一样的局限性。但是SSD也有其他的局限性,评估SSD时,顺序读写的性能很重要,在为多个OSD存储日志时,有着400MB/s顺序读写吞吐量的SSD性能远高于120MB/s的。

建议发觉SSD的用法来提升性能,在大量投入SSD前,强烈建议核实SSD的性能指标,并在测试环境下衡量性能。相对廉价的SSD虽然价格很诱人,但是要谨慎使用!一分钱一分货的道理是永恒不变的。

正是因为SSD没有移动机械部件,所以它很适合Ceph里不需要太多存储空间的地方。可接受的IOPS指标对选择用于Ceph的SSD还不够,用于日志和SSD时还有几个重要考量:

  • 写密集语意:写日志数据涉及密集语意,所以要确保选用的SSD写入性能和硬盘相当或者好于硬盘。廉价SSD可能在加速访问的同时引入写延时,有时候高性能的硬盘的写入速度可以和便宜的SSD硬盘相媲美。
  • 顺序写入:在一个SSD上为多个OSD存储多个日志时也必须考虑SSD的顺序写入极限,因为它们要同时处理多个OSD日志的写入请求。
  • 分区对齐:采用SSD的一个常见问题是人们喜欢分区,却常常忽略了分区对齐,这会导致SSD的数据传输速率慢很多,所以请确保分区对齐了。

SSD用于对象存储太昂贵了,但是把OSD的日志存到SSD、把对象数据存储到独立的硬盘可以明显提升性能。osd journal选项的默认值是/var/lib/ceph/osd/$cluster-$id/journal,所以说可以把目录存储的位置更改到SSD磁盘或SSD的分区上,这样它就不再是和对象数据一样存储在同一个硬盘上的文件了。

提升CephFS文件系统性能的一种方法是从CephFS文件内容中分离出元数据。Ceph提供了默认的metadata存储池来存储CephFS元数据,所以你不需要给CephFS元数据创建存储池,但是可以给它创建一个仅指向某主机SSD的CRUSH运行图。具体详情见OSD与Pool池的常见操作及管理

硬盘控制器

硬盘控制器也会对吞吐量有显著影响,要谨慎的选择控制器,以免产生性能瓶颈。

网络

建议每台机器最少两个千兆网卡,现在大多数的机械硬盘都能达到100MB/s的吞吐量,网卡应该能处理所有的OSD硬盘总吞吐量,所以推荐最少两个千兆网卡分别用于公网和集群网络。集群网络用来处理数据复制产生的额外负载,而且可以防止拒绝服务攻击,拒接服务攻击会干扰数据归置组,使OSD数据复制时不能回到active+clean状态。所以最好考虑使用两个万兆网卡。

通过 1Gbps 网络复制 1TB 数据耗时 3 小时,而 3TB (典型配置)需要 9 小时,相比之下,如果使用 10Gbps 复制时间可分别缩减到 20 分钟和 1 小时。在一个 PB 级集群中, OSD 磁盘失败是常态,而非异常;在性价比合理的的前提下,系统管理员想让 PG 尽快从 degraded (降级)状态恢复到 active + clean 状态。

增加的硬件成本可用节省的运营(网络安装、维护)成本抵消。使用 VLAN 来处理集群和计算栈(如 OpenStack 、 CloudStack 等等)之间的 VM 流量时,采用 10G 网卡仍然值得。每个网络的机架路由器到核心路由器应该有更大的带宽,如 40Gbps 到 100Gbps 。

其他要注意的点

可以在同一台主机上运行多个OSD,但是要确保OSD硬盘总吞吐量不超过客户端提供读写服务所需的网络带宽;还要考虑集群在每台主机上所存储的数据占总体的百分比,如果一台主机所占百分比太大而它宕机了,就可能导致诸如超过full ratio的问题,此问题会使Ceph中止运作以防止数据丢失。

保证内核是最新的,确保硬件性能可以达到期望值。

OSD数量比较多的主机会产生大量OSD线程,尤其是在恢复和重均匀期间。很多Linux内核默认的最大线程数较小(如 32K 个),如果遇到了这类问题,可以把kernel.pid_max 值调高些。理论最大值是 4194303 。例如把下列这行加入 /etc/sysctl.conf 文件:

kernel.pid_max = 4194303

故障域

故障域指任何导致不能访问一个或多个 OSD 的故障,可以是主机上停止的进程、硬盘故障、操作系统崩溃、有问题的网卡、损坏的电源、断网、断电等等。规划硬件需求时,要在多个需求间寻求平衡点,像付出很多努力减少故障域带来的成本削减、隔离每个潜在故障域增加的成本。

OSD与Pool池的常见操作及管理

查看osd状态

ceph -s

通过ceph -s可以查看集群的概况,其中包括了部分osd相关的健康信息。

ceph-s-osd-down-1-2020-07-26

ceph osd stat

ceph osd stat可以验证当前集群内的状态。

1
2
[ceph@servera ~]$ ceph osd stat
9 osds: 9 up, 9 in

当前集群内共有9个OSD,目前这9个OSD的状态均为OK!

ceph osd tree

ceph osd tree 显示所有的OSD列表

ceph-osd-tree-1-2020-10-23

在ID列,可以看到每一个OSD的ID均为正数,并且每个OSD的ID顺序是打乱、分散的。3台机器共9个OSD的ID被随机分配了。

值得注意的点是所有的主机和集群也被进行了ID编号,只不过它们的编号为负数。

ceph osd df

如果要查看每个OSD的使用情况以及数据所占用OSD空间的百分比,可以使用ceph osd df命令查看。

ceph-osd-df-1-2020-07-26

删除Pool

ceph osd pool delete rbd rbd --yes-i-really-really-mean-it

想要删除一个Pool你需要按照上面的格式进行确认,但是即便是一再确认,默认情况下MON节点还是不允许你删除Pool池。会提示Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

那么有下面两种方式可以删除Pool:

修改MON配置文件

修改配置文件,在配置文件中标记允许删除Pool,这样在重启集群所有的MON节点后会重新读取到这条配置文件,在删除Pool的时候不会进行阻拦。

vim /etc/ceph/ceph.conf

所有的MON节点下的配置文件中添加下面的配置:

1
2
[mon]
mon allow pool delete = true

修改后保存设置,重启集群内所有的MON节点服务

之后执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉。

这种方式要登录到所有的MON节点机器中修改配置,并且需要重启MON节点服务,如果你是单节点集群或者对集群的稳定性有严格需求,这种方式不太友好。

使用ceph tell运行时注入配置

Ceph支持运行时注入配置,那么可以进行下面的操作:

ceph tell mon.* injectargs --mon_allow_pool_delete true

之后会看到输出:

1
2
3
4
5
6
mon.vm1: {}
mon.vm2: {}
mon.vm3: {}
mon.vm1: mon_allow_pool_delete = 'true'
mon.vm2: mon_allow_pool_delete = 'true'
mon.vm3: mon_allow_pool_delete = 'true'

此时执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉刚才不能删除的Pool。

Pool池

Pool是一个抽象的存储池,它是PG之上的一层逻辑。它规定了数据冗余的类型以及对应的副本分布策略。

目前有两种pool类型:replicated类型和Erasure Code类型。

  • 一个pool由多个PG构成,一个PG只能属于一个Pool
  • 同一个Pool中的PG具有相同的类型,比如,如Pool为副本类型,则Pool中所有的PG都是多副本的

注意:在ceph 12.2.1(luminous)版本中,目前还不支持缩减PG、PGP数量,但是可以增加它们的数量,这适用于OSD存储节点的扩容,但是却不利于缩减OSD存储节点……
不过在

创建副本Pool

使用副本Pool时,每个对象都会被复制到n个osd上进行存储。复制几份由pool的size属性决定,默认情况下会有3个副本,在生产环境下应该至少存在3个副本才可以保证数据可靠性。

ceph osd pool create <poolname> <int[0-]> {<int[0-]>} {replicated|erasure} {<erasure_code_profile>} {<rule>} {<int>}

现在来创建一个名字叫rbd的Pool,使用默认的replicated模式创建并且默认的副本数量为3,将它的PG和PGP数量设置为64。

ceph osd pool create rbd 64 64

创建纠删码Pool

使用纠删码Pool可以减少副本的磁盘占用并且能与副本Pool得到同等的数据保护效果。它可以减少集群为了保护数据而而外付出的存储开销。

不过使用纠删码虽然与副本类型相比会减少很多存储空间,但是需要对数据进行较多的运算。在回复数据时会占用大量的计算资源如CPU、内存。

创建一个名字为reapool的PG、PGP数为50的纠删码类型Pool:

ceph osd pool create reapool 50 50 erasure

纠删码由配置定义,在创建纠删码存储池及其相关的 CRUSH 规则时用到。

创建 Ceph 集群时初始化的、名为 default 的纠删码配置可提供与两副本相同的冗余水平,却能节省 25% 的磁盘空间。在此配置中 k=2 和 m=1 ,其含义为数据分布于 3 个 OSD ( k+m==3 )且允许一个失效。

为了在不增加原始存储空间需求的前提下提升冗余性,你可以新建配置。例如,一个 k=10 且 m=4 的配置可容忍 4 个 OSD 失效,它会把一对象分布到 14 个( k+m=14 ) OSD 上。此对象先被分割为 10 块(若对象为 10MB ,那每块就是 1MB )、并计算出 4 个用于恢复的编码块(各编码块尺寸等于数据块,即 1MB );这样,原始空间仅多占用 10% 就可容忍 4 个 OSD 同时失效、且不丢失数据。

详见修改纠删码副本及冗余数量

管理和操作Pool

为Pool设置应用

在创建一个pool之后,你应该把这个pool分配一个application对这个pool进行标记。可以设置的应用有cephfsrbdrgw

ceph osd pool application enable <poolname> <app>

现在将刚刚创建名字为rbd这个Pool设置为用于rbd应用。

ceph osd pool application enable rbd rbd

在没有设置应用之前,使用ceph -s查看集群状态可能会有警告提示。设置之后再次查询,警告消失。

ceph -sceph health detail

通过eph osd pool application get rbd命令查看application发现已激活rbd应用在这个pool上。

1
2
3
4
[ceph@servera ~]$ ceph osd pool application get rbd
{
"rbd": {}
}

查看Pool信息

查看集群内的Pool

ceph osd lspools

1
2
[ceph@servera ~]$ ceph osd lspools
7 rbd,8 testpool,

ceph osd pool ls

1
2
3
[ceph@servera ~]$ ceph osd pool ls
rbd
testpool

查看集群内Pool的资源使用情况

ceph df

1
2
3
4
5
6
7
8
9
[ceph@servera ~]$ ceph df
GLOBAL:
SIZE AVAIL RAW USED %RAW USED
170G 169G 1071M 0.61
POOLS:
NAME ID USED %USED MAX AVAIL OBJECTS
rbd 7 0 0 82552M 0
testpool 8 0 0 82552M 0

查看每个OSD资源使用情况

ceph osd df

1
2
3
4
5
6
7
8
9
10
11
12
13
[ceph@servera ~]$ ceph osd df
ID CLASS WEIGHT REWEIGHT SIZE USE AVAIL %USE VAR PGS
0 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 197
3 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 213
8 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 204
2 hdd 0.01849 1.00000 19444M 127M 19317M 0.66 1.08 206
4 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 185
6 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 205
1 hdd 0.01849 1.00000 19444M 117M 19327M 0.61 0.99 181
5 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 200
7 hdd 0.01849 1.00000 19444M 117M 19327M 0.60 0.99 209
TOTAL 170G 1068M 169G 0.61
MIN/MAX VAR: 0.99/1.08 STDDEV: 0.02

查看Pool当前执行的任务,可以使用ceph osd pool stats来查看Pool当前正在执行的任务和写入、读取速度。

1
2
3
4
5
6
[ceph@servera ~]$ ceph osd pool stats
pool rbd id 7
nothing is going on

pool testpool id 8
nothing is going on

重命名Pool

你可以使用ceph osd pool rename命令重新命名你不满意的名字。

osd pool rename <current_poolname> <new_poolname>

对Pool进行快照

你可以创建或者删除一个Pool的快照。

ceph osd pool mksnap/rmsnap <poolname> <snap>

对当前的rbdPool进行创建快照操作:

ceph osd pool mksnap rbd rbd@snap-20200721

查看该Pool中创建的Pool快照:

rados lssnap -p rbd

1
2
3
[ceph@servera ~]$ rados lssnap -p rbd
1 rbd@snap-20200721 2020.07.21 15:26:39
1 snaps

删除刚刚创建的快照:

ceph osd pool rmsnap rbd rbd@snap-20200721

还原快照:

rados -p <poolname> rollback <obj-name> <snap-name>

rados -p <poolname> -s <snap-name> get <obj-name> file

Ceph支持两种类型的快照,一种是pool snaps,也就是Pool级别的快照,是给整个pool中的对象整体做一个快照。另一个是self managed snaps,rbd使用的就是这种类型的快照。
要注意的是:这两种快照类型是互斥的,不能同时存在。如果你要是用Pool快照那么默认情况下就不能在这个Pool下创建RBD了。

更改Pool参数

对Pool进行调整可以设置副本数、纠删码份数,还可以限制该Pool所使用的资源大小等。

ceph osd pool set <poolname> <parameter> <value>

限制Pool所用资源数量

管理员可以对Pool设置限额(quotas)来限制最大使用的存储量和对象(object)数量。

ceph osd pool set-quota <poolname> max_objects|max_bytes <val>

限制rbdPool最大仅能使用1GB存储空间:

ceph osd pool set-quota rbd max_bytes 1073741824

更改副本数/纠删码个数

修改副本数

在实际生产环境中副本数通常在3个或以上。默认的副本数是两个,不过保险起见生产环境下应越多越保险。

ceph osd pool set rbd size 3

修改纠删码副本及冗余数量

使用纠删码创建的Pool可以配置纠删码算法及相应规则,你可以自己新建一个纠删码规则适用于当前的业务需求。

和副本模式相比纠缠码可以大幅减少存储成本,但当集群内的其他OSD遇到数据盘损坏时会重新计算丢失的数据。这会对计算资源和网络资源造成较大的负担!

合理的配置纠删码文件可以带来更好的效率。

使用ceph osd erasure-code-profile get default查看创建一个纠删码模式的Pool时默认的的配置信息。

1
2
3
4
k=2
m=1
plugin=jerasure
technique=reed_sol_van
  • k 对对象分割的数量,k=2为默认值。对一个对象分割成两部分。
  • m 纠删码数量,默认m=1。假如k=2时,一个对象文件被分割成了两份存在了不同的OSD上,此时有一个OSD坏掉了的话通过纠删码就可以计算出坏掉的那个OSD磁盘中的数据。

创建一个新的纠删码配置

1
2
3
4
5
6
ceph osd erasure-code-profile set {name} \
[{directory=directory}] \
[{plugin=plugin}] \
[{stripe_unit=stripe_unit}] \
[{key=value} ...] \
[--force]
  • directory 设置纠删码插件的路径,需是目录。
  • plugin 指定纠删码插件来计算编码块、及恢复丢失块。
  • stripe_unit 每一个条带中、一个数据块的数据量。例如,在一个配置中,数据块为 2 且 stripe_unit=4K ,数据进来时会把 0-4K 放入块 0 , 4K-8K 放入块 1 ;然后 8K-12K 又是块 0 。为实现最佳性能,这里应该设置成 4K 的倍数。默认值是在存储池创建时从监视器配置选项 osd_pool_erasure_code_stripe_unit 获取的。一个使用着这个配置的存储池,其 stripe_width 值(条带宽度)就是数据块的数量乘以这里的 stripe_unit 值。
  • key 纠删码插件所定义的键/值对含义。

创建一个k=6,m=3的纠删码配置文件:

ceph osd erasure-code-profile set test k=6 m=3

查看test纠删码配置信息

ceph osd erasure-code-profile get test

1
2
3
4
5
6
7
8
9
10
[ceph@servera ~]$ ceph osd erasure-code-profile get test
crush-device-class=
crush-failure-domain=host
crush-root=default
jerasure-per-chunk-alignment=false
k=6
m=3
plugin=jerasure
technique=reed_sol_van
w=8

创建一个新的纠删码类型Pool并使用刚刚创建的test纠删码配置进行创建。

ceph osd pool create erasurepool 10 10 erasure test

查看Pool信息

ceph osd pool ls detail

pool 12 'erasurepool' erasure size 9 min_size 7 crush_rule 2 object_hash rjenkins pg_num 10 pgp_num 10 last_change 618 flags hashpspool stripe_width 24576

删除Pool

ceph osd pool delete rbd rbd --yes-i-really-really-mean-it

想要删除一个Pool你需要按照上面的格式进行确认,但是即便是一再确认,默认情况下MON节点还是不允许你删除Pool池。会提示Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool

那么有下面两种方式可以删除Pool:

修改MON配置文件

修改配置文件,在配置文件中标记允许删除Pool,这样在重启集群所有的MON节点后会重新读取到这条配置文件,在删除Pool的时候不会进行阻拦。

vim /etc/ceph/ceph.conf

所有的MON节点下的配置文件中添加下面的配置:

1
2
[mon]
mon allow pool delete = true

修改后保存设置,重启集群内所有的MON节点服务

之后执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉。

这种方式要登录到所有的MON节点机器中修改配置,并且需要重启MON节点服务,如果你是单节点集群或者对集群的稳定性有严格需求,这种方式不太友好。

使用ceph tell运行时注入配置

Ceph支持运行时注入配置,那么可以进行下面的操作:

ceph tell mon.* injectargs --mon_allow_pool_delete true

之后会看到输出:

1
2
3
4
5
6
mon.vm1: {}
mon.vm2: {}
mon.vm3: {}
mon.vm1: mon_allow_pool_delete = 'true'
mon.vm2: mon_allow_pool_delete = 'true'
mon.vm3: mon_allow_pool_delete = 'true'

此时执行ceph osd pool delete rbd rbd --yes-i-really-really-mean-it就可以删除掉刚才不能删除的Pool。

Pool命名空间

命名空间是Pool池的逻辑组。可以设置一个命名空间限制个个用户能访问到该Pool的范围,限制用户只访问到该Pool的部分范围。当然也可以按照不同应用应用的方式进行分组。

要存储一个对象到命名空间时客户端需要指明Pool和命名空间。

默认情况下每个Pool包括一个孔明成的命名空间作为默认的命名空间使用。

放置对象到命名空间

使用rados命令可以将Object对象放置在Pool上的指定命名空间内。

rados -p <poolname> [-N <namespace>] put <obj-name> [infile] [--offset offset]

rados -p rbd -N system put release /etc/redhat-release

上面这个命令是将/etc/redhat-release这个文件放在了rbd存储池的system命名空间里,并且文件名为release

列出命名空间内的对象

rados -p <poolname> [-N <namespace>] ls [--all]

列出rbd存储池中system命名空间下的对象:

rados -p rbd -N system ls

返回列表如下,返回的这些object都是属于system这个命名空间下的对象。

1
2
services-name
release

不过,在不指明命名空间的情况下,只能看得到默认命名空间里的对象,如果要显示出该Pool内全部命名空间的对象的话如何操作?

rados -p rbd ls --all

1
2
3
system  services-name
system release
release

这样就可以显示出全部命名空间里的对象名称了,那么没有名字的release对象就是存放在默认的命名空间下。

还可以以JSON的格式进行输出:

rados -p rbd ls --all --format=json | python -m json.tool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ceph@servera ~]$ rados -p rbd ls --all --format=json | python -m json.tool
[
{
"name": "services-name",
"namespace": "system"
},
{
"name": "release",
"namespace": "system"
},
{
"name": "release",
"namespace": ""
}
]

Ceph用户管理

本文档叙述了Ceph客户端的用户身份,以及Ceph存储集群的认证和授权。用户可以是个人或是系统角色(像应用程序),它们用Ceph客户端和Ceph服务器守护进程进行交互。

ceph-user-auth-2020-07-26

当Ceph开启用户认证时(默认开启),你必须指定一个用户名和密钥环来证明一个用户认证通过后才可以对Ceph进行相关操作。如果不指明用户名和密钥环,Ceph将会使用client.admin作为用户名,通过查找Ceph keyring设置搜索名称匹配的密钥环。

假如我们执行ceph health命令时没有指明任何用户名和密钥环文件存放地址。那么Ceph会自动的将其解析为如下命令并执行:

ceph -n client.admin --keyring=/etc/ceph/ceph.client.admin.keyring health

另外也可以用CEPH_ARGS环境变量来避免多次输入用户名和密钥。

概述

不论Ceph是从块设备、对象存储、文件系统、还是API中接收数据,最后都会将它们作为对象存储在Pool池中。

Ceph用户必须有权访问池才能读取和写入数据。此外,Ceph用户还应该具有执行权限才能使用Ceph的管理命令。下面的更多概念将会帮助了解Ceph用户管理。

用户

一个用户可以是一个个体,也可以是一个应用程序。通过创建用户,您可以控制哪些人(或什么人)可以访问您的Ceph存储集群以及Pool池中的数据。

Ceph有一个type的用户观念,这是出于用户管理的目的,类型总是client,并且以(.)分割标识不同的用户,以Type.ID这种形式表现。例如client.adminclient.user1

区分用户类型有助于区分客户端和其他用户的访问控制,更方便的进行用户监控和可追溯用户。

有时候Ceph的用户type类型会让你感到很迷惑,因为既可以指定Type来执行Ceph命令,也可以只使用用户名来进行访问。其实这取决于执行Ceph命令行时所使用的选项。当你使用--user或者 --id来指明一个用户时,此时client.user1可以省略为user1。如果使用--name-n来指定用户时,你就必须要加上Type类型了。

推荐使用--name-n提供Type类型和名称的方式进行用户访问。

授权

Ceph用能力(capabilities,caps)这个term术语来描述给某个已认证用户的授权。有一定权限后才可以使用mon、osd和元数据服务器等功能。能力也用于限制对一存储池内的数据、存储池内命名空间、或由应用标签所标识的一系列存储池的访问。

Ceph管理用户可以在创建或更新某一用户时赋予、更新他的能力。

能力的语法符合下面的形式:

{daemon-type} '{cap-spec}[, {cap-spec} ...]'

  • mon 监视器能力:监视器能力包括r 、 w 、 x 访问选项或 profile {name},例如:

    1
    2
    mon 'allow {access-spec} [network {network/prefix}]'
    mon 'profile {name}'

    {access-spec} 语法如下:

    * | all | [r][w][x]

    可选项 {network/prefix} 是个标准网络名和前缀长度( CIDR 表示法,如 10.3.0.0/16 )。如果设置了,此能力就仅限于从这个网络连接过来的客户端。

  • OSD 能力:OSD能力包括 r 、 w 、 x 、 class-read 、 class-write 访问选项和 profile {name} 。此外,OSD能力还支持存储池和命名空间的配置。

    1
    2
    osd 'allow {access-spec} [{match-spec}] [network {network/prefix}]'
    osd 'profile {name} [pool={pool-name} [namespace={namespace-name}]] [network {network/prefix}]'

    其中, {access-spec} 语法是下列之一:

    1
    2
    3
    * | all | [r][w][x] [class-read] [class-write]

    class {class name} [{method name}]

    可选的 {match-spec} 语法是下列之一:

    1
    2
    3
    pool={pool-name} [namespace={namespace-name}] [object_prefix {prefix}]

    [namespace={namespace-name}] tag {application} {key}={value}

    可选的 {network/prefix} 是一个标准网络名、且前缀长度遵循 CIDR 表示法(如 10.3.0.0/16 )。如果配置了,对此能力的使用就仅限于从这个网络连入的客户端。

  • 元数据服务器能力:对于管理员,设置 allow * 。对于其它的所有用户,如 CephFS 客户端,参考 CephFS 客户端用户

存储池

存储池是用户存储数据的逻辑分区。在Ceph部署中,经常创建存储池作为逻辑分区、用以归类相似的数据。例如,用Ceph作为Openstack的后端时,典型的部署通常会创建多个存储池,分别用于存储卷宗、映像、备份和虚拟机。

应用程序标签

可以将访问限定于指定存储池,正如其应用程序元数据所定义的那样。通配符 * 可以用于key参数、value参数或者二者全部。all* 同义。

命名空间

对象Object在Pool池中可以关联到命名空间,他是池中对象的逻辑组。用户对Pool池的访问可以与命名空间想关联,比如限制一个用户在命名空间内的读写权限。

命名空间主要适用于 librados 之上的应用程序,逻辑分组可减少新建存储池的必要。 Ceph 对象网关(从 luminous 起)就把命名空间用于各种元数据对象。

用 namespace 能力可以把访问权限局限于特定的 RADOS 命名空间。命名空间支持有限的通配;如果指定的命名空间最后一个字符是 * ,那就把访问权限授予所有以所提供参数打头的命名空间。

管理用户

用户管理功能赋予Ceph存储集群管理员直接从Ceph存储集群中间、更新和删除用户及能力。

挡在Ceph存储集群中创建或删除用户的时候,可能得把密钥文件分发到各客户端,一边加入他们的密钥环。详见密钥环管理

罗列显示用户

罗列显示集群内的用户,使用ceph auth ls命令。Ceph将罗列出集群内的所有用户。例如,在一个上节点示例集群中,ceph auth ls会显示类似如下的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
installed auth entries:

osd.0
key: AQCvCbtToC6MDhAATtuT70Sl+DymPCfDSsyV4w==
caps: [mon] allow profile osd
caps: [osd] allow *
osd.1
key: AQC4CbtTCFJBChAAVq5spj0ff4eHZICxIOVZeA==
caps: [mon] allow profile osd
caps: [osd] allow *
client.admin
key: AQBHCbtT6APDHhAA5W00cBchwkQjh3dkKsyPjw==
caps: [mds] allow
caps: [mon] allow *
caps: [osd] allow *
client.bootstrap-mds
key: AQBICbtTOK9uGBAAdbe5zcIGHZL3T/u2g6EBww==
caps: [mon] allow profile bootstrap-mds
client.bootstrap-osd
key: AQBHCbtT4GxqORAADE5u7RkpCN/oo4e5W0uBtw==
caps: [mon] allow profile bootstrap-osd

Type.ID 这种表示方法对于用户来说,如osd.0标示用户类型是osd,其ID是0;client.admin表示用户类型是client,ID是admin(即默认的client.admin)用户。还有,每条都有一行 key: 条目、和一或多行 caps: 条目。

你可以给 ceph auth ls加上-o {filename}选项,把输出保存到一个文件。

获取用户

想要获取一个用户的key和能力,执行下面的命令:

ceph auth get {Type.ID}

ceph auth get client.admin

得到如下结果:

1
2
3
4
5
6
7
8
[ceph@serverc ~]$ ceph auth get client.admin
exported keyring for client.admin
[client.admin]
key = AQDtYxJf2UeZHRAAZmPGLhLr3kLzHXh3Glba6g==
caps mds = "allow *"
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"

如果想要保存输出结果到文本文件中,可以使用-o 选项,和上面的一样。

ceph auth export {Type.ID} 使用export命令等价于get。它会把auid显示到终端上。

新增用户

添加一个用户,让其拥有密钥和应该有的能力。

用户的密钥是用户可以通过Ceph存储集群进行身份认证。可以对用户的能力进行授予,使他们拥有在Ceph监视器mon,Ceph OSD,或者Ceph元数据mds上的读取、写入或执行权限。

有下面几种方式添加用户:

  • ceph auth add:这种添加用户的方式是最规范的方法。它将创建用户,生成密钥并添加任何指定的能力。
  • ceph get-or-create-key:这个命令添加用户后并返回用户密钥环文件信息。这对于需要密钥的客户端非常方便。如果用户已经存在,那么会返回密钥文件格式,并不会重新生成一个新的用户去替换重名用户。使用-o选项将密钥环保存在本地文件。
  • ceph auth get-or-create-key:这种方式创建用户后会输出到控制台密钥,仅仅是密钥而不包括更多的钥匙环格式。
  • 如果需要批量新建用户,可以尝试使用密钥环批量创建用户

当创建了用户之后,可能没有给用户赋予任何的能力。一个用户如果没有任何能力就是一个毫无卵用的用户,因为客户端无法从监视器mon中获得任何集群信息。当然,你可以先创建一个没有能力的用户,之后再使用ceph auth caps命令赋予能力给用户。

标准的用户至少要用用Ceph监视器mon的可读的能力,并且在Ceph osd上具有读写的能力。此外,用户的OSD权限通常会限定至一个特定的Pool池中。

1
2
3
4
5
6
ceph auth add client.yeefire mon 'allow r' osd 'allow rw pool=rbd'
ceph auth get-or-create client.paul mon 'allow r' osd 'allow rw pool=liverpool'
ceph auth get-or-create client.yeefire mon 'allow r' osd 'allow * pool=rbd namespace=system' -o ceph.client.yeefire.keyring
ceph auth get-or-create client.george mon 'allow r' osd 'allow rw pool=liverpool' -o george.keyring
ceph auth get-or-create-key client.ringo mon 'allow r' osd 'allow rw pool=liverpool' -o ringo.key

如果你给用户分配了访问 OSD 的能力,但是没有限制他可以访问哪些存储池,那么他可以访问集群内的所有存储池!最好对用户能力再进行namespace上的限制,以达到最小能力。

更改用户能力

ceph auth caps 命令可以用来修改指定用户的能力。设置新能力时会覆盖当前能力。

ceph auth caps USERTYPE.USERID {daemon} 'allow [r|w|x|*|...] [pool={pool-name}] [namespace={namespace-name}]' [{daemon} 'allow [r|w|x|*|...] [pool={pool-name}] [namespace={namespace-name}]']

1
2
3
4
ceph auth get client.john
ceph auth caps client.john mon 'allow r' osd 'allow rw pool=liverpool'
ceph auth caps client.paul mon 'allow rw' osd 'allow rwx pool=liverpool'
ceph auth caps client.brian-manager mon 'allow *' osd 'allow *'

删除用户

要删除一用户,使用ceph auth del {Type}.{ID}命令:

ceph auth del client.yeefire

查看用户密钥

要想查看用户的密钥,可以通过以下方式进行获取:

1
2
3
ceph auth print-key client.yeefire
ceph auth get-key client.yeefire
ceph auth get-or-create-key client.yeefire -o key

他们都可以使用-o选项将标准输出内容输出到文件中。

使用auth print-keyauth get-key auth get-or-create-key返回的结果基本都是一样的。只不过 auth get-or-create-key在输出key的时候会在行末尾添加一个换行符。

导入用户

通过ceph auth getceph auth export导出的用户文件可以通过ceph auth import导入的方式恢复用户及他们的能力。

要导入一个或多个用户,可以用 ceph auth import 命令,并指定一个密钥环:

ceph auth import -i /path/to/all.keyring

Ceph 存储集群会新增用户、他们的密钥以及其能力,也会更新已有的用户们、他们的密钥和他们的能力。

管理密钥环

当你访问Ceph使,你的客户端会在一些目录下寻找当前用户的keyring。Ceph默认情况下会使用下面四个路径来搜索与当前用户对应的密钥环。

  • /etc/ceph/$cluster.$name.keyring
  • /etc/ceph/$cluster.keyring
  • /etc/ceph/keyring
  • /etc/ceph/keyring.bin

$cluster是你的集群名称,如client$name是你的用户类型和用户ID,如client.admin。因此合起来的话是/etc/ceph/ceph.client.admin.keyring

用户管理部分详细介绍了如何直接在Ceph存储群集中列出,获取,添加,修改和删除用户。Ceph还提供了ceph-authtool实用程序,使您可以从Ceph客户端管理密钥环。

把用户加入到密钥环

当你在 Ceph 存储集群中创建用户后,你可以用获取用户里面的方法获取此用户、及其密钥、能力,并存入一个密钥环文件。

当你希望每个密钥环中只有一个用户时,使用ceph auth get命令与-o选项搭配,将该用户的钥匙环保存在文件中。

ceph auth get client.yeefire -o ceph.client.admin.keyring

当你想把其他用户的钥匙环导入到一个目标钥匙环里,为了方便import的话,可以使用ceph-authtool工具进行导入:

ceph-authtool ceph.client.yeefire.keyring --import-keyring ceph.client.yeefire.sirius.keyring

通过钥匙环创建用户

Ceph提供了创建用户的功能,可以直接在集群中创建用户。但是如果要是批量新建用户,先在密钥环上创建用户之后再导入到Ceph集群中也是一个不错的选择!

可以将用户导入Ceph存储集群。例如:

ceph-authtool -C ceph.42team.keyring -n client.42team.admin --cap mon 'allow *' --cap osd 'allow *' --cap mgr 'allow *' --gen-key

可以继续创建新的用户,然后导入到ceph.42team.keyring密钥环文件中:

ceph-authtool -n client.42team.sirius --cap mon 'allow r' --cap osd 'allow rw pool=42team' ceph.42team.keyring -g

现在查看ceph.42team.keyring密钥环文件中的内容:

1
2
3
4
5
6
7
8
9
10
[ceph@serverc ~]$ cat ceph.42team.keyring
[client.42team.admin]
key = AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==
caps mgr = "allow *"
caps mon = "allow *"
caps osd = "allow *"
[client.42team.sirius]
key = AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps mon = "allow r"
caps osd = "allow rw pool=42team"

将密钥环文件导入到Ceph中创建用户:

ceph auth import -i ceph.42team.keyring

导入完成后使用ceph auth ls命令进行验证:

1
2
3
4
5
6
7
8
9
10
11
12
[ceph@serverc ~]$ ceph auth ls | grep client.42team -A5
installed auth entries:

client.42team.admin
key: AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
client.42team.sirius
key: AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps: [mon] allow r
caps: [osd] allow rw pool=42team

成功将2个用户导入到Ceph集群。

接下来将钥匙环放置到/etc/ceph/ceph.keyring

cp ceph.42team.keyring /etc/ceph/ceph.keyring

尝试使用client.42team.admin用户去执行Ceof osd命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ceph@serverc ~]$ ceph osd tree -n client.42team.admin
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.16644 root default
-3 0.05548 host serverc
0 hdd 0.01849 osd.0 up 1.00000 1.00000
3 hdd 0.01849 osd.3 up 1.00000 1.00000
8 hdd 0.01849 osd.8 up 1.00000 1.00000
-7 0.05548 host serverd
2 hdd 0.01849 osd.2 up 1.00000 1.00000
4 hdd 0.01849 osd.4 up 1.00000 1.00000
6 hdd 0.01849 osd.6 up 1.00000 1.00000
-5 0.05548 host servere
1 hdd 0.01849 osd.1 up 1.00000 1.00000
5 hdd 0.01849 osd.5 up 1.00000 1.00000
7 hdd 0.01849 osd.7 up 1.00000 1.00000

修改密钥环中用户能力

要修改密钥环中用户的能力,请指定密钥环,然后再指定用户,修改用户的能力不会重置用户的key

ceph-authtool ceph.42team.keyring -n client.42team.sirius --cap mon 'allow r'

撤销client.42team.sirius用户对osd的所有权限,目前该用户仅可以查看mon信息。

1
2
3
[client.42team.sirius]
key = AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps mon = "allow r"

要将刚刚在密钥环上的修改应用到ceph集群,必须将密钥环的用户更新到Ceph集群中的用户条目。

ceph auth import -i ceph.42team.keyring

成功导入后对修改进行验证:

ceph auth ls | grep ^client.42team -A5

1
2
3
4
5
6
7
8
9
10
11
[ceph@serverc ~]$ ceph auth ls | grep ^client.42team -A5
installed auth entries:

client.42team.admin
key: AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==
caps: [mgr] allow *
caps: [mon] allow *
caps: [osd] allow *
client.42team.sirius
key: AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==
caps: [mon] allow r

对导入用户不了解可以参见导入用户

不想使用ceph-authtool工具或者不想以密钥环方式添加用户可以参见更改用户能力新增用户

身份验证命令行

Ceph命令行几乎全局支持用户名和密钥的下列用法:

  • --id | --user:Ceph 用一个类型和 ID( 如 TYPE.ID 或 client.admin 、 client.user1 )来标识用户, id 、 name 、和 -n 选项可用于指定用户名(如 admin 、 user1 、 foo 等)的 ID 部分,你可以用 –id 指定用户并忽略类型,例如可用下列命令指定 client.foo 用户:
    1
    2
    ceph --id foo --keyring /path/to/keyring health
    ceph --user foo --keyring /path/to/keyring health
  • --name | -n:Ceph 用一个类型和 ID (如 TYPE.ID 或 client.admin 、 client.user1 )来标识用户, –name 和 -n 选项可用于指定完整的用户名,但必须指定用户类型(一般是 client )和用户 ID ,例如:
    1
    2
    ceph --name client.foo --keyring /path/to/keyring health
    ceph -n client.foo --keyring /path/to/keyring health
  • --keyring:包含一或多个用户名、密钥的密钥环路径。 --secret 选项提供了相同功能,但它不能用于 RADOS 网关,其 --secret 另有用途。你可以用 ceph auth get-or-create 获取密钥环并保存在本地,然后您就可以改用其他用户而无需重指定密钥环路径了。
    ceph --id 42team.admin --keyring /etc/ceph/ceph.keyring health

Ceph认证的局限性

cephx协议提供Ceph客户端和服务器间的相互认证,并没打算认证人类用户或者应用程序。如果有访问控制需求,那必须用另外一种机制,他对于前端用户访问Ceph对象存储可能是特定的,其任务是确保只有此机器上可接受的用户和程序才能访问Ceph的对象存储。

用于认证Ceph客户端和服务器的密钥通常以纯文本存储在权限合适的文件里,并保存于可信主机上。

密钥存储为纯文本文件有安全缺陷,但很难避免,它给了 Ceph 可用的基本认证方法,设置 Ceph 时应该注意这些缺陷。

尤其是任意用户、特别是移动机器不应该和 Ceph 直接交互,因为这种用法要求把明文认证密钥存储在不安全的机器上,这些机器的丢失、或盗用将泄露可访问 Ceph 集群的密钥。

相比于允许潜在的欠安全机器直接访问 Ceph 对象存储,应该要求用户先登录安全有保障的可信机器,这台可信机器会给人们存储明文密钥。未来的 Ceph 版本也许会更彻底地解决这些特殊认证问题。

当前,没有任何 Ceph 认证协议保证传送中消息的私密性。所以,即使物理线路窃听者不能创建用户或修改它们,但可以听到、并理解客户端和服务器间发送过的所有数据。此外, Ceph 没有可加密用户数据的选项,当然,用户可以手动加密、然后把它们存在对象库里,但 Ceph 没有自己加密对象的功能。在 Ceph 里存储敏感数据的用户应该考虑存入 Ceph 集群前先加密。

让你的Mac睡的更香

最近Mac的睡眠让我感到不太舒服,明明已经合上盖子拔掉电源,可是它还在熬着夜!不好好睡觉真让人生气!

所以得好好调教一下,让他该睡觉的时候老老实实趴下,该干活的时候就得全力以赴工作。

Mac是怎么睡觉的

Mac有两种睡觉有两个阶段,一开始是睡眠,在一定条件之后会从睡眠进入休眠。这两种睡觉方式就像我们人的小憩和睡大觉。小憩醒得快,睡大觉醒的就会慢一些。

在长时间无操作,或者把Macbook的盖子合上时以及手动点击进入睡眠时则进入睡眠状态,在睡眠状态下数据存储在内存中,此时的系统可以被快速唤醒,快速恢复到睡眠前的状态。

如果睡眠持续了一段时间之后,Mac会根据设定进入更深一层的休眠状态,此时Mac要根据你的配置来决定要不要把内存中的数据写入到磁盘中,然后会放弃对内存及设备的大部分供电,达到更加节省电量的目的。如果在休眠模式下唤醒,则Mac会将保存在硬盘中的数据再重新写入到内存之中并恢复程序运行,这样的话耗时比较长,速度比较慢。

pmset工具

Apple 提供了一个工具叫pmset来管理Apple 设备的电源选项。pmset这个工具的名字来源于 Power Manager Setting(pmset) ,通过调整macos的睡眠计划,可以让Mac睡的更香。

pmset用法

sudo pmset [-选项] <参数>

实例:

  • pmset -g cap: 查看当前供电方式下可以调节的参数
  • pmset -g custom : 查看全部供电方式下的电源参数信息
  • pmset restoredefaults : 还原自定义的设置

pmset常用选项

  • pmset -a : 全局调整睡眠电源计划
  • pmset -c : 仅调整外部供电时睡眠计划
  • pmset -b : 仅调整电池供电时睡眠计划
  • pmset -g : 查看当前供电方式下的睡眠计划

常用参数

  • sleep: 睡眠计时器,进入睡眠所需要的时间
  • hibernatemode: 睡眠模式
    • hibernatemode = 0 将数据保存在内存中持续为内存供电 非笔记本机器默认配置
    • hibernatemode = 3 safe sleep模式,数据保存在内存中并写入内存镜像到硬盘中备份。笔记本默认模式
    • hibernatemode = 25 将内存镜像直接写入到硬盘中
  • standby: 休眠计时器
  • highstandbythreshold: highstandbythreshold(电池剩余电量百分比)它是standbydelay模式选择阈值,默认 50% 电量。
    • 高于阈值,采用standbydelayhigh计算时间。
    • 低于阈值,采用standbydelaylow计算时间。
  • gpuswitch: 这个参数用来管理独立显卡的选择
    • gpuswitch=0 只使用集成显卡
    • gpuswitch=1 只使用独立显卡
    • gpuswitch=2 自动切换显卡

其他参数

  • lidwake:开盖时是否唤醒
  • tcpkeepalive:合盖时是否保存网络连接
  • displaysleep:屏幕休眠时间
  • disksleep:硬盘休眠时间
  • acwake:被同一 iCloud ID 下的设备唤醒

我的个人参数

外部供电环境下:

外部供电睡眠设置使用的是默认参数。

外部电源供电-2020-07-15

电池供电:

电池供电-2020-07-15

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
// 20分钟后睡眠
sudo pmset -b sleep 20

// 休眠模式使用3,在给内存供电的同时写入内存的镜像备份到磁盘中
sudo pmset -b hibernatemode 3

// 显示器15分钟后关闭
sudo pmset -b displaysleep 15

// 硬盘30分钟后休眠
sudo pmset -b disksleep 30

// 休眠后断网
sudo pmset -b tcpkeepalive 0

// 开盖唤醒
sudo pmset -b lidwake 1

// 关闭被同一 iCloud 下的设备唤醒
sudo pmset -b acwake 0

// gpuswitch 0 在使用电池的情况下只使用核心显卡
sudo pmset -b gpuswitch 0

// 在电池剩余电量高于75%的情况时,休眠计时器设定为2小时。低于75%的情况下1小时后进入休眠。
sudo pmset -b highstandbythreshold 75
sudo pmset -b standbydelayhigh 7200
sudo pmset -b standbydelaylow 3600

参考文章:

https://sspai.com/post/61379