乐趣区

关于java:云原生系列5-容器化日志之EFK

上图是 EFK 架构图,k8s 环境下常见的日志采集形式。

日志需要

1 集中采集微服务的日志,能够依据申请 id 追踪到残缺的日志;

2 统计申请接口的耗时,超出最长响应工夫的,须要做报警,并针对性的进行调优;

3 慢 sql 排行榜,并报警;

4 异样日志排行榜,并报警;

5 慢页面申请排行,并告警;

k8s 的日志采集

k8s 自身不会为你做日志采集,须要本人做;

k8s 的容器日志解决形式采纳的 集群层级日志,

即容器销毁,pod 漂移,Node 宕机不会对容器日志造成影响;

容器的日志会输入到 stdout,stderr, 对应的存储在宿主机的目录中,

即 /var/lib/docker/container;

Node 上通过日志代理转发

在每个 node 上部署一个 daemonset , 跑一个 logging-agent 收集日志,

比方 fluentd, 采集宿主机对应的数据盘上的日志,而后输入到日志存储服务或者音讯队列;

优缺点剖析:

比照 阐明
长处 1 每个 Node 只须要部署一个 Pod 采集日志 2 对利用无侵入
毛病 利用输入的日志都必须间接输入到容器的 stdout,stderr 中

Pod 外部通过 sidecar 容器转发到日志服务

通过在 pod 中启动一个 sidecar 容器,比方 fluentd,读取容器挂载的 volume 目录,输入到日志服务端;

日志输出源:日志文件

日志解决:logging-agent , 比方 fluentd

日志存储:比方 elasticSearch , kafka

优缺点剖析:

比照 阐明
长处 1 部署简略;2 对宿主机敌对;
毛病 1. 耗费较多的资源;2. 日志通过 kubectl logs 无奈看到

示例:

apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox
    args:
    - /bin/sh
    - -c
    - >
        i=0;
        while true;
        do
          echo "$i:$(data)" >> /var/log/1.log
          echo "$(data) INFO $i" >> /var/log/2.log
           i=$((i+1))
          sleep 1;
        done
    volumeMounts:
    - name: varlog
        mountPath: /var/log
  - name: count-agent
    image: k8s.gcr.io/fluentd-gcp:1.30
    env:
    - name: FLUENTD_ARGS
        value: -c /etc/fluentd-config/fluentd.conf
    valumeMounts:
    - name: varlog
        mountPath: /var/log
    - name: config-volume
        mountPath: /etc/fluentd-config
  volumes:
  - name: varlog
      emptyDir: {}
  - name: config-volume
      configMap:
        name: fluentd-config


Pod 外部通过 sidecar 容器输入到 stdout

实用于利用容器只能把日志输入到文件,无奈输入到 stdout,stderr 中的场景;

通过一个 sidecar 容器,间接读取日志文件,再从新输入到 stdout,stderr 中,

即可应用 Node 上通过日志代理转发的模式;

优缺点剖析:

比照 阐明
长处 只需消耗比拟少的 cpu 和内存,共享 volume 解决效率比拟高
毛病 宿主机上存在两份雷同的日志,磁盘利用率不高

利用容器间接输入日志到日志服务

实用于有成熟日志零碎的场景,日志不须要通过 k8s;

EFK 介绍

fluentd

fluentd 是一个对立日志层的开源数据收集器。

flentd 容许你对立日志收集并更好的应用和了解数据;

四大特色:

对立日志层

fluentd 隔断数据源,从后盾零碎提供对立日志层;

简略灵便
提供了 500 多个插件,连贯十分多的数据源和输入源,内核简略;

宽泛验证
5000 多家数据驱动公司以来 Fluentd
最大的客户通过它收集 5 万多台服务器的日志

** 云原生 **

是云原生 CNCF 的成员我的项目

4 大劣势:

对立 JSON 日志

fluentd 尝试采纳 JSON 结构化数据,这就对立了所有解决日志数据的方面,收集,过滤,缓存,输入日志到多目的地,上行流数据处理应用 Json 更简略,因为它曾经有足够的拜访构造并保留了足够灵便的 scemas;

插件化架构

fluntd 有灵便的插件体系容许社区扩大性能,500 多个社区奉献的插件连贯了很多数据源和目的地;通过插件,你能够开始更好的应用你的日志

最小资源耗费

c 和 ruby 写的,须要极少的系统资源,40M 左右的内存能够解决 13k/ 工夫 / 秒,如果你须要更紧凑的内存,能够应用 Fluent bit , 更轻量的 Fluentd

内核牢靠

Fluentd 反对内存和基于文件缓存,避免外部节点数据失落;
也反对 robust 失败并且能够配置高可用模式,2000 多家数据驱动公司在不同的产品中依赖 Fluentd,更好的应用和了解他们的日志数据 

应用 fluentd 的起因:

简略灵便

10 分钟即可在你的电脑上装置 fluentd,你能够马上下载它,500 多个插件买通数据源和目的地,插件也很好开发和部署;

开源

基于 Apache2.0 证书  齐全开源 

牢靠高性能

5000 多个数据驱动公司的不同产品和服务依赖 fluentd,更好的应用和了解数据,实际上,基于 datadog 的考察,是应用 docker 运行的排行 top7 的技术;

一些 fluentd 用户实时采集上千台机器的数据,每个实例只须要 40M 左右的内存,伸缩的时候,你能够节俭很多内存

社区

fluentd 能够改良软件并帮忙其它人更好的应用

大公司应用背书:微软,亚马逊;pptv ;

能够联合 elasticSearch + kibana 来一起组成日志套件;
疾速搭建 EFK 集群并收集利用的日志,配置性能排行榜;

elasticsearch

Elasticsearch 是一个分布式、RESTful 格调的搜寻和数据分析引擎,

可能解决不断涌现出的各种用例。作为 Elastic Stack 的外围,

它集中存储您的数据,帮忙您发现意料之中以及意料之外的状况。

具体介绍:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html

kibana

Kibana 是一款开源的数据分析和可视化平台,它是 Elastic Stack 成员之一,

设计用于和 Elasticsearch 合作。您能够应用 Kibana 对 Elasticsearch 索引中的数据进行搜寻、

查看、交互操作。您能够很不便的利用图表、表格及地图对数据进行多元化的剖析和出现。

Kibana 能够使大数据通俗易懂。它很简略,

基于浏览器的界面便于您疾速创立和分享动态数据仪表板来追踪 Elasticsearch 的实时数据变动.

具体介绍:https://www.elastic.co/guide/cn/kibana/current/introduction.html

容器化 EFK 实现门路

https://github.com/kayrus/elk-kubernetes

间接拖代码下来,而后配置后 context, namespace , 即可装置;

cd elk-kubernetes

./deploy.sh --watch

上面是 deploy.sh 的脚本,能够简略看一下:

#!/bin/sh

CDIR=$(cd `dirname "$0"` && pwd)
cd "$CDIR"

print_red() {printf '%b' "\033[91m$1\033[0m\n"}

print_green() {printf '%b' "\033[92m$1\033[0m\n"}

render_template() {eval "echo \"$(cat "$1")\""
}


KUBECTL_PARAMS="--context=250091890580014312-cc3174dcd4fc14cf781b6fc422120ebd8"
NAMESPACE=${NAMESPACE:-sm}
KUBECTL="kubectl ${KUBECTL_PARAMS} --namespace=\"${NAMESPACE}\""eval"kubectl ${KUBECTL_PARAMS} create namespace \"${NAMESPACE}\""

#NODES=$(eval "${KUBECTL} get nodes -l'kubernetes.io/role!=master'-o go-template=\"{{range .items}}{{\\\$name := .metadata.name}}{{\\\$unschedulable := .spec.unschedulable}}{{range .status.conditions}}{{if eq .reason \\\"KubeletReady\\\"}}{{if eq .status \\\"True\\\"}}{{if not \\\$unschedulable}}{{\\\$name}}{{\\\"\\\\n\\\"}}{{end}}{{end}}{{end}}{{end}}{{end}}\"")
NODES=$(eval "${KUBECTL} get nodes -l'sm.efk=data'-o go-template=\"{{range .items}}{{\\\$name := .metadata.name}}{{\\\$unschedulable := .spec.unschedulable}}{{range .status.conditions}}{{if eq .reason \\\"KubeletReady\\\"}}{{if eq .status \\\"True\\\"}}{{if not \\\$unschedulable}}{{\\\$name}}{{\\\"\\\\n\\\"}}{{end}}{{end}}{{end}}{{end}}{{end}}\"")
ES_DATA_REPLICAS=$(echo "$NODES" | wc -l)

if ["$ES_DATA_REPLICAS" -lt 3]; then
  print_red "Minimum amount of Elasticsearch data nodes is 3 (in case when you have 1 replica shard), you have ${ES_DATA_REPLICAS} worker nodes"
  print_red "Won't deploy more than one Elasticsearch data pod per node exiting..."
  exit 1
fi

print_green "Labeling nodes which will serve Elasticsearch data pods"
for node in $NODES; do
  eval "${KUBECTL} label node ${node} elasticsearch.data=true --overwrite"
done

for yaml in *.yaml.tmpl; do
  render_template "${yaml}" | eval "${KUBECTL} create -f -"
done

for yaml in *.yaml; do
  eval "${KUBECTL} create -f \"${yaml}\""
done

eval "${KUBECTL} create configmap es-config --from-file=es-config --dry-run -o yaml" | eval "${KUBECTL} apply -f -"
eval "${KUBECTL} create configmap fluentd-config --from-file=docker/fluentd/td-agent.conf --dry-run -o yaml" | eval "${KUBECTL} apply -f -"
eval "${KUBECTL} create configmap kibana-config --from-file=kibana.yml --dry-run -o yaml" | eval "${KUBECTL} apply -f -"

eval "${KUBECTL} get pods $@"

简略合成一下部署的流程:

我的 k8s 环境中没有搭建胜利,后续搭建胜利了再出具体的装置笔记。

小结

一句话概括本篇:EFK 是一种通过日志代理客户端采集利用日志比拟罕用的实现形式。

原创不易,关注诚可贵,转发价更高!转载请注明出处,让咱们互通有无,共同进步,欢送沟通交流。

退出移动版