第二章: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、索引设置、批量写入
下一章我们将学习日志收集配置。