SkyWalking - 在 Istio 中部署:Sidecar 模式 vs Mixer 替代方案
摘要: 本文探讨在Istio服务网格中集成SkyWalking APM的两种方案:Sidecar模式(推荐)和已弃用的Mixer替代方案。Sidecar模式通过在每个Pod注入SkyWalking Agent,实现无侵入式全链路追踪,兼容Istio最新架构,提供应用层与网络层双视角观测。详细步骤包括部署SkyWalking后端、构建带Agent的Java应用镜像,以及验证追踪数据。相比已废弃的Mi

👋 大家好,欢迎来到我的技术博客!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕SkyWalking这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!
文章目录
SkyWalking - 在 Istio 中部署:Sidecar 模式 vs Mixer 替代方案 🚀
在现代云原生架构中,服务网格(Service Mesh)已成为微服务治理的核心基础设施。Istio 作为当前最流行的服务网格实现之一,通过透明地注入 Sidecar 代理(如 Envoy)来管理服务间通信、安全、可观测性等横切关注点。而 Apache SkyWalking 是一个开源的 APM(Application Performance Monitoring)系统,专为分布式系统设计,尤其擅长追踪、指标收集和拓扑分析。
将 SkyWalking 集成到 Istio 环境中,可以显著提升对服务网格内应用的可观测能力。然而,如何集成?社区历史上曾提出两种主要路径:基于 Sidecar 的自动注入模式 和 基于 Mixer 的扩展方案。随着 Istio 架构演进(特别是 Mixer 组件在 1.8 版本后被弃用),这两种方案的命运也发生了巨大变化。
本文将深入探讨这两种集成方式的技术原理、实现细节、优缺点对比,并结合 Java 应用示例,帮助你在 Istio 环境中选择最适合的 SkyWalking 部署策略。无论你是 SRE、平台工程师还是应用开发者,都能从中获得实用的参考价值。
为什么需要在 Istio 中集成 SkyWalking?🔍
Istio 自带的遥测能力(如通过 Prometheus 收集指标、通过 Jaeger/Zipkin 实现追踪)虽然强大,但存在一些局限:
- 指标粒度有限:Istio 主要提供 L4/L7 网络层指标(如请求率、延迟、错误率),缺乏应用层上下文(如方法调用、SQL 执行、业务事务)。
- 追踪上下文不完整:Envoy 生成的追踪 Span 通常只覆盖网络跳转,无法深入到应用内部逻辑。
- 缺乏统一视图:Istio 的指标与应用自身的监控数据分散在不同系统中,难以关联分析。
SkyWalking 的优势在于:
✅ 全栈可观测性:从基础设施、服务网格到应用代码,提供端到端追踪。
✅ 自动探针(Agent):Java 应用无需修改代码即可自动注入追踪逻辑。
✅ 服务拓扑自动生成:可视化展示服务依赖关系,支持跨进程链路追踪。
✅ 强大的告警与诊断能力:内置 OAL(Observability Analysis Language)支持自定义指标分析。
因此,将 SkyWalking 与 Istio 结合,可以构建一个“网络层 + 应用层”双视角的可观测体系,真正实现“从用户点击到数据库查询”的全链路追踪。
💡 提示:SkyWalking 官方文档对 Istio 集成有详细说明,可参考 SkyWalking on Kubernetes。
方案一:Sidecar 模式(推荐 ✅)
原理概述
Sidecar 模式是当前 SkyWalking 与 Istio 集成的主流且推荐的方式。其核心思想是:
-
在每个 Pod 中注入两个 Sidecar 容器:
- Envoy:由 Istio 控制平面自动注入,处理服务网格通信。
- SkyWalking Agent:以 Init Container 或 Sidecar 形式注入,负责收集应用性能数据并上报至 OAP(Observability Analysis Platform)服务器。
-
应用容器保持“无侵入”:Java 应用通过 JVM 参数
-javaagent加载 SkyWalking Agent,Agent 自动拦截关键方法(如 HTTP 请求、JDBC 调用)生成追踪 Span。 -
数据上报路径:Agent → OAP Server → UI(或存储后端如 Elasticsearch)。
该模式完全兼容 Istio 的 Sidecar 注入机制,且不依赖已废弃的 Mixer 组件。
架构图
部署步骤
1. 部署 SkyWalking 后端(OAP + UI)
使用 Helm Chart 是最便捷的方式:
helm repo add apache-skywalking https://apache.jfrog.io/artifactory/skywalking-helm
helm install skywalking apache-skywalking/skywalking \
--set oap.replicas=1 \
--set ui.replicas=1 \
--set elasticsearch.clientPort=9200 \
--set elasticsearch.imageTag=7.17.3
确保 OAP 服务可通过 skywalking-oap.default.svc.cluster.local:11800 访问(默认 gRPC 端口)。
2. 准备 Java 应用
假设你有一个 Spring Boot 应用 user-service,代码如下:
// UserController.java
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
public ResponseEntity<User> getUser(@PathVariable String id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}
// UserService.java
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User findById(String id) {
// 模拟数据库查询
return userRepository.findById(id).orElse(null);
}
}
3. 构建 Docker 镜像(包含 SkyWalking Agent)
Dockerfile 示例:
FROM openjdk:11-jre-slim
# 下载 SkyWalking Agent
RUN mkdir -p /opt/skywalking && \
curl -L https://archive.apache.org/dist/skywalking/9.7.0/apache-skywalking-apm-9.7.0.tar.gz | tar xz --strip-components=1 -C /opt/skywalking
COPY target/user-service.jar /app.jar
# 设置 JVM 参数加载 Agent
ENV JAVA_OPTS="-javaagent:/opt/skywalking/agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=user-service \
-Dskywalking.collector.backend_service=skywalking-oap.default.svc.cluster.local:11800"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app.jar"]
⚠️ 注意:
skywalking.collector.backend_service必须指向集群内可解析的 OAP 地址。
4. 部署到 Kubernetes 并启用 Istio Sidecar
Deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
labels:
app: user-service
spec:
replicas: 1
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
annotations:
# 启用 Istio Sidecar 注入
sidecar.istio.io/inject: "true"
spec:
containers:
- name: user-service
image: your-registry/user-service:latest
ports:
- containerPort: 8080
应用此配置后,Istio 将自动注入 Envoy,而你的应用容器已内置 SkyWalking Agent。
5. 验证
- 访问
http://<ingress>/users/123触发请求。 - 打开 SkyWalking UI(通常通过
kubectl port-forward svc/skywalking-ui 8080:8080访问)。 - 查看服务拓扑、追踪链路,应能看到从入口网关 → user-service 的完整调用链。
优点 ✅
- 无 Mixer 依赖:完全适配 Istio 1.8+ 架构。
- 应用层深度可观测:Agent 可捕获方法级、SQL 级性能数据。
- 灵活配置:可通过环境变量动态调整 Agent 行为(如采样率、忽略路径)。
- 社区活跃:SkyWalking 官方持续维护 Istio 集成方案。
缺点 ❌
- 资源开销:每个 Pod 多一个 Agent 进程(约 50-100MB 内存)。
- 镜像耦合:需在应用镜像中打包 Agent,增加构建复杂度(可通过 Init Container 优化)。
- 语言限制:仅支持 Java、Go、Node.js 等有官方 Agent 的语言。
方案二:Mixer 替代方案(历史方案 ⚠️)
背景:Mixer 是什么?
在 Istio 早期版本(<1.8)中,Mixer 是一个独立的策略与遥测组件。它通过一组适配器(Adapters)从 Envoy 收集遥测数据,并转发给后端系统(如 Prometheus、StatsD、甚至自定义系统)。
Mixer 的工作流程如下:
- Envoy 在每次请求后向 Mixer 发送属性(Attributes)。
- Mixer 根据配置的 Instance/Handler/Rule,调用对应 Adapter 处理数据。
- Adapter 将数据转换为目标格式(如 Metrics、Logs、Traces)并发送。
因此,社区曾开发 SkyWalking Mixer Adapter,试图将 Envoy 的遥测数据直接上报至 SkyWalking。
架构图
实现方式(历史回顾)
-
编译 SkyWalking Mixer Adapter
该 Adapter 由 SkyWalking 社区提供,需从源码编译并打包进 Mixer 镜像。 -
配置 Mixer Handler/Rule
创建如下 YAML:
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: skywalking-handler
spec:
adapter: skywalking
connection:
address: skywalking-oap.default.svc.cluster.local:11800
---
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: skywalking-instance
spec:
template: tracespan
path: request.path
host: request.host
...
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: skywalking-rule
spec:
actions:
- handler: skywalking-handler
instances: [ skywalking-instance ]
- 部署修改后的 Mixer
替换 Istio 默认的 Mixer 镜像,包含 SkyWalking Adapter。
为什么 Mixer 方案被淘汰?🚫
Istio 团队在 2020 年宣布 弃用 Mixer,原因包括:
- 性能瓶颈:Mixer 作为中心化组件,成为高并发场景下的单点瓶颈。
- 延迟增加:每次请求需额外 RPC 调用 Mixer,增加 P99 延迟。
- 架构复杂:需维护 Adapter 生态,配置繁琐。
从 Istio 1.8 开始,Mixer 被彻底移除,遥测功能通过 Telemetry API(基于 Envoy WASM 或直接配置)实现。
📌 官方公告:Mixer is deprecated
因此,Mixer + SkyWalking 的方案已不可用于现代 Istio 集群。即使强行部署旧版 Istio,也会面临安全、性能和维护性问题。
如果你仍在使用旧版 Istio?
强烈建议升级 Istio 并迁移到 Sidecar 模式。若因特殊原因无法升级,可参考历史文档,但需自行承担风险。
Sidecar 模式的进阶优化 🛠️
虽然基础 Sidecar 模式已足够使用,但在生产环境中,我们常需进一步优化。
1. 使用 Init Container 注入 Agent(解耦镜像)
避免将 Agent 打包进应用镜像,改用 Init Container 动态挂载:
spec:
initContainers:
- name: skywalking-agent
image: apache/skywalking-java-agent:8.16.0-java11
volumeMounts:
- name: agent-volume
mountPath: /agent
containers:
- name: user-service
image: your-registry/user-service:latest
env:
- name: JAVA_TOOL_OPTIONS
value: "-javaagent:/agent/skywalking-agent.jar"
volumeMounts:
- name: agent-volume
mountPath: /agent
volumes:
- name: agent-volume
emptyDir: {}
这样,应用镜像无需修改,Agent 版本可独立管理。
2. 自定义采样策略
在高流量场景下,全量追踪可能造成 OAP 压力过大。可通过以下方式控制采样:
env:
- name: SW_AGENT_SAMPLE_N_PER_3_SECS
value: "10" # 每 3 秒最多采样 10 条
或通过 OAP 的动态配置中心(如 Nacos)远程调整。
3. 跨进程上下文传播
确保 SkyWalking 的 Trace Context 能在服务间正确传递。SkyWalking Agent 默认支持以下协议:
- HTTP Header:
sw8 - gRPC Metadata:
sw8
在 Istio 环境中,由于 Envoy 不识别 sw8,需确保:
- 应用间直接调用(非通过 ServiceEntry)时,Header 会透传。
- 若使用 Istio Gateway,需在 VirtualService 中显式允许
sw8:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
spec:
hosts:
- user-service.example.com
http:
- route:
- destination:
host: user-service
headers:
request:
set:
sw8: "%REQ(sw8)%"
💡 实际上,SkyWalking Agent 会自动注入
sw8到出站请求,只要应用框架(如 Spring Cloud)不丢弃自定义 Header,通常无需额外配置。
Java 应用深度集成示例 💻
除了自动探针,SkyWalking 还支持手动埋点,适用于异步、批处理等场景。
场景:异步任务追踪
假设 user-service 需要异步发送欢迎邮件:
@Service
public class EmailService {
@Trace(opName = "sendWelcomeEmail")
public void sendWelcomeEmail(String userId) {
// 模拟耗时操作
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Email sent to " + userId);
}
}
@Trace 注解会创建一个新的 Span,但默认与父请求断开。为保持上下文连续,需手动传递 Context:
// 在 Controller 中
@GetMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
// 创建用户逻辑...
// 手动捕获当前 Context
final Object contextSnapshot = ContextManager.capture();
executor.submit(() -> {
// 恢复 Context
ContextManager.continued(contextSnapshot);
try {
emailService.sendWelcomeEmail(user.getId());
} finally {
ContextManager.stopSpan(); // 结束 Span
}
});
return ResponseEntity.ok(user);
}
这样,邮件发送的 Span 会作为主请求的子 Span 出现在 SkyWalking UI 中。
场景:自定义指标
通过 SkyWalking 的 @Meter 注解,可暴露业务指标:
@Meter(name = "user.registration.count", unit = "COUNT")
public void registerUser(User user) {
// 注册逻辑
}
这些指标会被自动收集到 OAP,并可在 UI 中创建仪表盘。
🔗 更多 API 参考:SkyWalking Java Plugin Development Guide
性能与资源考量 ⚖️
任何可观测性方案都会带来开销,需权衡收益与成本。
Sidecar 模式开销
| 组件 | CPU | 内存 | 网络 |
|---|---|---|---|
| SkyWalking Agent | ~5% | 50-100MB | 每秒数 KB(取决于采样率) |
| Envoy | ~10% | 100-200MB | 与业务流量相关 |
在典型微服务(QPS < 1000)场景下,总开销可控。建议:
- 生产环境采样率设为 10-30%。
- OAP 集群化部署,避免单点故障。
- 使用 Kafka 作为缓冲(OAP 支持 Kafka 输入),应对流量高峰。
对比纯 Istio 遥测
| 能力 | Istio 原生 | Istio + SkyWalking |
|---|---|---|
| 服务拓扑 | ✅(服务间) | ✅(服务+实例+DB) |
| 方法级追踪 | ❌ | ✅ |
| SQL 分析 | ❌ | ✅ |
| 自定义指标 | 有限 | ✅ |
| 告警 | 需 Prometheus Alertmanager | 内置 OAL 告警 |
显然,SkyWalking 提供了更丰富的应用层洞察。
故障排查指南 🛠️
问题1:SkyWalking UI 无数据
排查步骤:
- 检查 OAP 日志:
kubectl logs -l app=skywalking-oap - 检查 Agent 是否启动:进入应用 Pod,查看 JVM 参数是否包含
-javaagent - 检查网络连通性:
telnet skywalking-oap 11800 - 检查采样率:是否设置为 0?
问题2:追踪链路断裂
常见原因:
- 中间件(如 Nginx)丢弃了
sw8Header。 - 异步调用未传递 Context。
- 多语言混合调用(如 Java → Python),需确保各语言 Agent 版本兼容。
问题3:OAP CPU 飙高
解决方案:
- 降低采样率。
- 升级 OAP 版本(新版本性能优化显著)。
- 增加 OAP 实例数,启用分片(Sharding)。
未来展望:eBPF 与 WASM 的可能性 🌐
随着技术演进,新的集成方式可能出现:
- eBPF:通过内核级观测,无需修改应用或注入 Sidecar。但目前对 Java 应用支持有限。
- Envoy WASM:Istio Telemetry v2 支持 WASM 扩展,理论上可开发 SkyWalking WASM 插件,直接在 Envoy 中生成 Span。但需解决上下文传播和应用层语义缺失问题。
目前,Sidecar + Agent 仍是平衡性最佳的方案。
结论:坚定不移选择 Sidecar 模式 ✅
- Mixer 方案已成为历史,不应在新项目中采用。
- Sidecar 模式 兼具深度可观测性与 Istio 兼容性,是当前唯一推荐路径。
- 通过合理配置(Init Container、采样率、上下文传播),可满足绝大多数生产需求。
在云原生时代,可观测性不是“可选项”,而是“必选项”。SkyWalking 与 Istio 的结合,为你提供了从网络到代码的全景视图,让故障无处遁形,让性能瓶颈无所遁形。
🌟 最后建议:定期关注 SkyWalking 官方博客 和 Istio 官方文档,获取最新集成实践。
Happy Observing! 🎯
🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨
更多推荐


所有评论(0)