以alpine作为基础镜像构建Golang可执行程序操作
作者:思维的深度
Alpine介绍
Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。
Alpine 由非商业组织维护的,支持广泛场景的 Linux发行版,它特别为资深/重度Linux用户而优化,关注安全,性能和资源效能。Alpine 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。
Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 docker-alpine 项目。
目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。
下表是官方镜像的大小比较:
REPOSITORY TAG IMAGE ID VIRTUAL SIZE alpine latest 4e38e38c8ce0 4.799 MB debian latest 4d6ce913b130 84.98 MB ubuntu latest b39b81afc8ca 188.3 MB centos latest 8efe422e6104 210 MB
Alpine和其他通用Linux发行版对于Golang编译出来的可执行文件要求有所不同,Alpine要求可执行文件必须是静态链接的可执行文件。
所以在编译Golang时需要添加 -tags netgo ,来生成静态链接的可执行文件。
示例:
代码示例:每三秒控制台输出一次消息,输出100次
package main import ( "fmt" "time" ) func main() { for i := 0 ; i< 100 ; i++ { fmt.Println("hello,",i) time.Sleep(time.Second*3) } }
编译成静态链接的可执行文件:
go build -tags netgo -o test
Dockerfile的参考内容:
FROM alpine:latest ADD test /usr/local/bin/ # Alpine Linux doesn't use pam, which means that there is no /etc/nsswitch.conf, # but Golang relies on /etc/nsswitch.conf to check the order of DNS resolving # (see https://github.com/golang/go/commit/9dee7771f561cf6aee081c0af6658cc81fac3918) # To fix this we just create /etc/nsswitch.conf and add the following line: RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf WORKDIR /usr/local/bin/ CMD ["test"]
构建镜像、运行容器即可
补充:编译后的go程序无法在alpine基础镜像创建的容器运行问题
问题描述:
我要使用容器创建一个使用golang的http的服务,为了不让镜像太大,所以选择了基础镜像alpine,才几m,但把go的程序编译之后无法在容器中运行,解决办法是在编译go程序时,加上参数-tags netgo。
具体做法如下:
1、首先下载apline基础镜像:
docker pull docker.io/alpine
2、编译go程序:(我的程序是sensor.go,编译之后放在sensors目录下)
go build -tags netgo -o sensors/sensor sensor.go
3、dockerfile文件,保存为sensor:
FROM docker.io/alpine:latest
MAINTAINER weinengl
# 拷贝相关文件。
COPY sensors/sensor /tmp/
RUN chmod +x /tmp/sensor
ENTRYPOINT ["/tmp/sensor"]
4、镜像制作命令:
docker build -t reg.netlab.com/temperature:v1 -f sensor .
制作完成之后运行即可:
docker run -itd -p 8881:8881 --name test10 reg.netlab.com/temperature:v1
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。