在Kubernetes上搭建日志收集、分析、展示平台ELK(Logstash+Elasticsearch+Kibana)

背景介绍
第一,对于企业来说,日志的重要性不言而喻,就不赘述了。


第二,日志收集分析展示平台的选择,这里给出几点选择ELK的理由。ELK是一套非常成熟的系统,她本身的构架非常适合Kubernetes集群,这里官网当中也是选用的
Elasticsearch作为Sample的,GitHub上下载的kubernetes二进制包中本身就有这个.yaml文件,所以使用ELK作为收集日志的理由相当充分。

----------

时间:2016年5月2日。
地点:南京某高校。
作者:duweike。
主机系统:Ubuntu14.04。
软件版本:
Docker1.10.3,Kubernetes1.2.1,Etcd2.3.0,Flannel0.5.5.
Logstash2.3镜像,Elasticsearch2.3镜像,Kibana4.5镜像,下载的均是官方镜像。

----------


第一,ELK结构介绍和在Kubernetes上部署规划。

<http://dockerone.com/uploads/article/20160502/94d2bf2f81b322cd9db4447f062da982.png>


上面的这一套构架相当完善,一目了然,由于我这里是一个测试环境,把中间的Redis和Logstash去掉了,节点上的Logstash把日志直接发向Elasticsearch。

我是这样结合Kubernetes设计的。

一、每个节点上的所有Pod的日志,通过数据卷全部存储在一个固定的目录里面,日志文件通过Pod命或者Pod里面的容器主机命命名,从而来区别不同的Pod的日志文件,同时也解决了日志持久化的问题。

二、每个Node上面部署一个Logstash-pod,监控Node上面指定好的目录里面的日志文件,如果日志文件有更新,则把更新日志发向Elasticsearch。

三、Elasticsearch+Kibana两个容器作为一个Pod,Elasticsearch接收各个Node上的Logstash发来的日志,Kibana用来展示日志信息。

示意图如下


<http://dockerone.com/uploads/article/20160502/99662102c47b35a5e60e4a3bd9aea8e0.jpg>


第二,镜像选择和部署。
一、制作镜像。

首先下载官方镜像,Logstash2.3镜像,Elasticsearch2.3镜像,Kibana4.5镜像。经过分析和尝试,这里Elasticsearch+Kibana是可以直接使用的,但是Logstash需要稍作修改才行。
先看一下官方的Logstash2.3的官方Dockerfile文件。
网址:https://github.com/docker-libr ... rfile
<https://github.com/docker-library/logstash/blob/master/2.3/Dockerfile>
这个官方的Dockerfile修改如下:

ENV PATH /opt/logstash/bin:$PATH #删除该行下面的,

COPY logstash.conf / #然后添加该行
下面是logstash.conf文件内容,可以进行详细的设置,这里只是个测试。

input {
file {
path => ["/var/lib/docker/logstash-logs/*.log"]
type => "logstash"
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["elasticsearch-kibana.development:9200"]
#上面的地址指向Elasticsearch+Kinana的Pod,
elasticsearch-kibana.development表示一个域名,通过Kubernetes DNS解析,development是Namespace。

}
}
然后把修改过的Dockerfile和logstash.conf放在一个目录build。

/elk/Dockerfile-logstash# ls
Dockerfile logstash.conf
/elk/Dockerfile-logstash# docker build -t logstash:dev .

二、部署。
这部分就相当简单了,直接贴.yaml
文件就行了,想要知道其中的细节为什么这样部署,建议阅读官方的Dockerfile文件。比如挂在路径为什么是:/usr/share/elasticsearch/data。
启动Elasticsearch+Kibana的Pod。

# kubectl create -f elasticsearch-kibana-svc.yaml
# kubectl create -f elasticsearch-kibana-rc.yaml
svc.yaml文件内容:

apiVersion: v1
kind: Service
metadata:
name: elasticsearch-kibana
labels:
name: elasticsearch-kibana
spec:
type: NodePort
selector:
name: elasticsearch-kibana
ports:
- name: elasticsearch-http
port: 9200
protocol: TCP
targetPort: 9200
- name: elasticsearch-transport
port: 9300
protocol: TCP
targetPort: 9300
- name: kibana
port: 5601
protocol: TCP
targetPort: 5601
nodePort: 30081
#该端口是访问Kubernetes集群的外部端口必须为30000-32767之间。
rc.yaml文件内容

apiVersion: v1
kind: ReplicationController
metadata:
name: elasticsearch-kibana
labels:
name: elasticsearch-kibana
spec:
replicas: 1
selector:
name: elasticsearch-kibana
template:
metadata:
labels:
name: elasticsearch-kibana
spec:
nodeSelector:
node: docker111
#这里是在指定的Node上面创建Pod的,
volumes:
- name: "elasticsearch-storage"
hostPath:
path: "/var/lib/docker/elk-data" 
#上面的路径是自定义设定的,为Elasticsearch的数据库存放位置。
containers:
- name: elasticsearch
image: elasticsearch:2.3
volumeMounts:
- name: "elasticsearch-storage"
mountPath: "/usr/share/elasticsearch/data"
ports:
- containerPort: 9200
name: http
protocol: TCP
- containerPort: 9300
name: transport
protocol: TCP
- name: kibana
image: kibana:4.5
ports:
- containerPort: 5601

下面是部署Logstash的Pod。

根据设计,需要每个Node上面启动一个Pod,不需要RC和Service,这里官方给出一个术语来形容:Daemon Set。
网址:http://kubernetes.io/docs/admin/daemons/
<http://kubernetes.io/docs/admin/daemons/>

启动Logstash pod

# kubectl create -f logstash-pod.yaml
pod.yaml内容为:

apiVersion: v1
kind: Pod
metadata:
name: logstash-dev
namespace: development
spec:
nodeSelector:
node: docker111
#在有该标签的Node上生成,如果没有该标签,就是所有Node上生成。
volumes:
- name: "logstash-django-log"
hostPath:
path: "/var/lib/docker/logstash-logs"
#该Node上的公共挂载路径,日志保存在这里,Logstash监控改路径。
containers:
- name: logstash-dev
image: logstash:dev
volumeMounts:
- name: "logstash-log"
mountPath: "/gikoo-logs/"
command: ["logstash","agent","-f","/logstash.conf"]
restartPolicy: Always

到此就部署结束了,可以在浏览器中访问UI界面查看了。

----------

第三,注意点。
1、Elasticsearch不允许root权限执行。
2、ELK三个镜像Run的容器都不是root权限,读取日志信息的时候用户用户组要做相应的权限修改。
3、Logstash占用内存比较大,也是为什么一个Node上面只启动一个Logstash pod的原因。