首页 > 解决方案 > 使用持久注册表文件在 Kubernetes 中运行 Filebeat?

问题描述

如果运行 filebeat 的容器丢失,而我们启动了一个新容器,旧容器的注册表文件也会丢失,新容器将不知道收割机应该从哪里读取新文件,这将导致不一致/不明确的数据弹性搜索。它将再次读取整个文件。那么,我应该如何创建一致的注册表文件呢?

我还应该挂载/var/lib/filebeat/到一些持久卷吗?

现在,我正在考虑 Kubernetes(AWS EKS)上下文。我有一个持久卷(AWS EFS)。我pvc为每个应用程序创建了一个(持久卷声明),比如说app1-pvcapp1。这pvc安装/var/log/app1/在应用程序和 filebeat 容器上的位置。Filebeat 正在从文件中读取输入/var/log/app1/api_info.log。因此,如果我的 filebeat 容器重新启动,注册表文件将丢失,并且将再次读取整个 api_info。

我的想法是否正确?如果是,那么有什么方法可以避免我在这里面临的情况?如果不是,它如何防止上述情况发生?还是我想错了?

标签: dockerkubernetesfilebeatpersistent-storage

解决方案


如今,kubernetes 中最直接的方法可能是使用ECK 运算符和对 filebeat 的原生BeatCRD 支持。截至今天,您可以在此处的官方文档中找到示例。

部署时,例如:

apiVersion: beat.k8s.elastic.co/v1beta1
kind: Beat
metadata:
  name: filebeat
spec:
  type: filebeat
  version: 7.16.2
  ...
  daemonSet:
    podTemplate:
      spec:
        serviceAccountName: filebeat
        ...
        containers:
          - name: filebeat
          ...

filebeat 将被部署为 aDaemonSet并且默认情况下将使用主机目录来存放状态文件,因此它将在重新启动之间继续存在。

正如您在 ECK 控制器的当前实现中所看到的,它将在下面创建一个主机卷/var/lib/<beat-namespace>/<beat-name>/<beat-type>-data

    DataMountPathTemplate = "/var/lib/%s/%s/%s-data"
...
func createDataVolume(dp DriverParams) volume.VolumeLike {
    dataMountPath := fmt.Sprintf(DataPathTemplate, dp.Beat.Spec.Type)
    hostDataPath := fmt.Sprintf(DataMountPathTemplate, dp.Beat.Namespace, dp.Beat.Name, dp.Beat.Spec.Type)

    return volume.NewHostVolume(
        DataVolumeName,
        hostDataPath,
        dataMountPath,
        false,
        corev1.HostPathDirectoryOrCreate)
}

就我而言,我elastic-system使用 k3s 将所有 ECK 资源存储在命名空间中,这些文件最终以存储在 host directory 中的状态文件结束/var/lib/elastic-system/filebeat/filebeat-data/


推荐阅读