前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >k8s 应用 10分钟接入 skywalking

k8s 应用 10分钟接入 skywalking

原创
作者头像
Duncan_
修改2022-05-24 10:06:24
2.8K0
修改2022-05-24 10:06:24
举报
文章被收录于专栏:云原生&可观测技术探索

k8s 应用 10分钟接入 skywalking

导读

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

前置准备

skywalking 服务/集群

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

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

代码语言:shell
复制
## 克隆 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
复制
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
复制
## 克隆 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
复制
## 部署
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
复制
# 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
复制
# 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
复制
# 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
复制
# 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
复制
# 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
复制
kubectl apply -f coffee-maker.yaml

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

代码语言:text
复制
  + 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
复制
  - 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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • k8s 应用 10分钟接入 skywalking
    • 导读
      • 前置准备
        • skywalking 服务/集群
        • agent 载包镜像
        • 待接入应用 manifest
      • 快速接入
        • 技术原理分析
          • 结语
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档