蛮子哥 蛮子哥
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • ArgoCD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)

蛮子哥

业精于勤,荒于嬉
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • ArgoCD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)
  • ansible系列文章

  • Kubernetes笔记

    • 安装篇-kubeadm
    • k8s入门
    • k8s安装篇二进制
    • k8s面试题
    • kubernetes(k8s)yaml文件详解
    • k8s报错小结
    • Kubernetes 安装配置ingress controller
    • cka考试真题
    • ingress配置证书
    • cka考试作业
    • k8s部署java项目
    • jenkins脚本式流水线部署k8s项目实例一
    • helm v3安装并创建例子
    • 使用helm将本地部署文件上传到harbor chart上
    • helm公共仓库创建
    • helm适应minio作为私有仓库
    • helm release使用说明
    • kubernetes核心概念
    • kubectl使用技巧
    • kubernetes卷的几种类型
    • kubernetes安全框架
    • 云原生-什么是HPA和PDB、VPA
    • k8s部署php项目示例
    • 配置kubeconfig 文件访问 Kubernetes 集群
    • configmap配置的几种方式
    • k8s配置go服务
    • k8s部署java项目
    • kubernetes部署prometheus监控
    • kubernetes部署elk日志系统
    • kubernetes环境devops流水线
    • kubernetes高阶技能必备的工具
    • deployment中使用configmap、secret的方式
    • 业务pod 飘移pending排查分析
    • debian 12安装kubernetes
    • istio入门
    • kubernetes证书续签到100年
    • kubernetes网络模式
    • etcd的备份和还原
    • Kubernetes 安装和配置 NFS 存储卷
    • VictoriaLogs集群采集Kubernetes Pod日志
    • 解决容器时区问题
    • 日志采集操作示例
      • 方案一:Java 应用直接输出到文件(Sidecar 采集模式)【推荐】
        • 1. Java 应用配置(Logback 示例)
        • 2. Kubernetes Deployment 配置
        • 3. 工作原理
      • 方案二:日志文件挂载到宿主机(hostPath)
        • 1. Java 应用配置(同上,Logback 配置写入指定路径)
        • 2. Deployment 使用 hostPath 挂载
        • 3. 修改 Fluent Bit 采集 hostPath 目录
      • 方案三:log4j2 配置示例
      • 方案对比与建议
    • operator 部署 VictoriaMetrics
  • elk

  • jenkins

  • GitLabCI_CD

  • AI编程

  • 提示词

  • ArgoCD

  • 专题
  • Kubernetes笔记
蛮子哥
2025-05-24
目录

日志采集操作示例

在 Kubernetes 环境中让 Java 应用的日志落地到指定目录,同时保证被 Fluent Bit 采集,需要从应用配置和运维部署两个层面配合实现。

下面是几种主流方案的完整示例。


# 方案一:Java 应用直接输出到文件(Sidecar 采集模式)【推荐】

这是最符合 Kubernetes 设计理念的方案:Java 应用将日志写入容器的指定目录,同 Pod 内的 Sidecar 容器负责将日志内容输出到 stdout,再让 Fluent Bit 自动采集。

# 1. Java 应用配置(Logback 示例)

在 src/main/resources/logback.xml 中配置日志输出到文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 定义日志文件路径 -->
    <property name="LOG_PATH" value="/app/logs" />
    <property name="LOG_FILE" value="${LOG_PATH}/app" />

    <!-- 控制台输出(保留用于其他用途) -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 文件输出(滚动策略) -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天滚动,自动压缩 -->
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 可选的 JSON 格式输出(便于结构化查询) -->
    <appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/app-json.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/app-json.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LogstashEncoder" />
    </appender>

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

Maven 依赖(JSON 格式需要):

<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.4</version>
</dependency>
1
2
3
4
5

# 2. Kubernetes Deployment 配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: java-app
  template:
    metadata:
      labels:
        app: java-app
    spec:
      containers:
      # 主容器:Java 应用
      - name: java-app
        image: your-java-app:latest
        volumeMounts:
        - name: app-logs                    # 挂载共享卷
          mountPath: /app/logs              # 日志写入目录(与 logback.xml 中 LOG_PATH 一致)
        env:
        - name: JAVA_OPTS
          value: "-Xms256m -Xmx512m"
        # 通过环境变量动态指定日志路径(可选)
        - name: LOG_PATH
          value: "/app/logs"
        resources:
          limits:
            memory: "1Gi"
            cpu: "500m"
      
      # Sidecar 容器:将文件日志输出到 stdout
      - name: log-sidecar
        image: busybox:latest
        command:
        - /bin/sh
        - -c
        - |
          # 等待日志文件出现
          echo "[$(date)] Waiting for log file..."
          while [ ! -f /logs/app.log ]; do
            sleep 2
          done
          echo "[$(date)] Starting to tail app.log..."
          tail -n+1 -f /logs/app.log
        volumeMounts:
        - name: app-logs
          mountPath: /logs                    # 挂载同一个共享卷
        resources:
          requests:
            memory: "32Mi"
            cpu: "10m"
          limits:
            memory: "64Mi"
            cpu: "20m"
      
      volumes:
      - name: app-logs
        emptyDir: {}                          # 临时存储,Pod 生命周期内有效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 3. 工作原理

  1. Java 应用将日志写入 /app/logs/app.log(容器内)
  2. Sidecar 容器通过 tail -f 读取同一个文件,输出到 stdout
  3. Fluent Bit DaemonSet 读取 /var/log/containers/*.log(即 Sidecar 的 stdout),自动采集并发送到 VictoriaLogs

优点:无需修改 Fluent Bit 配置,完全复用现有日志采集体系。


# 方案二:日志文件挂载到宿主机(hostPath)

如果需要日志文件长期保留在节点上,或者需要与节点上的其他工具集成,可以使用 hostPath 直接挂载到宿主机目录。

# 1. Java 应用配置(同上,Logback 配置写入指定路径)

# 2. Deployment 使用 hostPath 挂载

apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app-hostpath
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: java-app
  template:
    metadata:
      labels:
        app: java-app
    spec:
      # 重要:需要指定节点选择器,确保 Pod 总是调度到同一节点
      nodeSelector:
        kubernetes.io/hostname: k8s-node01
      
      containers:
      - name: java-app
        image: your-java-app:latest
        volumeMounts:
        - name: app-logs-host
          mountPath: /app/logs
        env:
        - name: LOG_PATH
          value: "/app/logs"
      
      volumes:
      - name: app-logs-host
        hostPath:
          path: /data/java-logs/default/java-app  # 宿主机路径
          type: DirectoryOrCreate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

# 3. 修改 Fluent Bit 采集 hostPath 目录

由于需要让 Fluent Bit 也能读取宿主机上的这个目录,需要修改 Fluent Bit DaemonSet,挂载同样的宿主机路径。

在 Fluent Bit DaemonSet 中添加 volume 和 volumeMount:

# fluent-bit-daemonset.yaml 的修改部分
spec:
  template:
    spec:
      containers:
      - name: fluent-bit
        volumeMounts:
        # ... 原有挂载 ...
        - name: java-app-logs               # 新增
          mountPath: /data/java-logs        # Fluent Bit 容器内的挂载点
          readOnly: true
      
      volumes:
      # ... 原有 volumes ...
      - name: java-app-logs                 # 新增
        hostPath:
          path: /data/java-logs
          type: DirectoryOrCreate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

然后修改 ConfigMap,添加新的 Input 来采集这个目录下的日志:

data:
  fluent-bit.conf: |
    # ... 原有配置 ...
    
    # 新增:采集 Java 应用的日志文件
    [INPUT]
        Name            tail
        Tag             java-app
        Path            /data/java-logs/*/*.log   # 匹配所有子目录下的日志
        DB              /var/log/flb_java.db
        Mem_Buf_Limit   5MB
        Skip_Long_Lines On
        Path_Key        log_file_path            # 记录文件路径用于区分 Pod
1
2
3
4
5
6
7
8
9
10
11
12
13

缺点:

  • Pod 需要固定节点(nodeSelector)
  • Pod 重建后,新 Pod 需要调度到同一节点才能读取历史日志
  • 节点故障时日志会丢失
  • 需要手动管理宿主机目录的权限和清理

# 方案三:log4j2 配置示例

如果使用 Log4j2,配置文件 log4j2.xml 示例如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <Property name="LOG_PATH">/app/logs</Property>
        <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>

    <Appenders>
        <!-- 控制台输出 -->
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>

        <!-- 文件输出(按大小和时间滚动) -->
        <RollingFile name="RollingFile"
                     fileName="${LOG_PATH}/app.log"
                     filePattern="${LOG_PATH}/app-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="50MB"/>
            </Policies>
            <DefaultRolloverStrategy max="30"/>
        </RollingFile>

        <!-- 异步日志(提升性能) -->
        <Async name="AsyncFile">
            <AppenderRef ref="RollingFile"/>
        </Async>
    </Appenders>

    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="AsyncFile"/>
        </Root>
    </Loggers>
</Configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 方案对比与建议

方案 适用场景 优点 缺点
Sidecar + emptyDir 通用场景,日志只需采集到 VictoriaLogs ✅ 无需修改 Fluent Bit
✅ Pod 可在任意节点调度
✅ 完全复用现有架构
Sidecar 占用少量资源
hostPath 直接挂载 日志需要保留在节点供其他工具使用 ✅ 日志持久化在节点
✅ 节点上可直接查看
❌ Pod 需固定节点
❌ 节点故障日志丢失
❌ 需手动管理清理
直接采集应用 stdout 最简单的场景 ✅ 零配置 ❌ 无法控制日志格式
❌ 不支持日志滚动

综合考虑你的环境,强烈推荐方案一(Sidecar 模式),因为它:

  • 不需要修改你已经部署好的 Fluent Bit DaemonSet
  • Pod 可以在任意节点调度,灵活性高
  • 日志通过 Sidecar 输出到 stdout,自动被 Fluent Bit 采集
  • 资源消耗极小(busybox sidecar 只用约 2-5MB 内存)
微信 支付宝
上次更新: 2026/05/25, 09:30:42

← 解决容器时区问题 operator 部署 VictoriaMetrics→

最近更新
01
VictoriaLogs集群采集Kubernetes Pod日志
05-24
02
kubernetes证书续签到100年
05-04
03
istio入门
04-29
更多文章>
Theme by Vdoing | Copyright © 2019-2026 | 点击查看十年之约 | 鄂ICP备2024072800号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式