在 alpine 上打包运行go服务

简介: 在 alpine 上打包运行go服务

前言


有一位朋友看了 Docker私有仓库搭建&Go服务部署之后就在自己的项目中开发环境用上了, 然后现在项目要部署到测试及生产环境, 因为他们之前的项目没用docker且go的版本为1.12, 当前项目的环境为go 1.14, 老大要求每个项目的环境必须隔离, 打包也必须要镜像内打包(避免人工打包失误), 这位朋友在容器内打包的时候遇到了挺麻烦的问题求助了一下我, 所以就有了这篇文章

上次讲的是开发环境自己在本地打包然后把二进制放在镜像里运行, 方便快捷, 这次线上环境要在容器内用go打包二进制运行文件的话就需要对应的环境和依赖安装了, 包管理的话还是建议go mod, 个人感觉方便好用


在 alpine 上打包运行go服务


之前的Dockerfile是这样


# 设置基础镜像
FROM golang:1.14.4-alpine
# 作者描述信息
LABEL maintainer="飞啊飞"
# 使用国内源
RUN echo -e http://mirrors.aliyun.com/alpine/v3.7/main/ > /etc/apk/repositories
# copy当前目录的文件到镜像里面的工作目录目录下
COPY ./config/test.json /demo/   // 配置文件
COPY server /demo/               // 打包的linux二进制文件
#设置东八区,北京时间
ENV TZ=Asia/Shanghai
RUN apk add --no-cache tzdata && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 指定路径
WORKDIR /demo/
# 执行命令  这里给文件增加执行权限
RUN ["chmod", "+x", "/demo/server"]
# 容器入口, 执行命令
CMD ["./server", "-config", "test.json"]


因为服务器版本的问题, 所以需要在docker内打包部署, 奉上一份正确的Dockerfile, 然后下面说遇到的问题

# 设置基础镜像
FROM golang:1.14.4-alpine
# 作者描述信息
LABEL maintainer="飞啊飞"
# copy整个项目
COPY ./config/test.json /demo/   // 配置文件
COPY . /demo/                    // 项目文件
# 使用阿里源&&设置东八区,北京时间
ENV TZ=Asia/Shanghai
RUN echo -e http://mirrors.aliyun.com/alpine/v3.10/main/ > /etc/apk/repositories \
    && apk update \
    && apk add --no-cache tzdata gcc g++ libffi-dev musl-dev openssl-dev make linux-headers libc-dev libc6-compat binutils \
    && ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
    && echo $TZ > /etc/timezone 
# 指定路径
WORKDIR /demo/
# 打包二进制&&增加执行权限
RUN export GOPROXY=https://mirrors.aliyun.com/goproxy/ \
    && go mod tidy \
    && export GOARCH=amd64 \
    && export GOOS=linux \
    && go build -o server ./main.go \
    && chmod +x server
# 容器入口, 执行命令
CMD ["./server", "-config", "test.json"]

说一下主要的两个坑

一 报错如下, 需要安装GCC

exec: "gcc": executable file not found in $PATH
# github.com/karalabe/usb
exec: "gcc": executable file not found in $PATH
# github.com/ethereum/go-ethereum/rpc
exec: "gcc": executable file not found in $PATH

二 GCC运行失败

# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: running gcc failed: exit status 1
/usr/lib/gcc/x86_64-alpine-linux-musl/6.4.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/go-link-364684937/000000.o: unable to initialize decompress status for section .debug_info
/usr/lib/gcc/x86_64-alpine-linux-musl/6.4.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/go-link-364684937/000000.o: unable to initialize decompress status for section .debug_info
/usr/lib/gcc/x86_64-alpine-linux-musl/6.4.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/go-link-364684937/000000.o: unable to initialize decompress status for section .debug_info
/usr/lib/gcc/x86_64-alpine-linux-musl/6.4.0/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/go-link-364684937/000000.o: unable to initialize decompress status for section .debug_info
/tmp/go-link-364684937/000000.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

参考一:

https://stackoverflow.com/questions/53964313/error-compiling-go-from-source-in-an-alpine-docker-container-loadinternal-can


20200807101331862.png


cgo在alpine 上运行需要依赖musl_dev 这个包, 在Dockerfile中加入后还是不行

参考二:

https://github.com/zmap/zlint/issues/316

20200807101629499.png


问题定位到了, 需要binutils 包的版本大于2.32并且 alpine 的版本大于等于 3.10, 我之前仓库用的是alpine 3.7版本的, 下载的binutils 包版本太低, 所以把阿里源的仓库版本改为3.10就好了, 问题解决


总结


找这种问题还是挺费劲的, 所以在此记录一下, 与人方便与己方便

目录
相关文章
|
21小时前
|
缓存 负载均衡 网络协议
使用Go语言开发高性能服务的深度解析
【5月更文挑战第21天】本文深入探讨了使用Go语言开发高性能服务的技巧,强调了Go的并发性能、内存管理和网络编程优势。关键点包括:1) 利用goroutine和channel进行并发处理,通过goroutine池优化资源;2) 注意内存管理,减少不必要的分配和释放,使用pprof分析;3) 使用非阻塞I/O和连接池提升网络性能,结合HTTP/2和负载均衡技术;4) 通过性能分析、代码优化、缓存和压缩等手段进一步提升服务性能。掌握这些技术能帮助开发者构建更高效稳定的服务。
|
6天前
|
存储 Java Linux
聊聊Go程序是如何运行的
本文作者 **sharkChili** 是一名 Java 和 Go 语言开发者,同时也是 CSDN 博客专家和 JavaGuide 维护者。文章探讨了 Go 语言的执行过程,从汇编角度出发,解释了如何从 `main.go` 文件开始,经过入口跳转、参数拷贝、启动协程、运行 `g0` 的 `main` 方法等步骤,最终执行到用户定义的 `main` 函数。文章还展示了相关汇编代码片段,并提供了运行时检查、系统初始化和调度器初始化的细节。结尾提到,有兴趣的读者可以加入作者创建的交流群进行深入讨论。
12 0
|
6天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
56 0
|
6天前
|
负载均衡 算法 Go
Golang深入浅出之-Go语言中的服务注册与发现机制
【5月更文挑战第4天】本文探讨了Go语言中服务注册与发现的关键原理和实践,包括服务注册、心跳机制、一致性问题和负载均衡策略。示例代码演示了使用Consul进行服务注册和客户端发现服务的实现。在实际应用中,需要解决心跳失效、注册信息一致性和服务负载均衡等问题,以确保微服务架构的稳定性和效率。
22 3
|
6天前
|
Go 微服务
4. 参考 go 代码——服务注册与发现
4. 参考 go 代码——服务注册与发现
|
6天前
|
存储 负载均衡 监控
【Go 语言专栏】构建高可靠性的 Go 语言服务架构
【4月更文挑战第30天】本文探讨了如何利用Go语言构建高可靠性的服务架构。Go语言凭借其高效、简洁和并发性能,在构建服务架构中备受青睐。关键要素包括负载均衡、容错机制、监控预警、数据存储和服务治理。文章详细阐述了实现这些要素的具体步骤,通过实际案例分析和应对挑战的策略,强调了Go语言在构建稳定服务中的作用,旨在为开发者提供指导。
|
6天前
|
缓存 监控 测试技术
【Go语言专栏】使用Go语言构建高性能Web服务
【4月更文挑战第30天】本文探讨了使用Go语言构建高性能Web服务的策略,包括Go语言在并发处理和内存管理上的优势、基本原则(如保持简单、缓存和并发控制)、标准库与第三方框架的选择、编写高效的HTTP处理器、数据库优化以及性能测试和监控。通过遵循最佳实践,开发者可以充分利用Go语言的特性,构建出高性能的Web服务。
|
6天前
|
运维 Serverless Go
Serverless 应用引擎产品使用之在阿里云函数计算中,Go语言的函数计算服务Go程序没有正确打包如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
27 0
|
6天前
|
Go 调度
|
6天前
|
安全 中间件 Go
Go语言Web服务性能优化与安全实践
【2月更文挑战第21天】本文将深入探讨Go语言在Web服务性能优化与安全实践方面的应用。通过介绍性能优化策略、并发编程模型以及安全加固措施,帮助读者理解并提升Go语言Web服务的性能表现与安全防护能力。