Golang的docker尝试


声明:本文转载自https://my.oschina.net/dingdayu/blog/1554105,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

一、 前言

docker 就不在这里介绍了,相关的文档已经很完善,中文文档 Docker —— 从入门到实践 写的很棒,推荐去看看。

docker 基于 Golang 开发,已经不用解释了,而 Golang 天生适合运行在 docker 容器中,却不是这个原因,这得益于:Golang 的静态编译,当在编译的时候关闭 cgo 的时候,可以完全不依赖系统环境。

二、 Golang代码

我们打算在 docker 中测试 Golang ,所以先编写一个 Golang 的测试代码。

新建文件:vi main.go

package main  import ( 	"fmt" 	"io/ioutil" 	"net/http" 	"os" )  func main() { 	resp, err := http.Get("https://www.baidu.com") 	check(err) 	body, err := ioutil.ReadAll(resp.Body) 	check(err) 	fmt.Println(len(body)) }  func check(err error) { 	if err != nil { 		fmt.Println(err) 		os.Exit(1) 	} }  

这是一个简单的程序,拉取百度的页面,并计算页面的字节大小。

需要注意的时,这里采用了 https ,这里埋下一个伏笔,后面解释。

三、 编写 dockerfile

1. 基于完整镜像

Docker官方提供了Golang各版本的镜像: Official Repository - golang.

新建文件:vi dockerfile

FROM golang:latest RUN mkdir /app  ADD . /app/  WORKDIR /app  RUN go build -o main .  CMD ["/app/main"] 

Docker的镜像必须基于某个镜像开始,然后开始创建新的镜像,这里基于 golang:latest 开始创建,在镜像里创建/app文件夹,并将当前所在文件夹内所有内容添加到镜像内的/app文件内,将镜像内的/app设置为容器工作目录(这里不可使用RUN cd /app切换当前工作目录); 然后编译当前目录下Golang代码,然后使用CMD命令运行刚才编译出的程序。

具体命令解释查看:Dockerfile 指令详情

1) 当前目录下文件

admin@dingdayu-DS:/volume1/docker/docker-golang$ ls dockerfile  main.go 

输入图片说明

2) 编译镜像

sudo docker build -t golang-latest-app . 

输入图片说明

受制于网络和机器的性能,编译镜像,竟然花了20多分钟。。。

镜像编译完成,完整大小739M,对于线上的部署,无论是编译时间还是大小都是不合适的,下面的scratch镜像,用来解决这个问题。

输入图片说明

sudo docker run -it --rm --name my-golang-app golang-latest-app 

执行镜像,查看效果:

输入图片说明

2. 基于scratch镜像

scratch 是一个特殊的镜像,它是一个虚拟镜像,也就是一个空白镜像;利用Golang的静态化编译无依赖性,可以大幅度减少编译时间和镜像大小。

1) 编译Golang

基于scratch必须先打包,然后才能进行运行。

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . 

GOOS=linux 是将交叉编译的目标设置为Linux,这样你在Mac或者Win下也不会出现问题。 -installsuffix cgo 是为了在静态编译中导入net

2) 编辑dockerfile

修改文件:vi dockerfile

FROM scratch RUN mkdir /app ADD main /app/ WORKDIR /app CMD ["/app/main"] 

3) 编译镜像

sudo docker build -t golang-scratch-app . 

输入图片说明

scratchgolang:latest的大小差了730多兆。。。。

4) 空白镜像挂载文件

启动镜像

sudo docker run -it --rm --name my-golang-scratch golang-scratch-app 

你会发现提示:

Get https://www.baidu.com: x509: failed to load system roots and no roots provided 

这是一个非常常见的问题:为了进行SSL请求,我们需要SSL根证书。

5) 挂载文件

根据操作系统,这些证书可以在许多不同的地方。如果您查看Gox509库,可以查看Go搜索的所有位置。对于许多Linux发行版,这是/etc/ssl/certs/cacert.pem。首先,我们将把我们的机器(或Linux VM在线证书提供者)的cacert.pem复制到我们的存储库中。然后,我们将在Docker文件中添加一个ADD,将这个文件放在Go所期望的位置:

下载 cacert.pem 到当前工作目录:

wget https://curl.haxx.se/ca/cacert.pem 

再次编辑dockerfile

FROM scratch ADD cacert.pem /etc/ssl/certs/ ADD main / CMD ["/main"] 

6) 执行镜像

sudo docker run -it --rm --name my-golang-scratch golang-scratch-app 

输入图片说明

完美执行!

四、 关键点

  • Dockerfile 指令详情
  • 镜像编译命令: sudo docker build -t golang-latest-app . => golang-latest-app 为镜像名
  • 容器启动命令: sudo docker run -it --rm --name my-golang-app golang-latest-app => my-golang-app 为容器名,golang-latest-app 为镜像名
  • Golang的静态编译: CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .

五、 链接

  1. Building Minimal Docker Containers for Go Applications
  2. [创建超小的Golang docker 镜像](http://colobu.com/2015/10/12/create-minimal-golang-docker-images/

本文发表于2017年10月20日 22:34
(c)注:本文转载自https://my.oschina.net/dingdayu/blog/1554105,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 1969 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1