基于K8S部署生产高可用的ES集群(附迁移方案)
ECK简介
https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html
Elastic Cloud on Kubernetes (ECK) 是一个官方提供的用于在 Kubernetes 集群中简化部署、管理和操作 Elastic Stack(包括 Elasticsearch 和 Kibana)的扩展。
ECK 是一个 Kubernetes Operator,它管理和自动化 Elastic Stack 的生命周期。通过使用 ECK,可以在 Kubernetes 环境中快速实现以下功能:
- 部署和管理 Elasticsearch 和 Kibana 实例,包括创建、删除、扩展和升级。
- 配置和调整 Elastic Stack 组件以满足特定需求。
- 自动处理故障检测、恢复和备份。
- 保护 Elasticsearch 集群,通过安全配置、证书管理和安全通信来确保数据安全。
- 监控 Elastic Stack 的性能和资源使用,从而优化集群性能。
支持的版本
- Kubernetes 1.26-1.30(ECK2.14.0,低版本可以支持低版本的K8S,请自行到官网查看。)
- Elasticsearch, Kibana, APM Server: 6.8+, 7.1+, 8+
- Beats: 7.0+, 8+
- Logstash: 8.7+
部署 operator
kubectl create -f https://download.elastic.co/downloads/eck/2.14.0/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/2.14.0/operator.yaml
部署 ES
部署版本:
- 7.17.24
部署模式:
- 3master节点,master,data共用节点。
- HTTP模式
- basic认证
- hostNetwork
- local-path
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: casslogs
namespace: elastic-system
spec:
version: 7.17.24
http:
tls:
selfSignedCertificate:
disabled: true
nodeSets:
- name: data
count: 3
# 禁用认证需要增加以下配置
#config:
# xpack.security.authc:
# anonymous:
# username: anonymous
# roles: superuser
# authz_exception: false
podTemplate:
spec:
initContainers:
- name: sysctl
securityContext:
privileged: true
runAsUser: 0
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
containers:
- name: elasticsearch
env:
- name: ES_JAVA_OPTS
value: "-Xms16g -Xmx16g"
- name: ES_SETTING_CLUSTER_MAX__SHARDS__PER__NODE
value: '90000'
- name: ES_SETTING_HTTP_MAX__CONTENT__LENGTH
value: 300MB
- name: ES_SETTING_HTTP_MAX__INITIAL__LINE__LENGTH
value: 20KB
- name: ES_SETTING_HTTP_MAX__HEADER__SIZE
value: 32KB
- name: ES_SETTING_THREAD__POOL_WRITE_QUEUE__SIZE
value: '2000'
- name: ES_SETTING_THREAD__POOL_SEARCH_QUEUE__SIZE
value: '2000'
- name: ES_SETTING_THREAD__POOL_GET_QUEUE__SIZE
value: '2000'
resources:
limits:
cpu: 8
memory: 32Gi
requests:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: timezone-volume
mountPath: /etc/localtime
readOnly: true
volumes:
- name: timezone-volume
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
elasticsearch.k8s.elastic.co/cluster-name: casslogs
topologyKey: kubernetes.io/hostname
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3000Gi
storageClassName: local-path
部署Kibana
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: kibana
namespace: elastic-system
spec:
version: 7.17.24
count: 3
elasticsearchRef:
name: casslogs
namespace: elastic-system
# 禁用认证需要增加以下配置
#config:
# xpack.security.enabled: false
http:
service:
spec:
type: NodePort
tls:
selfSignedCertificate:
disabled: true
podTemplate:
spec:
containers:
- name: kibana
env:
- name: NODE_OPTIONS
value: "--max-old-space-size=2048"
- name: I18N_LOCALE
value: zh-CN
- name: SERVER_PUBLICBASEURL
value: "http://log.casstime.cn"
resources:
requests:
memory: 100Mi
cpu: 0.5
limits:
memory: 4Gi
cpu: 2
# 禁用认证需要修改健康检查接口
#readinessProbe:
# failureThreshold: 3
# initialDelaySeconds: 10
# periodSeconds: 10
# successThreshold: 1
# timeoutSeconds: 5
# TCP健康检查方式
# tcpSocket:
# port: 5601
# HTTP健康检查方式
# httpGet:
# path: /
# port: 5601
# scheme: HTTP
volumeMounts:
- name: timezone-volume
mountPath: /etc/localtime
readOnly: true
volumes:
- name: timezone-volume
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
elasticsearch.k8s.elastic.co/name: kibana
topologyKey: kubernetes.io/hostname
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
用户管理
方式1
# 解析: Secret: casslogs-es-elastic-user
# 获取elastic的密码
# 登录kibana在Stack Management,安全管理中进行用户管理
http://10.1.0.26:5601/app/management/security/users
方式2
# 编辑部署ES的yaml文件
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: casslogs
namespace: elastic-system
spec:
version: 7.17.24
# 增加账号管理
auth:
fileRealm:
- secretName: es-users-secret
# 新增用户es-users-secret,设置组为超级管理员
kind: Secret
apiVersion: v1
metadata:
name: es-users-secret
namespace: elastic-system
stringData:
# 格式是 账号:密码
# 可以同时增加多个用户并设置对应的组
users: |-
casslogs:cfsa3fsdfs3s
users_roles: |-
superuser:casslogs
kibana配置优化
# 日期格式
MM-DD@HH:mm:ss.SSS
# 默认列
message
# 时间筛选速选范围
[
{
"from": "now-15m",
"to": "now",
"display": "最近 15 分钟"
},
{
"from": "now-30m",
"to": "now",
"display": "最近 30 分钟"
},
{
"from": "now-1h",
"to": "now",
"display": "最近 1 小时"
},
{
"from": "now-3h",
"to": "now",
"display": "最近 3 小时"
},
{
"from": "now-5h",
"to": "now",
"display": "最近 5 小时"
},
{
"from": "now-9h",
"to": "now",
"display": "最近 9 小时"
},
{
"from": "now-25h",
"to": "now",
"display": "最近 25 小时"
},
{
"from": "now/d",
"to": "now/d",
"display": "今日"
},
{
"from": "now-3d",
"to": "now",
"display": "最近 3 天"
},
{
"from": "now/w",
"to": "now/w",
"display": "本周"
}
]
ES数据迁移
方案 | elasticsearch-dump | esm | reindex | logstash | snapshot |
---|---|---|---|---|---|
基本原理 | 逻辑备份,类似mysqldump将数据一条一条导出后再执行导入 | ESM 是 medcl 开源的派生自:Elasticsearch Dumper 的工具,基于 go 语言开发。 | reindex 是 Elasticsearch 提供的一个 API 接口,可以把数据从一个集群迁移到另外一个集群 | 从一个集群中读取数据然后写入到另一个集群 | 从源集群通过Snapshot API 创建数据快照,然后在目标集群中进行恢复 |
网络要求 | 无网络互通要求 | 无网络互通要求 | 网络需要互通 | 网络需要互通 | 无网络互通要求 |
迁移速度 | 最慢 | 很慢 | 一般 | 很快 | 最快 |
适合场景 | 适用于数据量小的离线场景 | 适用于数据量小的离线场景 | 适用于数据量中等,在线迁移数据的场景 | 适用于数据量很大,实时数据传输的场景 | 适用于数据量特大,离线数据迁移的场景 |
配置复杂度 | 简单 | 简单 | 中等 | 中等 | 复杂 |
缺点 | 速度全宇宙最慢,没有之一 | 跨大版本不能迁移mapping,需要手动迁移 | 需要设置集群白名单,重启elasticsearch服务 | logstash对资源要求较高,建议单独的一台服务器运行。 | 在快照还原过程中无法修改分片数,分片数取决于源集群索引设置。 |
迁移时长(1100万条数据) | 3小时 | 1小时10分钟 | 15分钟 | 8分钟 | 2分钟 |
reindex
设置索引模板,保证写入速率最大化
# 完成迁移后在索引管理中将number_of_replicas和refresh_interval参数设置为合适的值即可。
PUT _template/hwprod
{
"index_patterns": [
"hwprod*"
],
"order": 999,
"settings": {
"refresh_interval": "-1",
"number_of_shards": "3",
"translog": {
"sync_interval": "60s",
"durability": "async"
},
"number_of_replicas": "0"
}
}
配置集群白名单,新增源数据集群es地址
# 修改配置文件方式
vim /etc/elasticsearch/elasticsearch.yml
reindex.remote.whitelist: "10.1.72.33:9200"
systemctl restart elasticsearch.service
# K8S部署环境变量模式
- name: ES_SETTING_REINDEX_REMOTE_WHITELIST
value: 10.1.72.33:9200
执行reindex迁移
# 请求
# size: 每批次的数据量
# slice: 切片数量, 和节点数一致
# wait_for_completion=false: 异步执行
POST _reindex?wait_for_completion=false
{
"source": {
"remote": {
"host": "http://10.1.72.33:9200",
"username": "elastic",
"password": "asdf1234"
},
"index": "hwprod-2024.9.1",
"size": 10000,
"slice": {
"id": 0,
"max": 3
}
},
"dest": {
"index": "hwprod-2024.9.1"
}
}
# 响应
{
"task": "PuSABDEeTsSXUiW7U--uAw:40193"
}
# 查询异步任务
GET _tasks/PuSABDEeTsSXUiW7U--uAw:40193
StarsL.cn