K8S 使用 SideCar 模式部署 Filebeat 收集容器日志
luenmicro · 637浏览 · 发布于2020-10-30 +关注

对于 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 中看到对应的日志。

相关推荐

KVM 虚拟机的热迁移

luenmicro · 12669浏览 · 2019-04-29 14:35:39
OpenStack入门科普

luenmicro · 1714浏览 · 2019-04-29 14:50:36
单云和多云的安全风险对比

冷月葬花魂 · 501浏览 · 2019-05-10 15:02:02
加载中

0评论

评论
本人有多年的互联网工作经验,专注技术研发,运维工作等。
分类专栏
小鸟云服务器
扫码进入手机网页