在Kubernetes上搭建EFK(Fluentd+Elasticsearch+Kibana)
1. 前言
kubernetes 默认会将容器的stdout和stderr录入node(minion)的/var/log/containers目录下,而kubernetes 组件的日志默认放置在/var/log目录下。
如果你是用kube-up启动的kubernetes集群,那么恭喜你,你可 以方便的启动k8s的日志功能。参考:http://kubernetes.io/docs/getting-started-guides/logging-elasticsearch/ 或者在k8s安装包的解压目录kubernetes/cluster/addons/fluentd-elasticsearch中找到安装文件。
如果你是通过命令或者脚本启动的k8s集群,那么也恭喜你,折腾等着你。
2. 实现需求
将各个pod中容器的stdout和stderr中的日志集中展示。
3. 部署结构
待传。
4. Elasticsearch & Kibana
这两个使用官网的镜像。Elasticsearch如果需要集群化,参考:
https://hub.docker.com/r/fabric8/elasticsearch/tags/
https://github.com/fabric8io/elasticsearch-cloud-kubernetes
由于本人的k8s环境并不通外网,需要先从官网下载镜像,再打上私有仓库的标签。
docker pull elasticsearch:2.3
docker pull kibana:4.5
docker tag elasticsearch:2.3 10.10.50.161:5000/elasticsearch:2.3
docker tag kibana:4.5 10.10.50.161:5000/kibana:4.5
docker push 10.10.50.161:5000/elasticsearch:2.3
docker push 10.10.50.161:5000/kibana:4.5
生成rc和svc:
kubectl create -f elasticsearch-kibana-svc.yaml
kubectl create -f elasticsearch-kibana-rc.yaml
elasticsearch-kibana-rc.yaml:
apiVersion: v1
kind: ReplicationController
metadata:
name: elasticsearch-kibana
namespace: kube-system
labels:
k8s-app: elasticsearch-kibana
version: v1
kubernetes.io/cluster-service: "true"
spec:
replicas: 1
selector:
k8s-app: elasticsearch-kibana
version: v1
template:
metadata:
labels:
k8s-app: elasticsearch-kibana
version: v1
kubernetes.io/cluster-service: "true"
spec:
containers:
- image: 10.10.50.161:5000/elasticsearch:2.3
name: elasticsearch
resources:
# keep request = limit to keep this container in guaranteed class
limits:
cpu: 100m
requests:
cpu: 100m
ports:
- containerPort: 9200
name: http
protocol: TCP
- containerPort: 9300
name: transport
protocol: TCP
volumeMounts:
- name: es-persistent-storage
mountPath: /usr/share/elasticsearch/data
- image: 10.10.50.161:5000/kibana:4.5
name: kibana
resources:
# keep request = limit to keep this container in guaranteed class
limits:
cpu: 100m
requests:
cpu: 100m
ports:
- containerPort: 5601
name: ui
protocol: TCP
env:
- name: ELASTICSEARCH_URL
value: http://localhost:9200
volumes:
- name: es-persistent-storage
emptyDir: {}
elasticsearch-kibana-svc.yaml:
apiVersion: v1
kind: Service
metadata:
name: elasticsearch-kibana
namespace: kube-system
labels:
k8s-app: elasticsearch-kibana
kubernetes.io/cluster-service: "true"
kubernetes.io/name: "elasticsearch-kibana"
spec:
type: NodePort
ports:
- name: elasticsearch-http
port: 9200
protocol: TCP
targetPort: http
- name: elasticsearch-transport
port: 9300
protocol: TCP
targetPort: transport
- name: kibana
port: 5601
protocol: TCP
targetPort: ui
nodePort: 30016
selector:
k8s-app: elasticsearch-kibana
注意:这里我把elasticsearch的日志存储放在了pod的empty volumns里了,真正的运行环境应该使用nodeSelector选定一台node,并把日志存储放在node里的/usr/share/elasticsearch/data。
5. Fluentd
重点就是fluentd,addons里的依赖kube.up里引用的make ca制作认证。而我的环境进行认证时,使用了前面一同事部署heapster+influxdb+grafana时用的单域名认证,之后再进行多域名认证时,搞得乱七八糟,索性决定绕过k8s内部环境。
多域名认证参考:
https://coreos.com/kubernetes/docs/latest/openssl.html
http://www.linuxidc.com/Linux/2014-10/108222.htm
http://apetec.com/support/GenerateSAN-CSR.htm
https://certificates.heanet.ie/node/17
这里使用fabric8的fabric8/fluentd-kubernetes镜像,但需要重新制作镜像。
fabric8/fluentd-kubernetes本身不依赖https和认证,但里面的fluentd插件fluent-plugin-kubernetes_metadata_filter依赖了https和认证,这也是比较蛋疼的事。
首先pull官网的镜像
docker pull fabric8/fluentd-kubernetes:v1.14
docker tag fabric8/fluentd-kubernetes:v1.14 10.10.50.161:5000/fabric8/fluentd-kubernetes:v1.14
制作镜像:
mkdir myfluent
cd fluent-plugin
touch Dockerfile
touch start-fluentd
Dockerfile:
FROM 10.10.50.161:5000/fabric8/fluentd-kubernetes:v1.14
MAINTAINER miaobainian <miaobainian36@163.com>
ADD start-fluentd /start-fluentd
start-fluentd:
#!/bin/sh
ELASTICSEARCH_HOST=${ELASTICSEARCH_HOST:-es-logging.default.svc}
ELASTICSEARCH_PORT=${ELASTICSEARCH_PORT:-9200}
ELASTICSEARCH_SCHEME=${ELASTICSEARCH_SCHEME:-http}
FLUENTD_FLUSH_INTERVAL=${FLUENTD_FLUSH_INTERVAL:-10s}
FLUENTD_FLUSH_THREADS=${FLUENTD_FLUSH_THREADS:-1}
FLUENTD_RETRY_LIMIT=${FLUENTD_RETRY_LIMIT:-10}
FLUENTD_DISABLE_RETRY_LIMIT=${FLUENTD_DISABLE_RETRY_LIMIT:-true}
FLUENTD_RETRY_WAIT=${FLUENTD_RETRY_WAIT:-1s}
FLUENTD_MAX_RETRY_WAIT=${FLUENTD_MAX_RETRY_WAIT:-60s}
FLUENTD_BUFFER_CHUNK_LIMIT=${FLUENTD_BUFFER_CHUNK_LIMIT:-8m}
FLUENTD_BUFFER_QUEUE_LIMIT=${FLUENTD_BUFFER_QUEUE_LIMIT:-8192}
FLUENTD_BUFFER_TYPE=${FLUENTD_BUFFER_TYPE:-memory}
FLUENTD_BUFFER_PATH=${FLUENTD_BUFFER_PATH:-/var/fluentd/buffer}
FLUENTD_LOGSTASH_FORMAT=${FLUENTD_LOGSTASH_FORMAT:-true}
KUBERNETES_PRESERVE_JSON_LOG=${KUBERNETES_PRESERVE_JSON_LOG:-true}
mkdir /etc/fluent
cat << EOF >> /etc/fluent/fluent.conf
<source>
type tail
path /var/log/containers/*.log
pos_file /var/log/es-containers.log.pos
time_format %Y-%m-%dT%H:%M:%S.%N
tag kubernetes.*
format json
read_from_head true
keep_time_key true
</source>
<filter kubernetes.**>
type kubernetes_metadata
preserve_json_log ${KUBERNETES_PRESERVE_JSON_LOG}
kubernetes_url ${KUBERNETES_URL}
verify_ssl ${VERIFY_SSL}
</filter>
<match **>
type elasticsearch$([ "${ELASTICSEARCH_DYNAMIC}" == "true" ] && echo _dynamic)
log_level info
include_tag_key true
time_key time
host ${ELASTICSEARCH_HOST}
port ${ELASTICSEARCH_PORT}
scheme ${ELASTICSEARCH_SCHEME}
$([ -n "${ELASTICSEARCH_USER}" ] && echo user ${ELASTICSEARCH_USER})
$([ -n "${ELASTICSEARCH_PASSWORD}" ] && echo password ${ELASTICSEARCH_PASSWORD})
buffer_type ${FLUENTD_BUFFER_TYPE}
$([ "${FLUENTD_BUFFER_TYPE}" == "file" ] && echo buffer_path ${FLUENTD_BUFFER_PATH})
buffer_chunk_limit ${FLUENTD_BUFFER_CHUNK_LIMIT}
buffer_queue_limit ${FLUENTD_BUFFER_QUEUE_LIMIT}
flush_interval ${FLUENTD_FLUSH_INTERVAL}
retry_limit ${FLUENTD_RETRY_LIMIT}
$([ "${FLUENTD_DISABLE_RETRY_LIMIT}" == "true" ] && echo disable_retry_limit)
retry_wait ${FLUENTD_RETRY_WAIT}
max_retry_wait ${FLUENTD_MAX_RETRY_WAIT}
num_threads ${FLUENTD_FLUSH_THREADS}
logstash_format ${FLUENTD_LOGSTASH_FORMAT}
$([ -n "${FLUENTD_LOGSTASH_PREFIX}" ] && echo logstash_prefix ${FLUENTD_LOGSTASH_PREFIX})
reload_connections false
EOF
cat << 'EOF' >> /etc/fluent/fluent.conf
</match>
EOF
exec je fluentd
注意这里比官方的start-fluentd增加关键的两行:
kubernetes_url ${KUBERNETES_URL}
verify_ssl ${VERIFY_SSL}
目的是绕过https://clusterIp:443的验证。
docker build -t 10.10.50.161:5000/fabric8/fluentd-kubernetes:v1.15 .
docker push 10.10.50.161:5000/fabric8/fluentd-kubernetes:v1.15
ok,fluentd的镜像定义好了之后,就可以生成pod了,可以使用static pod,但是推荐使用daemon sets
touch fluentd-daemon.yaml
fluentd-daemon.yaml :
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
template:
metadata:
labels:
k8s-app: fluentd-logging
spec:
containers:
- name: fluentd-elasticsearch
image: 10.10.50.161:5000/fabric8/fluentd-kubernetes:v1.16
resources:
limits:
cpu: 100m
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
env:
- name: KUBERNETES_URL
value: "http://10.10.50.156:8080/api"
- name: VERIFY_SSL
value: "false"
- name: ELASTICSEARCH_HOST
value: elasticsearch-kibana
- name: ELASTICSEARCH_PORT
value: "9200"
- name: FLUENTD_FLUSH_INTERVAL
value: "300s"
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
kubectl create -f fluentd-daemon.yaml
注意这里的环境变量:
KUBERNETES_URL使用的是k8s master node的master api。
VERIFY_SSL为false表示不验证ca。
ELASTICSEARCH_HOST是前面部署的elasticsearch-kibana服务名,依赖于dns(服务名即dns名),如果没有装dns,你也可以使用kubectl get svc --namespace=kube-system找到elasticsearch-kibana的集群ip,配置集群ip也可以。但集群ip是可变的,这个要注意。
ELASTICSEARCH_PORT是elasticsearch-kibana中elasticsearch的服务内部端口。
FLUENTD_FLUSH_INTERVAL用于标识收集时间间隔,设置为300s是因为第一次收集时,花费的时间较长,时间间隔不够会导致elasticsearch不停的重新连接。
ok,现在all is already。
在浏览器打开:
http://10.10.50.155:30016/
10.10.50.155是我的k8s集群中的一个node,30016是elasticsearch-kibana服务的node port。
进行kibana的界面。
默认进入Settings的indices界面。
将Index contains time-based events的打勾去掉。点击下面的create。
ok,喝杯coffee or tea,等待k8s的日志出现就可以了。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Kubernetes自建虚拟机实验环境(CentOS 7 环境下离线安装)
本文是《Docker自建虚拟机实验环境及基础入门》一文的 续篇,从上文实验环境下继续操作。 Kubernetes节点分为Master和Minion两种类型,Master节点只需一个,Minion节点可以有多个,组成集群。而集群通过ETCD服务保存集群配置信息,通过Flanneld服务协调集群内容器的IP地址段。下图是简单示意: 下面描述如何在一台虚拟机中安装一个伪Kubernetes集群,以实现Kubernetes集群的全部功能,达到学习Kubernetes的目的。 本文所用的文件请去 https://pan.baidu.com/s/1eSei6KM 里提取,下面是文件列表。 下面是安装步骤: 一、 安装ETCD rpm -ivh etcd-3.0.15-1.el7.x86_64.rpm etcd配置: 安装完成后,用下面命令查看etcd服务,找到etcd的启动脚本,然后进行修改: service etcd status Redirecting to /bin/systemctl status etcd.service ● etcd.service - Etcd Server Load...
-
下一篇
kubernetes代码阅读-apiserver基础篇
apiserver是整个kubernetes的核心模块,做的事情多,代码量也较大。市面上已经有 不少apiserver代码解读的文章了,但问题在于,由于k8s的代码变化很快,想写一篇长久能用的未必能做到。所以,我参照了《Kubernetes权威指南》和浙大SEL实验室的一些文章,先把我看到的东西记下来,待后观是否有用。 kubernetes源代码版本1.2.0 代码阅读方法 先简单讲讲整个代码的目录结构 目录 说明 api 输出接口文档用 build 构建脚本 cluster 适配不同I层的云,例如亚马逊AWS,微软Azure,谷歌GCE的集群启动脚本 cmd 所有的二进制可执行文件入口代码,例如apiserver/scheduler/kubelet contrib 项目贡献者 docs 文档,包括了用户文档、管理员文档、设计、新功能提议 example 使用案例 Godeps 项目中依赖使用的Go第三方包,例如docker客户端SDK,rest等 hack 工具箱,各种编译、构建、测试、校验的脚本都在这里面 hooks git提交前后触发的脚本 pkg 项目代码主目录,cmd的只是个...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- MySQL数据库在高并发下的优化方案
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果