跳转至

IK 中文分词插件安装 — 专项交接(需求规格书)

用途:把「给 monitoring/elasticsearch 装 IK 中文分词」这件事整体移交到 EFK 工程对话执行。 本文档是需求规格与验收标准,不是执行记录。执行方按此落地,结果回填到第 7 节约定路径。 生成时间:2026-10-13 | 生成方:知识库建设对话 起因:知识库(站名「百晓生」)需要中文分词检索,ES 必须装 IK;而 ES 是 EFK 共用组件,故归属本工程。 关联:本工程 manifests/10-elasticsearch.yaml、docs/SOP.md、docs/RUNBOOK.md


1. 目标

给 monitoring 命名空间的 elasticsearch(8.19.0)安装 analysis-ik 中文分词插件,使中文按词切分(ik_smart / ik_max_word),且满足两条硬要求:

  1. 重启后插件仍在(持久化,不能一次重启就丢);
  2. 不影响 EFK 现有索引与日志采集。

2. 已确认的环境事实(2026-10-13 实测,请勿重复取证)

项 事实
工作负载 monitoring/statefulset/elasticsearch,单副本,Pod elasticsearch-0,已运行 12d
镜像 docker.elastic.co/elasticsearch/elasticsearch:8.19.0
部署方式 裸 manifest(manifests/10-elasticsearch.yaml),kubectl apply 管理,非 helm
资源 limits 2C/4Gi,requests 500m/3Gi;ES_JAVA_OPTS=-Xms2g -Xmx2g
存储 仅一个卷 data → /usr/share/elasticsearch/data(PVC 50Gi,nfs-csi-hdd,RWO)
插件目录 /usr/share/elasticsearch/plugins 未挂载、未持久化(在容器可写层)
initContainer fix-data-perms(busybox),对 /usr/share/elasticsearch/data 做 chown -R 1000:1000 + chmod -R 0770
安全 xpack.security.enabled=true,HTTP/transport TLS 关闭;密码由 env ELASTIC_PASSWORD(来自 Secret elasticsearch-credentials,键 elastic-password)注入
调度 nodeSelector: kubernetes.io/hostname=k8s-node-02
IK 包地址 https://get.infini.cloud/elasticsearch/analysis-ik/8.19.0(不带 .zip;GET 200,application/zip,4618740 字节,22 个条目,顶层即插件内容、无外层目录,含 plugin-descriptor.properties)
容器内工具 有 curl、有 /usr/share/elasticsearch/bin/elasticsearch-plugin;无 python3、无 unzip
Pod 出网 可达 get.infini.cloud(实测 200)

3. 为什么不能按「exec 装 + 重启」做

常见写法是 kubectl exec … elasticsearch-plugin install <url> 后 rollout restart。在本环境行不通: plugins 目录未挂载持久卷(见第 2 节),rollout restart 会重建容器,插件随之丢失,等于没装。

因此必须让插件落到持久卷上。方案已在三个候选中定为 C:插件落 PVC(不改镜像、不依赖外网、无需 Harbor)。


4. 实施方案(路径:插件落 data PVC)

思路:把 plugins 目录挂到 data PVC 的子路径 plugins,让插件内容落进持久卷;用 ES 自带的 elasticsearch-plugin 工具安装(容器无 python3/unzip,该工具内部解压最稳)。

cd /home/rain/Documents/k8s_ins/monitoring-p2-20261001

# ---- S1 备份 ----
mkdir -p backup
cp manifests/10-elasticsearch.yaml backup/10-elasticsearch.yaml.bak.$(date +%Y%m%d-%H%M%S)
# 并在 backup/README.md 登记该备份(时间戳、原因、回滚方式)

# ---- S2 在 PVC 里预建插件目录(subPath 目标必须先存在)----
kubectl -n monitoring exec elasticsearch-0 -c elasticsearch -- \
  mkdir -p /usr/share/elasticsearch/data/plugins

# ---- S3 改 manifests/10-elasticsearch.yaml ----
# 在容器 elasticsearch 的 volumeMounts 下新增一条(与现有 data 挂载并列):
#     - name: data
#       mountPath: /usr/share/elasticsearch/plugins
#       subPath: plugins
# initContainer 无需改:它 chown 的是 data 整棵,已覆盖 plugins 子目录。

# ---- S4 应用(此处 Pod 重建,ES 中断约 1~2 分钟)----
kubectl apply -f manifests/10-elasticsearch.yaml
kubectl -n monitoring rollout status sts/elasticsearch --timeout=300s

# ---- S5 安装插件(内容写入 PVC,持久)----
kubectl -n monitoring exec elasticsearch-0 -c elasticsearch -- \
  /usr/share/elasticsearch/bin/elasticsearch-plugin install --batch \
  https://get.infini.cloud/elasticsearch/analysis-ik/8.19.0
kubectl -n monitoring exec elasticsearch-0 -c elasticsearch -- \
  /usr/share/elasticsearch/bin/elasticsearch-plugin list          # 期望输出:analysis-ik

# ---- S5b 补 config/ 词典(必需!实测 install 不落该目录)----
# 现象:不做这步,_analyze 报 NPE(_StopWords is null),索引创建失败、集群可能 red。
# 详见第 5 节 K6 与 docs/IK-INSTALL-RESULT.md 第 4.1 节。
curl -sL -o /tmp/ik.zip https://get.infini.cloud/elasticsearch/analysis-ik/8.19.0
python3 -c "import zipfile;zipfile.ZipFile('/tmp/ik.zip').extractall('/tmp/ik-extract')"
kubectl -n monitoring exec elasticsearch-0 -c elasticsearch -- \
  mkdir -p /usr/share/elasticsearch/plugins/analysis-ik/config
kubectl -n monitoring cp /tmp/ik-extract/config/. \
  monitoring/elasticsearch-0:/usr/share/elasticsearch/plugins/analysis-ik/config -c elasticsearch
rm -rf /tmp/ik.zip /tmp/ik-extract

# ---- S6 重启加载插件 ----
kubectl -n monitoring rollout restart sts/elasticsearch
kubectl -n monitoring rollout status sts/elasticsearch --timeout=300s

# ---- S7 验证分词 ----
kubectl -n monitoring exec elasticsearch-0 -c elasticsearch -- bash -c '
curl -s -u "elastic:$ELASTIC_PASSWORD" -H "Content-Type: application/json" \
  "http://localhost:9200/_analyze" \
  -d "{\"analyzer\":\"ik_smart\",\"text\":\"知识库搭建方案\"}"'
# 期望:中文被切成词(如 知识 / 库 / 搭建 / 方案),而非整串或单字

# ---- S8 持久性验证(本方案成立的关键判据)----
kubectl -n monitoring rollout restart sts/elasticsearch
kubectl -n monitoring rollout status sts/elasticsearch --timeout=300s
kubectl -n monitoring exec elasticsearch-0 -c elasticsearch -- \
  /usr/share/elasticsearch/bin/elasticsearch-plugin list          # 仍应含 analysis-ik

回滚

# 还原挂载(插件目录回到容器可写层,IK 不再加载;ES 本身不受影响)
kubectl apply -f backup/10-elasticsearch.yaml.bak.<ts>
kubectl -n monitoring rollout status sts/elasticsearch --timeout=300s
# PVC 中残留的 plugins/ 目录不影响 ES 运行,可保留或按需删除

5. 已知坑

# 坑 应对
K1 subPath 目录不存在时挂载可能异常 先做 S2 预建目录,再改 manifest
K2 版本不匹配会导致 ES 起不来 IK 包地址已按 ES 8.19.0 取;安装后 plugin list 校验
K3 重启期间 Filebeat 采集 Filebeat 自动重试堆积,不影响已存日志;选低峰执行
K4 只做 restart 不落 PVC 严格执行 S2~S5;S8 的持久性验证不可省
K5 误改 manifest 其他字段 只增一條 volumeMount;apply 前 diff 备份比对
K6 install 不落 config/ 词典 见 S5b。不补则 _analyze 报 NPE、索引创建失败、集群可能 red。重装或升级插件必须重复此步

6. 验收标准(逐条实测并留证据)

# 验收项 判据
A1 插件已安装 elasticsearch-plugin list 含 analysis-ik
A2 中文分词生效 _analyze 用 ik_smart 把「知识库搭建方案」切成词
A3 持久化 再 rollout restart 一次后 A1/A2 仍成立
A4 ES 健康 _cluster/health 为 green/yellow,Pod 1/1 Running
A5 EFK 无扰动 Kibana 可访问;Filebeat Pod 正常;已存日志索引仍在
A6 可回滚 按第 4 节回滚步骤还原后 ES 正常、IK 不再加载

7. 结果回填契约

结果写入路径:/home/rain/Documents/k8s_ins/monitoring-p2-20261001/docs/IK-INSTALL-RESULT.md

必备小节(顺序固定):

  1. ## 1. 实际改动清单(改了哪个文件、加了哪条挂载,附 diff)
  2. ## 2. 备份与时间戳(文件路径 + 登记位置)
  3. ## 3. 验收结果(逐条对 A1~A6,附实际命令输出)
  4. ## 4. 遇到的问题与绕过方式
  5. ## 5. 回滚实测(是否真跑过)
  6. ## 6. 遗留项与后续建议

约定:只写结论与关键证据;不写任何密码(ES 密码从 $ELASTIC_PASSWORD 取用,不落文档)。


8. 边界(本次不做)

  • ❌ 不改 ES 版本、不动 data 卷内容、不改 Kibana / Filebeat
  • ❌ 不做自定义镜像(方案 C,非方案 B)
  • ❌ 不为 EFK 现有索引新增 IK 映射(如需要另议,避免影响存量检索行为)
  • ❌ 不把凭据写入任何交付物

9. 给知识库侧的说明(背景,非本工程任务)

知识库(百晓生)在 monitoring/elasticsearch 上建独立索引(拟名 knowledge),中文字段用 ik_max_word,查询用 ik_smart。装 IK 是前置之一;知识库侧的索引与灌库由知识库工程负责,本工程只需保证插件可用且持久。


来源:/home/rain/Documents/k8s_ins/monitoring-p2-20261001/docs/IK-INSTALL-HANDOFF.md | 最后更新:2026-10-13 20:07(由 build/sync.py 同步,请勿在站点侧修改)