K8S Fluentd Mongo日志采集

K8S Fluentd Mongo日志采集

项目最近需要对K8S集群的容器日志进行统计采集,再汇聚起来持久化。最近比较火的开源日志方案是EFK(Elasticsearch、Fluentd、Kibana),目前项目只需要采集、存储,所以仅对接Fluentd,没有上E和K。

最终确定的日志方案是Fluentd+MongoDB。

Fluentd踩坑

在K8S源代码k8s.io\kubernetes\cluster\addons\fluentd-elasticsearch中有EFK的配置文件,由于我们只需要Fluentd,所以只需要关注fluentd-es-configmap.yamlfluentd-es-ds.yaml

fluentd-es-configmap.yaml

fluentd-es-configmap.yaml就是Fluentd的配置文件,官方比较复杂,根据我们自己的需求,只需要采集容器日志,所有只需要/var/log/containers/*.log,其他source都可以删除。

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

output

存储方案采用Mongo,参考mongo。这里需要安装Mongo插件,由于我们这里讲flunetd容器化,所以不太好安装插件,在docker hub找了全插件的fluentd容器docker pull theasp/fluentd-plugins

    <match **>
      @type mongo
      database k8s
      collection containers
      host mongo.mind-automl
      port 27017
      <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-ds.yaml

fluentd-ds.yaml是运行Fluentd damonset的配置文件,基本不需要修改,可能需要修改imageenv

pos_file

运行Fluentd失败,通过日志发现是pos_file没权限写。先把文件夹权限变成777,然后发现每个node上的pos_file文件权限很诡异,每个node上文件的用户和用户组都不一样。通过id命令发现uid都是1000,这个问题遗留。

log不可读

Fluentd成功运行了,并且已经写入mongo,但是发现读不了容器的日志文件。

容器日志

-rw-r-----+ 1 root root  140 Sep 20 05:17 fd12af59e3c534aae556738ded6e412ebfb23933824b004982513177ef9411bd-json.log

只有root用户可读,结合上面pos_file问题,应该是权限问题。通过阅读fluentd容器的Dockerfile,发现问题应该出在启动脚本上。

Dockerfile

# AUTOMATICALLY GENERATED
# DO NOT EDIT THIS FILE DIRECTLY, USE /Dockerfile.template.erb

FROM alpine:3.7
LABEL maintainer "TAGOMORI Satoshi <tagomoris@gmail.com>"
LABEL Description="Fluentd docker image" Vendor="Fluent Organization" Version="1.1"
ENV DUMB_INIT_VERSION=1.2.0

ENV SU_EXEC_VERSION=0.2

ARG DEBIAN_FRONTEND=noninteractive
# Do not split this into multiple RUN!
# Docker creates a layer for every RUN-Statement
# therefore an 'apk delete' has no effect
RUN apk update \
 && apk upgrade \
 && apk add --no-cache \
        ca-certificates \
        ruby ruby-irb \
        su-exec==${SU_EXEC_VERSION}-r0 \
        dumb-init==${DUMB_INIT_VERSION}-r0 \
 && apk add --no-cache --virtual .build-deps \
        build-base \
        ruby-dev wget gnupg \
 && update-ca-certificates \
 && echo 'gem: --no-document' >> /etc/gemrc \
 && gem install oj -v 2.18.3 \
 && gem install json -v 2.1.0 \
 && gem install fluentd -v 0.12.43 \
 && apk del .build-deps \
 && rm -rf /var/cache/apk/* \
 && rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem

# for log storage (maybe shared with host)
RUN mkdir -p /fluentd/log
# configuration/plugins path (default: copied from .)
RUN mkdir -p /fluentd/etc /fluentd/plugins

COPY fluent.conf /fluentd/etc/
COPY entrypoint.sh /bin/
RUN chmod +x /bin/entrypoint.sh


ENV FLUENTD_OPT=""
ENV FLUENTD_CONF="fluent.conf"

ENV LD_PRELOAD=""
ENV DUMB_INIT_SETSID 0
EXPOSE 24224 5140

ENTRYPOINT ["/bin/entrypoint.sh"]

CMD exec fluentd -c /fluentd/etc/${FLUENTD_CONF} -p /fluentd/plugins $FLUENTD_OPT

/bin/entrypoint.sh

#!/usr/bin/dumb-init /bin/sh

uid=${FLUENT_UID:-1000}

# check if a old fluent user exists and delete it
cat /etc/passwd | grep fluent
if [ $? -eq 0 ]; then
    deluser fluent
fi

# (re)add the fluent user with $FLUENT_UID
useradd -u ${uid} -o -c "" -m fluent
export HOME=/home/fluent

# source vars if file exists
DEFAULT=/etc/default/fluentd

if [ -r $DEFAULT ]; then
    set -o allexport
    source $DEFAULT
    set +o allexport
fi

chown home and data folder
chown -R fluent /home/fluent
chown -R fluent /fluentd

exec gosu fluent "$@"

很明显,fluentd容器创建了uid 1000的fluent用户,导致了一系列的权限问题。

解决之道

找到问题原因,解决方案有两个,一个是让1000用户有权限读容器日志,另一个是修改容器启动脚本。第一个方案需要改所有node,比较繁琐,所以采用第二种方法。

第二种方法直接暴力将脚本关于权限命令全部注释

#!/usr/bin/dumb-init /bin/sh

uid=${FLUENT_UID:-1000}

# check if a old fluent user exists and delete it
cat /etc/passwd | grep fluent
if [ $? -eq 0 ]; then
    deluser fluent
fi

# (re)add the fluent user with $FLUENT_UID
# useradd -u ${uid} -o -c "" -m fluent
export HOME=/home/fluent

#source vars if file exists
DEFAULT=/etc/default/fluentd

if [ -r $DEFAULT ]; then
    set -o allexport
    source $DEFAULT
    set +o allexport
fi

# chown home and data folder
# chown -R fluent /home/fluent
# chown -R fluent /fluentd

# exec gosu fluent "$@"
exec "$@"

修改好之后,重新commit新的容器镜像,经测试发现,可以用了。很棒。

fluent-plugin-k8s

虽然fluentd可以读取容器日志,并且存储到mongo里面了,但是日志内容不符合

{"log":"[info:2016-02-16T16:04:05.930-08:00] Some log text here\n","stream":"stdout","time":"2016-02-17T00:04:05.931087621Z"}

问题:

  1. 没有k8s相关信息;
  2. 由于采用tail,所以每次只读一行,根本无法聚合成完整的log文件。

想了很多方法,都没办法解决上面的问题(之前没接触过fluentd),只能回到原点,重头看k8s.io\kubernetes\cluster\addons\fluentd-elasticsearch\fluentd-es-configmap.yaml(大赞老外的注释),由于之前我觉得这个配置文件内容太多,没必要,所以只截取了自己需要的部分。

fluentd-es-configmap.yaml上面大段的注释中,详细说道了我的问题,普通的json信息都非常缺失,所以K8S提供了Kubernetes fluentd plugin解决这个问题,大赞。参考fluent-plugin-kubernetes_metadata_filter

kind: ConfigMap
apiVersion: v1
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    addonmanager.kubernetes.io/mode: Reconcile
data:
  k8s.conf: |-
    <source>
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/fluentd/fluentd-docker.pos
      time_format %Y-%m-%dT%H:%M:%S
      tag kubernetes.*
      format json
      read_from_head true
    </source>

    <filter kubernetes.var.log.containers.**.log>
      @type kubernetes_metadata
      ca_file /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file /var/run/secrets/kubernetes.io/serviceaccount/token
    </filter>

    <match **>
      @type mongo
      database k8s
      collection containers
      host mongo.mind-automl
      port 27017
      <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>

最终配置如上,这里采用serviceaccount访问K8S集群,所以需要配置ca_file以及bearer_token_file,对serviceaccount不清楚的同学,可以参考之前的文章Pod内进程访问k8s服务

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270