背景
本文介绍在 Kubernetes 集群中,如何通过 Sidecar 模式为 Java 应用无侵入式部署 SkyWalking 探针,并利用 DataKit 内置的 SkyWalking 采集器,一站式收集链路数据(Trace)与应用日志(Log),最终在观测云平台实现强大的链路与日志联动查询,全面提升可观测性能力。
部署 SkyWalking 探针
SkyWalking Agent Sidecar 容器
该容器负责提供 skywalking-agent.jar
及其配置文件。
- 环境变量: 配置应用名(
SW_AGENT_NAME
) - Volume 挂载: 将 Agent 目录挂载到共享 Volume
- Sidecar 容器镜像 dockerfile:
bash
FROM alpine:3.14
# 下载SkyWalking探针
RUN wget -O /tmp/skywalking-agent.tar.gz \
https://archive.apache.org/dist/skywalking/java-agent/8.8.0/apache-skywalking-java-agent-8.8.0.tgz \
&& tar -zxvf /tmp/skywalking-agent.tar.gz -C / \
&& mv /skywalking-agent /agent \
&& rm /tmp/skywalking-agent.tar.gz
# 复制启动脚本
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
bash
#!/bin/sh
# 创建配置目录
mkdir -p /agent/config
# 动态生成agent.config
cat <<EOF > /agent/config/agent.config
# 服务名由环境变量传入
agent.service_name=${SW_AGENT_NAME:demo}
# DataKit地址由环境变量传入
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:datakit-service.datakit.svc.cluster.local:11800}
EOF
# 将探针复制到共享卷
cp -r /agent/* /sw-agent/
# 保持容器运行
tail -f /dev/null
业务容器
- 无需修改镜像: 业务镜像本身无需包含任何 SkyWalking 依赖。
- JVM 参数注入: 通过 JAVA_TOOL_OPTIONS 环境变量,指向共享 Volume 中的 skywalking-agent.jar。
- Volume 挂载: 同样挂载共享 Volume,以访问其中的 Agent 文件。
业务 yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-b
spec:
replicas: 1
selector:
matchLabels:
app: service-b
template:
metadata:
labels:
app: service-b
spec:
volumes:
- name: sw-agent
emptyDir: {}
containers:
# 主应用容器
- name: service-b-app
image: zhaoje/service-b:sw3.0
ports:
- containerPort: 8081
volumeMounts:
- name: sw-agent
mountPath: /sw-agent
env:
- name: JAVA_TOOL_OPTIONS
value: "-javaagent:/sw-agent/skywalking-agent.jar"
# SkyWalking边车容器
- name: sw-agent-sidecar
image: xxx/sw-agent-sidecar:8.8.2
env:
- name: SW_AGENT_NAME
value: "service-b"
volumeMounts:
- name: sw-agent
mountPath: /sw-agent
---
apiVersion: v1
kind: Service
metadata:
name: service-b
spec:
#type: NodePort
selector:
app: service-b
ports:
- protocol: TCP
port: 8081
targetPort: 8080
应用日志关联 Trace
本最佳实践以 log4j2 示例,将 toolkit 依赖包添加到 maven 或者 gradle 中:
xml
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-log4j-2.x</artifactId>
<version>8.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.8.0</version>
</dependency>
apm-toolkit-log4j-2.x
: 这是最关键的依赖。它为Log4j2
这个日志框架提供了扩展。具体来说,它提供了一个特殊的%tid
模式转换器(Pattern Layout Converter)。正是因为有了这个依赖,您才能在后面的log4j2.xml
配置中使用[%tid]
来输出 Trace ID。apm-toolkit-trace
: 这个依赖提供了一些有用的 API,例如TraceContext.traceId()
用于在代码中手动获取当前链路的 Trace ID。虽然很多功能由探针自动完成,但如果您想在业务代码中主动操作追踪上下文,就需要它。
并在服务目录下新增 log4j2.xml 定义输出格式,在示例中的路径是:/root/service-a/src/main/resources
xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- 控制台输出 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n"/>
</Console>
<!-- SkyWalking gRPC日志输出 -->
<GRPCLogClientAppender name="GrpcLog">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n"/>
</GRPCLogClientAppender>
</Appenders>
<Loggers>
<!-- 设置Spring框架日志级别 -->
<Logger name="org.springframework" level="WARN" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="GrpcLog"/>
</Logger>
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="GrpcLog"/>
</Root>
</Loggers>
</Configuration>
DataKit 开启 SkyWalking 采集器
部署配置 DataKit
在观测云控制台点击「集成」-「DataKit」-「Kubernetes」,运行脚本下载。
arduino
wget https://static.guance.com/datakit/datakit.yaml
开启 SkyWalking 采集器
在 volumeMounts 中添加
yaml
- mountPath: /usr/local/datakit/conf.d/skywalking/skywalking.conf
name: datakit-conf
subPath: skywalking.conf
readOnly: true
在 configmap 中增加 SkyWalking 配置
ini
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-conf
namespace: datakit
data:
skywalking.conf: |-
[inputs.skywalking]
endpoints = ["/v3/trace", "/v3/metric", "/v3/logging", "/v3/profiling"]
address = "0.0.0.0:11800"
观测云
可以看到链路数据正常上报的观测云空间
链路和日志也通过 trace_id 串联起来
在日志页面也可以反向查询链路数据
总结
通过本文介绍的 Sidecar 模式与 DataKit 相结合的方案,我们成功实现了:
- 轻量级集成: 以非侵入方式为集群 Java 应用快速赋予了链路追踪能力。
- 架构简化: 利用 DataKit 替代了 SkyWalking OAP + Storage 的复杂组件,降低了运维成本。
- 数据融合: 最终在观测云平台上实现了链路追踪数据与应用日志数据的无缝关联与联动查询,形成了完整的可观测性闭环。