无感改造,完美监控:Docker 多阶段构建 Go 应用无侵入观测

news2025/5/9 23:59:52

作者:牧思

背景

随着云原生的普及,Golang 编程语言变得越来越热门。相比 Java,Golang 凭借其轻量,易学习的特点得到了越来越多工程师的青睐,然而由于 Golang 应用需要被编译成二进制文件再进行运行,Golang 编程语言相比 Java 这样的有运行时虚拟机的编程语言损失了较多的灵活性:比如在可观测领域,Java 应用通常利用 JVM 提供的字节码增强机制通过 Java Agent 来进行观测数据的采集,而对于 Golang 应用,通常需要更改源代码重新编译或者使用类似 opentelemetry-go-auto-instrumentation【1】 的编译时注入工具替换原本的 Golang 工具链才能达到类似的效果。本文将介绍一种基于 Docker 多阶段构建的无侵入 Golang 应用观测方法,通过此方法用户无需对 Golang 应用源代码或者编译指令做任何改造,即可零成本为 Golang 应用注入可观测能力。

Docker 多阶段构建

Docker 允许用户将镜像构建拆成多个阶段【2】,在下一个阶段可以获取到上一阶段的一些输出,Golang 开发者在构建 Golang 应用的镜像流水线时通常会编写如下所示的 Dockerfile:

# stage 1
FROM golang:1.22-alpine3.19 as builder

RUN go version
RUN go build -v -o /workspace/demo
# stage 2
FROM alpine

COPY --from=builder /workspace/demo /demo
export ENV1=e1
# 指定默认的启动命令
CMD ["/demo"]

在这个 Dockerfile 中,主要分为两个阶段,第一个阶段是构建阶段,在这个阶段中一般会通过组合 Golang 提供的各种编译工具,构建出需要执行的二进制文件并作为输出传递给第二阶段。第二阶段一般为运行阶段,第二阶段将会获取到第一阶段中构建好的二进制文件,之后设置运行时需要的环境变量后启动二进制文件,从而将 Golang 应用成功运行起来。

那么我们需要做什么改造,才能让这样一个经过 Docker 多阶段构建的 Golang 应用镜像拥有可观测能力呢?请看下文:

Step1:替换编译阶段基础镜像

# stage 1
# 替换为ARMS编译镜像,其余保持一致
FROM registry-cn-hangzhou.ack.aliyuncs.com/acs/golangbuilder-alpine-linux-amd64:0.0.1 as builder
RUN go version
RUN go build -v -o /workspace/demo
# stage 2
FROM alpine

COPY --from=builder /workspace/demo /demo
ENV ENV1=e1
# 指定默认的启动命令
CMD ["/demo"]

只需要把编译阶段的基础镜像替换为 ARMS 的编译镜像,其余的内容保持一致即可自动使用 ARMS 的 instgo 编译工具【3】进行混合编译,用户可以使用 docker build 命令构建该 Dockerfile 对应的镜像:

可以看到,在把编译阶段的基础镜像替换为 ARMS 的编译镜像后,在执行 Golang 应用构建时实际上是通过 ARMS 的 instgo 编译工具来进行的,同时对于其他的原生 Golang Tool,比如 go version,instgo 的执行效果与原生 Golang Tool 完全一致。

以上步骤完成后,我们就成功构建出了具有可观测能力的 Golang 应用镜像。

Step2:通过 ack-onepilot 为运行时镜像添加环境变量

在相关应用镜像构建完成后,用户需要把相关镜像运行起来,比如运行在阿里云的容器服务 ACK 产品【4】中,在相关应用运行前,用户通常需要去指定一些配置,比如在接入可观测能力后相关的观测数据上报到哪个地域的哪个应用下,是否启动观测数据的上报等等。自然地,用户可能会在 Dockerfile 中添加一些环境变量:

# stage 1
# 替换为ARMS编译镜像,其余保持一致
FROM registry-cn-hangzhou.ack.aliyuncs.com/acs/golangbuilder-alpine-linux-amd64:0.0.1 as builder
RUN go version
RUN go build -v -o /workspace/demo
# stage 2
FROM alpine

COPY --from=builder /workspace/demo /demo
ENV ENV1=e1
# 手动添加运行时环境变量
ENV ARMS_ENABLE=true
ENV ARMS_APP_NAME={AppName}
ENV ARMS_REGION_ID={regionId}
ENV ARMS_LICENSE_KEY={licenseKey}
# 指定默认的启动命令
CMD ["/demo"]

上面这种方案虽然可行,但是灵活性较差,如果相关的环境变量值需要发生变化,比如某天用户不想打开可观测能力,就需要重新修改 Dockerfile 构建镜像,同时如果用户需要接入的应用较多,这样的改动成本对用户来说成本过高。

另一种无感的使用方式是使用 ARMS 提供的 ack-onepilot 组件,首先在阿里云 ACK 的运维管理界面点击组件管理,并且在右上角通过关键字搜索 ack-onepilot 组件,并在卡片上点击安装。

在安装好 ack-onepilot 组件后,只需要在创建工作负载时将以下 labels 添加到 spec.template.metadata 层级下,即可完成 Golang 应用的接入:

labels:
  aliyun.com/app-language: golang # Go应用必填,标明此应用是Go应用。
  armsPilotAutoEnable: 'on'
  armsPilotCreateAppName: "<your-deployment-name>"    #请将<your-deployment-name>替换为您的应用名称。

加上相关标签后,在 ARMS 控制台上即可查看到对应 Golang 应用,点击应用进入详情页即可查看该应用详细的观测数据。

总结与展望

基于 Docker 多阶段构建的无侵入观测方案有效降低了用户接入 Golang Agent 的成本,并已商业化上线至阿里云公有云,为客户提供强大的监控能力。这项技术最初的设计初衷是为了让用户能够在不改动现有代码的前提下轻松地插入监控代码,从而实现对应用程序性能状态的实时监测与分析,但它的实际应用领域不止如此,包括服务治理、代码审计、应用安全、代码调试等,甚至在许多未被探索的领域中也展现出潜力。

我们已经将这项创新方案开源,并成功捐赠给 OpenTelemetry 社区【5】。开源不仅促进技术共享与提升,借助社区的力量还可以持续探索该方案在更多领域上的可能。

最后诚邀大家试用我们的商业化产品,并加入我们的钉钉群(开源群:102565007776,商业化群:35568145),共同提升 Go 应用监控与服务治理能力。通过群策群力,我们相信能为 Golang 开发者社区带来更加优质的云原生体验。

【1】opentelemetry-go-auto-instrumentation

https://github.com/alibaba/opentelemetry-go-auto-instrumentation

【2】多阶段|Docker 文档

https://docs.docker.com/build/building/multi-stage/

【3】Instgo 工具介绍

https://help.aliyun.com/zh/arms/application-monitoring/developer-reference/instgo-tool-introduction?spm=5176.arms.console-base_help.dexternal.6c32f167FF5WFW

【4】容器服务 Kubernetes 版 ACK

https://help.aliyun.com/zh/ack/

【5】OpenTelemetry 社区

https://github.com/open-telemetry/opentelemetry-go-compile-instrumentation

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2336081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

006.Gitlab CICD流水线触发

文章目录 触发方式介绍触发方式类型 触发方式实践分支名触发MR触发tag触发手动人为触发定时任务触发指定文件变更触发结合分支及文件变更触发正则语法触发 触发方式介绍 触发方式类型 Gitlab CICD流水线的触发方式非常灵活&#xff0c;常见的有如下几类触发方式&#xff1a; …

512天,倔强生长:一位技术创作者的独白

亲爱的读者与同行者&#xff1a; 我是倔强的石头_&#xff0c;今天是我在CSDN成为创作者的第512天。当系统提示我写下这篇纪念日文章时&#xff0c;我恍惚间想起了2023年11月19日的那个夜晚——指尖敲下《开端——》的标题&#xff0c;忐忑又坚定地按下了“发布”键。那时的我…

【目标检测】【YOLO综述】YOLOv1到YOLOv10:最快速、最精准的实时目标检测系统

YOLOv1 to YOLOv10&#xff1a; The fastest and most accurate real-time object detection systems YOLOv1到YOLOv10&#xff1a;最快速、最精准的实时目标检测系统 论文链接 0.论文摘要 摘要——本文是对YOLO系列系统的全面综述。与以往文献调查不同&#xff0c;本综述文…

日常学习开发记录-slider组件

日常学习开发记录-slider组件 从零开始实现一个优雅的Slider滑块组件前言一、基础实现1. 组件结构设计2. 基础样式实现3. 基础交互实现 二、功能增强1. 添加拖动功能2. 支持范围选择3. 添加垂直模式 三、高级特性1. 键盘操作支持2. 禁用状态 五、使用示例六、总结 从零开始实现…

Windows 系统如何使用Redis 服务

前言 在学习过程中&#xff0c;我们长期接触到的是Mysql 关系型数据库&#xff0c;也是够我们平时练习项目用的&#xff0c;但是后面肯定会有大型数据的访问就要借助新的新的工具。 一、什么是Redis Redis&#xff08;Remote Dictionary Server&#xff09;是一个基于内存的 键…

【unity游戏开发入门到精通——UGUI】CanvasScaler画布缩放器组件

注意&#xff1a;考虑到UGUI的内容比较多&#xff0c;我将UGUI的内容分开&#xff0c;并全部整合放在【unity游戏开发——UGUI】专栏里&#xff0c;感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、CanvasScaler画布缩放器组件是什么二、CanvasScaler的三种适配模式1、Cons…

Hugging Face 模型:AI 模型的“拥抱”与开源革命!!!

&#x1f310; Hugging Face 模型&#xff1a;AI 模型的“拥抱”与开源革命 用表情符号、图表和代码&#xff0c;探索开源模型生态的底层逻辑与应用场景&#xff01; &#x1f31f; 名字由来&#xff1a;为什么叫 Hugging Face&#xff1f; “Hugging”&#xff1a;象征 开放…

关于 人工智能(AI)发展简史 的详细梳理,按时间阶段划分,涵盖关键里程碑、技术突破、重要人物及挑战

以下是关于 人工智能&#xff08;AI&#xff09;发展简史 的详细梳理&#xff0c;按时间阶段划分&#xff0c;涵盖关键里程碑、技术突破、重要人物及挑战&#xff1a; 字数&#xff1a;约2500字 逻辑结构&#xff1a;时间线清晰&#xff0c;分阶段描述技术突破、关键事件与挑战…

微服务即时通信系统---(四)框架学习

目录 ElasticSearch 介绍 安装 安装kibana ES客户端安装 头文件包含和编译时链接库 ES核心概念 索引(Index) 类型(Type) 字段(Field) 映射(mapping) 文档(document) ES对比MySQL Kibana访问ES测试 创建索引库 新增数据 查看并搜索数据 删除索引 ES…

Android查看依赖树的方法,简单有效

一、使用命令打印 在工具栏“Terminal”中输入以下命令&#xff0c;即可打印依赖树信息 gradlew xxxx:dependencies (“xxxx”为module名称)二、工具栏双击打印 右侧“Gradle”工具栏打开按下图顺序依次查找到“dependencies”&#xff0c;双击后依赖树就会在控制台中打印出…

GitHub配置密钥

1.生成SSH密钥 1&#xff09;检查 SSH 密钥是否存在 首先&#xff0c;确认是否已经在本地系统中生成了 SSH 密钥对。可以通过以下命令检查&#xff1a; ls -al ~/.ssh 在命令输出中&#xff0c;应该能看到类似 id_rsa 和 id_rsa.pub 这样一对文件。如果这些文件不存在&#…

【2-10】E1与T1

前言 之前我们简单介绍了人类从电话线思维到如今的数据报分组交换思维过渡时期的各种技术产物&#xff0c;今天我们重点介绍 E1/T1技术。 文章目录 前言1. 产生背景2. T13. E14. SONET4.1 OC-14.2 OC-3 及其它 5. SDH5.1. STM-1 6. SONET VS SDH后记修改记录 1. 产生背景 E1/…

【设计模式】适配器模式:让不兼容的接口和谐共处

引言 在软件开发中&#xff0c;我们经常会遇到这样的情况&#xff1a;两个已经存在的接口无法直接协同工作&#xff0c;但我们又希望它们能够无缝对接。这时&#xff0c;适配器模式就派上用场了。适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&…

Pandas进行数据预处理(标准化数据)③

数据标准化处理代码解析 数据标准化处理代码解析课前预习1. 离差标准化&#xff08;Min - Max Scaling&#xff09;结果2. 标准差标准化&#xff08;Standard Scaling&#xff09;结果3. 小数定标标准化&#xff08;Decimal Scaling&#xff09;结果 代码整体概述代码详细解析1…

基于uniapp 实现画板签字

直接上效果图 代码 <template><view class"container"><!-- 签名画布 --><view class"canvas-container"><canvas canvas-id"signCanvas" class"sign-canvas"touchstart"handleTouchStart"touc…

JDBC 初认识、速了解

目录 一. JDBC的简介 1. 数据的持久化 2. 什么是JDBC 二. JDBC中常用的类和接口 1. Driver 接口 2. DriverManager 类 3. Connection 接口 4. Statement 接口 5. PreparedStatement接口 6. ResultSet 接口 三. 总结 前言 从现在开始就来讲解JDBC的相关知识了 本文的…

(2025亲测可用)Chatbox多端一键配置Claude/GPT/DeepSeek-网页端配置

1. 资源准备 API Key&#xff1a;此项配置填写在一步API官网创建API令牌&#xff0c;一键直达API令牌创建页面创建API令牌步骤请参考API Key的获取和使用API Host&#xff1a;此项配置填写https://yibuapi.com/v1查看支持的模型请参考这篇教程模型在线查询 2. ChatBox网页版配…

4.vtk光照vtkLight

文章目录 VTK中的光照1. vtkLight 的两种类型&#xff1a;位置光照和方向光照2. vtkLight 的常用方法3. 方法命名风格4. vtkProp 的可见性与 vtkLight 的开关 示例 VTK中的光照 vtkLight: 用于定义一个或多个光源。每个光源可以有其颜色、位置、焦点等属性。 vtkActor: 每个vtk…

YOLOv2学习笔记

YOLOv2 背景 YOLOv2是YOLO的第二个版本&#xff0c;其目标是显著提高准确性&#xff0c;同时使其更快 相关改进&#xff1a; 添加了BN层——Batch Norm采用更高分辨率的网络进行分类主干网络的训练 Hi-res classifier去除了全连接层&#xff0c;采用卷积层进行模型的输出&a…

【YOLOv8改进 - 卷积Conv】PConv(Pinwheel-shaped Conv): 风车状卷积用于红外小目标检测, 复现!

YOLOv8目标检测创新改进与实战案例专栏 专栏目录: YOLOv8有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例 专栏链接: YOLOv8基础解析+创新改进+实战案例 文章目录 YOLOv8目标检测创新改进与实战案例专栏介绍摘要文章链…