当前位置: 首页 > news >正文

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

作者:牧思

背景

随着云原生的普及,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 builderRUN go version
RUN go build -v -o /workspace/demo
# stage 2
FROM alpineCOPY --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 alpineCOPY --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 alpineCOPY --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

相关文章:

  • 【ES6新特性】Proxy进阶实战
  • 第IV部分有效应用程序的设计模式
  • 驱动速腾雷达16线并用rviz显示点云
  • C++进程间通信开发实战:高效解决项目中的IPC问题
  • 【c语言基础学习】qsort快速排序函数介绍与使用
  • 3D开发工具HOOPS助力Hexagon智能制造突破技术瓶颈,重塑测量软件用户体验!
  • 算法——置换与排列【基础】
  • LVGL Video控件和Radiobtn控件详解
  • 【无标题】Spark-SQL编程(2)
  • 玩转Docker | 使用Docker部署Xnote笔记工具
  • 从Gradio App创建Discord Bot/Slack Bot/Website Widget(2)——从Gradio App创建Slack Bot
  • 智谱开源 9B/32B 系列模型,性价比超 DeepSeek-R1,Z.ai 平台上线
  • 疾控01-实验室信息管理系统需求分析
  • 2025.4.15六年之约day11
  • linux0.11内核源码修仙传第十三章——进程调度之fork函数
  • 用DeepSeek AI高效制作专业PPT
  • DES对称加密算法实操(python)
  • 入门-C编程基础部分:4、数据类型
  • 【力扣】day1
  • 第十一章 网络编程
  • 子公司神州信息十年来首次亏损,神州控股遭国有股东广州城投派驻董事问责
  • 生于1987年,万宏宇已任内蒙古鄂温克旗委常委
  • 观察|上海算力生态蓬勃发展,如何助力千行百业数智化转型升级
  • 蚂蚁集团将向全体股东分红
  • 乐聚创始人:人形机器人当前要考虑泡沫问题,年底或将进入冷静期
  • 今年地质灾害防治形势严峻,哪些风险区被自然资源部点名?