Loading [MathJax]/jax/output/CommonHTML/config.js
部署DeepSeek模型,进群交流最in玩法!
立即加群
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >k8s 应用 10分钟接入 skywalking

k8s 应用 10分钟接入 skywalking

原创
作者头像
Duncan_
修改于 2022-05-24 02:06:24
修改于 2022-05-24 02:06:24
3.1K0
举报

k8s 应用 10分钟接入 skywalking

导读

本文主要介绍了 k8s 环境里面在不修改应用镜像的前提下,如何给 java 应用快速添加 skywalking agent 采集器,以及其中所涉及到的技术原理。k8s 应用接入 skywalking 是基于已有的 k8s 环境、待接入应用以及 skywalking 后端服务进行接入的。如果这些都已经准备好了,可以直接跳过 前置准备,从 快速接入 开始。如果还没有这些环境,至少需要准备一个干净的 k8s 环境,再按照 前置准备 中的步骤部署好前置的资源环境。

前置准备

skywalking 服务/集群

在接入 skywalking 之前,首选需要一个 skywalking 的后端服务/集群,用于收集采集到的监控数据,并对其进行聚合、存储以及展示。

如果还没有部署 skywaking 后端服务的,可以使用下面的 helm chart 部署一套 skywalking 后端服务。

代码语言:shell
AI代码解释
复制
## 克隆 helm chart
git clone --branch 1.0 git@e.coding.net:treezh/demo03/coffeemaker-helm.git
## 生成 helm chart
cd ./coffeemaker-helm
helm dep ./

## 确保当前 kubeconfig 配置正确情况下,执行下面指令进行部署
helm upgrade --install coffeemaker ./ --set coffee.enable=false --set skywalking.enabled=true --set jaeger.enabled=false

agent 载包镜像

Skywalking 需要从应用中采集链路数据并进行上报,然而应用本身不包含这些代码逻辑,这些逻辑通过 javaagent 方式被写到了 skywalking-agent.jar 里面。并且使用 javaagent 的特性与 bytebuddy 字节码织入技术,让应用加载这些代码到相应的位置。

所以我们需要一个镜像,把 skywalking-agent.jar 搬运到目标应用里面,并且让目标应用加载。

这个镜像只需要包含 skywalking-agent.jar 已经相应的依赖插件即可。可以自行制作,也可以官方提供 agent 镜像。这里以官方镜像的一个备份为例。

代码语言:shell
AI代码解释
复制
docker pull http://treezh-docker.pkg.coding.net/demo03/public/skywalking-java-agent:8.9.0-alpine

待接入应用 manifest

为了让应用加载 skywalking-agent.jar, 需要对应用的 deployment 做一些修改。所以需要准备待接入应用的 manifest。如果已经有待接入的应用,则可以通过 kubectl get deployment (deploymentName) -o yaml > app.yaml 获取对应的 manifest。如果还没有,则可以使用本文准备好的 helmchart 生成对应的 manifest。

代码语言:shell
AI代码解释
复制
## 克隆 helm chart
git clone --branch 1.0 git@e.coding.net:treezh/demo03/coffeemaker-helm.git

## 生成 helm chart
cd ./coffeemaker-helm

## 生成 mainifest 
helm template --set coffee.enabled=true --set skywalking.enabled=false --set jaeger.enabled=false ./ > coffee-maker.yaml

部署 coffee-maker 应用

代码语言:shell
AI代码解释
复制
## 部署
helm dep ./
helm upgrade --install coffeemaker ./ --set coffee.enabled=true --set skywalking.enabled=false --set jaeger.enabled=false

快速接入

这里以 coffee-maker 的 coffee-machine 应用为例子,快速接入 Skywalking 步骤如下

1. 找到 coffee-machine 的 manifest 中的 deployment 内容(非关键信息省略):

代码语言:yaml
AI代码解释
复制
# Source: coffee-maker/templates/coffee-material.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: coffee-material
spec:
    template:
        spec:
            containers:
                - name: coffee-material
                  image: "treezh-docker.pkg.coding.net/demo03/public/coffee-material:8bc05202416f680c2a3a7179703be94ad806a099"
                  imagePullPolicy: IfNotPresent
                  env:
                    - name: LOGGING_LEVEL_ROOT
                    value: "INFO"
                    ...
                ...
    ...

2. 添加 initContainer :

代码语言:yaml
AI代码解释
复制
# Source: coffee-maker/templates/coffee-material.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: coffee-material
spec:
    template:
        spec:
            initContainers:
                - name: skywalking-agent
                  image: "treezh-docker.pkg.coding.net/demo03/public/skywalking-java-agent:8.9.0-alpine"
            containers:
                - name: coffee-material
                  image: "treezh-docker.pkg.coding.net/demo03/public/coffee-material:8bc05202416f680c2a3a7179703be94ad806a099"
                  imagePullPolicy: IfNotPresent
                  env:
                    - name: LOGGING_LEVEL_ROOT
                    value: "INFO"
                    ...
                  ...
            ...

3. 添加 initContainer 与目标 container 共享目录:

代码语言:yaml
AI代码解释
复制
# Source: coffee-maker/templates/coffee-material.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: coffee-material
spec:
    template:
        spec:
            volumes:
                - name: skywalking-agent
                  emptyDir: { }
            initContainers:
                - name: skywalking-agent
                  image: "treezh-docker.pkg.coding.net/demo03/public/skywalking-java-agent:8.9.0-alpine"
                  volumeMounts:
                    - name: skywalking-agent
                      mountPath: /agent
            containers:
                - name: coffee-material
                  image: "treezh-docker.pkg.coding.net/demo03/public/coffee-material:8bc05202416f680c2a3a7179703be94ad806a099"
                  imagePullPolicy: IfNotPresent
                  env:
                    - name: LOGGING_LEVEL_ROOT
                    value: "INFO"
                    ...
                  volumeMounts:
                    - name: skywalking-agent
                      mountPath: /skywalking
                  ...
            ...

4. 把需要加载的文件从跟 initContainer 拷贝到共享文件夹

代码语言:yaml
AI代码解释
复制
# Source: coffee-maker/templates/coffee-material.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: coffee-material
spec:
    template:
        spec:
            volumes:
                - name: skywalking-agent
                  emptyDir: { }
            initContainers:
                - name: skywalking-agent
                  image: "treezh-docker.pkg.coding.net/demo03/public/skywalking-java-agent:8.9.0-alpine"
                  volumeMounts:
                    - name: skywalking-agent
                      mountPath: /agent
                  command: [ "/bin/sh" ]
                  args: [ "-c", "cp -R /skywalking/agent /agent/" ]
            containers:
                - name: coffee-material
                  image: "treezh-docker.pkg.coding.net/demo03/public/coffee-material:8bc05202416f680c2a3a7179703be94ad806a099"
                  imagePullPolicy: IfNotPresent
                  env:
                    - name: LOGGING_LEVEL_ROOT
                    value: "INFO"
                    ...
                  volumeMounts:
                    - name: skywalking-agent
                      mountPath: /skywalking
                  ...
            ...

5. 添加环境变量,指定从共享文件夹中加载 javaagent,并且设置应用名称,上报地址等信息

代码语言:yaml
AI代码解释
复制
# Source: coffee-maker/templates/coffee-material.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
    name: coffee-material
spec:
    template:
        spec:
            volumes:
                - name: skywalking-agent
                  emptyDir: { }
            initContainers:
                - name: skywalking-agent
                  image: "treezh-docker.pkg.coding.net/demo03/public/skywalking-java-agent:8.9.0-alpine"
                  volumeMounts:
                    - name: skywalking-agent
                      mountPath: /agent
                  command: [ "/bin/sh" ]
                  args: [ "-c", "cp -R /skywalking/agent /agent/" ]
            containers:
                - name: coffee-material
                  image: "treezh-docker.pkg.coding.net/demo03/public/coffee-material:8bc05202416f680c2a3a7179703be94ad806a099"
                  imagePullPolicy: IfNotPresent
                  env:
                    - name: LOGGING_LEVEL_ROOT
                    value: "INFO"
                    - name: JAVA_TOOL_OPTIONS
                      value: "-javaagent:/skywalking/agent/skywalking-agent.jar"
                    - name: SW_AGENT_NAME
                      value: "coffee-material"
                    - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
                      value: "oap:11800"
                    ...
                  volumeMounts:
                    - name: skywalking-agent
                      mountPath: /skywalking
                  ...
            ...

6. 完成配置,重新部署该服务。

使用如下指令重新部署:

代码语言:shell
AI代码解释
复制
kubectl apply -f coffee-maker.yaml

看到有 Picked up JAVA_TOOL_OPTIONS: ... 一行信息,就说明 skywalking agent 已经加载成功了。

代码语言:text
AI代码解释
复制
  + java -server -Djava.awt.headless=true -XX:-OmitStackTraceInFastThrow -Djava.security.egd=file:/dev/./urandom -jar /app/coffee-machine.jar
  Picked up JAVA_TOOL_OPTIONS: -javaagent:/skywalking/agent/skywalking-agent.jar
  DEBUG 2022-05-15 18:47:00:001 main AgentPackagePath : The beacon class location is jar:file:/skywalking/agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class.
  ...
  ...

如果想要确认是否已经加载了自己想要的包,以及链路信息是否正常上报等更多信息,则可以更改 Skywalking agent 的日志输出级别和输出方式来查看更多的信息。

代码语言:yaml
AI代码解释
复制
  - name: SW_LOGGING_LEVEL
    value: "DEBUG"
  - name: SW_LOGGING_OUTPUT
    value: "CONSOLE"

技术原理分析

要 k8s 环境里面在不修改应用镜像的前提下,给 java 应用加载到 skywalking agent 主要有两个问题需要解决。

第一个问题是如何在不修改应用镜像的前提下,把 javaagent.jar(指 skywalking-agent.jar) 放到应用容器可访问的路径里面。这个问题常见的解法就是添加一个与目标 container 有共享目录的 initContainer, 让这个新加的 initContainer 携带文件并拷贝文件到共享目录。

第二个问题是如何在不修改应用镜像前提下加载 javaagent.jar。有的人可能会想到通过修改目标容器的 commandargs ,往里面添加 -javaagent:/skywalking/agent/javaagent.jar 参数实现加载。这种方法要求知道目标容器的 java 路径和启动文件路径,而且容易覆盖掉原有的 java 启动参数。

解决第二个问题的另外一种办法,就是利用 JVM 支持的 JAVA_TOOL_OPTIONS,参考 JDK-4971166。该环境变量支持从环境变量读取 java 启动参数。但是实际支持情况也要看具体的 jdk 发行版与所在环境么。如在 oracle jdk 中,出于安全考虑,在一些操作系统中此环境变量默认是禁用的,参考 The JAVA_TOOL_OPTIONS Environment Variable。

结语

利用 JVM 的 JAVA_TOOL_OPTIONS 特性,可以在对应用镜像 0 知识的情况下让应用实现对 javaagent.jar 的加载。也就使得这个操作可以完全由 operator 代替手工操作,实现全自动的 agent 注入。其实本文所讲述的实现,正是 skywalking-swckopentelemetry-operator 支持全自动织入 agent 的实现原理。随着这些 operator 的成熟与普及,链路追踪的接入门槛降大大降低,实现真正意义上的链路追踪全流程的开箱即用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Redis-13Redis发布订阅
当使用银行卡消费的时候,银行往往会通过微信、短信或邮件通知用户这笔交易的信 息,这便是一种发布订阅模式, 1这里的发布是交易信息的发布,订阅则是各个渠道。这在实际工作中十分常用, Redis 支持这样的一个模式。
小小工匠
2021/08/17
4570
Redis 订阅模式详解
注意:发布返回的是订阅者数量,发布的消息不会持久化,没有订阅者时候,发布消息会丢失,当在发布消息之后对channel进行订阅不会收到之前发布的消息。
ruochen
2021/12/07
9550
Redis发布订阅模式
Redis自身提供了发布/订阅(publish/subscribe)模式。实现方式大致流程如下图:
ruochen
2021/11/22
9920
Redis:发布(pub)与订阅(sub)实战
Redis发布订阅(Pub/Sub)是Redis提供的一种消息传递机制,它使用“发布者-订阅者”(publisher-subscriber)模式来处理消息传递。在这种模式下,发布者将消息发布到一组订阅者中,而无需关心谁是订阅者,也不需要知道订阅者是否收到了消息。
不惑
2023/11/17
2.2K1
Redis:发布(pub)与订阅(sub)实战
补习系列(13)-springboot redis 与发布订阅
消息发布者是消息载体的生产者,其通过某些主题来向调度中心发送消息; 而消息订阅者会事先向调度中心订阅其"感兴趣"的主题,随后会获得新消息。
美码师
2019/01/23
1.9K0
设计模式之发布订阅模式(2) Redis 发布/订阅模式
Redis 通过 PUBLISH 、 SUBSCRIBE 等命令实现了发布订阅模式。该功能提供两种信息机制, 分别是“发布订阅到频道”和“发布订阅到模式”。
用户5546570
2019/06/06
1.6K0
设计模式之发布订阅模式(2) Redis 发布/订阅模式
重学SpringBoot3-集成Redis(六)之消息队列
Redis 不仅是一个高效的缓存解决方案,也具备强大的消息队列功能。通过 Redis 的 发布/订阅(Pub/Sub) 机制,开发者可以轻松实现服务之间的通信和消息传递功能,而无需引入专门的消息队列工具。这篇文章将介绍如何通过 Spring Boot 3 和 Redis 实现消息队列的发布与订阅功能。
CoderJia
2024/10/18
4760
重学SpringBoot3-集成Redis(六)之消息队列
redis事件监听的应用场景与案例实战
在使用Redis的过程中,我们对Redis做的每一个操作,下发的每一个命令, 都可以认为是事件的存在。所谓事件监听,就是Redis Server会对客户端下发命令进行一个监控, 一但有人对Redis Server做操作, Redis Server都能知道,并通过某种方式将监听到的事件转发到对应的订阅者。
蒋老湿
2020/03/20
5.9K1
redis事件监听的应用场景与案例实战
Springboot2 整合redis发布订阅 解决订阅多个频道重复代码过多 创建很多bean问题
之前的写法 每个频道都要写个@bean 重复代码太多 import cn.tim.util.Constants; import com.alibaba.druid.filter.config.ConfigTools; import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersC
heasy3
2020/10/10
1.8K0
springmvc+redis实现简单消息队列
有一只柴犬
2024/01/25
1570
领导:谁再用定时任务实现关闭订单,立马滚蛋!
在电商、支付等领域,往往会有这样的场景,用户下单后放弃支付了,那这笔订单会在指定的时间段后进行关闭操作,细心的你一定发现了像某宝、某东都有这样的逻辑,而且时间很准确,误差在1s内;那他们是怎么实现的呢?
做个快乐的码农
2021/12/10
7450
领导:谁再用定时任务实现关闭订单,立马滚蛋!
Spring Boot使用Redis消息队列
业务系统经常需要用到MQ消息队列,但是又不希望引入一个完整的中间件,比如RocketMQ,RabbitMQ,因为会增加接入成本和运维成本。所以当业务量不是很大,且一致性要求不是很强的场景下,可以选择Redis,使用其pub/sub机制作为消息队列的实现 添加依赖 ---- <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-
十毛
2019/05/17
2.4K0
【多人聊天室】WebSocket集群/分布式改造
https://github.com/qqxx6661/springboot-websocket-demo/releases/tag/%E9%9B%86%E7%BE%A4%E7%89%88
Java3y
2019/08/27
3.6K0
【多人聊天室】WebSocket集群/分布式改造
利用Spring Data Redis 来实现消息的发布订阅机制
redis是一款高性能key-value存储系统,不仅能做缓存,还能用于消息队列 这里利用Spring Data Redis 来实现消息的发布订阅机制 Demo地址:GitHub - jujunchen/redis-queue-demo: redis 实现的消息 发布/订阅机制 一共3个应用,1个发布者应用,2个订阅者应用 发布者应用 RedisConfig redis序列化配置 Person 示例传输的POJO对象 Publisher 发布服务 @Component public cla
阿提说说
2022/12/02
7090
redis过期监听
今天写拼团功能,如果24小时后还没有人满,则此次拼团就失败了,那么这里我用redis过期监听来实现,键过期去处理订单状态等业务
adu
2022/10/30
2.4K0
redis过期监听
[WebSocket]第二章:WebSocket集群分布式改造——实现多人在线聊天室
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
蛮三刀酱
2019/09/10
3.2K0
Spring认证中国教育管理中心-Spring Data Redis框架教程一
原标题:Spring认证中国教育管理中心-Spring Data Redis框架教程一
IT胶囊
2021/11/30
1.3K0
Spring认证中国教育管理中心-Spring Data Redis框架教程一
基于Redis的消息发布和订阅(广播模式)
如下如所示, 定义了2个Linstener, 模拟2个应用监听同一个通道. 根据发送和接收的数据类型我们可以选择合适的数据序列化和反序列化方式, 默认序列化方式为RedisSerializer.java(). 对于普通的Bean来说使用json()和java()的序列方式都可以.不同点在于:
悦stack
2023/06/30
1.1K0
什么鬼,面试官竟然让敖丙用Redis实现一个消息队列!!?
众所周知,redis是一个高性能的分布式key-value存储系统,在NoSQL数据库市场上,redis自己就占据了将近半壁江山,足以见到其强大之处。同时,由于redis的单线程特性,我们可以将其用作为一个消息队列。本篇文章就来讲讲如何将redis整合到spring boot中,并用作消息队列的……
敖丙
2020/02/20
8800
什么鬼,面试官竟然让敖丙用Redis实现一个消息队列!!?
浅析分布式下的事件驱动机制(PubSub模式)
上一篇文章《浅析Spring中的事件驱动机制》简单介绍了Spring对事件的支持。Event的整个生命周期,从publisher发出,经过applicationContext容器通知到EventListener,都是发生在单个Spring容器中,而在分布式场景下,有些时候一个事件的产生,可能需要被多个实例响应,本文主要介绍分布式场景下的事件驱动机制,由于使用了Redis,ActiveMQ,也可以换一个名词来理解:分布式下的发布订阅模式。 JMS 在日常项目开发中,我们或多或少的发现一些包一些类位于java
kirito-moe
2018/04/27
2.8K0
浅析分布式下的事件驱动机制(PubSub模式)
相关推荐
Redis-13Redis发布订阅
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档