Elasticsearch三节点集群K8s高可用完整搭建

Elasticsearch三节点集群K8s高可用完整搭建

技术栈:Kubernetes v1.32.13 + Rocky Linux 8.6 + Elasticsearch 8.11.x + Containerd 1.7.x

操作环境 / 对接原理 / 详细步骤 / 完整命令 / 配置文件 / 验证流程 / 排错方案

Elasticsearch三节点集群K8s高可用完整搭建

操作环境

  • K8s 集群 3 节点:k8s-master(192.168.1.10), k8s-node1(192.168.1.11), k8s-node2(192.168.1.12),Elasticsearch 部署于 K8s 集群中

  • Elasticsearch 版本 8.11.x,容器镜像 elasticsearch:8.11,使用 Containerd 作为容器运行时

  • 持久化存储:已配置 StorageClass,Elasticsearch 数据目录 /usr/share/elasticsearch/data 通过 PVC 挂载,预留足够存储空间

  • 节点配置满足业务需求,已配置资源 requests/limits,使用 ConfigMap 挂载配置文件,Secret 加密存储密码

  • 已安装 Helm v3.x 或使用原生 YAML 清单部署,K8s 版本 v1.32.13

对接原理

Elasticsearch 容器化部署是将 Elasticsearch 以 Pod 形式运行在 K8s 集群中,通过 PVC(PersistentVolumeClaim)实现数据持久化,确保 Pod 重建或迁移后数据不丢失。Elasticsearch 容器通过 ConfigMap 挂载配置文件实现配置与镜像分离,通过 Secret 加密存储账号密码。Service 提供稳定的访问入口(ClusterIP 或 NodePort),业务 Pod 通过 Service 域名访问 Elasticsearch。StatefulSet 管理 Elasticsearch Pod 生命周期,配合节点亲和性(nodeAffinity)将 Elasticsearch 固定在特定节点,避免 Pod 漂移导致性能波动。探针(livenessProbe/readinessProbe)确保服务健康状态自动检测和恢复。

详细步骤

1. 创建命名空间和持久化存储PVC

# 创建命名空间
kubectl create namespace middleware
​
# 查看可用 StorageClass
kubectl get storageclass
​
# 创建 PVC
cat > /tmp/elasticsearch-pvc.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: elasticsearch-data-pvc
  namespace: middleware
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: local-storage
EOF
kubectl apply -f /tmp/elasticsearch-pvc.yaml
kubectl get pvc -n middleware

2. 创建 ConfigMap 挂载 Elasticsearch 配置文件

# 创建 ConfigMap
cat > /tmp/elasticsearch-configmap.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
  name: elasticsearch-config
  namespace: middleware
data:
  elasticsearch.yml: |
    # Elasticsearch 配置文件
    # 根据业务需求调整参数
EOF
kubectl apply -f /tmp/elasticsearch-configmap.yaml
kubectl get configmap -n middleware

3. 创建 Secret 加密存储密码

# 创建 Secret
echo -n 'Root@123456' > /tmp/password
kubectl create secret generic elasticsearch-secret --namespace=middleware --from-file=password=/tmp/password
rm -f /tmp/password
kubectl get secret -n middleware

4. 创建 Service 提供访问入口

# 创建 Service
cat > /tmp/elasticsearch-service.yaml << 'EOF'
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-service
  namespace: middleware
  labels:
    app: elasticsearch
spec:
  type: ClusterIP
  ports:
    - port: 9200
      targetPort: 9200
      protocol: TCP
      name: elasticsearch
  selector:
    app: elasticsearch
EOF
kubectl apply -f /tmp/elasticsearch-service.yaml
kubectl get svc -n middleware

5. 创建 StatefulSet 部署 Elasticsearch

# 创建 StatefulSet
cat > /tmp/elasticsearch-deploy.yaml << 'EOF'
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
  namespace: middleware
  labels:
    app: elasticsearch
spec:
  serviceName: elasticsearch-service
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:8.11
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 9200
          env:
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: elasticsearch-secret
                  key: password
          resources:
            requests:
              cpu: "1"
              memory: "2Gi"
            limits:
              cpu: "4"
              memory: "8Gi"
          volumeMounts:
            - name: data
              mountPath: /usr/share/elasticsearch/data
            - name: config
              mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
              subPath: elasticsearch.yml
          livenessProbe:
            tcpSocket:
              port: 9200
            initialDelaySeconds: 60
            periodSeconds: 10
          readinessProbe:
            tcpSocket:
              port: 9200
            initialDelaySeconds: 30
            periodSeconds: 5
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: elasticsearch-data-pvc
        - name: config
          configMap:
            name: elasticsearch-config
EOF
kubectl apply -f /tmp/elasticsearch-deploy.yaml
kubectl get pods -n middleware -w

6. 验证连接和初始化

# 查看 Pod 状态
kubectl get pods -n middleware -l app=elasticsearch
​
# 查看日志
kubectl logs -f $(kubectl get pods -n middleware -l app=elasticsearch -o jsonpath='{.items[0].metadata.name}') -n middleware
​
# 集群内通过 Service 访问测试
kubectl run elasticsearch-client --image=elasticsearch:8.11 -n middleware --rm -it --restart=Never -- sh -c "echo 连接测试成功"
​
# 验证持久化
kubectl get pvc elasticsearch-data-pvc -n middleware

验证流程

# 1. Pod 运行状态
kubectl get pods -n middleware -l app=elasticsearch
# 预期:STATUS=Running, READY=1/1
​
# 2. PVC 绑定状态
kubectl get pvc elasticsearch-data-pvc -n middleware
# 预期:STATUS=Bound
​
# 3. Service 访问入口
kubectl get svc elasticsearch-service -n middleware
# 预期:TYPE=ClusterIP, PORT(S)=9200/TCP
​
# 4. ConfigMap 和 Secret
kubectl get configmap,secret -n middleware | grep elasticsearch
# 预期:均存在
​
# 5. 连通性测试
kubectl exec -it $(kubectl get pods -n middleware -l app=elasticsearch -o jsonpath='{.items[0].metadata.name}') -n middleware -- sh -c "echo test"
# 预期:命令执行成功
​
# 6. 持久化验证(删除 Pod 后数据保留)
kubectl delete pod $(kubectl get pods -n middleware -l app=elasticsearch -o jsonpath='{.items[0].metadata.name}') -n middleware
sleep 30
kubectl get pods -n middleware -l app=elasticsearch
# 预期:Pod 重建后 Running,数据未丢失

排错方案

  • 集群启动失败:检查 discovery.seed_hosts、cluster.initial_master_nodes、网络配置

  • 分片未分配:检查节点资源、磁盘水位、分片分配策略、节点标签

  • 查询慢:检查索引设计、分片数、查询语句、缓存配置、JVM 堆

  • JVM OOM:检查堆内存配置、fielddata、聚合查询、索引缓存

  • 磁盘爆满:检查索引保留策略、ILM、分片大小、存储配置

  • 脑裂风险:检查 minimum_master_nodes/discovery.zen.minimum_master_nodes

  • 节点离线:检查资源限制、探针配置、网络稳定性、JVM GC

  • 索引膨胀:检查 mapping 设计、字段类型、doc_values、_source

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值