对于 K8S 内的容器日志收集,业内一般有两种常用的方式:

  • 使用 DaemonSet 在每台 Node 上部署一个日志收集容器,用于收集当前 Node 上所有容器挂载到宿主机目录下的日志
  • 使用 SideCar 模式将日志收集容器与业务容器部署在同一个 Pod 中,只收集对应容器的日志

这两种方式各有优缺点。使用 DaemonSet 方式部署日志收集服务,管理起来简单,但是如果一个 Node 中运行了过多的 Pod,那么日志收集会存在性能瓶颈。使用 SideCar 模式可以更有针对性的收集容器的日志,但是缺点是在运行了很多的业务时,SideCar 占用的资源也会增加。同时这种方式也会出现跟业务耦合的问题。

在我们实践 K8S 的过程中,结合当前业务的特点,最终选定了 SideCar 的方式,虽然占用的资源会增加,但是基于后期大规模日志收集稳定性的考虑,这些资源消耗是在承受范围之内的。

而日志收集的组件,经过长时间比对各种开源服务,选择了 Filebeat。一个是因为在业务未上容器之前,就是使用的 Filebeat 来收集的日志,在维护方面有很多的经验。还有就是 Filebeat 可以处理一些日志收集中出现的复杂情况,例如对于多行日志的处理(堆栈日志)。

下面对于整个实施步骤进行说明。

一、创建命名空间

首先创建一个命名空间,yaml 文件内容如下:

---
apiVersion: v1
kind: Namespace
metadata:
name: ns-smc-gateway
labels:
name: ns-smc-gateway

二、创建 Filebeat 配置文件

由于是使用容器的方式运行 FIlebeat,所以需要使用 Configmap 创建一个 Filebeat 的配置文件,然后通过卷挂载的方式挂载到 Filebeat 容器的指定目录下。

创建 Configmap 的 yaml 文件内容如下(注意命名空间的配置,否则后面 Filebeat 无法挂载 Configmap,如果对于下面的配置有不清楚的地方,可以参考我的另一片博文:Filebeat根据不同的日志设置不同的索引):

---
apiVersion: v1
kind: ConfigMap
metadata:
name: filebeat-config
namespace: ns-smc-gateway
labels:
k8s-app: filebeat
data:
filebeat.yml: |-
filebeat.idle_timeout: 2s
filebeat.inputs:
- type: log
paths:
- /opt/logs/app.log
fields:
type: app-log
enabled: true
backoff: 1s
backoff_factor: 2
close_inactive: 1h
encoding: plain
harvester_buffer_size: 262144
max_backoff: 10s
max_bytes: 10485760
scan_frequency: 10s
tail_lines: true
- type: log
paths:
- /opt/logs/app.err
fields:
type: app-err-log
enabled: true
backoff: 1s
backoff_factor: 2
close_inactive: 1h
encoding: plain
harvester_buffer_size: 262144
max_backoff: 10s
max_bytes: 10485760
scan_frequency: 10s
tail_lines: true filebeat.name: filebeat-shiper
filebeat.spool_zie: 50000
output.elasticsearch:
bulk_max_size: 8192
hosts:
- 10.16.12.206:30187
- 10.16.12.207:30187
- 10.16.12.208:30187
- 10.16.13.214:30187
- 10.16.13.215:30187
index: smc-gateway-%{[fields.type]}-*
indices:
- index: smc-gateway-app-log-%{+yyyy.MM.dd}
when.equals:
fields.type: app-log
- index: smc-gateway-app-err-log-%{+yyyy.MM.dd}
when.equals:
fields.type: app-err-log
workers: 4
processors:
- drop_fields:
fields:
- agent.ephemeral_id
- agent.hostname
- agent.id
- agent.type
- agent.version
- ecs.version
- input.type
- log.offset
- version
- decode_json_fields:
fields:
- message
max_depth: 1
overwrite_keys: true
setup.ilm.enabled: false
setup.template.name: smc-gateway-log
setup.template.pattern: smc-gateway-*
setup.template.overwrite: true
setup.template.enabled: true

三、创建 Deployment

接下来使用 Deployment 控制器来部署 Pod,这个 Pod 中包含了业务容器和 Filebeat 服务容器。yaml 文件内容如下:

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: smc-gateway
namespace: ns-smc-gateway
labels:
app: smc-gateway
spec:
replicas: 1
selector:
matchLabels:
app: smc-gateway
template:
metadata:
name: smc-gateway
labels:
app: smc-gateway
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: smc-gateway-for-test # 业务容器的名称
image: 10.16.12.204/smc-gateway/smc-gateway:1.1 # 业务容器镜像的私服下载地址
imagePullPolicy: Always
env: # 需要传入到业务容器中的环境变量,在服务启动的时候调用
- name: data_center
value: bx
- name: server_mode
value: test
volumeMounts: # 指定业务日志在容器中输出的目录
- name: logdata
mountPath: /opt/logs - name: filebeat-for-smc-gateway # 指定 Filebeat 容器的名称
image: docker.elastic.co/beats/filebeat:7.3.0 # filebeat 镜像下载地址,这里使用的官方镜像仓库
args: [ # 指定服务启动时的参数
"-c", "/opt/filebeat/filebeat.yml", # 注意这里,文件的路径和名称要和 Configmap 传入的路径和名称一致
"-e",
]
env:
- name: POD_IP # 这里是将 pod 的 IP 地址赋值给这个变量传入容器中,便于后面 Filebeat 在日志中添加自定义的字段信息
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: pod_name # 这里是将 pod 的名称赋值给这个变量,便于后面 Filebeat 在日志中添加自定义的字段信息
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
securityContext: # 这里用于设置 Pod 的安全上下文
runAsUser: 0 # 指定容器内的服务以 ID 为 0 的用户运行(也就是root)
volumeMounts:
- name: config # 指定 filebeat 配置文件要挂载的路径
mountPath: /opt/filebeat/
- name: logdata # 指定卷的名称,这个名称要和前面业务容器指定的日志路径的卷名称一致,这样后面才会挂载同一个 emptyDir
mountPath: /opt/logs/ # 指定要将业务的日志挂载在 filebeat 容器中的路径,这个路径要和 Configmap 中指定的日志路径一致
volumes:
- name: logdata # 为前面声明名称为 logdata 的卷挂载一个 emptyDir 卷(filebeat 和业务容器都会挂载这个卷)
emptyDir: {}
- name: config # 为前面声明名称为 config 的卷(filebeat 配置文件)挂载一个 configmap,并指定configmap 的名称
configMap:
name: filebeat-config
items:
- key: filebeat.yml
path: filebeat.yml

需要注意的是,使用 SideCar 模式收集容器日志实现的本质,就是将业务容器内的日志路径存储到本地宿主机的一个目录下,然后这个目录也会同时挂载到日志收集服务容器中,这样日志收集服务才可以读取到业务的日志。

所以上面的 yaml 文件中,首先业务容器的日志目录声明为一个卷,并命名为 logdata。而下面的 Filebeat 容器中也声明了一个 logdata 的卷。由于这两个卷名称一样,所以这两个卷挂载是同一个 emptyDir。也就实现了在 Filebeat 容器中读取业务日志的目的。当然使用 emptyDir 将容器中的日志存储到宿主机本地并不是持久化存储,emptyDir 会随着容器的删除而销毁。

四、创建 Service

将业务容器的 8080 端口暴露出去,yaml 文件内容如下:

---
apiVersion: v1
kind: Service
metadata:
name: smc-service
labels:
app: smc-service
namespace: ns-smc-gateway
spec:
ports:
- port: 8080
targetPort: 8080
nodePort: 30378
selector:
app: smc-gateway
type: NodePort

五、验证

将以上 yaml 文件执行后,会在 ns-smc-gateway 命名空间下创建一个 Pod,这个 Pod 中包含两个容器。

[@k8s-master2 ~]# kubectl get pods -n ns-smc-gateway
NAME READY STATUS RESTARTS AGE
smc-gateway-fcf598c4b-wphhr 2/2 Running 0 150m [@k8s-master2 ~]# kubectl describe pod smc-gateway-fcf598c4b-wphhr -n ns-smc-gateway | grep -B1 "Container ID"
smc-gateway-for-test:
Container ID: docker://3711e3a5bc8fafc94ea174578c0a79774f5b25c7eae6c7aa47759e513645f221
--
filebeat-for-smc-gateway:
Container ID: docker://1b87242cdf8632edc1bea2fe23910f68c2d5da0254163b123bfc414829f7bea7

此时到 Kibana 中的索引管理中,会看到已经新增了两个业务索引,配置对应的索引模式后,就可以在 Kibana 中看到对应的日志。

K8S 使用 SideCar 模式部署 Filebeat 收集容器日志的更多相关文章

  1. Kubernetes部署ELK并使用Filebeat收集容器日志

    本文的试验环境为CentOS 7.3,Kubernetes集群为1.11.2,安装步骤参见kubeadm安装kubernetes V1.11.1 集群 1. 环境准备 Elasticsearch运行时 ...

  2. ELK日志分析系统(2)-logspout收集容器日志

    1. 概述 安装了ELK之后,就是要考虑怎么获取log数据了. 收集log数据的方式有很多种: 1). beats采集数据发布到logstash 2). Filebeat采集数据发布到logstash ...

  3. ELK学习实验018:filebeat收集docker日志

    Filebeat收集Docker日志 1 安装docker [root@node4 ~]# yum install -y yum-utils device-mapper-persistent-data ...

  4. ELK学习实验016:filebeat收集tomcat日志

    filebeat收集tomcat日志 1 安装tomcat [root@node4 ~]# yum -y install tomcat tomcat-webapps tomcat-admin-weba ...

  5. Docker 部署 ELK 收集 Nginx 日志

    一.简介 1.核心组成 ELK由Elasticsearch.Logstash和Kibana三部分组件组成: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引 ...

  6. 用elk+filebeat监控容器日志

    elk  为 elasticsearch(查询搜索引擎),logstash(对日志进行分析和过滤,然后转发给elasticsearch),kibana(一个web图形界面用于可视化elasticsea ...

  7. ELASTIC 5.2部署并收集nginx日志

    elastic 5.2集群安装笔记   设计架构如下: nginx_json_log ->filebeat ->logstash ->elasticsearch ->kiban ...

  8. ELK之filebeat收集多类型日志

    1.IP规划 10.0.0.33:filebeat+tomcat,filebeat收集系统日志.tomcat日志发送到logstash 10.0.0.32:logstash,将日志写入reids(in ...

  9. ELK学习实验017:filebeat收集java日志

    收集JAVA格式日志 1 查看Java格式日志 elasticsearch属于Java日志,可以收集elasticsearch作为Java日志范本 [root@node3 ~]# tail -f /u ...

随机推荐

  1. [GXYCTF2019]禁止套娃 1 &无参数RCE

    [GXYCTF2019]禁止套娃 1 啥都没有那只能上扫描器来一探究竟了. 扫完没有啥结果,但网上找了一下说是git泄露,但是我这里显示了403. <?php include "fla ...

  2. 基础篇:详解锁原理,volatile+cas、synchronized的底层实现

    目录 1 锁的分类 2 synchronized底层原理 3 Object的wait和notify方法原理 4 jvm对synchronized的优化 5 CAS的底层原理 6 CAS同步操作的问题 ...

  3. java内存屏障

    为什么会有内存屏障 每个CPU都会有自己的缓存(有的甚至L1,L2,L3),缓存的目的就是为了提高性能,避免每次都要向内存取.但是这样的弊端也很明显:不能实时的和内存发生信息交换,分在不同CPU执行的 ...

  4. @Autowired,@Resource,@Qualifier,@Primary,@Inject的作用和区别

    @Autowired注解的用法:可以用于构造器,方法,参数,字段进行属性注入,有一个required属性,默认是true,当改成false时,如果注入的属性在容器中不存在也不会报错@Resource该 ...

  5. Python-函数式编程-map reduce filter lambda 三元表达式 闭包

    lambda 匿名函数,核心是作为算子,处理逻辑只有一行但具有函数的特性,核心用于函数式编程中 三元运算符 其实本质上是if分支的简化版,满足条件返回 if 前面的值,不满足条件返回 else后面的值 ...

  6. 015 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 09 Unicode编码

    015 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 09 Unicode编码 本文知识点:Unicode编码以及字符如何表示? ASCII码是美国提出的标准信息 ...

  7. Windows下安装VScode,并使用,以及中文配置

    转载:https://blog.csdn.net/x15011238662/article/details/85094006 首先明确一点,VScode是开发Go应用的基础编辑器,是Microsoft ...

  8. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

  9. vue : 无法加载文件 C:\Users\Lenovo\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。

    第一步:用管理员身份打开 第二步:执行:set-ExecutionPolicy RemoteSigned 选择Y或A,回车

  10. ubuntu19.10 系统需要安装的软件

    将ubuntu18 升级到ubuntu19 期间好几次卡在启动界面,比较担心要不要重装系统,有幸后来正常了.明显感觉操作快了不少.下半年稳定版就出来,到时候免不了再折腾一番,提前把安全记录做好. 下面 ...