通过DaemonSet方式采集Kubernetes容器标准输出

重要

本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。

本文介绍如何通过控制台创建iLogtail采集配置,并以DaemonSet采集方式采集容器标准输出。

前提条件

  • 已安装Logtail组件。具体操作,请参见安装Logtail组件(阿里云Kubernetes集群)
  • 在您安装Logtail组件时所使用的Project中已完成Logstore创建。具体操作,请参见创建Logstore
  • 目标容器持续产生日志。
    重要 Logtail只采集增量日志。如果下发Logtail配置后,日志文件无更新,则Logtail不会采集该文件中的日志。更多信息,请参见读取日志

功能特点

Logtail支持采集容器内产生的标准输出,并附加容器的相关元数据信息一起上传到日志服务。Logtail具备以下功能特点。

  • 支持采集标准输出信息(stdout)和标准出错信息(stderr)。

  • 支持通过容器Label白名单指定待采集的容器。

  • 支持通过容器Label黑名单排除不要采集的容器。

  • 支持通过环境变量白名单指定待采集的容器。

  • 支持通过环境变量黑名单排除不要采集的容器。

  • 支持采集多行日志(例如Java Stack日志)。

  • 支持上报容器日志时自动关联Meta信息(例如容器名、镜像、Pod、Namespace、环境变量等)。

  • 当容器运行于Kubernetes时,Logtail还具有以下功能。

    • 支持通过Kubernetes Namespace名称、Pod名称、容器名称指定待采集的容器。

    • 支持通过Kubernetes Label白名单指定待采集的容器。

    • 支持通过Kubernetes Label黑名单排除不要采集的容器。

    • 支持上报容器日志时自动关联Kubernetes Label信息。

实现原理

Logtail与Docker的Domain Socket进行通信,查询该Docker上运行的所有容器,并根据容器中的Label和环境变量定位需要被采集的容器。Logtail通过docker logs命令获取指定容器日志。

Logtail在采集容器的标准输出时,会定期将采集的点位信息保存到checkpoint文件中。如果Logtail停止后再次启动,会从上一次保存的点位开始采集。实现原理

使用限制

  • 此功能目前仅支持Linux操作系统,依赖Logtail 0.16.0及以上版本。版本查看与升级,请参见安装Logtail(Linux系统)

  • Logtail支持Docker和Containerd两种容器引擎的数据采集,访问路径说明如下:

    • Docker:Logtail通过/run/docker.sock访问Docker,请确保该路径存在且具备访问权限。

    • Containerd:Logtail通过/run/containerd/containerd.sock访问Containerd,请确保该路径存在且具备访问权限。

  • 多行日志限制:为保证多行组成的一条日志不因为输出延迟而被分割成多条,多行日志情况下,采集的最后一条日志默认都会缓存一段时间。默认缓存时间为3秒,可通过BeginLineTimeoutMs参数修改,但此值不能低于1000(毫秒),否则容易出现误判。

  • 采集停止策略:当容器被停止后,Logtail监听到容器die的事件后会停止采集该容器的标准输出。如果此时采集出现延迟,则可能丢失停止前的部分输出。

  • Docker容器引擎限制:目前标准输出采集仅支持JSON类型的日志驱动。

  • 上下文限制:默认同一Logtail配置下的所有容器的标准输出处于同一上下文中,即无法使用控制台的上下文查询及Livetail功能直接查看某一容器标准输出的上下文。如果需要使用这些功能,请添加日志上下文聚合插件。更多信息,请参见aggregators配置

  • 数据处理:采集到的数据默认保存在content字段中。Logtail对于采集到的容器标准输出,支持数据处理。更多信息,请参见使用Logtail插件处理数据

创建Logtail采集配置

表单配置方式

登录日志服务控制台快速接入数据区域,单击Kubernetes-标准输出,按照配置向导操作

Logtail设置步骤中,完成如下配置。采集标准输出

重要参数说明如下:

全局配置

配置项

说明

配置名称

Logtail配置名称,在其所属Project内必须唯一。创建Logtail配置成功后,无法修改其名称。

高级参数

其它可选的与配置全局相关的高级功能参数,请参见创建Logtail流水线配置

输入配置

参数

说明

标准输出

选中该选项后,Logtail将采集容器标准输出。

标准错误

选中该选项后,Logtail将采集容器标准错误。

启用容器元信息预览

打开启用容器元信息预览后,您可以在创建Logtail配置后,查看容器元信息,包括匹配容器信息和全量容器信息。

容器过滤

Logtail版本

  • Logtail 1.0.34以下版本,只支持通过环境变量容器Label进行容器过滤。

  • Logtail 1.0.34及以上版本,推荐使用Kubernetes层级的信息(K8s Pod名称正则匹配K8s Namespace正则匹配K8s容器名称正则匹配K8s Pod标签白名单等)进行容器过滤。

过滤条件说明

重要
  • 容器Label为Docker inspect中的Label,不是Kubernetes中的Label。如何获取,请参见获取容器Label

  • 环境变量为容器启动中配置的环境变量信息。如何获取,请参见获取容器环境变量

  1. Kubernetes中的Namespace和容器名称会映射到容器Label中,分别为io.kubernetes.pod.namespaceio.kubernetes.container.name,推荐使用这两个容器Label进行容器过滤。例如,某Pod所属的命名空间为backend-prod,容器名为worker-server,如果您要采集包含该容器的日志,可以设置容器Label白名单为io.kubernetes.pod.namespace : backend-prodio.kubernetes.container.name : worker-server

  2. 如果以上两个容器Label不满足过滤需求,请使用环境变量的黑白名单进行容器过滤。

K8s Pod名称正则匹配

通过Pod名称指定待采集的容器,支持正则匹配。例如设置为^(nginx-log-demo.*)$,,表示匹配以nginx-log-demo开头的Pod下的所有容器。

说明

Logtail 1.0.34及以上版本支持该参数。

K8s Namespace正则匹配

通过Namespace名称指定采集的容器,支持正则匹配。例如设置为^(default|nginx)$,表示匹配nginx命名空间、default命名空间下的所有容器。

说明

Logtail 1.0.34及以上版本支持该参数。

K8s容器名称正则匹配

通过容器名称指定待采集的容器(Kubernetes容器名称是定义在spec.containers中),支持正则匹配。例如设置为^(container-test)$,表示匹配所有名为container-test的容器。

说明

Logtail 1.0.34及以上版本支持该参数。

容器label白名单

容器Label白名单,用于指定待采集的容器。默认为空,表示采集所有容器的标准输出。如果您要设置容器Label白名单,那么LabelKey必填,LabelValue可选填。

  • 如果LabelValue为空,则容器Label中包含LabelKey的容器都匹配。
  • 如果LabelValue不为空,则容器Label中包含LabelKey=LabelValue的容器才匹配。

    LabelValue默认为字符串匹配,即只有LabelValue和容器Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如:配置LabelKeyio.kubernetes.container.name,配置LabelValue^(nginx|cube)$,表示可匹配名为nginx、cube的容器。

多个白名单之间为或关系,即只要容器Label满足任一白名单即可被匹配。

容器label黑名单

容器Label黑名单,用于排除不采集的容器。默认为空,表示不排除任何容器。如果您要设置容器Label黑名单,那么LabelKey必填,LabelValue可选填。

  • 如果LabelValue为空,则容器Label中包含LabelKey的容器都将被排除。
  • 如果LabelValue不为空,则容器Label中包含LabelKey=LabelValue的容器才会被排除。

    LabelValue默认为字符串匹配,即只有LabelValue和容器Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如:设置LabelKeyio.kubernetes.container.name,设置LabelValue^(nginx|cube)$,表示可匹配名为nginx、cube的容器。

多个黑名单之间为或关系,即只要容器Label满足任一黑名单对即可被排除。

环境变量白名单

环境变量白名单,用于指定待采集的容器。默认为空,表示采集所有容器的标准输出。如果您要设置环境变量白名单,那么EnvKey必填,EnvValue可选填。

  • 如果EnvValue为空,则容器环境变量中包含EnvKey的容器都匹配。
  • 如果EnvValue不为空,则容器环境变量中包含EnvKey=EnvValue的容器才匹配。

    EnvValue默认为字符串匹配,即只有EnvValue和环境变量的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配,例如:设置EnvKeyNGINX_SERVICE_PORT,设置EnvValue^(80|6379)$,表示可匹配服务端口为80、6379的容器。

多个白名单之间为或关系,即只要容器的环境变量满足任一键值对即可被匹配。

环境变量黑名单

环境变量黑名单,用于排除不采集的容器。默认为空,表示不排除任何容器。如果您要设置环境变量黑名单,那么EnvKey必填,EnvValue可选填。

  • 如果EnvValue为空,则容器环境变量中包含EnvKey的容器的日志都将被排除。
  • 如果EnvValue不为空,则容器环境变量中包含EnvKey=EnvValue的容器才会被排除。

    EnvValue默认为字符串匹配,即只有EnvValue和环境变量的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配,例如:设置EnvKeyNGINX_SERVICE_PORT,设置EnvValue^(80|6379)$,表示可匹配服务端口为80、6379的容器。

多个黑名单之间为或关系,即只要容器的环境变量满足任一键值对即可被排除。

K8s Pod标签白名单

通过Kubernetes Label白名单指定待采集的容器。如果您要设置Kubernetes Label白名单,那么LabelKey必填,LabelValue可选填。

  • 如果LabelValue为空,则Kubernetes Label中包含LabelKey的容器都匹配。
  • 如果LabelValue不为空,则Kubernetes Label中包含LabelKey=LabelValue的容器才匹配。

    LabelValue默认为字符串匹配,即只有LabelValue和Kubernetes Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如设置LabelKeyapp,设置LabelValue^(test1|test2)$,表示匹配Kubernetes Label中包含app:test1、app:test2的容器。

多个白名单之间为或关系,即只要Kubernetes Label满足任一白名单即可被匹配。

说明
  • Logtail 1.0.34及以上版本支持该参数。

  • 由于在Kubernetes管控类资源(例如Deployment)运行时更改Label,不会重启具体的工作资源Pod,因此Pod无法感知此变更,可能导致匹配规则失效。设置K8s Label黑白名单时,请以Pod中的Kubernetes Label为准。关于Kubernetes Label的更多信息,请参见Labels and Selectors

K8s Pod标签黑名单

通过Kubernetes Label黑名单排除不采集的容器。如果您要设置Kubernetes Label黑名单,那么LabelKey必填,LabelValue可选填。

  • 如果LabelValue为空,则Kubernetes Label中包含LabelKey的容器都被排除。
  • 如果LabelValue不为空,则Kubernetes Label中包含LabelKey=LabelValue的容器才会被排除。

    LabelValue默认为字符串匹配,即只有LabelValue和Kubernetes Label的值完全相同才会匹配。如果该值以^开头并且以$结尾,则为正则匹配。例如设置LabelKeyapp,设置LabelValue^(test1|test2)$,表示匹配Kubernetes Label中包含app:test1、app:test2的容器。

多个黑名单之间为或关系,即只要Kubernetes Label满足任一黑名单对即可被排除。

说明
  • Logtail 1.0.34及以上版本支持该参数。

  • 由于在Kubernetes管控类资源(例如Deployment)运行时更改Label,不会重启具体的工作资源Pod,因此Pod无法感知此变更,可能导致匹配规则失效。设置K8s Label黑白名单时,请以Pod中的Kubernetes Label为准。关于Kubernetes Label的更多信息,请参见Labels and Selectors

日志标签富化

如果您使用的是Logtail 1.0.34及以上版本,您可以将环境变量和Kubernetes Label添加到日志,作为日志标签。

环境变量相关

设置环境变量扩展字段后,日志服务将在日志中新增环境变量相关字段。例如设置环境变量名VERSION,设置tag名env_version,当容器中包含环境变量VERSION=v1.0.0时,会将该信息添加到日志中,即添加字段__tag__:__env_version__: v1.0.0

Pod标签相关

设置Kubernetes Pod扩展字段后,日志服务将在日志中新增Kubernetes Pod相关字段。例如设置Pod标签名app,设置tag名k8s_pod_app,当Kubernetes中包含Labelapp=serviceA时,会将该信息添加到日志中,即添加字段__tag__:__k8s_pod_app__: serviceA

日志最大长度(字节)

日志最大长度,默认值为524288字节。取值范围为[1024, 20971520],单位:字节。

如果日志长度超过该值,则不再继续查找行首,直接上传。

首次采集回溯历史数据长度(字节)

首次采集时回溯历史数据长度,默认值为131072字节(128 KB)。建议取值范围为[131072,1048576],单位:字节。

高级参数

Logtail配置的部分参数需要手动输入,请参见创建Logtail流水线配置

处理配置

配置项

说明

多行模式

行首正则表达式

Logtail通过行首正则表达式去匹配一条日志的行首,如果匹配成功,则将该行作为一条新的日志,否则将此行拼接到上一条日志。

行首正则匹配长度(字节)

行首匹配的长度,默认值为10240字节。

如果行首匹配的正则表达式在前N个字节即可体现,推荐设置此参数,提升行首匹配效率。

行首匹配超时时间(毫秒)

行首匹配的超时时间,默认值为3000毫秒。

如果3000毫秒内没有出现新日志,则结束匹配,将最后一条日志上传到日志服务。

说明

如果日志为多行日志,请使用该选项。

处理模式

处理插件支持拓展插件。有关处理插件的更多信息,请参见处理插件概述

CRD-AliyunPipelineConfig(推荐)

警告

如果使用AliyunPipelineConfig,需要日志组件版本最低为0.5.1。

您只需要创建AliyunPipelineConfig CR即可创建iLogtail采集配置。创建完成后,系统自动应用该iLogtail采集配置

  1. 获取集群KubeConfig并通过kubectl工具连接集群

  2. 执行如下命令创建一个YAML文件。

    cube.yaml为文件名,请根据实际情况替换。

    vim cube.yaml
  3. 在YAML文件中输入如下脚本,并根据实际情况设置其中的参数。

    重要

    多行模式采集指定容器的标准输出

    创建名为example-k8s-stdout的iLogtail采集配置,对于集群内名称包含app的所有容器,以多行模式采集标准输出,直接发送到名称为k8s-stdout的Logstore,该Logstore属于名称为k8s-log-clusterid的Project。

    apiVersion: telemetry.alibabacloud.com/v1alpha1
    # 创建一个 ClusterAliyunPipelineConfig
    kind: ClusterAliyunPipelineConfig
    metadata:
      # 设置资源名,在当前Kubernetes集群内唯一。该名称也是创建出的iLogtail采集配置名
      name: example-k8s-stdout
    spec:
      # 指定目标project
      project:
        name: k8s-log-clusterid
      # 创建用于存储日志的 Logstore
      logstores:
        - name: k8s-stdout
      # 定义iLogtail采集配置
      config:
        # 日志样例(可不填写)
        sample: |
          2024-06-19 16:35:00 INFO test log
          line-1
          line-2
          end
        # 定义输入插件
        inputs:
          # 使用service_docker_stdout插件采集容器内文本日志
          - Type: service_docker_stdout
            Stdout: true
            Stderr: true
            # 配置容器信息过滤条件,多个选项之间为“且”的关系。
            # 指定待采集容器所在 Pod 所属的命名空间,支持正则匹配。
            K8sNamespaceRegex: "^(default)$"
            # 指定待采集容器的名称,支持正则匹配。
            K8sContainerRegex: "^(.*app.*)$"
            # 配置多行切分配置
            # 配置行首正则表达式
            BeginLineRegex: \d+-\d+-\d+.*
        # 定义输出插件
        flushers:
          # 使用flusher_sls插件输出到指定Logstore。
          - Type: flusher_sls
            Logstore: k8s-stdout
            Endpoint: cn-hangzhou.log.aliyuncs.com
            Region: cn-hangzhou
            TelemetryType: logs
  4. 执行如下命令使iLogtail采集配置生效。iLogtail采集配置生效后,Logtail开始采集各个容器上的标准输出,并发送到日志服务中。

    cube.yaml为文件名,请根据实际情况替换。

    kubectl apply -f cube.yaml
    重要

    采集到日志后,您需要先创建索引,才能在Logstore中查询和分析日志。具体操作,请参见创建索引

CRD-AliyunLogConfig

您只需要创建AliyunLogConfig CR即可创建iLogtail采集配置。创建完成后,系统自动应用该iLogtail采集配置。

  1. 获取集群KubeConfig并通过kubectl工具连接集群

  2. 执行如下命令创建一个YAML文件。cube.yaml为文件名,请根据实际情况替换。

    vim cube.yaml
  3. 在YAML文件中输入如下脚本,并根据实际情况设置其中的参数。

    重要
    • 请确保configName字段值在安装Logtail组件的Project中唯一。

    • 如果多个CR关联同一个iLogtail采集配置,则删除或修改任意一个CR均会影响到该iLogtail采集配置,导致其他关联该iLogtail采集配置的CR状态与日志服务中iLogtail采集配置的状态不一致。

    • CR字段的格式请参见使用AliyunLogConfig管理采集配置。本文的iLogtail采集配置样例包含基础的标准输出采集功能,具体参数参见CreateConfig - 创建Logtail采集配置

    单行模式采集指定容器的标准输出

    创建名为example-stdout-example的Logtail采集配置,以单行文本模式采集集群内所有名称开头为app的Pod的容器内的标准输出,直接发送到名称为k8s-stdout的Logstore,该Logstore属于名称为k8s-log-clusterid的Project。

    # 标准输出配置
    apiVersion: log.alibabacloud.com/v1alpha1
    kind: AliyunLogConfig
    metadata:
      # 设置资源名,在当前Kubernetes集群内唯一。
      name: simple-stdout-example
    spec:
      # 设置Logstore名称。如果您所指定的Logstore不存在,日志服务会自动创建。
      logstore: k8s-stdout
      # 设置Logtail采集配置。
      logtailConfig:
        # 设置采集的数据源类型。采集标准输出时,需设置为plugin。
        inputType: plugin
        # 设置Logtail采集配置的名称,必须与资源名(metadata.name)相同。
        configName: simple-stdout-example
        inputDetail:
          plugin:
            inputs:
              -
                # input type
                type: service_docker_stdout
                detail:
                  # 指定采集stdout和stderr。
                  Stdout: true
                  Stderr: true
                  K8sPodRegex: "^(app.*)$"
  4. 执行如下命令使iLogtail采集配置生效。iLogtail采集配置生效后,Logtail开始采集各个容器上的标准输出,并发送到日志服务中。

    cube.yaml为文件名,请根据实际情况替换。

    kubectl apply -f cube.yaml
    重要

    采集到日志后,您需要先创建索引,才能在Logstore中查询和分析日志。具体操作,请参见创建索引

预览容器元信息

创建Logtail配置后,您可以在Logtail配置页面查看容器元信息以及容器未匹配过滤条件的原因。

重要

仅Linux Logtail 1.4.0及以上版本或Windows Logtail 1.4.0.0及以上版本支持该功能。

  1. 登录日志服务控制台

  2. 在Project列表中,单击目标Project。

    此处需选择您在创建Logtail配置所使用的Project。

  3. 日志存储 > 日志库页签中,单击目标Logstore左侧的>,然后选择数据接入 > Logtail配置

    此处需选择您在创建Logtail配置所使用的Logstore。

  4. 在Logtail配置列表中,单击目标Logtail配置。

  5. Logtail配置页面中,单击编辑

  6. 打开启用容器元信息预览开关。

  7. 单击容器元信息预览

  8. 容器预览对话框中,查看容器的元信息。

    • 匹配容器页签中展示匹配您所设置的过滤条件的容器的元信息。

    • 全量容器页签中展示当前Kubernetes集群中所有容器的元信息以及容器未匹配过滤条件的原因。

日志字段

Kubernetes集群的每条日志默认上传的字段如下所示。

字段名称

说明

_time_

日志采集时间,例如2021-02-02T02:18:41.979147844Z

_source_

日志源类型,stdout或stderr。

_image_name_

镜像名

_container_name_

容器名

_pod_name_

Pod名

_namespace_

Pod所在的命名空间

_pod_uid_

Pod的唯一标识

问题排查

当您使用Logtail采集容器(标准容器、Kubernetes)日志遇到异常情况时,您可以参见如下内容进行排查。