精华内容
下载资源
问答
  • Kubernetes-基于EFK进行统一的日志管理

    千次阅读 2018-08-23 11:31:02
    1、统一日志管理的整体方案 通过应用和系统日志可以了解Kubernetes集群内所发生事情,对于调试问题和监视集群活动来说日志非常有用。对于大部分应用来说,都会具有某种日志机制。因此,大多数容器引擎同样被...

    1、统一日志管理的整体方案

    通过应用和系统日志可以了解Kubernetes集群内所发生的事情,对于调试问题和监视集群活动来说日志非常有用。对于大部分的应用来说,都会具有某种日志机制。因此,大多数容器引擎同样被设计成支持某种日志机制。对于容器化应用程序来说,最简单和最易接受的日志记录方法是将日志内容写入到标准输出和标准错误流。
    但是,容器引擎或运行时提供的本地功能通常不足以支撑完整的日志记录解决方案。例如,如果一个容器崩溃、一个Pod被驱逐、或者一个Node死亡,应用相关者可能仍然需要访问应用程序的日志。因此,日志应该具有独立于Node、Pod或者容器的单独存储和生命周期,这个概念被称为群集级日志记录。群集级日志记录需要一个独立的后端来存储、分析和查询日志。Kubernetes本身并没有为日志数据提供原生的存储解决方案,但可以将许多现有的日志记录解决方案集成到Kubernetes集群中。在Kubernetes中,有三个层次的日志:

    • 基础日志
    • Node级别的日志
    • 群集级别的日志架构

    1.1 基础日志

    kubernetes基础日志即将日志数据输出到标准输出流,可以使用kubectl  logs命令获取容器日志信息。如果Pod中有多个容器,可以通过将容器名称附加到命令来指定要访问哪个容器的日志。例如,在Kubernetes集群中的devops命名空间下有一个名称为nexus3-f5b7fc55c-hq5v7的Pod,就可以通过如下的命令获取日志:

    $ kubectl logs nexus3-f5b7fc55c-hq5v7 --namespace=devops

    1.2 Node级别的日志

    容器化应用写入到stdout和stderr的所有内容都是由容器引擎处理和重定向的。例如,docker容器引擎会将这两个流重定向到日志记录驱动,在Kubernetes中该日志驱动被配置为以json格式写入文件。docker json日志记录驱动将每一行视为单独的消息。当使用docker日志记录驱动时,并不支持多行消息,因此需要在日志代理级别或更高级别上处理多行消息。
    默认情况下,如果容器重新启动,kubectl将会保留一个已终止的容器及其日志。如果从Node中驱逐Pod,那么Pod中所有相应的容器也会连同它们的日志一起被驱逐。Node级别的日志中的一个重要考虑是实现日志旋转,这样日志不会消耗Node上的所有可用存储。Kubernetes目前不负责旋转日志,部署工具应该建立一个解决方案来解决这个问题。
    Node level logging

    在Kubernetes中有两种类型的系统组件:运行在容器中的组件和不在容器中运行的组件。例如:

    • Kubernetes调度器和kube-proxy在容器中运行。
    • kubelet和容器运行时,例如docker,不在容器中运行。

    在带有systemd的机器上,kubelet和容器运行时写入journaId。如果systemd不存在,它们会在/var/log目录中写入.log文件。在容器中的系统组件总是绕过默认的日志记录机制,写入到/var/log目录,它们使用golg日志库。可以找到日志记录中开发文档中那些组件记录严重性的约定。
    类似于容器日志,在/var/log目录中的系统组件日志应该被旋转。这些日志被配置为每天由logrotate进行旋转,或者当大小超过100mb时进行旋转。

    1.3 集群级别的日志架构

    Kubernetes本身没有为群集级别日志记录提供原生解决方案,但有几种常见的方法可以采用:

    • 使用运行在每个Node上的Node级别的日志记录代理;
    • 在应用Pod中包含一个用于日志记录的sidecar。
    • 将日志直接从应用内推到后端。

    经过综合考虑,本文采用通过在每个Node上包括Node级别的日志记录代理来实现群集级别日志记录。日志记录代理暴露日志或将日志推送到后端的专用工具。通常,logging-agent是一个容器,此容器能够访问该Node上的所有应用程序容器的日志文件。
    因为日志记录必须在每个Node上运行,所以通常将它作为DaemonSet副本、或一个清单Pod或Node上的专用本机进程。然而,后两种方法后续将会被放弃。使用Node级别日志记录代理是Kubernetes集群最常见和最受欢迎的方法,因为它只为每个节点创建一个代理,并且不需要对节点上运行的应用程序进行任何更改。但是,Node级别日志记录仅适用于应用程序的标准输出和标准错误。
    Kubernetes本身并没有指定日志记录代理,但是有两个可选的日志记录代理与Kubernetes版本打包发布:和谷歌云平台一起使用的Stackdriver和Elasticsearch,两者都使用自定义配置的fluentd作为Node上的代理。在本文的方案中,Logging-agent 采用 Fluentd,而 Logging Backend 采用 Elasticsearch,前端展示采用Grafana。即通过 Fluentd 作为 Logging-agent 收集日志,并推送给后端的Elasticsearch;Grafana从Elasticsearch中获取日志,并进行统一的展示。

     

    2、安装统一日志管理的组件

    在本文中采用使用Node日志记录代理的方面进行Kubernetes的统一日志管理,相关的工具采用:

    • 日志记录代理(logging-agent):日志记录代理用于从容器中获取日志信息,使用Fluentd
    • 日志记录后台(Logging-Backend):日志记录后台用于处理日志记录代理推送过来的日志,使用Elasticsearch
    • 日志记录展示:日志记录展示用于向用户显示统一的日志信息,使用Kibana

    在Kubernetes中通过了Elasticsearch 附加组件,此组件包括Elasticsearch、Fluentd和Kibana。Elasticsearch是一种负责存储日志并允许查询的搜索引擎。Fluentd从Kubernetes中获取日志消息,并发送到Elasticsearch;而Kibana是一个图形界面,用于查看和查询存储在Elasticsearch中的日志。在安装部署之前,对于环境的要求如下:

    2.1 安装部署Elasticsearch

    Elasticsearch是一个基于Apache Lucene(TM)的开源搜索和数据分析引擎引擎,Elasticsearch使用Java进行开发,并使用Lucene作为其核心实现所有索引和搜索的功能。它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。Elasticsearch不仅仅是Lucene和全文搜索,它还提供如下的能力:

    • 分布式的实时文件存储,每个字段都被索引并可被搜索;
    • 分布式的实时分析搜索引擎;
    • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据。

    在Elasticsearch中,包含多个索引(Index),相应的每个索引可以包含多个类型(Type),这些不同的类型每个都可以存储多个文档(Document),每个文档又有多个属性。索引 (index) 类似于传统关系数据库中的一个数据库,是一个存储关系型文档的地方。Elasticsearch 使用的是标准的 RESTful API 和 JSON。此外,还构建和维护了很多其他语言的客户端,例如 Java, Python, .NET, 和 PHP。

    下面是Elasticsearch的YAML配置文件,在此配置文件中,定义了一个名称为elasticsearch-logging的ServiceAccount,并授予其能够对命名空间、服务和端点读取的访问权限;并以StatefulSet类型部署Elasticsearch。

    # RBAC authn and authz
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: elasticsearch-logging
      namespace: kube-system
      labels:
        k8s-app: elasticsearch-logging
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: elasticsearch-logging
      labels:
        k8s-app: elasticsearch-logging
        kubernetes.io/cluster-service: "true"
        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
        kubernetes.io/cluster-service: "true"
        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
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: elasticsearch-logging
      namespace: kube-system
      labels:
        k8s-app: elasticsearch-logging
        version: v6.2.5
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    spec:
      serviceName: elasticsearch-logging
      replicas: 2
      selector:
        matchLabels:
          k8s-app: elasticsearch-logging
          version: v6.2.5
      template:
        metadata:
          labels:
            k8s-app: elasticsearch-logging
            version: v6.2.5
            kubernetes.io/cluster-service: "true"
        spec:
          serviceAccountName: elasticsearch-logging
          containers:
          - image: k8s.gcr.io/elasticsearch:v6.2.5
            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: 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:

    $ kubectl create -f {path}/es-statefulset.yaml

    下面Elasticsearch的代理服务YAML配置文件,代理服务暴露的端口为9200。

    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

    通过执行如下的命令部署Elasticsearch的代理服务:

    $ kubectl create -f {path}/es-service.yaml

    2.2 安装部署Fluentd

    Fluentd是一个开源数据收集器,通过它能对数据进行统一收集和消费,能够更好地使用和理解数据。Fluentd将数据结构化为JSON,从而能够统一处理日志数据,包括:收集、过滤、缓存和输出。Fluentd是一个基于插件体系的架构,包括输入插件、输出插件、过滤插件、解析插件、格式化插件、缓存插件和存储插件,通过插件可以扩展和更好的使用Fluentd。

    Fluentd v1.0 Plugin API Overview

    Fluentd的整体处理过程如下,通过Input插件获取数据,并通过Engine进行数据的过滤、解析、格式化和缓存,最后通过Output插件将数据输出给特定的终端。

    在本文中, Fluentd 作为 Logging-agent 进行日志收集,并将收集到的日子推送给后端的Elasticsearch。对于Kubernetes来说,DaemonSet确保所有(或一些)Node会运行一个Pod副本。因此,Fluentd被部署为DaemonSet,它将在每个节点上生成一个pod,以读取由kubelet,容器运行时和容器生成的日志,并将它们发送到Elasticsearch。为了使Fluentd能够工作,每个Node都必须标记beta.kubernetes.io/fluentd-ds-ready=true。

    下面是Fluentd的ConfigMap配置文件,此文件定义了Fluentd所获取的日志数据源,以及将这些日志数据输出到Elasticsearch中。

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: fluentd-es-config-v0.1.4
      namespace: kube-system
      labels:
        addonmanager.kubernetes.io/mode: Reconcile
    data:
      system.conf: |-
        <system>
          root_dir /tmp/fluentd-buffers/
        </system>
      containers.input.conf: |-
        <source>
          @id fluentd-containers.log
          @type tail
          path /var/log/containers/*.log
          pos_file /var/log/es-containers.log.pos
          time_format %Y-%m-%dT%H:%M:%S.%NZ
          tag raw.kubernetes.*
          read_from_head true
          <parse>
            @type multi_format
            <pattern>
              format json
              time_key time
              time_format %Y-%m-%dT%H:%M:%S.%NZ
            </pattern>
            <pattern>
              format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/
              time_format %Y-%m-%dT%H:%M:%S.%N%:z
            </pattern>
          </parse>
        </source>
        # Detect exceptions in the log output and forward them as one log entry.
        <match raw.kubernetes.**>
          @id raw.kubernetes
          @type detect_exceptions
          remove_tag_prefix raw
          message log
          stream stream
          multiline_flush_interval 5
          max_bytes 500000
          max_lines 1000
        </match>
      output.conf: |-
        # Enriches records with Kubernetes metadata
        <filter kubernetes.**>
          @type kubernetes_metadata
        </filter>
        <match **>
          @id elasticsearch
          @type elasticsearch
          @log_level info
          include_tag_key true
          host elasticsearch-logging
          port 9200
          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 2M
            queue_limit_length 8
            overflow_action block
          </buffer>
        </match>

    通过执行如下的命令创建Fluentd的ConfigMap:

    $ kubectl create -f {path}/fluentd-es-configmap.yaml

    Fluentd本身的YAML配置文件如下所示:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: fluentd-es
      namespace: kube-system
      labels:
        k8s-app: fluentd-es
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: fluentd-es
      labels:
        k8s-app: fluentd-es
        kubernetes.io/cluster-service: "true"
        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
        kubernetes.io/cluster-service: "true"
        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.2.0
      namespace: kube-system
      labels:
        k8s-app: fluentd-es
        version: v2.2.0
        kubernetes.io/cluster-service: "true"
        addonmanager.kubernetes.io/mode: Reconcile
    spec:
      selector:
        matchLabels:
          k8s-app: fluentd-es
          version: v2.2.0
      template:
        metadata:
          labels:
            k8s-app: fluentd-es
            kubernetes.io/cluster-service: "true"
            version: v2.2.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:
            scheduler.alpha.kubernetes.io/critical-pod: ''
            seccomp.security.alpha.kubernetes.io/pod: 'docker/default'
        spec:
          priorityClassName: system-node-critical
          serviceAccountName: fluentd-es
          containers:
          - name: fluentd-es
            image: k8s.gcr.io/fluentd-elasticsearch:v2.2.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: /var/lib/docker/containers
              readOnly: true
            - name: config-volume
              mountPath: /etc/fluent/config.d
          nodeSelector:
            beta.kubernetes.io/fluentd-ds-ready: "true"
          terminationGracePeriodSeconds: 30
          volumes:
          - name: varlog
            hostPath:
              path: /var/log
          - name: varlibdockercontainers
            hostPath:
              path: /var/lib/docker/containers
          - name: config-volume
            configMap:
              name: fluentd-es-config-v0.1.4

    通过执行如下的命令部署Fluentd:

    $ kubectl create -f {path}/fluentd-es-ds.yaml

    2.3 安装部署Kibana

    Kibana是一个开源的分析与可视化平台,被设计用于和Elasticsearch一起使用的。通过kibana可以搜索、查看和交互存放在Elasticsearch中的数据,利用各种不同的图表、表格和地图等,Kibana能够对数据进行分析与可视化。Kibana部署的YAML如下所示,通过环境变量ELASTICSEARCH_URL,指定所获取日志数据的Elasticsearch服务,此处为:http://elasticsearch-logging:9200,elasticsearch.cattle-logging是elasticsearch在Kubernetes中代理服务的名称。在Fluented配置文件中,有下面的一些关键指令:

    • source指令确定输入源。
    • match指令确定输出目标。
    • filter指令确定事件处理管道。
    • system指令设置系统范围的配置。
    • label指令将输出和过滤器分组以进行内部路由
    • @include指令包含其他文件。
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: kibana-logging
      namespace: kube-system
      labels:
        k8s-app: kibana-logging
        kubernetes.io/cluster-service: "true"
        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:6.2.4
            resources:
              # need more cpu upon initialization, therefore burstable class
              limits:
                cpu: 1000m
              requests:
                cpu: 100m
            env:
              - name: ELASTICSEARCH_URL
                value: http://elasticsearch-logging:9200
            ports:
            - containerPort: 5601
              name: ui
              protocol: TCP

    通过执行如下的命令部署Kibana的代理服务:

    $ kubectl create -f {path}/kibana-deployment.yaml

    下面Kibana的代理服务YAML配置文件,代理服务的类型为NodePort。

    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:
      type: NodePort
      ports:
      - port: 5601
        protocol: TCP
        targetPort: ui
      selector:
        k8s-app: kibana-logging

    通过执行如下的命令部署Kibana的代理服务:

    $ kubectl create -f {path}/kibana-service.yaml

    3、日志数据展示

    通过如下命令获取Kibana的对外暴露的端口:

    $ kubectl get svc --namespace=kube-system

    从输出的信息可以知道,kibana对外暴露的端口为30471,因此在Kubernetes集群外可以通过:http://{NodeIP}:30471 访问kibana。

    通过点击“Discover”,就能够实时看看从容器中获取到的日志信息:

     

    参考资料

    1.《Logging Architecture》地址:https://kubernetes.io/docs/concepts/cluster-administration/logging/

    2.《Kubernetes Logging with Fluentd》地址:https://docs.fluentd.org/v0.12/articles/kubernetes-fluentd

    3.《Quickstart Guide》地址:https://docs.fluentd.org/v0.12/articles/quickstart

    4.《fluentd-elasticsearch》地址:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/fluentd-elasticsearch

    5.《Elasticsearch》地址:https://www.elastic.co/products/elasticsearch

    6.《What is Fluentd?》地址:https://www.fluentd.org/architecture

    7.《Configuration File Syntax》地址:https://docs.fluentd.org/v1.0/articles/config-file

    8.《A Practical Introduction to Elasticsearch》地址:https://www.elastic.co/blog/a-practical-introduction-to-elasticsearch

    展开全文
  • 1、统一日志管理的整体方案 通过应用和系统日志可以了解Kubernetes集群内所发生...对于容器化应用程序来说,最简单和最易接受的日志记录方法是将日志内容写入到标准输出和标准错误流。 但是,容器引擎或运行时提供...

    1、统一日志管理的整体方案

    通过应用和系统日志可以了解Kubernetes集群内所发生的事情,对于调试问题和监视集群活动来说日志非常有用。对于大部分的应用来说,都会具有某种日志机制。因此,大多数容器引擎同样被设计成支持某种日志机制。对于容器化应用程序来说,最简单和最易接受的日志记录方法是将日志内容写入到标准输出和标准错误流。

    但是,容器引擎或运行时提供的本地功能通常不足以支撑完整的日志记录解决方案。例如,如果一个容器崩溃、一个Pod被驱逐、或者一个Node死亡,应用相关者可能仍然需要访问应用程序的日志。因此,日志应该具 有独立于Node、Pod或者容器的单独存储和生命周期,这个概念被称为群集级日志记录。群集级日志记录需要一个独立的后端来存储、分析和查询日志。Kubernetes本身并没有为日志数据提供原生的存储解决方案,但可以将许多现有的日志记录解决方案集成到Kubernetes集群中。在Kubernetes中,有三个层次的日志:

    • 基础日志

    • Node级别的日志

    • 群集级别的日志架构

    1.1 基础日志

    kubernetes基础日志即将日志数据输出到标准输出流,可以使用kubectl logs命令获取容器日志信息。如果Pod中有多个容器,可以通过将容器名称附加到命令来指定要访问哪个容器的日志。例如,在Kubernetes集群中的devops命名空间下有一个名称为nexus3-f5b7fc55c-hq5v7的Pod,就可以通过如下的命令获取日志:

    
    

    $ kubectl logs nexus3-f5b7fc55c-hq5v7 --namespace=devops

    1.2 Node级别的日志

    容器化应用写入到stdout和stderr的所有内容都是由容器引擎处理和重定向的。例如,docker容器引擎会将这两个流重定向到日志记录驱动,在Kubernetes中该日志驱动被配置为以json格式写入文件。docker json日志记录驱动将每一行视为单独的消息。当使用docker日志记录驱动时,并不支持多行消息,因此需要在日志代理级别或更高级别上处理多行消息。

    默认情况下,如果容器重新启动,kubectl将会保留一个已终止的容器及其日志。如果从Node中驱逐Pod,那么Pod中所有相应的容器也会连同它们的日志一起被驱逐。Node级别的日志中的一个重要考虑是实现日志旋转,这样日志不会消耗Node上的所有可用存储。Kubernetes目前不负责旋转日志,部署工具应该建立一个解决方案来解决这个问题。

    1

    在Kubernetes中有两种类型的系统组件:运行在容器中的组件和不在容器中运行的组件。例如:

    • Kubernetes调度器和kube-proxy在容器中运行。

    • kubelet和容器运行时,例如docker,不在容器中运行。

    在带有systemd的机器上,kubelet和容器运行时写入journaId。如果systemd不存在,它们会在/var/log目录中写入.log文件。在容器中的系统组件总是绕过默认的日志记录机制,写入到/var/log目录,它们使用golg日志库。可以找到日志记录中开发文档中那些组件记录严重性的约定。

    类似于容器日志,在/var/log目录中的系统组件日志应该被旋转。这些日志被配置为每天由logrotate进行旋转,或者当大小超过100mb时进行旋转。

    1.3 集群级别的日志架构

    Kubernetes本身没有为群集级别日志记录提供原生解决方案,但有几种常见的方法可以采用:

    • 使用运行在每个Node上的Node级别的日志记录代理;

    • 在应用Pod中包含一个用于日志记录的sidecar。

    • 将日志直接从应用内推到后端。

    经过综合考虑,本文采用通过在每个Node上包括Node级别的日志记录代理来实现群集级别日志记录。日志记录代理暴露日志或将日志推送到后端的专用工具。通常,logging-agent是一个容器,此容器能够访问该Node上的所有应用程序容器的日志文件。

    因为日志记录必须在每个Node上运行,所以通常将它作为DaemonSet副本、或一个清单Pod或Node上的专用本机进程。然而,后两种方法后续将会被放弃。使用Node级别日志记录代理是Kubernetes集群最常见和最受欢迎的方法,因为它只为每个节点创建一个代理,并且不需要对节点上运行的应用程序进行任何更改。但是,Node级别日志记录仅适用于应用程序的标准输出和标准错误。

    Kubernetes本身并没有指定日志记录代理,但是有两个可选的日志记录代理与Kubernetes版本打包发布:和谷歌云平台一起使用的Stackdriver和Elasticsearch,两者都使用自定义配置的fluentd作为Node上的代理。在本文的方案中,Logging-agent 采用 Fluentd,而 Logging Backend 采用 Elasticsearch,前端展示采用Grafana。即通过 Fluentd 作为 Logging-agent 收集日志,并推送给后端的Elasticsearch;Grafana从Elasticsearch中获取日志,并进行统一的展示。

    1

    2、安装统一日志管理的组件

    在本文中采用使用Node日志记录代理的方面进行Kubernetes的统一日志管理,相关的工具采用:

    • 日志记录代理(logging-agent):日志记录代理用于从容器中获取日志信息,使用Fluentd;

    • 日志记录后台(Logging-Backend):日志记录后台用于处理日志记录代理推送过来的日志,使用Elasticsearch;

    • 日志记录展示:日志记录展示用于向用户显示统一的日志信息,使用Kibana。

    在Kubernetes中通过了Elasticsearch 附加组件,此组件包括Elasticsearch、Fluentd和Kibana。Elasticsearch是一种负责存储日志并允许查询的搜索引擎。Fluentd从Kubernetes中获取日志消息,并发送到Elasticsearch;而Kibana是一个图形界面,用于查看和查询存储在Elasticsearch中的日志。在安装部署之前,对于环境的要求如下:

    2.1 安装部署Elasticsearch

    Elasticsearch是一个基于Apache Lucene(TM)的开源搜索和数据分析引擎引擎,Elasticsearch使用Java进行开发,并使用Lucene作为其核心实现所有索引和搜索的功能。它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。Elasticsearch不仅仅是Lucene和全文搜索,它还提供如下的能力:

    • 分布式的实时文件存储,每个字段都被索引并可被搜索;

    • 分布式的实时分析搜索引擎;

    • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据。

    在Elasticsearch中,包含多个索引(Index),相应的每个索引可以包含多个类型(Type),这些不同的类型每个都可以存储多个文档(Document),每个文档又有多个属性。索引 (index) 类似于传统关系数据库中的一个数据库,是一个存储关系型文档的地方。Elasticsearch 使用的是标准的 RESTful API 和 JSON。此外,还构建和维护了很多其他语言的客户端,例如 Java, Python, .NET, 和 PHP。

    下面是Elasticsearch的YAML配置文件,在此配置文件中,定义了一个名称为elasticsearch-logging的ServiceAccount,并授予其能够对命名空间、服务和端点读取的访问权限;并以StatefulSet类型部署Elasticsearch。

    
    

    # RBAC authn and authz

    apiVersion: v1

    kind: ServiceAccount

    metadata:

    name: elasticsearch-logging

    namespace: kube-system

    labels:

    k8s-app: elasticsearch-logging

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    ---

    kind: ClusterRole

    apiVersion: rbac.authorization.k8s.io/v1

    metadata:

    name: elasticsearch-logging

    labels:

    k8s-app: elasticsearch-logging

    kubernetes.io/cluster-service: "true"

    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

    kubernetes.io/cluster-service: "true"

    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

    apiVersion: apps/v1

    kind: StatefulSet

    metadata:

    name: elasticsearch-logging

    namespace: kube-system

    labels:

    k8s-app: elasticsearch-logging

    version: v6.2.5

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    spec:

    serviceName: elasticsearch-logging

    replicas: 2

    selector:

    matchLabels:

    k8s-app: elasticsearch-logging

    version: v6.2.5

    template:

    metadata:

    labels:

    k8s-app: elasticsearch-logging

    version: v6.2.5

    kubernetes.io/cluster-service: "true"

    spec:

    serviceAccountName: elasticsearch-logging

    containers:

    - image: k8s.gcr.io/elasticsearch:v6.2.5

    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: 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:

    
    

    $ kubectl create -f {path}/es-statefulset.yaml

    下面Elasticsearch的代理服务YAML配置文件,代理服务暴露的端口为9200。

    
    

    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

    通过执行如下的命令部署Elasticsearch的代理服务:

    
    

    $ kubectl create -f {path}/es-service.yaml

    2.2 安装部署Fluentd

    1

    Fluentd是一个开源数据收集器,通过它能对数据进行统一收集和消费,能够更好地使用和理解数据。Fluentd将数据结构化为JSON,从而能够统一处理日志数据,包括:收集、过滤、缓存和输出。Fluentd是一个基于插件体系的架构,包括输入插件、输出插件、过滤插件、解析插件、格式化插件、缓存插件和存储插件,通过插件可以扩展和更好的使用Fluentd。

    1

    Fluentd的整体处理过程如下,通过Input插件获取数据,并通过Engine进行数据的过滤、解析、格式化和缓存,最后通过Output插件将数据输出给特定的终端。

    1

    在本文中, Fluentd 作为 Logging-agent 进行日志收集,并将收集到的日子推送给后端的Elasticsearch。对于Kubernetes来说,DaemonSet确保所有(或一些)Node会运行一个Pod副本。因此,Fluentd被部署为DaemonSet,它将在每个节点上生成一个pod,以读取由kubelet,容器运行时和容器生成的日志,并将它们发送到Elasticsearch。为了使Fluentd能够工作,每个Node都必须标记beta.kubernetes.io/fluentd-ds-ready=true。

    下面是Fluentd的ConfigMap配置文件,此文件定义了Fluentd所获取的日志数据源,以及将这些日志数据输出到Elasticsearch中。

    
    

    kind: ConfigMap

    apiVersion: v1

    metadata:

    name: fluentd-es-config-v0.1.4

    namespace: kube-system

    labels:

    addonmanager.kubernetes.io/mode: Reconcile

    data:

    system.conf: |-

    <system>

    root_dir /tmp/fluentd-buffers/

    </system>

    containers.input.conf: |-

    <source>

    @id fluentd-containers.log

    @type tail

    path /var/log/containers/*.log

    pos_file /var/log/es-containers.log.pos

    time_format %Y-%m-%dT%H:%M:%S.%NZ

    tag raw.kubernetes.*

    read_from_head true

    <parse>

    @type multi_format

    <pattern>

    format json

    time_key time

    time_format %Y-%m-%dT%H:%M:%S.%NZ

    </pattern>

    <pattern>

    format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/

    time_format %Y-%m-%dT%H:%M:%S.%N%:z

    </pattern>

    </parse>

    </source>

    # Detect exceptions in the log output and forward them as one log entry.

    <match raw.kubernetes.**>

    @id raw.kubernetes

    @type detect_exceptions

    remove_tag_prefix raw

    message log

    stream stream

    multiline_flush_interval 5

    max_bytes 500000

    max_lines 1000

    </match>

    output.conf: |-

    # Enriches records with Kubernetes metadata

    <filter kubernetes.**>

    @type kubernetes_metadata

    </filter>

    <match **>

    @id elasticsearch

    @type elasticsearch

    @log_level info

    include_tag_key true

    host elasticsearch-logging

    port 9200

    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 2M

    queue_limit_length 8

    overflow_action block

    </buffer>

    </match>

    通过执行如下的命令创建Fluentd的ConfigMap:

    
    

    $ kubectl create -f {path}/fluentd-es-configmap.yaml

    Fluentd本身的YAML配置文件如下所示:

    
    

    apiVersion: v1

    kind: ServiceAccount

    metadata:

    name: fluentd-es

    namespace: kube-system

    labels:

    k8s-app: fluentd-es

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    ---

    kind: ClusterRole

    apiVersion: rbac.authorization.k8s.io/v1

    metadata:

    name: fluentd-es

    labels:

    k8s-app: fluentd-es

    kubernetes.io/cluster-service: "true"

    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

    kubernetes.io/cluster-service: "true"

    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.2.0

    namespace: kube-system

    labels:

    k8s-app: fluentd-es

    version: v2.2.0

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    spec:

    selector:

    matchLabels:

    k8s-app: fluentd-es

    version: v2.2.0

    template:

    metadata:

    labels:

    k8s-app: fluentd-es

    kubernetes.io/cluster-service: "true"

    version: v2.2.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:

    scheduler.alpha.kubernetes.io/critical-pod: ''

    seccomp.security.alpha.kubernetes.io/pod: 'docker/default'

    spec:

    priorityClassName: system-node-critical

    serviceAccountName: fluentd-es

    containers:

    - name: fluentd-es

    image: k8s.gcr.io/fluentd-elasticsearch:v2.2.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: /var/lib/docker/containers

    readOnly: true

    - name: config-volume

    mountPath: /etc/fluent/config.d

    nodeSelector:

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

    terminationGracePeriodSeconds: 30

    volumes:

    - name: varlog

    hostPath:

    path: /var/log

    - name: varlibdockercontainers

    hostPath:

    path: /var/lib/docker/containers

    - name: config-volume

    configMap:

    name: fluentd-es-config-v0.1.4

    通过执行如下的命令部署Fluentd:

    
    

    $ kubectl create -f {path}/fluentd-es-ds.yaml

    2.3 安装部署Kibana

    Kibana是一个开源的分析与可视化平台,被设计用于和Elasticsearch一起使用的。通过kibana可以搜索、查看和交互存放在Elasticsearch中的数据,利用各种不同的图表、表格和地图等,Kibana能够对数据进行分析与可视化。Kibana部署的YAML如下所示,通过环境变量ELASTICSEARCH_URL,指定所获取日志数据的Elasticsearch服务,此处为:http://elasticsearch-logging:9200,elasticsearch.cattle-logging是elasticsearch在Kubernetes中代理服务的名称。在Fluented配置文件中,有下面的一些关键指令:

    • source指令确定输入源。

    • match指令确定输出目标。

    • filter指令确定事件处理管道。

    • system指令设置系统范围的配置。

    • label指令将输出和过滤器分组以进行内部路由

    • @include指令包含其他文件。

    
    

    apiVersion: apps/v1

    kind: Deployment

    metadata:

    name: kibana-logging

    namespace: kube-system

    labels:

    k8s-app: kibana-logging

    kubernetes.io/cluster-service: "true"

    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:6.2.4

    resources:

    # need more cpu upon initialization, therefore burstable class

    limits:

    cpu: 1000m

    requests:

    cpu: 100m

    env:

    - name: ELASTICSEARCH_URL

    value: http://elasticsearch-logging:9200

    ports:

    - containerPort: 5601

    name: ui

    protocol: TCP

    通过执行如下的命令部署Kibana的代理服务:

    
    

    $ kubectl create -f {path}/kibana-deployment.yaml

    下面Kibana的代理服务YAML配置文件,代理服务的类型为NodePort。

    
    

    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:

    type: NodePort

    ports:

    - port: 5601

    protocol: TCP

    targetPort: ui

    selector:

    k8s-app: kibana-logging

    通过执行如下的命令部署Kibana的代理服务:

    
    

    $ kubectl create -f {path}/kibana-service.yaml

    3、日志数据展示

    通过如下命令获取Kibana的对外暴露的端口:

    
    

    $ kubectl get svc --namespace=kube-system

    1

    从输出的信息可以知道,kibana对外暴露的端口为30471,因此在Kubernetes集群外可以通过:http://{NodeIP}:30471 访问kibana。

    1

    通过点击“Discover”,就能够实时看看从容器中获取到的日志信息:

    1本文转自掘金-Kubernetes基于EFK进行统一的日志管理方案

    展开全文
  • 1、统一日志管理的整体方案 通过应用和系统日志可以了解Kubernetes集群内所发生...对于容器化应用程序来说,最简单和最易接受的日志记录方法是将日志内容写入到标准输出和标准错误流。 但是,容器引擎或运行时提供...

    1、统一日志管理的整体方案

    通过应用和系统日志可以了解Kubernetes集群内所发生的事情,对于调试问题和监视集群活动来说日志非常有用。对于大部分的应用来说,都会具有某种日志机制。因此,大多数容器引擎同样被设计成支持某种日志机制。对于容器化应用程序来说,最简单和最易接受的日志记录方法是将日志内容写入到标准输出和标准错误流。

    但是,容器引擎或运行时提供的本地功能通常不足以支撑完整的日志记录解决方案。例如,如果一个容器崩溃、一个Pod被驱逐、或者一个Node死亡,应用相关者可能仍然需要访问应用程序的日志。因此,日志应该具 有独立于Node、Pod或者容器的单独存储和生命周期,这个概念被称为群集级日志记录。群集级日志记录需要一个独立的后端来存储、分析和查询日志。Kubernetes本身并没有为日志数据提供原生的存储解决方案,但可以将许多现有的日志记录解决方案集成到Kubernetes集群中。在Kubernetes中,有三个层次的日志:

    • 基础日志

    • Node级别的日志

    • 群集级别的日志架构

    1.1 基础日志

    kubernetes基础日志即将日志数据输出到标准输出流,可以使用kubectl logs命令获取容器日志信息。如果Pod中有多个容器,可以通过将容器名称附加到命令来指定要访问哪个容器的日志。例如,在Kubernetes集群中的devops命名空间下有一个名称为nexus3-f5b7fc55c-hq5v7的Pod,就可以通过如下的命令获取日志:

    
    

    $ kubectl logs nexus3-f5b7fc55c-hq5v7 --namespace=devops

    1.2 Node级别的日志

    容器化应用写入到stdout和stderr的所有内容都是由容器引擎处理和重定向的。例如,docker容器引擎会将这两个流重定向到日志记录驱动,在Kubernetes中该日志驱动被配置为以json格式写入文件。docker json日志记录驱动将每一行视为单独的消息。当使用docker日志记录驱动时,并不支持多行消息,因此需要在日志代理级别或更高级别上处理多行消息。

    默认情况下,如果容器重新启动,kubectl将会保留一个已终止的容器及其日志。如果从Node中驱逐Pod,那么Pod中所有相应的容器也会连同它们的日志一起被驱逐。Node级别的日志中的一个重要考虑是实现日志旋转,这样日志不会消耗Node上的所有可用存储。Kubernetes目前不负责旋转日志,部署工具应该建立一个解决方案来解决这个问题。

    1

    在Kubernetes中有两种类型的系统组件:运行在容器中的组件和不在容器中运行的组件。例如:

    • Kubernetes调度器和kube-proxy在容器中运行。

    • kubelet和容器运行时,例如docker,不在容器中运行。

    在带有systemd的机器上,kubelet和容器运行时写入journaId。如果systemd不存在,它们会在/var/log目录中写入.log文件。在容器中的系统组件总是绕过默认的日志记录机制,写入到/var/log目录,它们使用golg日志库。可以找到日志记录中开发文档中那些组件记录严重性的约定。

    类似于容器日志,在/var/log目录中的系统组件日志应该被旋转。这些日志被配置为每天由logrotate进行旋转,或者当大小超过100mb时进行旋转。

    1.3 集群级别的日志架构

    Kubernetes本身没有为群集级别日志记录提供原生解决方案,但有几种常见的方法可以采用:

    • 使用运行在每个Node上的Node级别的日志记录代理;

    • 在应用Pod中包含一个用于日志记录的sidecar。

    • 将日志直接从应用内推到后端。

    经过综合考虑,本文采用通过在每个Node上包括Node级别的日志记录代理来实现群集级别日志记录。日志记录代理暴露日志或将日志推送到后端的专用工具。通常,logging-agent是一个容器,此容器能够访问该Node上的所有应用程序容器的日志文件。

    因为日志记录必须在每个Node上运行,所以通常将它作为DaemonSet副本、或一个清单Pod或Node上的专用本机进程。然而,后两种方法后续将会被放弃。使用Node级别日志记录代理是Kubernetes集群最常见和最受欢迎的方法,因为它只为每个节点创建一个代理,并且不需要对节点上运行的应用程序进行任何更改。但是,Node级别日志记录仅适用于应用程序的标准输出和标准错误。

    Kubernetes本身并没有指定日志记录代理,但是有两个可选的日志记录代理与Kubernetes版本打包发布:和谷歌云平台一起使用的Stackdriver和Elasticsearch,两者都使用自定义配置的fluentd作为Node上的代理。在本文的方案中,Logging-agent 采用 Fluentd,而 Logging Backend 采用 Elasticsearch,前端展示采用Grafana。即通过 Fluentd 作为 Logging-agent 收集日志,并推送给后端的Elasticsearch;Grafana从Elasticsearch中获取日志,并进行统一的展示。

    1

    2、安装统一日志管理的组件

    在本文中采用使用Node日志记录代理的方面进行Kubernetes的统一日志管理,相关的工具采用:

    • 日志记录代理(logging-agent):日志记录代理用于从容器中获取日志信息,使用Fluentd;

    • 日志记录后台(Logging-Backend):日志记录后台用于处理日志记录代理推送过来的日志,使用Elasticsearch;

    • 日志记录展示:日志记录展示用于向用户显示统一的日志信息,使用Kibana。

    在Kubernetes中通过了Elasticsearch 附加组件,此组件包括Elasticsearch、Fluentd和Kibana。Elasticsearch是一种负责存储日志并允许查询的搜索引擎。Fluentd从Kubernetes中获取日志消息,并发送到Elasticsearch;而Kibana是一个图形界面,用于查看和查询存储在Elasticsearch中的日志。在安装部署之前,对于环境的要求如下:

    2.1 安装部署Elasticsearch

    Elasticsearch是一个基于Apache Lucene(TM)的开源搜索和数据分析引擎引擎,Elasticsearch使用Java进行开发,并使用Lucene作为其核心实现所有索引和搜索的功能。它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。Elasticsearch不仅仅是Lucene和全文搜索,它还提供如下的能力:

    • 分布式的实时文件存储,每个字段都被索引并可被搜索;

    • 分布式的实时分析搜索引擎;

    • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据。

    在Elasticsearch中,包含多个索引(Index),相应的每个索引可以包含多个类型(Type),这些不同的类型每个都可以存储多个文档(Document),每个文档又有多个属性。索引 (index) 类似于传统关系数据库中的一个数据库,是一个存储关系型文档的地方。Elasticsearch 使用的是标准的 RESTful API 和 JSON。此外,还构建和维护了很多其他语言的客户端,例如 Java, Python, .NET, 和 PHP。

    下面是Elasticsearch的YAML配置文件,在此配置文件中,定义了一个名称为elasticsearch-logging的ServiceAccount,并授予其能够对命名空间、服务和端点读取的访问权限;并以StatefulSet类型部署Elasticsearch。

    
    

    # RBAC authn and authz

    apiVersion: v1

    kind: ServiceAccount

    metadata:

    name: elasticsearch-logging

    namespace: kube-system

    labels:

    k8s-app: elasticsearch-logging

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    ---

    kind: ClusterRole

    apiVersion: rbac.authorization.k8s.io/v1

    metadata:

    name: elasticsearch-logging

    labels:

    k8s-app: elasticsearch-logging

    kubernetes.io/cluster-service: "true"

    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

    kubernetes.io/cluster-service: "true"

    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

    apiVersion: apps/v1

    kind: StatefulSet

    metadata:

    name: elasticsearch-logging

    namespace: kube-system

    labels:

    k8s-app: elasticsearch-logging

    version: v6.2.5

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    spec:

    serviceName: elasticsearch-logging

    replicas: 2

    selector:

    matchLabels:

    k8s-app: elasticsearch-logging

    version: v6.2.5

    template:

    metadata:

    labels:

    k8s-app: elasticsearch-logging

    version: v6.2.5

    kubernetes.io/cluster-service: "true"

    spec:

    serviceAccountName: elasticsearch-logging

    containers:

    - image: k8s.gcr.io/elasticsearch:v6.2.5

    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: 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:

    
    

    $ kubectl create -f {path}/es-statefulset.yaml

    下面Elasticsearch的代理服务YAML配置文件,代理服务暴露的端口为9200。

    
    

    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

    通过执行如下的命令部署Elasticsearch的代理服务:

    
    

    $ kubectl create -f {path}/es-service.yaml

    2.2 安装部署Fluentd

    1

    Fluentd是一个开源数据收集器,通过它能对数据进行统一收集和消费,能够更好地使用和理解数据。Fluentd将数据结构化为JSON,从而能够统一处理日志数据,包括:收集、过滤、缓存和输出。Fluentd是一个基于插件体系的架构,包括输入插件、输出插件、过滤插件、解析插件、格式化插件、缓存插件和存储插件,通过插件可以扩展和更好的使用Fluentd。

    1

    Fluentd的整体处理过程如下,通过Input插件获取数据,并通过Engine进行数据的过滤、解析、格式化和缓存,最后通过Output插件将数据输出给特定的终端。

    1

    在本文中, Fluentd 作为 Logging-agent 进行日志收集,并将收集到的日子推送给后端的Elasticsearch。对于Kubernetes来说,DaemonSet确保所有(或一些)Node会运行一个Pod副本。因此,Fluentd被部署为DaemonSet,它将在每个节点上生成一个pod,以读取由kubelet,容器运行时和容器生成的日志,并将它们发送到Elasticsearch。为了使Fluentd能够工作,每个Node都必须标记beta.kubernetes.io/fluentd-ds-ready=true。

    下面是Fluentd的ConfigMap配置文件,此文件定义了Fluentd所获取的日志数据源,以及将这些日志数据输出到Elasticsearch中。

    
    

    kind: ConfigMap

    apiVersion: v1

    metadata:

    name: fluentd-es-config-v0.1.4

    namespace: kube-system

    labels:

    addonmanager.kubernetes.io/mode: Reconcile

    data:

    system.conf: |-

    <system>

    root_dir /tmp/fluentd-buffers/

    </system>

    containers.input.conf: |-

    <source>

    @id fluentd-containers.log

    @type tail

    path /var/log/containers/*.log

    pos_file /var/log/es-containers.log.pos

    time_format %Y-%m-%dT%H:%M:%S.%NZ

    tag raw.kubernetes.*

    read_from_head true

    <parse>

    @type multi_format

    <pattern>

    format json

    time_key time

    time_format %Y-%m-%dT%H:%M:%S.%NZ

    </pattern>

    <pattern>

    format /^(?<time>.+) (?<stream>stdout|stderr) [^ ]* (?<log>.*)$/

    time_format %Y-%m-%dT%H:%M:%S.%N%:z

    </pattern>

    </parse>

    </source>

    # Detect exceptions in the log output and forward them as one log entry.

    <match raw.kubernetes.**>

    @id raw.kubernetes

    @type detect_exceptions

    remove_tag_prefix raw

    message log

    stream stream

    multiline_flush_interval 5

    max_bytes 500000

    max_lines 1000

    </match>

    output.conf: |-

    # Enriches records with Kubernetes metadata

    <filter kubernetes.**>

    @type kubernetes_metadata

    </filter>

    <match **>

    @id elasticsearch

    @type elasticsearch

    @log_level info

    include_tag_key true

    host elasticsearch-logging

    port 9200

    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 2M

    queue_limit_length 8

    overflow_action block

    </buffer>

    </match>

    通过执行如下的命令创建Fluentd的ConfigMap:

    
    

    $ kubectl create -f {path}/fluentd-es-configmap.yaml

    Fluentd本身的YAML配置文件如下所示:

    
    

    apiVersion: v1

    kind: ServiceAccount

    metadata:

    name: fluentd-es

    namespace: kube-system

    labels:

    k8s-app: fluentd-es

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    ---

    kind: ClusterRole

    apiVersion: rbac.authorization.k8s.io/v1

    metadata:

    name: fluentd-es

    labels:

    k8s-app: fluentd-es

    kubernetes.io/cluster-service: "true"

    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

    kubernetes.io/cluster-service: "true"

    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.2.0

    namespace: kube-system

    labels:

    k8s-app: fluentd-es

    version: v2.2.0

    kubernetes.io/cluster-service: "true"

    addonmanager.kubernetes.io/mode: Reconcile

    spec:

    selector:

    matchLabels:

    k8s-app: fluentd-es

    version: v2.2.0

    template:

    metadata:

    labels:

    k8s-app: fluentd-es

    kubernetes.io/cluster-service: "true"

    version: v2.2.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:

    scheduler.alpha.kubernetes.io/critical-pod: ''

    seccomp.security.alpha.kubernetes.io/pod: 'docker/default'

    spec:

    priorityClassName: system-node-critical

    serviceAccountName: fluentd-es

    containers:

    - name: fluentd-es

    image: k8s.gcr.io/fluentd-elasticsearch:v2.2.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: /var/lib/docker/containers

    readOnly: true

    - name: config-volume

    mountPath: /etc/fluent/config.d

    nodeSelector:

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

    terminationGracePeriodSeconds: 30

    volumes:

    - name: varlog

    hostPath:

    path: /var/log

    - name: varlibdockercontainers

    hostPath:

    path: /var/lib/docker/containers

    - name: config-volume

    configMap:

    name: fluentd-es-config-v0.1.4

    通过执行如下的命令部署Fluentd:

    
    

    $ kubectl create -f {path}/fluentd-es-ds.yaml

    2.3 安装部署Kibana

    Kibana是一个开源的分析与可视化平台,被设计用于和Elasticsearch一起使用的。通过kibana可以搜索、查看和交互存放在Elasticsearch中的数据,利用各种不同的图表、表格和地图等,Kibana能够对数据进行分析与可视化。Kibana部署的YAML如下所示,通过环境变量ELASTICSEARCH_URL,指定所获取日志数据的Elasticsearch服务,此处为:http://elasticsearch-logging:9200,elasticsearch.cattle-logging是elasticsearch在Kubernetes中代理服务的名称。在Fluented配置文件中,有下面的一些关键指令:

    • source指令确定输入源。

    • match指令确定输出目标。

    • filter指令确定事件处理管道。

    • system指令设置系统范围的配置。

    • label指令将输出和过滤器分组以进行内部路由

    • @include指令包含其他文件。

    
    

    apiVersion: apps/v1

    kind: Deployment

    metadata:

    name: kibana-logging

    namespace: kube-system

    labels:

    k8s-app: kibana-logging

    kubernetes.io/cluster-service: "true"

    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:6.2.4

    resources:

    # need more cpu upon initialization, therefore burstable class

    limits:

    cpu: 1000m

    requests:

    cpu: 100m

    env:

    - name: ELASTICSEARCH_URL

    value: http://elasticsearch-logging:9200

    ports:

    - containerPort: 5601

    name: ui

    protocol: TCP

    通过执行如下的命令部署Kibana的代理服务:

    
    

    $ kubectl create -f {path}/kibana-deployment.yaml

    下面Kibana的代理服务YAML配置文件,代理服务的类型为NodePort。

    
    

    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:

    type: NodePort

    ports:

    - port: 5601

    protocol: TCP

    targetPort: ui

    selector:

    k8s-app: kibana-logging

    通过执行如下的命令部署Kibana的代理服务:

    
    

    $ kubectl create -f {path}/kibana-service.yaml

    3、日志数据展示

    通过如下命令获取Kibana的对外暴露的端口:

    
    

    $ kubectl get svc --namespace=kube-system

    1

    从输出的信息可以知道,kibana对外暴露的端口为30471,因此在Kubernetes集群外可以通过:http://{NodeIP}:30471 访问kibana。

    1

    通过点击“Discover”,就能够实时看看从容器中获取到的日志信息:

    1本文转自掘金-Kubernetes基于EFK进行统一的日志管理方案

    展开全文
  • 分析问题 (1)zookeeper在预装的时候并没有给我们很好的处理日志的问题,系统会默认在你...(2)从上面我们知道zookeeper的日志输出路径没有一个统一的模式,这样子日志文件不好控制,对于我们去维护没有一个精准,所

    分析问题

    (1)zookeeper在预装的时候并没有给我们很好的处理日志的问题,系统会默认在你启动的地方吧日志打印到当前的路径下面,比如我现在当前目录下面启动zk服务器并通过ll密令就发现在当前路径下面多出来了一个 zookeeper.out的文件


    设计思想

    (2)从上面我们知道zookeeper的日志输出路径没有一个统一的模式,这样子日志文件不好控制,对于我们去维护没有一个精准,所以我们要给日志文件统一处理。

    统一处理

    a. 修改Zookeeper的home目录下面的bin目录的zkEnv.sh脚本

    (1)ZOO_LOG_DIR
    把这个属性的值改成你要指定要输出日志的路径就可以了,比如这里是/app/zookeeper-3.4.5/logs。

    测试

    (1)首先我们在主目录下面启动服务器,然后查看zookeeper.out这个文件是否还在这个路径下面,如果不存在,那么我们就去我们制定的输出路径下面看看该文件已经存在,那么久可以证明我们的修改成功的!

    (2)使用命令pwd来验证我们在修改的路径就是现在这个路径,我们会发现zookeeper.out这个文件已经被统一放在这个路径下面了

    如果是集群环境的话,修改一个,然后scp到其他服务器就可以了。zookeeper服务在打印日志也是一种性能消耗和内存积累,但是日志文件很重要,通过日志我们可以分析出我们想要的信息,这个根绝业务需求,系统默认是INFO及以上级别的日志,INFO信息都是些启动服务器时候打印的信息,也可以修改成WARN级别以上的,这样子可以减少很多日志上面的性能消耗!

    修改日志级别

    修改日志级别需要修改两个地方:
    (1)zookeeper全局变量的脚本:zkEnv.sh的ZOO_LOG4J_PROP属性值, 也就是上面蓝色的地方,把INFO改成WARN就可以。

    (2)conf目录下面的log4j.properties文件的zookeeper.root.logger属性

    (3)测试日志级别打印
    a.测试启动看看有没有启动日志
    [hadoop@hadoop07 logs]$ zkServer.sh restart
    JMX enabled by default
    Using config: /app/zookeeper-3.4.5/bin/../conf/zoo.cfg
    JMX enabled by default
    Using config: /app/zookeeper-3.4.5/bin/../conf/zoo.cfg
    Stopping zookeeper ... STOPPED
    JMX enabled by default
    Using config: /app/zookeeper-3.4.5/bin/../conf/zoo.cfg
    Starting zookeeper ... STARTED
    [hadoop@hadoop07 logs]$ ll
    total 0
    -rw-rw-r-- 1 hadoop hadoop 0 Dec 30 15:00 zookeeper.out
    
    从上面我们可以看到当前的zookeeper.out这个文件大小为0,所以里面是没有任何东西的。
    b.我们把改服务器的myid里面的值改变一下,然后重启,系统肯定报错,然后再查看日志是否会打印!

    [hadoop@hadoop07 logs]$ cat zookeeper.out 
    2017-12-30 15:02:32,981 [myid:5] - ERROR [main:QuorumPeer@171] - Setting LearnerType to PARTICIPANT but 5 not in QuorumPeers. 
    2017-12-30 15:02:32,990 [myid:5] - ERROR [main:QuorumPeerMain@89] - Unexpected exception, exiting abnormally
    java.lang.RuntimeException: My id 5 not in the peer list
    	at org.apache.zookeeper.server.quorum.QuorumPeer.startLeaderElection(QuorumPeer.java:479)
    	at org.apache.zookeeper.server.quorum.QuorumPeer.start(QuorumPeer.java:411)
    	at org.apache.zookeeper.server.quorum.QuorumPeerMain.runFromConfig(QuorumPeerMain.java:151)
    	at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:111)
    	at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:78)
    [hadoop@hadoop07 logs]$ 
    
    从上面我们不难看出,我们修改了myid的值以后,报错日志级别在WARN以上,所以会在zookeeper.out写入错误信息,说明我们的修改成功!
    完!
    展开全文
  • 系统日志管理

    2018-06-14 12:37:00
    系统日志管理 日志文件分类(日志保存在/var/log下) 内核及系统日志 由系统服务syslog统一进行管理  /var/log/messages 内核及公共消息日志 /var/log/cron 计划任务日志 /var/log/dmesg 系统...
  • Eventlog Analyzer日志管理系统、日志分析工具、日志服务器功能及作用 Eventlog Analyzer是用来分析和审计系统及事件日志管理软件,能够对全网范围内主机、服务器、网络设备、数据库以及各种应用服务系统等...
  • 为您提供Logstash日志管理系统下载,Logstash是一个应用程序日志、事件传输、处理、管理和搜索平台。你可以用它来统一对应用程序日志进行收集管理,提供Web接口用于查询和统计。Logstash现在是ElasticSearch家族...
  • 为您提供Logstash日志管理系统下载,Logstash是一个应用程序日志、事件传输、处理、管理和搜索平台。你可以用它来统一对应用程序日志进行收集管理,提供Web接口用于查询和统计。Logstash现在是ElasticSearch家族...
  • 统一管理系统

    2018-08-04 17:59:04
    公司有eureka管理页面、spring admin管理页面、kafka管理页面、日志查询页面和文件系统查询页面,现在要将这些页面放到一个统一的网页中管理,通过标签分别跳转到不同的页面,省去了分别点开的麻烦 这些单个的系统...
  • 运维日志管理系统

    2014-07-18 17:41:36
    GlusterFS+ lagstash + elasticsearch + kibana 3 + redis 整合在一起的日志管理应用:安装,配置过程,使用情况等续一,glusterfs分布式文件系统部署:说明:公司想做网站业务日志及系统日志统一收集和管理,...
  • Systemd 统一管理所有 Unit 启动日志。带来好处就是,可以只用journalctl一个命令,查看所有日志(内核日志和应用日志)。日志的配置文件是/etc/systemd/journald.conf。journalctl功能强大,用法非常多。// 查看...
  • 通过应用和系统日志可以了解Kubernetes集群内所发生事情,对于调试问题和监视集群活动来说日志非常有用。对于大部分应用来说,都会具有某种日志机制。因此,大多数容器引擎同样被设计成支持某种日志机制。对于...
  • 为您提供Logstash日志管理系统下载,Logstash是一个应用程序日志、事件传输、处理、管理和搜索平台。你可以用它来统一对应用程序日志进行收集管理,提供Web接口用于查询和统计。Logstash现在是ElasticSearch家族...
  •  在分布式系统中,我们有多个web app,这些web app可能分别部署在不同的物理服务器上,并且有各自的日志输出。当生产问题来临时,很多时候都需要去各个日志文件中查找可能的异常,相当耗费人力。日志存储多以文本...
  • 为您提供Logstash日志管理系统下载,Logstash是一个应用程序日志、事件传输、处理、管理和搜索平台。你可以用它来统一对应用程序日志进行收集管理,提供Web接口用于查询和统计。Logstash现在是ElasticSearch家族...
  •  在分布式系统当中,我们有各种各样的WebService,这些服务可能分别部署在不同的服务器上,并且有各自的日志输出。为了方便对这些日志进行统一管理和分析。我们可以将日志统一输出到指定的数据库系统中,而再由日志...
  • 文章目录1 journald(统一放一个位置)1.1 journactl用法1.2 journal永久保存设定2 rsyslog(分类)2.1 自定义日志采集路径2.2 更改日志采集格式2.3 将日志统一发送至192.168.0.11主机3 timedatectl4 同步时间 ...
  • 系统中的绝大多数日志文件是由 rsyslogd 服务来统一管理的,只要各个进程将信息给予这个服务,它就会自动地把日志按照特定的格式记录到不同的日志文件中。 观察rsyslogd程序,可以看出此服务正在运行。 常见的系统...
  • 日志管理 日志文件:系统中各个运行消息的文件,不同的日志文件记录了不同类型的信息,如内核消息、错误消息等 syslog服务:syslogd: 系统,非内核产生的信息klogd:内核,专门负责记录内核产生的日志信息 一....
  • 学生日志管理统一、功能介绍二、功能代码1、定义学生类2、定义日志类3、定义一个日志系统类三、演示效果图 一、功能介绍 学生日志内容管理系统,日志信息主要包含日志编号,今日学习内容,掌握程度,疑问,日志...
  • 这一节介绍的方法主要是用于对Controller层抛出的异常做统一的处理。使用 @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理,只要设计得当,就再也不用在 Controller 层进行 try-catch 了。...
  • 通过这三个组件,构建一个统一的日志管理系统,用来收集分布式部署系统中分散在不同设备上的日志,方便后续进行日志分析。   其中,Elasticsearch是一个实时的分布式搜索和分析引擎,建立在全文搜索引擎Apache ...
  • 保证日志的安全性是安全日志服务器一个基本目的,加密和认证是常用保证日志信息安全性重要方法,而密钥管理又是...最后重点讨论了安全日志服务器密钥管理系统中密钥分配问题和多个CA之间交叉认证模式选择。
  • 1.了解日志:日志:记录系统和程序运行的信息,用于排查故障和...2.常见的日志文件及其作用:/var/log/messages 包括内核及系统日志,大多的日志都在这文件中。推荐使用命令:tail -f /var/log/messages 或者:less ...
  • 日志管理

    2018-08-07 09:31:39
    日志管理 日志功能:系统和程序“日记本” • 记录系统、程序运行中发生各种事件 • 通过查看日志,了解几排除故障 • 日志是信息安全控制“依据”。 内核及系统日志:由系统服务rsyslog统一记录/...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,327
精华内容 530
关键字:

统一的日志管理系统