Files
wiki/存储/Ceph/知识库/13-监控告警与Dashboard篇.md
T
2026-09-18 13:49:11 +08:00

5771 lines
281 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
> 基于 Ceph 官方文档整理 | 文档版本:**Tentacle v20.2.4** | 抓取日期:2026-09-17 | 源文:ceph/ceph@v20.2.4 `doc/monitoring/`、`doc/mgr/`
> 官网入口:https://docs.ceph.com/en/tentacle/monitoring/ 、https://docs.ceph.com/en/tentacle/mgr/
# 手册第 13 册 · 监控、告警与 Dashboard 篇
---
## 本册导读
本册覆盖 Ceph Tentacle v20.2.4 中「看见集群状态」与「把状态变成告警/图形/接口」这一整条链路。全册内容均来自官方文档源文(`doc/monitoring/`、`doc/mgr/`、`doc/jaegertracing/`、`doc/hardware-monitoring/`),不引入官方文档以外的第三方实践作为事实陈述;凡属本册作者推断/补充的内容,均以 `> 💡 补充:` 显式标注。
**本册的知识地图:**
| 层次 | 组件 | 本册章节 | 作用 |
|---|---|---|---|
| 采集层 | `ceph_exporter` 守护进程、各 Ceph 守护进程 perf counters | 一、三 | 把 Ceph 原生性能计数器转成 Prometheus 指标 |
| 汇聚层 | `ceph-mgr` + `prometheus` 模块 | 二、三 | 汇总全集群视图,暴露 HTTP 抓取端点 |
| 存储/查询层 | Prometheus(PromQL) | 一、三 | 时序存储与查询 |
| 可视化层 | Grafana、Ceph Dashboard 嵌入 Grafana | 四 | 图形化展示 |
| 告警层 | Alertmanager、Dashboard 告警接收器、`alerts` 模块 | 四、五 | 告警通知与静默管理 |
| 交互层 | Ceph Dashboard(WebUI)、Ceph RESTful API、Orchestrator CLI | 四、六、七 | 人/程序操作集群的入口 |
| 扩展层 | 各内置 mgr 模块(crash/progress/insights/telemetry/nfs/smb…) | 八 | 具体功能 |
| 深挖层 | Jaeger 分布式追踪、RedFish 硬件监控 | 九、十 | 请求级追踪与带外硬件监控 |
**阅读建议:**
- 想快速搭起监控:先看 **一(监控总览)→ 三(Prometheus)→ 四(Dashboard 的 Grafana 嵌入与告警)**。
- 想搞懂 ceph-mgr 本身(为什么 standby 也能打开 Dashboard、模块怎么加载):看 **二**。
- 想写自动化:看 **六(RESTful API)** 与 **七(Orchestrator CLI)**。
- 想落地运维规范:看 **十一(监控实践建议)** 与 **十二(命令速查表)**。
**关于配置项默认值的说明:** rst 源文中的 `.. confval::` 默认值是构建期生成的占位符,本册所有真实默认值均通过在 `src/common/options/*.yaml.in`(本机路径 `handbook-src/options/`)中检索得到,并在表格中标注「(默认值取自 src/common/options/*.yaml.in @ v20.2.4)」。若该选项在 `*.yaml.in` 中不存在(多数 `mgr/<module>/<option>` 形式的模块选项是定义在模块 Python 源码的 `MODULE_OPTIONS` 中,不在 yaml.in 里),则标注「文档未明确」或引用 rst 源文中明确写出的数值。
---
## 一、监控总览
来源页面:`monitoring/index.rst`(约 19KB)
### 1.1 Ceph 监控体系总览
Ceph 提供一套**集成(integrated)的监控栈**,由 `cephadm` 部署(即 cephadm 文档中的 "Monitoring Services" 一节所述的 Prometheus / Alertmanager / Grafana / node-exporter 等)。若用户已有外部的全机房(fleetwide)监控与可观测性系统,也可以**关掉 Ceph 默认部署的这套栈**。
管理员可以利用 Prometheus、Alertmanager、Grafana 以及脚本,构建自定义的监控工具。
### 1.2 告警来源(Alerting sources)
从源文归纳,Ceph 的告警与健康信息来源有以下几类(本册范围内):
| 来源 | 说明 | 消费方式 |
|---|---|---|
| Ceph health checks(集群健康检查) | 由 mon / mgr / OSD 等产生,形如 `OSD_DOWN`、`PG_DEGRADED`、`OSDMAP_FLAGS` | `ceph health`、`ceph status`、`ceph_health_detail` 指标 |
| `ceph_health_detail` Prometheus 指标 | prometheus 模块把 health check 暴露为离散指标,带 `name` 与 `severity` 标签 | Alertmanager rules |
| health check 历史 | prometheus 模块维护内存中的 health-check 状态历史 | `ceph healthcheck history ls` |
| Prometheus alerting rules + Alertmanager | 用户自定义规则 | Dashboard 的 Monitoring 页面 / webhook |
| Dashboard 通知接收器(notification receiver) | Alertmanager 通过 webhook 推送到 Dashboard | Dashboard 内部通知 |
| `alerts` mgr 模块 | 通过 SMTP 邮件发送集群健康变化通知 | 邮件 |
| daemon crash dumps | `crash` 模块收集,产生 `RECENT_CRASH` 健康告警 | `ceph crash ls-new` |
| 硬件健康(SMART / RedFish) | `devicehealth` / `node-proxy` 采集 | `ceph device ls`、`orch hardware status` |
> 💡 补充:上表是把本册各章节(monitoring/index、prometheus、alerts、crash、hardware-monitoring)中分散描述的告警来源归并到一处,源文本身没有这样一张汇总表。
### 1.3 Ceph 指标(Ceph metrics)
Ceph 的指标来源于**每个 Ceph 守护进程暴露的性能计数器(performance counters)**,这是 Ceph 的**原生指标(native Ceph metrics)**。
指标链路:
1. **性能计数器 → Prometheus 指标**:由 `ceph_exporter` 守护进程完成。
2. `ceph_exporter` **运行在集群的每一台主机上**,暴露一个端点,把**该主机上**运行的 Ceph 守护进程的性能计数器以 Prometheus 指标形式呈现。
3. 除了 `ceph_exporter`,Ceph Manager 的 **`prometheus` 模块** 额外暴露**整个集群层面(cluster as a whole)**的指标。
4. Ceph 提供一个 Prometheus 端点,可以从中获取完整可用指标列表;管理员、Grafana、Alertmanager 都可以对该端点执行查询。
5. Prometheus 及其相关系统接受 **PromQL** 表达式查询。
**如何找到 Prometheus 端点:**
```bash
# ceph orch ps --service_name prometheus
NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
prometheus.cephtest-node-00 cephtest-node-00.cephlab.com *:9095 running (103m) 50s ago 5w 142M - 2.33.4 514e6a882f6e efe3cbc2e521
```
据此可访问 `http://cephtest-node-00.cephlab.com:9095` 打开 Prometheus 服务界面(包含 targets 列表、表达式浏览器、Prometheus 自身指标)。
**完整指标清单(带描述)地址:**
```
http://cephtest-node-00.cephlab.com:9095/api/v1/targets/metadata
```
Ceph Dashboard 本身也提供丰富的图形与面板来展示最重要的集群与服务指标;本页的很多示例即取自 Dashboard 图形或由 Dashboard 暴露的指标外推得到。
### 1.4 Ceph 守护进程健康指标(Ceph daemon health metrics)
`ceph_exporter` 提供名为 **`ceph_daemon_socket_up`** 的指标,基于守护进程能否通过 admin socket 响应来判定其健康状态:
- `1` = 健康(healthy)
- `0` = 不健康(unhealthy)
即使守护进程「还活着」,只要报告 `ceph_daemon_socket_up=0`,也说明其功能出现了显著问题。因此该指标是**检测任意主要 Ceph 守护进程问题的极佳手段**。
**标签:**
| 标签 | 含义 |
|---|---|
| `ceph_daemon` | 在该主机上暴露 admin socket 的 Ceph 守护进程标识 |
| `hostname` | 运行该 Ceph 守护进程的主机名 |
示例:
```text
ceph_daemon_socket_up{ceph_daemon="mds.a",hostname="testhost"} 1
ceph_daemon_socket_up{ceph_daemon="osd.1",hostname="testhost"} 0
```
**查询最近 12 小时内曾经失去响应的任何 Ceph 守护进程:**
```promql
ceph_daemon_socket_up == 0 or min_over_time(ceph_daemon_socket_up[12h]) == 0
```
### 1.5 性能度量(Performance metrics)
以下指标**共同带有**的标签:
| 标签 | 含义 |
|---|---|
| `ceph_daemon` | 采集该指标的 Ceph 守护进程标识 |
| `instance` | 暴露该指标的 exporter 实例的 IP 地址 |
| `job` | Prometheus 抓取任务名 |
示例查询结果:
```text
ceph_osd_op_r{ceph_daemon="osd.0", instance="192.168.122.7:9283", job="ceph"} = 73981
```
**集群吞吐(Cluster throughput)** —— 查询 `ceph_osd_op_r_out_bytes` 与 `ceph_osd_op_w_in_bytes`:
```promql
# Writes (B/s):
sum(irate(ceph_osd_op_w_in_bytes[1m]))
# Reads (B/s):
sum(irate(ceph_osd_op_r_out_bytes[1m]))
```
**集群 I/O(operations / IOPS)** —— 查询 `ceph_osd_op_r`、`ceph_osd_op_w`:
```promql
# Writes (ops/s):
sum(irate(ceph_osd_op_w[1m]))
# Reads (ops/s):
sum(irate(ceph_osd_op_r[1m]))
```
**延迟(Latency)** —— 查询 `ceph_osd_op_latency_sum`,衡量从客户端请求到 OSD 开始传输数据的延迟:
```promql
sum(irate(ceph_osd_op_latency_sum[1m]))
```
### 1.6 OSD 性能
上面这些集群级指标均采集自 OSD 指标。通过指定合适的标签值或正则表达式,可以检索单个或一组 OSD 的性能指标:
```promql
# OSD 0 read latency
irate(ceph_osd_op_r_latency_sum{ceph_daemon=~"osd.0"}[1m]) / on (ceph_daemon) irate(ceph_osd_op_r_latency_count[1m])
# OSD 0 write IOPS
irate(ceph_osd_op_w{ceph_daemon=~"osd.0"}[1m])
# OSD 0 write thughtput (bytes)
irate(ceph_osd_op_w_in_bytes{ceph_daemon=~"osd.0"}[1m])
# OSD.0 total raw capacity available
ceph_osd_stat_bytes{ceph_daemon="osd.0", instance="cephtest-node-00.cephlab.com:9283", job="ceph"} = 536451481
```
### 1.7 物理存储设备性能(Physical storage drive performance)
把 Prometheus `node_exporter` 的指标与 Ceph 集群指标结合,可以推导出支撑 Ceph OSD 的物理存储介质性能信息。
```promql
# Read latency of device used by osd.0
label_replace(irate(node_disk_read_time_seconds_total[1m]) / irate(node_disk_reads_completed_total[1m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
# Write latency of device used by osd.0
label_replace(irate(node_disk_write_time_seconds_total[1m]) / irate(node_disk_writes_completed_total[1m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
# IOPS of device used by osd.0
# reads:
label_replace(irate(node_disk_reads_completed_total[1m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
# writes:
label_replace(irate(node_disk_writes_completed_total[1m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
# Throughput for device used by osd.0
# reads:
label_replace(irate(node_disk_read_bytes_total[1m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
# writes:
label_replace(irate(node_disk_written_bytes_total[1m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
# Physical drive utilization (%) for osd.0 in the last 5 minutes. Note that this value has limited mean for SSDs
label_replace(irate(node_disk_io_time_seconds_total[5m]), "instance", "$1", "instance", "([^:.]*).*") and on (instance, device) label_replace(label_replace(ceph_disk_occupation_human{ceph_daemon=~"osd.0"}, "device", "$1", "device", "/dev/(.*)"), "instance", "$1", "instance", "([^:.]*).*")
```
> 源文特别注明:物理盘利用率(% )这一数值**对 SSD 而言意义有限**。
### 1.8 Pool 指标
**共同标签:**
| 标签 | 含义 |
|---|---|
| `instance` | 提供该指标的 exporter 的 IP 地址 |
| `pool_id` | Pool 的数字标识 |
| `job` | Prometheus 抓取任务名 |
**Pool 专属指标:**
| 指标 | 说明 |
|---|---|
| `ceph_pool_metadata` | Pool 的元信息,可与其它指标联用为查询结果/图形补充信息。除上面三个公共标签外,还提供:`compression_mode`(压缩类型,取值 `lz4` / `snappy` / `zlib` / `zstd` / `none`,例:`compression_mode="none"`)、`description`(数据保护策略简述,含副本数或 EC profile,例:`description="replica:3"`)、`name`(Pool 名,例:`name=".mgr"`)、`type`(数据保护策略,`replicated` 或 EC,例:`type="replicated"`) |
| `ceph_pool_bytes_used` | 用户数据与元数据消耗的总原始容量(**经过复制或 EC 之后**) |
| `ceph_pool_stored` | Pool 中存放的客户端数据总量(**数据保护之前**) |
| `ceph_pool_compress_under_bytes` | Pool 中可被压缩的数据量 |
| `ceph_pool_compress_bytes_used` | Pool 中已压缩的数据量 |
| `ceph_pool_rd` | 每 Pool 的客户端读操作数(reads per second) |
| `ceph_pool_rd_bytes` | 每 Pool 的客户端读操作字节数 |
| `ceph_pool_wr` | 每 Pool 的客户端写操作数(writes per second) |
| `ceph_pool_wr_bytes` | 每 Pool 的客户端写操作字节数 |
**常用查询:**
```promql
# Total raw capacity available in the cluster:
sum(ceph_osd_stat_bytes)
# Total raw capacity consumed in the cluster (including metadata + redundancy):
sum(ceph_pool_bytes_used)
# Total client data stored in the cluster:
sum(ceph_pool_stored)
# Compression savings:
sum(ceph_pool_compress_under_bytes - ceph_pool_compress_bytes_used)
# Client IOPS for a specific pool
reads: irate(ceph_pool_rd[1m]) * on(pool_id) group_left(instance,name) ceph_pool_metadata{name=~"testrbdpool"}
writes: irate(ceph_pool_wr[1m]) * on(pool_id) group_left(instance,name) ceph_pool_metadata{name=~"testrbdpool"}
# Client throughput for a specific pool
reads: irate(ceph_pool_rd_bytes[1m]) * on(pool_id) group_left(instance,name) ceph_pool_metadata{name=~"testrbdpool"}
writes: irate(ceph_pool_wr_bytes[1m]) * on(pool_id) group_left(instance,name) ceph_pool_metadata{name=~"testrbdpool"}
```
### 1.9 RGW 指标
**共同标签:** `instance`(exporter IP)、`instance_id`(RGW 守护进程实例标识)、`job`(抓取任务名)。
```text
ceph_rgw_req{instance="192.168.122.7:9283", instance_id="154247", job="ceph"} = 12345
```
**通用指标(Generic metrics):**
| 指标 | 说明 |
|---|---|
| `ceph_rgw_metadata` | RGW 守护进程通用信息,可与其它指标联用提供上下文。额外提供:`ceph_daemon`(RGW 守护进程实例名,例 `ceph_daemon="rgw.rgwtest.cephtest-node-00.sxizyq"`)、`ceph_version`(RGW 版本,例 `ceph_version="ceph version 17.2.6 (...) quincy (stable)"`)、`hostname`(所在主机名,例 `hostname:"cephtest-node-00.cephlab.com"`) |
| `ceph_rgw_req` | 守护进程已处理的请求数(`GET`+`PUT`+`DELETE`),用于发现瓶颈与优化负载分布 |
| `ceph_rgw_qlen` | 守护进程的操作队列长度,用于发现瓶颈与优化负载分布 |
| `ceph_rgw_failed_req` | 被中止的请求,用于发现守护进程错误 |
**GET 操作指标:**
| 指标 | 说明 |
|---|---|
| `ceph_rgw_op_global_get_obj_lat_count` | `GET` 请求数量 |
| `ceph_rgw_op_global_get_obj_lat_sum` | `GET` 请求总延迟 |
| `ceph_rgw_op_global_get_obj_ops` | `GET` 请求总数 |
| `ceph_rgw_op_global_get_obj_bytes` | `GET` 请求传输的总字节数 |
**PUT 操作指标:**
| 指标 | 说明 |
|---|---|
| `ceph_rgw_op_global_put_obj_lat_count` | get 操作数量(源文原文为 "Number of get operations",疑为源文笔误,实际语境指 PUT 操作计数) |
| `ceph_rgw_op_global_put_obj_lat_sum` | `PUT` 操作总延迟时间 |
| `ceph_rgw_op_global_put_obj_ops` | `PUT` 操作总数 |
| `ceph_rgw_op_global_get_obj_bytes` | `PUT` 操作传输的总字节数(源文此处指标名写作 `ceph_rgw_op_global_get_obj_bytes`,疑为笔误,实际应为 `ceph_rgw_op_global_put_obj_bytes`,见下方 Bandwidth 查询示例) |
> 💡 补充:上面两处 PUT 指标名的疑误已在表格中标注。下方 "Bandwidth consumed by PUT operations" 查询使用的是 `ceph_rgw_op_global_put_obj_bytes`,可据此判定 PUT 字节数的真实指标名。
**其它常用查询:**
```promql
# Average GET latency
rate(ceph_rgw_op_global_get_obj_lat_sum[30s]) / rate(ceph_rgw_op_global_get_obj_lat_count[30s]) * on (instance_id) group_left (ceph_daemon) ceph_rgw_metadata
# Average PUT latency
rate(ceph_rgw_op_global_put_obj_lat_sum[30s]) / rate(ceph_rgw_op_global_put_obj_lat_count[30s]) * on (instance_id) group_left (ceph_daemon) ceph_rgw_metadata
# Requests per second
rate(ceph_rgw_req[30s]) * on (instance_id) group_left (ceph_daemon) ceph_rgw_metadata
# Total number of "other" operations (LIST, DELETE, etc)
rate(ceph_rgw_req[30s]) - (rate(ceph_rgw_op_global_get_obj_ops[30s]) + rate(ceph_rgw_op_global_put_obj_ops[30s]))
# GET latency per RGW instance
rate(ceph_rgw_op_global_get_obj_lat_sum[30s]) / rate(ceph_rgw_op_global_get_obj_lat_count[30s]) * on (instance_id) group_left (ceph_daemon) ceph_rgw_metadata
# PUT latency per RGW instance
rate(ceph_rgw_op_global_put_obj_lat_sum[30s]) / rate(ceph_rgw_op_global_put_obj_lat_count[30s]) * on (instance_id) group_left (ceph_daemon) ceph_rgw_metadata
# Bandwidth consumed by GET operations
sum(rate(ceph_rgw_op_global_get_obj_bytes[30s]))
# Bandwidth consumed by PUT operations
sum(rate(ceph_rgw_op_global_put_obj_bytes[30s]))
# Bandwidth consumed by RGW instance (PUTs + GETs)
sum by (instance_id) (rate(ceph_rgw_op_global_get_obj_bytes[30s]) + rate(ceph_rgw_op_global_put_obj_bytes[30s])) * on (instance_id) group_left (ceph_daemon) ceph_rgw_metadata
# HTTP errors and other request failures
rate(ceph_rgw_failed_req[30s])
```
### 1.10 CephFS 指标
**共同标签:** `ceph_daemon`(MDS 守护进程名)、`instance`(exporter 的 IP 与端口)、`job`(抓取任务名)。
```text
ceph_mds_request{ceph_daemon="mds.test.cephtest-node-00.hmhsoh", instance="192.168.122.7:9283", job="ceph"} = 1452
```
**重要指标:**
| 指标 | 说明 |
|---|---|
| `ceph_mds_metadata` | MDS 守护进程通用信息,可与其它指标联用提供上下文。额外提供:`ceph_version`(MDS 版本)、`fs_id`(CephFS 文件系统 ID)、`hostname`(主机名)、`public_addr`(所在主机的公共地址)、`rank`(MDS 的 rank) |
| `ceph_mds_request` | MDS 的总请求数 |
| `ceph_mds_reply_latency_sum` | 应答延迟总和 |
| `ceph_mds_reply_latency_count` | 应答延迟计数 |
| `ceph_mds_server_handle_client_request` | 客户端请求数 |
| `ceph_mds_sessions_session_count` | 会话计数 |
| `ceph_mds_sessions_total_load` | 总负载 |
| `ceph_mds_sessions_sessions_open` | 当前打开的会话数 |
| `ceph_mds_sessions_sessions_stale` | 当前 stale 的会话数 |
| `ceph_objecter_op_r` | 读操作数量 |
| `ceph_objecter_op_w` | 写操作数量 |
| `ceph_mds_root_rbytes` | 该守护进程管理的总字节数 |
| `ceph_mds_root_rfiles` | 该守护进程管理的总文件数 |
`ceph_mds_metadata` 示例:
```text
ceph_mds_metadata{ceph_daemon="mds.test.cephtest-node-00.hmhsoh", ceph_version="ceph version 17.2.6 (d7ff0d10654d2280e08f1ab989c7cdf3064446a5) quincy (stable)", fs_id="-1", hostname="cephtest-node-00.cephlab.com", instance="cephtest-node-00.cephlab.com:9283", job="ceph", public_addr="192.168.122.145:6801/118896446", rank="-1"}
```
**常用查询:**
```promql
# Total MDS read workload:
sum(rate(ceph_objecter_op_r[1m]))
# Total MDS daemons workload:
sum(rate(ceph_objecter_op_w[1m]))
# Read workload for a specific MDS
sum(rate(ceph_objecter_op_r{ceph_daemon=~"mdstest"}[1m]))
# Write workload for a specific MDS
sum(rate(ceph_objecter_op_r{ceph_daemon=~"mdstest"}[1m]))
# Average reply latency
rate(ceph_mds_reply_latency_sum[30s]) / rate(ceph_mds_reply_latency_count[30s])
# Total requests per second
rate(ceph_mds_request[30s]) * on (instance) group_right (ceph_daemon) ceph_mds_metadata
```
> 💡 补充:源文中 "Write workload for a specific MDS" 的示例查询仍使用 `ceph_objecter_op_r`(与上一行 Read workload 相同),疑为源文笔误;写负载语义上应使用 `ceph_objecter_op_w`。此处按源文原样保留,并提示读者注意。
### 1.11 块存储(RBD)指标
**默认情况下不采集 RBD image 级别的指标**,因为其基数(cardinality)可能很高,这样做有助于保障 Manager `prometheus` 模块的性能。
要产生 RBD image 指标,需要配置 Manager 选项 **`mgr/prometheus/rbd_stats_pools`**(详见第三章:「RBD IO statistics」)。
**共同标签:** `image`(image/卷名)、`instance`(运行 exporter 的节点)、`job`(Prometheus 抓取任务名)、`pool`(RBD pool 名)。
```text
ceph_rbd_read_bytes{image="test2", instance="cephtest-node-00.cephlab.com:9283", job="ceph", pool="testrbdpool"}
```
**重要指标:**
| 指标 | 说明 |
|---|---|
| `ceph_rbd_read_bytes` | RBD 读取字节数 |
| `ceph_rbd_write_bytes` | RBD image 写入字节数 |
| `ceph_rbd_read_latency_count` | RBD 读操作延迟计数 |
| `ceph_rbd_read_latency_sum` | RBD 读操作延迟总时长 |
| `ceph_rbd_read_ops` | RBD 读操作计数 |
| `ceph_rbd_write_ops` | RBD 写操作计数 |
| `ceph_rbd_write_latency_count` | RBD 写操作延迟计数 |
| `ceph_rbd_write_latency_sum` | RBD 写操作延迟总时长 |
**常用查询:**
```promql
# Average read latency
rate(ceph_rbd_read_latency_sum[30s]) / rate(ceph_rbd_read_latency_count[30s]) * on (instance) group_left (ceph_daemon) ceph_rgw_metadata
```
### 1.12 监控通道(Monitoring channels)
> 💡 补充:「监控通道」一词在本册中有两个官方语境,此处一并列出,避免混淆:
> ① 本节下表=**获取 Ceph 可观测数据的途径/通道**;
> ② `telemetry` 模块中的 **channel**=遥测上报的数据分类(basic / crash / device / ident / perf),见第八章。
| 通道 | 用途 |
|---|---|
| `ceph_exporter` 守护进程(每主机一个) | 把**该主机上** Ceph 守护进程的 perf counters 转为 Prometheus 指标;提供 `ceph_daemon_socket_up` 健康指标 |
| mgr `prometheus` 模块(HTTP 端点,默认 `9283`) | 暴露**集群整体**指标、pool/OSD/metadata 序列、health check 历史 |
| Prometheus server(默认 `9095`,自监控 `9090`) | 时序存储与 PromQL 查询;`/api/v1/targets/metadata` 可列出全部指标 |
| Prometheus `node_exporter`(`9100`) | 主机/磁盘/OS 层指标,用于与 Ceph OSD 指标关联(`ceph_disk_occupation_human`) |
| Alertmanager(默认 `9093`) | 接收/管理告警与静默(silence),可通过 webhook 推送给 Dashboard |
| Grafana | 可视化;Dashboard 通过 iframe 嵌入 |
| Ceph Dashboard | WebUI 监控 + 管理;提供集群日志、性能计数器、配置编辑器、告警页等 |
| Ceph RESTful API(`/api`) | 编程化获取集群状态与管理能力(OAuth2/JWT 认证) |
| Orchestrator CLI(`ceph orch ...`) | 命令行编排与状态查询 |
| `alerts` mgr 模块(SMTP) | 无外部监控基础设施时的邮件告警 |
| `crash` mgr 模块 | 守护进程崩溃转储的收集、归档与 `RECENT_CRASH` 健康告警 |
| `insights` mgr 模块 | 面向 Insights Core 分析框架的系统信息导出(含近 24 小时健康与崩溃汇总) |
| `telemetry` mgr 模块 | 向 Ceph 社区匿名上报集群使用与问题数据 |
| `telegraf` / `influx` mgr 模块 | 通过 socket listener / InfluxDB 输出时序数据 |
| Jaeger(`6799`/`16686`) | 分布式请求级追踪(RGW/OSD) |
| `node-proxy`(RedFish API + `ceph-mgr`) | 带外(Out-Of-Band)硬件清单与状态监控 |
| `ceph -s` / `ceph -w` / `ceph crash ls` 等 CLI | 人工排查与临时查看 |
### 1.13 硬件监控
源文 `monitoring/index.rst` 在最后指向硬件监控章节(本册第十章)。
> 引自:[Monitoring overview](https://docs.ceph.com/en/tentacle/monitoring/)
---
## 二、ceph-mgr 架构
来源页面:`mgr/index.rst`、`mgr/administrator.rst`
### 2.1 MGR 角色定位
**Ceph Manager 守护进程(ceph-mgr)与 monitor 守护进程一起运行**,用于提供**额外的监控能力**以及**面向外部监控/管理系统的接口**。
版本演进:
| Ceph 版本 | ceph-mgr 地位 |
|---|---|
| 11.x(*kraken*) | 可选组件(optional component) |
| 12.x(*luminous*)及以后 | **正常运行所必需**(required for normal operations) |
关键性质:
- **默认无需额外配置**,只需确保它在运行。
- 如果**没有 mgr 守护进程在运行**,你会看到相应的**健康告警**;且 `ceph status` 输出中的部分信息会**缺失或变成陈旧数据**,直到某个 mgr 启动为止。
- 应使用常规部署工具(如 ceph-ansible 或 cephadm)在每个 mon 节点上部署 ceph-mgr。**并不强制**把 mgr 与 mon 放在同一节点,但**几乎总是合理的选择**。
### 2.2 手动安装 ceph-mgr
通常使用 ceph-ansible 之类的工具部署;源文给出手动部署步骤:
**第一步:为守护进程创建认证密钥**
```bash
ceph auth get-or-create mgr.$name mon 'allow profile mgr' osd 'allow *' mds 'allow *'
```
**第二步:放置 keyring**
把该密钥放到 `mgr data` 路径下名为 `keyring` 的文件中。对集群名 `ceph`、mgr 名 `foo` 而言,路径为 `/var/lib/ceph/mgr/ceph-foo`,即 `/var/lib/ceph/mgr/ceph-foo/keyring`。
**第三步:启动 ceph-mgr 守护进程**
```bash
ceph-mgr -i $name
```
**第四步:确认已启动**
查看 `ceph status` 输出,应包含 mgr 状态行:
```text
mgr active: $name
```
### 2.3 解读 Manager 守护进程状态
集群健康状态中,每个 `ceph-mgr` 守护进程会处于以下**三种状态之一**:
| 状态 | 含义 |
|---|---|
| **active** | 该 Manager 守护进程已完全初始化,已准备好接收并执行命令。**任一时刻只有一个** Manager 处于该状态。 |
| **active (starting)** | 该 Manager 守护进程**已被选为** `active`,但尚未完成初始化。虽然它还不能执行命令,但运维人员仍可下发命令,这些命令会被**暂存**并在该 Manager 变为 `active` 后执行。**任一时刻只有一个** 处于该状态。 |
| **standby** | 当前不接收也不执行命令,但**随时可以接管**(如果当前 active Manager 不可用)。管理员可通过 `ceph mgr fail` **手动提升**一个 standby 为 active。所有非 `active` / `active (starting)` 的 Manager 守护进程都处于此状态。 |
`ceph status` 输出示例:
```text
$ ceph status
cluster:
id: b150f540-745a-460c-a566-376b28b95ac3
health: HEALTH_OK
services:
mon: 3 daemons, quorum a,b,c (age 47m) [leader: a]
mgr: x(active, starting, since 3s)
mds: 1/1 daemons up, 2 standby
osd: 4 osds: 4 up (since 47m), 4 in (since 47m)
data:
volumes: 1/1 healthy
pools: 4 pools, 177 pgs
objects: 24 objects, 451 KiB
usage: 4.0 GiB used, 400 GiB / 404 GiB avail
pgs: 177 active+clean
```
### 2.4 客户端认证(Client authentication)
Manager 是一个需要**新的 CephX capabilities** 的新守护进程。
- 如果从旧版本 Ceph 升级集群,或使用默认的安装/部署工具,admin 客户端**应该会自动获得**该 capability。
- 如果使用其它来源的工具,调用某些 ceph 集群命令时可能遇到 **EACCES 错误**。
- 解决办法:通过「修改用户 Capabilities」为客户端的 CephX capabilities 增加 `mgr allow \*` 段。
### 2.5 高可用(High availability)
| 项目 | 说明 |
|---|---|
| 部署建议 | 一般应在**每个运行 ceph-mon 的主机上**都部署一个 ceph-mgr,以获得同等可用性级别 |
| active 选举 | 默认**最先启动**的 ceph-mgr 实例被 monitors 置为 active,其余为 standby |
| 是否需要 quorum | **ceph-mgr 守护进程之间不需要 quorum** |
| 故障切换触发 | 若 active 守护进程**超过 `mon_mgr_beacon_grace`** 未向 monitors 发送 beacon,则被某个 standby 取代 |
| 主动抢占式切换 | 可用 `ceph mgr fail <mgr name>` **显式地**把一个 ceph-mgr 守护进程标记为 failed |
### 2.6 性能与可扩展性(Performance and Scalability)
**共享缓存:** 所有 mgr 模块共享一个缓存,可用以下命令启用:
```bash
ceph config set mgr mgr_ttl_cache_expire_seconds <seconds>
```
其中 `seconds` 是缓存的 Python 对象的生存时间(TTL)。
官方建议:
- 当 **OSD 数 ≥ 500** 或 **PG 数 ≥ 10k** 时,建议启用缓存并设 **TTL = 10 秒**,因为内部结构会变大,请求大结构时会导致延迟问题。
- 举例:一个含 1000 个 OSD 的 OSDMap 大约 **4MiB**。
- 在 3000 OSD 的集群上、重负载情况下,启用缓存带来过 **1.5 倍**的性能提升。
**查看缓存命中率:**
```bash
ceph daemon mgr.${MGRNAME} perf dump
```
在其中 `mgr.cache_hit` 与 `mgr.cache_miss` 可找到 mgr 缓存的命中/未命中比率。
**`mgr_ttl_cache_expire_seconds` 配置项:**
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| `mgr_ttl_cache_expire_seconds` | `uint` | `0`(默认值取自 src/common/options/global.yaml.in @ v20.2.4) | 设置缓存的生存时间(秒);**设为 0 表示禁用缓存**。`level: dev`,`services: [mgr]` |
### 2.7 自动 Stats 周期调优(Automatic Stats Period Tuning)
Manager 会**基于消息队列深度自动调整 `mgr_stats_period`**,以防止集群高活动期过载。该特性**默认启用**,由以下设置控制:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| `mgr_stats_period_autotune` | `bool` | `true`(默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;rst 源文亦注明 default: true) | 启用/禁用 stats period 的自动调优 |
| `mgr_stats_period_autotune_queue_threshold` | `int` | `100`(默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;rst 源文亦注明 default: 100) | 触发 stats period 增大的消息队列深度阈值 |
行为逻辑:
- 当**队列深度超过该阈值**时,stats period **被增大**以降低负载。
- 反之,若**队列深度保持较低**且 stats period 高于基线,则 period **被减小**以提升响应性。
- **无论这些设置如何,有效的 stats period 不会超过 60 秒**,以确保更新及时。
### 2.8 使用模块(Using modules)
**查看模块:**
```bash
ceph mgr module ls
```
若要看**被禁用模块**的详细元数据:
```bash
ceph mgr module ls --format=json-pretty
```
**启用/禁用模块:**
```bash
ceph mgr module enable <module>
ceph mgr module disable <module>
```
**模块被 enable 后的行为:** active ceph-mgr 守护进程会加载并执行它。对于**提供服务**的模块(例如 HTTP 服务器),模块在加载时可能会**发布其地址**。查看这些地址:
```bash
ceph mgr services
```
**standby 模式(standby mode):** 部分模块可实现一种特殊的 standby 模式,它**同时运行在 standby 与 active 的 ceph-mgr 守护进程上**。这使得提供服务的模块可以在客户端尝试连接 standby 时,**把客户端重定向到 active 守护进程**。
**启用 Dashboard 模块的完整示例:**
```bash
ceph mgr module ls
```
```json
{
"enabled_modules": [
"status"
],
"disabled_modules": [
"dashboard"
]
}
```
```bash
ceph mgr module enable dashboard
ceph mgr module ls
```
```json
{
"enabled_modules": [
"status",
"dashboard"
],
"disabled_modules": [
]
}
```
```bash
ceph mgr services
```
```json
{
"dashboard": "http://myserver.com:7789/"
}
```
**`mgr_initial_modules`:** 集群**首次启动**时,使用 `mgr_initial_modules` 设置来覆盖要启用哪些模块。但**该设置在集群此后的生命周期中被忽略**——只能用于引导(bootstrapping)。例如,首次启动 monitor 守护进程之前,可在 `ceph.conf` 中加入:
```ini
[mon]
mgr_initial_modules = dashboard balancer
```
### 2.9 模块 Pool(Module Pool)
Manager 会创建一个供其模块存储状态的 pool,名为 **`.mgr`**(前缀 `.` 表示这是保留的 pool 名)。
> **注意:** 在 Quincy 之前,`devicehealth` 模块会创建一个 `device_health_metrics` pool 来存放设备 SMART 统计。从 Quincy 起,该 pool 会被**自动重命名**为通用的 manager 模块 pool。
### 2.10 调用模块命令(Calling module commands)
若某模块实现了命令行钩子,其命令将作为**普通的 Ceph 命令**被访问。Ceph 会自动把模块命令整合进标准 CLI 接口,并**路由到相应模块**:
```bash
ceph <command | help>
```
### 2.11 配置项(Configuration)
以下为 `mgr/administrator.rst` 中列出的全部配置项,逐项列出:
| 配置项 | 类型 | 默认值 | 说明 | 默认值来源 |
|---|---|---|---|---|
| `mgr_module_path` | `str` | `@CEPH_INSTALL_DATADIR@/mgr`(构建期占位,实际通常为 `/usr/share/ceph/mgr` 之类安装路径) | Manager 模块所在的文件系统路径 | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4,源文中为构建占位符 `@CEPH_INSTALL_DATADIR@/mgr`;`level: advanced`) |
| `mgr_initial_modules` | `str` | `iostat nfs nvmeof` | 集群**首次启动**时要启用的 Manager 模块列表;逗号或空格分隔。此后更新请用 `mgr module [enable|disable]` 命令。flags: `no_mon_update`、`cluster_create` | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: basic`) |
| `mgr_disabled_modules` | `str` | `@mgr_disabled_modules@`(构建期占位符,源文未给出具体字面量) | 永远不会被加载的 Manager 模块列表(逗号分隔)。该列表在 Manager 启动时读取;其中的模块**根本不会被加载**。flags: `startup`;`level: advanced` | 默认值取自 src/common/options/mgr.yaml.in @ v20.2.4(为构建占位符,具体值文档未明确) |
| `mgr_standby_modules` | `bool` | `true` | 当 mgr 处于 standby 时,以 standby(redirect)模式启动模块。默认 standby 模块会用 **HTTP redirect** 应答进入的请求,把用户重定向到 active manager,这样用户可以把浏览器指向任意一个 manager | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: advanced`) |
| `mgr_data` | `str` | `/var/lib/ceph/mgr/$cluster-$id` | Manager 数据目录的文件系统路径,其中包含 keyring 及其它数据 | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: advanced`) |
| `mgr_tick_period` | `secs` | `2` | 向 monitor 发送 beacon 消息的周期(秒),以及其它周期性检查的间隔 | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: advanced`) |
| `mon_mgr_beacon_grace` | `secs` | `30` | 从最后一次 beacon 算起,超过该秒数后 monitor 将把一个 manager 守护进程**标记为 failed** | (默认值取自 src/common/options/mon.yaml.in @ v20.2.4;`level: advanced`,`services: [mon]`) |
| `mgr_stats_period` | `int` | `5` | OSD/MDS 向 manager 上报 stats 的周期(秒)。用于调节从守护进程采集时间序列数据的粒度;若 manager CPU 负载过高或不需要最新性能计数器数据,可调大 | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: basic`,`services: [mgr, common]`) |
| `mgr_stats_period_autotune` | `bool` | `true` | 基于 Manager 消息队列深度自动调整 `mgr_stats_period` | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: basic`) |
| `mgr_stats_period_autotune_queue_threshold` | `int` | `100` | 触发 `mgr_stats_period` 自动增大的消息队列深度阈值 | (默认值取自 src/common/options/mgr.yaml.in @ v20.2.4;`level: advanced`) |
> 💡 补充:源文 `administrator.rst` 的 Configuration 段以 `.. confval::` 列出上述 11 个选项,但**没有** `mgr_ttl_cache_expire_seconds`;后者出现在 2.6 节的命令示例中,本册在 `global.yaml.in` 中查到其默认值为 `0`。
### 2.12 模块机制(模块开发视角)
来源页面:`mgr/modules.rst`(约 31KB,为 ceph-mgr 模块开发者指南,本节择其与运维理解相关的部分)
**模块是什么:** 在 `pybind/mgr/` 下创建一个 Python 模块,目录内**必须**包含名为 `module.py` 的文件,其中定义一个继承自 `MgrModule` 的类。
**最重要可覆写的方法:**
| 方法 | 用途 |
|---|---|
| `serve()` | 服务器型模块(server-type modules)使用;该函数应当**永久阻塞** |
| `notify()` | 当模块需要在**新的集群数据可用时**采取行动时实现 |
| `handle_command()` | 当模块暴露 CLI 命令时实现;**该方式已被弃用**,详见「Exposing commands」 |
部分模块会与外部编排器对接以部署 Ceph 服务,这类模块还会继承 `Orchestrator`(在 `MgrModule` 基础上增加方法)。
**安装模块:** 模块出现在 `mgr module path` 配置指定的位置后,即可启用:
```bash
ceph mgr module enable mymodule
```
> ⚠️ **注意:`MgrModule` 接口并不稳定**,因此维护在 Ceph 代码树之外的任何模块,在更新或更旧版本的 Ceph 上运行时都可能失效。
**日志(Logging):**
- 模块有一个 `log_level` 选项,指定模块当前的 Python 日志级别。
- 查询/修改:
```bash
ceph config get mgr mgr/<module_name>/log_level
ceph config set mgr mgr/<module_name>/log_level <info|debug|critical|error|warning|>
```
- 模块启动时使用的日志级别**由 mgr 守护进程当前的日志级别决定**,除非之前用 `config set ...` 显式设置过 `log_level`。mgr 守护进程日志级别到 Python 日志级别的映射:
| mgr 守护进程日志级别 | Python 日志级别 |
|---|---|
| `<= 0` | CRITICAL |
| `<= 1` | WARNING |
| `<= 4` | INFO |
| `<= +inf` | DEBUG |
- 取消模块的日志级别设置、回落到 mgr 守护进程日志级别:
```bash
ceph config set mgr mgr/<module_name>/log_level ''
```
- **模块独立日志文件:** 默认模块的日志消息由 Ceph 日志层处理,记录在 mgr 守护进程日志文件中。也可以让模块日志写入自己的文件,文件位于 Manager 守护进程日志文件同一目录,命名模式为:
```text
<mgr_daemon_log_file_name>.<module_name>.log
```
启用/查询/禁用模块文件日志:
```bash
ceph config set mgr mgr/<module_name>/log_to_file true
ceph config get mgr mgr/<module_name>/log_to_file
ceph config set mgr mgr/<module_name>/log_to_file false
```
> 注意:启用模块文件日志后,模块日志消息**停止写入** Manager 守护进程日志文件,**只写入**模块自己的日志文件。
**暴露命令(Exposing commands):** 两种方式
1. `@CLICommand` 装饰器(推荐)。也可用 `@CLIReadCommand`(只需读权限)或 `@CLIWriteCommand`(只需写权限)。
2. 模块类的 `COMMANDS` 属性(旧方式)。
`@CLICommand` 示例:
```python
@CLICommand('antigravity send to blackhole',
perm='rw')
def send_to_blackhole(self, oid: str, blackhole: Optional[str] = None, inbuf: Optional[str] = None):
'''
Send the specified object to black hole
'''
obj = self.find_object(oid)
if obj is None:
return HandleCommandResult(-errno.ENOENT, stderr=f"object '{oid}' not found")
...
return HandleCommandResult(stdout=f"the black hole swallowed '{oid}'")
```
要点:
- 第一个参数是命令「名字」;Ceph 命令很多,通常用公共前缀分组(如上例 `antigravity`)。
- 方法参数的**类型注解是强制的**,这样 `ceph` CLI 才能正确报告用法,manager 守护进程才能在传给处理函数前把序列化的参数转换成期望类型;类型实现得当还能对参数做健全性检查。
- 参数名属于命令接口的一部分,改名时要考虑向后兼容;但 **`inbuf` 参数名不可更改**,它用于传递 `ceph --in-file` 选项指定的文件内容。
- 方法的 **docstring** 用作命令描述。
- `ceph --help` 输出中会自动生成形如 `antigravity send to blackhole <oid> [<blackhole>] Send the specified object to black hole` 的用法行。
`COMMANDS` 方式示例:
```python
COMMANDS = [
{
"cmd": "foobar name=myarg,type=CephString",
"desc": "Do something awesome",
"perm": "rw",
# optional:
"poll": "true"
}
]
```
- `cmd` 部分的解析方式与 Ceph 内部 mon 与 admin socket 命令一致(参见 Ceph 源码 `mon/MonCommands.h`)。
- `poll` 字段可选,**默认 False**;它告知 `ceph` CLI 应重复调用该命令并输出结果(参见 `ceph -h` 及其 `--period` 选项)。
- 每个命令应返回三元组 `(retval, stdout, stderr)`:`retval` 是表示 libc 错误码的整数(如 EINVAL、EPERM,无错误为 0);`stdout` 是任意非错误输出字符串;`stderr` 是进度或错误说明输出字符串(类似 stderr)。两者都可为空。
**响应与格式化:**
- 处理 manager 命令的函数应返回类型签名 `Tuple[int, str, str]` 的三元组;也可用 `mgr_module.HandleCommandResult` 类型代替。
- **异常处理两种做法:**
1. 什么都不做,让异常冒泡到 manager —— manager 会自动把返回码设为 `-EINVAL`,并在错误输出中记录 traceback(可能很长)。
2. 在 try-except 中处理异常,转换成更合适的错误码(例如把 `KeyError` 转成 `-ENOENT`),并可设置更具体、可操作的错误输出。
- **结构化输出:** 较新版本的 Ceph 中,manager 命令常被设计为返回结构化输出(JSON/YAML/XML 等,最常见是 JSON)。**自 Ceph Reef 起**,`object_format` 模块提供了一组新装饰器,用于自动处理输出格式化与异常。多数新代码应使用 **`Responder`** 装饰器。
```python
@CLICommand('antigravity list wormholes', perm='r')
@Responder()
def list_wormholes(self, oid: str, details: bool = False) -> List[Dict[str, Any]]:
'''List wormholes associated with the supplied oid.
'''
with self.open_wormhole_db() as db:
wormholes = db.query(oid=oid)
if not details:
return [{'name': wh.name} for wh in wormholes]
return [{'name': wh.name, 'age': wh.get_age(), 'destination': wh.dest}
for wh in wormholes]
```
- `Responder` 自动把 Python 对象转换成带格式化输出的响应元组,默认支持 JSON 与 YAML;命令行可用 `--format` 选择,未指定时**返回 JSON**。自动格式化适用于任何基本 Python 类型;其它对象若满足 `SimpleDataProvider` 协议(提供 `to_simplified` 方法)也可自动格式化。
- 错误处理:`Responder` 可自动把继承自 `ErrorResponseBase` 的异常转换为响应元组。常用 `ErrorResponse`(可直接使用,带错误输出与返回值参数;也可用 `wrap` 类方法从已有异常构造,会自动使用异常文本及可用时的 `errno` 属性)。
- 其它装饰器:
- `ErrorResponseHandler`:必须返回 manager 响应元组、但仍想以异常方式处理错误时使用;只处理异常,不格式化输出。
- `EmptyResponder`:成功时**不产生任何输出**(避免 `{}` / `[]`),遵循「沉默是金(Rule of Silence)」;被装饰函数应返回 `None`。
**配置项(Module configuration options):**
- 模块使用 `set_module_option` / `get_module_option` 加载与存储配置。
- 必须在 `MODULE_OPTIONS` 类属性中声明:
```python
MODULE_OPTIONS = [
Option(name="check_interval",
level=OptionLevel.ADVANCED,
default=60,
type="secs",
desc="The interval in seconds to check the inbox",
long_desc="The interval in seconds to check the inbox. Set to 0 to disable the check",
min=0,
runtime=True)
]
```
支持的属性(**逐项列出**):
| 属性 | 是否必填 | 说明 |
|---|---|---|
| `name` | **必填**(唯一必填项) | 选项名 |
| `type` | 可选,默认 `str` | 数据类型,见下表 |
| `desc` | — | 简短描述(可以是句子片段) |
| `long_desc` | — | 详细描述(完整句子或段落) |
| `default` | — | 默认值 |
| `min` / `max` | — | 允许的最小/最大值 |
| `enum_allowed` | — | 对 `str` 类型:允许的字符串值列表,集合外的值会被拒绝 |
| `see_also` | — | 相关选项名列表(仅用于文档) |
| `tags` | — | 用于分类的标签列表(仅用于文档) |
| `runtime` | 默认 `False` | 该选项是否可在模块加载后更新 |
| `level` | — | 选项级别(如 `OptionLevel.ADVANCED`) |
`type` 支持的类型:
| 类型 | 含义 |
|---|---|
| `uint` | 无符号 64 位整数 |
| `int` | 有符号 64 位整数 |
| `str` | 字符串 |
| `float` | 双精度浮点 |
| `bool` | 布尔 |
| `addr` | 用于 peer 通信的 Ceph messenger 地址 |
| `addrvec` | 逗号分隔的 Ceph messenger 地址列表 |
| `uuid` | `RFC 4122` 定义的 UUID |
| `size` | 大小值(存为 uint64_t) |
| `secs` | 时间跨度,格式 `"<number><unit>..."`,如 `"3h 2m 1s"` 或 `"3weeks"` |
| `millisecs` | 毫秒时间跨度 |
`secs` 支持的单位:`s`、`sec`、`second(s)`、`m`、`min`、`minute(s)`、`h`、`hr`、`hour(s)`、`d`、`day(s)`、`w`、`wk`、`week(s)`、`mo`、`month(s)`、`y`、`yr`、`year(s)`。
要点:
- 若对未在 `MODULE_OPTIONS` 中声明的选项使用 `set_module_option` / `get_module_option`,**会抛异常**。
- 用户也可用 `ceph config set` 修改,Manager 模块的配置项名形如 **`mgr/<module name>/<option>`**。
- **本地化(localized)配置**:若某配置项因 Manager 运行在哪个节点而不同(例如监听地址),使用 `get_localized_module_option` / `set_localized_module_option`。外部可用 `ceph config set` 设置,键名形如 **`mgr/<module name>/<mgr id>/<option>`**。
- 使用提示:
- **读很快**:ceph-mgr 保存本地内存副本,多数情况下每次使用选项时直接 `get_module_option` 即可,不必复制到变量。
- **写会阻塞**直到值被持久化(即往返一次 monitor),但其它线程的读会立即看到新值。
- 若用户从命令行 `config set`,新值对 `get_module_option` 立即可见;不过 mon→mgr 的更新是异步的,`config set` 会比新值在 mgr 上可见**早几分之一秒**返回。
- **删除配置值(恢复默认)**:给 `set_module_option` 传 `None`。
**KV store:**
- 模块可访问一个**私有的(per-module)键值存储**,用 monitor 的 "config-key" 命令实现,通过 `set_store` / `get_store` 访问。
- 读快(本地缓存);写阻塞于持久化并往返 monitor。
- 可在 ceph-mgr 之外用 `ceph config-key [get|set]` 访问,键名约定与配置选项相同。
- ⚠️ **从 ceph-mgr 外部更新的值,运行的模块要等到下次重启才能看到**。应劝阻用户从外部访问模块 KV 数据;若确需用户填充数据,模块应提供专门的命令来设置。
- 用 `get_store_prefix` 函数枚举某个前缀下的所有键。
**访问集群数据:**
- 模块可访问 mgr 维护的 Ceph 集群状态的**内存副本**,访问器函数以 `MgrModule` 成员形式暴露。
- 访问集群或守护进程状态的调用一般是从 Python 进入原生 C++ 例程,有一定开销,但远小于调用 REST API 或 SQL 数据库。
- **没有一致性保证**:例如某个 OSD 可能存在于 OSDMap 中但没有 metadata,反之亦然。健康集群上这些是非常短暂的瞬态,但模块应能应对。
- ⚠️ 这些访问器**不可在模块的 `__init__` 函数中调用**,否则会导致循环加锁异常。
主要访问器(源文以 `automethod` 列出):`get`、`get_server`、`list_servers`、`get_metadata`、`get_daemon_status`、`get_unlabeled_perf_schema`、`get_unlabeled_counter`、`get_latest_unlabeled_counter`、`get_perf_schema`、`get_latest_counter`、`get_mgr_id`、`get_daemon_health_metrics`。
**暴露健康检查(Exposing health checks):** 模块可以产生**一等公民(first class)的 Ceph 健康检查**,会显示在 `ceph status` 输出以及其它报告集群健康的地方。若用 `set_health_checks` 报告问题,**务必在问题消失时再次以空 dict 调用它来清除**。
**如果 mons 都挂了怎么办:** manager 守护进程的大部分状态(如集群 map)来自 monitor。若 monitor 集群不可访问,当前 active 的 manager 会**基于内存中最新看到的状态继续运行**。如果模块要向用户展示集群状态,可能不希望误导用户展示过期状态,可用 `have_mon_connection` 检查当前是否与 monitor 集群有连接。
**报告模块无法运行:** 若模块因任何原因无法运行(例如缺少依赖),可实现 `can_run` 函数。注意:只有当模块**始终可被 import** 时该机制才正常工作——如果 import 的依赖可能缺失,应放在 try/except 块中,这样即使依赖缺失,模块也能加载到足以使用 `can_run`。
**发送命令:** 提供非阻塞设施向集群发送 monitor 命令:`send_command`。
**接收通知(Receiving notifications):** manager 守护进程可在关键集群状态(如集群 map)更新时对 active 模块调用 `notify` 方法。
> **重要:** 只有**显式声明**对某一通知类型感兴趣的模块才会收到它。
```python
NOTIFY_TYPES = [
NotifyType.mon_map,
NotifyType.osd_map,
NotifyType.crush_map,
...
]
```
通知**不包含实际数据**,只是提示「有东西变了」;模块需自行用 `mgr.get(...)` 获取最新数据。
**访问 RADOS 或 CephFS:** 使用模块实例的 `rados` 属性(为使用 mgr 守护进程已有 Ceph context 构造的 `rados.Rados` 实例),**务必使用这个专门构造的实例**而不是自己构造。使用 libcephfs 时,用 `create_with_rados` 从 `MgrModule.rados` 构造以继承正确的 context。记住:模块可能在集群其它部分宕机时仍在运行,**不要假设** librados / libcephfs 调用会及时返回,应考虑超时或阻塞。
**实现 standby 模式:** 对某些模块而言,在 standby manager 守护进程上也运行是有用的(例如 HTTP 服务器可以从 standby 返回 HTTP redirect,让用户把浏览器指向任意 manager daemon 而不必关心哪个是 active)。
- Standby manager 守护进程会在每个模块中寻找 `StandbyModule` 的子类。**找不到则该模块在 standby 守护进程上完全不被使用**;找到则调用其 `serve` 方法。
- `StandbyModule` 的实现必须继承自 `mgr_module.MgrStandbyModule`。
- `MgrStandbyModule` 的接口相比 `MgrModule` **受限很多**——**没有任何 Ceph 集群状态可用**。`serve` 与 `shutdown` 用法同普通模块类;`get_active_uri` 方法让 standby 模块发现其 active peer 的地址以便做重定向。
- 可参考 `dashboard` 模块的源码。
**模块间通信:** 模块可以调用其它模块的成员函数(`remote`)。务必处理 `ImportError` 以应对目标模块未启用的情况。若远端方法抛出 Python 异常,会在调用方被转成 `RuntimeError`,消息字符串描述原始异常。若逻辑要干净地处理某些错误,更好的做法是**修改远端方法返回错误值而不是抛异常**。目前(撰写时)模块间调用**不做拷贝或序列化**,返回 Python 对象时返回的是引用;**建议不要依赖**这种引用传递,未来实现可能改为序列化参数与返回值。
**干净关闭:** 若模块实现了 `serve()`,也应实现 `shutdown()` 以干净关闭;行为不端的模块可能阻止 ceph-mgr 干净关闭。
**限制:** 不能在模块的 `__init__()` 方法中回调 C++ 代码。例如此时调用 `self.get_module_option()` 会导致 ceph-mgr 断言失败。对实现了 `serve()` 的模块,通常应把大部分初始化放在 `serve()` 中。
**调试:** 除日志设施外,还可用 `ceph_mgr_repl.py` 进入与 `selftest` 模块对话的交互式 shell。使用步骤:
1. 准备好一个 Ceph 集群
2. 启用 `selftest` 模块
3. 设置必要的环境变量
4. 启动工具
示例会话:
```console
$ cd build
$ MDS=0 MGR=1 OSD=3 MON=1 ../src/vstart.sh -n -x
$ bin/ceph mgr module enable selftest
$ ../src/pybind/ceph_mgr_repl.py --show-env
$ export PYTHONPATH=/home/me/ceph/src/pybind:/home/me/ceph/build/lib/cython_modules/lib.3:/home/me/ceph/src/python-common:$PYTHONPATH
$ export LD_LIBRARY_PATH=/home/me/ceph/build/lib:$LD_LIBRARY_PATH
$ export PYTHONPATH=/home/me/ceph/src/pybind:/home/me/ceph/build/lib/cython_modules/lib.3:/home/me/ceph/src/python-common:$PYTHONPATH
$ export LD_LIBRARY_PATH=/home/me/ceph/build/lib:$LD_LIBRARY_PATH
$ ../src/pybind/ceph_mgr_repl.py
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
(MgrModuleInteractiveConsole)
[mgr self-test eval] >>> print(mgr.version)
ceph version Development (no_version) quincy (dev)
[mgr self-test eval] >>> from timeit import timeit
[mgr self-test eval] >>> timeit(mgr.get_mgr_id)
0.16303414600042743
[mgr self-test eval] >>>
```
若要与该工具对话的不是 `selftest` 模块,可像 `selftest` 添加 `mgr self-test eval` 那样给你的模块加一个命令;或把 `eval()` 方法提升为一个 `Mixin` 类并让你的 `MgrModule` 子类继承它,然后定义命令。假设命令前缀是 `mgr my-module eval`,则运行:
```bash
../src/pybind/ceph_mgr_repl.py --prefix "mgr my-module eval"
```
**是否还缺什么:** ceph-mgr 的 Python 接口并非一成不变。若有当前接口无法满足的需求,可在 ceph-devel 邮件列表提出。虽然希望避免接口膨胀,但如果有充分理由,把已有数据暴露给 Python 代码通常并不难。
> 引自:[ceph-mgr administrator's guide](https://docs.ceph.com/en/tentacle/mgr/administrator/)
> 引自:[ceph-mgr module developer's guide](https://docs.ceph.com/en/tentacle/mgr/modules/)
---
## 三、Prometheus 模块
来源页面:`mgr/prometheus.rst`(约 15KB)
### 3.1 模块原理
Manager 的 `prometheus` 模块实现了一个 **Prometheus exporter**,从 Manager 这个**采集点(collection point)**暴露 Ceph 性能计数器。
工作流程:
1. Manager 从**所有 `MgrClient` 进程**(包括 mons 和 OSDs)接收 **`MMgrReport` 消息**,其中带有性能计数器的 **schema 数据**与**计数器数据**。
2. Manager 维护一个**最新样本的环形缓冲区(circular buffer)**。
3. 该模块**监听一个 HTTP 端点**,被抓取(scraped)时取出每个计数器的最新样本。
4. **HTTP 路径与查询参数被忽略**。
5. **所有**现存计数器、**所有**上报实体的数据,都会以 **Prometheus exposition 格式**返回。
### 3.2 启用
```bash
ceph mgr module enable prometheus
```
### 3.3 配置项(逐项)
> ⚠️ **注意:`prometheus` Manager 模块必须重启才能应用配置变更。**
| 配置项(完整键名) | 说明 | 默认值 | 默认值来源 |
|---|---|---|---|
| `mgr/prometheus/server_addr` | 监听地址。默认在主机**所有 IPv4 与 IPv6 地址**上接受 HTTP 请求 | `::`(所有 IPv4/IPv6 地址) | rst 源文明确「默认绑定所有 IPv4 和 IPv6 地址」;`*.yaml.in` 中**无**该模块选项(模块选项定义在模块 Python 源码的 `MODULE_OPTIONS` 中),故精确字面默认值文档未明确 |
| `mgr/prometheus/server_port` | 监听端口 | `9283` | rst 源文明确「默认在端口 `9283`」;该端口已在 Prometheus 的 [Default port allocations](https://github.com/prometheus/prometheus/wiki/Default-port-allocations) 注册 |
| `mgr/prometheus/scrape_interval` | 抓取间隔(秒)。**必须与 Prometheus 的 scrape interval 匹配才能正常工作**。该值在模块内用于**缓存目的**以及判定缓存是否陈旧。**不建议使用小于 10 秒**;**推荐 15 秒**,某些情况下增大也有用 | 文档未明确(源文仅给出推荐值 15) | 源文未给出字面默认;`*.yaml.in` 中无此项 |
| `mgr/prometheus/cache` | 是否启用缓存。**默认启用**。大集群(>1000 OSDs)取指标耗时显著,无缓存时(尤其配合多个 Prometheus 实例)可能压垮 manager 导致无响应或崩溃 | `true`(源文:「the cache is enabled by default」) | 源文明确默认启用 |
| `mgr/prometheus/stale_cache_strategy` | 缓存陈旧时的行为:默认返回 **HTTP 503(service unavailable)**;设为 `return` 则返回可能陈旧的缓存内容;设为 `fail` 返回 service unavailable | `fail`(源文:「By default, it will return a 503 HTTP status code (service unavailable)」) | 源文明确默认行为 |
| `mgr/prometheus/rbd_stats_pools` | 采集 RBD 每镜像 IO 统计的 pool 列表,逗号或空格分隔的 `pool[/namespace]` 条目。若未指定 RBD namespace,则采集该 pool 中**所有 namespace** 的统计。可用通配符 `*` 表示所有 pool 或 namespace | 空(**默认不采集 RBD image 指标**) | 源文明确「By default RBD metrics for images are not gathered」 |
| `mgr/prometheus/rbd_stats_pools_refresh_interval` | 刷新可用 image 列表的周期(秒);若发现此前未知的 RBD image 的统计数据,模块会**提前强制刷新** | `300`(5 分钟) | rst 源文明确「defaults to 300 seconds (5 minutes)」 |
| `mgr/prometheus/standby_behaviour` | 在反向代理/负载均衡器之后使用时,可切换为 `error` 模式简化 active 实例的发现:设为 `error` 时,从 standby 实例请求 `/` 会返回 HTTP 错误;设回 `default` 恢复默认行为 | `default` | 源文明确「To switch back to the default behaviour, simply set the config key to `default`」 |
| `mgr/prometheus/standby_error_status_code` | 上述 `error` 模式下的 HTTP 响应码,**默认 500**;**合法取值 400–599** | `500` | 源文明确「The default error code is 500」 |
| `mgr/prometheus/exclude_perf_counters` | 随着 `ceph-exporter` 守护进程的引入,`prometheus` 模块**默认不再导出 Ceph 守护进程 perf counters** 作为 Prometheus 指标。设该选项为 `false` 可**重新启用**导出这些指标 | `true`(默认排除 perf counters) | 源文明确「will no longer export Ceph daemon perf counters as Prometheus metrics by default」 |
| `mgr/prometheus/healthcheck_history_max_entries` | 内存中跟踪的**唯一 health check 条目最大数量**,用于避免大规模或长生命周期集群中内存无界增长 | `1000` | rst 源文明确「default: 1000」 |
### 3.4 监听地址与端口配置
```bash
ceph config set mgr mgr/prometheus/server_addr 0.0.0.0
ceph config set mgr mgr/prometheus/server_port 9283
```
### 3.5 抓取间隔(scrape_interval)
> ⚠️ **警告:该模块的 `mgr/prometheus/scrape_interval` 必须与 Prometheus 的抓取间隔匹配,才能正常工作。**
模块内的抓取间隔用于**缓存目的**以及**判定缓存何时陈旧**。
- **不建议使用小于 10 秒**的抓取间隔。
- **推荐使用 15 秒**作为抓取间隔;某些情况下增大间隔可能有用。
设置示例:
```bash
ceph config set mgr mgr/prometheus/scrape_interval 20
```
### 3.6 缓存与陈旧缓存策略
在**大集群(>1000 OSDs)**上,取回指标的时间可能变得显著。**如果没有缓存**,prometheus manager 模块(尤其配合多个 Prometheus 实例时)**可能压垮 manager,导致 Ceph Manager 实例无响应或崩溃**。因此**缓存默认启用**。
这意味着**缓存有可能变得陈旧(stale)**。当**从 Ceph 取回指标的时间超过配置的 `mgr/prometheus/scrape_interval`** 时,缓存即被视为陈旧。
此时会**记录一条 warning 日志**,并且模块会:
- 要么以 **503 HTTP 状态码**(service unavailable)响应;
- 要么返回缓存内容,**即使它可能已陈旧**。
该行为可配置,**默认是返回 503**。
**配置为返回可能陈旧的数据:**
```bash
ceph config set mgr mgr/prometheus/stale_cache_strategy return
```
**配置为返回 "service unavailable":**
```bash
ceph config set mgr mgr/prometheus/stale_cache_strategy fail
```
**如果你确信不需要缓存,可以禁用它:**
```bash
ceph config set mgr mgr/prometheus/cache false
```
### 3.7 反向代理 / 负载均衡后的 standby 行为
如果你在反向代理或负载均衡器之后使用 `prometheus` 模块,可切换到 `error` 模式来**简化 active 实例的发现**:
```bash
ceph config set mgr mgr/prometheus/standby_behaviour error
```
设置后,`prometheus` 模块在**从 standby 实例请求 `/`** 时会返回 HTTP 错误。默认错误码是 500,可用以下命令配置 HTTP 响应码:
```bash
ceph config set mgr mgr/prometheus/standby_error_status_code 503
```
**合法错误码范围:400–599。**
切回默认行为:
```bash
ceph config set mgr mgr/prometheus/standby_behaviour default
```
### 3.8 Ceph 健康检查(Ceph Health Checks)
`prometheus` 模块**跟踪并维护 Ceph 健康检查的历史**,把它们作为**离散指标**暴露给 Prometheus server,从而允许为**特定 health check 事件**配置 Alertmanager 规则。
指标形式:
```text
# HELP ceph_health_detail healthcheck status by type (0=inactive, 1=active)
# TYPE ceph_health_detail gauge
ceph_health_detail{name="OSDMAP_FLAGS",severity="HEALTH_WARN"} 0.0
ceph_health_detail{name="OSD_DOWN",severity="HEALTH_WARN"} 1.0
ceph_health_detail{name="PG_DEGRADED",severity="HEALTH_WARN"} 1.0
```
**含义:** `0` = inactive(未触发),`1` = active(正在触发)。
模块还维护一份**内存中的 health-check 状态历史**。默认历史**最多保留 1000 条**条目,该上限可通过运行时选项 `mgr/prometheus/healthcheck_history_max_entries` 配置(默认 1000)。此设置有助于**避免大规模或长生命周期集群中内存无界增长**。
**获取与清除 health check 历史:**
```bash
ceph healthcheck history ls [--format {plain|json|json-pretty}]
ceph healthcheck history clear
```
`ceph healthcheck history ls` 提供自上次 `clear` 命令以来集群遇到过的健康检查概览:
```text
Healthcheck Name First Seen (UTC) Last seen (UTC) Count Active
OSDMAP_FLAGS 2021/09/16 03:17:47 2021/09/16 22:07:40 2 No
OSD_DOWN 2021/09/17 00:11:59 2021/09/17 00:11:59 1 Yes
PG_DEGRADED 2021/09/17 00:11:59 2021/09/17 00:11:59 1 Yes
3 health check(s) listed
```
| 列 | 含义 |
|---|---|
| `Healthcheck Name` | 健康检查名称 |
| `First Seen (UTC)` | 首次出现时间(UTC) |
| `Last seen (UTC)` | 最近出现时间(UTC) |
| `Count` | 出现次数 |
| `Active` | 是否当前仍然活跃 |
> 💡 补充:源文中「The `ceph healthcheck ls` command provides an overview...」一句的命令名与后续示例 `ceph healthcheck history ls` 不一致,且官方命令清单中列出的是 `ceph healthcheck history ls`;建议以 `ceph healthcheck history ls` 为准。
### 3.9 RBD IO 统计(RBD IO statistics)
`prometheus` 模块**可选地**通过启用**动态 OSD 性能计数器**来采集 RBD 每镜像(per-image)IO 统计。统计针对由 `mgr/prometheus/rbd_stats_pools` 配置参数指定的 pool 中的**所有 image** 采集。该参数是一个**逗号或空格分隔**的 `pool[/namespace]` 条目列表;若未指定 RBD namespace,则采集该 pool 中**所有 namespace** 的统计。
**为 `pool1`、`pool2`、`poolN` 启用统计采集:**
```bash
ceph config set mgr mgr/prometheus/rbd_stats_pools "pool1,pool2,poolN"
```
**使用通配符表示所有 pool 或 namespace:**
```bash
ceph config set mgr mgr/prometheus/rbd_stats_pools "*"
```
模块通过扫描指定的 pool 与 namespace 维护一份所有可用 image 的列表。刷新周期由 `mgr/prometheus/rbd_stats_pools_refresh_interval` 配置,**默认 300 秒(5 分钟)**。若模块检测到来自**此前未知 RBD image** 的统计数据,**会提前强制刷新**。
**把同步间隔设为 10 分钟:**
```bash
ceph config set mgr mgr/prometheus/rbd_stats_pools_refresh_interval 600
```
### 3.10 Ceph 守护进程性能计数器指标
随着 `ceph-exporter` 守护进程的引入,`prometheus` 模块**默认不再**导出 Ceph 守护进程 perf counters 作为 Prometheus 指标。但可以通过把模块选项 `exclude_perf_counters` 设为 `false` **重新启用**导出:
```bash
ceph config set mgr mgr/prometheus/exclude_perf_counters false
```
### 3.11 指标命名规则与标签(Statistic names and labels)
**命名规则:**
- Prometheus 统计名称 = **Ceph 原生名称**,把非法字符 **`.`、`-` 和 `::`** 翻译为 **`_`**,并**加上 `ceph_` 前缀**。
**标签规则:**
- **所有守护进程统计**都带一个 **`ceph_daemon`** 标签,取值标识其来源守护进程的**类型与 ID**,例如 `osd.123`。
- 一个给定指标**可能被多种类型的守护进程上报**,因此例如在查询 OSD RocksDB 统计时,你可能要用形如 `ceph_daemon=~'osd.*'` 的模式来约束查询,以**排除 Monitor 的 RocksDB 指标**。
- **集群级统计**(即 Ceph 集群全局的统计)带有与所报告实体相适应的标签。例如与 pool 相关的指标带有 **`pool_id`** 标签。
- 表示 Ceph 统计直方图的**长期平均值(long-running averages)**由成对的 **`<name>_sum`** 和 **`<name>_count`** 指标表示。这与 Prometheus 中 histogram 的表示方式类似,也可类似地处理。
### 3.12 Pool 与 OSD 元数据序列(metadata series)
导出这些序列是为了便于展示与查询某些元数据字段。
**Pool 的 `ceph_pool_metadata`:**
```text
ceph_pool_metadata{pool_id="2",name="cephfs_metadata_a"} 1.0
```
**OSD 的 `ceph_osd_metadata`:**
```text
ceph_osd_metadata{cluster_addr="172.21.9.34:6802/19096",device_class="ssd",ceph_daemon="osd.0",public_addr="172.21.9.34:6801/19096",weight="1.0"} 1.0
```
### 3.13 与 node_exporter 关联磁盘统计
Ceph 集群的 Prometheus 指标通常与 Prometheus `node_exporter` 的通用主机指标结合使用。
为了让 Ceph OSD 统计与 `node_exporter` 的磁盘统计能够关联,Ceph 创建如下形式的序列:
```text
ceph_disk_occupation_human{ceph_daemon="osd.0", device="sdd", exported_instance="myhost"}
```
要按 OSD ID 查询磁盘指标,可在 Prometheus 查询中使用 **`and`** 运算符或 **`*`** 运算符。**所有元数据指标(如 `ceph_disk_occupation_human`)的值都是 `1`**,因此它们与 PromQL 的 `*` 运算符结合时是中性的。使用 `*` 允许配合 `group_left` / `group_right` 分组修饰符,使结果带上来自查询某一侧的额外标签。
示例:
```promql
rate(node_disk_written_bytes_total[30s]) and
on (device,instance) ceph_disk_occupation_human{ceph_daemon="osd.0"}
```
> ⚠️ **开箱即用时上面的查询不会返回任何指标**,因为两个指标的 `instance` 标签不匹配:`ceph_disk_occupation_human` 的 `instance` 标签是**当前 active 的 Manager**。
> **注意:** 如果你需要按 `ceph_daemon` 标签而不是 `device` 与 `instance` 标签分组,使用 `ceph_disk_occupation_human` **可能不可靠**,建议改用 **`ceph_disk_occupation`**。区别在于:`ceph_disk_occupation_human` 在**多个 OSD 共享一个设备**的情况下,会把若干 OSD 合并到单个 `ceph_daemon` 标签的取值中。
**方法一:使用 `label_replace`**
`label_replace` 函数可在查询内为指标添加或修改标签。要把某个 OSD 与其磁盘的写入速率关联,可使用如下查询:
```promql
label_replace(
rate(node_disk_written_bytes_total[30s]),
"exported_instance",
"$1",
"instance",
"(.*):.*"
) and on (device, exported_instance) ceph_disk_occupation_human{ceph_daemon="osd.0"}
```
**方法二:在 Prometheus target 配置中自定义 `instance` 标签**(见 3.15)
### 3.14 关键指标清单(含告警建议)
> ⚠️ **关于「告警建议」列:** 下列表格中「告警建议」一列**不是**官方文档内容,官方文档未给出任何告警阈值。该列为本册作者基于指标语义给出的实践建议,属于推测性内容,请读者结合自身环境校准。
> `> 💡 补充:以下所有「告警建议」均为本册补充,官方文档未提供告警阈值或推荐规则。`
**A. 守护进程健康类**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_daemon_socket_up` | 守护进程能否通过 admin socket 响应;`1`=健康,`0`=不健康 | 持续 2–5 分钟 `== 0` 即告警(critical for mon/mgr/mds,warning for 单个 osd);用 `min_over_time(...[12h]) == 0` 捕捉间歇性故障 |
| `ceph_health_detail` | health check 状态,`0`=inactive,`1`=active;带 `name`、`severity` 标签 | 对 `severity="HEALTH_ERR"` 且 `== 1` 立即告警;`HEALTH_WARN` 持续 10m+ 告警;可按 `name` 分级(如 `OSD_DOWN`、`PG_DEGRADED`、`PG_AVAILABILITY`) |
**B. 集群性能类**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_osd_op_w_in_bytes` | 客户端写吞吐(字节) | 一般不直接告警,用于容量/性能趋势;突降为 0 可能意味客户端断流 |
| `ceph_osd_op_r_out_bytes` | 客户端读吞吐(字节) | 同上 |
| `ceph_osd_op_w` | 客户端写操作数(IOPS) | 同上 |
| `ceph_osd_op_r` | 客户端读操作数(IOPS) | 同上 |
| `ceph_osd_op_latency_sum` | 从客户端请求到 OSD 开始传输数据的延迟总和 | 结合 `_count` 求平均延迟;平均读/写延迟持续超过基线(如 100ms+)告警 |
**C. 容量类**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_osd_stat_bytes` | OSD 原始容量(按 OSD 分别报告) | `sum(ceph_osd_stat_bytes)` 为集群总原始容量;用于容量规划 |
| `ceph_pool_bytes_used` | Pool 消耗的总原始容量(含副本/EC 开销) | `sum(ceph_pool_bytes_used)/sum(ceph_osd_stat_bytes)` 达 70%/80%/85% 分档告警 |
| `ceph_pool_stored` | 客户端数据总量(数据保护之前) | 用于计算冗余开销比 `bytes_used/stored` |
| `ceph_pool_compress_under_bytes` | 可压缩数据量 | — |
| `ceph_pool_compress_bytes_used` | 已压缩数据量 | 压缩节省 = `sum(ceph_pool_compress_under_bytes - ceph_pool_compress_bytes_used)` |
**D. Pool 明细类**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_pool_metadata` | Pool 元数据(`name`、`type`、`description`、`compression_mode`) | 用于 join 补充标签,不直接告警 |
| `ceph_pool_rd` / `ceph_pool_wr` | 每 pool 客户端读/写 IOPS | 单个 pool 异常突增告警(可能是异常客户端) |
| `ceph_pool_rd_bytes` / `ceph_pool_wr_bytes` | 每 pool 客户端读/写字节 | 同上 |
**E. RGW 类**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_rgw_metadata` | RGW 守护进程元数据(`ceph_daemon`、`ceph_version`、`hostname`) | 用于 join;不同实例 `ceph_version` 不一致告警(版本漂移) |
| `ceph_rgw_req` | 已处理请求数(GET+PUT+DELETE) | RPS 突降为 0 告警(实例可能失联) |
| `ceph_rgw_qlen` | 操作队列长度 | 持续高队列长度告警(瓶颈) |
| `ceph_rgw_failed_req` | 被中止的请求 | `rate(ceph_rgw_failed_req[30s])` 持续 > 0 告警 |
| `ceph_rgw_op_global_get_obj_lat_sum` / `_count` | GET 延迟总和/计数 | 平均 GET 延迟超阈值告警 |
| `ceph_rgw_op_global_put_obj_lat_sum` / `_count` | PUT 延迟总和/计数 | 平均 PUT 延迟超阈值告警 |
| `ceph_rgw_op_global_get_obj_bytes` | GET 传输字节 | 带宽趋势 |
| `ceph_rgw_op_global_get_obj_ops` / `ceph_rgw_op_global_put_obj_ops` | GET/PUT 操作总数 | `rate(ceph_rgw_req) - (rate(get_ops)+rate(put_ops))` 得「其它」操作速率 |
**F. CephFS / MDS 类**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_mds_metadata` | MDS 元数据(`ceph_version`、`fs_id`、`hostname`、`public_addr`、`rank`) | 用于 join;`rank` 异常变动告警 |
| `ceph_mds_request` | MDS 总请求数 | RPS 突降告警 |
| `ceph_mds_reply_latency_sum` / `_count` | 应答延迟总和/计数 | 平均应答延迟超阈值告警 |
| `ceph_mds_server_handle_client_request` | 客户端请求数 | — |
| `ceph_mds_sessions_session_count` | 会话计数 | 接近 `mds_max_sessions` 上限告警 |
| `ceph_mds_sessions_total_load` | 总负载 | MDS 负载不均衡告警(配合 `mds_bal_*`) |
| `ceph_mds_sessions_sessions_open` | 当前打开会话数 | — |
| `ceph_mds_sessions_sessions_stale` | 当前 stale 会话数 | 持续 > 0 告警(客户端可能僵死) |
| `ceph_objecter_op_r` / `ceph_objecter_op_w` | MDS 读/写操作数量 | 工作负载趋势 |
| `ceph_mds_root_rbytes` / `ceph_mds_root_rfiles` | 该 MDS 管理的字节数/文件数 | 单 MDS 承载过大告警(可能需要加 rank) |
**G. RBD 类(需先配置 `rbd_stats_pools`)**
| 指标 | 含义 | 告警建议(💡 补充) |
|---|---|---|
| `ceph_rbd_read_bytes` / `ceph_rbd_write_bytes` | RBD 读写字节 | 单镜像异常吞吐告警 |
| `ceph_rbd_read_ops` / `ceph_rbd_write_ops` | RBD 读写操作计数 | — |
| `ceph_rbd_read_latency_sum` / `_count` | 读延迟总和/计数 | 平均读延迟超阈值告警 |
| `ceph_rbd_write_latency_sum` / `_count` | 写延迟总和/计数 | 平均写延迟超阈值告警 |
### 3.15 配置 Prometheus server
**`honor_labels`**
为了让 Ceph 输出关于任意主机的**正确标签**数据,在把 Manager 端点加入 Prometheus 配置时应使用 **`honor_labels`** 设置。
- 该设置指示 Ceph 导出正确的 `instance` 标签而**不在入库时被 Prometheus 覆盖**。
- 若**没有**该设置,Prometheus 会在入库时应用一个 `instance` 标签,其中包含抓取该指标的端点的**主机名与端口**。由于 Ceph 集群**有多个 Manager 守护进程**,这会导致 **active Manager 守护进程变化时 `instance` 标签随之改变**。
- 若不希望如此,可在 Prometheus target 配置中设置一个**自定义 `instance` 标签**,例如设为第一个 Manager 的主机名,或任意值如 `ceph_cluster`。
**`node_exporter` 主机名标签**
把 `instance` 标签设置为与 Ceph OSD 元数据中 `instance` 字段一致的值(通常是节点的**短主机名**)。
只有在你希望**把 Ceph 统计与主机统计关联**时才需要这样做,但为了便于未来关联历史数据,这样做通常是有用的。
**示例配置**
该示例展示一个 Manager 与 `node_exporter` 都部署在名为 `senta04` 的服务器上的部署形态。注意这需要为每个 `node_exporter` target 添加一个**适当且唯一的 `instance` 标签**。
> 这只是示例;配置 Prometheus 抓取目标与标签重写规则还有很多其它方式。
`prometheus.yml`:
```yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node'
file_sd_configs:
- files:
- node_targets.yml
- job_name: 'ceph'
honor_labels: true
file_sd_configs:
- files:
- ceph_targets.yml
```
`ceph_targets.yml`:
```json
[
{
"targets": [ "senta04.mydomain.com:9283" ],
"labels": {}
}
]
```
`node_targets.yml`:
```json
[
{
"targets": [ "senta04.mydomain.com:9100" ],
"labels": {
"instance": "senta04"
}
}
]
```
### 3.16 需要注意的其它事项(Notes)
- **导出的是 counters 和 gauges。Histogram 与 long-running averages 目前不导出。** Ceph 的 2-D histograms 有可能被规约为两个独立的 1-D histogram;long-running averages 有可能被导出为 Prometheus 的 `Summary` 类型指标。(源文表述为可能性,非承诺。)
- **时间戳(Timestamps):** 与许多 exporter 一样,时间戳由 Prometheus **在入库时**设置为 Prometheus server 的抓取时间。Prometheus 期望它是在**同步轮询**真正的计数器进程。虽然可以随统计报告一起提供时间戳,但 **Prometheus 团队强烈建议不要这样做**——这会导致时间戳被延迟一个不可预测的量。目前尚不清楚这是否会带来问题,但值得了解。
> 引自:[Prometheus Module](https://docs.ceph.com/en/tentacle/mgr/prometheus/)
---
## 四、Dashboard 模块
来源页面:`mgr/dashboard.rst`(约 58KB,本册重点章节)
### 4.1 概述
**Ceph Dashboard 是一个基于 Web 的 Ceph 管理与监控工具**,可用于**检视(inspect)**与**管理(administer)**集群中的资源。它作为 **ceph-mgr 模块**实现。
**架构与技术栈:**
- 最初的 Ceph Dashboard 随 **Ceph Luminous** 发布,只是一个对 Ceph 集群运行时信息与性能数据的**简单只读视图**,架构简单。
- 之后对更丰富的、基于 Web 的管理能力的需求增长(面向更偏好 WebUI 而非 CLI 的用户)。
- 新版 Dashboard 模块的架构与功能**源自 `openATTIC` Ceph 管理与监控工具**。开发最初由 SUSE 的 openATTIC 团队推动,并有 Ceph 社区成员以及包括 Red Hat 在内的公司参与支持。
- **后端**使用 **CherryPy** 框架,实现自定义 REST API。
- **WebUI** 基于 **Angular/TypeScript**,既包含原 dashboard 的功能,也包含最初为独立版 openATTIC 开发的新特性。
- Ceph Dashboard 模块实现为一个应用程序,通过由 **`ceph-mgr`** 托管的 Web 服务器提供信息与统计的图形化展示。
### 4.2 功能概览(Feature Overview)
#### 4.2.1 平台级特性
| 特性 | 说明 |
|---|---|
| **多用户与角色管理(Multi-User and Role Management)** | 支持具有不同权限(角色)的多个用户账户。用户账户与角色既可通过命令行管理,也可通过 WebUI 管理。支持多种增强密码安全性的方法:可配置密码复杂度规则,可要求用户首次登录后或经过一段可配置时间后修改密码 |
| **单点登录(SSO)** | 支持通过外部身份提供方(IdP)使用 **SAML 2.0** 协议或 **OAuth2** 协议进行认证 |
| **SSL/TLS 支持** | 浏览器与 dashboard 之间的所有 HTTP 通信**默认**通过 SSL 保护。可用内置命令创建自签名证书,也可以导入由 CA 签发颁发的自定义证书 |
| **审计(Auditing)** | 后端可配置为把所有 `PUT`、`POST`、`DELETE` API 请求记录到 Ceph audit log |
| **国际化(I18N)** | dashboard 文本所用语言可在运行时选择 |
#### 4.2.2 监控与管理能力(逐项)
| 能力 | 说明 |
|---|---|
| **整体集群健康(Overall cluster health)** | 展示性能与容量指标以及集群状态 |
| **嵌入式 Grafana Dashboards** | Ceph Dashboard 的 Grafana 面板可嵌入外部应用与网页,以呈现由 `prometheus` 模块采集的信息与性能指标 |
| **集群日志(Cluster logs)** | 展示集群 event 与 audit 日志文件的最新更新。日志条目可按**优先级、日期或关键字**过滤 |
| **主机(Hosts)** | 展示所有集群主机列表,及其存储驱动器、正在运行的服务、已安装的 Ceph 版本 |
| **性能计数器(Performance counters)** | 展示每个运行中服务的详细服务专属统计 |
| **Monitors** | 列出所有 Mon、其 quorum 状态与打开的会话 |
| **Monitoring** | 支持创建、重建、编辑与过期(expire)Prometheus 的 silences;列出告警配置以及所有已配置与正在触发(firing)的告警;对正在触发的告警显示通知 |
| **配置编辑器(Configuration Editor)** | 展示所有可用配置选项及其描述、类型、默认值与当前设置值;这些值也可编辑 |
| **Pools** | 列出 Ceph pool 及其详情(如 applications、pg-autoscaling、placement groups、副本数、EC profile、CRUSH 规则、配额等) |
| **OSDs** | 列出 OSD、其状态与用量统计,以及属性(OSD map)、metadata、性能计数器、读写操作用量直方图等详细信息。可把 OSD 标记为 up/down/out、purge 与 reweight OSD、执行 scrub 操作、修改各种 scrub 相关配置选项、选择 profile 以调整 backfill 活动级别。可列出与某 OSD 关联的所有驱动器。可设置与更改 OSD 的 device class,按 device class 展示与排序 OSD。可在新驱动器与新主机上部署 OSD |
| **设备管理(Device management)** | 列出编排器已知的所有主机;列出主机上挂载的所有驱动器及其属性;展示驱动器健康预测与 SMART 数据;闪烁(blink)机箱 LED |
| **iSCSI** | 列出所有运行 TCMU runner 服务的主机,展示所有 image 及其性能特征(读/写 ops、流量)。通过 `ceph-iscsi` 创建、修改与删除 iSCSI target。展示 iSCSI gateway 状态与活动 initiator 信息 |
| **RBD** | 列出所有 RBD image 及其属性(size、objects、features)。创建、复制、修改与删除 RBD image(含快照)并管理 RBD namespace。在全局、每 pool 或每 image 级别定义各种 I/O 或带宽限制设置。创建、删除与回滚所选 image 的快照,protect/unprotect 这些快照以防修改。复制或克隆快照,flatten 克隆的 image |
| **RBD mirroring** | 启用并配置到远端 Ceph server 的 RBD mirroring。列出活动守护进程及其状态、pool 与 RBD image(含同步进度) |
| **CephFS** | 列出活动文件系统客户端及关联 pool(含用量统计)。驱逐(evict)活动的 CephFS 客户端。管理 CephFS 配额与快照。浏览 CephFS 目录结构 |
| **Object Gateway** | 列出所有活动 object gateway 及其性能计数器。展示并管理(增/改/删)object gateway 用户及其详情(如配额),以及用户的 bucket 及其详情(如 placement targets、owner、配额、版本控制、MFA) |
| **NFS** | 通过 NFS Ganesha 管理 CephFS 文件系统与 RGW S3 bucket 的 NFS 导出 |
| **Ceph Manager Modules** | 启用与禁用 Ceph Manager 模块,管理模块专属的配置设置 |
### 4.3 Dashboard 落地页(Landing Page)
Ceph Dashboard 的落地页作为主页,展示诸如**整体集群状态、性能与容量**等指标。它提供集群任何变化的**实时更新**,并允许快速访问 dashboard 的其它部分。
> **注意(源文):** 可以把落地页切回旧版本:`Cluster >> Manager Modules >> Dashboard >> Edit`。编辑 **`FEATURE_TOGGLE_DASHBOARD`** 选项会在两种视图之间切换落地页。**注意旧版落地页将在未来版本中被禁用。**
#### 4.3.1 Details
提供集群配置概览,展示集群的各个关键方面。
#### 4.3.2 Status
提供集群健康的视觉指示,并展示**按严重程度分组**的集群告警。
#### 4.3.3 Capacity
| 项 | 说明 |
|---|---|
| **Used** | 已用容量,占存储节点(OSD)提供的总物理容量的比例 |
| **Warning** | 显示 OSD 的 `nearfull` 阈值 |
| **Danger** | 显示 OSD 的 `full` 阈值 |
#### 4.3.4 Inventory
集群内所有资产的清单(inventory)。从该卡片的每一项可直接访问 dashboard 的子页面。
#### 4.3.5 Cluster Utilization(集群利用率)
| 项 | 说明 |
|---|---|
| **Used Capacity** | 集群已用总容量;图表最大值为集群的最大容量 |
| **IOPS** | 读与写操作的数量 |
| **Latency** | 处理一个读或写请求所花的时间 |
| **Client Throughput** | 客户端向集群读或写的数据量 |
| **Recovery Throughput** | 客户端向集群读或写的**恢复数据**量 |
### 4.4 支持的浏览器
| 浏览器 | 版本 |
|---|---|
| Chrome 及基于 Chromium 的浏览器 | 最近 2 个主要版本 |
| Firefox | 最近 2 个主要版本 |
| Firefox ESR | 最近的主要版本 |
虽然 Ceph Dashboard 可能在更旧的浏览器上工作,但**无法保证兼容性**,建议保持浏览器更新。
### 4.5 启用
- 如果你从发行版软件包安装了 `ceph-mgr-dashboard`,包管理系统应该已经处理了所有必需的依赖。
- 如果你从源码构建 Ceph 并想在开发环境中启动 dashboard,请参阅源码目录 `src/pybind/mgr/dashboard` 中的 `README.rst` 与 `HACKING.rst`。
在一个运行中的 Ceph 集群上,启用 Ceph Dashboard:
```bash
ceph mgr module enable dashboard
```
### 4.6 SSL/TLS 支持
**所有到 dashboard 的 HTTP 连接默认都用 SSL/TLS 保护。**
**快速上手:生成并安装自签名证书**
```bash
ceph dashboard create-self-signed-cert
```
> 注意:大多数浏览器会**抱怨自签名证书**,并要求显式确认后才能与 dashboard 建立安全连接。
**正式部署:使用 CA 签发的证书**
为了妥善保护部署并消除警告,应使用**由证书颁发机构(CA)签发**的证书。
生成密钥对的示例命令:
```bash
openssl req -new -nodes -x509 \
-subj "/O=IT/CN=ceph-mgr-dashboard" -days 3650 \
-keyout dashboard.key -out dashboard.crt -extensions v3_ca
```
`dashboard.crt` 文件随后应由 CA 签名。签名完成后,可用以下命令为 Ceph manager 实例启用它:
```bash
ceph dashboard set-ssl-certificate -i dashboard.crt
ceph dashboard set-ssl-certificate-key -i dashboard.key
```
**为每个 manager 实例使用不同证书:** 若希望每个 manager 实例有唯一证书,可包含实例名(`$name` 是 `ceph-mgr` 实例名,通常是主机名):
```bash
ceph dashboard set-ssl-certificate $name -i dashboard.crt
ceph dashboard set-ssl-certificate-key $name -i dashboard.key
```
**禁用 SSL:**
```bash
ceph config set mgr mgr/dashboard/ssl false
```
如果 dashboard 运行在**不支持对上游服务器使用 SSL 的代理之后**,或者其它不需要 SSL 的场景,这会很有用。
> ⚠️ **警告:禁用 SSL 时要谨慎,因为用户名与密码将以未加密方式发送到 dashboard。**
> **注意:更改 SSL 证书与密钥后,必须重启 Ceph manager 进程。** 可以执行 `ceph mgr fail mgr`,或者禁用再启用 dashboard 模块(这也会触发 manager 自我重启):
```bash
ceph mgr module disable dashboard
ceph mgr module enable dashboard
```
### 4.7 主机名与端口(Host Name and Port)
- 与多数 Web 应用一样,dashboard 绑定到一个 **TCP/IP 地址**与一个 **TCP 端口**。
- 默认情况下,托管 dashboard 的 `ceph-mgr` 守护进程(即当前 active 的 manager)会绑定到 TCP 端口 **`8443`**;**当 SSL 被禁用时**绑定到 **`8080`**。
- 如果**未配置具体地址**,Web 应用会绑定到 **`::`**,对应**所有可用的 IPv4 与 IPv6 地址**。
**集群级修改(对所有 manager 实例生效):**
```bash
ceph config set mgr mgr/dashboard/server_addr $IP
ceph config set mgr mgr/dashboard/server_port $PORT
ceph config set mgr mgr/dashboard/ssl_server_port $PORT
```
**针对特定 manager 实例修改:** 由于每个 `ceph-mgr` 都托管自己的 dashboard 实例,可能需要分别配置。特定 manager 实例的 IP 与端口可用以下命令更改:
```bash
ceph config set mgr mgr/dashboard/$name/server_addr $IP
ceph config set mgr mgr/dashboard/$name/server_port $PORT
ceph config set mgr mgr/dashboard/$name/ssl_server_port $PORT
```
把 `$name` 替换为托管 dashboard 的 ceph-mgr 实例的 ID。
> **注意:** `ceph mgr services` 命令会显示当前配置的所有端点。查找 `dashboard` 键即可获得访问 dashboard 的 URL。
### 4.8 用户名与密码
要能登录,需要创建一个用户账户并**关联至少一个角色**。官方提供一组预定义的 **system roles** 可供直接使用(详见 4.14 用户与角色管理)。
**创建一个具有 administrator 角色的用户:**
```bash
ceph dashboard ac-user-create <username> -i <file-containing-password> administrator
```
### 4.9 账户锁定(Account Lock-out)
该功能会在用户**多次**输入错误凭据后**禁用**用户账户,**默认启用**,用于**防止暴力破解或字典攻击**。
```bash
ceph dashboard get-account-lockout-attempts
ceph dashboard set-account-lockout-attempts <value:int>
```
> ⚠️ **警告:可通过把默认锁定尝试次数设为 0 来禁用该功能。** 但禁用后账户更易受到暴力破解或字典攻击:
```bash
ceph dashboard set-account-lockout-attempts 0
```
**启用被锁定的用户:** 若用户账户因多次无效登录尝试被禁用,需要管理员手动启用:
```bash
ceph dashboard ac-user-enable <username>
```
### 4.10 访问 Dashboard
现在可以用(启用了 JavaScript 的)浏览器访问 dashboard,指向运行 manager 实例的任意主机名或 IP 地址以及所选 TCP 端口,例如 `http(s)://<$IP>:<$PORT>/`。
Dashboard 页面会显示并要求输入此前定义的用户名与密码。
### 4.11 启用 Object Gateway 管理前端
- 当 RGW **通过 cephadm 部署**时,dashboard 使用的 RGW 凭据会**自动配置**。
- 也可以手动强制设置凭据:
```bash
ceph dashboard set-rgw-credentials
```
这会为系统中的**每个 realm** 创建一个 uid 为 `dashboard` 的 RGW 用户。
**自定义 'admin' resource:** 如果你在 RGW admin API 中配置了自定义的 'admin' resource,也应在这里设置:
```bash
ceph dashboard set-rgw-api-admin-resource <admin_resource>
```
**自签名证书:** 如果 Object Gateway 使用自签名证书,应在 dashboard 中**禁用证书校验**以避免连接被拒(例如由未知 CA 签名的证书或主机名不匹配的证书导致):
```bash
ceph dashboard set-rgw-api-ssl-verify False
```
**为 RGW gateway 设置自定义主机名或地址:** 相应地设置 `RGW_HOSTNAME_PER_DAEMON` 的值:
```bash
ceph dashboard set-rgw-hostname <gateway_name> <hostname>
```
取消该设置:
```bash
ceph dashboard unset-rgw-hostname <gateway_name>
```
**请求超时:** 如果 Object Gateway 处理请求耗时过长导致 dashboard 超时,可按需设置超时值:
```bash
ceph dashboard set-rest-requests-timeout <seconds>
```
**默认值为 45 秒。**
### 4.12 启用 iSCSI 管理
Ceph Dashboard 可使用 `ceph-iscsi` 的 `rbd-target-api` 服务提供的 REST API 管理 iSCSI target。请确保该服务已在 iSCSI gateway 上**安装并启用**。
> **注意:** Ceph Dashboard 的 iSCSI 管理功能依赖于 `ceph-iscsi` 项目的**最新版本 3**。请确保你的操作系统提供了正确版本,否则 dashboard 不会启用这些管理特性。
如果 `ceph-iscsi` REST API 配置为 HTTPS 模式且使用自签名证书,需要配置 dashboard 在访问 ceph-iscsi API 时**避免 SSL 证书校验**:
```bash
ceph dashboard set-iscsi-api-ssl-verification false
```
**定义可用的 iSCSI gateway:**
```bash
ceph dashboard iscsi-gateway-list
# Gateway URL format for a new gateway: <scheme>://<username>:<password>@<host>[:port]
ceph dashboard iscsi-gateway-add -i <file-containing-gateway-url> [<gateway_name>]
ceph dashboard iscsi-gateway-rm <gateway_name>
```
### 4.13 认证与用户/角色管理(User and Role Management)
#### 4.13.1 密码策略(Password Policy)
**默认情况下密码策略特性是启用的**,包含以下检查:
- 密码是否长于 N 个字符?
- 旧密码与新密码是否相同?
**整体开关:**
```bash
ceph dashboard set-pwd-policy-enabled <true|false>
```
**各项独立开关:**
```bash
ceph dashboard set-pwd-policy-check-length-enabled <true|false>
ceph dashboard set-pwd-policy-check-oldpwd-enabled <true|false>
ceph dashboard set-pwd-policy-check-username-enabled <true|false>
ceph dashboard set-pwd-policy-check-exclusion-list-enabled <true|false>
ceph dashboard set-pwd-policy-check-complexity-enabled <true|false>
ceph dashboard set-pwd-policy-check-sequential-chars-enabled <true|false>
ceph dashboard set-pwd-policy-check-repetitive-chars-enabled <true|false>
```
**其它可配置选项:**
| 选项 | 命令 | 默认值 |
|---|---|---|
| 最小密码长度 | `ceph dashboard set-pwd-policy-min-length <N>` | `8` |
| 最小密码复杂度 | `ceph dashboard set-pwd-policy-min-complexity <N>` | `10` |
| 禁止使用的逗号分隔词表 | `ceph dashboard set-pwd-policy-exclusion-list <word>[,...]` | 文档未明确(源文未给出默认词表) |
**密码复杂度的计算方式:** 通过对密码中**每个字符**分类来计算。复杂度计数**从 0 开始**,一个字符按以下规则**按给定顺序**计分:
| 规则 | 增量 |
|---|---|
| 字符是数字(digit) | +1 |
| 字符是小写 ASCII 字符 | +1 |
| 字符是大写 ASCII 字符 | +2 |
| 字符是特殊字符,如 `!"#$%&'()*+,-./:;<=>?@[\]^_\`{\|}~` | +3 |
| 字符未被前面任何规则分类(如非 ASCII) | +5 |
#### 4.13.2 用户账户(User Accounts)
Ceph Dashboard 支持**多个用户账户**。每个用户账户由以下组成:
- 一个**用户名**
- 一个**密码**(以 **`bcrypt`** 加密形式存储)
- 一个**可选的名字**
- 一个**可选的邮箱地址**
如果通过 Web UI 创建新用户,可以设置一个选项,要求该用户**首次登录时必须设置新密码**。
**用户账户存储在 monitors 的配置数据库中**,对**所有 `ceph-mgr` 实例**可用。
**管理用户账户的 CLI 命令(逐项):**
| 用途 | 命令 |
|---|---|
| 查看用户 | `ceph dashboard ac-user-show [<username>]` |
| 创建用户 | `ceph dashboard ac-user-create [--enabled] [--force-password] [--pwd_update_required] <username> -i <file-containing-password> [<rolename>] [<name>] [<email>] [<pwd_expiration_date>]` |
| 删除用户 | `ceph dashboard ac-user-delete <username>` |
| 修改密码 | `ceph dashboard ac-user-set-password [--force-password] <username> -i <file-containing-password>` |
| 修改密码哈希 | `ceph dashboard ac-user-set-password-hash <username> -i <file-containing-password-hash>` |
| 修改用户信息(name、email) | `ceph dashboard ac-user-set-info <username> <name> <email>` |
| 禁用用户 | `ceph dashboard ac-user-disable <username>` |
| 启用用户 | `ceph dashboard ac-user-enable <username>` |
说明:
- 使用 **`force-password`** 选项可**绕过密码策略检查**。
- 加上 **`pwd_update_required`** 选项,则新创建的用户**首次登录后必须修改密码**。
- 密码哈希必须是 **bcrypt hash and salt**,例如 `$2b$12$Pt3Vq/rDt2y9glTPSV.VFegiLkQeIpddtkhoFetNApYmIJOY8gau2`。这可用于**从外部数据库导入用户**。
#### 4.13.3 用户角色与权限(User Roles and Permissions)
用户账户与一组**角色(roles)**关联,角色定义了**可以访问哪些 dashboard 功能**。
**安全作用域(security scope):** Dashboard 的功能/模块被分组在安全作用域内。安全作用域是**预定义且静态的**。当前可用的安全作用域(**逐项**):
| 安全作用域 | 覆盖范围 |
|---|---|
| `hosts` | 与 `Hosts` 菜单项相关的所有功能 |
| `config-opt` | 与 Ceph 配置选项管理相关的所有功能 |
| `pool` | 与 pool 管理相关的所有功能 |
| `osd` | 与 OSD 管理相关的所有功能 |
| `monitor` | 与 monitor 管理相关的所有功能 |
| `rbd-image` | 与 RBD image 管理相关的所有功能 |
| `rbd-mirroring` | 与 RBD mirroring 管理相关的所有功能 |
| `iscsi` | 与 iSCSI 管理相关的所有功能 |
| `rgw` | 与 RADOS Gateway(RGW)管理相关的所有功能 |
| `cephfs` | 与 CephFS 管理相关的所有功能 |
| `nfs-ganesha` | 与 NFS Ganesha 管理相关的所有功能 |
| `manager` | 与 Ceph Manager 管理相关的所有功能 |
| `log` | 与 Ceph 日志管理相关的所有功能 |
| `grafana` | 与 Grafana proxy 相关的所有功能 |
| `prometheus` | 与 Prometheus 告警管理相关的所有功能 |
| `dashboard-settings` | 允许修改 dashboard 设置 |
**权限(permissions):** 角色定义「安全作用域 → 一组权限」的映射。共有**四种**权限:
- **`read`**
- **`create`**
- **`update`**
- **`delete`**
角色规范示例(Python 字典形式):
```python
# example of a role
{
'role': 'my_new_role',
'description': 'My new role',
'scopes_permissions': {
'pool': ['read', 'create'],
'rbd-image': ['read', 'create', 'update', 'delete']
}
}
```
上例表示:用户对 **pool 管理**相关功能有 `read` 与 `create` 权限;对 **RBD image 管理**相关功能有完整权限(read/create/update/delete)。
**系统预置角色(system roles):** Dashboard 提供一组预定义角色,新的 Ceph Dashboard 安装即可直接使用。
| 系统角色 | 权限范围 |
|---|---|
| `administrator` | **所有**安全作用域的完整权限 |
| `read-only` | 除 **dashboard settings** 之外的所有安全作用域的 `read` 权限 |
| `block-manager` | `rbd-image`、`rbd-mirroring`、`iscsi` 三个作用域的完整权限 |
| `rgw-manager` | `rgw` 作用域的完整权限 |
| `cluster-manager` | `hosts`、`osd`、`monitor`、`manager`、`config-opt` 作用域的完整权限 |
| `pool-manager` | `pool` 作用域的完整权限 |
| `cephfs-manager` | `cephfs` 作用域的完整权限 |
**角色管理命令(逐项):**
| 用途 | 命令 |
|---|---|
| 查看可用角色 | `ceph dashboard ac-role-show [<rolename>]` |
| 创建角色 | `ceph dashboard ac-role-create <rolename> [<description>]` |
| 删除角色 | `ceph dashboard ac-role-delete <rolename>` |
| 为角色添加作用域权限 | `ceph dashboard ac-role-add-scope-perms <rolename> <scopename> <permission> [<permission>...]` |
| 从角色删除作用域权限 | `ceph dashboard ac-role-del-scope-perms <rolename> <scopename>` |
| 设置用户角色 | `ceph dashboard ac-user-set-roles <username> <rolename> [<rolename>...]` |
| 为用户添加角色 | `ceph dashboard ac-user-add-roles <username> <rolename> [<rolename>...]` |
| 从用户删除角色 | `ceph dashboard ac-user-del-roles <username> <rolename> [<rolename>...]` |
#### 4.13.4 用户与自定义角色创建完整示例
创建一个可以管理 RBD image、查看并创建 Ceph pool、对其它作用域只有只读访问的用户账户:
```bash
# 1. 创建用户
ceph dashboard ac-user-create bob -i <file-containing-password>
# 2. 创建角色并指定作用域权限
ceph dashboard ac-role-create rbd/pool-manager
ceph dashboard ac-role-add-scope-perms rbd/pool-manager rbd-image read create update delete
ceph dashboard ac-role-add-scope-perms rbd/pool-manager pool read create
# 3. 把角色关联到用户
ceph dashboard ac-user-set-roles bob rbd/pool-manager read-only
```
### 4.14 单点登录(SSO)
#### 4.14.1 SAML2 SSO
Ceph Dashboard 支持通过 **SAML 2.0** 协议使用外部身份提供方进行用户认证。
- 你需要**先创建用户账户并关联所需角色**,因为**授权(authorization)由 Dashboard 执行**;而**认证(authentication)过程**可由已存在的身份提供方(IdP)执行。
> **注意:** Ceph Dashboard 的 SSO 支持依赖 onelogin 的 **`python-saml`** 库。请确保系统上已安装该库(通过发行版包管理器或 Python 的 `pip`)。
**配置命令:**
```bash
ceph dashboard sso setup saml2 <ceph_dashboard_base_url> <idp_metadata> {<idp_username_attribute>} {<idp_entity_id>} {<sp_x_509_cert>} {<sp_private_key>}
```
**参数(逐项):**
| 参数 | 是否可选 | 说明 |
|---|---|---|
| `<ceph_dashboard_base_url>` | 必填 | Ceph Dashboard 可访问的基础 URL,例如 `https://cephdashboard.local` |
| `<idp_metadata>` | 必填 | IdP 元数据 XML 的远程(`http://`、`https://`)或本地(`file://`)路径或内容,例如 `https://myidp/metadata`、`file:///home/myuser/metadata.xml` |
| `<idp_username_attribute>` | 可选 | 用于从认证响应中取用户名的属性。**默认 `uid`** |
| `<idp_entity_id>` | 可选 | 当 IdP 元数据中存在**多于一个** entity id 时使用 |
| `<sp_x_509_cert>` / `<sp_private_key>` | 可选 | Ceph Dashboard(Service Provider)用于**签名与加密**的证书文件路径(这些文件路径应能被 **active 的 ceph-mgr 实例**访问) |
> **注意:** SAML 请求的 issuer 值遵循以下模式:
```text
<ceph_dashboard_base_url>/auth/saml2/metadata
```
**其它 SAML2 命令:**
| 用途 | 命令 |
|---|---|
| 显示当前 SAML 2.0 配置 | `ceph dashboard sso show saml2` |
| 禁用 SSO | `ceph dashboard sso disable` |
| 检查 SSO 是否启用 | `ceph dashboard sso status` |
| 启用 SSO(SAML2) | `ceph dashboard sso enable saml2` |
> 关于 `onelogin_settings` 的更多信息,请查阅 [onelogin 文档](https://github.com/onelogin/python-saml)。
#### 4.14.2 OAuth2 SSO
Ceph Dashboard 支持通过 **OAuth** 协议使用外部身份提供方进行用户认证。
**前置条件:**
- 必须启用 **`cephadm` 作为编排器**,并且要有活动的 **`mgmt-gateway`** 与 **`oauth2-proxy`** 服务。
**IdP 配置:**
- 官方**当前推荐并测试过的 IdP 是 Keycloak**。
- 在 IdP 上,配置 `oauth2-proxy` 服务配置中所用的 client,校验以下重定向 URL:
- login_url:`https://<host_name>|<IP_address>/oauth2/callback`
- logout_url:`https://<host_name>|<IP_address>/ /oauth2/sign_out`
- 同样在 IdP 上,需要一个**具有有效角色**的用户,该用户将用于执行**授权**。可以创建一个类似 `'administator'`(源文原文拼写)的角色,赋予该用户 admin 级访问权限。
**确认 `enable_auth` 标志:**
确保在 `ceph orch apply mgmt-gateway` 命令中包含 `enable_auth` 标志,并已通过如下形式的命令把它设为 `true`:
```bash
ceph orch apply mgmt-gateway --enable-auth=true --placement=<ceph-node-02>
```
> 💡 补充:源文此处命令写作 `--enable_auth=true`(下划线),而同册 `orchestrator`/cephadm 语境中常见写法为 `--enable-auth=true`(连字符)。建议以 `ceph orch apply mgmt-gateway --help` 的实际输出为准。
**OAuth2 相关命令:**
| 用途 | 命令 |
|---|---|
| 禁用 SSO | `ceph dashboard sso disable` |
| 检查 SSO 是否启用 | `ceph dashboard sso status` |
| 启用 SSO(OAuth2) | `ceph dashboard sso enable oauth2` |
### 4.15 启用 Prometheus 告警(Prometheus Alerting)
要使用 Prometheus 进行告警,必须定义 **alerting rules**(告警规则),它们由 **Alertmanager** 管理。如果你尚未使用 Alertmanager,请先安装它——它接收并管理来自 Prometheus 的告警。
**Dashboard 消费 Alertmanager 能力有三种方式:**
1. **使用 dashboard 的通知接收器(notification receiver)**
2. **使用 Prometheus Alertmanager API**
3. **同时使用两者**
三种方式都会通知你。若同时使用两者,**不会被通知两次**;但**你必须至少消费 Alertmanager API 才能管理 silences**。
#### 方式 1:使用 dashboard 的通知接收器
- 允许你按 Alertmanager 的配置获得通知。
- 一旦有通知发出,你会**在 dashboard 内部**收到通知,但**不能管理告警**。
- 在 Alertmanager 配置中添加 dashboard receiver 与新的 route,形如:
```yaml
route:
receiver: 'ceph-dashboard'
...
receivers:
- name: 'ceph-dashboard'
webhook_configs:
- url: '<url-to-dashboard>/api/prometheus_receiver'
```
- 确保 Alertmanager 认为你的 dashboard SSL 证书是有效的(关于正确配置,请查阅 Alertmanager 的 `<http_config>` 文档)。
#### 方式 2:使用 Prometheus 与 Alertmanager 的 API
- 允许你**管理告警与静默(silences)**,并会启用 `Cluster` 菜单项下 `Monitoring` 区中的 **"Active Alerts"、"All Alerts" 以及 "Silences"** 标签页。
- **告警**可按 name、job、severity、state 与 start time 排序。
- 遗憾的是,**无法知道**某个告警是何时依据你的配置由 Alertmanager 通过通知发出的;因此 dashboard 会在**告警有任何可见变化**时通知用户,并会通知发生变化的告警。
- **静默**可按 id、creator、status、start、updated 与 end time 排序。静默可用多种方式创建,也可以让它们过期:
1. **从零创建(Create from scratch)**
2. **基于选中的告警(Based on a selected alert)**
3. **从已过期的静默重建(Recreate from expired silence)**
4. **更新一个静默**(这会重建并使其过期——Alertmanager 的默认行为)
**配置 Alertmanager 主机与端口:**
```bash
ceph dashboard set-alertmanager-api-host <alertmanager-host:port> # default: ''
```
例如:
```bash
ceph dashboard set-alertmanager-api-host 'http://localhost:9093'
```
**配置 Prometheus API 的 URL:** 要能看到**所有已配置的告警**,需要配置到 Prometheus API 的 URL。借助该 API,UI 还会帮助验证一个新的静默是否会匹配相应的告警。
```bash
ceph dashboard set-prometheus-api-host <prometheus-host:port> # default: ''
```
例如:
```bash
ceph dashboard set-prometheus-api-host 'http://localhost:9090'
```
设置完主机后,**刷新浏览器的 dashboard 窗口或标签页**。
#### 方式 3:同时使用两种方法
两种方式的行为被配置成互不干扰,不过可能会弹出烦人的重复通知。
#### 自签名证书处理
如果你在 Prometheus 或 Alertmanager 中使用自签名证书,应在 dashboard 中禁用证书校验,以避免由未知 CA 签名的证书或主机名不匹配导致的连接被拒。
- 对 Prometheus:
```bash
ceph dashboard set-prometheus-api-ssl-verify False
```
- 对 Alertmanager:
```bash
ceph dashboard set-alertmanager-api-ssl-verify False
```
### 4.16 嵌入 Grafana Dashboards
**背景:** Grafana 从 Prometheus 拉取数据。虽然 Grafana 可以使用其它数据源,但我们提供的 Grafana dashboards 包含的查询是 **Prometheus 专属**的,因此**需要 Prometheus 作为数据源**。Ceph 的 `prometheus` 模块以 Prometheus exposition 格式导出数据。这些 Grafana 面板依赖于 **prometheus 模块的指标名**与 **Node exporter** 的指标名。Node exporter 是一个提供机器指标的独立应用。
> **Prometheus 安全模型提示(源文):** Prometheus 的安全模型**假定不可信用户可以访问** Prometheus 的 HTTP 端点与日志。不可信用户可以访问数据库中 Prometheus 收集到的所有(元)数据,以及各种运维与调试信息。不过,Prometheus 的 HTTP API **仅限于只读操作**:**不能**通过 API 更改配置,**不会**暴露 secrets。此外 Prometheus 内置了一些缓解拒绝服务攻击影响的措施。
#### 4.16.1 使用 cephadm 安装与配置
Grafana 与 Prometheus 可以使用 `cephadm` 安装,它们会**被 `cephadm` 自动配置**。详见 cephadm 文档的 monitoring 部分(本册不展开,归属 cephadm 册)。
#### 4.16.2 手动安装与配置
在合适的主机上安装好 Prometheus、Grafana 与 Node exporter 后,按以下步骤进行:
**第 1 步:启用作为 Ceph Manager 模块提供的 Ceph Exporter**
```bash
ceph mgr module enable prometheus
```
**第 2 步:向 Prometheus 添加相应的抓取配置**
```yaml
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'ceph'
static_configs:
- targets: ['localhost:9283']
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
```
> **注意:** 上例中,Prometheus 被配置为从自身(端口 9090)、Ceph manager 的 `prometheus` 模块(端口 9283,导出 Ceph 内部数据)以及 Node Exporter(端口 9100,提供每台主机的 OS 与硬件指标)抓取数据。
>
> 根据你的配置,可能需要更改 Node Exporter 的主机名或为其添加额外的配置项。**不太可能需要更改默认 TCP 端口。**
>
> 此外,你**不必**为 Ceph 专属数据配置多于一个 target(`prometheus` mgr 模块提供)。但**建议**配置 Prometheus 从**所有已存在的 Ceph manager** 抓取 Ceph 专属数据。这启用了内置的**高可用机制**:若某个 Ceph Manager 宕机,运行在该 manager 主机上的服务会自动在另一个 manager 主机上重启。
**第 3 步:把 Prometheus 作为数据源添加到 Grafana**(通过 Grafana Web UI)
> **重要:数据源必须命名为 `"Dashboard1"`。**
**第 4 步:安装 Grafana 插件**
```bash
grafana-cli plugins install vonage-status-panel
grafana-cli plugins install grafana-piechart-panel
```
**第 5 步:向 Grafana 添加 Dashboards**
可以通过导入 dashboard JSON 文件来添加。用以下命令下载 JSON 文件:
```bash
wget https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/dashboards_out/<Dashboard-name>.json
```
各种 dashboard JSON 文件可在 [ceph/ceph 仓库的 `monitoring/ceph-mixin/dashboards_out`](https://github.com/ceph/ceph/tree/main/monitoring/ceph-mixin/dashboards_out) 找到。
例如,ceph-cluster 总览:
```bash
wget https://raw.githubusercontent.com/ceph/ceph/main/monitoring/ceph-mixin/dashboards_out/ceph-cluster.json
```
你也可以自己编写 dashboard。
**第 6 步:在 `/etc/grafana/grafana.ini` 中配置匿名模式**
```ini
[auth.anonymous]
enabled = true
org_name = Main Org.
org_role = Viewer
```
在较新版本的 Grafana(**从 6.2.0-beta1 开始**)中引入了一个新设置 `allow_embedding`。该设置**必须显式设为 `true`**,Ceph Dashboard 中的 Grafana 集成才能工作,因为**默认是 `false`**:
```ini
[security]
allow_embedding = true
```
#### 4.16.3 启用 RBD-Image 监控
**RBD image 的监控默认是禁用的**,因为它会**显著影响性能**。更多信息见第三章「RBD IO statistics」。禁用时,Grafana 中的总览与详情 dashboard 会是空的,Prometheus 中也看不到相关指标。
#### 4.16.4 配置 Dashboard 连接 Grafana
设置好 Grafana 与 Prometheus 之后,需要配置 Ceph Dashboard 用于访问 Grafana 的连接信息。
**告诉 dashboard Grafana 实例运行在哪个 URL:**
```bash
ceph dashboard set-grafana-api-url <grafana-server-url> # default: ''
```
URL 格式为:`<protocol>:<IP-address>:<port>`
> **注意:** Ceph Dashboard 通过 **`iframe`** HTML 元素嵌入 Grafana dashboards。如果 Grafana **未配置 SSL/TLS 支持**,而 dashboard 启用了 SSL(默认启用),大多数浏览器会**阻止嵌入不安全内容**。如果按上述步骤启用后看不到嵌入的 Grafana dashboard,请查阅浏览器文档了解如何解除对混合内容(mixed content)的阻止。或者考虑在 Grafana 中启用 SSL/TLS 支持。
**自签名证书处理:**
```bash
ceph dashboard set-grafana-api-ssl-verify False
```
**清除 Grafana API URL 配置:**
```bash
ceph dashboard reset-grafana-api-url
```
#### 4.16.5 面向浏览器的替代 URL(Alternative URL for Browsers)
Ceph Dashboard 后端需要 Grafana URL,以便在前端加载之前**验证 Grafana Dashboard 是否存在**。由于 Grafana 在 Ceph Dashboard 中的实现方式,这意味着要在 Ceph Dashboard 中看到 Grafana 图形,需要**两条可用的连接**:
1. **后端(Ceph Mgr 模块)**需要验证所请求图形的存在性。若该请求成功,它会通知前端可以安全访问 Grafana。
2. **前端**随后通过 iframe **直接从用户的浏览器**请求 Grafana 图形。Grafana 实例被**直接访问,不经过 Ceph Dashboard** 的任何中转。
现在可能存在这样的情形:你的环境使得用户的浏览器难以直接访问 Ceph Dashboard 中配置的 URL。为解决该问题,可以配置一个**单独的 URL**,它**仅**用于告诉前端(用户的浏览器)应该使用哪个 URL 访问 Grafana。**该设置永远不会自动更改**,这与 `GRAFANA_API_URL` 不同(后者在**使用 cephadm 部署监控服务时**会被 `cephadm` 设置)。
```bash
ceph dashboard set-grafana-frontend-api-url <grafana-server-url>
```
如果没有为该选项设置值,它会**回落到 `GRAFANA_API_URL` 选项的值**。如果设置了,它会指示浏览器使用该 URL 访问 Grafana。
### 4.17 NFS-Ganesha 管理
Dashboard 需要启用 **NFS 模块**才能用于管理 NFS 集群与 NFS 导出。详见第八章的 nfs 模块。
### 4.18 代理配置(Proxy Configuration)
在具有**多个 `ceph-mgr` 实例**的 Ceph 集群中,**只有当前 active 的 `ceph-mgr` 守护进程上运行的 dashboard 会处理进入的请求**。连接到 **standby `ceph-mgr` 实例**上 dashboard TCP 端口的连接会收到一个 **HTTP 重定向(303)到 active manager 的 dashboard URL**。这使你可以把浏览器指向**任意一个** `ceph-mgr` 实例来访问 dashboard。
如果你想建立一个**固定的 URL**来访问 dashboard,或者不想允许到 manager 节点的直接连接,可以设置一个**自动把进入的请求转发到 active `ceph-mgr` 实例**的代理。
#### 4.18.1 配置 URL 前缀(URL Prefix)
如果你通过反向代理访问 dashboard,可能希望把它放在某个 URL 前缀下提供服务。要让 dashboard 使用包含该前缀的超链接,可以设置 `url_prefix`:
```bash
ceph config set mgr mgr/dashboard/url_prefix $PREFIX
```
这样就可以通过 `http://$IP:$PORT/$PREFIX/` 访问 dashboard。
#### 4.18.2 禁用重定向(Disable the redirection)
如果 dashboard 位于类似 **HAProxy** 的负载均衡代理之后,你可能希望**禁用重定向**,以避免把内部的(无法解析的)URL 发布给前端客户端。使用以下命令让 dashboard **以 HTTP 错误(默认 500)响应**,而不是重定向到 active dashboard:
```bash
ceph config set mgr mgr/dashboard/standby_behaviour "error"
```
恢复默认重定向:
```bash
ceph config set mgr mgr/dashboard/standby_behaviour "redirect"
```
#### 4.18.3 配置错误状态码(Configure the error status code)
当重定向被禁用时,你可能希望自定义 standby dashboard 的 HTTP 状态码:
```bash
ceph config set mgr mgr/dashboard/standby_error_status_code 503
```
#### 4.18.4 在重定向前把 IP 地址解析为主机名(Resolve IP address to hostname before redirect)
从 standby dashboard 到 active dashboard 的重定向是通过 **manager 的 IP 地址**完成的,而不是通过 manager 的主机名。在虚拟化环境中,相比基于主机名的解析,**基于 IP 地址的重定向能降低出错率**。由于基于主机名的解析**出错风险更高**,**主机名解析选项默认被禁用**。
不过某些情况下,通过主机名重定向会更有帮助。例如,如果配置的 TLS 证书**只匹配主机名而不匹配这些主机的 IP 地址**,那么主机名重定向会更合适。
**激活通过 manager 主机名从 standby dashboard 重定向到 active dashboard:**
```bash
ceph config set mgr mgr/dashboard/redirect_resolve_ip_addr True
```
**禁用主机名重定向:**
```bash
ceph config set mgr mgr/dashboard/redirect_resolve_ip_addr False
```
> ⚠️ **警告:** 如果你尝试用上述命令激活重定向,却收到错误消息 `EINVAL: unrecognized config option 'mgr/dashboard/redirect_resolve_ip_addr'`,那么你可能运行的是**早于 17.2.6** 的 Ceph 版本。该特性在 **17.2.6** 中引入([PR #48219](https://github.com/ceph/ceph/pull/48219))。
#### 4.18.5 HAProxy 示例配置
以下是一个使用 HAProxy 做 **SSL/TLS passthrough** 的示例配置。
请注意该配置在以下条件下工作:如果 dashboard 发生故障切换,前端客户端可能会收到 HTTP 重定向(303)响应,并被重定向到一个**无法解析的主机**。这发生在**故障切换发生在两次 HAProxy 健康检查之间**的时候。此时,此前 active 的 dashboard 节点现在会响应一个指向新 active 节点的 303。为防止这种情况,你应考虑**在 standby 节点上禁用重定向**。
```text
defaults
log global
option log-health-checks
timeout connect 5s
timeout client 50s
timeout server 450s
frontend dashboard_front
mode http
bind *:80
option httplog
redirect scheme https code 301 if !{ ssl_fc }
frontend dashboard_front_ssl
mode tcp
bind *:443
option tcplog
default_backend dashboard_back_ssl
backend dashboard_back_ssl
mode tcp
option httpchk GET /
http-check expect status 200
server x <HOST>:<PORT> check check-ssl verify none
server y <HOST>:<PORT> check check-ssl verify none
server z <HOST>:<PORT> check check-ssl verify none
```
### 4.19 审计 API 请求(Auditing API Requests)
REST API 可以把 `PUT`、`POST` 与 `DELETE` 请求记录到 **Ceph audit log**。该特性**默认禁用**,可用以下命令启用:
```bash
ceph dashboard set-audit-api-enabled <true|false>
```
启用后,**每个请求**会记录以下参数:
| 参数 | 说明 | 示例 |
|---|---|---|
| `from` | 请求来源 | `https://[::1]:44410` |
| `path` | REST API 路径 | `/api/auth` |
| `method` | HTTP 方法 | `PUT`、`POST` 或 `DELETE` |
| `user` | 用户名,否则为 `'None'` | `admin` |
**请求载荷(payload,即参数及其值)的日志记录默认是启用的。** 执行以下命令可禁用该行为:
```bash
ceph dashboard set-audit-api-log-payload <true|false>
```
一条日志条目示例:
```text
2018-10-22 15:27:01.302514 mgr.x [INF] [DASHBOARD] from='https://[::ffff:127.0.0.1]:37022' path='/api/rgw/user/klaus' method='PUT' user='admin' params='{"max_buckets": "1000", "display_name": "Klaus Mustermann", "uid": "klaus", "suspended": "0", "email": "klaus.mustermann@ceph.com"}'
```
### 4.20 审计与日志(Auditing and Logs)
> 📌 本节汇总 Dashboard 与日志相关的全部能力。审计 API 请求见 4.19;集群日志展示见 4.2.2「Cluster logs」;集中式日志(Loki/Promtail)见 4.22.4。
### 4.21 多 Dashboard 与 HA
在具有多个 `ceph-mgr` 实例的集群中:
- **每个 `ceph-mgr` 都托管自己的 dashboard 实例**(见 4.7 主机名与端口,可为每个实例单独配置 `server_addr` / `server_port` / `ssl_server_port`)。
- **只有 active 实例处理请求**;standby 实例返回 **303 重定向**到 active 的 URL(默认行为)。
- 要使浏览器用**固定 URL** 访问,需配置反向代理(见 4.18);建议同时把 standby 行为改为 `error`(默认 500,可配 `standby_error_status_code`),这样 HAProxy 的健康检查能正确识别 active 实例。
- **Prometheus 抓取侧的高可用**:建议配置 Prometheus 从**所有** Ceph manager 抓取 Ceph 指标,以启用内置 HA 机制(见 4.16.2 第 2 步)。
- **SSL 证书**:可为每个 manager 实例(`mgr/dashboard/$name/...`)单独配置;更改证书后必须重启 manager 进程。
### 4.22 插件(Plug-ins)
插件以**模块化、松耦合**的方式扩展 Ceph Dashboard 的功能。
> ⚠️ **源文说明:** `dashboard.rst` 在此处通过 `.. include::` 引入了三个插件文档片段:`dashboard_plugins/feature_toggles.inc.rst`、`dashboard_plugins/debug.inc.rst`、`dashboard_plugins/motd.inc.rst`。**这三个 include 文件未包含在本册抓取的源文集合中**,因此这三个插件(feature_toggles、debug、motd)的具体配置项与用法在本册中为**文档未明确**(详见末尾「文档未明确项」)。
> 💡 补充:从 dashboard.rst 其它位置可知 `FEATURE_TOGGLE_DASHBOARD` 是 feature toggles 类插件暴露的一个选项(用于切换新旧落地页),可推断 feature toggles 插件提供的是「功能开关」能力;但完整开关列表与默认值源文未提供。
### 4.23 Dashboard 排障(Troubleshooting)
#### 4.23.1 定位 Dashboard
如果不确定 Ceph Dashboard 的位置,运行:
```bash
ceph mgr services | jq .dashboard
```
```text
"https://host:port"
```
该命令返回 Ceph Dashboard 所在的 URL:`https://<host>:<port>/`
> **注意:** 许多 Ceph 工具以 JSON 格式返回结果。建议安装 **`jq`** 命令行工具以方便处理 JSON 数据。
#### 4.23.2 无法访问 Dashboard
按顺序检查:
**第 1 步:验证 Ceph Dashboard 模块已启用**
```bash
ceph mgr module ls | jq .enabled_modules
```
确保 Ceph Dashboard 模块出现在返回值中,输出片段示例:
```json
[
"dashboard",
"iostat",
"restful"
]
```
**第 2 步:如果未列出,激活该模块**
```bash
ceph mgr module enable dashboard
```
**第 3 步:检查 Ceph Dashboard 和/或 `ceph-mgr` 日志文件是否有错误**
- 检查 `ceph-mgr` 日志消息是否被写入文件:
```bash
ceph config get mgr log_to_file
```
```text
true
```
- 获取日志文件位置(默认是 `/var/log/ceph/<cluster-name>-<daemon-name>.log`):
```bash
ceph config get mgr log_file
```
```text
/var/log/ceph/$cluster-$name.log
```
**第 4 步:确保 SSL/TLS 支持已正确配置**
- 检查 SSL/TLS 支持是否启用:
```bash
ceph config get mgr mgr/dashboard/ssl
```
- 如果命令返回 `true`,验证证书是否存在:
```bash
ceph config-key get mgr/dashboard/crt
```
以及:
```bash
ceph config-key get mgr/dashboard/key
```
- 如果返回**不是** `true`,运行以下命令生成自签名证书,或按 4.6 节的说明操作:
```bash
ceph dashboard create-self-signed-cert
```
#### 4.23.3 无法登录 Dashboard
**第 1 步:检查凭据是否正确。** 如果登录 Ceph Dashboard 时看到 "invalid credentials" 通知消息,很可能使用了错误的凭据。仔细检查用户名和密码,并确保不小心没有开启键盘大写锁定(caps lock)。
**第 2 步:如果凭据正确但仍报同样错误,检查用户账户是否存在:**
```bash
ceph dashboard ac-user-show <username>
```
该命令返回用户数据。如果用户不存在,会打印:
```text
Error ENOENT: User <username> does not exist
```
**第 3 步:检查用户是否已启用:**
```bash
ceph dashboard ac-user-show <username> | jq .enabled
```
```text
true
```
检查你的用户的 `enabled` 是否为 `true`。如果不是,则该用户未启用,运行:
```bash
ceph dashboard ac-user-enable <username>
```
#### 4.23.4 Dashboard 某个功能不工作
当后端发生错误时,通常会在前端收到错误通知。按以下场景排查:
1. **检查 Ceph Dashboard 与 `ceph-mgr` 日志文件是否有错误。** 可以通过搜索关键字(如 *500 Internal Server Error*,后跟 `traceback`)找到。traceback 的末尾包含有关具体错误的更多细节。
2. **检查 Web 浏览器的 JavaScript Console 是否有错误。**
#### 4.23.5 Dashboard 日志
##### Dashboard Debug 标志
启用该标志后,**后端响应中会包含错误 traceback**。
- 通过 Ceph Dashboard 启用:导航 `Cluster` → `Manager modules`,选择 `Dashboard module` 并点击编辑按钮,勾选 `debug` 复选框并更新。
- 通过 CLI 启用:
```bash
ceph dashboard debug enable
```
##### 设置 Dashboard 模块的日志级别
把日志级别设为 debug 会让日志更详细,有助于调试。
**第 1 步:提高 manager 守护进程的日志级别:**
```bash
ceph tell mgr config set debug_mgr 20
```
**第 2 步:通过 Dashboard 或 CLI 调整 Ceph Dashboard 模块的日志级别:**
- 通过 Dashboard:导航 `Cluster` → `Manager modules`,选择 `Dashboard module` 并点击编辑按钮,修改 `log_level` 配置。
- 通过 CLI:
```bash
bin/ceph config set mgr mgr/dashboard/log_level debug
```
**第 3 步:高日志级别会产生可观的日志量,很容易填满文件系统。** 应在未来一小时、一天或一周设置一个日历提醒,以便**回退这个临时的日志级别提升**。大致如下:
```bash
ceph config log
```
```text
...
--- 11 --- 2020-11-07 11:11:11.960659 --- mgr.x/dashboard/log_level = debug ---
...
```
```bash
ceph config reset 11
```
##### 在 Dashboard 中启用集中式日志(Centralized Logging)
1. 使用 "Create Services" 选项在任意特定主机上创建 **Loki** 服务。
2. 类似地创建 **Promtail** 服务,它会**默认部署在所有运行中的主机上**。
3. 要通过 CLI 同时看到 debug 级别消息与 info 级别事件,运行:
```bash
ceph config set mgr mgr/cephadm/log_to_cluster_level debug
```
4. 要启用记录到文件,运行:
```bash
ceph config set global log_to_file true
ceph config set global mon_cluster_log_to_file true
```
5. 点击 `Cluster -> Logs` 下的 `Daemon Logs` 标签页。
6. 点击 Log browser 按钮可以看到一些预定义标签,如 `filename`、`job` 等,可帮助你一次性查询日志。
7. 可以用 **LogQL** 查询日志进行高级搜索并执行一些计算 —— https://grafana.com/docs/loki/latest/logql/
##### 从 Dashboard 报告问题(Reporting issues)
Ceph-Dashboard 提供两种方式在 Ceph Issue Tracker 中创建 issue:使用 Ceph 命令行接口,或使用 Ceph Dashboard 用户界面。
要在 Ceph Issue Tracker 创建 issue,用户需要在 issue tracker 上拥有一个账户。在 Ceph Issue Tracker 的 `my account` 标签页下,用户可以看到其 **API access key**。该 key 用于创建新 issue 时的认证。存储 Ceph API access key:
```bash
ceph dashboard set-issue-tracker-api-key -i <file-containing-key>
```
成功更新后,即可创建 issue:
```bash
ceph dashboard create issue <project> <tracker_type> <subject> <description>
```
**可创建 issue 的项目(逐项):**
1. `dashboard`
2. `block`
3. `object`
4. `file_system`
5. `ceph_manager`
6. `orchestrator`
7. `ceph_volume`
8. `core_ceph`
**可用的 tracker 类型:**
1. `bug`
2. `feature`
subject 与 description 由用户设定。
也可以通过 Dashboard 用户界面创建 issue:导航栏右上角的设置图标下拉菜单中有 `Raise an issue` 选项。点击它会打开一个模态对话框,可从各自的下拉菜单中选择 project 与 tracker。subject 与多行 description 由用户添加,然后即可提交该 issue。
### 4.24 Dashboard 配置项逐项汇总表
下表汇总本册中出现的**全部** Dashboard 相关配置项与命令。凡 `mgr/dashboard/*` 形式的**模块选项**,其默认值定义在模块 Python 源码的 `MODULE_OPTIONS` 中,`src/common/options/*.yaml.in` 中**未收录**,因此除源文明确写出的部分外均标注「文档未明确」。
#### 4.24.1 通过 `ceph config set mgr` 设置的模块选项
| 配置项 | 说明 | 默认值 | 默认值来源 |
|---|---|---|---|
| `mgr/dashboard/ssl` | 是否为 dashboard 启用 SSL/TLS。**默认启用** | `true`(源文:「All HTTP connections to the dashboard are secured with SSL/TLS by default」) | 源文明确 |
| `mgr/dashboard/server_addr` | dashboard 绑定的 TCP/IP 地址。未配置时绑定 `::`(所有可用 IPv4 与 IPv6 地址) | `::` | 源文明确 |
| `mgr/dashboard/server_port` | dashboard 绑定的 TCP 端口(SSL 禁用时使用) | `8080`(源文:「will bind to TCP port 8443 or 8080 when SSL is disabled」) | 源文明确 |
| `mgr/dashboard/ssl_server_port` | 启用 SSL 时 dashboard 绑定的 TCP 端口 | `8443` | 源文明确 |
| `mgr/dashboard/$name/server_addr` | 指定 manager 实例(`$name`)的绑定地址 | 继承集群级设置 | 文档未明确 |
| `mgr/dashboard/$name/server_port` | 指定 manager 实例的绑定端口 | 继承集群级设置 | 文档未明确 |
| `mgr/dashboard/$name/ssl_server_port` | 指定 manager 实例的 SSL 绑定端口 | 继承集群级设置 | 文档未明确 |
| `mgr/dashboard/url_prefix` | 反向代理场景下的 URL 前缀,使 dashboard 生成的超链接包含该前缀。访问地址为 `http://$IP:$PORT/$PREFIX/` | 空(无前缀) | 文档未明确(源文未给出字面默认) |
| `mgr/dashboard/standby_behaviour` | standby 实例行为:`redirect`(默认,返回 303 重定向到 active)或 `error`(返回 HTTP 错误) | `redirect` | 源文明确(「To reset the setting to default redirection」使用 `redirect`) |
| `mgr/dashboard/standby_error_status_code` | `standby_behaviour="error"` 时返回的 HTTP 状态码。**默认 500** | `500` | 源文明确(「respond with an HTTP error (500 by default)」) |
| `mgr/dashboard/redirect_resolve_ip_addr` | 重定向前是否把 IP 地址解析为主机名。**默认禁用**(因基于主机名的解析出错风险更高) | `False` | 源文明确(「the option for hostname resolution is disabled by default」) |
| `mgr/dashboard/log_level` | Dashboard 模块的日志级别,可选 `info`、`debug`、`critical`、`error`、`warning`(或空串以回落到 mgr 守护进程级别) | 继承 mgr 守护进程日志级别(未显式设置时) | 文档未明确(源文未给字面默认) |
| `mgr/dashboard/log_to_file` | 是否把 Dashboard 模块日志写入模块独立日志文件 `<mgr_daemon_log_file_name>.dashboard.log`;启用后**不再**写入 mgr 守护进程日志 | `false`(mgr 模块通用默认) | 文档未明确(源文未给字面默认,见 2.12 节通用模块日志说明) |
| `FEATURE_TOGGLE_DASHBOARD` | 切换新旧落地页(通过 `Cluster >> Manager Modules >> Dashboard >> Edit` 编辑)。**旧版落地页将在未来版本中禁用** | 文档未明确 | 文档未明确(属 feature_toggles 插件,其 include 文件未抓取) |
#### 4.24.2 通过 `ceph dashboard ...` 命令设置的配置项(逐项)
**SSL / 证书类**
| 命令 | 作用 |
|---|---|
| `ceph dashboard create-self-signed-cert` | 生成并安装自签名证书 |
| `ceph dashboard set-ssl-certificate -i dashboard.crt` | 设置 SSL 证书(集群级) |
| `ceph dashboard set-ssl-certificate-key -i dashboard.key` | 设置 SSL 私钥(集群级) |
| `ceph dashboard set-ssl-certificate $name -i dashboard.crt` | 为指定 manager 实例设置 SSL 证书 |
| `ceph dashboard set-ssl-certificate-key $name -i dashboard.key` | 为指定 manager 实例设置 SSL 私钥 |
**认证 / 账户类**
| 命令 | 作用 | 默认值 |
|---|---|---|
| `ceph dashboard get-account-lockout-attempts` | 获取账户锁定尝试次数阈值 | 文档未明确 |
| `ceph dashboard set-account-lockout-attempts <value:int>` | 设置账户锁定尝试次数阈值;**设为 0 可禁用该功能** | 默认启用该功能 |
| `ceph dashboard ac-user-enable <username>` | 启用(解锁/激活)用户 | — |
| `ceph dashboard set-pwd-policy-enabled <true\|false>` | 密码策略总开关 | 默认启用 |
| `ceph dashboard set-pwd-policy-check-length-enabled <true\|false>` | 长度检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-check-oldpwd-enabled <true\|false>` | 新旧密码相同检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-check-username-enabled <true\|false>` | 用户名相关性检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-check-exclusion-list-enabled <true\|false>` | 排除词表检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-check-complexity-enabled <true\|false>` | 复杂度检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-check-sequential-chars-enabled <true\|false>` | 连续字符检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-check-repetitive-chars-enabled <true\|false>` | 重复字符检查开关 | 文档未明确 |
| `ceph dashboard set-pwd-policy-min-length <N>` | 最小密码长度 | `8` |
| `ceph dashboard set-pwd-policy-min-complexity <N>` | 最小密码复杂度 | `10` |
| `ceph dashboard set-pwd-policy-exclusion-list <word>[,...]` | 禁止出现在密码中的逗号分隔词表 | 文档未明确 |
**RGW / iSCSI / 超时类**
| 命令 | 作用 | 默认值 |
|---|---|---|
| `ceph dashboard set-rgw-credentials` | 为每个 realm 创建 uid 为 `dashboard` 的 RGW 用户(cephadm 部署时自动配置) | — |
| `ceph dashboard set-rgw-api-admin-resource <admin_resource>` | 设置 RGW admin API 的自定义 'admin' resource | 文档未明确 |
| `ceph dashboard set-rgw-api-ssl-verify False` | 关闭 RGW API 的 SSL 证书校验 | 默认校验 |
| `ceph dashboard set-rgw-hostname <gateway_name> <hostname>` | 设置某 RGW gateway 的自定义主机名/地址(底层为 `RGW_HOSTNAME_PER_DAEMON`) | 文档未明确 |
| `ceph dashboard unset-rgw-hostname <gateway_name>` | 取消上述设置 | — |
| `ceph dashboard set-rest-requests-timeout <seconds>` | REST 请求超时(秒) | `45` |
| `ceph dashboard set-iscsi-api-ssl-verification false` | 关闭 ceph-iscsi API 的 SSL 证书校验 | 默认校验 |
| `ceph dashboard iscsi-gateway-list` | 列出 iSCSI gateway | — |
| `ceph dashboard iscsi-gateway-add -i <file-containing-gateway-url> [<gateway_name>]` | 添加 iSCSI gateway,URL 格式 `<scheme>://<username>:<password>@<host>[:port]` | — |
| `ceph dashboard iscsi-gateway-rm <gateway_name>` | 移除 iSCSI gateway | — |
**Grafana / Prometheus / Alertmanager 类**
| 命令 | 作用 | 默认值 |
|---|---|---|
| `ceph dashboard set-grafana-api-url <grafana-server-url>` | Grafana 实例 URL,格式 `<protocol>:<IP-address>:<port>` | `''`(空) |
| `ceph dashboard reset-grafana-api-url` | 清除 Grafana API URL 配置 | — |
| `ceph dashboard set-grafana-frontend-api-url <grafana-server-url>` | 仅供浏览器(前端 iframe)访问 Grafana 的 URL;未设置时回落到 `GRAFANA_API_URL` | 回落到 `GRAFANA_API_URL` |
| `ceph dashboard set-grafana-api-ssl-verify False` | 关闭 Grafana API 的 SSL 证书校验 | 默认校验 |
| `ceph dashboard set-alertmanager-api-host <alertmanager-host:port>` | Alertmanager 主机与端口 | `''`(空) |
| `ceph dashboard set-alertmanager-api-ssl-verify False` | 关闭 Alertmanager API 的 SSL 证书校验 | 默认校验 |
| `ceph dashboard set-prometheus-api-host <prometheus-host:port>` | Prometheus API 主机与端口 | `''`(空) |
| `ceph dashboard set-prometheus-api-ssl-verify False` | 关闭 Prometheus API 的 SSL 证书校验 | 默认校验 |
**SSO 类**
| 命令 | 作用 |
|---|---|
| `ceph dashboard sso setup saml2 <ceph_dashboard_base_url> <idp_metadata> {<idp_username_attribute>} {<idp_entity_id>} {<sp_x_509_cert>} {<sp_private_key>}` | 配置 SAML2 SSO |
| `ceph dashboard sso show saml2` | 显示当前 SAML 2.0 配置 |
| `ceph dashboard sso enable saml2` | 启用 SAML2 SSO |
| `ceph dashboard sso enable oauth2` | 启用 OAuth2 SSO |
| `ceph dashboard sso disable` | 禁用 SSO |
| `ceph dashboard sso status` | 检查 SSO 是否启用 |
**审计 / 调试 / 问题上报类**
| 命令 | 作用 | 默认值 |
|---|---|---|
| `ceph dashboard set-audit-api-enabled <true\|false>` | 是否把 `PUT`/`POST`/`DELETE` API 请求记录到 Ceph audit log | `false`(默认禁用) |
| `ceph dashboard set-audit-api-log-payload <true\|false>` | 是否记录请求载荷(参数及其值) | `true`(默认启用) |
| `ceph dashboard debug enable` | 在后端响应中包含错误 traceback | 默认禁用 |
| `ceph dashboard set-issue-tracker-api-key -i <file-containing-key>` | 存储 Ceph Issue Tracker 的 API access key | — |
| `ceph dashboard create issue <project> <tracker_type> <subject> <description>` | 在 Ceph Issue Tracker 创建 issue | — |
> 引自:[Ceph Dashboard](https://docs.ceph.com/en/tentacle/mgr/dashboard/)
---
## 五、告警模块(alerts)
来源页面:`mgr/alerts.rst`
### 5.1 用途与定位
`alerts` 模块可以通过**电子邮件(e-mail)**发送关于**集群健康**的简单告警消息。未来它也将支持其它通知方式。
> **⚠️ 官方明确声明:该模块并非要成为一个健壮的(robust)监控解决方案。** 它作为 Ceph 集群自身的一部分运行,这一事实在根本上是受限的:**`ceph-mgr` 守护进程的故障会导致告警无法发出**。不过,对于那些**存在于没有其它监控基础设施的环境中**的**独立集群(standalone clusters)**,该模块仍然有用。
### 5.2 告警源
- **集群健康状态(cluster health status)**:模块**默认每分钟(once per minute)**检查一次集群健康,并在**集群健康状态发生变化时**发送一条消息。
- 也可通过 `ceph alerts send` **强制立即发送**一次告警。
### 5.3 启用
```bash
ceph mgr module enable alerts
```
### 5.4 配置项(逐项)
> **注意:配置 SMTP 时,以下所有 config 选项都必须设置。** 设置 `mgr/alerts/smtp_destination` 时,多个邮件地址用**逗号**分隔。
| 配置项 | 说明 | 默认值 | 默认值来源 |
|---|---|---|---|
| `mgr/alerts/smtp_host` | SMTP 服务器地址 | 无(**必须设置**) | 文档未明确(`*.yaml.in` 中无此模块选项) |
| `mgr/alerts/smtp_destination` | 收件人邮件地址;多个用逗号分隔 | 无(**必须设置**) | 文档未明确 |
| `mgr/alerts/smtp_sender` | 发件人(From)邮件地址 | 无(**必须设置**) | 文档未明确 |
| `mgr/alerts/smtp_ssl` | 是否使用 SSL | `true`(源文:「uses SSL ... by default」) | 源文明确 |
| `mgr/alerts/smtp_port` | SMTP 端口 | `465`(源文:「port 465 by default」) | 源文明确 |
| `mgr/alerts/smtp_user` | SMTP 认证用户名 | 无(如需认证则必须设置) | 文档未明确 |
| `mgr/alerts/smtp_password` | SMTP 认证密码 | 无(如需认证则必须设置) | 文档未明确 |
| `mgr/alerts/smtp_from_name` | `From:` 行中显示的名字 | `Ceph`(源文:「By default, the name in the `From:` line is simply `Ceph`」) | 源文明确 |
| `mgr/alerts/interval` | 检查集群健康的频率 | `1m`(每分钟一次,源文:「checks the cluster health once per minute」) | 源文明确 |
### 5.5 配置示例
```bash
# 必填三项
ceph config set mgr mgr/alerts/smtp_host *<smtp-server>*
ceph config set mgr mgr/alerts/smtp_destination *<email-address-to-send-to>*
ceph config set mgr mgr/alerts/smtp_sender *<from-email-address>*
# 非 SSL / 非 465 端口时
ceph config set mgr mgr/alerts/smtp_ssl false # if not SSL
ceph config set mgr mgr/alerts/smtp_port *<port-number>* # if not 465
# SMTP 认证
ceph config set mgr mgr/alerts/smtp_user *<username>*
ceph config set mgr mgr/alerts/smtp_password *<password>*
# 自定义 From 显示名(用于标识是哪个集群)
ceph config set mgr mgr/alerts/smtp_from_name 'Ceph Cluster Foo'
# 修改健康检查频率(例如 5 分钟)
ceph config set mgr mgr/alerts/interval *<interval>* # e.g., "5m" for 5 minutes
```
### 5.6 命令(Commands)
**强制立即发送一次告警:**
```bash
ceph alerts send
```
### 5.7 告警列表与处置
> 💡 补充:`alerts.rst` 源文本身**没有**给出「告警列表」——该模块发送的是**集群健康状态变化**的通知,其具体内容取决于 Ceph health checks。源文只描述了「健康状态变化即发信」这一行为。下表把本册其它章节中出现的、与「告警/健康事件处置」相关的命令汇总,作为处置手册使用。
| 场景 | 处置命令 | 说明 |
|---|---|---|
| 想立刻收到一次健康状态邮件 | `ceph alerts send` | 强制立即发送 |
| 查看当前集群健康 | `ceph health` / `ceph status` | 官方未在本页列出,属通用命令 |
| 查看 health check 历史 | `ceph healthcheck history ls [--format {plain\|json\|json-pretty}]` | 见 3.8 |
| 清除 health check 历史 | `ceph healthcheck history clear` | 见 3.8 |
| 查看最近崩溃 | `ceph crash ls-new` | 见 8.1 |
| 归档崩溃(消除 `RECENT_CRASH` 告警) | `ceph crash archive <crashid>` / `ceph crash archive-all` | 见 8.1 |
| 管理与静默告警(Prometheus 侧) | Dashboard 的 `Cluster -> Monitoring` 页面(Active Alerts / All Alerts / Silences) | 见 4.15 |
> 引自:[Alerts module](https://docs.ceph.com/en/tentacle/mgr/alerts/)
---
## 六、RESTful API(Ceph API)
来源页面:`mgr/ceph_api/index.rst`、`mgr/cli_api.rst`
### 6.1 简介
**Ceph RESTful API**(下称 **Ceph API**)由 **Dashboard 模块**提供。Ceph API 服务与常规 Ceph Dashboard 位于**同一 URL**,位于 **`/api`** 基础路径下:
```text
http://<server_addr>:<server_port>/api
```
若启用 HTTPS:
```text
https://<server_addr>:<ssl_server_port>/api
```
**Ceph API 采用的标准(逐项):**
| 标准 | 用途 |
|---|---|
| `HTTP 1.1`(RFC 7231) | API 语法与语义 |
| `JSON`(RFC 8259) | 内容编码 |
| `HTTP Content Negotiation`(RFC 2295)与 `MIME`(RFC 2045) | 版本控制 |
| `OAuth 2.0`(RFC 6750)与 `JWT`(RFC 7519) | 认证与授权 |
> ⚠️ **警告:部分端点仍在积极开发中,应谨慎使用,因为新的 Ceph 发布可能带来向后不兼容的变更。**
### 6.2 认证与授权(Authentication and Authorization)
对 Ceph API 的请求会经过**两个访问控制检查点**:
| 检查点 | 作用 |
|---|---|
| **Authentication(认证)** | 确保请求是代表一个**存在且有效**的用户账户执行的 |
| **Authorization(授权)** | 确保已认证的用户**确实可以**对目标端点执行特定动作(create、read、update、delete) |
**获取 JWT:** 在开始消费 Ceph API 之前,必须先获取一个有效的 **JSON Web Token(JWT)**,之后可复用于后续请求。`/api/auth` 端点会提供有效 token:
```bash
curl -X POST "https://example.com:8443/api/auth" \
-H "Accept: application/vnd.ceph.api.v1.0+json" \
-H "Content-Type: application/json" \
-d '{"username": <username>, "password": <password>}'
```
响应:
```json
{ "token": "<redacted_token>", ...}
```
**携带 token:** 获取的 token 必须随每个 API 请求放在 **`Authorization` HTTP 头**中:
```bash
curl -H "Authorization: Bearer <token>" ...
```
**认证与授权的进一步配置**可通过 Ceph CLI、Ceph-Dashboard UI 以及 Ceph API 自身完成(参见 4.13 用户与角色管理)。
### 6.3 版本控制(Versioning)
Ceph API 的主要目标之一是**保持稳定的接口**。为此,Ceph API 建立在以下原则之上:
| 原则 | 说明 |
|---|---|
| **Mandatory(强制性)** | 为避免隐式默认值,**所有端点都要求显式的默认版本**(从 `1.0` 开始) |
| **Per-endpoint(按端点)** | 由于该 API 封装了许多不同的 Ceph 组件,这允许**更细粒度的变更控制** |
| **Content/MIME Type** | 特定端点所期望的版本由 HTTP 头 `Accept: application/vnd.ceph.api.v<major>.<minor>+json` 声明。若当前 Ceph API server 无法满足该特定 major 版本,会返回 **415 - Unsupported Media Type** 响应 |
| **Semantic Versioning** | 采用 `major.minor` 版本号:**major** 变更**向后不兼容**(可能导致特定端点请求/响应格式的非增量式变化);**minor** 变更**向后/向前兼容**(基本上是对端点请求或响应格式的增量式增加) |
**示例:**
```bash
curl -X GET "https://example.com:8443/api/osd" \
-H "Accept: application/vnd.ceph.api.v1.0+json" \
-H "Authorization: Bearer <token>"
```
### 6.4 规范(Specification)
Ceph API 的规范由 OpenAPI 定义自动生成,源文通过 `.. openapi:: ../../../src/pybind/mgr/dashboard/openapi.yaml` 引入(带 `:group:`、`:examples:`、`:encoding: utf-8`)。
> 📌 说明:具体的端点清单(路径、方法、参数、响应模型)由该 OpenAPI 文件在文档构建期展开,源文中**不包含**逐端点的文本描述,因此本册不列举具体端点,只给出 API 的结构、认证与版本控制机制。实际可用端点请访问已部署集群上的 `openapi.yaml` 或 Dashboard 中的 API 文档页面。
> 💡 补充:在有 Dashboard 运行的集群上,通常可通过 `https://<dashboard-host>:<port>/api/` 附近的 Swagger/OpenAPI UI 或源码 `src/pybind/mgr/dashboard/openapi.yaml` 查看完整端点清单;这一点源文未明说。
### 6.5 常用 API 相关路径(本册范围内出现)
| 路径 | 用途 | 出现章节 |
|---|---|---|
| `/api/auth` | 认证,获取 JWT | 6.2 |
| `/api/osd` | OSD 相关(示例) | 6.3 |
| `/api/prometheus_receiver` | Alertmanager webhook 推送到 dashboard 的接收器 | 4.15 方式 1 |
| `/api/rgw/user/<uid>` | RGW 用户管理(审计日志示例) | 4.19 |
### 6.6 CLI API 模块(cli_api)
来源页面:`mgr/cli_api.rst`
**用途:** CLI API 模块通过 CLI 命令暴露**大部分 ceph-mgr Python API**。该 API **可被基准测试(benchmarked)**。
**启用:**
```bash
ceph mgr module enable cli_api
```
**确认已启用:**
```bash
ceph mgr module ls | grep cli_api
```
**使用(Usage):**
Manager CLI 命令的一般形式:
```bash
ceph mgr cli <command> <param>
```
**打印服务器列表:**
```bash
ceph mgr cli list_servers
```
**列出所有可用的 Manager 模块命令:**
```bash
ceph mgr cli --help
```
**对命令做基准测试:**
```bash
ceph mgr cli_benchmark <number of calls> <number of threads> <command> <param>
```
例如,对获取 `osd_map` 的命令做基准测试:
```bash
ceph mgr cli_benchmark 100 10 get osd_map
```
> 💡 补充:`cli_api` 暴露的是 ceph-mgr 的 Python API(见 2.12「访问集群数据」中的 `get`、`get_server`、`list_servers`、`get_metadata`、`get_daemon_status`、`get_perf_schema`、`get_latest_counter`、`get_mgr_id`、`get_daemon_health_metrics` 等),因此 `ceph mgr cli --help` 输出的方法名与这些访问器是对应的。
> 引自:[Ceph RESTful API](https://docs.ceph.com/en/tentacle/mgr/ceph_api/)
> 引自:[CLI API Commands Module](https://docs.ceph.com/en/tentacle/mgr/cli_api/)
---
## 七、编排器(Orchestrator)
来源页面:`mgr/orchestrator.rst`、`mgr/orchestrator_modules.rst`
### 7.1 概念
`orchestrator` 模块为**编排器模块(orchestrator modules)**提供**命令行接口(CLI)**。编排器模块是 **`ceph-mgr` 插件**,用于与外部编排服务(external orchestration services)对接。
### 7.2 术语定义(Definition of Terms)
编排器 CLI 统一了多个外部编排器,因此需要一套通用术语:
| 术语 | 定义 |
|---|---|
| ***host*** | 物理主机的 **hostname(不是 DNS 名)**。不是 podname、不是容器名、也不是容器内的 hostname |
| ***service type*** | 服务的类型,例如 `nfs`、`mds`、`osd`、`mon`、`rgw`、`mgr`、`iscsi` |
| ***service*** | 一个**逻辑服务**。通常由分布在多个主机上的多个服务实例组成以实现 HA。例如:`mds` 类型对应 `fs_name`;`rgw` 类型对应 `rgw_zone`;`nfs` 类型对应 `ganesha_cluster_id` |
| ***daemon*** | 一个服务的**单个实例**。通常是一个守护进程,但也可能是内核服务(例如 LIO 或 knfsd)。该标识符应能**唯一标识**该实例 |
**名称之间的关系:**
- 一个 *service* 有一个特定的 *service type*。
- 一个 *daemon* 是某个 *service type* 的**物理实例**。
> **注意:编排器模块可能只实现下面列出的命令的一个子集,且各模块之间的实现可能不同。**
### 7.3 状态(Status)
```bash
ceph orch status [--detail]
```
该命令显示**当前的编排器模式**及其高层状态(编排器插件是否可用且可运行)。
### 7.4 无状态服务(Stateless services)
适用于 **MDS / RGW / NFS / rbd-mirror / iSCSI**。
> **注意:编排器不会配置这些服务。** 有关如何配置特定服务的详细信息,请参阅相关文档。
`name` 参数标识那组实例的**种类(kind)**:
- 一个 **CephFS 文件系统**标识一组 MDS 守护进程。
- 一个 **zone 名**标识一组 RGW。
**创建/扩容/缩容/移除服务:**
```bash
ceph orch apply mds <fs_name> [--placement=<placement>] [--dry-run]
ceph orch apply rgw <name> [--realm=<realm>] [--zone=<zone>] [--port=<port>] [--ssl] [--placement=<placement>] [--dry-run]
ceph orch apply nfs <name> <pool> [--namespace=<namespace>] [--placement=<placement>] [--dry-run]
ceph orch rm <service_name> [--force]
```
其中 `placement` 是一个 placement spec。
示例:
```bash
ceph orch apply mds myfs --placement="3 host1 host2 host3"
```
**服务命令:**
```bash
ceph orch <start|stop|restart|redeploy|reconfig> <service_name>
```
> **注意:这些命令仅适用于 cephadm 容器化守护进程。**
**选项(逐项):**
| 选项 | 说明 |
|---|---|
| `start` | 在相应主机上**启动**守护进程 |
| `stop` | 在相应主机上**停止**守护进程 |
| `restart` | 在相应主机上**重启**守护进程 |
| `redeploy` | 在相应主机上**重新部署** Ceph 守护进程。这会在 `/var/lib/ceph/<fsid>/<daemon-name>` 下**重新创建**守护进程目录结构(若不存在)、刷新其配置文件、重新生成其 unit-file 并重启 systemd daemon |
| `reconfig` | 在相应主机上**重新配置**守护进程。这会刷新配置文件然后重启守护进程。**注意:该命令假定 `/var/lib/ceph/<fsid>/<daemon-name>` 守护进程目录已存在** |
### 7.5 配置 Orchestrator CLI
**选择编排器后端:**
```bash
ceph orch set backend <module>
```
**示例:启用并使用 Rook 编排器模块**
```bash
ceph mgr module enable rook
ceph orch set backend rook
```
**确认后端已正确配置:**
```bash
ceph orch status
```
**禁用编排器:** 使用空字符串 `""`:
```bash
ceph orch set backend ""
ceph mgr module disable rook
```
### 7.6 当前实现状态(Rook vs Cephadm)
| 命令 | Rook | Cephadm |
|---|---|---|
| `apply iscsi` | ⚪ 未实现 | ✔ 已实现 |
| `apply mds` | ✔ | ✔ |
| `apply mgr` | ⚪ | ✔ |
| `apply mon` | ✔ | ✔ |
| `apply nfs` | ✔ | ✔ |
| `apply osd` | ✔ | ✔ |
| `apply rbd-mirror` | ✔ | ✔ |
| `apply cephfs-mirror` | ⚪ | ✔ |
| `apply grafana` | ⚪ | ✔ |
| `apply prometheus` | ❌ 不适用 | ✔ |
| `apply alertmanager` | ❌ 不适用 | ✔ |
| `apply node-exporter` | ❌ 不适用 | ✔ |
| `apply rgw` | ✔ | ✔ |
| `apply container` | ⚪ | ✔ |
| `apply snmp-gateway` | ❌ 不适用 | ✔ |
| `host add` | ⚪ | ✔ |
| `host ls` | ✔ | ✔ |
| `host rm` | ⚪ | ✔ |
| `host maintenance enter` | ❌ | ✔ |
| `host maintenance exit` | ❌ | ✔ |
| `daemon status` | ⚪ | ✔ |
| `daemon {stop,start,...}` | ⚪ | ✔ |
| `device {ident,fault}-(on,off}` | ⚪ | ✔ |
| `device ls` | ✔ | ✔ |
| `iscsi add` | ⚪ | ✔ |
| `mds add` | ⚪ | ✔ |
| `nfs add` | ⚪ | ✔ |
| `rbd-mirror add` | ⚪ | ✔ |
| `rgw add` | ⚪ | ✔ |
| `ls` | ✔ | ✔ |
| `ps` | ✔ | ✔ |
| `status` | ✔ | ✔ |
| `upgrade` | ❌ | ✔ |
**图例:**
- ⚪ = not yet implemented(尚未实现)
- ❌ = not applicable(不适用)
- ✔ = implemented(已实现)
### 7.7 编排器模块(Orchestrator modules,开发者视角)
来源页面:`mgr/orchestrator_modules.rst`
> ⚠️ **这是开发者文档,描述 Ceph 内部机制,只对编写 ceph-mgr 编排器模块的人有意义。**
**定位:**
- 在此语境中,*orchestrator* 指某个**外部服务**,它提供**发现设备与创建 Ceph 服务**的能力。这包括像 **Rook** 这样的外部项目。
- 一个 *orchestrator module* 是一个 ceph-mgr 模块,它使用特定的 orchestrator 实现**通用的管理操作**。
- 编排器模块继承 **`Orchestrator`** 类:该类是一个**接口(interface)**,只提供待子类实现的方法定义。为不同编排器定义这一通用接口的目的,是让**通用 UI 代码(例如 dashboard)**能够配合各种不同后端工作。
**架构关系(源文 graphviz 图所示):**
```text
ceph-mgr
+------------------------------------------------+
| mgr/volumes mgr/rook mgr/dashboard |
| mgr/orchestrator (CLI) |
| | |
| v |
| Orchestrator Interface |
| | |
| +-------+--------+ |
| v v |
| mgr/rook ------> Rook (外部) |
| mgr/cephadm |
+------------------------------------------------+
```
即:`volumes` → `orchestrator`;`dashboard` → `orchestrator`;`orchestrator_cli` → `orchestrator`;`orchestrator` → `rook` → Rook;`orchestrator` → `cephadm`。
**本质目的:** 在所有抽象背后,编排器模块的目的很简单——让 Ceph 能够做诸如**发现可用硬件、创建与销毁 OSD、运行 MDS 与 RGW 服务**这类事情。
**术语表(Glossary):**
| 术语 | 定义 |
|---|---|
| **Stateful service** | 使用本地存储的守护进程,例如 OSD 或 mon |
| **Stateless service** | 不使用任何本地存储的守护进程,例如 MDS、RGW、nfs-ganesha、iSCSI gateway |
| **Label** | 管理员可施加到主机上的**任意字符串标签**。管理员通常用标签指示**哪些主机应运行哪类服务**。标签是**建议性的**(来自人工输入),**不保证**主机具备特定的物理能力 |
| **Drive group** | 具有**共同/共享 OSD 格式化方式**的块设备集合(典型情形:一个或多个 SSD 作为一组 HDD 的 journal/db) |
| **Placement** | 选择**由哪台主机**运行某个服务 |
**关键概念(Key Concepts):**
- **底层编排器是关于「服务是否在运行、什么在哪里运行、哪些主机可用」等信息的唯一真相来源(source of truth)。** 编排器模块应**避免**保留这些信息的任何内部副本,并尽可能**直接从编排器后端读取**。
- **引导主机并把它们加入底层编排系统,不在 Ceph 编排器接口的范围内。** Ceph 只能在编排器**已经知晓**这些主机时对其进行操作。
- 在可能的情况下,**无状态服务的放置应交给编排器决定**。
**Completions 与批处理(Completions and batching):**
- 所有**读取或修改系统状态**的方法都可能是**长时间运行**的,因此模块需要**调度**这些操作。
- 每个编排器模块自行实现其底层的 completion 机制。这可能涉及在线程中运行底层操作,或把操作**批处理**起来稍后在后台一次性执行。若实现这种批处理模式,模块在某个操作**出现在传给 `process` 的 completions 列表中之前**不会对其做任何工作。
**错误处理(Error Handling):**
编排器模块内错误处理的主要目标是**提供调试信息,协助用户处理部署错误**。
需要显式处理的错误类型(**逐项**):
| # | 错误类型 | 处理方式 |
|---|---|---|
| 1 | **未配置编排器(No orchestrator configured)** | 见 `NoOrchestrator` 类 |
| 2 | **编排器未实现某个特定方法**(例如某 Orchestrator 不支持 `add_host`) | 抛出 `NotImplementedError` |
| 3 | **已实现方法内缺少特性**(例如后端不支持某命令的可选参数,如 rook 后端下 `Orchestrator.apply_mons` 命令的 hosts 字段) | 见 `OrchestratorValidationError` |
| 4 | **输入校验错误** | `orchestrator` 模块与其它调用模块应提供有意义的错误信息。见 `OrchestratorValidationError` |
| 5 | **实际执行命令时出错** | 返回的 `Completion` 应包含一个有助于理解问题的错误字符串;此外 `Completion.is_errored` 被设为 `True` |
| 6 | **编排器模块内的无效配置** | 可类似第 5 点处理 |
**所有其它错误都是意外的编排器问题**,应抛出异常并记录到 mgr 日志文件。如果此时存在 completion 对象,`Completion.result` 可能包含错误消息。
**被排除的功能(Excluded functionality):**
- Ceph 的编排器接口**不是**用于管理 Linux 服务器的通用框架——它被**有意限制为只管理 Ceph 集群的服务**。
- **不处理多路径存储**(Ceph 集群不需要多路径)。假设每个驱动器**只在单个主机上可见**。
**主机管理(Host management):** 方法包括 `add_host`、`remove_host`、`get_hosts`、`update_host_addr`、`add_host_label`、`remove_host_label`;类 `HostSpec`。
**设备(Devices):** 方法 `get_inventory`;类 `InventoryFilter`、`Devices`、`Device`。
**放置(Placement):** 一个 placement spec 定义某个服务的守护进程放在哪里。一般而言,**无状态服务不需要任何特定的放置规则**,因为只要有足够的系统资源,它们可以运行在任何地方。不过某些编排器可能不包含以这种方式选择位置的功能。(可选地)可以在创建无状态服务时指定一个位置。类 `PlacementSpec`。
**服务(Services):** 类 `ServiceDescription`、`ServiceSpec`;方法 `describe_service`、`service_action`、`remove_service`。
**守护进程(Daemons):** 方法 `list_daemons`、`remove_daemons`、`daemon_action`;类 `DaemonDescription`、`DaemonDescriptionStatus`。
**OSD 管理:** 方法 `create_osds`、`blink_device_light`;类 `DeviceLightLoc`。
**OSD 替换(OSD Replacement):** 替换 OSD 本质上是一个**两阶段过程**,因为用户需要物理更换驱动器。编排器因此把这两个阶段暴露出来:
- **阶段一**:调用 `Orchestrator.remove_daemons` 并带 `destroy=True`,以把该 OSD 标记为 destroyed。
- **阶段二**:调用 `Orchestrator.create_osds`,使用一个把 `DriveGroupSpec.osd_id_claims` 设为那些被销毁的 OSD id 的 Drive Group。
底层流程参见 rados 文档中的「替换 OSD」。
**服务(第二批):** 方法 `add_daemon`、`apply_mon`、`apply_mgr`、`apply_mds`、`apply_rbd_mirror`;类 `RGWSpec`;方法 `apply_rgw`;类 `NFSServiceSpec`;方法 `apply_nfs`。
**升级(Upgrades):** 方法 `upgrade_available`、`upgrade_start`、`upgrade_status`;类 `UpgradeStatusSpec`。
**工具(Utility):** 方法 `available`、`get_feature_set`。
**客户端模块(Client Modules):** 类 `OrchestratorClientMixin`。
### 7.8 与 cephadm / rook 的关系
| 编排器 | 模块名 | 特点 | 本册相关章节 |
|---|---|---|---|
| **cephadm** | `cephadm` | 官方默认编排器;实现最完整(上表 30 项中仅无 ❌ 项缺失,⚪ 项也已基本实现);可部署监控栈(Prometheus/Grafana/Alertmanager/node-exporter/Loki/Promtail)、mgmt-gateway、oauth2-proxy 等 | 4.16.1、4.14.2、七 |
| **rook** | `rook` | 在 **Kubernetes** 内运行 Ceph;为编排器框架(供 `dashboard` 等模块控制集群服务)与 Rook 之间提供集成。要求 Rook **0.9 或更新**。因其 ceph-mgr 守护进程运行在 Kubernetes pod 中,`rook` 模块**无需显式配置**即可连接 Kubernetes API | 7.5、7.6、8.12 |
> **注意:编排器模块只向其它模块提供服务,其它模块再提供用户界面。** 想试用 rook 模块,可以配合 Orchestrator CLI 模块使用。
**rook 模块的要求:**
- 用 Rook 在 Kubernetes 中部署的、正在运行的 **ceph-mon 与 ceph-mgr** 服务。
- **Rook 0.9 或更新**。
> 引自:[Orchestrator CLI](https://docs.ceph.com/en/tentacle/mgr/orchestrator/)
> 引自:[ceph-mgr orchestrator modules](https://docs.ceph.com/en/tentacle/mgr/orchestrator_modules/)
---
## 八、各内置模块逐个讲
`mgr/index.rst` 的 toctree 给出了 Tentacle 官方文档收录的 ceph-mgr 模块清单,本章逐个讲其中的**内置功能模块**(Dashboard / Prometheus / alerts / RESTful API / Orchestrator CLI 已在前面章节专门讲过,这里不重复):
| 官方 toctree 条目 | 页面文件名 | 本册位置 |
|---|---|---|
| Installation and Configuration | `administrator` | 第二章 |
| Writing modules | `modules` | 第二章(模块机制) |
| Writing orchestrator plugins | `orchestrator_modules` | 第七章 |
| Dashboard module | `dashboard` | 第四章 |
| Ceph RESTful API | `ceph_api/index` | 第六章 |
| Alerts module | `alerts` | 第五章 |
| DiskPrediction module | `diskprediction` | 8.8 |
| Local pool module | `localpool` | 8.9 |
| Prometheus module | `prometheus` | 第三章 |
| Influx module | `influx` | 8.6 |
| Hello module | `hello` | 8.10 |
| Telegraf module | `telegraf` | 8.5 |
| Telemetry module | `telemetry` | 8.4 |
| Iostat module | `iostat` | 8.7 |
| Crash module | `crash` | 8.1 |
| Insights module | `insights` | 8.3 |
| Orchestrator module | `orchestrator` | 第七章 |
| Rook module | `rook` | 8.12 |
| RGW module | `rgw` | 8.13 |
| MDS Autoscaler module | `mds_autoscaler` | 8.11 |
| NFS module | `nfs` | 8.14 |
| SMB module | `smb` | 8.15 |
| Progress Module | `progress` | 8.2 |
| CLI API Commands module | `cli_api` | 第二章 / 第六章 |
> 💡 补充:上表把 `mgr/index.rst` 的 toctree 顺序与本册章节做了映射,方便你按官方目录对照阅读。
### 8.1 crash —— 守护进程崩溃转储收集
**用途**
`crash` 模块收集守护进程崩溃转储(crashdump)信息,并把它存储在 Ceph 集群中以供后续分析。官方明确指出:`crash` 是**始终开启、无法禁用**的模块之一("one of the modules which are always on and cannot be disabled")。
**启用命令**
不需要(也不能)`ceph mgr module enable crash`。要做的是为其**配置上传凭据**:
```bash
ceph auth get-or-create client.crash mon 'profile crash' mgr 'profile crash'
```
把生成的 key 存放到集群每个节点的 `/etc/ceph/ceph.client.crash.keyring`。
**自动化收集**
- 守护进程崩溃转储默认落在 `/var/lib/ceph/crash`,可通过配置项 `crash dir` 修改。
- 崩溃目录以「时间日期 + 随机生成的 UUID」命名,目录内含一个元数据文件 `meta` 与一个最近的日志文件;两者的 `crash_id` 相同。
- 由 `ceph-crash.service` 监视崩溃目录,并用 `ceph crash post` 自动上传,持久化到 **monitors 的存储**中。
- `ceph-crash` 会依次尝试这些认证名:`client.crash.$hostname`、`client.crash`、`client.admin`。要成功上传,这些身份需要具备 `mon profile crash` 与 `mgr profile crash` 权限,且 keyring 必须位于 `/etc/ceph` 下。
**配置项**
| 配置项 | 默认值 | 说明 | 默认值来源 |
|---|---|---|---|
| `crash dir` | `/var/lib/ceph/crash` | 崩溃转储归档目录(rst 中写作 `crash dir`,对应 `crash_dir`) | `src/common/options/global.yaml.in` @ v20.2.4(`type: str`,`level: advanced`,`flags: startup`,desc: Directory where crash reports are archived) |
| `mgr/crash/warn_recent_interval` | 2 weeks | 定义「近期」的时长窗口,用于触发 `RECENT_CRASH` 健康告警 | rst 源文明确写出(默认值为构建期占位符,未收录于 `*.yaml.in`) |
| `mgr/crash/retain_interval` | 1 year | 崩溃报告在集群中保留多久后被自动清理 | rst 源文明确写出 |
**命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph crash post -i <metafile>` | 保存一个崩溃转储。`metafile` 是崩溃目录中名为 `meta` 的 JSON blob;照例可用 `-i -` 从 stdin 读取 |
| `ceph crash rm <crashid>` | 删除指定的崩溃转储 |
| `ceph crash ls` | 列出全部 new 与 archived 崩溃信息的 timestamp/uuid crashid |
| `ceph crash ls-new` | 只列出 **new** 状态的崩溃信息 |
| `ceph crash stat` | 按时间分组显示已保存崩溃信息的汇总 |
| `ceph crash info <crashid>` | 显示某个已保存崩溃的全部细节 |
| `ceph crash prune <keep>` | 删除早于 `keep` 天的崩溃记录;`<keep>` 必须为整数 |
| `ceph crash archive <crashid>` | 归档某个崩溃报告,使其不再参与 `RECENT_CRASH` 健康检查、也不再出现在 `ceph crash ls-new` 输出中(**仍会出现在** `ceph crash ls` 中) |
| `ceph crash archive-all` | 归档所有 new 崩溃报告 |
**使用示例**
```bash
# 1. 创建专用 keyring 并分发
ceph auth get-or-create client.crash mon 'profile crash' mgr 'profile crash' \
> /etc/ceph/ceph.client.crash.keyring
# 2. 手工上报一次崩溃(在崩溃目录下)
ceph crash post -i /var/lib/ceph/crash/2026-09-17T10:22:33.123456Z_abcd/meta
# 3. 查看与处置
ceph crash ls-new
ceph crash stat
ceph crash info 2026-09-17T10:22:33.123456Z_abcd
ceph crash archive-all # 确认已处理后归档,消除 RECENT_CRASH
ceph crash prune 30 # 清理 30 天前的崩溃记录
```
**注意事项**
- `crash` 模块无法禁用;只应通过认证配置与目录配置去调整它。
- 归档(archive)**不等于**删除:归档只影响 `RECENT_CRASH` 健康检查与 `ls-new` 输出,`ls` 仍能看到。真正释放空间要用 `rm` 或 `prune`。
- 若节点的 keyring 不在 `/etc/ceph` 下,或身份缺 `profile crash`,`ceph-crash.service` 的自动上传会静默失败。
> 引自:[Crash Module](https://docs.ceph.com/en/tentacle/mgr/crash/)
### 8.2 progress —— 恢复进度可视化
**用途**
`progress` 模块用于告知用户受事件影响的 PG(Placement Group)的**恢复进度**。触发场景包括两类:
1. OSD 被标记 in / out;
2. `pg_autoscaler` 调整以匹配目标 PG 数。
`ceph -status`(即 `ceph -s`)返回的 **"Global Recovery Progress"** 就来自该模块,它基于处于 `active+clean` 状态的 PG 数量汇报总体恢复进度。
**启用命令**
默认已启用;也可手工开关:
```bash
ceph progress on
ceph progress off
```
**配置项**
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `mgr/progress/allow_pg_recovery_event` | `false`(默认关闭) | 是否在 `ceph progress` 中为每个受恢复影响的 PG 显示一个 event。官方明确说明:这是可选功能,**默认禁用**,因为它带来的 CPU 开销可能对 Monitors 造成不利影响 |
**命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph progress` | 显示所有进行中与已完成 event 的汇总及其持续时间 |
| `ceph progress json` | 以 JSON 格式显示进行中与已完成 event 的汇总 |
| `ceph progress clear` | 清除所有进行中与已完成 event |
**使用示例**
```bash
# 打开每个 PG 的恢复 event(注意 CPU 开销)
ceph config set mgr mgr/progress/allow_pg_recovery_event true
# 观察恢复进度
ceph progress
ceph progress json
# 事件处理完后清空列表
ceph progress clear
```
**注意事项**
- `allow_pg_recovery_event` 在大集群上开启会显著增加 Monitor 负担,**不建议长期开启**,排障时临时打开、用完关掉。
- `ceph progress clear` 只清展示列表,不影响真实的数据恢复过程。
> 引自:[Progress Module](https://docs.ceph.com/en/tentacle/mgr/progress/)
### 8.3 insights —— 面向 Insights Core 的数据采集
**用途**
`insights` 模块收集并把系统信息暴露给 **Insights Core 数据分析框架**。其设计意图是替代「显式调用 Ceph CLI 与守护进程 admin socket 做巡检」的做法,从而**减小 Insights 所依赖的 API 面**。
**报告内容**
| 内容类别 | 说明 |
|---|---|
| **Health reports**(健康报告) | 除当前集群健康状态外,还汇报**最近 24 小时**健康检查的汇总。这一点很重要,因为可捕获那些**瞬时出现、生成报告时已消失**的健康问题。健康检查会做**去重**,避免数据无界增长 |
| **Crash reports**(崩溃报告) | 最近 24 小时内守护进程崩溃的汇总,按守护进程类型(如 `ceph-osd`)统计时间窗内的崩溃**次数**。完整崩溃细节需配合 `crash` 模块获取 |
| 其它 | 软件版本、存储使用率、集群 map、PG 汇总、monitor 状态、集群配置、OSD metadata |
**启用命令**
```bash
ceph mgr module enable insights
```
**配置项**
官方文档本页面**未列出任何模块配置项**。
**命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph insights` | 生成完整报告 |
| `ceph insights prune-health <hours>` | 清除早于 `<hours>` 小时的历史健康数据;传 `0` 表示清空全部健康数据 |
**使用示例**
```bash
ceph mgr module enable insights
ceph insights
# 在自动生成夜间报告之前先清一遍历史,避免把维护期间的假告警带进去
ceph insights prune-health 0
```
**注意事项**
- `prune-health` 的用途是**清洗健康历史**,不是回收存储空间——官方明确说明「无需为了回收空间而清理健康数据,垃圾回收会定期执行,从持久存储中移除旧的健康数据」。
- 典型用法:在做完系统维护、产生了一批已被解决的假健康检查后,先 `prune-health` 再生成报告。
> 引自:[Insights Module](https://docs.ceph.com/en/tentacle/mgr/insights/)
### 8.4 telemetry —— 匿名遥测上报
**用途**
`telemetry` 模块把集群的**匿名**数据发回开发者,用于汇报 Ceph 被如何使用、以及用户遇到的问题。这些数据会可视化在公共看板 `https://telemetry-public.ceph.com/` 上,社区可以看到汇报集群数量、总容量与 OSD 数量、版本分布趋势等汇总统计。
**Channels(通道)**
遥测报告被拆分为若干 "channel"(通道),每个通道承载不同类别的信息。**遥测启用后**,各通道可单独开关;如果遥测本身是关闭的,逐通道设置不起作用。
| 通道 | 默认 | 上报内容 |
|---|---|---|
| **basic** | on | 集群基础信息:集群容量;mon/mgr/osd/mds/RGW 及其它守护进程数量;当前使用的软件版本;RADOS pool 与 CephFS 文件系统数量及类型;**被改动过的配置项名称**(注意:*不包含其值*) |
| **crash** | on | 守护进程崩溃信息:守护进程类型、守护进程版本、操作系统(发行版、内核版本)、堆栈回溯(定位崩溃发生在 Ceph 代码的哪个位置) |
| **device** | on | 设备指标信息:**匿名化后的 SMART 指标** |
| **ident** | off | 用户提供的集群标识信息:集群描述、联系邮箱 |
| **perf** | off | 集群各类性能指标,可用于揭示整体健康、识别负载模式、排查延迟/限流/内存管理等问题、按守护进程监控性能 |
**关于隐私的官方声明**
- 上报数据**不包含任何敏感数据**:不包含 pool 名、object 名、object 内容、主机名、设备序列号。
- 上报内容是与部署方式、Ceph 版本、OS 发行版等相关的**计数器与统计值**。
- 数据通过 `https://telemetry.ceph.com` **加密发送**。
- 设备报告**单独生成**,主机名与设备序列号均被匿名化;设备遥测发送到**不同 endpoint**,且不与特定集群关联。
- `smartmontools` **7.0 或更高版本**必须安装,以便能指定并解析 JSON 输出。如对报告内容有隐私顾虑,可联系 Ceph 开发者。
**启用命令(含许可协议)**
```bash
ceph telemetry on
```
> **必须**加上 `--license sharing-1-0`:遥测数据遵循 *Community Data License Agreement - Sharing - Version 1.0*(CDLA-Sharing-1.0),只有在 `ceph telemetry on` 后追加 `--license sharing-1-0` 才能启用。
```bash
ceph telemetry on --license sharing-1-0
ceph telemetry off
```
**通道开关命令(逐项)**
```bash
# 单通道
ceph telemetry enable channel basic
ceph telemetry enable channel crash
ceph telemetry enable channel device
ceph telemetry enable channel ident
ceph telemetry enable channel perf
ceph telemetry disable channel basic
ceph telemetry disable channel crash
ceph telemetry disable channel device
ceph telemetry disable channel ident
ceph telemetry disable channel perf
# 多通道(一次指定多个)
ceph telemetry enable channel basic crash device ident perf
ceph telemetry disable channel basic crash device ident perf
# 全部通道
ceph telemetry enable channel all
ceph telemetry disable channel all
# 列出通道
ceph telemetry channel ls
```
`ceph telemetry channel ls` 的输出形如:
```text
NAME ENABLED DEFAULT DESC
basic ON ON Share basic cluster information (size, version)
crash ON ON Share metadata about Ceph daemon crashes (version, stack straces, etc)
device ON ON Share device health metrics (e.g., SMART data, minus potentially identifying info like serial numbers)
ident OFF OFF Share a user-provided description and/or contact email for the cluster
perf ON OFF Share various performance metrics of a cluster
```
> 注意:必须 telemetry 已启用,上述 enable/disable 命令才会生效。官方 `channel ls` 示例输出中 `perf` 一行的 ENABLED 为 `ON`、DEFAULT 为 `OFF`,说明该示例取自一个已额外开启 perf 的集群。
**Collections(集合)**
Collection 表示**通道内部**不同方面的数据。
```bash
ceph telemetry collection ls
```
输出示例:
```text
NAME STATUS DESC
basic_base NOT REPORTING: NOT OPTED-IN Basic information about the cluster (capacity, number and type of daemons, version, etc.)
basic_mds_metadata NOT REPORTING: NOT OPTED-IN MDS metadata
basic_pool_flags NOT REPORTING: NOT OPTED-IN Per-pool flags
basic_pool_options_bluestore NOT REPORTING: NOT OPTED-IN Per-pool bluestore config options
basic_pool_usage NOT REPORTING: NOT OPTED-IN Default pool application and usage statistics
basic_rook_v01 NOT REPORTING: NOT OPTED-IN Basic Rook deployment data
basic_stretch_cluster NOT REPORTING: NOT OPTED-IN Stretch Mode information for stretch clusters deployments
basic_usage_by_class NOT REPORTING: NOT OPTED-IN Default device class usage statistics
crash_base NOT REPORTING: NOT OPTED-IN Information about daemon crashes (daemon type and version, backtrace, etc.)
device_base NOT REPORTING: NOT OPTED-IN Information about device health metrics
ident_base NOT REPORTING: NOT OPTED-IN, CHANNEL ident IS OFF User-provided identifying information about the cluster
perf_memory_metrics NOT REPORTING: NOT OPTED-IN, CHANNEL perf IS OFF Heap stats and mempools for mon and mds
perf_perf NOT REPORTING: NOT OPTED-IN, CHANNEL perf IS OFF Information about performance counters of the cluster
```
字段释义:
| 字段 | 含义 |
|---|---|
| `NAME` | Collection 名称;**前缀表示它所属的 channel**(如 `basic_`、`crash_`、`device_`、`ident_`、`perf_`) |
| `STATUS` | 该 collection 的指标是否被上报;由「所属 channel 的启用/禁用状态」与「collection 自身的登记状态(用户是否 opted-in)」共同决定 |
| `DESC` | 该 collection 的概要描述 |
相关命令:
```bash
ceph telemetry diff # 显示「你已登记的 collections」与「新增可用 collections」之间的差异
ceph telemetry on # 登记到最新的一组 collections
ceph telemetry enable channel <channel_name>
```
**配置项**
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `mgr/telemetry/interval` | 24(小时) | 遥测模块编译并发送新报告的间隔。官方示例写 `ceph config set mgr mgr/telemetry/interval 72 # report every three days`,据此默认值为 24 小时 |
| `mgr/telemetry/proxy` | 文档未明确(无代理) | 当集群无法直连遥测 endpoint(默认 `telemetry.ceph.com`)时,配置 HTTP/HTTPS 代理 |
| `mgr/telemetry/contact` | 文档未明确 | 报告中的联系人,形如 `'John Doe <john.doe@example.com>'` |
| `mgr/telemetry/description` | 文档未明确 | 报告中的集群描述,形如 `'My first Ceph cluster'` |
| `mgr/telemetry/channel_ident` | `false` | 是否开启 ident 通道(配合 contact/description 使用) |
| `mgr/telemetry/leaderboard` | 文档未明确 | 是否参与公共看板的 leaderboard |
| `mgr/telemetry/leaderboard_description` | 文档未明确 | leaderboard 上用于识别集群的描述文字 |
**命令(完整逐项)**
| 命令 | 说明 |
|---|---|
| `ceph telemetry on [--license sharing-1-0]` | 启用遥测(必须带 license 参数) |
| `ceph telemetry off` | 关闭遥测 |
| `ceph telemetry enable channel <name>...` / `all` | 启用通道 |
| `ceph telemetry disable channel <name>...` / `all` | 禁用通道 |
| `ceph telemetry channel ls` | 列出所有通道及其 ENABLED / DEFAULT / DESC |
| `ceph telemetry collection ls` | 列出所有 collection 及其 STATUS / DESC |
| `ceph telemetry diff` | 显示已登记 collections 与新增可用 collections 的差异 |
| `ceph telemetry show` | telemetry **已启用**时,显示实际将上报的数据 |
| `ceph telemetry preview` | telemetry **已禁用**时,预览一份示例报告 |
| `ceph telemetry show-device` | 已启用时显示设备报告 |
| `ceph telemetry preview-device` | 已禁用时预览设备报告 |
| `ceph telemetry show-all` | 已启用时,在**单一输出**中生成两份报告 |
| `ceph telemetry preview-all` | 已禁用时,在单一输出中查看两份报告 |
| `ceph telemetry show <channel_name>` | 已启用时,按通道显示上报数据 |
| `ceph telemetry preview <channel_name>` | 已禁用时,按通道预览示例报告 |
| `ceph telemetry status` | 打印 telemetry 模块当前配置 |
| `ceph telemetry send [--license sharing-1-0]` | 异步发送一次一次性遥测数据 |
**使用示例**
```bash
# 启用并额外打开 perf 通道
ceph telemetry on --license sharing-1-0
ceph telemetry enable channel perf
# 通过代理上报(含用户名密码)
ceph config set mgr mgr/telemetry/proxy https://ceph:telemetry@10.0.0.1:8080
# 上报间隔改为 3 天
ceph config set mgr mgr/telemetry/interval 72
# 填写联系人与描述并打开 ident
ceph config set mgr mgr/telemetry/contact 'John Doe <john.doe@example.com>'
ceph config set mgr mgr/telemetry/description 'My first Ceph cluster'
ceph config set mgr mgr/telemetry/channel_ident true
# 参与 leaderboard
ceph config set mgr mgr/telemetry/leaderboard true
ceph config set mgr mgr/telemetry/leaderboard_description 'Ceph cluster for Computational Biology at the University of XYZ'
# 先看再报
ceph telemetry preview
ceph telemetry preview-device
ceph telemetry status
ceph telemetry send --license sharing-1-0
```
**注意事项**
- 生成示例报告在大集群(数百 OSD 或更多)上**可能需要一些时间**。
- 若 telemetry **已开启**、但某个 `<channel_name>` 通道被禁用,`ceph telemetry show <channel_name>` 仍会按用户已登记的 collections 输出一份该通道的示例报告——**但这些数据并不会真的被上报**。
- 如果 ident 通道已启用,其细节**不会**显示在 leaderboard 上。
- leaderboard 上显示的是基础信息:集群总存储容量与 OSD 数量。
> 引自:[Telemetry Module](https://docs.ceph.com/en/tentacle/mgr/telemetry/)
### 8.5 telegraf —— 把统计序列发给 Telegraf
**用途**
`telegraf` 模块收集并把统计**序列**发送给 **Telegraf agent**。Telegraf agent 可以对数据进行缓冲、聚合、解析与处理,再输出到 InfluxDB、ElasticSearch 等。该模块自 **13.x Mimic** 引入。
目前**唯一**的发送方式是 Telegraf 的 **socket listener**(套接字监听器),可通过 **UDP、TCP 或 UNIX socket** 发送。
**启用命令**
```bash
ceph mgr module enable telegraf
ceph mgr module disable telegraf
```
**配置项**
配置通过模块自有命令设置(**注意:不是** `ceph config set mgr`):
```bash
ceph telegraf config-set <key> <value>
```
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `address` | `unixgram:///tmp/telegraf.sock` | 统计发送目标地址。支持 `udp://`、`tcp://`、`unix://`、`unixgram://`、`tcp4://`、`tcp6://`、`udp4://`、`udp6://` 形式 |
| `interval` | `15` | 发送间隔(秒) |
其余可用 key 官方文档未逐项列出。
**Telegraf 侧配置(socket listener + influx 数据格式)**
```ini
[[inputs.socket_listener]]
# service_address = "tcp://:8094"
# service_address = "tcp://127.0.0.1:http"
# service_address = "tcp4://:8094"
# service_address = "tcp6://:8094"
# service_address = "tcp6://[2001:db8::1]:8094"
service_address = "udp://:8094"
# service_address = "udp4://:8094"
# service_address = "udp6://:8094"
# service_address = "unix:///tmp/telegraf.sock"
# service_address = "unixgram:///tmp/telegraf.sock"
data_format = "influx"
```
**使用示例**
```bash
ceph mgr module enable telegraf
ceph telegraf config-set address udp://:8094
ceph telegraf config-set interval 10
```
**注意事项**
- 模块侧 `address` 必须与 Telegraf `[[inputs.socket_listener]]` 的 `service_address` 匹配;上例中 Telegraf 用 `udp://:8094`,模块侧就要设为 `udp://:8094`。
- 数据格式**必须**是 `influx`(`data_format = "influx"`)。
- 只支持 socket listener 一种输入方式,没有 HTTP/其它输出方式的官方支持说明。
> 引自:[Telegraf Module](https://docs.ceph.com/en/tentacle/mgr/telegraf/)
### 8.6 influx —— 时间序列写入 InfluxDB
**用途**
`influx` 模块持续收集并把**时间序列数据**发送到 InfluxDB 数据库。自 **13.x Mimic** 引入。
**启用命令**
```bash
ceph mgr module enable influx
ceph mgr module disable influx
```
**配置项(逐项)**
配置方式:
```bash
ceph config set mgr mgr/influx/<key> <value>
```
| 配置项(key) | 默认值 | 说明 |
|---|---|---|
| `hostname` | 文档未明确 | InfluxDB 服务器地址(官方列为最重要的三项之一) |
| `username` | 文档未明确 | 认证用户名(官方列为最重要的三项之一) |
| `password` | 文档未明确 | 认证密码(官方列为最重要的三项之一) |
| `interval` | 文档未明确 | 采集/发送间隔 |
| `database` | 文档未明确 | 目标 database 名 |
| `port` | 文档未明确 | InfluxDB 端口 |
| `ssl` | 文档未明确 | 是否启用 SSL |
| `verify_ssl` | 文档未明确 | 是否校验 SSL 证书 |
| `threads` | 文档未明确 | 发送线程数 |
| `batch_size` | 文档未明确 | 批量大小 |
> 默认值说明:`influx.rst` 用 `.. confval::` 列出上述 10 个配置项,但页面中的默认值是构建期占位符;`handbook-src/options/*.yaml.in` 中**未收录** `mgr/influx/*` 这类模块选项(它们定义在模块 Python 源码的 `MODULE_OPTIONS` 中),因此此处标注为「文档未明确」。
**调试(Debugging)**
默认只打印少量调试语句与错误语句,可按需增强:
1. 在 `ceph.conf` 中加入:
```ini
[mgr]
debug_mgr = 20
```
2. 执行 `ceph influx self-test`。
3. 查看日志文件;用 `mgr[influx]` 过滤会更容易。
**指标清单(Pools)**
| Counter | Description |
|---|---|
| `stored` | Bytes stored in the pool not including copies |
| `max_avail` | Max available number of bytes in the pool |
| `objects` | Number of objects in the pool |
| `wr_bytes` | Number of bytes written in the pool |
| `dirty` | Number of bytes dirty in the pool |
| `rd_bytes` | Number of bytes read in the pool |
| `stored_raw` | Bytes used in pool including copies made |
**指标清单(OSDs · 客户端操作)**
| Counter | Description |
|---|---|
| `op_w` | Client write operations |
| `op_in_bytes` | Client operations total write size |
| `op_r` | Client read operations |
| `op_out_bytes` | Client operations total read size |
**指标清单(OSDs · 延迟与读写细分)**
| Counter | Description |
|---|---|
| `op_wip` | Replication operations currently being processed (primary) |
| `op_latency` | Latency of client operations (including queue time) |
| `op_process_latency` | Latency of client operations (excluding queue time) |
| `op_prepare_latency` | Latency of client operations (excluding queue time and wait for finished) |
| `op_r_latency` | Latency of read operation (including queue time) |
| `op_r_process_latency` | Latency of read operation (excluding queue time) |
| `op_w_in_bytes` | Client data written |
| `op_w_latency` | Latency of write operation (including queue time) |
| `op_w_process_latency` | Latency of write operation (excluding queue time) |
| `op_w_prepare_latency` | Latency of write operations (excluding queue time and wait for finished) |
| `op_rw` | Client read-modify-write operations |
| `op_rw_in_bytes` | Client read-modify-write operations write in |
| `op_rw_out_bytes` | Client read-modify-write operations read out |
| `op_rw_latency` | Latency of read-modify-write operation (including queue time) |
| `op_rw_process_latency` | Latency of read-modify-write operation (excluding queue time) |
| `op_rw_prepare_latency` | Latency of read-modify-write operations (excluding queue time and wait for finished) |
| `op_before_queue_op_lat` | Latency of IO before calling queue (before really queue into ShardedOpWq) `op_before_dequeue_op_lat` |
| `op_before_dequeue_op_lat` | Latency of IO before calling dequeue_op (already dequeued and get PG lock) |
> 官方文档原文注明:**Latency counters are measured in microseconds unless otherwise specified in the description.**(延迟类计数器单位为微秒,除非描述中另行指定。)
**使用示例**
```bash
ceph mgr module enable influx
ceph config set mgr mgr/influx/hostname influx.mydomain.com
ceph config set mgr mgr/influx/username admin123
ceph config set mgr mgr/influx/password p4ssw0rd
ceph influx self-test
```
**注意事项**
- 官方只说 `hostname`、`username`、`password` 是「最重要的设置」,其余 7 项的含义与取值范围文档未展开。
- 密码会以明文形式进入 Ceph 的 config store,注意权限管控。
- 与 `telegraf` 模块的分工不同:`influx` 直连 InfluxDB;`telegraf` 只发到 Telegraf agent,再由 Telegraf 决定输出到哪里。
> 引自:[Influx Module](https://docs.ceph.com/en/tentacle/mgr/influx/)
### 8.7 iostat —— 集群吞吐与 IOPS
**用途**
`iostat` 模块汇报集群的**吞吐量(throughput)与 IOPS** 指标。
**启用命令**
```bash
ceph mgr module ls # 确认是否已启用
ceph mgr module enable iostat
```
**配置项**
官方文档本页面**未列出任何模块配置项**。
**命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph iostat` | 执行模块,输出统计 |
| `ceph iostat -p <period in seconds>` | 改变统计打印频率 |
| `Ctrl-C` | 停止模块输出 |
**使用示例**
```bash
ceph mgr module ls
ceph mgr module enable iostat
ceph iostat # 默认频率输出
ceph iostat -p 5 # 每 5 秒打印一次
# Ctrl-C 停止
```
**注意事项**
- `iostat` 是 `mgr_initial_modules` 的默认成员之一(默认值 `iostat nfs nvmeof`,见第二章),即新集群默认已启用。
- `ceph iostat` 是一个**交互式持续输出**命令,不是一次性输出,需用 `Ctrl-C` 退出;在脚本中使用需注意。
- 若需要长期存储与告警,应使用 `prometheus` 模块(第三章)而非 `iostat`。
> 引自:[iostat](https://docs.ceph.com/en/tentacle/mgr/iostat/)
### 8.8 diskprediction_local —— 本地磁盘故障预测
**用途**
`diskprediction` 模块利用 Ceph 的 **device health checks** 采集磁盘健康指标,并使用**内部预测器**产出磁盘故障预测,再把结果返回给 Ceph。它**不需要任何外部服务器**做数据分析与结果输出。其内部预测器的**准确率约为 70%**。
**启用命令**
```bash
# 启用模块(注意模块名是 diskprediction_local)
ceph mgr module enable diskprediction_local
# 启用本地预测器
ceph config set global device_failure_prediction_mode local
# 关闭预测
ceph config set global device_failure_prediction_mode none
```
**配置项**
| 配置项 | 默认值 | 说明 | 默认值来源 |
|---|---|---|---|
| `device_failure_prediction_mode` | `none` | 预测模式。`none` 关闭预测;`local` 使用运行在 mgr 守护进程内的预测模型;`cloud` 与云服务共享指标并查询设备预期寿命 | `src/common/options/global.yaml.in` @ v20.2.4(`type: str`,`level: basic`) |
| `mgr/diskprediction_local/predict_interval` | 1 天(官方描述为 "performs the prediction on a daily basis by default") | 预测执行间隔,单位为秒 | rst 源文描述(构建期占位符,未收录于 `*.yaml.in`) |
**命令**
| 命令 | 说明 |
|---|---|
| `ceph device predict-life-expectancy <device id>` | 获取指定设备的预期寿命 |
**使用示例**
```bash
ceph mgr module enable diskprediction_local
ceph config set global device_failure_prediction_mode local
# 调整预测间隔(示例:12 小时一次)
ceph config set mgr mgr/diskprediction_local/predict_interval 43200
# 查询某块盘的预期寿命
ceph device predict-life-expectancy <device id>
```
**调试(Debugging)**
把 Manager 日志级别调到 debug,模块会打印以 `mgr[diskprediction]` 为前缀的日志,便于过滤:
```ini
[mgr]
debug mgr = 20
```
**注意事项**
- `diskprediction_local` 需要**至少 6 组**设备健康指标数据才能预测设备预期寿命;而这些健康指标**只有在 health monitoring 已启用**的情况下才会被采集。
- 预测准确率约 70%,**不能**作为唯一的换盘依据。
- 模块名是 `diskprediction_local`,与页面标题 `DiskPrediction Module` 不同,启用时不要写错。
- 官方 `ceph.conf` 片段示例写作 `debug mgr = 20`(带空格);Ceph 配置项通常写作 `debug_mgr = 20`(见 8.6 influx 示例)。此处照录原文。
> 引自:[DiskPrediction Module](https://docs.ceph.com/en/tentacle/mgr/diskprediction/)
### 8.9 localpool —— 按故障域自动创建本地化池
**用途**
`localpool` 模块可以自动创建**局限于集群某个子集**的 RADOS 池。举例:默认情况下,它为集群中每个不同的 `rack` 各创建一个池。适用于「希望部分数据本地分布、部分数据全局分布」的部署形态。一个典型用例是:隔离地测量与测试特定型号硬盘、网卡或机箱的性能与行为。
**启用命令**
```bash
ceph mgr module enable localpool
```
**配置项(逐项)**
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `subtree` | 文档未明确 | 子树类型(默认行为体现为「按 rack 建池」,官方说 "by default, it creates a pool for each distinct rack") |
| `failure_domain` | 文档未明确 | 故障域 |
| `pg_num` | 文档未明确 | PG 数量 |
| `num_rep` | 文档未明确 | 副本数 |
| `min_size` | 文档未明确 | 最小副本数 |
| `prefix` | `by-$subtreetype-` | 池名前缀。官方原文:The default is ``by-$subtreetype-`` |
> 默认值说明:以上 6 项除 `prefix` 外,`localpool.rst` 仅用 `.. confval::` 列出名称,未给出默认值;`handbook-src/options/*.yaml.in` 中未收录 `mgr/localpool/*`。
**使用示例**
```bash
ceph mgr module enable localpool
# 改为 2 副本、64 PG
ceph config set mgr mgr/localpool/num_rep 2
ceph config set mgr mgr/localpool/pg_num 64
```
**注意事项**
- 官方文档提示这些选项是通过 `config-key` 接口设置的,但示例中实际使用的是 `ceph config set mgr ...`。两处表述存在不一致。
- 该模块会**自动建池**,在生产环境启用前应先明确 `subtree` / `failure_domain`,否则可能产生大量预期外的池。
> 引自:[Local Pool Module](https://docs.ceph.com/en/tentacle/mgr/localpool/)
### 8.10 hello —— 模块骨架示例
**用途**
这是一个**为文档目的**提供的简单模块骨架(module skeleton),用于演示如何编写一个 ceph-mgr 模块。
**启用命令**
```bash
ceph mgr module enable hello
ceph mgr module ls # 确认已启用
```
**配置项**
官方文档本页面**未列出任何模块配置项**。
**命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph hello` | 运行该模块 |
| `ceph mgr module disable hello` + `ceph mgr module enable hello` | 修改模块文件后重新加载以生效 |
| `init-ceph restart mgr` | 另一种重载模块并使其设置改动生效的方式 |
**使用示例**
```bash
ceph mgr module enable hello
ceph mgr module ls
ceph hello
# 编辑 src/pybind/mgr/hello/module.py 后重载
ceph mgr module disable hello
ceph mgr module enable hello
```
**日志位置**
```text
build/out/mgr.x.log
```
**文档化要求(官方对新模块的要求)**
- 新增 mgr 模块后,务必把它的文档加到 `doc/mgr/module_name.rst`;
- 同时把新模块的链接加入 `doc/mgr/index.rst`。
**注意事项**
- 这是开发/教学用模块,生产环境无需启用。
- 日志路径 `build/out/mgr.x.log` 是**源码树内构建**的路径,实际部署中日志位置取决于发行版打包方式。
> 引自:[Hello World Module](https://docs.ceph.com/en/tentacle/mgr/hello/)
### 8.11 mds_autoscaler —— MDS 守护进程数量自动调整
**用途**
MDS Autoscaler 模块监视文件系统,确保**有足够数量的 MDS 守护进程**可用。其工作方式是调整 MDS 服务在编排器后端的 **placement specification(放置规格)**。
**启用命令**
```bash
ceph mgr module enable mds_autoscaler
```
**监视的文件系统设置**
| 设置 | 说明 |
|---|---|
| `max_mds` | 文件系统设置,决定活跃 MDS 数量 |
| `standby_count_wanted` | 文件系统设置,决定期望的 standby 数量 |
**职责边界**
> **Ceph monitor 守护进程仍然负责**根据这些设置来 promote 或 stop MDS。`mds_autoscaler` 只是**调整编排器派生出的 MDS 守护进程数量**。
**配置项**
官方文档明确注明:**截至 Tentacle 版本没有任何模块配置项**("There are no module configurations as of the Tentacle release")。
**CLI**
官方文档明确注明:**截至 Tentacle 版本没有 CLI**("There is no CLI as of the Tentacle release")。开关功能只能通过启用/禁用模块来完成。
**注意事项**
- 该模块**依赖编排器后端**(需要能调整 placement spec),没有编排器时无实际效果。
- 没有配置项、没有 CLI,行为完全由 `max_mds` 与 `standby_count_wanted` 驱动。
> 引自:[MDS Autoscaler Module](https://docs.ceph.com/en/tentacle/mgr/mds_autoscaler/)
### 8.12 rook —— Kubernetes 编排器后端
**用途**
Rook(https://rook.io/)是一个可以在 **Kubernetes 集群内运行 Ceph** 的编排工具。`rook` 模块为 **Ceph 的编排器框架**(被 `dashboard` 等模块用于控制集群服务)与 **Rook** 之间提供集成。
> 编排器模块只向其它模块提供服务,其它模块再提供用户界面。想试用 rook 模块,可以配合 Orchestrator CLI 模块使用。
**要求(Requirements)**
| 要求 | 说明 |
|---|---|
| 运行中的 ceph-mon 与 ceph-mgr | 必须由 Rook 在 Kubernetes 中部署 |
| Rook 版本 | **0.9 或更新** |
**启用/配置**
```bash
ceph orch set backend rook
```
**配置项**
**无需显式配置**。因为 Rook 集群的 ceph-mgr 守护进程运行在 Kubernetes **pod** 中,`rook` 模块**可以直接连接 Kubernetes API**。
**开发**
开发者环境搭建参见官方文档的 `kubernetes-dev` 一节。
**注意事项**
- `rook` 模块本身不提供用户接口;要操作,请使用 `ceph orch` CLI(Orchestrator CLI 模块)或 Dashboard。
- 与 cephadm 的功能覆盖差异见第七章 7.6 的状态矩阵。
> 引自:[Rook](https://docs.ceph.com/en/tentacle/mgr/rook/)
### 8.13 rgw —— RGW 多站点引导与配置
**用途**
`rgw` 模块为部署 RGW **multisite(多站点)** 提供一个简单接口,帮助引导(bootstrap)并配置 RGW 的 **realm、zonegroup** 以及各类相关实体。
**启用命令**
```bash
ceph mgr module enable rgw
```
**配置项**
官方文档本页面**未列出任何模块配置项**(配置通过 spec 文件 / 命令行参数传入)。
**命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph rgw realm bootstrap [--realm-name] [--zonegroup-name] [--zone-name] [--port] [--placement] [--start-radosgw]` | 引导创建新的 RGW realm 实体 + 新的 zonegroup + 新的 zone;配置一个可用于 multisite 同步操作的 system user;底层会让编排器创建并部署对应的 RGW 守护进程。支持命令行传参或用 spec 文件(`-i`) |
| `ceph rgw realm bootstrap -i myrgw.yaml` | 用 spec 文件形式引导 |
| `ceph rgw realm tokens` | 列出已创建(或已存在)realm 的可用 token |
| `ceph rgw zone create -i spec.yaml` | 用 realm token 加入已有 realm,在另一个集群创建 secondary zone |
| `ceph rgw admin [*]` | RGW admin 入口 |
**Realm Credentials Token**
- Token 是一个 **base64 字符串**,封装了 realm 信息与其 master zone endpoint 的认证数据。
- `ceph rgw realm tokens | jq` 输出形如:
```json
[
{
"realm": "myrealm1",
"token": "ewogICAgInJlYWxtX25hbWUiOiAibXlyZWFs....NHlBTFhoIgp9"
},
{
"realm": "myrealm2",
"token": "ewogICAgInJlYWxtX25hbWUiOiAibXlyZWFs....RUU12ZDB0Igp9"
}
]
```
**spec 文件示例**
RGW multisite spec(会启动 cephadm 守护进程):
```yaml
rgw_realm: myrealm
rgw_zonegroup: myzonegroup
rgw_zone: myzone
placement:
hosts:
- ceph-node-1
- ceph-node-2
spec:
rgw_frontend_port: 5500
```
带自定义 zone endpoints 的 spec(**不会**启动 cephadm 守护进程):
```yaml
rgw_realm: myrealm
rgw_zonegroup: myzonegroup
rgw_zone: myzone
zone_endpoints: http://<rgw_host1>:<rgw_port1>, http://<rgw_host2>:<rgw_port2>
```
secondary zone spec(使用 realm token):
```yaml
rgw_zone: my-secondary-zone
rgw_realm_token: <token>
placement:
hosts:
- ceph-node-1
- ceph-node-2
spec:
rgw_frontend_port: 5500
```
**使用示例**
```bash
ceph mgr module enable rgw
# 主集群:引导 realm
ceph rgw realm bootstrap -i spec.yaml
# 取出 token
ceph rgw realm tokens | jq
# 备集群:凭 token 创建 secondary zone
ceph rgw zone create -i zone-spec.yaml
```
**升级 Root CA 证书(Upgrading Root CA Certificates)**
1. 确认 RGW 服务正在运行。
2. 确认 RGW 服务已起来。
3. 确认 RGW 服务已升级到最新版本。
4. 在**主集群**的 Manager 节点上执行:
```bash
ceph orch cert-store get cert cephadm_root_ca_cert
```
5. 在运行 RGW 服务的节点上,把证书存放到:
```text
/etc/pki/ca-trust/source/anchors/<cert_name>.crt
```
6. 校验证书:
```bash
openssl x509 -in <cert_name>.crt -noout -text
```
7. 在所有**备集群**的 Manager 节点与 RGW 节点上重复上述步骤。
8. 所有集群校验通过后,在所有生成证书的集群上执行:
```bash
update-ca-trust
```
9. 从主集群确认 `curl` 可用:
```bash
curl https://<host_ip>:443
```
**注意事项**
- RGW multisite spec 文件**与 cephadm 编排器 spec 文件格式相同**,因此可以指定任何受支持的 RGW 参数,包括 SSL 证书等高级配置。
- 如果在 spec(或命令行)中指定了自定义 zone endpoints,则**不会**启动 cephadm 守护进程。
- `ceph rgw realm bootstrap` 底层依赖编排器,需要先有可用的编排器后端(cephadm / rook)。
> 引自:[RGW Module](https://docs.ceph.com/en/tentacle/mgr/rgw/)
### 8.14 nfs —— NFS 集群与导出管理(CephFS / RGW over NFS)
**用途**
CephFS 命名空间与 RGW bucket 可以通过 **NFS-Ganesha NFS server** 以 NFS 协议导出。`nfs` manager 模块提供统一接口来管理 CephFS 目录或 RGW bucket 的 NFS 导出,既可以用 CLI(`ceph nfs export ...`)也可以用 dashboard 管理。
nfs-ganesha 守护进程的部署也可以自动管理——前提是启用了 `cephadm` 或 `rook` 编排器。若两者都没用(例如用 Ansible / Puppet 等外部编排器部署 Ceph),则必须手工部署 nfs-ganesha 守护进程。
> **注意:从 Ceph Pacific 开始,`nfs` mgr 模块必须启用。**
> **`nfs` 是 `mgr_initial_modules` 的默认成员之一**(默认值 `iostat nfs nvmeof`)。
#### 8.14.1 NFS 集群管理
**创建集群**
```bash
ceph nfs cluster create <cluster_id> [<placement>] [--ingress] [--virtual_ip <value>] [--ingress-mode {default|keepalive-only|haproxy-standard|haproxy-protocol}] [--port <int>] [--enable-nfsv3]
```
该命令会:为所有 NFS Ganesha 守护进程创建一个**公共 recovery pool**;基于 `cluster_id` 创建一个**新用户**;创建一个**公共的 NFS Ganesha 配置 RADOS 对象**。
| 参数 | 说明 |
|---|---|
| `<cluster_id>` | 任意字符串,作为该 NFS Ganesha 集群的标识(例如 `mynfs`) |
| `<placement>` | 可选字符串,指定哪些主机上运行 NFS Ganesha 守护进程容器,并可(可选地)指定集群中守护进程总数。例如 `"host1,host2"` 表示在 host1 与 host2 上各部署一个;`"2 host1,host2"` 表示 host1 与 host2 各部署 1 个、集群共 2 个 |
| `--port <int>` | 部署在非 2049(默认)端口上 |
| `--enable-nfsv3` | 默认只启用 NFS v4;加上此 flag 同时启用 v3 与 v4 |
| `--ingress` | 部署高可用前端(虚拟 IP + 负载均衡器),会组合部署 keepalived 与 haproxy |
| `--virtual_ip <value>` | 配合 `--ingress` 指定的虚拟 IP 地址 |
| `--ingress-mode {default\|keepalive-only\|haproxy-standard\|haproxy-protocol}` | 选择 ingress 服务的配置方式,见下表 |
**`--ingress-mode` 取值(逐项)**
| 取值 | 说明 |
|---|---|
| `keepalive-only` | 部署简化版 ingress 服务:提供虚拟 IP,nfs server 直接绑定该虚拟 IP,**不做**任何负载均衡或流量重定向。此模式限制只能部署 **1 个** nfs 守护进程(多个无法绑定虚拟 IP 上同一端口) |
| `haproxy-standard` | 部署完整 ingress 服务,用 HAProxy + keepalived 提供负载均衡与高可用。**客户端 IP 对后端 NFS server 不可见**,基于 IP 的 NFS export 限制**不会生效** |
| `haproxy-protocol` | 部署完整 ingress 服务,用 HAProxy + keepalived 提供负载均衡与高可用。**客户端 IP 对后端 NFS server 可见**,基于 IP 的 export 限制**可用**。此模式**需要 NFS Ganesha 5.0 或更高版本** |
| `default` | 等价于不显式指定其它 ingress mode;未指定时默认使用 `haproxy-standard` |
**ingress 成熟度提示(原文保留)**
> The ingress implementation is not yet complete. Enabling ingress will deploy multiple ganesha instances and balance load across them, but a host failure will not immediately cause cephadm to deploy a replacement daemon before the NFS grace period expires. This high-availability functionality is expected to be completed by the Quincy release (March 2022).
> 💡 补充:这段是官方在文档中保留的历史性说明(预期 Quincy 完成),本册基于 Tentacle v20.2.4 源文照录,未做时效性改写。
**placement 说明**:更多细节参见编排器文档的 placement spec,但**注意:NFS 不支持通过 YAML 文件指定 placement**。
**异步性提示**:NFS 守护进程与 ingress 服务的部署是**异步**的,命令可能在服务完全启动前就返回。建议检查服务是否真的起来并持续运行:
```bash
ceph orch ls --service_name=nfs.<cluster_id>
ceph orch ls --service_name=ingress.nfs.<cluster_id>
```
**其余集群命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph nfs cluster info [<cluster_id>]` | 查看 NFS 集群的 IP endpoint,包括各 NFS 守护进程的 IP,以及 ingress 服务的虚拟 IP(如有)。**rook 后端不适用**,改用 `kubectl patch service -n rook-ceph -p '{"spec":{"type": "NodePort"}}' rook-ceph-nfs-<cluster-name>-<node-id>` 与 `kubectl get services -n rook-ceph rook-ceph-nfs-<cluster-name>-<node-id>` |
| `ceph nfs cluster rm <cluster_id>` | 删除已部署的集群(删除同样是异步的,可用上面两条 `orch ls` 确认) |
| `ceph nfs cluster ls` | 列出已部署的集群 |
| `ceph nfs cluster config set <cluster_id> -i <config_file>` | 设置自定义 Ganesha 配置,优先级高于默认配置块 |
| `ceph nfs cluster config get <cluster_id>` | 输出用户自定义配置(如有) |
| `ceph nfs cluster config reset <cluster_id>` | 移除用户自定义配置 |
**更新集群参数**
要修改集群参数(例如端口或 placement),应通过编排器接口更新 NFS service spec。最安全的做法是「导出当前 spec → 修改 → 重新 apply」:
```bash
ceph orch ls --service-name nfs.foo --export > nfs.foo.yaml
emacs nfs.foo.yaml
ceph orch apply -i nfs.foo.yaml
```
**自定义配置示例**
改日志级别:
```text
LOG {
COMPONENTS {
ALL = FULL_DEBUG;
}
}
```
添加自定义 export block(**该 export 不会由 `ceph nfs export` 接口管理**):
```text
EXPORT {
Export_Id = 100;
Transports = TCP;
Path = /;
Pseudo = /ceph/;
Protocols = 4;
Access_Type = RW;
Attr_Expiration_Time = 0;
Squash = None;
FSAL {
Name = CEPH;
Filesystem = "filesystem name";
User_Id = "user id";
Secret_Access_Key = "secret key";
}
}
```
> FSAL 块中指定的 user 必须具备让 NFS-Ganesha 守护进程访问 Ceph 集群的合适 caps,可用 `auth get-or-create` 创建:
```bash
ceph auth get-or-create client.<user_id> mon 'allow r' osd 'allow rw pool=.nfs namespace=<nfs_cluster_name>, allow rw tag cephfs data=<fs_name>' mds 'allow rw path=<export_path>'
```
#### 8.14.2 导出(Export)管理
> **警告(原文)**:Currently, the nfs interface is not integrated with dashboard. Both dashboard and nfs interface have different export requirements and create exports differently. Management of dashboard created exports is not supported.
**创建 CephFS 导出**
```bash
ceph nfs export create cephfs --cluster-id <cluster_id> --pseudo-path <pseudo_path> --fsname <fsname> [--readonly] [--path=/path/in/cephfs] [--client_addr <value>...] [--squash <value>] [--sectype <value>...] [--cmount_path <value>]
```
| 参数 | 说明 |
|---|---|
| `--cluster-id <cluster_id>` | NFS Ganesha 集群 ID |
| `--pseudo-path <pseudo_path>` | 导出在 NFS v4 Pseudo Filesystem 中的位置;必须是**绝对路径且唯一** |
| `--fsname <fsname>` | 提供该导出的 NFS Ganesha 集群所使用的 FS volume 名 |
| `--path` | CephFS 内的路径,需为有效路径,**默认为 `/`**,不必唯一。子卷路径可用 `ceph fs subvolume getpath <vol_name> <subvol_name> [--group_name <subvol_group_name>]` 获取 |
| `--client_addr <value>...` | 应用这些导出权限的客户端地址列表。默认所有客户端均可按指定权限访问 |
| `--squash <value>` | 用户 id squash 方式,**默认 `no_root_squash`** |
| `--sectype <value>...` | 连接该导出时使用的认证方法,有效值:`krb5p`、`krb5i`、`krb5`、`sys`、`none`。可指定多个:多次写 flag(`--sectype=krb5p --sectype=krb5i`)或逗号分隔(`--sectype krb5p,krb5i`)。服务端**从左到右**优先与客户端协商 |
| `--cmount_path <value>` | 该导出在 CephFS 内的挂载路径,可以是 `/` 与 `EXPORT {path}` 之间任意完整路径层级(若 `EXPORT { Path }` 为 `/foo/bar`,则 cmount_path 可以是 `/`、`/foo` 或 `/foo/bar`)。若与其它 `EXPORT { FSAL {} }` 选项在多个导出间相同,则这些导出**共享同一个 CephFS client**;未指定时默认为 `/` |
| `--readonly` | 只读导出 |
**创建 RGW 导出**
RGW 导出有两类:
| 类型 | 说明 |
|---|---|
| **user 导出** | 导出某个 RGW 用户拥有的**全部 bucket**,导出的顶层目录是 bucket 列表 |
| **bucket 导出** | 只导出**单个 bucket**,顶层目录是该 bucket 中的 object |
bucket 导出:
```bash
ceph nfs export create rgw --cluster-id <cluster_id> --pseudo-path <pseudo_path> --bucket <bucket_name> [--user-id <user-id>] [--readonly] [--client_addr <value>...] [--squash <value>] [--sectype <value>...]
```
user 导出:
```bash
ceph nfs export create rgw --cluster-id <cluster_id> --pseudo-path <pseudo_path> --user-id <user-id> [--readonly] [--client_addr <value>...] [--squash <value>]
```
| 参数 | 说明 |
|---|---|
| `--cluster-id` | NFS Ganesha 集群 ID |
| `--pseudo-path` | 导出在 NFS v4 Pseudo Filesystem 中的位置,必须绝对路径且唯一 |
| `--bucket <bucket_name>` | 要导出的 bucket 名 |
| `--user-id <user-id>` | 可选,指定对 bucket 读写所用的 RGW 用户;不指定则使用 bucket 的属主 |
示例:
```bash
# 把 mybucket 通过 mynfs 集群导出到 /bucketdata,仅允许 192.168.10.0/24
ceph nfs export create rgw --cluster-id mynfs --pseudo-path /bucketdata --bucket mybucket --client_addr 192.168.10.0/24
# 把用户 myuser 的全部 bucket 导出到 /bucketdata
ceph nfs export create rgw --cluster-id mynfs --pseudo-path /bucketdata --user-id myuser --client_addr 192.168.10.0/24
```
**其余导出命令(逐项)**
| 命令 | 说明 |
|---|---|
| `ceph nfs export rm <cluster_id> <pseudo_path>` | 删除导出;`pseudo_path` 必须是绝对路径 |
| `ceph nfs export ls <cluster_id> [--detailed]` | 列出某集群的导出;`--detailed` 显示完整 export block |
| `ceph nfs export info <cluster_id> <pseudo_path>` | 按 pseudo root 名显示某集群的 export block |
| `ceph nfs export apply <cluster_id> -i <json_file>` | 用 JSON(或 Ganesha EXPORT 配置片段)创建或更新导出 |
**JSON 方式创建/更新导出**
先 dump:
```bash
ceph nfs export info mynfs /cephfs > update_cephfs_export.json
cat update_cephfs_export.json
```
```json
{
"export_id": 1,
"path": "/",
"cluster_id": "mynfs",
"pseudo": "/cephfs",
"access_type": "RW",
"squash": "no_root_squash",
"security_label": true,
"protocols": [
4
],
"transports": [
"TCP"
],
"fsal": {
"name": "CEPH",
"fs_name": "a",
"sec_label_xattr": "",
"cmount_path": "/"
},
"clients": []
}
```
修改后重新 apply(下例改了 `pseudo` 与 `access_type`):
```bash
ceph nfs export apply mynfs -i update_cephfs_export.json
```
```json
{
"export_id": 1,
"path": "/",
"cluster_id": "mynfs",
"pseudo": "/cephfs_testing",
"access_type": "RO",
"squash": "no_root_squash",
"security_label": true,
"protocols": [
4
],
"transports": [
"TCP"
],
"fsal": {
"name": "CEPH",
"fs_name": "a",
"sec_label_xattr": "",
"cmount_path": "/"
},
"clients": []
}
```
也可以用 Ganesha NFS EXPORT 配置片段来创建/更新:
```bash
ceph nfs export apply mynfs -i update_cephfs_export.conf
```
```text
EXPORT {
FSAL {
name = "CEPH";
filesystem = "a";
}
export_id = 1;
path = "/";
pseudo = "/a";
access_type = "RW";
squash = "none";
attr_expiration_time = 0;
security_label = true;
protocols = 4;
transports = "TCP";
}
```
导出的 JSON 既可以是描述**单个导出的 dict**,也可以是包含**多个导出 dict 的 JSON list**。
#### 8.14.3 挂载
```bash
mount -t nfs <ganesha-host-name>:<pseudo_path> <mount-point>
```
若集群是用 `--ingress --virtual-ip 192.168.10.10` 创建的、导出的 pseudo-path 是 `/foo`,则挂载到 `/mnt`:
```bash
mount -t nfs 192.168.10.10:/foo /mnt
```
若 NFS 服务运行在非标准端口:
```bash
mount -t nfs -o port=<ganesha-port> <ganesha-host-name>:<ganesha-pseudo_path> <mount-point>
```
#### 8.14.4 排障
| 编排器 | 查日志方式 |
|---|---|
| `cephadm` | `ceph orch ps --daemon-type nfs` 列出 NFS 守护进程;然后 `cephadm logs --fsid <fsid> --name nfs.mynfs.0.0.myhost.xkfzal` |
| `rook` | `kubectl logs -n rook-ceph rook-ceph-nfs-<cluster_id>-<node_id> nfs-ganesha` |
NFS 日志级别可用 `nfs cluster config set` 调整。
#### 8.14.5 手工部署 Ganesha(无编排器)
> 官方提示:手工配置**未经测试也未完整文档化**("Manual configuration is not tested or fully documented; your mileage may vary")。
**限制(Limitations)**
若没有为 Ceph Manager 启用编排器模块,`ceph nfs cluster` 开头的集群管理命令**将无法工作**。但是,只要必要的 RADOS 对象已创建,`ceph nfs export` 系列命令**应当仍可工作**。所需 RADOS 对象的确切集合**当前没有文档**(支持尚不完整),可阅读 `src/pybind/mgr/nfs` 源码了解细节。
**依赖包要求**
启用 CephFS 与 RGW 导出需要(**3.3 及以上版本**):
- `nfs-ganesha`
- `nfs-ganesha-ceph`
- `nfs-ganesha-rados-grace`
- `nfs-ganesha-rados-urls`
**Ganesha 配置层次结构**
Cephadm 与 rook 为每个 nfs-ganesha 守护进程启动一个**最小化 bootstrap 配置**文件,它从 `.nfs` RADOS 池中拉取共享的 **common** 配置,并**监视 common 配置的变化**。每个 export 被写入**独立的 RADOS 对象**,再由 common config 通过 URL 引用。
```text
rados://$pool/$namespace/export-$i rados://$pool/$namespace/userconf-nfs.$cluster_id
(export config) (user config)
+----------+ +----------+ +----------+ +---------------------------+
| | | | | | | |
| export-1 | | export-2 | | export-3 | | userconf-nfs.$cluster_id |
| | | | | | | |
+----+-----+ +----+-----+ +-----+----+ +-------------+-------------+
^ ^ ^ ^
| | | |
+--------------------------------+-------------------------+
%url |
|
+--------+--------+
| | rados://$pool/$namespace/conf-nfs.$svc
| conf+nfs.$svc | (common config)
| |
+--------+--------+
^
|
watch_url |
+----------------------------------------------+
| | |
| | | RADOS
+----------------------------------------------------------------------------------+
| | | CONTAINER
watch_url | watch_url | watch_url |
| | |
+--------+-------+ +--------+-------+ +-------+--------+
| | | | | | /etc/ganesha/ganesha.conf
| nfs.$svc.a | | nfs.$svc.b | | nfs.$svc.c | (bootstrap config)
| | | | | |
+----------------+ +----------------+ +----------------+
```
**注意事项汇总**
- 由 cephadm 部署的 NFS Ganesha 守护进程**监听标准端口**,因此**每个主机上只能部署一个守护进程**。
- **只支持 NFS v4.0+**。
- 截至文档撰写时(01 Jan 2024),**没有任何版本的 Microsoft Windows 原生支持挂载 NFS v4.x 导出**。
- 若启用了 RGW 多站点,Ceph **只能导出 default realm 中的 RGW bucket**。
- `sectype` 中涉及 Kerberos 的值只在服务端配置了 Kerberos 支持时才有效。
- `user_id` 在 `fsal` 块中**不应被修改或提及**——CephFS 导出会自动生成,格式为 `nfs.<cluster_id>.<fs_name>.<hash_id>`。
- 修改导出时,提交的 JSON 应完整描述导出**新的完整状态**(与新建时一样),**认证凭据例外**——其会尽可能沿用先前状态。
- rook 部署下,ganesha pod 必须**显式重启**才能让新配置块生效。
> 引自:[CephFS & RGW Exports over NFS](https://docs.ceph.com/en/tentacle/mgr/nfs/)
### 8.15 smb —— SMB 集群与共享管理
**用途**
借助 **Samba suite** 与 **samba-container** 镜像(由 Ceph 管理),可以通过 **SMB 协议**把 CephFS 访问能力提供给客户端。`smb` manager 模块提供用于**部署并控制 Samba 服务集群**以及**管理 SMB 共享**的接口。
在 `smb` 模块中,一个 **cluster(集群)** 是一个逻辑管理单元,可能映射到一个或多个被管理的 Samba 服务——集群本身**可能使用也可能不使用**高可用机制。
**启用命令**
```bash
ceph mgr module enable smb
```
**两种交互方式**
| 方式 | 入口 | 适合人群 |
|---|---|---|
| **命令式(imperative)** | `ceph smb cluster create ...`、`ceph smb share rm ...` | 熟悉 Ceph `nfs` manager 模块 CLI 的人 |
| **声明式(declarative)** | `ceph smb apply` + YAML/JSON 「resource description」 | 熟悉 cephadm 编排(用 SMB 专属 resource type)的人 |
**重要限制(原文)**
- Ceph 管理的 Samba **只支持 SMB2 与 SMB3**;SMB1(有时称为 CIFS)**不支持**。某些系统(如 Linux kernel)在 "CIFS" 名称下同时提供 SMB1 与 SMB2+ 工具,请查阅所用软件包文档确认其支持 SMB2+。
- 当前 `smb` 模块**需要 cephadm 编排**,没有编排就无法工作。
#### 8.15.1 命令式管理
**集群命令**
```bash
ceph smb cluster create <cluster_id> {user|active-directory} [--domain-realm=<domain_realm>] [--domain-join-user-pass=<domain_join_user_pass>] [--define-user-pass=<define_user_pass>] [--custom-dns=<custom_dns>] [--placement=<placement>] [--clustering=<clustering>] [--password-filter=<password_filter>] [--password-filter-out=<password_filter_out>]
```
创建集群时**必须指定认证模式**,二选一:
| 认证模式 | 关键字 | 含义 |
|---|---|---|
| 自定义用户与组(独立服务器 / standalone server) | `user` | — |
| Active Directory (AD) 域成员服务器 | `active-directory` | — |
参数逐项:
| 参数 | 说明 |
|---|---|
| `cluster_id` | 唯一标识集群的短字符串 |
| `auth_mode` | `user` 或 `active-directory` |
| `domain_realm` | 标识 AD 域的 domain/realm 值;选择 `active-directory` 时**必填** |
| `domain_join_user_pass` | `<username>%<password>` 形式的字符串,用于把 Samba 服务器加入 AD 域 |
| `define_user_pass` | `<username>%<password>` 形式的字符串,在 `user` auth_mode 下用于认证 |
| `custom_dns` | 可选,**可多次指定**。一个或多个 IP 地址,应用到 Samba 容器以覆盖默认 DNS 解析器。用于 Ceph 宿主节点无法解析 AD 域内 DNS 条目的场景 |
| `placement` | 一个 Ceph 编排 placement specifier |
| `clustering` | 可选。控制集群抽象是否真正使用 Samba 的集群机制,取值 `default` / `always` / `never`。`default`:当 placement count 不等于 1 时启用集群;`always`:无论 placement count 多少都启用;`never`:无论 placement count 多少都禁用。未指定时假定为 `default` |
| `public_addrs` | 可选。`<ipaddress/prefixlength>[%<destination interface>]` 形式的字符串。**仅在使用 Samba 集群机制时支持**。分配由集群子系统管理的「虚拟」IP 地址,可在运行 Samba 容器的节点之间自动漂移 |
| `password_filter` | `none` 或 `base64`。`none`:命令行上的密码视为明文;`base64`:密码值被视为经 base64 混淆。若未指定 `--password-filter-out`,此 filter 也应用于输出 |
| `password_filter_out` | `none`、`base64` 或 `hidden`。`none`:输出中的密码字段为明文;`base64`:用 base64 混淆;`hidden`:用一个只含星号的无效通用替换字符串取代密码值 |
```bash
ceph smb cluster rm <cluster_id> [--password-filter=<password_filter>]
ceph smb cluster ls [--format=<format>]
```
- `cluster rm`:从 Ceph 集群中移除一个逻辑 SMB 集群;`password_filter` 取值 `none` / `base64` / `hidden`。
- `cluster ls`:打印 cluster id 列表。**默认 JSON**,可用 `--format=yaml` 选择 YAML。
**共享命令**
```bash
ceph smb share create <cluster_id> <share_id> <cephfs_volume> <path> [--share-name=<share_name>] [--subvolume=<subvolume>] [--readonly]
ceph smb share rm <cluster_id> <share_id>
ceph smb share ls <cluster_id> [--format=<format>]
```
| 参数 | 说明 |
|---|---|
| `cluster_id` | 唯一标识集群的短字符串 |
| `share_id` | 唯一标识共享的短字符串 |
| `cephfs_volume` | 要共享的 cephfs volume 名 |
| `path` | 相对于 volume 和/或 subvolume 根的路径 |
| `share_name` | 可选。共享对客户端可见的公开名称;未提供则自动使用 `share_id` |
| `subvolume` | 可选。`[<subvolumegroup>/]<subvolume>` 形式的子卷名;该选项使 `path` 相对于指定的 CephFS subvolume |
| `readonly` | 创建只读共享 |
`share ls` 默认 JSON,可用 `--format=yaml`。
#### 8.15.2 声明式管理
```bash
ceph smb apply -i /path/to/resources.yaml
ceph smb apply [--format=<format>] [--password-filter=<password_filter>] [--password-filter-out=<password_filter_out>] -i <input>
```
| 参数 | 说明 |
|---|---|
| `format` | `json`(默认)或 `yaml`。**输出格式可独立于输入格式选择** |
| `password_filter` | `none` 或 `base64`(语义同 8.15.1) |
| `password_filter_out` | `none`、`base64` 或 `hidden`(语义同 8.15.1) |
| `input` | 文件名,或 `-` 表示 stdin |
**查看已应用资源**
```bash
ceph smb show ceph.smb.cluster.cluster1
ceph smb show [resource_name...] [--format=<format>] [--results=<results>] [--password-filter=<password_filter>]
```
| 参数 | 说明 |
|---|---|
| `resource_name` | 一个或多个指定资源或资源类型的字符串,见下表 |
| `format` | `json`(默认)或 `yaml` |
| `results` | `collapsed`(默认)或 `full`。`collapsed`:若只找到一项,只输出该项的 JSON/YAML;`full`:即使只有一项也始终带 wrapper 对象,形如(伪 JSON)`{"resources": [...Resource objects...]}` |
| `password_filter` | `none`、`base64` 或 `hidden` |
`resource_name` 的合法形式(逐项):
| 形式 | 含义 |
|---|---|
| `ceph.smb.cluster` | 显示所有 cluster 资源 |
| `ceph.smb.cluster.<cluster_id>` | 显示指定 cluster ID 的特定 cluster |
| `ceph.smb.share` | 显示所有 share 资源 |
| `ceph.smb.share.<cluster_id>` | 显示某集群下的所有 share 资源 |
| `ceph.smb.share.<cluster_id>.<share_id>` | 显示指定 cluster 与 share id 的特定 share 资源 |
| `ceph.smb.usersgroups` | 显示所有 Users & Groups 资源 |
| `ceph.smb.usersgroups.<users_goups_id>` | 显示特定的 Users & Groups 资源 |
| `ceph.smb.join.auth` | 显示所有 join auth 资源 |
| `ceph.smb.join.auth.<auth_id>` | 显示特定的 join auth 资源 |
示例:
```bash
ceph smb show ceph.smb.cluster.bob ceph.smb.share.bob
```
> **注意**:`show` 子命令输出的资源形式与 `apply` 接受的**完全相同**,因此可以在 show 与 apply 之间「往返(round-trip)」取值。
#### 8.15.3 资源规格的书写形式
一个资源规格由一个或多个 Ceph SMB 资源描述组成(JSON 或 YAML)。多资源的表达方式:
1. 包含在一个 JSON/YAML **list** 中;
2. 一个 JSON/YAML 对象,含 `resources` 键,其值为**list**;
3. YAML 规范还可以是**一系列 YAML document**,每个 document 含一个资源。
YAML 简单 list:
```yaml
- resource_type: ceph.smb.cluster
cluster_id: rhumba
# ... other fields skipped for brevity ...
- resource_type: ceph.smb.cluster
cluster_id: salsa
# ... other fields skipped for brevity ...
- resource_type: ceph.smb.share
cluster_id: salsa
share_id: foo
# ... other fields skipped for brevity ...
```
JSON 简单 list:
```json
[
{"resource_type": "ceph.smb.cluster",
"cluster_id": "rhumba",
"...": "... other fields skipped for brevity ..."
},
{"resource_type": "ceph.smb.cluster",
"cluster_id": "salsa",
"...": "... other fields skipped for brevity ..."
},
{"resource_type": "ceph.smb.share",
"cluster_id": "salsa",
"share_id": "foo",
"...": "... other fields skipped for brevity ..."
}
]
```
YAML `resources` list:
```yaml
resources:
- resource_type: ceph.smb.cluster
cluster_id: rhumba
# ... other fields skipped for brevity ...
- resource_type: ceph.smb.cluster
cluster_id: salsa
# ... other fields skipped for brevity ...
- resource_type: ceph.smb.share
cluster_id: salsa
share_id: foo
# ... other fields skipped for brevity ...
```
JSON `resources` list:
```json
{
"resources": [
{"resource_type": "ceph.smb.cluster",
"cluster_id": "rhumba",
"...": "... other fields skipped for brevity ..."
},
{"resource_type": "ceph.smb.cluster",
"cluster_id": "salsa",
"...": "... other fields skipped for brevity ..."
},
{"resource_type": "ceph.smb.share",
"cluster_id": "salsa",
"share_id": "foo",
"...": "... other fields skipped for brevity ..."
}
]
}
```
多 document YAML:
```yaml
---
resource_type: ceph.smb.cluster
cluster_id: rhumba
# ... other fields skipped for brevity ...
---
resource_type: ceph.smb.cluster
cluster_id: salsa
# ... other fields skipped for brevity ...
---
resource_type: ceph.smb.share
cluster_id: salsa
share_id: foo
# ... other fields skipped for brevity ...
```
> 后续示例只使用 YAML;假定等价的 JSON 形式同样有效。
#### 8.15.4 Cluster Resource(`ceph.smb.cluster`)字段
| 字段 | 说明 |
|---|---|
| `resource_type` | 字面量字符串 `ceph.smb.cluster` |
| `cluster_id` | 标识集群的短字符串 |
| `auth_mode` | `user` 或 `active-directory` |
| `intent` | `present` 或 `removed`。未提供则假定 `present`;若为 `removed`,其后所有字段均为可选 |
| `domain_settings` | 对象。`user` 认证下忽略/可选;`active-directory` 下**必填**。子字段:`realm`(必填字符串,AD 域/realm 名)、`join_sources`(必填 list,每个元素是一个带 join source fields 的对象) |
| `user_group_settings` | list。`active-directory` 下忽略/可选。每个元素是一个带 user group source fields 的对象 |
| `custom_dns` | 可选。IP 地址列表。这些 IP 将用作 Samba 容器中的 DNS 解析器,使容器即使在 Ceph 主机未配置时也能使用域 DNS |
| `custom_ports` | 可选。服务名到端口号的映射,覆盖对应服务的默认端口。服务名为:`smb`、`smbmetrics`、`ctdb`、`remote-control`。未出现在映射中的服务名使用默认端口。例如 `{"smb": 4455, "smbmetrics": 9009}` 会改变客户端访问与指标导出器使用的端口,但不改变 CTDB 集群守护进程的端口。**注意:并非所有 SMB 客户端都能使用非默认端口号** |
| `bind_addrs` | 可选。对象列表,指示 SMB 及相关服务可绑定到哪个 IP 地址或 IP 网络。对象的字段**互斥**,但**至少需要一个字段**。(与 clustering 和 `public_addrs` 同用时行为会变化,见下方 warning。)子字段:`address`(可选,单个 IP 地址字符串,例如 `192.168.7.50`)、`network`(可选,单个 IP 网络字符串,总含 `/` 前缀长度,例如 `192.168.7.0/24`) |
| `placement` | 可选。Ceph 编排 placement specifier。未提供时默认为**一个主机** |
| `clustering` | 同 8.15.1 的 `--clustering`:`default` / `always` / `never` |
| `public_addrs` | 对象列表;可选。**仅在使用 Samba 集群机制时支持**。子字段:`address`(**必填**字符串,带前缀长度的 IP,例如 `192.168.4.51/24`,将被分配到主机的某个网络设备上并自动管理)、`destination`(可选,字符串或字符串列表,每个字符串值必须是网络地址,例如 `192.168.4.0/24`;通常只用恰好一个 destination,因此可用字符串而非单元素列表;每个 destination 网络会映射到主机上的某个设备,可运行 `cephadm list-networks` 查看这类映射;未提供时网络由 `address` 值自动推断并作为 destination) |
| `remote_control` | 可选对象。配置 SMB 集群额外部署一个 **remote control** 服务,提供 gRPC server,可用于枚举已连接客户端并把客户端从共享中断开。该服务使用 **mTLS** 认证,默认端口 **54445**,可用集群资源的 `custom_ports` 参数修改。若服务已启用而 `cert`/`key`/`ca_cert` 任一未填充,则 mTLS 被禁用、服务以**只读模式**运行;官方**不建议**在 mTLS 禁用状态下运行。子字段:`enabled`(可选布尔;显式设为 `true`/`false` 则启用/禁用;未设置则检查 TLS 字段——若已填则自动启用)、`cert`(可选对象,tls source fields)、`key`(可选对象,tls source fields)、`ca_cert`(可选对象,tls source fields) |
| `custom_smb_global_options` | 可选映射。键值对会被**直接**加入 Samba 服务器的全局 `smb.conf` 选项(或等价物)。**除非你准备好自己调试 Samba 实例,否则不要使用此选项**。此选项面向开发者、特性调研者与其它高级用户,使他们无需改动 Ceph 代码库即可更直接地控制共享选项。映射中的条目应与 `smb.conf` 中的参数及其值匹配。映射中**必须**出现一个特殊键 `_allow_customization`,其值为 `i-take-responsibility-for-all-samba-configuration-errors`,表示用户已知晓使用此选项可能以 Ceph 团队无法协助的方式破坏系统。该特殊键会从传给 Samba 的选项列表中自动移除 |
**join source fields**(被 `domain_settings.join_sources` 引用)
| 字段 | 说明 |
|---|---|
| `source_type` | 可选。若指定,必须为 `resource` |
| `ref` | 字符串。`source_type: resource` 时**必填**。必须指向一个 `ceph.smb.join.auth` 资源的 ID |
**user group source fields**(被 `user_group_settings` 引用)
| 字段 | 说明 |
|---|---|
| `source_type` | 可选。`resource`(默认)或 `empty` |
| `ref` | 字符串。`source_type: resource` 时必填。必须指向一个 `ceph.smb.join.auth` 资源的 ID |
> 💡 补充:官方在 `user_group_source_fields` 中把 `ref` 描述为「必须指向 `ceph.smb.join.auth` 资源的 ID」,语义上更可能是指 `ceph.smb.usersgroups`;**此处照录原文,存疑**(见「文档未明确项」)。
**tls source fields**(被 `remote_control.cert` / `key` / `ca_cert` 引用)
| 字段 | 说明 |
|---|---|
| `source_type` | 可选。若指定,必须为 `resource` |
| `ref` | 字符串。`source_type: resource` 时必填。必须指向一个 `ceph.smb.tls.credential` 资源的 ID |
**官方警告(原文保留)**
> 设置 `clustering` 选项允许管理员自行决定何时使用 Samba 的 CTDB 集群。默认情况下,是否使用集群由 `placement` count 推导。如果你选择设置 `clustering`,请确保理解集群与 placement 之间的相互作用。特别要注意:在**未启用集群**的情况下运行同一 `smb` 服务的多个实例,可能导致意外行为。
> 在集群上**同时**使用 `bind_addrs` 与 `public_addrs` 时,系统行为可能导致**非预期结果**。`smbd` 进程只有在被分配去监听某个**网络设备**(例如 `eth0`)而非某个**具体地址**时,才能动态地添加/移除 public address。如果该网络设备被分配了多个地址,且这些地址与另一个 smb 集群的地址**重叠**,则服务可能启动失败。目前必须**人工确保**某个 IP 或网络所使用的设备被该网络独占使用,才能保证 SMB 服务正常启动。
> 官方 note(原文保留):`source_type` 取 `empty` 一般仅用于**调试和测试**该模块,生产部署中不应需要。
**示例**
一个配置为 **AD 域成员**的集群:
```yaml
resource_type: ceph.smb.cluster
cluster_id: tango
auth_mode: active-directory
domain_settings:
realm: DOMAIN1.SINK.TEST
join_sources:
# this join source refers to a join auth resource with id "join1-admin"
- source_type: resource
ref: join1-admin
custom_dns:
- "192.168.76.204"
placement:
count: 1
```
一个配置为 **standalone(独立运行)**的集群:
```yaml
resource_type: ceph.smb.cluster
cluster_id: rhumba
auth_mode: user
user_group_settings:
- source_type: resource
ref: ug1
placement:
hosts:
- node6.mycluster.sink.test
```
一个带 **intent: removed**(意图删除)的集群资源:
```yaml
resource_type: ceph.smb.cluster
cluster_id: rhumba
intent: removed
```
> 💡 补充:上面三个示例分别演示了 `domain_settings.join_sources` 引用 join auth 资源、`user_group_settings` 引用 usersgroups 资源、以及 `placement` 既可用 `count:` 也可用 `hosts:` 列表的写法。生产环境中**通常不应使用 Administrator 用户**来执行加域操作(官方在 8.15.9 的完整示例中亦如此提醒)。
#### 8.15.5 Share Resource(`ceph.smb.share`)字段
| 字段 | 说明 |
|---|---|
| `resource_type` | 字面量字符串 `ceph.smb.share` |
| `cluster_id` | 集群 ID |
| `share_id` | 共享 ID |
| `intent` | `present`(默认)或 `removed`;`removed` 时其后字段均可选 |
| `name` | 可选字符串。更长的名称,可含空格与其它字符,呈现给 SMB 客户端 |
| `readonly` | 可选布尔,**默认 false**。为 true 时不允许任何客户端写入该共享 |
| `browseable` | 可选布尔,**默认 true**。为 true 时该共享会包含在客户端可见的共享列表中 |
| `comment` | 可选字符串。单行描述,用于提供人类可读的说明或备注 |
| `max_connections` | 可选整数。指定特定共享的最大同时客户端连接数。**默认值 0**,表示连接数无限制 |
| `cephfs` | **必填**对象。子字段:`volume`(必填字符串,要使用的 cephfs volume 名)、`path`(必填字符串,volume 或 subvolume 内要共享的路径)、`subvolumegroup`(可选字符串,要共享的 subvolumegroup 名)、`subvolume`(可选字符串,要共享的 subvolume 名。若 `subvolumegroup` 未设置且该值**恰好含一个 `/` 字符**,subvolume 字段会**自动拆分**为 `<subvolumegroup>/<subvolume>` 两部分以便书写)、`provider`(见下一行) |
| `provider` | 可选。选择 CephFS 存储应以何种方式提供给该共享。取值可为 `samba-vfs`、`samba-vfs/classic`、`samba-vfs/new` 或 `samba-vfs/proxied`;**未指定时假定为 `samba-vfs`**。其中:`samba-vfs/new` 选择新的 Samba VFS 插件连接 CephFS;`samba-vfs/proxied` 同样使用新 VFS 插件,但把连接**经由代理路由**——它允许该共享承载**更多**并发客户端连接,代价是**性能**;`samba-vfs/classic` 使用较旧的 Samba VFS 插件连接 CephFS;`samba-vfs` 自动选择首选的基于 VFS 的实现,**当前为 `samba-vfs/proxied`**。该选项适用于绝大多数用例,**多数共享可以不指定** |
| `restrict_access` | 可选布尔,**默认 false**。为 true 时,共享只允许 `login_control` 中**显式列出**的用户访问 |
| `login_control` | 可选对象列表。子字段:`name`(**必填**字符串,用户或组的名称)、`category`(可选,`user`(默认)或 `group`)、`access`(`read`(别名 `r`)、`read-write`(别名 `rw`)、`none` 或 `admin`。登录该共享时授予该用户或组的**具体访问级别**;其中 `none` 表示**拒绝**访问该共享,且**不受 `restrict_access` 取值影响**) |
| `custom_smb_share_options` | 可选映射。指定会被**直接加入** Samba 服务器 `smb.conf`(或等价物)的键值对。**除非你准备好自己调试 Samba 实例,否则不要使用此选项**。此选项面向开发者、特性调研者与其它高级用户,使其无需改动 Ceph 代码库即可更直接地控制共享选项。映射中的条目应与 `smb.conf` 中的参数及其值匹配。映射中**必须**出现一个特殊键 `_allow_customization`,其值为 `i-take-responsibility-for-all-samba-configuration-errors`,表示用户已知晓使用此选项可能以 Ceph 团队无法协助的方式破坏系统。该特殊键会从传给 Samba 的选项列表中自动移除 |
> 💡 补充:本字段在官方 rst 中的字段名是 `provider`(位于 `cephfs` 对象内),本册前一版曾把它写作 `share_vfs`,现按源文更正为 `provider`;取值集合以源文为准(`samba-vfs` / `samba-vfs/classic` / `samba-vfs/new` / `samba-vfs/proxied`)。
**示例**
一个共享:
```yaml
resource_type: ceph.smb.share
cluster_id: tango
share_id: sp1
name: "Staff Pics"
cephfs:
volume: cephfs
path: /pics
subvolumegroup: smbshares
subvolume: staff
```
另一个示例,这次是带 intent: removed 的共享:
```yaml
resource_type: ceph.smb.share
cluster_id: tango
share_id: sp2
intent: removed
```
> 💡 补充:`custom_smb_share_options` 与 8.15.4 中的 `custom_smb_global_options` 是同一套「逃生舱」机制的两级:后者作用于**全局** `smb.conf`,前者作用于**单个共享**;两者都要求写入 `_allow_customization` 键,且官方都明确表示**由此引发的配置错误 Ceph 团队无法协助**。
#### 8.15.6 Join-Auth Resource(`ceph.smb.join.auth`)字段
| 字段 | 说明 |
|---|---|
| `resource_type` | 字面量字符串 `ceph.smb.join.auth` |
| `auth_id` | 标识 join auth 资源的短字符串 |
| `intent` | `present`(默认)或 `removed` |
| `auth` | **必填**对象。子字段:`username`(**必填**字符串,有权把系统加入 AD 的用户)、`password`(**必填**字符串,该 AD 用户的密码) |
| `linked_to_cluster` | 可选。包含 cluster ID 的字符串。若设置,该资源**只能**与该被链接的集群一起使用,并且在该被链接的集群被移除时会**自动被移除** |
**示例**
```yaml
resource_type: ceph.smb.join.auth
auth_id: join1-admin
auth:
username: Administrator
password: Passw0rd
```
#### 8.15.7 Users-and-Groups Resource(`ceph.smb.usersgroups`)字段
| 字段 | 说明 |
|---|---|
| `resource_type` | 字面量字符串 `ceph.smb.usersgroups` |
| `users_groups_id` | 标识 users and groups 资源的短字符串 |
| `intent` | `present`(默认)或 `removed` |
| `values` | **必填**对象。子字段:`users`(对象列表。字段:`name`(用户名)、`password`(密码))、`groups`(对象列表。字段:`name`(组名)) |
| `linked_to_cluster` | 可选。包含 cluster ID 的字符串。若设置,该资源只能与该被链接的集群一起使用,并且在该被链接的集群被移除时会自动被移除 |
**示例**
```yaml
resource_type: ceph.smb.usersgroups
users_groups_id: ug1
values:
users:
- name: chuckx
password: 3xample101
- name: steves
password: F00Bar123
groups: []
```
#### 8.15.8 TLS Credential Resource(`ceph.smb.tls.credential`)字段
| 字段 | 说明 |
|---|---|
| `resource_type` | 字面量字符串 `ceph.smb.tls.credential` |
| `tls_credential_id` | 标识 TLS credential 资源的短字符串 |
| `intent` | `present`(默认)或 `removed` |
| `credential_type` | **必填**字符串。取值 `cert`、`key` 或 `ca-cert`,表示该 value 字段持有的 TLS 凭据类型 |
| `value` | 包含 TLS 证书或密钥值的字符串,**PEM 编码** |
| `linked_to_cluster` | 可选。包含 cluster ID 的字符串。若设置,该资源只能与该被链接的集群一起使用,并且在该被链接的集群被移除时会自动被移除 |
**示例**
```yaml
resource_type: ceph.smb.tls.credential
tls_credential_id: mycert1
credential_type: cert
# NOTE: The value below is truncated to make the documentation more
# consise. A real embedded certificate is expected to be valid and
# will be longer than this example.
value: |
-----BEGIN CERTIFICATE-----
MIIFDjCCA/agAwIBAgISBtFQfoXc4RmyVabbv28RClKdMA0GCSqGSIb3DQEBCwUA
MDMxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQD
EwNSMTAwHhcNMjUwNTE5MTAyNzUyWhcNMjUwODE3MTAyNzUxWjASMRAwDgYDVQQD
EwdjZXBoLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx6fif6PQ
LOTdnO8d1JHcF7D+oB/mQlplFz4vwq/GB6Y4oWK3uCQ4PPz/qyvE4wyvc5EPhjfg
d8XNc4ajEBcSUoRj3UwWwiA4oht0SyoJIfwVGp/kF5jxHhVCLdoaaqAxv7nAghWM
6Dg=
-----END CERTIFICATE-----
```
> 说明:上面的证书值是官方文档为节省篇幅而**截断**的示例(原文注释写得很清楚:真实嵌入的证书应当是**有效的**、且比这个示例**更长**),**不可直接复制使用**。
#### 8.15.9 一个完整的声明式配置示例
利用上面描述的资源(resource)定义,我们可以拼出一个**从零开始**创建集群与共享的示例。首先创建如下内容的 YAML:
```yaml
resources:
# Define an AD member server cluster
- resource_type: ceph.smb.cluster
cluster_id: tango
auth_mode: active-directory
domain_settings:
realm: DOMAIN1.SINK.TEST
join_sources:
- source_type: resource
ref: join1-admin
custom_dns:
- "192.168.76.204"
# deploy 1 set of samba containers on a host labeled "ilovesmb"
placement:
count: 1
label: ilovesmb
# Define a join auth that our cluster will use to join AD
# Warning: Typically you do not want to use the Administrator user
# to perform joins on a production AD
- resource_type: ceph.smb.join.auth
auth_id: join1-admin
auth:
username: Administrator
password: Passw0rd
# A share that uses the root of a subvolume
# The share name is the same as its id
- resource_type: ceph.smb.share
cluster_id: tango
share_id: cache
cephfs:
volume: cephfs
subvolumegroup: smb1
subvolume: cache
path: /
# A share that uses the a sub-dir of a subvolume
# The share name is not the same as its id
- resource_type: ceph.smb.share
cluster_id: tango
share_id: sp1
name: "Staff Pics"
cephfs:
volume: cephfs
path: /pics
subvolumegroup: smb1
subvolume: staff
```
把这段文本保存为名为 `resources.yaml` 的 YAML 文件,并使其在**集群管理主机**上可用,然后执行:
```bash
ceph smb apply -i resources.yaml
```
该命令会**打印一份所做变更的摘要**,并开始**自动部署**所需的资源。关于如何测试这个示例部署,参见 8.15.11「访问共享」。
**一次性清理**
之后如果这些资源不再需要,可以用一个新的文件 `removed.yaml` 一次性清理掉,其内容为:
```yaml
resources:
- resource_type: ceph.smb.cluster
cluster_id: tango
intent: removed
- resource_type: ceph.smb.join.auth
auth_id: join1-admin
intent: removed
- resource_type: ceph.smb.share
cluster_id: tango
share_id: cache
intent: removed
- resource_type: ceph.smb.share
cluster_id: tango
share_id: sp1
intent: removed
```
然后执行:
```bash
ceph smb apply -i removed.yaml
```
> 💡 补充:这份示例展示了声明式用法的两个关键工程价值——**幂等**(同一份文件可反复 apply)与**可 round-trip**(`ceph smb show` 导出的资源可以直接回灌 `ceph smb apply`);同时它也说明:删除时**只需给出足以定位资源的字段**(`resource_type` + 各资源 ID + `intent: removed`),其余字段全部可省。
#### 8.15.10 SMB 集群管理(部署行为)
- `smb` 模块会使用 **cephadm 编排**自动在主机上部署逻辑集群。该编排在「**某集群至少配置了一个 share**」时被自动触发。
- cluster 资源的 `placement` 字段被传递给编排层,用于决定 Samba 容器运行在 Ceph 集群的哪些节点上。
- **当前 Samba 服务只能监听 445 端口**。受此限制,单个 Ceph 节点上同时只能运行**一个** Samba 服务器(且只能属于一个集群)。**请确保各集群的 placement spec 不重叠。**
- 各 `smb` 集群之间**完全隔离**。只要 Ceph 集群资源充足,可以运行多个互相独立的集群,它们可以加入也可以不加入相同的 AD 域/林。
- 但**不应**把同一个目录共享给多个可能具有不同认证模式和/或身份映射方案的集群。
> 官方 note(原文保留):未来版本的 `smb` 模块**可能**会以编程方式尝试阻止上述情况(指把同一目录共享给多个认证/映射方案不同的集群)。
#### 8.15.11 访问共享
一旦集群及其组件 Samba 容器部署完成、共享配置就绪,客户端即可连接到这些服务器:
- **Microsoft Windows**:系统内置 SMB 支持,在 Windows Explorer 中可这样指定共享:`\\<hostname>\<sharename>`。例如 `\\ceph0.mycluster.sink.test\Staff Pics`。Windows 节点会**自动尝试登录**该共享。若集群与 Windows 客户端都配置了**相同的 AD 域**,则会自动执行**免密单点登录**;若集群配置为 `user` 认证,则应出现**用户名与密码提示**,此时输入在集群和/或 `ceph.smb.usersgroups` 资源中指定的某一组用户名与密码即可。
- **MacOS X 系统与许多基于 Linux 的系统**也支持连接 SMB 共享,如何连接请查阅对应操作系统与发行版的文档。
- **快速验证**:想要快速测试共享是否可用的 Ceph 集群运维人员,可以安装 `smbclient`,或使用 `samba-container` 项目提供的 Samba Client Container 镜像(镜像为 `quay.io/samba.org/samba-client:latest`)。在客户端上或在该容器内运行:
```bash
smbclient -U <username> //<hostname>/<sharename>
```
然后在提示符下输入密码。更多细节参见 `smbclient` 文档(<https://www.samba.org/samba/docs/current/man-html/smbclient.1.html>)。
**注意事项汇总**
- 只支持 SMB2/SMB3,不支持 SMB1/CIFS。
- 必须启用 cephadm 编排。
- 445 端口限制 ⇒ 单节点单 Samba 实例;多集群 placement 不可重叠。
- `clustering` 与 `placement` 的相互作用需要理解清楚,否则多实例可能出现意外行为。
- `custom_smb_global_options` 是「自己负责」的逃生舱,生产环境慎用。
- `remote_control` 服务默认 54445 端口、使用 mTLS;未配置完整 TLS 字段时会退化为只读模式,官方不建议。
- 声明式 `show` 与 `apply` 可 round-trip,适合做 GitOps 式管理。
> 引自:[SMB Module](https://docs.ceph.com/en/tentacle/mgr/smb/)
---
## 九、分布式追踪(Jaeger)
Ceph 的指标(metrics)回答「**发生了多少**」,日志回答「**发生了什么**」,而分布式追踪回答「**一次请求在系统中经过了哪些路径、各段耗时多少**」。本章基于官方 `jaegertracing/index.rst`。
### 9.1 基本架构与术语
Jaeger 为分布式系统提供开箱即用的追踪服务。
| 术语 | 官方定义(照录 + 中译) |
|---|---|
| **TRACE** | 一次 trace 展示数据/执行穿过一个系统的**路径**(A trace shows the data/execution path through a system) |
| **SPAN** | trace 的**单个单元**。一种数据结构,保存诸如 operation name、时间戳、以及在 trace 中的顺序等信息 |
| **JAEGER CLIENT** | OpenTracing API 的**语言特定实现** |
| **JAEGER AGENT** | 一个监听通过 **UDP** 发来的 span 的守护进程。agent 应被放置在与**被埋点应用相同的主机**上(Jaeger agent 充当 sidecar listener 的角色) |
| **JAEGER COLLECTOR** | 接收 Jaeger agent 发来 span 的守护进程,然后把这些 span **拼接成 trace**(可启用数据库来持久化这些 trace) |
| **JAEGER QUERY AND CONSOLE FRONTEND** | 基于 UI 的前端,展示 jaeger trace 报告。访问地址 `http://<jaeger frontend host>:16686` |
延伸阅读:https://www.jaegertracing.io/docs/
### 9.2 Jaeger 的部署方式
Jaeger 可以用 **cephadm** 部署,也可以**手工**部署。
**cephadm 方式(作为 service 部署)**
官方指向 *Cephadm Jaeger Services Deployment*(`../cephadm/services/tracing/`)。
> 注意:`cephadm/services/monitoring.rst` 与 `cephadm/services/tracing.rst` 归属 **cephadm 册**,本册不展开。
**单节点手工测试部署(Jaeger OpenTelemetry all-in-one 容器)**
```bash
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-e COLLECTOR_OTLP_ENABLED=true \
-p 6799:6799/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 4317:4317 \
-p 4318:4318 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:latest --processor.jaeger-compact.server-host-port=6799
```
端口逐项说明(按官方命令照录):
| 端口 | 协议 | 说明(💡 补充:依据官方命令中出现的标准 Jaeger 端口整理,官方页面本身未逐项解释) |
|---|---|---|
| `6799` | UDP | **Ceph tracer 实际发送 span 的端口**(见下方 note) |
| `6832` | UDP | Jaeger agent 的 binary thrift 紧凑协议端口 |
| `5778` | TCP | agent 的配置/管理端口 |
| `16686` | TCP | **Jaeger Query / Console 前端** |
| `4317` | TCP | OTLP gRPC |
| `4318` | TCP | OTLP HTTP |
| `14250` | TCP | 接受 model.proto(gRPC) |
| `14268` | TCP | 接受 jaeger.thrift over HTTP |
| `14269` | TCP | 管理/健康检查端口 |
| `9411` | TCP | Zipkin 兼容接收端口(`COLLECTOR_ZIPKIN_HOST_PORT=:9411`) |
> **官方 note(重要,原文保留)**:
> - Jaeger agent **必须运行在每个主机上**(且**不能**运行在 all-in-one 模式下)。因为 span 是**发给本地 Jaeger agent** 的;没有活跃 Jaeger agent 的主机,其 span **会丢失**。
> - Jaeger agent 的**默认配置端口与官方默认的 6831 不同**,因为 **Ceph tracer 被配置为向监听 6799 端口的 agent 发送 trace**。手工部署 Jaeger 时请使用 `--processor.jaeger-compact.server-host-port=6799`。
更多参考:
- Jaeger Deployment:https://www.jaegertracing.io/docs/1.25/deployment/
- Jaeger Performance Tuning:https://www.jaegertracing.io/docs/1.25/performance-tuning/
### 9.3 在 Ceph 中启用 tracing
**Ceph 中的 tracing 默认是禁用的。**
tracing 可以**全局**启用,也可以**按实体(entity)单独**启用(例如只给 rgw 开)。
```bash
# 全局启用
ceph config set global jaeger_tracing_enable true
# 按实体启用
ceph config set <entity> jaeger_tracing_enable true
```
例如只对 RGW 开启:
```bash
ceph config set rgw jaeger_tracing_enable true
```
> 💡 补充:上面 `ceph config set rgw ...` 是按实体启用的一个具体写法示例;官方原文只给出 `ceph config set <entity> jaeger_tracing_enable true` 的通用形式。
### 9.4 配置项
| 配置项 | 类型 | 默认值 | level | 适用服务 | 说明 |
|---|---|---|---|---|---|
| `jaeger_tracing_enable` | `bool` | `false` | advanced | `rgw`、`osd` | 是否让 Ceph 使用 jaeger tracing 系统(desc: Ceph should use jaeger tracing system)。带 `with_legacy: true` |
| `jaeger_agent_port` | `int` | `6799` | advanced | `rgw`、`osd` | jaeger agent 的端口号(desc: port number of the jaeger agent) |
> 默认值取自 `src/common/options/global.yaml.in` @ v20.2.4。Ceph 选择 **6799** 而非 Jaeger 官方默认的 6831,这是本册反复强调的关键点。
> 💡 补充:官方 `jaegertracing/index.rst` 页面本身**没有**给出 `jaeger_agent_host` / `jaeger_service_name` 等其它 jaeger 配置项;`global.yaml.in` 中与 jaeger 相关的也只有上述两项(已用 `- name: jaeger*` 全量核对)。因此除 `jaeger_tracing_enable` 与 `jaeger_agent_port` 外,本册不列出其它 jaeger 配置项。
### 9.5 RGW 中的 trace
运行在 RGW 上的 trace,可以在 Jaeger 前端的 **`rgw` 这个 Service 下**找到。
**Requests(请求)**
- **每个用户请求都会被追踪**。
- 每个 trace 包含以下 tag:`Operation name`、`User id`、`Object name`、`Bucket name`。
- 对**分段上传(Multipart upload)**操作,还会有 `Upload id` tag。
- 请求 trace 的命名格式:`<command> <transaction id>`。
**Multipart upload(分段上传)**
- 存在一类 trace,它由「分段上传过程中每次请求对应的一个 span」组成,并包含**所有 `Put Object` 请求**。
- 分段上传 trace 的命名格式:`multipart_upload <upload id>`。
**前端截图**
官方页面给出了两张截图(本册无法内嵌,按原文标注):
- `rgw service in Jaeger Frontend`:`./rgw_jaeger.png`(width 400)
- `osd service in Jaeger Frontend`:`./osd_jaeger.png`(width 400)
### 9.6 注意事项
- **生产环境不要依赖 all-in-one 容器**:官方明确说 agent 必须跑在每个主机上且不能用 all-in-one 模式,all-in-one 只适用于「单节点测试」。
- **端口 6799 是 Ceph 侧的约定**,与 Jaeger 官方默认的 6831 不同;改端口要同时改 `jaeger_agent_port`。
- 追踪会带来额外开销,且**默认关闭**;建议按需、按实体(如只开 rgw)临时开启排查。
- 已启用 tracing 的实体里,官方 `services` 标注为 `rgw` 与 `osd`。
> 引自:[JAEGER - DISTRIBUTED TRACING](https://docs.ceph.com/en/tentacle/jaegertracing/)
---
## 十、硬件监控(Redfish / node-proxy)
本章基于官方 `hardware-monitoring/index.rst`。
### 10.1 什么是 node-proxy
`node-proxy` 是**内部名称**,指代那个**清点一台机器硬件、提供各种状态、并让运维人员能够执行某些动作**的运行中 agent。
它从 **RedFish API** 采集细节数据,处理后**推送到 Ceph manager 守护进程中的 agent endpoint**。
数据流(对应官方 graphviz 图):
| 步骤 | 方向 | 说明 |
|---|---|---|
| 1 | agent → redfish | Collects data from redfish API(从 RedFish API 采集数据) |
| 2 | agent → ceph manager | Pushes data to ceph mgr(把数据推送给 ceph mgr) |
| 3 | ceph dashboard → ceph manager | Query ceph mgr(dashboard 查询 ceph mgr) |
```text
+--------------+ 1. 采集 +---------+
| agent | ------------> | redfish |
| (node-proxy) | +---------+
+------+-------+
| 2. 推送
v
+--------------+ 3. 查询 +---------------+
| ceph manager | <------------ | ceph dashboard|
+--------------+ +---------------+
```
> 💡 补充:上面这张 ASCII 图是根据官方 graphviz 图的节点与边(含 Legend 三条说明)重绘的等价示意,非官方原文图形。
### 10.2 局限性(Limitations)
> For the time being, the `node-proxy` agent relies on the RedFish API.
> It implies both `node-proxy` agent and `ceph-mgr` daemon need to be able to access the **Out-Of-Band network** to work.
要点:
- 目前 `node-proxy` agent **依赖 RedFish API**(即本册主题中提到的 Redfish;官方页面**未提及 SNMP**,本册不杜撰)。
- 这意味着 **`node-proxy` agent 与 `ceph-mgr` 守护进程两者都需要能够访问带外(Out-Of-Band)网络**才能工作。
### 10.3 部署 agent(Deploying the agent)
官方给出的两步:
1. **提供带外管理工具的凭据**(out of band management tool credentials)。可以在**添加主机时通过一个 service spec 文件**完成。该 `host.yml` 的内容为:
```yaml
# cat host.yml
---
service_type: host
hostname: node-10
addr: 10.10.10.10
oob:
addr: 20.20.20.10
username: admin
password: p@ssword
```
即:在 `service_type: host` 的 spec 中,用 **`oob`** 这一段提供带外管理口的 `addr`、`username`、`password`;`addr` 则是该主机在正常(业务/前端)网络上的地址。
然后应用该 spec:
```bash
# ceph orch apply -i host.yml
Added host 'node-10' with addr '10.10.10.10'
```
2. **开启硬件监控**:
```bash
# ceph config set mgr mgr/cephadm/hw_monitoring true
```
**配置项**
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `mgr/cephadm/hw_monitoring` | 文档未明确(示例显式设为 `true`) | 启用 cephadm 的硬件监控(部署 node-proxy agent)。官方以 `ceph config set mgr mgr/cephadm/hw_monitoring true` 的形式给出 |
> 说明:`mgr/cephadm/*` 属 cephadm 模块选项,未收录于 `handbook-src/options/*.yaml.in`,故默认值标注为「文档未明确」。
### 10.4 CLI
```text
orch hardware status [hostname] [--category CATEGORY] [--format plain | json]
```
即:
```bash
ceph orch hardware status [hostname] [--category CATEGORY] [--format plain|json]
```
**支持的 category(逐项,官方原文顺序)**
| # | category | 说明 |
|---|---|---|
| 1 | `summary` | **默认** |
| 2 | `memory` | 内存 |
| 3 | `storage` | 存储 |
| 4 | `processors` | 处理器 |
| 5 | `network` | 网络 |
| 6 | `power` | 电源 |
| 7 | `fans` | 风扇 |
| 8 | `temperatures` | 温度 |
| 9 | `firmware` | 固件 |
| 10 | `criticals` | 严重告警项 |
> 💡 补充:`--format` 的可选值为 `plain` 与 `json`;`plain` 是上面这类**表格文本**(默认),`json` 则适合交给脚本/监控系统二次处理。`hostname` 与 `--category` 均为可选:不带 `hostname` 时通常列出全部已纳管主机。
**示例 1:默认 summary**
```bash
# ceph orch hardware status
+------------+---------+-----+-----+--------+-------+------+
| HOST | STORAGE | CPU | NET | MEMORY | POWER | FANS |
+------------+---------+-----+-----+--------+-------+------+
| node-10 | ok | ok | ok | ok | ok | ok |
+------------+---------+-----+-----+--------+-------+------+
```
**示例 2:指定主机 + storage**
```bash
# ceph orch hardware status IBM-Ceph-1 --category storage
+------------+--------------------------------------------------------+------------------+----------------+----------+----------------+--------+---------+
| HOST | NAME | MODEL | SIZE | PROTOCOL | SN | STATUS | STATE |
+------------+--------------------------------------------------------+------------------+----------------+----------+----------------+--------+---------+
| node-10 | Disk 8 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT99QLL | OK | Enabled |
| node-10 | Disk 10 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT98ZYX | OK | Enabled |
| node-10 | Disk 11 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT98ZWB | OK | Enabled |
| node-10 | Disk 9 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT98ZC9 | OK | Enabled |
| node-10 | Disk 3 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT9903Y | OK | Enabled |
| node-10 | Disk 1 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT9901E | OK | Enabled |
| node-10 | Disk 7 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT98ZQJ | OK | Enabled |
| node-10 | Disk 2 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT99PA2 | OK | Enabled |
| node-10 | Disk 4 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT99PFG | OK | Enabled |
| node-10 | Disk 0 in Backplane 0 of Storage Controller in Slot 2 | MZ7L33T8HBNAAD3 | 3840755981824 | SATA | S6M5NE0T800539 | OK | Enabled |
| node-10 | Disk 1 in Backplane 0 of Storage Controller in Slot 2 | MZ7L33T8HBNAAD3 | 3840755981824 | SATA | S6M5NE0T800554 | OK | Enabled |
| node-10 | Disk 6 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT98ZER | OK | Enabled |
| node-10 | Disk 0 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT98ZEJ | OK | Enabled |
| node-10 | Disk 5 in Backplane 1 of Storage Controller in Slot 2 | ST20000NM008D-3D | 20000588955136 | SATA | ZVT99QMH | OK | Enabled |
| node-10 | Disk 0 on AHCI Controller in SL 6 | MTFDDAV240TDU | 240057409536 | SATA | 22373BB1E0F8 | OK | Enabled |
| node-10 | Disk 1 on AHCI Controller in SL 6 | MTFDDAV240TDU | 240057409536 | SATA | 22373BB1E0D5 | OK | Enabled |
+------------+--------------------------------------------------------+------------------+----------------+----------+----------------+--------+---------+
```
> 注意:官方示例中命令写的是主机 `IBM-Ceph-1`,但输出表的 HOST 列是 `node-10`;这是官方文档示例本身的不一致,本册照录。
**示例 3:firmware**
```bash
# ceph orch hardware status node-10 --category firmware
+------------+----------------------------------------------------------------------------+--------------------------------------------------------------+----------------------+-------------+--------+
| HOST | COMPONENT | NAME | DATE | VERSION | STATUS |
+------------+----------------------------------------------------------------------------+--------------------------------------------------------------+----------------------+-------------+--------+
| node-10 | current-107649-7.03__raid.backplane.firmware.0 | Backplane 0 | 2022-12-05T00:00:00Z | 7.03 | OK |
... omitted output ...
| node-10 | previous-25227-6.10.30.20__idrac.embedded.1-1 | Integrated Remote Access Controller | 00:00:00Z | 6.10.30.20 | OK |
+------------+----------------------------------------------------------------------------+--------------------------------------------------------------+----------------------+-------------+--------+
```
> 说明:官方示例在中间用 `... omitted output ...` 省略了若干行(本册照录)。从首尾两行可以看出 firmware 报告的关键特征:`COMPONENT` 列同时编码了**固件槽位/版本**(如 `current-107649-7.03__raid.backplane.firmware.0`、`previous-25227-6.10.30.20__idrac.embedded.1-1`),即同一组件可能同时存在 **current(当前)** 与 **previous(上一版,用于回退)** 两份固件;`NAME` 列给出人类可读的部件名(如 Backplane 0、Integrated Remote Access Controller,后者即 iDRAC)。
**示例 4:criticals**
```bash
# ceph orch hardware status --category criticals
+------------+-----------+------------+----------+-----------------+
| HOST | COMPONENT | NAME | STATUS | STATE |
+------------+-----------+------------+----------+-----------------+
| node-10 | power | PS2 Status | critical | unplugged |
+------------+-----------+------------+----------+-----------------+
```
### 10.5 NodeProxyEndpoint(开发者视角)
官方页面以 autodoc 方式列出了 `NodeProxyEndpoint` 类及其方法(共 **14 个 automethod**):
| # | 方法 | 对应能力 |
|---|---|---|
| 1 | `NodeProxyEndpoint.__init__` | 构造 |
| 2 | `NodeProxyEndpoint.oob` | 带外(out-of-band)相关 |
| 3 | `NodeProxyEndpoint.data` | 原始数据 |
| 4 | `NodeProxyEndpoint.fullreport` | 完整报告 |
| 5 | `NodeProxyEndpoint.summary` | 汇总(对应 `summary` category) |
| 6 | `NodeProxyEndpoint.criticals` | 严重项(对应 `criticals` category) |
| 7 | `NodeProxyEndpoint.memory` | 内存(对应 `memory` category) |
| 8 | `NodeProxyEndpoint.storage` | 存储(对应 `storage` category) |
| 9 | `NodeProxyEndpoint.network` | 网络(对应 `network` category) |
| 10 | `NodeProxyEndpoint.power` | 电源(对应 `power` category) |
| 11 | `NodeProxyEndpoint.processors` | 处理器(对应 `processors` category) |
| 12 | `NodeProxyEndpoint.fans` | 风扇(对应 `fans` category) |
| 13 | `NodeProxyEndpoint.temperatures` | 温度(对应 `temperatures` category) |
| 14 | `NodeProxyEndpoint.firmware` | 固件(对应 `firmware` category) |
| 15 | `NodeProxyEndpoint.led` | LED(灯,通常用于定位磁盘/机箱) |
> 说明:官方以 `.. autoclass:: NodeProxyEndpoint` + 14 条 `.. automethod::` 声明;上表把 `__init__` 与其余 13 个端点方法合并列出(即 `oob` 起共 14 个端点方法)。各方法的参数与返回值细节由 Sphinx autodoc 从源码生成,**官方文档 rst 源文本身不含这些签名**,故本册不展开。
### 10.6 注意事项
- 依赖 **RedFish API**,且 **agent 与 ceph-mgr 都要能访问带外网络**——这是部署前必须先打通的网络前提。
- `mgr/cephadm/hw_monitoring` 属 cephadm 模块选项,需要在 **mgr** 上设置。
- `orch hardware status` 的 category 与 `NodeProxyEndpoint` 的方法名一一对应,便于从 CLI 映射到 API。
- 带外凭据(`oob.addr` / `oob.username` / `oob.password`)是**随主机一起**在 `service_type: host` 的 spec 里下发的,密码在 spec 中以**明文**出现,因此该 YAML 文件需要按凭据文件的标准来保管(权限、版本库是否入库等)。
- `summary` 只是 6 列健康态速览(STORAGE / CPU / NET / MEMORY / POWER / FANS),要看具体部件(如磁盘型号、序列号、固件版本)必须显式指定 `--category`。
- 官方只支持 **RedFish** 一种带外协议(页面未提及 SNMP / IPMI 直连),因此硬件是否可被监控,取决于 BMC/iDRAC/iLO 等是否提供可用的 RedFish API。
> 💡 补充:官方该页的小节标题拼写为 `Developpers`(多了一个 `p`),属官方文档笔误,本册在 10.5 中按语义译作「开发者视角」。
> 引自:[Hardware Monitoring](https://docs.ceph.com/en/tentacle/hardware-monitoring/)
---
## 十一、监控实践建议
> ⚠️ **本章为「官方未给出、由本册作者补充」的实践建议**。凡本章给出的阈值、选型与落地步骤,均**不是** Ceph 官方文档的原文承诺,请结合自身环境验证后再用于生产。按本册写作规范,以下内容以 `💡 补充` 标注。
### 11.1 采集层该采什么
> 💡 补充:建议按「三层」组织采集,避免一上来就全采。
| 层 | 采集对象 | 手段 | 关键理由 |
|---|---|---|---|
| **Ceph 自身(集群级)** | 集群健康、容量、PG 状态、OSD 状态、pool 用量、RGW/CephFS/MDS 指标 | mgr `prometheus` 模块(第三章) | 这是唯一能拿到集群全局视图的通道 |
| **Ceph 自身(主机/守护进程级)** | 每个守护进程是否活着、进程级资源占用 | `ceph_exporter`(每主机) | 官方通过 `ceph_daemon_socket_up` 指标暴露守护进程健康(1=健康 / 0=不健康,标签 `ceph_daemon`、`hostname`) |
| **宿主机(OS 级)** | CPU / 内存 / 磁盘 IO / 网络 / 文件系统 | `node_exporter` | Ceph 指标无法解释「机器本身是否健康」 |
| **硬件(带外)** | 电源、风扇、温度、磁盘、固件、严重项 | `node-proxy` + RedFish(第十章) | 带外信息是 Ceph 指标与 OS 指标的盲区(如 PSU 掉电、风扇停转) |
| **请求链路(可选)** | 单次请求的跨组件路径与耗时 | Jaeger tracing(第九章) | 只在排查延迟类问题时临时开启,默认关闭 |
### 11.2 汇聚与存储的落地要点
> 💡 补充:以下要点均来自第三章的官方约束,此处只是把它们整理成检查清单。
- **scrape_interval 要匹配**:mgr `prometheus` 模块有缓存与 `stale_cache_strategy`(`503` / `return` / `fail`),Prometheus 侧的 `scrape_interval` 与模块缓存策略要配合,否则会拿到陈旧数据或直接报错。
- **`honor_labels`**:Prometheus 抓取 Ceph 目标时注意 label 冲突处理。
- **磁盘占用指标优先用 `ceph_disk_occupation_human`**:它比 `ceph_disk_occupation` 更适合人类阅读/展示(详见第三章指标清单)。
- **每个主机都要跑 `ceph_exporter`**:否则该主机的守护进程健康指标缺失。
- **Grafana 数据源命名**:若要在 Dashboard 中嵌入 Grafana,数据源**必须**命名为 `Dashboard1`,且 Grafana 需开启 `allow_embedding=true`(第四章)。
### 11.3 建议优先建立的关键告警
> 💡 补充:下表阈值仅为**起点建议**,必须结合集群规模与业务 SLA 调整;**官方文档未给出这些阈值**。
| 优先级 | 告警对象 | 建议的判定方向 | 备注 |
|---|---|---|---|
| P0 | 守护进程存活 | `ceph_daemon_socket_up == 0` 持续一段时间 | 直接反映守护进程不健康 |
| P0 | 集群健康 | `ceph_health_status` 非 healthy | 配合 `ceph health detail` 定位 |
| P0 | 容量 | 集群已用比例接近满水位 | 容量告警应分「预警」与「紧急」两级 |
| P1 | OSD down/out | down 的 OSD 数超过冗余可承受范围 | 与 CRUSH 故障域联动判断 |
| P1 | PG 状态 | 存在非 `active+clean` 的 PG(尤其是 degraded / undersized / inactive) | 用 `ceph progress`(8.2)观察恢复进度 |
| P1 | MON quorum | monitor 数量低于 quorum 要求 | 直接威胁集群可用性 |
| P2 | 慢请求 / 延迟 | OSD 或 RGW 的 op latency 显著升高 | 必要时临时开 Jaeger(第九章)定位 |
| P2 | 崩溃 | 出现新的 crash(`RECENT_CRASH`) | 用 `ceph crash ls-new` / `crash archive`(8.1)处置 |
| P2 | MDS | MDS 数量不足 / CephFS 降级 | 可启用 `mds_autoscaler`(8.11) |
| P3 | 硬件 | `orch hardware status --category criticals` 有输出 | 需要带外网络(第十章) |
| P3 | SMART / 设备健康 | 设备预期寿命预测 | `diskprediction_local`(8.8),注意准确率约 70% |
### 11.4 Prometheus + Grafana + Alertmanager 的组合建议
> 💡 补充:
| 组件 | 角色 | 与 Ceph 的接口 |
|---|---|---|
| `ceph_exporter`(每主机) | 采集主机/守护进程级指标 | 由 cephadm 作为监控栈的一部分部署(详见 cephadm 册) |
| mgr `prometheus` 模块 | 暴露**集群级**指标 | HTTP 端点(第三章) |
| Prometheus | 抓取与存储 | 通过 `ceph_targets.yml` / `node_targets.yml` 做**文件服务发现**(第三章有示例) |
| Alertmanager | 告警路由、静默、去重、升级 | Dashboard 支持三种 Alertmanager 消费方式(第四章) |
| Grafana | 可视化;也可嵌入 Dashboard | 数据源需命名为 `Dashboard1` + `allow_embedding=true`(第四章) |
| Ceph Dashboard | 官方原生管理与可视化 | 第四章 |
**告警闭环建议(💡 补充):**
1. Prometheus 负责**判定**(rules);
2. Alertmanager 负责**路由与降噪**(按 severity / team 分派、inhibition、静默窗口);
3. Dashboard 负责**呈现与处置入口**(查看告警、关联到具体 OSD/PG/主机);
4. `crash` / `insights` / `telemetry` 三个模块分别补齐「崩溃取证」「健康与巡检报告」「匿名使用数据回流」三块能力(第八章)。
### 11.5 日常巡检清单(💡 补充)
| 频率 | 动作 | 命令/入口 |
|---|---|---|
| 每日 | 看集群健康与容量 | `ceph -s`、Dashboard 首页 |
| 每日 | 看是否有新崩溃 | `ceph crash ls-new`、`ceph crash stat` |
| 每日 | 看是否有未完成的恢复 | `ceph progress` |
| 每周 | 清理已确认的崩溃 | `ceph crash archive-all`、`ceph crash prune <keep>` |
| 每周 | 硬件严重项巡检 | `ceph orch hardware status --category criticals` |
| 每月 | 生成一次巡检报告 | `ceph insights`(可先 `ceph insights prune-health 0`) |
| 按需 | 上报/预览遥测 | `ceph telemetry status` / `ceph telemetry preview` |
| 按需 | 排查延迟 | 临时开启 Jaeger tracing(第九章) |
---
## 十二、命令速查表
> 说明:本表汇总本册出现过的命令。同一命令的详细参数请回到对应章节查看。
### 12.1 mgr 与模块管理
| 命令 | 说明 | 章节 |
|---|---|---|
| `ceph mgr module ls` | 列出所有 mgr 模块及其启用状态 | 2、8.7、8.10 |
| `ceph mgr module enable <module>` | 启用模块 | 8 |
| `ceph mgr module disable <module>` | 禁用模块 | 8 |
| `ceph mgr fail <mgr name>` | 把指定 mgr 标记为 failed(可强制切主) | 2 |
| `ceph mgr services` | 列出 mgr 模块暴露的所有服务端点(如 dashboard、prometheus) | 2、4 |
### 12.2 Dashboard
| 命令 | 说明 | 章节 |
|---|---|---|
| `ceph mgr module enable dashboard` | 启用 Dashboard | 4 |
| `ceph dashboard create-self-signed-cert` | 生成自签证书 | 4 |
| `ceph dashboard set-ssl-certificate -i <file>` | 设置 SSL 证书 | 4 |
| `ceph dashboard set-ssl-certificate-key -i <file>` | 设置 SSL 私钥 | 4 |
| `ceph config set mgr mgr/dashboard/server_addr <ip>` | 设置监听地址 | 4 |
| `ceph config set mgr mgr/dashboard/ssl_server_port <port>` | 设置 SSL 端口(默认 8443) | 4 |
| `ceph config set mgr mgr/dashboard/server_port <port>` | 设置非 SSL 端口(默认 8080) | 4 |
| `ceph dashboard ac-user-create <username> -i <file-containing-password> administrator` | 创建管理员用户 | 4 |
| `ceph dashboard ac-user-create [--enabled] [--force-password] [--pwd_update_required] <username> -i <file-containing-password> [<rolename>] [<name>] [<email>] [<pwd_expiration_date>]` | 创建用户的完整形式 | 4 |
| `ceph dashboard set-alertmanager-api-host <alertmanager-host:port>` | 配置 Alertmanager(默认 `''`) | 4 |
| `ceph dashboard set-alertmanager-api-ssl-verify False` | Alertmanager SSL 校验 | 4 |
| `ceph dashboard set-grafana-api-url <grafana-server-url>` | 配置 Grafana(默认 `''`) | 4 |
| `ceph dashboard reset-grafana-api-url` | 重置 Grafana URL | 4 |
| `ceph dashboard set-grafana-api-ssl-verify False` | Grafana SSL 校验 | 4 |
| `ceph mgr services \| jq .dashboard` | 查看 dashboard 端点 | 4 |
### 12.3 Prometheus / 告警
| 命令 | 说明 | 章节 |
|---|---|---|
| `ceph mgr module enable prometheus` | 启用 prometheus 模块 | 3 |
| `ceph config set mgr mgr/prometheus/server_addr <ip>` | 设置监听地址 | 3 |
| `ceph config set mgr mgr/prometheus/server_port <port>` | 设置监听端口 | 3 |
| `ceph config set mgr mgr/prometheus/scrape_interval <sec>` | 设置抓取/缓存间隔 | 3 |
| `ceph config set mgr mgr/prometheus/stale_cache_strategy return\|fail` | 陈旧缓存策略(**默认**行为是返回 503 HTTP 状态码) | 3 |
| `ceph config set mgr mgr/prometheus/healthcheck_history_max_entries <n>` | health check 历史最大条目数(默认 1000) | 3 |
| `ceph healthcheck history ls [--format {plain\|json\|json-pretty}]` | 列出 health check 历史 | 3.8 |
| `ceph healthcheck history clear` | 清除 health check 历史 | 3.8 |
| `ceph alerts send` | 立即发送一次告警邮件 | 5 |
### 12.4 RESTful API / 编排器
| 命令 | 说明 | 章节 |
|---|---|---|
| `curl -k https://<mgr>:8443/api/... -H "Authorization: Bearer <jwt>"` | 调用 Ceph RESTful API | 6 |
| `ceph orch status [--detail]` | 查看编排器状态 | 7 |
| `ceph orch set backend <module>` | 设置编排器后端 | 7 |
| `ceph orch set backend ""` | 禁用编排器后端 | 7 |
| `ceph orch ls [--service_name=...] [--export]` | 列出服务 | 7、8.14 |
| `ceph orch ps [--daemon-type <type>]` | 列出守护进程 | 7、8.14 |
| `ceph orch apply -i <spec.yaml>` | 应用服务规格 | 7、8.14、10 |
| `ceph orch rm <service>` | 移除服务 | 7 |
| `ceph orch hardware status [hostname] [--category CATEGORY] [--format plain\|json]` | 硬件状态 | 10 |
| `ceph orch cert-store get cert cephadm_root_ca_cert` | 取出根 CA 证书 | 8.13 |
### 12.5 各内置模块
| 命令 | 说明 | 章节 |
|---|---|---|
| `ceph crash post -i <metafile>` | 上报崩溃 | 8.1 |
| `ceph crash ls` / `ls-new` / `stat` / `info <id>` / `rm <id>` | 崩溃查询与删除 | 8.1 |
| `ceph crash prune <keep>` | 按天清理崩溃 | 8.1 |
| `ceph crash archive <id>` / `archive-all` | 归档崩溃 | 8.1 |
| `ceph progress` / `progress json` / `progress clear` | 恢复进度 | 8.2 |
| `ceph progress on` / `off` | 开关 progress 模块 | 8.2 |
| `ceph insights` | 生成 insights 报告 | 8.3 |
| `ceph insights prune-health <hours>` | 清理健康历史 | 8.3 |
| `ceph telemetry on --license sharing-1-0` / `off` | 开关遥测 | 8.4 |
| `ceph telemetry enable channel <name>...\|all` | 启用通道 | 8.4 |
| `ceph telemetry disable channel <name>...\|all` | 禁用通道 | 8.4 |
| `ceph telemetry channel ls` / `collection ls` / `diff` / `status` | 遥测查询 | 8.4 |
| `ceph telemetry show` / `show-device` / `show-all` | 查看将上报的数据 | 8.4 |
| `ceph telemetry preview` / `preview-device` / `preview-all` | 预览示例报告 | 8.4 |
| `ceph telemetry send [--license sharing-1-0]` | 立即上报一次 | 8.4 |
| `ceph telegraf config-set <key> <value>` | 配置 telegraf 模块 | 8.5 |
| `ceph config set mgr mgr/influx/<key> <value>` | 配置 influx 模块 | 8.6 |
| `ceph influx self-test` | influx 自检 | 8.6 |
| `ceph iostat [-p <seconds>]` | 查看吞吐与 IOPS | 8.7 |
| `ceph device predict-life-expectancy <device id>` | 查询设备预期寿命 | 8.8 |
| `ceph config set global device_failure_prediction_mode local\|none` | 开关本地预测 | 8.8 |
| `ceph hello` | 运行 hello 模块 | 8.10 |
| `ceph rgw realm bootstrap [-i spec.yaml]` | 引导 RGW 多站点 | 8.13 |
| `ceph rgw realm tokens` | 列出 realm token | 8.13 |
| `ceph rgw zone create -i spec.yaml` | 创建 secondary zone | 8.13 |
| `ceph nfs cluster create <cluster_id> [placement] [options]` | 创建 NFS 集群 | 8.14 |
| `ceph nfs cluster info [cluster_id]` | 查看 NFS 集群 IP | 8.14 |
| `ceph nfs cluster ls` / `rm <cluster_id>` | 列出/删除 NFS 集群 | 8.14 |
| `ceph nfs cluster config set\|get\|reset <cluster_id>` | 自定义 Ganesha 配置 | 8.14 |
| `ceph nfs export create cephfs\|rgw ...` | 创建导出 | 8.14 |
| `ceph nfs export ls <cluster_id> [--detailed]` | 列出导出 | 8.14 |
| `ceph nfs export info <cluster_id> <pseudo_path>` | 查看导出 | 8.14 |
| `ceph nfs export apply <cluster_id> -i <file>` | 用 JSON/配置片段创建或更新导出 | 8.14 |
| `ceph nfs export rm <cluster_id> <pseudo_path>` | 删除导出 | 8.14 |
| `ceph smb cluster create <cluster_id> {user\|active-directory} [options]` | 创建 SMB 集群 | 8.15 |
| `ceph smb cluster ls [--format=yaml]` / `rm <cluster_id>` | 列出/删除 SMB 集群 | 8.15 |
| `ceph smb share create <cluster_id> <share_id> <cephfs_volume> <path> [options]` | 创建 SMB 共享 | 8.15 |
| `ceph smb share ls <cluster_id>` / `rm <cluster_id> <share_id>` | 列出/删除共享 | 8.15 |
| `ceph smb apply -i <resources.yaml>` | 声明式应用资源 | 8.15 |
| `ceph smb show [resource_name...] [--format ...] [--results collapsed\|full]` | 查看已应用资源 | 8.15 |
### 12.6 追踪与配置
| 命令 | 说明 | 章节 |
|---|---|---|
| `ceph config set global jaeger_tracing_enable true` | 全局开启 tracing | 9 |
| `ceph config set <entity> jaeger_tracing_enable true` | 按实体开启 tracing | 9 |
| `ceph config set mgr mgr/cephadm/hw_monitoring true` | 开启硬件监控 | 10 |
| `ceph config set mgr mgr/<module>/<key> <value>` | 通用:设置模块配置项 | 2、8 |
| `ceph config set mgr mgr/crash/warn_recent_interval <val>` | 崩溃「近期」窗口(默认 2 weeks) | 8.1 |
| `ceph config set mgr mgr/crash/retain_interval <val>` | 崩溃保留期(默认 1 year) | 8.1 |
| `ceph config set mgr mgr/progress/allow_pg_recovery_event true` | 打开每 PG 恢复 event | 8.2 |
| `ceph config set mgr mgr/telemetry/interval <hours>` | 遥测上报间隔(默认 24) | 8.4 |
| `ceph config set mgr mgr/telemetry/proxy <url>` | 遥测代理 | 8.4 |
| `ceph config set mgr mgr/diskprediction_local/predict_interval <seconds>` | 预测间隔 | 8.8 |
| `ceph config set mgr mgr/localpool/num_rep <n>` / `pg_num <n>` | localpool 副本与 PG | 8.9 |
---
## 文档未明确项
本节如实列出本册编写过程中**无法从本机官方文档源文确认**的内容,避免读者误以为这些信息来自官方文档。
### A. 因本机抓取被安全策略拦截而缺失的内容
| # | 来源文件 | 缺失范围 | 影响 |
|---|---|---|---|
| 1 | `mgr/smb.rst` | ~~第 **560 行之后**的内容~~ **已补齐**:源文第 560–1036 行已完整读取,8.15.4(含 `bind_addrs` + `public_addrs` 警告)、8.15.5–8.15.9 的字段与完整 YAML 示例、8.15.10、8.15.11 均已按源文补齐 | 已消除 |
| 2 | `mgr/smb.rst` | ~~`linked_to_cluster` 字段的完整语义~~ **已补齐**:原文为「若设置,该资源只能与被链接的集群一起使用,并在该集群被移除时自动被移除」 | 已消除 |
| 3 | `hardware-monitoring/index.rst` | ~~第 **45 行之后**的部分内容~~ **已补齐**:源文第 45–185 行已完整读取,`host.yml` 中 `oob`(`addr` / `username` / `password`)结构与示例输出已按源文补齐 | 已消除 |
| 4 | `mgr/dashboard.rst` | 三个 include 插件文件的正文:`feature_toggles.inc.rst`、`debug.inc.rst`、`motd.inc.rst` | 第四章中 Dashboard 的 feature toggles、debug、MOTD 三块细节无法展开 |
### B. 源文本身未给出、且 `*.yaml.in` 中也查不到的默认值
| # | 配置项 | 说明 |
|---|---|---|
| 1 | `mgr/prometheus/*` 全部模块选项 | 定义在模块 Python 源码的 `MODULE_OPTIONS` 中,`handbook-src/options/*.yaml.in` 未收录;本册采用 rst 源文中明确写出的值,其余标注「文档未明确」 |
| 2 | `mgr/dashboard/*` 全部模块选项 | 同上 |
| 3 | `mgr/alerts/*` 模块选项 | 同上 |
| 4 | `mgr/influx/*` 全部 10 项(`hostname`、`username`、`password`、`interval`、`database`、`port`、`ssl`、`verify_ssl`、`threads`、`batch_size`) | 页面只用 `.. confval::` 列出名称,默认值是构建期占位符 |
| 5 | `mgr/localpool/*`(`subtree`、`failure_domain`、`pg_num`、`num_rep`、`min_size`) | 同上;仅 `prefix` 的默认值 `by-$subtreetype-` 由 rst 明确给出 |
| 6 | `mgr/telemetry/*` 除 `interval` 外各项(`proxy`、`contact`、`description`、`channel_ident`、`leaderboard`、`leaderboard_description`) | 同上 |
| 7 | `mgr/cephadm/hw_monitoring` | 同上 |
| 8 | `mgr/diskprediction_local/predict_interval` 的**具体秒数** | rst 只说 "performs the prediction on a daily basis by default",未给出数字默认值 |
| 9 | `mgr/crash/warn_recent_interval`、`mgr/crash/retain_interval` | rst 明确写出 `2 weeks` / `1 year`,但这两个值来自 rst 文本而非 `*.yaml.in`(模块选项不在 yaml.in 中),因此无法用 yaml.in 二次校验 |
### C. 官方文档中发现的笔误 / 前后不一致(存疑,本册照录未改)
| # | 位置 | 问题 |
|---|---|---|
| 1 | `mgr/prometheus.rst` | PUT 指标名 `ceph_rgw_op_global_put_obj_lat_count` 的描述写成了 "Number of **get** operations" |
| 2 | `mgr/prometheus.rst` | `ceph_rgw_op_global_get_obj_bytes` 被重复用于描述 PUT 字节数(实际更可能是 `ceph_rgw_op_global_put_obj_bytes`) |
| 3 | `mgr/prometheus.rst` | CephFS「Write workload for a specific MDS」示例仍用 `ceph_objecter_op_r`(写负载更可能是 `ceph_objecter_op_w`) |
| 4 | `mgr/prometheus.rst` | 描述 health check 历史的正文写「The `ceph healthcheck ls` command provides an overview...」,但命令清单中列出的是 `ceph healthcheck history ls`(本册以 `history ls` 为准) |
| 5 | `mgr/dashboard.rst` | OAuth2 示例写作 `ceph orch apply mgmt-gateway --enable_auth=true`,与常见连字符写法 `--enable-auth=true` 不一致 |
| 6 | `mgr/smb.rst` | `ceph smb cluster create` 的命令签名中**没有** `public_addrs`,但 Options 段落却描述了该参数 |
| 7 | `mgr/smb.rst` | `user group source fields` 的 `ref` 被描述为「必须指向 `ceph.smb.join.auth` 资源的 ID」,语义上更可能指 `ceph.smb.usersgroups` |
| 8 | `mgr/diskprediction.rst` | `ceph.conf` 片段写作 `debug mgr = 20`(带空格),而 `mgr/influx.rst` 中写作 `debug_mgr = 20` |
| 9 | `hardware-monitoring/index.rst` | 示例中命令写 `ceph orch hardware status IBM-Ceph-1`,但输出表 HOST 列是 `node-10` |
| 10 | `mgr/localpool.rst` | 正文说选项「set via the `config-key` interface」,示例却用 `ceph config set mgr ...` |
| 11 | `mgr/nfs.rst` | ingress 成熟度 note 仍保留 "expected to be completed by the Quincy release (March 2022)" 的历史性表述 |
| 12 | `mgr/telemetry.rst` | `channel ls` 示例输出中 `perf` 的 ENABLED 为 `ON` 而 DEFAULT 为 `OFF`,与「perf 默认 off」的文字说明需结合上下文理解 |
### D. 本册作者补充、非官方内容的范围声明
以下内容**不是** Ceph 官方文档原文,已在本册中以 `💡 补充` 显式标注:
1. 第三章指标表中的「告警建议」列;
2. 第九章 Jaeger 端口表中各端口用途的说明(官方只给出 docker run 命令,未逐项解释端口);
3. 第十章的 ASCII 数据流示意图(依据官方 graphviz 图的节点与 Legend 重绘);
4. 第十一章全部内容(采集分层、告警优先级与阈值、组件组合建议、巡检清单);
5. 第八章开头「官方 toctree 条目 ↔ 本册章节」的映射表;
6. 各章节中形如「💡 补充:……」的提示块。
### E. 本册未覆盖的范围(归属其它分册)
| 内容 | 归属 |
|---|---|
| `cephadm/services/monitoring.rst`(监控栈的 cephadm 部署) | cephadm 册(按用户要求,本册不读、不讲) |
| `cephadm/services/tracing.rst`(Jaeger 的 cephadm 部署) | cephadm 册(本册仅给出官方指向) |
| RGW / CephFS / RBD 各自的业务指标细节 | 对应存储接口分册 |
| `mgr/modules.rst` 中「如何编写自定义 mgr 模块」的开发者细节 | 本册只在第二章引用其模块机制部分 |