Skip to content

K8s 挂载 PVC 日志采集“轻量级”玩法

本文介绍一种使用 K8s 挂载 PVC 日志采集时的轻量级部署方式。

目标读者

数字化系统开发运维(DevOps)工程师、稳定性工程师(SRE)、可观测平台运维人员等。

使用场景

随着 K8s 和云的普及,越来越多的公司将业务系统部署到云上,并且使用 K8s 来部署应用。日志采集是 K8s 应用中非常重要的运维工具,日志服务提供了Daemonset 和 Sidecar 两种针对 K8s 的采集方式,对于 K8s 应用的日志采集提供了极大的便捷性。当日志目录挂载 PVC 时,可以使用Sidecar 方式共享数据卷的方式采集,这种方式需要每个业务容器伴随一个 logtail 容器,具有非常高的采集性能,另一方面也需要更多的资源开销。 本文提供一种相对 Sidecar 部署更轻量级的采集方式,只需要部署少量的 Logtail 容器,即可采集不同业务容器的日志。主要场景如下:

场景 1:业务容器用 PVC 挂载日志目录

K8s 的 CSI 插件支持用户可以指定多种存储服务,很多用户也选择用 PVC 的方式挂载日志目录,在这种方式下 Daemonset 的采集方式不适合(Daemonset 默认通过采集容器映射到宿主机的目录来采集日志);

业务 pod 由于各种原因崩溃的时候,如果业务容器的日志没有保存在持久化的存储上,可能会有日志的丢失,使用 PVC 将业务容器的日志目录挂载在持久化存储比如网盘中,这样可以保证业务容器的日志最大限度的保存。

场景 2:Logtail 容器使用 PVC 挂载 checkpoint 目录

对于 Node 宕机的情况,业务容器的日志和 Logtail 的本身的 checkpoint 信息如果都是保存在宿主机的文件系统,可能也会造成一定程度的丢失。这时除了将业务容器的日志使用 PVC 挂载,也可以将 Logtail 的持久化目录进行 PVC 挂载,保证 Checkpoint 的持久化。

相关概念

Logtail

Logtail 是日志服务提供的日志采集 Agent,用于采集阿里云 ECS、自建 IDC、其他云厂商等服务器上的日志。本文介绍 Logtail 的功能、优势、使用限制及配置流程等信息。

PVC

全称:PersistentVolumeClaim,PersistentVolumes 是用户在不知道特定云环境的细节的情况下,实现持久化存储的一种方式。使得开发人员可以不需要关心背后存储的情况下,直接指定相应的存储需求。PVC 与 PV 的关系类似接口与实现的关系。

方案架构

本方案主要通过业务容器和 Logtail 容器共享同样的 PVC 来实现日志采集,同时一定程度上避免了 Sidecar 的开销。 image.png

方案优势

通过将业务容器的日志目录通过 PVC 的方式挂载到持久化的网盘或者 NAS 中,这样可以最大程度的保证无论是 Pod 崩溃还是 Node(物理机节点或者虚拟机节点)崩溃的情况下,日志得以持久化到网盘或者 NAS 中;同时 Logtail 的持久化配置也可以借助 NAS 来进行持久化保存,以保证采集过程中的日志的连续性。

其中 Logtail 持久化方案可以参考《K8s 采集专题-稳定性:iLogtail 容器重启数据可靠性探讨》

方案实施

前提条件

开通阿里云日志服务,并创建相应的 Project,Logstore。 K8s 集群已创建对应 NAS 存储卷的 PVC,具体操作可以参考容器服务 Kubernetes 集群中使用阿里云 NAS 存储卷。

操作步骤

以下步骤中假设已经创建好的资源如下: > 日志服务,已创建好的北京地域的 Project 和 Logstore > PVC 名称为:nas-pvc > 业务容器模拟日志输出到文件

步骤一:创建业务容器并将日志目录挂载 PVC

创建业务 pod,yaml 为内容如下,其中 volumeMounts 中的 subPathExpr 为了区分不同的容器输出的日志目录,也可以根据自己的业务进行调整

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mock-nginx-test
  name: mock-nginx-test
  namespace: default
spec:
  replicas: 4
  selector:
    matchLabels:
      app: mock-nginx-test
  template:
    metadata:
      labels:
        app: mock-nginx-test
    spec:
      containers:
        - args:
            - '--log-type=nginx'
            - '--stdout=false'
            - '--stderr=true'
            - '--path=/var/log/nginx/access.log'
            - '--total-count=1000000000'
            - '--logs-per-sec=100'
          command:
            - /bin/mock_log
          image: 'registry.cn-hangzhou.aliyuncs.com/log-service/docker-log-test:latest'
          imagePullPolicy: Always
          name: mock-nginx-test
          # 在env中提取相关容器信息
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: NODE_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
          # subPathExpr设置跟容器相关的路径,便于后续Topic提取
          volumeMounts:
            - mountPath: /var/log/nginx
              name: volume-nas-pvc
              subPathExpr: test-nginx-nas/$(POD_NAMESPACE)_$(POD_NAME)_$(POD_IP)_$(NODE_IP)_$(NODE_NAME)
      restartPolicy: Always
      volumes:
        - name: volume-nas-pvc
          persistentVolumeClaim:
            claimName: nas-pvc

步骤二:创建 Logtail 采集容器

.replicas 设置 1,不需要启动多个容器 .ALIYUN_LOGTAIL_USER_ID:填写阿里云账号 ID .ALIYUN_LOGTAIL_USER_DEFINED_ID:填写自定义的机器组标识,本例以 logtail-state-machinegroup 为例 .user_config_file_path、docker_file_cache_path、check_point_filename、buffer_file_path 记录 logtail 持久化的信息。相关配置参考强烈建议阅读《K8s 采集专题-稳定性:iLogtail 容器重启数据可靠性探讨》。 .与业务容器公用 pvc:nas-pvc .volumeMounts 包含业务容器的目录和 logtail 本身持久化信息的目录

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: logtail-state-pod
  name: logtail-state-pod
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: logtail-state-pod
  template:
    metadata:
      labels:
        app: logtail-state-pod
    spec:
      containers:
        - env:
            - name: ALIYUN_LOGTAIL_USER_ID
              value: '${your_aliyun_user_id}'
            - name: ALIYUN_LOGTAIL_USER_DEFINED_ID
              value: '${your_machine_group_user_defined_id}'
            - name: ALIYUN_LOGTAIL_CONFIG
              value: /etc/ilogtail/conf/${your_region}/ilogtail_config.json
            - name: user_config_file_path
              value: /etc/ilogtail/checkpoint/user_log_config.json
            - name: docker_file_cache_path
              value: /etc/ilogtail/checkpoint/docker_path_config.json
            - name: check_point_filename
              value: /etc/ilogtail/checkpoint/logtail_check_point
            - name: check_point_dump_interval
              value: '60'
            - name: buffer_file_path
              value: /etc/ilogtail/checkpoint
          image: 'registry.cn-beijing.aliyuncs.com/log-service/logtail:latest'
          imagePullPolicy: Always
          name: logtail-state-pod
          resources:
            requests:
              cpu: 250m
              memory: 512Mi
          volumeMounts:
            - mountPath: /var/log/nginx
              name: volume-nas-pvc
              subPath: test-nginx-nas
            - mountPath: /etc/ilogtail/checkpoint
              name: volume-nas-pvc
              subPath: logtail_checkpoint
      volumes:
        - name: volume-nas-pvc
          persistentVolumeClaim:
            claimName: nas-pvc

参数说明如下:

参数说明
${your_region}该参数由日志服务 Project 所在 Region 以及网络类型决定,请根据网络类型输入正确的格式。包括:公网:region-internet。例如,华东一为 cn-hangzhou-internet。阿里云内网:region。例如,华东一为 cn-hangzhou。其中,region 为 表一,请根据 Project 地域选择正确的参数。
${your_aliyun_user_id}用户标识,请替换为您的阿里云主账号用户 ID。主账号用户 ID 为字符串形式,如何查看 ID 请参考用户标识配置中的 2.1 节。
${your_machine_group_user_defined_id}Logtail 的机器组自定义标识。需确保该标识在您的日志服务所在 Region 内唯一。详细内容可参考创建用户自定义标识机器组。

步骤三:在日志服务控制台创建自定义标识机器组

  1. 登录日志服务控制台。
  2. 在 Project 列表区域,单击目标 Project。
  3. 在左侧导航栏中,单击机器组。
  4. 选择机器组右侧的 image.png

创建机器组。

  • 在创建机器组对话框中,配置如下参数,单击确定。以下以 logtail-state-machinegroup 为例创建机器组,logtail-state-machinegroup 对应步骤二中的${your_machine_group_user_defined_id}。需要保持一致。 image.png

步骤四:创建 Logtail 采集配置

  1. 登录日志服务控制台
  2. 选择目标 Project 和 Logstore,点开 logstore 菜单,选择数据接入->logtail 配置,点击+号,选择单行-文本日志。
  3. 下一步选择机器组时,选择使用现有机器组,选择在步骤三中创建的机器组。然后将该机器组从源机器组移动到应用机器组中。
  4. Logtail 配置选择,极简模式,默认关闭 Docker 文件开关(不要打开),日志路径使用业务容器和 logtail 容器都挂载的/var/log/nginx image.png
  5. 下一步,点击完成。

步骤五:查询采集后的日志

  1. 登录日志服务控制台
  2. 选择目标 Project 和 Logstore,点开 logstore 菜单,选择放大镜按钮,查询分析,即可查询采集到的日志。

image.png

步骤六:设置 Topic 生成方式(可选)

  1. 登录日志服务控制台
  2. 选择目标 Project 和 Logstore,点开 logstore 菜单,选择数据接入->logtail 配置,进入配置详情

image.png

  1. 修改 Topic 生成方式为文件路径正则,输入自定义正则(该正则根据需要修改):
\/var\/log\/(?P<app>.\*?)\/(?P<namespace>[^_]+?)_(?P<podname>[^_]+?)_(?P<podip>[\d\.]+?)_(?P<nodeip>[\d\.]+?)_(?P<nodename>[^_]+?)\/access.log
  1. 进入查询分析,可以看到查到数据有了相关的 tag。

image.png

常见问题

.采集过程中业务 pod 的元信息丢失了,不像 daemonset 或者 sidecar 中可以获取到业务 pod 的信息? .主要是由于该方案中 Logtail 作为一个单独的容器部署,通过挂载共享 NAS 的方式采集日志,Logtail 无法获取原始容器的信息,可以通过如下方式实现: .可以设置业务容器的挂载目录的 subPathExpr,来将 pod 信息注入到路径中,通过文件路径正则的方式,将 pod 信息写入 tag 中。 .对于只需要区分不同的业务的日志,可以直接将业务容器的目录 subPath 设置成固定的几个,比如 app1,app2,这样同一个业务的 pod 的日志输出到同一个共享文件中,采集时可以通路径简单区分不同业务。 .整个集群是否只能部署一份 Logtail 容器? .对于同一个文件使用单独的一个 Logtail 容器部署;不同类型的业务 Pod 也可以部署对应的 logtail 采集容器,本质上,需要 logtail 容器中可以看到被采集的业务容器的共享名录。

参考

.K8s 采集专题-稳定性:iLogtail 容器重启数据可靠性探讨:https://developer.aliyun.com/article/901257 .Kubernetes 文件采集实践:Sidecar + hostPath 卷:https://developer.aliyun.com/article/801162 .使用 Logtail 采集 Kubernetes 上挂载的 NAS 日志:https://developer.aliyun.com/article/691428 .日志主题设置:https://help.aliyun.com/document_detail/60069.html#section-os0-j2r-cvx .SLS(日志服务)云原生观测分析平台:https://www.aliyun.com/product/sls .欢迎扫群加入阿里云-日志服务(SLS)技术交流或关注公众号, 获得第一手资料与支持: image.png