在Kubernetes上使用Elasticsearch+Fluentd+Kibana集中管理日志

2017-01-21 阅读: Kubernetes

Kubernetes和EFK

我们使用Kubernetes作为微服务架构的基础,在我们的系统中每个微服务都有多个副本,每个副本的数量以及所在的Node都是可变的。因此对于日志需要集中化管理,在使用Kubernetes之前,我们的系统使用ELK(Elasticsearch+Logstash+Kibana)实现日志的聚集、查询和展现。由于Kubernetes推荐使用Fluentd,所以我们尝试使用EFK(Elasticsearch+Fluentd+Kibana)作为我们的日志集中管理组件。

Kubernetes官方文档Logging and Monitoring Cluster Activity中给出了在Node上通过Logging Agent将日志收集到Logging Backend中的架构方案,如下图:

Using a node logging agent

其中Logging Agent推荐使用Fluentd,Logging Backend推荐使用Elasticsearch和Kibana。

准备镜像

Kubernetes已经给了Logging Agent For Elasticsearch的部署参考,我们从其中的 fluentd-es-ds.yaml, es-controller.yaml, kibana-controller.yaml中可以看出我们需要如下三个Docker镜像:

gcr.io/google_containers/fluentd-elasticsearch:1.22
gcr.io/google_containers/elasticsearch:v2.4.1-2
gcr.io/google_containers/kibana:v4.6.1-1

由于某些的原因,我们从gcr.io/google_containers上pull镜像会遇到一些麻烦,这里我们做一些准备工作,到这里查看gcr.io的host,并配置到各个Node的hosts中。

测试Node到grc连接:

curl https://gcr.io/v1

并可在某个Node上测试pull这些镜像:

docker pull gcr.io/google_containers/fluentd-elasticsearch:1.22
docker pull gcr.io/google_containers/elasticsearch:v2.4.1-2
docker pull gcr.io/google_containers/kibana:v4.6.1-1

以DaemonSet形式启动Fluentd

Fluentd需要作为Logging Agent的形式在每个Node启动,因此DaemonSet是最好的选择。

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml

接下来创建DaemonSet时出错了:

kubectl create -f fluentd-es-ds.yaml
error: error validating "fluentd-es-ds.yaml": error validating data: found invalid field tolerations for v1.PodSpec; if you choose to ignore these errors, turn validation off with --validate=false

修改fluentd-es-ds.yaml,注释掉下面的几行:

      nodeSelector:
        beta.kubernetes.io/fluentd-ds-ready: "true"
      tolerations:
      - key : "node.alpha.kubernetes.io/ismaster"
        effect: "NoSchedule"

这下创建成功了:

kubectl create -f fluentd-es-ds.yaml
daemonset "fluentd-es-v1.22" created

查看创建结果:

 kubectl get ds --namespace=kube-system -l k8s-app=fluentd-es
NAME               DESIRED   CURRENT   READY     NODE-SELECTOR   AGE
fluentd-es-v1.22   3         3         3         <none>          1m
kubectl get pod --namespace=kube-system -l k8s-app=fluentd-es -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
fluentd-es-v1.22-38x88   1/1       Running   0          3m        10.244.3.102   cent1
fluentd-es-v1.22-5579j   1/1       Running   0          3m        10.244.2.17    cent2
fluentd-es-v1.22-5sd4b   1/1       Running   0          3m        10.244.0.158   cent0

可以看出fluentd的DaemonSet正常创建,同时在集群的每个Node上启动了一个Pod。

启动Elasticsearch

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/es-service.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/es-controller.yaml

创建ES的RC和Service:

kubectl create -f es-controller.yaml
replicationcontroller "elasticsearch-logging-v1" created

kubectl create -f es-service.yaml
service "elasticsearch-logging" created

查看创建的Service和Pod:

kubectl get svc --namespace=kube-system -l k8s-app=elasticsearch-logging -o wide
NAME                    CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE       SELECTOR
elasticsearch-logging   10.97.140.122   <none>        9200/TCP   1m        k8s-app=elasticsearch-logging


kubectl get rc --namespace=kube-system -l k8s-app=elasticsearch-logging
NAME                       DESIRED   CURRENT   READY     AGE
elasticsearch-logging-v1   2         2         2         2m


kubectl get pod --namespace=kube-system -l k8s-app=elasticsearch-logging -o wide
NAME                             READY     STATUS    RESTARTS   AGE       IP             NODE
elasticsearch-logging-v1-67v53   1/1       Running   0          3m        10.244.3.103   cent1
elasticsearch-logging-v1-sn8h9   1/1       Running   0          3m        10.244.2.18    cent2

启动Kibana

wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/kibana-controller.yaml
wget https://raw.githubusercontent.com/kubernetes/kubernetes/master/cluster/addons/fluentd-elasticsearch/kibana-service.yaml
kubectl create -f kibana-controller.yaml
kubectl create -f kibana-service.yaml

查看创建的Service和Pod:

kubectl get svc --namespace=kube-system -l k8s-app=kibana-logging -o wide
NAME             CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE       SELECTOR
kibana-logging   10.110.251.77   <none>        5601/TCP   1m        k8s-app=kibana-logging


kubectl get deploy --namespace=kube-system -l k8s-app=kibana-logging
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kibana-logging   1         1         1            1           1m


kubectl get pod --namespace=kube-system -l k8s-app=kibana-logging -o wide
NAME                              READY     STATUS    RESTARTS   AGE       IP            NODE
kibana-logging-1918083406-6cq9n   1/1       Running   0          1m        10.244.2.19   cent2

查看Kibana服务的地址:

kubectl cluster-info
Kibana is running at http://localhost:8080/api/v1/proxy/namespaces/kube-system/services/kibana-logging

看到Kibana服务只在Master Node的localhost好用,下面我们kubectl proxy代理api server:

kubectl proxy --port=8011 --address=192.168.61.100 --accept-hosts='^192\.168\.61\.*'
Starting to serve on 192.168.61.100:8011

使用下面的地址访问Kibana:

http://192.168.61.100:8011/api/v1/proxy/namespaces/kube-system/services/kibana-logging

创建index后,就可以在Kibana中查看到Kubernetes集群中的日志了:

最后

Kubernetes官方EFK的部署参考中,Elasticsearch挂载的Volume是emptyDir。

  template:
    metadata:
      labels:
        k8s-app: elasticsearch-logging
        version: v1
        kubernetes.io/cluster-service: "true"
    spec:
      containers:
      - image: gcr.io/google_containers/elasticsearch:v2.4.1-2
        name: elasticsearch-logging
        resources:
          # need more cpu upon initialization, therefore burstable class
          limits:
            cpu: 1000m
          requests:
            cpu: 100m
        ports:
        - containerPort: 9200
          name: db
          protocol: TCP
        - containerPort: 9300
          name: transport
          protocol: TCP
        volumeMounts:
        - name: es-persistent-storage
          mountPath: /data
        env:
        - name: "NAMESPACE"
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
      volumes:
      - name: es-persistent-storage
        emptyDir: {}

因此官方的部署参考仅可用于试验,实际部署到生产环境时需要使用Persistent Volume。

参考

标题:在Kubernetes上使用Elasticsearch+Fluentd+Kibana集中管理日志
本文链接:https://blog.frognew.com/2017/01/kubernetes-logging-efk.html
转载请注明出处。

目录