以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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • 构建Golang应用最小Docker镜像的实现

    我通常使用docker运行我的 golang 程序,在这里分享一下我构建 docker 镜像的经验.我构建 docker 镜像不仅优化构建后的体积,还要优化构建速度. 示例应用 首先贴出代码例子,我们假设要构建一个 http 服务 package main import ( "fmt" "net/http" "time" "github.com/gin-gonic/gin" ) func main() { fmt.Printl

  • golang将切片或数组根据某个字段进行分组操作

    我就废话不多说了,大家还是直接看代码 吧~ package main import ( "fmt" "sort" ) type Person struct { Name string Age int } func main() { p1 := Person{"Tom",20} p2 := Person{"Lily",21} p3 := Person{"Linda",23} p4 := Person{&quo

  • golang定时器和超时的使用详解

    我就废话不多说了,大家还是直接看代码吧~ func main() { var a chan string a =make(chan string) go sendDataTo(a) go timing() getAchan(10*time.Second,a) } func sendDataTo(a chan string) { for { a <- "我是a通道的数据" time.Sleep(1e9 *3) } } //在一定时间内接收不到a的数据则超时 func getAcha

  • golang gin框架获取参数的操作

    1.获取URL参数 GET请求参数通过URL传递 URL参数可以通过DefaultQuery()或Query()方法获取 DefaultQuery()若参数不存在,返回默认值,Query()若参数不存在,返回空串 user_id := com.StrTo(ctx.Query("user_id")).MustInt64() page := com.StrTo(ctx.DefaultQuery("page", "1")).MustInt() 2.获取

  • Golang的select多路复用及channel使用操作

    看到有个例子实现了一个类似于核弹发射装置,在发射之前还是需要随时能输入终止发射. 这里就可以用到cahnnel 配合select 实现多路复用. select的写法用法有点像switch.但是和switch不同的是,select的一个case代表一个通信操作(在某个channel上进行发送或者接收)并且会包含一些语句组成的一个语句块.现在让我们来实现一下这个核弹发射器 package main import ( "fmt" "time" "os"

  • 以alpine作为基础镜像构建Golang可执行程序操作

    Alpine介绍 Alpine 操作系统是一个面向安全的轻型 Linux 发行版.它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐.在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种

  • Docker 部署Go的两种基础镜像的实现

    一. golang:latest 基础镜像 mkdir gotest touch main.go touch Dockerfile 1. 实例代码 package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { f

  • Docker镜像构建原理解析(不装docker也能构建镜像)

    在devops流程里面 构建镜像是一个非常重要的过程,一般构建镜像是写dockerfile文件然后通过docker client来构建的image. docker client 会先检查本地有没有image,如果没有帮你 从镜像仓库 pull 下来 然后解析你写的dockerfile构建新的image. 本文带你了解 pull 命令 背后是怎么做的? build 命令 背后是怎么做的? 下篇文章带你解析: 如果我不用docker 我如何构建一个镜像? 我们以微软的aspnet2.2为基础构建一个

  • Docker 制作镜像Dockerfile和commit操作

    构建镜像 构建镜像主要有两种方式: 使用docker commit命令从运行中的容器提交为镜像: 使用docker build命令从 Dockerfile 构建镜像. 首先介绍下如何从运行中的容器提交为镜像.我依旧使用 busybox 镜像举例,使用以下命令创建一个名为 busybox 的容器并进入 busybox 容器. $ docker run --rm --name=busybox -it busybox sh 执行完上面的命令后,当前窗口会启动一个 busybox 容器并且进入容器中.在

  • 从零开始构建docker基础镜像的方法

    段子 今年基本已经结束了,我问了很多朋友今年挣钱了没?大多朋友都有挣,而且挣得五花八门:有挣个屁的,有挣个锤子的,有挣个毛的,更有甚者挣个妹的,奢侈之极!最恐怖的是挣个鬼的!有的还可以,挣个球,下午我碰见一朋友,问今年挣了吗?他望着天空喃喃自语:挣个鸟!看吧,只要肯努力,什么都能挣到. 年末将至,忽然发现,从创建开始到现在,整整一年时间,没有写过多少东西.为了留下一点痕迹,也是为了整理一下自己的收获,为17年画上一笔浓郁的色彩. 最近在看一本入门级机器学习的书,里面的案例基本上是python实现

  • Docker构建Maven+Tomcat基础镜像的实现

    前言 在 Java 编程中,大多数应用都是是基于 Maven 构建的,而交付的结果大多是采用的 Tomcat 的 war 包形式,所以,构建一个基于 Maven 和 Tomcat 的基础镜像很有必要,不仅能帮助我们提升平时自主实验研究分析的效率,还可以在一定程度能减少运维减少编写 Dockerfile 的复杂度,提升整体项目交付效率. 1.创建编译目录 mkdir -p build_docker cd build_docker vim Dockerfile 2.编写 Dockerfile 首先,

  • docker 基于golang镜像构建 ssh服务的方法

    下面给大家介绍下docker 基于golang镜像构建 ssh服务的代码,具体内容如下所示: # golang:latest镜像 FROM ee23292e2826 # 作者 MAINTAINER dechao@qq.com # 添加Golang环境变量 ENV GOPROXY https://goproxy.cn,direct ENV GO111MODULE on # 配置apt-get源 ADD sources.list /etc/apt/ # 更新apt-get源 安装ssh服务 修改ro

  • Docker中镜像构建文件Dockerfile与相关命令的详细介绍

    前言 使用docker build命令或使用Docker Hub的自动构建功能构建Docker镜像时,都需要一个Dockerfile文件.Dockerfile文件是一个由一系列构建指令组成的文本文件,docker build命令会根据这些构建指令完成Docker镜像的构建.本文将会介绍Dockerfile文件,及其中使用的构建指令. 1. Dockerfile文件使用 docker build命令会根据Dockerfile文件及上下文构建新Docker镜像.构建上下文是指Dockerfile所在

  • 使用Docker镜像构建Go应用的实现方法

    目录 修炼背景 第一次尝试 第二次尝试 第三次尝试 神功练成 项目地址 修炼背景 我夜以继日,加班加点开发了一个最简单的 Go Hello world 应用,虽然只是跑了打印一下就退出了,但是老板也要求我上线这个我能写出的唯一应用. 项目结构如下: . ├── go.mod └── hello.go hello.go 代码如下: package main func main() { println("hello world!") } 并且,老板要求用 docker 部署,显得咱们紧跟潮

随机推荐