Kubernetes 中 搭建 EFK 日志搜索中心
简介
Elastic 官方已经发布了Elasticsearch Operator ,简化了 elasticsearch 以及 kibana的部署与升级,结合 fluentd-kubernetes-daemonset,现在在kubernetes 部署 EFK 已经非常方便。
部署 Elasticsearch Operator 和 一些必要的资源
这个yaml 文件比较大 我放了个链接,我这里主要修改了 namespace
kubectl apply -f https://download.elastic.co/downloads/eck/1.1.2/all-in-one.yaml
部署 Elasticsearch 集群
先创建几个 PersistentVolume StorageClass,我这里用的是localpv,我会部署3个data节点 所以创建三个pv,默认 elastic 用户 的密码是自动生成的 可以到 secrect 中查看,这个secret 名字以 elastic-user 结尾,用base64 解压就行。
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage-es-test
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: es-test-pv-
namespace: efk
spec:
capacity:
storage: 100G
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage-es-test
local:
path: /data/elasticsearch-test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node-
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: es-test-pv-
namespace: efk
spec:
capacity:
storage: 100G
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage-es-test
local:
path: /data/elasticsearch-test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node-
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: es-test-pv-
namespace: efk
spec:
capacity:
storage: 100G
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage-es-test
local:
path: /data/elasticsearch-test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-node-
---
然后创建es集群,文件里对不好理解的我写了注释
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: cluster-test
namespace: efk
spec:
version: 7.3.
http:
tls:
selfSignedCertificate:
## 取消默认的tls
disabled: true
nodeSets:
## master 节点 名称
- name: master
count:
podTemplate:
spec:
volumes:
- name: elasticsearch-data
emptyDir: {}
initContainers:
- name: sysctl
securityContext:
privileged: true
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
containers:
- name: elasticsearch
readinessProbe:
exec:
command:
- bash
- -c
- /mnt/elastic-internal/scripts/readiness-probe-script.sh
failureThreshold:
initialDelaySeconds:
periodSeconds:
successThreshold:
timeoutSeconds:
env:
## jvm 内存
- name: ES_JAVA_OPTS
value: -Xms1g -Xmx1g
- name: READINESS_PROBE_TIMEOUT
value: ""
resources:
requests:
cpu: 100m
limits:
cpu: 1000m
config:
## 是不是master节点 ,节点这里可以看文档,一个节点既可以是master 也可以是 data
node.master: "true"
node.data: "false"
node.ingest: "false"
- name: data
count:
volumeClaimTemplates:
- metadata:
name: elasticsearch-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100G
## 我定义的 sc
storageClassName: local-storage-es-test
podTemplate:
spec:
initContainers:
- name: sysctl
securityContext:
privileged: true
command: ['sh', '-c', 'sysctl -w vm.max_map_count=262144']
- name: increase-fd-ulimit
securityContext:
privileged: true
command: ["sh", "-c", "ulimit -n 65536"]
containers:
- name: elasticsearch
readinessProbe:
exec:
command:
- bash
- -c
- /mnt/elastic-internal/scripts/readiness-probe-script.sh
failureThreshold:
initialDelaySeconds:
periodSeconds:
successThreshold:
timeoutSeconds:
env:
- name: ES_JAVA_OPTS
value: -Xms1g -Xmx1g
- name: READINESS_PROBE_TIMEOUT
value: ""
resources:
requests:
cpu: 100m
limits:
cpu: 1000m
config:
node.master: "false"
node.data: "true"
node.ingest: "true"
部署 Kibana 与 ingress
这里我主要设置了 Kinana Prefix 访问路径
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: kibana-test
namespace: efk
spec:
version: 7.3.
http:
tls:
selfSignedCertificate:
disabled: true
count:
elasticsearchRef:
name: cluster-test
podTemplate:
spec:
containers:
- name: kibana
resources:
limits:
cpu: 1000m
requests:
cpu: 100m
env:
- name: SERVER_BASEPATH
value: "/kibana-test"
- name: SERVER_REWRITEBASEPATH
value: 'true'
readinessProbe:
failureThreshold:
httpGet:
path: /kibana-test/login
port:
scheme: HTTP
initialDelaySeconds:
periodSeconds:
successThreshold:
timeoutSeconds: ---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-kibana-test
namespace: efk
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: ks.***.cn
http:
paths:
- path: /kibana-test
backend:
serviceName: kibana-test-kb-http
servicePort:
部署 Fluentd
这里贴一下 kubernetes_metadata 使用部分的源码,默认支持几个kubernetes_metadata的配置,所有配置看文档,这是一个 fluentd filter ,这个细节也可以不看。
<filter kubernetes.**>
@type kubernetes_metadata
@id filter_kube_metadata
kubernetes_url "#{ENV['FLUENT_FILTER_KUBERNETES_URL'] || 'https://' + ENV.fetch('KUBERNETES_SERVICE_HOST') + ':' + ENV.fetch('KUBERNETES_SERVICE_PORT') + '/api'}"
verify_ssl "#{ENV['KUBERNETES_VERIFY_SSL'] || true}"
ca_file "#{ENV['KUBERNETES_CA_FILE']}"
skip_labels "#{ENV['FLUENT_KUBERNETES_METADATA_SKIP_LABELS'] || 'false'}"
skip_container_metadata "#{ENV['FLUENT_KUBERNETES_METADATA_SKIP_CONTAINER_METADATA'] || 'false'}"
skip_master_url "#{ENV['FLUENT_KUBERNETES_METADATA_SKIP_MASTER_URL'] || 'false'}"
skip_namespace_metadata "#{ENV['FLUENT_KUBERNETES_METADATA_SKIP_NAMESPACE_METADATA'] || 'false'}"
</filter>
这里贴一下 kubernetes 日志 tail input 使用部分的源码,默认路径为 /var/log/containers/*.log ,这里需要注意一些 fluentd pod volumes 的配置,保证在pod内 可以拿得到日志文件 。
<source>
@type tail
@id in_tail_container_logs
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag "#{ENV['FLUENT_CONTAINER_TAIL_TAG'] || 'kubernetes.*'}"
exclude_path "#{ENV['FLUENT_CONTAINER_TAIL_EXCLUDE_PATH'] || use_default}"
read_from_head true
<parse>
@type "#{ENV['FLUENT_CONTAINER_TAIL_PARSER_TYPE'] || 'json'}"
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
这里是 fluentd DaemonSet 的配置 由于我的 docker 主目录在 /Data/docker 下 ,而且/var/log/ 下的文件只是一个链接 ,所以 我特意加了一个 volume ,总之要保证获取到文件。还有 es 的账号密码 我建议自己创一个,因为默认生成的elastic 用户密码是随机的(我之前创建集群的时候还不能自定义初始用户密码,我写这篇文章的时候没有特意去查,因为对我来说这点不是特别重要)。
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: efk
labels:
app: fluentd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd
labels:
app: fluentd
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: efk
---
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-test
namespace: efk
labels:
app: fluentd-test
spec:
selector:
matchLabels:
app: fluentd-test
template:
metadata:
labels:
app: fluentd-test
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.11.0-debian-elasticsearch7-1.0
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "cluster-test-es-http.efk.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_USER
value: "admin"
- name: FLUENT_ELASTICSEARCH_PASSWORD
value: ""
- name: FLUENT_ELASTICSEARCH_PORT
value: ""
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENTD_SYSTEMD_CONF
value: disable
- name: FLUENT_KUBERNETES_METADATA_SKIP_CONTAINER_METADATA
value: 'true'
- name: FLUENT_KUBERNETES_METADATA_SKIP_MASTER_URL
value: 'true'
- name: FLUENT_KUBERNETES_METADATA_SKIP_NAMESPACE_METADATA
value: 'true'
- name: FLUENT_KUBERNETES_METADATA_SKIP_LABELS
value: 'true'
- name: FLUENT_ELASTICSEARCH_INCLUDE_TIMESTAMP
value: 'true'
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/log/containers
readOnly: true
- name: varlibdockercontainers-kube-path
mountPath: /var/log/pods
readOnly: true
- name: varlibdockercontainers-real-path
mountPath: /data/docker/containers
readOnly: true
terminationGracePeriodSeconds:
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/log/containers
- name: varlibdockercontainers-kube-path
hostPath:
path: /var/log/pods
- name: varlibdockercontainers-real-path
hostPath:
path: /data/docker/containers
查看日志
进入 kibana ,查看 所有 index 可以看到以下界面

这个名字什么的是可以改的,贴源码
<match **>
@type elasticsearch
@id out_es
@log_level info
include_tag_key true
host "#{ENV['FLUENT_ELASTICSEARCH_HOST']}"
port "#{ENV['FLUENT_ELASTICSEARCH_PORT']}"
path "#{ENV['FLUENT_ELASTICSEARCH_PATH']}"
scheme "#{ENV['FLUENT_ELASTICSEARCH_SCHEME'] || 'http'}"
ssl_verify "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERIFY'] || 'true'}"
ssl_version "#{ENV['FLUENT_ELASTICSEARCH_SSL_VERSION'] || 'TLSv1_2'}"
user "#{ENV['FLUENT_ELASTICSEARCH_USER'] || use_default}"
password "#{ENV['FLUENT_ELASTICSEARCH_PASSWORD'] || use_default}"
reload_connections "#{ENV['FLUENT_ELASTICSEARCH_RELOAD_CONNECTIONS'] || 'false'}"
reconnect_on_error "#{ENV['FLUENT_ELASTICSEARCH_RECONNECT_ON_ERROR'] || 'true'}"
reload_on_failure "#{ENV['FLUENT_ELASTICSEARCH_RELOAD_ON_FAILURE'] || 'true'}"
log_es_400_reason "#{ENV['FLUENT_ELASTICSEARCH_LOG_ES_400_REASON'] || 'false'}"
logstash_prefix "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_PREFIX'] || 'logstash'}"
logstash_dateformat "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_DATEFORMAT'] || '%Y.%m.%d'}"
logstash_format "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_FORMAT'] || 'true'}"
index_name "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_INDEX_NAME'] || 'logstash'}"
type_name "#{ENV['FLUENT_ELASTICSEARCH_LOGSTASH_TYPE_NAME'] || 'fluentd'}"
include_timestamp "#{ENV['FLUENT_ELASTICSEARCH_INCLUDE_TIMESTAMP'] || 'false'}"
template_name "#{ENV['FLUENT_ELASTICSEARCH_TEMPLATE_NAME'] || use_nil}"
template_file "#{ENV['FLUENT_ELASTICSEARCH_TEMPLATE_FILE'] || use_nil}"
template_overwrite "#{ENV['FLUENT_ELASTICSEARCH_TEMPLATE_OVERWRITE'] || use_default}"
sniffer_class_name "#{ENV['FLUENT_SNIFFER_CLASS_NAME'] || 'Fluent::Plugin::ElasticsearchSimpleSniffer'}"
request_timeout "#{ENV['FLUENT_ELASTICSEARCH_REQUEST_TIMEOUT'] || '5s'}"
<buffer>
flush_thread_count "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_FLUSH_THREAD_COUNT'] || '8'}"
flush_interval "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_FLUSH_INTERVAL'] || '5s'}"
chunk_limit_size "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_CHUNK_LIMIT_SIZE'] || '2M'}"
queue_limit_length "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_QUEUE_LIMIT_LENGTH'] || '32'}"
retry_max_interval "#{ENV['FLUENT_ELASTICSEARCH_BUFFER_RETRY_MAX_INTERVAL'] || '30'}"
retry_forever true
</buffer>
</match>
创建 Index patterns。

然后就可以查看了

Kubernetes 中 搭建 EFK 日志搜索中心的更多相关文章
- kubernetes集群EFK日志系统搭建
日志收集架构 Kubernetes 集群本身不提供日志收集的解决方案,一般来说有主要的3种方案来做日志收集: 在节点上运行一个 agent 来收集日志 在 Pod 中包含一个 sidecar 容器来收 ...
- centos7搭建EFK日志分析系统
前言 EFK可能都不熟悉,实际上EFK是大名鼎鼎的日志系统ELK的一个变种 在没有分布式日志的时候,每次出问题了需要查询日志的时候,需要登录到Linux服务器,使用命令cat -n xxxx|grep ...
- Kubernetes 系列(八):搭建EFK日志收集系统
Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch.Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案. Elasticsearch 是一个 ...
- Kubernetes 日志:搭建 EFK 日志系统
Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch.Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案. Elasticsearch 是一个 ...
- 十九,基于helm搭建EFK日志收集系统
目录 EFK日志系统 一,EFK日志系统简介: 二,EFK系统部署 1,EFK系统部署方式 2,基于Helm方式部署EFK EFK日志系统 一,EFK日志系统简介: 关于系统日志收集处理方案,其实有很 ...
- Docker搭建EFK日志收集系统,并自定义es索引名
EFK架构图 一.EFK简介 EFK不是一个软件,而是一套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用,是目前主流的一种日志系统. EFK是三个开源软件的缩写,分 ...
- k8s集群搭建EFK日志平台:ElasticSearch + Fluentd + Kibana
k8s集群 kubectl get node EFK简介 ElasticSearch:分布式存储检索引擎,用来搜索.存储日志 Fluentd:日志采集 Kibana:读取es中数据进行可视化web界面 ...
- 在kubernetes中搭建harbor,并利用MinIO对象存储保存镜像文件
前言:此文档是用来在线下环境harbor利用MinIO做镜像存储的,至于那些说OSS不香吗?或者单机harbor的,不用看了.此文档对你没啥用,如果是采用单机的harbor连接集群MinIO,请看我的 ...
- k8s-搭建 EFK 日志系统
搭建 EFK 日志系统 大家介绍了 Kubernetes 集群中的几种日志收集方案,Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch.Fluentd 和 Kibana( ...
随机推荐
- Java实现 蓝桥杯VIP 算法训练 连通分块(并查集)
试题 算法训练 连通分块 资源限制 时间限制:200ms 内存限制:8.0MB 问题描述 连通分块 输入格式 输入的第一行包含两个整数n, m n代表图中的点的个数,m代表边的个数 接下来m行,每行2 ...
- Java实现 蓝桥杯 算法提高 字符串匹配
试题 算法提高 字符串匹配 问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符:当选项关闭时 ...
- Java实现 LeetCode 679 24 点游戏(递归)
679. 24 点游戏 你有 4 张写有 1 到 9 数字的牌.你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24. 示例 1: 输入: [4, 1, 8, 7] 输出: True 解释: ...
- Java实现 LeetCode 26 删除排序数组中的重复项
26. 删除排序数组中的重复项 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) ...
- Java实现 LeetCode 4 寻找两个有序数组的中位数
寻找两个有序数组的中位数 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 n ...
- java实现放麦子问题
/* 你一定听说过这个故事.国王对发明国际象棋的大臣很佩服, 问他要什么报酬,大臣说:请在第 1 个棋盘格放 1 粒麦子, 在第 2 个棋盘格放 2 粒麦子,在第 3 个棋盘格放 4 粒麦子, 在第 ...
- java实现第七届蓝桥杯取球博弈
题目9.取球博弈 取球博弈 两个人玩取球的游戏. 一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目. 如果无法继续取球,则游戏结束. 此时,持有奇数个球的一方获胜. 如果两 ...
- 面试三轮我倒在了一道sql题上——sql性能优化
一.前言 最近小农在找工作,因为今年疫情的特殊原因,导致工作不是特别好找,所以一旦有面试电话,如果可以,都会去试一试,刚好接到一个面试邀请,感觉公司还不错,于是就确定了面试时间,准备了一下就去面试了. ...
- 如何拿到阿里P8 Offer-候选人视角谈面试
自我介绍 首先简单自我介绍一下,我叫陈映平,花名叫做小卡,2011年校招进入腾讯,是腾讯课堂B侧的前端技术负责人.2015年响应总理的号召,跟朋友一起出来创业,跟前面一位讲师的经历有点像,然后2018 ...
- 用my eclipse 新建hibernate 第一个程序
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库. 今天就来开始建我们的第一个hibernat ...