必须用statefulset而非deployment,因elasticsearch是有状态服务,需稳定节点名(如elasticsearch-0)、固定dns解析(配合headless service)、独占pvc持久存储,否则将导致集群发现失败、分片丢失或脑裂。

直接上生产环境,别用 Deployment —— Elasticsearch 是有状态服务,节点名、网络标识、存储卷必须稳定,否则集群发现失败、分片丢失、脑裂频发。
为什么必须用 StatefulSet 而不是 Deployment
Deployment 会随机生成 Pod 名(如 es-5f8b9d7c4-xyz),而 Elasticsearch 节点间靠固定主机名通信(如 elasticsearch-0.elasticsearch)。StatefulSet 保证:elasticsearch-0 永远调度到同一 PV、永远解析为同一 DNS 记录、重启后名字不变。
- Headless Service(
clusterIP: None)是必须的,它让每个 Pod 拥有独立可解析的 DNS 名 - 若用
Deployment+ClusterIPService,所有请求都打到同一个入口,节点无法互相发现 - 官方镜像启动时检查
discovery.seed_hosts,若解析不到真实 Pod IP,日志里会反复报failed to resolve host
vm.max_map_count 必须提前调,否则 Pod 卡在 Pending 或 CrashLoopBackOff
Elasticsearch 启动时强制检查内核参数 vm.max_map_count,默认值(通常 65530)远低于要求(最低 262144)。Kubernetes 不会帮你改宿主机内核,Pod 启动直接失败,日志里只有一行:ERROR: [1] bootstrap checks failed。
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
- 在所有 Worker 节点执行:
sysctl -w vm.max_map_count=262144 - 写入持久化配置:
echo "vm.max_map_count=262144" >> /etc/sysctl.conf - 注意:仅修改 kubelet 所在节点,Master 节点不运行 ES Pod 就不用动
ConfigMap 中的 discovery.seed_hosts 和 cluster.initial_master_nodes 容易配错
这两个配置项决定集群能否完成首次选举。常见错误是写死 IP 或用 Service 名代替 Headless Service 的 DNS 格式。
-
discovery.seed_hosts应填 StatefulSet 域名格式:elasticsearch-0.elasticsearch,elasticsearch-1.elasticsearch(注意后缀是 Service 名,不是命名空间) -
cluster.initial_master_nodes必须与 Pod 名完全一致:elasticsearch-0,elasticsearch-1(不能带域名,不能有空格) - 若用 Helm Chart 或 ECK,这些由模板自动生成;手写 YAML 时最容易漏掉
.elasticsearch这个 DNS 后缀 - ES 8.x 默认启用安全认证,
xpack.security.enabled: true时,还需提前创建Secret存密码,否则健康检查 401
PV/PVC 绑定失败常因 StorageClass 不匹配或 local-path 权限问题
StatefulSet 每个副本需独占 PVC,而 PVC 绑定 PV 失败会导致 Pod 一直卡在 Pending 状态,kubectl describe pod 显示 Waiting for volume to be created。
- 确认 StorageClass 名与 PVC 中
storageClassName字段严格一致(大小写敏感) - 若用
local-path类型 PV,宿主机目录(如/data/es)必须属主为 UID 1001(Elasticsearch 官方镜像默认用户)且权限 755 - NFS 场景下,确保 export 配置含
no_root_squash,否则容器以 root 写入会被拒绝 - ES 8.x 对磁盘剩余空间有硬性要求(默认需 > 5%),PV 空间不足也会拒绝挂载
真正麻烦的不是写完 YAML,而是节点加入后分片不分配、_cat/shards 里一堆 UNASSIGNED,那往往是 discovery.seed_hosts 解析对了但 network.host 没监听对网卡——它默认只绑 127.0.0.1,得显式设成 0.0.0.0 或具体 Pod IP。










