学习
实践
活动
专区
工具
TVP
写文章
专栏首页Serverless+基于 Alpine 的 Docker 镜像编译的程序无法在云函数环境运行
原创

基于 Alpine 的 Docker 镜像编译的程序无法在云函数环境运行

最近有一个用户反馈, 他使用 golang:1.13.1-alpine3.10 这个镜像来编译的可执行程序无法在云函数的环境运行, 报错信息如下:

fork/exec /var/user/main: no such file or directory

macOS 下编译则没有这个问题

问题定位

还未来得及定位问题, 用户便反馈说换了一个镜像就没问题了, 于是没能获得更多信息

过了几天, 有一个同事在群里贴出了 Go 程序链接出错的信息, 看起来也是在 Alpine Linux 下编译的, 有人回复道 Alpine Linux 使用的不是 glibc

啊哈, 终于有线索了, 写代码验证一下

package main

import "fmt"

func main() {
	fmt.Println("hello world")
}

CentOS 上编译后, 使用 ldd 查看一下程序依赖哪些 .so(也可以使用 readelf -d)

$ ldd main
        not a dynamic executable

程序太简单了, 没有依赖动态库

搜索了一下, 发现 Go 的仓库有一个 issue #33019, 和我们的问题很类似

package main

import (
	"net"
	"fmt"
	"os"
)

func main() {
	ips, err := net.LookupIP("localhost")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Could not get IPs: %v\n", err)
		os.Exit(1)
	}
	for _, ip := range ips {
		fmt.Printf("localhost. IN A %s\n", ip.String())
	}
}

编译这段代码, 再次使用 ldd 查看一下程序依赖哪些 .so

$ ldd main
        linux-vdso.so.1 =>  (0x00007ffca89c9000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f6c4b4bd000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f6c4b0f9000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f6c4aef5000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f6c4b6d9000)

终于和 glibc 扯上关系了

使用 golang:1.13.1-alpine3.10 这个镜像重新编译一下这段代码, 看看结果有什么不同

$ docker run -v $PWD:/go/src/test -w /go/src/test golang:1.13.1-alpine3.10 go build -o main-alpine
$ ldd main-alpine
        linux-vdso.so.1 =>  (0x00007ffe0055e000)
        libc.musl-x86_64.so.1 => not found
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f2512754000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f2512390000)
        /lib/ld-musl-x86_64.so.1 => /lib64/ld-linux-x86-64.so.2 (0x00007f2512958000)

可以看到, 缺失了 libc.musl-x86_64.so.1, 运行一下程序

$ ./main-alpine
-bash: ./main-alpine: /lib/ld-musl-x86_64.so.1: bad ELF interpreter: No such file or directory

No such file or directory 正是本文一开始提到的出错信息

(完整的出错信息可通过使用 Go 的 os/exec 包启动 main-alpine 获得)

解决方案

问题的原因在于云函数的运行环境(CentOS)提供的是 glibc, 而 Alpine Linux 却是 musl libc. 因而使用 golang:1.13.1-alpine3.10 这个镜像编译出来的程序如果依赖于 musl libc, 则会在程序加载的时候找不到所需的动态库

解决问题的方法很简单, 只需将镜像换成 golang:<version> 的版本(如golang:1.12)即可

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

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

登录 后参与评论
0 条评论

相关文章

  • Docker容器镜像体积缩小技巧

    描述:前面我们学习并且记录了 Dockerfile 最佳实践的一些规则,但是仅仅停在理论中并不是我的风格,所以出现了本篇文章同时也加深学习; 从最佳实践原则我们...

    WeiyiGeek
  • 从Docker镜像构建演化史来了解多阶段构建的影响

    现在很多开发者都会慢慢习惯在开发环境通过Docker来构建开发环境,有时候可能会有环境移植的问题,所以需要我们写好一套Dockerfile来构建相关的开发镜像,...

    云爬虫技术研究笔记
  • 优化Docker镜像,加速应用部署,教你6个小窍门

    基于Kubernetes的新版小米应用引擎在小米生态云上线3个多月来,深受大家喜爱。为了让用户的云端应用管理更高效、更方便,今天从6个方面分享一些溜到飞起的小窍...

    DevOps云学堂
  • Dockerfile 之最小化 Java 镜像的常用技巧

    随着容器技术的普及,越来越多的应用被容器化。人们使用容器的频率越来越高,但常常忽略一个基本但又非常重要的问题 - 容器镜像的体积。本文将介绍精简容器镜像的必要性...

    kubernetes中文社区
  • Docker 工作原理及容器化简易指南

    Docker 非常棒! 它使软件开发者无需担心配置和依赖性,在任何地方打包,发送和运行他们的应用程序。而在与 Kubernetes 相结合后,它使应用集群部署和...

    SDNLAB
  • NodeJS 服务 Docker 镜像极致优化指北

    以一个例子开头,大部分刚接触 Docker 的同学应该都会这样编写项目的 Dockerfile,如下所示:

    winty
  • 三个技巧 大幅减少 Docker 镜像体积

    在构建 Docker 容器时,应该尽量想办法获得体积更小的镜像,因为传输和部署体积较小的镜像速度更快。但 RUN 语句总是会创建一个新层,而且在生成镜像之前还需...

    Debian中国
  • 三个技巧,将Docker镜像体积减小90%

    在构建 Docker 容器时,应该尽量想办法获得体积更小的镜像,因为传输和部署体积较小的镜像速度更快。

    菲宇
  • 如何缩小您的docker 镜像体积

    写好node代码后,打包进docker发现镜像非常大,下面方法有助于构建一个一个体积小很多的镜像;

    常见_iginkgo
  • 三个技巧,将Docker镜像体积减小90%【面试+工作】

    在构建Docker容器时,应该尽量想办法获得体积更小的镜像,因为传输和部署体积较小的镜像速度更快。

    Java帮帮
  • 什么时候使用Dockerfiles(什么时候不使用……)

    在这篇文章中,我们将讨论一些使用 Dockerfile 的最佳实践,探索一些注意事项,并使用 Dockerfile 和云原生 Buildpacks 构建应用。你...

    CNCF
  • 还在用Alpine作为你Docker的Python开发基础镜像?其实Ubuntu更好一点

        但是先别着急,假设我们的python应用需要做一些科学计算,并且将数据以图形的方式展示出来,这时候就需要matplotlib和pandas这两个库的帮助...

    用户9127725
  • 前端开发需要掌握的 Docker 知识

    学习一门技术,我们不仅仅要看到它的 API,还要站在更高的角度去看待它的发展,它的整个生命周期。

    拿我格子衫来
  • Docker 镜像优化:从 1.16GB 到 22.4MB

    Docker 是一个供软件开发人员和系统管理员使用容器构建、运行和与分享应用程序的平台。容器是在独立环境中运行的进程,它运行在自己的文件系统上,该文件系统是使用...

    肉眼品世界
  • Docker 镜像优化:从 1.16GB 到 22.4MB

    Docker 是一个供软件开发人员和系统管理员使用容器构建、运行和与分享应用程序的平台。容器是在独立环境中运行的进程,它运行在自己的文件系统上,该文件系统是使用...

    终码一生
  • Docker镜像优化:从1.16GB到22.4MB!

    Docker 是一个供软件开发人员和系统管理员使用容器构建、运行和与分享应用程序的平台。容器是在独立环境中运行的进程,它运行在自己的文件系统上,该文件系统是使用...

    macrozheng
  • Docker镜像优化:从1.16GB到22.4MB

    Docker 是一个供软件开发人员和系统管理员使用容器构建、运行和与分享应用程序的平台。容器是在独立环境中运行的进程,它运行在自己的文件系统上,该文件系统是使用...

    码农架构
  • 3.Docker学习之Dockerfile

    描述:Dockerfile是一个文本格式的配置文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当...

    WeiyiGeek
  • Docker 构建 Tengine 2.2.2 镜像

    Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型...

    緣來

作者介绍

ritchiechen

腾讯后台开发工程师

腾讯 · 后台开发工程师 (已认证)

专栏

精选专题

活动推荐

关注

腾讯云开发者公众号
10元无门槛代金券
洞察腾讯核心技术
剖析业界实践案例
腾讯云开发者公众号二维码

扫码关注腾讯云开发者

领取腾讯云代金券