跳转至

第二章:Elasticsearch 部署

本章介绍 Elasticsearch 在 Kubernetes 环境中的部署和配置。

部署方式

使用 ECK Operator(推荐)

Elastic Cloud on Kubernetes (ECK) 是官方推荐的部署方式:

# 安装 ECK Operator
kubectl apply -f https://download.elastic.co/downloads/eck/2.8.0/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/2.8.0/operator.yaml

# 验证安装
kubectl get pods -n elastic-system

部署 Elasticsearch 集群

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elasticsearch
  namespace: logging
spec:
  version: 8.11.0
  nodeSets:
  - name: masters
    count: 3
    config:
      node.roles: ["master", "data_hot", "data_content"]
    resources:
      requests:
        memory: 4Gi
        cpu: 2
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 100Gi
        storageClassName: standard
  - name: data
    count: 3
    config:
      node.roles: ["data_hot", "data_content"]
    resources:
      requests:
        memory: 8Gi
        cpu: 4
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 500Gi
        storageClassName: standard

使用 Helm

# 添加 Elastic Helm 仓库
helm repo add elastic https://helm.elastic.co
helm repo update

# 部署 Elasticsearch
helm install elasticsearch elastic/elasticsearch \
  --namespace logging \
  --create-namespace \
  --set replicas=3 \
  --set resources.requests.memory=4Gi \
  --set resources.requests.cpu=2 \
  --set persistence.size=100Gi

节点角色

Elasticsearch 8.x 支持多种节点角色:

角色 说明 资源需求
master 集群管理 CPU 低,内存中
data_hot 热数据存储 CPU 高,内存高,IO 高
data_warm 温数据存储 CPU 中,内存中,IO 中
data_cold 冷数据存储 CPU 低,内存低,IO 低
data_content 内容数据 平衡配置
ingest 数据预处理 CPU 高
ml 机器学习 CPU 高,GPU 可选
transform 数据转换 CPU 中

分层存储架构

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elasticsearch
spec:
  version: 8.11.0
  nodeSets:
  # Master 节点
  - name: master
    count: 3
    config:
      node.roles: ["master"]
    resources:
      requests:
        memory: 2Gi
        cpu: 1
  # 热数据节点
  - name: hot
    count: 3
    config:
      node.roles: ["data_hot", "data_content"]
    resources:
      requests:
        memory: 16Gi
        cpu: 8
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        resources:
          requests:
            storage: 1Ti
  # 温数据节点
  - name: warm
    count: 2
    config:
      node.roles: ["data_warm"]
    resources:
      requests:
        memory: 8Gi
        cpu: 4
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        resources:
          requests:
            storage: 2Ti
  # 冷数据节点
  - name: cold
    count: 1
    config:
      node.roles: ["data_cold"]
    resources:
      requests:
        memory: 4Gi
        cpu: 2

索引配置

索引模板

PUT _index_template/logs-template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "index.lifecycle.name": "logs-policy",
      "index.lifecycle.rollover_alias": "logs"
    },
    "mappings": {
      "properties": {
        "@timestamp": { "type": "date" },
        "message": { "type": "text" },
        "level": { "type": "keyword" },
        "service": { "type": "keyword" },
        "trace_id": { "type": "keyword" },
        "duration_ms": { "type": "long" }
      }
    }
  }
}

数据流

# 创建数据流
PUT _data_stream/logs-app

# 写入数据
POST logs-app/_doc
{
  "@timestamp": "2024-01-15T10:30:00Z",
  "message": "User login",
  "level": "INFO",
  "service": "auth-service"
}

索引生命周期管理 (ILM)

PUT _ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "min_age": "0ms",
        "actions": {
          "rollover": {
            "max_age": "1d",
            "max_primary_shard_size": "50gb"
          },
          "set_priority": {
            "priority": 100
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          },
          "forcemerge": {
            "max_num_segments": 1
          },
          "set_priority": {
            "priority": 50
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "freeze": {},
          "set_priority": {
            "priority": 0
          }
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

安全配置

启用安全

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elasticsearch
spec:
  version: 8.11.0
  secureSettings:
  - secretName: elasticsearch-secrets
  nodeSets:
  - name: default
    count: 3
    config:
      xpack.security.enabled: true
      xpack.security.transport.ssl.enabled: true
      xpack.security.http.ssl.enabled: true

创建用户

# 获取密码
kubectl get secret elasticsearch-es-elastic-user -n logging -o jsonpath='{.data.elastic}' | base64 -d

# 创建用户
curl -u elastic:$PASSWORD -X POST "https://elasticsearch-es-http:9200/_security/user/kibana" -H 'Content-Type: application/json' -d'
{
  "password": "kibana-password",
  "roles": ["kibana_system"],
  "full_name": "Kibana User"
}'

角色配置

PUT _security/role/logs_reader
{
  "indices": [
    {
      "names": ["logs-*"],
      "privileges": ["read", "view_index_metadata"]
    }
  ]
}

性能调优

JVM 配置

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
spec:
  nodeSets:
  - name: default
    config:
      # JVM 堆内存(建议不超过 32GB)
      xpack.security.enabled: false
    jvm: |
      -Xms8g
      -Xmx8g
      -XX:+UseG1GC
      -XX:G1HeapRegionSize=16m

索引设置优化

PUT logs-*/_settings
{
  "index": {
    "refresh_interval": "30s",
    "number_of_replicas": 0,
    "translog": {
      "durability": "async",
      "sync_interval": "30s"
    }
  }
}

批量写入

from elasticsearch import Elasticsearch, helpers

es = Elasticsearch(['http://elasticsearch:9200'])

def bulk_index(docs):
    actions = [
        {
            "_index": f"logs-{doc['service']}",
            "_source": doc
        }
        for doc in docs
    ]
    helpers.bulk(es, actions, chunk_size=1000)

监控

集群健康

# 集群状态
curl -X GET "elasticsearch:9200/_cluster/health?pretty"

# 节点状态
curl -X GET "elasticsearch:9200/_nodes/stats?pretty"

# 索引状态
curl -X GET "elasticsearch:9200/_cat/indices?v"

关键指标

指标 说明 告警阈值
cluster_status 集群状态 yellow/warning, red/critical
jvm_heap_percent JVM 堆使用率 > 85%
disk_usage 磁盘使用率 > 85%
search_latency 搜索延迟 P99 > 1s
indexing_latency 索引延迟 P99 > 500ms

小结

Elasticsearch 部署要点:

  • 部署方式:ECK Operator 或 Helm
  • 节点角色:master、data_hot、data_warm、data_cold
  • 索引管理:模板、数据流、ILM
  • 安全配置:认证、授权、加密
  • 性能调优:JVM、索引设置、批量写入

下一章我们将学习日志收集配置。