快速搭建Kubernetes日志系统EFK

前面我们介绍了 Kubernetes 集群中的几种日志收集方案,Kubernetes 中比较流行的日志收集解决方案是 Elasticsearch、Fluentd 和 Kibana(EFK)技术栈,也是官方现在比较推荐的一种方案。

Elasticsearch 是一个实时的、分布式的可扩展的搜索引擎,允许进行全文、结构化搜索,它通常用于索引和搜索大量日志数据,也可用于搜索许多不同类型的文档。 Elasticsearch 通常与 Kibana 一起部署,Kibana 是 Elasticsearch 的一个功能强大的数据可视化 Dashboard,Kibana 允许你通过 web 界面来浏览 Elasticsearch 日志数据。 Fluentd是一个流行的开源数据收集器,我们将在 Kubernetes 集群节点上安装 Fluentd,通过获取容器日志文件、过滤和转换日志数据,然后将数据传递到 Elasticsearch 集群,在该集群中对其进行索引和存储。

我们先来配置启动一个可扩展的 Elasticsearch 集群,然后在 Kubernetes 集群中创建一个 Kibana 应用,最后通过 DaemonSet 来运行 Fluentd,以便它在每个 Kubernetes 工作节点上都可以运行一个 Pod。

创建 Elasticsearch 集群

Kubernetes1.16.8版本安装目录中包含的有EFK集群安装的所有文件、这里我们直接去对应目录下面创建相应资源即可。我们使用3个 Elasticsearch Pod 来避免高可用下多节点集群中出现的“脑裂”问题,当一个或多个节点无法与其他节点通信时会产生“脑裂”,可能会出现几个主节点。我们应该设置参数discover.zen.minimum_master_nodes=N/2+1,其中N是 Elasticsearch 集群中符合主节点的节点数,比如这里3个节点,意味着N应该设置为2。这样,如果一个节点暂时与集群断开连接,则另外两个节点可以选择一个新的主节点,并且集群可以在最后一个节点尝试重新加入时继续运行,在扩展 Elasticsearch 集群时,一定要记住这个参数。

注:关于 Elasticsearch 集群脑裂问题,大家可以查看文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html#split-brain

我们先去创建一个名为 elasticsearch-logging 的无头服务,文件路径是 /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch/es-service.yaml :

# /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-logging
  namespace: kube-system
  labels:
    k8s-app: elasticsearch-logging
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "Elasticsearch"
spec:
  ports:
  - port: 9200
    protocol: TCP
    targetPort: db
  selector:
    k8s-app: elasticsearch-logging

img

我们使用kubectl直接创建上面的服务资源对象:

# 创建服务资源对象
kubectl apply -f es-service.yaml
# 查看svc资源对象
kubectl get svc -n kube-system

img

现在我们已经为 Pod 设置了无头服务和一个稳定的域名 .elasticsearch.kube-system.svc.cluster.local,接下来我们通过 StatefulSet 来创建具体的 Elasticsearch 的 Pod 应用。对应文件是 /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch/es-statefulset.yaml:

# RBAC authn and authz
# 定义服务账号
apiVersion: v1
kind: ServiceAccount
metadata:
  name: elasticsearch-logging
  namespace: kube-system
  labels:
    k8s-app: elasticsearch-logging
    addonmanager.kubernetes.io/mode: Reconcile
---
# 定义集群角色
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: elasticsearch-logging
  labels:
    k8s-app: elasticsearch-logging
    addonmanager.kubernetes.io/mode: Reconcile
rules:
- apiGroups:
  - ""
  resources:
  - "services"
  - "namespaces"
  - "endpoints"
  verbs:
  - "get"
---
# 集群角色绑定
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: kube-system
  name: elasticsearch-logging
  labels:
    k8s-app: elasticsearch-logging
    addonmanager.kubernetes.io/mode: Reconcile
subjects:
- kind: ServiceAccount
  name: elasticsearch-logging
  namespace: kube-system
  apiGroup: ""
roleRef:
  kind: ClusterRole
  name: elasticsearch-logging
  apiGroup: ""
---
# Elasticsearch deployment itself
# 定义elasticsearch-logging StatefulSet资源对象
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch-logging
  namespace: kube-system
  labels:
    k8s-app: elasticsearch-logging
    version: v7.2.0
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  serviceName: elasticsearch-logging
  replicas: 3
  # 数据持久化
  volumeClaimTemplates:
  - metadata:
      name: data
      labels:
        k8s-app: elasticsearch-logging
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName:  elasticsearch-data-db
      resources:
        requests:
          storage: 100Gi
  selector:
    matchLabels:
      k8s-app: elasticsearch-logging
      version: v7.2.0
  template:
    metadata:
      labels:
        k8s-app: elasticsearch-logging
        version: v7.2.0
    spec:
      serviceAccountName: elasticsearch-logging
      containers:
      - image: quay.io/fluentd_elasticsearch/elasticsearch:v7.2.0
        name: elasticsearch-logging
        imagePullPolicy: IfNotPresent
        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: elasticsearch-logging
          mountPath: /data
        env:
        - name: "NAMESPACE"
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
      volumes:
      - name: elasticsearch-logging
        emptyDir: {}
      # Elasticsearch requires vm.max_map_count to be at least 262144.
      # If your OS already sets up this number to a higher value, feel free
      # to remove this init container.
      initContainers:
      - image: alpine:3.6
        command: ["/sbin/sysctl", "-w", "vm.max_map_count=262144"]
        name: elasticsearch-logging-init
        securityContext:
          privileged: true

文件最上面定义了 elasticsearch-logging 的ServiceAccount服务账号,ClusterRole集群角色和ClusterRoleBinding集群角色绑定。

下面文件中定义了一个名为 elasticsearch-logging 的 StatefulSet 对象,然后定义 serviceName=elasticsearch-logging 和前面创建的 Service 相关联。这可以确保使用以下 DNS 地址访问 StatefulSet 中的每一个 Pod:elasticsearch-logging-[0,1,2].elasticsearch.kube-system.svc.cluster.local,其中[0,1,2]对应于已分配的 Pod 序号。 然后指定3个副本,matchLabels 设置为 k8s-app: elasticsearch-logging,所以 Pod 的模板部分.spec.template.metadata.lables也必须包含 k8s-app: elasticsearch-logging 标签。

上面 StatuefulSet 中的Pod使用的是 quay.io/fluentd_elasticsearch/elasticsearch:v7.2.0镜像,暴露了9200和9300两个端口,当然你也可以使用-oss后缀的开源镜像。文件最下面定义了一个主应用程序运行之前的Init容器,这个容器执行完成后才会启动主应用程序。然后我们就可以通过 volumeMount来声明数据持久化目录了,下面我们需要手动添加 volumeClaimTemplates,具体添加内容如下:

......  
volumeClaimTemplates:
  - metadata:
      name: data
      labels:
        k8s-app: elasticsearch-logging
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName:  elasticsearch-data-db
      resources:
        requests:
          storage: 100Gi
...... 

我们使用 volumeClaimTemplates 来定义持久化模板,Kubernetes 会使用它为 Pod 创建 PersistentVolume,设置访问模式为ReadWriteOnce,这意味着它只能被 mount 到单个节点上进行读写,然后最重要的是使用了一个名为elasticsearch-data-db的 StorageClass 对象,所以我们需要提前创建该对象,我们这里使用的 NFS 作为存储后端,所以需要安装一个对应的 provisioner 驱动,前面关于 StorageClass 的课程中已经和大家介绍过方法,新建一个 es-storageclass.yaml 的文件,文件内容如下:

apiVersion: storage.k8s.io/v1 
kind: StorageClass 
metadata: 
  name: elasticsearch-data-db 
provisioner: fuseim.pri/ifs # 该值需要和 provisioner 配置的保持一致

我们指定了每个 PersistentVolume 的大小为 100GB,当然我们也可以根据自己的实际需要进行调整该值。现在我们直接使用Kubectl工具来部署相关资源:

# 创建storageclass
kubectl apply -f es-storageclass.yaml 

# 创建storageclass
kubectl apply -f es-statefulset.yaml

img

资源创建成功之后,我们可以看到 kube-system 命名空间下面的所有资源对象:

img

Pods 部署完成后,我们可以通过请求一个 REST API 来检查 Elasticsearch 集群是否正常运行。使用下面的命令将本地端口9200转发到 Elasticsearch 节点(如elasticsearch-logging-0)对应的端口:

# 端口转发
kubectl port-forward elasticsearch-logging-0 9200:9200 --namespace=kube-system

img

然后,在另外的终端窗口中,执行如下请求。正常来说,应该会看到类似于如下的信息:

# 端口转发
curl http://localhost:9200/_cluster/state?pretty

img

看到上面的信息就表明前面名为 elasticsearch-logging 的 Elasticsearch 集群成功创建了3个节点:elasticsearch-logging-0,elasticsearch-logging-1,和elasticsearch-logging-2,当前主节点是 elasticsearch-logging-0。

我们现在去看看 pvc和pv 的状态,我们可以看到当前已经自动创建了 pvc和pv 并自动绑定成功,我们去NFS共享目录下面也可以看到相关文件内容:

# 查看PVC
kubectl get pvc -n kube-system | grep elasticsearch-data-db

# 查看PV
kubectl get pv -n kube-system | grep elasticsearch-data-db

# 查看文件
ls /mnt/lv/k8s

img

创建Kibana服务

Elasticsearch 集群启动成功后,接下来我们可以来部署 Kibana 服务,Kibana 的资源对象有两个:Service和Deployment,Service文件路径在 /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch/kibana-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: kibana-logging
  namespace: kube-system
  labels:
    k8s-app: kibana-logging
    kubernetes.io/cluster-service: "true"
    addonmanager.kubernetes.io/mode: Reconcile
    kubernetes.io/name: "Kibana"
spec:
  ports:
  - port: 5601
    protocol: TCP
    targetPort: ui
  selector:
    k8s-app: kibana-logging

Deployment文件路径在 /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch/kibana-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana-logging
  namespace: kube-system
  labels:
    k8s-app: kibana-logging
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: kibana-logging
  template:
    metadata:
      labels:
        k8s-app: kibana-logging
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
    spec:
      containers:
      - name: kibana-logging
        image: docker.elastic.co/kibana/kibana-oss:7.2.0
        #image: kibana:7.6.0
        resources:
          # need more cpu upon initialization, therefore burstable class
          limits:
            cpu: 1000m
          requests:
            cpu: 100m
        env:
          - name: ELASTICSEARCH_HOSTS
            value: http://elasticsearch-logging:9200
         # - name: SERVER_NAME
         #   value: kibana-logging
         # - name: SERVER_BASEPATH
         #   value: /api/v1/namespaces/kube-system/services/kibana-logging/proxy
         # - name: SERVER_REWRITEBASEPATH
         #   value: "false"
        ports:
        - containerPort: 5601
          name: ui
          protocol: TCP
       # 下面这一部分要注释掉
       # livenessProbe:
       #   httpGet:
       #     path: /api/status
       #     port: ui
       #   initialDelaySeconds: 5
       #   timeoutSeconds: 10
       # readinessProbe:
       #   httpGet:
       #     path: /api/status
       #     port: ui
       #   initialDelaySeconds: 5
       #   timeoutSeconds: 10

上面的两个资源对象,一个 Service 和 Deployment,Kibana Pod 中配置都比较简单,唯一需要注意的是我们使用 ELASTICSEARCH_HOSTS 这个环境变量来设置 Elasticsearch 集群的端点和端口,直接使用 Kubernetes DNS 即可,此端点对应服务名称为 elasticsearch-logging,由于是一个 headless service,所以该域将解析为3个 Elasticsearch Pod 的 IP 地址列表。配置完成后,直接使用 kubectl 工具创建:

kubectl apply -f kibana-service.yaml
kubectl apply -f kibana-deployment.yaml

img

创建完成后,可以查看 Kibana Pod 的运行状态:

kubectl get pod -n kube-system
kubectl get svc -n kube-system

img

如果 Pod 已经是 Running 状态了,证明应用已经部署成功了;因为前面我们配置了Traefik Ingress,所有这里我们需要单独写一个Traefik的配置文件 kibana-route.yaml:

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: kibana-logging
  namespace: kube-system
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`kibana.z0ukun.com`)
    kind: Rule
    services:
    - name: kibana-logging
      namespace: kube-system
      port: 5601

这里我们直接创建Ingress资源,创建完成以后我们就可以在Traefik HTTP Routers页面看到相应的域名状态了:

kubectl create -f kibana-route.yaml

img

注:如果您没有配置Ingress,你也可以通过 NodePort 来访问 Kibana 这个服务,只需要修改上面的Deployment服务模式为NodePort即可。

这里我们直接访问上面配置的 kibana.z0ukun.com 域名即可(记得提前修改hosts)。如果看到如下欢迎界面证明 Kibana 已经成功部署到了 Kubernetes集群之中:

img

注:如果输入域名之后一直没反应请小伙伴们耐心等待一会。

部署 Fluentd

Fluentd 是一个高效的日志聚合器,是用 Ruby 编写的,并且可以很好地扩展。对于大部分企业来说,Fluentd 足够高效并且消耗的资源相对较少。另外一个工具 Fluent-bit 更轻量级,占用资源更少。但是插件相对 Fluentd 来说不够丰富,所以整体来说,Fluentd 更加成熟,使用更加广泛,这里我们使用 Fluentd 来作为日志收集工具。

Fluentd 通过一组给定的数据源抓取日志数据,处理后(转换成结构化的数据格式)将它们转发给其他服务,比如 Elasticsearch、对象存储等等。Fluentd 支持超过300个日志存储和分析服务,所以在这方面是非常灵活的。主要运行步骤如下:

  • 首先 Fluentd 从多个日志源获取数据;
  • 结构化并且标记这些数据;
  • 然后根据匹配的标签将数据发送到多个目标服务去。

img

日志源配置

一般来说我们是通过一个配置文件来告诉 Fluentd 如何采集、处理数据的,下面简单和大家介绍下 Fluentd 的配置方法。比如我们这里为了收集 Kubernetes 节点上的所有容器日志,就需要做如下的日志源配置:

<source> 
@id fluentd-containers.log 
@type tail 
path /var/log/containers/*.log 
pos_file /var/log/fluentd-containers.log.pos 
time_format %Y-%m-%dT%H:%M:%S.%NZ 
tag raw.kubernetes.* 
format json 
read_from_head true 
</source>

上面配置部分参数说明如下:

  • id:表示引用该日志源的唯一标识符,该标识可用于进一步过滤和路由结构化日志数据;
  • type:Fluentd 内置的指令,tail表示 Fluentd 从上次读取的位置通过 tail 不断获取数据,另外一个是http表示通过一个 GET 请求来收集数据;
  • path:tail类型下的特定参数,告诉 Fluentd 采集/var/log/containers目录下的所有日志,这是 docker 在 Kubernetes 节点上用来存储运行容器 stdout 输出日志数据的目录;
  • pos_file:检查点,如果 Fluentd 程序重新启动了,它将使用此文件中的位置来恢复日志数据收集;
  • tag:用来将日志源与目标或者过滤器匹配的自定义字符串,Fluentd 匹配源/目标标签来路由日志数据。

    路由配置

上面是日志源的配置,接下来看看如何将日志数据发送到 Elasticsearch:

<match **>
@id elasticsearch
@type elasticsearch
@log_level info
include_tag_key true
type_name fluentd
host "#{ENV['OUTPUT_HOST']}"
port "#{ENV['OUTPUT_PORT']}"
logstash_format true
<buffer>
@type file
path /var/log/fluentd-buffers/kubernetes.system.buffer
flush_mode interval
retry_type exponential_backoff
flush_thread_count 2
flush_interval 5s
retry_forever
retry_max_interval 30
chunk_limit_size "#{ENV['OUTPUT_BUFFER_CHUNK_LIMIT']}"
queue_limit_length "#{ENV['OUTPUT_BUFFER_QUEUE_LIMIT']}"
overflow_action block
</buffer>
  • match:标识一个目标标签,后面是一个匹配日志源的正则表达式,我们这里想要捕获所有的日志并将它们发送给 Elasticsearch,所以需要配置成 **。
  • id:目标的一个唯一标识符。
  • type:支持的输出插件标识符,我们这里要输出到 Elasticsearch,所以配置成 elasticsearch,这是 Fluentd 的一个内置插件。
  • log_level:指定要捕获的日志级别,我们这里配置成info ,表示任何该级别或者该级别以上(INFO、WARNING、ERROR)的日志都将被路由到 Elsasticsearch。
  • host/port:定义 Elasticsearch 的地址,也可以配置认证信息,我们的 Elasticsearch 不需要认证,所以这里直接指定 host 和 port 即可。
  • logstash_format:Elasticsearch 服务对日志数据构建反向索引进行搜索,将 logstash_format 设置为 true,Fluentd 将会以 logstash 格式来转发结构化的日志数据。
  • Buffer: Fluentd 允许在目标不可用时进行缓存,比如,如果网络出现故障或者 Elasticsearch 不可用的时候。缓冲区配置也有助于降低磁盘的 IO。

Fluentd安装

要收集 Kubernetes 集群的日志,直接用 DasemonSet 控制器来部署 Fluentd 应用,这样,它就可以从 Kubernetes 节点上采集日志,确保在集群中的每个节点上始终运行一个 Fluentd 容器。当然可以直接使用 Helm 来进行一键安装,为了能够了解更多实现细节,我们这里还是采用手动方法来进行安装。

首先需要通过 ConfigMap 对象来指定 Fluentd 配置文件,ConfigMap资源对象的文件路径为 /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch/fluentd-es-configmap.yaml(内容过长,请大家自己去查看)。fluentd-es-configmap.yaml 文件中配置了 docker 容器日志目录以及 docker、kubelet 应用的日志的收集,收集到数据经过处理后发送到 elasticsearch-logging:9200 服务。DasemonSet 资源对象文件路径为 /opt/k8s/work/kubernetes/kubernetes/cluster/addons/fluentd-elasticsearch/fluentd-es-ds.yaml:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd-es
  namespace: kube-system
  labels:
    k8s-app: fluentd-es
    addonmanager.kubernetes.io/mode: Reconcile
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: fluentd-es
  labels:
    k8s-app: fluentd-es
    addonmanager.kubernetes.io/mode: Reconcile
rules:
- apiGroups:
  - ""
  resources:
  - "namespaces"
  - "pods"
  verbs:
  - "get"
  - "watch"
  - "list"
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: fluentd-es
  labels:
    k8s-app: fluentd-es
    addonmanager.kubernetes.io/mode: Reconcile
subjects:
- kind: ServiceAccount
  name: fluentd-es
  namespace: kube-system
  apiGroup: ""
roleRef:
  kind: ClusterRole
  name: fluentd-es
  apiGroup: ""
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-es-v2.7.0
  namespace: kube-system
  labels:
    k8s-app: fluentd-es
    version: v2.7.0
    addonmanager.kubernetes.io/mode: Reconcile
spec:
  selector:
    matchLabels:
      k8s-app: fluentd-es
      version: v2.7.0
  template:
    metadata:
      labels:
        k8s-app: fluentd-es
        version: v2.7.0
      # This annotation ensures that fluentd does not get evicted if the node
      # supports critical pod annotation based priority scheme.
      # Note that this does not guarantee admission on the nodes (#40573).
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
    spec:
      priorityClassName: system-node-critical
      serviceAccountName: fluentd-es
      containers:
      - name: fluentd-es
        image: quay.io/fluentd_elasticsearch/fluentd:v2.7.0
        env:
        - name: FLUENTD_ARGS
          value: --no-supervisor -q
        resources:
          limits:
            memory: 500Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /data/k8s/docker/data
          readOnly: true
        - name: config-volume
          mountPath: /etc/fluent/config.d
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /data/k8s/docker/data
      - name: config-volume
        configMap:
          name: fluentd-es-config-v0.2.0

上面创建的 ConfigMap 资源对象通过 volumes 被挂载到了 Fluentd 容器中。如果你想灵活控制哪些节点的日志可以被收集,你可以添加一个 nodSelector 属性;然后给相应的节点打上标签即可,这里我们采用默认配置:

nodeSelector: 
  beta.kubernetes.io/fluentd-ds-ready: "true"

如果你的集群使用的是 kubeadm 搭建的,默认情况下 master 节点有污点;要想收集 master 节点的日志,需要添加上容忍:

tolerations:
- key: node-role.kubernetes.io/master
  operator: Exists
  effect: NoSchedule

另外需要注意的地方是,我们再前面不是Kubernetes集群的时候更改了 docker 的根目录:

img

所以我们需要把 docker 的容器目录需要更改成/data/k8s/docker/data。这个地方非常重要,如果你没有更改 docker 根目录则使用默认的/var/lib/docker/containers目录即可。 然后我们分别创建上面的 ConfigMap 对象和 DaemonSet:

kubectl apply -f fluentd-es-configmap.yaml
kubectl apply -f fluentd-es-ds.yaml

img

Fluentd 启动成功后,我们可以前往 Kibana 的 Dashboard 页面中,点击左侧的Discover,可以看到如下配置页面:

img

这里可以配置我们需要的 Elasticsearch 索引,前面 Fluentd 配置文件中采集的日志使用的是 logstash 格式,这里只需要在文本框中输入logstash-*即可匹配到 Elasticsearch 集群中的所有日志数据,然后点击下一步,进入以下页面:

img

然后点击下一步、在下拉列表中,选择@timestamp字段。然后点击Create index pattern,创建完成后,点击左侧导航菜单中的Discover,然后就可以看到一些直方图和最近采集到的日志数据了:

img

img

Fluentd测试

现在我们来将下面的计数器应用部署到集群中,并在 Kibana 中来查找该日志数据。我们新建 counter.yaml 文件,文件内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox
    args: [/bin/sh, -c,
            'i=0; while true; do echo "i:(date)"; i=$((i+1)); sleep 1; done']

该 Pod 只是简单将日志信息打印到 stdout,所以正常来说 Fluentd 会收集到这个日志数据,在 Kibana 中也就可以找到对应的日志数据了,使用 kubectl 工具创建该 Pod:

kubectl apply -f counter.yaml

Pod 创建并运行后,我们回到 Kibana Dashboard 页面,在上面的Discover页面搜索栏中输入kubernetes.pod_name:counter,就可以过滤 Pod 名为 counter 的日志数据:

img

当然,我们也可以通过其他元数据来过滤日志数据,比如你可以单击任何日志条目以查看其他元数据,如容器名称,Kubernetes 节点,命名空间等。到这里,我们就在 Kubernetes 集群上成功部署了 EFK ,要了解如何使用 Kibana 进行日志数据分析,可以参考 Kibana 用户指南文档:https://www.elastic.co/guide/en/kibana/current/index.html 。对于在生产环境上使用 Elaticsearch 或者 Fluentd,还需要结合实际的环境做一系列的优化工作

推荐文章