SkyWalking全链路监控:Kubernetes环境下的Sidecar模式部署实战

在微服务架构日益普及的今天,全链路监控已成为保障系统稳定性的关键组件。Apache SkyWalking 作为一款优秀的应用性能监控(APM)工具,提供了灵活的 Agent 接入方式。本文将详细阐述如何在 Kubernetes 环境下,通过 Sidecar 模式部署 SkyWalking Agent,并针对 Spring Boot 微服务进行实战配置。

一、SkyWalking Agent在K8s中的部署模式分析与选型

在 Java 应用中接入 SkyWalking Agent,主要有以下三种方式:

  1. 使用官方基础镜像:直接基于 skywalking-base 镜像构建应用。
  2. 构建集成镜像:将 Agent 包直接构建到业务镜像中。
  3. Sidecar 模式挂载:推荐模式。

为何推荐 Sidecar 模式?

官方镜像属于精简版 OpenJDK,可能缺少部分常用命令,且修改基础镜像会增加维护成本。而 Sidecar 模式具有显著优势:

  • 零侵入:无需修改原有的业务基础镜像,也无需重新构建服务镜像。
  • 解耦:Agent 与应用容器分离,通过共享 Volume 的方式挂载文件,互不干扰。
  • 灵活性:便于统一管理和升级 Agent 版本。

二、构建独立的SkyWalking Agent Docker镜像

首先,我们需要构建一个包含 SkyWalking Agent 的独立镜像,以便在 K8s 中作为 Sidecar 使用。

1. 编写 Dockerfile

基于 Alpine Linux 构建轻量级镜像,并开启必要的插件(如 trace-ignore-plugin 用于忽略特定路径)以及日志配置。

FROM alpine:3.8

LABEL maintainer="DevOps Team"

ENV SKYWALKING_VERSION=8.5.0

# 下载并解压 SkyWalking
ADD https://archive.apache.org/dist/skywalking/${SKYWALKING_VERSION}/apache-skywalking-apm-${SKYWALKING_VERSION}.tar.gz /

RUN tar -zxvf /apache-skywalking-apm-${SKYWALKING_VERSION}.tar.gz && \
    mv apache-skywalking-apm-bin skywalking && \
    # 启用 trace-ignore-plugin 插件
    mv /skywalking/agent/optional-plugins/apm-trace-ignore-plugin* /skywalking/agent/plugins/ && \
    # 优化日志配置,防止日志文件过多
    sed -i 's@# logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:-1}@logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:2}@' /skywalking/agent/config/agent.config && \
    # 配置忽略路径(例如健康检查)
    echo -e "\n# Ignore Path" >> /skywalking/agent/config/agent.config && \
    echo "trace.ignore_path=${SW_IGNORE_PATH:/health}" >> /skywalking/agent/config/agent.config

2. 构建与推送

构建完成后,将其推送到私有镜像仓库。

$ docker build -t harbor.nebulait.cn/library/skywalking-agent:8.5.0 .

$ docker push harbor.nebulait.cn/library/skywalking-agent:8.5.0

三、Sidecar模式挂载机制与基础实现

Sidecar 模式的核心在于 Kubernetes 的 Init Containers 和 emptyDir 卷。

实现原理:

  1. Init Container:启动时先将 Agent 文件从 Sidecar 镜像复制到共享的 emptyDir 卷中。
  2. Application Container:业务容器启动时,将共享卷挂载到指定目录,并通过 JVM 参数加载 Agent。

示例:以 Nginx 为例的挂载配置

虽然 Nginx 不需要 Java Agent,但以下 YAML 清晰地展示了 Sidecar 挂载的标准结构:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-skywalking
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-skywalking
  template:
    metadata:
      labels:
        app: demo-skywalking
    spec:
      initContainers:
        - name: init-skywalking-agent
          image: harbor.nebulait.cn/library/skywalking-agent:8.5.0
          command: ['sh', '-c', 'set -ex; mkdir -p /vmskywalking/agent; cp -r /skywalking/agent/* /vmskywalking/agent;']
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
        - image: nginx:1.7.9
          name: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /opt/skywalking/agent
              name: skywalking-agent
      volumes:
        - name: skywalking-agent
          emptyDir: {}

四、Spring Cloud应用的集成与K8s部署

对于 Java/Spring Boot 应用,我们需要在 Dockerfile 中预设 Agent 的挂载点,并在 K8s 启动参数中指明 OAP 服务地址。

1. 改造 Spring Boot Dockerfile

注意 ENTRYPOINT 中的 -javaagent 参数配置,这是 Java Agent 生效的关键。

FROM harbor.nebulait.cn/library/openjdk:8-jdk

COPY ./springdemo2023.jar /opt/

# 创建必要目录
RUN mkdir -p data/logs/ && mkdir -p data/skywalking/agent

# 设置时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo 'Asia/Shanghai' > /etc/timezone

# 配置启动参数:包含 Agent 路径、服务名及后端 OAP 地址
ENTRYPOINT [ "java", \
"-Dapp.id=springdemo2023", \
"-javaagent:/data/skywalking/agent/skywalking-agent.jar", \
"-Dskywalking.agent.service_name=springdemo2023", \
"-Dskywalking.collector.backend_service=skywalking-oap.devops.svc.cluster.local:11800", \
"-jar", "/opt/springdemo2023.jar" , \
"-Dfile.encoding=UTF-8" ]

注意:Kubernetes 内部服务调用需使用完全限定域名(FQDN),格式为 <service-name>.<namespace>.svc.cluster.local。跨命名空间访问时必须使用完整域名。

$ docker build -t harbor.nebulait.cn/library/springdemo-skywalking:v1 .$ docker push harbor.nebulait.cn/library/springdemo-skywalking:v1

2. 编写 Kubernetes 部署文件 (YAML)

完整的 Deployment 配置包含 InitContainer、业务容器探针以及 Service 暴露。

apiVersion: v1
kind: Service
metadata:
  name: springdemo2023
  namespace: default
spec:
  ports:
    - port: 8080
      targetPort: 8080
  selector:
    app: springdemo2023
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: springdemo2023
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: springdemo2023
  template:
    metadata:
      labels:
        app: springdemo2023
    spec:
      imagePullSecrets:
        - name: harborsecret
      initContainers:
        - name: init-skywalking-agent
          image: harbor.nebulait.cn/library/skywalking-agent:8.5.0
          command: ['sh', '-c', 'set -ex; mkdir -p /vmskywalking/agent; cp -r /skywalking/agent/* /vmskywalking/agent;']
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
        - image: harbor.nebulait.cn/demo/springdemo-skywalking:v1
          name: springdemo2023
          ports:
            - containerPort: 8080
          # 健康检查配置
          livenessProbe:
            httpGet:
              path: /apptwo
              port: 8080
            initialDelaySeconds: 30
          readinessProbe:
            httpGet:
              path: /apptwo
              port: 8080
            initialDelaySeconds: 20
          volumeMounts:
            - mountPath: /data/skywalking/agent
              name: skywalking-agent
      volumes:
        - name: skywalking-agent
          emptyDir: {}

五、生产环境微服务全链路监控实战

在实际的微服务场景中,通常包含 UI、业务中台(Office、Account)等模块。以下展示了典型的多服务部署配置。

1. UI 服务 (acme-financial-ui)

UI 服务通常作为流量入口,通过 Ingress 暴露。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: acme-financial-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      app: acme-financial-ui
  template:
    metadata:
      labels:
        app: acme-financial-ui
    spec:
      initContainers:
        - name: init-skywalking-agent
          image: harbor.nebulait.cn/library/skywalking-agent:8.5.0
          command: ['sh', '-c', 'set -ex; mkdir -p /vmskywalking/agent; cp -r /skywalking/agent/* /vmskywalking/agent;']
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
        - name: ui
          image: harbor.nebulait.cn/library/acme-financial-ui:v0.1
          env:
            # 通过环境变量传递 JVM 参数,灵活注入 Agent
            - name: JAVA_OPTS
              value: "-javaagent:/opt/sw/agent/skywalking-agent.jar"
            - name: SW_AGENT_NAME
              value: "acme-financial-ui"
            - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
              value: "skywalking-oap.devops.svc.cluster.local:11800"
          ports:
            - containerPort: 8081
          volumeMounts:
            - mountPath: /opt/sw/agent
              name: skywalking-agent
      volumes:
        - name: skywalking-agent
          emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: acme-financial-ui
spec:
  ports:
    - port: 8081
  selector:
    app: acme-financial-ui

2. 其他微服务 (Office/Account/Customer)

其他后端服务(如 acme-financial-officeacme-financial-account)的配置结构完全一致,仅需修改 SW_AGENT_NAME、镜像名称及端口号即可。

配置要点:

  • SW_AGENT_NAME:在 SkyWalking UI 中显示的服务名称,需保证唯一性。
  • InitContainer:所有微服务 Pod 均需包含此步骤以拷贝 Agent。
  • Volume 挂载:确保 Agent 目录挂载路径与 JAVA_OPTS 中的路径一致。

Springboot微服务 – office服务:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: acme-financial-office
  name: acme-financial-office
spec:
  replicas: 1
  selector:
    matchLabels:
      app: acme-financial-office
  template:
    metadata:
      labels:
        app: acme-financial-office
    spec:
      initContainers:
        - name: init-skywalking-agent
          image: harbor.nebulait.cn/library/skywalking-agent:8.5.0
          command:
            - 'sh'
            - '-c'
            - 'set -ex;mkdir -p /vmskywalking/agent;cp -r /skywalking/agent/* /vmskywalking/agent;'
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
      - env:
        - name: JAVA_OPTS
          value: "-javaagent:/opt/sw/agent/skywalking-agent.jar"
        - name: SW_AGENT_NAME
          value: "acme-financial-office"
        - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
          value: "skywalking-oap.devops.svc.cluster.local:11800"
        image: harbor.nebulait.cn/library/acme-financial-office:v0.1
        imagePullPolicy: Always
        name: office
        ports:
        - containerPort: 8082
          protocol: TCP
        volumeMounts:
        - mountPath: /opt/sw/agent
          name: skywalking-agent
      volumes: 
      - name: skywalking-agent
        emptyDir: {}

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: acme-financial-office
  name: acme-financial-back-office
spec:
  ports:
  - name: http
    port: 8082
    protocol: TCP
    targetPort: 8082
  selector:
    app: acme-financial-office
  sessionAffinity: None
  type: ClusterIP

Springboot微服务 – account服务:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: acme-financial-account
  name: acme-financial-account
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: acme-financial-account
  template:
    metadata:
      labels:
        app: acme-financial-account
    spec:
      initContainers:
        - name: init-skywalking-agent
          image: harbor.nebulait.cn/library/skywalking-agent:8.5.0
          command:
            - 'sh'
            - '-c'
            - 'set -ex;mkdir -p /vmskywalking/agent;cp -r /skywalking/agent/* /vmskywalking/agent;'
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
      - env:
        - name: JAVA_OPTS
          value: "-javaagent:/opt/sw/agent/skywalking-agent.jar"
        - name: SW_AGENT_NAME
          value: "acme-financial-account"
        - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
          value: "skywalking-oap.devops.svc.cluster.local:11800"
        image: harbor.nebulait.cn/library/acme-financial-account:v0.1
        imagePullPolicy: Always
        name: account
        ports:
        - containerPort: 8083
          protocol: TCP
        volumeMounts:
        - mountPath: /opt/sw/agent
          name: skywalking-agent
      volumes: 
      - name: skywalking-agent
        emptyDir: {}
---

apiVersion: v1
kind: Service
metadata:
  labels:
    app: acme-financial-account
  name: acme-financial-account
spec:
  ports:
  - name: http
    port: 8083
    protocol: TCP
    targetPort: 8083
  selector:
    app: acme-financial-account
  sessionAffinity: None
  type: ClusterIP

Springboot微服务 – customer服务:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: acme-financial-customer
  name: acme-financial-customer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: acme-financial-customer
  template:
    metadata:
      labels:
        app: acme-financial-customer
    spec:
      initContainers:
        - name: init-skywalking-agent
          image: harbor.nebulait.cn/library/skywalking-agent:8.5.0
          command:
            - 'sh'
            - '-c'
            - 'set -ex;mkdir -p /vmskywalking/agent;cp -r /skywalking/agent/* /vmskywalking/agent;'
          volumeMounts:
            - mountPath: /vmskywalking/agent
              name: skywalking-agent
      containers:
      - env:
        - name: JAVA_OPTS
          value: "-javaagent:/opt/sw/agent/skywalking-agent.jar"
        - name: SW_AGENT_NAME
          value: "acme-financial-customer"
        - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
          value: "skywalking-oap.devops.svc.cluster.local:11800"
        image: harbor.nebulait.cn/library/acme-financial-customer:v0.1
        imagePullPolicy: Always
        name: customer
        ports:
        - containerPort: 8084
          protocol: TCP
        volumeMounts:
        - mountPath: /opt/sw/agent
          name: skywalking-agent
      volumes: 
      - name: skywalking-agent
        emptyDir: {}

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: acme-financial-customer
  name: acme-financial-customer
  namespace: default
spec:
  ports:
  - name: http
    port: 8084
    protocol: TCP
    targetPort: 8084
  selector:
    app: acme-financial-customer
  sessionAffinity: None
  type: ClusterIP

3. 配置 Ingress

最后,配置 Ingress 将外部流量路由至 UI 服务。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: acme-financial-ing
spec:
  ingressClassName: nginx
  rules:
  - host: acme.zhoumx.cc
    http:
      paths:
        - pathType: Prefix
          backend:
            service:
              name: acme-financial-ui
              port:
                number: 8081
          path: /

六、流量模拟与SkyWalking数据大盘验证

部署完成后,我们需要通过模拟流量来验证监控数据的准确性。

1. 模拟 API 访问压力

使用 curl 循环调用 UI 服务的不同接口,生成追踪数据。

## 模拟正常接口调用
$ for i in {1..5000}; do curl http://acme.zhoumx.cc/hello && sleep 1; done

## 模拟业务启动流程
$ for i in {1..5000}; do curl http://acme.zhoumx.cc/start && sleep 1; done

## 模拟超时/慢调用场景
$ for i in {1..5000}; do curl http://acme.zhoumx.cc/readtimeout && sleep 1; done

2. SkyWalking UI 指标解读

登录 SkyWalking Web 控制台,观察以下核心指标:

  • 吞吐量 (CPM):每分钟调用次数,反映系统负载。
  • Apdex (应用性能指数):衡量用户对应用性能满意度的标准分数。
  • 响应时间百分位:重点关注 P99、P95、P90,识别长尾请求。
  • SLA (服务等级协议):通常指 HTTP 状态码为 200 的请求成功率。
  • 拓扑图:可视化的服务调用链路图,点击节点可查看具体实例的监控详情。
  • 追踪查询:定位具体的慢请求或报错接口,分析调用栈耗时。
SkyWalking全链路监控:Kubernetes环境下的Sidecar模式部署实战
SkyWalking全链路监控:Kubernetes环境下的Sidecar模式部署实战
SkyWalking全链路监控:Kubernetes环境下的Sidecar模式部署实战

通过以上步骤,我们已在 Kubernetes 环境下成功实现了基于 Sidecar 模式的 SkyWalking 全链路监控部署。这种模式既保证了业务镜像的纯净性,又实现了监控能力的灵活注入,非常适合生产环境的微服务治理。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
SkyWalking云原生

基于Helm部署Skywalking

2025-7-15 6:24:12

Ceph云原生

使用cephadm部署ceph集群

2025-7-15 6:28:44

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
本站支持IPv6访问