go 构建image图像
在本系列中有关源到图像 (S2I)的第一篇文章中,我们检查了所需的文件,并讨论了S2I标准如何与任何编程语言(从Python到Ruby到Go)一起使用。 现在,让我们探索设计专门用于Go应用程序的S2I构建。 免责声明:尽管仍未正式将Go称为Golang,但我仍喜欢将其称为Golang。
Golang S2I文件
所有S2I环境的核心都始于定义为Dockerfile的配置文件。 我们的Golang构建器图像也不例外; 这个项目将需要一个Dockerfile 创建构建器,具有用于编译Go应用程序的逻辑的汇编脚本,用于启动应用程序的运行脚本(仅出于方便目的)以及用于保存已编译应用程序的save-artifacts脚本。
让我们看一下这些必需的文件,因为我们将它们用于构建器映像。
注意:所有引用的文件都在我的golang-s2i GitHub存储库中 。
Docker文件
这个Dockerfile不是很复杂。 该构建器映像将使用上游golang:1.12映像作为其基础,因此我们不必安装Go并设置环境。 必须设置两个环境变量以允许Go应用程序在容器环境中运行:
- CGO_ENABLED = 0
- GOOS = Linux
如果您想进一步了解为什么要使用它们,请查看Kelsey Hightower的出色文章“ 为静态Go二进制文件构建Docker映像 ”。
还需要在Dockerfile中设置GOCACHE = / tmp环境变量,以避免在以root以外的用户身份运行构建时避免写入错误。 这是OKD / OpenShift约定,以支持运行具有任意UID的容器 ,但这也是避免同时需要root特权进行构建的良好实践。 请查看Dan Walsh的文章“ 只是对容器中的root拒绝 ”,以了解为什么这是一件好事。
然后再设置两个环境变量:
- STI_SCRIPTS_PATH = / usr / libexec / s2i
- SOURCE_DIR = / go / src / app
第一个告诉S2I在哪里可以找到需要运行的脚本,第二个只是为了方便起见,所以我们的项目是DRY 。
在下一节中, 复制 S2I脚本(见下文)的制造商形象,创造和chmod的$ SOURCE_DIR放在脚本将编译应用程序,以便后续操作发生在该目录中其设置为WORKDIR:
COPY .
/ s2i
/ bin
/
${STI_SCRIPTS_PATH}
RUN
mkdir
-p
$SOURCE_DIR \
&&
chmod 0777
$SOURCE_DIR
WORKDIR
$SOURCE_DIR
注意: $ SOURCE_DIR设置为/ go / src / app,因为父golang:1.12映像中的$ GOPATH变量设置为/ go 。
最后,如上所述,将USER 1001设置为放弃root特权并确保对随机UID的支持,并将CMD设置为S2I使用脚本:
USER
1001
CMD
[
"/usr/libexec/s2i/usage"
]
此时,我们的Dockerfile应该看起来像我的GitHub存储库中的Dockerfile ,除了一些标签和注释。
组装
S2I使用汇编脚本来编译Go应用。
当S2I将应用程序代码复制到构建器映像中时,它将放置在/ tmp / src中 。 由于上游映像将GOPATH设置为/ go ,因此汇编脚本仅需要复制到该目录中:我们在映像中先前设置的$ SOURCE_DIR 。 然后,只需运行go get and go build即可 。 由于WORKDIR设置为同一目录,因此脚本将从此处运行:
#!/bin/bash -e
# Copy the src to the current directory - the WORKDIR/$SOURCE_DIR.
cp
-Rf
/ tmp
/ src
/ . .
/
go get
-v
go build
-v
-o app
-a
-installsuffix cgo
使用-o app build标志运行go build命令,以便生成的二进制文件具有可预测的名称(特别是“ app”)。
这就是汇编脚本所需的全部内容,但是还可以在脚本的末尾包含go test -v ,以确保应用程序通过所有代码测试(因为如果任何测试失败,它将使映像构建失败)。
汇编脚本就是这样。 GitHub中的组装脚本包括一些命令,用于从先前的版本中复制工件,但其他方面是相同的。
跑
如果S2I正在运行所生成图像生成的容器,则S2I使用运行脚本来执行该应用程序。 适当地,它只有两行:
#!/bin/bash
exec app
注意:如果应用程序需要参数,则需要对该脚本进行一些微调以传递这些参数(这就是为什么当应用程序本身只是“运行”脚本时,Go才包含该脚本的原因)。
保存工件
S2I不需要保存工件图像。 它的目的是重用以前构建的构件(例如:下载的PIP软件包或Ruby gem)并进行增量构建,以便可以更快地构建开发映像。 Golang构建器映像将使用它一点不同:允许我们提取已编译的二进制文件,以便可以将其包含在更苗条的运行时映像中(请参见下文)。
S2I期望save-artifacts脚本获取应用程序的所有文件和依赖项,并通过tar命令将它们流式传输到stdout,以便可以在另一端接收并保存它们。 从理论上讲这很容易,但是如果您不小心,可能会很棘手。 流到stdout的内容必须仅包含tar文件的内容; 我们必须小心以防止发送文本或其他内容。 我们需要将tar以外的所有其他输出通过管道传递到/ dev / null,以确保tar归档文件不会被其他数据破坏。
专家提示:如果我们尝试通过运行save-artifacts脚本作为容器的命令来手动将tar文件的内容从容器中流出来,则我们一定不要使用-i或-t参数,因为tar拒绝流输出到伪终端。
在我们的例子中,由于构建器正在编译单个二进制文件,因此该脚本也只有两行,并且没有其他需要担心的输出:
#!/bin/sh -e
tar cf – app
现在,我们为Golang应用程序提供了功能齐全的S2I环境。 我们可以在命令行上解决这个问题。 如果您需要对所有这些文件进行复习,请返回并阅读本系列的第一篇文章 。 在下一篇文章中,我们将继续构建过程,并完成构建Go应用程序的工作流程。
翻译自: https://opensource.com/article/19/5/source-image-golang-part-2
go 构建image图像