問題概述
Elasticsearch 集羣狀態為 "red",由於某個索引的主分片數據在所有節點上丟失,導致集羣健康檢查失敗,Pod 就緒探針無法通過。
故障現象
- 集羣狀態:
red - 未分配分片: 1個
- Pod 狀態:
0/1(就緒探針失敗) - 錯誤信息:
no_valid_shard_copy - 影響: 服務不可用,應用無法連接 Elasticsearch
根本原因
索引分片數據損壞或丟失,所有節點上均找不到有效的數據副本。
環境信息
- 命名空間:
system - Elasticsearch 集羣: 3節點 StatefulSet
- 認證: 啓用基礎認證
- 就緒探針: 要求集羣狀態達到 yellow
處理步驟
步驟1: 診斷集羣狀態
bash
# 檢查集羣健康狀態
kubectl exec -it -n system elasticsearch-master-0 -- curl -u <username>:<password> http://localhost:9200/_cluster/health?pretty
# 查看未分配的分片詳情
kubectl exec -it -n system elasticsearch-master-0 -- curl -u <username>:<password> http://localhost:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason | grep UNASSIGNED
# 分析分片分配問題
kubectl exec -it -n system elasticsearch-master-0 -- curl -u <username>:<password> http://localhost:9200/_cluster/allocation/explain?pretty
步驟2: 識別問題分片
執行診斷命令後,通常會看到類似輸出:
json
{
"index" : "problem_index",
"shard" : 2,
"primary" : true,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "CLUSTER_RECOVERED",
"last_allocation_status" : "no_valid_shard_copy"
},
"can_allocate" : "no_valid_shard_copy"
}
步驟3: 處理損壞的分片
根據業務需求選擇以下方案:
方案A: 刪除損壞索引(數據可丟失時使用)本次修復使用的就是刪除損壞索引,刪除後會出發其他分片重新分配
- active_primary_shards: 大量減少
- unassigned_shards: 大量增加
- initializing_shards: 有分片在初始化
- 這表明刪除索引觸發了大規模的分片重新平衡,但集羣可能遇到了資源或配置問題。
bash
# 刪除有問題的索引(謹慎操作!)
kubectl exec -it -n system elasticsearch-master-0 -- curl -X DELETE -u <username>:<password> http://localhost:9200/problem_index
# 驗證刪除結果
kubectl exec -it -n system elasticsearch-master-0 -- curl -u <username>:<password> http://localhost:9200/_cluster/health?pretty
方案B: 強制分配空分片(保留索引結構)
bash
# 強制分配空的主分片(接受數據丟失)
kubectl exec -it -n system elasticsearch-master-0 -- curl -X POST -u <username>:<password> http://localhost:9200/_cluster/reroute -H 'Content-Type: application/json' -d'
{
"commands": [
{
"allocate_empty_primary": {
"index": "problem_index",
"shard": 2,
"node": "target-node-id",
"accept_data_loss": true
}
}
]
}'
方案C: 從備份恢復(如果有可用備份)
bash
# 從快照恢復索引
kubectl exec -it -n system elasticsearch-master-0 -- curl -X POST -u <username>:<password> http://localhost:9200/_snapshot/repository/snapshot_name/_restore -H 'Content-Type: application/json' -d'
{
"indices": "problem_index",
"ignore_unavailable": false
}'
步驟4: 驗證修復結果
bash
# 檢查集羣狀態(應該變為 green 或 yellow)
kubectl exec -it -n system elasticsearch-master-0 -- curl -u <username>:<password> http://localhost:9200/_cluster/health?pretty
# 檢查 Pod 狀態(應該變為 Ready)
kubectl get pods -n system -l app=elasticsearch-master
# 測試服務連接
kubectl exec -it -n system elasticsearch-master-0 -- curl -u <username>:<password> http://elasticsearch-master.dacs.svc.cluster.local:9200/
緊急恢復方案
如果上述方法無效,考慮集羣重啓:
方案D: 集羣順序重啓
bash
# 1. 縮減副本數為1
kubectl scale statefulset -n dacs elasticsearch-master --replicas=1
# 2. 等待單節點穩定
kubectl logs -n system elasticsearch-master-0 -f
# 3. 逐步擴展回3節點
kubectl scale statefulset -n system elasticsearch-master --replicas=3
方案E: 完全重建(最後手段)
bash
# 完全清理並重建(數據會丟失!)
kubectl delete statefulset -n system elasticsearch-master
kubectl delete pvc -n system -l app=elasticsearch-master
# 重新部署
kubectl apply -f elasticsearch-statefulset.yaml
故障預防建議
1. 配置優化
yaml
# 增加副本數提高容錯
index.number_of_replicas: 1
# 配置定期快照
path.repo: ["/snapshots"]
2. 監控告警
- 監控集羣狀態(green/yellow/red)
- 設置未分配分片數量告警
- 監控節點磁盤使用率
3. 運維規範
- 定期備份重要索引
- 測試恢復流程
- 避免直接操作生產集羣數據
注意事項
- 數據丟失風險: 方案A和方案B會導致數據丟失,務必確認業務影響
- 備份優先: 優先考慮從備份恢復
- 業務影響: 處理期間服務可能不可用
- 權限要求: 需要集羣管理員權限執行修復操作
成功標準
- 集羣狀態變為
green或yellow - 未分配分片數量為
0 - 所有 Pod 狀態為
Ready - 服務可正常連接和訪問
- 應用功能恢復正常