运维与安全 — CodeRoadMap运维与安全:ILM、快照、RBAC 与监控
这一课你将能做到
- 写一个 ILM 策略:hot 阶段 rollover,warm 阶段收缩,到期自动删除;并把索引模板挂到策略上
- 配置快照仓库并用 SLM 定时备份题库,能完成一次恢复演练
- 用角色 + API Key 做最小权限控制,说出磁盘水位、滚动重启、JVM 堆三个运维红线
为什么要学
开发交付的搜索功能要「活下去」:磁盘满了集群会自动只读、误删数据没有备份就无法挽回、应用拿着超级用户密码连接是定时炸弹。运维不是上线后才想的事——索引第一天就要规划生命周期(数据怎么滚动、何时归档),第一天就该有备份。对求职而言,「说得出 ILM、快照、水位线」是区分「只会调接口」和「能扛服务」的分界线。
人话:ILM(Index Lifecycle Management)是索引的「自动人生规划」——新数据在热层高速读写,变老后挪到便宜的机器,过期自动删。快照是「后悔药」,SLM 让后悔药每天自动吃一次。RBAC 保证「搜索服务账号只能搜题、不能删库」。
先建立图像
ILM 五阶段:
hot 可读写,活跃数据;触发 rollover(按大小/文档数/存在时间)→ 新建索引
warm 只读,可 shrink(收缩分片)、force merge,挪到 warm 节点
cold 只读,更少副本,查询可接受更慢
frozen 可搜索快照,几乎不占本地存储
delete 自动删除
本站题库的简化策略(数据小、长期保留):
hot:rollover 当索引 ≥ 10GB 或 满 30 天
delete:保留 365 天后删(也可不删,按合规定)
安全与备份全景:
快照仓库(共享文件系统/对象存储 S3、OSS、COS)
← SLM 定时 PUT 快照
RBAC:用户名密码 / API Key / Service Account
监控:_cat API、Stack Monitoring、告警规则
跟着做
步骤 1:创建 ILM 策略
curl -u elastic:abcd1234 -X PUT "_ilm/policy/questions_policy" -H "Content-Type: application/json" -d'
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_primary_shard_size": "10gb",
"max_age": "30d"
}
}
},
"warm": {
"min_age": "2d",
"actions": {
"shrink": { "number_of_shards": 1 },
"forcemerge": { "max_num_segments": 1 }
}
},
"delete": {
"min_age": "365d",
"actions": { "delete": {} }
}
}
}
}'
要让 rollover 滚动起来,索引名要按序列命名(如 questions-000001),并通过索引模板把别名 questions 指向它,应用始终读写别名:
curl -u elastic:abcd1234 -X PUT "_index_template/questions_tpl" -H "Content-Type: application/json" -d'
{
"index_patterns": ["questions-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "questions_policy",
"index.lifecycle.rollover_alias": "questions"
},
"aliases": { "questions": {} }
}
}'
# 用别名引导第一个索引
curl -u elastic:abcd1234 -X PUT "questions-000001" -H "Content-Type: application/json" -d'
{
"aliases": {
"questions": { "is_write_index": true }
}
}'
之后写入 questions 别名,rollover 触发时 ES 自动建 questions-000002 并把写别名切过去,对应用透明。
步骤 2:配置快照仓库
本地学习可用文件系统仓库(先在 elasticsearch.yml 配置 path.repo,Docker 加挂载):
docker run -d --name es01 --net es-net -p 9200:9200 \
-v "$PWD/es-backup:/usr/share/elasticsearch/backup" \
-e "discovery.type=single-node" \
-e "ELASTIC_PASSWORD=abcd1234" \
-e "xpack.security.http.ssl.enabled=false" \
-e "path.repo=/usr/share/elasticsearch/backup" \
docker.elastic.co/elasticsearch/elasticsearch:8.11.0
curl -u elastic:abcd1234 -X PUT "_snapshot/question_repo" -H "Content-Type: application/json" -d'
{
"type": "fs",
"settings": {
"location": "/usr/share/elasticsearch/backup"
}
}'
# 立即备份题库(生产用 S3/OSS 类型仓库,需装 repository-s3 等插件并配凭证)
curl -u elastic:abcd1234 -X PUT "_snapshot/question_repo/snap_questions_2026_10_07?wait_for_completion=false" \
-H "Content-Type: application/json" -d'
{
"indices": "questions",
"include_global_state": false
}'
快照是增量的:段不可变,已存过的段不会重复上传,所以每日快照成本很低。
步骤 3:用 SLM 自动备份并演练恢复
curl -u elastic:abcd1234 -X PUT "_slm/policy/daily_questions" -H "Content-Type: application/json" -d'
{
"schedule": "0 30 2 * * ?",
"name": "<daily-questions-{now/d}>",
"repository": "question_repo",
"config": {
"indices": ["questions-*"],
"include_global_state": false
},
"retention": {
"expire_after": "30d",
"min_count": 7,
"max_count": 30
}
}'
# 删除索引(假设事故)
# 恢复到新索引名,避免覆盖在线索引
curl -u elastic:abcd1234 -X POST "_snapshot/question_repo/snap_questions_2026_10_07/_restore" -H "Content-Type: application/json" -d'
{
"indices": "questions",
"rename_pattern": "questions",
"rename_replacement": "questions_restored"
}'
步骤 4:RBAC——给应用最小权限
不要让应用用 elastic 超级用户。创建角色 + API Key:
curl -u elastic:abcd1234 -X POST "_security/api_key" -H "Content-Type: application/json" -d'
{
"name": "question-search-app",
"role_descriptors": {
"question_reader": {
"index": [
{
"names": ["questions"],
"privileges": ["read", "view_index_metadata"]
}
]
}
},
"expiration": "365d"
}'
应用拿到返回的 API Key,请求时带头部 Authorization: ApiKey base64(id:key)。需要写入权限的后台服务另发一把带 index 特权的 Key,读写分离。用户体系则可创建 role(映射索引特权)和 user,或对接 LDAP/SAML/OIDC 单点登录。
步骤 5:监控、水位线与滚动操作
# 日常巡检三板斧
curl -u elastic:abcd1234 "_cat/health?v"
curl -u elastic:abcd1234 "_cat/indices?v&s=index"
curl -u elastic:abcd1234 "_cat/allocation?v"
# 查看节点磁盘与线程池
curl -u elastic:abcd1234 "_cat/nodes?h=name,disk.used_percent,heap.percent,cpu,load_1m"
磁盘水位默认:85% 不再向该节点分配新分片;90%(flood_stage)索引自动置为只读。清空间后需手动解除:
curl -u elastic:abcd1234 -X PUT "questions/_settings" -H "Content-Type: application/json" -d'
{ "index.blocks.read_only_allow_delete": null }'
滚动重启(升级/改配置的标准做法):逐个节点——先 PUT _cluster/settings 关闭分片分配 → 停节点、操作、启动 → 等集群 GREEN → 恢复分配 → 下一个节点。全程服务不中断。
JVM 堆红线:堆大小设为物理内存的 50% 左右但不超过 31GB(超过会失去指针压缩),-Xms 与 -Xmx 设成一样;监控 GC,不要把堆当缓存用。
讲清楚要点
- ILM 与 rollover 是为持续增长的数据流设计的:日志、行为记录类必须按序列索引+别名滚动;本站题库低频更新,单索引加年度新索引也能接受,但方法要会。
- 快照是唯一可靠的灾难恢复手段:副本防的是节点故障,不防误删(删操作会同步到副本)、不防整集群故障。快照必须异地(对象存储),并定期恢复演练。
- 最小权限原则:应用用 API Key,只授需要的索引和动作;超级用户只用于运维。密钥进环境变量/KMS,不进代码仓库。
- 监控要告警而不是只看图:集群状态变红、磁盘超水位、堆 GC 过长、拒绝线程池(
rejected)都应配 Watcher/告警通道通知到人。
- 变更走灰度和滚动:索引设置、mapping、插件、版本升级全部按「可回滚、逐节点」的方式执行;变更前先确认快照可用。
你可能会懵的地方
- 副本能不能替代备份?
不能。副本实时同步,误删、错误更新、被攻击都会同步到副本;快照基于不可变段、有时间点、可异地保存,二者职责完全不同。
- ILM 策略不执行怎么办?
ILM 服务在所有 master 节点运行。查
GET questions/_ilm/explain 看索引当前所处步骤和报错;常见原因:rollover 别名没配对、策略名没挂上、分片不可用。
- 快照能只备份部分索引/部分数据吗?
可以,创建快照时指定 indices(支持通配),但段是最小复用单位,不能只备份某几条文档;要导子集用 reindex。
- API Key 泄露了怎么办?
立即
PUT _security/api_key/{id} 置 invalidate(或批量按名称失效),重新签发;泄露期间有被滥用风险时同步排查访问日志。
- 为什么堆内存不能设太大?
JVM 超过约 31GB 后压缩指针失效,同样堆占用更多内存且缓存效率下降;超过物理内存一半会不给文件系统缓存留空间,而 ES 查询很依赖文件缓存。
错法对照
| 错法 | 问题 | 正解 |
|---|
| 把副本当备份 | 误删同步、集群级故障无救 | 快照 + SLM + 演练 |
| 应用直连使用 elastic 账号 | 权限失控 | API Key + 最小特权 |
| 磁盘满了才想起来清理 | 索引只读、写入失败 | 监控告警 + ILM |
| 多节点同时重启 | 集群可能 RED/不可用 | 逐节点滚动重启 |
| 堆内存拍脑袋设 64GB | 压缩指针失效、GC 更差 | ≤31GB、约为物理内存一半 |
| 快照只放本机盘 | 机器损毁备份一起没 | 异地对象存储仓库 |
卡点急救
- 集群进入只读(read_only_allow_delete):磁盘触发 flood_stage。先扩容或清理快照/旧索引,再解除索引块;查
_cat/allocation 找满的节点。
- 快照卡住或失败:
GET _snapshot/仓库/快照/_status 看分片级状态;对象存储场景检查凭证、网络和桶权限;失败的快照可删除重来,不影响已有快照。
- 节点 GC 频繁、查询变慢:查堆使用率和大聚合(fielddata/大 terms),收窄查询;确认堆没有被缓存类需求占用;内存不足时按容量扩容而不是盲目调大堆。
面试常问
-
说一下 ES 的 ILM。
索引生命周期管理,按 hot、warm、cold、frozen、delete 五阶段自动执行动作:hot 可读写并按大小/时间 rollover 到新索引;warm 可收缩分片、force merge;cold/frozen 进一步降本;delete 到期删除。配合索引模板和写别名实现对应用透明的滚动,适合持续增长的数据。
-
ES 怎么做备份?和副本有什么区别?
用快照注册共享文件系统或对象存储仓库,快照基于不可变段、增量存储,用 SLM 定时创建,可异地保存并恢复到任意集群。副本只是分片的实时拷贝,防节点故障但防不了误删和整集群事故,二者不能互相替代。
-
ES 的安全怎么做?
8.x 默认开启认证和 TLS;应用侧用 API Key/服务账号并遵循最小权限(限定索引与 read/index 特权),用户侧通过角色(RBAC)或对接 SAML/OIDC/LDAP;传输加密、审计日志、密钥托管在 KMS,配合 Spaces 隔离资产。
自测三问
- 一次 rollover 从触发到对应用透明,需要哪些配置(模板、别名、命名)协同?
- 误删索引后,恢复到在线索引同名会有什么风险?正确恢复姿势是什么?
- 磁盘 90% 后集群会发生什么?解除只读前要先做什么?
小结一句话
运维三件事——用 ILM 管数据生死、用快照 SLM 留后悔药、用 RBAC 收权限,再配上磁盘水位告警和滚动变更纪律,搜索服务才算真正上线。
延伸