Files
wiki/存储/Ceph/知识库/05-cephadm-部署与运维篇.md
T
2026-09-18 13:49:11 +08:00

5124 lines
208 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.
# 第 05 册 · cephadm 部署与运维篇
> 基于 Ceph 官方文档整理 | 文档版本:**Tentacle v20.2.4** | 抓取日期:2026-09-17 | 源文:ceph/ceph@v20.2.4 `doc/cephadm/`
> 官网入口:https://docs.ceph.com/en/tentacle/cephadm/
---
## 本册导读
本册覆盖 Ceph Tentacle 官方文档 `doc/cephadm/` 目录下的全部 25 个页面(根目录 10 页 + `services/` 子目录 15 页),系统讲解如何用 **cephadm** 完成 Ceph 集群的部署、扩容、服务编排、OSD 管理、升级、证书管理与日常运维。
### 覆盖页面清单
| 源文文件 | 页面标题 | 对应本册章节 |
|---|---|---|
| `index.rst` | Cephadm | 一、二 |
| `compatibility.rst` | Compatibility and Stability | 一(前提)、十三 |
| `install.rst` | Using cephadm to Deploy a New Ceph Cluster | 三 |
| `adoption.rst` | Converting an existing cluster to cephadm | 十二 |
| `host-management.rst` | Host Management | 四 |
| `services/index.rst` | Service Management | 五 |
| `services/mon.rst` | MON Service | 七 |
| `services/mgr.rst` | MGR Service | 七 |
| `services/mds.rst` | MDS Service | 七 |
| `services/rgw.rst` | RGW Service | 七 |
| `services/nfs.rst` | NFS Service | 七 |
| `services/iscsi.rst` | iSCSI Service | 七 |
| `services/smb.rst` | SMB Service | 七 |
| `services/snmp-gateway.rst` | SNMP Gateway Service | 七 |
| `services/monitoring.rst` | Monitoring Services | 七 |
| `services/mgmt-gateway.rst` | Management Gateway | 七 |
| `services/oauth2-proxy.rst` | OAuth2 Proxy | 七 |
| `services/tracing.rst` | Tracing Services | 七 |
| `services/custom-container.rst` | Custom Container Service | 七 |
| `services/osd.rst` | OSD Service | 六 |
| `certmgr.rst` | Certificate Management | 十 |
| `upgrade.rst` | Upgrading Ceph | 九 |
| `operations.rst` | Cephadm Operations | 八 |
| `client-setup.rst` | Basic Ceph Client Setup | 十一 |
| `troubleshooting.rst` | Troubleshooting | 十四 |
### 建议阅读顺序
1. **第一次部署**:一 → 三 → 四 → 六(OSD)→ 七(按需选服务)→ 十一(客户端)。
2. **已有集群迁移**:一 → 十三(兼容性核对)→ 十二(adoption)→ 八。
3. **日常运维**:四(主机/label/maintenance/drain)→ 五(orch 命令与 spec)→ 八(日志、健康检查、keyring)。
4. **变更与风险操作**:九(升级)→ 十(证书)→ 十四(排障)。
5. **速查**:直接跳到十五(命令速查表)。
### 本册约定
- 中文叙述;**命令、参数名、配置项、默认值、spec 字段名一律保留英文原文**不翻译。
- 代码块按语言标注:`bash` / `yaml` / `ini` / `json` / `text`。
- 官方源文未写明、由本册补充的内容,以 `> 💡 补充:...` 标注。
- 源文未涉及或无法从源文确认的内容,明确写「文档未明确」,不做推测。
---
## 一、cephadm 是什么
### 1.1 定位
`cephadm` 是一个用于管理 Ceph 集群的实用程序(utility)。官方对它的能力描述是:
- `cephadm` can add a Ceph container to the cluster.(向集群添加 Ceph 容器)
- `cephadm` can remove a Ceph container from the cluster.(从集群移除 Ceph 容器)
- `cephadm` can update Ceph containers.(更新 Ceph 容器)
`cephadm` 管理 Ceph 集群的**完整生命周期**:从 bootstrapping 开始(在单节点上创建一个最小集群:一个 monitor + 一个 manager),随后通过 orchestration interface 扩展集群、添加主机、供给(provision)Ceph 守护进程与服务。整个生命周期管理既可以通过 Ceph CLI 完成,也可以通过 Dashboard(GUI)完成。
关键事实:
- `cephadm` 于 **Ceph v15.2.0(Octopus)** 引入,**不支持更老的 Ceph 版本**。
- `cephadm` **不依赖** Ansible、Rook、Salt 这类外部配置管理工具;但这些工具仍可用于自动化 cephadm 自身未覆盖的操作:
- cephadm-ansible:https://github.com/ceph/cephadm-ansible
- Rook:https://rook.io/docs/rook/v1.10/Getting-Started/intro/
- ceph-salt:https://github.com/ceph/ceph-salt
> 引自:[Cephadm](https://docs.ceph.com/en/tentacle/cephadm/)
### 1.2 与 ceph-deploy / ceph-ansible / Rook 的对比
> 💡 补充:下面表格中的「cephadm」一列依据本册源文(index.rst / install.rst / adoption.rst);ceph-deploy、ceph-ansible、Rook 三列属于本册源文范围之外的工具,源文仅出现名称、未做能力对比,因此相关格子标注「文档未明确(本册源文未覆盖)」,以免编造。
| 维度 | cephadm | ceph-deploy | ceph-ansible | Rook |
|---|---|---|---|---|
| 官方引入版本 | v15.2.0 (Octopus) | 文档未明确(本册源文未覆盖) | 文档未明确(本册源文未覆盖) | 文档未明确(本册源文未覆盖) |
| 部署形态 | 容器(Podman / Docker),守护进程以容器运行 | 文档未明确(本册源文未覆盖) | 文档未明确(本册源文未覆盖) | Kubernetes Operator 形态,文档未明确细节 |
| 是否依赖外部配置管理工具 | **不依赖** Ansible / Rook / Salt | 文档未明确 | 文档未明确 | 文档未明确 |
| 主机纳管方式 | SSH + 容器运行时,主机需满足 `cephadm-host-requirements` | 文档未明确 | 文档未明确 | 文档未明确 |
| 集群生命周期管理 | 完整生命周期:bootstrap → 加主机 → 供给守护进程/服务 → 升级 | 文档未明确 | 文档未明确 | 文档未明确 |
| 旧集群纳管 | 支持,见 `adoption.rst`;**仅支持 BlueStore OSD** | 文档未明确 | 文档未明确 | 文档未明确 |
| 配置来源 | Monitor 的集中配置数据库(`ceph config ...`),而非 `ceph.conf` | 文档未明确 | 文档未明确 | 文档未明确 |
| 官方替代关系 | Octopus 之后官方主推的部署方式 | 文档未明确 | 文档未明确 | 文档未明确 |
### 1.3 适用场景与前提
**适用场景:**
- 新建 Ceph 集群(单节点起步再扩展)。
- 把由 `ceph-deploy`、`ceph-ansible`、`DeepSea` 部署的**部分**已有集群转换为 cephadm 管理(见第十二章,限制:仅 BlueStore OSD)。
- 需要声明式(declarative)管理服务与守护进程数量的场景(ServiceSpec + placement)。
**主机前提(`cephadm-host-requirements`):**
| 前提项 | 要求 |
|---|---|
| Python | Python 3(`cephadm` 具体要求 **Python 3.6 或更高**) |
| init 系统 | Systemd |
| 容器运行时 | Podman 或 Docker |
| 时间同步 | 需要,例如 Chrony 或传统的 `ntpd` |
| 存储供给 | LVM2(用于 provisioning storage devices) |
| Linux 发行版 | 任何现代 Linux 发行版均可;依赖项由 bootstrap 过程自动安装 |
| SSH | `ssh` 必须已安装并处于运行状态,否则 bootstrap 会失败 |
其他相关前提与说明:
- **Podman 版本兼容性**:并非每个 Podman 版本都与 Ceph 兼容,详见第十三章的 Podman 版本矩阵。
- **Docker Live Restore**:可选特性,允许重启 Docker Engine 而不重启所有运行中的容器,参见 Docker 官方文档。
- **`cephadm` 新版本形态**:较新版本的 `cephadm` 是由源码编译出的可执行文件;**不再**能简单地从 Ceph git 树里复制单个脚本来运行。若要运行开发版本,需要自行构建 cephadm 独立可执行文件(源文指向 `compiling-cephadm`)。
- **部署 OSD 时**:目标主机上**不要**安装 `ceph-osd` 包,否则可能与 cephadm 的管理控制产生冲突,导致错误或异常行为(`osd.rst` 的 warning)。
- **`ssh` 用户**:默认是 `root`;若使用非 root 用户,该用户必须具备 **passwordless sudo** 权限。
> 引自:[Using cephadm to Deploy a New Ceph Cluster](https://docs.ceph.com/en/tentacle/cephadm/install/)、[Compatibility and Stability](https://docs.ceph.com/en/tentacle/cephadm/compatibility/)、[Converting an existing cluster to cephadm](https://docs.ceph.com/en/tentacle/cephadm/adoption/)
---
## 二、cephadm 架构
### 2.1 组件构成
| 组件 | 说明 |
|---|---|
| `cephadm` 二进制 / 可执行文件 | 在主机上直接执行的命令行工具。负责 bootstrap、add-repo、install、prepare-host、adopt、shell、enter、logs、rm-cluster、deploy 等本地动作。较新版本为**由源码编译出的可执行文件**。 |
| `cephadm` mgr module | Ceph Manager 中的一个模块(`mgr module`),是编排能力的实际执行者。可用 `ceph mgr module enable/disable cephadm` 启停;用 `ceph orch set backend cephadm` 指定为编排后端。 |
| orchestrator(编排器)与 `ceph orch ...` CLI | 通过 orchestration interface 与 mgr module 交互;所有 `ceph orch *` 命令都经由它。用 `ceph orch set backend ''` + `ceph mgr module disable cephadm` 可完全禁用。 |
| ServiceSpec(服务规格) | 描述「部署什么服务、放在哪里、用什么配置」的数据结构,通常以 YAML 提交给 `ceph orch apply -i`。 |
| placement(放置规格) | ServiceSpec 的一部分,决定在哪些主机上部署多少个守护进程(`count` / `label` / `hosts` / `host_pattern` / `count_per_host`)。 |
| DriveGroupSpec(OSD 服务规格) | `service_type: osd` 的特殊 spec,用磁盘属性(model / vendor / size / rotational / paths …)描述集群布局。 |
| 守护进程容器化机制 | 每个守护进程是一个 systemd unit + 一个容器:unit 名形如 `ceph-<fsid>@<daemon-name>`;容器执行命令可从 `/var/lib/ceph/<cluster-fsid>/<service-name>/unit.run` 查看。 |
| 声明式状态(Declarative State) | cephadm 持续比对「实际运行的守护进程列表」与「服务规格声明的列表」,按差异新增/删除守护进程。 |
### 2.2 声明式协调循环(Algorithm description)
cephadm 的声明式状态由一组「包含 placement 的 service specifications」构成。它持续把集群中实际运行的守护进程列表与规格列表对比,必要时增加新守护进程、移除旧守护进程。
候选主机的选择顺序(优先级从高到低):
1. 显式的主机名(`hosts:` / 命令行直接给主机名)——找到就用它们;
2. 否则找 label 规格(`label:`);
3. 再否则按 host pattern(`host_pattern`)匹配;
4. 最后兜底:选择所有已知主机作为候选。
其他行为要点:
- cephadm **知道**现有守护进程的位置,并**尽量避免移动**它们。
- 支持部署指定数量的服务;若候选主机上的守护进程数少于 `count`,则在候选主机中**随机**选择主机部署新的;多于 `count` 则**移除**已有守护进程;最后移除落在候选主机列表之外的守护进程。
- 特例:当 placement 选出的主机数**少于** `count` 要求时,cephadm 只在被选中的主机上部署。
### 2.3 数据落地位置
| 路径 | 内容 |
|---|---|
| `/var/log/ceph/<cluster-fsid>` | 全部集群日志(默认走 stderr / journald,除非启用 log to file) |
| `/var/lib/ceph/<cluster-fsid>` | 全部集群守护进程数据(日志除外) |
| `/var/lib/ceph/<cluster-fsid>/<daemon-name>` | 单个守护进程的数据 |
| `/var/lib/ceph/<cluster-fsid>/crash` | 集群 crash 报告 |
| `/var/lib/ceph/<cluster-fsid>/removed` | 被 cephadm 移除的有状态守护进程(如 monitor、prometheus)的旧数据目录 |
| `/var/lib/ceph/<cluster-fsid>/<service-name>/unit.run` | 容器实际执行命令 |
| `/var/log/ceph/cephadm.log` | `cephadm` 可执行文件自身的日志(默认) |
| `/etc/ceph/ceph.conf`、`/etc/ceph/ceph.client.admin.keyring` | bootstrap 写入的访问集群所需文件 |
| `/var/lib/ceph/<fsid>/config` | 自 16.2.10(Pacific) / 17.2.1(Quincy) 起,cephadm 额外保存的 config 与 keyring 目录(cephadm 专用) |
| `var/lib/ceph/{FSID}/cephadm.{DIGEST}` | cephadm 二进制的本地副本(`{DIGEST}` 为当前运行 Ceph 版本的字母数字串) |
> 💡 补充:由于 monitor、prometheus 等守护进程会在 `/var/lib/ceph` 下存放大量数据,官方建议把该目录单独放到独立的磁盘、分区或逻辑卷上,避免撑爆根文件系统。
> 引自:[Service Management](https://docs.ceph.com/en/tentacle/cephadm/services/index/)、[Cephadm Operations](https://docs.ceph.com/en/tentacle/cephadm/operations/)
---
## 三、安装 cephadm 与 bootstrap
### 3.1 获取 cephadm
有两种获取初始 `cephadm` 的方式,**二者互斥**,不要在同一系统上混用:
1. **发行版包安装**(distribution-specific installation)
2. **curl 下载**(curl-based installation)
#### 3.1.1 发行版包安装
```bash
# Ubuntu
apt install -y cephadm
# CentOS Stream
dnf search release-ceph
dnf install --assumeyes centos-release-ceph-<stable-release>
dnf install --assumeyes cephadm
# Fedora
dnf -y install cephadm
# SUSE
zypper install -y cephadm
```
#### 3.1.2 curl 方式
```bash
CEPH_RELEASE=18.2.0 # replace this with the active release
curl --silent --remote-name --location https://download.ceph.com/rpm-${CEPH_RELEASE}/el9/noarch/cephadm
chmod +x cephadm
./cephadm <arguments...>
```
> 说明:源文示例中 `CEPH_RELEASE=18.2.0`,并提示应从 releases 页面的 "latest active releases" 中确定实际版本。
若 `cephadm` 运行报错(含 `bad interpreter` 字样),通常是 Python 版本不对;可显式指定 Python 运行:
```bash
python3.8 ./cephadm <arguments...>
```
#### 3.1.3 把 cephadm 安装到主机上
独立 `cephadm` 足以 bootstrap 集群,但官方建议把 `cephadm` 命令安装到主机:
```bash
./cephadm add-repo --release <stable-release>
./cephadm install
which cephadm # 期望输出 /usr/sbin/cephadm
```
### 3.2 Bootstrap 新集群
#### 3.2.1 前置说明
- 第一步是在集群的第一台主机上运行 `cephadm bootstrap`,该动作会创建集群的第一个 Monitor 守护进程。
- **必须**把第一台主机的 IP 地址传给 bootstrap(`--mon-ip`)。
- **`ssh` 必须已安装并运行**,否则 bootstrap 失败。
- 若主机有多个网络/网卡,务必选择一个所有需要访问该集群的主机都能连通的地址。
- 官方建议:典型集群部署 3 或 5 个 Monitor 分散在不同主机;若集群有 5 个及以上节点,建议部署 5 个 Monitor;绝大多数集群不需要 7 个或更多。
#### 3.2.2 基本命令
```bash
cephadm bootstrap --mon-ip *<mon-ip>*
```
该命令会:
1. 在本地主机上为新集群创建 Monitor 与 Manager 守护进程;
2. 为集群生成新的 SSH key,并加入 root 用户的 `/root/.ssh/authorized_keys`;
3. 把公钥副本写到 `/etc/ceph/ceph.pub`;
4. 把最小配置文件写到 `/etc/ceph/ceph.conf`(与 Ceph 守护进程通信所需);
5. 把 `client.admin` 管理密钥(特权!)写到 `/etc/ceph/ceph.client.admin.keyring`;
6. 给 bootstrap 主机打上 `_admin` label。默认任何带该 label 的主机都会(也)获得 `ceph.conf` 与 `ceph.client.admin.keyring` 的副本。
#### 3.2.3 bootstrap 参数逐项表
> 说明:源文以散文 + 示例形式介绍 bootstrap 选项,并提示可用 `cephadm bootstrap -h` 查看全部可用选项。下表逐项列出本册源文中**明确出现**的参数;「默认值」一列为源文明确写出的默认值,源文未写默认值的标注「文档未明确」。
| 参数 | 默认值 | 含义 |
|---|---|---|
| `--mon-ip *<mon-ip>*` | 无(必填) | 集群第一台主机的 IP 地址,用于创建第一个 MON。 |
| `--cluster-network *<cidr>*` | 文档未明确(不指定则源文未说明) | 定义 cluster network(承载 OSD 之间的复制、恢复、心跳)。**必须是 CIDR 表示的子网**,例如 `10.90.90.0/24` 或 `fe80::/64`。 |
| `--ssh-user *<user>*` | root(源文称 root 为 default option) | 指定 cephadm 用于连接主机的 SSH 用户;对应 SSH key 会加入 `~<user>/.ssh/authorized_keys`;该用户必须具备 passwordless sudo 权限。 |
| `--ssh-private-key <private-key-filepath>` | 文档未明确 | 使用自定义 SSH 私钥(不再让 cephadm 自动生成密钥对)。 |
| `--ssh-public-key <public-key-filepath>` | 文档未明确 | 使用自定义 SSH 公钥;与 `--ssh-private-key` 配对使用。**与 `--ssh-signed-cert` 互斥**:同时传 `--ssh-public-key` 会被 cephadm 拒绝。 |
| `--ssh-signed-cert <signed-cert-file>` | 文档未明确 | 使用 CA 签名的 SSH 证书替代普通公钥认证。 |
| `--registry-json <path to json file>` | 文档未明确 | 需要登录的私有镜像仓库:JSON 文件内容形如 `{"url":"REGISTRY_URL", "username":"REGISTRY_USERNAME", "password":"REGISTRY_PASSWORD"}`。cephadm 会尝试登录并把登录信息存入其 config database,后续加入集群的主机也可以使用该认证仓库。 |
| `--registry-url` | **本册源文未出现该参数** | 源文中对应能力由 `--registry-json`(登录信息 JSON)与 `ceph cephadm registry-login`(集群运行后登录仓库)提供。`--registry-url` 是否仍存在于 `cephadm bootstrap -h` 中,**文档未明确**。 |
| `--single-host-defaults` | 不设置 | 单主机部署专用,等价于设置以下三项配置(见 3.5)。 |
| `--config *<config-file>*` | 文档未明确 | 以标准 ini 风格配置文件向新集群传入初始 Ceph 配置项。 |
| `--output-dir *<directory>*` | `/etc/ceph` | 指定写入 `ceph.conf` / keyring 等文件的目录(例如传 `.` 放到当前目录),避免与主机上已有的 Ceph 配置冲突。守护进程容器本身不需要 `/etc/ceph`。 |
| `--log-to-file` | 不启用(默认日志走 stdout/stderr,被容器运行时捕获,多数系统上进入 journald) | 让 Ceph 写传统日志文件到 `/var/log/ceph/$fsid`。 |
| `--log-dest=file` / `--log-dest=syslog`(或两者) | 文档未明确 | `cephadm` 可执行文件自身的日志落盘位置;在 bootstrap 时指定会被记录,供后续 cephadm 编排模块调用 cephadm 时复用。 |
| `--image *<image>*` | 文档未明确 | 指定容器镜像(隔离环境部署时使用,例如 `cephadm --image <hostname>:5000/ceph/ceph bootstrap --mon-ip <mon-ip>`)。 |
| `--skip-monitoring-stack` | 不设置(默认会部署基础监控栈) | 跳过监控栈部署。 |
| `--apply-spec` | 不设置 | bootstrap 期间直接应用集群 spec 文件(与 `ceph orch apply -i` 的多文档 YAML 配合使用)。 |
| `--skip-mon-network` | 文档未明确 | 排障章节出现的错误提示中提到该参数(`ERROR: Failed to infer CIDR network for mon ip ***; pass --skip-mon-network to configure it later`),可让 MON 网络稍后再配置。 |
> 💡 补充:`cephadm bootstrap -h` 是获取当前版本完整参数清单与默认值的权威方式;上表只覆盖本册源文中出现过的参数。
#### 3.2.4 通过 `--config` 传入初始配置
```bash
cat <<EOF > initial-ceph.conf
[global]
osd crush chooseleaf type = 0
EOF
./cephadm bootstrap --config initial-ceph.conf ...
```
也可用同样机制设置 cephadm 自身日志目标:
```bash
cat >/tmp/bootstrap.conf <<EOF
[mgr]
mgr/cephadm/cephadm_log_destination = syslog
EOF
cephadm bootstrap --config /tmp/bootstrap.conf # ... other bootstrap arguments ...
```
### 3.3 启用 Ceph CLI
cephadm 不要求在主机上安装任何 Ceph 包,但建议启用便捷的 `ceph` 命令访问:
```bash
# 方式一:cephadm shell(默认会把 /etc/ceph 下的 config 与 keyring 传入容器环境)
cephadm shell
# 注意:在 MON 主机上执行时,cephadm shell 会从 MON 容器推断 config,而不是用默认配置。
# --mount <path> 可把主机上的文件或目录挂到容器内 /mnt 下
# 方式二:直接执行命令
cephadm shell -- ceph -s
# 方式三:安装 ceph-common 包(含 ceph / rbd / mount.ceph 等)
cephadm add-repo --release <stable-release>
cephadm install ceph-common
```
验证:
```bash
ceph -v
ceph status
```
### 3.4 后续步骤
```bash
# 给更多主机加 _admin label,便于多机使用 Ceph CLI
ceph orch host label add *<host>* _admin
# 添加主机(详见第四章)
ceph orch host add <newhost> <ip> --labels _admin
# 添加 MON(详见第七章)
# 添加存储
ceph orch apply osd --all-available-devices
```
### 3.5 不同部署场景
#### 3.5.1 单主机(Single host)
```bash
cephadm bootstrap --mon-ip <mon-ip> --single-host-defaults
```
`--single-host-defaults` 会设置以下配置:
```ini
global/osd_crush_chooseleaf_type = 0
global/osd_pool_default_size = 2
mgr/mgr_standby_modules = False
```
> 源文提示:此类集群通常**不适合生产环境**。
#### 3.5.2 隔离环境 / 离线部署(airgapped)
步骤:
1. 运行本地容器仓库:
```bash
podman run --privileged -d --name registry -p 5000:5000 -v /var/lib/registry:/var/lib/registry --restart=always registry:2
```
2. 若使用 insecure registry,需要在 Podman/Docker 中配置仓库的 hostname 与 port(**每台**访问该仓库的主机都要做)。
3. 把镜像推入本地仓库,需要准备的镜像包括:Ceph container image、Prometheus、Node exporter、Grafana、Alertmanager。
4. 创建临时配置文件保存监控镜像名:
```ini
[mgr]
mgr/cephadm/container_image_prometheus = <hostname>:5000/prometheus
mgr/cephadm/container_image_node_exporter = <hostname>:5000/node_exporter
mgr/cephadm/container_image_grafana = <hostname>:5000/grafana
mgr/cephadm/container_image_alertmanager = <hostname>:5000/alertmanger
```
5. 用 `--image` 执行 bootstrap:
```bash
cephadm --image <hostname>:5000/ceph/ceph bootstrap --mon-ip <mon-ip>
```
#### 3.5.3 使用自定义 SSH 密钥
```bash
cephadm bootstrap --mon-ip <ip-addr> --ssh-private-key <private-key-filepath> --ssh-public-key <public-key-filepath>
```
> 前提:公钥必须已经作为目标主机 ssh 用户(通常 root)的 authorized key 分发到位。
#### 3.5.4 使用 CA 签名的 SSH 密钥
先在待加入集群的主机上把 CA 公钥设为可信 CA key:
```bash
# 生成 CA key
ssh-keygen -t rsa -f ca-key -N ""
# 在本机安装并标记为可信
cp ca-key.pub /etc/ssh
vi /etc/ssh/sshd_config # 增加:TrustedUserCAKeys /etc/ssh/ca-key.pub
systemctl restart sshd
# 分发到其他主机并做同样配置
scp /etc/ssh/ca-key.pub host2:/etc/ssh/
```
再生成密钥对并用 CA 签名(`-V +52w` 指定有效期):
```bash
ssh-keygen -t rsa -f cephadm-ssh-key -N ""
ssh-keygen -s ca-key -I user_root -n root -V +52w cephadm-ssh-key
ls
# ca-key ca-key.pub cephadm-ssh-key cephadm-ssh-key-cert.pub cephadm-ssh-key.pub
# 验证:私钥与签名证书需在同一目录
ssh -i cephadm-ssh-key host2
```
最后传给 bootstrap:
```bash
cephadm bootstrap --mon-ip <ip-addr> --ssh-private-key cephadm-ssh-key --ssh-signed-cert cephadm-ssh-key-cert.pub
```
要点:
- 该方式**不需要**把对应公钥分发到其他节点;
- cephadm 在收到 `--ssh-signed-cert` 时会**拒绝**同时传入的 `--ssh-public-key`;
- 密钥轮换只需用同一 CA 再签一把新钥,把新的私钥与证书交给 cephadm 即可,无需再向节点分发密钥。
### 3.6 OSD 内存自动调优(bootstrap 默认行为)
> ⚠️ 官方 warning:默认情况下,cephadm 在 bootstrap 时**启用** `osd_memory_target_autotune`,且 `mgr/cephadm/autotune_memory_target_ratio` 设为 **`.7`**(即总内存的 70%)。这对于「Ceph 与计算共用节点」的融合(converged)架构通常不合适。
融合架构下建议先调低比例:
```bash
# converged only:
ceph config set mgr mgr/cephadm/autotune_memory_target_ratio 0.2
```
然后启用内存自动调优:
```bash
ceph config set osd osd_memory_target_autotune true
```
> 引自:[Using cephadm to Deploy a New Ceph Cluster](https://docs.ceph.com/en/tentacle/cephadm/install/)
<!--CEPHADM_HB_ANCHOR-->
---
## 四、主机管理(Host Management)
### 4.1 查看主机
```bash
ceph orch host ls [--format yaml] [--host-pattern <name>] [--label <label>] [--host-status <status>] [--detail]
```
过滤参数说明:
| 参数 | 作用 |
|---|---|
| `--host-pattern <name>` | 正则,匹配主机名,只返回匹配的主机 |
| `--label <label>` | 只返回带指定 label 的主机 |
| `--host-status <status>` | 只返回指定状态的主机(当前可选值:`offline` 或 `maintenance`) |
| `--detail` | 对 cephadm 集群返回更多主机相关信息 |
| `--format yaml` | YAML 输出 |
三个过滤参数可以任意组合使用(同时按名称 + label + status 过滤,或只用其中任意子集)。
`--detail` 输出示例:
```text
HOSTNAME ADDRESS LABELS STATUS VENDOR/MODEL CPU HDD SSD NIC
ceph-master 192.168.122.73 _admin QEMU (Standard PC (Q35 + ICH9, 2009)) 4C/4T 4/1.6TB - 1
1 hosts in cluster
```
### 4.2 添加主机
主机必须满足 `cephadm-host-requirements`(见 1.3),否则添加会失败。分两步:
```bash
# 1) 把集群公钥安装到新主机 root 用户的 authorized_keys
ssh-copy-id -f -i /etc/ceph/ceph.pub root@<new-host>
# 例:
ssh-copy-id -f -i /etc/ceph/ceph.pub root@host2
ssh-copy-id -f -i /etc/ceph/ceph.pub root@host3
# 2) 告知 Ceph 该节点属于集群
ceph orch host add <newhost> [<ip>] [<label1> ...]
# 例:
ceph orch host add host2 10.10.0.102
ceph orch host add host3 10.10.0.103
ceph orch host add host4 10.10.0.104 --labels _admin
```
要点:
- **最好显式提供主机 IP**。若不提供地址,会立即通过 DNS 解析主机名并使用解析结果。
- 添加时可同时打 label;默认 `_admin` label 会让 cephadm 在 `/etc/ceph` 维护 `ceph.conf` 与 `client.admin` keyring。
- 从 16.2.10 (Pacific) 和 17.2.1 (Quincy) 起,除默认位置 `/etc/ceph/` 外,cephadm 还会把 config 与 keyring 存放在 `/var/lib/ceph/<fsid>/config` 目录。
### 4.3 删除主机
安全删除的前提:该主机上的所有守护进程都已被移除。
```bash
# 1) 排空主机上的所有守护进程
ceph orch host drain <host>
# 2) 查看是否还有守护进程残留
ceph orch ps <host>
# 3) 确认清空后移除主机
ceph orch host rm <host>
```
`drain` 会给主机打上 `_no_schedule` 与 `_no_conf_keyring` 两个 label(见 4.4)。
相关变体:
| 命令 | 行为 |
|---|---|
| `ceph orch host drain <host>` | 排空守护进程;施加 `_no_schedule` 与 `_no_conf_keyring`;主机上所有 OSD 会被安排移除 |
| `ceph orch host drain <host> --keep-conf-keyring` | 排空守护进程,但**保留**受管的 `ceph.conf` 与 keyring 文件;只施加 `_no_schedule` |
| `ceph orch host drain <host> --zap-osd-devices` | 排空时顺带把被移除 OSD 的设备 zap 掉 |
| `ceph orch host rm <host> --offline --force` | 主机离线且无法恢复时强制移除。**可能导致数据丢失**:会对每个 OSD 调用 `osd purge-actual` 强制清除;仍需手动更新包含该主机的 service specs |
| `ceph orch host rm <host> --rm-crush-entry` | 移除主机时一并尝试从 CRUSH map 移除对应 host bucket |
查看 OSD 移除进度:
```bash
ceph orch osd rm status
```
> ⚠️ `--rm-crush-entry`:如果主机上仍有 OSD,从 CRUSH map 移除会失败;应先用 `ceph orch host drain` 清掉 OSD。若失败,cephadm 会报告失败且主机仍受管。
### 4.4 特殊主机标签(Special host labels)
所有对 cephadm 有特殊含义的 label 都以 `_` 开头:
| label | 含义 | 备注 |
|---|---|---|
| `_no_schedule` | 不要在该主机上调度或部署守护进程 | 若加到已有 Ceph 守护进程的主机上,cephadm 会把这些守护进程**迁移到别处**(OSD 除外,不会被自动移除) |
| `_no_conf_keyring` | 不要在该主机上部署配置文件或 keyring | 与 `_no_schedule` 类似,但作用于 cephadm 管理的 client keyring 与 ceph conf 文件 |
| `_no_autotune_memory` | 不要在该主机上做内存自动调优 | 即使对一个或多个守护进程启用了 `osd_memory_target_autotune` 之类选项,该主机上的守护进程内存也不会被调优 |
| `_admin` | 把 `client.admin` 与 `ceph.conf` 分发到该主机 | 默认施加于执行 bootstrap 的第一台主机;通过 `ceph orch client-keyring ...` 机制分发。自 16.2.10 / 17.2.1 起,还会写入 `/var/lib/ceph/<fsid>/config` |
### 4.5 普通标签(Host labels)
label 本身是自由格式(free form),没有固定含义,每台主机可以有多个 label,主要用途是指定守护进程放置(placement)。
```bash
# 添加主机时打 label
ceph orch host add my_hostname --labels=my_label1
ceph orch host add my_hostname --labels=my_label1,my_label2
# 给已有主机添加 label
ceph orch host label add my_hostname my_label
# 移除 label
ceph orch host label rm my_hostname my_label
```
### 4.6 维护模式(Maintenance Mode)
进入维护模式会**停止该主机上的所有 Ceph 守护进程**:
```bash
ceph orch host maintenance enter <hostname> [--force] [--yes-i-really-mean-it]
ceph orch host maintenance exit <hostname> [--force] [--offline]
```
| 参数 | 适用于 | 作用 |
|---|---|---|
| `--force` | `enter` | 允许绕过 warning(但**不能**绕过 alert) |
| `--yes-i-really-mean-it` | `enter` | 绕过**所有**安全检查,强制进入维护模式 |
| `--force` + `--offline` | `exit` | 把「处于维护模式且离线」的主机标记为不再处于维护模式。若主机重新上线,其上的 Ceph 守护进程**仍保持停止状态**。该组合用于「主机永久离线、随后用 `ceph orch host rm` 移除」的场景 |
> ⚠️ 使用 `--yes-i-really-mean-it` 强制进入维护模式可能导致数据可用性丧失、MON 数量过少导致 quorum 崩溃、mgr module 命令(如 `ceph orch ...`)无响应等问题。仅在完全明确后果时使用。
另见 FQDN 相关说明(4.10)。
### 4.7 重新扫描设备(Rescanning Host Devices)
某些服务器或外部盘柜可能不会向内核注册设备的移除/插入事件,此时需要执行设备重扫(通常无中断):
```bash
ceph orch host rescan <hostname> [--with-summary]
```
`--with-summary` 会给出发现的 HBA 数量与扫描结果细分:
```text
Ok. 2 adapters detected: 2 rescanned, 0 skipped, 0 failed (0.32s)
```
### 4.8 批量创建主机
可以用 `ceph orch apply -i` 提交多文档 YAML 一次添加多台主机:
```yaml
service_type: host
hostname: node-00
addr: 192.168.0.10
labels:
- example1
- example2
---
service_type: host
hostname: node-01
addr: 192.168.0.11
labels:
- grafana
---
service_type: host
hostname: node-02
addr: 192.168.0.12
```
该 YAML 可与 service specifications 组合成「整集群 spec 文件」,一条命令部署整个集群;也可以在 bootstrap 阶段用 `cephadm bootstrap --apply-spec` 完成。**注意:集群 SSH key 必须事先已复制到这些主机。**
### 4.9 设置主机的初始 CRUSH 位置
主机可以带 `location` 标识,指示 cephadm 在指定层级创建新的 CRUSH host bucket;可以指定树的多个层级(例如同时确保 rack 也加入 default bucket):
```yaml
service_type: host
hostname: node-00
addr: 192.168.0.10
location:
root: default
rack: rack1
```
> 注意:`location` **只影响初始 CRUSH 位置**,后续对 `location` 的修改会被忽略;移除主机不会移除关联的 CRUSH bucket,除非给 `orch host rm` 传 `--rm-crush-entry`。
### 4.10 OS 调优 Profile(tuned-profile)
cephadm 可以管理对一组主机应用 `sysctl` 设置的操作系统调优 profile。
YAML spec 格式:
```yaml
profile_name: 23-mon-host-profile
placement:
hosts:
- mon-host-01
- mon-host-02
settings:
fs.file-max: 1000000
vm.swappiness: '13'
```
应用:
```bash
ceph orch tuned-profile apply -i <tuned-profile-file-name>
```
该 profile 会被写入 `placement` 指定主机上的 `/etc/sysctl.d/` 下的文件,然后执行 `sysctl --system`。
关键细节:
| 项 | 说明 |
|---|---|
| 落盘文件名 | `/etc/sysctl.d/<profile-name>-cephadm-tuned-profile.conf`,其中 `<profile-name>` 就是 spec 里的 `profile_name` |
| 命名建议 | 遵循 `sysctl.d` 的 `NN-xxxxx` 约定;因 sysctl 设置按文件名字典序应用,profile_name 的选择决定了它是在其他 conf 之前还是之后生效 |
| 作用范围 | **仅主机级**,与任何具体守护进程或容器无关 |
| 幂等性 | 传 `--no-overwrite` 时重复应用是幂等的,且不会覆盖同名已有 profile |
| 修改 placement | 需要用同名 profile 重新 apply;同名 profile 会覆盖旧的,**除非**传了 `--no-overwrite` |
管理命令:
```bash
# 查看当前所有受管 profile
ceph orch tuned-profile ls
# 以易复制/可重新 apply 的 YAML 形式查看
ceph orch tuned-profile ls --format yaml
# 移除 profile(会清理之前写入 /etc/sysctl.d 的文件)
ceph orch tuned-profile rm <profile-name>
# 在已有 profile 中新增或修改一项设置
ceph orch tuned-profile add-setting <profile-name> <setting-name> <value>
# 从已有 profile 中移除一项设置
ceph orch tuned-profile rm-setting <profile-name> <setting-name>
```
### 4.11 SSH 配置
cephadm 通过 SSH 连接远程主机,并用 key 进行认证。
#### 4.11.1 默认行为
集群 SSH key 存放在 monitor 中;bootstrap 时自动生成,无需额外配置。
```bash
# 生成新的 SSH key
ceph cephadm generate-key
# 获取公钥部分
ceph cephadm get-pub-key
# 删除当前存储的 SSH key
ceph cephadm clear-key
# 直接导入已有 key
ceph config-key set mgr/cephadm/ssh_identity_key -i <key>
ceph config-key set mgr/cephadm/ssh_identity_pub -i <pub>
# 导入后需重启 mgr 守护进程以重新加载配置
ceph mgr fail
```
#### 4.11.2 配置不同的 SSH 用户
cephadm 必须能以「有足够权限下载容器镜像、启动容器、免密执行命令」的用户登录所有集群节点。默认用户是 `root`;若不想用 root:
```bash
ceph cephadm set-user <user>
```
前置条件:集群 SSH key 已加入该用户的 `authorized_keys`,且非 root 用户具备 **passwordless sudo**。
#### 4.11.3 自定义 SSH 配置
cephadm 生成的 `ssh_config` 大致如下:
```text
Host *
User root
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
```
两种自定义方式:
```bash
# 方式一:导入自定义配置,存放在 monitor 中
ceph cephadm set-ssh-config -i <ssh_config_file>
# 恢复默认行为
ceph cephadm clear-ssh-config
# 方式二:指定 SSH 配置文件路径(官方不推荐)
ceph config set mgr mgr/cephadm/ssh_config_file <path>
```
> 源文明确**不推荐**方式二:该路径必须对**任何** mgr 守护进程可见,而 cephadm 以容器方式运行所有守护进程,因此文件要么被打进自定义容器镜像,要么手动分发到 mgr 数据目录(主机上 `/var/lib/ceph/<cluster-fsid>/mgr.<id>`,容器内可见为 `/var/lib/ceph/mgr/ceph-<id>`)。
#### 4.11.4 使用 CA 签名密钥
```bash
ceph config-key set mgr/cephadm/ssh_identity_key -i <private-key-file>
ceph config-key set mgr/cephadm/ssh_identity_cert -i <signed-cert-file>
```
### 4.12 FQDN 与裸主机名(Fully qualified domain names vs bare host names)
> ⚠️ cephadm **要求** `ceph orch host add` 给出的主机名**等于**远程主机上 `hostname` 命令的输出。
否则 cephadm 无法保证 `ceph * metadata` 返回的名字与它所知的主机匹配,可能产生 `CEPHADM_STRAY_HOST` warning。
两种**合法**的主机名设置方式:
| 方式 | `hostname` 输出 | 其他命令 |
|---|---|---|
| 1. 使用裸主机名(bare host name) | 裸主机名 | `hostname -f` 返回 FQDN |
| 2. 使用 FQDN 作为主机名 | FQDN | `hostname -s` 返回裸主机名 |
`man hostname` 推荐 `hostname` 返回**裸主机名**(FQDN 建议通过 `/etc/hosts`、DNS 或 NIS 让主机名成为全限定名的别名,例如 `/etc/hosts` 中的 `127.0.1.1 ursula.example.com ursula`)。因此 Ceph 的 `ceph * metadata` 返回裸主机名,cephadm 也就要求用裸主机名添加主机:`ceph orch host add <bare-name>`。
> 引自:[Host Management](https://docs.ceph.com/en/tentacle/cephadm/host-management/)
---
## 五、服务与守护进程管理
### 5.1 服务状态(Service Status)
```bash
# 列出编排器已知的所有服务
ceph orch ls [--service_type type] [--service_name name] [--export] [--format f] [--refresh]
# 查看某个服务的状态
ceph orch ls --service_type type --service_name <name> [--refresh]
# 导出服务规格(YAML),可直接用于 ceph orch apply -i
ceph orch ls --export
```
- `--host`:把输出限定在某台主机上的服务(源文在描述中提及该可选参数)。
- `--type`:限定服务类型(mon, osd, mgr, mds, rgw)。
- 导出的 YAML 可与 `ceph orch apply -i` 配合使用。
### 5.2 守护进程状态(Daemon Status)
守护进程(daemon)是一个正在运行、属于某个服务的 systemd unit。
```bash
ceph orch ps [--hostname host] [--daemon_type type] [--service_name name] [--daemon_id id] [--format f] [--refresh]
# 例:查某个 OSD(OSD 的 id 是数字 OSD ID)
ceph orch ps --daemon_type osd --daemon_id 0
```
对于 MDS 服务,id 是文件系统名。
> 注意:`ceph orch ps` 的输出**可能不反映守护进程的当前状态**——默认每 10 分钟更新一次。可通过 `mgr/cephadm/daemon_cache_timeout`(单位秒)缩短间隔,例如 `ceph config set mgr mgr/cephadm/daemon_cache_timeout 60` 缩短到 1 分钟。除使用 `--refresh` 外,信息每 `daemon_cache_timeout` 秒更新一次;`--refresh` 会触发一次刷新请求(大集群可能耗时)。输出中的 `REFRESHED` 值即表示信息的时效。
### 5.3 Service Specification(服务规格)
Service Specification 是用于描述服务部署的数据结构。除 `placement`、`networks` 等参数外,还可以通过 `config` 段设置服务配置参数的初始值;对每一组 param/value,cephadm 会调用:
```bash
ceph config set <service-name> <param> <value>
```
若 spec 中出现无效配置参数,cephadm 会报 `CEPHADM_INVALID_CONFIG_OPTION`;若应用配置选项时出错,报 `CEPHADM_FAILED_SET_OPTION`。
#### 5.3.1 示例与字段
```yaml
service_type: rgw
service_id: realm.zone
placement:
hosts:
- host1
- host2
- host3
config:
param_1: val_1
...
param_N: val_N
unmanaged: false
networks:
- 192.169.142.0/24
spec:
# Additional service specific attributes.
```
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `service_type` | string | 无(必填) | 服务类型,如 `mon`、`mgr`、`osd`、`mds`、`rgw`、`nfs`、`iscsi`、`smb`、`snmp-gateway`、`container`、`ingress`、`prometheus`、`grafana`、`alertmanager`、`node-exporter`、`mgmt-gateway`、`oauth2-proxy`、`host` 等 |
| `service_id` | string | 文档未明确(`mon`、`mgr` 与监控类服务**不需要** `service_id`) | 服务 ID,与 `service_type` 共同构成服务名 |
| `service_name` | string | 文档未明确 | 服务名(例如 `rgw.<realm>.<zone>`),部分服务(如 mds)可直接用 `service_name` |
| `placement` | mapping | 文档未明确 | 放置规格,见 5.4 |
| `config` | mapping | 空 | 初始化的 Ceph 配置项,每项由 cephadm 转成 `ceph config set` |
| `unmanaged` | bool | `false` | 为 `true` 时关闭该服务的守护进程自动部署/移除,见 5.6 |
| `networks` | list of CIDR | 文档未明确 | 服务绑定到的网络列表(如 `- 192.169.142.0/24`) |
| `spec` | mapping | 空 | 服务特有的附加属性(各服务章节详述) |
| `extra_container_args` | list | 空 | 传给容器运行时的额外参数,见 5.7 |
| `extra_entrypoint_args` | list | 空 | 追加给容器内 entrypoint 进程的参数,见 5.8 |
| `custom_configs` | list | 空 | 自定义配置文件挂载,见 5.9 |
> 💡 补充:`ServiceSpec` 的完整字段由源码 docstring 通过 Sphinx `autoclass` 生成(`.. autoclass:: ServiceSpec :members:`),源文 rst 中并未逐项列出字段表,因此上表仅覆盖源文示例中出现并在正文中解释过的字段;其余字段(**文档未明确**)请以 `ceph orch ls --export` 的实际输出与源码为准。
#### 5.3.2 一次提交多个服务规格(multi-document YAML)
```bash
cat <<EOF | ceph orch apply -i -
service_type: mon
placement:
host_pattern: "mon*"
---
service_type: mgr
placement:
host_pattern: "mgr*"
---
service_type: osd
service_id: default_drive_group
placement:
host_pattern: "osd*"
data_devices:
all: true
EOF
```
#### 5.3.3 获取与更新运行中的 ServiceSpec
```bash
# 导出
ceph orch ls --service-name rgw.<realm>.<zone> --export > rgw.<realm>.<zone>.yaml
ceph orch ls --service-type mgr --export > mgr.yaml
ceph orch ls --export > cluster.yaml
# 更新流程
ceph orch ls --service_name=<service-name> --export > myservice.yaml
vi myservice.yaml
ceph orch apply -i myservice.yaml [--dry-run]
```
### 5.4 Daemon Placement(放置规格)
放置规格可以命令行传入,也可以写在 YAML 里。
> 注意:cephadm **不会**在带 `_no_schedule` label 的主机上部署守护进程。
> ⚠️ **apply 命令容易踩坑**:每个 `ceph orch apply <service-name>` 都会**取代**前一次。例如依次执行 `ceph orch apply mon host1`、`host2`、`host3`,最终只有 host3 上有 mon。正确做法是 `ceph orch apply mon "host1,host2,host3"`,或用 YAML 文件 `ceph orch apply -i file.yaml`。
#### 5.4.1 放置方式汇总表
| 方式 | 命令行示例 | YAML 写法 | 说明 |
|---|---|---|---|
| 显式主机 | `ceph orch apply prometheus --placement="host1 host2 host3"` | `placement: {hosts: [host1, host2, host3]}` | 直接指定主机 |
| 按 label | `ceph orch apply prometheus --placement="label:mylabel"` | `placement: {label: "mylabel"}` | 只在带该 label 的主机上部署 |
| 按 host pattern(fnmatch) | `ceph orch apply prometheus --placement='myhost[1-3]'` | `placement: {host_pattern: "myhost[1-3]"}` | 默认使用 fnmatch(UNIX shell 风格通配) |
| 所有主机 | `ceph orch apply node-exporter --placement='*'` | `placement: {host_pattern: "*"}` | `*` 表示所有主机 |
| 正则 pattern(命令行) | `ceph orch apply prometheus --placement='regex:FOO[0-9]\|BAR[0-9]'` | — | 命令行需在 pattern 前加 `regex: ` 前缀 |
| 正则 pattern(YAML) | — | 见下 | 需要 `pattern` + `pattern_type: regex` |
| 指定数量 count | `ceph orch apply prometheus --placement=3` | `placement: {count: 3}` | 只创建指定数量的守护进程 |
| count + 主机子集 | `ceph orch apply prometheus --placement="2 host1 host2 host3"` | `placement: {count: 2, hosts: [host1, host2, host3]}` | 在指定主机中挑 count 个 |
| count 大于主机数 | `ceph orch apply prometheus --placement="3 host1 host2"` | — | 源文明确:结果只会得到 2 个 Prometheus 守护进程 |
| 每主机多个(co-location) | — | `placement: {label: rgw, count_per_host: 2}` | 同一主机部署多个守护进程(Pacific 引入) |
YAML 正则写法:
```yaml
service_type: prometheus
placement:
host_pattern:
pattern: 'FOO[0-9]|BAR[0-9]'
pattern_type: regex
```
MON 等服务的增强网络写法:
```bash
ceph orch daemon add mon --placement="myhost:[v2:1.2.3.4:3300,v1:1.2.3.4:6789]=name"
```
其中 `[v2:1.2.3.4:3300,v1:1.2.3.4:6789]` 是 monitor 的网络地址,`=name` 指定新 monitor 的名字。
#### 5.4.2 命令行 label 方式完整示例
```bash
ceph orch host label add host1 mylabel
ceph orch host label add host2 mylabel
ceph orch host label add host3 mylabel
ceph orch host ls
```
```text
HOST ADDR LABELS STATUS
host1 mylabel
host2 mylabel
host3 mylabel
host4
host5
```
```bash
ceph orch apply prometheus --placement="label:mylabel"
```
### 5.5 Extra Container Arguments(容器运行时额外参数)
> ⚠️ 只能用你所使用容器引擎 `run` 命令支持的参数;传了不支持的参数或非法值会导致守护进程启动失败。
> 注意区分:这里是给**容器运行时**的参数;给容器内进程的参数见 5.6(`extra_entrypoint_args`)。
```yaml
service_type: mon
service_name: mon
placement:
hosts:
- host1
- host2
- host3
extra_container_args:
- "--cpus=2"
```
两种表达形式:
| 形式 | 规则 |
|---|---|
| 字符串 | 若字符串含空格,cephadm 会**自动拆分**成多个参数,例如 `--cpus 2` → `["--cpus", "2"]` |
| 对象(mapping) | 必填键 `argument`(必须是单个字符串)+ 可选键 `split`(布尔)。`split: true` 按空格拆分;`split: false` 保留空格;**不提供 `split` 时默认为 false** |
```yaml
service_type: mon
service_name: mon
placement:
hosts:
- tiebreaker
extra_container_args:
# No spaces, always treated as a single argument
- argument: "--timout=3000"
# Splitting explicitly disabled, one single argument
- argument: "--annotation=com.example.name=my favorite mon"
split: false
# Splitting explicitly enabled, will become two arguments
- argument: "--cpuset-cpus 1-3,7-11"
split: true
# Splitting implicitly disabled, one single argument
- argument: "--annotation=com.example.note=a simple example"
```
挂载额外文件是常见用法(为兼容不支持参数中带空格的旧版本 Ceph,推荐下列写法):
```yaml
extra_container_args:
- "-v"
- "/absolute/file/path/on/host:/absolute/file/path/in/container"
```
例如:
```yaml
extra_container_args:
- "-v"
- "/opt/ceph_cert/host.cert:/etc/grafana/certs/cert_file:ro"
```
### 5.6 Extra Entrypoint Arguments(容器内进程额外参数)
```yaml
service_type: node-exporter
service_name: node-exporter
placement:
host_pattern: '*'
extra_entrypoint_args:
- "--collector.textfile.directory=/var/lib/node_exporter/textfile_collector2"
```
表达形式与 `extra_container_args` 完全一致(字符串自动拆分;对象形式 `argument` + `split`,`split` 缺省为 false):
```yaml
service_type: mon
service_name: mon
placement:
hosts:
- host1
- host2
- host3
extra_entrypoint_args:
- "--debug_ms 2"
```
```yaml
# An theoretical data migration service
service_type: pretend
service_name: imagine1
placement:
hosts:
- host1
extra_entrypoint_args:
# No spaces, always treated as a single argument
- argument: "--timout=30m"
# Splitting explicitly disabled, one single argument
- argument: "--import=/mnt/usb/My Documents"
split: false
# Splitting explicitly enabled, will become two arguments
- argument: "--tag documents"
split: true
# Splitting implicitly disabled, one single argument
- argument: "--title=Imported Documents"
```
### 5.7 Custom Config Files(自定义配置文件)
用户可以提供配置文件内容 + 文件在守护进程容器内的挂载位置;应用带 `custom_configs` 的 YAML spec 并重新部署对应守护进程后,这些文件会被挂载到指定位置。
```yaml
service_type: grafana
service_name: grafana
custom_configs:
- mount_path: /etc/example.conf
content: |
setting1 = value1
setting2 = value2
- mount_path: /usr/share/grafana/example.cert
content: |
-----BEGIN PRIVATE KEY-----
V2VyIGRhcyBsaWVzdCBpc3QgZG9vZi4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt
ZXQsIGNvbnNldGV0dXIgc2FkaXBzY2luZyBlbGl0ciwgc2VkIGRpYW0gbm9udW15
IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu
YSBhbGlxdXlhbSBlcmF0LCBzZWQgZGlhbSB2b2x1cHR1YS4gQXQgdmVybyBlb3Mg
ZXQgYWNjdXNhbSBldCBqdXN0byBkdW8=
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
V2VyIGRhcyBsaWVzdCBpc3QgZG9vZi4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt
ZXQsIGNvbnNldGV0dXIgc2FkaXBzY2luZyBlbGl0ciwgc2VkIGRpYW0gbm9udW15
IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu
YSBhbGlxdXlhbSBlcmF0LCBzZWQgZGlhbSB2b2x1cHR1YS4gQXQgdmVybyBlb3Mg
ZXQgYWNjdXNhbSBldCBqdXN0byBkdW8=
-----END CERTIFICATE-----
```
字段:
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `mount_path` | string | 无(必填) | 文件在守护进程容器内的挂载路径(绝对路径) |
| `content` | string | 无(必填) | 文件内容,建议用 `|` 块保留换行 |
让配置真正生效需要重新部署守护进程:
```bash
ceph orch redeploy <service-name>
# 例:
ceph orch redeploy grafana
```
### 5.8 移除服务
```bash
ceph orch rm <service-name>
# 例:
ceph orch rm rgw.myrgw
```
该命令会移除服务及其所有守护进程。
### 5.9 关闭守护进程自动部署(unmanaged)
#### 5.9.1 通过 spec
```yaml
service_type: mgr
unmanaged: true
placement:
label: mgr
```
```bash
ceph orch apply -i mgr.yaml
```
#### 5.9.2 通过 CLI
```bash
ceph orch set-unmanaged mon # 等价于 unmanaged: true
ceph orch set-managed mon # 等价于 unmanaged: false
```
参数为 `ceph orch ls` 中显示的服务名。
要点:
- 应用该变更后,cephadm **不再部署任何新守护进程**(即使 placement 匹配到更多主机)。
- 特殊:`osd` 服务(用于跟踪不绑定特定 spec 的 OSD)**永远被标记为 unmanaged**;对它执行 `set-unmanaged` / `set-managed` 会返回:`No service of name osd found. Check "ceph orch ls" for all known services`。
- 若要彻底移除服务,用 `ceph orch rm`(不是 unmanaged)。
#### 5.9.3 手动部署 / 移除单个守护进程
> 该 workflow 适用场景非常有限,仅应在罕见情况下使用。
步骤:
1. 取出服务现有 spec,加上 `unmanaged: true`,apply 回去;
2. 手动部署守护进程:
```bash
ceph orch daemon add <daemon-type> --placement=<placement spec>
# 例:
ceph orch daemon add mgr --placement=my_host
```
移除:
```bash
ceph orch daemon rm <daemon name>... [--force]
# 例:
ceph orch daemon rm mgr.my_host.xyzxyz
```
注意:
- 对受管服务(`unmanaged=False`),执行 `rm` 后 cephadm 会在几秒后**自动重新部署**一个新守护进程。
- 从 spec 中移除 `unmanaged: true` 会重新启用该服务的协调循环,可能根据 placement 导致该守护进程被移除。
> 引自:[Service Management](https://docs.ceph.com/en/tentacle/cephadm/services/index/)
---
## 六、OSD 部署(OSD Service)
### 6.1 列出设备
`ceph-volume` 会周期性扫描集群中每台主机,判断哪些设备存在且响应正常,并判定其是否有资格作为 block、DB 或 WAL 角色的新 OSD。
```bash
ceph orch device ls [--hostname=...] [--wide] [--refresh]
```
输出示例:
```text
Hostname Path Type Serial Size Health Ident Fault Available
srv-01 /dev/sdb hdd 15P0A0YFFRD6 300G Unknown N/A N/A No
srv-01 /dev/sdc hdd 15R0A08WFRD6 300G Unknown N/A N/A No
srv-01 /dev/sdd hdd 15R0A07DFRD6 300G Unknown N/A N/A No
srv-01 /dev/sde hdd 15P0A0QDFRD6 300G Unknown N/A N/A No
srv-02 /dev/sdb hdd 15R0A033FRD6 300G Unknown N/A N/A No
srv-02 /dev/sdc hdd 15R0A05XFRD6 300G Unknown N/A N/A No
srv-02 /dev/sde hdd 15R0A0ANFRD6 300G Unknown N/A N/A No
srv-02 /dev/sdf hdd 15R0A06EFRD6 300G Unknown N/A N/A No
srv-03 /dev/sdb hdd 15R0A0OGFRD6 300G Unknown N/A N/A No
srv-03 /dev/sdc hdd 15R0A0P7FRD6 300G Unknown N/A N/A No
srv-03 /dev/sdd hdd 15R0A0O7FRD6 300G Unknown N/A N/A No
```
> 注意:`ceph orch device ls` 报告的列可能随 release 变化。
#### 6.1.1 增强设备扫描(libstoragemgmt)
输出中的 `Health`、`Ident`、`Fault` 三列来自与 `libstoragemgmt` 的集成。**默认关闭**(因为该库可能与硬件不是 100% 兼容)。如需这些字段:
```bash
ceph config set mgr mgr/cephadm/device_enhanced_scan true
```
启用后输出示例:
```text
Hostname Path Type Serial Size Health Ident Fault Available
srv-01 /dev/sdb hdd 15P0A0YFFRD6 300G Good Off Off No
srv-01 /dev/sdc hdd 15R0A08WFRD6 300G Good Off Off No
```
> ⚠️ 警告:`libstoragemgmt` 虽发出标准 SCSI(SES) inquiry 调用,但无法保证硬件与固件正确实现这些标准,在部分老旧硬件上可能导致异常行为甚至 bus reset。**启用前请先测试兼容性**,最简单的方式:
>
> ```bash
> cephadm shell lsmcli ldl
> ```
>
> 若硬件受支持,会看到类似:
>
> ```text
> Path | SCSI VPD 0x83 | Link Type | Serial Number | Health Status
> ----------------------------------------------------------------------------
> /dev/sda | 50000396082ba631 | SAS | 15P0A0R0FRD6 | Good
> /dev/sdb | 50000396082bbbf9 | SAS | 15P0A0YFFRD6 | Good
> ```
> 限制:当前 `libstoragemgmt`(1.8.8)仅支持 SCSI、SAS、SATA 本地盘;**不支持** NVMe(PCIe)设备、SAN LUN、以及复杂/ exotic metadevices。
#### 6.1.2 可用(available)设备的判定条件
一个存储设备被认为 *available*,必须**同时**满足:
| 条件 |
|---|
| 设备没有分区(no partitions) |
| 设备没有任何 LVM state |
| 设备未被挂载(not mounted) |
| 设备不含文件系统 |
| 设备不含 Ceph BlueStore OSD |
| 设备容量大于 5 GB |
不满足以上条件的设备,Ceph **不会**在其上供给 OSD。
#### 6.1.3 `--wide` 选项
`--wide` 显示设备细节,包括设备为何不能作为 OSD 使用的原因:
```text
HOST PATH TYPE DEVICE ID SIZE AVAILABLE REFRESHED REJECT REASONS
davidsthubbins /dev/sdc hdd SEAGATE_ST20000NM002D_ZVTBJNGC17010W339UW25 18.1T No 22m ago Has a FileSystem, Insufficient space (<10 extents) on vgs, LVM detected
nigeltufnel /dev/sdd hdd SEAGATE_ST20000NM002D_ZVTBJNGC17010C3442787 18.1T No 22m ago Has a FileSystem, Insufficient space (<10 extents) on vgs, LVM detected
```
#### 6.1.4 获取块设备的精确容量
编排器按 size 过滤时使用的值可通过下列命令获得:
```bash
cephadm shell ceph-volume inventory </dev/sda> --format json | jq .sys_api.human_readable_size
```
以 TB 报告的大小乘以 1024 即为 GB 精确值。示例:
```bash
cephadm shell ceph-volume inventory /dev/sdc --format json | jq .sys_api.human_readable_size
```
```text
"3.64 TB"
```
即精确容量为 3.64 TB = 3727.36 GB。
### 6.2 创建 OSD 的多种方式
| 方式 | 命令 | 说明 |
|---|---|---|
| 消费所有可用且未使用的设备 | `ceph orch apply osd --all-available-devices` | 声明式,持久生效(见 6.3) |
| 从指定主机的指定设备创建 | `ceph orch daemon add osd <host>:<device-path>` | 例:`ceph orch daemon add osd host1:/dev/sdb` |
| 高级:指定 data/db 设备与每设备 OSD 数 | `ceph orch daemon add osd host1:data_devices=/dev/sda,/dev/sdb,db_devices=/dev/sdc,osds_per_device=2` | CLI 内联形式 |
| 在指定 LVM 逻辑卷上创建 | `ceph orch daemon add osd <host>:<lvm-path>` | 例:`ceph orch daemon add osd host1:/dev/vg_osd/lvm_osd1701` |
| 使用 drive group spec | `ceph orch apply -i spec.yml` | 按设备属性分类,见 6.6 起 |
> ⚠️ 用 cephadm 部署新 OSD 时,确保目标主机上**没有安装** `ceph-osd` 包;若已安装,可能在 OSD 的管理与控制上产生冲突,导致错误或意外行为。
> 注意:用 `ceph orch daemon add osd` 创建的 OSD 会被归入 `osd.default`,作为有合法 spec 的受管(managed)OSD。要把已有 OSD 挂到另一个受管服务下,用:
>
> ```bash
> ceph orch osd set-spec-affinity <service_name> <osd_id(s)>
> # 例:
> ceph orch osd set-spec-affinity osd.default_drive_group 0 1
> ```
### 6.3 声明式状态(Declarative State)与 unmanaged
`ceph orch apply` 的效果是**持久的**:
```bash
ceph orch apply osd --all-available-devices
```
执行后:
- 之后加入系统的新硬盘会被**自动**用于创建 OSD;
- 移除 OSD 并清理 LVM physical volume 后,也会**自动**发现并创建新 OSD。
若不想这样(禁止在可用设备上自动创建 OSD):
```bash
ceph orch apply osd --all-available-devices --unmanaged=true
```
三个必须记住的事实(源文原文要点):
1. `ceph orch apply` 的默认行为会让 cephadm **持续协调(constantly reconcile)**,即一检测到新盘就创建 OSD。
2. 设置 `unmanaged: True` 会**禁用** OSD 创建;此时即使 apply 一个新的 OSD 服务也不会发生任何事。
3. `ceph orch daemon add` 会创建 OSD,但**不会**添加 OSD 服务。
### 6.4 Dry Run
`--dry-run` 让编排器只预览将要发生什么,不真正创建 OSD:
```bash
ceph orch apply osd --all-available-devices --dry-run
```
```text
NAME HOST DATA DB WAL
all-available-devices node1 /dev/vdb - -
all-available-devices node2 /dev/vdc - -
all-available-devices node3 /dev/vdd - -
```
对 spec 文件同样可用:
```bash
ceph orch apply -i <osd_spec_file> --dry-run
```
```text
NAME HOST DATA DB WAL
<name_of_osd_spec> node1 /dev/vdb - -
```
### 6.5 移除与替换 OSD
#### 6.5.1 移除 OSD
移除一个 OSD 涉及两步:(1) 把该 OSD 上的所有 PG 疏散;(2) 把已无 PG 的 OSD 从集群移除。一条命令完成两步:
```bash
ceph orch osd rm <osd_id(s)> [--replace] [--force] [--zap]
# 例:
ceph orch osd rm 0
ceph orch osd rm 1138 --zap
```
```text
Scheduled OSD(s) for removal
```
| 参数 | 作用 |
|---|---|
| `--replace` | 走替换流程而非永久移除(见 6.5.3) |
| `--force` | 源文未展开说明具体语义(用于强制执行) |
| `--zap` | 让编排器清掉 OSD 盘上的所有 LVM 与分区信息,使之成为可重新部署或另作他用的空白盘;不安全销毁(not safe to destroy)的 OSD 会被拒绝 |
> 注意:移除 OSD 后,如果这些盘重新变为 available,且匹配到已存在的 drivegroup spec,cephadm 可能**自动**在上面再部署 OSD。若不希望如此,**最好在移除前先修改 drivegroup spec**:要么设 `unmanaged: true` 停止拾取新盘,要么改到不再匹配待删 OSD 所用磁盘,然后重新 apply。
#### 6.5.2 监控 OSD 移除状态 / 停止移除
```bash
ceph orch osd rm status
```
```text
OSD_ID HOST STATE PG_COUNT REPLACE FORCE STARTED_AT
2 cephadm-dev done, waiting for purge 0 True False 2020-07-17 13:01:43.147684
3 cephadm-dev draining 17 False True 2020-07-17 13:01:45.162158
4 cephadm-dev started 42 False True 2020-07-17 13:01:45.162158
```
当 OSD 上没有 PG 剩余时,它会被 decommissioned 并从集群移除。
停止排队中的 OSD 移除:
```bash
ceph orch osd rm stop <osd_id(s)>
# 例:
ceph orch osd rm stop 4
```
```text
Stopped OSD(s) removal
```
该操作会重置 OSD 状态并把它从移除队列中移除。
#### 6.5.3 替换 OSD(保留 OSD ID)
```bash
ceph orch osd rm <osd_id(s)> --replace [--force]
# 例:
ceph orch osd rm 4 --replace
```
```text
Scheduled OSD(s) for replacement
```
流程与移除 OSD 相同,唯一区别:OSD **不会**从 CRUSH 层级中被永久移除,而是被打上 `destroyed` 标志。
- `destroyed` 标志用于决定哪些 OSD ID 会在下一次 OSD 部署中被复用。
- 如果你使用 OSDSpecs 部署,新加的盘会被分配其替换对象(replaced counterpart)的 OSD ID(前提是新盘仍匹配该 OSDSpecs)。
- **新的 OSD 必须创建在被移除 OSD 所在的同一台主机上。**
- 建议先用 `--dry-run` 确认 `ceph orch apply osd` 的行为符合预期。
> Tip:OSDSpec 的名字可以用 `ceph orch ls` 查到。
#### 6.5.4 擦除设备(Zapping Devices)
```bash
ceph orch device zap <hostname> <path>
# 例:
ceph orch device zap my_hostname /dev/sdx
```
`zap` 会在远程主机上调用 `ceph-volume zap`。
> 注意:若未设置 `unmanaged`,cephadm 会自动部署匹配 OSDSpec 的盘。例如创建 OSD 时用了 `all-available-devices`,那么 zap 一个设备后,cephadm 编排器会**自动**在该设备上创建新 OSD。禁用方法见 6.3。
### 6.6 Advanced OSD Service Specifications(Drive Group Spec)
`service_type: osd` 的 ServiceSpec 让用户可以用**磁盘属性**描述集群布局,无需知道具体的设备名与路径。它支持 `.yaml` 或 `.json` 文件。
> 建议:高级 OSD spec 都应带 `service_id`。用 `ceph orch daemon add` 或 `ceph orch apply osd --all-available-devices` 创建的 OSD 会放进普通的 `osd` 服务里;若你的 OSD spec 不带 `service_id`,集群会把你的 OSD 与这些 OSD 混在一起,可能覆盖 cephadm 为跟踪它们而创建的 service specs。**较新版本的 cephadm 会拒绝(block)不带 `service_id` 的 OSD spec。**
最基础的示例(`osd_spec.yml`):
```yaml
service_type: osd
service_id: default_drive_group # custom name of the osd spec
placement:
host_pattern: '*' # which hosts to target
spec:
data_devices: # the type of devices you are applying specs to
all: true # a filter, check below for a full list
```
含义:在匹配 glob `'*'` 的所有主机上,把所有 available 设备(由 `ceph-volume` 判定 available)变成 OSD。
应用:
```bash
ceph orch apply -i /path/to/osd_spec.yml
ceph orch apply -i /path/to/osd_spec.yml --dry-run
```
### 6.7 过滤器(Filters)逐项表
> 默认过滤器之间使用 **AND** 运算:一块盘必须匹配所有过滤条件才会被选中。可以通过在 OSD spec 中设置 `filter_logic: OR` 改变该行为。
过滤所用属性由 `ceph-volume` 的 drive inventory 采集,可用下列命令查看:
```bash
ceph-volume inventory </path/to/drive>
```
| 过滤器字段 | 类型 | 默认值 | 含义 | 示例 |
|---|---|---|---|---|
| `model` | string | 文档未明确 | 按型号(SKU)匹配;支持部分匹配(源文注释:`HDD-123` 也能匹配 `HDD-123-foo`) | `model: drive_model_name` |
| `vendor` | string | 文档未明确 | 按厂商 / 制造商匹配 | `vendor: drive_vendor_name` |
| `size` | string(size_spec) | 文档未明确 | 按容量匹配。支持 4 种形式:`LOW:HIGH`、`:HIGH`、`LOW:`、`EXACT`。单位 M/G/T,也接受带 B 后缀的 `MB`/`GB`/`TB` | `size: '10T'` / `'10T:40T'` / `':1701G'` / `'666G:'` |
| `rotational` | int(0 或 1) | 文档未明确 | 依据内核报告的 rotational 属性匹配:`1` 匹配所有机械盘;`0` 匹配所有非机械盘(SATA、NVMe SSD、SAN LUN 等) | `rotational: 1` |
| `all` | bool | 文档未明确 | 匹配所有 available 的盘(无分区、无 GPT label 等)。**只能用于 `data_devices`** | `all: true` |
| `limit` | int | 文档未明确 | 当过滤条件匹配到很多盘时,限制最多使用多少块。仅适用于特定场景(例如部分盘要用于非 Ceph 用途,或打算实施多种 OSD 策略) | `limit: 2` |
| `paths` | list(字符串或对象) | 文档未明确 | 直接指定设备路径(要求所有匹配主机上的设备呈现一致)。对象形式可按路径指定 `crush_device_class` | 见 6.7.2 |
| `filter_logic` | string(`OR`) | `AND`(默认) | 改变同一层内多个过滤条件的组合逻辑 | `filter_logic: OR` |
#### 6.7.1 `size` 规格说明
| 形式 | 含义 | 示例 |
|---|---|---|
| `LOW:HIGH` | 容量区间 | `size: '10T:40T'` |
| `:HIGH` | 小于等于上限 | `size: ':1701G'`(≤ 1701 GB) |
| `LOW:` | 大于等于下限 | `size: '666G:'`(≥ 666 GB) |
| `EXACT` | 精确容量 | `size: '10T'` |
- 支持单位:Megabyte(M)、Gigabyte(G)、Terabyte(T);带 `B` 后缀也可:`MB`、`GB`、`TB`。
- 源文建议:由于硬盘容量通常不是单位的整数倍,**最佳实践是用区间匹配**(同时也能兼容未来同级别但不同型号、容量略有不同的盘)。
#### 6.7.2 `rotational` 的特殊说明
某些 exotic 或分层设备(网络 SAN LUN、`dCache`、`Bcache`、`OpenCAS` 呈现的复合设备)的 rotational 属性可能与预期不符。可通过 `udev` 规则覆盖默认行为,示例(**不适用于所有场景,需自行判断**):
```text
ACTION=="add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}="0"
ACTION=="add|change", KERNEL=="dm*", ATTR{queue/rotational}="0"
ACTION=="add|change", KERNEL=="nbd*", ATTR{queue/rotational}="0"
```
### 6.8 OSD spec 附加选项(Additional Options)
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `data_devices` | mapping(过滤器) | 无 | 作为 OSD 数据盘的设备集合 |
| `db_devices` | mapping(过滤器) | 文档未明确 | 作为 DB(WAL+DB offload)设备集合 |
| `wal_devices` | mapping(过滤器) | 文档未明确 | 作为独立 WAL 设备集合(默认 WAL 与 DB 同盘共存) |
| `db_slots` | int | 文档未明确 | 把 DB 设备切成这么多份,每份供对应数量的 data OSD 使用(源文示例:5 → 一块 DB 设备服务 5 个 HDD OSD) |
| `wal_slots` | int | 文档未明确 | 与 `db_slots` 类似,用于 WAL 分片。**本册源文的示例中未出现该字段,其存在性与语义文档未明确** |
| `encrypted` | bool | `false`(源文只在示例中显式写 `encrypted: true`) | 部署加密 OSD |
| `tpm2` | bool | 文档未明确 | **自 Ceph Squid 起**支持对 LUKS2 设备做 TPM2 token enrollment;需与 `encrypted: true` 同时使用 |
| `crush_device_class` | string | 文档未明确 | 应用到由该 spec(`paths` 过滤器)创建的 OSD 上的 CRUSH device class;也可在 `paths` 的每一条路径上单独指定 |
| `osds_per_device` | int | 文档未明确 | 每块设备上的 OSD 数量;源文中以 CLI 形式出现:`osds_per_device=2` |
| `filter_logic` | string | `AND` | 见 6.7 |
> 💡 补充:`DriveGroupSpec` 的完整字段同样由 Sphinx `autoclass`(`.. autoclass:: DriveGroupSpec :members:`)从源码 docstring 生成,源文 rst 未给出字段清单。上表仅覆盖源文示例中出现、且正文解释过的字段;其余字段**文档未明确**,请以 `ceph orch ls --export` 与源码为准。
加密示例:
```yaml
service_type: osd
service_id: example_osd_spec
placement:
host_pattern: '*'
spec:
data_devices:
all: true
encrypted: true
```
> 注意:若 Linux MD mirroring 被用于 boot、`/var/log` 或其他卷,上述 spec **可能**会抢走替换盘或新增盘(在你把它们用于非 OSD 用途之前)。可以设置 `unmanaged` 暂停自动部署,直到你准备好。
TPM2 示例(Ceph Squid 起):
```yaml
service_type: osd
service_id: example_osd_spec_with_tpm2
placement:
host_pattern: '*'
spec:
data_devices:
all: true
encrypted: true
tpm2: true
```
### 6.9 OSD spec 典型范例
#### 6.9.1 简单场景(所有节点磁盘一致)
硬件:10 块 HDD(VendorA / HDD-123-foo / 4TB)+ 2 块 SAS/SATA SSD(VendorB / MC-55-44-ZX / 512GB)。
按 model 描述:
```yaml
service_type: osd
service_id: osd_spec_default
placement:
host_pattern: '*'
spec:
data_devices:
model: HDD-123-foo # Note, HDD-123 would also be valid
db_devices:
model: MC-55-44-XZ # Same here, MC-55-44 is valid
```
更推荐按属性过滤(型号会随换盘/加盘变化):
```yaml
service_type: osd
service_id: osd_spec_default
placement:
host_pattern: '*'
spec:
data_devices:
rotational: 1 # The kernel flags as HDD
db_devices:
rotational: 0 # The kernel flags as SSD (SAS/SATA/NVMe)
```
按容量过滤(> 2TB 做数据盘,< 2TB 做 WAL/DB):
```yaml
service_type: osd
service_id: osd_spec_default
placement:
host_pattern: '*'
spec:
data_devices:
size: '2TB:' # Drives larger than 2 TB
db_devices:
size: ':2TB' # Drives smaller than 2TB
```
> 源文注:以上三种 spec 都同样有效,用哪个取决于个人偏好以及你预期节点布局变化的程度。
#### 6.9.2 单主机上多套 OSD spec(混合介质)
硬件:10 HDD(VendorA/HDD-123-foo/4TB)、12 SAS/SATA SSD(VendorB/MC-55-44-ZX/512GB)、2 NVMe SSD(VendorC/NVME-QQQQ-987/256GB)。
目标:10 个 HDD OSD 用 2 块 SATA/SAS SSD 做 WAL+DB offload;10 个 SATA/SAS SSD OSD 共享 2 块 NVMe SSD 做 WAL+DB offload。
```yaml
service_type: osd
service_id: osd_spec_hdd
placement:
host_pattern: '*'
spec:
data_devices: # Select all drives the kernel identifies as HDDs
rotational: 1 # for OSD data
db_devices:
model: MC-55-44-XZ # Select only this model for WAL+DB offload
limit: 2 # Select at most two for this purpose
db_slots: 5 # Chop the DB device into this many slices and
# use one for each of this many HDD OSDs
---
service_type: osd
service_id: osd_spec_ssd # Unique so it doesn't overwrite the above
placement:
host_pattern: '*'
spec: # This scenario is uncommon
data_devices:
model: MC-55-44-XZ # Select drives of this model for OSD data
db_devices: # Select drives of this brand for WAL+DB. Since the
vendor: VendorC # data devices are SAS/SATA SSDs this would make sense for NVMe SSDs
db_slots: 2 # Back two slower SAS/SATA SSD data devices with each NVMe slice
```
#### 6.9.3 不同主机不同磁盘布局(多个 spec 按 label 区分)
```yaml
service_type: osd
service_id: disk_layout_a
placement:
label: disk_layout_a
spec:
data_devices:
rotational: 1 # All drives identified as HDDs
db_devices:
rotational: 0 # All drives identified as SSDs
---
service_type: osd
service_id: disk_layout_b
placement:
label: disk_layout_b
spec:
data_devices:
model: MC-55-44-XZ # Only this model
db_devices:
model: SSD-123-foo # Only this model
```
要点:
- `service_id` 必须唯一;若用已存在的 `service_id` apply 新 spec,旧 spec 会被取代,cephadm 会基于新 spec 在未使用的盘上创建新 OSD,**已有 OSD 守护进程不受影响**。
- 假设每台主机磁盘布局不同,则每个 OSD spec 都应有唯一的 `service_id`。
#### 6.9.4 专用 WAL + DB(WAL 与 DB 分离)
默认 WAL 与 DB 同盘共存;也可以把 WAL 部署到独立设备:
```yaml
service_type: osd
service_id: osd_spec_default
placement:
host_pattern: '*'
spec:
data_devices:
model: MC-55-44-XZ
db_devices:
model: SSD-123-foo
wal_devices:
model: NVME-QQQQ-987
```
也可以直接指定路径(要求所有匹配主机设备呈现一致):
```yaml
service_type: osd
service_id: osd_using_paths
placement:
hosts:
- node01
- node02
spec:
data_devices:
paths:
- /dev/sdb
db_devices:
paths:
- /dev/sdc
wal_devices:
paths:
- /dev/sdd
```
> 源文提示:多数情况下用 `size` 或 `vendor` 等过滤器更好,这样当 Linux 或 HBA 在不同启动间枚举设备顺序变化、或增删硬盘时,OSD 服务能自适应。
#### 6.9.5 crush_device_class(全局与 per-path)
对整个 spec 生效:
```yaml
service_type: osd
service_id: osd_using_paths
placement:
hosts:
- node01
- node02
crush_device_class: ssd
spec:
data_devices:
paths:
- /dev/sdb
- /dev/sdc
db_devices:
paths:
- /dev/sdd
wal_devices:
paths:
- /dev/sde
```
按路径粒度指定(覆盖外部值):
```yaml
service_type: osd
service_id: osd_using_paths
placement:
hosts:
- node01
- node02
crush_device_class: ssd
spec:
data_devices:
paths:
- path: /dev/sdb
crush_device_class: ssd
- path: /dev/sdc
crush_device_class: nvme
db_devices:
paths:
- /dev/sdd
wal_devices:
paths:
- /dev/sde
```
### 6.10 OSD 内存自动调优(Automatically tuning OSD memory)
OSD 守护进程会依据 `osd_memory_target` 配置选项调整内存占用。若 Ceph 部署在**不与其他服务共享内存的专用节点**上,cephadm 会基于总 RAM 与已部署 OSD 数量自动调整每个 OSD 的内存目标,从而充分利用可用内存,并随 OSD 或 RAM 的增删自适应。
> ⚠️ cephadm 默认把 `osd_memory_target_autotune` 设为 `true`,这对融合架构(converged,同一节点既跑 Ceph 又跑计算)通常不合适。
算法:取可用内存的 `mgr/cephadm/autotune_memory_target_ratio` 比例,减去未被自动调优的守护进程(非 OSD,以及 `osd_memory_target_autotune` 为 false 的 OSD)消耗的内存,再除以 OSD 数量。
最终目标值会反映在配置数据库中:
```text
WHO MASK LEVEL OPTION VALUE
osd host:foo basic osd_memory_target 126092301926
osd host:bar basic osd_memory_target 6442450944
```
限制值与每个守护进程当前内存占用可在 `ceph orch ps` 输出的 `MEM LIMIT` 列看到:
```text
NAME HOST PORTS STATUS REFRESHED AGE MEM USED MEM LIMIT VERSION IMAGE ID CONTAINER ID
osd.1 dael running (3h) 10s ago 3h 72857k 117.4G 17.0.0-3781-gafaed750 7015fda3cd67 9e183363d39c
osd.2 dael running (81m) 10s ago 81m 63989k 117.4G 17.0.0-3781-gafaed750 7015fda3cd67 1f0cc479b051
osd.3 dael running (62m) 10s ago 62m 64071k 117.4G 17.0.0-3781-gafaed750 7015fda3cd67 ac5537492f27
```
排除某个 OSD 参与自动调优(关闭 autotune 并显式设定目标):
```bash
ceph config set osd.123 osd_memory_target_autotune false
ceph config set osd.123 osd_memory_target 16G
```
主机级排除:给主机打 `_no_autotune_memory` label(见 4.4)。
### 6.11 激活已有 OSD(Activate existing OSDs)
若某主机的操作系统被重装,已有 OSD 需要重新激活。cephadm 提供了 `ceph-volume lvm activate` 的包装,可激活一台主机上的所有已有 OSD。
示例场景:`ceph01` 是具备 admin keyring 的主机,`ceph04` 是刚重装操作系统的主机。
```bash
# 1) 在 ceph04 上安装 cephadm 与 podman(命令取决于操作系统)
# 2) 在 ceph01 上取回公钥
cd /tmp ; ceph cephadm get-pub-key > ceph.pub
# 3) 把公钥复制到重装后的主机
ssh-copy-id -f -i ceph.pub root@<hostname>
# 4) 取回私钥以测试连接
cd /tmp ; ceph config-key get mgr/cephadm/ssh_identity_key > ceph-private.key
# 5) 修改私钥权限
chmod 400 ceph-private.key
# 6) 从 ceph01 登录 ceph04 测试
ssh -i /tmp/ceph-private.key ceph04
# 7) 清理临时文件
cd /tmp ; rm ceph.pub ceph-private.key
# 8) 若使用自建容器仓库,在每台主机上让编排器登录仓库
ceph cephadm registry-login my-registry.domain <user> <password>
# 9) 激活主机上的 OSD
ceph cephadm osd activate ceph04
```
要点:
- 第 8 步(registry login)时,编排器会尝试把缺失的守护进程部署到主机上,包括 `crash`、`node-exporter` 以及该主机在重装前运行的其他守护进程。
- cephadm 会对其管理的所有在线主机尝试部署缺失守护进程。「在线」指出现在 `ceph orch host ls` 输出中且状态不是 `offline` 或 `maintenance`。若需要登录仓库才能拉取镜像,则登录完成前部署会失败。
- 不使用自建容器仓库时不需要第 8 步;如果主机仍在 host list(`ceph orch host ls`)中,也不必执行。
- 第 9 步会让 cephadm 扫描所有已有磁盘中的 OSD,并部署目标主机上缺失的守护进程。
> 注意:通常**不安全**的做法是在运行中的集群上执行 `ceph orch restart osd.myosdservice`——因为它不考虑 CRUSH failure domain,并行重启 OSD 可能导致临时数据不可用,极端情况下甚至数据丢失。
> 引自:[OSD Service](https://docs.ceph.com/en/tentacle/cephadm/services/osd/)
---
## 七、各服务部署
### 7.1 MON Service
#### 7.1.1 部署与规模
- 典型集群有 3 或 5 个 monitor 守护进程分布在不同主机;若有 5 个及以上节点,建议部署 5 个 monitor。
- 集群扩大时 Ceph 会自动部署 monitor,缩小时自动回撤;该自动扩缩依赖正确的子网配置。
- bootstrap 过程会把第一个 monitor 分配到某个子网,并将该子网指定为集群的默认子网;除非另行指示,新 monitor 默认也分配到该子网。
- 若所有 monitor 都在同一子网,无需手工管理 monitor:随着新主机加入,cephadm 会按需自动添加**最多 5 个** monitor。
- 默认情况下,cephadm 会在任意主机上部署 **5 个**守护进程(可用 placement 指定)。
#### 7.1.2 指定 monitor 子网(public_network)
```bash
ceph config set mon public_network <mon-cidr-network>
# 例:
ceph config set mon public_network 10.1.2.0/24
```
cephadm 只会在拥有该子网内 IP 地址的主机上部署新的 monitor 守护进程。
指定两个 public network(列表形式):
```bash
ceph config set mon public_network <mon-cidr-network1>,<mon-cidr-network2>
# 例:
ceph config set mon public_network 10.1.2.0/24,192.168.0.1/24
```
#### 7.1.3 在特定网络部署 monitor(unmanaged + 手动 add)
```bash
# 1) 关闭 monitor 自动部署
ceph orch apply mon --unmanaged
# 2) 手动逐个添加
ceph orch daemon add mon <host1:ip-or-network1>
# 例:在 newhost1 上用 IP 10.1.2.123 部署第二个 monitor;
# 在 newhost2 上用网络 10.1.2.0/24 部署第三个 monitor
ceph orch daemon add mon newhost1:10.1.2.123
ceph orch daemon add mon newhost2:10.1.2.0/24
# 3) 恢复自动放置(先 dry-run 确认)
ceph orch apply mon --placement="newhost1,newhost2,newhost3" --dry-run
ceph orch apply mon --placement="newhost1,newhost2,newhost3"
```
#### 7.1.4 把 monitor 迁移到另一个网络
步骤:**先在新网络部署新 monitor,再从旧网络移除 monitor。不建议手工修改并注入 monmap。**
```bash
# 1) 关闭自动放置
ceph orch apply mon --unmanaged
# 2) 在新网络上部署 monitor
ceph orch daemon add mon newhost1:10.1.2.123
ceph orch daemon add mon newhost2:10.1.2.0/24
# 3) 从旧网络移除 monitor
ceph orch daemon rm mon.<oldhost1>
# 4) 更新 public_network
ceph config set mon public_network 10.1.2.0/24
# 5) 恢复自动放置
ceph orch apply mon --placement="newhost1,newhost2,newhost3" --dry-run
ceph orch apply mon --placement="newhost1,newhost2,newhost3"
```
#### 7.1.5 设置 monitor 的 CRUSH location
cephadm 支持通过 mon 服务 spec 按主机名设置 CRUSH location。当 cephadm 在匹配的主机上部署 mon 时,会加上 `--set-crush-location <CRUSH-location>`,取该主机 CRUSH location 列表中的第一项;若一个主机设置了多个 location,cephadm 会尝试用 `ceph mon set_location` 命令设置其余 location。
```yaml
service_type: mon
service_name: mon
placement:
count: 5
spec:
crush_locations:
host1:
- datacenter=a
host2:
- datacenter=b
- rack=2
host3:
- datacenter=a
```
要点:
- 在 spec 中设置 CRUSH location 是**替换 tiebreaker mon 守护进程的推荐方式**(tiebreaker mon 在被添加时要求设置 location)。
- Tiebreaker mon 守护进程属于 stretch mode 集群。
- 有时由于 mon 加入 quorum 的时序问题,指定多个 location 时 cephadm 可能未能为部分 mon 设置 CRUSH location;此时建议**重新 apply 同一个 mon spec** 以再次触发服务动作。
- mon 守护进程只有在 cephadm 真正部署它们时才会带上 `--set-crush-location` 标志;若 spec 应用于一个已部署的 mon,可能需要对该 mon 执行 redeploy 才会生效。
> 引自:[MON Service](https://docs.ceph.com/en/tentacle/cephadm/services/mon/)
### 7.2 MGR Service
cephadm MGR 服务承载多个模块,包括 dashboard 与 cephadm manager module。
#### 7.2.1 指定网络
MGR 服务支持只绑定到某个网络内的特定 IP:
```yaml
service_type: mgr
networks:
- 192.169.142.0/24
```
#### 7.2.2 允许 MGR 守护进程共存(co-location)
在只有单主机的部署场景中,cephadm 仍需部署**至少两个** MGR 守护进程,以便支持集群的自动升级(相关配置项为 `mgr_standby_modules`)。可与通用的 `count_per_host` co-location 机制(见 5.4.1)配合使用。
> 引自:[MGR Service](https://docs.ceph.com/en/tentacle/cephadm/services/mgr/)
### 7.3 MDS Service(CephFS)
使用 CephFS 需要一个或多个 MDS 守护进程;若使用较新的 `ceph fs volume` 接口创建文件系统,MDS 会自动创建。
```bash
ceph fs volume create <fs_name> --placement="<placement spec>"
# 例:把新 volume foo 的 MDS 放在带 mds label 的主机上
ceph fs volume create foo --placement="label:mds"
```
创建后也可更新 placement:
```bash
ceph orch apply mds foo 'mds-[012]'
```
手动部署 MDS 的 spec 形式:
```yaml
service_type: mds
service_id: fs_name
placement:
count: 3
label: mds
```
```bash
ceph orch apply -i mds.yaml
```
> 引自:[MDS Service](https://docs.ceph.com/en/tentacle/cephadm/services/mds/)
### 7.4 RGW Service
#### 7.4.1 部署
cephadm 把 Object Gateway (RGW) 作为一组守护进程部署,用于管理单集群部署或 multisite 部署中的某个 *realm* 与 *zone*。
> 注意:使用 cephadm 时,`radosgw` 守护进程通过 **monitor 配置数据库**配置,而不是通过 `ceph.conf` 或命令行。若相应配置(通常在 `client.rgw.<something>` 段)不到位,`radosgw` 守护进程会以默认设置启动(例如绑定 80 端口)。
```bash
ceph orch apply rgw <name> [--realm=<realm-name>] [--zone=<zone-name>] --placement="<num-daemons> [<host1> ...]"
# 最简单的例子(service id 为 foo,默认部署两个守护进程):
ceph orch apply rgw foo
```
#### 7.4.2 Designated gateways(同一主机多实例 + 连续端口)
常见场景:给一组主机打 label 作为网关,并在其上以 8000、8001 连续端口运行多个 radosgw 实例。
```bash
ceph orch host label add gwhost1 rgw # the 'rgw' label can be anything
ceph orch host label add gwhost2 rgw
ceph orch apply rgw foo '--placement=label:rgw count-per-host:2' --port=8000
```
#### 7.4.3 指定网络
```yaml
service_type: rgw
service_id: foo
placement:
label: rgw
count_per_host: 2
networks:
- 192.169.142.0/24
spec:
rgw_frontend_port: 8080
```
#### 7.4.4 传递 frontend 额外参数
```yaml
service_type: rgw
service_id: foo
placement:
label: rgw
count_per_host: 2
spec:
rgw_realm: myrealm
rgw_zone: myzone
rgw_frontend_type: "beast"
rgw_frontend_port: 5000
rgw_frontend_extra_args:
- "tcp_nodelay=1"
- "max_header_size=65536"
```
> 注意:cephadm 会把 `spec` 段中的参数与 `rgw_frontend_extra_args` 组合成**单个以空格分隔**的参数列表,用于设置 `rgw_frontends` 配置参数的值。
#### 7.4.5 Multisite zones
```bash
# 为 multisite 的 myorg realm / us-east-1 zone 在 myhost1、myhost2 上部署 RGW
ceph orch apply rgw east --realm=myorg --zonegroup=us-east-zg-1 --zone=us-east-1 --placement="2 myhost1 myhost2"
```
> 在 multisite 场景中,cephadm **只负责部署守护进程**,不会创建或更新 realm / zone 配置。需要用 mgr rgw module 或下列命令创建:
```bash
radosgw-admin realm create --rgw-realm=<realm-name>
radosgw-admin zonegroup create --rgw-zonegroup=<zonegroup-name> --master
radosgw-admin zone create --rgw-zonegroup=<zonegroup-name> --rgw-zone=<zone-name> --master
radosgw-admin period update --rgw-realm=<realm-name> --commit
```
#### 7.4.6 启用 HTTPS
```yaml
service_type: rgw
service_id: myrgw
spec:
rgw_frontend_ssl_certificate: |
-----BEGIN PRIVATE KEY-----
V2VyIGRhcyBsaWVzdCBpc3QgZG9vZi4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt
ZXQsIGNvbnNldGV0dXIgc2FkaXBzY2luZyBlbGl0ciwgc2VkIGRpYW0gbm9udW15
IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu
YSBhbGlxdXlhbSBlcmF0LCBzZWQgZGlhbSB2b2x1cHR1YS4gQXQgdmVybyBlb3Mg
ZXQgYWNjdXNhbSBldCBqdXN0byBkdW8=
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
V2VyIGRhcyBsaWVzdCBpc3QgZG9vZi4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFt
ZXQsIGNvbnNldGV0dXIgc2FkaXBzY2luZyBlbGl0ciwgc2VkIGRpYW0gbm9udW15
IGVpcm1vZCB0ZW1wb3IgaW52aWR1bnQgdXQgbGFib3JlIGV0IGRvbG9yZSBtYWdu
YSBhbGlxdXlhbSBlcmF0LCBzZWQgZGlhbSB2b2x1cHR1YS4gQXQgdmVybyBlb3Mg
ZXQgYWNjdXNhbSBldCBqdXN0byBkdW8=
-----END CERTIFICATE-----
ssl: true
```
```bash
ceph orch apply -i myrgw.yaml
```
> 注意:`rgw_frontend_ssl_certificate` 的值是用 `|` 标记的**字面字符串**,保留换行符。
#### 7.4.7 带通配符 SAN 的 HTTPS
```yaml
service_type: rgw
service_id: foo
placement:
label: rgw
count_per_host: 1
spec:
ssl: true
generate_cert: true
rgw_frontend_port: 8080
wildcard_enabled: true # Enables wildcard SANs in the certificate
zonegroup_hostnames:
- s3.cephlab.com
```
```bash
ceph orch apply -i myrgw.yaml
```
- `wildcard_enabled` 确保自签证书中包含通配符 SAN 条目,从而支持以 virtual host 方式访问 bucket。**该标志默认关闭。**
- 示例通配符 SAN:`(*.s3.cephlab.com)`。
#### 7.4.8 关闭 multisite 同步流量
RGW 有配置项 `rgw_run_sync_thread` 可让 RGW 守护进程不传输 multisite 复制数据(适用于希望该 RGW 专用于 I/O 的场景)。RGW spec 提供 `disable_multisite_sync_traffic`,设为 `True` 时 cephadm 会为该服务下所有 RGW 守护进程把 `rgw_run_sync_thread` 设为 false。
```yaml
service_type: rgw
service_id: foo
placement:
label: rgw
spec:
rgw_realm: myrealm
rgw_zone: myzone
rgw_zonegroup: myzg
disable_multisite_sync_traffic: True
```
> 注意:这只会阻止该 RGW 守护进程**发送**复制数据;它仍然可以**接收**复制数据,除非已将其从 zonegroup 与 zone 的复制端点中移除。
#### 7.4.9 关闭时排空客户端连接(rgw_exit_timeout_secs)
任何原因(包括 cephadm 升级过程)停止 RGW 守护进程时,RGW 提供一个设置用于延迟关闭,以便完成正在进行的客户端请求。该设置**默认关闭**,可通过给 RGW 进程传 `--stop-timeout=<timeout-in-seconds>` 或为 RGW 守护进程设置 `rgw_exit_timeout_secs` 配置项来手动启用;也可以在 RGW 服务 spec 中指定:
```yaml
service_type: rgw
service_id: foo
placement:
label: rgw
spec:
rgw_realm: myrealm
rgw_zone: myzone
rgw_zonegroup: myzg
rgw_exit_timeout_secs: 120
```
含义:让 cephadm 为 `rgw.foo` 服务部署的 RGW 守护进程最多等待 120 秒以完成当前客户端请求;在此期间 RGW 守护进程会**拒绝新的**客户端请求。
要点:
- **在 cephadm 部署中,该设置默认为 on 且为 120 秒**;若要禁用,必须在 spec 中把 `rgw_exit_timeout_secs` 设为 `0`。
- spec 中对该设置的修改,只有在用 `ceph orch redeploy <service-name>` 或 `ceph orch daemon redeploy <daemon-name>` 重新部署 RGW 守护进程后才会生效。
#### 7.4.10 RGW 相关 spec 字段汇总
> 💡 补充:`RGWSpec` 的完整字段由 `.. autoclass:: RGWSpec :members:` 从源码生成,源文 rst 未逐项列出。下表仅覆盖源文示例中出现并在正文解释过的字段;其余字段**文档未明确**。
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `rgw_realm` | string | 文档未明确 | multisite realm 名 |
| `rgw_zone` | string | 文档未明确 | multisite zone 名 |
| `rgw_zonegroup` | string | 文档未明确 | multisite zonegroup 名 |
| `zonegroup_hostnames` | list | 文档未明确 | 与 wildcard SAN 配合的 zonegroup 主机名列表 |
| `rgw_frontend_type` | string | 文档未明确 | frontend 类型,例如 `"beast"` |
| `rgw_frontend_port` | int | 文档未明确(未配置时 radosgw 以默认设置启动,例如绑定 80 端口) | frontend 端口 |
| `rgw_frontend_extra_args` | list of string | 空 | 追加给 frontend 的参数,与 spec 中其他参数合并进 `rgw_frontends` |
| `rgw_frontend_ssl_certificate` | string(字面块 `|`) | 文档未明确 | SSL 证书 + 私钥(PEM),配合 `ssl: true` 使用 |
| `ssl` | bool | 文档未明确(示例显式写 `true`) | 启用 HTTPS |
| `generate_cert: true` | bool | 文档未明确 | 让 cephadm 生成自签证书 |
| `wildcard_enabled` | bool | `false`(源文:"By default, this flag is disabled") | 在自签证书中加入通配符 SAN |
| `disable_multisite_sync_traffic` | bool | 文档未明确(示例写 `True`) | 设为 True 时把 `rgw_run_sync_thread` 置为 false |
| `rgw_exit_timeout_secs` | int | cephadm 部署中**默认为 on 且 120 秒**;显式设 `0` 可禁用 | 关闭时等待客户端请求完成的秒数 |
#### 7.4.11 RGW 高可用:ingress 服务(haproxy + keepalived)
*ingress* 服务用最少的配置项为 RGW 创建高可用端点:编排器会部署并管理 haproxy + keepalived 的组合,在浮动虚拟 IP 上提供负载均衡。
机制说明:
- 若 RGW 服务启用了 SSL,ingress 服务会在 backend 配置中使用 `ssl` 与 `verify none` 选项(因为 backend 是按 IP 而非 FQDN 访问,故禁用信任校验)。
- 部署 ingress 的 N 台主机上,每台运行一个 haproxy 与一个 keepalived 守护进程;虚拟 IP 同一时刻只会在其中一台主机上配置。
- 每个 keepalived 每隔几秒检查同主机上的 haproxy 是否响应,同时检查 master keepalived 是否正常。若 master 或 active haproxy 无响应,其余 backup 状态的 keepalived 中会选出一个成为 master,虚拟 IP 漂移到该节点。
- active haproxy 作为负载均衡器,把请求分发到所有可用的 RGW 守护进程。
前提:已存在一个 RGW 服务。
部署:
```bash
ceph orch apply -i <ingress_spec_file>
```
单个虚拟 IP 的 spec:
```yaml
service_type: ingress
service_id: rgw.something # adjust to match your existing RGW service
placement:
hosts:
- host1
- host2
- host3
spec:
backend_service: rgw.something # adjust to match your existing RGW service
virtual_ip: <string>/<string> # ex: 192.168.20.1/24
frontend_port: <integer> # ex: 8080
monitor_port: <integer> # ex: 1967, used by haproxy for load balancer status
virtual_interface_networks: [ ... ] # optional: list of CIDR networks
use_keepalived_multicast: <bool> # optional: Default is False.
vrrp_interface_network: <string>/<string> # optional: ex: 192.168.20.0/24
health_check_interval: <string> # optional: Default is 2s.
ssl_cert: | # optional: SSL certificate and key
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
```
多虚拟 IP 的 spec:
```yaml
service_type: ingress
service_id: rgw.something # adjust to match your existing RGW service
placement:
hosts:
- host1
- host2
- host3
spec:
backend_service: rgw.something # adjust to match your existing RGW service
virtual_ips_list:
- <string>/<string> # ex: 192.168.20.1/24
- <string>/<string> # ex: 192.168.20.2/24
- <string>/<string> # ex: 192.168.20.3/24
frontend_port: <integer> # ex: 8080
monitor_port: <integer> # ex: 1967, used by haproxy for load balancer status
virtual_interface_networks: [ ... ] # optional: list of CIDR networks
first_virtual_router_id: <integer> # optional: default 50
health_check_interval: <string> # optional: Default is 2s.
ssl_cert: | # optional: SSL certificate and key
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
```
ingress spec 字段逐项表:
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `service_type` | string | 必填,固定为 `ingress` | 服务类型 |
| `service_id` | string | 文档未明确 | 服务名。建议以被代理的服务命名,例如 `rgw.foo` |
| `placement hosts` | list | 文档未明确 | 运行 HA 守护进程的主机;每台会部署一个 haproxy 与一个 keepalived 容器。这些主机**不需要**与 RGW 所在节点相同 |
| `backend_service` | string | 无 | 被代理的后端服务名(例如 `rgw.something`) |
| `virtual_ip` | string(CIDR) | 文档未明确 | ingress 服务对外可用的虚拟 IP 及网络,CIDR 格式 |
| `virtual_ips_list` | list of CIDR | 文档未明确 | 多个虚拟 IP;每个 VIP 会在运行 ingress 服务的某个节点上作为 primary。**VIP 数量必须小于或等于 ingress 节点数** |
| `virtual_interface_networks` | list of CIDR | 文档未明确 | 用于识别把虚拟 IP 配在哪个以太网接口上的网络列表 |
| `frontend_port` | int | 文档未明确 | 访问 ingress 服务所使用的端口 |
| `monitor_port` | int | 文档未明确 | haproxy 负载均衡状态页端口(示例 1967) |
| `ssl_cert` | string(PEM 块) | 文档未明确 | 启用 SSL 时的证书;必须同时包含 certificate 与 private key 块(.pem 格式) |
| `use_keepalived_multicast` | bool | `False` | 默认 cephadm 让 keepalived 使用**单播** IP(即 cephadm 连接主机所用的 IP)。设为 `True` 则使用组播 IP `224.0.0.18`,接口与 VIP 所在接口相同 |
| `vrrp_interface_network` | string(CIDR) | 与 VIP 相同的接口 | 默认 keepalived 用 VIP 所在接口做 VRRP 通信;如需其他接口,用该字段指定网络来识别接口 |
| `first_virtual_router_id` | int | `50` | 部署多个 ingress 时用于保证每个 keepalived 的 `virtual_router_id` 不同。使用 `virtual_ips_list` 时每个 IP 会创建自己的 virtual router:第一个用 `first_virtual_router_id`,第二个 +1,以此类推。合法取值 1–255 |
| `health_check_interval` | string | `2s` | haproxy 对后端服务器做健康检查的间隔 |
#### 7.4.12 为虚拟 IP 选择网络接口
**不能**直接指定网络接口名(因为接口名可能随主机或重启变化)。cephadm 基于已配置的 IP 地址来选择接口:
- 通常,虚拟 IP 会配在**第一个**拥有同子网已存在 IP 的网络接口上。例如 VIP 为 `192.168.0.80/24`,而 eth2 有静态 IP `192.168.0.40/24`,则使用 eth2。
- 若 VIP 与现有静态 IP 不在同一子网,可以提供一组用于匹配的子网,cephadm 会把 VIP 放到第一个匹配的接口上:
```yaml
service_type: ingress
service_id: rgw.something
spec:
virtual_ip: 192.168.0.80/24
virtual_interface_networks:
- 10.10.0.0/16
...
```
- 该策略的后果:**无法**把 VIP 配在一个没有任何 IP 地址的接口上。此时建议在正确接口上配置一个不可路由网络中的「dummy」IP,并在 networks 列表中引用该 dummy 网络。
#### 7.4.13 ingress 使用建议
- 建议至少部署 3 个 `radosgw` 守护进程,以兼顾可用性与负载均衡。
- 建议 `ingress` 服务至少使用 3 台主机。
> 引自:[RGW Service](https://docs.ceph.com/en/tentacle/cephadm/services/rgw/)
### 7.5 NFS Service(NFS Ganesha)
> 注意:**仅支持 NFSv4 协议**。
> 管理 NFS 最简单的方式是用 `ceph nfs cluster ...` 命令(mgr nfs module);直接用 cephadm 服务管理只应在非常规 NFS 配置下使用。
#### 7.5.1 部署
```bash
ceph orch apply nfs <svc_id> [--port <port>] [--placement ...]
# 例:service id 为 foo,使用默认端口 2049、默认放置(单个守护进程)
ceph orch apply nfs foo
```
NFS 的配置存放在 `.nfs` pool 中,export 通过 `ceph nfs export ...` 命令与 dashboard 管理。
#### 7.5.2 服务规格
```yaml
service_type: nfs
service_id: mynfs
placement:
hosts:
- host1
- host2
spec:
port: 12345
monitoring_port: 567
enable_nfsv3: true
```
```bash
ceph orch apply -i nfs.yaml
```
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `port` | int | `2049` | NFS 服务端口(上例改为非默认的 12345) |
| `monitoring_port` | int | 文档未明确 | NFS 监控端口 |
| `enable_nfsv3` | bool | 仅启用 NFSv4(默认不启用 v3) | 设为 `true` 可启用 NFSv3 |
| `virtual_ip` | string | 文档未明确 | 让 NFS 守护进程绑定到指定的虚拟 IP(与 `keepalive_only` ingress 搭配) |
| `enable_haproxy_protocol` | bool | 文档未明确 | 启用 HAProxy protocol 支持(需 NFS-Ganesha v5.0+),NFS 与 Ingress 两侧必须设为相同值 |
#### 7.5.3 NFS 高可用(ingress)
为已有的 *nfs* 服务部署 *ingress* 服务可提供:稳定的虚拟 IP、主机故障时的 failover、跨多个 NFS 网关的负载分发(虽然很少必要)。
```yaml
service_type: ingress
service_id: nfs.mynfs
placement:
count: 2
spec:
backend_service: nfs.mynfs
frontend_port: 2049
monitor_port: 9000
virtual_ip: 10.0.0.123/24
```
要点:
- `virtual_ip` 必须带 CIDR 前缀长度。VIP 通常配在第一个拥有同子网已存在 IP 的网口上;也可以用 `virtual_interface_networks` 匹配其他网络的 IP(见 7.4.12)。
- `monitor_port` 用于访问 haproxy 负载状态页。用户默认为 `admin`,可通过 spec 中的 *admin* 属性修改。若没有通过 *password* 属性指定密码,自动生成的密码可用下列命令获取:
```bash
ceph config-key get mgr/cephadm/ingress.*{svc_id}*/monitor_password
# 例:
ceph config-key get mgr/cephadm/ingress.nfs.myfoo/monitor_password
```
- 后端服务(上例 `nfs.mynfs`)应使用**非 2049** 的 `port`,以避免与可能位于同一主机的 ingress 服务冲突。
#### 7.5.4 只有 keepalived(无 haproxy)的 NFS
cephadm 也支持只部署 keepalived 而不部署 haproxy:由 keepalived 提供虚拟 IP,NFS 守护进程直接绑定该 IP,流量不再经过 haproxy。
建议先用 nfs module 创建服务,或**先放置 ingress 服务**使 VIP 就位,再让 nfs 守护进程绑定。ingress 服务需带 `keepalive_only: true`:
```yaml
service_type: ingress
service_id: nfs.foo
placement:
count: 1
hosts:
- host1
- host2
- host3
spec:
backend_service: nfs.foo
monitor_port: 9049
virtual_ip: 192.168.122.100/24
keepalive_only: true
```
然后创建指定 `virtual_ip` 的 nfs 服务,让它绑定到该 IP:
```yaml
service_type: nfs
service_id: foo
placement:
count: 1
hosts:
- host1
- host2
- host3
spec:
port: 2049
virtual_ip: 192.168.122.100
```
> 注意:这类配置中,nfs 的 placement 必须包含 `count: 1`,因为**只有一个** nfs 守护进程能绑定到该虚拟 IP。
#### 7.5.5 带 HAProxy Protocol 支持的 NFS
工作方式与 HA NFS 相同,但额外支持在 NFS Export 上做客户端 IP 级配置;该特性要求 **NFS-Ganesha v5.0 或更高**。
要求:NFS Service 与 Ingress service 的 `enable_haproxy_protocol` 必须设为**相同值**。
```yaml
service_type: ingress
service_id: nfs.foo
placement:
count: 1
hosts:
- host1
- host2
- host3
spec:
backend_service: nfs.foo
monitor_port: 9049
virtual_ip: 192.168.122.100/24
enable_haproxy_protocol: true
```
```yaml
service_type: nfs
service_id: foo
placement:
count: 1
hosts:
- host1
- host2
- host3
spec:
port: 2049
enable_haproxy_protocol: true
```
> 引自:[NFS Service](https://docs.ceph.com/en/tentacle/cephadm/services/nfs/)
### 7.6 iSCSI Service
#### 7.6.1 部署
创建 YAML 服务规格:
```yaml
service_type: iscsi
service_id: iscsi
placement:
hosts:
- host1
- host2
spec:
pool: mypool # RADOS pool where ceph-iscsi config data is stored.
trusted_ip_list: "IP_ADDRESS_1,IP_ADDRESS_2"
api_port: ... # optional
api_user: ... # optional
api_password: ... # optional
api_secure: true/false # optional
ssl_cert: | # optional
...
ssl_key: | # optional
...
```
完整示例:
```yaml
service_type: iscsi
service_id: iscsi
placement:
hosts:
- [...]
spec:
pool: iscsi_pool
trusted_ip_list: "IP_ADDRESS_1,IP_ADDRESS_2,IP_ADDRESS_3,..."
api_user: API_USERNAME
api_password: API_PASSWORD
ssl_cert: |
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIYMC4xNzc1NDQxNjEzMzc2MjMyXzxvQ7EcMA0GCSqGSIb3
DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARVdGFoMRcwFQYDVQQHDA5T
[...]
-----END CERTIFICATE-----
ssl_key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5jdYbjtNTAKW4
/CwQr/7wOiLGzVxChn3mmCIF3DwbL/qvTFTX2d8bDf6LjGwLYloXHscRfxszX/4h
[...]
-----END PRIVATE KEY-----
```
```bash
ceph orch apply -i iscsi.yaml
```
#### 7.6.2 iSCSI spec 字段
> 💡 补充:`IscsiServiceSpec` 的完整字段由 `.. autoclass:: IscsiServiceSpec :members:` 从源码生成,源文未给出字段表。下表仅覆盖源文示例中出现并注释说明的字段。
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `pool` | string | 无(必填) | 存放 ceph-iscsi 配置数据的 RADOS pool |
| `trusted_ip_list` | string(逗号分隔 IP) | 无(必填) | 可信 IP 列表 |
| `api_port` | int | 文档未明确(optional) | iSCSI 网关 API 端口 |
| `api_user` | string | 文档未明确(optional) | API 用户名 |
| `api_password` | string | 文档未明确(optional) | API 密码 |
| `api_secure` | bool | 文档未明确(optional) | 是否启用 API 安全(true/false) |
| `ssl_cert` | string(PEM 块) | 文档未明确(optional) | SSL 证书 |
| `ssl_key` | string(PEM 块) | 文档未明确(optional) | SSL 私钥 |
容器化的 iscsi 服务可以从任何主机使用(配置 iSCSI initiator 后通过 TCP/IP 向 iSCSI target(gateway)发送 SCSI 命令)。
> 引自:[iSCSI Service](https://docs.ceph.com/en/tentacle/cephadm/services/iscsi/)
### 7.7 SMB Service
> ⚠️ SMB 支持处于积极开发中,很多特性可能缺失或不成熟。Ceph 提供了名为 `smb` 的 MGR module 来组织与管理 SMB 相关特性;除非确认为不满足需求,官方**推荐使用该 module** 而不是直接用 smb service spec。
#### 7.7.1 部署
```bash
ceph orch apply smb <cluster_id> <config_uri> [--features ...] [--placement ...] ...
```
spec 形式:
```yaml
service_type: smb
service_id: tango
placement:
hosts:
- ceph0
spec:
cluster_id: tango
features:
- domain
config_uri: rados://.smb/tango/scc.toml
custom_dns:
- "192.168.76.204"
join_sources:
- "rados:mon-config-key:smb/config/tango/join1.json"
include_ceph_users:
- client.smb.fs.cluster.tango
```
```bash
ceph orch apply -i smb.yaml
```
#### 7.7.2 SMB spec 字段逐项表
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `cluster_id` | string | 无 | 标识 SMB「cluster」的短名。这里的 cluster 只是一个管理单元(一组共享同一配置的 Samba 服务),未必提供真正的集群或可用性机制 |
| `features` | list of string | 空列表(合法) | 启用特定部署特性的预定义术语。支持:`domain`(启用 domain member mode)、`clustered`(启用 Samba 原生集群模式) |
| `config_uri` | string(URI) | 无 | 指向 Samba 容器作为主配置文件加载的配置源。支持的 scheme:`http:`、`https:`、`rados:`、`rados:mon-config-key:` |
| `user_sources` | list of string(URI) | 文档未明确 | 认证凭据(credentials)所在位置;scheme 同 `config_uri` |
| `join_sources` | list of string(URI) | 文档未明确 | 执行 domain join 所需的认证数据位置;按顺序尝试直到某个成功;scheme 同 `config_uri` |
| `custom_dns` | list of IP | 文档未明确 | 用作 Samba 容器 DNS 服务器的 IP 列表,使 Samba 容器能集成 Active Directory,即便 Ceph 主机节点不在 AD DNS 域中 |
| `custom_ports` | mapping(服务名 → 端口) | 各服务默认端口 | 覆盖默认端口。服务名:`smb`、`smbmetrics`、`ctdb`。未出现在映射中的服务名使用默认端口。例:`{"smb": 4455, "smbmetrics": 9009}` |
| `bind_addrs` | list of object | 文档未明确 | 指定 SMB 及相关服务可绑定到哪个 IP 或 IP 网络。字段互斥,但**至少需要一个**:`address`(单个 IP 字符串,如 `192.168.7.50`)、`network`(IP 网络字符串,含 `/` 前缀长度,如 `192.168.7.0/24`) |
| `include_ceph_users` | list of string | 文档未明确 | Samba 容器可使用的 cephx 用户(entity)名列表;列表中每个用户的 cephx key 会被自动加入容器内的 keyring |
| `cluster_meta_uri` | string(URI) | 无(设置 `clustered` 时**必需**) | 集群结构元数据的存放位置,必须是 RADOS pseudo-URI |
| `cluster_lock_uri` | string(URI) | 无(设置 `clustered` 时**必需**) | Samba/CTDB 存放 cluster lock 的位置,必须是 RADOS pseudo-URI |
| `cluster_public_addrs` | list of object | 文档未明确(optional) | 仅在使用 Samba clustering 时支持。分配由集群子系统管理、可在运行 Samba 容器的节点间自动漂移的「虚拟」IP。字段:`address`(必需,带前缀长度的 IP,如 `192.168.4.51/24`)、`destination`(可选,字符串或字符串列表,定义 IP 被分配到哪个网络,例如 `192.168.4.0/24`;可运行 `cephadm list-networks` 查看网络到设备的映射;不提供时由 address 自动推导) |
> 注意:若需要 smbd 实例之间的集群(High-Availability / "transparent state migration"),必须使用 `clustered` feature flag。不指定该 flag 时,cephadm 可能部署多个 smb server,但缺少真正 HA 集群所需的协调;指定后 cephadm 会额外部署管理该协调的容器,且必须同时指定 `cluster_meta_uri` 与 `cluster_lock_uri`。前者供 cephadm 向 samba 容器描述 smb 集群布局,后者由 Samba 的 CTDB 组件管理内部 cluster lock。
#### 7.7.3 配置存放方式
| 存放位置 | 组织方式 | URI 形式 | 写入方式 |
|---|---|---|---|
| RADOS 对象 | pool 名为 `.smb`,其中 namespace 以 `cluster_id` 命名 | `rados://.smb/<cluster_id>/<object_name>`,例如 `rados://.smb/tango/config.json` | `rados --pool=.smb --namespace=tango put config.json /tmp/config.json` |
| MON Key/Value Store | key 名 `smb/config/<cluster_id>/<name>` | `rados:mon-config-key:smb/config/<cluster_id>/<name>`,例如 `rados:mon-config-key:smb/config/tango/config.json` | `ceph config-key set smb/config/tango/config.json -i /tmp/config.json` |
| HTTP/HTTPS | 放在 HTTP(S) 服务器上由 Samba 容器自动读取 | `http:` / `https:` | 源文未给出("left as an exercise for the reader") |
容器会自动被部署带 cephx key 的凭据,只要使用上述 scheme 与命名,即可读取对应资源而无需额外配置。
#### 7.7.4 限制
- DNS 是 Active Directory 的关键组件。若要为 domain membership 配置 SMB 服务,Ceph 主机节点必须能解析 AD 域,或者使用 `custom_dns` 选项;两种情况下,AD 域的 DNS 主机都必须能从 Ceph 集群所在网段访问。
- 服务必须绑定到 TCP 端口 445;**同一节点上运行多个 SMB 服务尚不支持**,会触发端口占用冲突。
> 引自:[SMB Service](https://docs.ceph.com/en/tentacle/cephadm/services/smb/)
### 7.8 SNMP Gateway Service
SNMP 仍是跨硬件/软件平台监控分布式系统的主流协议。Ceph 的 SNMP 集成思路是:把 **Prometheus Alertmanager 的告警转发给一个 gateway 守护进程**,由该守护进程把告警转换成 SNMP Notification 再发给指定的 SNMP 管理平台。gateway 守护进程来自 `snmp_notifier` 项目,支持 SNMP V2c 与 V3(认证与加密)。
默认情况下,cephadm 只部署 **1 个** SNMP gateway 实例。可以通过 placement 增加实例数,但要注意:**部署多个 gateway 时,同一个事件会让 SNMP 管理平台收到多条重复通知**。
#### 7.8.1 SNMP 版本兼容性
| SNMP Version | 是否支持 | 说明 |
|---|---|---|
| V1 | ❌ | `snmp_notifier` 不支持 |
| V2c | ✔ | 仅 community string |
| V3 authNoPriv | ✔ | 用户名/密码认证,**不加密**(NoPriv = no privacy) |
| V3 authPriv | ✔ | 用户名/密码认证 **+ 加密** 到 SNMP 管理平台 |
#### 7.8.2 部署方式与命令格式
V2c 与 V3 都需要凭据。**凭据不支持在命令行上直接给出**,必须:① 提供一个 YAML 格式的 credentials 文件(`-i <filename>`),或 ② 在完整 YAML spec 文件中写 `credentials` 段。
命令格式:
```bash
ceph orch apply snmp-gateway <snmp_version:V2c|V3> <destination> [<port:int>] [<engine_id>] [<auth_protocol: MD5|SHA>] [<privacy_protocol:DES|AES>] [<placement>] ...
```
参数说明:
| 参数 | 默认值 | 含义 |
|---|---|---|
| `--snmp-version` | 无(**必须提供**) | `V2c` 或 `V3` |
| `--destination` | 无(**必须提供**) | 格式 `hostname:port` |
| `--port` | `9464` | gateway 监听端口 |
| `--engine-id` | 无 | 设备唯一标识(十六进制),**仅 SNMP v3 必需**。建议值 `8000C53F<fsid>`,其中 fsid 取自集群且去掉 `-` 符号 |
| `--auth-protocol` | `SHA` | 仅 V3;可选 `MD5`/`SHA` |
| `--privacy-protocol` | 无 | 仅 V3 且需要加密时**必须**定义;可选 `DES`/`AES` |
| `-i <filename>` | 无 | **必须提供**,用于把 secrets/passwords 传给 orchestrator |
> 注意:凭据保存在主机上、仅限 `root` 用户可读,并以 environment file(`--env-file`)形式传给 `snmp_notifier` 守护进程,以限制暴露面。
#### 7.8.3 部署范例
**SNMP V2c(命令行 + credentials 文件)**
```bash
ceph orch apply snmp-gateway --port 9464 --snmp_version=V2c --destination=192.168.122.73:162 -i ./snmp_creds.yaml
```
```yaml
---
snmp_community: public
```
**SNMP V2c(单一 YAML spec 文件)**
```bash
ceph orch apply -i snmp-gateway.yml
```
```yaml
service_type: snmp-gateway
service_name: snmp-gateway
placement:
count: 1
spec:
credentials:
snmp_community: public
port: 9464
snmp_destination: 192.168.122.73:162
snmp_version: V2c
```
**SNMP V3 authNoPriv**
```bash
ceph orch apply snmp-gateway --snmp-version=V3 --engine-id=800C53F000000 --destination=192.168.122.1:162 -i ./snmpv3_creds.yml
```
```yaml
---
snmp_v3_auth_username: myuser
snmp_v3_auth_password: mypassword
```
或等价的 spec 文件:
```yaml
service_type: snmp-gateway
service_name: snmp-gateway
placement:
count: 1
spec:
credentials:
snmp_v3_auth_password: mypassword
snmp_v3_auth_username: myuser
engine_id: 800C53F000000
port: 9464
snmp_destination: 192.168.122.1:162
snmp_version: V3
```
**SNMP V3 authPriv(认证 + 加密)**
```bash
ceph orch apply snmp-gateway --snmp-version=V3 --engine-id=800C53F000000 --destination=192.168.122.1:162 --privacy-protocol=AES -i ./snmpv3_creds.yml
```
```yaml
---
snmp_v3_auth_username: myuser
snmp_v3_auth_password: mypassword
snmp_v3_priv_password: mysecret
```
#### 7.8.4 credentials 字段汇总
| 字段 | 适用版本 | 含义 |
|---|---|---|
| `snmp_community` | V2c | community string |
| `snmp_v3_auth_username` | V3 | 认证用户名 |
| `snmp_v3_auth_password` | V3 | 认证密码 |
| `snmp_v3_priv_password` | V3 authPriv | 加密(privacy)密码 |
#### 7.8.5 Alertmanager 集成与 MIB
- 当 SNMP gateway 服务被部署或更新时,**Prometheus Alertmanager 的配置会被自动更新**:任何带 `OID` label 的告警都会被转发给 SNMP gateway 守护进程处理。
- 要让 SNMP 管理平台能理解这些通知/trap,需要把 MIB(`CEPH-MIB.txt`)导入 SNMP 管理平台;该文件可从 Ceph GitHub 仓库的 `monitoring/snmp` 目录下载。
> 引自:[SNMP Gateway Service](https://docs.ceph.com/en/tentacle/cephadm/services/snmp-gateway/)
### 7.9 Monitoring Services(Prometheus / Grafana / Alertmanager / node-exporter)
Ceph Dashboard 使用 Prometheus、Grafana 及相关工具来存储和可视化集群利用率与性能指标。用户有三种选择:
| 选项 | 说明 |
|---|---|
| 让 cephadm 部署并配置这些服务 | **默认行为**,除非 bootstrap 时使用了 `--skip-monitoring-stack` |
| 手工部署与配置 | 适合环境中已有 Prometheus 服务的用户(以及 Ceph 跑在 Kubernetes + Rook 的场景) |
| 完全跳过监控栈 | 部分 Ceph dashboard 图表将不可用 |
监控栈组成:**Prometheus**、Prometheus exporters(mgr prometheus module、Node exporter)、**Prometheus Alertmanager**、**Grafana**。
> ⚠️ 官方安全提示:Prometheus 的安全模型**假定不可信用户可以访问**其 HTTP endpoint 与日志——这些用户能拿到数据库里收集的全部(元)数据以及大量运维/调试信息。不过其 HTTP API 仅限只读操作,不能修改配置、不暴露 secrets,并且内置了一些缓解 DoS 的措施。
#### 7.9.1 为「没有监控栈」的集群补装
```bash
ceph orch apply node-exporter # 主机级指标:CPU、内存利用率等
ceph orch apply alertmanager
ceph orch apply prometheus # 单实例即可;HA 可用下面这条
ceph orch apply prometheus --placement 'count:2'
ceph orch apply grafana
```
#### 7.9.2 启用监控栈安全加固
默认情况下 cephadm 部署的监控组件**不启用安全措施**。有严格安全需求的场景可通过:
```bash
ceph config set mgr mgr/cephadm/secure_monitoring_stack true
```
该变更会触发所有监控守护进程的一连串 reconfig,通常需要几分钟才会全部就绪。加固后的配置包括:
| 组件 | 加固内容 |
|---|---|
| Prometheus | Web 门户需要 basic authentication;启用 TLS |
| Alertmanager | Web 门户需要 basic authentication;启用 TLS |
| Node Exporter | 启用 TLS |
| Grafana | 启用 TLS;访问 datasource 信息需要认证 |
在安全模式下,Prometheus 与 Alertmanager 的**默认用户名/密码均为 `admin`/`admin`**,可用下列命令修改(支持参数直接传入或通过 JSON 文件传入,后者更安全):
| 命令 | 用途 |
|---|---|
| `ceph orch prometheus set-credentials` | 设置 Prometheus 用户名/密码 |
| `ceph orch alertmanager set-credentials` | 设置 Alertmanager 用户名/密码 |
| `ceph orch prometheus get-credentials` | 读取当前 Prometheus 凭据 |
| `ceph orch alertmanager get-credentials` | 读取当前 Alertmanager 凭据 |
#### 7.9.3 集中式日志(Loki + Promtail)
Ceph 通过两个新服务提供 Centralized Log Management(CLM):
| 服务 | 角色 |
|---|---|
| `loki` | 日志聚合系统,用于查询日志;可在 Grafana 中配置为 datasource |
| `promtail` | agent,从系统收集日志并提供给 Loki |
优势:线性事件时间线、实时日志监控、灵活保留策略(per-daemon 日志轮转通常只有 1–2 周)、增强的安全与备份(可 HA)。
**这两个服务默认不随集群部署**,需按 `centralized-logging` 章节的步骤启用。
#### 7.9.4 网络与端口
所有监控服务都可以通过 YAML service spec 配置其绑定的 network 与 port。默认 cephadm 配置 Grafana 时使用 **`https` 协议**,除非用户显式把 `protocol` 设为 `http`。
```yaml
service_type: grafana
service_name: grafana
placement:
count: 1
networks:
- 192.169.142.0/24
spec:
port: 4200
protocol: http
```
#### 7.9.5 默认镜像
`cephadm` 会在 `var/lib/ceph/{FSID}/cephadm.{DIGEST}` 保存一份 `cephadm` 二进制的本地副本(`{DIGEST}` 是表示当前运行 Ceph 版本的字母数字串)。查看默认容器镜像:
```bash
cephadm list-images
```
默认监控镜像定义在源码 `/src/python-common/ceph/cephadm/images.py` 的 `DefaultImages` 类中。
> 💡 补充:源文此处通过 `autoclass:: ceph.cephadm.images.DefaultImages` 自动展开,具体的镜像名与 tag 列表在抓取到的 rst 文本中未以明文出现,故本册不逐一列出;实际值请以 `cephadm list-images` 的输出为准。
#### 7.9.6 使用自定义镜像
可用的镜像配置项(均为 `mgr/cephadm/` 下的配置):
| 配置项 | 对应组件 |
|---|---|
| `container_image_prometheus` | Prometheus |
| `container_image_grafana` | Grafana |
| `container_image_alertmanager` | Alertmanager |
| `container_image_node_exporter` | Node exporter |
| `container_image_loki` | Loki |
| `container_image_promtail` | Promtail |
| `container_image_haproxy` | HAProxy(ingress) |
| `container_image_keepalived` | Keepalived(ingress) |
| `container_image_snmp_gateway` | SNMP gateway |
| `container_image_elasticsearch` | Elasticsearch(tracing) |
| `container_image_jaeger_agent` | Jaeger agent |
| `container_image_jaeger_collector` | Jaeger collector |
| `container_image_jaeger_query` | Jaeger query |
设置方式:
```bash
ceph config set mgr mgr/cephadm/<option_name> <value>
# 例:
ceph config set mgr mgr/cephadm/container_image_prometheus prom/prometheus:v1.4.1
```
若已有同类型的守护进程在运行,**必须 redeploy 才会使用新镜像**:
```bash
ceph orch redeploy prometheus
```
> 注意:设置自定义镜像只是**覆盖(override)而非改写(overwrite)默认值**。默认值会随更新变化,但一旦设置了自定义镜像,该组件就**无法再自动更新**——必须手工修改配置(含镜像名与 tag)才能升级。要恢复默认值用 `ceph config rm`:
> ```bash
> ceph config rm mgr mgr/cephadm/<option_name>
> # 例:
> ceph config rm mgr mgr/cephadm/container_image_prometheus
> ```
另见 airgap(离线环境)相关章节。
#### 7.9.7 使用自定义配置文件(覆盖 Jinja2 模板)
cephadm 内部**本就用 Jinja2 模板**生成所有监控组件的配置文件。从 **17.2.3** 起,cephadm 支持 Prometheus http service discovery,并用该 endpoint 管理内嵌 Prometheus 服务:endpoint 监听在 `https://<mgr-ip>:8765/sd/`(端口可通过变量 `service_discovery_port` 配置),返回 `http_sd_config` 格式的 scrape target 信息。
外部监控栈的用户也可以使用 ceph-mgr 的 service discovery endpoint 获取抓取配置;服务端根证书可用:
```bash
ceph orch sd dump cert
```
可被覆盖的模板名(即 `ceph config-key set` 时使用的 option name):
| option name | 对应源码模板 |
|---|---|
| `services/alertmanager/alertmanager.yml` | `services/alertmanager/alertmanager.yml.j2` |
| `services/alertmanager/web.yml` | `services/alertmanager/web.yml.j2` |
| `services/grafana/ceph-dashboard.yml` | `services/grafana/ceph-dashboard.yml.j2` |
| `services/grafana/grafana.ini` | `services/grafana/grafana.ini.j2` |
| `services/ingress/haproxy.cfg` | `services/ingress/haproxy.cfg.j2` |
| `services/ingress/keepalived.conf` | `services/ingress/keepalived.conf.j2` |
| `services/iscsi/iscsi-gateway.cfg` | `services/iscsi/iscsi-gateway.cfg.j2` |
| `services/mgmt-gateway/external_server.conf` | `services/mgmt-gateway/external_server.conf.j2` |
| `services/mgmt-gateway/internal_server.conf` | `services/mgmt-gateway/internal_server.conf.j2` |
| `services/mgmt-gateway/nginx.conf` | `services/mgmt-gateway/nginx.conf.j2` |
| `services/nfs/ganesha.conf` | `services/nfs/ganesha.conf.j2` |
| `services/node-exporter/web.yml` | `services/node-exporter/web.yml.j2` |
| `services/nvmeof/ceph-nvmeof.conf` | `services/nvmeof/ceph-nvmeof.conf.j2` |
| `services/oauth2-proxy/oauth2-proxy.conf` | `services/oauth2-proxy/oauth2-proxy.conf.j2` |
| `services/prometheus/prometheus.yml` | `services/prometheus/prometheus.yml.j2` |
| `services/prometheus/web.yml` | `services/prometheus/web.yml.j2` |
| `services/loki.yml` | `services/loki.yml.j2` |
| `services/promtail.yml` | `services/promtail.yml.j2` |
当前模板源文件位于 `src/pybind/mgr/cephadm/templates`。
用法:
```bash
# 单行值
ceph config-key set mgr/cephadm/<option_name> <value>
# 把文件内容作为模板(必须用绝对路径)
ceph config-key set mgr/cephadm/<option_name> -i $PWD/<filename>
```
设置后需要 **reconfig** 才能重新生成配置文件:
```bash
# 把 ./prometheus.yml.j2 设为模板
ceph config-key set mgr/cephadm/services/prometheus/prometheus.yml \
-i $PWD/prometheus.yml.j2
# reconfig prometheus 服务
ceph orch reconfig prometheus
```
追加自定义告警规则:
```bash
ceph config-key set mgr/cephadm/services/prometheus/alerting/custom_alerts.yml \
-i $PWD/custom_alerts.yml
```
> 注意:自定义告警规则**不经过 Jinja 解析**,因此不存在转义问题。
>
> 注意:自定义模板在 cephadm 默认配置变更时也会被保留;如果希望使用更新后的默认配置,需在**每次 Ceph 升级后手工迁移**自定义模板。
#### 7.9.8 不用 cephadm 部署监控
若已有 Prometheus 基础设施:
```bash
ceph mgr module enable prometheus
```
默认 ceph-mgr 在每个运行 mgr 守护进程的主机上以 **9283** 端口暴露 Prometheus 指标,配置 Prometheus 抓取即可。也可使用 cephadm 的 service discovery endpoint `https://<mgr-ip>:8765/sd/`(返回 `http_sd_config` 格式)。示例 job 定义:
```yaml
- job_name: 'ceph-exporter'
http_sd_configs:
- url: http://<mgr-ip>:8765/sd/prometheus/sd-config?service=ceph-exporter
```
#### 7.9.9 关闭监控
```bash
ceph orch rm grafana
ceph orch rm prometheus --force # 这会删除到目前为止已采集的 metrics 数据
ceph orch rm node-exporter
ceph orch rm alertmanager
ceph mgr module disable prometheus
```
#### 7.9.10 RBD 镜像监控
出于性能原因,**RBD image 监控默认关闭**。未启用时,Grafana 的 overview 与 details 面板为空,Prometheus 中也看不到相关指标。详见 `prometheus-rbd-io-statistics`。
#### 7.9.11 设置 Prometheus 的 retention
cephadm 可通过 Prometheus service spec 中的 `retention_time` 与 `retention_size` 配置 TSDB 保留策略。
| 字段 | 默认值 | 支持单位 | 含义 |
|---|---|---|---|
| `retention_time` | `15d`(15 天) | `y`、`w`、`d`、`h`、`m`、`s` | 按时间保留 |
| `retention_size` | `0`(禁用) | `B`、`KB`、`MB`、`GB`、`TB`、`PB`、`EB` | 按大小保留,`0` 表示禁用 |
```yaml
service_type: prometheus
placement:
count: 1
spec:
retention_time: "1y"
retention_size: "1GB"
```
> 注意:如果是**更新已有 spec**(而非全新部署 Prometheus),改完还必须 `ceph orch redeploy prometheus` 才会生效。
#### 7.9.12 设置 Grafana
**手工指定 Grafana URL**:某些部署中,Dashboard 用户的浏览器可能无法访问 Ceph Dashboard 里配置的 Grafana URL(例如集群与访问者处于不同 DNS zone)。可用下面的 Dashboard 配置项指定浏览器访问 Grafana 的 URL,该值**永不被 cephadm 修改**:
```bash
ceph dashboard set-grafana-frontend-api-url <grafana-server-api>
```
部署完成后(通常需一两分钟),`ceph orch ls` 应能看到类似输出:
```text
NAME RUNNING REFRESHED IMAGE NAME IMAGE ID SPEC
alertmanager 1/1 6s ago docker.io/prom/alertmanager:latest 0881eb8f169f present
crash 2/2 6s ago docker.io/ceph/daemon-base:latest-master-devel mix present
grafana 1/1 0s ago docker.io/pcuzner/ceph-grafana-el8:latest f77afcf0bcf6 absent
node-exporter 2/2 6s ago docker.io/prom/node-exporter:latest e5a616e4b9cf present
prometheus 1/1 6s ago docker.io/prom/prometheus:latest e935122ab143 present
```
**配置 SSL/TLS**:cephadm 使用 ceph key/value store 中定义的证书部署 Grafana;若未指定证书,cephadm 会在部署 Grafana 服务时**生成自签名证书**,且每个证书只针对其生成所在的主机。自定义证书:
```bash
ceph config-key set mgr/cephadm/{hostname}/grafana_key -i $PWD/key.pem
ceph config-key set mgr/cephadm/{hostname}/grafana_crt -i $PWD/certificate.pem
```
其中 `{hostname}` 是 Grafana 服务所在主机的主机名。若 Grafana 已部署,需要 reconfig 以更新配置:
```bash
ceph orch reconfig grafana
```
`reconfig` 同时会为 Ceph Dashboard 设置正确的 URL。
**设置初始 admin 密码**:默认 Grafana **不会创建初始 admin 用户**。要创建,请编写 `grafana.yaml`:
```yaml
service_type: grafana
spec:
initial_admin_password: mypassword
```
```bash
ceph orch apply -i grafana.yaml
ceph orch redeploy grafana
```
之后 Grafana 会创建一个名为 `admin`、密码为指定值的管理员用户。
**关闭匿名访问**:默认 cephadm 允许匿名用户(未提供任何登录信息的用户)以 **viewer-only** 的有限权限访问 Grafana dashboard。若要求仅登录用户可查看,在 spec 中设置 `anonymous_access: False`:
```yaml
service_type: grafana
placement:
hosts:
- host1
spec:
anonymous_access: False
initial_admin_password: "mypassword"
```
> 注意:由于把 `anonymous_access` 设为 false 却不设置初始 admin 密码会导致 dashboard 完全无法访问,**cephadm 要求在 `anonymous_access: False` 时必须同时设置 `initial_admin_password`**。
#### 7.9.13 设置 Alertmanager
**添加 webhook**:在 spec 中增加额外的 webhook URL:
```yaml
service_type: alertmanager
spec:
user_data:
default_webhook_urls:
- "https://foo"
- "https://bar"
```
`default_webhook_urls` 是一个 URL 列表,会被追加到默认 receiver 的 `<webhook_configs>` 配置中。改完需:
```bash
ceph orch reconfig alertmanager
```
**开启证书校验**:若 Alertmanager 使用证书且希望校验这些证书,把 spec 中的 `secure` 设为 `true`(**默认 false**):
```yaml
service_type: alertmanager
spec:
secure: true
```
若此前已有 alertmanager 守护进程在运行,必须 reconfig:
```bash
ceph orch reconfig alertmanager
```
#### 7.9.14 Grafana / Alertmanager 常用 spec 字段汇总
| 字段 | 所属服务 | 类型 | 默认值 | 含义 |
|---|---|---|---|---|
| `port` | grafana | int | 文档未明确(示例为 4200) | Grafana 监听端口 |
| `protocol` | grafana | string | `https` | `http` 或 `https` |
| `initial_admin_password` | grafana | string | 无(不创建 admin 用户) | 初始 admin 用户密码 |
| `anonymous_access` | grafana | bool | `True` | 是否允许匿名 viewer 访问 |
| `networks` | 通用 | list of CIDR | 无 | 绑定网段 |
| `retention_time` | prometheus | string | `15d` | TSDB 时间保留 |
| `retention_size` | prometheus | string | `0`(禁用) | TSDB 大小保留 |
| `user_data.default_webhook_urls` | alertmanager | list of string | 无 | 追加到默认 receiver 的 webhook URL |
| `secure` | alertmanager | bool | `false` | 是否校验证书 |
| `enable_stretch` 等其它字段 | — | — | — | 文档未明确 |
> 💡 补充:源文对 Grafana/Alertmanager 的完整 spec 字段采用 `autoclass` 自动生成,抓取到的 rst 文本只给出了示例中出现的字段与上表所列字段,其余字段「文档未明确」。
> 引自:[Monitoring Services](https://docs.ceph.com/en/tentacle/cephadm/services/monitoring/)
### 7.10 Management Gateway(mgmt-gateway)
从 **Squid** 版本起,`mgmt-gateway` 引入了一种基于模块化、服务化架构的 Ceph 应用新设计。该服务由 cephadm 管理、构建在 **nginx** 之上,作为 Ceph 集群的**新前端与统一入口**,为包括 Ceph dashboard 与监控栈在内的所有 Ceph 应用提供统一访问。它本质上是一个**反向代理**,把请求路由到合适的 Ceph 应用实例。
```bash
ceph orch apply mgmt-gateway [--placement ...] ...
```
一旦应用,cephadm 会 reconfig 特定的运行中守护进程(如监控组件),让它们跑到这个新服务**背后**;**外部将无法再直接访问这些服务**,访问会被统一收敛到新端点:`https://<node-ip>:<port>`。
#### 7.10.1 收益
| 收益 | 说明 |
|---|---|
| `Unified Access` | 通过 nginx 收敛访问,提升安全性,提供单一入口 |
| `Improved user experience` | 用户不必再知道每个应用跑在哪个 ip/host 上 |
| `High Availability for dashboard` | 利用 nginx HA 机制为 Ceph dashboard 提供高可用 |
| `High Availability for monitoring` | 利用 nginx HA 机制为监控栈提供高可用 |
**安全增强**:部署 `mgmt-gateway` 后,用户**不能**在未经 Ceph dashboard 认证的情况下访问监控服务。
**HA 增强**:对 Ceph dashboard,用户无需知道 active manager 在哪——`mgmt-gateway` 透明处理 manager failover 并把用户重定向到 active manager;对监控栈,当存在多个 Prometheus / Alertmanager / Grafana 实例时,`mgmt-gateway` 负责 HA,反向代理会自动检测健康实例并用其处理用户请求。
#### 7.10.2 mgmt-gateway 自身的高可用
多个 `mgmt-gateway` 实例可用 **keepalived** 以 active/standby 配置部署以实现无缝 failover;`oauth2-proxy` 服务可部署多个**无状态**实例,由 nginx 以 **round-robin** 策略在其间做负载均衡。该部署方式消除了单点故障。
在此模式下,底层内部服务遵循同一套 HA 机制:它们不再直接访问 `mgmt-gateway` 的内部端点,而是使用 spec 中指定的 **virtual IP**,从而让 `mgmt-gateway` 的 HA 机制对其它服务透明。
推荐且最简单的 HA 部署方式是使用 **label**:
```bash
ceph orch apply mgmt-gateway --virtual_ip 192.168.100.220 --enable-auth=true --placement="label:mgmt"
```
或等价的 spec 文件:
```yaml
service_type: mgmt-gateway
placement:
label: mgmt
spec:
enable_auth: true
virtual_ip: 192.168.100.220
```
此外,**必须**再配置一个 ingress 服务为 `mgmt-gateway` 提供 virtual IP 功能:
```yaml
service_type: ingress
service_id: ingress-mgmt-gw
placement:
label: mgmt
virtual_ip: 192.168.100.220
backend_service: mgmt-gateway
keepalive_only: true
```
部署实例数由带 `mgmt` label 的主机数量决定。ingress 配置为 `keepalive_only` 模式,配合 label 可确保 `mgmt-gateway` 守护进程的任何变更都能复制到对应的 keepalived 实例。
> ⚠️ 注意:`virtual_ip` 参数在 ingress 与 `mgmt-gateway` 两个 spec 中**必须完全一致**。
#### 7.10.3 Service Spec 与字段
```yaml
service_type: mgmt-gateway
service_id: gateway
placement:
hosts:
- ceph0
spec:
port: 5000
ssl: True
ssl_protocols:
- TLSv1.2
- TLSv1.3
- ...
ssl_ciphers:
- AES128-SHA
- AES256-SHA
- ...
ssl_cert: |
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIYMC4xNzc1NDQxNjEzMzc2MjMyXzxvQ7EcMA0GCSqGSIb3
DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARVdGFoMRcwFQYDVQQHDA5T
[...]
-----END CERTIFICATE-----
ssl_key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5jdYbjtNTAKW4
/CwQr/7wOiLGzVxChn3mmCIF3DwbL/qvTFTX2d8bDf6LjGwLYloXHscRfxszX/4h
[...]
-----END PRIVATE KEY-----
```
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `enable_auth` | bool | 文档未明确(示例 `true`) | 是否启用认证(配合 oauth2-proxy 使用) |
| `virtual_ip` | string | 无 | HA 虚拟 IP,必须与配套 ingress spec 中的值一致 |
| `port` | int | 文档未明确(示例 `5000`) | 对外服务端口 |
| `ssl` | bool | 文档未明确(示例 `True`) | 是否启用 SSL/TLS |
| `ssl_protocols` | list of string | 文档未明确(示例 `TLSv1.2`、`TLSv1.3`) | 启用的 TLS 协议版本 |
| `ssl_ciphers` | list of string | 文档未明确(示例 `AES128-SHA`、`AES256-SHA`) | 允许的加密套件 |
| `ssl_cert` | string(PEM) | 无 | TLS 证书 |
| `ssl_key` | string(PEM) | 无 | TLS 私钥 |
> 💡 补充:源文对 `MgmtGatewaySpec` 采用 `autoclass` 自动展开,抓取到的 rst 中仅上述字段以明文出现在示例与命令行中,完整字段清单「文档未明确」。
应用 spec:
```bash
ceph orch apply -i mgmt-gateway.yaml
```
> ⚠️ 官方警告:TLSv1.3 目前被认为是安全的,且默认包含一组安全 cipher。为旧版本(尤其 **TLSv1.2**)配置 SSL/TLS cipher 时,务必只使用**安全 cipher 的子集**;使用弱或过时的 cipher 会严重损害系统安全。任何对 cipher 列表的修改都由系统管理员负责,不要在不充分理解后果的情况下修改——错误配置会导致弱加密、缺乏前向保密、易受多种攻击等问题。
#### 7.10.4 访问方式
部署 `mgmt-gateway` 后,将**不再允许**直接访问监控服务;Prometheus、Grafana、Alertmanager 需通过 `Administration > Services` 中的链接访问。
#### 7.10.5 限制与默认镜像
- 服务必须绑定到与被代理应用相匹配的正确端口,需确保没有端口冲突。
- 默认使用 nginx 反向代理,镜像由 `mgr/cephadm/container_image_nginx` 指定:
```text
mgr/cephadm/container_image_nginx = 'quay.io/ceph/nginx:sclorg-nginx-126'
```
更换镜像(已有守护进程时必须 redeploy):
```bash
ceph config set mgr mgr/cephadm/container_image_nginx <new-nginx-image>
ceph orch redeploy mgmt-gateway
```
> 引自:[Management Gateway](https://docs.ceph.com/en/tentacle/cephadm/services/mgmt-gateway/)
### 7.11 OAuth2 Proxy(oauth2-proxy)
从 **Squid** 版本起,`oauth2-proxy` 服务为 Ceph 应用引入了一种更高级的认证与访问控制方式。它通过 **OIDC(OpenID Connect)** 协议与外部 Identity Provider(IDP)集成,`oauth2-proxy` 充当**认证网关**,确保对包括 Ceph Dashboard 与监控栈在内的所有 Ceph 应用的访问受到严格控制。
```bash
ceph orch apply oauth2-proxy [--placement ...] ...
```
一旦应用,cephadm 会重新配置相关组件以使用 `oauth2-proxy` 进行认证;该服务负责处理登录流程、把用户重定向到合适的 IDP 完成认证,并管理 session token。
#### 7.11.1 收益与 HA
| 收益 | 说明 |
|---|---|
| `Enhanced Security` | 通过 OIDC 与外部 IDP 集成提供强认证 |
| `Seamless SSO` | 跨所有 Ceph 应用的单点登录 |
| `Centralized Authentication` | 集中认证管理,降低复杂度、提升控制力 |
HA 方面:`oauth2-proxy` 通常与 `mgmt-gateway` 配合使用,可部署多个**无状态**实例,由 `mgmt-gateway`(nginx 反向代理)以 round-robin 策略做负载均衡。由于 `oauth2-proxy` 与外部 IDP 集成,**登录的高可用由外部负责**,不属于本服务的职责。
#### 7.11.2 Service Spec
部署 `oauth2-proxy` 前,**请先部署 `mgmt-gateway` 并打开 `--enable_auth`**:
```bash
ceph orch apply mgmt-gateway --enable_auth=true
```
An `oauth2-proxy` service 也可以通过 spec 文件应用,示例如下:
```yaml
service_type: oauth2-proxy
service_id: auth-proxy
placement:
label: mgmt
spec:
https_address: "0.0.0.0:4180"
provider_display_name: "My OIDC Provider"
client_id: "your-client-id"
oidc_issuer_url: "http://192.168.100.1:5556/dex"
client_secret: "your-client-secret"
cookie_secret: "your-cookie-secret"
ssl_certificate: |
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIYMC4xNzc1NDQxNjEzMzc2MjMyXzxvQ7EcMA0GCSqGSIb3
DQEBCwUAMG0xCzAJBgNVBAYTAlVTMQ0wCwYDVQQIDARVdGFoMRcwFQYDVQQHDA5T
[...]
-----END CERTIFICATE-----
ssl_certificate_key: |
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5jdYbjtNTAKW4
/CwQr/7wOiLGzVxChn3mmCIF3DwbL/qvTFTX2d8bDf6LjGwLYloXHscRfxszX/4h
[...]
-----END PRIVATE KEY-----
```
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `https_address` | string | 文档未明确(示例 `0.0.0.0:4180`) | 监听地址与端口 |
| `provider_display_name` | string | 无 | IDP 在 UI 上的展示名 |
| `client_id` | string | 无 | OIDC client id |
| `oidc_issuer_url` | string | 无 | OIDC issuer URL |
| `client_secret` | string | 无 | OIDC client secret |
| `cookie_secret` | string | 无 | session cookie 加密密钥 |
| `ssl_certificate` | string(PEM) | 无 | TLS 证书 |
| `ssl_certificate_key` | string(PEM) | 无 | TLS 私钥 |
> 💡 补充:源文对 `OAuth2ProxySpec` 同样使用 `autoclass` 展开,rst 中仅上述字段以明文出现;其余字段「文档未明确」,更详细的字段说明需参考 oauth2-proxy 项目自身文档。
应用 spec:
```bash
ceph orch apply -i oauth2-proxy.yaml
```
一旦服务可用,cephadm 会**自动 redeploy `mgmt-gateway` 服务**,并调整其配置,把认证重定向到新部署的 `oauth2-proxy` 服务。
#### 7.11.3 限制
- **不支持** `oauth2-proxy` 自身的高可用配置。
- 正确配置 IDP 与 OAuth2 参数至关重要,配置错误会导致认证失败/访问问题。
#### 7.11.4 容器镜像
```bash
ceph config get mgr mgr/cephadm/container_image_oauth2_proxy
```
更换镜像(已有守护进程时必须 redeploy):
```bash
ceph config set mgr mgr/cephadm/container_image_oauth2_proxy <new-oauth2-proxy-image>
ceph orch redeploy oauth2-proxy
```
> 引自:[OAuth2 Proxy](https://docs.ceph.com/en/tentacle/cephadm/services/oauth2-proxy/)
### 7.12 Tracing Services(Jaeger)
Ceph 使用 **Jaeger** 作为 tracing 后端;要使用 tracing,需要部署相应服务。
Jaeger 服务由 3 个服务组成:
| 组件 | 说明 |
|---|---|
| Jaeger Agent | 1 |
| Jaeger Collector | 2 |
| Jaeger Query | 3 |
Jaeger 需要一个数据库存放 traces,**默认使用 Elasticsearch(version 6)**。
部署方式:
```bash
# 1) 部署 jaeger 服务,并同时起一个新的 elasticsearch 容器
ceph orch apply jaeger
# 2) 使用已有的 elasticsearch 集群和已有的 jaeger query(只部署 agents 和 collectors)
ceph orch apply jaeger --without-query --es_nodes=ip:port,..
```
> 💡 补充:源文此页(972 字节)非常简短,未给出 tracing 服务的 spec 字段表、端口、镜像配置项等细节;相关镜像可用 `container_image_jaeger_agent` / `container_image_jaeger_collector` / `container_image_jaeger_query` 配置(见 7.9.6)。更多 tracing 细节需参考 Ceph Tracing 文档(`https://docs.ceph.com/en/latest/jaegertracing/#jaeger-distributed-tracing/`)。
> 引自:[Tracing Services](https://docs.ceph.com/en/tentacle/cephadm/services/tracing/)
### 7.13 Custom Container Service
orchestrator 支持通过 YAML 文件部署**自定义容器**。对应的 service spec 形如:
```yaml
service_type: container
service_id: foo
placement:
...
spec:
image: docker.io/library/foo:latest
entrypoint: /usr/bin/foo
uid: 1000
gid: 1000
args:
- "--net=host"
- "--cpus=2"
ports:
- 8080
- 8443
envs:
- SECRET=mypassword
- PORT=8080
- PUID=1000
- PGID=1000
volume_mounts:
CONFIG_DIR: /etc/foo
bind_mounts:
- ['type=bind', 'source=lib/modules', 'destination=/lib/modules', 'ro=true']
dirs:
- CONFIG_DIR
files:
CONFIG_DIR/foo.conf:
- refresh=true
- username=xyz
- "port: 1234"
```
#### 7.13.1 spec 字段逐项说明
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `service_id` | string | 无(必需) | 服务的唯一名称 |
| `image` | string | 无 | Docker 镜像名 |
| `uid` | int | 无 | 在主机系统上创建目录和文件时使用的 UID |
| `gid` | int | 无 | 在主机系统上创建目录和文件时使用的 GID |
| `entrypoint` | string | 镜像默认 ENTRYPOINT | 覆盖镜像的默认 ENTRYPOINT |
| `args` | list of string | 无 | 额外的 Podman/Docker 命令行参数列表 |
| `ports` | list of int | 无 | 需要在主机防火墙中放开的 **TCP 端口**列表 |
| `envs` | list of string | 无 | 环境变量列表 |
| `bind_mounts` | list | 无 | bind mount:把主机上的文件或目录挂载进容器。相对路径 `source=...` 位于 `/var/lib/ceph/<cluster-fsid>/<daemon-name>` 之下 |
| `volume_mounts` | mapping | 无 | volume mount:在主机 Docker 存储目录中创建新目录,内容由 Docker 管理。相对 source 路径位于 `/var/lib/ceph/<cluster-fsid>/<daemon-name>` 之下 |
| `dirs` | list of string | 无 | 需要创建的目录列表,位于 `/var/lib/ceph/<cluster-fsid>/<daemon-name>` 之下 |
| `files` | mapping(相对路径 → 内容) | 无 | 要创建的文件。key 是文件的相对路径,value 是文件内容。用字符串时内容**必须加双引号**,换行用 `\\n`;否则把多行内容定义为字符串列表。文件创建在 `/var/lib/ceph/<cluster-fsid>/<daemon-name>` 之下;**文件所在目录的绝对路径必须已存在**,必要时用 `dirs` 先创建 |
| `init_containers` | list of object | 无(可选) | "init container" 定义列表,用于在主容器启动前执行准备步骤;可以定义一个或多个 |
#### 7.13.2 init_containers 字段
init container 用于在**主容器启动前**运行预备步骤,可选,可定义一个或多个。每个定义可包含:
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
| `image` | string | 继承顶层 spec 的 `image` | init container 使用的镜像名 |
| `entrypoint` | string | 镜像默认 | 自定义镜像的默认 entrypoint |
| `entrypoint_args` | list | 无 | 传给 entrypoint 的参数,行为与通用 `extra_entrypoint_args` 字段相同 |
| `volume_mounts` | mapping | 继承主容器的取值 | 选择挂载进 init container 的 volume |
| `envs` | list of string | 无 | 环境变量列表 |
| `privileged` | bool | 继承主容器的取值 | 容器是否以特权模式运行 |
#### 7.13.3 带 init containers 的完整示例
```yaml
service_type: container
service_id: foo
placement:
...
spec:
image: quay.io/example/foosystem:latest
entrypoint: /usr/bin/foo
uid: 1000
gid: 1000
ports:
- 8889
dirs:
- CONFIG_DIR
- DATA_DIR
volume_mounts:
CONFIG_DIR: /etc/foo
DATA_DIR: /var/lib/foo
files:
CONFIG_DIR/foo.conf:
- db_path=/var/lib/foo/db
init_containers:
- image: quay.io/example/curly:howard
entrypoint: bash
entrypoint_args:
- argument: "-c"
- argument: "[ -f /var/lib/foo/db ] || curl -o /var/lib/foo/sample.dat https://foo.example.com/samples/1.dat"
volume_mounts:
DATA_DIR: /var/lib/foo
- entrypoint: /usr/bin/foo-initialize-db
entrypoint_args:
- "--option=threads=8"
- entrypoint: /usr/local/bin/import-sample-datasets.sh
entrypoint_args:
- "/var/lib/foo/sample.dat"
envs:
- FOO_SOURCE_MISSING=ignore
- FOO_CLEANUP=yes
```
> ⚠️ 注意:init containers 目前实现为「服务启动前运行的一个步骤」,**受启动超时约束**:**所有 init container 的总运行时间不能超过 200 秒**,否则服务将启动失败。
> 引自:[Custom Container Service](https://docs.ceph.com/en/tentacle/cephadm/services/custom-container/)
## 八、运维操作(Cephadm Operations)
### 8.1 查看 cephadm 日志消息
cephadm orchestrator module 会把日志写到 **`cephadm` cluster log channel**。
| 命令 | 用途 |
|---|---|
| `ceph -W cephadm` | 实时查看日志(默认只显示 **info 级别及以上**) |
| `ceph log last cephadm` | 查看最近的事件 |
要看 debug 级别消息:
```bash
ceph config set mgr mgr/cephadm/log_to_cluster_level debug
ceph -W cephadm --watch-debug
```
> ⚠️ 官方警告:debug 消息**非常冗长(very verbose)**。
这些事件同时也会被记录到 **monitor 主机上的 `ceph.cephadm.log` 文件**以及 monitor 守护进程的 **stderr**。
### 8.2 守护进程控制(Ceph daemon control)
#### 8.2.1 停止 / 启动 / 重启
单个守护进程:
```bash
ceph orch daemon stop <daemonid>
ceph orch daemon start <daemonid>
ceph orch daemon restart <daemonid>
```
整个服务的所有守护进程:
```bash
ceph orch stop <serviceid>
ceph orch start <serviceid>
ceph orch restart <serviceid>
```
> ⚠️ 注意:在**运行中的集群**上执行 `ceph orch restart osd.myosdservice` **通常是不安全的**——因为它不会顾及 CRUSH failure domain,并行的 OSD 重启可能导致数据暂时不可用,极端情况下甚至数据丢失。
#### 8.2.2 Redeploy 与 Reconfig
```bash
ceph orch daemon redeploy <name> [--image <image>]
```
该命令会停止容器、重新创建并重新启动它。可选提供容器镜像名,以强制使用特定镜像(而不是 `container_image` 配置项指定的镜像)。
如果**只需要重新生成 ceph 配置**,用 `reconfig`——它会重写 `ceph.conf` 文件但**不会触发守护进程重启**:
```bash
ceph orch daemon reconfig <name>
```
#### 8.2.3 轮换守护进程认证密钥
集群中所有 Ceph 与 gateway 守护进程都有一个用于连接并认证到集群的 secret key,可以轮换(替换为新 key):
```bash
ceph orch daemon rotate-key <name>
```
- 对 **MDS、OSD、MGR** 守护进程:**不需要重启**守护进程。
- 对**其它守护进程**(例如 RGW):**可能会重启**守护进程以切换到新 key。
### 8.3 Ceph 守护进程日志
#### 8.3.1 默认输出到 journald
Ceph 守护进程传统上写日志到 `/var/log/ceph`,但**默认改为写 journald**,由容器运行时环境捕获,通过 `journalctl` 访问。
> 注意:**Quincy 之前**,Ceph 守护进程日志写到 stderr。
示例:查看集群 ID 为 `5c5a50ae-272a-455d-99e9-32c6a013e694`、守护进程 `mon.foo` 的日志:
```bash
journalctl -u ceph-5c5a50ae-272a-455d-99e9-32c6a013e694@mon.foo
```
#### 8.3.2 改为输出到文件
启用文件日志(日志会出现在 `/var/log/ceph/<cluster-fsid>`):
```bash
ceph config set global log_to_file true
ceph config set global mon_cluster_log_to_file true
```
同时建议禁用 journald/stderr 日志,否则**所有内容会被记录两次**:
```bash
ceph config set global log_to_stderr false
ceph config set global mon_cluster_log_to_stderr false
ceph config set global log_to_journald false
ceph config set global mon_cluster_log_to_journald false
```
> 注意:也可以在 bootstrap 新集群时通过 `--log-to-file` 改变默认行为。
#### 8.3.3 修改日志保留策略
cephadm 默认在每台主机上配置了日志轮转。可通过修改 **`/etc/logrotate.d/ceph.<cluster-fsid>`** 配置保留策略。
### 8.4 每节点 cephadm 日志(Per-node cephadm logs)
`cephadm` 可执行文件(无论由用户直接执行,还是由 cephadm 编排模块执行)也会产生日志,且**独立于运行在容器中的其它 Ceph 组件**。默认写到文件 **`/var/log/ceph/cephadm.log`**。
该目的地可配置为:文件、syslog/journal,或两者。
#### 8.4.1 在 bootstrap 时设置
```bash
cephadm --log-dest=syslog bootstrap # ... 其它 bootstrap 参数 ...
```
`--log-dest` 可选 `file`、`syslog`,或两者。当这些选项用于 `cephadm bootstrap` 时,系统会**自动记录**这些设置,供后续由 cephadm 编排模块发起的 `cephadm` 调用使用。
也可以在初始配置文件的 `[mgr]` 段下添加 `mgr/cephadm/cephadm_log_destination`,独立于 `--log-dest` 精确指定:
```bash
cat >/tmp/bootstrap.conf <<EOF
[mgr]
mgr/cephadm/cephadm_log_destination = syslog
EOF
cephadm bootstrap --config /tmp/bootstrap.conf # ... 其它 bootstrap 参数 ...
```
#### 8.4.2 在已有集群上设置
```bash
# 让 cephadm 可执行文件写到 syslog
ceph config set mgr mgr/cephadm/cephadm_log_destination syslog
# 同时写到日志文件与 syslog
ceph config set mgr mgr/cephadm/cephadm_log_destination file,syslog
# 只写到日志文件
ceph config set mgr mgr/cephadm/cephadm_log_destination file
```
| 取值 | 含义 |
|---|---|
| `file` | 写到 `/var/log/ceph/cephadm.log` |
| `syslog` | 写到 syslog/journal |
| `file,syslog` | 两者都写 |
> 注意:如果**直接手工执行** cephadm 命令(例如 `cephadm shell`),该配置**不适用**;此时需使用上面 bootstrap 小节里描述的 `--log-dest` 选项。
### 8.5 数据位置(Data location)
| 路径 | 内容 |
|---|---|
| `/var/log/ceph/<cluster-fsid>` | 所有集群日志。默认 cephadm 通过 stderr 和容器运行时输出日志,**除非启用了文件日志,否则这些文件不存在** |
| `/var/lib/ceph/<cluster-fsid>` | 所有集群守护进程数据(日志除外) |
| `/var/lib/ceph/<cluster-fsid>/<daemon-name>` | 单个守护进程的全部数据 |
| `/var/lib/ceph/<cluster-fsid>/crash` | 集群的 crash 报告 |
| `/var/lib/ceph/<cluster-fsid>/removed` | 已被 cephadm 移除的**有状态**守护进程(如 monitor、prometheus)的旧数据目录 |
**磁盘使用建议**:由于少数 Ceph 守护进程(尤其是 **monitors** 和 **prometheus**)会在 `/var/lib/ceph` 下存放大量数据,建议把该目录**移到独立的磁盘、分区或逻辑卷**,避免撑爆根文件系统。
### 8.6 健康检查(Health checks)
cephadm 模块在集群默认健康检查之外提供额外健康检查,分两类:
| 类别 | 说明 |
|---|---|
| **cephadm operations** | 只要 cephadm 模块处于 active 就**始终执行** |
| **cluster configuration** | **可选**,关注集群中主机的配置一致性 |
#### 8.6.1 CEPHADM_PAUSED
**现象**:表示 cephadm 的后台工作已被 `ceph orch pause` 暂停。
**说明**:cephadm 仍会执行被动监控活动(如检查主机与守护进程状态),但**不会做任何变更**(如部署或移除守护进程)。
**恢复**:
```bash
ceph orch resume
```
#### 8.6.2 CEPHADM_STRAY_HOST
**现象**:一台或多台主机上运行着 Ceph 守护进程,但这些主机**没有注册为 cephadm 管理的主机**。
**影响**:这些服务当前无法被 cephadm 管理(例如无法 restart、upgrade,也不会出现在 `ceph orch ps` 中)。
**解决**:
```bash
ceph orch host add <hostname>
```
> 注意:执行前可能需要先配置到该远程主机的 SSH 访问。
其它处理方式:
- 参见 `cephadm-fqdn`(主机名与域名)章节;
- 或者手工登录该主机,确保上面的服务被移除,或迁移到一台由 cephadm 管理的主机;
- 也可用下面命令**完全关闭**该告警:
```bash
ceph config set mgr mgr/cephadm/warn_on_stray_hosts false
```
#### 8.6.3 CEPHADM_STRAY_DAEMON
**现象**:一个或多个 Ceph 守护进程在运行但**不受 cephadm 管理**(可能是用别的工具部署的,或者手工启动的),同样无法 restart / upgrade / 出现在 `ceph orch ps` 中。
**解决**:
- 若守护进程是**有状态的**(monitor 或 OSD),应**纳管(adopt)**它(见第十二章 `cephadm-adoption`);
- 对于**无状态**守护进程,通常最简单的做法是:用 `ceph orch apply` 新起一个守护进程,然后停掉那个不受管的;
- 若 stray 守护进程所在主机未被 cephadm 管理,可用 `ceph orch host add <hostname>` 管理该主机(可能需要先配置 SSH);
- 关闭该告警:
```bash
ceph config set mgr mgr/cephadm/warn_on_stray_daemons false
```
#### 8.6.4 CEPHADM_HOST_CHECK_FAILED
**现象**:一台或多台主机未通过 cephadm 的基础主机检查。
**原因**:该检查验证两件事:① 主机可达且 cephadm 能在其上执行;② 主机满足基本前提,如可用的容器运行时(podman 或 docker)与可用的时间同步。检查失败则 cephadm 无法管理该主机上的服务。
**排查与解决**:
```bash
# 手工运行该检查
ceph cephadm check-host <hostname>
# 把有问题的主机移出管理
ceph orch host rm <hostname>
# 关闭该健康告警
ceph config set mgr mgr/cephadm/warn_on_failed_host_check false
```
#### 8.6.5 Cluster Configuration Checks(集群配置检查)
cephadm 会周期性扫描集群中每台主机,以了解 **OS、磁盘、网络接口**等状态,然后跨主机做一致性分析,识别配置异常。
**启用**(**可选特性**):
```bash
ceph config set mgr mgr/cephadm/config_checks_enabled true
```
配置检查在**每次主机扫描后**触发。cephadm 日志中会显示检查的当前状态与结果:
| 状态 | 日志示例 |
|---|---|
| 已禁用(`config_checks_enabled false`) | `ALL cephadm checks are disabled, use 'ceph config set mgr mgr/cephadm/config_checks_enabled true' to enable` |
| 已启用 | `CEPHADM 8/8 checks enabled and executed (0 bypassed, 0 disabled). No issues detected` |
**子命令**:
```bash
# 查看配置检查是否启用(返回 "Enabled" 或 "Disabled")
ceph cephadm config-check status
# 列出所有配置检查及其状态
ceph cephadm config-check ls
# 禁用某个具体检查
ceph cephadm config-check disable <name>
# 例:
ceph cephadm config-check disable kernel_security
```
`ceph cephadm config-check ls` 的输出示例:
```text
NAME HEALTHCHECK STATUS DESCRIPTION
kernel_security CEPHADM_CHECK_KERNEL_LSM enabled check that SELINUX/Apparmor profiles are consistent across cluster hosts
os_subscription CEPHADM_CHECK_SUBSCRIPTION enabled check that subscription states are consistent for all cluster hosts
public_network CEPHADM_CHECK_PUBLIC_MEMBERSHIP enabled check that all hosts have a network interface on the Ceph public_network
osd_mtu_size CEPHADM_CHECK_MTU enabled check that OSD hosts share a common MTU setting
osd_linkspeed CEPHADM_CHECK_LINKSPEED enabled check that OSD hosts share a common network link speed
network_missing CEPHADM_CHECK_NETWORK_MISSING enabled check that the cluster/public networks as defined exist on the Ceph hosts
ceph_release CEPHADM_CHECK_CEPH_RELEASE enabled check for Ceph version consistency: all Ceph daemons should be the same release unless upgrade is in progress
kernel_version CEPHADM_CHECK_KERNEL_VERSION enabled checks that the maj.min version of the kernel is consistent across Ceph hosts
```
**8 项检查逐项说明**:
| NAME | HEALTHCHECK | 检查内容 |
|---|---|---|
| `kernel_security` | `CEPHADM_CHECK_KERNEL_LSM` | 集群内每台主机应处于相同的 **Linux Security Module(LSM)** 状态。例如若多数主机的 SELINUX 为 enforcing 模式,则任何不处于该模式的主机被标记为异常并触发 WARNING |
| `os_subscription` | `CEPHADM_CHECK_SUBSCRIPTION` | 与 OS 厂商订阅状态相关。**仅对使用 RHEL 的主机执行**,确认所有主机都被有效订阅覆盖,以保证补丁与更新可用 |
| `public_network` | `CEPHADM_CHECK_PUBLIC_MEMBERSHIP` | 集群所有成员都应至少在 public network 的某个子网内配置了网络接口。不在 public network 上的主机将依赖路由,可能影响性能 |
| `osd_mtu_size` | `CEPHADM_CHECK_MTU` | 检查运行 OSD 服务的主机,确保 MTU 在集群内配置一致。基准取**多数主机**使用的 MTU 设置,异常则触发健康检查 |
| `osd_linkspeed` | `CEPHADM_CHECK_LINKSPEED` | 与 MTU 检查类似,检查 OSD 主机网络接口的链路速度一致性。基准为多数 OSD 主机的链路速度,速率更低的主机触发健康检查 |
| `network_missing` | `CEPHADM_CHECK_NETWORK_MISSING` | `public_network` 与 `cluster_network` 支持 IPv4/IPv6 子网定义;若这些设置在集群中**任何主机上都找不到**,则触发健康检查 |
| `ceph_release` | `CEPHADM_CHECK_CEPH_RELEASE` | 正常情况下集群所有守护进程应为同一 Ceph release(如 Reef)。本检查确定每个守护进程的 active release,异常则报告为健康检查。**升级进行中时该检查会被 bypass** |
| `kernel_version` | `CEPHADM_CHECK_KERNEL_VERSION` | 检查各主机 OS kernel 版本(maj.min)一致性,以多数主机的 kernel 版本为基准识别异常 |
### 8.7 Client keyrings and configs
cephadm 可以把 `ceph.conf` 与 client keyring 文件**分发到主机**。
从 **16.2.10(Pacific)与 17.2.1(Quincy)** 起,除默认位置 `/etc/ceph/` 之外,cephadm 还会把 config 与 keyring 文件存放在 **`/var/lib/ceph/<fsid>/config`** 目录。
> 注意:**Ceph 守护进程仍然使用 `/etc/ceph/` 下的文件**;新位置 `/var/lib/ceph/<fsid>/config` **仅被 cephadm 使用**。把该配置目录放在 fsid 之下,有助于 cephadm 加载与集群关联的配置。
通常建议在**任何用于 CLI 管理集群的主机**上保存一份 config 与 `client.admin` keyring。默认情况下,cephadm 会为带 `_admin` label 的所有节点做这件事(通常包含 bootstrap 主机)。
**当一个 client keyring 被纳入管理,cephadm 会**:
- 基于指定的 placement spec 构建目标主机列表;
- 在指定主机上保存 `/etc/ceph/ceph.conf` 的副本;
- 在指定主机上保存 `ceph.conf` 到 `/var/lib/ceph/<fsid>/config/ceph.conf`;
- 在指定主机上保存 `ceph.client.admin.keyring` 到 `/var/lib/ceph/<fsid>/config/ceph.client.admin.keyring`;
- 在指定主机上保存 keyring 文件的副本;
- 按需更新 `ceph.conf`(例如集群 monitors 发生变化时);
- 若该 entity 的 key 被改变(例如通过 `ceph auth ...` 命令),更新 keyring 文件;
- 确保 keyring 文件具有指定的属主与 mode;
- 当 client keyring 管理被禁用时移除该 keyring 文件;
- 若 keyring 的 placement spec 被更新,按需从旧主机上移除 keyring 文件。
#### 8.7.1 命令
```bash
# 列出当前受管的 client keyrings
ceph orch client-keyring ls
# 把一个 keyring 纳入管理
ceph orch client-keyring set <entity> <placement> [--mode=<mode>] [--owner=<uid>.<gid>] [--path=<path>]
# 取消对某个 keyring 文件的管理
ceph orch client-keyring rm <entity>
```
| 参数 | 默认值 | 含义 |
|---|---|---|
| `<entity>` | 无 | Cephx entity 名 |
| `<placement>` | 无 | placement spec;`*`(所有主机)是常见取值 |
| `--mode` | `0600` | keyring 文件权限 |
| `--owner` | `0:0`(user root, group root) | keyring 文件属主 |
| `--path` | `/etc/ceph/client.{entity}.keyring` | 存放路径(这是 Ceph 默认查找的位置)。**指定其它位置时要小心,已有文件可能被覆盖** |
| `--no-ceph-conf` | 不指定 | 默认 cephadm 还会在写入 keyring 的主机上管理 `/etc/ceph/ceph.conf`;用该选项可**抑制**此行为 |
范例:创建一个 `client.rbd` key 并部署到带 `rbd-client` label 的主机,且让 uid/gid 107(qemu)组可读:
```bash
ceph auth get-or-create-key client.rbd mon 'profile rbd' mgr 'profile rbd' osd 'profile rbd pool=my_rbd_pool'
ceph orch client-keyring set client.rbd label:rbd-client --owner 107:107 --mode 640
```
生成的 keyring 文件:
```text
-rw-r-----. 1 qemu qemu 156 Apr 21 08:47 /etc/ceph/client.client.rbd.keyring
```
抑制 `ceph.conf` 管理:
```bash
ceph orch client-keyring set client.foo label:foo 0:0 --no-ceph-conf
```
> 注意:`ceph orch client-keyring rm <entity>` **会删除**此前写入到集群节点的该 entity 的所有 keyring 文件。
### 8.8 /etc/ceph/ceph.conf 的分发
#### 8.8.1 向没有 keyring 的主机分发 ceph.conf
默认 cephadm **只在同时分发了 client keyring 的主机上**部署 `ceph.conf`。要向没有 client keyring 的主机写配置文件:
```bash
ceph config set mgr mgr/cephadm/manage_etc_ceph_ceph_conf true
```
#### 8.8.2 用 placement spec 指定哪些主机获得 ceph.conf
默认配置会写到**所有主机**(即 `ceph orch host ls` 列出的主机)。要指定范围:
```bash
ceph config set mgr mgr/cephadm/manage_etc_ceph_ceph_conf_hosts <placement spec>
```
例如分发到带 `bare_config` label 的主机:
```bash
ceph config set mgr mgr/cephadm/manage_etc_ceph_ceph_conf_hosts label:bare_config
```
### 8.9 限制 Password-less sudo 访问
默认 cephadm 安装指南建议为 cephadm 用户启用 password-less `sudo`——最灵活、最具前瞻性,但并非所有环境都接受。管理员可以把 `sudo` 限制为**仅允许无密码运行一份精确的命令清单**。
> 注意:该清单**可能随 Ceph 版本变化**;选择此方式的管理员在升级前应阅读目标版本的 release notes 与该版本文档中的清单。若清单有差异,必须在升级**前**扩充 password-less `sudo` 命令清单。
**需要 password-less sudo 支持的命令**:
| 命令 | 备注 |
|---|---|
| `chmod` | |
| `chown` | |
| `ls` | |
| `mkdir` | |
| `mv` | |
| `rm` | |
| `sysctl` | |
| `touch` | |
| `true` | |
| `which` | 见下方说明 |
| `/usr/bin/cephadm` 或 python 可执行文件 | 见下方说明 |
> 说明:通常 cephadm 会执行 `which` 来确定可用的 python3 命令,然后在后续命令中使用 `which` 返回的结果。配置 `sudo` **之前**请先运行 `which python3` 以确定要加入 sudo 配置的 python 命令。在极少数配置中会使用 `/usr/bin/cephadm` 代替。
`sudoers` 文件可用 `visudo` 等工具配置,添加/替换如下用户配置行:
```text
# 假设 cephadm 用户名为 "ceph"
ceph ALL=(ALL) NOPASSWD:/usr/bin/chmod,/usr/bin/chown,/usr/bin/ls,/usr/bin/mkdir,/usr/bin/mv,/usr/bin/rm,/usr/sbin/sysctl,/usr/bin/touch,/usr/bin/true,/usr/bin/which,/usr/bin/cephadm,/usr/bin/python3
```
### 8.10 清除集群(Purging a cluster)
> ☠️ **危险:此操作会摧毁该集群中存储的全部数据。**
步骤:
1. 禁用 cephadm 以停止所有编排操作(避免继续部署新守护进程):
```bash
ceph mgr module disable cephadm
```
2. 确认集群的 FSID:
```bash
ceph fsid
```
3. 从集群所有主机上清除 ceph 守护进程(**对每台主机**执行):
```bash
cephadm rm-cluster --force --zap-osds --fsid <fsid>
```
### 8.11 替换设备(Replacing a device)
`ceph orch device replace` 命令**自动化**了替换 OSD 底层设备的流程(此前该流程在多个阶段需要人工介入):
```bash
ceph orch device replace <host> <device-path>
```
> 注意:**仅支持基于 LVM 部署的 OSD**。
**共享设备场景**:如果被替换的设备被多个 OSD 共享(例如 DB/WAL 设备被多个 OSD 共享),orchestrator 会告警:
```text
[ceph: root@ceph /]# ceph orch device replace osd-1 /dev/vdd
Error EINVAL: /dev/vdd is a shared device.
Replacing /dev/vdd implies destroying OSD(s): ['0', '1'].
Please, *be very careful*, this can be a very dangerous operation.
If you know what you are doing, pass --yes-i-really-mean-it
```
确认无误后加上 `--yes-i-really-mean-it`:
```text
[ceph: root@ceph /]# ceph orch device replace osd-1 /dev/vdd --yes-i-really-mean-it
Scheduled to destroy osds: ['6', '7', '8'] and mark /dev/vdd as being replaced.
```
`cephadm` 会让 `ceph-volume` zap 并销毁所有相关设备,并把对应 OSD 标记为 `destroyed`,**从而保留原有 OSD ID**:
```text
[ceph: root@ceph-1 /]# ceph osd tree
ID CLASS WEIGHT TYPE NAME STATUS REWEIGHT PRI-AFF
-1 0.97659 root default
-3 0.97659 host devel-1
0 hdd 0.29300 osd.0 destroyed 1.00000 1.00000
1 hdd 0.29300 osd.1 destroyed 1.00000 1.00000
2 hdd 0.19530 osd.2 up 1.00000 1.00000
3 hdd 0.19530 osd.3 up 1.00000 1.00000
```
被替换的设备会被标记为 `being replaced`,**防止 cephadm 过快重新部署 OSD**:
```text
[ceph: root@ceph-1 /]# ceph orch device ls
HOST PATH TYPE DEVICE ID SIZE AVAILABLE REFRESHED REJECT REASONS
osd-1 /dev/vdb hdd 200G Yes 13s ago
osd-1 /dev/vdc hdd 200G Yes 13s ago
osd-1 /dev/vdd hdd 200G Yes 13s ago Is being replaced
osd-1 /dev/vde hdd 200G No 13s ago Has a FileSystem, Insufficient space (<10 extents) on vgs, LVM detected
osd-1 /dev/vdf hdd 200G No 13s ago Has a FileSystem, Insufficient space (<10 extents) on vgs, LVM detected
```
**清除 replace 标记**:
```bash
ceph orch device replace <host> <device> --clear
```
```text
[ceph: root@devel-1 /]# ceph orch device replace devel-1 /dev/vdk --clear
Replacement header cleared on /dev/vdk
```
之后,cephadm 会在几分钟内重新部署 OSD 服务 spec(**除非该服务被设为 `unmanaged`**)。
### 8.12 cephadm shell 与进入容器
| 命令 | 用途 |
|---|---|
| `cephadm shell` | 启动一个带完整 Ceph 工具环境的容器 shell(设置的环境适合做扩展的守护进程维护与交互式运行守护进程) |
| `cephadm shell --name <daemon-name>` | 进入指定守护进程的容器环境,可运行 `ceph-objectstore-tool`、`ceph-monstore-tool` 等工具 |
| `cephadm enter --name <daemon-name>` | **进入**守护进程容器本身(用于访问 admin socket 等) |
| `cephadm unit --name <daemon-name> stop` | 停止该守护进程的 systemd unit |
典型用法(以 mon 为例):
```bash
root@myhostname # cephadm unit --name mon.myhostname stop
root@myhostname # cephadm shell --name mon.myhostname
[ceph: root@myhostname /]# ceph-monstore-tool /var/lib/ceph/mon/ceph-myhostname get monmap > monmap
[ceph: root@myhostname /]# monmaptool --print monmap
monmaptool: monmap file monmap
epoch 1
fsid 28596f44-3b56-11ec-9034-482ae35a5fbb
last_changed 2021-11-01T20:57:19.755111+0000
created 2021-11-01T20:57:19.755111+0000
min_mon_release 17 (quincy)
election_strategy: 1
0: [v2:127.0.0.1:3300/0,v1:127.0.0.1:6789/0] mon.myhostname
```
> 引自:[Cephadm Operations](https://docs.ceph.com/en/tentacle/cephadm/operations/)
## 九、升级(Upgrading Ceph)
cephadm 可以安全地把 Ceph 从一个 point release 升级到下一个(例如 v15.2.0 → v15.2.1)。
自动升级流程遵循 Ceph 最佳实践:
- **升级顺序**:从 managers 开始,然后 monitors,再其它守护进程;
- **每个守护进程只有在 Ceph 确认集群仍将保持可用之后才会重启**。
> 注意:升级期间集群健康状态很可能会切换为 `HEALTH_WARNING`。
>
> 注意:如果某台集群主机不可用(或在升级过程中变为不可用),**升级会被暂停**,直到该主机恢复。
>
> 注意:当**任何** pool 的 PG autoscaler mode 为 `on` 时,建议在升级期间**关闭 autoscaler**,以免升级中途发生 PG split/merge 拖延升级进度。在超大规模集群中这可能轻易使完成时间增加一天以上,尤其当该升级恰好改变了 PG autoscaler 行为(例如 `mon_target_pg_per_osd` 的默认值)时。
> ```bash
> ceph osd pool set noautoscale
> # 执行升级
> ceph osd pool unset noautoscale
> ```
> 以这种方式暂停 autoscaler 时,每个 pool 现有的 mode(`off`/`on`/`warn`)预期会保持。如果新版本改变了上述 target 值,unset 之后**可能**发生 PG 的 splitting 或 merging。
### 9.1 升级前的准备
#### 9.1.1 CephFS 相关:`fail_fs` 选项
> 注意:使用下述 CephFS 升级特性**可能需要**对 Monitors 与 Managers 采用 `Staggered Upgrade`。
cephadm **默认会把 `max_mds` 降为 `1`**。对大规模 CephFS 部署这具有破坏性:集群无法快速把 active MDS 降到 `1`,且单个 active MDS 即使短时间也难以承载所有客户端负载。因此,若要在**不降低 `max_mds`** 的情况下升级 MDS,需在发起升级前把 `fail_fs` 设为 `true`(**默认 `false`**):
```bash
ceph config set mgr mgr/orchestrator/fail_fs true
```
该选项的效果:
1. **Fail CephFS filesystems**:把 active MDS 守护进程带到 `up:standby` 状态;
2. 安全升级 MDS 守护进程;
3. 把 CephFS filesystems 重新拉起,active MDS 从 `up:standby` 回到 `up:active`。
#### 9.1.2 确认集群状态
```bash
ceph -s
```
### 9.2 开始升级
```bash
ceph orch upgrade start --ceph-version <version>
```
例如升级到 v16.2.6:
```bash
ceph orch upgrade start --ceph-version 16.2.6
```
> 注意:**从 v16.2.6 起不再使用 Docker Hub registry**,因此如果使用 Docker,必须指向 quay.io registry 中的镜像:
```bash
ceph orch upgrade start --image quay.io/ceph/ceph:v16.2.6
```
### 9.3 监控升级进度
```bash
# 判断(1)是否有升级在进行(2)集群正在升级到哪个版本
ceph orch upgrade status
```
升级期间,`ceph status` 输出中会出现进度条:
```text
# ceph -s
[...]
progress:
Upgrade to docker.io/ceph/ceph:v15.2.1 (00h 20m 12s)
[=======.....................] (time remaining: 01h 43m 31s)
```
也可以实时观察 cephadm 日志:
```bash
ceph -W cephadm
```
### 9.4 取消升级
```bash
ceph orch upgrade stop
```
可以随时停止升级过程。
### 9.5 升级后的动作
如果新版本是基于 `cephadm` 的,升级完成后用户必须把 **`cephadm` 包**(若不使用 `cephadm shell`,则是 **ceph-common 包**)更新到与新版本兼容的版本。
### 9.6 常见问题与故障处理
| 现象 | 原因 | 解决 |
|---|---|---|
| `ceph orch upgrade status` 返回 `Error ENOENT: Module not found` | orchestrator **已崩溃**;可能由某个 mgr config-key 中的**非法 JSON** 引起(参见 Redmine Issue #67329 与 ceph-users 邮件列表讨论) | 排查并修正 mgr config-key 中的非法 JSON |
| 告警 `UPGRADE_NO_STANDBY_MGR` | Ceph 未检测到 active standby Manager 守护进程。继续升级**必须**有一个 active standby Manager(可理解为"第二个 manager") | `ceph orch apply mgr 2`(或更多);用 `ceph orch ps --daemon-type mgr` 查看现有 Manager 状态;若某 Manager 已停止,用 `ceph orch daemon restart <name>` 尝试重启 |
| 告警 `UPGRADE_FAILED_PULL` | Ceph 无法拉取目标版本的容器镜像。可能指定的版本/镜像不存在(如 "1.2.3"),或集群中一台或多台主机无法访问容器 registry | 先 `ceph orch upgrade stop`,再用 `ceph orch upgrade start --ceph-version <version>` 指定其它目标版本 |
### 9.7 使用自定义容器镜像升级
对多数用户,升级只需指定 Ceph 版本即可:cephadm 通过把 `container_image_base` 配置项(**默认 `docker.io/ceph/ceph`**)与 `vX.Y.Z` 形式的 tag 组合,来定位要使用的 Ceph 容器镜像。
也可以升级到任意容器镜像,例如某个开发构建:
```bash
ceph orch upgrade start --image quay.ceph.io/ceph-ci/ceph:recent-git-branch-name
```
### 9.8 Staggered Upgrade(分阶段升级)
从 **16.2.11 与 17.2.1** 起,upgrade 命令支持参数来限制**单次**升级命令影响哪些守护进程。
| 参数 | 说明 |
|---|---|
| `daemon_types` | 逗号分隔的守护进程类型列表,只升级这些类型的守护进程 |
| `services` | 与 `daemon_types` **互斥**;一次只能接受一种服务类型(例如不能同时给 OSD 和 RGW 服务);只升级属于这些服务的守护进程 |
| `hosts` | 可与 `daemon_types` 或 `services` 组合,也可单独提供;格式与 placement spec 的命令行选项相同 |
| `limit` | 取值 **> 0** 的整数,对 cephadm 将升级的守护进程数量提供数值上限;**可与任何其它参数组合** |
例如:指定在 host1、host2 上升级 osd 类型守护进程且 `limit=3`,则 cephadm 会升级 Host1 上(最多)3 个 osd 守护进程。
**示例 1:指定 daemon types 与 hosts**
```bash
ceph orch upgrade start --image <image-name> --daemon-types mgr,mon --hosts host1,host2
```
**示例 2:指定 services 并使用 limit**
```bash
ceph orch upgrade start --image <image-name> --services rgw.example1,rgw.example2 --limit 2
```
> 注意:**cephadm 在 staggered upgrade 场景下仍严格执行守护进程升级顺序**,当前顺序为:
> `mgr -> mon -> crash -> osd -> mds -> rgw -> rbd-mirror -> cephfs-mirror -> iscsi -> nfs`
> 如果指定的参数会导致守护进程**乱序**升级,upgrade 命令会**阻塞**并提示继续执行会漏掉哪些守护进程。
>
> 注意:带限制参数的升级命令会在开始前**校验选项**,这可能需要拉取新容器镜像;因此带限制参数时 `upgrade start` 命令**返回较慢**是正常现象。
>
> 注意:在 staggered upgrade 场景(提供了限制参数)下,**监控栈守护进程(含 Prometheus 与 node-exporter)会在 Manager 守护进程升级完成后被刷新**,因此 Manager 升级耗时可能比预期长。注意监控栈守护进程的版本在不同 Ceph release 之间**可能不变**,此时它们只是被 redeploy。
#### 9.8.1 从「不支持 staggered upgrade」的版本升级到「支持」的版本
若源版本已支持 staggered upgrade,直接提供必要参数即可。若要升级到支持 staggered upgrade 的版本、而源版本不支持,则需要一个 workaround:**先手工升级 Manager 守护进程**,然后照常传限制参数。
> ⚠️ 警告:执行该过程前,**请确保有多个运行中的 mgr 守护进程**。
步骤:
1. 确定哪个 Manager 是 active、哪些是 standby(例如看 `ceph -s` 输出);
2. 手工升级每个 **standby** mgr 守护进程:
```bash
ceph orch daemon redeploy mgr.example1.abcdef --image <new-image-name>
```
> 注意:如果 cephadm 版本非常早(Octopus 早期),`orch daemon redeploy` 可能**没有 `--image` 参数**。这种情况下必须手工设置 Manager 容器镜像 `ceph config set mgr container_image <new-image-name>`,然后再 redeploy:`ceph orch daemon redeploy mgr.example1.abcdef`。
3. 触发 Manager failover,使 active Manager 变为运行新版本的那个:
```bash
ceph mgr fail
```
4. 验证 active Manager 已是新版本;然后完成 Manager 升级:
```bash
ceph orch upgrade start --image <new-image-name> --daemon-types mgr
```
至此所有 Manager 守护进程都在新版本上,可以为其后的升级指定限制参数了。
### 9.9 更新非 Ceph 镜像的服务
```bash
ceph orch update service <service_type> <image>
```
例如:
```bash
ceph orch update service prometheus quay.io/prometheus/prometheus:v2.55.1
```
> 引自:[Upgrading Ceph](https://docs.ceph.com/en/tentacle/cephadm/upgrade/)
## 十、证书管理(Certificate Management)
### 10.1 简介
Cephadm `certmgr` 充当 **Root Certificate Authority(CA)**,为 Cephadm 生成的**所有自签名证书**提供根 CA。对需要 SSL 的服务,管理员可以:① 自带证书(bring your own certificate),或 ② 让 Cephadm 生成自签名证书。
### 10.2 证书管理行为
`certmgr` 会**自动检测**一个证书是自签名的(由 Cephadm 生成)还是用户提供的,这决定了它如何处理过期与续期:
| 证书类型 | 行为 |
|---|---|
| **Self-Signed Certificates**(自签名) | `certmgr` 可以**全自动续期**,确保服务无缝运行。自动化受若干配置参数控制:证书有效期(duration)、续期阈值(renewal threshold),以及是否启用自动轮换(automated rotation) |
| **User-Provided Certificates**(用户提供) | `certmgr` **不会自动续期**,但会持续监控其状态。一旦发现问题(例如临近过期),会发出健康告警/错误 **`CEPHADM_CERT_ERROR`** 提醒管理员,由管理员**手工替换**证书 |
### 10.3 配置项逐项说明
| 配置项 | 默认值 | 取值范围 | 含义 |
|---|---|---|---|
| `mgr/cephadm/certificate_automated_rotation_enabled` | `True` | bool | 控制 Cephadm 是否在证书到期时**自动轮换**。默认启用,无需人工干预即可保证连续性与安全性。**禁用后**,cephadm 仍会周期性检查证书,但不会自动续期已过期的自签名证书,而是在发现问题时发出 health error/warning |
| `mgr/cephadm/certificate_duration_days` | `3 * 365` | min `90`,max `10 * 365` | 由 Cephadm root CA 生成并签名的**自签名证书的有效天数**,决定需要续期前的使用期限 |
| `mgr/cephadm/certificate_renewal_threshold_days` | `30` | min `10`,max `90` | 在证书过期**前多少天** Cephadm 应发起续期,确保在过期前及时替换。**同时适用于自签名与用户提供的证书**;对用户提供的证书,Cephadm 会发出 health error 或 warning 提醒管理员续期临近 |
| `mgr/cephadm/certificate_check_period` | `1` | min `0`,max `30` | 每隔多少**天**检查一次证书有效性。设为 `0` 会**禁用证书检查功能** |
设置示例:
```bash
ceph config set mgr mgr/cephadm/certificate_automated_rotation_enabled true
ceph config set mgr mgr/cephadm/certificate_duration_days 365
ceph config set mgr mgr/cephadm/certificate_renewal_threshold_days 30
ceph config set mgr mgr/cephadm/certificate_check_period 1
```
### 10.4 证书健康监控
Cephadm 持续监控受管证书的状态:
- 若发现任何证书**无效或已过期**,发出 health error,代码 **`CEPHADM_CERT_ERROR`**;
- 若证书**临近过期**,发出 health warning。
### 10.5 已知证书与密钥(Known Certificates and Keys)
`CertMgr` 类维护一份已知证书与密钥列表。
> 💡 补充:源文此处用 `automodule:: mgr.cephadm.cert_mgr`(`known_certs`、`known_keys`)自动生成,具体的证书名/密钥名清单在抓取到的 rst 文本中未以明文出现,故本册不逐一列出;实际可用 `ceph orch certmgr cert ls` 与 `ceph orch certmgr key ls` 查询。
### 10.6 证书作用域(Certificate Scopes)
cephadm certmgr 支持三种不同的证书管理作用域:
| 作用域 | 说明 | 示例 |
|---|---|---|
| **Global Scope** | 证书在**所有服务守护进程间共享**,无论运行在哪个主机上 | `mgmt-gateway` 证书是全局共享证书,被所有服务守护进程使用 |
| **Per-Host Scope** | 证书按主机分配,**每台主机有自己唯一的证书**。配置自定义证书时必须指定该证书适用于哪台主机 | `grafana` 服务证书在**主机级别**配置,仅适用于单台机器 |
| **Per-Service Scope** | 证书按服务名配置,**服务的每个实例可以有自己的证书**。指定自定义证书时必须定义其所属的服务 | `rgw` 服务证书被专门且仅分配给某个 RGW 服务 |
### 10.7 certmgr 命令速查
| 命令 | 用途 |
|---|---|
| `ceph orch certmgr reload` | 从 Monitors 重新加载证书管理器配置,**无需重启服务**即可立即应用变更 |
| `ceph orch certmgr cert ls [--show-details]` | 列出 orchestrator 管理的所有证书;`--show-details` 提供额外信息,包括颁发机构与证书扩展项 |
| `ceph orch certmgr entity ls` | 列出与证书关联的所有 entity(entity 即使用受管证书的服务) |
| `ceph orch certmgr cert check` | 检查所有受管证书的完整性与过期状态 |
| `ceph orch certmgr key ls` | 列出与受管证书关联的所有私钥 |
| `ceph orch certmgr cert get <certificate_name> [--service_name <value>] [--hostname <value>] [--no-exception-when-missing]` | 获取指定证书内容。对 host/service scope 的证书,按需加 `--hostname` 或 `--service_name` |
| `ceph orch certmgr key get <key_name> [--service_name <value>] [--hostname <value>] [--no-exception-when-missing]` | 获取指定证书关联的私钥,同上 |
| `ceph orch certmgr cert-key set <entity> [--cert <value>] [--key <value>] [--service_name <value>] [--hostname <value>] [-i <cert-key-path>] [--force]` | 为某服务上传或替换证书/密钥对。`-i` 指定一个 PEM 格式文件,其中**证书与私钥拼接在一起** |
| `ceph orch certmgr cert set <certificate_name> [--cert <value>] [--service_name <value>] [--hostname <value>] [-i <cert-path>]` | 更新或设置新证书 |
| `ceph orch certmgr key set <key-name> [--key <value>] [--service_name <value>] [--hostname <value>] [-i <key-path>]` | 为服务提供新的私钥 |
| `ceph orch certmgr cert rm <certificate_name> [--service_name <value>] [--hostname <value>]` | 移除已有证书 |
| `ceph orch certmgr key rm <key-name> [--service_name <value>] [--hostname <value>]` | 移除已有私钥 |
| `ceph orch certmgr generate-certificates <module_name>` | 为指定的 Manager module 自动生成新的证书与密钥对 |
参数说明:
| 参数 | 含义 |
|---|---|
| `<certificate_name>` / `<key_name>` | 必须是有效的证书/密钥名;分别用 `ceph orch certmgr cert ls` / `ceph orch certmgr key ls` 查看支持的名字 |
| `<entity>` | 用 `ceph orch certmgr entity ls` 查看实际 entity 名 |
| `--service_name <value>` | 指定 service scope 的目标 |
| `--hostname <value>` | 指定 host scope 的目标 |
| `-i <path>` | 从文件读入(PEM 格式) |
| `--force` | (`cert-key set`)强制覆盖 |
| `--no-exception-when-missing` | (`cert get` / `key get`)缺失时不抛异常 |
> ⚠️ 注意:`cert rm` 与 `key rm` 对 host 或 service scope 的证书/密钥,**必须**用 `--service-name` 或 `--hostname` 指定目标。
> 💡 补充:源文第 274 行原命令写作 `cehp orch certmgr generate-certificates <module_name>`(`cehp` 为官方文档笔误),本册已按正确命令 `ceph orch certmgr generate-certificates <module_name>` 记录。
> 引自:[Certificate Management](https://docs.ceph.com/en/tentacle/cephadm/certmgr/)
## 十一、客户端配置(Basic Ceph Client Setup)
客户端主机需要基本配置才能与 Ceph 集群交互。
> 注意:**多数客户端主机只需要安装 `ceph-common` 包及其依赖**。这样的安装提供基础的 `ceph` 与 `rados` 命令,以及 `mount.ceph`、`rbd` 等其它命令。
### 11.1 配置文件(Config File Setup)
客户端主机所需的配置文件通常比后端集群主机更小。生成最小配置文件的步骤:
1. 登录到一台**已配置为客户端**的主机,或一台**正在运行集群守护进程**的主机;
2. 执行:
```bash
ceph config generate-minimal-conf
```
该命令生成的最小配置文件告诉客户端**如何到达 Ceph Monitors**。该文件通常应被复制到每台客户端主机的 **`/etc/ceph/ceph.conf`**。
### 11.2 Keyring(Keyring Setup)
多数 Ceph 集群启用认证,这意味着客户端需要 key 才能与 Ceph 守护进程通信。为 `client.fs` 生成 keyring 文件:
```bash
ceph auth get-or-create client.fs
```
生成的输出应被写入 keyring 文件,通常是 **`/etc/ceph/ceph.keyring`**。
### 11.3 相关阅读
- 想更全面地了解 client keyring 的分发与管理,参见本册 8.7 节(Client keyrings and configs)。
- 想看如何把 `ceph.conf` 分发到带 `bare_config` label 的主机,参见本册 8.8 节。
> 引自:[Basic Ceph Client Setup](https://docs.ceph.com/en/tentacle/cephadm/client-setup/)
## 十二、纳管已有集群(Converting an existing cluster to cephadm)
可以把**部分**已有集群转换为可由 `cephadm` 管理的状态。这适用于一些用 **`ceph-deploy`**、**`ceph-ansible`** 或 **DeepSea** 部署的集群。
### 12.1 限制
- **Cephadm 只支持 BlueStore OSD。**
### 12.2 准备(Preparation)
1. 确保 `cephadm` 命令行工具在已有集群的**每台主机**上都可用(参见获取 cephadm 的章节)。
2. 在每台主机上执行,使其为 `cephadm` 所用:
```bash
cephadm prepare-host
```
3. 选择用于转换的 Ceph 版本:**Octopus(15.2.z)或更高**均可,默认使用**最新的 stable release**。如果在转换的同时还要从更早的 Ceph 版本升级,请务必遵循该版本的升级相关说明。
通过如下方式把 Ceph 容器镜像传给 cephadm:
```bash
cephadm --image $IMAGE <rest of command goes here>
```
4. 通过 `cephadm ls` 确认转换正在进行,并确认守护进程的 **style 已改变**:
```bash
cephadm ls
```
转换开始前,`cephadm ls` 报告所有已存在守护进程的 style 为 **`legacy`**;随着纳管过程推进,被纳管的守护进程会以 style **`cephadm:v1`** 出现。
### 12.3 纳管流程(Adoption process)
**第 1 步:把 ceph 配置迁移到集群的中央配置数据库。**
如果 `/etc/ceph/ceph.conf` 在所有主机上都相同,则可在**一台**主机上执行下面的命令,效果对所有主机生效:
```bash
ceph config assimilate-conf -i /etc/ceph/ceph.conf
```
如果各主机之间存在配置差异,则需在**每台主机**上重复该命令;注意若各主机之间存在冲突的选项设置,**以最后一台主机的值为准**。
纳管过程中可用下面的命令查看集群中央配置,确认其完整:
```bash
ceph config dump
```
**第 2 步:纳管每个 Monitor。**
```bash
cephadm adopt --style legacy --name mon.<hostname>
```
每个 legacy Monitor 会停止,然后**快速以 cephadm 容器形式重启**,并重新加入 quorum。
**第 3 步:纳管每个 Manager。**
```bash
cephadm adopt --style legacy --name mgr.<hostname>
```
**第 4 步:启用 cephadm 编排。**
```bash
ceph mgr module enable cephadm
ceph orch set backend cephadm
```
**第 5 步:为 cephadm 生成 SSH key。**
```bash
ceph cephadm generate-key
ceph cephadm get-pub-key > ~/ceph.pub
```
**第 6 步:把 cephadm SSH key 安装到集群的每台主机。**
```bash
ssh-copy-id -f -i ~/ceph.pub root@<host>
```
> 注意:也可以导入已有的 SSH key,参见排障文档中的 "SSH errors" 部分。
>
> 注意:也可以让 cephadm 使用**非 root 用户** SSH 登录集群主机。该用户需要具有 passwordless sudo 访问权限。使用 `ceph cephadm set-user <user>`,并把 SSH key 复制到每台主机上该用户的 home 目录。参见 `cephadm-ssh-user`。
**第 7 步:告诉 cephadm 要管理哪些主机。**
```bash
ceph orch host add <hostname> [ip-address]
```
添加前会在每台主机上运行 **`cephadm check-host`**,以确保主机功能正常。**建议提供 IP 地址参数**;若不提供,则通过 DNS 解析主机名。
**第 8 步:验证被纳管的 monitor 与 manager 守护进程可见。**
```bash
ceph orch ps
```
**第 9 步:纳管集群中的所有 OSD。**
```bash
cephadm adopt --style legacy --name <name>
```
例如:
```bash
cephadm adopt --style legacy --name osd.1
cephadm adopt --style legacy --name osd.2
```
**第 10 步:重新部署 CephFS MDS 守护进程(如已部署)。**
告诉 cephadm 每个文件系统要运行多少个守护进程。先用 `ceph fs ls` 按名称列出 CephFS 文件系统,然后在 master 节点上运行:
```bash
ceph orch apply mds <fs-name> [--placement=<placement>]
```
例如,集群中有一个名为 `foo` 的文件系统:
```bash
ceph fs ls
```
```text
name: foo, metadata pool: foo_metadata, data pools: [foo_data ]
```
```bash
ceph orch apply mds foo 2
```
确认新的 MDS 守护进程已启动:
```bash
ceph orch ps --daemon-type mds
```
最后,停止并移除 legacy MDS 守护进程:
```bash
systemctl stop ceph-mds.target
rm -rf /var/lib/ceph/mds/ceph-*
```
**第 11 步:重新部署 Ceph Object Gateway RGW 守护进程(如已部署)。**
Cephadm **按 zone 管理** RGW 守护进程。对每个 zone,用 cephadm 部署新的 RGW 守护进程:
```bash
ceph orch apply rgw <svc_id> [--realm=<realm>] [--zone=<zone>] [--port=<port>] [--ssl] [--placement=<placement>]
```
其中 `<placement>` 可以是简单的守护进程数量,也可以是具体主机列表(参见 placement spec)。**`zone` 与 `realm` 参数仅在 multisite 部署中需要**。
守护进程启动并确认功能正常后,停止并移除 legacy 守护进程:
```bash
systemctl stop ceph-rgw.target
rm -rf /var/lib/ceph/radosgw/ceph-*
```
**第 12 步:检查 `ceph health detail` 的输出**,查看是否存在关于 stray cluster daemons 或尚未被 cephadm 管理的主机的 cephadm 告警。
> 引自:[Converting an existing cluster to cephadm](https://docs.ceph.com/en/tentacle/cephadm/adoption/)
## 十三、版本兼容性(Compatibility and Stability)
### 13.1 与 Podman 版本的兼容性
Podman 与 Ceph 的生命周期(EOL)策略不同,因此必须谨慎选择相互兼容的 Podman 与 Ceph 版本。下表显示哪些版本组合预期可用 / 不可用:
| Ceph \ Podman | 1.9 | 2.0 | 2.1 | 2.2 | 3.0 | > 3.0 |
|---|---|---|---|---|---|---|
| **<= 15.2.5** | True | False | False | False | False | False |
| **>= 15.2.6** | True | True | True | False | False | False |
| **>= 16.2.1** | False | True | True | False | True | True |
| **>= 17.2.0** | False | True | True | False | True | True |
> 注意:虽然并非所有 Podman 版本都与所有 Ceph 版本做过主动测试,但目前**没有已知问题**表明 Podman 3.0 或更高版本不能与 Ceph Quincy 及之后的版本配合使用。
> ⚠️ 警告:要在 **Ceph Pacific** 上使用 Podman,**必须使用 2.0.0 或更高版本**的 Podman。但 **Podman 2.2.1 不能与 Ceph Pacific 一起工作**。
>
> "Kubic stable" 已知可与 Ceph Pacific 配合使用,但必须运行在较新的内核上。
### 13.2 稳定性(Stability)
Cephadm 相对稳定,但**仍在持续添加新功能**,偶尔也会发现 bug。如发现问题,请在 Orchestrator 组件下提交 tracker issue:https://tracker.ceph.com/projects/orchestrator/issues
以下特性的 cephadm 支持**仍在开发中**:
| 特性 | 说明 |
|---|---|
| ceph-exporter deployment | ceph-exporter 部署 |
| stretch mode integration | stretch mode 集成 |
| monitoring stack | 正在朝 prometheus service discovery 演进,并提供 TLS |
| RGW multisite deployment support | RGW multisite 部署支持(**目前需要大量手工步骤**) |
| cephadm agent | cephadm agent |
如果某个 cephadm 命令失败或某个服务运行不正常,参见本册 14.1 节(Pausing or Disabling cephadm)了解如何暂停集群后台活动以及如何禁用 cephadm。
> 引自:[Compatibility and Stability](https://docs.ceph.com/en/tentacle/cephadm/compatibility/)
## 十四、排障(Troubleshooting)
cephadm 把守护进程部署在**容器内**,排查容器化守护进程的过程与排查通过包安装的传统守护进程不同。
### 14.1 暂停或禁用 cephadm
**场景**:cephadm 行为异常。
**解决**:先暂停 Ceph 集群的大部分后台活动:
```bash
ceph orch pause
```
这会停止 Ceph 集群中的所有变更,但 cephadm **仍会周期性检查主机**以刷新其守护进程与设备的清单。
要**完全禁用** cephadm:
```bash
ceph orch set backend ''
ceph mgr module disable cephadm
```
这两条命令会禁用所有 `ceph orch ...` CLI 命令;**此前已部署的守护进程容器会继续运行**,并会像执行这些命令之前那样启动。
> 关于禁用单个服务,参见 `cephadm-spec-unmanaged`(本册第五章 unmanaged 一节)。
### 14.2 Per-service 与 Per-daemon 事件
为便于调试失败的守护进程,cephadm **按服务和按守护进程存储事件**,这些事件常包含与排障相关的信息。
**查看服务事件**:
```bash
ceph orch ls --service_name=<service-name> --format yaml
```
返回形如:
```yaml
service_type: alertmanager
service_name: alertmanager
placement:
hosts:
- unknown_host
status:
...
running: 1
size: 1
events:
- 2021-02-01T08:58:02.741162 service:alertmanager [INFO] "service was created"
- '2021-02-01T12:09:25.264584 service:alertmanager [ERROR] "Failed to apply: Cannot
place <AlertManagerSpec for service_name=alertmanager> on unknown_host: Unknown hosts"'
```
**查看守护进程事件**:
```bash
ceph orch ps --service-name <service-name> --daemon-id <daemon-id> --format yaml
```
返回形如:
```yaml
daemon_type: mds
daemon_id: cephfs.hostname.ppdhsz
hostname: hostname
status_desc: running
...
events:
- 2021-02-01T08:59:43.845866 daemon:mds.cephfs.hostname.ppdhsz [INFO] "Reconfigured
mds.cephfs.hostname.ppdhsz on host 'hostname'"
```
### 14.3 检查 cephadm 日志
实时监控方式见本册 8.1 节。若集群已配置为**把事件记录到文件**,则**所有 monitor 主机**上会有 `ceph.cephadm.log` 文件(详见本册 8.3 节)。
### 14.4 收集日志文件
> 注意:**cephadm 现在默认把日志存放在 journald**,这意味着**不会再在 `/var/log/ceph/` 下找到守护进程日志**。
读取某个具体守护进程的日志:
```bash
cephadm logs --name <name-of-daemon>
```
> 注意:该命令**仅在守护进程所在的同一台主机上运行时有效**。要获取运行在其它主机上的守护进程的日志,需加 `--fsid` 选项:
```bash
cephadm logs --fsid <fsid> --name <name-of-daemon>
```
其中 `<fsid>` 对应 `ceph status` 命令返回的集群 ID。
抓取某台主机上**所有守护进程**的全部日志:
```bash
for name in $(cephadm ls | jq -r '.[].name') ; do
cephadm logs --fsid <fsid> --name "$name" > $name;
done
```
### 14.5 收集 systemd 状态
打印某个 systemd unit 的状态:
```bash
systemctl status "ceph-$(cephadm shell ceph fsid)@<service name>.service";
```
抓取某台主机上所有守护进程的状态:
```bash
fsid="$(cephadm shell ceph fsid)"
for name in $(cephadm ls | jq -r '.[].name') ; do
systemctl status "ceph-$fsid@$name.service" > $name;
done
```
### 14.6 列出所有已下载的容器镜像
```bash
podman ps -a --format json | jq '.[].Image' "docker.io/library/centos:8" "registry.opensuse.org/opensuse/leap:15.2"
```
> 注意:`Image` 也可能叫 `ImageID`。
### 14.7 手工运行容器
cephadm 运行容器时使用了一层薄封装(small wrappers)。容器执行命令可参考:
```text
/var/lib/ceph/<cluster-fsid>/<service-name>/unit.run
```
### 14.8 SSH 错误
**现象 / 错误信息**:
```text
execnet.gateway_bootstrap.HostNotFound: -F /tmp/cephadm-conf-73z09u6g -i /tmp/cephadm-identity-ky7ahp_5 root@10.10.1.2
...
raise OrchestratorError(msg) from e
orchestrator._interface.OrchestratorError: Failed to connect to 10.10.1.2 (10.10.1.2).
Please make sure that the host is reachable and accepts connections using the cephadm SSH key
...
```
**原因**:`cephadm` 与目标主机之间的 SSH 连接失败。
**排查步骤**:
**① 确保 cephadm 有 SSH identity key:**
```bash
[root@mon1~]# cephadm shell -- ceph config-key get mgr/cephadm/ssh_identity_key > ~/cephadm_private_key
INFO:cephadm:Inferring fsid f8edc08a-7f17-11ea-8707-000c2915dd98
INFO:cephadm:Using recent ceph image docker.io/ceph/ceph:v15 obtained 'mgr/cephadm/ssh_identity_key'
[root@mon1 ~] # chmod 0600 ~/cephadm_private_key
```
如果上述命令失败,说明 cephadm 没有 key,用下面任一命令修复:
```bash
[root@mon1 ~]# cephadm shell -- ceph cephadm generate-ssh-key
```
或
```bash
[root@mon1 ~]# cat ~/cephadm_private_key | cephadm shell -- ceph cephadm set-ssh-key -i -
```
**② 确保 SSH 配置正确:**
```bash
[root@mon1 ~]# cephadm shell -- ceph cephadm get-ssh-config > config
```
**③ 验证能否连接到主机:**
```bash
[root@mon1 ~]# ssh -F config -i ~/cephadm_private_key root@mon1
```
#### 14.8.1 验证公钥已列入 authorized_keys
```bash
[root@mon1 ~]# cephadm shell -- ceph cephadm get-pub-key > ~/ceph.pub
[root@mon1 ~]# grep "`cat ~/ceph.pub`" /root/.ssh/authorized_keys
```
### 14.9 Failed to Infer CIDR network 错误
**现象 / 错误信息**(二者之一):
```text
ERROR: Failed to infer CIDR network for mon ip ***; pass --skip-mon-network to configure it later
```
```text
Must set public_network config option or specify a CIDR network, ceph addrvec, or plain IP
```
**原因**:未设置 `public_network`,cephadm 无法推断 mon ip 的 CIDR 网络。
**解决**:
```bash
ceph config set mon public_network <mon_network>
```
更多细节参见 `deploy_additional_monitors`。
### 14.10 访问 Admin Socket
每个 Ceph 守护进程都提供一个 admin socket,允许运行时设置选项与读取统计信息(参见 `rados-monitoring-using-admin-socket`)。
1. 在主机上**进入**守护进程容器:
```bash
[root@mon1 ~]# cephadm enter --name <daemon-name>
```
2. 查看 admin socket 的配置与其它可用操作:
```bash
[ceph: root@mon1 /]# ceph --admin-daemon /var/run/ceph/ceph-<daemon-name>.asok config show
[ceph: root@mon1 /]# ceph --admin-daemon /var/run/ceph/ceph-<daemon-name>.asok help
```
### 14.11 运行各类 Ceph 工具
要运行 `ceph-objectstore-tool`、`ceph-monstore-tool` 等 Ceph 工具,使用 `cephadm shell --name <daemon-name>`:
```bash
root@myhostname # cephadm unit --name mon.myhostname stop
root@myhostname # cephadm shell --name mon.myhostname
[ceph: root@myhostname /]# ceph-monstore-tool /var/lib/ceph/mon/ceph-myhostname get monmap > monmap
[ceph: root@myhostname /]# monmaptool --print monmap
monmaptool: monmap file monmap
epoch 1
fsid 28596f44-3b56-11ec-9034-482ae35a5fbb
last_changed 2021-11-01T20:57:19.755111+0000
created 2021-11-01T20:57:19.755111+0000
min_mon_release 17 (quincy)
election_strategy: 1
0: [v2:127.0.0.1:3300/0,v1:127.0.0.1:6789/0] mon.myhostname
```
`cephadm shell` 所设置的环境适合进行**扩展的守护进程维护**与**交互式运行守护进程**。
### 14.12 恢复 Monitor Quorum
**现象**:Ceph Monitor 守护进程(mons)**无法形成 quorum**。
**影响**:在 quorum 恢复之前,**cephadm 将无法管理集群**。
**解决**:把不健康的 monitor 从 monmap 中移除,步骤如下:
1. **停止所有 Monitors**:用 `ssh` 连接到每台 Monitor 的主机,然后用 `cephadm` 停止 Monitor 守护进程:
```bash
ssh {mon-host}
cephadm unit --name {mon.hostname} stop
```
2. **找出一个存活的 Monitor 并登录其主机**:
```bash
ssh {mon-host}
cephadm enter --name {mon.hostname}
```
3. 按照 `rados-mon-remove-from-unhealthy` 中的步骤操作。
### 14.13 手工部署 Manager 守护进程
**场景**:cephadm 至少需要**一个** Manager(mgr)守护进程才能管理集群。如果**最后一个 Manager 已被移除**,需按下面步骤在集群中任选一台主机上部署一个新的 Manager。下例中新部署的 Manager 守护进程名为 `mgr.hostname.smfvfd`。
1. **禁用 cephadm 调度器**,防止 `cephadm` 移除新建的 Manager:
```bash
ceph config-key set mgr/cephadm/pause true
```
2. 获取或创建该新 Manager 的 "auth entry":
```bash
ceph auth get-or-create mgr.hostname.smfvfd mon "profile mgr" osd "allow *" mds "allow *"
```
3. 获取 Monitor 的配置:
```bash
ceph config generate-minimal-conf
```
4. 获取容器镜像:
```bash
ceph config get "mgr.hostname.smfvfd" container_image
```
5. 创建 `config-json.json` 文件,包含部署该守护进程所需的信息:
```json
{
"config": "# minimal ceph.conf for 8255263a-a97e-4934-822c-00bfe029b28f\n[global]\n\tfsid = 8255263a-a97e-4934-822c-00bfe029b28f\n\tmon_host = [v2:192.168.0.1:40483/0,v1:192.168.0.1:40484/0]\n",
"keyring": "[mgr.hostname.smfvfd]\n\tkey = V2VyIGRhcyBsaWVzdCBpc3QgZG9vZi4=\n"
}
```
6. 部署 Manager 守护进程:
```bash
cephadm --image <container-image> deploy --fsid <fsid> --name mgr.hostname.smfvfd --config-json config-json.json
```
### 14.14 捕获 Core Dumps
使用 cephadm 的 Ceph 集群可以配置为捕获 core dump。core dump 的**初始捕获与处理由 `systemd-coredump`** 完成。
启用 coredump 处理:
```bash
ulimit -c unlimited
```
> 注意:**core dump 不被内核按 namespace 隔离**,这意味着 core dump 会被写到**容器宿主机**上的 `/var/lib/systemd/coredump`。并且 `ulimit -c unlimited` 设置**只在系统重启前有效**。
然后等待 crash 再次发生。要模拟守护进程崩溃,可运行例如 `killall -3 ceph-mon`。
### 14.15 使用 cephadm 运行调试器
#### 14.15.1 单次调试会话
用 `cephadm shell` 发起调试会话。在 shell 容器内需要安装调试器与 debuginfo 包。调试由 systemd 捕获的 core 文件:
1. 启动 shell 会话:
```bash
cephadm shell --mount /var/lib/system/coredump
```
2. 在 shell 会话内执行:
```bash
dnf install ceph-debuginfo gdb zstd
```
```bash
unzstd /var/lib/systemd/coredump/core.ceph-*.zst
```
```bash
gdb /usr/bin/ceph-mon /mnt/coredump/core.ceph-*.zst
```
3. 在 gdb 提示符下运行调试命令:
```text
(gdb) bt
```
```text
#0 0x00007fa9117383fc in pthread_cond_wait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1 0x00007fa910d7f8f0 in std::condition_variable::wait(std::unique_lock<std::mutex>&) () from /lib64/libstdc++.so.6
#2 0x00007fa913d3f48f in AsyncMessenger::wait() () from /usr/lib64/ceph/libceph-common.so.2
#3 0x0000563085ca3d7e in main ()
```
#### 14.15.2 重复调试会话
用 `cephadm shell` 时,对容器的任何修改都是**临时的(ephemeral)**——shell 会话退出后,下载并安装的文件就不再可用。可以每次都重跑相同命令,但为节省时间与资源,可以**创建一个新的容器镜像**用于重复调试。
下面创建一个构建该容器镜像的简单文件(示例用 podman,替换成 docker 也可正常工作):
```bash
cat >Containerfile <<EOF
ARG BASE_IMG=quay.io/ceph/ceph:v18
FROM \${BASE_IMG}
# install ceph debuginfo packages, gdb and other potentially useful packages
RUN dnf install --enablerepo='*debug*' -y ceph-debuginfo gdb zstd strace python3-debuginfo
EOF
podman build -t ceph:debugging -f Containerfile .
# pass --build-arg=BASE_IMG=<your image> to customize the base image
```
上面的文件创建了一个名为 **`ceph:debugging`** 的本地新镜像。该镜像可在构建它的机器上使用,也可以推送到容器仓库,或保存后复制到运行其它 Ceph 容器的节点。
使用该镜像发起重复调试会话:
```bash
cephadm --image ceph:debugging shell --mount /var/lib/system/coredump
```
#### 14.15.3 调试活进程(Debugging live processes)
gdb 可以 attach 到运行中的进程。对容器化进程,可使用调试镜像并**加入目标进程所在的同一 PID namespace**。
这需要带一些自定义参数运行容器命令。可以生成一个脚本来调试运行中容器里的进程:
```bash
cephadm --image ceph:debugging shell --dry-run > /tmp/debug.sh
```
这会生成一个包含 `cephadm` 用于创建 shell 的容器命令的脚本。**修改该脚本**:去掉 `--init` 参数,替换为「加入某个运行中容器所用 namespace」的参数。例如,假设要调试 Manager,并已确定 Manager 运行在名为 `ceph-bc615290-685b-11ee-84a6-525400220000-mgr-ceph0-sluwsk` 的容器中,则应使用参数:
```text
--pid=container:ceph-bc615290-685b-11ee-84a6-525400220000-mgr-ceph0-sluwsk
```
然后用 `sh /tmp/debug.sh` 运行调试容器。在 shell 内可运行 `ps` 等命令获取 Manager 进程的 PID(下例中为 `2`),并在 gdb 中 attach 到该运行进程:
```text
(gdb) attach 2
(gdb) info threads
(gdb) bt
```
> 引自:[Troubleshooting](https://docs.ceph.com/en/tentacle/cephadm/troubleshooting/)
## 十五、cephadm 常用命令速查表
### 15.1 cephadm 二进制(主机本地执行)
| 命令 | 用途 |
|---|---|
| `cephadm bootstrap --mon-ip <mon-ip>` | 引导创建新集群(首个 mon + mgr) |
| `cephadm add-repo --release <stable-release>` | 添加官方 Ceph 仓库 |
| `cephadm install` | 在本机安装 cephadm |
| `cephadm prepare-host` | 为主机做好被 cephadm 使用的准备(纳管流程用) |
| `cephadm adopt --style legacy --name <name>` | 纳管 legacy 守护进程(mon/mgr/osd) |
| `cephadm ls` | 列出本机守护进程及其 style(`legacy` / `cephadm:v1`) |
| `cephadm list-images` | 查看默认容器镜像清单 |
| `cephadm list-networks` | 查看网络到设备的映射 |
| `cephadm logs --name <name>` / `--fsid <fsid> --name <name>` | 查看守护进程日志 |
| `cephadm shell` | 启动 Ceph 工具容器 shell |
| `cephadm shell --name <daemon-name>` | 在指定守护进程环境中运行工具 |
| `cephadm enter --name <daemon-name>` | 进入守护进程容器 |
| `cephadm unit --name <daemon-name> stop` | 停止守护进程 systemd unit |
| `cephadm deploy --fsid <fsid> --name <name> --config-json <file>` | 手工部署守护进程 |
| `cephadm rm-cluster --force --zap-osds --fsid <fsid>` | 清除集群(危险) |
| `cephadm ceph-volume ...` | 对 ceph-volume 的封装(详见 OSD 章) |
| `cephadm --image <image> ...` | 指定容器镜像执行 |
| `cephadm --log-dest=file\|syslog ...` | 指定 cephadm 自身日志目的地 |
### 15.2 集群与编排总览
| 命令 | 用途 |
|---|---|
| `ceph orch ls` | 列出服务 |
| `ceph orch ps` | 列出守护进程 |
| `ceph orch status` | 编排器状态 |
| `ceph orch pause` / `ceph orch resume` | 暂停 / 恢复 cephadm 后台工作 |
| `ceph orch set backend cephadm` / `ceph orch set backend ''` | 设置 / 清空编排后端 |
| `ceph mgr module enable cephadm` / `ceph mgr module disable cephadm` | 启用 / 禁用 cephadm mgr 模块 |
| `ceph orch apply -i <file.yaml>` | 从 YAML spec 应用服务 |
| `ceph orch rm <service>` | 移除服务 |
| `ceph orch set-unmanaged <service>` / `ceph orch set-managed <service>` | 设置 / 取消 unmanaged |
| `ceph orch sd dump cert` | 导出 service discovery 端点根证书 |
### 15.3 主机管理
| 命令 | 用途 |
|---|---|
| `ceph orch host ls` | 列出主机 |
| `ceph orch host add <hostname> [ip]` | 添加主机 |
| `ceph orch host rm <hostname> [--rm-crush-entry]` | 删除主机 |
| `ceph orch host label add <host> <label>` / `... label rm <host> <label>` | 增删主机标签 |
| `ceph orch host maintenance enter <host>` / `... exit <host>` | 进入 / 退出维护模式 |
| `ceph orch host drain <host>` | 排空主机 |
| `ceph orch host rescan <host>` | 重新扫描主机设备 |
| `ceph cephadm check-host <hostname>` | 手工执行主机检查 |
| `ceph cephadm generate-key` / `get-pub-key` / `set-ssh-key -i -` / `clear-key` | SSH 密钥管理 |
| `ceph cephadm set-user <user>` | 设置 SSH 登录用户 |
| `ceph cephadm set-ssh-config` / `get-ssh-config` / `clear-ssh-config` | SSH 配置管理 |
| `ceph cephadm config-check status` / `ls` / `disable <name>` | 集群配置检查 |
| `ceph orch tuned-profile apply/ls/rm/add-setting/rm-setting` | tuned profile 管理 |
### 15.4 守护进程与服务控制
| 命令 | 用途 |
|---|---|
| `ceph orch daemon add <type> <placement>` | 手工部署守护进程 |
| `ceph orch daemon rm <name>` | 移除守护进程 |
| `ceph orch daemon stop/start/restart <name>` | 停止 / 启动 / 重启守护进程 |
| `ceph orch stop/start/restart <serviceid>` | 对服务的所有守护进程执行对应操作 |
| `ceph orch daemon redeploy <name> [--image <image>]` | 重建守护进程容器 |
| `ceph orch daemon reconfig <name>` | 重新生成配置(不重启) |
| `ceph orch daemon rotate-key <name>` | 轮换守护进程认证密钥 |
| `ceph orch redeploy <service>` | 重新部署服务的所有守护进程(换镜像后常用) |
| `ceph orch reconfig <service>` | 重新配置服务(改 Jinja2 模板后常用) |
### 15.5 设备与 OSD
| 命令 | 用途 |
|---|---|
| `ceph orch device ls [--wide]` | 列出设备 |
| `ceph orch device zap <host> <path>` | 擦除设备 |
| `ceph orch device replace <host> <device> [--yes-i-really-mean-it] [--clear]` | 替换设备 / 清除 replace 标记 |
| `ceph orch apply osd --all-available-devices` | 在所有可用设备上部署 OSD |
| `ceph orch daemon add osd <host>:/dev/<dev>` | 在指定设备上部署 OSD |
| `ceph orch osd rm <osd_id>... [--replace] [--force] [--zap]` | 移除 OSD |
| `ceph orch osd rm status` / `ceph orch osd rm stop` | 查看 / 停止 OSD 移除 |
| `ceph cephadm osd activate <host>` | 激活已有 OSD |
### 15.6 各服务部署
| 命令 | 用途 |
|---|---|
| `ceph orch apply mon [--placement ...]` / `ceph orch daemon add mon host:ip-or-network` | 部署 MON |
| `ceph orch apply mgr <count>` | 部署 MGR |
| `ceph fs volume create <fs_name> --placement=` / `ceph orch apply mds <fs-name> [--placement=]` | 部署 MDS |
| `ceph orch apply rgw <svc_id> [--realm=] [--zone=] [--port=] [--ssl] [--placement=]` | 部署 RGW |
| `ceph orch apply ingress ...` | 部署 ingress(haproxy + keepalived) |
| `ceph orch apply nfs <svc_id> [--port]` | 部署 NFS(默认端口 2049) |
| `ceph orch apply iscsi <pool> ...` | 部署 iSCSI |
| `ceph orch apply smb ...` | 部署 SMB |
| `ceph orch apply snmp-gateway ... -i <creds.yaml>` | 部署 SNMP gateway(默认端口 9464) |
| `ceph orch apply node-exporter / alertmanager / prometheus / grafana` | 部署监控组件 |
| `ceph orch apply mgmt-gateway [--virtual_ip ...] [--enable-auth=true] [--placement ...]` | 部署 mgmt-gateway |
| `ceph orch apply oauth2-proxy [--placement ...]` | 部署 oauth2-proxy |
| `ceph orch apply jaeger [--without-query --es_nodes=ip:port]` | 部署 Jaeger tracing |
| `ceph orch apply -i container.yaml`(`service_type: container`) | 部署自定义容器 |
### 15.7 升级与镜像
| 命令 | 用途 |
|---|---|
| `ceph orch upgrade start --ceph-version <version>` / `--image <image>` | 开始升级 |
| `ceph orch upgrade status` | 查看升级状态 |
| `ceph orch upgrade stop` | 停止升级 |
| `ceph orch update service <service_type> <image>` | 更新非 Ceph 镜像的服务 |
| `ceph config set mgr mgr/cephadm/container_image_<component> <image>` | 设置自定义镜像 |
| `ceph config rm mgr mgr/cephadm/container_image_<component>` | 恢复默认镜像 |
| `ceph config-key set mgr/cephadm/<template_name> -i <file>` | 覆盖 Jinja2 模板 |
### 15.8 运维与配置分发
| 命令 | 用途 |
|---|---|
| `ceph -W cephadm` / `ceph -W cephadm --watch-debug` | 实时查看 cephadm 日志 |
| `ceph log last cephadm` | 查看最近 cephadm 事件 |
| `ceph orch client-keyring ls / set / rm` | client keyring 管理 |
| `ceph config generate-minimal-conf` | 生成最小 ceph.conf(客户端用) |
| `ceph auth get-or-create client.fs` | 生成客户端 keyring |
| `ceph orch certmgr ...` | 证书管理(见第十章) |
| `ceph fsid` | 查看集群 FSID |
## 文档未明确项
本章汇总本册范围内**官方文档未明确说明**、因而无法从源文直接确定的内容,供读者在使用或二次核实时注意。
| # | 主题 | 文档未明确的内容 |
|---|---|---|
| 1 | 默认容器镜像清单 | `monitoring.rst` 通过 `autoclass:: ceph.cephadm.images.DefaultImages` 自动生成,抓取到的 rst 未以明文给出各监控组件默认镜像名与 tag;需以 `cephadm list-images` 实际输出为准 |
| 2 | `MgmtGatewaySpec` 完整字段 | `mgmt-gateway.rst` 用 `autoclass:: MgmtGatewaySpec` 展开,仅示例中出现的 `enable_auth`、`virtual_ip`、`port`、`ssl`、`ssl_protocols`、`ssl_ciphers`、`ssl_cert`、`ssl_key` 有明文;其余字段及默认值未明确 |
| 3 | `OAuth2ProxySpec` 完整字段 | `oauth2-proxy.rst` 用 `autoclass:: OAuth2ProxySpec` 展开,仅 `https_address`、`provider_display_name`、`client_id`、`oidc_issuer_url`、`client_secret`、`cookie_secret`、`ssl_certificate`、`ssl_certificate_key` 有明文;其余未明确,官方建议参考 oauth2-proxy 项目自身文档 |
| 4 | Grafana / Alertmanager 完整 spec 字段 | 仅 `port`、`protocol`、`initial_admin_password`、`anonymous_access`、`retention_time`、`retention_size`、`default_webhook_urls`、`secure` 等在示例或叙述中出现,完整字段表未明确 |
| 5 | `known_certs` / `known_keys` 清单 | `certmgr.rst` 用 `automodule:: mgr.cephadm.cert_mgr` 自动生成,具体证书名/密钥名未以明文出现;需通过 `ceph orch certmgr cert ls` / `key ls` 查询 |
| 6 | Tracing 服务细节 | `tracing.rst` 仅 972 字节,未给出 spec 字段、端口、默认镜像等;仅说明 Jaeger 由 agent/collector/query 组成、默认使用 Elasticsearch 6 |
| 7 | `--registry-url` 参数 | 用户任务描述中提到的该参数在 install.rst 源文中**未出现**;源文对应的是 `--registry-json`(以 JSON 形式指定自定义 registry 及凭据) |
| 8 | 升级的显式「回滚(rollback)」步骤 | `upgrade.rst` 只提供 `ceph orch upgrade stop` 用于**停止**升级,**未提供回退到旧版本的操作步骤**;回滚方式文档未明确 |
| 9 | mgr/cephadm 元数据的备份与还原 | 用户任务提到的「备份还原(mgr/cephadm 元数据)」在 `operations.rst` 中**没有对应章节**;cephadm 元数据如何备份/还原,文档未明确 |
| 10 | `CEPHADM_PAUSED` 之外的编排暂停实现细节 | `troubleshooting.rst` 用 `ceph orch pause` 暂停,`operations.rst` 手工部署 mgr 时用 `ceph config-key set mgr/cephadm/pause true`;两者关系与适用场景未明确说明 |
| 11 | `snmp-gateway` 的 systemd / 容器端口映射细节 | 仅给出 `--port` 默认 `9464`,容器内外部端口映射关系未明确 |
| 12 | 官方笔误 | `certmgr.rst` 第 274 行原命令写作 `cehp orch certmgr generate-certificates <module_name>`,本册已按正确命令 `ceph orch certmgr generate-certificates` 记录 |