如何在Kubernetes环境中使用Docker镜像部署 EFK (Elastic Search + Filebeat/Fluentd + Kibana) 日志监控系统?本文将示例如何编写Elastic Search的部署文件,部署中间会遇到什么坑,如何解决?(详见末尾!详见末尾!!详见末尾!!!)
上部署文件: 个人在18年预研时编写的,当时的资料是很少的
- es-dep.yaml
# 指定部署类型为Deployment,实际生产时可能会部署为有状态的StatefulSet类型,并使用持久存储。
apiVersion: apps/v1beta1
kind: Deployment
# 设置元数据信息
metadata:
name: es
#namespace: ebk
labels: # (可选)为该Pod添加标签
component: elasticsearch # 标签的key可任意命名
# 具体部署配置项
spec:
selector: # (可选)指定具体的template,如指定则必须与spec.template.metadata.labels匹配,否则会创建不成功;如不指定,则默认是spec.template.metadata.labels
matchLabels:
component: elasticsearch
replicas: 3 # 副本数量为3,可理解为部署3个Pod
template: # 每个副本的模板配置项,k8s会按下面配置创建各个副本
metadata:
labels:
component: elasticsearch
spec:
# 创建一个初始容器,此容器会先于后面的应用容器运行,只有init容器运行成功后,才会运行后面的应用容器,如果运行失败,默认kubernetes会不断重启该Pod,直到Init容器成功运行。
# 下面这种写法仅支持kubernetes1.6以上版本,在此用于为该Pod设置特殊资源请求或限制的最大值
initContainers:
- name: init-sysctl # 容器名,任意指定
image: busybox:1.27.2 # 指定镜像来源及版本号
command: # 容器启动命令,这里要设置vm.max_map_count=262144,否则ES会无法启动。
- sysctl
- -w
- vm.max_map_count=262144
securityContext: # 开启特权,否则上面命令无法执行
privileged: true
# 配置具体的应用容器
containers:
- name: es-node
# 下面镜像来源k8s官方示例推荐,其在官方elasticsearch镜像基础上,对一些配置进行了抽取,此更便于我们的部署配置
image: quay.io/pires/docker-elasticsearch-kubernetes:6.3.0
# 配置应用容器中的环境变量
env:
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: CLUSTER_NAME # 环境变量名
value: myesdb # 变量值
# 指定DISCOVERY_SERVICE变量值,镜像中默认值为elasticsearch-discovery,这里修改为下面配置的Service的名称elasticsearch
- name: DISCOVERY_SERVICE
value: "elasticsearch"
# 设置集群的最小主节点数量,这里表示集群至少需要2个主节点才能运行
- name: NUMBER_OF_MASTERS
value: "2"
# 实际生产部署可能需要对Master/Ingest/Data功能做拆分,不会集中在一个Pod上。
# 设置该容器是否是主节点
- name: NODE_MASTER
value: "true"
# 设置该容器是否用于摄取期间的Document预处理
- name: NODE_INGEST
value: "true"
# 设置是否用于数据存储
- name: NODE_DATA
value: "true"
# 设置开启HTTP API
- name: HTTP_ENABLE
value: "true"
# 设置网络参数,否则会启动报错
- name: NETWORK_HOST
value: _site_,_lo_
# 设置JVM参数
- name: ES_JAVA_OPTS
value: -Xms512m -Xmx512m
# 设置CPU资源
- name: PROCESSORS
valueFrom:
resourceFieldRef:
resource: limits.cpu
# 设置最低资源及最大资源限制
resources:
requests:
cpu: 0.25
limits:
cpu: 1
# 设置容器暴露的端口
ports:
- containerPort: 9200
name: http
- containerPort: 9300
name: transport
# 设置卷挂载
volumeMounts:
- name: storage
mountPath: /data
# 实际部署时此处应定义主机上真是存在的路径,用于ES做卷挂载进行数据存储,这里使用emptyDir,在ES Pod重启后,之前的数据会丢失。
volumes:
- name: storage
emptyDir: {}
# 实际生产部署需要指定数据具体存储路径,下面为使用主机/ebk/es/data来挂载存储ES数据
#- name: storage
#hostPath:
#path: /ebk/es/data
- es-svc.yaml
# 指定部署类型为Service
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
labels:
component: elasticsearch
spec:
selector:
component: elasticsearch
# 设置Service暴露的端口为9200和9300,如不配置targetPort(Pod暴露的端口),则默认和配置的port相同
ports:
- name: http
port: 9200
#targetPort: 9200
protocol: TCP
- name: transport
port: 9300
protocol: TCP
上命令运行:
# 按顺序创建Pod和Service
kubectl create -f es-dep.yaml
kubectl create -f es-svc.yaml
# 创建完成后可以使用下面命令查看Pod和Service状态
root@k8s:~# kubectl get pod
NAME READY STATUS RESTARTS AGE
es-b74f6c98b-bbmj2 1/1 Running 0 4d
es-b74f6c98b-dn74h 1/1 Running 0 4d
es-b74f6c98b-fbkf5 1/1 Running 0 4d
root@k8s:~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch ClusterIP 10.43.175.154 <none> 9200/TCP,9300/TCP 4d
# 使用命令查看es service的IP地址,然后通过命令查看集群部署是否成功
root@k8s:~# kubectl get svc elasticsearch
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch ClusterIP 10.43.175.154 <none> 9200/TCP,9300/TCP 4d
root@k8s:~# curl 10.43.175.154:9200
{
"name" : "es-b74f6c98b-dn74h",
"cluster_name" : "myesdb",
"cluster_uuid" : "5C0TiQmqR2yYVTl_QDjeRA",
"version" : {
"number" : "6.3.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "424e937",
"build_date" : "2018-06-11T23:38:03.357887Z",
"build_snapshot" : false,
"lucene_version" : "7.3.1",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
root@k8s:~# curl 10.43.175.154:9200/_cluster/health?pretty
{
"cluster_name" : "myesdb",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 41,
"active_shards" : 82,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
可能会遇到的坑:
- 因未修改vm.max_map_count的值导致ES容器无法启动;
- 在k8s1.5版本使用annotation的方式设置vm.max_map_count=262144无效,导致启动ES容器报错;
- 由于未将ES服务发现做单独拆分,所以需要修改配置DISCOVERY_SERVICE的值,否则无法访问该集群;
- 需要配置NETWORK_HOST,否则ES API会无法访问,或者启动会报错。
以上纯原创,未完待续! 后续将更新 Filebeat/Fluentd、Kibana、Grafana、ElastAlert、Packetbeat等工具部署,欢迎加关注、收藏、点赞、打赏(代码闲聊站)~